Add almost-working support for writing to ipods
This commit is contained in:
parent
a99afd75ff
commit
b624be9800
|
@ -30,9 +30,11 @@ public:
|
||||||
|
|
||||||
virtual QString LocalPath() const { return QString(); }
|
virtual QString LocalPath() const { return QString(); }
|
||||||
|
|
||||||
|
virtual void StartCopy() {}
|
||||||
virtual bool CopyToStorage(const QString& source, const QString& destination,
|
virtual bool CopyToStorage(const QString& source, const QString& destination,
|
||||||
const Song& metadata, bool overwrite,
|
const Song& metadata, bool overwrite,
|
||||||
bool remove_original) = 0;
|
bool remove_original) = 0;
|
||||||
|
virtual void FinishCopy() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(MusicStorage*);
|
Q_DECLARE_METATYPE(MusicStorage*);
|
||||||
|
|
|
@ -35,6 +35,7 @@ Organise::Organise(TaskManager* task_manager, MusicStorage* destination,
|
||||||
copy_(copy),
|
copy_(copy),
|
||||||
overwrite_(overwrite),
|
overwrite_(overwrite),
|
||||||
files_(files),
|
files_(files),
|
||||||
|
started_(false),
|
||||||
task_id_(0),
|
task_id_(0),
|
||||||
progress_(0)
|
progress_(0)
|
||||||
{
|
{
|
||||||
|
@ -56,8 +57,15 @@ void Organise::Start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Organise::ProcessSomeFiles() {
|
void Organise::ProcessSomeFiles() {
|
||||||
|
if (!started_) {
|
||||||
|
destination_->StartCopy();
|
||||||
|
started_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
// None left?
|
// None left?
|
||||||
if (progress_ >= files_.count()) {
|
if (progress_ >= files_.count()) {
|
||||||
|
destination_->FinishCopy();
|
||||||
|
|
||||||
task_manager_->SetTaskFinished(task_id_);
|
task_manager_->SetTaskFinished(task_id_);
|
||||||
|
|
||||||
// Move back to the original thread so deleteLater() can get called in
|
// Move back to the original thread so deleteLater() can get called in
|
||||||
|
|
|
@ -50,6 +50,8 @@ private:
|
||||||
const bool overwrite_;
|
const bool overwrite_;
|
||||||
QStringList files_;
|
QStringList files_;
|
||||||
|
|
||||||
|
bool started_;
|
||||||
|
|
||||||
int task_id_;
|
int task_id_;
|
||||||
int progress_;
|
int progress_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -562,6 +562,38 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
||||||
d->filename_ = QString::fromLocal8Bit(track->ipod_path);
|
d->filename_ = QString::fromLocal8Bit(track->ipod_path);
|
||||||
d->basefilename_ = QFileInfo(d->filename_).fileName();
|
d->basefilename_ = QFileInfo(d->filename_).fileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CopyStr(const QString& str, gchar** dest_p) {
|
||||||
|
Q_ASSERT(*dest_p == NULL);
|
||||||
|
const QByteArray data = str.toUtf8();
|
||||||
|
const int size = data.size() + 1;
|
||||||
|
|
||||||
|
gchar* dest = new gchar[size];
|
||||||
|
std::copy(data.constData(), data.constData() + size, dest);
|
||||||
|
*dest_p = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::ToItdb(Itdb_Track *track) const {
|
||||||
|
CopyStr(d->title_, &track->title);
|
||||||
|
CopyStr(d->album_, &track->album);
|
||||||
|
CopyStr(d->artist_, &track->artist);
|
||||||
|
CopyStr(d->albumartist_, &track->albumartist);
|
||||||
|
CopyStr(d->composer_, &track->composer);
|
||||||
|
track->track_nr = d->track_;
|
||||||
|
track->cd_nr = d->disc_;
|
||||||
|
track->BPM = d->bpm_;
|
||||||
|
track->year = d->year_;
|
||||||
|
CopyStr(d->genre_, &track->genre);
|
||||||
|
CopyStr(d->comment_, &track->comment);
|
||||||
|
track->compilation = d->compilation_;
|
||||||
|
track->tracklen = d->length_ * 1000;
|
||||||
|
track->bitrate = d->bitrate_;
|
||||||
|
track->samplerate = d->samplerate_;
|
||||||
|
track->time_modified = d->mtime_;
|
||||||
|
track->time_added = d->ctime_;
|
||||||
|
track->size = d->filesize_;
|
||||||
|
track->type2 = d->filetype_ == Type_Mp4 ? 0 : 1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Song::MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle) {
|
void Song::MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle) {
|
||||||
|
|
|
@ -128,6 +128,7 @@ class Song {
|
||||||
|
|
||||||
#ifdef HAVE_LIBGPOD
|
#ifdef HAVE_LIBGPOD
|
||||||
void InitFromItdb(Itdb_Track* track);
|
void InitFromItdb(Itdb_Track* track);
|
||||||
|
void ToItdb(Itdb_Track* track) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static QString Decode(const TagLib::String& tag, const QTextCodec* codec);
|
static QString Decode(const TagLib::String& tag, const QTextCodec* codec);
|
||||||
|
|
|
@ -23,10 +23,11 @@
|
||||||
|
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
|
||||||
ConnectedDevice::ConnectedDevice(const QUrl&, DeviceLister* lister,
|
ConnectedDevice::ConnectedDevice(const QUrl& url, DeviceLister* lister,
|
||||||
const QString& unique_id, DeviceManager* manager,
|
const QString& unique_id, DeviceManager* manager,
|
||||||
int database_id, bool)
|
int database_id, bool)
|
||||||
: QObject(manager),
|
: QObject(manager),
|
||||||
|
url_(url),
|
||||||
lister_(lister),
|
lister_(lister),
|
||||||
unique_id_(unique_id),
|
unique_id_(unique_id),
|
||||||
database_id_(database_id),
|
database_id_(database_id),
|
||||||
|
|
|
@ -51,6 +51,7 @@ protected:
|
||||||
void InitBackendDirectory(const QString& mount_point, bool first_time);
|
void InitBackendDirectory(const QString& mount_point, bool first_time);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
QUrl url_;
|
||||||
DeviceLister* lister_;
|
DeviceLister* lister_;
|
||||||
QString unique_id_;
|
QString unique_id_;
|
||||||
int database_id_;
|
int database_id_;
|
||||||
|
|
|
@ -29,7 +29,8 @@ GPodDevice::GPodDevice(
|
||||||
int database_id, bool first_time)
|
int database_id, bool first_time)
|
||||||
: ConnectedDevice(url, lister, unique_id, manager, database_id, first_time),
|
: ConnectedDevice(url, lister, unique_id, manager, database_id, first_time),
|
||||||
loader_thread_(new QThread(this)),
|
loader_thread_(new QThread(this)),
|
||||||
loader_(new GPodLoader(url.path(), manager->task_manager(), backend_))
|
loader_(new GPodLoader(url.path(), manager->task_manager(), backend_)),
|
||||||
|
active_copy_db_(NULL)
|
||||||
{
|
{
|
||||||
InitBackendDirectory(url.path(), first_time);
|
InitBackendDirectory(url.path(), first_time);
|
||||||
model_->Init();
|
model_->Init();
|
||||||
|
@ -44,13 +45,65 @@ GPodDevice::GPodDevice(
|
||||||
}
|
}
|
||||||
|
|
||||||
GPodDevice::~GPodDevice() {
|
GPodDevice::~GPodDevice() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPodDevice::StartCopy() {
|
||||||
|
active_copy_mutex_.lock();
|
||||||
|
|
||||||
|
// Load the iTunes database
|
||||||
|
GError* error = NULL;
|
||||||
|
active_copy_db_ = itdb_parse(url_.path().toLocal8Bit(), &error);
|
||||||
|
|
||||||
|
// Check for errors
|
||||||
|
if (!active_copy_db_) {
|
||||||
|
qDebug() << "GPodDevice error:" << error->message;
|
||||||
|
emit Error(QString::fromUtf8(error->message));
|
||||||
|
g_error_free(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPodDevice::CopyToStorage(
|
bool GPodDevice::CopyToStorage(
|
||||||
const QString &source, const QString &destination,
|
const QString& source, const QString&,
|
||||||
const Song &metadata, bool overwrite, bool remove_original)
|
const Song& metadata, bool, bool remove_original)
|
||||||
{
|
{
|
||||||
|
if (!active_copy_db_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Create the track
|
||||||
|
Itdb_Track* track = itdb_track_new();
|
||||||
|
metadata.ToItdb(track);
|
||||||
|
|
||||||
|
// Add it to the DB and the master playlist
|
||||||
|
// The DB takes ownership of the track
|
||||||
|
itdb_track_add(active_copy_db_, track, -1);
|
||||||
|
Itdb_Playlist* mpl = itdb_playlist_mpl(active_copy_db_);
|
||||||
|
itdb_playlist_add_track(mpl, track, -1);
|
||||||
|
|
||||||
|
// Copy the file
|
||||||
|
GError* error = NULL;
|
||||||
|
itdb_cp_track_to_ipod(track, source.toLocal8Bit().constData(), &error);
|
||||||
|
if (error) {
|
||||||
|
qDebug() << "GPodDevice error:" << error->message;
|
||||||
|
emit Error(QString::fromUtf8(error->message));
|
||||||
|
g_error_free(error);
|
||||||
|
|
||||||
|
// Need to remove the track from the db again
|
||||||
|
itdb_track_remove(track);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPodDevice::FinishCopy() {
|
||||||
|
GError* error = NULL;
|
||||||
|
itdb_write(active_copy_db_, &error);
|
||||||
|
if (error) {
|
||||||
|
qDebug() << "GPodDevice error:" << error->message;
|
||||||
|
emit Error(QString::fromUtf8(error->message));
|
||||||
|
g_error_free(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
active_copy_mutex_.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "connecteddevice.h"
|
#include "connecteddevice.h"
|
||||||
#include "core/musicstorage.h"
|
#include "core/musicstorage.h"
|
||||||
|
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
class GPodLoader;
|
class GPodLoader;
|
||||||
|
|
||||||
class GPodDevice : public ConnectedDevice, public MusicStorage {
|
class GPodDevice : public ConnectedDevice, public MusicStorage {
|
||||||
|
@ -36,12 +38,17 @@ public:
|
||||||
|
|
||||||
MusicStorage* storage() { return this; }
|
MusicStorage* storage() { return this; }
|
||||||
|
|
||||||
|
void StartCopy();
|
||||||
bool CopyToStorage(const QString &source, const QString &destination,
|
bool CopyToStorage(const QString &source, const QString &destination,
|
||||||
const Song &metadata, bool overwrite, bool remove_original);
|
const Song &metadata, bool overwrite, bool remove_original);
|
||||||
|
void FinishCopy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QThread* loader_thread_;
|
QThread* loader_thread_;
|
||||||
GPodLoader* loader_;
|
GPodLoader* loader_;
|
||||||
|
|
||||||
|
QMutex active_copy_mutex_;
|
||||||
|
Itdb_iTunesDB* active_copy_db_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GPODDEVICE_H
|
#endif // GPODDEVICE_H
|
||||||
|
|
Loading…
Reference in New Issue