static void
playlist_iter_func (GtkTreeModel *model,
		    GtkTreeIter *iter,
		    char **uri,
		    char **title,
		    gboolean *custom_title,
		    gpointer user_data)
{
	RhythmDBEntry *entry;

	gtk_tree_model_get (model, iter, 0, &entry, -1);

	if (uri != NULL) {
		*uri = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_LOCATION);
	}
	if (title != NULL) {
		*title = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE);
	}
	if (custom_title != NULL) {
		*custom_title = TRUE;
	}

	if (entry != NULL) {
		rhythmdb_entry_unref (entry);
	}
}
AudioscrobblerEntry *
rb_audioscrobbler_entry_create (RhythmDBEntry *rb_entry)
{
	AudioscrobblerEntry *as_entry = g_new0 (AudioscrobblerEntry, 1);

	as_entry->title = rhythmdb_entry_dup_string (rb_entry, RHYTHMDB_PROP_TITLE);
	as_entry->track = rhythmdb_entry_get_ulong (rb_entry, RHYTHMDB_PROP_TRACK_NUMBER);
	as_entry->artist = rhythmdb_entry_dup_string (rb_entry, RHYTHMDB_PROP_ARTIST);
	as_entry->album = rhythmdb_entry_dup_string (rb_entry, RHYTHMDB_PROP_ALBUM);
	if (strcmp (as_entry->album, _("Unknown")) == 0) {
		g_free (as_entry->album);
		as_entry->album = g_strdup ("");
	}

	as_entry->length = rhythmdb_entry_get_ulong (rb_entry, RHYTHMDB_PROP_DURATION);
	as_entry->mbid = rhythmdb_entry_dup_string (rb_entry, RHYTHMDB_PROP_MUSICBRAINZ_TRACKID);
	if (strcmp (as_entry->mbid, _("Unknown")) == 0) {
		g_free (as_entry->mbid);
		as_entry->mbid = g_strdup ("");
	}

	/*
	 * TODO: identify the source type.  we just use 'P' for everything for now.
	 * should use 'R' for iradio, 'P' for everything else except last.fm.
	 * for last.fm, we need to extract the recommendation key from the db entry's
	 * extra data (see RBLastfmTrackEntryData in rb-lastfm-source.c) and include
	 * that in the source info here.
	 */
	as_entry->source = g_strdup ("P");

	return as_entry;
}
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;
	}
}
static LIBMTP_track_t *
transfer_track (RBMtpSource *source,
		LIBMTP_mtpdevice_t *device,
		RhythmDBEntry *entry,
		const char *filename,
		guint64 filesize,
		const char *mimetype)
{
	LIBMTP_track_t *trackmeta = LIBMTP_new_track_t ();
	GDate d;
	int ret;

	trackmeta->title = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE);
	trackmeta->album = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ALBUM);
	trackmeta->artist = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ARTIST);
	trackmeta->genre = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_GENRE);
	trackmeta->filename = g_path_get_basename (filename);

	if (rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DATE) > 0) { /* Entries without a date returns 0, g_date_set_julian don't accept that */
		g_date_set_julian (&d, rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DATE));
		trackmeta->date	= gdate_to_char (&d);
	}
	trackmeta->tracknumber = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_TRACK_NUMBER);
	trackmeta->duration = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DURATION) * 1000;
	trackmeta->rating = rhythmdb_entry_get_double (entry, RHYTHMDB_PROP_RATING) * 20;
	trackmeta->usecount = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_PLAY_COUNT);
	trackmeta->filesize = filesize;
	if (mimetype == NULL) {
		mimetype = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MIMETYPE);
	}
	trackmeta->filetype = mimetype_to_filetype (source, mimetype);
	rb_debug ("using libmtp filetype %d (%s) for source media type %s",
		  trackmeta->filetype,
		  LIBMTP_Get_Filetype_Description (trackmeta->filetype),
		  mimetype);

#ifdef HAVE_LIBMTP_030
	ret = LIBMTP_Send_Track_From_File (device, filename, trackmeta, NULL, NULL);
#else
	ret = LIBMTP_Send_Track_From_File (device, filename, trackmeta, NULL, NULL, 0);
#endif
	rb_debug ("LIBMTP_Send_Track_From_File (%s) returned %d", filename, ret);
	if (ret != 0) {
		report_libmtp_errors (device, TRUE);
		LIBMTP_destroy_track_t (trackmeta);
		return NULL;
	}

	if (strcmp (trackmeta->album, _("Unknown")) != 0) {
		add_track_to_album (source, trackmeta->album, trackmeta);
	}

	return trackmeta;
}
static char *
impl_build_dest_uri (RBRemovableMediaSource *source,
		     RhythmDBEntry *entry,
		     const char *mimetype,
		     const char *extension)
{
	char* file = g_strdup_printf ("%s/%s-%s.%s", g_get_tmp_dir (),
				      rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ARTIST),
				      rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE),
				      extension);
	char* uri = g_filename_to_uri (file, NULL, NULL);
	g_free (file);
	return uri;
}
static char *
podcast_get_playback_uri (RhythmDBEntryType *entry_type, RhythmDBEntry *entry)
{
	if (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MOUNTPOINT) != NULL) {
		return rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_LOCATION);
	}
	return NULL;
}
static gboolean
burn_source_iter_func (GtkTreeModel *model,
                       GtkTreeIter  *iter,
                       char        **uri,
                       char        **artist,
                       char        **title,
                       gulong       *duration)
{
    RhythmDBEntry *entry;

    gtk_tree_model_get (model, iter, 0, &entry, -1);

    *uri = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_LOCATION);
    *title = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE);
    *artist = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ARTIST);
    *duration = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DURATION);

    return TRUE;
}
static void
missing_plugins_retry_cb (gpointer instance, gboolean installed, RhythmDBImportJob *job)
{
	GSList *retry = NULL;
	GSList *i;

	g_mutex_lock (&job->priv->lock);
	g_assert (job->priv->retried == FALSE);
	if (installed == FALSE) {
		rb_debug ("plugin installation was not successful; job complete");
		g_signal_emit (job, signals[COMPLETE], 0, job->priv->total);
	} else {
		job->priv->retried = TRUE;

		/* reset the job state to just show the retry information */
		job->priv->total = g_slist_length (job->priv->retry_entries);
		rb_debug ("plugin installation was successful, retrying %d entries", job->priv->total);
		job->priv->imported = 0;

		/* remove the import error entries and build the list of URIs to retry */
		for (i = job->priv->retry_entries; i != NULL; i = i->next) {
			RhythmDBEntry *entry = (RhythmDBEntry *)i->data;
			char *uri;

			uri = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_LOCATION);
			rhythmdb_entry_delete (job->priv->db, entry);

			g_hash_table_insert (job->priv->outstanding, g_strdup (uri), GINT_TO_POINTER (1));
			retry = g_slist_prepend (retry, uri);
		}
		rhythmdb_commit (job->priv->db);
		retry = g_slist_reverse (retry);
	}
	g_mutex_unlock (&job->priv->lock);

	for (i = retry; i != NULL; i = i->next) {
		char *uri = (char *)i->data;

		rhythmdb_add_uri_with_types (job->priv->db,
					     uri,
					     job->priv->entry_type,
					     job->priv->ignore_type,
					     job->priv->error_type);
	}

	rb_slist_deep_free (retry);
}
static void
save_playlist_entry (GtkTreeModel *model, GtkTreeIter *iter,
		     char **uri, char **title,
		     gboolean *custom_title,
		     RBGenericPlayerPlaylistSource *source)
{
	RBGenericPlayerPlaylistSourcePrivate *priv = GET_PRIVATE (source);
	RhythmDBEntry *entry;
	const char *host_uri;

	entry = rhythmdb_query_model_iter_to_entry (RHYTHMDB_QUERY_MODEL (model),
						    iter);
	if (entry == NULL) {
		return;
	}

	host_uri = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
	*uri = rb_generic_player_source_uri_to_playlist_uri (priv->player_source, host_uri);
	*title = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE);
	*custom_title = TRUE;
}
static void
missing_plugins_retry_cb (gpointer instance, gboolean installed, RhythmDBImportJob *job)
{
	GSList *i;

	g_mutex_lock (&job->priv->lock);
	g_assert (job->priv->retried == FALSE);
	if (installed == FALSE) {
		rb_debug ("plugin installation was not successful; job complete");
		job->priv->complete = TRUE;
		g_signal_emit (job, signals[COMPLETE], 0, job->priv->total);
		g_object_notify (G_OBJECT (job), "task-outcome");
	} else {
		job->priv->retried = TRUE;

		/* reset the job state to just show the retry information */
		job->priv->total = g_slist_length (job->priv->retry_entries);
		rb_debug ("plugin installation was successful, retrying %d entries", job->priv->total);
		job->priv->processed = 0;

		/* remove the import error entries and build the list of URIs to retry */
		for (i = job->priv->retry_entries; i != NULL; i = i->next) {
			RhythmDBEntry *entry = (RhythmDBEntry *)i->data;
			char *uri;

			uri = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_LOCATION);
			rhythmdb_entry_delete (job->priv->db, entry);

			g_queue_push_tail (job->priv->outstanding, g_strdup (uri));
		}
		rhythmdb_commit (job->priv->db);
	}

	maybe_start_more (job);

	g_mutex_unlock (&job->priv->lock);
}
Exemple #11
0
static void
prepare_encoder_sink_cb (RBEncoderFactory *factory,
			 const char *stream_uri,
			 GObject *sink,
			 RBMtpSource *source)
{
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	RhythmDBEntry *entry;
	RhythmDB *db;
	LIBMTP_track_t *track;
	char **bits;
	char *extension;
	LIBMTP_filetype_t filetype;
	gulong track_id;
	GDate d;
	char **folder_path;

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

	/* extract the entry ID, extension, and MTP filetype from the URI */
	bits = g_strsplit (stream_uri + strlen ("xrbmtp://"), "/", 3);
	track_id = strtoul (bits[0], NULL, 0);
	extension = g_strdup (bits[1]);
	filetype = strtoul (bits[2], NULL, 0);
	g_strfreev (bits);

	db = get_db_for_source (source);
	entry = rhythmdb_entry_lookup_by_id (db, track_id);
	g_object_unref (db);
	if (entry == NULL) {
		g_free (extension);
		return;
	}

	track = LIBMTP_new_track_t ();
	track->title = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE);
	track->album = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ALBUM);
	track->artist = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ARTIST);
	track->genre = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_GENRE);

	/* build up device filename */
	track->filename = g_strdup_printf ("%s - %s.%s",
					   rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST),
					   rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE),
					   extension);
	g_free (extension);

	/* construct folder path: artist/album */
	folder_path = g_new0 (char *, 3);
	folder_path[0] = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ALBUM_ARTIST);
	if (folder_path[0] == NULL || folder_path[0][0] == '\0') {
		g_free (folder_path[0]);
		folder_path[0] = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ARTIST);
	}
	folder_path[1] = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_ALBUM);

	/* ensure the filename is safe for FAT filesystems and doesn't contain slashes */
	sanitize_for_mtp (track->filename);
	sanitize_for_mtp (folder_path[0]);
	sanitize_for_mtp (folder_path[1]);

	if (rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DATE) > 0) {
		g_date_set_julian (&d, rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DATE));
		track->date = gdate_to_char (&d);
	}
	track->tracknumber = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_TRACK_NUMBER);
	track->duration = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DURATION) * 1000;
	track->rating = rhythmdb_entry_get_double (entry, RHYTHMDB_PROP_RATING) * 20;
	track->usecount = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_PLAY_COUNT);

	track->filetype = filetype;

	g_object_set (sink,
		      "device-thread", priv->device_thread,
		      "folder-path", folder_path,
		      "mtp-track", track,
		      NULL);
	rhythmdb_entry_unref (entry);
	g_strfreev (folder_path);

	g_hash_table_insert (priv->track_transfer_map, g_strdup (stream_uri), track);
}
static gboolean
start_next (RBTrackTransferBatch *batch)
{
	GstEncodingProfile *profile = NULL;

	if (batch->priv->cancelled == TRUE) {
		return FALSE;
	}

	if (batch->priv->entries == NULL) {
		/* guess we must be done.. */
		g_signal_emit (batch, signals[COMPLETE], 0);
		g_object_notify (G_OBJECT (batch), "task-outcome");
		return FALSE;
	}

	batch->priv->current_fraction = 0.0;

	rb_debug ("%d entries remain in the batch", g_list_length (batch->priv->entries));

	while ((batch->priv->entries != NULL) && (batch->priv->cancelled == FALSE)) {
		RhythmDBEntry *entry;
		guint64 filesize;
		gulong duration;
		double fraction;
		GList *n;
		char *media_type;
		char *extension;

		n = batch->priv->entries;
		batch->priv->entries = g_list_remove_link (batch->priv->entries, n);
		entry = (RhythmDBEntry *)n->data;
		g_list_free_1 (n);

		rb_debug ("attempting to transfer %s", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));

		/* calculate the fraction of the transfer that this entry represents */
		filesize = rhythmdb_entry_get_uint64 (entry, RHYTHMDB_PROP_FILE_SIZE);
		duration = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DURATION);
		if (batch->priv->total_duration > 0) {
			g_assert (duration > 0);	/* otherwise total_duration would be 0 */
			fraction = ((double)duration) / (double) batch->priv->total_duration;
		} else if (batch->priv->total_size > 0) {
			g_assert (filesize > 0);	/* otherwise total_size would be 0 */
			fraction = ((double)filesize) / (double) batch->priv->total_size;
		} else {
			int count = g_list_length (batch->priv->entries) +
				    g_list_length (batch->priv->done_entries) + 1;
			fraction = 1.0 / ((double)count);
		}

		profile = NULL;
		if (select_profile_for_entry (batch, entry, &profile, FALSE) == FALSE) {
			rb_debug ("skipping entry %s, can't find an encoding profile",
				  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
			rhythmdb_entry_unref (entry);
			batch->priv->total_fraction += fraction;
			continue;
		}

		if (profile != NULL) {
			media_type = rb_gst_encoding_profile_get_media_type (profile);
			extension = g_strdup (rb_gst_media_type_to_extension (media_type));

			rb_gst_encoding_profile_set_preset (profile, NULL);
			if (batch->priv->settings != NULL) {
				GVariant *preset_settings;
				char *active_preset;

				preset_settings = g_settings_get_value (batch->priv->settings,
									"media-type-presets");
				active_preset = NULL;
				g_variant_lookup (preset_settings, media_type, "s", &active_preset);

				rb_debug ("setting preset %s for media type %s",
					  active_preset, media_type);
				rb_gst_encoding_profile_set_preset (profile, active_preset);

				g_free (active_preset);
			}
		} else {
			media_type = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_MEDIA_TYPE);
			extension = g_strdup (rb_gst_media_type_to_extension (media_type));
			if (extension == NULL) {
				extension = get_extension_from_location (entry);
			}
		}

		g_free (batch->priv->current_dest_uri);
		batch->priv->current_dest_uri = NULL;
		g_signal_emit (batch, signals[GET_DEST_URI], 0,
			       entry,
			       media_type,
			       extension,
			       &batch->priv->current_dest_uri);
		g_free (media_type);
		g_free (extension);

		if (batch->priv->current_dest_uri == NULL) {
			rb_debug ("unable to build destination URI for %s, skipping",
				  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
			rhythmdb_entry_unref (entry);
			batch->priv->total_fraction += fraction;
			continue;
		}

		batch->priv->current = entry;
		batch->priv->current_entry_fraction = fraction;
		batch->priv->current_profile = profile;
		break;
	}

	if (batch->priv->current != NULL) {
		g_signal_emit (batch, signals[TRACK_STARTED], 0,
			       batch->priv->current,
			       batch->priv->current_dest_uri);
		start_encoding (batch, FALSE);
		g_object_notify (G_OBJECT (batch), "task-detail");
	}

	return TRUE;
}
Exemple #13
0
RBDAAPRecord *
rb_daap_record_new (RhythmDBEntry *entry)
{
	RBDAAPRecord *record = NULL;
	record = RB_DAAP_RECORD (g_object_new (RB_TYPE_DAAP_RECORD, NULL));

	/* When browsing, entry will be NULL because we will pull
	 * the metadata from the DAAP query. When sharing, entry will
	 * point to an existing entry from the Rhythmbox DB.
	 */
	if (entry) {
		gchar *ext;

		record->priv->filesize = rhythmdb_entry_get_uint64
						(entry, RHYTHMDB_PROP_FILE_SIZE);

		record->priv->location = rhythmdb_entry_dup_string
						(entry, RHYTHMDB_PROP_LOCATION);

		record->priv->title    = rhythmdb_entry_dup_string
						(entry, RHYTHMDB_PROP_TITLE);

		record->priv->artist   = rhythmdb_entry_dup_string
						(entry, RHYTHMDB_PROP_ARTIST);

		record->priv->album    = rhythmdb_entry_dup_string
						(entry, RHYTHMDB_PROP_ALBUM);

		/* Since we don't support album id's on Rhythmbox, "emulate" it */
		record->priv->albumid  = (gintptr) rhythmdb_entry_get_refstring
						(entry, RHYTHMDB_PROP_ALBUM);

		record->priv->genre    = rhythmdb_entry_dup_string
						(entry, RHYTHMDB_PROP_GENRE);

		/* FIXME: Support transcoding: */
		/* FIXME: we should use RHYTHMDB_PROP_MIMETYPE instead */
		ext = strrchr (record->priv->location, '.');
		if (ext == NULL) {
			ext = "mp3";
		} else {
			ext++;
		}
		record->priv->mediakind = DMAP_MEDIA_KIND_MUSIC;
		record->priv->real_format = g_strdup (ext);
		record->priv->format = g_strdup (record->priv->real_format);

		/* Only support songs */
		record->priv->mediakind = 1;

		record->priv->track    = rhythmdb_entry_get_ulong
						(entry, RHYTHMDB_PROP_TRACK_NUMBER);

		record->priv->duration = rhythmdb_entry_get_ulong
						(entry, RHYTHMDB_PROP_DURATION);

		record->priv->rating   = (gint) rhythmdb_entry_get_double
						(entry, RHYTHMDB_PROP_RATING);

		record->priv->year     = rhythmdb_entry_get_ulong
						(entry, RHYTHMDB_PROP_YEAR);

		record->priv->firstseen = rhythmdb_entry_get_ulong
						(entry, RHYTHMDB_PROP_FIRST_SEEN);

		record->priv->mtime     = rhythmdb_entry_get_ulong
						(entry, RHYTHMDB_PROP_MTIME);

		record->priv->disc      = rhythmdb_entry_get_ulong
						(entry, RHYTHMDB_PROP_DISC_NUMBER);

		record->priv->bitrate   = rhythmdb_entry_get_ulong
						(entry, RHYTHMDB_PROP_BITRATE);
	}

	return record;
}