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); }
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"); }
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); }
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); }
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); }
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; } }
/** * 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; }
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); }
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; }
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; }
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; }
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"); }
/** * 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); }
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; }
/** * 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; }