Пример #1
0
static int
handle_configval (xmmsv_t *v, void *data)
{
	xmmsc_result_t *res2;
	xmonitor_t *mon = data;
	const gchar *val;

	if (!xmmsv_get_string (v, &val)) {
		ERR ("Couldn't register value in server!");
		return FALSE;
	}

	res2 = xmmsc_configval_get (mon->conn, val);
	xmmsc_result_notifier_set (res2, handle_watch_dirs, mon);
	xmmsc_result_unref (res2);

	return FALSE;
}
Пример #2
0
void
cmd_playlist_active (xmmsc_connection_t *conn, gint argc, gchar **argv)
{
	const gchar *active_name;
	xmmsc_result_t *active_res;
	xmmsv_t *active_val;

	active_res = xmmsc_playlist_current_active (conn);
	xmmsc_result_wait (active_res);
	active_val = xmmsc_result_get_value (active_res);

	if (!xmmsv_is_error (active_val) &&
	    xmmsv_get_string (active_val, &active_name)) {
		print_info ("%s",active_name);
	}

	xmmsc_result_unref (active_res);
}
Пример #3
0
xmmsv_coll_t *
xmmsv_coll_copy (xmmsv_coll_t *orig_coll)
{
	xmmsv_coll_t *new_coll, *coll_elem;
	xmmsv_list_iter_t *it;
	xmmsv_dict_iter_t *itd;
	xmmsv_t *v, *list, *dict;
	const char *key;
	int32_t i;
	const char *s;

	new_coll = xmmsv_coll_new (xmmsv_coll_get_type (orig_coll));

	list = xmmsv_coll_idlist_get (orig_coll);
	x_return_val_if_fail (xmmsv_get_list_iter (list, &it), NULL);
	while (xmmsv_list_iter_valid (it)) {
		xmmsv_list_iter_entry (it, &v);
		xmmsv_get_int (v, &i);
		xmmsv_coll_idlist_append (new_coll, i);
		xmmsv_list_iter_next (it);
	}
	xmmsv_list_iter_explicit_destroy (it);

	list = xmmsv_coll_operands_get (orig_coll);
	x_return_val_if_fail (xmmsv_get_list_iter (list, &it), NULL);
	while (xmmsv_list_iter_valid (it)) {
		xmmsv_list_iter_entry (it, &v);
		xmmsv_get_coll (v, &coll_elem);
		xmmsv_coll_add_operand (new_coll, xmmsv_coll_copy (coll_elem));
		xmmsv_list_iter_next (it);
	}
	xmmsv_list_iter_explicit_destroy (it);

	dict = xmmsv_coll_attributes_get (orig_coll);
	x_return_val_if_fail (xmmsv_get_dict_iter (dict, &itd), NULL);
	while (xmmsv_dict_iter_valid (itd)) {
		xmmsv_dict_iter_pair (itd, &key, &v);
		xmmsv_get_string (v, &s);
		xmmsv_coll_attribute_set (new_coll, key, s);
		xmmsv_dict_iter_next (itd);
	}
	xmmsv_dict_iter_explicit_destroy (itd);
	return new_coll;
}
Пример #4
0
static void
attr_each (const char *key, xmmsv_t *value, void *udata)
{
	const char *s;

	xmmsv_get_string (value, &s);

	switch (XPOINTER_TO_INT (udata)) {
		case EACH_PAIR:
			rb_yield_values (2, rb_str_new2 (key), rb_str_new2 (s));
			break;
		case EACH_KEY:
			rb_yield_values (1, rb_str_new2 (key));
			break;
		case EACH_VALUE:
			rb_yield_values (1, rb_str_new2 (s));
			break;
	}
}
Пример #5
0
static int
updater_config_register (xmmsv_t *value, void *udata)
{
	xmmsc_result_t *res;
	const gchar *conf;
	updater_t *updater;

	updater = (updater_t *) udata;

	g_return_val_if_fail (updater, FALSE);

	if (!xmmsv_get_string (value, &conf)) {
		g_error ("Failed to register config value\n");
		return FALSE;
	}

	res = xmmsc_config_get_value (updater->conn, conf);
	xmmsc_result_notifier_set (res, updater_config_get, updater);
	xmmsc_result_unref (res);

	return FALSE;
}
Пример #6
0
static gint
reload_active_playlist (xmmsv_t *val, void *udata)
{
	cli_infos_t *infos = (cli_infos_t *) udata;
	xmmsc_result_t *refres;
	const gchar *buf;

	/* FIXME: Also listen to playlist renames, in case the active PL is renamed! */
	/* Refresh playlist name */
	if (xmmsv_get_string (val, &buf)) {
		g_free (infos->cache->active_playlist_name);
		infos->cache->active_playlist_name = g_strdup (buf);
	}

	/* Get all the entries again */
	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 (&infos->cache->freshness_active_playlist);

	return TRUE;
}
Пример #7
0
void
print_config (cli_infos_t *infos, xmmsc_result_t *res, gchar *confname)
{
	const gchar *confval;
	xmmsv_t *val;

	if (confname == NULL) {
		res = xmmsc_configval_list (infos->sync);
		xmmsc_result_wait (res);
		val = xmmsc_result_get_value (res);
		xmmsv_dict_foreach (val, print_config_entry, NULL);
	} else {
		res = xmmsc_configval_get (infos->sync, confname);
		xmmsc_result_wait (res);
		val = xmmsc_result_get_value (res);
		xmmsv_get_string (val, &confval);
		print_config_entry (confname, val, NULL);
	}

	cli_infos_loop_resume (infos);

	xmmsc_result_unref (res);
}
Пример #8
0
/* Write all attributes of a collection to the DB. */
static void
dbwrite_coll_attributes (const char *key, xmmsv_t *value, void *udata)
{
	gchar *query;
	coll_dbwrite_t *dbwrite_infos = udata;
	gchar *esc_key;
	gchar *esc_val;
	const gchar *s;
	int r;

	r = xmmsv_get_string (value, &s);
	g_return_if_fail (r);

	esc_key = sqlite_prepare_string (key);
	esc_val = sqlite_prepare_string (s);
	query = g_strdup_printf ("INSERT INTO CollectionAttributes VALUES(%d, %s, %s)",
	                         dbwrite_infos->collid, esc_key, esc_val);
	xmms_medialib_select (dbwrite_infos->session, query, NULL);

	g_free (query);
	g_free (esc_key);
	g_free (esc_val);
}
Пример #9
0
static void
__int_xmms_cmd_retrieve (xmms_object_t *object, xmms_object_cmd_arg_t *arg)
{
	xmmsv_t *t;
	if (xmmsv_list_get_size (arg->args) != 1) {
		XMMS_DBG ("Wrong number of arguments to retrieve (%d)", xmmsv_list_get_size (arg->args));
		xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to retrieve");
		return;
	}
	const char * argval0;

	if (!xmmsv_list_get (arg->args, 0, &t)) {
		XMMS_DBG ("Missing arg 0 in retrieve");
		xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in retrieve");
		return;
	}
	if (!xmmsv_get_string (t, &argval0)) {
		XMMS_DBG ("Error parsing arg 0 in retrieve");
		xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in retrieve");
		return;
	}

	arg->retval = xmms_bindata_client_retrieve ((xmms_bindata_t *) object, argval0, &arg->error);
}
Пример #10
0
static void
__int_xmms_cmd_move_entry (xmms_object_t *object, xmms_object_cmd_arg_t *arg)
{
	xmmsv_t *t;
	if (xmmsv_list_get_size (arg->args) != 2) {
		XMMS_DBG ("Wrong number of arguments to move_entry (%d)", xmmsv_list_get_size (arg->args));
		xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to move_entry");
		return;
	}
	gint32 argval0;
	const char * argval1;

	if (!xmmsv_list_get (arg->args, 0, &t)) {
		XMMS_DBG ("Missing arg 0 in move_entry");
		xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in move_entry");
		return;
	}
	if (!xmmsv_get_int (t, &argval0)) {
		XMMS_DBG ("Error parsing arg 0 in move_entry");
		xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in move_entry");
		return;
	}
	if (!xmmsv_list_get (arg->args, 1, &t)) {
		XMMS_DBG ("Missing arg 1 in move_entry");
		xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 1 in move_entry");
		return;
	}
	if (!xmmsv_get_string (t, &argval1)) {
		XMMS_DBG ("Error parsing arg 1 in move_entry");
		xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 1 in move_entry");
		return;
	}

	xmms_medialib_client_move_entry ((xmms_medialib_t *) object, argval0, argval1, &arg->error);
	arg->retval = xmmsv_new_none ();
}
Пример #11
0
int
xmmsv_bitbuffer_serialize_value (xmmsv_t *bb, xmmsv_t *v)
{
	bool ret;
	int32_t i;
	const char *s;
	xmmsv_coll_t *c;
	const unsigned char *bc;
	unsigned int bl;
	xmmsv_type_t type;

	type = xmmsv_get_type (v);
	ret = _internal_put_on_bb_int32 (bb, type);
	if (!ret)
		return ret;

	switch (type) {
	case XMMSV_TYPE_ERROR:
		if (!xmmsv_get_error (v, &s)) {
			return false;
		}
		ret = _internal_put_on_bb_error (bb, s);
		break;
	case XMMSV_TYPE_INT32:
		if (!xmmsv_get_int (v, &i)) {
			return false;
		}
		ret = _internal_put_on_bb_int32 (bb, i);
		break;
	case XMMSV_TYPE_STRING:
		if (!xmmsv_get_string (v, &s)) {
			return false;
		}
		ret = _internal_put_on_bb_string (bb, s);
		break;
	case XMMSV_TYPE_COLL:
		if (!xmmsv_get_coll (v, &c)) {
			return false;
		}
		ret = _internal_put_on_bb_collection (bb, c);
		break;
	case XMMSV_TYPE_BIN:
		if (!xmmsv_get_bin (v, &bc, &bl)) {
			return false;
		}
		ret = _internal_put_on_bb_bin (bb, bc, bl);
		break;
	case XMMSV_TYPE_LIST:
		ret = _internal_put_on_bb_value_list (bb, v);
		break;
	case XMMSV_TYPE_DICT:
		ret = _internal_put_on_bb_value_dict (bb, v);
		break;

	case XMMSV_TYPE_NONE:
		break;
	default:
		x_internal_error ("Tried to serialize value of unsupported type");
		return false;
	}

	return ret;
}
Пример #12
0
void media_info_get (xmmsv_t *value, media_info *info) {
	xmmsv_t *infos, *dict_entry;
	const char *artist, *album, *title, *url, *comment, *genre, *date;

	assert(value);
	assert(info);

	infos = xmmsv_propdict_to_dict(value, NULL);
	
	if (!xmmsv_dict_get (infos, "id", &dict_entry) ||
	    !xmmsv_get_int (dict_entry, &info->id)) {
		info->id = 0;
	}
	if (!xmmsv_dict_get (infos, "artist", &dict_entry) ||
	    !xmmsv_get_string (dict_entry, &artist)) {
		artist = "[Unknown Artist]";
	}
	if (!xmmsv_dict_get (infos, "album", &dict_entry) ||
	    !xmmsv_get_string (dict_entry, &album)) {
		album = "[Unknown Album]";
	}
	if (!xmmsv_dict_get (infos, "url", &dict_entry) ||
	    !xmmsv_get_string (dict_entry, &url)) {
		url = "[Unknown URL]";
	}
	if (!xmmsv_dict_get (infos, "title", &dict_entry) ||
	    !xmmsv_get_string (dict_entry, &title)) {
		title = ecore_file_file_get(url);
	}
	if (!xmmsv_dict_get (infos, "comment", &dict_entry) ||
	    !xmmsv_get_string (dict_entry, &comment)) {
		comment = "";
	}
	if (!xmmsv_dict_get (infos, "genre", &dict_entry) ||
	    !xmmsv_get_string (dict_entry, &genre)) {
		genre = "[Unknown Genre]";
	}
	if (!xmmsv_dict_get (infos, "date", &dict_entry) ||
	    !xmmsv_get_string (dict_entry, &date)) {
		date = "";
	}	
	if (!xmmsv_dict_get (infos, "duration", &dict_entry) ||
	    !xmmsv_get_int (dict_entry, &info->duration)) {
		info->duration = 0;
	}
	if (!xmmsv_dict_get (infos, "bitrate", &dict_entry) ||
	    !xmmsv_get_int (dict_entry, &info->bitrate)) {
		info->bitrate = 0;
	}
	if (!xmmsv_dict_get (infos, "tracknr", &dict_entry) ||
	    !xmmsv_get_int (dict_entry, &info->tracknr)) {
		info->tracknr = 0;
	}

	info->artist = strdup(artist);
	info->album = strdup(album);
	info->title = decode_url(title);
	info->url = decode_url(url);
	info->comment = strdup(comment);
	info->genre = strdup(genre);
	info->date = strdup(date);

	xmmsv_unref(infos);
}
Пример #13
0
/**
 * Encodes an url with arguments stored in dict args.
 *
 * The encoded url is allocated using malloc and has to be freed by the user.
 *
 * @param url The url to encode.
 * @param args The dict with arguments, or NULL.
 * @return The encoded url
 */
char *
xmmsc_medialib_encode_url_full (const char *url, xmmsv_t *args)
{
	static const char hex[16] = "0123456789abcdef";
	int i = 0, j = 0, extra = 0, l;
	char *res;
	xmmsv_dict_iter_t *it;

	x_api_error_if (!url, "with a NULL url", NULL);

	if (args) {
		if (!xmmsv_dict_foreach (args, _sum_len_string_dict, (void *) &extra)) {
			return NULL;
		}
	}

	/* Provide enough room for the worst-case scenario (all characters of the
	   URL must be encoded), the args, and a \0. */
	res = malloc (strlen (url) * 3 + 1 + extra);
	if (!res) {
		return NULL;
	}

	for (i = 0; url[i]; i++) {
		unsigned char chr = url[i];
		if (GOODCHAR (chr)) {
			res[j++] = chr;
		} else if (chr == ' ') {
			res[j++] = '+';
		} else {
			res[j++] = '%';
			res[j++] = hex[((chr & 0xf0) >> 4)];
			res[j++] = hex[(chr & 0x0f)];
		}
	}

	if (args) {
		for (xmmsv_get_dict_iter (args, &it), i = 0;
		     xmmsv_dict_iter_valid (it);
		     xmmsv_dict_iter_next (it), i++) {

			const char *arg, *key;
			xmmsv_t *val;

			xmmsv_dict_iter_pair (it, &key, &val);
			l = strlen (key);
			res[j] = (i == 0) ? '?' : '&';
			j++;
			memcpy (&res[j], key, l);
			j += l;
			if (xmmsv_get_string (val, &arg)) {
				l = strlen (arg);
				res[j] = '=';
				j++;
				memcpy (&res[j], arg, l);
				j += l;
			}
		}
	}

	res[j] = '\0';

	return res;
}
Пример #14
0
/**
 * This function will make a pretty string about the information in
 * xmmsv dict.
 *
 * @param target A allocated char *
 * @param len Length of target
 * @param fmt A format string to use. You can insert items from the dict by
 * using specialformat "${field}".
 * @param val The #xmmsv_t that contains the dict.
 *
 * @returns The number of chars written to target
 */
int
xmmsv_dict_format (char *target, int len, const char *fmt, xmmsv_t *val)
{
	const char *pos;

	if (!target) {
		return 0;
	}

	if (!fmt) {
		return 0;
	}

	memset (target, 0, len);

	pos = fmt;
	while (strlen (target) + 1 < len) {
		char *next_key, *key, *end;
		int keylen;
		xmmsv_dict_iter_t *it;
		xmmsv_t *v;

		next_key = strstr (pos, "${");
		if (!next_key) {
			strncat (target, pos, len - strlen (target) - 1);
			break;
		}

		strncat (target, pos, MIN (next_key - pos, len - strlen (target) - 1));
		keylen = strcspn (next_key + 2, "}");
		key = malloc (keylen + 1);

		if (!key) {
			fprintf (stderr, "Unable to allocate %u bytes of memory, OOM?", keylen);
			break;
		}

		memset (key, 0, keylen + 1);
		strncpy (key, next_key + 2, keylen);

		xmmsv_get_dict_iter (val, &it);

		if (strcmp (key, "seconds") == 0) {
			int64_t duration;

			if (xmmsv_dict_iter_find (it, "duration")) {
				xmmsv_dict_iter_pair (it, NULL, &v);
				xmmsv_get_int (v, &duration);
			} else {
				duration = 0;
			}

			if (!duration) {
				strncat (target, "00", len - strlen (target) - 1);
			} else {
				char seconds[21];
				/* rounding */
				duration += 500;
				snprintf (seconds, sizeof (seconds), "%02" PRId64, (duration/1000)%60);
				strncat (target, seconds, len - strlen (target) - 1);
			}
		} else if (strcmp (key, "minutes") == 0) {
			int64_t duration;

			if (xmmsv_dict_iter_find (it, "duration")) {
				xmmsv_dict_iter_pair (it, NULL, &v);
				xmmsv_get_int (v, &duration);
			} else {
				duration = 0;
			}

			if (!duration) {
				strncat (target, "00", len - strlen (target) - 1);
			} else {
				char minutes[21];
				/* rounding */
				duration += 500;
				snprintf (minutes, sizeof (minutes), "%02" PRId64, duration/60000);
				strncat (target, minutes, len - strlen (target) - 1);
			}
		} else {
			const char *result = NULL;
			char tmp[21];

			if (xmmsv_dict_iter_find (it, key)) {
				xmmsv_dict_iter_pair (it, NULL, &v);

				xmmsv_type_t type = xmmsv_get_type (v);
				if (type == XMMSV_TYPE_STRING) {
					xmmsv_get_string (v, &result);
				} else if (type == XMMSV_TYPE_INT64) {
					int64_t i;
					xmmsv_get_int (v, &i);
					snprintf (tmp, 21, "%" PRId64, i);
					result = tmp;
				} else if (type == XMMSV_TYPE_FLOAT) {
					float f;
					xmmsv_get_float (v, &f);
					snprintf (tmp, 12, "%.6f", f);
					result = tmp;
				}
			}

			if (result)
				strncat (target, result, len - strlen (target) - 1);
		}

		free (key);
		end = strchr (next_key, '}');

		if (!end) {
			break;
		}

		pos = end + 1;
	}

	return strlen (target);
}
Пример #15
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;
}
Пример #16
0
int
main (int argc, char **argv)
{
	/*
	 * The first part of this program is
	 * commented on in tut1.c and tut2.c
	 */
	xmmsc_connection_t *connection;
	xmmsc_result_t *result;
	xmmsv_t *return_value;
	const char *err_buf;

	/*
	 * Variables that we'll need later
	 */
	const char *val;
	int intval;
	int id;
	xmmsv_t *dict_entry;
	xmmsv_t *infos;

	connection = xmmsc_init ("tutorial3");
	if (!connection) {
		fprintf (stderr, "OOM!\n");
		exit (EXIT_FAILURE);
	}

	if (!xmmsc_connect (connection, getenv ("XMMS_PATH"))) {
		fprintf (stderr, "Connection failed: %s\n",
		         xmmsc_get_last_error (connection));

		exit (EXIT_FAILURE);
	}

	/*
	 * Ok, let' do the same thing as we did in
	 * tut2.c and retrieve the current playing
	 * entry. We need that to get information
	 * about the song.
	 */
	result = xmmsc_playback_current_id (connection);
	xmmsc_result_wait (result);
	return_value = xmmsc_result_get_value (result);

	if (xmmsv_is_error (return_value) &&
	    xmmsv_get_error (return_value, &err_buf)) {
		fprintf (stderr, "playback current id returns error, %s\n",
		         err_buf);
	}

	if (!xmmsv_get_int (return_value, &id)) {
		fprintf (stderr, "xmmsc_playback_current_id didn't "
		         "return int as expected\n");
		/* Fake id (ids are >= 1) used as an error flag. */
		id = 0;
	}

	/* Print the value */
	printf ("Currently playing id is %d\n", id);

	/*
	 * Same drill as before. Release memory
	 * so that we can reuse it in the next
	 * clientlib call.
	 * */
	xmmsc_result_unref (result);

	/*
	 * Something about the medialib and xmms2. All
	 * entries that are played, put into playlists
	 * have to be in the medialib. A song's metadata
	 * will be added to the medialib the first time
	 * you do "xmms2 add" or equivalent.
	 *
	 * When we request information for an entry, it will
	 * be requested from the medialib, not the playlist
	 * or the playback. The playlist and playback only
	 * know the unique id of the entry. All other
	 * information must be retrieved in subsequent calls.
	 *
	 * Entry 0 is non valid. Only 1-inf is valid.
	 * So let's check for 0 and don't ask medialib for it.
	 */
	if (id == 0) {
		fprintf (stderr, "Nothing is playing.\n");
		exit (EXIT_FAILURE);
	}

	/*
	 * And now for something about return types from
	 * clientlib. The clientlib will always return
	 * an xmmsc_result_t that will eventually contain the
	 * return value as a xmmsv_t struct.
	 * The value can contain an int and string as
	 * base type. It can also contain more complex
	 * types like lists and dicts.
	 * A list is a sequence of values, each of them
	 * wrapped in its own xmmsv_t struct (of any type).

	 * A dict is a key<->value representation where key
	 * is always a string but the value is again wrapped
	 * in its own xmmsv_t struct (of any type).
	 *
	 * When retrieving an entry from the medialib, you
	 * get a dict as return. Let's print out some
	 * entries from it and then traverse the dict.
	 */
	result = xmmsc_medialib_get_info (connection, id);

	/* And waaait for it .. */
	xmmsc_result_wait (result);

	/* Let's reuse the previous return_value pointer, it
	 * was invalidated as soon as we freed the result that
	 * contained it anyway.
	 */
	return_value = xmmsc_result_get_value (result);

	if (xmmsv_is_error (return_value) &&
	    xmmsv_get_error (return_value, &err_buf)) {
		/*
		 * This can return error if the id
		 * is not in the medialib
		 */
		fprintf (stderr, "medialib get info returns error, %s\n",
		         err_buf);
		exit (EXIT_FAILURE);
	}

	/*
	 * Because of the nature of the dict returned by
	 * xmmsc_medialib_get_info, we need to convert it to
	 * a simpler dict using xmmsv_propdict_to_dict.
	 * Let's not worry about that for now and accept it
	 * as a fact of life.
	 *
	 * See tut5 for a discussion about dicts and propdicts.
	 *
	 * Note that xmmsv_propdict_to_dict creates a new
	 * xmmsv_t struct, which we will need to free manually
	 * when we're done with it.
	 */
	infos = xmmsv_propdict_to_dict (return_value, NULL);

	/*
	 * We must first retrieve the xmmsv_t struct
	 * corresponding to the "artist" key in the dict,
	 * and then extract the string from that struct.
	 */
	if (!xmmsv_dict_get (infos, "artist", &dict_entry) ||
	    !xmmsv_get_string (dict_entry, &val)) {
		/*
		 * if we end up here it means that the key "artist" wasn't
		 * in the dict or that the value for "artist" wasn't a
		 * string.
		 *
		 * You can check the type of the entry (if there is one) with
		 * xmmsv_get_type (dict_entry). It will return an
		 * xmmsv_type_t enum describing the type.
		 *
		 * Actually this is no disaster, it might just mean that
		 * we don't have an artist tag on this entry. Let's
		 * call it "No Artist" for now.
		 */
		val = "No Artist";
	}

	/* print the value */
	printf ("artist = %s\n", val);

	if (!xmmsv_dict_get (infos, "title", &dict_entry) ||
	    !xmmsv_get_string (dict_entry, &val)) {
		val = "No Title";
	}
	printf ("title = %s\n", val);

	/*
	 * Let's extract an integer as well
	 */
	if (!xmmsv_dict_get (infos, "bitrate", &dict_entry) ||
	    !xmmsv_get_int (dict_entry, &intval)) {
		intval = 0;
	}
	printf ("bitrate = %i\n", intval);

	/*
	 * We need to free infos manually here, else we will leak.
	 */
	xmmsv_unref (infos);

	/*
	 * !!Important!!
	 *
	 * When unreffing the result here we will free
	 * the memory that we have extracted from the dict,
	 * and that includes all the string pointers of the
	 * dict entries! So if you want to keep strings
	 * somewhere you need to copy that memory! Very
	 * important otherwise you will get undefined behaviour.
	 */
	xmmsc_result_unref (result);

	xmmsc_unref (connection);

	return (EXIT_SUCCESS);
}
Пример #17
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);
}
Пример #18
0
int show_xmmsinfo_c(lua_State *L)
{
	xmmsc_connection_t *connection;
	xmmsc_result_t *state;
	xmmsv_t *state_value;
	const char *err_buf;
	int32_t status;

	// string containing the current xmms2 state
	char *state_str;

	// initialize the Info struct
	struct Info i;

	// initialize the connection
	connection = xmmsc_init("xmmsinfo");
	if (!connection) {
		fprintf(stderr, "No connection!\n");
		return(EXIT_FAILURE);
	}

	// try to connect
	if (!xmmsc_connect(connection, getenv("XMMS_PATH"))) {
		fprintf(stderr, "Connection failed, %s\n",
				xmmsc_get_last_error(connection));
		return(EXIT_FAILURE);
	}

	// get current xmms2 status
	state = xmmsc_playback_status(connection);
	xmmsc_result_wait(state);
	state_value = xmmsc_result_get_value(state);

	if(xmmsv_get_error(state_value, &err_buf)) {
		fprintf(stderr, "Error while asking for the connection status, %s\n",
				err_buf);
	}

	if(!xmmsv_get_int(state_value, &status)) {
		fprintf(stderr, "Couldn't get connection status, %d\n", status);
	}

	// 0 == stopped; 1 == playing; 2 == paused
	if(status == XMMS_PLAYBACK_STATUS_PLAY) {
		state_str = "playing";
	} else if (status == XMMS_PLAYBACK_STATUS_PAUSE) {
		state_str = "paused";
	} else {
		state_str = "stopped";
	}

	i.state = state_str;

	// get current position in the playlist
	xmmsc_result_t *current_id;
	xmmsv_t *current_id_value;
	int32_t cur_id;

	current_id = xmmsc_playback_current_id(connection);
	xmmsc_result_wait(current_id);
	current_id_value = xmmsc_result_get_value(current_id);
	xmmsv_get_int(current_id_value, &cur_id);



	// initialize variables for the song info
	xmmsc_result_t *result;
	xmmsv_t *return_value;
	xmmsv_t *dict_entry;
	xmmsv_t *infos;
	const char *val;

	result = xmmsc_medialib_get_info(connection, cur_id);
	xmmsc_result_wait(result);
	return_value = xmmsc_result_get_value(result);

	if(xmmsv_get_error(return_value, &err_buf)) {
		fprintf(stderr, "Medialib returns error, %s\n",
				err_buf);
		return(EXIT_FAILURE);
	}

	infos = xmmsv_propdict_to_dict(return_value, NULL);
	if(!xmmsv_dict_get(infos, "artist", &dict_entry) ||
			!xmmsv_get_string(dict_entry, &val)) {
		val = "No Artist";
	}

	i.artist = val;

	if(!xmmsv_dict_get(infos, "album", &dict_entry) ||
			!xmmsv_get_string(dict_entry, &val)) {
		val = "No Album";
	}

	i.album = val;

	if(!xmmsv_dict_get(infos, "title", &dict_entry) ||
			!xmmsv_get_string(dict_entry, &val)) {
		val = "No Title";
	}

	i.song = val;

	i.id = cur_id;

	if(!xmmsv_dict_get(infos, "url", &dict_entry) ||
			!xmmsv_get_string(dict_entry, &val)) {
		val = NULL;
	}

	i.uri = val;

	// push everything to lua
	lua_pushstring(L, i.state);
	lua_pushstring(L, i.artist);
	lua_pushstring(L, i.album);
	lua_pushstring(L, i.song);
	lua_pushinteger(L, i.id);
	lua_pushstring(L, i.uri);


	// clean up
	xmmsv_unref(infos);
	xmmsc_result_unref(result);
	xmmsc_result_unref(state);
	xmmsc_result_unref(current_id);
	xmmsc_unref(connection);
	return 6;
}