diff --git a/data/images/grooveshark.png b/data/images/grooveshark.png
new file mode 100644
index 000000000..d7cd43b33
Binary files /dev/null and b/data/images/grooveshark.png differ
diff --git a/resources.qrc b/resources.qrc
index 8b9160c9b..bd779ef74 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -133,6 +133,7 @@
data/images/headphones-bigger.png
data/images/no-album-no-case.png
data/images/rdio.png
+ data/images/grooveshark.png
data/sql/dbmigrate-27_to_28.sql
data/images/process-stop.png
diff --git a/src/libtomahawk/utils/groovesharkparser.cpp b/src/libtomahawk/utils/groovesharkparser.cpp
index ec088cc08..d8353dfb9 100644
--- a/src/libtomahawk/utils/groovesharkparser.cpp
+++ b/src/libtomahawk/utils/groovesharkparser.cpp
@@ -39,6 +39,10 @@
#include
#include
+#include
+#include
+#include
+
using namespace Tomahawk;
QPixmap* GroovesharkParser::s_pixmap = 0;
@@ -72,15 +76,17 @@ GroovesharkParser::~GroovesharkParser()
void
GroovesharkParser::lookupUrl( const QString& link )
{
- if( link.contains( "playlist" ) )
+ if ( link.contains( "playlist" ) )
{
- if( !m_createNewPlaylist )
+ if ( !m_createNewPlaylist )
m_trackMode = true;
else
m_trackMode = false;
lookupGroovesharkPlaylist( link );
}
+ else if ( link.contains( "grooveshark.com/s/" ) || link.contains( "grooveshark.com/#/s/" ) )
+ lookupGroovesharkTrack( link );
else
return;
@@ -97,7 +103,7 @@ GroovesharkParser::lookupGroovesharkPlaylist( const QString& linkRaw )
tDebug() << "no fragment, setting fragment to path";
urlFragment = QUrl(linkRaw).path();
}
-
+
tDebug() << urlFragment;
int paramStartingPostition = urlFragment.indexOf( "?" );
@@ -108,22 +114,22 @@ GroovesharkParser::lookupGroovesharkPlaylist( const QString& linkRaw )
bool ok;
QStringList urlParts = urlFragment.split( "/", QString::SkipEmptyParts );
-
+
tDebug() << urlParts;
-
+
int playlistID = urlParts.at( 2 ).toInt( &ok, 10 );
if (!ok)
{
tDebug() << "incorrect grooveshark url";
return;
}
-
-
-
+
+
+
m_title = urlParts.at( 1 );
-
+
tDebug() << "should get playlist " << playlistID;
-
+
DropJob::DropType type;
type = DropJob::Playlist;
@@ -153,6 +159,53 @@ GroovesharkParser::lookupGroovesharkPlaylist( const QString& linkRaw )
m_queries.insert( reply );
}
+
+void
+GroovesharkParser::lookupGroovesharkTrack( const QString& track )
+{
+ tLog() << "Parsing Grooveshark Track Page:" << track;
+
+ QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( QUrl( track ) ) );
+ connect( reply, SIGNAL( finished() ), this, SLOT( trackPageFetchFinished() ) );
+
+ m_browseJob = new DropJobNotifier( pixmap(), "Grooveshark", DropJob::Track, reply );
+ JobStatusView::instance()->model()->addJob( m_browseJob );
+
+ m_queries << reply;
+}
+
+
+void
+GroovesharkParser::trackPageFetchFinished()
+{
+ QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
+ Q_ASSERT( r );
+
+ m_queries.remove( r );
+ r->deleteLater();
+
+ QWebPage page;
+ page.settings()->setAttribute( QWebSettings::JavascriptEnabled, false );
+ page.settings()->setAttribute( QWebSettings::PluginsEnabled, false );
+ page.settings()->setAttribute( QWebSettings::JavaEnabled, false );
+ page.settings()->setAttribute( QWebSettings::AutoLoadImages, false );
+ page.mainFrame()->setHtml( QString::fromUtf8( r->readAll() ) );
+ QWebElement title = page.mainFrame()->findFirstElement("span[itemprop='name']");
+ QWebElement artist = page.mainFrame()->findFirstElement("noscript span[itemprop='byArtist']");
+ QWebElement album = page.mainFrame()->findFirstElement("noscript span[itemprop='inAlbum']");
+
+ if ( !title.toPlainText().isEmpty() && !artist.toPlainText().isEmpty() )
+ {
+ tDebug() << "Got track info from grooveshark, enough to create a query:" << title.toPlainText() << artist.toPlainText() << album.toPlainText();
+
+ Tomahawk::query_ptr q = Tomahawk::Query::get( artist.toPlainText(), title.toPlainText(), album.toPlainText(), uuid(), true );
+ m_tracks << q;
+ }
+
+ checkTrackFinished();
+}
+
+
void
GroovesharkParser::groovesharkLookupFinished()
{
@@ -179,7 +232,7 @@ GroovesharkParser::groovesharkLookupFinished()
foreach (const QVariant& var, list)
{
QVariantMap trackResult = var.toMap();
-
+
QString title, artist, album;
title = trackResult.value( "SongName", QString() ).toString();
@@ -195,7 +248,7 @@ GroovesharkParser::groovesharkLookupFinished()
Tomahawk::query_ptr q = Tomahawk::Query::get( artist, title, album, uuid(), m_trackMode );
m_tracks << q;
}
-
+
} else
{
@@ -231,7 +284,7 @@ GroovesharkParser::checkPlaylistFinished()
return;
}
-
+
emit tracks( m_tracks );
deleteLater();
diff --git a/src/libtomahawk/utils/groovesharkparser.h b/src/libtomahawk/utils/groovesharkparser.h
index a387ed928..af04dac3d 100644
--- a/src/libtomahawk/utils/groovesharkparser.h
+++ b/src/libtomahawk/utils/groovesharkparser.h
@@ -42,7 +42,7 @@ class QNetworkReply;
namespace Tomahawk
{
-
+
class DropJobNotifier;
class DLLEXPORT GroovesharkParser : public QObject
@@ -58,6 +58,7 @@ signals:
private slots:
void groovesharkLookupFinished();
+ void trackPageFetchFinished();
void playlistCreated();
private:
@@ -65,6 +66,8 @@ private:
void lookupUrl( const QString& url );
void lookupGroovesharkPlaylist( const QString& playlist );
+ void lookupGroovesharkTrack( const QString& track );
+
void checkTrackFinished();
void checkPlaylistFinished();
int m_limit;
@@ -79,7 +82,7 @@ private:
QCA::SymmetricKey m_apiKey;
static QPixmap* s_pixmap;
-
+
};
}
diff --git a/src/libtomahawk/utils/shortenedlinkparser.cpp b/src/libtomahawk/utils/shortenedlinkparser.cpp
index f11646607..e28b1a1d3 100644
--- a/src/libtomahawk/utils/shortenedlinkparser.cpp
+++ b/src/libtomahawk/utils/shortenedlinkparser.cpp
@@ -21,6 +21,7 @@
#include "utils/logger.h"
#include "utils/tomahawkutils.h"
+#include "dropjobnotifier.h"
#include "query.h"
#include "jobview/ErrorStatusMessage.h"
#include "jobview/JobStatusModel.h"
@@ -33,6 +34,7 @@
using namespace Tomahawk;
+QPixmap* ShortenedLinkParser::s_pixmap = 0;
ShortenedLinkParser::ShortenedLinkParser ( const QStringList& urls, QObject* parent )
: QObject( parent )
@@ -61,6 +63,8 @@ ShortenedLinkParser::handlesUrl( const QString& url )
url.contains( "itun.es" ) ||
url.contains( "tinyurl.com" ) ||
url.contains( "tinysong.com" ) ||
+ url.contains( "grooveshark.com/s/~/" ) || // These redirect to the 'real' grooveshark track url
+ url.contains( "grooveshark.com/#/s/~/" ) ||
url.contains( "rd.io" ) );
}
@@ -68,11 +72,18 @@ void
ShortenedLinkParser::lookupUrl ( const QString& url )
{
tDebug() << "Looking up..." << url;
+ QString cleaned = url;
+ if ( cleaned.contains( "/#/s/" ) )
+ cleaned.replace( "/#", "" );
- QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( QUrl( url ) ) );
+ QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( QUrl( cleaned ) ) );
connect( reply, SIGNAL( finished() ), this, SLOT( lookupFinished() ) );
m_queries.insert( reply );
+
+ m_expandJob = new DropJobNotifier( pixmap(), "shortened", DropJob::Track, reply );
+ JobStatusView::instance()->model()->addJob( m_expandJob );
+
}
void
@@ -95,7 +106,7 @@ ShortenedLinkParser::lookupFinished()
else
{
tLog() << "Got a redirected url:" << r->url().toString();
- m_links << r->url().toString();
+ m_links << r->url().toString();
m_queries.remove( r );
r->deleteLater();
checkFinished();
@@ -114,3 +125,13 @@ ShortenedLinkParser::checkFinished()
deleteLater();
}
}
+
+
+QPixmap
+ShortenedLinkParser::pixmap()
+{
+ if ( !s_pixmap )
+ s_pixmap = new QPixmap( RESPATH "images/add.png" );
+
+ return *s_pixmap;
+}
diff --git a/src/libtomahawk/utils/shortenedlinkparser.h b/src/libtomahawk/utils/shortenedlinkparser.h
index 4fd358749..8c503acd3 100644
--- a/src/libtomahawk/utils/shortenedlinkparser.h
+++ b/src/libtomahawk/utils/shortenedlinkparser.h
@@ -26,12 +26,15 @@
#include
#include
#include
+#include
class QNetworkReply;
namespace Tomahawk
{
+class DropJobNotifier;
+
/**
* Small class to parse whitelisted shortened links into the redirected urls
*
@@ -58,8 +61,13 @@ private:
void lookupUrl( const QString& url );
void checkFinished();
+ static QPixmap pixmap();
+
QStringList m_links;
QSet< QNetworkReply* > m_queries;
+ DropJobNotifier* m_expandJob;
+
+ static QPixmap* s_pixmap;
};
}