Load local files from the DB if we already have them.

This commit is contained in:
John Maguire 2010-08-31 19:45:33 +00:00
parent bf5245d499
commit ad16a8b1ba
8 changed files with 70 additions and 37 deletions

View File

@ -16,6 +16,8 @@
#include "songloader.h"
#include "core/song.h"
#include "library/librarybackend.h"
#include "library/sqlrow.h"
#include "playlistparsers/parserbase.h"
#include "playlistparsers/playlistparser.h"
#include "radio/fixlastfm.h"
@ -32,14 +34,15 @@
QSet<QString> SongLoader::sRawUriSchemes;
const int SongLoader::kDefaultTimeout = 5000;
SongLoader::SongLoader(QObject *parent)
SongLoader::SongLoader(LibraryBackend* library, QObject *parent)
: QObject(parent),
timeout_timer_(new QTimer(this)),
playlist_parser_(new PlaylistParser(this)),
timeout_(kDefaultTimeout),
state_(WaitingForType),
success_(false),
parser_(NULL)
parser_(NULL),
library_(library)
{
if (sRawUriSchemes.isEmpty()) {
sRawUriSchemes << "udp" << "mms" << "mmsh" << "mmst" << "mmsu" << "rtsp"
@ -66,7 +69,7 @@ SongLoader::Result SongLoader::Load(const QUrl& url) {
url_ = url;
if (url_.scheme() == "file") {
return LoadLocal();
return LoadLocal(url_.toLocalFile());
}
if (sRawUriSchemes.contains(url_.scheme())) {
@ -87,15 +90,19 @@ SongLoader::Result SongLoader::Load(const QUrl& url) {
#endif
}
SongLoader::Result SongLoader::LoadLocal() {
qDebug() << "Loading local file" << url_;
SongLoader::Result SongLoader::LoadLocal(const QString& filename, bool block) {
qDebug() << "Loading local file" << filename;
// First check to see if it's a directory - if so we can load all the songs
// inside right away.
QString filename = url_.toLocalFile();
if (QFileInfo(filename).isDir()) {
QtConcurrent::run(this, &SongLoader::LoadLocalDirectory, filename);
return WillLoadAsync;
if (!block) {
QtConcurrent::run(this, &SongLoader::LoadLocalDirectory, filename);
return WillLoadAsync;
} else {
LoadLocalDirectory(filename);
return Success;
}
}
// It's a local file, so check if it looks like a playlist.
@ -116,13 +123,27 @@ SongLoader::Result SongLoader::LoadLocal() {
qDebug() << "Parsing using" << parser->name();
// It's a playlist!
QtConcurrent::run(this, &SongLoader::LoadPlaylist, parser, filename);
return WillLoadAsync;
if (!block) {
QtConcurrent::run(this, &SongLoader::LoadPlaylist, parser, filename);
return WillLoadAsync;
} else {
LoadPlaylist(parser, filename);
return Success;
}
}
// Not a playlist, so just assume it's a song
QFileInfo info(filename);
LibraryQuery query;
query.SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec);
query.AddWhere("filename", info.canonicalFilePath());
Song song;
song.InitFromFile(filename, -1);
if (library_->ExecQuery(&query) && query.Next()) {
qDebug() << "Found it in db!";
song.InitFromQuery(query);
} else {
song.InitFromFile(filename, -1);
}
if (song.is_valid())
songs_ << song;
return Success;
@ -151,11 +172,8 @@ void SongLoader::LoadLocalDirectory(const QString& filename) {
QDirIterator::Subdirectories);
while (it.hasNext()) {
QString path = it.next();
Song song;
song.InitFromFile(path, -1);
if (song.is_valid())
songs_ << song;
// This is in another thread so we can do blocking calls.
LoadLocal(filename, true);
}
qStableSort(songs_.begin(), songs_.end(), CompareSongs);

View File

@ -29,13 +29,14 @@
# include <gst/gst.h>
#endif
class LibraryBackend;
class ParserBase;
class PlaylistParser;
class SongLoader : public QObject {
Q_OBJECT
public:
SongLoader(QObject* parent = 0);
SongLoader(LibraryBackend* library, QObject* parent = 0);
~SongLoader();
enum Result {
@ -69,7 +70,7 @@ private:
Finished,
};
Result LoadLocal();
Result LoadLocal(const QString& filename, bool block = false);
void LoadLocalDirectory(const QString& filename);
void LoadPlaylist(ParserBase* parser, const QString& filename);
@ -106,6 +107,7 @@ private:
ParserBase* parser_;
QString mime_type_;
QByteArray buffer_;
LibraryBackend* library_;
#ifdef HAVE_GSTREAMER
boost::shared_ptr<GstElement> pipeline_;

View File

@ -51,13 +51,17 @@ using boost::shared_ptr;
const char* Playlist::kRowsMimetype = "application/x-clementine-playlist-rows";
const char* Playlist::kPlayNowMimetype = "application/x-clementine-play-now";
Playlist::Playlist(PlaylistBackend* backend, TaskManager* task_manager,
int id, QObject *parent)
Playlist::Playlist(PlaylistBackend* backend,
TaskManager* task_manager,
LibraryBackend* library,
int id,
QObject *parent)
: QAbstractListModel(parent),
proxy_(new PlaylistFilter(this)),
queue_(new Queue(this)),
backend_(backend),
task_manager_(task_manager),
library_(library),
id_(id),
current_is_paused_(false),
current_virtual_index_(-1),
@ -554,7 +558,7 @@ bool Playlist::dropMimeData(const QMimeData* data, Qt::DropAction action, int ro
}
void Playlist::InsertUrls(const QList<QUrl> &urls, bool play_now, int pos) {
SongLoaderInserter* inserter = new SongLoaderInserter(task_manager_, this);
SongLoaderInserter* inserter = new SongLoaderInserter(task_manager_, library_, this);
connect(inserter, SIGNAL(Error(QString)), SIGNAL(LoadTracksError(QString)));
connect(inserter, SIGNAL(PlayRequested(QModelIndex)), SIGNAL(PlayRequested(QModelIndex)));

View File

@ -27,10 +27,11 @@
#include "core/song.h"
#include "radio/radioitem.h"
class RadioService;
class LibraryBackend;
class PlaylistBackend;
class PlaylistFilter;
class Queue;
class RadioService;
class TaskManager;
class QSortFilterProxyModel;
@ -50,7 +51,10 @@ class Playlist : public QAbstractListModel {
friend class PlaylistUndoCommands::MoveItems;
public:
Playlist(PlaylistBackend* backend, TaskManager* task_manager, int id,
Playlist(PlaylistBackend* backend,
TaskManager* task_manager,
LibraryBackend* library,
int id,
QObject* parent = 0);
~Playlist();
@ -214,6 +218,7 @@ class Playlist : public QAbstractListModel {
PlaylistBackend* backend_;
TaskManager* task_manager_;
LibraryBackend* library_;
int id_;
PlaylistItemList items_;

View File

@ -63,7 +63,7 @@ void PlaylistManager::Init(LibraryBackend* library_backend,
}
Playlist* PlaylistManager::AddPlaylist(int id, const QString& name) {
Playlist* ret = new Playlist(playlist_backend_, task_manager_, id);
Playlist* ret = new Playlist(playlist_backend_, task_manager_, library_backend_, id);
ret->set_sequence(sequence_);
connect(ret, SIGNAL(CurrentSongChanged(Song)), SIGNAL(CurrentSongChanged(Song)));
@ -101,7 +101,7 @@ void PlaylistManager::New(const QString& name, const SongList& songs) {
void PlaylistManager::Load(const QString& filename) {
QUrl url = QUrl::fromLocalFile(filename);
SongLoader* loader = new SongLoader(this);
SongLoader* loader = new SongLoader(library_backend_, this);
connect(loader, SIGNAL(LoadFinished(bool)), SLOT(LoadFinished(bool)));
SongLoader::Result result = loader->Load(url);
QFileInfo info(filename);

View File

@ -19,15 +19,16 @@
#include "core/songloader.h"
#include "core/taskmanager.h"
SongLoaderInserter::SongLoaderInserter(TaskManager* task_manager, QObject *parent)
: QObject(parent),
task_manager_(task_manager),
destination_(NULL),
row_(-1),
play_now_(true),
async_load_id_(0),
async_progress_(0)
{
SongLoaderInserter::SongLoaderInserter(
TaskManager* task_manager, LibraryBackend* library, QObject *parent)
: QObject(parent),
task_manager_(task_manager),
destination_(NULL),
row_(-1),
play_now_(true),
async_load_id_(0),
async_progress_(0),
library_(library) {
}
SongLoaderInserter::~SongLoaderInserter() {
@ -41,7 +42,7 @@ void SongLoaderInserter::Load(Playlist *destination, int row, bool play_now,
play_now_ = play_now;
foreach (const QUrl& url, urls) {
SongLoader* loader = new SongLoader(this);
SongLoader* loader = new SongLoader(library_, this);
SongLoader::Result ret = loader->Load(url);
if (ret == SongLoader::WillLoadAsync) {

View File

@ -23,6 +23,7 @@
#include "core/song.h"
class LibraryBackend;
class Playlist;
class SongLoader;
class TaskManager;
@ -32,7 +33,7 @@ class QModelIndex;
class SongLoaderInserter : public QObject {
Q_OBJECT
public:
SongLoaderInserter(TaskManager* task_manager, QObject* parent = 0);
SongLoaderInserter(TaskManager* task_manager, LibraryBackend* library, QObject* parent = 0);
~SongLoaderInserter();
void Load(Playlist* destination, int row, bool play_now, const QList<QUrl>& urls);
@ -59,6 +60,7 @@ private:
QSet<SongLoader*> pending_;
int async_load_id_;
int async_progress_;
LibraryBackend* library_;
};
#endif // SONGLOADERINSERTER_H

View File

@ -627,7 +627,8 @@ void MainWindow::AddFilesToPlaylist(bool clear_first, const QList<QUrl>& urls) {
}
void MainWindow::AddUrls(bool play_now, const QList<QUrl> &urls) {
SongLoaderInserter* inserter = new SongLoaderInserter(task_manager_, this);
SongLoaderInserter* inserter =
new SongLoaderInserter(task_manager_, library_->backend(), this);
connect(inserter, SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
connect(inserter, SIGNAL(PlayRequested(QModelIndex)), SLOT(PlayIndex(QModelIndex)));