1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-02-26 12:53:41 +01:00

Support (lazy) loading of XSPF Playlists through JSResolvers

This commit is contained in:
Uwe L. Korn 2013-07-28 12:32:43 +02:00
parent 8cf2f38896
commit 832305008b
11 changed files with 244 additions and 19 deletions

View File

@ -326,6 +326,7 @@ list(APPEND libSources
playlist/PlaylistUpdaterInterface.cpp
playlist/PlaylistTemplate.cpp
playlist/XspfPlaylistTemplate.cpp
playlist/dynamic/DynamicPlaylist.cpp
playlist/dynamic/GeneratorFactory.cpp
playlist/dynamic/GeneratorInterface.cpp

View File

@ -62,3 +62,9 @@ Tomahawk::PlaylistTemplate::tracks() const
return d->queries;
}
Tomahawk::PlaylistTemplate::PlaylistTemplate( Tomahawk::PlaylistTemplatePrivate* d )
: QObject( 0 )
, d_ptr( d )
{
}

View File

@ -16,6 +16,7 @@
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef PLAYLISTTEMPLATE_H
#define PLAYLISTTEMPLATE_H
@ -43,11 +44,12 @@ public:
/**
* 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:
PlaylistTemplate( PlaylistTemplatePrivate* d );
PlaylistTemplatePrivate* d_ptr;
private:
@ -56,4 +58,6 @@ private:
}
Q_DECLARE_METATYPE( QSharedPointer< Tomahawk::PlaylistTemplate > )
#endif // PLAYLISTTEMPLATE_H

View File

@ -52,7 +52,7 @@ public:
Q_DECLARE_PUBLIC( PlaylistTemplate )
PlaylistTemplate* q_ptr;
private:
protected:
source_ptr author;
QString guid;
QString title;
@ -65,6 +65,4 @@ private:
}
Q_DECLARE_METATYPE( QSharedPointer< Tomahawk::PlaylistTemplate > )
#endif // PLAYLISTTEMPLATE_P_H

View 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

View 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

View 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

View File

@ -24,10 +24,12 @@
#include "database/Database.h"
#include "database/DatabaseImpl.h"
#include "playlist/PlaylistTemplate.h"
#include "playlist/XspfPlaylistTemplate.h"
#include "resolvers/ScriptEngine.h"
#include "network/Servent.h"
#include "utils/Logger.h"
#include "utils/Closure.h"
#include "utils/NetworkAccessManager.h"
#include "utils/Logger.h"
#include "config.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 ) );
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
{
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
JSResolverHelper::setResolverConfig( const QVariantMap& config )
{

View File

@ -76,6 +76,7 @@ public slots:
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 );
private:
Tomahawk::query_ptr parseTrack( const QVariantMap& track );

View File

@ -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 )
, m_autoCreate( autoCreate )
, m_autoUpdate( autoUpdate )
, m_autoResolve( true )
, m_autoDelete( true )
, m_guid( guid )
, m_NS( "http://xspf.org/ns/0/" )
{
qRegisterMetaType< XSPFErrorCode >("XSPFErrorCode");
if ( m_guid.isEmpty() )
{
m_guid = uuid();
}
}
@ -117,6 +123,22 @@ XSPFLoader::title() const
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
XSPFLoader::load( const QUrl& url )
@ -302,17 +324,7 @@ XSPFLoader::gotBody()
if ( m_autoCreate )
{
m_playlist = Playlist::create( SourceList::instance()->getLocal(),
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 );
emit ok( getPlaylistForRecentUrl() );
}
else
{

View File

@ -37,12 +37,16 @@ Q_OBJECT
public:
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();
QList< Tomahawk::query_ptr > entries() const;
QString title() const;
/**
* Get the playlist for the most recent parsed XSPF url.
*/
Tomahawk::playlist_ptr getPlaylistForRecentUrl();
void setOverrideTitle( const QString& newTitle );
void setAutoResolveTracks( bool autoResolve );
void setAutoDelete( bool autoDelete );
@ -69,6 +73,7 @@ private:
void gotBody();
bool m_autoCreate, m_autoUpdate, m_autoResolve, m_autoDelete;
QString m_guid;
QString m_NS,m_overrideTitle;
QList< Tomahawk::query_ptr > m_entries;
QString m_title, m_info, m_creator, m_errorTitle;