1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-06 06:07:37 +02:00

Add grooveshark track parsing, and add a job notification for shortened url unwrapping

This commit is contained in:
Leo Franchi
2012-03-02 22:41:19 -05:00
parent 06cc52744d
commit a2d0899285
6 changed files with 103 additions and 17 deletions

BIN
data/images/grooveshark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@@ -133,6 +133,7 @@
<file>data/images/headphones-bigger.png</file> <file>data/images/headphones-bigger.png</file>
<file>data/images/no-album-no-case.png</file> <file>data/images/no-album-no-case.png</file>
<file>data/images/rdio.png</file> <file>data/images/rdio.png</file>
<file>data/images/grooveshark.png</file>
<file>data/sql/dbmigrate-27_to_28.sql</file> <file>data/sql/dbmigrate-27_to_28.sql</file>
<file>data/images/process-stop.png</file> <file>data/images/process-stop.png</file>
</qresource> </qresource>

View File

@@ -39,6 +39,10 @@
#include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkReply>
#include <QWebPage>
#include <QWebFrame>
#include <QWebElement>
using namespace Tomahawk; using namespace Tomahawk;
QPixmap* GroovesharkParser::s_pixmap = 0; QPixmap* GroovesharkParser::s_pixmap = 0;
@@ -72,15 +76,17 @@ GroovesharkParser::~GroovesharkParser()
void void
GroovesharkParser::lookupUrl( const QString& link ) GroovesharkParser::lookupUrl( const QString& link )
{ {
if( link.contains( "playlist" ) ) if ( link.contains( "playlist" ) )
{ {
if( !m_createNewPlaylist ) if ( !m_createNewPlaylist )
m_trackMode = true; m_trackMode = true;
else else
m_trackMode = false; m_trackMode = false;
lookupGroovesharkPlaylist( link ); lookupGroovesharkPlaylist( link );
} }
else if ( link.contains( "grooveshark.com/s/" ) || link.contains( "grooveshark.com/#/s/" ) )
lookupGroovesharkTrack( link );
else else
return; return;
@@ -97,7 +103,7 @@ GroovesharkParser::lookupGroovesharkPlaylist( const QString& linkRaw )
tDebug() << "no fragment, setting fragment to path"; tDebug() << "no fragment, setting fragment to path";
urlFragment = QUrl(linkRaw).path(); urlFragment = QUrl(linkRaw).path();
} }
tDebug() << urlFragment; tDebug() << urlFragment;
int paramStartingPostition = urlFragment.indexOf( "?" ); int paramStartingPostition = urlFragment.indexOf( "?" );
@@ -108,22 +114,22 @@ GroovesharkParser::lookupGroovesharkPlaylist( const QString& linkRaw )
bool ok; bool ok;
QStringList urlParts = urlFragment.split( "/", QString::SkipEmptyParts ); QStringList urlParts = urlFragment.split( "/", QString::SkipEmptyParts );
tDebug() << urlParts; tDebug() << urlParts;
int playlistID = urlParts.at( 2 ).toInt( &ok, 10 ); int playlistID = urlParts.at( 2 ).toInt( &ok, 10 );
if (!ok) if (!ok)
{ {
tDebug() << "incorrect grooveshark url"; tDebug() << "incorrect grooveshark url";
return; return;
} }
m_title = urlParts.at( 1 ); m_title = urlParts.at( 1 );
tDebug() << "should get playlist " << playlistID; tDebug() << "should get playlist " << playlistID;
DropJob::DropType type; DropJob::DropType type;
type = DropJob::Playlist; type = DropJob::Playlist;
@@ -153,6 +159,53 @@ GroovesharkParser::lookupGroovesharkPlaylist( const QString& linkRaw )
m_queries.insert( reply ); 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 void
GroovesharkParser::groovesharkLookupFinished() GroovesharkParser::groovesharkLookupFinished()
{ {
@@ -179,7 +232,7 @@ GroovesharkParser::groovesharkLookupFinished()
foreach (const QVariant& var, list) foreach (const QVariant& var, list)
{ {
QVariantMap trackResult = var.toMap(); QVariantMap trackResult = var.toMap();
QString title, artist, album; QString title, artist, album;
title = trackResult.value( "SongName", QString() ).toString(); 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 ); Tomahawk::query_ptr q = Tomahawk::Query::get( artist, title, album, uuid(), m_trackMode );
m_tracks << q; m_tracks << q;
} }
} else } else
{ {
@@ -231,7 +284,7 @@ GroovesharkParser::checkPlaylistFinished()
return; return;
} }
emit tracks( m_tracks ); emit tracks( m_tracks );
deleteLater(); deleteLater();

View File

@@ -42,7 +42,7 @@ class QNetworkReply;
namespace Tomahawk namespace Tomahawk
{ {
class DropJobNotifier; class DropJobNotifier;
class DLLEXPORT GroovesharkParser : public QObject class DLLEXPORT GroovesharkParser : public QObject
@@ -58,6 +58,7 @@ signals:
private slots: private slots:
void groovesharkLookupFinished(); void groovesharkLookupFinished();
void trackPageFetchFinished();
void playlistCreated(); void playlistCreated();
private: private:
@@ -65,6 +66,8 @@ private:
void lookupUrl( const QString& url ); void lookupUrl( const QString& url );
void lookupGroovesharkPlaylist( const QString& playlist ); void lookupGroovesharkPlaylist( const QString& playlist );
void lookupGroovesharkTrack( const QString& track );
void checkTrackFinished(); void checkTrackFinished();
void checkPlaylistFinished(); void checkPlaylistFinished();
int m_limit; int m_limit;
@@ -79,7 +82,7 @@ private:
QCA::SymmetricKey m_apiKey; QCA::SymmetricKey m_apiKey;
static QPixmap* s_pixmap; static QPixmap* s_pixmap;
}; };
} }

View File

@@ -21,6 +21,7 @@
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/tomahawkutils.h" #include "utils/tomahawkutils.h"
#include "dropjobnotifier.h"
#include "query.h" #include "query.h"
#include "jobview/ErrorStatusMessage.h" #include "jobview/ErrorStatusMessage.h"
#include "jobview/JobStatusModel.h" #include "jobview/JobStatusModel.h"
@@ -33,6 +34,7 @@
using namespace Tomahawk; using namespace Tomahawk;
QPixmap* ShortenedLinkParser::s_pixmap = 0;
ShortenedLinkParser::ShortenedLinkParser ( const QStringList& urls, QObject* parent ) ShortenedLinkParser::ShortenedLinkParser ( const QStringList& urls, QObject* parent )
: QObject( parent ) : QObject( parent )
@@ -61,6 +63,8 @@ ShortenedLinkParser::handlesUrl( const QString& url )
url.contains( "itun.es" ) || url.contains( "itun.es" ) ||
url.contains( "tinyurl.com" ) || url.contains( "tinyurl.com" ) ||
url.contains( "tinysong.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" ) ); url.contains( "rd.io" ) );
} }
@@ -68,11 +72,18 @@ void
ShortenedLinkParser::lookupUrl ( const QString& url ) ShortenedLinkParser::lookupUrl ( const QString& url )
{ {
tDebug() << "Looking up..." << 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() ) ); connect( reply, SIGNAL( finished() ), this, SLOT( lookupFinished() ) );
m_queries.insert( reply ); m_queries.insert( reply );
m_expandJob = new DropJobNotifier( pixmap(), "shortened", DropJob::Track, reply );
JobStatusView::instance()->model()->addJob( m_expandJob );
} }
void void
@@ -95,7 +106,7 @@ ShortenedLinkParser::lookupFinished()
else else
{ {
tLog() << "Got a redirected url:" << r->url().toString(); tLog() << "Got a redirected url:" << r->url().toString();
m_links << r->url().toString(); m_links << r->url().toString();
m_queries.remove( r ); m_queries.remove( r );
r->deleteLater(); r->deleteLater();
checkFinished(); checkFinished();
@@ -114,3 +125,13 @@ ShortenedLinkParser::checkFinished()
deleteLater(); deleteLater();
} }
} }
QPixmap
ShortenedLinkParser::pixmap()
{
if ( !s_pixmap )
s_pixmap = new QPixmap( RESPATH "images/add.png" );
return *s_pixmap;
}

View File

@@ -26,12 +26,15 @@
#include <QObject> #include <QObject>
#include <QSet> #include <QSet>
#include <QStringList> #include <QStringList>
#include <QPixmap>
class QNetworkReply; class QNetworkReply;
namespace Tomahawk namespace Tomahawk
{ {
class DropJobNotifier;
/** /**
* Small class to parse whitelisted shortened links into the redirected urls * Small class to parse whitelisted shortened links into the redirected urls
* *
@@ -58,8 +61,13 @@ private:
void lookupUrl( const QString& url ); void lookupUrl( const QString& url );
void checkFinished(); void checkFinished();
static QPixmap pixmap();
QStringList m_links; QStringList m_links;
QSet< QNetworkReply* > m_queries; QSet< QNetworkReply* > m_queries;
DropJobNotifier* m_expandJob;
static QPixmap* s_pixmap;
}; };
} }