Пример #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);
}
Пример #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");
}
Пример #4
0
static gboolean
uri_recurse_func (GFile *file, GFileInfo *info, RhythmDBImportJob *job)
{
	RhythmDBEntry *entry;
	char *uri;

	if (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE) == G_FILE_TYPE_DIRECTORY) {
		return TRUE;
	}

	if (g_cancellable_is_cancelled (job->priv->cancel))
		return FALSE;

	if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK)) {
		GFile *r;
		r = rb_file_resolve_symlink (file, NULL);
		if (r != NULL) {
			uri = g_file_get_uri (r);
			g_object_unref (r);
		} else {
			return FALSE;
		}
	} else {
		uri = g_file_get_uri (file);
	}

	/* if it's not already in the db, add it to the list of things to process */
	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_queue_push_tail (job->priv->outstanding, g_strdup (uri));

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

		maybe_start_more (job);

		g_mutex_unlock (&job->priv->lock);
	} else {
		/* skip it if it's a different entry type */
		RhythmDBEntryType *et;
		et = rhythmdb_entry_get_entry_type (entry);
		if (et == job->priv->entry_type ||
		    et == job->priv->ignore_type ||
		    et == job->priv->error_type) {
			rhythmdb_add_uri_with_types (job->priv->db,
						     uri,
						     job->priv->entry_type,
						     job->priv->ignore_type,
						     job->priv->error_type);
		}
	}

	g_free (uri);
	return TRUE;
}
Пример #5
0
/**
 * rb_transfer_target_check_category:
 * @target: an #RBTransferTarget
 * @entry: a #RhythmDBEntry to check
 *
 * This checks that the entry type of @entry is in a suitable
 * category for transfer.  This can be used to implement
 * @should_transfer.
 *
 * Return value: %TRUE if the entry is in a suitable category
 */
gboolean
rb_transfer_target_check_category (RBTransferTarget *target, RhythmDBEntry *entry)
{
	RhythmDBEntryCategory cat;
	RhythmDBEntryType *entry_type;

	entry_type = rhythmdb_entry_get_entry_type (entry);
	g_object_get (entry_type, "category", &cat, NULL);
	return (cat == RHYTHMDB_ENTRY_NORMAL);
}
static gboolean
check_entry_type (RBIRadioSource *source, RhythmDBEntry *entry)
{
	RhythmDBEntryType *entry_type;
	gboolean matches = FALSE;

	g_object_get (source, "entry-type", &entry_type, NULL);
	if (entry != NULL && rhythmdb_entry_get_entry_type (entry) == entry_type)
		matches = TRUE;
	g_object_unref (entry_type);

	return matches;
}
/**
 * _rb_source_check_entry_type:
 * @source: a #RBSource
 * @entry: a #RhythmDBEntry
 *
 * Checks if a database entry matches the entry type for the source.
 *
 * Return value: %TRUE if the entry matches the source's entry type.
 */
gboolean
_rb_source_check_entry_type (RBSource *source, RhythmDBEntry *entry)
{
	RhythmDBEntryType entry_type;
	gboolean ret = TRUE;

	g_object_get (source, "entry-type", &entry_type, NULL);
	if (entry_type != RHYTHMDB_ENTRY_TYPE_INVALID &&
	    rhythmdb_entry_get_entry_type (entry) != entry_type) {
		ret = FALSE;
	}
	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
	return ret;
}
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;
}
Пример #9
0
/**
 * _rb_source_check_entry_type:
 * @source: a #RBSource
 * @entry: a #RhythmDBEntry
 *
 * Checks if a database entry matches the entry type for the source.
 *
 * Return value: %TRUE if the entry matches the source's entry type.
 */
gboolean
_rb_source_check_entry_type (RBSource *source, RhythmDBEntry *entry)
{
	RhythmDBEntryType *entry_type;
	gboolean ret = TRUE;

	g_object_get (source, "entry-type", &entry_type, NULL);
	if (entry_type != NULL) {
		if (rhythmdb_entry_get_entry_type (entry) != entry_type) {
			ret = FALSE;
		}
		g_object_unref (entry_type);
	}
	return ret;
}
Пример #10
0
static gboolean
uri_recurse_func (GFile *file, gboolean dir, RhythmDBImportJob *job)
{
	RhythmDBEntry *entry;
	char *uri;

	if (dir) {
		return TRUE;
	}

	if (g_cancellable_is_cancelled (job->priv->cancel))
		return FALSE;

	uri = g_file_get_uri (file);

	/* if it's not already in the db, add it to the list of things to process */
	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_queue_push_tail (job->priv->outstanding, g_strdup (uri));

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

		maybe_start_more (job);

		g_mutex_unlock (&job->priv->lock);
	} else {
		/* skip it if it's a different entry type */
		RhythmDBEntryType *et;
		et = rhythmdb_entry_get_entry_type (entry);
		if (et == job->priv->entry_type ||
		    et == job->priv->ignore_type ||
		    et == job->priv->error_type) {
			rhythmdb_add_uri_with_types (job->priv->db,
						     uri,
						     job->priv->entry_type,
						     job->priv->ignore_type,
						     job->priv->error_type);
		}
	}

	g_free (uri);
	return TRUE;
}
Пример #11
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_track_transfer_batch_start:
 * @batch: a #RBTrackTransferBatch
 * @queue: the #RBTrackTransferQueue
 *
 * Starts the batch transfer.  Only to be called by the #RBTrackTransferQueue.
 */
void
_rb_track_transfer_batch_start (RBTrackTransferBatch *batch, GObject *queue)
{
	gboolean total_duration_valid;
	gboolean total_size_valid;
	gboolean origin_valid;
	guint64 filesize;
	gulong duration;
	RBSource *origin = NULL;
	RBShell *shell;
	GList *l;

	g_object_get (queue, "shell", &shell, NULL);

	/* calculate total duration and file size and figure out the
	 * origin source if we weren't given one to start with.
	 */
	total_duration_valid = TRUE;
	total_size_valid = TRUE;
	origin_valid = TRUE;
	for (l = batch->priv->entries; l != NULL; l = l->next) {
		RhythmDBEntry *entry = (RhythmDBEntry *)l->data;

		filesize = rhythmdb_entry_get_uint64 (entry, RHYTHMDB_PROP_FILE_SIZE);
		if (total_size_valid && filesize > 0) {
			batch->priv->total_size += filesize;
		} else {
			total_size_valid = FALSE;
			batch->priv->total_size = 0;
		}

		duration = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_DURATION);
		if (total_duration_valid && duration > 0) {
			batch->priv->total_duration += duration;
		} else {
			total_duration_valid = FALSE;
			batch->priv->total_duration = 0;
		}

		if (batch->priv->source == NULL) {
			RhythmDBEntryType *entry_type;
			RBSource *entry_origin;

			entry_type = rhythmdb_entry_get_entry_type (entry);
			entry_origin = rb_shell_get_source_by_entry_type (shell, entry_type);
			if (origin == NULL && origin_valid  == TRUE) {
				origin = entry_origin;
			} else if (origin != entry_origin) {
				origin = NULL;
				origin_valid = FALSE;
			}
		}
	}

	g_object_unref (shell);

	if (origin != NULL) {
		batch->priv->source = origin;
	}

	batch->priv->queue = RB_TRACK_TRANSFER_QUEUE (queue);
	batch->priv->cancelled = FALSE;
	batch->priv->total_fraction = 0.0;

	g_signal_emit (batch, signals[STARTED], 0);
	g_object_notify (G_OBJECT (batch), "task-progress");
	g_object_notify (G_OBJECT (batch), "task-detail");

	start_next (batch);
}
Пример #13
0
/**
 * rb_transfer_target_transfer:
 * @target: an #RBTransferTarget
 * @entries: (element-type RB.RhythmDBEntry): a #GList of entries to transfer
 * @defer: if %TRUE, don't start the transfer until
 *
 * Starts tranferring @entries to the target.  This returns the
 * #RBTrackTransferBatch that it starts, so the caller can track
 * the progress of the transfer, or NULL if the target doesn't
 * want any of the entries.
 *
 * Return value: (transfer full): an #RBTrackTransferBatch, or NULL
 */
RBTrackTransferBatch *
rb_transfer_target_transfer (RBTransferTarget *target, GList *entries, gboolean defer)
{
	RBTrackTransferQueue *xferq;
	RBTaskList *tasklist;
	RBShell *shell;
	GList *l;
	RhythmDBEntryType *our_entry_type;
	RBTrackTransferBatch *batch;
	gboolean start_batch = FALSE;

	g_object_get (target,
		      "shell", &shell,
		      "entry-type", &our_entry_type,
		      NULL);
	g_object_get (shell,
		      "track-transfer-queue", &xferq,
		      "task-list", &tasklist,
		      NULL);
	g_object_unref (shell);

	batch = g_object_steal_data (G_OBJECT (target), "transfer-target-batch");

	if (batch == NULL) {
		batch = rb_track_transfer_batch_new (NULL, NULL, G_OBJECT (target));

		g_signal_connect_object (batch, "get-dest-uri", G_CALLBACK (get_dest_uri_cb), target, 0);
		g_signal_connect_object (batch, "track-done", G_CALLBACK (track_done_cb), target, 0);
	} else {
		start_batch = TRUE;
	}

	for (l = entries; l != NULL; l = l->next) {
		RhythmDBEntry *entry;
		RhythmDBEntryType *entry_type;
		const char *location;

		entry = (RhythmDBEntry *)l->data;
		location = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
		entry_type = rhythmdb_entry_get_entry_type (entry);

		if (entry_type != our_entry_type) {
			if (rb_transfer_target_should_transfer (target, entry)) {
				rb_debug ("pasting entry %s", location);
				rb_track_transfer_batch_add (batch, entry);
				start_batch = TRUE;
			} else {
				rb_debug ("target doesn't want entry %s", location);
			}
		} else {
			rb_debug ("can't copy entry %s from the target to itself", location);
		}
	}
	g_object_unref (our_entry_type);

	if (start_batch) {
		if (defer) {
			g_object_set_data_full (G_OBJECT (target), "transfer-target-batch", g_object_ref (batch), g_object_unref);
		} else {
			GstEncodingTarget *encoding_target;
			char *name;
			char *label;

			g_object_get (target, "encoding-target", &encoding_target, NULL);
			g_object_set (batch, "encoding-target", encoding_target, NULL);
			gst_encoding_target_unref (encoding_target);

			g_object_get (target, "name", &name, NULL);
			label = g_strdup_printf (_("Transferring tracks to %s"), name);
			g_object_set (batch, "task-label", label, NULL);
			g_free (name);
			g_free (label);
			
			rb_task_list_add_task (tasklist, RB_TASK_PROGRESS (batch));

			rb_track_transfer_queue_start_batch (xferq, batch);
		}
	} else {
		g_object_unref (batch);
		batch = NULL;
	}
	g_object_unref (xferq);
	g_object_unref (tasklist);
	return batch;
}