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;
}
Beispiel #2
0
static RhythmDBEntry *
add_mtp_track_to_db (RBMtpSource *source,
		     RhythmDB *db,
		     LIBMTP_track_t *track)
{
	RhythmDBEntry *entry = NULL;
	RhythmDBEntryType *entry_type;
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	char *name = NULL;

	/* ignore everything except audio (allow audio/video types too, since they're probably pretty common) */
	if (!(LIBMTP_FILETYPE_IS_AUDIO (track->filetype) || LIBMTP_FILETYPE_IS_AUDIOVIDEO (track->filetype))) {
		rb_debug ("ignoring non-audio item %d (filetype %s)",
			  track->item_id,
			  LIBMTP_Get_Filetype_Description (track->filetype));
		return NULL;
	}

	/* Set URI */
	g_object_get (G_OBJECT (source), "entry-type", &entry_type, NULL);
	name = g_strdup_printf ("xrbmtp://%i/%s", track->item_id, track->filename);
	entry = rhythmdb_entry_new (RHYTHMDB (db), entry_type, name);
	g_free (name);
        g_object_unref (entry_type);

	if (entry == NULL) {
		rb_debug ("cannot create entry %i", track->item_id);
		g_object_unref (G_OBJECT (db));
		return NULL;
	}

	/* Set track number */
	if (track->tracknumber != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_ULONG);
		g_value_set_ulong (&value, track->tracknumber);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
				    RHYTHMDB_PROP_TRACK_NUMBER,
				    &value);
		g_value_unset (&value);
	}

	/* Set length */
	if (track->duration != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_ULONG);
		g_value_set_ulong (&value, track->duration/1000);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
				    RHYTHMDB_PROP_DURATION,
				    &value);
		g_value_unset (&value);
	}

	/* Set file size */
	if (track->filesize != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_UINT64);
		g_value_set_uint64 (&value, track->filesize);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
				    RHYTHMDB_PROP_FILE_SIZE,
				    &value);
		g_value_unset (&value);
	}

	/* Set playcount */
	if (track->usecount != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_ULONG);
		g_value_set_ulong (&value, track->usecount);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
					       RHYTHMDB_PROP_PLAY_COUNT,
					       &value);
		g_value_unset (&value);
	}
	/* Set rating */
	if (track->rating != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_DOUBLE);
		g_value_set_double (&value, track->rating/20);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
					       RHYTHMDB_PROP_RATING,
					       &value);
		g_value_unset (&value);
	}
	/* Set release date */
	if (track->date != NULL && track->date[0] != '\0') {
		GTimeVal tv;
		if (g_time_val_from_iso8601 (track->date, &tv)) {
			GDate d;
			GValue value = {0, };
			g_value_init (&value, G_TYPE_ULONG);
			g_date_set_time_val (&d, &tv);
			g_value_set_ulong (&value, g_date_get_julian (&d));
			rhythmdb_entry_set (RHYTHMDB (db), entry, RHYTHMDB_PROP_DATE, &value);
			g_value_unset (&value);
		}
	}

	/* Set title */
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_TITLE, track->title);

	/* Set album, artist and genre from MTP */
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_ARTIST, track->artist);
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_ALBUM, track->album);
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_GENRE, track->genre);

	g_hash_table_insert (priv->entry_map, entry, track);
	rhythmdb_commit (RHYTHMDB (db));

	return entry;
}
static void
metadata_cb (SjMetadataGetter *metadata,
	     GList *albums,
	     GError *error,
	     RBAudioCdSource *source)
{
	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
	GList *cd_track = priv->tracks;
	RhythmDB *db;
	GValue true_value = {0,};
	AlbumDetails *album;

	g_assert (metadata == priv->metadata);

	if (error != NULL) {
		rb_debug ("Failed to load cd metadata: %s", error->message);
		/* TODO display error to user? */
		g_object_unref (metadata);
		priv->metadata = NULL;
		return;
	}
	if (albums == NULL) {
		rb_debug ("Musicbrainz didn't return any CD metadata, but didn't give an error");
		g_object_unref (metadata);
		priv->metadata = NULL;
		return;
	}
	if (cd_track == NULL) {
		/* empty cd? */
		rb_debug ("no tracks on the CD?");
		g_object_unref (metadata);
		priv->metadata = NULL;
		return;
	}

	db = get_db_for_source (source);

	g_value_init (&true_value, G_TYPE_BOOLEAN);
	g_value_set_boolean (&true_value, TRUE);

	g_free (priv->submit_url);
	priv->submit_url = NULL;

	/* if we have multiple results, ask the user to pick one */
	if (g_list_length (albums) > 1) {
		album = multiple_album_dialog (albums, source);
		if (album == NULL)
			album = (AlbumDetails *)albums->data;
	} else
		album = (AlbumDetails *)albums->data;

#if GTK_CHECK_VERSION(2,17,6)
	if (album->metadata_source != SOURCE_MUSICBRAINZ) {
		priv->submit_url = sj_metadata_getter_get_submit_url (metadata);
		if (priv->submit_url != NULL)
			gtk_widget_show (priv->info_bar);
	}
#endif

	if (album->metadata_source == SOURCE_FALLBACK) {
		rb_debug ("ignoring CD metadata from fallback source");
		g_object_unref (metadata);
		priv->metadata = NULL;
		g_object_unref (db);
		return;
	}

	if (album->artist != NULL) {
		gtk_entry_set_text (GTK_ENTRY (priv->artist_entry), album->artist);
	}
	if (album->artist_sortname != NULL) {
		gtk_entry_set_text (GTK_ENTRY (priv->artist_sort_entry), album->artist_sortname);
	}
	if (album->title != NULL) {
		gtk_entry_set_text (GTK_ENTRY (priv->album_entry), album->title);
	}
	if (album->release_date != NULL) {
		char *year;
		year = g_strdup_printf ("%d", g_date_get_year (album->release_date));
		gtk_entry_set_text (GTK_ENTRY (priv->year_entry), year);
		g_free (year);
	}
	if (album->disc_number != 0) {
		char *num;
		num = g_strdup_printf ("%d", album->disc_number);
		gtk_entry_set_text (GTK_ENTRY (priv->disc_number_entry), num);
		g_free (num);
	}
	if (album->genre != NULL) {
		gtk_entry_set_text (GTK_ENTRY (priv->genre_entry), album->genre);
	}

	g_object_set (G_OBJECT (source), "name", album->title, NULL);
	rb_debug ("musicbrainz_albumid: %s", album->album_id);
	rb_debug ("musicbrainz_albumartistid: %s", album->artist_id);
	rb_debug ("album artist: %s", album->artist);
	rb_debug ("disc number: %d", album->disc_number);
	rb_debug ("genre: %s", album->genre);

	while (album->tracks && cd_track) {
		TrackDetails *track = (TrackDetails*)album->tracks->data;
		RhythmDBEntry *entry = cd_track->data;
		GValue value = {0, };

		rb_debug ("storing metadata for %s - %s - %s", track->artist, album->title, track->title);

		rb_debug ("musicbrainz_trackid: %s", track->track_id);
		rb_debug ("musicbrainz_artistid: %s", track->artist_id);
		rb_debug ("artist sortname: %s", track->artist_sortname);

		/* record track info in entry*/
		entry_set_string_prop (db, entry, RHYTHMDB_PROP_TITLE, FALSE, track->title);
		entry_set_string_prop (db, entry, RHYTHMDB_PROP_ARTIST, FALSE, track->artist);
		entry_set_string_prop (db, entry, RHYTHMDB_PROP_ALBUM, FALSE, album->title);
		entry_set_string_prop (db, entry, RHYTHMDB_PROP_GENRE, FALSE, album->genre);
		entry_set_string_prop (db, entry, RHYTHMDB_PROP_MUSICBRAINZ_TRACKID, TRUE, track->track_id);
		entry_set_string_prop (db, entry, RHYTHMDB_PROP_MUSICBRAINZ_ARTISTID, TRUE, track->artist_id);
		entry_set_string_prop (db, entry, RHYTHMDB_PROP_MUSICBRAINZ_ALBUMID, TRUE, album->album_id);
		entry_set_string_prop (db, entry, RHYTHMDB_PROP_MUSICBRAINZ_ALBUMARTISTID, TRUE, album->artist_id);
		entry_set_string_prop (db, entry, RHYTHMDB_PROP_ARTIST_SORTNAME, TRUE, track->artist_sortname);

		g_value_init (&value, G_TYPE_ULONG);
		g_value_set_ulong (&value, track->duration);
		rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DURATION, &value);
		g_value_unset (&value);

		if (album->disc_number != 0) {
			g_value_init (&value, G_TYPE_ULONG);
			g_value_set_ulong (&value, album->disc_number);
			rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DISC_NUMBER, &value);
			g_value_unset (&value);
		}

		/*album->release_date (could potentially have multiple values)*/
		/* in current sj-structures.h, however, it does not */

		if (album->release_date) {
			GType type = rhythmdb_get_property_type (db, RHYTHMDB_PROP_DATE);
			g_value_init (&value, type);
			g_value_set_ulong (&value, g_date_get_julian (album->release_date));
			rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DATE, &value);
			g_value_unset (&value);
		}

		rhythmdb_commit (db);

		album->tracks = g_list_next (album->tracks);
		cd_track = g_list_next (cd_track);
	}

	while (cd_track) {
		/* Musicbrainz doesn't report data tracks on multisession CDs.
		 * These aren't interesting to us anyway, so they should be hidden.
		 */
		RhythmDBEntry *entry = cd_track->data;
		rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_HIDDEN, &true_value);
		rhythmdb_commit (db);

		cd_track = g_list_next (cd_track);
	}

	/* And free the albums list, as it belongs to us, not
	 * the metadata getter */
	g_list_foreach (albums, (GFunc)album_details_free, NULL);
	g_list_free (albums);

	g_object_unref (metadata);
	priv->metadata = NULL;

	g_object_unref (db);
}
static RhythmDBEntry *
rb_audiocd_create_track_entry (RBAudioCdSource *source,
			       RhythmDB *db,
			       guint track_number)
{
	RhythmDBEntry *entry;
	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
	char *audio_path;
	guint64 duration;
	GValue value = {0, };
	gchar *str;
	RhythmDBEntryType entry_type;
	RBAudioCDEntryData *extra_data;

	audio_path = g_strdup_printf ("cdda://%d#%s", track_number, priv->device_path);

	g_object_get (G_OBJECT (source), "entry-type", &entry_type, NULL);
	rb_debug ("Audio CD - create entry for track %d from %s", track_number, audio_path);
	entry = rhythmdb_entry_new (db, entry_type, audio_path);
	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
	if (entry == NULL) {
		g_free (audio_path);
		return NULL;
	}

	/* generate track # */
	g_value_init (&value, G_TYPE_ULONG);
	g_value_set_ulong (&value, track_number);
	rhythmdb_entry_set (db, entry,
			    RHYTHMDB_PROP_TRACK_NUMBER,
			    &value);
	g_value_unset (&value);

	/* generate track name */
	g_value_init (&value, G_TYPE_STRING);
	str = g_strdup_printf (_("Track %u"), track_number);
	g_value_take_string (&value, str);
	rhythmdb_entry_set (db, entry,
			    RHYTHMDB_PROP_TITLE,
			    &value);
	g_value_unset (&value);

	/* determine the duration
	 * FIXME: http://bugzilla.gnome.org/show_bug.cgi?id=551011 */
	if (gst_tag_list_get_uint64 (GST_CDDA_BASE_SRC(priv->cdda)->tracks[track_number - 1].tags, GST_TAG_DURATION, &duration)) {
		g_value_init (&value, G_TYPE_ULONG);
		g_value_set_ulong (&value, (gulong)(duration / GST_SECOND));
		rhythmdb_entry_set (db, entry,
				    RHYTHMDB_PROP_DURATION,
				    &value);
		g_value_unset (&value);
	} else {
		g_warning ("Failed to query cd track duration");
	}

	entry_set_string_prop (db, entry, RHYTHMDB_PROP_ARTIST, FALSE, NULL);
	entry_set_string_prop (db, entry, RHYTHMDB_PROP_ALBUM, FALSE, NULL);
	entry_set_string_prop (db, entry, RHYTHMDB_PROP_GENRE, FALSE, NULL);
	entry_set_string_prop (db, entry, RHYTHMDB_PROP_MIMETYPE, TRUE, "audio/x-raw-int");

	extra_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBAudioCDEntryData);
	extra_data->extract = TRUE;

	rhythmdb_commit (db);
	g_free (audio_path);

	return entry;
}