mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-06 06:07:37 +02:00
Support (lazy) loading of XSPF Playlists through JSResolvers
This commit is contained in:
@@ -326,6 +326,7 @@ list(APPEND libSources
|
|||||||
|
|
||||||
playlist/PlaylistUpdaterInterface.cpp
|
playlist/PlaylistUpdaterInterface.cpp
|
||||||
playlist/PlaylistTemplate.cpp
|
playlist/PlaylistTemplate.cpp
|
||||||
|
playlist/XspfPlaylistTemplate.cpp
|
||||||
playlist/dynamic/DynamicPlaylist.cpp
|
playlist/dynamic/DynamicPlaylist.cpp
|
||||||
playlist/dynamic/GeneratorFactory.cpp
|
playlist/dynamic/GeneratorFactory.cpp
|
||||||
playlist/dynamic/GeneratorInterface.cpp
|
playlist/dynamic/GeneratorInterface.cpp
|
||||||
|
@@ -62,3 +62,9 @@ Tomahawk::PlaylistTemplate::tracks() const
|
|||||||
|
|
||||||
return d->queries;
|
return d->queries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tomahawk::PlaylistTemplate::PlaylistTemplate( Tomahawk::PlaylistTemplatePrivate* d )
|
||||||
|
: QObject( 0 )
|
||||||
|
, d_ptr( d )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@@ -16,6 +16,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 PLAYLISTTEMPLATE_H
|
#ifndef PLAYLISTTEMPLATE_H
|
||||||
#define PLAYLISTTEMPLATE_H
|
#define PLAYLISTTEMPLATE_H
|
||||||
|
|
||||||
@@ -43,11 +44,12 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Create or get the playlist for this template.
|
* Create or get the playlist for this template.
|
||||||
*/
|
*/
|
||||||
Tomahawk::playlist_ptr get();
|
virtual Tomahawk::playlist_ptr get();
|
||||||
|
|
||||||
QList<Tomahawk::query_ptr> tracks() const;
|
virtual QList<Tomahawk::query_ptr> tracks() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
PlaylistTemplate( PlaylistTemplatePrivate* d );
|
||||||
PlaylistTemplatePrivate* d_ptr;
|
PlaylistTemplatePrivate* d_ptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -56,4 +58,6 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE( QSharedPointer< Tomahawk::PlaylistTemplate > )
|
||||||
|
|
||||||
#endif // PLAYLISTTEMPLATE_H
|
#endif // PLAYLISTTEMPLATE_H
|
||||||
|
@@ -52,7 +52,7 @@ public:
|
|||||||
Q_DECLARE_PUBLIC( PlaylistTemplate )
|
Q_DECLARE_PUBLIC( PlaylistTemplate )
|
||||||
PlaylistTemplate* q_ptr;
|
PlaylistTemplate* q_ptr;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
source_ptr author;
|
source_ptr author;
|
||||||
QString guid;
|
QString guid;
|
||||||
QString title;
|
QString title;
|
||||||
@@ -65,6 +65,4 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECLARE_METATYPE( QSharedPointer< Tomahawk::PlaylistTemplate > )
|
|
||||||
|
|
||||||
#endif // PLAYLISTTEMPLATE_P_H
|
#endif // PLAYLISTTEMPLATE_P_H
|
||||||
|
47
src/libtomahawk/playlist/XspfPlaylistTemplate.cpp
Normal file
47
src/libtomahawk/playlist/XspfPlaylistTemplate.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include "XspfPlaylistTemplate_p.h"
|
||||||
|
|
||||||
|
namespace Tomahawk {
|
||||||
|
|
||||||
|
XspfPlaylistTemplate::XspfPlaylistTemplate( const QString& _url, const source_ptr& source, const QString& guid )
|
||||||
|
: PlaylistTemplate( new XspfPlaylistTemplatePrivate( this, _url, source, guid ) )
|
||||||
|
{
|
||||||
|
Q_D( XspfPlaylistTemplate );
|
||||||
|
|
||||||
|
connect( d->xspfLoader.data(), SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ),
|
||||||
|
SLOT( xspfTracksLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XspfPlaylistTemplate::~XspfPlaylistTemplate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
playlist_ptr XspfPlaylistTemplate::get()
|
||||||
|
{
|
||||||
|
Q_D( XspfPlaylistTemplate );
|
||||||
|
|
||||||
|
return d->xspfLoader->getPlaylistForRecentUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
XspfPlaylistTemplate::load()
|
||||||
|
{
|
||||||
|
Q_D( XspfPlaylistTemplate );
|
||||||
|
|
||||||
|
d->xspfLoader->load( d->url );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
XspfPlaylistTemplate::xspfTracksLoaded( const QList< Tomahawk::query_ptr >& tracks )
|
||||||
|
{
|
||||||
|
Q_D( XspfPlaylistTemplate );
|
||||||
|
|
||||||
|
d->queries = tracks;
|
||||||
|
emit tracksLoaded( tracks );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Tomahawk
|
65
src/libtomahawk/playlist/XspfPlaylistTemplate.h
Normal file
65
src/libtomahawk/playlist/XspfPlaylistTemplate.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/* === 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef TOMAHAWK_XSPFPLAYLISTTEMPLATE_H
|
||||||
|
#define TOMAHAWK_XSPFPLAYLISTTEMPLATE_H
|
||||||
|
|
||||||
|
#include "playlist/PlaylistTemplate.h"
|
||||||
|
|
||||||
|
namespace Tomahawk {
|
||||||
|
|
||||||
|
class XspfPlaylistTemplatePrivate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PlaylistTemplate for loading XSPF playlists.
|
||||||
|
*
|
||||||
|
* Be aware that get() should only be called after tracksLoaded was emitted.
|
||||||
|
* Functions using this class that they handover this class
|
||||||
|
* to other functions which work only on PlaylistTemplates should ensure
|
||||||
|
* that tracksLoaded was emitted BEFORE passing on an object of this class.
|
||||||
|
*/
|
||||||
|
class XspfPlaylistTemplate : public Tomahawk::PlaylistTemplate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
XspfPlaylistTemplate( const QString& _url, const source_ptr& source, const QString& guid );
|
||||||
|
virtual ~XspfPlaylistTemplate();
|
||||||
|
|
||||||
|
virtual Tomahawk::playlist_ptr get();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the XSPF and load all tracks.
|
||||||
|
*
|
||||||
|
* When loading is done, tracksLoaded will be emitted.
|
||||||
|
*/
|
||||||
|
void load();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void tracksLoaded( const QList< Tomahawk::query_ptr >& tracks );
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void xspfTracksLoaded( const QList< Tomahawk::query_ptr >& tracks );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DECLARE_PRIVATE( XspfPlaylistTemplate )
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Tomahawk
|
||||||
|
|
||||||
|
#endif // TOMAHAWK_XSPFPLAYLISTTEMPLATE_H
|
49
src/libtomahawk/playlist/XspfPlaylistTemplate_p.h
Normal file
49
src/libtomahawk/playlist/XspfPlaylistTemplate_p.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* === 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef XSPFPLAYLISTTEMPLATE_P_H
|
||||||
|
#define XSPFPLAYLISTTEMPLATE_P_H
|
||||||
|
|
||||||
|
#include "playlist/PlaylistTemplate_p.h"
|
||||||
|
#include "playlist/XspfPlaylistTemplate.h"
|
||||||
|
#include "utils/XspfLoader.h"
|
||||||
|
|
||||||
|
namespace Tomahawk
|
||||||
|
{
|
||||||
|
|
||||||
|
class XspfPlaylistTemplatePrivate: public PlaylistTemplatePrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XspfPlaylistTemplatePrivate( XspfPlaylistTemplate* q, const QString& _url, const source_ptr& source, const QString& guid )
|
||||||
|
: PlaylistTemplatePrivate( q, source, guid, QString(), QString(), QString(), false, QList<query_ptr>() )
|
||||||
|
, url( _url )
|
||||||
|
, xspfLoader( new XSPFLoader( false, true, 0, guid ) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_PUBLIC( XspfPlaylistTemplate )
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString url;
|
||||||
|
QSharedPointer<XSPFLoader> xspfLoader;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Tomahawk
|
||||||
|
|
||||||
|
#endif // XSPFPLAYLISTTEMPLATE_P_H
|
@@ -24,10 +24,12 @@
|
|||||||
#include "database/Database.h"
|
#include "database/Database.h"
|
||||||
#include "database/DatabaseImpl.h"
|
#include "database/DatabaseImpl.h"
|
||||||
#include "playlist/PlaylistTemplate.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/Logger.h"
|
#include "utils/Closure.h"
|
||||||
#include "utils/NetworkAccessManager.h"
|
#include "utils/NetworkAccessManager.h"
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "JSResolver_p.h"
|
#include "JSResolver_p.h"
|
||||||
@@ -324,6 +326,33 @@ JSResolverHelper::addUrlResult( const QString& url, const QVariantMap& result )
|
|||||||
playlisttemplate_ptr pltemplate( new PlaylistTemplate( source, guid, title, info, creator, false, queries ) );
|
playlisttemplate_ptr pltemplate( new PlaylistTemplate( source, guid, title, info, creator, false, queries ) );
|
||||||
emit m_resolver->informationFound( url, pltemplate.objectCast<QObject>() );
|
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( Tomahawk::Database::instance()->impl()->dbid() );
|
||||||
|
|
||||||
|
// 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
|
else
|
||||||
{
|
{
|
||||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << m_resolver->name() << "No usable information found for " << url;
|
tLog( LOGVERBOSE ) << Q_FUNC_INFO << m_resolver->name() << "No usable information found for " << url;
|
||||||
@@ -360,6 +389,14 @@ JSResolverHelper::tracksAdded( const QList<query_ptr>&, const ModelMode, const c
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 )
|
||||||
{
|
{
|
||||||
|
@@ -76,6 +76,7 @@ public slots:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::ModelMode, const Tomahawk::collection_ptr& collection );
|
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 );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Tomahawk::query_ptr parseTrack( const QVariantMap& track );
|
Tomahawk::query_ptr parseTrack( const QVariantMap& track );
|
||||||
|
@@ -59,15 +59,21 @@ XSPFLoader::errorToString( XSPFErrorCode error )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XSPFLoader::XSPFLoader( bool autoCreate, bool autoUpdate, QObject* parent )
|
XSPFLoader::XSPFLoader( bool autoCreate, bool autoUpdate, QObject* parent, const QString& guid )
|
||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
, m_autoCreate( autoCreate )
|
, m_autoCreate( autoCreate )
|
||||||
, m_autoUpdate( autoUpdate )
|
, m_autoUpdate( autoUpdate )
|
||||||
, m_autoResolve( true )
|
, m_autoResolve( true )
|
||||||
, m_autoDelete( true )
|
, m_autoDelete( true )
|
||||||
|
, m_guid( guid )
|
||||||
, m_NS( "http://xspf.org/ns/0/" )
|
, m_NS( "http://xspf.org/ns/0/" )
|
||||||
{
|
{
|
||||||
qRegisterMetaType< XSPFErrorCode >("XSPFErrorCode");
|
qRegisterMetaType< XSPFErrorCode >("XSPFErrorCode");
|
||||||
|
|
||||||
|
if ( m_guid.isEmpty() )
|
||||||
|
{
|
||||||
|
m_guid = uuid();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -117,6 +123,22 @@ XSPFLoader::title() const
|
|||||||
return m_title;
|
return m_title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playlist_ptr XSPFLoader::getPlaylistForRecentUrl()
|
||||||
|
{
|
||||||
|
m_playlist = Playlist::create( SourceList::instance()->getLocal(),
|
||||||
|
m_guid,
|
||||||
|
m_title,
|
||||||
|
m_info,
|
||||||
|
m_creator,
|
||||||
|
false,
|
||||||
|
m_entries );
|
||||||
|
|
||||||
|
// 10 minute default---for now, no way to change it
|
||||||
|
new Tomahawk::XspfUpdater( m_playlist, 600000, m_autoUpdate, m_url.toString() );
|
||||||
|
|
||||||
|
return m_playlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
XSPFLoader::load( const QUrl& url )
|
XSPFLoader::load( const QUrl& url )
|
||||||
@@ -302,17 +324,7 @@ XSPFLoader::gotBody()
|
|||||||
|
|
||||||
if ( m_autoCreate )
|
if ( m_autoCreate )
|
||||||
{
|
{
|
||||||
m_playlist = Playlist::create( SourceList::instance()->getLocal(),
|
emit ok( getPlaylistForRecentUrl() );
|
||||||
uuid(),
|
|
||||||
m_title,
|
|
||||||
m_info,
|
|
||||||
m_creator,
|
|
||||||
false,
|
|
||||||
m_entries );
|
|
||||||
|
|
||||||
// 10 minute default---for now, no way to change it
|
|
||||||
new Tomahawk::XspfUpdater( m_playlist, 600000, m_autoUpdate, m_url.toString() );
|
|
||||||
emit ok( m_playlist );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -37,12 +37,16 @@ Q_OBJECT
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum XSPFErrorCode { ParseError, InvalidTrackError, FetchError };
|
enum XSPFErrorCode { ParseError, InvalidTrackError, FetchError };
|
||||||
explicit XSPFLoader( bool autoCreate = true, bool autoUpdate = false, QObject* parent = 0 );
|
explicit XSPFLoader( bool autoCreate = true, bool autoUpdate = false, QObject* parent = 0, const QString& guid = QString() );
|
||||||
|
|
||||||
virtual ~XSPFLoader();
|
virtual ~XSPFLoader();
|
||||||
QList< Tomahawk::query_ptr > entries() const;
|
QList< Tomahawk::query_ptr > entries() const;
|
||||||
QString title() const;
|
QString title() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the playlist for the most recent parsed XSPF url.
|
||||||
|
*/
|
||||||
|
Tomahawk::playlist_ptr getPlaylistForRecentUrl();
|
||||||
void setOverrideTitle( const QString& newTitle );
|
void setOverrideTitle( const QString& newTitle );
|
||||||
void setAutoResolveTracks( bool autoResolve );
|
void setAutoResolveTracks( bool autoResolve );
|
||||||
void setAutoDelete( bool autoDelete );
|
void setAutoDelete( bool autoDelete );
|
||||||
@@ -69,6 +73,7 @@ private:
|
|||||||
void gotBody();
|
void gotBody();
|
||||||
|
|
||||||
bool m_autoCreate, m_autoUpdate, m_autoResolve, m_autoDelete;
|
bool m_autoCreate, m_autoUpdate, m_autoResolve, m_autoDelete;
|
||||||
|
QString m_guid;
|
||||||
QString m_NS,m_overrideTitle;
|
QString m_NS,m_overrideTitle;
|
||||||
QList< Tomahawk::query_ptr > m_entries;
|
QList< Tomahawk::query_ptr > m_entries;
|
||||||
QString m_title, m_info, m_creator, m_errorTitle;
|
QString m_title, m_info, m_creator, m_errorTitle;
|
||||||
|
Reference in New Issue
Block a user