static PyObject* file_metadata(LIBMTP_mtpdevice_t *device, PyObject *errs, uint32_t item_id, uint32_t storage_id) { LIBMTP_file_t *nf; PyObject *ans = NULL; Py_BEGIN_ALLOW_THREADS; nf = LIBMTP_Get_Filemetadata(device, item_id); Py_END_ALLOW_THREADS; if (nf == NULL) dump_errorstack(device, errs); else { ans = build_file_metadata(nf, storage_id); LIBMTP_destroy_file_t(nf); } return ans; }
/** * @brief Get's the correct object from the device. * !Important! Release Device after using the returned object * @param pathItems A QStringList containing the items of the filepath * @return QPair with the object and its device. pair.fist is a nullpointer if the object doesn't exist or for root or, depending on the pathItems size device (1), storage (2) or file (>=3) */ QPair<void*, LIBMTP_mtpdevice_t*> MTPSlave::getPath ( const QString& path ) { QStringList pathItems = path.split ( QLatin1Char ( '/' ), QString::SkipEmptyParts ); kDebug ( KIO_MTP ) << path << pathItems.size(); QPair<void*, LIBMTP_mtpdevice_t*> ret; // Don' handle the root directory if ( pathItems.size() <= 0 ) { return ret; } QMap<QString, LIBMTP_raw_device_t*> devices = getRawDevices(); if ( devices.contains ( pathItems.at ( 0 ) ) ) { LIBMTP_mtpdevice_t *device = LIBMTP_Open_Raw_Device_Uncached ( devices.value ( pathItems.at ( 0 ) ) ); // return specific device if ( pathItems.size() == 1 ) { ret.first = device; ret.second = device; kDebug(KIO_MTP) << "returning LIBMTP_mtpdevice_t"; } if ( pathItems.size() > 2 ) { // Query Cache after we have the device uint32_t c_fileID = fileCache->queryPath ( path ); if ( c_fileID != 0 ) { kDebug() << "Match found in cache, checking device"; LIBMTP_file_t* file = LIBMTP_Get_Filemetadata ( device, c_fileID ); if ( file ) { kDebug ( KIO_MTP ) << "Found file in cache"; ret.first = file; ret.second = device; kDebug(KIO_MTP) << "returning LIBMTP_file_t"; return ret; } } // Query cache for parent else if ( pathItems.size() > 3 ) { QString parentPath = convertToPath ( pathItems, pathItems.size() - 1 ); uint32_t c_parentID = fileCache->queryPath ( parentPath ); kDebug() << "Match for parent found in cache, checking device"; LIBMTP_file_t* parent = LIBMTP_Get_Filemetadata ( device, c_parentID ); if ( parent ) { kDebug ( KIO_MTP ) << "Found parent in cache"; fileCache->addPath( parentPath, c_parentID ); QMap<QString, LIBMTP_file_t*> files = getFiles ( device, parent->storage_id, c_parentID ); if ( files.contains ( pathItems.last() ) ) { LIBMTP_file_t* file = files.value( pathItems.last() ); ret.first = file; ret.second = device; kDebug(KIO_MTP) << "returning LIBMTP_file_t"; fileCache->addPath( path, file->item_id ); } return ret; } } } QMap<QString, LIBMTP_devicestorage_t*> storages = getDevicestorages ( device ); if ( pathItems.size() > 1 && storages.contains ( pathItems.at ( 1 ) ) ) { LIBMTP_devicestorage_t *storage = storages.value ( pathItems.at ( 1 ) ); if ( pathItems.size() == 2 ) { ret.first = storage; ret.second = device; kDebug(KIO_MTP) << "returning LIBMTP_devicestorage_t"; return ret; } int currentLevel = 2, currentParent = 0xFFFFFFFF; QMap<QString, LIBMTP_file_t*> files; // traverse further while depth not reached while ( currentLevel < pathItems.size() ) { files = getFiles ( device, storage->id, currentParent ); if ( files.contains ( pathItems.at ( currentLevel ) ) ) { currentParent = files.value ( pathItems.at ( currentLevel ) )->item_id; } else { kDebug(KIO_MTP) << "returning LIBMTP_file_t"; return ret; } currentLevel++; } ret.first = LIBMTP_Get_Filemetadata ( device, currentParent ); ret.second = device; fileCache->addPath ( path, currentParent ); } } return ret; }
static void download_track (RBMtpThread *thread, RBMtpThreadTask *task) { LIBMTP_file_t *fileinfo; LIBMTP_error_t *stack; GError *error = NULL; GFile *dir; RBMtpDownloadCallback cb = (RBMtpDownloadCallback) task->callback; /* first, check there's enough space to copy it */ fileinfo = LIBMTP_Get_Filemetadata (thread->device, task->track_id); if (fileinfo == NULL) { stack = LIBMTP_Get_Errorstack (thread->device); rb_debug ("unable to get track metadata for %u: %s", task->track_id, stack->error_text); error = g_error_new (RB_MTP_THREAD_ERROR, RB_MTP_THREAD_ERROR_GET_TRACK, _("Unable to copy file from MTP device: %s"), stack->error_text); LIBMTP_Clear_Errorstack (thread->device); cb (task->track_id, NULL, error, task->user_data); g_error_free (error); return; } if (task->filename[0] == '\0') { dir = g_file_new_for_path (g_get_tmp_dir ()); } else { GFile *file = g_file_new_for_path (task->filename); dir = g_file_get_parent (file); g_object_unref (file); } rb_debug ("checking for %" G_GINT64_FORMAT " bytes available", fileinfo->filesize); if (rb_check_dir_has_space (dir, fileinfo->filesize) == FALSE) { char *dpath = g_file_get_path (dir); rb_debug ("not enough space in %s", dpath); error = g_error_new (RB_MTP_THREAD_ERROR, RB_MTP_THREAD_ERROR_NO_SPACE, _("Not enough space in %s"), dpath); g_free (dpath); } LIBMTP_destroy_file_t (fileinfo); g_object_unref (dir); if (error != NULL) { rb_debug ("bailing out due to error: %s", error->message); cb (task->track_id, NULL, error, task->user_data); g_error_free (error); return; } if (task->filename[0] == '\0') { /* download to a temporary file */ int fd; GError *tmperror = NULL; g_free (task->filename); fd = g_file_open_tmp ("rb-mtp-temp-XXXXXX", &task->filename, &tmperror); if (fd == -1) { rb_debug ("unable to open temporary file: %s", tmperror->message); error = g_error_new (RB_MTP_THREAD_ERROR, RB_MTP_THREAD_ERROR_TEMPFILE, _("Unable to open temporary file: %s"), tmperror->message); g_error_free (tmperror); cb (task->track_id, NULL, error, task->user_data); g_error_free (error); return; } else { rb_debug ("downloading track %u to file descriptor %d", task->track_id, fd); if (LIBMTP_Get_Track_To_File_Descriptor (thread->device, task->track_id, fd, NULL, NULL)) { stack = LIBMTP_Get_Errorstack (thread->device); rb_debug ("unable to retrieve track %u: %s", task->track_id, stack->error_text); error = g_error_new (RB_MTP_THREAD_ERROR, RB_MTP_THREAD_ERROR_GET_TRACK, _("Unable to copy file from MTP device: %s"), stack->error_text); LIBMTP_Clear_Errorstack (thread->device); cb (task->track_id, NULL, error, task->user_data); g_error_free (error); close (fd); remove (task->filename); return; } rb_debug ("done downloading track"); close (fd); } } else { if (LIBMTP_Get_Track_To_File (thread->device, task->track_id, task->filename, NULL, NULL)) { stack = LIBMTP_Get_Errorstack (thread->device); error = g_error_new (RB_MTP_THREAD_ERROR, RB_MTP_THREAD_ERROR_GET_TRACK, _("Unable to copy file from MTP device: %s"), stack->error_text); LIBMTP_Clear_Errorstack (thread->device); cb (task->track_id, NULL, error, task->user_data); g_error_free (error); return; } } cb (task->track_id, task->filename, NULL, task->user_data); }