diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index ef42f97f8..d94dfbbc0 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -114,7 +114,6 @@ set( libGuiSources utils/M3uLoader.cpp utils/ItunesParser.cpp utils/ItunesLoader.cpp - utils/RdioParser.cpp utils/ShortenedLinkParser.cpp utils/TomahawkStyle.cpp utils/DropJobNotifier.cpp diff --git a/src/libtomahawk/DropJob.cpp b/src/libtomahawk/DropJob.cpp index dae05a036..aa744d129 100644 --- a/src/libtomahawk/DropJob.cpp +++ b/src/libtomahawk/DropJob.cpp @@ -30,7 +30,6 @@ #include "utils/SpotifyParser.h" #include "utils/ItunesParser.h" #include "utils/ItunesLoader.h" -#include "utils/RdioParser.h" #include "utils/M3uLoader.h" #include "utils/ShortenedLinkParser.h" #include "utils/Logger.h" @@ -663,24 +662,6 @@ DropJob::handleSpotifyUrls( const QString& urlsRaw ) } -void -DropJob::handleRdioUrls( const QString& urlsRaw ) -{ - QStringList urls = urlsRaw.split( QRegExp( "\\s+" ), QString::SkipEmptyParts ); - qDebug() << "Got Rdio urls!" << urls; - - if ( dropAction() == Default ) - setDropAction( Create ); - - RdioParser* rdio = new RdioParser( this ); - connect( rdio, SIGNAL( tracks( QList ) ), this, SLOT( onTracksAdded( QList< Tomahawk::query_ptr > ) ) ); - - m_queryCount++; - rdio->setCreatePlaylist( dropAction() == Create ); - rdio->parse( urls ); -} - - void DropJob::handleGroovesharkUrls ( const QString& urlsRaw ) { @@ -731,8 +712,6 @@ DropJob::handleAllUrls( const QString& urls ) && ( urls.contains( "playlist" ) || urls.contains( "artist" ) || urls.contains( "album" ) || urls.contains( "track" ) ) && s_canParseSpotifyPlaylists ) handleSpotifyUrls( urls ); - else if ( urls.contains( "rdio.com" ) ) - handleRdioUrls( urls ); #ifdef QCA2_FOUND else if ( urls.contains( "grooveshark.com" ) ) handleGroovesharkUrls( urls ); @@ -769,17 +748,6 @@ DropJob::handleTrackUrls( const QString& urls ) connect( spot, SIGNAL( tracks( QList ) ), this, SLOT( onTracksAdded( QList< Tomahawk::query_ptr > ) ) ); m_queryCount++; } - else if ( urls.contains( "rdio.com" ) ) - { - QStringList tracks = urls.split( QRegExp( "\\s+" ), QString::SkipEmptyParts ); - - tDebug() << "Got a list of rdio urls!" << tracks; - RdioParser* rdio = new RdioParser( this ); - connect( rdio, SIGNAL( tracks( QList ) ), this, SLOT( onTracksAdded( QList< Tomahawk::query_ptr > ) ) ); - m_queryCount++; - - rdio->parse( tracks ); - } else if ( ShortenedLinkParser::handlesUrl( urls ) ) { QStringList tracks = urls.split( QRegExp( "\\s+" ), QString::SkipEmptyParts ); diff --git a/src/libtomahawk/DropJob.h b/src/libtomahawk/DropJob.h index 64e94e45c..6b03ac9fe 100644 --- a/src/libtomahawk/DropJob.h +++ b/src/libtomahawk/DropJob.h @@ -113,7 +113,6 @@ public: void handleXspfs( const QString& files ); void handleM3u( const QString& urls ); void handleSpotifyUrls( const QString& urls ); - void handleRdioUrls( const QString& urls ); void handleGroovesharkUrls( const QString& urls ); static bool canParseSpotifyPlaylists(); diff --git a/src/libtomahawk/GlobalActionManager.cpp b/src/libtomahawk/GlobalActionManager.cpp index a84949b54..320f75199 100644 --- a/src/libtomahawk/GlobalActionManager.cpp +++ b/src/libtomahawk/GlobalActionManager.cpp @@ -34,7 +34,6 @@ #include "utils/JspfLoader.h" #include "utils/Logger.h" #include "utils/NetworkAccessManager.h" -#include "utils/RdioParser.h" #include "utils/ShortenedLinkParser.h" #include "utils/ShortLinkHelper.h" #include "utils/SpotifyParser.h" @@ -147,8 +146,6 @@ GlobalActionManager::openUrl( const QString& url ) return parseTomahawkLink( url ); else if ( url.contains( "open.spotify.com" ) || url.startsWith( "spotify:" ) ) return openSpotifyLink( url ); - else if ( url.contains( "www.rdio.com" ) ) - return openRdioLink( url ); // Can we parse the Url using a ScriptResolver? bool canParse = false; @@ -716,8 +713,6 @@ GlobalActionManager::doQueueAdd( const QStringList& parts, const QList< QPair< Q { if ( queueSpotify( parts, queryItems ) ) return true; - else if ( queueRdio( parts, queryItems ) ) - return true; QPair< QString, QString > pair; QString title, artist, album, urlStr; @@ -856,29 +851,6 @@ GlobalActionManager::queueSpotify( const QStringList& , const QList< QPair< QStr } -bool -GlobalActionManager::queueRdio( const QStringList& , const QList< QPair< QString, QString > >& queryItems ) -{ - QString url; - - QPair< QString, QString > pair; - foreach ( pair, queryItems ) - { - if ( pair.first == "rdioURL" ) - url = pair.second; - else if ( pair.first == "rdioURI" ) - url = pair.second; - } - - if ( url.isEmpty() ) - return false; - - openRdioLink( url ); - - return true; -} - - bool GlobalActionManager::handleSearchCommand( const QUrl& url ) { @@ -1184,8 +1156,6 @@ GlobalActionManager::handlePlayCommand( const QUrl& url ) { if ( playSpotify( url ) ) return true; - else if ( playRdio( url ) ) - return true; QPair< QString, QString > pair; QString title, artist, album, urlStr; @@ -1254,20 +1224,6 @@ GlobalActionManager::playOrQueueNow( const query_ptr& q ) } -bool -GlobalActionManager::playRdio( const QUrl& url ) -{ - if ( !urlHasQueryItem( url, "rdioURI" ) && !urlHasQueryItem( url, "rdioURL" ) ) - return false; - - QString rdioUrl = urlHasQueryItem( url, "rdioURI" ) ? urlQueryItemValue( url, "spotifyURI" ) : urlQueryItemValue( url, "rdioURL" ); - RdioParser* p = new RdioParser( this ); - p->parse( rdioUrl ); - connect( p, SIGNAL( track( Tomahawk::query_ptr ) ), this, SLOT( playOrQueueNow( Tomahawk::query_ptr ) ) ); - - return true; -} - void GlobalActionManager::showPlaylist() { @@ -1322,17 +1278,6 @@ GlobalActionManager::openSpotifyLink( const QString& link ) return true; } - -bool -GlobalActionManager::openRdioLink( const QString& link ) -{ - RdioParser* rdio = new RdioParser( this ); - connect( rdio, SIGNAL( track( Tomahawk::query_ptr ) ), this, SLOT( handleOpenTrack( Tomahawk::query_ptr ) ) ); - rdio->parse( link ); - - return true; -} - #endif diff --git a/src/libtomahawk/GlobalActionManager.h b/src/libtomahawk/GlobalActionManager.h index c7864d88a..0fb7a548a 100644 --- a/src/libtomahawk/GlobalActionManager.h +++ b/src/libtomahawk/GlobalActionManager.h @@ -58,9 +58,6 @@ public slots: /// Takes a spotify link and performs the default open action on it bool openSpotifyLink( const QString& link ); - /// Takes a spotify link and performs the default open action on it - bool openRdioLink( const QString& link ); - /// Creates a link from the requested data and copies it to the clipboard void copyToClipboard( const Tomahawk::query_ptr& query ); @@ -111,8 +108,6 @@ private: bool playSpotify( const QUrl& url ); bool queueSpotify( const QStringList& parts, const QList< QPair< QString, QString > >& queryItems ); - bool playRdio( const QUrl& url ); - bool queueRdio( const QStringList& parts, const QList< QPair< QString, QString > >& queryItems ); #endif bool handleCollectionCommand( const QUrl& url ); diff --git a/src/libtomahawk/utils/RdioParser.cpp b/src/libtomahawk/utils/RdioParser.cpp deleted file mode 100644 index c0fcf3270..000000000 --- a/src/libtomahawk/utils/RdioParser.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * Copyright 2010-2011, Hugo Lindström - * - * Tomahawk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tomahawk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tomahawk. If not, see . - */ - -#include "RdioParser.h" - -#include "ShortenedLinkParser.h" -#include "config.h" -#include "DropJob.h" -#include "DropJobNotifier.h" -#include "ViewManager.h" -#include "SourceList.h" -#include "jobview/JobStatusView.h" -#include "jobview/JobStatusModel.h" -#include "jobview/ErrorStatusMessage.h" -#include "utils/NetworkReply.h" -#include "utils/TomahawkUtils.h" -#include "utils/Logger.h" -#include "utils/NetworkAccessManager.h" - - -#include - -#include -#include -#include -#include -#include - -using namespace Tomahawk; - -QPixmap* RdioParser::s_pixmap = 0; - -#ifdef QCA2_FOUND -QCA::Initializer RdioParser::m_qcaInit = QCA::Initializer(); -#endif - - -RdioParser::RdioParser( QObject* parent ) - : QObject( parent ) - , m_count( 0 ) - , m_browseJob( 0 ) - , m_createPlaylist( false ) -{ -} - - -RdioParser::~RdioParser() -{ -} - - -void -RdioParser::parse( const QString& url ) -{ - m_multi = false; - m_total = 1; - parseUrl( url ); -} - - -void -RdioParser::parse( const QStringList& urls ) -{ - m_multi = true; - m_total = urls.count(); - - foreach ( const QString& url, urls ) - parseUrl( url ); -} - - -void -RdioParser::parseUrl( const QString& url ) -{ - if ( url.contains( "rd.io" ) ) // shortened - { - ShortenedLinkParser* p = new ShortenedLinkParser( QStringList() << url, this ); - connect( p, SIGNAL( urls( QStringList ) ), this, SLOT( expandedLinks( QStringList ) ) ); - return; - } - - if ( url.contains( "artist" ) && url.contains( "album" ) && url.contains( "track" ) ) - parseTrack( url ); - else - { - DropJob::DropType type = DropJob::None; - if ( url.contains( "artist" ) && url.contains( "album" ) ) - type = DropJob::Album; - else if ( url.contains( "artist" ) ) - type = DropJob::Artist; - else if ( url.contains( "people" ) && url.contains( "playlist" ) ) - type = DropJob::Playlist; - else - { - tLog() << "Got Rdio URL I can't parse!" << url; - return; - } - - // artist, album, or playlist link requre fetching - fetchObjectsFromUrl( url, type ); - } -} - - -void -RdioParser::fetchObjectsFromUrl( const QString& url, DropJob::DropType type ) -{ - QList< QPair< QByteArray, QByteArray > > params; - params.append( QPair( "extras", "tracks" ) ); - - QString cleanedUrl = url; - cleanedUrl.replace("#/", ""); - - QByteArray data; - QNetworkRequest request = generateRequest( "getObjectFromUrl", cleanedUrl, params, &data ); - - request.setHeader( QNetworkRequest::ContentTypeHeader, QLatin1String( "application/x-www-form-urlencoded" ) ); - NetworkReply* reply = new NetworkReply( Tomahawk::Utils::nam()->post( request, data ) ); - connect( reply, SIGNAL( finished() ), SLOT( rdioReturned() ) ); - -#ifndef ENABLE_HEADLESS - m_browseJob = new DropJobNotifier( pixmap(), QString( "Rdio" ), type, reply ); - JobStatusView::instance()->model()->addJob( m_browseJob ); -#endif - - m_reqQueries.insert( reply ); -} - - -void -RdioParser::rdioReturned() -{ - NetworkReply* r = qobject_cast< NetworkReply* >( sender() ); - Q_ASSERT( r ); - m_reqQueries.remove( r ); - m_count++; - r->deleteLater(); - - if ( r->reply()->error() == QNetworkReply::NoError ) - { - QJson::Parser p; - bool ok; - QVariantMap res = p.parse( r->reply(), &ok ).toMap(); - QVariantMap result = res.value( "result" ).toMap(); - - if ( !ok || result.isEmpty() ) - { - tLog() << "Failed to parse json from Rdio browse item:" << p.errorString() << "On line" << p.errorLine() << "With data:" << res; - - return; - } - - QVariantList tracks = result.value( "tracks" ).toList(); - if ( tracks.isEmpty() ) - { - tLog() << "Got no tracks in result, ignoring!" << result; - return; - } - - // Playlists will have these - m_title = result[ "name" ].toString(); - m_creator = result[ "owner" ].toString(); - - foreach( QVariant track, tracks ) - { - QVariantMap rdioResult = track.toMap(); - QString title, artist, album; - - title = rdioResult.value( "name", QString() ).toString(); - artist = rdioResult.value( "artist", QString() ).toString(); - album = rdioResult.value( "album", QString() ).toString(); - - if ( title.isEmpty() && artist.isEmpty() ) // don't have enough... - { - tLog() << "Didn't get an artist and track name from Rdio, not enough to build a query on. Aborting" << title << artist << album; - return; - } - - Tomahawk::query_ptr q = Tomahawk::Query::get( artist, title, album, uuid(), !m_createPlaylist ); - if ( q.isNull() ) - continue; - - m_tracks << q; - } - } - else - { -#ifndef ENABLE_HEADLESS - JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( tr( "Error fetching Rdio information from the network!" ) ) ); -#endif - - tLog() << "Error in network request to Rdio for track decoding:" << r->reply()->errorString(); - } - - checkFinished(); -} - - -void -RdioParser::parseTrack( const QString& origUrl ) -{ - QString url = origUrl; - QString artist, trk, album, playlist; - QString realUrl = url.replace( "_", " " ); - QString matchStr = "/%1/([^/]*)/"; - QString matchPlStr = "/%1/(?:[^/]*)/([^/]*)/"; - - QRegExp r( QString( matchStr ).arg( "artist" ) ); - - int loc = r.indexIn( realUrl ); - if ( loc >= 0 ) - artist = r.cap( 1 ); - - r = QRegExp( QString( matchStr ).arg( "album" ) ); - loc = r.indexIn( realUrl ); - if ( loc >= 0 ) - album = r.cap( 1 ); - - r = QRegExp( QString( matchStr ).arg( "track" ) ); - loc = r.indexIn( realUrl ); - if ( loc >= 0 ) - trk = r.cap( 1 ); - - r = QRegExp( QString( matchPlStr ).arg( "playlists" ) ); - loc = r.indexIn( realUrl ); - if ( loc >= 0 ) - playlist = r.cap( 1 ); - - if ( trk.isEmpty() || artist.isEmpty() ) - { - tLog() << "Parsed Rdio track url but it's missing artist or track!" << url; - return; - } - - query_ptr q = Query::get( artist, trk, album, uuid(), !m_createPlaylist ); - m_count++; - m_tracks << q; - - checkFinished(); -} - - -QNetworkRequest -RdioParser::generateRequest( const QString& method, const QString& url, const QList< QPair< QByteArray, QByteArray > >& extraParams, QByteArray* data ) -{ - QUrl fetchUrl( "http://api.rdio.com/1/" ); - QUrl toSignUrl = fetchUrl; - - - QPair param; - foreach ( param, extraParams ) - { - TomahawkUtils::urlAddQueryItem( toSignUrl, param.first, param.second ); - } - TomahawkUtils::urlAddQueryItem( toSignUrl, "method", method ); - TomahawkUtils::urlAddQueryItem( toSignUrl, "oauth_consumer_key", "gk8zmyzj5xztt8aj48csaart" ); - QString nonce; - for ( int i = 0; i < 8; i++ ) - nonce += QString::number( qrand() % 10 ); - TomahawkUtils::urlAddQueryItem( toSignUrl, "oauth_nonce", nonce ); - TomahawkUtils::urlAddQueryItem( toSignUrl, "oauth_signature_method", "HMAC-SHA1"); - TomahawkUtils::urlAddQueryItem( toSignUrl, "oauth_timestamp", QString::number(QDateTime::currentMSecsSinceEpoch() / 1000 ) ); - TomahawkUtils::urlAddQueryItem( toSignUrl, "oauth_version", "1.0"); - TomahawkUtils::urlAddQueryItem( toSignUrl, "url", QUrl::toPercentEncoding( url ) ); - - int size = TomahawkUtils::urlQueryItems( toSignUrl ).size(); - for( int i = 0; i < size; i++ ) { - const QPair< QString, QString > item = TomahawkUtils::urlQueryItems( toSignUrl ).at( i ); - data->append( item.first + "=" + item.second + "&" ); - } - data->truncate( data->size() - 1 ); // remove extra & - - QByteArray toSign = "POST&" + QUrl::toPercentEncoding( fetchUrl.toEncoded() ) + '&' + QUrl::toPercentEncoding( *data ); - qDebug() << "Rdio" << toSign; - - TomahawkUtils::urlAddQueryItem( toSignUrl, "oauth_signature", QUrl::toPercentEncoding( hmacSha1("yt35kakDyW&", toSign ) ) ); - - data->clear(); - size = TomahawkUtils::urlQueryItems( toSignUrl ).size(); - for( int i = 0; i < size; i++ ) { - const QPair< QString, QString > item = TomahawkUtils::urlQueryItems( toSignUrl ).at( i ); - data->append( item.first.toLatin1() + "=" + item.second.toLatin1() + "&" ); - } - data->truncate( data->size() - 1 ); // remove extra & - - QNetworkRequest request = QNetworkRequest( fetchUrl ); - request.setHeader( QNetworkRequest::ContentTypeHeader, QLatin1String( "application/x-www-form-urlencoded" ) ); - - return request; -} - - -QByteArray -RdioParser::hmacSha1(QByteArray key, QByteArray baseString) -{ -#ifdef QCA2_FOUND - QCA::MessageAuthenticationCode hmacsha1( "hmac(sha1)", QCA::SecureArray() ); - QCA::SymmetricKey keyObject( key ); - hmacsha1.setup( keyObject ); - - hmacsha1.update( QCA::SecureArray( baseString ) ); - QCA::SecureArray resultArray = hmacsha1.final(); - - QByteArray result = resultArray.toByteArray().toBase64(); - return result; -#else - tLog() << "Tomahawk compiled without QCA support, cannot generate HMAC signature"; - return QByteArray(); -#endif -} - - -void -RdioParser::checkFinished() -{ - tDebug() << "Checking for Rdio batch playlist job finished" << m_reqQueries.isEmpty(); - if ( m_reqQueries.isEmpty() ) // we're done - { - if ( m_browseJob ) - m_browseJob->setFinished(); - - if ( m_tracks.isEmpty() ) - return; - - if ( m_createPlaylist ) - { - m_playlist = Playlist::create( SourceList::instance()->getLocal(), - uuid(), - m_title, - "", - m_creator, - false, - m_tracks ); - - connect( m_playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( playlistCreated() ) ); - - return; - } - else - { - if ( !m_multi ) - emit track( m_tracks.first() ); - else if ( m_multi && m_count == m_total ) - emit tracks( m_tracks ); - - m_tracks.clear(); - } - - deleteLater(); - } -} - - -void -RdioParser::playlistCreated( Tomahawk::PlaylistRevision ) -{ - ViewManager::instance()->show( m_playlist ); -} - - -void -RdioParser::expandedLinks( const QStringList& urls ) -{ - foreach( const QString& url, urls ) - { - if ( url.contains( "rdio.com" ) || url.contains( "rd.io" ) ) - parseUrl( url ); - } -} - - -QPixmap -RdioParser::pixmap() const -{ - if ( !s_pixmap ) - s_pixmap = new QPixmap( RESPATH "images/rdio.png" ); - - return *s_pixmap; -} diff --git a/src/libtomahawk/utils/RdioParser.h b/src/libtomahawk/utils/RdioParser.h deleted file mode 100644 index 362939430..000000000 --- a/src/libtomahawk/utils/RdioParser.h +++ /dev/null @@ -1,105 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2010-2011, Leo Franchi - * Copyright 2010-2011, Hugo Lindström - * - * Tomahawk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tomahawk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tomahawk. If not, see . - */ - -#ifndef RDIOPARSER_H -#define RDIOPARSER_H - -#include "jobview/JobStatusItem.h" -#include "Query.h" -#include "config.h" -#include "DropJob.h" -#include "Typedefs.h" -#include "Playlist.h" - -#include -#include -#include - -#include - -#ifdef QCA2_FOUND -#include -#endif - -class NetworkReply; - -namespace Tomahawk -{ - -class DropJobNotifier; - -/** - * Small class to parse spotify links into query_ptrs - * - * Connect to the signals to get the results - */ - -class RdioParser : public QObject -{ - Q_OBJECT -public: - - explicit RdioParser( QObject* parent = 0 ); - virtual ~RdioParser(); - - void parse( const QString& url ); - void parse( const QStringList& urls ); - - void setCreatePlaylist( bool createPlaylist ) { m_createPlaylist = createPlaylist; } - -signals: - void track( const Tomahawk::query_ptr& track ); - void tracks( const QList< Tomahawk::query_ptr > tracks ); - -private slots: - void expandedLinks( const QStringList& ); - void rdioReturned(); - - void playlistCreated( Tomahawk::PlaylistRevision ); -private: - void parseTrack( const QString& url ); - void fetchObjectsFromUrl( const QString& url, DropJob::DropType type ); - - QByteArray hmacSha1(QByteArray key, QByteArray baseString); - QNetworkRequest generateRequest( const QString& method, const QString& url, const QList< QPair< QByteArray, QByteArray > >& extraParams, QByteArray* postData ); - QPixmap pixmap() const; - void checkFinished(); - void parseUrl( const QString& url ); - - bool m_multi; - int m_count, m_total; - QSet< NetworkReply* > m_reqQueries; - DropJobNotifier* m_browseJob; - - QString m_title, m_creator; - playlist_ptr m_playlist; - - static QPixmap* s_pixmap; - - bool m_createPlaylist; - QList< query_ptr > m_tracks; - -#ifdef QCA2_FOUND - static QCA::Initializer m_qcaInit; -#endif -}; - -} - -#endif // RDIOPARSER_H