/**
 * rb_static_playlist_source_remove_location:
 * @source: an #RBStaticPlaylistSource
 * @location: location to remove
 *
 * Removes the specified location from the playlist.  This affects both
 * the location map and the query model, whether an entry exists for the
 * location or not.
 */
void
rb_static_playlist_source_remove_location (RBStaticPlaylistSource *source,
					   const char *location)
{
	RBPlaylistSource *psource = RB_PLAYLIST_SOURCE (source);
	RhythmDB *db;
	RhythmDBEntry *entry;

	g_return_if_fail (rb_playlist_source_location_in_map (psource, location));

	db = rb_playlist_source_get_db (psource);
	entry = rhythmdb_entry_lookup_by_location (db, location);

	if (entry != NULL) {
		RhythmDBQueryModel *model = rb_playlist_source_get_query_model (psource);

		/* if this fails, the model and the playlist are out of sync */
		g_assert (rhythmdb_query_model_remove_entry (model, entry));
		rb_playlist_source_mark_dirty (psource);
	}
}
/**
 * rb_static_playlist_source_add_location:
 * @source: an #RBStaticPlaylistSource
 * @location: location (URI) to add to the playlist
 * @index: position at which to add the location (-1 to add at the end)
 *
 * If the location matches an entry in the database, the entry is added
 * to the playlist.  Otherwise, if it identifies a directory, the contents
 * of that directory are added.
 */
void
rb_static_playlist_source_add_location (RBStaticPlaylistSource *source,
					const char *location,
					gint index)
{
	RhythmDB *db;
	RhythmDBEntry *entry;

	db = rb_playlist_source_get_db (RB_PLAYLIST_SOURCE (source));
	entry = rhythmdb_entry_lookup_by_location (db, location);

	/* if there is an entry, it won't be a directory */
	if (entry == NULL && rb_uri_is_directory (location))
		rb_uri_handle_recursively (location,
					   NULL,
					   (RBUriRecurseFunc) _add_location_cb,
					   source);
	else
		rb_static_playlist_source_add_location_internal (source, location, index);

}
static void
uri_recurse_func (GFile *file, gboolean dir, RhythmDBImportJob *job)
{
	RhythmDBEntry *entry;
	char *uri;

	if (dir) {
		return;
	}

	uri = g_file_get_uri (file);

	/* only add the entry to the map of entries we're waiting for
	 * if it's not already in the db.
	 */
	entry = rhythmdb_entry_lookup_by_location (job->priv->db, uri);
	if (entry == NULL) {
		rb_debug ("waiting for entry %s", uri);
		g_mutex_lock (&job->priv->lock);
		job->priv->total++;
		g_hash_table_insert (job->priv->outstanding, g_strdup (uri), GINT_TO_POINTER (1));

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

	rhythmdb_add_uri_with_types (job->priv->db,
				     uri,
				     job->priv->entry_type,
				     job->priv->ignore_type,
				     job->priv->error_type);
	g_free (uri);
}
gboolean
impl_receive_drag (RBDisplayPage *page, GtkSelectionData *data)
{
	GList *entries;
	RhythmDB *db;
	char *type;

	entries = NULL;
	type = gdk_atom_name (gtk_selection_data_get_data_type (data));
        db = get_db_for_source (RB_SOURCE (page));

	if (strcmp (type, "text/uri-list") == 0) {
		GList *list;
		GList *i;

		rb_debug ("parsing uri list");
		list = rb_uri_list_parse ((const char *) gtk_selection_data_get_data (data));

		for (i = list; i != NULL; i = g_list_next (i)) {
			char *uri;
			RhythmDBEntry *entry;

			if (i->data == NULL)
				continue;

			uri = i->data;
			entry = rhythmdb_entry_lookup_by_location (db, uri);

			if (entry == NULL) {
				/* add to the library */
				rb_debug ("received drop of unknown uri: %s", uri);
			} else {
				/* add to list of entries to copy */
				entries = g_list_prepend (entries, entry);
			}
			g_free (uri);
		}
		g_list_free (list);
	} else if (strcmp (type, "application/x-rhythmbox-entry") == 0) {
		char **list;
		char **i;

		rb_debug ("parsing entry ids");
		list = g_strsplit ((const char*) gtk_selection_data_get_data (data), "\n", -1);
		for (i = list; *i != NULL; i++) {
			RhythmDBEntry *entry;
			gulong id;

			id = atoi (*i);
			entry = rhythmdb_entry_lookup_by_id (db, id);
			if (entry != NULL)
				entries = g_list_prepend (entries, entry);
		}

		g_strfreev (list);
	} else {
		rb_debug ("received unknown drop type");
	}

	g_object_unref (db);
	g_free (type);

	if (entries) {
		entries = g_list_reverse (entries);
		if (rb_source_can_paste (RB_SOURCE (page))) {
			rb_source_paste (RB_SOURCE (page), entries);
		}
		g_list_free (entries);
	}

	return TRUE;
}
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;
}
Exemple #6
0
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");
}
static void
rhythmdb_directory_change_cb (GFileMonitor *monitor,
			      GFile *file,
			      GFile *other_file,
			      GFileMonitorEvent event_type,
			      RhythmDB *db)
{
	char *canon_uri;
	char *other_canon_uri = NULL;
	RhythmDBEntry *entry;

	canon_uri = g_file_get_uri (file);
	if (other_file != NULL) {
		other_canon_uri = g_file_get_uri (other_file);
	}

	rb_debug ("directory event %d for %s", event_type, canon_uri);

	switch (event_type) {
        case G_FILE_MONITOR_EVENT_CREATED:
		{
			gboolean in_library = FALSE;
			int i;

			if (!g_settings_get_boolean (db->priv->settings, "monitor-library"))
				break;

			if (rb_uri_is_hidden (canon_uri))
				break;

			/* ignore new files outside of the library locations */
			for (i = 0; db->priv->library_locations[i] != NULL; i++) {
				if (g_str_has_prefix (canon_uri, db->priv->library_locations[i])) {
					in_library = TRUE;
					break;
				}
			}

			if (!in_library)
				break;
		}

		/* process directories immediately */
		if (rb_uri_is_directory (canon_uri)) {
			actually_add_monitor (db, file, NULL);
			rhythmdb_add_uri (db, canon_uri);
		} else {
			add_changed_file (db, canon_uri);
		}
		break;
	case G_FILE_MONITOR_EVENT_CHANGED:
        case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
		if (rhythmdb_entry_lookup_by_location (db, canon_uri)) {
			add_changed_file (db, canon_uri);
		}
		break;
	case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
		/* hmm.. */
		break;
	case G_FILE_MONITOR_EVENT_DELETED:
		entry = rhythmdb_entry_lookup_by_location (db, canon_uri);
		if (entry != NULL) {
			g_hash_table_remove (db->priv->changed_files, entry->location);
			rhythmdb_entry_set_visibility (db, entry, FALSE);
			rhythmdb_commit (db);
		}
		break;
	case G_FILE_MONITOR_EVENT_MOVED:
		if (other_canon_uri == NULL) {
			break;
		}

		entry = rhythmdb_entry_lookup_by_location (db, other_canon_uri);
		if (entry != NULL) {
			rb_debug ("file move target %s already exists in database", other_canon_uri);
			entry = rhythmdb_entry_lookup_by_location (db, canon_uri);
			if (entry != NULL) {
				g_hash_table_remove (db->priv->changed_files, entry->location);
				rhythmdb_entry_set_visibility (db, entry, FALSE);
				rhythmdb_commit (db);
			}
		} else {
			entry = rhythmdb_entry_lookup_by_location (db, canon_uri);
			if (entry != NULL) {
				GValue v = {0,};
				g_value_init (&v, G_TYPE_STRING);
				g_value_set_string (&v, other_canon_uri);
				rhythmdb_entry_set_internal (db, entry, TRUE, RHYTHMDB_PROP_LOCATION, &v);
				g_value_unset (&v);
			}
		}
		break;
	case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
	case G_FILE_MONITOR_EVENT_UNMOUNTED:
	default:
		break;
	}

	g_free (canon_uri);
	g_free (other_canon_uri);
}
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);
}