Example #1
0
static void
playing_song_changed_cb (RBShellPlayer *player, RhythmDBEntry *entry, RBGriloPlugin *plugin)
{
	const char *uri;
	RhythmDBEntryType *entry_type;
	RBGriloEntryData *data;

	if (entry == NULL)
		return;

	entry_type = rhythmdb_entry_get_entry_type (entry);
	if (RB_IS_GRILO_ENTRY_TYPE (entry_type) == FALSE) {
		return;
	}

	data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBGriloEntryData);
	uri = grl_data_get_string (data->grilo_data, GRL_METADATA_KEY_THUMBNAIL);
	if (uri != NULL) {
		RBExtDBKey *key;

		key = rb_ext_db_key_create_storage ("album", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM));
		rb_ext_db_key_add_field (key, "artist", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST));

		rb_ext_db_store_uri (plugin->art_store,
				     key,
				     RB_EXT_DB_SOURCE_SEARCH,
				     uri);
		rb_ext_db_key_free (key);
	}
}
static void
entry_added_cb (RhythmDB *db,
		RhythmDBEntry *entry,
		RhythmDBImportJob *job)
{
	const char *uri;
	gboolean ours;

	uri = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);

	g_mutex_lock (&job->priv->lock);
	ours = g_hash_table_remove (job->priv->outstanding, uri);

	if (ours) {
		const char *details;

		job->priv->imported++;
		rb_debug ("got entry %s; %d now imported", uri, job->priv->imported);
		g_signal_emit (job, signals[ENTRY_ADDED], 0, entry);

		/* if it's an import error with missing plugins, add it to the retry list */
		details = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMMENT);
		if (rhythmdb_entry_get_entry_type (entry) == job->priv->error_type &&
		    (details != NULL && details[0] != '\0')) {
			rb_debug ("entry %s is an import error with missing plugin details: %s", uri, details);
			job->priv->retry_entries = g_slist_prepend (job->priv->retry_entries, rhythmdb_entry_ref (entry));
		}

		if (job->priv->status_changed_id == 0) {
			job->priv->status_changed_id = g_idle_add ((GSourceFunc) emit_status_changed, job);
		}
	}
	g_mutex_unlock (&job->priv->lock);
}
Example #3
0
END_TEST

START_TEST (test_rhythmdb_podcast_upgrade)
{
	RhythmDBEntry *entry;
	const char *mountpoint;

	/* load db with old podcasts setups */
	g_object_set (G_OBJECT (db), "name", SHARE_UNINSTALLED_DIR "/../tests/podcast-upgrade.xml", NULL);
	set_waiting_signal (G_OBJECT (db), "load-complete");
	rhythmdb_load (db);
	wait_for_signal ();

	entry = rhythmdb_entry_lookup_by_location (db, "file:///home/tester/Desktop/BBC%20Xtra/xtra_20080906-1226a.mp3");

	fail_unless (entry != NULL, "entry missing");
	fail_unless (rhythmdb_entry_get_entry_type (entry) == RHYTHMDB_ENTRY_TYPE_PODCAST_POST, "entry isn't a podcast");
	mountpoint = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MOUNTPOINT);

	fail_unless (mountpoint != NULL, "no mountpoint for podcast");
	fail_unless (strcmp (mountpoint, "http://downloads.bbc.co.uk/podcasts/worldservice/xtra/xtra_20080906-1226a.mp3") == 0, "wrong mountpoint for podcast");

	entry = rhythmdb_entry_lookup_by_location (db, "http://downloads.bbc.co.uk/podcasts/worldservice/xtra/xtra_20080903-1217a.mp3");
	fail_unless (entry != NULL, "entry not upgraded");
	fail_unless (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MOUNTPOINT) == NULL, "wrong mountpoint for podcast");
}
Example #4
0
static void
entry_activated_cb (RBEntryView *entry_view, RhythmDBEntry *entry, RBImportDialog *dialog)
{
	rb_debug ("import dialog entry %s activated", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
	rb_shell_load_uri (dialog->priv->shell,
			   rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION),
			   TRUE,
			   NULL);
}
Example #5
0
static void
episode_entry_activated_cb (RBEntryView *entry_view, RhythmDBEntry *entry, RBPodcastAddDialog *dialog)
{
	rb_debug ("search result podcast entry %s activated", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
	rb_shell_load_uri (dialog->priv->shell,
			   rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION),
			   TRUE,
			   NULL);
}
Example #6
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);
}
static gboolean
rb_static_playlist_source_filter_entry_drop (RhythmDBQueryModel *model,
					     RhythmDBEntry *entry, 
					     RBStaticPlaylistSource *source)
{
	if (_rb_source_check_entry_type (RB_SOURCE (source), entry)) {
		rb_debug ("allowing drop of entry %s", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
		return TRUE;
	}
	rb_debug ("preventing drop of entry %s", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
	return FALSE;
}
static void
update_track_info (MxLabel *label, RhythmDB *db, RhythmDBEntry *entry, const char *streaming_title)
{
    const char *title;
    ClutterActor *text;
    GString *str;

    text = mx_label_get_clutter_text (label);

    str = g_string_sized_new (100);
    if (entry == NULL) {
        g_string_append_printf (str, "<big>%s</big>", _("Not Playing"));
    } else {
        title = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE);

        if (streaming_title) {
            str_append_printf_escaped (str, "<big>%s</big>\n", streaming_title);
            str_append_printf_escaped (str, _("from <i>%s</i>"), title);
        } else {
            const char *artist_template = NULL;
            const char *album_template = NULL;
            const char *artist;
            const char *album;
            gboolean space = FALSE;

            artist = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST);
            album = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM);
            get_artist_album_templates (artist, album, &artist_template, &album_template);

            str_append_printf_escaped (str, "<big>%s</big>\n", title);

            if (album != NULL && album[0] != '\0') {
                str_append_printf_escaped (str, album_template, album);
                space = TRUE;
            }
            if (artist != NULL && artist[0] != '\0') {
                if (space) {
                    g_string_append_c (str, ' ');
                }
                str_append_printf_escaped (str, artist_template, artist);
            }
        }
    }

    /* tiny bit of extra padding */
    g_string_append (str, "  ");
    clutter_text_set_markup (CLUTTER_TEXT (text), str->str);
    clutter_text_set_ellipsize (CLUTTER_TEXT (text), PANGO_ELLIPSIZE_NONE);
    g_string_free (str, TRUE);
}
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);
}
Example #10
0
static void
impl_get_entries (RBMediaPlayerSource *source,
		  const char *category,
		  GHashTable *map)
{
	RhythmDBQueryModel *model;
	GtkTreeIter iter;
	gboolean podcast;

	/* we don't have anything else to distinguish podcasts from regular
	 * tracks, so just use the genre.
	 */
	podcast = (g_str_equal (category, SYNC_CATEGORY_PODCAST));

	g_object_get (source, "base-query-model", &model, NULL);
	if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter) == FALSE) {
		g_object_unref (model);
		return;
	}

	do {
		RhythmDBEntry *entry;
		const char *genre;
		entry = rhythmdb_query_model_iter_to_entry (model, &iter);
		genre = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE);
		if (g_str_equal (genre, "Podcast") == podcast) {
			_rb_media_player_source_add_to_map (map, entry);
		}
	} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter));

	g_object_unref (model);
}
static void
impl_save_contents_to_xml (RBPlaylistSource *source,
			   xmlNodePtr node)
{
	RBStaticPlaylistSourcePrivate *priv = RB_STATIC_PLAYLIST_SOURCE_GET_PRIVATE (source);
	GtkTreeIter iter;

	xmlSetProp (node, RB_PLAYLIST_TYPE, RB_PLAYLIST_STATIC);

	if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->base_model), &iter))
		return;

	do {
		xmlNodePtr child_node = xmlNewChild (node, NULL, RB_PLAYLIST_LOCATION, NULL);
		RhythmDBEntry *entry;
		xmlChar *encoded;
		const char *location;

		gtk_tree_model_get (GTK_TREE_MODEL (priv->base_model), &iter, 0, &entry, -1);

		location = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
		encoded = xmlEncodeEntitiesReentrant (NULL, BAD_CAST location);

		xmlNodeSetContent (child_node, encoded);

		g_free (encoded);
		rhythmdb_entry_unref (entry);
	} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->base_model), &iter));
}
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;
	}
}
Example #13
0
/**
 * rb_source_gather_selected_properties:
 * @source: a #RBSource
 * @prop: property for which to gather selection
 *
 * Returns a list containing the values of the specified
 * property from the selected entries in the source.
 * This is used to implement the 'browse this artist' (etc.)
 * actions.
 *
 * Return value: (element-type utf8) (transfer full): list of property values
 */
GList *
rb_source_gather_selected_properties (RBSource *source,
				      RhythmDBPropType prop)
{
	RBEntryView *entryview;
	GList *selected, *tem;
	GHashTable *selected_set;

	entryview = rb_source_get_entry_view (source);
	if (entryview == NULL)
		return NULL;

	selected_set = g_hash_table_new (g_str_hash, g_str_equal);
	selected = rb_entry_view_get_selected_entries (entryview);

	for (tem = selected; tem; tem = tem->next) {
		RhythmDBEntry *entry = tem->data;
		char *val = g_strdup (rhythmdb_entry_get_string (entry, prop));
		g_hash_table_insert (selected_set, val, NULL);
	}

	g_list_foreach (selected, (GFunc)rhythmdb_entry_unref, NULL);
	g_list_free (selected);

	tem = NULL;
	g_hash_table_foreach (selected_set, (GHFunc) rb_source_gather_hash_keys,
			      &tem);
	g_hash_table_destroy (selected_set);
	return tem;
}
Example #14
0
static void
missing_plugins_retry_cb (gpointer instance, gboolean installed, RBImportErrorsSource *source)
{
	GtkTreeIter iter;
	RhythmDBEntryType *error_entry_type;

	gtk_info_bar_set_response_sensitive (GTK_INFO_BAR (source->priv->infobar),
					     GTK_RESPONSE_OK,
					     TRUE);

	if (installed == FALSE) {
		rb_debug ("installer failed, not retrying imports");
		return;
	}

	g_object_get (source, "entry-type", &error_entry_type, NULL);

	do {
		RhythmDBEntry *entry;

		entry = rhythmdb_query_model_iter_to_entry (source->priv->missing_plugin_model, &iter);
		rhythmdb_add_uri_with_types (source->priv->db,
					     rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION),
					     source->priv->normal_entry_type,
					     source->priv->ignore_entry_type,
					     error_entry_type);
	} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (source->priv->missing_plugin_model), &iter));

	g_object_unref (error_entry_type);
}
Example #15
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;
}
Example #16
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);
}
static gboolean
save_playlist_foreach (GtkTreeModel *model,
		       GtkTreePath *path,
		       GtkTreeIter *iter,
		       SavePlaylistData *data)
{
	RBGenericPlayerPlaylistSourcePrivate *priv = GET_PRIVATE (data->source);
	RhythmDBEntry *entry;
	TotemPlPlaylistIter pl_iter;
	const char *host_uri;
	char *uri;

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

	host_uri = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
	uri = rb_generic_player_source_uri_to_playlist_uri (priv->player_source, host_uri, data->playlist_type);

	totem_pl_playlist_append (data->playlist, &pl_iter);
	totem_pl_playlist_set (data->playlist, &pl_iter, TOTEM_PL_PARSER_FIELD_URI, uri, NULL);
	set_field_from_property (data->playlist, &pl_iter, entry, RHYTHMDB_PROP_ARTIST, TOTEM_PL_PARSER_FIELD_AUTHOR);
	set_field_from_property (data->playlist, &pl_iter, entry, RHYTHMDB_PROP_GENRE, TOTEM_PL_PARSER_FIELD_GENRE);
	set_field_from_property (data->playlist, &pl_iter, entry, RHYTHMDB_PROP_ALBUM, TOTEM_PL_PARSER_FIELD_ALBUM);
	set_field_from_property (data->playlist, &pl_iter, entry, RHYTHMDB_PROP_TITLE, TOTEM_PL_PARSER_FIELD_TITLE);
	rhythmdb_entry_unref (entry);

	g_free (uri);
	return FALSE;
}
Example #18
0
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;
}
Example #19
0
END_TEST

START_TEST (test_rhythmdb_mirroring)
{
	GValue val = {0,};
	RhythmDBEntry *entry;
	const char *str;

	entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///foo.mp3");
	fail_unless (entry != NULL, "failed to create entry");

	/* check the last-played date is mirrored */
	g_value_init (&val, G_TYPE_ULONG);
	g_value_set_ulong (&val, 1354285);
	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_LAST_PLAYED, &val);
	g_value_unset (&val);
	rhythmdb_commit (db);

	str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LAST_PLAYED_STR);
	fail_unless (str && (strlen (str) > 0), "date not converted to string");

	/* check folded and sort-key varients */
	g_value_init (&val, G_TYPE_STRING);
	g_value_set_static_string (&val, "FOO");
	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TITLE, &val);
	g_value_unset (&val);
	rhythmdb_commit (db);

	str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE_SORT_KEY);
	fail_unless (str && (strlen (str) > 0), "sort-key not generated");
	str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE_FOLDED);
	fail_unless (str && (strcmp (str, "foo") == 0), "folded variant not generated");

	g_value_init (&val, G_TYPE_STRING);
	g_value_set_static_string (&val, "BAR");
	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TITLE, &val);
	g_value_unset (&val);
	rhythmdb_commit (db);

	str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE_SORT_KEY);
	fail_unless (str && (strlen (str) > 0), "sort-key not generated");
	str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE_FOLDED);
	fail_unless (str && (strcmp (str, "bar") == 0), "folded variant not generated");


}
Example #20
0
/**
 * rb_transfer_target_check_duplicate:
 * @target: an #RBTransferTarget
 * @entry: a #RhythmDBEntry to check
 *
 * This checks for an existing entry in the target that matches
 * the title, album, artist, and track number of the entry being
 * considered.  This can be used to implement @should_transfer.
 *
 * Return value: %TRUE if the entry already exists on the target.
 */
gboolean
rb_transfer_target_check_duplicate (RBTransferTarget *target, RhythmDBEntry *entry)
{
	RhythmDBEntryType *entry_type;
	RhythmDB *db;
	RBShell *shell;
	const char *title;
	const char *album;
	const char *artist;
	gulong track_number;
	GtkTreeModel *query_model;
	GtkTreeIter iter;
	gboolean is_dup;

	g_object_get (target, "shell", &shell, "entry-type", &entry_type, NULL);
	g_object_get (shell, "db", &db, NULL);
	g_object_unref (shell);

	query_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db));
	title = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE);
	album = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM);
	artist = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST);
	track_number = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_TRACK_NUMBER);
	rhythmdb_do_full_query (db, RHYTHMDB_QUERY_RESULTS (query_model),
				RHYTHMDB_QUERY_PROP_EQUALS,
				RHYTHMDB_PROP_TYPE, entry_type,
				RHYTHMDB_QUERY_PROP_EQUALS,
				RHYTHMDB_PROP_ARTIST, artist,
				RHYTHMDB_QUERY_PROP_EQUALS,
				RHYTHMDB_PROP_ALBUM, album,
				RHYTHMDB_QUERY_PROP_EQUALS,
				RHYTHMDB_PROP_TITLE, title,
				RHYTHMDB_QUERY_PROP_EQUALS,
				RHYTHMDB_PROP_TRACK_NUMBER, track_number,
				RHYTHMDB_QUERY_END);

	is_dup = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (query_model), &iter);
	g_object_unref (entry_type);
	g_object_unref (query_model);
	g_object_unref (db);
	if (is_dup) {
		rb_debug ("not transferring %lu - %s - %s - %s as already present",
			  track_number, title, album, artist);
	}
	return is_dup;
}
/**
 * rb_static_playlist_source_remove_entry:
 * @source: an #RBStaticPlaylistSource
 * @entry: the entry to remove
 *
 * Removes the specified entry from the playlist.
 */
void
rb_static_playlist_source_remove_entry (RBStaticPlaylistSource *source,
					RhythmDBEntry *entry)
{
	const char *location;

	location = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
	rb_static_playlist_source_remove_location (source, location);
}
void
rb_generic_player_source_trash_or_delete_entries (RBGenericPlayerSource *source,
						  GList *entries,
						  gboolean _delete)
{
	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
	GList *tem;

	if (priv->read_only != FALSE)
		return;

	for (tem = entries; tem != NULL; tem = tem->next) {
		RhythmDBEntry *entry;
		const char *uri;
		GFile *file;
		GFile *dir;

		entry = tem->data;
		uri = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
		file = g_file_new_for_uri (uri);
		if (_delete)
			g_file_delete (file, NULL, NULL);
		else
			g_file_trash (file, NULL, NULL);

		/* now walk up the directory structure and delete empty dirs
		 * until we reach the root or one of the device's audio folders.
		 */
		dir = g_file_get_parent (file);
		while (can_delete_directory (source, dir)) {
			GFile *parent;
			char *path;

			path = g_file_get_path (dir);
			rb_debug ("trying to delete %s", path);
			g_free (path);

			if (g_file_delete (dir, NULL, NULL) == FALSE) {
				break;
			}

			parent = g_file_get_parent (dir);
			if (parent == NULL) {
				break;
			}
			g_object_unref (dir);
			dir = parent;
		}

		g_object_unref (dir);
		g_object_unref (file);

		rhythmdb_entry_delete (priv->db, entry);
	}

	rhythmdb_commit (priv->db);
}
Example #23
0
static void
entry_added_cb (RhythmDB *db,
		RhythmDBEntry *entry,
		RhythmDBImportJob *job)
{
	const char *uri;
	GList *link;

	uri = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);

	g_mutex_lock (&job->priv->lock);
	link = g_queue_find_custom (job->priv->processing, uri, (GCompareFunc) g_strcmp0);

	if (link != NULL) {
		const char *details;
		RhythmDBEntryType *entry_type;

		entry_type = rhythmdb_entry_get_entry_type (entry);

		job->priv->processed++;

		if (entry_type == job->priv->entry_type) {
			job->priv->imported++;
			g_signal_emit (job, signals[ENTRY_ADDED], 0, entry);
		}
		rb_debug ("got entry %s; %d imported, %d processed", uri, job->priv->imported, job->priv->processed);

		/* if it's an import error with missing plugins, add it to the retry list */
		details = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_COMMENT);
		if (entry_type == job->priv->error_type &&
		    (details != NULL && details[0] != '\0')) {
			rb_debug ("entry %s is an import error with missing plugin details: %s", uri, details);
			job->priv->retry_entries = g_slist_prepend (job->priv->retry_entries, rhythmdb_entry_ref (entry));
		}

		if (job->priv->status_changed_id == 0) {
			job->priv->status_changed_id = g_idle_add ((GSourceFunc) emit_status_changed, job);
		}

		g_queue_delete_link (job->priv->processing, link);
		maybe_start_more (job);
	}
	g_mutex_unlock (&job->priv->lock);
}
/**
 * rb_static_playlist_source_add_entry:
 * @source: an #RBStaticPlaylistSource
 * @entry: entry to add to the playlist
 * @index: position at which to add it (-1 to add at the end)
 *
 * Adds the specified entry to the playlist.
 */
void
rb_static_playlist_source_add_entry (RBStaticPlaylistSource *source,
				     RhythmDBEntry *entry,
				     gint index)
{
	const char *location;

	location = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
	rb_static_playlist_source_add_location_internal (source, location, index);
}
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 void
set_field_from_property (TotemPlPlaylist *playlist,
			 TotemPlPlaylistIter *iter,
			 RhythmDBEntry *entry,
			 RhythmDBPropType property,
			 const char *field)
{
	const char *value;

	value = rhythmdb_entry_get_string (entry, property);
	if (value != NULL) {
		totem_pl_playlist_set (playlist, iter, field, value, NULL);
	}
}
static gboolean
visit_playlist_dirs (GFile *file,
		     gboolean dir,
		     RBGenericPlayerSource *source)
{
	char *basename;
	char *uri;
	RhythmDBEntry *entry;
	RhythmDBEntryType entry_type;
	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);

	if (dir) {
		return TRUE;
	}

	/* check if we've already got an entry 
	 * for this file, just to save some i/o.
	 */
	uri = g_file_get_uri (file);
	entry = rhythmdb_entry_lookup_by_location (priv->db, uri);
	g_free (uri);
	if (entry != NULL) {
		gboolean is_song;

		is_song = FALSE;

		g_object_get (source, "entry-type", &entry_type, NULL);
		is_song = (rhythmdb_entry_get_entry_type (entry) == entry_type);
		g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);

		if (is_song) {
			rb_debug ("%s was loaded as a song",
				  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
			return TRUE;
		}
	}

	basename = g_file_get_basename (file);
	if (strcmp (basename, ".is_audio_player") != 0) {
		char *playlist_path;
		playlist_path = g_file_get_path (file);
		load_playlist_file (source, playlist_path, basename);
		g_free (playlist_path);
	}

	g_free (basename);

	return TRUE;
}
Example #28
0
/**
 * rb_track_transfer_batch_check_media_types:
 * @batch: a #RBTrackTransferBatch
 *
 * Checks that all entries in the batch can be transferred in a format
 * supported by the destination.
 *
 * Return value: number of entries that cannot be transferred
 */
guint
rb_track_transfer_batch_check_media_types (RBTrackTransferBatch *batch)
{
	RBEncoder *encoder = rb_encoder_new ();
	guint count = 0;
	GList *l;

	for (l = batch->priv->entries; l != NULL; l = l->next) {
		RhythmDBEntry *entry = (RhythmDBEntry *)l->data;
		/* check that we can transfer this entry to the device */
		if (rb_encoder_get_media_type (encoder,
					       entry,
					       batch->priv->media_types,
					       NULL,
					       NULL) == FALSE) {
			rb_debug ("unable to transfer %s (media type %s)",
				  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION),
				  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MIMETYPE));
			count++;
		}
	}
	g_object_unref (encoder);
	return count;
}
static gboolean
copy_entry (RhythmDBQueryModel *model,
	    GtkTreePath *path,
	    GtkTreeIter *iter,
	    GList **list)
{
	RBAudioCDEntryData *extra_data;
	RhythmDBEntry *entry;
	GList *l;

	entry = rhythmdb_query_model_iter_to_entry (model, iter);
	extra_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBAudioCDEntryData);
	if (extra_data->extract) {
		rb_debug ("adding track %s to transfer list",
			  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
		l = g_list_append (*list, entry);
		*list = l;
	} else {
		rb_debug ("skipping track %s",
			  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
		rhythmdb_entry_unref (entry);
	}
	return FALSE;
}
static gboolean
song_can_sync_metadata (RhythmDBEntryType *entry_type,
			RhythmDBEntry *entry)
{
	const char *mimetype;
	gboolean can_sync;
	RhythmDB *db;

	g_object_get (entry_type, "db", &db, NULL);

	mimetype = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MIMETYPE);
	can_sync = rb_metadata_can_save (db->priv->metadata, mimetype);

	g_object_unref (db);
	return can_sync;
}