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 void StartCopy() {}
|
||||
virtual bool CopyToStorage(const QString& source, const QString& destination,
|
||||
const Song& metadata, bool overwrite,
|
||||
bool remove_original) = 0;
|
||||
virtual void FinishCopy() {}
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(MusicStorage*);
|
||||
|
|
|
@ -35,6 +35,7 @@ Organise::Organise(TaskManager* task_manager, MusicStorage* destination,
|
|||
copy_(copy),
|
||||
overwrite_(overwrite),
|
||||
files_(files),
|
||||
started_(false),
|
||||
task_id_(0),
|
||||
progress_(0)
|
||||
{
|
||||
|
@ -56,8 +57,15 @@ void Organise::Start() {
|
|||
}
|
||||
|
||||
void Organise::ProcessSomeFiles() {
|
||||
if (!started_) {
|
||||
destination_->StartCopy();
|
||||
started_ = true;
|
||||
}
|
||||
|
||||
// None left?
|
||||
if (progress_ >= files_.count()) {
|
||||
destination_->FinishCopy();
|
||||
|
||||
task_manager_->SetTaskFinished(task_id_);
|
||||
|
||||
// Move back to the original thread so deleteLater() can get called in
|
||||
|
|
|
@ -50,6 +50,8 @@ private:
|
|||
const bool overwrite_;
|
||||
QStringList files_;
|
||||
|
||||
bool started_;
|
||||
|
||||
int task_id_;
|
||||
int progress_;
|
||||
};
|
||||
|
|
|
@ -562,6 +562,38 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
|||
d->filename_ = QString::fromLocal8Bit(track->ipod_path);
|
||||
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
|
||||
|
||||
void Song::MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle) {
|
||||
|
|
|
@ -128,6 +128,7 @@ class Song {
|
|||
|
||||
#ifdef HAVE_LIBGPOD
|
||||
void InitFromItdb(Itdb_Track* track);
|
||||
void ToItdb(Itdb_Track* track) const;
|
||||
#endif
|
||||
|
||||
static QString Decode(const TagLib::String& tag, const QTextCodec* codec);
|
||||
|
|
|
@ -23,10 +23,11 @@
|
|||
|
||||
#include <QtDebug>
|
||||
|
||||
ConnectedDevice::ConnectedDevice(const QUrl&, DeviceLister* lister,
|
||||
ConnectedDevice::ConnectedDevice(const QUrl& url, DeviceLister* lister,
|
||||
const QString& unique_id, DeviceManager* manager,
|
||||
int database_id, bool)
|
||||
: QObject(manager),
|
||||
url_(url),
|
||||
lister_(lister),
|
||||
unique_id_(unique_id),
|
||||
database_id_(database_id),
|
||||
|
|
|
@ -51,6 +51,7 @@ protected:
|
|||
void InitBackendDirectory(const QString& mount_point, bool first_time);
|
||||
|
||||
protected:
|
||||
QUrl url_;
|
||||
DeviceLister* lister_;
|
||||
QString unique_id_;
|
||||
int database_id_;
|
||||
|
|
|
@ -29,7 +29,8 @@ GPodDevice::GPodDevice(
|
|||
int database_id, bool first_time)
|
||||
: ConnectedDevice(url, lister, unique_id, manager, database_id, first_time),
|
||||
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);
|
||||
model_->Init();
|
||||
|
@ -44,13 +45,65 @@ 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(
|
||||
const QString &source, const QString &destination,
|
||||
const Song &metadata, bool overwrite, bool remove_original)
|
||||
const QString& source, const QString&,
|
||||
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;
|
||||
}
|
||||
|
||||
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 "core/musicstorage.h"
|
||||
|
||||
#include <QMutex>
|
||||
|
||||
class GPodLoader;
|
||||
|
||||
class GPodDevice : public ConnectedDevice, public MusicStorage {
|
||||
|
@ -36,12 +38,17 @@ public:
|
|||
|
||||
MusicStorage* storage() { return this; }
|
||||
|
||||
void StartCopy();
|
||||
bool CopyToStorage(const QString &source, const QString &destination,
|
||||
const Song &metadata, bool overwrite, bool remove_original);
|
||||
void FinishCopy();
|
||||
|
||||
private:
|
||||
QThread* loader_thread_;
|
||||
GPodLoader* loader_;
|
||||
|
||||
QMutex active_copy_mutex_;
|
||||
Itdb_iTunesDB* active_copy_db_;
|
||||
};
|
||||
|
||||
#endif // GPODDEVICE_H
|
||||
|
|
Loading…
Reference in New Issue