mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-11 16:44:05 +02:00
Extract ShortLink handling into utils/
This commit is contained in:
@@ -126,6 +126,7 @@ set( libGuiSources
|
|||||||
utils/NetworkReply.cpp
|
utils/NetworkReply.cpp
|
||||||
utils/NetworkProxyFactory.cpp
|
utils/NetworkProxyFactory.cpp
|
||||||
utils/NetworkAccessManager.cpp
|
utils/NetworkAccessManager.cpp
|
||||||
|
utils/ShortLinkHelper.cpp
|
||||||
|
|
||||||
widgets/AnimatedCounterLabel.cpp
|
widgets/AnimatedCounterLabel.cpp
|
||||||
widgets/AnimatedSplitter.cpp
|
widgets/AnimatedSplitter.cpp
|
||||||
|
@@ -32,13 +32,14 @@
|
|||||||
#include "resolvers/ScriptCommand_LookupUrl.h"
|
#include "resolvers/ScriptCommand_LookupUrl.h"
|
||||||
#include "utils/JspfLoader.h"
|
#include "utils/JspfLoader.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
#include "utils/NetworkAccessManager.h"
|
||||||
#include "utils/RdioParser.h"
|
#include "utils/RdioParser.h"
|
||||||
#include "utils/ShortenedLinkParser.h"
|
#include "utils/ShortenedLinkParser.h"
|
||||||
|
#include "utils/ShortLinkHelper.h"
|
||||||
#include "utils/SpotifyParser.h"
|
#include "utils/SpotifyParser.h"
|
||||||
#include "utils/TomahawkUtils.h"
|
#include "utils/TomahawkUtils.h"
|
||||||
#include "utils/XspfLoader.h"
|
#include "utils/XspfLoader.h"
|
||||||
#include "utils/XspfGenerator.h"
|
#include "utils/XspfGenerator.h"
|
||||||
#include "utils/NetworkAccessManager.h"
|
|
||||||
#include "widgets/SearchWidget.h"
|
#include "widgets/SearchWidget.h"
|
||||||
|
|
||||||
#include "Album.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
|
bool
|
||||||
GlobalActionManager::openUrl( const QString& url )
|
GlobalActionManager::openUrl( const QString& url )
|
||||||
{
|
{
|
||||||
@@ -207,52 +185,6 @@ GlobalActionManager::openUrl( const QString& url )
|
|||||||
|
|
||||||
#ifndef ENABLE_HEADLESS
|
#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
|
QString
|
||||||
GlobalActionManager::copyPlaylistToClipboard( const dynplaylist_ptr& playlist )
|
GlobalActionManager::copyPlaylistToClipboard( const dynplaylist_ptr& playlist )
|
||||||
{
|
{
|
||||||
@@ -337,7 +269,13 @@ void
|
|||||||
GlobalActionManager::copyToClipboard( const query_ptr& query )
|
GlobalActionManager::copyToClipboard( const query_ptr& query )
|
||||||
{
|
{
|
||||||
m_clipboardLongUrl = openLinkFromQuery( 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
|
bool
|
||||||
GlobalActionManager::handleQueueCommand( const QUrl& url )
|
GlobalActionManager::handleQueueCommand( const QUrl& url )
|
||||||
{
|
{
|
||||||
@@ -1278,110 +1232,6 @@ GlobalActionManager::playRdio( const QUrl& url )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
GlobalActionManager::shortenLinkRequestFinished()
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>( 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<QNetworkReply*>( 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<QNetworkReply*>( 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
|
void
|
||||||
GlobalActionManager::showPlaylist()
|
GlobalActionManager::showPlaylist()
|
||||||
{
|
{
|
||||||
@@ -1455,15 +1305,3 @@ GlobalActionManager::hostname() const
|
|||||||
{
|
{
|
||||||
return QString( "http://toma.hk" );
|
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;
|
|
||||||
}
|
|
||||||
|
@@ -47,7 +47,6 @@ public:
|
|||||||
QUrl openLink( const QString& title, const QString& artist, const QString& album ) const;
|
QUrl openLink( const QString& title, const QString& artist, const QString& album ) const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void shortenLink( const QUrl& url, const QVariant &callbackObj = QVariant() );
|
|
||||||
|
|
||||||
#ifndef ENABLE_HEADLESS
|
#ifndef ENABLE_HEADLESS
|
||||||
|
|
||||||
@@ -70,7 +69,6 @@ public slots:
|
|||||||
void savePlaylistToFile( const Tomahawk::playlist_ptr& playlist, const QString& filename );
|
void savePlaylistToFile( const Tomahawk::playlist_ptr& playlist, const QString& filename );
|
||||||
|
|
||||||
bool parseTomahawkLink( const QString& link );
|
bool parseTomahawkLink( const QString& link );
|
||||||
void getShortLink( const Tomahawk::playlist_ptr& playlist );
|
|
||||||
void waitingForResolved( bool );
|
void waitingForResolved( bool );
|
||||||
|
|
||||||
Tomahawk::dynplaylist_ptr loadDynamicPlaylist( const QUrl& url, bool station );
|
Tomahawk::dynplaylist_ptr loadDynamicPlaylist( const QUrl& url, bool station );
|
||||||
@@ -81,17 +79,11 @@ public slots:
|
|||||||
void handlePlayTrack( const Tomahawk::query_ptr& qry );
|
void handlePlayTrack( const Tomahawk::query_ptr& qry );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
signals:
|
|
||||||
void shortLinkReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& callbackObj );
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void informationForUrl( const QString& url, const QSharedPointer<QObject>& information );
|
void informationForUrl( const QString& url, const QSharedPointer<QObject>& information );
|
||||||
|
void copyToClipboardReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& callbackObj );
|
||||||
void shortenLinkRequestFinished();
|
|
||||||
void shortenLinkRequestError( QNetworkReply::NetworkError );
|
|
||||||
|
|
||||||
#ifndef ENABLE_HEADLESS
|
#ifndef ENABLE_HEADLESS
|
||||||
void postShortenFinished();
|
|
||||||
void showPlaylist();
|
void showPlaylist();
|
||||||
|
|
||||||
void playlistCreatedToShow( const Tomahawk::playlist_ptr& pl );
|
void playlistCreatedToShow( const Tomahawk::playlist_ptr& pl );
|
||||||
@@ -131,8 +123,6 @@ private:
|
|||||||
|
|
||||||
QString hostname() const;
|
QString hostname() const;
|
||||||
|
|
||||||
inline QByteArray percentEncode( const QUrl& url ) const;
|
|
||||||
|
|
||||||
Tomahawk::playlist_ptr m_toShow;
|
Tomahawk::playlist_ptr m_toShow;
|
||||||
Tomahawk::query_ptr m_waitingToPlay;
|
Tomahawk::query_ptr m_waitingToPlay;
|
||||||
QUrl m_clipboardLongUrl;
|
QUrl m_clipboardLongUrl;
|
||||||
|
@@ -20,12 +20,12 @@
|
|||||||
|
|
||||||
#include "InfoSystemWorker.h"
|
#include "InfoSystemWorker.h"
|
||||||
|
|
||||||
#include "utils/TomahawkUtils.h"
|
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
#include "utils/ShortLinkHelper.h"
|
||||||
|
#include "utils/TomahawkUtils.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "InfoSystemCache.h"
|
|
||||||
#include "GlobalActionManager.h"
|
#include "GlobalActionManager.h"
|
||||||
|
#include "InfoSystemCache.h"
|
||||||
#include "PlaylistEntry.h"
|
#include "PlaylistEntry.h"
|
||||||
#include "Source.h"
|
#include "Source.h"
|
||||||
|
|
||||||
@@ -388,8 +388,13 @@ InfoSystemWorker::getShortUrl( Tomahawk::InfoSystem::InfoPushData pushData )
|
|||||||
|
|
||||||
QUrl longUrl = GlobalActionManager::instance()->openLink( title, artist, album );
|
QUrl longUrl = GlobalActionManager::instance()->openLink( title, artist, album );
|
||||||
|
|
||||||
GlobalActionManager::instance()->shortenLink( longUrl, QVariant::fromValue< Tomahawk::InfoSystem::InfoPushData >( pushData ) );
|
Tomahawk::Utils::ShortLinkHelper* slh = new Tomahawk::Utils::ShortLinkHelper();
|
||||||
connect( GlobalActionManager::instance(), SIGNAL( shortLinkReady( QUrl, QUrl, QVariant ) ), this, SLOT( shortLinkReady( QUrl, QUrl, QVariant ) ), Qt::UniqueConnection );
|
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++;
|
m_shortLinksWaiting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
212
src/libtomahawk/utils/ShortLinkHelper.cpp
Normal file
212
src/libtomahawk/utils/ShortLinkHelper.cpp
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||||
|
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
|
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 <qjson/serializer.h>
|
||||||
|
|
||||||
|
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
|
67
src/libtomahawk/utils/ShortLinkHelper.h
Normal file
67
src/libtomahawk/utils/ShortLinkHelper.h
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||||
|
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
|
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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<ShortLinkHelperPrivate> 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
|
50
src/libtomahawk/utils/ShortLinkHelper_p.h
Normal file
50
src/libtomahawk/utils/ShortLinkHelper_p.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||||
|
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
|
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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
|
@@ -883,5 +883,15 @@ urlSetQuery( QUrl& url, const QString& query )
|
|||||||
#endif
|
#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
|
} // ns
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef TOMAHAWKUTILS_H
|
#ifndef TOMAHAWKUTILS_H
|
||||||
#define TOMAHAWKUTILS_H
|
#define TOMAHAWKUTILS_H
|
||||||
|
|
||||||
@@ -153,6 +154,7 @@ namespace TomahawkUtils
|
|||||||
DLLEXPORT QString ageToString( const QDateTime& time, bool appendAgoString = false );
|
DLLEXPORT QString ageToString( const QDateTime& time, bool appendAgoString = false );
|
||||||
DLLEXPORT QString filesizeToString( unsigned int size );
|
DLLEXPORT QString filesizeToString( unsigned int size );
|
||||||
DLLEXPORT QString extensionToMimetype( const QString& extension );
|
DLLEXPORT QString extensionToMimetype( const QString& extension );
|
||||||
|
DLLEXPORT QByteArray percentEncode( const QUrl& url );
|
||||||
|
|
||||||
DLLEXPORT void msleep( unsigned int ms );
|
DLLEXPORT void msleep( unsigned int ms );
|
||||||
DLLEXPORT bool newerVersion( const QString& oldVersion, const QString& newVersion );
|
DLLEXPORT bool newerVersion( const QString& oldVersion, const QString& newVersion );
|
||||||
|
@@ -81,7 +81,7 @@ SocialWidget::SocialWidget( QWidget* parent )
|
|||||||
connect( ui->textEdit, SIGNAL( textChanged() ), SLOT( onChanged() ) );
|
connect( ui->textEdit, SIGNAL( textChanged() ), SLOT( onChanged() ) );
|
||||||
connect( ui->facebookButton, SIGNAL( clicked( bool ) ), SLOT( onChanged() ) );
|
connect( ui->facebookButton, SIGNAL( clicked( bool ) ), SLOT( onChanged() ) );
|
||||||
connect( ui->twitterButton, 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();
|
onChanged();
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ SocialWidget::setQuery( const Tomahawk::query_ptr& query )
|
|||||||
onChanged();
|
onChanged();
|
||||||
|
|
||||||
QUrl longUrl = GlobalActionManager::instance()->openLinkFromQuery( query );
|
QUrl longUrl = GlobalActionManager::instance()->openLinkFromQuery( query );
|
||||||
GlobalActionManager::instance()->shortenLink( longUrl );
|
m_slh.shortenLink( longUrl );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#include "Query.h"
|
#include "Query.h"
|
||||||
|
|
||||||
|
#include "utils/ShortLinkHelper.h"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QAbstractItemView>
|
#include <QAbstractItemView>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@@ -79,6 +81,7 @@ private:
|
|||||||
QWidget* m_parent;
|
QWidget* m_parent;
|
||||||
QRect m_parentRect;
|
QRect m_parentRect;
|
||||||
QTimer m_timer;
|
QTimer m_timer;
|
||||||
|
Tomahawk::Utils::ShortLinkHelper m_slh;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SOCIALWIDGET_H
|
#endif // SOCIALWIDGET_H
|
||||||
|
@@ -31,21 +31,23 @@
|
|||||||
#include "sourcetree/items/SourceItem.h"
|
#include "sourcetree/items/SourceItem.h"
|
||||||
#include "SourcePlaylistInterface.h"
|
#include "SourcePlaylistInterface.h"
|
||||||
#include "TomahawkSettings.h"
|
#include "TomahawkSettings.h"
|
||||||
#include "GlobalActionManager.h"
|
|
||||||
#include "DropJob.h"
|
#include "DropJob.h"
|
||||||
#include "items/GenericPageItems.h"
|
#include "items/GenericPageItems.h"
|
||||||
#include "items/TemporaryPageItem.h"
|
#include "items/TemporaryPageItem.h"
|
||||||
#include "database/DatabaseCommand_SocialAction.h"
|
#include "database/DatabaseCommand_SocialAction.h"
|
||||||
#include "database/Database.h"
|
#include "database/Database.h"
|
||||||
#include "LatchManager.h"
|
#include "LatchManager.h"
|
||||||
#include "utils/TomahawkUtilsGui.h"
|
#include "GlobalActionManager.h"
|
||||||
#include "utils/Logger.h"
|
|
||||||
#include "utils/Closure.h"
|
#include "utils/Closure.h"
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
#include "utils/ShortLinkHelper.h"
|
||||||
|
#include "utils/TomahawkUtilsGui.h"
|
||||||
#include "widgets/SourceTreePopupDialog.h"
|
#include "widgets/SourceTreePopupDialog.h"
|
||||||
#include "PlaylistEntry.h"
|
#include "PlaylistEntry.h"
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QClipboard>
|
||||||
#include <QContextMenuEvent>
|
#include <QContextMenuEvent>
|
||||||
#include <QDragEnterEvent>
|
#include <QDragEnterEvent>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
@@ -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
|
void
|
||||||
SourceTreeView::copyPlaylistLink()
|
SourceTreeView::copyPlaylistLink()
|
||||||
{
|
{
|
||||||
@@ -491,7 +501,13 @@ SourceTreeView::copyPlaylistLink()
|
|||||||
const PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex );
|
const PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex );
|
||||||
const playlist_ptr playlist = item->playlist();
|
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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -87,6 +87,8 @@ private slots:
|
|||||||
|
|
||||||
void onDeletePlaylistResult( bool result );
|
void onDeletePlaylistResult( bool result );
|
||||||
|
|
||||||
|
void shortLinkReady( const Tomahawk::playlist_ptr& playlist, const QUrl& shortUrl );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
void drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||||
void drawBranches( QPainter *painter, const QRect &rect, const QModelIndex &index ) const;
|
void drawBranches( QPainter *painter, const QRect &rect, const QModelIndex &index ) const;
|
||||||
|
Reference in New Issue
Block a user