Beispiel #1
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 #2
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 #3
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 #4
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;
}