From 93e2a8697cd110d5f76d5af02144b2e059e662ce Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Mon, 8 Jul 2013 12:33:51 +0200 Subject: [PATCH] Move handling of URLs into GAM --- src/libtomahawk/GlobalActionManager.cpp | 182 +++++++++++++++++++----- src/libtomahawk/GlobalActionManager.h | 8 ++ src/tomahawk/TomahawkApp.cpp | 126 ++-------------- src/tomahawk/TomahawkApp.h | 1 - 4 files changed, 163 insertions(+), 154 deletions(-) diff --git a/src/libtomahawk/GlobalActionManager.cpp b/src/libtomahawk/GlobalActionManager.cpp index 56cb8743d..5ba15e433 100644 --- a/src/libtomahawk/GlobalActionManager.cpp +++ b/src/libtomahawk/GlobalActionManager.cpp @@ -1,40 +1,44 @@ -/* - Copyright (C) 2011 Leo Franchi - Copyright (C) 2011, Jeff Mitchell - Copyright (C) 2011-2012, Christian Muehlhaeuser +/* === This file is part of Tomahawk Player - === + * + * Copyright (C) 2011 Leo Franchi + * Copyright (C) 2011, Jeff Mitchell + * Copyright (C) 2011-2012, Christian Muehlhaeuser + * Copyright (C) 2013, Uwe L. Korn + * + * 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 2 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 . + */ - This program 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 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ #include "GlobalActionManager.h" #include "audio/AudioEngine.h" #include "database/LocalCollection.h" -#include "playlist/dynamic/GeneratorInterface.h" - #include "echonest/Playlist.h" - +#include "playlist/dynamic/GeneratorInterface.h" +#include "playlist/PlaylistTemplate.h" +#include "playlist/PlaylistView.h" +#include "resolvers/ExternalResolver.h" +#include "resolvers/ScriptCommand_LookupUrl.h" +#include "utils/JspfLoader.h" +#include "utils/Logger.h" +#include "utils/RdioParser.h" +#include "utils/ShortenedLinkParser.h" +#include "utils/SpotifyParser.h" +#include "utils/TomahawkUtils.h" #include "utils/XspfLoader.h" #include "utils/XspfGenerator.h" -#include "utils/Logger.h" -#include "utils/TomahawkUtils.h" - -#include "utils/JspfLoader.h" -#include "utils/SpotifyParser.h" -#include "utils/ShortenedLinkParser.h" -#include "utils/RdioParser.h" +#include "widgets/SearchWidget.h" #include "Album.h" #include "Artist.h" @@ -42,25 +46,18 @@ #include "PlaylistEntry.h" #include "SourceList.h" #include "TomahawkSettings.h" +#include "ViewManager.h" #include #include -#ifndef ENABLE_HEADLESS - #include "ViewManager.h" - #include "playlist/PlaylistView.h" - #include "widgets/SearchWidget.h" - - #include - #include -#endif - +#include +#include +#include #include #include #include #include - -#include #include @@ -168,6 +165,45 @@ GlobalActionManager::shortenLink( const QUrl& url, const QVariant& callbackObj ) } +bool +GlobalActionManager::openUrl( const QString& url ) +{ + // Native Implementations + if ( url.startsWith( "tomahawk://" ) ) + 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; + QList< QPointer< ExternalResolver > > possibleResolvers; + foreach ( QPointer resolver, Pipeline::instance()->scriptResolvers() ) + { + if ( resolver->canParseUrl( url, ExternalResolver::Any ) ) + { + canParse = true; + possibleResolvers << resolver; + } + } + if ( canParse ) + { + m_queuedUrl = url; + foreach ( QPointer resolver, possibleResolvers ) + { + ScriptCommand_LookupUrl* cmd = new ScriptCommand_LookupUrl( resolver, url ); + connect( cmd, SIGNAL( information( QString, QSharedPointer ) ), this, SLOT( informationForUrl( QString, QSharedPointer ) ) ); + cmd->enqueue(); + } + + return true; + } + + return false; +} + + #ifndef ENABLE_HEADLESS void @@ -595,6 +631,74 @@ GlobalActionManager::handlePlayTrack( const query_ptr& qry ) } +void +GlobalActionManager::informationForUrl(const QString& url, const QSharedPointer& information) +{ + tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Got Information for URL:" << url; + if ( m_queuedUrl != url ) + { + // This url is not anymore active, result was too late. + return; + } + if ( information.isNull() ) + { + // No information was transmitted, nothing to do. + tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Empty information received."; + return; + } + + // If we reach this point, we found information that can be parsed. + // So invalidate queued Url + m_queuedUrl = ""; + + // Try to interpret as Artist + Tomahawk::artist_ptr artist = information.objectCast(); + if ( !artist.isNull() ) + { + // The Url describes an artist + ViewManager::instance()->show( artist ); + return; + } + + // Try to interpret as Album + Tomahawk::album_ptr album = information.objectCast(); + if ( !album.isNull() ) + { + // The Url describes an album + ViewManager::instance()->show( album ); + return; + } + + Tomahawk::playlisttemplate_ptr pltemplate = information.objectCast(); + if ( !pltemplate.isNull() ) + { + ViewManager::instance()->show( pltemplate->get() ); + return; + } + + // Try to interpret as Track/Query + Tomahawk::query_ptr query = information.objectCast(); + if ( !query.isNull() ) + { + // The Url describes a track + ViewManager::instance()->show( query ); + return; + } + + // Try to interpret as Playlist + Tomahawk::playlist_ptr playlist = information.objectCast(); + if ( !playlist.isNull() ) + { + // The url describes a playlist + ViewManager::instance()->show( playlist ); + return; + } + + // Could not cast to a known type. + tLog() << Q_FUNC_INFO << "Can't load parsed information for " << url; +} + + bool GlobalActionManager::handleQueueCommand( const QUrl& url ) { diff --git a/src/libtomahawk/GlobalActionManager.h b/src/libtomahawk/GlobalActionManager.h index b63117150..57d7d3136 100644 --- a/src/libtomahawk/GlobalActionManager.h +++ b/src/libtomahawk/GlobalActionManager.h @@ -52,6 +52,11 @@ public slots: #ifndef ENABLE_HEADLESS + /** + * Try to open a URL as Playlist/Album/Artist/Track + */ + bool openUrl( const QString& url ); + /// Takes a spotify link and performs the default open action on it bool openSpotifyLink( const QString& link ); @@ -81,6 +86,8 @@ signals: void shortLinkReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& callbackObj ); private slots: + void informationForUrl( const QString& url, const QSharedPointer& information ); + void shortenLinkRequestFinished(); void shortenLinkRequestError( QNetworkReply::NetworkError ); @@ -130,6 +137,7 @@ private: Tomahawk::playlist_ptr m_toShow; Tomahawk::query_ptr m_waitingToPlay; QUrl m_clipboardLongUrl; + QString m_queuedUrl; static GlobalActionManager* s_instance; }; diff --git a/src/tomahawk/TomahawkApp.cpp b/src/tomahawk/TomahawkApp.cpp index 43e4198b1..d82503b4c 100644 --- a/src/tomahawk/TomahawkApp.cpp +++ b/src/tomahawk/TomahawkApp.cpp @@ -714,74 +714,6 @@ TomahawkApp::ipDetectionFailed( QNetworkReply::NetworkError error, QString error } -void -TomahawkApp::informationForUrl( const QString& url, const QSharedPointer& information ) -{ - tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Got Information for URL:" << url; - if ( m_queuedUrl != url ) - { - // This url is not anymore active, result was too late. - return; - } - if ( information.isNull() ) - { - // No information was transmitted, nothing to do. - tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Empty information received."; - return; - } - - // If we reach this point, we found information that can be parsed. - // So invalidate queued Url - m_queuedUrl = ""; - - // Try to interpret as Artist - Tomahawk::artist_ptr artist = information.objectCast(); - if ( !artist.isNull() ) - { - // The Url describes an artist - ViewManager::instance()->show( artist ); - return; - } - - // Try to interpret as Album - Tomahawk::album_ptr album = information.objectCast(); - if ( !album.isNull() ) - { - // The Url describes an album - ViewManager::instance()->show( album ); - return; - } - - Tomahawk::playlisttemplate_ptr pltemplate = information.objectCast(); - if ( !pltemplate.isNull() ) - { - ViewManager::instance()->show( pltemplate->get() ); - return; - } - - // Try to interpret as Track/Query - Tomahawk::query_ptr query = information.objectCast(); - if ( !query.isNull() ) - { - // The Url describes a track - ViewManager::instance()->show( query ); - return; - } - - // Try to interpret as Playlist - Tomahawk::playlist_ptr playlist = information.objectCast(); - if ( !playlist.isNull() ) - { - // The url describes a playlist - ViewManager::instance()->show( playlist ); - return; - } - - // Could not cast to a known type. - tLog() << Q_FUNC_INFO << "Can't load parsed information for " << url; -} - - void TomahawkApp::spotifyApiCheckFinished() { @@ -806,60 +738,26 @@ TomahawkApp::activate() bool TomahawkApp::loadUrl( const QString& url ) { -#ifndef ENABLE_HEADLESS - if ( url.startsWith( "tomahawk://" ) ) - return GlobalActionManager::instance()->parseTomahawkLink( url ); - else if ( url.contains( "open.spotify.com" ) || url.startsWith( "spotify:" ) ) - return GlobalActionManager::instance()->openSpotifyLink( url ); - else if ( url.contains( "www.rdio.com" ) ) - return GlobalActionManager::instance()->openRdioLink( url ); - else + QFile f( url ); + QFileInfo info( f ); + if ( info.suffix() == "xspf" ) { - QFile f( url ); - QFileInfo info( f ); - if ( info.suffix() == "xspf" ) - { - XSPFLoader* l = new XSPFLoader( true, this ); - tDebug( LOGINFO ) << "Loading spiff:" << url; - l->load( QUrl::fromUserInput( url ) ); + XSPFLoader* l = new XSPFLoader( true, this ); + tDebug( LOGINFO ) << "Loading spiff:" << url; + l->load( QUrl::fromUserInput( url ) ); - return true; - } - else if ( info.suffix() == "jspf" ) - { - JSPFLoader* l = new JSPFLoader( true, this ); - tDebug( LOGINFO ) << "Loading j-spiff:" << url; - l->load( QUrl::fromUserInput( url ) ); - - return true; - } + return true; } - // Can we parse the Url using a ScriptResolver? - bool canParse = false; - QList< QPointer< ExternalResolver > > possibleResolvers; - foreach ( QPointer resolver, Pipeline::instance()->scriptResolvers() ) + else if ( info.suffix() == "jspf" ) { - if ( resolver->canParseUrl( url, ExternalResolver::Any ) ) - { - canParse = true; - possibleResolvers << resolver; - } - } - if ( canParse ) - { - m_queuedUrl = url; - foreach ( QPointer resolver, possibleResolvers ) - { - ScriptCommand_LookupUrl* cmd = new ScriptCommand_LookupUrl( resolver, url ); - connect( cmd, SIGNAL( information( QString, QSharedPointer ) ), this, SLOT( informationForUrl( QString, QSharedPointer ) ) ); - cmd->enqueue(); - } + JSPFLoader* l = new JSPFLoader( true, this ); + tDebug( LOGINFO ) << "Loading j-spiff:" << url; + l->load( QUrl::fromUserInput( url ) ); return true; } -#endif - return false; + return GlobalActionManager::instance()->openUrl( url ); } diff --git a/src/tomahawk/TomahawkApp.h b/src/tomahawk/TomahawkApp.h index ea492bc32..e0337174d 100644 --- a/src/tomahawk/TomahawkApp.h +++ b/src/tomahawk/TomahawkApp.h @@ -114,7 +114,6 @@ private slots: void spotifyApiCheckFinished(); void onInfoSystemReady(); - void informationForUrl( const QString& url, const QSharedPointer& information ); void ipDetectionFailed( QNetworkReply::NetworkError error, QString errorString );