// Device.put_file {{{ static PyObject * Device_put_file(Device *self, PyObject *args) { PyObject *stream, *callback = NULL, *errs, *fo = NULL; ProgressCallback cb; unsigned long parent_id, storage_id; unsigned long long filesize; int ret; char *name; LIBMTP_file_t f; ENSURE_DEV(NULL); ENSURE_STORAGE(NULL); if (!PyArg_ParseTuple(args, "kksOK|O", &storage_id, &parent_id, &name, &stream, &filesize, &callback)) return NULL; errs = PyList_New(0); if (errs == NULL) { PyErr_NoMemory(); return NULL; } if (callback == NULL || !PyCallable_Check(callback)) callback = NULL; cb.obj = callback; cb.extra = stream; f.parent_id = (uint32_t)parent_id; f.storage_id = (uint32_t)storage_id; f.item_id = 0; f.filename = name; f.filetype = LIBMTP_FILETYPE_UNKNOWN; f.filesize = (uint64_t)filesize; Py_XINCREF(callback); Py_INCREF(stream); cb.state = PyEval_SaveThread(); ret = LIBMTP_Send_File_From_Handler(self->device, data_from_python, &cb, &f, report_progress, &cb); PyEval_RestoreThread(cb.state); Py_XDECREF(callback); Py_DECREF(stream); if (ret != 0) dump_errorstack(self->device, errs); else fo = file_metadata(self->device, errs, f.item_id, storage_id); if (fo == NULL) { fo = Py_None; Py_INCREF(fo); } return Py_BuildValue("NN", fo, errs); } // }}}
/* Extract the information from the entry, serialize and send it out. * Return 0 on success, -1 on error. */ static int send_dirent_info (TSK_FS_FILE *fsfile, const char *path) { XDR xdr; int ret = 0; size_t len = 0; struct guestfs_int_tsk_dirent dirent; CLEANUP_FREE char *buf = NULL, *fname = NULL; /* Set dirent fields */ memset (&dirent, 0, sizeof dirent); /* Build the full relative path of the entry */ ret = asprintf (&fname, "%s%s", path, fsfile->name->name); if (ret < 0) { perror ("asprintf"); return -1; } dirent.tsk_inode = fsfile->name->meta_addr; dirent.tsk_type = file_type (fsfile); dirent.tsk_name = fname; dirent.tsk_flags = file_flags (fsfile); file_metadata (fsfile->meta, &dirent); /* Serialize tsk_dirent struct. */ buf = malloc (GUESTFS_MAX_CHUNK_SIZE); if (buf == NULL) { perror ("malloc"); return -1; } xdrmem_create (&xdr, buf, GUESTFS_MAX_CHUNK_SIZE, XDR_ENCODE); ret = xdr_guestfs_int_tsk_dirent (&xdr, &dirent); if (ret == 0) { perror ("xdr_guestfs_int_tsk_dirent"); return -1; } len = xdr_getpos (&xdr); xdr_destroy (&xdr); /* Send serialised tsk_dirent out. */ return send_file_write (buf, len); }
/* * "File the metadata areas" -- I think this function is supposed to declare * which parts of the drive are metadata and thus off-limits to dmraid. */ static void file_metadata_areas(struct lib_context *lc, struct dev_info *di, void *meta) { uint8_t *buf; struct asr *asr = meta; uint64_t start = asr->rb.raidtbl; if (!(buf = read_metadata_chunk(lc, di, start))) return; /* Register the raid tables. */ file_metadata(lc, handler, di->path, buf, ASR_DISK_BLOCK_SIZE * 17, start * ASR_DISK_BLOCK_SIZE); dbg_free(buf); /* Record the device size if -D was specified. */ file_dev_size(lc, handler, di); }
// Device.create_folder {{{ static PyObject * Device_create_folder(Device *self, PyObject *args) { PyObject *errs, *fo = NULL; unsigned long storage_id, parent_id; uint32_t folder_id; char *name; ENSURE_DEV(NULL); ENSURE_STORAGE(NULL); if (!PyArg_ParseTuple(args, "kks", &storage_id, &parent_id, &name)) return NULL; errs = PyList_New(0); if (errs == NULL) { PyErr_NoMemory(); return NULL; } Py_BEGIN_ALLOW_THREADS; folder_id = LIBMTP_Create_Folder(self->device, name, (uint32_t)parent_id, (uint32_t)storage_id); Py_END_ALLOW_THREADS; if (folder_id == 0) dump_errorstack(self->device, errs); else fo = file_metadata(self->device, errs, folder_id, storage_id); if (fo == NULL) { fo = Py_None; Py_INCREF(fo); } return Py_BuildValue("NN", fo, errs); } // }}}
//----------------------------------------------------------------- void MP3Worker::run_implementation() { auto file_name = m_source_info.absoluteFilePath().replace('/', QDir::separator()); // QTemporaryFile and QThreads are not playing fine together, the temp names are being reused // and taglib fails upon reading the file. This approach seems to work. auto id = QUuid::createUuid(); QTemporaryFile temp_file(id.toString()); if(!temp_file.open()) { emit error_message(QString("Couldn't open temporary file for file '%1'.").arg(file_name)); return; } QFile original_file(file_name); if(!original_file.open(QFile::ReadOnly)) { emit error_message(QString("Couldn't open file '%1'.").arg(file_name)); return; } // taglib wouldn't open files with unicode names. temp_file.write(original_file.readAll()); temp_file.waitForBytesWritten(-1); temp_file.flush(); temp_file.close(); auto temp_name = temp_file.fileName() + MP3_EXTENSION; temp_file.rename(temp_name); // taglib won't open a file if it doesn't have the correct extension. ¿¿?? original_file.close(); QString track_title; { // ensure TagLib File object is destroyed at the end of scope. TagLib::MPEG::File file_metadata(temp_name.toStdString().c_str()); if(file_metadata.hasID3v1Tag() || file_metadata.hasID3v2Tag()) { if(m_configuration.useMetadataToRenameOutput()) { if(!file_metadata.hasID3v2Tag()) { track_title = parse_metadata(file_metadata.tag()); } else { track_title = parse_metadata_id3v2(file_metadata.ID3v2Tag()); } } emit progress(25); if(m_configuration.extractMetadataCoverPicture() && file_metadata.hasID3v2Tag()) { extract_cover(file_metadata.ID3v2Tag()); } emit progress(50); if(m_configuration.stripTagsFromMp3()) { file_metadata.strip(); file_metadata.save(); } } } emit progress(75); if(track_title.isEmpty()) { track_title = m_source_info.absoluteFilePath().split('/').last().remove(MP3_EXTENSION); } track_title = Utils::formatString(track_title, m_configuration.formatConfiguration()); auto source_name = m_source_info.absoluteFilePath().split('/').last(); emit information_message(QString("Renaming '%1' from '%2'.").arg(track_title).arg(source_name)); auto final_name = m_source_path + track_title; original_file.rename(original_file.fileName() + TEMP_EXTENSION); if(!QFile::copy(temp_file.fileName(), final_name)) { emit error_message(QString("Couldn't copy file '%1' to '%2'.").arg(m_source_info.absoluteFilePath()).arg(final_name)); original_file.rename(original_file.fileName().remove(TEMP_EXTENSION)); } else { original_file.remove(); } }