static void currently_playing_update_info (currently_playing_t *entry, xmmsv_t *value) { const gchar *noinfo_fields[] = { "playback_status", "playtime", "position"}; const gchar *time_fields[] = { "duration"}; xmmsv_t *info; gint i; info = xmmsv_propdict_to_dict (value, NULL); enrich_mediainfo (info); /* copy over fields that are not from metadata */ for (i = 0; i < G_N_ELEMENTS (noinfo_fields); i++) { xmmsv_t *copy; if (xmmsv_dict_get (entry->data, noinfo_fields[i], ©)) { xmmsv_dict_set (info, noinfo_fields[i], copy); } } /* pretty format time fields */ for (i = 0; i < G_N_ELEMENTS (time_fields); i++) { gint32 tim; if (xmmsv_dict_entry_get_int (info, time_fields[i], &tim)) { gchar *p = format_time (tim, FALSE); xmmsv_dict_set_string (info, time_fields[i], p); g_free (p); } } xmmsv_unref (entry->data); entry->data = info; }
static void cli_list_print_row (column_display_t *coldisp, xmmsv_t *propdict) { xmmsv_t *info = xmmsv_propdict_to_dict (propdict, NULL); enrich_mediainfo (info); column_display_print (coldisp, info); }
static gboolean ol_player_xmms2_get_music_length (int *len) { /* ol_log_func (); */ ol_assert_ret (len != NULL, FALSE); if (!ol_player_xmms2_ensure_connection ()) return FALSE; *len = 0; int32_t id = ol_player_xmms2_get_currend_id (); if (id > 0) { xmmsc_result_t *result = xmmsc_medialib_get_info (connection, id); xmmsc_result_wait (result); xmmsv_t *return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value)) { ol_error ("Get music info from XMMS2 failed."); } else { xmmsv_t *dict = xmmsv_propdict_to_dict (return_value, NULL); *len = ol_player_xmms2_get_dict_int (return_value, "duration"); xmmsv_unref (dict); } xmmsc_result_unref (result); } return TRUE; }
/* * call-seq: * rawdict.to_propdict( src_prefs ) -> propdict * * Transforms a RawDict (key-source-value) to a regular * key-value dict. * The optional src_prefs argument restricts which sources * are considered. The value may be a string or an array * of strings, which may contain wildcards. * Example: rawdict.to_propdict( ['server','plugin/*'] ) */ static VALUE c_raw_dict_to_propdict (int argc, VALUE *argv, VALUE self) { VALUE value, sources = Qnil; RbDict *dict = NULL, *dict2 = NULL; xmmsv_t *inner_dict; const char **csources = NULL; Data_Get_Struct (self, RbDict, dict); rb_scan_args (argc, argv, "01", &sources); if (!NIL_P (sources)) csources = parse_string_array (sources); inner_dict = xmmsv_propdict_to_dict (dict->real, csources); if (csources) free (csources); value = Data_Make_Struct (cDict, RbDict, c_dict_mark, c_dict_free, dict2); // don't add a second reference here dict2->real = inner_dict; dict2->parent = dict->parent; rb_obj_call_init (value, 0, NULL); return value; }
void PropDict::setSource( const std::list< std::string >& src ) { std::vector< const char* > prefs; fillCharArray( src, prefs ); xmmsv_t *flat = xmmsv_propdict_to_dict( propdict_, &prefs[0] ); setValue( flat ); // setValue refs flat, unref here to get back to refcount of 1 xmmsv_unref ( flat ); }
PropDict::PropDict( xmmsv_t* val ) : Dict( val ), propdict_( val ) { xmmsv_ref( propdict_ ); // Immediately replace with a "flat" dict (default sources) xmmsv_t *flat = xmmsv_propdict_to_dict( propdict_, NULL ); setValue( flat ); // setValue refs flat, unref here to get back to refcount of 1 xmmsv_unref ( flat ); }
static void id_coldisp_print_info (cli_infos_t *infos, column_display_t *coldisp, guint id) { xmmsc_result_t *infores; xmmsv_t *info; infores = xmmsc_medialib_get_info (infos->sync, id); xmmsc_result_wait (infores); info = xmmsv_propdict_to_dict (xmmsc_result_get_value (infores), NULL); column_display_print (coldisp, info); xmmsc_result_unref (infores); xmmsv_unref (info); }
static gboolean ol_player_xmms2_get_music_info (OlMusicInfo *info) { /* ol_log_func (); */ ol_assert_ret (info != NULL, FALSE); if (!ol_player_xmms2_ensure_connection ()) return FALSE; ol_music_info_clear (info); int32_t id = ol_player_xmms2_get_currend_id (); if (id > 0) { xmmsc_result_t *result = xmmsc_medialib_get_info (connection, id); xmmsc_result_wait (result); xmmsv_t *return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value)) { ol_error ("Get music info from XMMS2 failed."); } else { xmmsv_t *dict = xmmsv_propdict_to_dict (return_value, NULL); info->title = ol_player_xmms2_get_dict_string (dict, "title"); info->artist = ol_player_xmms2_get_dict_string (dict, "artist"); info->album = ol_player_xmms2_get_dict_string (dict, "album"); info->track_number = ol_player_xmms2_get_dict_int (dict, "tracknr"); info->uri = ol_player_xmms2_get_dict_string (dict, "url"); ol_logf (OL_DEBUG, "%s\n" " title:%s\n" " artist:%s\n" " album:%s\n" " uri:%s\n", __FUNCTION__, info->title, info->artist, info->album, info->uri); xmmsv_unref (dict); } xmmsc_result_unref (result); } return TRUE; }
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 */ }
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); }
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; }
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); }
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); }
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); }