Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Fix url lookup by adding LinkParser plugins #395

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/libtomahawk/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ set( libGuiSources
utils/LinkGenerator.cpp
utils/LinkGeneratorPlugin.cpp
utils/TomaHkLinkGeneratorPlugin.cpp
utils/LinkParser.cpp
utils/LinkParserPlugin.cpp

viewpages/SearchViewPage.cpp
viewpages/SourceViewPage.cpp
Expand Down Expand Up @@ -350,22 +352,23 @@ list(APPEND libSources
resolvers/ScriptCommand_AllArtists.cpp
resolvers/ScriptCommand_AllAlbums.cpp
resolvers/ScriptCommand_AllTracks.cpp
resolvers/ScriptCommand_LookupUrl.cpp
resolvers/ScriptCommandQueue.cpp
resolvers/ScriptPluginFactory.cpp

# ScriptPlugins
resolvers/ScriptCollection.cpp
resolvers/plugins/ScriptCollectionFactory.cpp
resolvers/ScriptInfoPlugin.cpp
resolvers/plugins/ScriptInfoPluginFactory.cpp
resolvers/plugins/ScriptLinkParserPlugin.cpp
resolvers/plugins/ScriptLinkParserPluginFactory.cpp


sip/SipPlugin.cpp
sip/SipInfo.cpp
sip/PeerInfo.cpp
sip/SipStatusMessage.cpp

utils/UrlType.cpp
utils/Cloudstream.cpp
utils/Json.cpp
utils/TomahawkUtils.cpp
Expand Down
54 changes: 12 additions & 42 deletions src/libtomahawk/DropJob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Copyright 2011, Leo Franchi <[email protected]>
* Copyright 2011-2012, Jeff Mitchell <[email protected]>
* Copyright 2011-2012, Christian Muehlhaeuser <[email protected]>
* Copyright 2016, Dominik Schmidt <[email protected]>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -35,6 +36,7 @@
#include "utils/Logger.h"
#include "utils/TomahawkUtils.h"
#include "utils/XspfLoader.h"
#include "utils/LinkParser.h"

#include "Artist.h"
#include "Album.h"
Expand Down Expand Up @@ -172,12 +174,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
if ( url.contains( "grooveshark.com" ) && url.contains( "playlist" ) )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably remove this as well, as grooveshark is dead by now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough

return true;

// Check Scriptresolvers
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
{
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypePlaylist ) )
return true;
}
return Tomahawk::Utils::LinkParser::instance()->canParseUrl( url, Tomahawk::Utils::UrlTypePlaylist );
}

if ( acceptedType.testFlag( Track ) )
Expand All @@ -198,12 +195,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|| url.contains( "playlists" ) ) ) )
return true;

// Check Scriptresolvers
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
{
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeTrack ) )
return true;
}
return Tomahawk::Utils::LinkParser::instance()->canParseUrl( url, Tomahawk::Utils::UrlTypeTrack );
}

if ( acceptedType.testFlag( Album ) )
Expand All @@ -215,12 +207,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
if ( url.contains( "rdio.com" ) && ( url.contains( "artist" ) && url.contains( "album" ) && !url.contains( "track" ) ) )
return true;

// Check Scriptresolvers
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
{
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeAlbum ) )
return true;
}
return Tomahawk::Utils::LinkParser::instance()->canParseUrl( url, Tomahawk::Utils::UrlTypeAlbum );
}

if ( acceptedType.testFlag( Artist ) )
Expand All @@ -232,12 +219,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
if ( url.contains( "rdio.com" ) && ( url.contains( "artist" ) && !url.contains( "album" ) && !url.contains( "track" ) ) )
return true;

// Check Scriptresolvers
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
{
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeArtist ) )
return true;
}
return Tomahawk::Utils::LinkParser::instance()->canParseUrl( url, Tomahawk::Utils::UrlTypeArtist );
}

// We whitelist certain url-shorteners since they do some link checking. Often playable (e.g. spotify) links hide behind them,
Expand Down Expand Up @@ -303,15 +285,7 @@ DropJob::isDropType( DropJob::DropType desired, const QMimeData* data )
if ( ShortenedLinkParser::handlesUrl( url ) )
return true;

// Check Scriptresolvers
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
{
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypePlaylist ) )
{
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Accepting current drop as a playlist" << resolver->name();
return true;
}
}
return Tomahawk::Utils::LinkParser::instance()->canParseUrl( url, Tomahawk::Utils::UrlTypePlaylist );

}

Expand Down Expand Up @@ -761,16 +735,12 @@ DropJob::handleTrackUrls( const QString& urls )

foreach ( QString track, tracks )
{
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
QList< QSharedPointer< Utils::LinkParserPlugin > > parserPlugins = Utils::LinkParser::instance()->parserPluginsForUrl( track, Utils::UrlTypeAny );
if( !parserPlugins.isEmpty() )
{
if ( resolver->canParseUrl( track, ExternalResolver::UrlTypeAny ) )
{
ScriptCommand_LookupUrl* cmd = new ScriptCommand_LookupUrl( resolver, track );
connect( cmd, SIGNAL( information( QString, QSharedPointer<QObject> ) ), this, SLOT( informationForUrl( QString, QSharedPointer<QObject> ) ) );
cmd->enqueue();
m_queryCount++;
break;
}
Tomahawk::Utils::LinkParser::instance()->lookupUrl( track, parserPlugins );
connect( Tomahawk::Utils::LinkParser::instance(), SIGNAL( informationFound( QString, QSharedPointer<QObject> ) ), this, SLOT( informationForUrl( QString, QSharedPointer<QObject> ) ) );
m_queryCount++;
}
}
}
Expand Down
28 changes: 7 additions & 21 deletions src/libtomahawk/GlobalActionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Copyright (C) 2011-2014, Christian Muehlhaeuser <[email protected]>
* Copyright (C) 2013, Uwe L. Korn <[email protected]>
* Copyright (C) 2013, Teo Mrnjavac <[email protected]>
* Copyright (C) 2016, Dominik Schmidt <[email protected]>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -35,13 +36,13 @@
#include "playlist/TrackView.h"
#include "playlist/PlayableModel.h"
#include "resolvers/ExternalResolver.h"
#include "resolvers/ScriptCommand_LookupUrl.h"
#include "utils/JspfLoader.h"
#include "utils/Logger.h"
#include "utils/SpotifyParser.h"
#include "utils/XspfLoader.h"
#include "utils/XspfGenerator.h"
#include "viewpages/SearchViewPage.h"
#include "utils/LinkParser.h"

#include "Pipeline.h"
#include "TomahawkSettings.h"
Expand Down Expand Up @@ -162,27 +163,12 @@ GlobalActionManager::openUrl( const QString& url )
else if ( url.contains( "open.spotify.com" ) || url.startsWith( "spotify:" ) )
return openSpotifyLink( url );

// Can we parse the Url using a ScriptResolver?
bool canParse = false;
QList< QPointer< ExternalResolver > > possibleResolvers;
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
// Can we parse the Url using LinkParser?
QList< QSharedPointer< Utils::LinkParserPlugin > > parserPlugins = Utils::LinkParser::instance()->parserPluginsForUrl( url, Utils::UrlTypeAny );
if( !parserPlugins.isEmpty() )
{
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeAny ) )
{
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();
}

Tomahawk::Utils::LinkParser::instance()->lookupUrl( url, parserPlugins );
connect( Tomahawk::Utils::LinkParser::instance(), SIGNAL( informationFound( QString, QSharedPointer<QObject> ) ), this, SLOT( informationForUrl( QString, QSharedPointer<QObject> ) ), Qt::UniqueConnection );
return true;
}

Expand Down
17 changes: 15 additions & 2 deletions src/libtomahawk/accounts/spotify/SpotifyAccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,15 +842,28 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
const QString qid = msg.value( "qid" ).toString();
if ( m_qidToSlotMap.contains( qid ) )
{
QObject* receiver = m_qidToSlotMap[ qid ].first;
QPointer< QObject > receiver = m_qidToSlotMap[ qid ].first;
QString slot = m_qidToSlotMap[ qid ].second;
m_qidToSlotMap.remove( qid );


QVariant extraData;
if ( m_qidToExtraData.contains( qid ) )
extraData = m_qidToExtraData.take( qid );

QMetaObject::invokeMethod( receiver, slot.toLatin1(), Q_ARG( QString, msgType ), Q_ARG( QVariantMap, msg ), Q_ARG( QVariant, extraData ) );
// FIXME: SpotifyParser is sometimes a dangling pointer, haven't found a real way to reproduce: happens sometimes when dropping a playlist url onto the sidebar
//Q_ASSERT( !receiver.isNull() );

if ( !receiver.isNull() )
{
QMetaObject::invokeMethod( receiver, slot.toLatin1(), Q_ARG( QString, msgType ), Q_ARG( QVariantMap, msg ), Q_ARG( QVariant, extraData ) );
}
else
{
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage(
tr( "Spotify account could not finish action. Try again." )
) );
}
}
else if ( msgType == "allPlaylists" )
{
Expand Down
2 changes: 1 addition & 1 deletion src/libtomahawk/accounts/spotify/SpotifyAccount.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ private slots:
QPointer<ScriptResolver> m_spotifyResolver;
QPointer< InfoSystem::SpotifyInfoPlugin > m_infoPlugin;

QMap<QString, QPair<QObject*, QString> > m_qidToSlotMap;
QMap<QString, QPair< QPointer< QObject >, QString> > m_qidToSlotMap;
QMap<QString, QVariant > m_qidToExtraData;

// List of synced spotify playlists in config UI
Expand Down
32 changes: 3 additions & 29 deletions src/libtomahawk/resolvers/ExternalResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]>
* Copyright 2010-2011, Leo Franchi <[email protected]>
* Copyright 2013, Teo Mrnjavac <[email protected]>
* Copyright 2016, Dominik Schmidt <[email protected]>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -24,8 +25,6 @@
#include "Source.h"
#include "DllMacro.h"
#include "Resolver.h"
#include "ScriptCommandQueue.h"
#include "ScriptCommand_LookupUrl.h"
#include "Typedefs.h"

#include <QObject>
Expand All @@ -45,7 +44,6 @@ class DLLEXPORT ExternalResolver : public Resolver
{
Q_OBJECT

friend class ScriptCommandQueue;
friend class ScriptCommand_LookupUrl;

public:
Expand All @@ -61,26 +59,13 @@ Q_OBJECT
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
UrlLookup = 0x8 // can be queried for information on an Url
};
Q_DECLARE_FLAGS( Capabilities, Capability )
Q_FLAGS( Capabilities )

enum UrlType
{
UrlTypeAny = 0x00,
UrlTypePlaylist = 0x01,
UrlTypeTrack = 0x02,
UrlTypeAlbum = 0x04,
UrlTypeArtist = 0x08,
UrlTypeXspf = 0x10
};
Q_DECLARE_FLAGS( UrlTypes, UrlType )
Q_FLAGS( UrlTypes )

ExternalResolver( const QString& filePath )
: m_commandQueue( new ScriptCommandQueue( this ) )
{ m_filePath = filePath; }
: m_filePath( filePath )
{}

QString filePath() const { return m_filePath; }
virtual void setIcon( const QPixmap& ) {}
Expand All @@ -92,12 +77,6 @@ Q_OBJECT
virtual bool running() const = 0;
virtual Capabilities capabilities() const = 0;

// UrlLookup, sync call
virtual bool canParseUrl( const QString& url, UrlType type ) = 0;

virtual void enqueue( const QSharedPointer< ScriptCommand >& req )
{ m_commandQueue->enqueue( req ); }

public slots:
virtual void start() = 0;
virtual void stop() = 0;
Expand All @@ -112,11 +91,6 @@ public slots:

protected:
void setFilePath( const QString& path ) { m_filePath = path; }
ScriptCommandQueue* m_commandQueue;

// Should only be called by ScriptCommands
// UrlLookup
virtual void lookupUrl( const QString& url ) = 0;

private:
QString m_filePath;
Expand Down
Loading