static RhythmDBEntry * create_entry (RhythmDB *db, const char *location, const char *name, const char *album, const char *artist, const char *genre) { RhythmDBEntry *entry; GValue val = {0, }; entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, location); g_assert (entry); g_value_init (&val, G_TYPE_STRING); g_value_set_static_string (&val, genre); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_GENRE, &val); g_value_unset (&val); g_value_init (&val, G_TYPE_STRING); g_value_set_static_string (&val, artist); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ARTIST, &val); g_value_unset (&val); g_value_init (&val, G_TYPE_STRING); g_value_set_static_string (&val, album); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ALBUM, &val); g_value_unset (&val); g_value_init (&val, G_TYPE_STRING); g_value_set_static_string (&val, name); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TITLE, &val); g_value_unset (&val); return entry; }
END_TEST START_TEST (test_rhythmdb_multiple) { RhythmDBEntry *entry1, *entry2, *entry3; /* add multiple entries */ entry1 = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///foo.mp3"); rhythmdb_commit (db); fail_unless (entry1 != NULL, "failed to create entry"); fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///foo.mp3") == entry1, "entry missing"); entry2 = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///bar.mp3"); rhythmdb_commit (db); fail_unless (entry2 != NULL, "failed to create entry"); fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///bar.mp3") == entry2, "entry missing"); entry3 = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///baz.mp3"); rhythmdb_commit (db); fail_unless (entry3 != NULL, "failed to create entry"); fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///baz.mp3") == entry3, "entry missing"); /* check they're still there */ fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///foo.mp3") == entry1, "entry missing"); fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///bar.mp3") == entry2, "entry missing"); fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///baz.mp3") == entry3, "entry missing"); /* remove the middle one and check again */ rhythmdb_entry_delete (db, entry2); rhythmdb_commit (db); fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///foo.mp3") == entry1, "entry missing"); fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///bar.mp3") == NULL, "entry not deleted"); fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///baz.mp3") == entry3, "entry missing"); /* and the others */ rhythmdb_entry_delete (db, entry1); rhythmdb_entry_delete (db, entry3); rhythmdb_commit (db); fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///foo.mp3") == NULL, "entry not deleted"); fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///bar.mp3") == NULL, "entry not deleted"); fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///baz.mp3") == NULL, "entry not deleted"); }
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"); }
END_TEST START_TEST (test_rhythmdb_modify_after_delete) { RhythmDBEntry *entry; GValue val = {0,}; entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///whee.ogg"); fail_unless (entry != NULL, "failed to create entry"); g_value_init (&val, G_TYPE_STRING); g_value_set_static_string (&val, "Anything"); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_GENRE, &val); g_value_unset (&val); g_value_init (&val, G_TYPE_STRING); g_value_set_static_string (&val, "Nothing"); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ARTIST, &val); g_value_unset (&val); g_value_init (&val, G_TYPE_STRING); g_value_set_static_string (&val, "Something"); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ALBUM, &val); g_value_unset (&val); g_value_init (&val, G_TYPE_STRING); g_value_set_static_string (&val, "Thing"); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TITLE, &val); g_value_unset (&val); rhythmdb_commit (db); rhythmdb_entry_ref (entry); rhythmdb_entry_delete (db, entry); rhythmdb_commit (db); g_value_init (&val, G_TYPE_STRING); g_value_set_static_string (&val, "Something Else"); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ALBUM, &val); g_value_unset (&val); rhythmdb_commit (db); rhythmdb_entry_unref (entry); }
END_TEST /* this tests that chained query models, where the base shows hidden entries * forwards visibility changes correctly. This is basically what static playlists do */ START_TEST (test_hidden_chain_filter) { RhythmDBQueryModel *base_model; RhythmDBQueryModel *filter_model; RhythmDBQuery *query; RhythmDBEntry *entry; GtkTreeIter iter; GValue val = {0,}; start_test_case (); /* setup */ base_model = rhythmdb_query_model_new_empty (db); g_object_set (base_model, "show-hidden", TRUE, NULL); filter_model = rhythmdb_query_model_new_empty (db); g_object_set (filter_model, "base-model", base_model, NULL); query = g_ptr_array_new (); g_object_set (filter_model, "query", query, NULL); rhythmdb_query_free (query); entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///whee.ogg"); rhythmdb_commit (db); g_value_init (&val, G_TYPE_BOOLEAN); /* add entry to base, should be in both */ rhythmdb_query_model_add_entry (base_model, entry, -1); fail_unless (rhythmdb_query_model_entry_to_iter (base_model, entry, &iter)); fail_unless (rhythmdb_query_model_entry_to_iter (filter_model, entry, &iter)); end_step (); /* hide entry, should be in base and not filtered */ g_value_set_boolean (&val, TRUE); set_waiting_signal (G_OBJECT (db), "entry-changed"); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_HIDDEN, &val); rhythmdb_commit (db); wait_for_signal (); fail_unless (rhythmdb_query_model_entry_to_iter (base_model, entry, &iter)); fail_if (rhythmdb_query_model_entry_to_iter (filter_model, entry, &iter)); end_step (); /* show entry again, should be in both */ g_value_set_boolean (&val, FALSE); set_waiting_signal (G_OBJECT (db), "entry-changed"); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_HIDDEN, &val); rhythmdb_commit (db); wait_for_signal (); fail_unless (rhythmdb_query_model_entry_to_iter (base_model, entry, &iter)); fail_unless (rhythmdb_query_model_entry_to_iter (filter_model, entry, &iter)); end_step (); /* tidy up */ rhythmdb_entry_delete (db, entry); g_object_unref (base_model); g_object_unref (filter_model); g_value_unset (&val); end_test_case (); }
static RhythmDBEntry * add_mtp_track_to_db (RBMtpSource *source, RhythmDB *db, LIBMTP_track_t *track) { RhythmDBEntry *entry = NULL; RhythmDBEntryType *entry_type; RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source); char *name = NULL; /* ignore everything except audio (allow audio/video types too, since they're probably pretty common) */ if (!(LIBMTP_FILETYPE_IS_AUDIO (track->filetype) || LIBMTP_FILETYPE_IS_AUDIOVIDEO (track->filetype))) { rb_debug ("ignoring non-audio item %d (filetype %s)", track->item_id, LIBMTP_Get_Filetype_Description (track->filetype)); return NULL; } /* Set URI */ g_object_get (G_OBJECT (source), "entry-type", &entry_type, NULL); name = g_strdup_printf ("xrbmtp://%i/%s", track->item_id, track->filename); entry = rhythmdb_entry_new (RHYTHMDB (db), entry_type, name); g_free (name); g_object_unref (entry_type); if (entry == NULL) { rb_debug ("cannot create entry %i", track->item_id); g_object_unref (G_OBJECT (db)); return NULL; } /* Set track number */ if (track->tracknumber != 0) { GValue value = {0, }; g_value_init (&value, G_TYPE_ULONG); g_value_set_ulong (&value, track->tracknumber); rhythmdb_entry_set (RHYTHMDB (db), entry, RHYTHMDB_PROP_TRACK_NUMBER, &value); g_value_unset (&value); } /* Set length */ if (track->duration != 0) { GValue value = {0, }; g_value_init (&value, G_TYPE_ULONG); g_value_set_ulong (&value, track->duration/1000); rhythmdb_entry_set (RHYTHMDB (db), entry, RHYTHMDB_PROP_DURATION, &value); g_value_unset (&value); } /* Set file size */ if (track->filesize != 0) { GValue value = {0, }; g_value_init (&value, G_TYPE_UINT64); g_value_set_uint64 (&value, track->filesize); rhythmdb_entry_set (RHYTHMDB (db), entry, RHYTHMDB_PROP_FILE_SIZE, &value); g_value_unset (&value); } /* Set playcount */ if (track->usecount != 0) { GValue value = {0, }; g_value_init (&value, G_TYPE_ULONG); g_value_set_ulong (&value, track->usecount); rhythmdb_entry_set (RHYTHMDB (db), entry, RHYTHMDB_PROP_PLAY_COUNT, &value); g_value_unset (&value); } /* Set rating */ if (track->rating != 0) { GValue value = {0, }; g_value_init (&value, G_TYPE_DOUBLE); g_value_set_double (&value, track->rating/20); rhythmdb_entry_set (RHYTHMDB (db), entry, RHYTHMDB_PROP_RATING, &value); g_value_unset (&value); } /* Set release date */ if (track->date != NULL && track->date[0] != '\0') { GTimeVal tv; if (g_time_val_from_iso8601 (track->date, &tv)) { GDate d; GValue value = {0, }; g_value_init (&value, G_TYPE_ULONG); g_date_set_time_val (&d, &tv); g_value_set_ulong (&value, g_date_get_julian (&d)); rhythmdb_entry_set (RHYTHMDB (db), entry, RHYTHMDB_PROP_DATE, &value); g_value_unset (&value); } } /* Set title */ entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_TITLE, track->title); /* Set album, artist and genre from MTP */ entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_ARTIST, track->artist); entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_ALBUM, track->album); entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_GENRE, track->genre); g_hash_table_insert (priv->entry_map, entry, track); rhythmdb_commit (RHYTHMDB (db)); return entry; }
static RhythmDBEntry * rb_audiocd_create_track_entry (RBAudioCdSource *source, RhythmDB *db, guint track_number) { RhythmDBEntry *entry; RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source); char *audio_path; guint64 duration; GValue value = {0, }; gchar *str; RhythmDBEntryType entry_type; RBAudioCDEntryData *extra_data; audio_path = g_strdup_printf ("cdda://%d#%s", track_number, priv->device_path); g_object_get (G_OBJECT (source), "entry-type", &entry_type, NULL); rb_debug ("Audio CD - create entry for track %d from %s", track_number, audio_path); entry = rhythmdb_entry_new (db, entry_type, audio_path); g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type); if (entry == NULL) { g_free (audio_path); return NULL; } /* generate track # */ g_value_init (&value, G_TYPE_ULONG); g_value_set_ulong (&value, track_number); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TRACK_NUMBER, &value); g_value_unset (&value); /* generate track name */ g_value_init (&value, G_TYPE_STRING); str = g_strdup_printf (_("Track %u"), track_number); g_value_take_string (&value, str); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TITLE, &value); g_value_unset (&value); /* determine the duration * FIXME: http://bugzilla.gnome.org/show_bug.cgi?id=551011 */ if (gst_tag_list_get_uint64 (GST_CDDA_BASE_SRC(priv->cdda)->tracks[track_number - 1].tags, GST_TAG_DURATION, &duration)) { g_value_init (&value, G_TYPE_ULONG); g_value_set_ulong (&value, (gulong)(duration / GST_SECOND)); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DURATION, &value); g_value_unset (&value); } else { g_warning ("Failed to query cd track duration"); } entry_set_string_prop (db, entry, RHYTHMDB_PROP_ARTIST, FALSE, NULL); entry_set_string_prop (db, entry, RHYTHMDB_PROP_ALBUM, FALSE, NULL); entry_set_string_prop (db, entry, RHYTHMDB_PROP_GENRE, FALSE, NULL); entry_set_string_prop (db, entry, RHYTHMDB_PROP_MIMETYPE, TRUE, "audio/x-raw-int"); extra_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBAudioCDEntryData); extra_data->extract = TRUE; rhythmdb_commit (db); g_free (audio_path); return entry; }
static RhythmDBEntry * create_entry_for_media (RhythmDB *db, RhythmDBEntryType *entry_type, GrlData *data, GrlData *container) { RhythmDBEntry *entry; RBGriloEntryData *entry_data; entry = rhythmdb_entry_lookup_by_location (db, grl_media_get_url (GRL_MEDIA (data))); if (entry != NULL) { return entry; } rb_debug ("creating entry for %s / %s", grl_media_get_url (GRL_MEDIA (data)), grl_media_get_id (GRL_MEDIA (data))); entry = rhythmdb_entry_new (db, entry_type, grl_media_get_url (GRL_MEDIA (data))); /* just use the url? */ if (entry == NULL) { /* crap. */ return NULL; } set_string_prop_from_key (db, entry, RHYTHMDB_PROP_TITLE, data, GRL_METADATA_KEY_TITLE); set_string_prop_from_key (db, entry, RHYTHMDB_PROP_ALBUM, data, GRL_METADATA_KEY_ALBUM); set_string_prop_from_key (db, entry, RHYTHMDB_PROP_ARTIST, data, GRL_METADATA_KEY_ARTIST); set_string_prop_from_key (db, entry, RHYTHMDB_PROP_GENRE, data, GRL_METADATA_KEY_GENRE); set_string_prop_from_key (db, entry, RHYTHMDB_PROP_TITLE, data, GRL_METADATA_KEY_TITLE); if (grl_data_has_key (data, GRL_METADATA_KEY_PUBLICATION_DATE)) { /* something - grilo has this as a string? */ } if (grl_data_has_key (data, GRL_METADATA_KEY_BITRATE)) { GValue v = {0,}; g_value_init (&v, G_TYPE_ULONG); g_value_set_ulong (&v, grl_data_get_int (data, GRL_METADATA_KEY_BITRATE)); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_BITRATE, &v); g_value_unset (&v); } if (grl_data_has_key (data, GRL_METADATA_KEY_DURATION)) { /* this is probably in seconds */ GValue v = {0,}; g_value_init (&v, G_TYPE_ULONG); g_value_set_ulong (&v, grl_data_get_int (data, GRL_METADATA_KEY_DURATION)); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DURATION, &v); g_value_unset (&v); } if (grl_data_has_key (data, GRL_METADATA_KEY_MIME)) { const char *media_type; media_type = rb_gst_mime_type_to_media_type (grl_data_get_string (data, GRL_METADATA_KEY_MIME)); if (media_type) { GValue v = {0,}; g_value_init (&v, G_TYPE_STRING); g_value_set_string (&v, media_type); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_MEDIA_TYPE, &v); g_value_unset (&v); } } if (grl_data_has_key (data, GRL_METADATA_KEY_TRACK_NUMBER)) { GValue v = {0,}; g_value_init (&v, G_TYPE_ULONG); g_value_set_ulong (&v, grl_data_get_int (data, GRL_METADATA_KEY_TRACK_NUMBER)); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TRACK_NUMBER, &v); g_value_unset (&v); } /* rating and play count? */ entry_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBGriloEntryData); entry_data->grilo_data = g_object_ref (data); if (container != NULL) { entry_data->grilo_container = g_object_ref (container); } /* might want to consider batching this */ rhythmdb_commit (db); return entry; }
void rb_iradio_source_add_station (RBIRadioSource *source, const char *uri, const char *title, const char *genre) { RhythmDBEntry *entry; GValue val = { 0, }; char *real_uri = NULL; char *fixed_title; char *fixed_genre = NULL; RhythmDBEntryType *entry_type; real_uri = guess_uri_scheme (uri); if (real_uri) uri = real_uri; entry = rhythmdb_entry_lookup_by_location (source->priv->db, uri); if (entry) { rb_debug ("uri %s already in db", uri); g_free (real_uri); return; } g_object_get (source, "entry-type", &entry_type, NULL); entry = rhythmdb_entry_new (source->priv->db, entry_type, uri); g_object_unref (entry_type); if (entry == NULL) { g_free (real_uri); return; } g_value_init (&val, G_TYPE_STRING); if (title) { fixed_title = rb_make_valid_utf8 (title, '?'); } else { fixed_title = g_uri_unescape_string (uri, NULL); } g_value_take_string (&val, fixed_title); rhythmdb_entry_set (source->priv->db, entry, RHYTHMDB_PROP_TITLE, &val); g_value_reset (&val); if ((!genre) || (strcmp (genre, "") == 0)) { genre = _("Unknown"); } else { fixed_genre = rb_make_valid_utf8 (genre, '?'); genre = fixed_genre; } g_value_set_string (&val, genre); rhythmdb_entry_set (source->priv->db, entry, RHYTHMDB_PROP_GENRE, &val); g_value_unset (&val); g_free (fixed_genre); g_value_init (&val, G_TYPE_DOUBLE); g_value_set_double (&val, 0.0); rhythmdb_entry_set (source->priv->db, entry, RHYTHMDB_PROP_RATING, &val); g_value_unset (&val); rhythmdb_commit (source->priv->db); g_free (real_uri); }