Beispiel #1
0
void
list_plugins (cli_infos_t *infos, xmmsc_result_t *res)
{
	const gchar *name, *desc, *err;
	xmmsv_t *val;

	val = xmmsc_result_get_value (res);

	if (!xmmsv_get_error (val, &err)) {
		xmmsv_list_iter_t *it;

		xmmsv_get_list_iter (val, &it);

		for (xmmsv_list_iter_first (it);
		     xmmsv_list_iter_valid (it);
		     xmmsv_list_iter_next (it)) {
			xmmsv_t *elem;

			xmmsv_list_iter_entry (it, &elem);
			xmmsv_dict_entry_get_string (elem, "shortname", &name);
			xmmsv_dict_entry_get_string (elem, "description", &desc);

			g_printf ("%s - %s\n", name, desc);
		}
	} else {
		g_printf (_("Server error: %s\n"), err);
	}

	xmmsc_result_unref (res);

	cli_infos_loop_resume (infos);
}
Beispiel #2
0
static gboolean
run_tests (xmms_medialib_t *medialib, xmmsv_t *testcases, xmms_test_predicate predicate,
           gint format, const gchar *datasetname)
{
	xmmsv_list_iter_t *it;
	xmmsv_t *dict;
	gboolean result = TRUE;

	xmmsv_get_list_iter (testcases, &it);
	while (xmmsv_list_iter_entry (it, &dict)) {
		xmmsv_t *content, *specification, *expected, *coll;
		const gchar *name;

		xmmsv_dict_entry_get_string (dict, "name", &name);

		xmmsv_dict_get (dict, "medialib", &content);
		xmmsv_dict_get (dict, "specification", &specification);
		xmmsv_dict_get (dict, "collection", &coll);
		xmmsv_dict_get (dict, "expected", &expected);

		result &= predicate (medialib, name, content, coll, specification,
		                     expected, format, datasetname);

		xmmsv_list_iter_next (it);
	}

	return result;
}
Beispiel #3
0
static void
run_tests (xmms_medialib_t *medialib, xmmsv_t *testcases, xmms_test_predicate predicate,
           gint format, const gchar *datasetname)
{
	xmmsv_list_iter_t *it;

	xmmsv_get_list_iter (testcases, &it);
	while (xmmsv_list_iter_valid (it)) {
		xmmsv_t *dict, *content, *specification, *holder, *expected;
		xmmsv_coll_t *coll;
		const gchar *name;
		dict = NULL;

		g_assert (xmmsv_list_iter_entry (it, &dict));

		xmmsv_dict_entry_get_string (dict, "name", &name);

		xmmsv_dict_get (dict, "medialib", &content);
		xmmsv_dict_get (dict, "specification", &specification);
		xmmsv_dict_get (dict, "collection", &holder);
		xmmsv_dict_get (dict, "expected", &expected);

		xmmsv_get_coll (holder, &coll);

		predicate (medialib, name, content, coll, specification,
		           expected, format, datasetname);

		xmmsv_list_iter_next (it);
	}
}
Beispiel #4
0
/* Extract the string value out of a xmmsv_t object. */
static const gchar *
value_get_dict_string (xmmsv_t *val, const gchar *key)
{
	const gchar *s;
	xmmsv_dict_entry_get_string (val, key, &s);
	return s;
}
Beispiel #5
0
static xmmsv_t *
parse_collection (xmmsv_t *dict)
{
	xmmsv_coll_type_t type = 0;
	xmmsv_t *coll;
	xmmsv_t *attributes, *operands, *list;
	const char *name;

	assert (xmmsv_is_type (dict, XMMSV_TYPE_DICT));
	xmmsv_dict_entry_get_string (dict, "type", &name);
	assert (collection_type_from_string (name, &type));

	coll = xmmsv_new_coll (type);

	if (xmmsv_dict_get (dict, "attributes", &attributes))
		parse_attributes (coll, attributes);

	if (xmmsv_dict_get (dict, "operands", &operands))
		parse_operands (coll, operands);

	if (xmmsv_dict_get (dict, "idlist", &list))
		parse_idlist (coll, list);

	return coll;
}
Beispiel #6
0
/**
 * Signals callback
 */
static void
xmms_playlist_updater_need_update (xmms_object_t *object, xmmsv_t *val,
                                   gpointer udata)
{
	xmms_playlist_updater_t *updater = (xmms_playlist_updater_t *) udata;
	const gchar *plname, *ns;

	if (xmmsv_dict_entry_get_string (val, "namespace", &ns)) {
		if (g_strcmp0 (ns, XMMS_COLLECTION_NS_PLAYLISTS) != 0) {
			return;
		}
	}

	if (!xmmsv_dict_entry_get_string (val, "name", &plname)) {
		return;
	}

	xmms_playlist_updater_push (updater, plname);
}
Beispiel #7
0
static void
on_collection_changed (xmms_object_t *object, xmmsv_t *val, gpointer udata)
{
	xmms_playlist_t *playlist = (xmms_playlist_t *) udata;
	const gchar *ns, *name;

	g_return_if_fail (playlist);
	g_return_if_fail (xmmsv_is_type (val, XMMSV_TYPE_DICT));
	g_return_if_fail (xmmsv_dict_entry_get_string (val, "namespace", &ns));

	if (strcmp (ns, XMMS_COLLECTION_NS_PLAYLISTS) != 0) {
		/* Not a playlist, not our concern... */
		return;
	}

	g_return_if_fail (xmmsv_dict_entry_get_string (val, "name", &name));

	XMMS_PLAYLIST_CHANGED_MSG (XMMS_PLAYLIST_CHANGED_UPDATE, 0, name);
}
Beispiel #8
0
static int
handle_stats (xmmsv_t *v, void *userdata)
{
	const gchar *tstr;

	if (xmmsv_dict_entry_get_string (v, "version", &tstr)) {
		server_version = g_strdup (tstr);
	}

	return TRUE;
}
static gint
update_active_playlist (xmmsv_t *val, void *udata)
{
	cli_infos_t *infos = (cli_infos_t *) udata;
	cli_cache_t *cache = infos->cache;
	xmmsc_result_t *refres;
	gint pos, newpos, type;
	gint id;
	const gchar *name;

	xmmsv_dict_entry_get_int (val, "type", &type);
	xmmsv_dict_entry_get_int (val, "position", &pos);
	xmmsv_dict_entry_get_int (val, "id", &id);
	xmmsv_dict_entry_get_string (val, "name", &name);

	/* Active playlist not changed, nevermind */
	if (strcmp (name, cache->active_playlist_name) != 0) {
		return TRUE;
	}

	/* Apply changes to the cached playlist */
	switch (type) {
	case XMMS_PLAYLIST_CHANGED_ADD:
		g_array_append_val (cache->active_playlist, id);
		break;

	case XMMS_PLAYLIST_CHANGED_INSERT:
		g_array_insert_val (cache->active_playlist, pos, id);
		break;

	case XMMS_PLAYLIST_CHANGED_MOVE:
		xmmsv_dict_entry_get_int (val, "newposition", &newpos);
		g_array_remove_index (cache->active_playlist, pos);
		g_array_insert_val (cache->active_playlist, newpos, id);
		break;

	case XMMS_PLAYLIST_CHANGED_REMOVE:
		g_array_remove_index (cache->active_playlist, pos);
		break;

	case XMMS_PLAYLIST_CHANGED_SHUFFLE:
	case XMMS_PLAYLIST_CHANGED_SORT:
	case XMMS_PLAYLIST_CHANGED_CLEAR:
		/* Oops, reload the whole playlist */
		refres = xmmsc_playlist_list_entries (infos->conn, XMMS_ACTIVE_PLAYLIST);
		xmmsc_result_notifier_set (refres, &refresh_active_playlist, infos->cache);
		xmmsc_result_unref (refres);
		freshness_requested (&cache->freshness_active_playlist);
		break;
	}

	return TRUE;
}
void plugin_config_setup (xmmsc_connection_t *con) 
{
    xmmsc_result_t* res;
    xmmsv_t *val;
    const gchar *err, *name;
    
    /* call only once */
    g_assert(plugins == NULL );

    /* get translation of plugins/configs */
    plugin_config_init_translation();

    /* get list of available plugins */
    res = xmmsc_main_list_plugins (con, XMMS_PLUGIN_TYPE_OUTPUT);
    /* we havn't entered async xmmsc_mainloop, so it's ok todo sync ops */
    xmmsc_result_wait (res);
    val = xmmsc_result_get_value (res);

    if (!xmmsv_get_error (val, &err)) {
	xmmsv_list_iter_t *it;

	xmmsv_get_list_iter (val, &it);
	for (xmmsv_list_iter_first (it);
	     xmmsv_list_iter_valid (it);
	     xmmsv_list_iter_next (it)) 
	{
	    xmmsv_t *elem;
	    Plugin *plugin;
	    xmmsv_list_iter_entry (it, &elem);
	    xmmsv_dict_entry_get_string (elem, "shortname", &name);

	    /* not blacklisted */
	    if ( g_strrstr( PLUGIN_BLACKLIST, name ) != NULL ) 
		continue;

	    plugin = g_slice_new( Plugin );
	    plugin->name = g_strdup(name);
	    plugin->config = NULL;
	    plugins = g_list_append(plugins, plugin);
	}
    } else {
	g_error ( "Server error: %s", err);
    }
    xmmsc_result_unref (res);

    /* get configuration options */
    res = xmmsc_config_list_values (con );
    xmmsc_result_wait (res);
    val = xmmsc_result_get_value (res);
    xmmsv_dict_foreach( val, plugin_config_setup_parameter, NULL);
        
}
Beispiel #11
0
static int
handle_config (xmmsv_t *v, void *userdata)
{
	const gchar *value;

	if (!xmmsv_dict_entry_get_string (v, "output.plugin", &value))
		return TRUE;

	g_free (output_plugin);
	output_plugin = g_strdup (value);

	return TRUE;
}
Beispiel #12
0
static gint
update_active_playlist_name (xmmsv_t *val, void *udata)
{
    cli_cache_t *cache = (cli_cache_t *) udata;
    gint type;
    const gchar *name, *newname;

    xmmsv_dict_entry_get_int (val, "type", &type);
    xmmsv_dict_entry_get_string (val, "name", &name);

    /* Active playlist have not been renamed */
    if (strcmp (name, cache->active_playlist_name) != 0) {
        return TRUE;
    }

    if (type == XMMS_COLLECTION_CHANGED_RENAME) {
        g_free (cache->active_playlist_name);
        xmmsv_dict_entry_get_string (val, "newname", &newname);
        cache->active_playlist_name = g_strdup (newname);
    }

    return TRUE;
}
Beispiel #13
0
static int
updater_config_changed (xmmsv_t *value, void *udata)
{
	updater_t *updater = (updater_t *) udata;
	const gchar *path;

	g_return_val_if_fail (updater, FALSE);

	if (xmmsv_dict_entry_get_string (value, "clients.mlibupdater.watch_dirs", &path)) {
		if (*path) {
			updater_switch_directory (updater, path);
		}
	}

	return TRUE;
}
Beispiel #14
0
static int
handle_config_changed (xmmsv_t *v, void *data)
{
	xmonitor_t *mon = data;
	const gchar *val = NULL;
	int s;

	s = xmmsv_dict_entry_get_string (v,
	                                 "clients.mlibupdater.watch_dirs",
	                                 &val);
	if (s) {
		do_watch_dir (mon, val);
	}

	return TRUE; /* keep broadcast alive */
}
Beispiel #15
0
/**
 * Recursively scan a directory for media files.
 *
 * @return a reverse sorted list of encoded urls
 */
static gboolean
process_dir (xmms_medialib_t *medialib, xmmsv_t *entries,
             const gchar *directory, xmms_error_t *error)
{
	xmmsv_list_iter_t *it;
	xmmsv_t *list, *val;

	list = xmms_xform_browse (directory, error);
	if (!list) {
		return FALSE;
	}

	xmmsv_get_list_iter (list, &it);

	while (xmmsv_list_iter_entry (it, &val)) {
		const gchar *str;
		gint isdir;

		xmmsv_dict_entry_get_string (val, "path", &str);
		xmmsv_dict_entry_get_int (val, "isdir", &isdir);

		if (isdir == 1) {
			process_dir (medialib, entries, str, error);
		} else {
			xmms_medialib_session_t *session;
			xmms_medialib_entry_t entry;

			do {
				session = xmms_medialib_session_begin (medialib);
				entry = xmms_medialib_entry_new_encoded (session, str, error);
			} while (!xmms_medialib_session_commit (session));

			if (entry) {
				xmmsv_coll_idlist_append (entries, entry);
			}
		}

		xmmsv_list_iter_remove (it);
	}

	xmmsv_unref (list);

	return TRUE;
}
Beispiel #16
0
static void
print_server_stats (xmmsc_result_t *res)
{
	gint uptime;
	const gchar *version, *err;

	xmmsv_t *val;

	val = xmmsc_result_get_value (res);

	if (!xmmsv_get_error (val, &err)) {
		xmmsv_dict_entry_get_string (val, "version", &version);
		xmmsv_dict_entry_get_int (val, "uptime", &uptime);
		g_printf ("uptime = %d\n"
		          "version = %s\n", uptime, version);
	} else {
		g_printf ("Server error: %s\n", err);
	}
}
Beispiel #17
0
void
xmms_playlist_changed_msg_send (xmms_playlist_t *playlist, xmmsv_t *dict)
{
	const gchar *plname;
	gint type;

	g_return_if_fail (playlist);
	g_return_if_fail (dict);

	/* If local playlist change, trigger a COLL_CHANGED signal */
	if (xmmsv_dict_entry_get_int (dict, "type", &type) &&
	    xmmsv_dict_entry_get_string (dict, "name", &plname) &&
	    type != XMMS_PLAYLIST_CHANGED_UPDATE) {
		XMMS_COLLECTION_PLAYLIST_CHANGED_MSG (playlist->colldag, plname);
	}

	xmms_object_emit (XMMS_OBJECT (playlist),
	                  XMMS_IPC_SIGNAL_PLAYLIST_CHANGED,
	                  dict);
}
Beispiel #18
0
static int
handle_mediainfo (xmmsv_t *v, void *userdata)
{
	static const gchar *props[] = {"chain", NULL};
	static const gchar *pref[] = {"server", NULL};
	GString *str;
	const gchar *tstr;
	gint tint, i;
	xmmsv_t *dict;

	str = g_string_new ("");

	/* convert propdict to dict */
	dict = xmmsv_propdict_to_dict (v, pref);

	for (i = 0; props[i]; i++) {
		switch (xmmsv_dict_entry_get_type (dict, props[i])) {
		case XMMSV_TYPE_STRING:
			if (xmmsv_dict_entry_get_string (dict, props[i], &tstr)) {
				g_string_append_printf (str, "%s=%s\n", props[i], tstr);
			}
			break;
		case XMMSV_TYPE_INT32:
			if (xmmsv_dict_entry_get_int (dict, props[i], &tint)) {
				g_string_append_printf (str, "%s=%d\n", props[i], tint);
			}
			break;
		default:
			/* noop */
			break;
		}
	}

	send_msg ("New media", str);

	g_string_free (str, TRUE);
	return TRUE; /* keep broadcast alive */
}
Beispiel #19
0
static gint
normalize_aggregate_function (xmmsv_t *fetch, xmms_error_t *err)
{
	const gchar *name;
	guint32 aggregate;

	if (xmmsv_dict_entry_get_type (fetch, "aggregate") == XMMSV_TYPE_NONE) {
		xmmsv_dict_set_string (fetch, "aggregate", "first");
	}

	/* Default to first as the aggregation function */
	if (!xmmsv_dict_entry_get_string (fetch, "aggregate", &name)) {
		xmms_error_set (err, XMMS_ERROR_INVAL, "'aggregate' must be a string.");
		return -1;
	}

	if (!aggregate_value_from_string (name, &aggregate)) {
		const gchar *message = "'aggregate' must be 'first', 'sum', 'max', 'min', 'list', 'set', 'random', or 'avg'";
		xmms_error_set (err, XMMS_ERROR_INVAL, message);
		return -1;
	}

	return aggregate;
}
Beispiel #20
0
/**
 * Converts a fetch specification in xmmsv_t form into a
 * fetch_spec_t structure
 */
xmms_fetch_spec_t *
xmms_fetch_spec_new (xmmsv_t *fetch, xmms_fetch_info_t *info,
                     s4_sourcepref_t *prefs, xmms_error_t *err)
{
	const char *type;

	if (xmmsv_get_type (fetch) != XMMSV_TYPE_DICT) {
		xmms_error_set (err, XMMS_ERROR_INVAL, "A fetch specification must be a dict.");
		return NULL;
	}

	if (xmmsv_dict_entry_get_type (fetch, "type") == XMMSV_TYPE_NONE) {
		xmmsv_dict_set_string (fetch, "type", "metadata");
	}

	if (!xmmsv_dict_entry_get_string (fetch, "type", &type)) {
		xmms_error_set (err, XMMS_ERROR_INVAL, "A fetch specification must have a type.");
		return NULL;
	}

	if (strcmp (type, "metadata") == 0) {
		return xmms_fetch_spec_new_metadata (fetch, info, prefs, err);
	} else if (strcmp (type, "cluster-list") == 0) {
		return xmms_fetch_spec_new_cluster_list (fetch, info, prefs, err);
	} else if (strcmp (type, "cluster-dict") == 0) {
		return xmms_fetch_spec_new_cluster_dict (fetch, info, prefs, err);
	} else if (strcmp (type, "organize") == 0) {
		return xmms_fetch_spec_new_organize (fetch, info, prefs, err);
	} else if (strcmp (type, "count") == 0) {
		return xmms_fetch_spec_new_count (fetch, info, prefs, err);
	}

	xmms_error_set (err, XMMS_ERROR_INVAL, "Unknown fetch type.");

	return NULL;
}
Beispiel #21
0
/**
 * TODO: Should check for '/' in the key, and set source if found.
 */
static void
populate_medialib (xmms_medialib_t *medialib, xmmsv_t *content)
{
	xmms_medialib_session_t *session;
	xmms_medialib_entry_t entry = 0;
	xmmsv_list_iter_t *lit;

	session = xmms_medialib_session_begin (medialib);

	xmmsv_get_list_iter (content, &lit);
	while (xmmsv_list_iter_valid (lit)) {
		xmmsv_dict_iter_t *dit;
		xmms_error_t err;
		xmmsv_t *dict;

		xmms_error_reset (&err);

		xmmsv_list_iter_entry (lit, &dict);

		if (xmmsv_dict_has_key (dict, "url")) {
			const gchar *url;
			xmmsv_dict_entry_get_string (dict, "url", &url);
			entry = xmms_medialib_entry_new (session, url, &err);
		} else {
			gchar *url;
			url = g_strdup_printf ("file://%d.mp3", entry + 1);
			entry = xmms_medialib_entry_new (session, url, &err);
			g_free (url);
		}

		xmmsv_get_dict_iter (dict, &dit);

		while (xmmsv_dict_iter_valid (dit)) {
			const gchar *key, *source;
			gchar **parts;
			xmmsv_t *container;

			xmmsv_dict_iter_pair (dit, &key, &container);

			parts = g_strsplit (key, "/", 2);

			key = (parts[1] != NULL) ? parts[1] : key;
			source = (parts[1] != NULL) ? parts[0] : NULL;

			if (xmmsv_is_type (container, XMMSV_TYPE_STRING)) {
				const gchar *value;

				xmmsv_get_string (container, &value);

				if (source != NULL) {
					xmms_medialib_entry_property_set_str_source (session, entry, key, value, source);
				} else {
					xmms_medialib_entry_property_set_str (session, entry, key, value);
				}
			} else {
				gint32 value;

				xmmsv_get_int (container, &value);

				if (source != NULL) {
					xmms_medialib_entry_property_set_int_source (session, entry, key, value, source);
				} else {
					xmms_medialib_entry_property_set_int (session, entry, key, value);
				}
			}

			g_strfreev (parts);

			xmmsv_dict_iter_next (dit);
		}

		xmmsv_list_iter_next (lit);
	}

	xmms_medialib_session_commit (session);
}
Beispiel #22
0
/**
 * Retrieve a string attribute from the given collection.
 *
 * @param coll The collection to retrieve the attribute from.
 * @param key  The name of the attribute.
 * @param value The value of the attribute if found (owned by the collection).
 * @return 1 if the attribute was found, 0 otherwise
 */
int
xmmsv_coll_attribute_get_string (xmmsv_t *coll, const char *key, const char **value)
{
	x_return_val_if_fail (xmmsv_is_type (coll, XMMSV_TYPE_COLL), 0);
	return xmmsv_dict_entry_get_string (coll->value.coll->attributes, key, value);
}
Beispiel #23
0
void
format_pretty_list (xmmsc_connection_t *conn, GList *list)
{
	guint count = 0;
	GList *n;
	gint columns;
	gchar *format_header, *format_rows;

	columns = find_terminal_width ();
	format_header = make_justified_columns_format (columns, 's');
	format_rows   = make_justified_columns_format (columns, 'd');

	print_padded_string (columns, '-', TRUE, "-[Result]-");
	print_info (format_header, "Id", "Artist", "Album", "Title");

	for (n = list; n; n = g_list_next (n)) {
		const gchar *title;
		xmmsc_result_t *res;
		xmmsv_t *propdict, *val;
		gint mid = XPOINTER_TO_INT (n->data);

		if (!mid) {
			print_error ("Empty result!");
		}

		res = xmmsc_medialib_get_info (conn, mid);
		xmmsc_result_wait (res);
		propdict = xmmsc_result_get_value (res);
		val = xmmsv_propdict_to_dict (propdict, NULL);

		if (xmmsv_dict_entry_get_string (val, "title", &title)) {
			const gchar *artist, *album;
			if (!xmmsv_dict_entry_get_string (val, "artist", &artist)) {
				artist = "Unknown";
			}

			if (!xmmsv_dict_entry_get_string (val, "album", &album)) {
				album = "Unknown";
			}

			print_info (format_rows, mid, artist, album, title);
		} else {
			const gchar *url;
			xmmsv_dict_entry_get_string (val, "url", &url);
			if (url) {
				gchar *filename = g_path_get_basename (url);
				if (filename) {
					print_info ("%-5.5d| %s", mid, filename);
					g_free (filename);
				}
			}
		}

		count++;

		xmmsv_unref (val);
		xmmsc_result_unref (res);
	}

	print_padded_string (columns, '-', FALSE, "-[Count:%6.d]-----", count);

	g_free (format_header);
	g_free (format_rows);
}
Beispiel #24
0
/**
 * Decodes a cluster fetch specification from a dictionary.
 * The 'cluster-by' must be one of 'id', 'position' or 'value'. If set
 * to 'value', then an additional 'cluster-field' will be used to specify
 * which meta data attribute to cluster on.
 */
static xmms_fetch_spec_t *
xmms_fetch_spec_new_cluster (xmmsv_t *fetch, xmms_fetch_info_t *info,
                             s4_sourcepref_t *prefs, xmms_error_t *err)
{
	xmmsv_t *cluster_by, *cluster_field, *cluster_data;
	xmms_fetch_spec_t *data, *spec = NULL;
	s4_sourcepref_t *sp;
	const gchar *value = NULL;
	const gchar *field = NULL;
	const gchar *fallback = NULL;
	gint cluster_type;

	if (!xmmsv_dict_get (fetch, "cluster-by", &cluster_by)) {
		cluster_by = xmmsv_new_string ("value");
		xmmsv_dict_set (fetch, "cluster-by", cluster_by);
		xmmsv_unref (cluster_by);
	}

	if (!xmmsv_dict_entry_get_string (fetch, "cluster-by", &value)) {
		const gchar *message = "'cluster-by' must be a string.";
		xmms_error_set (err, XMMS_ERROR_INVAL, message);
		return NULL;
	}

	xmmsv_get_string (cluster_by, &value);

	if (!cluster_by_from_string (value, &cluster_type)) {
		const gchar *message = "'cluster-by' must be 'id', 'position', or 'value'.";
		xmms_error_set (err, XMMS_ERROR_INVAL, message);
		return NULL;
	}

	if (cluster_type == CLUSTER_BY_VALUE) {
		if (!xmmsv_dict_entry_get_string (fetch, "cluster-field", &field)) {
			const gchar *message = "'cluster-field' must  if 'cluster-by' is 'value'.";
			xmms_error_set (err, XMMS_ERROR_INVAL, message);
			return NULL;
		}
	}

	if (!xmmsv_dict_get (fetch, "data", &cluster_data)) {
		const gchar *message = "Required field 'data' not set in cluster.";
		xmms_error_set (err, XMMS_ERROR_INVAL, message);
		return NULL;
	}

	if (xmmsv_dict_entry_get_type (fetch, "cluster-fallback") == XMMSV_TYPE_NONE) {
		fallback = NULL;
	} else if (!xmmsv_dict_entry_get_string (fetch, "cluster-fallback", &fallback)) {
		const gchar *message = "Optional field 'default' must be a string.";
		xmms_error_set (err, XMMS_ERROR_INVAL, message);
		return NULL;
	}

	sp = normalize_source_preferences (fetch, prefs, err);
	if (xmms_error_iserror (err)) {
		return NULL;
	}

	data = xmms_fetch_spec_new (cluster_data, info, sp, err);
	if (xmms_error_iserror (err)) {
		s4_sourcepref_unref (sp);
		return NULL;
	}

	spec = g_new0 (xmms_fetch_spec_t, 1);
	spec->data.cluster.data = data;
	spec->data.cluster.type = cluster_type;
	spec->data.cluster.fallback = fallback;

	switch (spec->data.cluster.type) {
		case CLUSTER_BY_ID:
			spec->data.cluster.column = xmms_fetch_info_add_song_id(info, cluster_field);
			break;
		case CLUSTER_BY_VALUE:
			xmmsv_dict_get (fetch, "cluster-field", &cluster_field);
			spec->data.cluster.column = xmms_fetch_info_add_key (info, cluster_field,
			                                                     field, sp);
			break;
		case CLUSTER_BY_POSITION:
			/* do nothing */
			break;
		default:
			g_assert_not_reached ();
	}

	s4_sourcepref_unref (sp);

	return spec;
}
Beispiel #25
0
void
cmd_list (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	gchar *playlist = NULL;
	xmmsc_result_t *res;
	xmmsv_t *val;
	xmmsv_list_iter_t *it;
	gulong total_playtime = 0;
	gint p = 0;
	guint pos = 0;

	if (argc > 2) {
		playlist = argv[2];
	}

	res = xmmsc_playlist_current_pos (conn, playlist);
	xmmsc_result_wait (res);
	val = xmmsc_result_get_value (res);

	if (!xmmsv_is_error (val)) {
		if (!xmmsv_dict_entry_get_int (val, "position", &p)) {
			print_error ("Broken resultset");
		}
		xmmsc_result_unref (res);
	}

	res = xmmsc_playlist_list_entries (conn, playlist);
	xmmsc_result_wait (res);
	val = xmmsc_result_get_value (res);

	if (xmmsv_is_error (val)) {
		print_error ("%s", xmmsv_get_error_old (val));
	}

	xmmsv_get_list_iter (val, &it);
	while (xmmsv_list_iter_valid (it)) {
		xmmsc_result_t *info_res;
		xmmsv_t *val_id, *propdict, *info_val;
		gchar line[80];
		gint playtime = 0;
		guint ui;

		xmmsv_list_iter_entry (it, &val_id);
		if (!xmmsv_get_uint (val_id, &ui)) {
			print_error ("Broken resultset");
		}

		info_res = xmmsc_medialib_get_info (conn, ui);
		xmmsc_result_wait (info_res);
		propdict = xmmsc_result_get_value (info_res);
		info_val = xmmsv_propdict_to_dict (propdict, NULL);

		if (xmmsv_is_error (info_val)) {
			print_error ("%s", xmmsv_get_error_old (info_val));
		}

		if (xmmsv_dict_entry_get_int (info_val, "duration", &playtime)) {
			total_playtime += playtime;
		}

		if (val_has_key (info_val, "channel")) {
			if (val_has_key (info_val, "title")) {
				xmmsc_entry_format (line, sizeof (line),
				                    "[stream] ${title}", info_val);
			} else {
				xmmsc_entry_format (line, sizeof (line),
				                    "${channel}", info_val);
			}
		} else if (!val_has_key (info_val, "title")) {
			const gchar *url;
			gchar dur[10];

			xmmsc_entry_format (dur, sizeof (dur),
			                    "(${minutes}:${seconds})", info_val);

			if (xmmsv_dict_entry_get_string (info_val, "url", &url)) {
				gchar *filename = g_path_get_basename (url);
				if (filename) {
					g_snprintf (line, sizeof (line), "%s %s", filename, dur);
					g_free (filename);
				} else {
					g_snprintf (line, sizeof (line), "%s %s", url, dur);
				}
			}
		} else {
			xmmsc_entry_format (line, sizeof (line), listformat, info_val);
		}

		if (p == pos) {
			print_info ("->[%d/%d] %s", pos, ui, line);
		} else {
			print_info ("  [%d/%d] %s", pos, ui, line);
		}

		pos++;

		xmmsc_result_unref (info_res);
		xmmsv_unref (info_val);
		xmmsv_list_iter_next (it);
	}
	xmmsc_result_unref (res);

	/* rounding */
	total_playtime += 500;

	print_info ("\nTotal playtime: %d:%02d:%02d", total_playtime / 3600000,
	            (total_playtime / 60000) % 60, (total_playtime / 1000) % 60);
}