mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-01-18 23:17:59 +01:00
Add UrlLookup functionality to JSResolvers
This commit is contained in:
parent
6c75a94479
commit
03e4570452
@ -83,7 +83,8 @@ var TomahawkResolverCapability = {
|
||||
NullCapability: 0,
|
||||
Browsable: 1,
|
||||
PlaylistSync: 2,
|
||||
AccountFactory: 4
|
||||
AccountFactory: 4,
|
||||
UrlLookup: 8
|
||||
};
|
||||
|
||||
|
||||
|
@ -336,6 +336,7 @@ list(APPEND libSources
|
||||
resolvers/ScriptCommand_AllArtists.cpp
|
||||
resolvers/ScriptCommand_AllAlbums.cpp
|
||||
resolvers/ScriptCommand_AllTracks.cpp
|
||||
resolvers/ScriptCommand_LookupUrl.cpp
|
||||
resolvers/ScriptCommandQueue.cpp
|
||||
|
||||
sip/SipPlugin.cpp
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "ScriptCommand_AllArtists.h"
|
||||
#include "ScriptCommand_AllAlbums.h"
|
||||
#include "ScriptCommand_AllTracks.h"
|
||||
#include "ScriptCommand_LookupUrl.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
#include <boost/function.hpp>
|
||||
@ -53,6 +54,7 @@ Q_OBJECT
|
||||
friend class ::ScriptCommand_AllArtists;
|
||||
friend class ::ScriptCommand_AllAlbums;
|
||||
friend class ::ScriptCommand_AllTracks;
|
||||
friend class ::ScriptCommand_LookupUrl;
|
||||
|
||||
public:
|
||||
enum ErrorState {
|
||||
@ -66,7 +68,8 @@ public:
|
||||
NullCapability = 0x0,
|
||||
Browsable = 0x1, // can be represented in one or more collection tree views
|
||||
PlaylistSync = 0x2, // can sync playlists
|
||||
AccountFactory = 0x4 // can configure multiple accounts at the same time
|
||||
AccountFactory = 0x4, // can configure multiple accounts at the same time
|
||||
UrlLookup = 0x8 // can be queried for information on an Url
|
||||
};
|
||||
Q_DECLARE_FLAGS( Capabilities, Capability )
|
||||
Q_FLAGS( Capabilities )
|
||||
@ -85,6 +88,9 @@ public:
|
||||
virtual Capabilities capabilities() const = 0;
|
||||
virtual QMap< QString, Tomahawk::collection_ptr > collections() { return m_collections; }
|
||||
|
||||
// UrlLookup, sync call
|
||||
virtual bool canParseUrl( const QString& url ) = 0;
|
||||
|
||||
virtual void enqueue( const QSharedPointer< ScriptCommand >& req )
|
||||
{ m_commandQueue->enqueue( req ); }
|
||||
|
||||
@ -100,6 +106,7 @@ signals:
|
||||
void artistsFound( const QList< Tomahawk::artist_ptr >& );
|
||||
void albumsFound( const QList< Tomahawk::album_ptr >& );
|
||||
void tracksFound( const QList< Tomahawk::query_ptr >& );
|
||||
void informationFound( const QString&, const QSharedPointer<QObject>& );
|
||||
|
||||
protected:
|
||||
void setFilePath( const QString& path ) { m_filePath = path; }
|
||||
@ -107,9 +114,12 @@ protected:
|
||||
ScriptCommandQueue* m_commandQueue;
|
||||
|
||||
// Should only be called by ScriptCommands
|
||||
// ScriptCollection
|
||||
virtual void artists( const Tomahawk::collection_ptr& collection ) = 0;
|
||||
virtual void albums( const Tomahawk::collection_ptr& collection, const Tomahawk::artist_ptr& artist ) = 0;
|
||||
virtual void tracks( const Tomahawk::collection_ptr& collection, const Tomahawk::album_ptr& album ) = 0;
|
||||
// UrlLookup
|
||||
virtual void lookupUrl( const QString& url ) = 0;
|
||||
|
||||
private:
|
||||
QString m_filePath;
|
||||
|
@ -406,6 +406,65 @@ JSResolver::tracks( const Tomahawk::collection_ptr& collection, const Tomahawk::
|
||||
tDebug() << errorMessage << m;
|
||||
}
|
||||
|
||||
bool JSResolver::canParseUrl( const QString& url )
|
||||
{
|
||||
Q_D( 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 ) )
|
||||
{
|
||||
QString eval = QString( "resolver.canParseUrl( '%1' );" )
|
||||
.arg( QString( url ).replace( "'", "\\'" ) );
|
||||
return d->engine->mainFrame()->evaluateJavaScript( eval ).toBool();
|
||||
}
|
||||
else
|
||||
{
|
||||
// We cannot do URL lookup.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolver::lookupUrl( const QString& url )
|
||||
{
|
||||
Q_D( JSResolver );
|
||||
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "lookupUrl", Qt::QueuedConnection,
|
||||
Q_ARG( QString, url ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !capabilities().testFlag( UrlLookup ) )
|
||||
{
|
||||
emit informationFound( url, QSharedPointer<QObject>() );
|
||||
return;
|
||||
}
|
||||
|
||||
QString eval = QString( "resolver.lookupUrl( '%1' );" )
|
||||
.arg( QString( url ).replace( "'", "\\'" ) );
|
||||
|
||||
QVariantMap m = d->engine->mainFrame()->evaluateJavaScript( eval ).toMap();
|
||||
if ( m.isEmpty() )
|
||||
{
|
||||
// if the resolver doesn't return anything, async api is used
|
||||
return;
|
||||
}
|
||||
|
||||
QString errorMessage = tr( "Script Resolver Warning: API call %1 returned data synchronously." ).arg( eval );
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( errorMessage ) );
|
||||
tDebug() << errorMessage << m;
|
||||
}
|
||||
|
||||
|
||||
Tomahawk::ExternalResolver::ErrorState
|
||||
JSResolver::error() const
|
||||
|
@ -58,6 +58,8 @@ public:
|
||||
|
||||
virtual void setIcon( const QPixmap& icon );
|
||||
|
||||
virtual bool canParseUrl( const QString& url );
|
||||
|
||||
public slots:
|
||||
virtual void resolve( const Tomahawk::query_ptr& query );
|
||||
virtual void stop();
|
||||
@ -67,6 +69,8 @@ public slots:
|
||||
virtual void artists( const Tomahawk::collection_ptr& collection );
|
||||
virtual void albums( const Tomahawk::collection_ptr& collection, const Tomahawk::artist_ptr& artist );
|
||||
virtual void tracks( const Tomahawk::collection_ptr& collection, const Tomahawk::album_ptr& album );
|
||||
// For UrlLookup
|
||||
virtual void lookupUrl( const QString& url );
|
||||
|
||||
signals:
|
||||
void stopped();
|
||||
|
@ -215,6 +215,40 @@ JSResolverHelper::addAlbumTrackResults( const QVariantMap& results )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolverHelper::addUrlResult( const QString& url, const QVariantMap& result )
|
||||
{
|
||||
QString type = result.value( "type" ).toString();
|
||||
if ( type == "track" )
|
||||
{
|
||||
QString title = result.value( "title" ).toString();
|
||||
QString artist = result.value( "artist" ).toString();
|
||||
QString album = result.value( "album" ).toString();
|
||||
tLog( LOGVERBOSE ) << m_resolver->name() << "Got track for url" << url << title << artist << album;
|
||||
if ( title.isEmpty() || artist.isEmpty() )
|
||||
{
|
||||
// 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>() );
|
||||
}
|
||||
|
||||
Tomahawk::query_ptr query = Tomahawk::Query::get( artist, title, album );
|
||||
QString resultHint = result.value( "hint" ).toString();
|
||||
if ( !resultHint.isEmpty() )
|
||||
{
|
||||
query->setResultHint( resultHint );
|
||||
query->setSaveHTTPResultHint( true );
|
||||
}
|
||||
emit m_resolver->informationFound( url, query.objectCast<QObject>() );
|
||||
}
|
||||
else
|
||||
{
|
||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << m_resolver->name() << "No usable information found for " << url;
|
||||
emit m_resolver->informationFound( url, QSharedPointer<QObject>() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolverHelper::reportCapabilities( const QVariant& v )
|
||||
{
|
||||
|
@ -70,6 +70,8 @@ public slots:
|
||||
void addAlbumResults( const QVariantMap& results );
|
||||
void addAlbumTrackResults( const QVariantMap& results );
|
||||
|
||||
void addUrlResult( const QString& url, const QVariantMap& result );
|
||||
|
||||
void reportCapabilities( const QVariant& capabilities );
|
||||
|
||||
private:
|
||||
|
74
src/libtomahawk/resolvers/ScriptCommand_LookupUrl.cpp
Normal file
74
src/libtomahawk/resolvers/ScriptCommand_LookupUrl.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptCommand_LookupUrl_p.h"
|
||||
|
||||
ScriptCommand_LookupUrl::ScriptCommand_LookupUrl( Tomahawk::ExternalResolver* resolver, const QString& url, QObject* parent )
|
||||
: ScriptCommand( parent )
|
||||
, d_ptr( new ScriptCommand_LookupUrlPrivate( this, resolver, url ) )
|
||||
{
|
||||
}
|
||||
|
||||
ScriptCommand_LookupUrl::~ScriptCommand_LookupUrl()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommand_LookupUrl::enqueue()
|
||||
{
|
||||
Q_D( ScriptCommand_LookupUrl );
|
||||
d->resolver->enqueue( QSharedPointer< ScriptCommand >( this ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommand_LookupUrl::exec()
|
||||
{
|
||||
Q_D( ScriptCommand_LookupUrl );
|
||||
connect( d->resolver, SIGNAL( informationFound( QString , QSharedPointer<QObject> ) ),
|
||||
this, SLOT( onResolverDone( QString, QSharedPointer<QObject> ) ) );
|
||||
|
||||
d->resolver->lookupUrl( d->url );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommand_LookupUrl::reportFailure()
|
||||
{
|
||||
Q_D( ScriptCommand_LookupUrl );
|
||||
emit information( d->url, QSharedPointer<QObject>() );
|
||||
emit done();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommand_LookupUrl::onResolverDone( const QString& url, const QSharedPointer<QObject>& _information )
|
||||
{
|
||||
Q_D( ScriptCommand_LookupUrl );
|
||||
|
||||
qDebug() << Q_FUNC_INFO << url << _information.isNull();
|
||||
if ( url != d->url )
|
||||
{
|
||||
// This data is not for us, skip.
|
||||
return;
|
||||
}
|
||||
emit information( d->url, _information );
|
||||
emit done();
|
||||
}
|
63
src/libtomahawk/resolvers/ScriptCommand_LookupUrl.h
Normal file
63
src/libtomahawk/resolvers/ScriptCommand_LookupUrl.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SCRIPTCOMMAND_LOOKUPURL_H
|
||||
#define SCRIPTCOMMAND_LOOKUPURL_H
|
||||
|
||||
#include "ScriptCommand.h"
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
class ScriptCommand_LookupUrlPrivate;
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class ExternalResolver;
|
||||
|
||||
}
|
||||
|
||||
class DLLEXPORT ScriptCommand_LookupUrl : public ScriptCommand
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScriptCommand_LookupUrl( Tomahawk::ExternalResolver* resolver, const QString& url, QObject* parent = 0 );
|
||||
virtual ~ScriptCommand_LookupUrl();
|
||||
|
||||
virtual void enqueue();
|
||||
|
||||
signals:
|
||||
void information( const QString& url, const QSharedPointer<QObject>& variant );
|
||||
void done();
|
||||
|
||||
protected:
|
||||
virtual void exec();
|
||||
virtual void reportFailure();
|
||||
|
||||
private slots:
|
||||
void onResolverDone( const QString& url, const QSharedPointer<QObject>& information );
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE( ScriptCommand_LookupUrl )
|
||||
ScriptCommand_LookupUrlPrivate* d_ptr;
|
||||
};
|
||||
|
||||
#endif // SCRIPTCOMMAND_LOOKUPURL_H
|
43
src/libtomahawk/resolvers/ScriptCommand_LookupUrl_p.h
Normal file
43
src/libtomahawk/resolvers/ScriptCommand_LookupUrl_p.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SCRIPTCOMMAND_LOOKUPURL_P_H
|
||||
#define SCRIPTCOMMAND_LOOKUPURL_P_H
|
||||
|
||||
#include "ScriptCommand_LookupUrl.h"
|
||||
|
||||
#include "ExternalResolver.h"
|
||||
|
||||
class ScriptCommand_LookupUrlPrivate
|
||||
{
|
||||
public:
|
||||
ScriptCommand_LookupUrlPrivate( ScriptCommand_LookupUrl* q, Tomahawk::ExternalResolver* _resolver, const QString& _url )
|
||||
: q_ptr ( q )
|
||||
, url( _url )
|
||||
, resolver( _resolver )
|
||||
{
|
||||
}
|
||||
ScriptCommand_LookupUrl* q_ptr;
|
||||
Q_DECLARE_PUBLIC ( ScriptCommand_LookupUrl )
|
||||
|
||||
private:
|
||||
QString url;
|
||||
Tomahawk::ExternalResolver* resolver;
|
||||
};
|
||||
|
||||
#endif // SCRIPTCOMMAND_LOOKUPURL_P_H
|
@ -64,6 +64,8 @@ public:
|
||||
|
||||
void sendMessage( const QVariantMap& map );
|
||||
|
||||
virtual bool canParseUrl( const QString& ) { return false; }
|
||||
|
||||
signals:
|
||||
void terminated();
|
||||
void customMessage( const QString& msgType, const QVariantMap& msg );
|
||||
@ -77,6 +79,7 @@ public slots:
|
||||
virtual void artists( const Tomahawk::collection_ptr& ) {}
|
||||
virtual void albums( const Tomahawk::collection_ptr&, const Tomahawk::artist_ptr& ) {}
|
||||
virtual void tracks( const Tomahawk::collection_ptr&, const Tomahawk::album_ptr& ) {}
|
||||
virtual void lookupUrl( const QString& ) {}
|
||||
|
||||
|
||||
private slots:
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "network/DbSyncConnection.h"
|
||||
#include "web/Api_v1.h"
|
||||
#include "SourceList.h"
|
||||
#include "ViewManager.h"
|
||||
#include "ShortcutHandler.h"
|
||||
#include "filemetadata/ScanManager.h"
|
||||
#include "TomahawkSettings.h"
|
||||
@ -706,6 +707,67 @@ TomahawkApp::ipDetectionFailed( QNetworkReply::NetworkError error, QString error
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkApp::informationForUrl( const QString& url, const QSharedPointer<QObject>& 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<Tomahawk::Artist>();
|
||||
if ( !artist.isNull() )
|
||||
{
|
||||
// The Url describes an artist
|
||||
ViewManager::instance()->show( artist );
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to interpret as Album
|
||||
Tomahawk::album_ptr album = information.objectCast<Tomahawk::Album>();
|
||||
if ( !album.isNull() )
|
||||
{
|
||||
// The Url describes an album
|
||||
ViewManager::instance()->show( album );
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to interpret as Track/Query
|
||||
Tomahawk::query_ptr query = information.objectCast<Tomahawk::Query>();
|
||||
if ( !query.isNull() )
|
||||
{
|
||||
// The Url describes a track
|
||||
ViewManager::instance()->show( query );
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to interpret as Playlist
|
||||
Tomahawk::playlist_ptr playlist = information.objectCast<Tomahawk::Playlist>();
|
||||
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()
|
||||
{
|
||||
@ -758,6 +820,30 @@ TomahawkApp::loadUrl( const QString& url )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Can we parse the Url using a ScriptResolver?
|
||||
bool canParse = false;
|
||||
QList< QPointer< ExternalResolver > > possibleResolvers;
|
||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||
{
|
||||
if ( resolver->canParseUrl( url ) )
|
||||
{
|
||||
canParse = true;
|
||||
possibleResolvers << resolver;
|
||||
}
|
||||
}
|
||||
if ( canParse )
|
||||
{
|
||||
m_queuedUrl = url;
|
||||
foreach ( QPointer<ExternalResolver> resolver, possibleResolvers )
|
||||
{
|
||||
ScriptCommand_LookupUrl* cmd = new ScriptCommand_LookupUrl( resolver, url );
|
||||
connect( cmd, SIGNAL( information( QString, QSharedPointer<QObject> ) ), this, SLOT( informationForUrl( QString, QSharedPointer<QObject> ) ) );
|
||||
cmd->enqueue();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
@ -114,6 +114,7 @@ private slots:
|
||||
|
||||
void spotifyApiCheckFinished();
|
||||
void onInfoSystemReady();
|
||||
void informationForUrl( const QString& url, const QSharedPointer<QObject>& information );
|
||||
|
||||
void ipDetectionFailed( QNetworkReply::NetworkError error, QString errorString );
|
||||
|
||||
@ -135,6 +136,7 @@ private:
|
||||
QPointer<Tomahawk::ShortcutHandler> m_shortcutHandler;
|
||||
QPointer< Tomahawk::Accounts::AccountManager > m_accountManager;
|
||||
bool m_scrubFriendlyName;
|
||||
QString m_queuedUrl;
|
||||
|
||||
#ifdef LIBLASTFM_FOUND
|
||||
Scrobbler* m_scrobbler;
|
||||
|
Loading…
x
Reference in New Issue
Block a user