Copy files to afc devices. Doesn't quite work yet
This commit is contained in:
parent
d29fb119a4
commit
a228e2b806
@ -415,7 +415,7 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBGPOD
|
||||
void Song::InitFromItdb(Itdb_Track* track) {
|
||||
void Song::InitFromItdb(const Itdb_Track* track) {
|
||||
d->valid_ = true;
|
||||
|
||||
d->title_ = QString::fromUtf8(track->title);
|
||||
@ -438,23 +438,14 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
||||
d->filesize_ = track->size;
|
||||
d->filetype_ = track->type2 ? Type_Mpeg : Type_Mp4;
|
||||
|
||||
itdb_filename_ipod2fs(track->ipod_path);
|
||||
|
||||
d->filename_ = QString::fromLocal8Bit(track->ipod_path);
|
||||
d->filename_.replace(':', '/');
|
||||
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 {
|
||||
using Utilities::CopyStr;
|
||||
|
||||
CopyStr(d->title_, &track->title);
|
||||
CopyStr(d->album_, &track->album);
|
||||
CopyStr(d->artist_, &track->artist);
|
||||
@ -473,7 +464,9 @@ void Song::InitFromLastFM(const lastfm::Track& track) {
|
||||
track->time_modified = d->mtime_;
|
||||
track->time_added = d->ctime_;
|
||||
track->size = d->filesize_;
|
||||
track->type1 = 0;
|
||||
track->type2 = d->filetype_ == Type_Mp4 ? 0 : 1;
|
||||
track->mediatype = 1; // Audio
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -106,7 +106,7 @@ class Song {
|
||||
void MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle& bundle);
|
||||
|
||||
#ifdef HAVE_LIBGPOD
|
||||
void InitFromItdb(Itdb_Track* track);
|
||||
void InitFromItdb(const Itdb_Track* track);
|
||||
void ToItdb(Itdb_Track* track) const;
|
||||
#endif
|
||||
|
||||
|
@ -135,4 +135,14 @@ void RemoveRecursive(const QString& path) {
|
||||
dir.rmdir(path);
|
||||
}
|
||||
|
||||
void CopyStr(const QString& str, char** dest_p) {
|
||||
Q_ASSERT(*dest_p == NULL);
|
||||
const QByteArray data = str.toUtf8();
|
||||
const int size = data.size() + 1;
|
||||
|
||||
char* dest = new char[size];
|
||||
std::copy(data.constData(), data.constData() + size, dest);
|
||||
*dest_p = dest;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -29,6 +29,8 @@ namespace Utilities {
|
||||
|
||||
QString MakeTempDir();
|
||||
void RemoveRecursive(const QString& path);
|
||||
|
||||
void CopyStr(const QString& str, char** dest_p);
|
||||
}
|
||||
|
||||
#endif // UTILITIES_H
|
||||
|
@ -15,9 +15,11 @@
|
||||
*/
|
||||
|
||||
#include "afcdevice.h"
|
||||
#include "afcfile.h"
|
||||
#include "afctransfer.h"
|
||||
#include "devicemanager.h"
|
||||
#include "gpodloader.h"
|
||||
#include "imobiledeviceconnection.h"
|
||||
#include "core/utilities.h"
|
||||
|
||||
#include <QThread>
|
||||
@ -25,19 +27,23 @@
|
||||
AfcDevice::AfcDevice(
|
||||
const QUrl& url, DeviceLister* lister, const QString& unique_id,
|
||||
DeviceManager* manager, int database_id, bool first_time)
|
||||
: ConnectedDevice(url, lister, unique_id, manager, database_id, first_time),
|
||||
loader_thread_(new QThread(this)),
|
||||
transfer_(NULL),
|
||||
loader_(NULL),
|
||||
db_(NULL)
|
||||
: GPodDevice(url, lister, unique_id, manager, database_id, first_time),
|
||||
transfer_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
AfcDevice::~AfcDevice() {
|
||||
Utilities::RemoveRecursive(local_path_);
|
||||
}
|
||||
|
||||
void AfcDevice::Init() {
|
||||
// Make a new temporary directory for the iTunesDB. We copy it off the iPod
|
||||
// so that libgpod can have a local directory to use.
|
||||
local_path_ = Utilities::MakeTempDir();
|
||||
InitBackendDirectory(local_path_, first_time, false);
|
||||
InitBackendDirectory(local_path_, first_time_, false);
|
||||
model_->Init();
|
||||
|
||||
transfer_ = new AfcTransfer(url.host(), local_path_, manager_->task_manager());
|
||||
transfer_ = new AfcTransfer(url_.host(), local_path_, manager_->task_manager());
|
||||
transfer_->moveToThread(loader_thread_);
|
||||
|
||||
connect(transfer_, SIGNAL(TaskStarted(int)), SIGNAL(TaskStarted(int)));
|
||||
@ -46,10 +52,6 @@ AfcDevice::AfcDevice(
|
||||
loader_thread_->start();
|
||||
}
|
||||
|
||||
AfcDevice::~AfcDevice() {
|
||||
Utilities::RemoveRecursive(local_path_);
|
||||
}
|
||||
|
||||
void AfcDevice::CopyFinished() {
|
||||
transfer_->deleteLater();
|
||||
transfer_ = NULL;
|
||||
@ -66,19 +68,77 @@ void AfcDevice::CopyFinished() {
|
||||
QMetaObject::invokeMethod(loader_, "LoadDatabase");
|
||||
}
|
||||
|
||||
void AfcDevice::LoadFinished(Itdb_iTunesDB* db) {
|
||||
QMutexLocker l(&db_mutex_);
|
||||
db_ = db;
|
||||
db_wait_cond_.wakeAll();
|
||||
bool AfcDevice::CopyToStorage(
|
||||
const QString& source, const QString&,
|
||||
const Song& metadata, bool, bool remove_original) {
|
||||
Q_ASSERT(db_);
|
||||
|
||||
loader_->deleteLater();
|
||||
loader_ = NULL;
|
||||
Itdb_Track* track = AddTrackToITunesDb(metadata);
|
||||
|
||||
// Get an unused filename on the device
|
||||
iMobileDeviceConnection connection(url_.host());
|
||||
QString dest = connection.GetUnusedFilename(db_, metadata);
|
||||
if (dest.isEmpty()) {
|
||||
itdb_track_remove(track);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy the file
|
||||
{
|
||||
QFile source_file(source);
|
||||
AfcFile dest_file(&connection, dest);
|
||||
source_file.open(QIODevice::ReadOnly);
|
||||
dest_file.open(QIODevice::WriteOnly);
|
||||
dest_file.write(source_file.readAll());
|
||||
}
|
||||
|
||||
track->transferred = 1;
|
||||
|
||||
// Set the filetype_marker
|
||||
QString suffix = dest.section('.', -1, -1).toUpper();
|
||||
track->filetype_marker = 0;
|
||||
for (int i=0 ; i<4 ; ++i) {
|
||||
track->filetype_marker = track->filetype_marker << 8;
|
||||
if (i >= suffix.length())
|
||||
track->filetype_marker |= ' ';
|
||||
else
|
||||
track->filetype_marker |= suffix[i].toAscii();
|
||||
}
|
||||
qDebug() << track->filetype_marker;
|
||||
|
||||
// Set the filename
|
||||
Utilities::CopyStr(dest, &track->ipod_path);
|
||||
itdb_filename_fs2ipod(track->ipod_path);
|
||||
qDebug() << track->ipod_path;
|
||||
|
||||
AddTrackToModel(track, "afc://" + url_.host());
|
||||
|
||||
// Remove the original if it was requested
|
||||
if (remove_original) {
|
||||
QFile::remove(source);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AfcDevice::CopyToStorage(const QString &source, const QString &destination,
|
||||
const Song &metadata, bool overwrite,
|
||||
bool remove_original) {
|
||||
return false;
|
||||
void AfcDevice::FinishCopy() {
|
||||
// Temporarily unset the GUID so libgpod doesn't lock the device for syncing
|
||||
itdb_device_set_sysinfo(db_->device, "FirewireGuid", NULL);
|
||||
|
||||
GPodDevice::FinishCopy();
|
||||
}
|
||||
|
||||
void AfcDevice::FinaliseDatabase() {
|
||||
// Set the GUID again to lock the device for syncing
|
||||
itdb_device_set_sysinfo(db_->device, "FirewireGuid", url_.host().toUtf8().constData());
|
||||
|
||||
// Copy the files back to the iPod
|
||||
// No need to start another thread since we're already in the organiser thread
|
||||
AfcTransfer transfer(url_.host(), local_path_, NULL);
|
||||
|
||||
itdb_start_sync(db_);
|
||||
transfer.CopyToDevice();
|
||||
itdb_stop_sync(db_);
|
||||
}
|
||||
|
||||
bool AfcDevice::DeleteFromStorage(const Song &metadata) {
|
||||
|
@ -17,7 +17,7 @@
|
||||
#ifndef AFCDEVICE_H
|
||||
#define AFCDEVICE_H
|
||||
|
||||
#include "connecteddevice.h"
|
||||
#include "gpoddevice.h"
|
||||
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
@ -27,7 +27,7 @@
|
||||
class AfcTransfer;
|
||||
class GPodLoader;
|
||||
|
||||
class AfcDevice : public ConnectedDevice {
|
||||
class AfcDevice : public GPodDevice {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@ -36,29 +36,29 @@ public:
|
||||
int database_id, bool first_time);
|
||||
~AfcDevice();
|
||||
|
||||
void Init();
|
||||
|
||||
static QStringList url_schemes() { return QStringList() << "afc"; }
|
||||
|
||||
bool CopyToStorage(const QString &source, const QString &destination,
|
||||
const Song &metadata, bool overwrite, bool remove_original);
|
||||
void FinishCopy();
|
||||
|
||||
bool DeleteFromStorage(const Song &metadata);
|
||||
|
||||
protected:
|
||||
void FinaliseDatabase();
|
||||
|
||||
private slots:
|
||||
void CopyFinished();
|
||||
void LoadFinished(Itdb_iTunesDB* db);
|
||||
|
||||
private:
|
||||
void RemoveRecursive(const QString& path);
|
||||
|
||||
private:
|
||||
QThread* loader_thread_;
|
||||
AfcTransfer* transfer_;
|
||||
GPodLoader* loader_;
|
||||
|
||||
QString local_path_;
|
||||
|
||||
QWaitCondition db_wait_cond_;
|
||||
QMutex db_mutex_;
|
||||
Itdb_iTunesDB* db_;
|
||||
};
|
||||
|
||||
#endif // AFCDEVICE_H
|
||||
|
@ -33,18 +33,24 @@ AfcTransfer::AfcTransfer(const QString& uuid, const QString& local_destination,
|
||||
}
|
||||
|
||||
void AfcTransfer::CopyFromDevice() {
|
||||
int task_id = task_manager_->StartTask(tr("Copying iPod database"));
|
||||
emit TaskStarted(task_id);
|
||||
int task_id = 0;
|
||||
if (task_manager_) {
|
||||
task_id = task_manager_->StartTask(tr("Copying iPod database"));
|
||||
emit TaskStarted(task_id);
|
||||
}
|
||||
|
||||
// Connect to the device
|
||||
iMobileDeviceConnection c(uuid_);
|
||||
|
||||
CopyDirFromDevice(&c, "/iTunes_Control/Artwork");
|
||||
CopyDirFromDevice(&c, "/iTunes_Control/Device");
|
||||
CopyDirFromDevice(&c, "/iTunes_Control/iTunes");
|
||||
|
||||
moveToThread(original_thread_);
|
||||
task_manager_->SetTaskFinished(task_id);
|
||||
emit CopyFinished();
|
||||
if (task_manager_) {
|
||||
moveToThread(original_thread_);
|
||||
task_manager_->SetTaskFinished(task_id);
|
||||
emit CopyFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void AfcTransfer::CopyDirFromDevice(iMobileDeviceConnection* c, const QString& path) {
|
||||
@ -74,5 +80,35 @@ void AfcTransfer::CopyFileFromDevice(iMobileDeviceConnection *c, const QString &
|
||||
}
|
||||
|
||||
void AfcTransfer::CopyToDevice() {
|
||||
// Connect to the device
|
||||
iMobileDeviceConnection c(uuid_);
|
||||
|
||||
CopyDirToDevice(&c, "/iTunes_Control/Artwork");
|
||||
CopyDirToDevice(&c, "/iTunes_Control/Device");
|
||||
CopyDirToDevice(&c, "/iTunes_Control/iTunes");
|
||||
}
|
||||
|
||||
void AfcTransfer::CopyDirToDevice(iMobileDeviceConnection* c, const QString& path) {
|
||||
QDir dir(local_destination_ + path);
|
||||
|
||||
foreach (const QString& filename, dir.entryList(QDir::Files | QDir::NoDotAndDotDot)) {
|
||||
CopyFileToDevice(c, path + "/" + filename);
|
||||
}
|
||||
|
||||
foreach (const QString& dir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
|
||||
CopyDirToDevice(c, path + "/" + dir);
|
||||
}
|
||||
}
|
||||
|
||||
void AfcTransfer::CopyFileToDevice(iMobileDeviceConnection *c, const QString &path) {
|
||||
QString local_filename = local_destination_ + path;
|
||||
qDebug() << "Copying file" << path;
|
||||
|
||||
QFile source(local_filename);
|
||||
AfcFile dest(c, path);
|
||||
|
||||
dest.open(QIODevice::WriteOnly);
|
||||
source.open(QIODevice::ReadOnly);
|
||||
|
||||
dest.write(source.readAll());
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ signals:
|
||||
private:
|
||||
void CopyDirFromDevice(iMobileDeviceConnection* c, const QString& path);
|
||||
void CopyFileFromDevice(iMobileDeviceConnection* c, const QString& path);
|
||||
void CopyDirToDevice(iMobileDeviceConnection* c, const QString& path);
|
||||
void CopyFileToDevice(iMobileDeviceConnection* c, const QString& path);
|
||||
|
||||
private:
|
||||
QThread* original_thread_;
|
||||
|
@ -25,9 +25,10 @@
|
||||
|
||||
ConnectedDevice::ConnectedDevice(const QUrl& url, DeviceLister* lister,
|
||||
const QString& unique_id, DeviceManager* manager,
|
||||
int database_id, bool)
|
||||
int database_id, bool first_time)
|
||||
: QObject(manager),
|
||||
url_(url),
|
||||
first_time_(first_time),
|
||||
lister_(lister),
|
||||
unique_id_(unique_id),
|
||||
database_id_(database_id),
|
||||
|
@ -38,6 +38,8 @@ public:
|
||||
int database_id, bool first_time);
|
||||
~ConnectedDevice();
|
||||
|
||||
virtual void Init() = 0;
|
||||
|
||||
DeviceLister* lister() const { return lister_; }
|
||||
QString unique_id() const { return unique_id_; }
|
||||
LibraryModel* model() const { return model_; }
|
||||
@ -54,6 +56,7 @@ protected:
|
||||
|
||||
protected:
|
||||
QUrl url_;
|
||||
bool first_time_;
|
||||
DeviceLister* lister_;
|
||||
QString unique_id_;
|
||||
int database_id_;
|
||||
|
@ -469,6 +469,8 @@ boost::shared_ptr<ConnectedDevice> DeviceManager::Connect(int row) {
|
||||
if (!ret) {
|
||||
qWarning() << "Could not create device for" << device_url.toString();
|
||||
} else {
|
||||
ret->Init();
|
||||
|
||||
info.device_ = ret;
|
||||
emit dataChanged(index(row), index(row));
|
||||
connect(info.device_.get(), SIGNAL(TaskStarted(int)), SLOT(DeviceTaskStarted(int)));
|
||||
|
@ -58,9 +58,10 @@ FilesystemDevice::FilesystemDevice(
|
||||
connect(watcher, SIGNAL(CompilationsNeedUpdating()),
|
||||
backend_, SLOT(UpdateCompilations()));
|
||||
connect(watcher, SIGNAL(ScanStarted(int)), SIGNAL(TaskStarted(int)));
|
||||
}
|
||||
|
||||
InitBackendDirectory(url.toLocalFile(), first_time);
|
||||
|
||||
void FilesystemDevice::Init() {
|
||||
InitBackendDirectory(url_.toLocalFile(), first_time_);
|
||||
model_->Init();
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,8 @@ public:
|
||||
int database_id, bool first_time);
|
||||
~FilesystemDevice();
|
||||
|
||||
void Init();
|
||||
|
||||
static QStringList url_schemes() { return QStringList() << "file"; }
|
||||
|
||||
private:
|
||||
|
@ -31,12 +31,16 @@ 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_(),
|
||||
db_(NULL)
|
||||
{
|
||||
InitBackendDirectory(url.path(), first_time);
|
||||
}
|
||||
|
||||
void GPodDevice::Init() {
|
||||
InitBackendDirectory(url_.path(), first_time_);
|
||||
model_->Init();
|
||||
|
||||
loader_ = new GPodLoader(url_.path(), manager_->task_manager(), backend_);
|
||||
loader_->moveToThread(loader_thread_);
|
||||
|
||||
connect(loader_, SIGNAL(Error(QString)), SIGNAL(Error(QString)));
|
||||
@ -70,12 +74,7 @@ void GPodDevice::StartCopy() {
|
||||
db_busy_.lock();
|
||||
}
|
||||
|
||||
bool GPodDevice::CopyToStorage(
|
||||
const QString& source, const QString&,
|
||||
const Song& metadata, bool, bool remove_original)
|
||||
{
|
||||
Q_ASSERT(db_);
|
||||
|
||||
Itdb_Track* GPodDevice::AddTrackToITunesDb(const Song& metadata) {
|
||||
// Create the track
|
||||
Itdb_Track* track = itdb_track_new();
|
||||
metadata.ToItdb(track);
|
||||
@ -86,6 +85,26 @@ bool GPodDevice::CopyToStorage(
|
||||
Itdb_Playlist* mpl = itdb_playlist_mpl(db_);
|
||||
itdb_playlist_add_track(mpl, track, -1);
|
||||
|
||||
return track;
|
||||
}
|
||||
|
||||
void GPodDevice::AddTrackToModel(Itdb_Track* track, const QString& prefix) {
|
||||
// Add it to our LibraryModel
|
||||
Song metadata_on_device;
|
||||
metadata_on_device.InitFromItdb(track);
|
||||
metadata_on_device.set_directory_id(1);
|
||||
metadata_on_device.set_filename(prefix + metadata_on_device.filename());
|
||||
songs_to_add_ << metadata_on_device;
|
||||
}
|
||||
|
||||
bool GPodDevice::CopyToStorage(
|
||||
const QString& source, const QString&,
|
||||
const Song& metadata, bool, bool remove_original)
|
||||
{
|
||||
Q_ASSERT(db_);
|
||||
|
||||
Itdb_Track* track = AddTrackToITunesDb(metadata);
|
||||
|
||||
// Copy the file
|
||||
GError* error = NULL;
|
||||
itdb_cp_track_to_ipod(track, source.toLocal8Bit().constData(), &error);
|
||||
@ -99,12 +118,7 @@ bool GPodDevice::CopyToStorage(
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add it to our LibraryModel
|
||||
Song metadata_on_device;
|
||||
metadata_on_device.InitFromItdb(track);
|
||||
metadata_on_device.set_directory_id(1);
|
||||
metadata_on_device.set_filename(url_.path() + metadata_on_device.filename());
|
||||
songs_to_add_ << metadata_on_device;
|
||||
AddTrackToModel(track, url_.path());
|
||||
|
||||
// Remove the original if it was requested
|
||||
if (remove_original) {
|
||||
@ -123,6 +137,8 @@ void GPodDevice::FinishCopy() {
|
||||
emit Error(QString::fromUtf8(error->message));
|
||||
g_error_free(error);
|
||||
} else {
|
||||
FinaliseDatabase();
|
||||
|
||||
// Update the library model
|
||||
if (!songs_to_add_.isEmpty())
|
||||
backend_->AddOrUpdateSongs(songs_to_add_);
|
||||
|
@ -37,6 +37,8 @@ public:
|
||||
int database_id, bool first_time);
|
||||
~GPodDevice();
|
||||
|
||||
void Init();
|
||||
|
||||
static QStringList url_schemes() { return QStringList() << "ipod"; }
|
||||
|
||||
void StartCopy();
|
||||
@ -48,10 +50,16 @@ public:
|
||||
bool DeleteFromStorage(const Song& metadata);
|
||||
void FinishDelete();
|
||||
|
||||
private slots:
|
||||
protected slots:
|
||||
void LoadFinished(Itdb_iTunesDB* db);
|
||||
|
||||
private:
|
||||
protected:
|
||||
Itdb_Track* AddTrackToITunesDb(const Song& metadata);
|
||||
void AddTrackToModel(Itdb_Track* track, const QString& prefix);
|
||||
|
||||
virtual void FinaliseDatabase() {}
|
||||
|
||||
protected:
|
||||
QThread* loader_thread_;
|
||||
GPodLoader* loader_;
|
||||
|
||||
|
@ -141,3 +141,58 @@ QString iMobileDeviceConnection::GetFileInfo(const QString& path, const QString&
|
||||
free(infolist);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool iMobileDeviceConnection::Exists(const QString& path) {
|
||||
return !GetFileInfo(path, "st_ifmt").isNull();
|
||||
}
|
||||
|
||||
QString iMobileDeviceConnection::GetUnusedFilename(
|
||||
Itdb_iTunesDB* itdb, const Song& metadata) {
|
||||
// This function does the same as itdb_cp_get_dest_filename, except it
|
||||
// accesses the device's filesystem through imobiledevice.
|
||||
|
||||
// Get the total number of F.. directories
|
||||
int total_musicdirs = 0;
|
||||
for ( ; ; ++total_musicdirs) {
|
||||
QString dir;
|
||||
dir.sprintf("/iTunes_Control/Music/F%02d", total_musicdirs);
|
||||
|
||||
if (!Exists(dir))
|
||||
break;
|
||||
}
|
||||
|
||||
if (total_musicdirs <= 0) {
|
||||
qWarning() << "No 'F..'' directories found on iPod";
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Pick one at random
|
||||
const int dir_num = qrand() % total_musicdirs;
|
||||
QString dir;
|
||||
dir.sprintf("/iTunes_Control/Music/F%02d", dir_num);
|
||||
|
||||
if (!Exists(dir)) {
|
||||
qWarning() << "Music directory doesn't exist:" << dir;
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Use the same file extension as the original file, default to mp3.
|
||||
QString extension = metadata.filename().section('.', -1, -1).toLower();
|
||||
if (extension.isEmpty())
|
||||
extension = "mp3";
|
||||
|
||||
// Loop until we find an unused filename.
|
||||
// Use the same naming convention as libgpod, which is
|
||||
// "libgpod" + 6-digit random number
|
||||
static const int kRandMax = 999999;
|
||||
QString filename;
|
||||
forever {
|
||||
filename.sprintf("libgpod%06d", qrand() % kRandMax);
|
||||
filename += "." + extension;
|
||||
|
||||
if (!Exists(dir + "/" + filename))
|
||||
break;
|
||||
}
|
||||
|
||||
return dir + "/" + filename;
|
||||
}
|
||||
|
@ -17,9 +17,12 @@
|
||||
#ifndef IMOBILEDEVICECONNECTION_H
|
||||
#define IMOBILEDEVICECONNECTION_H
|
||||
|
||||
#include "core/song.h"
|
||||
|
||||
#include <libimobiledevice/afc.h>
|
||||
#include <libimobiledevice/libimobiledevice.h>
|
||||
#include <libimobiledevice/lockdown.h>
|
||||
#include <gpod/itdb.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QStringList>
|
||||
@ -35,10 +38,14 @@ public:
|
||||
quint64 GetInfoLongLong(const QString& key);
|
||||
QStringList ReadDirectory(const QString& path, QDir::Filters filters = QDir::NoFilter);
|
||||
|
||||
QString GetFileInfo(const QString& path, const QString& key);
|
||||
bool Exists(const QString& path);
|
||||
|
||||
QString GetUnusedFilename(Itdb_iTunesDB* itdb, const Song& metadata);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(iMobileDeviceConnection);
|
||||
|
||||
QString GetFileInfo(const QString& path, const QString& key);
|
||||
|
||||
idevice_t device_;
|
||||
lockdownd_client_t lockdown_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user