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); }
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; }
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; }