Basic working use of resolvers for XSPF playlists.

This commit is contained in:
John Maguire 2011-07-28 17:33:58 +02:00
parent 8091f9d1cd
commit 2bda4966fc
6 changed files with 98 additions and 3 deletions

View File

@ -191,6 +191,7 @@ set(SOURCES
playlistparsers/xspfparser.cpp
resolvers/libraryresolver.cpp
resolvers/songresolver.cpp
smartplaylists/generator.cpp
smartplaylists/generatorinserter.cpp
@ -402,6 +403,7 @@ set(HEADERS
resolvers/libraryresolver.h
resolvers/resolver.h
resolvers/songresolver.h
smartplaylists/generator.h
smartplaylists/generatorinserter.h

View File

@ -19,6 +19,7 @@
#include "library/librarybackend.h"
#include "library/libraryquery.h"
#include "library/sqlrow.h"
#include "resolvers/songresolver.h"
#include <QUrl>
@ -31,6 +32,9 @@ ParserBase::ParserBase(LibraryBackendInterface* library, QObject *parent)
void ParserBase::LoadSong(const QString& filename_or_url, qint64 beginning,
const QDir& dir, Song* song) const {
if (filename_or_url.isEmpty()) {
// Try and resolve from various sources.
SongResolver resolver(library_);
resolver.ResolveSong(song);
return;
}

View File

@ -90,13 +90,13 @@ Song XSPFParser::ParseTrack(QXmlStreamReader* reader, const QDir& dir) const {
}
return_song:
Song song = LoadSong(location, 0, dir);
// Override metadata with what was in the playlist
Song song;
song.set_title(title);
song.set_artist(artist);
song.set_album(album);
song.set_length_nanosec(nanosec);
LoadSong(location, 0, dir, &song);
return song;
}

View File

@ -22,6 +22,7 @@ int LibraryResolver::ResolveSong(const Song& song) {
LibraryQuery* query = new LibraryQuery;
query->AddWhere("artist", song.artist());
query->AddWhere("title", song.title());
query->SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec);
QFuture<bool> future = QtConcurrent::run(
backend_, &LibraryBackendInterface::ExecQuery, query);

View File

@ -0,0 +1,51 @@
#include "songresolver.h"
#include "core/logging.h"
#include "core/song.h"
#include "internet/internetmodel.h"
#include "internet/spotifyservice.h"
#include "libraryresolver.h"
#include "spotifyresolver.h"
SongResolver::SongResolver(LibraryBackendInterface* library, QObject* parent)
: QObject(parent),
song_(NULL),
resolvers_finished_(0),
resolved_(false) {
// Register in the other they should be checked.
RegisterResolver(new LibraryResolver(library));
RegisterResolver(new SpotifyResolver(InternetModel::Service<SpotifyService>()->server()));
}
SongResolver::~SongResolver() {
qDeleteAll(resolvers_);
resolvers_.clear();
}
void SongResolver::RegisterResolver(Resolver* resolver) {
resolvers_ << resolver;
connect(resolver, SIGNAL(ResolveFinished(int, SongList)), SLOT(ResolveFinished(int, SongList)));
}
bool SongResolver::ResolveSong(Song* song) {
song_ = song;
foreach (Resolver* resolver, resolvers_) {
resolver->ResolveSong(*song);
}
loop_.exec();
return resolved_;
}
void SongResolver::ResolveFinished(int, SongList resolved_songs) {
++resolvers_finished_;
if (resolvers_finished_ == resolvers_.size()) {
loop_.quit();
}
if (!resolved_songs.isEmpty()) {
*song_ = resolved_songs.first();
qLog(Debug) << "Resolved song:" << song_->title() << "from:" << sender()->metaObject()->className();
resolved_ = true;
loop_.quit();
}
}

View File

@ -0,0 +1,37 @@
#ifndef SONGRESOLVER_H
#define SONGRESOLVER_H
#include <QEventLoop>
#include <QList>
#include <QObject>
#include "core/song.h"
class LibraryBackendInterface;
class Resolver;
class SongResolver : public QObject {
Q_OBJECT
public:
SongResolver(LibraryBackendInterface* library, QObject* parent = 0);
virtual ~SongResolver();
// Blocking
bool ResolveSong(Song* song);
private slots:
void ResolveFinished(int, SongList resolved_songs);
private:
void RegisterResolver(Resolver* resolver);
QList<Resolver*> resolvers_;
Song* song_;
QEventLoop loop_;
int resolvers_finished_;
bool resolved_;
};
#endif