Example #1
0
// 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);

} // }}}
Example #2
0
/* 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);
}
Example #3
0
/*
 * "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);
}
Example #4
0
// 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();
  }
}