static xmms_fetch_spec_t * xmms_fetch_spec_new_organize (xmmsv_t *fetch, xmms_fetch_info_t *info, s4_sourcepref_t *prefs, xmms_error_t *err) { xmms_fetch_spec_t *spec; xmmsv_dict_iter_t *it; s4_sourcepref_t *sp; xmmsv_t *org_data; gint org_idx; if (!xmmsv_dict_get (fetch, "data", &org_data)) { xmms_error_set (err, XMMS_ERROR_INVAL, "Required field 'data' not set in organize."); return NULL; } if (xmmsv_get_type (org_data) != XMMSV_TYPE_DICT) { xmms_error_set (err, XMMS_ERROR_INVAL, "Field 'data' in organize must be a dict."); return NULL; } sp = normalize_source_preferences (fetch, prefs, err); if (xmms_error_iserror (err)) { return NULL; } spec = g_new0 (xmms_fetch_spec_t, 1); spec->type = FETCH_ORGANIZE; spec->data.organize.count = xmmsv_dict_get_size (org_data); spec->data.organize.keys = g_new0 (const char *, spec->data.organize.count); spec->data.organize.data = g_new0 (xmms_fetch_spec_t *, spec->data.organize.count); org_idx = 0; xmmsv_get_dict_iter (org_data, &it); while (xmmsv_dict_iter_valid (it)) { xmms_fetch_spec_t *orgee; const gchar *str; xmmsv_t *entry; xmmsv_dict_iter_pair (it, &str, &entry); orgee = xmms_fetch_spec_new (entry, info, sp, err); if (xmms_error_iserror (err)) { xmms_fetch_spec_free (spec); spec = NULL; break; } spec->data.organize.keys[org_idx] = str; spec->data.organize.data[org_idx] = orgee; org_idx++; xmmsv_dict_iter_next (it); } xmmsv_dict_iter_explicit_destroy (it); s4_sourcepref_unref (sp); return spec; }
static xmms_fetch_spec_t * xmms_fetch_spec_new_metadata (xmmsv_t *fetch, xmms_fetch_info_t *info, s4_sourcepref_t *prefs, xmms_error_t *err) { xmms_fetch_spec_t *ret = NULL; s4_sourcepref_t *sp; const gchar *key; xmmsv_t *gets, *fields; gint i, size, aggregate, get; aggregate = normalize_aggregate_function (fetch, err); if (xmms_error_iserror (err)) { return NULL; } fields = normalize_metadata_fields (fetch, err); if (xmms_error_iserror (err)) { return NULL; } gets = normalize_metadata_get (fetch, err); if (xmms_error_iserror (err)) { return NULL; } sp = normalize_source_preferences (fetch, prefs, err); if (xmms_error_iserror (err)) { xmmsv_unref (gets); return NULL; } ret = g_new0 (xmms_fetch_spec_t, 1); ret->type = FETCH_METADATA; ret->data.metadata.aggr_func = aggregate; for (i = 0; i < 4 && xmmsv_list_get_int (gets, i, &get); i++) { ret->data.metadata.get[i] = get; } ret->data.metadata.get_size = i; if (fields != NULL) { size = xmmsv_list_get_size (fields); ret->data.metadata.col_count = size; ret->data.metadata.cols = g_new (gint32, size); for (i = 0; xmmsv_list_get_string (fields, i, &key); i++) { ret->data.metadata.cols[i] = xmms_fetch_info_add_key (info, fetch, key, sp); } } else { /* No fields requested, fetching all available */ ret->data.metadata.col_count = 1; ret->data.metadata.cols = g_new0 (gint32, 1); ret->data.metadata.cols[0] = xmms_fetch_info_add_key (info, fetch, NULL, sp); } s4_sourcepref_unref (sp); xmmsv_unref (gets); return ret; }
static void xmms_playlist_client_insert_collection (xmms_playlist_t *playlist, const gchar *plname, gint32 pos, xmmsv_coll_t *coll, xmmsv_t *order, xmms_error_t *err) { xmmsv_list_iter_t *it; xmmsv_t *list; list = xmms_collection_query_ids (playlist->colldag, coll, 0, 0, order, err); if (xmms_error_iserror (err)) { return; } xmmsv_get_list_iter (list, &it); xmmsv_list_iter_last (it); while (xmmsv_list_iter_valid (it)) { xmms_medialib_entry_t mid; xmmsv_t *entry; xmmsv_list_iter_entry (it, &entry); xmmsv_get_int (entry, &mid); xmms_playlist_insert_entry (playlist, plname, pos, mid, err); xmmsv_list_iter_prev (it); } xmmsv_unref (list); }
static gint xmms_playlist_set_current_position_do (xmms_playlist_t *playlist, guint32 pos, xmms_error_t *err) { gint size; xmms_medialib_entry_t mid; xmmsv_coll_t *plcoll; const gchar *jumplist; g_return_val_if_fail (playlist, FALSE); plcoll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, err); if (plcoll == NULL) { return 0; } size = xmms_playlist_coll_get_size (plcoll); if (pos == size && xmmsv_coll_attribute_get (plcoll, "jumplist", &jumplist)) { xmms_collection_set_int_attr (plcoll, "position", 0); XMMS_PLAYLIST_CURRPOS_MSG (0, XMMS_ACTIVE_PLAYLIST); xmms_playlist_client_load (playlist, jumplist, err); if (xmms_error_iserror (err)) { return 0; } plcoll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, err); if (plcoll == NULL) { return 0; } } else if (pos < size) { XMMS_DBG ("newpos! %d", pos); xmms_collection_set_int_attr (plcoll, "position", pos); XMMS_PLAYLIST_CURRPOS_MSG (pos, XMMS_ACTIVE_PLAYLIST); } else { xmms_error_set (err, XMMS_ERROR_INVAL, "Can't set pos outside the current playlist!"); return 0; } xmmsv_coll_idlist_get_index (plcoll, pos, &mid); return mid; }
/** * Performance test predicate */ static gboolean run_performance_test (xmms_medialib_t *medialib, const gchar *name, xmmsv_t *content, xmmsv_t *coll, xmmsv_t *specification, xmmsv_t *expected, gint format, const gchar *datasetname) { xmms_medialib_session_t *session; xmms_error_t err; GTimeVal t0, t1; guint64 duration; xmmsv_t *ret; session = xmms_medialib_session_begin (medialib); g_get_current_time (&t0); ret = xmms_medialib_query (session, coll, specification, &err); g_get_current_time (&t1); xmms_medialib_session_commit (session); duration = (guint64)((t1.tv_sec - t0.tv_sec) * G_USEC_PER_SEC) + (t1.tv_usec - t0.tv_usec); if (format == FORMAT_PRETTY) g_print ("* Test %s\n", name); if (xmms_error_iserror (&err)) { if (format == FORMAT_CSV) { g_print ("\"%s\",\"%s\",0,0\n", datasetname, name); } else { g_print (" - Query failed: %s\n", xmms_error_message_get (&err)); } } else { if (format == FORMAT_CSV) { g_print ("\"%s\",\"%s\",1,%" G_GUINT64_FORMAT "\n", datasetname, name, duration); } else { g_print (" - Time elapsed: %.3fms\n", duration / 1000.0); } } xmmsv_unref (ret); return TRUE; }
static gboolean xmms_daap_init (xmms_xform_t *xform) { gint dbid; GSList *dbid_list = NULL; xmms_daap_data_t *data; xmms_daap_login_data_t *login_data; xmms_error_t err; const gchar *url; const gchar *metakey; gchar *command, *hash; guint filesize; g_return_val_if_fail (xform, FALSE); url = xmms_xform_indata_get_str (xform, XMMS_STREAM_TYPE_URL); g_return_val_if_fail (url, FALSE); data = g_new0 (xmms_daap_data_t, 1); xmms_error_reset (&err); if (!get_data_from_url (url, &(data->host), &(data->port), &command, &err)) { goto init_error; } hash = g_strdup_printf ("%s:%u", data->host, data->port); login_data = g_hash_table_lookup (login_sessions, hash); if (!login_data) { XMMS_DBG ("creating login data for %s", hash); login_data = g_new0 (xmms_daap_login_data_t, 1); login_data->request_id = 1; login_data->logged_in = TRUE; login_data->session_id = daap_command_login (data->host, data->port, login_data->request_id, &err); if (xmms_error_iserror (&err)) { g_free (login_data); goto init_error; } g_hash_table_insert (login_sessions, hash, login_data); } login_data->revision_id = daap_command_update (data->host, data->port, login_data->session_id, login_data->request_id); dbid_list = daap_command_db_list (data->host, data->port, login_data->session_id, login_data->revision_id, login_data->request_id); if (!dbid_list) { goto init_error; } /* XXX: see XXX in the browse function above */ dbid = ((cc_item_record_t *) dbid_list->data)->dbid; /* want to request a stream, but don't read the data yet */ data->conn = daap_command_init_stream (data->host, data->port, login_data->session_id, login_data->revision_id, login_data->request_id, dbid, command, &filesize); if (! data->conn) { goto init_error; } login_data->request_id++; metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE; xmms_xform_metadata_set_int (xform, metakey, filesize); xmms_xform_private_data_set (xform, data); xmms_xform_outdata_type_add (xform, XMMS_STREAM_TYPE_MIMETYPE, "application/octet-stream", XMMS_STREAM_TYPE_END); g_slist_foreach (dbid_list, (GFunc) cc_item_record_free, NULL); g_slist_free (dbid_list); g_free (command); return TRUE; init_error: if (data) { if (data->host) g_free (data->host); g_free (data); } return FALSE; }
/** * Scan a daap server for songs. */ static gboolean daap_get_urls_from_server (xmms_xform_t *xform, gchar *host, guint port, xmms_error_t *err) { GSList *dbid_list = NULL; GSList *song_list = NULL, *song_el; cc_item_record_t *db_data; xmms_daap_login_data_t *login_data; gchar *hash; hash = g_strdup_printf ("%s:%u", host, port); login_data = g_hash_table_lookup (login_sessions, hash); if (!login_data) { login_data = g_new0 (xmms_daap_login_data_t, 1); login_data->session_id = daap_command_login (host, port, 0, err); if (xmms_error_iserror (err)) { g_free (login_data); return FALSE; } login_data->revision_id = daap_command_update (host, port, login_data->session_id, 0); login_data->request_id = 1; login_data->logged_in = TRUE; g_hash_table_insert (login_sessions, hash, login_data); } else { login_data->revision_id = daap_command_update (host, port, login_data->session_id, 0); } dbid_list = daap_command_db_list (host, port, login_data->session_id, login_data->revision_id, 0); if (!dbid_list) { return FALSE; } /* XXX i've never seen more than one db per server out in the wild, * let's hope that never changes *wink* * just use the first db in the list */ db_data = (cc_item_record_t *) dbid_list->data; song_list = daap_command_song_list (host, port, login_data->session_id, login_data->revision_id, 0, db_data->dbid); g_slist_foreach (dbid_list, (GFunc) cc_item_record_free, NULL); g_slist_free (dbid_list); if (!song_list) { return FALSE; } for (song_el = song_list; song_el; song_el = g_slist_next (song_el)) { daap_add_song_to_list (xform, song_el->data); } g_slist_foreach (song_list, (GFunc) cc_item_record_free, NULL); g_slist_free (song_list); return TRUE; }
/** * 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; }