mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-05 05:37:29 +02:00
Move lookupUrl stuff from JSResolverHelper to JSResolver, to be moved to own plugin type
This commit is contained in:
@@ -173,7 +173,8 @@ var TomahawkUrlType = {
|
|||||||
Playlist: 1,
|
Playlist: 1,
|
||||||
Track: 2,
|
Track: 2,
|
||||||
Album: 4,
|
Album: 4,
|
||||||
Artist: 8
|
Artist: 8,
|
||||||
|
Xspf: 16
|
||||||
};
|
};
|
||||||
|
|
||||||
//Deprecated for 0.9 resolvers. Use Tomahawk.ConfigTestResultType instead.
|
//Deprecated for 0.9 resolvers. Use Tomahawk.ConfigTestResultType instead.
|
||||||
|
@@ -175,7 +175,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|
|||||||
// Check Scriptresolvers
|
// Check Scriptresolvers
|
||||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||||
{
|
{
|
||||||
if ( resolver->canParseUrl( url, ExternalResolver::Playlist ) )
|
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypePlaylist ) )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,7 +201,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|
|||||||
// Check Scriptresolvers
|
// Check Scriptresolvers
|
||||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||||
{
|
{
|
||||||
if ( resolver->canParseUrl( url, ExternalResolver::Track ) )
|
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeTrack ) )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,7 +218,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|
|||||||
// Check Scriptresolvers
|
// Check Scriptresolvers
|
||||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||||
{
|
{
|
||||||
if ( resolver->canParseUrl( url, ExternalResolver::Album ) )
|
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeAlbum ) )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|
|||||||
// Check Scriptresolvers
|
// Check Scriptresolvers
|
||||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||||
{
|
{
|
||||||
if ( resolver->canParseUrl( url, ExternalResolver::Artist ) )
|
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeArtist ) )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,7 +306,7 @@ DropJob::isDropType( DropJob::DropType desired, const QMimeData* data )
|
|||||||
// Check Scriptresolvers
|
// Check Scriptresolvers
|
||||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||||
{
|
{
|
||||||
if ( resolver->canParseUrl( url, ExternalResolver::Playlist ) )
|
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypePlaylist ) )
|
||||||
{
|
{
|
||||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Accepting current drop as a playlist" << resolver->name();
|
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Accepting current drop as a playlist" << resolver->name();
|
||||||
return true;
|
return true;
|
||||||
@@ -763,7 +763,7 @@ DropJob::handleTrackUrls( const QString& urls )
|
|||||||
{
|
{
|
||||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||||
{
|
{
|
||||||
if ( resolver->canParseUrl( track, ExternalResolver::Any ) )
|
if ( resolver->canParseUrl( track, ExternalResolver::UrlTypeAny ) )
|
||||||
{
|
{
|
||||||
ScriptCommand_LookupUrl* cmd = new ScriptCommand_LookupUrl( resolver, track );
|
ScriptCommand_LookupUrl* cmd = new ScriptCommand_LookupUrl( resolver, track );
|
||||||
connect( cmd, SIGNAL( information( QString, QSharedPointer<QObject> ) ), this, SLOT( informationForUrl( QString, QSharedPointer<QObject> ) ) );
|
connect( cmd, SIGNAL( information( QString, QSharedPointer<QObject> ) ), this, SLOT( informationForUrl( QString, QSharedPointer<QObject> ) ) );
|
||||||
|
@@ -167,7 +167,7 @@ GlobalActionManager::openUrl( const QString& url )
|
|||||||
QList< QPointer< ExternalResolver > > possibleResolvers;
|
QList< QPointer< ExternalResolver > > possibleResolvers;
|
||||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||||
{
|
{
|
||||||
if ( resolver->canParseUrl( url, ExternalResolver::Any ) )
|
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeAny ) )
|
||||||
{
|
{
|
||||||
canParse = true;
|
canParse = true;
|
||||||
possibleResolvers << resolver;
|
possibleResolvers << resolver;
|
||||||
|
@@ -68,11 +68,12 @@ public:
|
|||||||
|
|
||||||
enum UrlType
|
enum UrlType
|
||||||
{
|
{
|
||||||
Any = 0x00,
|
UrlTypeAny = 0x00,
|
||||||
Playlist = 0x01,
|
UrlTypePlaylist = 0x01,
|
||||||
Track = 0x02,
|
UrlTypeTrack = 0x02,
|
||||||
Album = 0x04,
|
UrlTypeAlbum = 0x04,
|
||||||
Artist = 0x08
|
UrlTypeArtist = 0x08,
|
||||||
|
UrlTypeXspf = 0x10
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS( UrlTypes, UrlType )
|
Q_DECLARE_FLAGS( UrlTypes, UrlType )
|
||||||
Q_FLAGS( UrlTypes )
|
Q_FLAGS( UrlTypes )
|
||||||
|
@@ -46,6 +46,12 @@
|
|||||||
#include "JSAccount.h"
|
#include "JSAccount.h"
|
||||||
#include "ScriptJob.h"
|
#include "ScriptJob.h"
|
||||||
|
|
||||||
|
// lookupUrl stuff
|
||||||
|
#include "playlist/PlaylistTemplate.h"
|
||||||
|
#include "playlist/XspfPlaylistTemplate.h"
|
||||||
|
#include "database/Database.h"
|
||||||
|
#include "database/DatabaseImpl.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
@@ -319,20 +325,13 @@ JSResolver::canParseUrl( const QString& url, UrlType type )
|
|||||||
{
|
{
|
||||||
Q_D( const JSResolver );
|
Q_D( const JSResolver );
|
||||||
|
|
||||||
// FIXME: How can we do this?
|
|
||||||
/*if ( QThread::currentThread() != thread() )
|
|
||||||
{
|
|
||||||
QMetaObject::invokeMethod( this, "canParseUrl", Qt::QueuedConnection,
|
|
||||||
Q_ARG( QString, url ) );
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if ( d->capabilities.testFlag( UrlLookup ) )
|
if ( d->capabilities.testFlag( UrlLookup ) )
|
||||||
{
|
{
|
||||||
QString eval = QString( "canParseUrl( '%1', %2 )" )
|
QVariantMap arguments;
|
||||||
.arg( JSAccount::escape( QString( url ) ) )
|
arguments["url"] = url;
|
||||||
.arg( (int) type );
|
arguments["type"] = (int) type;
|
||||||
return callOnResolver( eval ).toBool();
|
|
||||||
|
return scriptObject()->syncInvoke( "canParseUrl", arguments ).toBool();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -345,34 +344,185 @@ JSResolver::canParseUrl( const QString& url, UrlType type )
|
|||||||
void
|
void
|
||||||
JSResolver::lookupUrl( const QString& url )
|
JSResolver::lookupUrl( const QString& url )
|
||||||
{
|
{
|
||||||
if ( QThread::currentThread() != thread() )
|
|
||||||
{
|
|
||||||
QMetaObject::invokeMethod( this, "lookupUrl", Qt::QueuedConnection,
|
|
||||||
Q_ARG( QString, url ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_D( const JSResolver );
|
Q_D( const JSResolver );
|
||||||
|
|
||||||
|
|
||||||
if ( !d->capabilities.testFlag( UrlLookup ) )
|
if ( !d->capabilities.testFlag( UrlLookup ) )
|
||||||
{
|
{
|
||||||
emit informationFound( url, QSharedPointer<QObject>() );
|
emit informationFound( url, QSharedPointer<QObject>() );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString eval = QString( "lookupUrl( '%1' )" )
|
QVariantMap arguments;
|
||||||
.arg( JSAccount::escape( QString( url ) ) );
|
arguments["url"] = url;
|
||||||
|
Tomahawk::ScriptJob* job = scriptObject()->invoke( "lookupUrl", arguments );
|
||||||
|
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onLookupUrlRequestDone( QVariantMap ) ) );
|
||||||
|
job->setProperty( "url", url );
|
||||||
|
job->start();
|
||||||
|
}
|
||||||
|
|
||||||
QVariantMap m = callOnResolver( eval ).toMap();
|
|
||||||
if ( m.isEmpty() )
|
void
|
||||||
|
JSResolver::onLookupUrlRequestDone( const QVariantMap& result )
|
||||||
|
{
|
||||||
|
sender()->deleteLater();
|
||||||
|
|
||||||
|
QString url = sender()->property( "url" ).toString();
|
||||||
|
|
||||||
|
tLog() << "ON LOOKUP URL REQUEST DONE" << url << result;
|
||||||
|
|
||||||
|
// It may seem a bit weird, but currently no slot should do anything
|
||||||
|
// more as we starting on a new URL and not task are waiting for it yet.
|
||||||
|
m_pendingUrl = QString();
|
||||||
|
m_pendingAlbum = album_ptr();
|
||||||
|
|
||||||
|
UrlTypes type = (UrlTypes) result.value( "type" ).toInt();
|
||||||
|
if ( type == UrlTypeArtist )
|
||||||
{
|
{
|
||||||
// if the resolver doesn't return anything, async api is used
|
QString name = result.value( "name" ).toString();
|
||||||
return;
|
Q_ASSERT( !name.isEmpty() );
|
||||||
|
emit informationFound( url, Artist::get( name, true ).objectCast<QObject>() );
|
||||||
|
}
|
||||||
|
else if ( type == UrlTypeAlbum )
|
||||||
|
{
|
||||||
|
QString name = result.value( "name" ).toString();
|
||||||
|
QString artist = result.value( "artist" ).toString();
|
||||||
|
album_ptr album = Album::get( Artist::get( artist, true ), name );
|
||||||
|
m_pendingUrl = url;
|
||||||
|
m_pendingAlbum = album;
|
||||||
|
connect( album.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
|
||||||
|
SLOT( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ) );
|
||||||
|
if ( !album->tracks().isEmpty() )
|
||||||
|
{
|
||||||
|
emit informationFound( url, album.objectCast<QObject>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( type == UrlTypeTrack )
|
||||||
|
{
|
||||||
|
Tomahawk::query_ptr query = parseTrack( result );
|
||||||
|
if ( query.isNull() )
|
||||||
|
{
|
||||||
|
// A valid track result shoud have non-empty title and artist.
|
||||||
|
tLog() << Q_FUNC_INFO << name() << "Got empty track information for " << url;
|
||||||
|
emit informationFound( url, QSharedPointer<QObject>() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emit informationFound( url, query.objectCast<QObject>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( type == UrlTypePlaylist )
|
||||||
|
{
|
||||||
|
QString guid = result.value( "guid" ).toString();
|
||||||
|
Q_ASSERT( !guid.isEmpty() );
|
||||||
|
// Append nodeid to guid to make it globally unique.
|
||||||
|
guid += instanceUUID();
|
||||||
|
|
||||||
|
// Do we already have this playlist loaded?
|
||||||
|
{
|
||||||
|
playlist_ptr playlist = Playlist::get( guid );
|
||||||
|
if ( !playlist.isNull() )
|
||||||
|
{
|
||||||
|
emit informationFound( url, playlist.objectCast<QObject>() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all information to build a new playlist but do not build it until we know,
|
||||||
|
// if it is really handled as a playlist and not as a set of tracks.
|
||||||
|
Tomahawk::source_ptr source = SourceList::instance()->getLocal();
|
||||||
|
const QString title = result.value( "title" ).toString();
|
||||||
|
const QString info = result.value( "info" ).toString();
|
||||||
|
const QString creator = result.value( "creator" ).toString();
|
||||||
|
QList<query_ptr> queries;
|
||||||
|
foreach( QVariant track, result.value( "tracks" ).toList() )
|
||||||
|
{
|
||||||
|
query_ptr query = parseTrack( track.toMap() );
|
||||||
|
if ( !query.isNull() )
|
||||||
|
{
|
||||||
|
queries << query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tLog( LOGVERBOSE ) << Q_FUNC_INFO << name() << "Got playlist for " << url;
|
||||||
|
playlisttemplate_ptr pltemplate( new PlaylistTemplate( source, guid, title, info, creator, false, queries ) );
|
||||||
|
emit informationFound( url, pltemplate.objectCast<QObject>() );
|
||||||
|
}
|
||||||
|
else if ( type == UrlTypeXspf )
|
||||||
|
{
|
||||||
|
QString xspfUrl = result.value( "url" ).toString();
|
||||||
|
Q_ASSERT( !xspfUrl.isEmpty() );
|
||||||
|
QString guid = QString( "xspf-%1-%2" ).arg( xspfUrl.toUtf8().toBase64().constData() ).arg( instanceUUID() );
|
||||||
|
|
||||||
|
// Do we already have this playlist loaded?
|
||||||
|
{
|
||||||
|
playlist_ptr playlist = Playlist::get( guid );
|
||||||
|
if ( !playlist.isNull() )
|
||||||
|
{
|
||||||
|
emit informationFound( url, playlist.objectCast<QObject>() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get all information to build a new playlist but do not build it until we know,
|
||||||
|
// if it is really handled as a playlist and not as a set of tracks.
|
||||||
|
Tomahawk::source_ptr source = SourceList::instance()->getLocal();
|
||||||
|
QSharedPointer<XspfPlaylistTemplate> pltemplate( new XspfPlaylistTemplate( xspfUrl, source, guid ) );
|
||||||
|
NewClosure( pltemplate, SIGNAL( tracksLoaded( QList< Tomahawk::query_ptr > ) ),
|
||||||
|
this, SLOT( pltemplateTracksLoadedForUrl( QString, Tomahawk::playlisttemplate_ptr ) ),
|
||||||
|
url, pltemplate.objectCast<Tomahawk::PlaylistTemplate>() );
|
||||||
|
tLog( LOGVERBOSE ) << Q_FUNC_INFO << name() << "Got playlist for " << url;
|
||||||
|
pltemplate->load();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tLog( LOGVERBOSE ) << Q_FUNC_INFO << name() << "No usable information found for " << url;
|
||||||
|
emit informationFound( url, QSharedPointer<QObject>() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
query_ptr
|
||||||
|
JSResolver::parseTrack( const QVariantMap& track )
|
||||||
|
{
|
||||||
|
QString title = track.value( "track" ).toString();
|
||||||
|
QString artist = track.value( "artist" ).toString();
|
||||||
|
QString album = track.value( "album" ).toString();
|
||||||
|
if ( title.isEmpty() || artist.isEmpty() )
|
||||||
|
{
|
||||||
|
return query_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString errorMessage = tr( "Script Resolver Warning: API call %1 returned data synchronously." ).arg( eval );
|
Tomahawk::query_ptr query = Tomahawk::Query::get( artist, title, album );
|
||||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( errorMessage ) );
|
QString resultHint = track.value( "hint" ).toString();
|
||||||
tDebug() << errorMessage << m;
|
if ( !resultHint.isEmpty() )
|
||||||
|
{
|
||||||
|
query->setResultHint( resultHint );
|
||||||
|
query->setSaveHTTPResultHint( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
JSResolver::tracksAdded( const QList<query_ptr>&, const ModelMode, const collection_ptr&)
|
||||||
|
{
|
||||||
|
// Check if we still are actively waiting
|
||||||
|
if ( m_pendingAlbum.isNull() || m_pendingUrl.isNull() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
emit informationFound( m_pendingUrl, m_pendingAlbum.objectCast<QObject>() );
|
||||||
|
m_pendingAlbum = album_ptr();
|
||||||
|
m_pendingUrl = QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
JSResolver::pltemplateTracksLoadedForUrl( const QString& url, const playlisttemplate_ptr& pltemplate )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
|
emit informationFound( url, pltemplate.objectCast<QObject>() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -589,3 +739,10 @@ JSResolver::onResolveRequestDone( const QVariantMap& data )
|
|||||||
|
|
||||||
sender()->deleteLater();
|
sender()->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString
|
||||||
|
JSResolver::instanceUUID()
|
||||||
|
{
|
||||||
|
return Tomahawk::Database::instance()->impl()->dbid();
|
||||||
|
}
|
||||||
|
@@ -91,6 +91,7 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onResolveRequestDone(const QVariantMap& data);
|
void onResolveRequestDone(const QVariantMap& data);
|
||||||
|
void onLookupUrlRequestDone(const QVariantMap& data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
@@ -105,6 +106,16 @@ private:
|
|||||||
|
|
||||||
Q_DECLARE_PRIVATE( JSResolver )
|
Q_DECLARE_PRIVATE( JSResolver )
|
||||||
QScopedPointer<JSResolverPrivate> d_ptr;
|
QScopedPointer<JSResolverPrivate> d_ptr;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: move lookupUrl stuff to its own plugin type
|
||||||
|
QString instanceUUID();
|
||||||
|
static Tomahawk::query_ptr parseTrack( const QVariantMap& track );
|
||||||
|
QString m_pendingUrl;
|
||||||
|
Tomahawk::album_ptr m_pendingAlbum;
|
||||||
|
private slots:
|
||||||
|
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::ModelMode, const Tomahawk::collection_ptr& collection );
|
||||||
|
void pltemplateTracksLoadedForUrl( const QString& url, const Tomahawk::playlisttemplate_ptr& pltemplate );
|
||||||
};
|
};
|
||||||
|
|
||||||
} // ns: Tomahawk
|
} // ns: Tomahawk
|
||||||
|
@@ -21,10 +21,6 @@
|
|||||||
|
|
||||||
#include "JSResolverHelper.h"
|
#include "JSResolverHelper.h"
|
||||||
|
|
||||||
#include "database/Database.h"
|
|
||||||
#include "database/DatabaseImpl.h"
|
|
||||||
#include "playlist/PlaylistTemplate.h"
|
|
||||||
#include "playlist/XspfPlaylistTemplate.h"
|
|
||||||
#include "resolvers/ScriptEngine.h"
|
#include "resolvers/ScriptEngine.h"
|
||||||
#include "network/Servent.h"
|
#include "network/Servent.h"
|
||||||
#include "utils/Closure.h"
|
#include "utils/Closure.h"
|
||||||
@@ -140,36 +136,6 @@ JSResolverHelper::log( const QString& message )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
query_ptr
|
|
||||||
JSResolverHelper::parseTrack( const QVariantMap& track )
|
|
||||||
{
|
|
||||||
QString title = track.value( "title" ).toString();
|
|
||||||
QString artist = track.value( "artist" ).toString();
|
|
||||||
QString album = track.value( "album" ).toString();
|
|
||||||
if ( title.isEmpty() || artist.isEmpty() )
|
|
||||||
{
|
|
||||||
return query_ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
Tomahawk::query_ptr query = Tomahawk::Query::get( artist, title, album );
|
|
||||||
QString resultHint = track.value( "hint" ).toString();
|
|
||||||
if ( !resultHint.isEmpty() )
|
|
||||||
{
|
|
||||||
query->setResultHint( resultHint );
|
|
||||||
query->setSaveHTTPResultHint( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString
|
|
||||||
JSResolverHelper::instanceUUID()
|
|
||||||
{
|
|
||||||
return Tomahawk::Database::instance()->impl()->dbid();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString
|
QString
|
||||||
JSResolverHelper::uuid() const
|
JSResolverHelper::uuid() const
|
||||||
{
|
{
|
||||||
@@ -464,120 +430,6 @@ JSResolverHelper::currentCountry() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
JSResolverHelper::addUrlResult( const QString& url, const QVariantMap& result )
|
|
||||||
{
|
|
||||||
// It may seem a bit weird, but currently no slot should do anything
|
|
||||||
// more as we starting on a new URL and not task are waiting for it yet.
|
|
||||||
m_pendingUrl = QString();
|
|
||||||
m_pendingAlbum = album_ptr();
|
|
||||||
|
|
||||||
QString type = result.value( "type" ).toString();
|
|
||||||
if ( type == "artist" )
|
|
||||||
{
|
|
||||||
QString name = result.value( "name" ).toString();
|
|
||||||
Q_ASSERT( !name.isEmpty() );
|
|
||||||
emit m_resolver->informationFound( url, Artist::get( name, true ).objectCast<QObject>() );
|
|
||||||
}
|
|
||||||
else if ( type == "album" )
|
|
||||||
{
|
|
||||||
QString name = result.value( "name" ).toString();
|
|
||||||
QString artist = result.value( "artist" ).toString();
|
|
||||||
album_ptr album = Album::get( Artist::get( artist, true ), name );
|
|
||||||
m_pendingUrl = url;
|
|
||||||
m_pendingAlbum = album;
|
|
||||||
connect( album.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
|
|
||||||
SLOT( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ) );
|
|
||||||
if ( !album->tracks().isEmpty() )
|
|
||||||
{
|
|
||||||
emit m_resolver->informationFound( url, album.objectCast<QObject>() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( type == "track" )
|
|
||||||
{
|
|
||||||
Tomahawk::query_ptr query = parseTrack( result );
|
|
||||||
if ( query.isNull() )
|
|
||||||
{
|
|
||||||
// A valid track result shoud have non-empty title and artist.
|
|
||||||
tLog() << Q_FUNC_INFO << m_resolver->name() << "Got empty track information for " << url;
|
|
||||||
emit m_resolver->informationFound( url, QSharedPointer<QObject>() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
emit m_resolver->informationFound( url, query.objectCast<QObject>() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( type == "playlist" )
|
|
||||||
{
|
|
||||||
QString guid = result.value( "guid" ).toString();
|
|
||||||
Q_ASSERT( !guid.isEmpty() );
|
|
||||||
// Append nodeid to guid to make it globally unique.
|
|
||||||
guid += instanceUUID();
|
|
||||||
|
|
||||||
// Do we already have this playlist loaded?
|
|
||||||
{
|
|
||||||
playlist_ptr playlist = Playlist::get( guid );
|
|
||||||
if ( !playlist.isNull() )
|
|
||||||
{
|
|
||||||
emit m_resolver->informationFound( url, playlist.objectCast<QObject>() );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all information to build a new playlist but do not build it until we know,
|
|
||||||
// if it is really handled as a playlist and not as a set of tracks.
|
|
||||||
Tomahawk::source_ptr source = SourceList::instance()->getLocal();
|
|
||||||
const QString title = result.value( "title" ).toString();
|
|
||||||
const QString info = result.value( "info" ).toString();
|
|
||||||
const QString creator = result.value( "creator" ).toString();
|
|
||||||
QList<query_ptr> queries;
|
|
||||||
foreach( QVariant track, result.value( "tracks" ).toList() )
|
|
||||||
{
|
|
||||||
query_ptr query = parseTrack( track.toMap() );
|
|
||||||
if ( !query.isNull() )
|
|
||||||
{
|
|
||||||
queries << query;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << m_resolver->name() << "Got playlist for " << url;
|
|
||||||
playlisttemplate_ptr pltemplate( new PlaylistTemplate( source, guid, title, info, creator, false, queries ) );
|
|
||||||
emit m_resolver->informationFound( url, pltemplate.objectCast<QObject>() );
|
|
||||||
}
|
|
||||||
else if ( type == "xspf-url" )
|
|
||||||
{
|
|
||||||
QString xspfUrl = result.value( "url" ).toString();
|
|
||||||
Q_ASSERT( !xspfUrl.isEmpty() );
|
|
||||||
QString guid = QString( "xspf-%1-%2" ).arg( xspfUrl.toUtf8().toBase64().constData() ).arg( instanceUUID() );
|
|
||||||
|
|
||||||
// Do we already have this playlist loaded?
|
|
||||||
{
|
|
||||||
playlist_ptr playlist = Playlist::get( guid );
|
|
||||||
if ( !playlist.isNull() )
|
|
||||||
{
|
|
||||||
emit m_resolver->informationFound( url, playlist.objectCast<QObject>() );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Get all information to build a new playlist but do not build it until we know,
|
|
||||||
// if it is really handled as a playlist and not as a set of tracks.
|
|
||||||
Tomahawk::source_ptr source = SourceList::instance()->getLocal();
|
|
||||||
QSharedPointer<XspfPlaylistTemplate> pltemplate( new XspfPlaylistTemplate( xspfUrl, source, guid ) );
|
|
||||||
NewClosure( pltemplate, SIGNAL( tracksLoaded( QList< Tomahawk::query_ptr > ) ),
|
|
||||||
this, SLOT( pltemplateTracksLoadedForUrl( QString, Tomahawk::playlisttemplate_ptr ) ),
|
|
||||||
url, pltemplate.objectCast<Tomahawk::PlaylistTemplate>() );
|
|
||||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << m_resolver->name() << "Got playlist for " << url;
|
|
||||||
pltemplate->load();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << m_resolver->name() << "No usable information found for " << url;
|
|
||||||
emit m_resolver->informationFound( url, QSharedPointer<QObject>() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
JSResolverHelper::nativeReportCapabilities( const QVariant& v )
|
JSResolverHelper::nativeReportCapabilities( const QVariant& v )
|
||||||
{
|
{
|
||||||
@@ -614,27 +466,6 @@ JSResolverHelper::unregisterScriptPlugin( const QString& type, const QString& ob
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
JSResolverHelper::tracksAdded( const QList<query_ptr>&, const ModelMode, const collection_ptr&)
|
|
||||||
{
|
|
||||||
// Check if we still are actively waiting
|
|
||||||
if ( m_pendingAlbum.isNull() || m_pendingUrl.isNull() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
emit m_resolver->informationFound( m_pendingUrl, m_pendingAlbum.objectCast<QObject>() );
|
|
||||||
m_pendingAlbum = album_ptr();
|
|
||||||
m_pendingUrl = QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
JSResolverHelper::pltemplateTracksLoadedForUrl( const QString& url, const playlisttemplate_ptr& pltemplate )
|
|
||||||
{
|
|
||||||
tLog() << Q_FUNC_INFO;
|
|
||||||
emit m_resolver->informationFound( url, pltemplate.objectCast<QObject>() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
JSResolverHelper::setResolverConfig( const QVariantMap& config )
|
JSResolverHelper::setResolverConfig( const QVariantMap& config )
|
||||||
{
|
{
|
||||||
|
@@ -133,7 +133,6 @@ public slots:
|
|||||||
QByteArray readRaw( const QString& fileName );
|
QByteArray readRaw( const QString& fileName );
|
||||||
QString readBase64( const QString& fileName );
|
QString readBase64( const QString& fileName );
|
||||||
QString readCompressed( const QString& fileName );
|
QString readCompressed( const QString& fileName );
|
||||||
QString instanceUUID();
|
|
||||||
QString uuid() const;
|
QString uuid() const;
|
||||||
int currentCountry() const;
|
int currentCountry() const;
|
||||||
QString compress( const QString& data );
|
QString compress( const QString& data );
|
||||||
@@ -142,8 +141,6 @@ public slots:
|
|||||||
void log( const QString& message );
|
void log( const QString& message );
|
||||||
bool fakeEnv() { return false; }
|
bool fakeEnv() { return false; }
|
||||||
|
|
||||||
void addUrlResult( const QString& url, const QVariantMap& result );
|
|
||||||
|
|
||||||
void nativeReportCapabilities( const QVariant& capabilities );
|
void nativeReportCapabilities( const QVariant& capabilities );
|
||||||
|
|
||||||
void reportScriptJobResults( const QVariantMap& result );
|
void reportScriptJobResults( const QVariantMap& result );
|
||||||
@@ -153,12 +150,9 @@ public slots:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void gotStreamUrl( IODeviceCallback callback, NetworkReply* reply );
|
void gotStreamUrl( IODeviceCallback callback, NetworkReply* reply );
|
||||||
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::ModelMode, const Tomahawk::collection_ptr& collection );
|
|
||||||
void pltemplateTracksLoadedForUrl( const QString& url, const Tomahawk::playlisttemplate_ptr& pltemplate );
|
|
||||||
void nativeAsyncRequestDone( int requestId, NetworkReply* reply );
|
void nativeAsyncRequestDone( int requestId, NetworkReply* reply );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Tomahawk::query_ptr parseTrack( const QVariantMap& track );
|
|
||||||
void returnStreamUrl( const QString& streamUrl, const QMap<QString, QString>& headers,
|
void returnStreamUrl( const QString& streamUrl, const QMap<QString, QString>& headers,
|
||||||
std::function< void( const QString&, QSharedPointer< QIODevice >& ) > callback );
|
std::function< void( const QString&, QSharedPointer< QIODevice >& ) > callback );
|
||||||
|
|
||||||
@@ -171,8 +165,6 @@ private:
|
|||||||
QHash< QString, std::function< void( const QString&, QSharedPointer< QIODevice >& ) > > m_streamCallbacks;
|
QHash< QString, std::function< void( const QString&, QSharedPointer< QIODevice >& ) > > m_streamCallbacks;
|
||||||
QHash< QString, std::function< void( const QString& ) > > m_translatorCallbacks;
|
QHash< QString, std::function< void( const QString& ) > > m_translatorCallbacks;
|
||||||
bool m_urlCallbackIsAsync;
|
bool m_urlCallbackIsAsync;
|
||||||
QString m_pendingUrl;
|
|
||||||
Tomahawk::album_ptr m_pendingAlbum;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // ns: Tomahawk
|
} // ns: Tomahawk
|
||||||
|
Reference in New Issue
Block a user