Esempio n. 1
0
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;
}
Esempio n. 2
0
/**
 * @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;
}
Esempio n. 3
0
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);
}