diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 139f759b6..2c8b25ab8 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -126,6 +126,7 @@ set( libGuiSources utils/NetworkReply.cpp utils/NetworkProxyFactory.cpp utils/NetworkAccessManager.cpp + utils/ShortLinkHelper.cpp widgets/AnimatedCounterLabel.cpp widgets/AnimatedSplitter.cpp diff --git a/src/libtomahawk/GlobalActionManager.cpp b/src/libtomahawk/GlobalActionManager.cpp index 91eee3b18..6ed7a7698 100644 --- a/src/libtomahawk/GlobalActionManager.cpp +++ b/src/libtomahawk/GlobalActionManager.cpp @@ -32,13 +32,14 @@ #include "resolvers/ScriptCommand_LookupUrl.h" #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" #include "utils/TomahawkUtils.h" #include "utils/XspfLoader.h" #include "utils/XspfGenerator.h" -#include "utils/NetworkAccessManager.h" #include "widgets/SearchWidget.h" #include "Album.h" @@ -143,29 +144,6 @@ GlobalActionManager::openLink( const QString& title, const QString& artist, cons } -void -GlobalActionManager::shortenLink( const QUrl& url, const QVariant& callbackObj ) -{ - tDebug() << Q_FUNC_INFO << "callbackObj is valid: " << ( callbackObj.isValid() ? "true" : "false" ); - if ( QThread::currentThread() != thread() ) - { - qDebug() << "Reinvoking in correct thread:" << Q_FUNC_INFO; - QMetaObject::invokeMethod( this, "shortenLink", Qt::QueuedConnection, Q_ARG( QUrl, url ), Q_ARG( QVariant, callbackObj ) ); - return; - } - - QNetworkRequest request; - request.setUrl( url ); - - qDebug() << "Doing lookup:" << url.toEncoded(); - QNetworkReply *reply = Tomahawk::Utils::nam()->get( request ); - if ( callbackObj.isValid() ) - reply->setProperty( "callbackobj", callbackObj ); - connect( reply, SIGNAL( finished() ), SLOT( shortenLinkRequestFinished() ) ); - connect( reply, SIGNAL( error( QNetworkReply::NetworkError ) ), SLOT( shortenLinkRequestError( QNetworkReply::NetworkError ) ) ); -} - - bool GlobalActionManager::openUrl( const QString& url ) { @@ -207,52 +185,6 @@ GlobalActionManager::openUrl( const QString& url ) #ifndef ENABLE_HEADLESS -void -GlobalActionManager::getShortLink( const playlist_ptr& pl ) -{ - QVariantMap m; - m[ "title" ] = pl->title(); - m[ "creator" ] = pl->author().isNull() ? "" : pl->author()->friendlyName(); - QVariantList tracks; - foreach( const plentry_ptr& pl, pl->entries() ) - { - if ( pl->query().isNull() ) - continue; - - QVariantMap track; - track[ "title" ] = pl->query()->track()->track(); - track[ "creator" ] = pl->query()->track()->artist(); - track[ "album" ] = pl->query()->track()->album(); - - tracks << track; - } - m[ "track" ] = tracks; - - QVariantMap jspf; - jspf["playlist"] = m; - - QJson::Serializer s; - QByteArray msg = s.serialize( jspf ); - - // No built-in Qt facilities for doing a FORM POST. So we build the payload ourselves... - const QByteArray boundary = "----------------------------2434992cccab"; - QByteArray data( QByteArray( "--" + boundary + "\r\n" ) ); - data += "Content-Disposition: form-data; name=\"data\"; filename=\"playlist.jspf\"\r\n"; - data += "Content-Type: application/octet-stream\r\n\r\n"; - data += msg; - data += "\r\n\r\n"; - data += "--" + boundary + "--\r\n\r\n"; - - const QUrl url( QString( "%1/p/").arg( hostname() ) ); - QNetworkRequest req( url ); - req.setHeader( QNetworkRequest::ContentTypeHeader, QString( "multipart/form-data; boundary=%1" ).arg( QString::fromLatin1( boundary ) ) ); - QNetworkReply *reply = Tomahawk::Utils::nam()->post( req, data ); - - connect( reply, SIGNAL( finished() ), SLOT( postShortenFinished() ) ); - connect( reply, SIGNAL( error( QNetworkReply::NetworkError ) ), SLOT( shortenLinkRequestError( QNetworkReply::NetworkError ) ) ); -} - - QString GlobalActionManager::copyPlaylistToClipboard( const dynplaylist_ptr& playlist ) { @@ -337,7 +269,13 @@ void GlobalActionManager::copyToClipboard( const query_ptr& query ) { m_clipboardLongUrl = openLinkFromQuery( query ); - shortenLink( m_clipboardLongUrl ); + Tomahawk::Utils::ShortLinkHelper* slh = new Tomahawk::Utils::ShortLinkHelper(); + connect( slh, SIGNAL( shortLinkReady( QUrl, QUrl, QVariant ) ), + SLOT( copyToClipboardReady( QUrl, QUrl, QVariant ) ) ); + connect( slh, SIGNAL( done() ), + slh, SLOT( deleteLater() ), + Qt::QueuedConnection ); + slh->shortenLink( m_clipboardLongUrl ); } @@ -700,6 +638,22 @@ GlobalActionManager::informationForUrl(const QString& url, const QSharedPointer< } +void +GlobalActionManager::copyToClipboardReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& ) +{ + // Copy resulting url to clipboard + if ( m_clipboardLongUrl == longUrl ) + { + QClipboard* cb = QApplication::clipboard(); + + QByteArray data = TomahawkUtils::percentEncode( shortUrl.isEmpty() ? longUrl : shortUrl ); + cb->setText( data ); + + m_clipboardLongUrl.clear(); + } +} + + bool GlobalActionManager::handleQueueCommand( const QUrl& url ) { @@ -1278,110 +1232,6 @@ GlobalActionManager::playRdio( const QUrl& url ) return true; } -#endif - - -void -GlobalActionManager::shortenLinkRequestFinished() -{ - qDebug() << Q_FUNC_INFO; - QNetworkReply *reply = qobject_cast( sender() ); - bool error = false; - - // NOTE: this should never happen - if ( !reply ) - { - emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() ); - return; - } - - QVariant callbackObj; - if ( reply->property( "callbackobj" ).isValid() ) - callbackObj = reply->property( "callbackobj" ); - - // Check for the redirect attribute, as this should be the shortened link - QVariant urlVariant = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ); - - // NOTE: this should never happen - if ( urlVariant.isNull() || !urlVariant.isValid() ) - error = true; - - QUrl longUrl = reply->request().url(); - QUrl shortUrl = urlVariant.toUrl(); - - // NOTE: this should never happen - if ( !shortUrl.isValid() ) - error = true; - -#ifndef ENABLE_HEADLESS - // Success! Here is the short link - if ( m_clipboardLongUrl == reply->request().url() ) - { - QClipboard* cb = QApplication::clipboard(); - - QByteArray data = percentEncode( error ? longUrl : shortUrl ); - cb->setText( data ); - - m_clipboardLongUrl.clear(); - } - else -#endif - { - if ( !error ) - emit shortLinkReady( longUrl, shortUrl, callbackObj ); - else - emit shortLinkReady( longUrl, longUrl, callbackObj ); - } - - reply->deleteLater(); -} - - -#ifndef ENABLE_HEADLESS - -void -GlobalActionManager::postShortenFinished() -{ - QNetworkReply* reply = qobject_cast( sender() ); - Q_ASSERT( reply ); - const QByteArray raw = reply->readAll(); - - const QUrl url = QUrl::fromUserInput( raw ); - QClipboard* cb = QApplication::clipboard(); - - const QByteArray data = percentEncode( url ); - cb->setText( data ); - - reply->deleteLater(); -} - -#endif - - -void -GlobalActionManager::shortenLinkRequestError( QNetworkReply::NetworkError error ) -{ - tDebug() << Q_FUNC_INFO << "Network Error:" << error; - - QNetworkReply *reply = qobject_cast( sender() ); - - // NOTE: this should never happen - if ( !reply ) - { - emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() ); - return; - } - - QVariantMap callbackMap; - if ( reply->property( "callbackMap" ).canConvert< QVariantMap >() && !reply->property( "callbackMap" ).toMap().isEmpty() ) - callbackMap = reply->property( "callbackMap" ).toMap(); - reply->deleteLater(); - emit shortLinkReady( QUrl( "" ), QUrl( "" ), callbackMap ); -} - - -#ifndef ENABLE_HEADLESS - void GlobalActionManager::showPlaylist() { @@ -1455,15 +1305,3 @@ GlobalActionManager::hostname() const { return QString( "http://toma.hk" ); } - - -QByteArray -GlobalActionManager::percentEncode( const QUrl& url ) const -{ - QByteArray data = url.toEncoded(); - - data.replace( "'", "%27" ); // QUrl doesn't encode ', which it doesn't have to. Some apps don't like ' though, and want %27. Both are valid. - data.replace( "%20", "+" ); - - return data; -} diff --git a/src/libtomahawk/GlobalActionManager.h b/src/libtomahawk/GlobalActionManager.h index 457e72386..869d02f86 100644 --- a/src/libtomahawk/GlobalActionManager.h +++ b/src/libtomahawk/GlobalActionManager.h @@ -47,7 +47,6 @@ public: QUrl openLink( const QString& title, const QString& artist, const QString& album ) const; public slots: - void shortenLink( const QUrl& url, const QVariant &callbackObj = QVariant() ); #ifndef ENABLE_HEADLESS @@ -70,7 +69,6 @@ public slots: void savePlaylistToFile( const Tomahawk::playlist_ptr& playlist, const QString& filename ); bool parseTomahawkLink( const QString& link ); - void getShortLink( const Tomahawk::playlist_ptr& playlist ); void waitingForResolved( bool ); Tomahawk::dynplaylist_ptr loadDynamicPlaylist( const QUrl& url, bool station ); @@ -81,17 +79,11 @@ public slots: void handlePlayTrack( const Tomahawk::query_ptr& qry ); #endif -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 ); + void copyToClipboardReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& callbackObj ); #ifndef ENABLE_HEADLESS - void postShortenFinished(); void showPlaylist(); void playlistCreatedToShow( const Tomahawk::playlist_ptr& pl ); @@ -131,8 +123,6 @@ private: QString hostname() const; - inline QByteArray percentEncode( const QUrl& url ) const; - Tomahawk::playlist_ptr m_toShow; Tomahawk::query_ptr m_waitingToPlay; QUrl m_clipboardLongUrl; diff --git a/src/libtomahawk/infosystem/InfoSystemWorker.cpp b/src/libtomahawk/infosystem/InfoSystemWorker.cpp index f5d76773c..fbe974f2e 100644 --- a/src/libtomahawk/infosystem/InfoSystemWorker.cpp +++ b/src/libtomahawk/infosystem/InfoSystemWorker.cpp @@ -20,12 +20,12 @@ #include "InfoSystemWorker.h" -#include "utils/TomahawkUtils.h" #include "utils/Logger.h" - +#include "utils/ShortLinkHelper.h" +#include "utils/TomahawkUtils.h" #include "config.h" -#include "InfoSystemCache.h" #include "GlobalActionManager.h" +#include "InfoSystemCache.h" #include "PlaylistEntry.h" #include "Source.h" @@ -388,8 +388,13 @@ InfoSystemWorker::getShortUrl( Tomahawk::InfoSystem::InfoPushData pushData ) QUrl longUrl = GlobalActionManager::instance()->openLink( title, artist, album ); - GlobalActionManager::instance()->shortenLink( longUrl, QVariant::fromValue< Tomahawk::InfoSystem::InfoPushData >( pushData ) ); - connect( GlobalActionManager::instance(), SIGNAL( shortLinkReady( QUrl, QUrl, QVariant ) ), this, SLOT( shortLinkReady( QUrl, QUrl, QVariant ) ), Qt::UniqueConnection ); + Tomahawk::Utils::ShortLinkHelper* slh = new Tomahawk::Utils::ShortLinkHelper(); + connect( slh, SIGNAL( shortLinkReady( QUrl, QUrl, QVariant ) ), + SLOT( shortLinkReady( QUrl, QUrl, QVariant ) ) ); + connect( slh, SIGNAL( done() ), + slh, SLOT( deleteLater() ), + Qt::QueuedConnection ); + slh->shortenLink( longUrl, QVariant::fromValue< Tomahawk::InfoSystem::InfoPushData >( pushData ) ); m_shortLinksWaiting++; } diff --git a/src/libtomahawk/utils/ShortLinkHelper.cpp b/src/libtomahawk/utils/ShortLinkHelper.cpp new file mode 100644 index 000000000..f0870af97 --- /dev/null +++ b/src/libtomahawk/utils/ShortLinkHelper.cpp @@ -0,0 +1,212 @@ +/* === 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 . + */ + +#include "ShortLinkHelper_p.h" + +#include "utils/Closure.h" +#include "utils/NetworkAccessManager.h" +#include "utils/TomahawkUtils.h" +#include "Playlist.h" +#include "Source.h" +#include "Track.h" + +#include + +namespace Tomahawk { +namespace Utils { + +ShortLinkHelper::ShortLinkHelper(QObject *parent) + : QObject( parent ) + , d_ptr( new ShortLinkHelperPrivate( this ) ) +{ +} + +ShortLinkHelper::~ShortLinkHelper() +{ +} + + +void +ShortLinkHelper::shortLink( const Tomahawk::playlist_ptr& pl ) +{ + Q_D( ShortLinkHelper ); + if ( QThread::currentThread() != thread() ) + { + QMetaObject::invokeMethod( this, "shortLink", Qt::QueuedConnection, + Q_ARG( const Tomahawk::playlist_ptr&, pl) ); + return; + } + + QVariantMap m; + m[ "title" ] = pl->title(); + m[ "creator" ] = pl->author().isNull() ? "" : pl->author()->friendlyName(); + QVariantList tracks; + foreach( const plentry_ptr& pl, pl->entries() ) + { + if ( pl->query().isNull() ) + continue; + + QVariantMap track; + track[ "title" ] = pl->query()->track()->track(); + track[ "creator" ] = pl->query()->track()->artist(); + track[ "album" ] = pl->query()->track()->album(); + + tracks << track; + } + m[ "track" ] = tracks; + + QVariantMap jspf; + jspf["playlist"] = m; + + QJson::Serializer s; + QByteArray msg = s.serialize( jspf ); + + // No built-in Qt facilities for doing a FORM POST. So we build the payload ourselves... + const QByteArray boundary = "----------------------------2434992cccab"; + QByteArray data( QByteArray( "--" + boundary + "\r\n" ) ); + data += "Content-Disposition: form-data; name=\"data\"; filename=\"playlist.jspf\"\r\n"; + data += "Content-Type: application/octet-stream\r\n\r\n"; + data += msg; + data += "\r\n\r\n"; + data += "--" + boundary + "--\r\n\r\n"; + + const QUrl url( QString( "%1/p/").arg( hostname() ) ); + QNetworkRequest req( url ); + req.setHeader( QNetworkRequest::ContentTypeHeader, QString( "multipart/form-data; boundary=%1" ).arg( QString::fromLatin1( boundary ) ) ); + d->reply = Tomahawk::Utils::nam()->post( req, data ); + + NewClosure( d->reply, SIGNAL( finished() ), + this, SLOT( shortLinkRequestFinished( Tomahawk::playlist_ptr ) ), pl ); + connect( d->reply, SIGNAL( error( QNetworkReply::NetworkError ) ), SLOT( shortenLinkRequestError( QNetworkReply::NetworkError ) ) ); +} + + +void +ShortLinkHelper::shortenLink( const QUrl& url, const QVariant& callbackObj ) +{ + Q_D( ShortLinkHelper ); + if ( QThread::currentThread() != thread() ) + { + QMetaObject::invokeMethod( this, "shortenLink", Qt::QueuedConnection, + Q_ARG( const QUrl&, url ), + Q_ARG( const QVariant&, callbackObj ) ); + return; + } + + QNetworkRequest request; + request.setUrl( url ); + + d->reply = Tomahawk::Utils::nam()->get( request ); + if ( callbackObj.isValid() ) + d->reply->setProperty( "callbackobj", callbackObj ); + connect( d->reply, SIGNAL( finished() ), SLOT( shortenLinkRequestFinished() ) ); + connect( d->reply, SIGNAL( error( QNetworkReply::NetworkError ) ), SLOT( shortenLinkRequestError( QNetworkReply::NetworkError ) ) ); +} + + +QString +ShortLinkHelper::hostname() const +{ + return QString( "http://toma.hk" ); +} + + +void +ShortLinkHelper::shortLinkRequestFinished( const playlist_ptr& playlist ) +{ + Q_D( ShortLinkHelper ); + Q_ASSERT( d->reply ); + + const QByteArray raw = d->reply->readAll(); + const QUrl url = QUrl::fromUserInput( raw ); + const QByteArray data = TomahawkUtils::percentEncode( url ); + + emit shortLinkReady( playlist, QString( data.constData() ) ); + emit done(); + + d->reply->deleteLater(); +} + +void +ShortLinkHelper::shortenLinkRequestFinished() +{ + Q_D( ShortLinkHelper ); + bool error = false; + + // NOTE: this should never happen + if ( !d->reply ) + { + emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() ); + emit done(); + return; + } + + QVariant callbackObj; + if ( d->reply->property( "callbackobj" ).isValid() ) + callbackObj = d->reply->property( "callbackobj" ); + + // Check for the redirect attribute, as this should be the shortened link + QVariant urlVariant = d->reply->attribute( QNetworkRequest::RedirectionTargetAttribute ); + + // NOTE: this should never happen + if ( urlVariant.isNull() || !urlVariant.isValid() ) + error = true; + + QUrl longUrl = d->reply->request().url(); + QUrl shortUrl = urlVariant.toUrl(); + + // NOTE: this should never happen + if ( !shortUrl.isValid() ) + error = true; + + if ( !error ) + emit shortLinkReady( longUrl, shortUrl, callbackObj ); + else + emit shortLinkReady( longUrl, longUrl, callbackObj ); + emit done(); + + d->reply->deleteLater(); +} + + +void +ShortLinkHelper::shortenLinkRequestError( QNetworkReply::NetworkError ) +{ + Q_D( ShortLinkHelper ); + + // NOTE: this should never happen + if ( !d->reply ) + { + emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() ); + emit done(); + return; + } + + QVariantMap callbackMap; + if ( d->reply->property( "callbackMap" ).canConvert< QVariantMap >() && !d->reply->property( "callbackMap" ).toMap().isEmpty() ) + callbackMap = d->reply->property( "callbackMap" ).toMap(); + d->reply->deleteLater(); + emit shortLinkReady( QUrl( "" ), QUrl( "" ), callbackMap ); + emit done(); +} + +} // namespace Utils +} // namespace Tomahawk diff --git a/src/libtomahawk/utils/ShortLinkHelper.h b/src/libtomahawk/utils/ShortLinkHelper.h new file mode 100644 index 000000000..a73467bf8 --- /dev/null +++ b/src/libtomahawk/utils/ShortLinkHelper.h @@ -0,0 +1,67 @@ +/* === 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 . + */ + +#pragma once +#ifndef TOMAHAWK_UTILS_SHORTLINKHELPER_H +#define TOMAHAWK_UTILS_SHORTLINKHELPER_H + +#include "DllMacro.h" +#include "Typedefs.h" + +namespace Tomahawk { +namespace Utils { + +class ShortLinkHelperPrivate; + +class DLLEXPORT ShortLinkHelper : public QObject +{ + Q_OBJECT +public: + explicit ShortLinkHelper( QObject *parent = 0 ); + virtual ~ShortLinkHelper(); + + QString hostname() const; + +public slots: + void shortLink( const Tomahawk::playlist_ptr& playlist ); + void shortenLink( const QUrl& url, const QVariant &callbackObj = QVariant() ); + +signals: + void shortLinkReady( const Tomahawk::playlist_ptr& playlist, const QUrl& shortUrl ); + void shortLinkReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& callbackObj ); + void done(); + +protected: + QScopedPointer d_ptr; + +private slots: + void shortLinkRequestFinished( const Tomahawk::playlist_ptr& playlist ); + void shortenLinkRequestFinished(); + void shortenLinkRequestError( QNetworkReply::NetworkError ); + +private: + Q_DECLARE_PRIVATE( ShortLinkHelper ) +}; + +} // namespace Utils +} // namespace Tomahawk + +#endif // TOMAHAWK_UTILS_SHORTLINKHELPER_H diff --git a/src/libtomahawk/utils/ShortLinkHelper_p.h b/src/libtomahawk/utils/ShortLinkHelper_p.h new file mode 100644 index 000000000..eae31f064 --- /dev/null +++ b/src/libtomahawk/utils/ShortLinkHelper_p.h @@ -0,0 +1,50 @@ +/* === 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 . + */ + +#pragma once +#ifndef SHORTLINKHELPER_P_H +#define SHORTLINKHELPER_P_H + +#include "ShortLinkHelper.h" + +namespace Tomahawk +{ +namespace Utils +{ + +class ShortLinkHelperPrivate +{ +public: + ShortLinkHelperPrivate( ShortLinkHelper* q ) + : q_ptr( q ) + { + } + + ShortLinkHelper* q_ptr; + Q_DECLARE_PUBLIC( ShortLinkHelper ) +private: + QNetworkReply* reply; +}; + +} +} + +#endif // SHORTLINKHELPER_P_H diff --git a/src/libtomahawk/utils/TomahawkUtils.cpp b/src/libtomahawk/utils/TomahawkUtils.cpp index 95d3e5454..5f11ca650 100644 --- a/src/libtomahawk/utils/TomahawkUtils.cpp +++ b/src/libtomahawk/utils/TomahawkUtils.cpp @@ -883,5 +883,15 @@ urlSetQuery( QUrl& url, const QString& query ) #endif } +QByteArray +percentEncode( const QUrl& url ) +{ + QByteArray data = url.toEncoded(); + + data.replace( "'", "%27" ); // QUrl doesn't encode ', which it doesn't have to. Some apps don't like ' though, and want %27. Both are valid. + data.replace( "%20", "+" ); + + return data; +} } // ns diff --git a/src/libtomahawk/utils/TomahawkUtils.h b/src/libtomahawk/utils/TomahawkUtils.h index b8b4dba68..e533dcf0a 100644 --- a/src/libtomahawk/utils/TomahawkUtils.h +++ b/src/libtomahawk/utils/TomahawkUtils.h @@ -18,6 +18,7 @@ * along with Tomahawk. If not, see . */ +#pragma once #ifndef TOMAHAWKUTILS_H #define TOMAHAWKUTILS_H @@ -153,6 +154,7 @@ namespace TomahawkUtils DLLEXPORT QString ageToString( const QDateTime& time, bool appendAgoString = false ); DLLEXPORT QString filesizeToString( unsigned int size ); DLLEXPORT QString extensionToMimetype( const QString& extension ); + DLLEXPORT QByteArray percentEncode( const QUrl& url ); DLLEXPORT void msleep( unsigned int ms ); DLLEXPORT bool newerVersion( const QString& oldVersion, const QString& newVersion ); diff --git a/src/tomahawk/SocialWidget.cpp b/src/tomahawk/SocialWidget.cpp index 69ba8a77d..0076373f4 100644 --- a/src/tomahawk/SocialWidget.cpp +++ b/src/tomahawk/SocialWidget.cpp @@ -81,7 +81,7 @@ SocialWidget::SocialWidget( QWidget* parent ) connect( ui->textEdit, SIGNAL( textChanged() ), SLOT( onChanged() ) ); connect( ui->facebookButton, SIGNAL( clicked( bool ) ), SLOT( onChanged() ) ); connect( ui->twitterButton, SIGNAL( clicked( bool ) ), SLOT( onChanged() ) ); - connect( GlobalActionManager::instance(), SIGNAL( shortLinkReady( QUrl, QUrl, QVariant ) ), SLOT( onShortLinkReady( QUrl, QUrl, QVariant ) ) ); + connect( &m_slh, SIGNAL( shortLinkReady( QUrl, QUrl, QVariant ) ), SLOT( onShortLinkReady( QUrl, QUrl, QVariant ) ) ); onChanged(); @@ -181,7 +181,7 @@ SocialWidget::setQuery( const Tomahawk::query_ptr& query ) onChanged(); QUrl longUrl = GlobalActionManager::instance()->openLinkFromQuery( query ); - GlobalActionManager::instance()->shortenLink( longUrl ); + m_slh.shortenLink( longUrl ); } diff --git a/src/tomahawk/SocialWidget.h b/src/tomahawk/SocialWidget.h index e43812896..ecd070cde 100644 --- a/src/tomahawk/SocialWidget.h +++ b/src/tomahawk/SocialWidget.h @@ -22,6 +22,8 @@ #include "Query.h" +#include "utils/ShortLinkHelper.h" + #include #include #include @@ -79,6 +81,7 @@ private: QWidget* m_parent; QRect m_parentRect; QTimer m_timer; + Tomahawk::Utils::ShortLinkHelper m_slh; }; #endif // SOCIALWIDGET_H diff --git a/src/tomahawk/sourcetree/SourceTreeView.cpp b/src/tomahawk/sourcetree/SourceTreeView.cpp index 6631983e9..2c5c0cba7 100644 --- a/src/tomahawk/sourcetree/SourceTreeView.cpp +++ b/src/tomahawk/sourcetree/SourceTreeView.cpp @@ -31,21 +31,23 @@ #include "sourcetree/items/SourceItem.h" #include "SourcePlaylistInterface.h" #include "TomahawkSettings.h" -#include "GlobalActionManager.h" #include "DropJob.h" #include "items/GenericPageItems.h" #include "items/TemporaryPageItem.h" #include "database/DatabaseCommand_SocialAction.h" #include "database/Database.h" #include "LatchManager.h" -#include "utils/TomahawkUtilsGui.h" -#include "utils/Logger.h" +#include "GlobalActionManager.h" #include "utils/Closure.h" +#include "utils/Logger.h" +#include "utils/ShortLinkHelper.h" +#include "utils/TomahawkUtilsGui.h" #include "widgets/SourceTreePopupDialog.h" #include "PlaylistEntry.h" #include #include +#include #include #include #include @@ -472,6 +474,14 @@ SourceTreeView::onDeletePlaylistResult( bool result ) } +void +SourceTreeView::shortLinkReady( const playlist_ptr&, const QUrl& shortUrl ) +{ + QByteArray data = TomahawkUtils::percentEncode( shortUrl ); + QApplication::clipboard()->setText( data ); +} + + void SourceTreeView::copyPlaylistLink() { @@ -491,7 +501,13 @@ SourceTreeView::copyPlaylistLink() const PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex ); const playlist_ptr playlist = item->playlist(); - GlobalActionManager::instance()->getShortLink( playlist ); + Tomahawk::Utils::ShortLinkHelper* slh = new Tomahawk::Utils::ShortLinkHelper(); + connect( slh, SIGNAL( shortLinkReady( Tomahawk::playlist_ptr, QUrl ) ), + SLOT( shortLinkReady( Tomahawk::playlist_ptr, QUrl ) ) ); + connect( slh, SIGNAL( done() ), + slh, SLOT( deleteLater() ), + Qt::QueuedConnection ); + slh->shortLink( playlist ); } } diff --git a/src/tomahawk/sourcetree/SourceTreeView.h b/src/tomahawk/sourcetree/SourceTreeView.h index b8f2608b8..d08454f8d 100644 --- a/src/tomahawk/sourcetree/SourceTreeView.h +++ b/src/tomahawk/sourcetree/SourceTreeView.h @@ -87,6 +87,8 @@ private slots: void onDeletePlaylistResult( bool result ); + void shortLinkReady( const Tomahawk::playlist_ptr& playlist, const QUrl& shortUrl ); + protected: void drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; void drawBranches( QPainter *painter, const QRect &rect, const QModelIndex &index ) const;