예제 #1
0
static gboolean
request_album_art_idle (RequestAlbumArtData *data)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (data->source);
	const char *album;

	/* pretty sure we don't need any extra locking here - we only touch the artwork
	 * request map on the main thread anyway.
	 */

	album = rhythmdb_entry_get_string (data->entry, RHYTHMDB_PROP_ALBUM);
	if (g_hash_table_lookup (priv->artwork_request_map, album) == NULL) {
		GValue *metadata;
		RhythmDB *db = get_db_for_source (data->source);

		rb_debug ("requesting cover art image for album %s", album);
		g_hash_table_insert (priv->artwork_request_map, (gpointer) album, GINT_TO_POINTER (1));
		metadata = rhythmdb_entry_request_extra_metadata (db, data->entry, "rb:coverArt");
		if (metadata) {
			artwork_notify_cb (db, data->entry, "rb:coverArt", metadata, data->source);
			g_value_unset (metadata);
			g_free (metadata);
		}
		g_object_unref (db);
	}

	g_object_unref (data->source);
	rhythmdb_entry_unref (data->entry);
	g_free (data);
	return FALSE;
}
예제 #2
0
static LIBMTP_filetype_t
mimetype_to_filetype (RBMtpSource *source, const char *mimetype)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);

	if (!strcmp (mimetype, "audio/mpeg") || !strcmp (mimetype, "application/x-id3")) {
		return LIBMTP_FILETYPE_MP3;
	}  else if (!strcmp (mimetype, "audio/x-wav")) {
		return  LIBMTP_FILETYPE_WAV;
	} else if (!strcmp (mimetype, "application/ogg")) {
		return LIBMTP_FILETYPE_OGG;
	} else if (!strcmp (mimetype, "audio/x-m4a") || !strcmp (mimetype, "video/quicktime")) {
		/* try a few different filetypes that might work */
		if (priv->supported_types[LIBMTP_FILETYPE_M4A])
			return LIBMTP_FILETYPE_M4A;
		else if (!priv->supported_types[LIBMTP_FILETYPE_AAC] && priv->supported_types[LIBMTP_FILETYPE_MP4])
			return LIBMTP_FILETYPE_MP4;
		else
			return LIBMTP_FILETYPE_AAC;

	} else if (!strcmp (mimetype, "audio/x-ms-wma") || !strcmp (mimetype, "audio/x-ms-asf")) {
		return LIBMTP_FILETYPE_WMA;
	} else if (!strcmp (mimetype, "video/x-ms-asf")) {
		return LIBMTP_FILETYPE_ASF;
	} else if (!strcmp (mimetype, "audio/x-flac")) {
		return LIBMTP_FILETYPE_FLAC;
	} else {
		rb_debug ("\"%s\" is not a supported mimetype", mimetype);
		return LIBMTP_FILETYPE_UNKNOWN;
	}
}
예제 #3
0
static void
queue_free_space_update (RBMtpSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	rb_mtp_thread_queue_callback (priv->device_thread,
				      (RBMtpThreadCallback) update_free_space_cb, source, NULL);
}
예제 #4
0
static void
unmount_done_cb (GObject *object, GAsyncResult *result, gpointer psource)
{
	GMount *mount;
	RBMtpSource *source;
	gboolean ok;
	GError *error = NULL;
	RBMtpSourcePrivate *priv;

	mount = G_MOUNT (object);
	source = RB_MTP_SOURCE (psource);
	priv = MTP_SOURCE_GET_PRIVATE (source);

	ok = g_mount_unmount_with_operation_finish (mount, result, &error);
	if (ok) {
		rb_debug ("successfully unmounted mtp device");
		priv->remount_volume = g_mount_get_volume (mount);

		open_device (source);
	} else {
		g_warning ("Unable to unmount MTP device: %s", error->message);
		g_error_free (error);
	}

	g_object_unref (mount);
	g_object_unref (source);
}
예제 #5
0
static void
prepare_source (RBMtpSource *source, const char *stream_uri, GObject *src)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	RhythmDBEntry *entry;
	RhythmDB *db;

	/* make sure this stream is for a file on our device */
	if (g_str_has_prefix (stream_uri, "xrbmtp://") == FALSE)
		return;

	db = get_db_for_source (source);
	entry = rhythmdb_entry_lookup_by_location (db, stream_uri);
	g_object_unref (db);
	if (entry == NULL)
		return;

	if (_rb_source_check_entry_type (RB_SOURCE (source), entry) == FALSE) {
		rhythmdb_entry_unref (entry);
		return;
	}

	rb_debug ("setting device-thread for stream %s", stream_uri);
	g_object_set (src, "device-thread", priv->device_thread, NULL);
	rhythmdb_entry_unref (entry);
}
예제 #6
0
static guint64
impl_get_free_space	(RBMediaPlayerSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	/* probably need a lock for this */
	return priv->free_space;
}
예제 #7
0
static void
rb_mtp_source_set_property (GObject *object,
			    guint prop_id,
			    const GValue *value,
			    GParamSpec *pspec)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (object);
	LIBMTP_raw_device_t *raw_device;

	switch (prop_id) {
	case PROP_RAW_DEVICE:
		raw_device = g_value_get_pointer (value);
		priv->raw_device = *raw_device;
		break;
#if defined(HAVE_GUDEV)
	case PROP_UDEV_DEVICE:
		priv->udev_device = g_value_dup_object (value);
		break;
#else
	case PROP_UDI:
		priv->udi = g_value_dup_string (value);
		break;
#endif
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
예제 #8
0
static void
artwork_notify_cb (RhythmDB *db,
		   RhythmDBEntry *entry,
		   const char *property_name,
		   const GValue *metadata,
		   RBMtpSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	GdkPixbuf *pixbuf;
	const char *album_name;

	album_name = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM);

	/* check if we're looking for art for this entry, and if we actually got some */
	if (g_hash_table_remove (priv->artwork_request_map, album_name) == FALSE)
		return;

	if (G_VALUE_HOLDS (metadata, GDK_TYPE_PIXBUF) == FALSE)
		return;

	pixbuf = GDK_PIXBUF (g_value_get_object (metadata));

	rb_mtp_thread_set_album_image (priv->device_thread, album_name, pixbuf);
	queue_free_space_update (source);
}
예제 #9
0
static gboolean
ensure_loaded (RBMtpSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
#if defined(HAVE_GUDEV)
	GMount *mount;
#endif
	if (priv->tried_open) {
		RBSourceLoadStatus status;
		g_object_get (source, "load-status", &status, NULL);
		return (status == RB_SOURCE_LOAD_STATUS_LOADED);
	}
	priv->tried_open = TRUE;

	/* try to open the device.  if gvfs has mounted it, unmount it first */
#if defined(HAVE_GUDEV)
	mount = find_mount_for_device (priv->udev_device);
	if (mount != NULL) {
		rb_debug ("device is already mounted, waiting until activated");
		g_mount_unmount_with_operation (mount,
						G_MOUNT_UNMOUNT_NONE,
						NULL,
						NULL,
						unmount_done_cb,
						g_object_ref (source));
		/* mount gets unreffed in callback */
	} else {
		rb_debug ("device isn't mounted");
		open_device (source);
	}
#else
	open_device (source);
#endif
	return FALSE;
}
예제 #10
0
static void
rb_mtp_source_get_property (GObject *object,
			    guint prop_id,
			    GValue *value,
			    GParamSpec *pspec)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (object);

	switch (prop_id) {
	case PROP_RAW_DEVICE:
		g_value_set_pointer (value, &priv->raw_device);
		break;
#if defined(HAVE_GUDEV)
	case PROP_UDEV_DEVICE:
		g_value_set_object (value, priv->udev_device);
		break;
#else
	case PROP_UDI:
		g_value_set_string (value, priv->udi);
		break;
#endif
	case PROP_DEVICE_SERIAL:
		g_value_set_string (value, priv->serial);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
static char *
rb_mtp_source_get_playback_uri (RhythmDBEntry *entry, gpointer data)
{
	RBMtpSourcePrivate *priv;
	LIBMTP_track_t *track;
	char *path;
	char *uri = NULL;
	GError *error = NULL;

	priv = MTP_SOURCE_GET_PRIVATE (data);

	track = g_hash_table_lookup (priv->entry_map, entry);
	path = g_strdup_printf ("%s/%s-%s",
				g_get_tmp_dir (),
				rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ARTIST),
				rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE));
	uri = g_filename_to_uri (path, NULL, &error);
	g_free (path);
	if (error != NULL) {
		g_warning ("unable to convert path %s to filename: %s", path, error->message);
		g_error_free (error);
		g_free (path);
		return NULL;
	}

	if (rb_mtp_source_transfer_track_to_disk (priv->device, track, uri) == TRUE) {
		rb_debug ("playback URI for %s: %s",
			  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION),
			  uri);
		return uri;
	} else {
		g_free (uri);
		return NULL;
	}
}
예제 #12
0
static void
impl_delete_entries	(RBMediaPlayerSource *source,
			 GList *entries,
			 RBMediaPlayerSourceDeleteCallback callback,
			 gpointer user_data,
			 GDestroyNotify destroy_data)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	RhythmDB *db;
	GList *i;
	TracksDeletedCallbackData *cb_data;

	cb_data = g_new0 (TracksDeletedCallbackData, 1);
	cb_data->source = g_object_ref (source);
	cb_data->callback_data = user_data;
	cb_data->callback = callback;
	cb_data->destroy_data = destroy_data;
	cb_data->check_folders = g_hash_table_new (g_direct_hash, g_direct_equal);

	db = get_db_for_source (RB_MTP_SOURCE (source));
	for (i = entries; i != NULL; i = i->next) {
		LIBMTP_track_t *track;
		const char *uri;
		const char *album_name;
		RhythmDBEntry *entry;

		entry = i->data;
		uri = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
		track = g_hash_table_lookup (priv->entry_map, entry);
		if (track == NULL) {
			rb_debug ("Couldn't find track on mtp-device! (%s)", uri);
			continue;
		}

		album_name = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM);
		if (g_strcmp0 (album_name, _("Unknown")) != 0) {
			rb_mtp_thread_remove_from_album (priv->device_thread, track, album_name);
		}
		rb_mtp_thread_delete_track (priv->device_thread, track);

		g_hash_table_insert (cb_data->check_folders,
				     GUINT_TO_POINTER (track->parent_id),
				     GINT_TO_POINTER (1));

		g_hash_table_remove (priv->entry_map, entry);
		rhythmdb_entry_delete (db, entry);
	}

	/* callback when all tracks have been deleted */
	rb_mtp_thread_queue_callback (priv->device_thread,
				      (RBMtpThreadCallback) delete_done_cb,
				      cb_data,
				      (GDestroyNotify) free_delete_data);

	rhythmdb_commit (db);
}
예제 #13
0
/* this callback runs on the device handling thread, so it can call libmtp directly */
static void
mtp_device_open_cb (LIBMTP_mtpdevice_t *device, RBMtpSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	DeviceOpenedData *data;

	if (device == NULL) {
		/* can't delete the source on this thread, so move it to the main thread */
		g_idle_add ((GSourceFunc) device_open_failed_idle, g_object_ref (source));
		return;
	}

	/* set the source name to match the device, ignoring some
	 * particular broken device names.
	 */
	data = g_new0 (DeviceOpenedData, 1);
	data->source = g_object_ref (source);
	data->name = LIBMTP_Get_Friendlyname (device);
	if (data->name == NULL || strcmp (data->name, "?????") == 0) {
		g_free (data->name);
		data->name = LIBMTP_Get_Modelname (device);
	}
	if (data->name == NULL) {
		data->name = g_strdup (_("Digital Audio Player"));
	}

	/* get some other device information that doesn't change */
	priv->manufacturer = LIBMTP_Get_Manufacturername (device);
	priv->device_version = LIBMTP_Get_Deviceversion (device);
	priv->model_name = LIBMTP_Get_Modelname (device);
	priv->serial = LIBMTP_Get_Serialnumber (device);

	/* calculate the device capacity */
	priv->capacity = 0;
	if (LIBMTP_Get_Storage (device, LIBMTP_STORAGE_SORTBY_NOTSORTED) == 0) {
		LIBMTP_devicestorage_t *storage;
		for (storage = device->storage;
		     storage != NULL;
		     storage = storage->next) {
			priv->capacity += storage->MaxCapacity;
		}
	}

	update_free_space_cb (device, RB_MTP_SOURCE (source));

	/* figure out the set of formats supported by the device */
	if (LIBMTP_Get_Supported_Filetypes (device, &data->types, &data->num_types) != 0) {
		rb_mtp_thread_report_errors (priv->device_thread, FALSE);
	}

	g_idle_add ((GSourceFunc) device_opened_idle, data);

	/* now get the track list */
	rb_mtp_thread_get_track_list (priv->device_thread, (RBMtpTrackListCallback) mtp_tracklist_cb, g_object_ref (source), g_object_unref);
}
예제 #14
0
static void
rb_mtp_source_init (RBMtpSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);

	priv->entry_map = g_hash_table_new_full (g_direct_hash,
						 g_direct_equal,
						 NULL,
						 (GDestroyNotify) LIBMTP_destroy_track_t);

	priv->track_transfer_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
예제 #15
0
static void
rb_mtp_source_name_changed_cb (RBMtpSource *source,
			       GParamSpec *spec,
			       gpointer data)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	char *name = NULL;

	g_object_get (source, "name", &name, NULL);
	rb_mtp_thread_set_device_name (priv->device_thread, name);
	g_free (name);
}
예제 #16
0
static void
open_device (RBMtpSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);

	rb_debug ("actually opening device");
	priv->device_thread = rb_mtp_thread_new ();
	rb_mtp_thread_open_device (priv->device_thread,
				   &priv->raw_device,
				   (RBMtpOpenCallback)mtp_device_open_cb,
				   g_object_ref (source),
				   g_object_unref);
}
static void
rb_mtp_source_name_changed_cb (RBMtpSource *source,
			       GParamSpec *spec,
			       gpointer data)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	char *name = NULL;

	g_object_get (source, "name", &name, NULL);
	if (LIBMTP_Set_Friendlyname (priv->device, name) != 0) {
		report_libmtp_errors (priv->device, TRUE);
	}
	g_free (name);
}
static void
rb_mtp_source_init (RBMtpSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);

	priv->entry_map = g_hash_table_new_full (g_direct_hash,
						 g_direct_equal,
						 NULL,
						 (GDestroyNotify) LIBMTP_destroy_track_t);
	priv->album_map = g_hash_table_new_full (g_str_hash,
						 g_str_equal,
						 NULL,
						 (GDestroyNotify) LIBMTP_destroy_album_t);
	priv->artwork_request_map = g_hash_table_new (g_direct_hash, g_direct_equal);
}
static void
rb_mtp_source_finalize (GObject *object)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (object);

	g_hash_table_destroy (priv->entry_map);
	g_hash_table_destroy (priv->album_map);
	g_hash_table_destroy (priv->artwork_request_map);

	g_free (priv->udi);

	LIBMTP_Release_Device (priv->device);

	G_OBJECT_CLASS (rb_mtp_source_parent_class)->finalize (object);
}
static void
impl_delete (RBSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	GList *sel;
	GList *tem;
	RBEntryView *tracks;
	RhythmDB *db;
	int ret;

	db = get_db_for_source (RB_MTP_SOURCE (source));

	tracks = rb_source_get_entry_view (source);
	sel = rb_entry_view_get_selected_entries (tracks);
	for (tem = sel; tem != NULL; tem = tem->next) {
		LIBMTP_track_t *track;
		RhythmDBEntry *entry;
		const char *uri;
		const char *album_name;

		entry = (RhythmDBEntry *)tem->data;
		uri = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
		track = g_hash_table_lookup (priv->entry_map, entry);
		if (track == NULL) {
			rb_debug ("Couldn't find track on mtp-device! (%s)", uri);
			continue;
		}

		ret = LIBMTP_Delete_Object (priv->device, track->item_id);
		if (ret != 0) {
			rb_debug ("Delete track %d failed", track->item_id);
			report_libmtp_errors (priv->device, TRUE);
			continue;
		}

		album_name = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM);
		if (strcmp (album_name, _("Unknown")) != 0) {
			remove_track_from_album (RB_MTP_SOURCE (source), album_name, track);
		}

		g_hash_table_remove (priv->entry_map, entry);
		rhythmdb_entry_delete (db, entry);
	}
	rhythmdb_commit (db);

	g_list_free (sel);
	g_list_free (tem);
}
예제 #21
0
static void
art_request_cb (RBExtDBKey *key, RBExtDBKey *store_key, const char *filename, GValue *data, RBMtpSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);

	if (G_VALUE_HOLDS (data, GDK_TYPE_PIXBUF)) {
		GdkPixbuf *pixbuf;
		const char *album_name;

		pixbuf = GDK_PIXBUF (g_value_get_object (data));

		album_name = rb_ext_db_key_get_field (key, "album");
		rb_mtp_thread_set_album_image (priv->device_thread, album_name, pixbuf);
		queue_free_space_update (source);
	}
}
static gboolean
impl_track_added (RBRemovableMediaSource *isource,
		  RhythmDBEntry *entry,
		  const char *dest,
		  guint64 filesize,
		  const char *mimetype)
{
	RBMtpSource *source = RB_MTP_SOURCE (isource);
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	GFile *file;
	char *path;
	LIBMTP_track_t *track = NULL;

	file = g_file_new_for_uri (dest);
	path = g_file_get_path (file);
	track = transfer_track (source, priv->device, entry, path, filesize, mimetype);
	g_free (path);

	g_file_delete (file, NULL, NULL);

	if (track != NULL) {
		RhythmDB *db = get_db_for_source (source);

		if (priv->album_art_supported) {
			const char *album;

			album = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM);
			if (g_hash_table_lookup (priv->artwork_request_map, album) == NULL) {
				GValue *metadata;

				rb_debug ("requesting cover art image for album %s", album);
				g_hash_table_insert (priv->artwork_request_map, (gpointer) album, GINT_TO_POINTER (1));
				metadata = rhythmdb_entry_request_extra_metadata (db, entry, "rb:coverArt");
				if (metadata) {
					artwork_notify_cb (db, entry, "rb:coverArt", metadata, source);
					g_value_unset (metadata);
					g_free (metadata);
				}
			}
		}

		add_mtp_track_to_db (source, db, track);
		g_object_unref (db);
	}

	return FALSE;
}
예제 #23
0
static gboolean
impl_uri_is_source (RBSource *source, const char *uri)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	char *source_uri;
	gboolean result;

	if (g_str_has_prefix (uri, "gphoto2://") == FALSE)
		return FALSE;

	source_uri = g_strdup_printf ("gphoto2://[usb:%03d,%03d]/", 
				      priv->raw_device.bus_location,
				      priv->raw_device.devnum);
	result = g_str_has_prefix (uri, source_uri);
	g_free (source_uri);
	return result;
}
예제 #24
0
static gboolean
impl_track_add_error (RBRemovableMediaSource *source,
		      RhythmDBEntry *entry,
		      const char *dest,
		      GError *error)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	/* we don't actually do anything with the error here, we just need to clean up the transfer map */
	LIBMTP_track_t *track = g_hash_table_lookup (priv->track_transfer_map, dest);
	if (track != NULL) {
		LIBMTP_destroy_track_t (track);
		g_hash_table_remove (priv->track_transfer_map, dest);
	} else {
		rb_debug ("track-add-error called, but can't find a track for dest URI %s", dest);
	}

	return TRUE;
}
예제 #25
0
static void
update_free_space_cb (LIBMTP_mtpdevice_t *device, RBMtpSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	LIBMTP_devicestorage_t *storage;
	int ret;

	ret = LIBMTP_Get_Storage (device, LIBMTP_STORAGE_SORTBY_NOTSORTED);
	if (ret != 0) {
		rb_mtp_thread_report_errors (priv->device_thread, FALSE);
	}

	/* probably need a lock for this.. */
	priv->free_space = 0;
	for (storage = device->storage; storage != NULL; storage = storage->next) {
		priv->free_space += storage->FreeSpaceInBytes;
	}
}
static void
add_track_to_album (RBMtpSource *source, const char *album_name, LIBMTP_track_t *track)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	LIBMTP_album_t *album;

	album = g_hash_table_lookup (priv->album_map, album_name);
	if (album != NULL) {
		/* add track to album */

		album->tracks = realloc (album->tracks, sizeof(uint32_t) * (album->no_tracks+1));
		album->tracks[album->no_tracks] = track->item_id;
		album->no_tracks++;
		rb_debug ("adding track ID %d to album ID %d; now %d tracks",
			  track->item_id,
			  album->album_id,
			  album->no_tracks);

		if (LIBMTP_Update_Album (priv->device, album) != 0) {
			rb_debug ("LIBMTP_Update_Album failed..");
			report_libmtp_errors (priv->device, FALSE);
		}
	} else {
		/* add new album */
		album = LIBMTP_new_album_t ();
		album->name = strdup (album_name);
		album->no_tracks = 1;
		album->tracks = malloc (sizeof(uint32_t));
		album->tracks[0] = track->item_id;
		album->storage_id = track->storage_id;

		/* fill in artist and genre? */

		rb_debug ("creating new album (%s) for track ID %d", album->name, track->item_id);

		if (LIBMTP_Create_New_Album (priv->device, album) != 0) {
			LIBMTP_destroy_album_t (album);
			rb_debug ("LIBMTP_Create_New_Album failed..");
			report_libmtp_errors (priv->device, FALSE);
		} else {
			g_hash_table_insert (priv->album_map, album->name, album);
		}
	}
}
예제 #27
0
static gboolean
device_open_failed_idle (RBMtpSource *source)
{
	/* libmtp doesn't give us a useful error message in this case, so
	 * all we can offer is this generic message.
	 */
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	rb_error_dialog (NULL,
			 _("Media player device error"),
			 /* Translators: first %s is the device manufacturer,
			  * second is the product name.
			  */
			 _("Unable to open the %s %s device"),
			 priv->raw_device.device_entry.vendor,
			 priv->raw_device.device_entry.product);
	rb_source_delete_thyself (RB_SOURCE (source));
	g_object_unref (source);
	return FALSE;
}
static GList *
impl_copy (RBSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (RB_MTP_SOURCE (source));
	RhythmDB *db;
	GList *selected_entries;
	GList *iter;
	GList *copy_entries;
	int ret = -1;
	LIBMTP_track_t *track = NULL;

	db = get_db_for_source (RB_MTP_SOURCE (source));

	copy_entries = NULL;
	selected_entries = rb_entry_view_get_selected_entries (rb_source_get_entry_view (source));
	for (iter = selected_entries; iter != NULL; iter = g_list_next (iter)) {
		RhythmDBEntry *entry;
		char *path;
		char *uri;

		entry = (RhythmDBEntry *)iter->data;
		track = g_hash_table_lookup (priv->entry_map, entry);

		if (track == NULL)
			continue;

		path = g_strdup_printf ("%s/%s", g_get_tmp_dir (), track->filename);
		uri = g_filename_to_uri (path, NULL, NULL);
		g_free (path);
		ret = rb_mtp_source_transfer_track_to_disk (priv->device, track, uri);

		if (ret == 0) {
			entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_LOCATION, uri);
			copy_entries = g_list_prepend (copy_entries, entry);
		}
		g_free (uri);
	}

	g_list_free (selected_entries);
	g_object_unref (G_OBJECT (db));

	return copy_entries;
}
예제 #29
0
static gboolean
impl_track_added (RBTransferTarget *target,
		  RhythmDBEntry *entry,
		  const char *dest,
		  guint64 filesize,
		  const char *media_type)
{
	LIBMTP_track_t *track = NULL;
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (target);
	RhythmDB *db;

	track = g_hash_table_lookup (priv->track_transfer_map, dest);
	if (track == NULL) {
		rb_debug ("track-added called, but can't find a track for dest URI %s", dest);
		return FALSE;
	}
	g_hash_table_remove (priv->track_transfer_map, dest);

	if (strcmp (track->album, _("Unknown")) != 0) {
		rb_mtp_thread_add_to_album (priv->device_thread, track, track->album);

		if (priv->album_art_supported) {
			RBExtDBKey *key;

			/* need to do this in an idle handler? */
			key = rb_ext_db_key_create_lookup ("album", track->album);
			rb_ext_db_key_add_field (key, "artist", track->artist);
			rb_ext_db_request (priv->art_store,
					   key,
					   (RBExtDBRequestCallback) art_request_cb,
					   g_object_ref (target),
					   (GDestroyNotify) g_object_unref);
			rb_ext_db_key_free (key);
		}
	}

	db = get_db_for_source (RB_MTP_SOURCE (target));
	add_mtp_track_to_db (RB_MTP_SOURCE (target), db, track);
	g_object_unref (db);

	queue_free_space_update (RB_MTP_SOURCE (target));
	return FALSE;
}
예제 #30
0
static void
rb_mtp_source_dispose (GObject *object)
{
	RBMtpSource *source = RB_MTP_SOURCE (object);
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	RhythmDBEntryType *entry_type;
	RhythmDB *db;

	if (priv->device_thread != NULL) {
		g_object_unref (priv->device_thread);
		priv->device_thread = NULL;
	}

#if defined(HAVE_GUDEV)
	if (priv->remount_volume != NULL) {
		rb_debug ("remounting gvfs volume for mtp device");
		/* the callback will unref remount_volume */
		g_volume_mount (priv->remount_volume,
				G_MOUNT_MOUNT_NONE,
				NULL,
				NULL,
				remount_done_cb,
				NULL);
		priv->remount_volume = NULL;
	}
#endif
	if (priv->art_store != NULL) {
		g_object_unref (priv->art_store);
		priv->art_store = NULL;
	}

	db = get_db_for_source (source);

	g_object_get (G_OBJECT (source), "entry-type", &entry_type, NULL);
	rhythmdb_entry_delete_by_type (db, entry_type);
	g_object_unref (entry_type);

	rhythmdb_commit (db);
	g_object_unref (db);

	G_OBJECT_CLASS (rb_mtp_source_parent_class)->dispose (object);
}