gint compare_filelist_entry_path(gconstpointer filelist_entry1, gconstpointer filelist_entry2) { const struct mpd_entity *e1, *e2; int n = 0; e1 = ((const struct filelist_entry *)filelist_entry1)->entity; e2 = ((const struct filelist_entry *)filelist_entry2)->entity; if (e1 != NULL && e2 != NULL && mpd_entity_get_type(e1) == mpd_entity_get_type(e2)) { switch (mpd_entity_get_type(e1)) { case MPD_ENTITY_TYPE_UNKNOWN: break; case MPD_ENTITY_TYPE_DIRECTORY: n = g_utf8_collate(mpd_directory_get_path(mpd_entity_get_directory(e1)), mpd_directory_get_path(mpd_entity_get_directory(e2))); break; case MPD_ENTITY_TYPE_SONG: break; case MPD_ENTITY_TYPE_PLAYLIST: n = g_utf8_collate(mpd_playlist_get_path(mpd_entity_get_playlist(e1)), mpd_playlist_get_path(mpd_entity_get_playlist(e2))); } } return n; }
/* * pgmpc_lsplaylists * List all playlists of remote server. */ Datum pgmpc_lsplaylists(PG_FUNCTION_ARGS) { TupleDesc tupdesc; Tuplestorestate *tupstore; /* Initialize function context */ pgmpc_init_setof_single(fcinfo, TEXTOID, "playlist", &tupdesc, &tupstore); /* * Run the command to get all the songs. */ pgmpc_init(); if (!mpd_send_list_playlists(mpd_conn)) pgmpc_print_error(); /* Now get all the songs and send them back to caller */ while (true) { Datum values[1]; bool nulls[1]; struct mpd_playlist *playlist = mpd_recv_playlist(mpd_conn); /* Leave if done */ if (playlist == NULL) break; /* Assign song name */ nulls[0] = false; values[0] = CStringGetTextDatum(mpd_playlist_get_path(playlist)); /* Save values */ tuplestore_putvalues(tupstore, tupdesc, values, nulls); /* Clean up for the next one */ mpd_playlist_free(playlist); } /* We may be in error state, so check for it */ if (mpd_connection_get_error(mpd_conn) != MPD_ERROR_SUCCESS) { const char *message = mpd_connection_get_error_message(mpd_conn); pgmpc_reset(); ereport(ERROR, (errcode(ERRCODE_SYSTEM_ERROR), errmsg("mpd command failed: %s", message))); } /* Clean up */ pgmpc_reset(); /* clean up and return the tuplestore */ tuplestore_donestoring(tupstore); return (Datum) 0; }
/* * Retrieves the list of stored playlists. * * Returns true on success, false on failure. */ bool Control::update_playlist_index() { string name; struct mpd_playlist * playlist; Playlist * local_playlist; vector<Playlist *>::iterator local_playlist_iterator; EXIT_IDLE; pms->log(MSG_DEBUG, 0, "Updating the list of stored playlists.\n"); if (!mpd_send_list_playlists(conn->h())) { return false; } /* Mark all playlists as not belonging to MPD, in order to be able to * detect a deleted playlist. */ local_playlist_iterator = playlists.begin(); while (local_playlist_iterator != playlists.end()) { (*local_playlist_iterator)->set_exists_in_mpd(false); ++local_playlist_iterator; } while ((playlist = mpd_recv_playlist(conn->h())) != NULL) { name = mpd_playlist_get_path(playlist); local_playlist_iterator = playlists.begin(); while (local_playlist_iterator != playlists.end()) { if ((*local_playlist_iterator)->filename == name) { local_playlist = *local_playlist_iterator; break; } ++local_playlist_iterator; } if (local_playlist_iterator == playlists.end()) { local_playlist = new Playlist(); local_playlist->filename = name; playlists.push_back(local_playlist); pms->disp->add_list(local_playlist); } local_playlist->assign_metadata_from_mpd(playlist); pms->log(MSG_DEBUG, 0, "Playlist '%s' was last modified on %u\n", local_playlist->filename.c_str(), local_playlist->get_last_modified()); mpd_playlist_free(playlist); } return get_error_bool(); }
/** * Set filename and last_modified tags from MPD playlist. */ void Playlist::assign_metadata_from_mpd(mpd_playlist * playlist) { time_t last_mod = _last_modified; filename = mpd_playlist_get_path(playlist); _last_modified = mpd_playlist_get_last_modified(playlist); _exists_in_mpd = true; if (_last_modified > last_mod) { _synchronized = false; } }
int cmd_loadtab ( int argc, char ** argv, struct mpd_connection *conn ) { struct mpd_playlist *pl; if (argc != 1) return 0; if (!mpd_send_list_meta(conn, NULL)) printErrorAndExit(conn); while ((pl = mpd_recv_playlist(conn)) != NULL) { if (strncmp(mpd_playlist_get_path(pl), argv[0], strlen(argv[0])) == 0) printf("%s\n", charset_from_utf8(mpd_playlist_get_path(pl))); mpd_playlist_free(pl); } my_finishCommand(conn); return 0; }
/* create a list suitable for GCompletion from path */ GList * gcmp_list_from_path(struct mpdclient *c, const gchar *path, GList *list, gint types) { struct mpd_connection *connection; struct mpd_entity *entity; connection = mpdclient_get_connection(c); if (connection == NULL) return list; mpd_send_list_meta(connection, path); while ((entity = mpd_recv_entity(connection)) != NULL) { char *name; if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_DIRECTORY && types & GCMP_TYPE_DIR) { const struct mpd_directory *dir = mpd_entity_get_directory(entity); gchar *tmp = utf8_to_locale(mpd_directory_get_path(dir)); gsize size = strlen(tmp)+2; name = g_malloc(size); g_strlcpy(name, tmp, size); g_strlcat(name, "/", size); g_free(tmp); } else if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG && types & GCMP_TYPE_FILE) { const struct mpd_song *song = mpd_entity_get_song(entity); name = utf8_to_locale(mpd_song_get_uri(song)); } else if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_PLAYLIST && types & GCMP_TYPE_PLAYLIST) { const struct mpd_playlist *playlist = mpd_entity_get_playlist(entity); name = utf8_to_locale(mpd_playlist_get_path(playlist)); } else { mpd_entity_free(entity); continue; } list = g_list_append(list, name); mpd_entity_free(entity); } return list; }
void print_entity_list(struct mpd_connection *c, enum mpd_entity_type filter_type) { struct mpd_entity *entity; while ((entity = mpd_recv_entity(c)) != NULL) { const struct mpd_directory *dir; const struct mpd_song *song; const struct mpd_playlist *playlist; enum mpd_entity_type type = mpd_entity_get_type(entity); if (filter_type != MPD_ENTITY_TYPE_UNKNOWN && type != filter_type) type = MPD_ENTITY_TYPE_UNKNOWN; switch (type) { case MPD_ENTITY_TYPE_UNKNOWN: break; case MPD_ENTITY_TYPE_DIRECTORY: dir = mpd_entity_get_directory(entity); printf("%s\n", mpd_directory_get_path(dir)); //charset_from_utf8(mpd_directory_get_path(dir))); break; case MPD_ENTITY_TYPE_SONG: song = mpd_entity_get_song(entity); /*if (options.custom_format) { pretty_print_song(song); puts(""); } else*/ printf("%s\n", mpd_song_get_uri(song)); //charset_from_utf8(mpd_song_get_uri(song))); break; case MPD_ENTITY_TYPE_PLAYLIST: playlist = mpd_entity_get_playlist(entity); printf("%s\n", mpd_playlist_get_path(playlist)); //charset_from_utf8(mpd_playlist_get_path(playlist))); break; } mpd_entity_free(entity); } }
int mpd_put_browse(char *buffer, char *path, unsigned int offset) { char *cur = buffer; const char *end = buffer + MAX_SIZE; struct mpd_entity *entity; unsigned int entity_count = 0; if (!mpd_send_list_meta(mpd.conn, path)) RETURN_ERROR_AND_RECOVER("mpd_send_list_meta"); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"browse\",\"data\":[ "); while((entity = mpd_recv_entity(mpd.conn)) != NULL) { const struct mpd_song *song; const struct mpd_directory *dir; const struct mpd_playlist *pl; if(offset > entity_count) { mpd_entity_free(entity); entity_count++; continue; } else if(offset + MAX_ELEMENTS_PER_PAGE - 1 < entity_count) { mpd_entity_free(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\",\"count\":"); cur += json_emit_int(cur, end - cur, entity_count); cur += json_emit_raw_str(cur, end - cur, "} "); break; } switch (mpd_entity_get_type(entity)) { case MPD_ENTITY_TYPE_UNKNOWN: break; case MPD_ENTITY_TYPE_SONG: song = mpd_entity_get_song(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song)); cur += json_emit_raw_str(cur, end - cur, ",\"duration\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song)); cur += json_emit_raw_str(cur, end - cur, ",\"title\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song)); cur += json_emit_raw_str(cur, end - cur, "},"); break; case MPD_ENTITY_TYPE_DIRECTORY: dir = mpd_entity_get_directory(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"directory\",\"dir\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_directory_get_path(dir)); cur += json_emit_raw_str(cur, end - cur, "},"); break; case MPD_ENTITY_TYPE_PLAYLIST: pl = mpd_entity_get_playlist(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"playlist\",\"plist\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_playlist_get_path(pl)); cur += json_emit_raw_str(cur, end - cur, "},"); break; } mpd_entity_free(entity); entity_count++; } if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(mpd.conn)) { fprintf(stderr, "MPD mpd_send_list_meta: %s\n", mpd_connection_get_error_message(mpd.conn)); mpd.conn_state = MPD_FAILURE; return 0; } /* remove last ',' */ cur--; cur += json_emit_raw_str(cur, end - cur, "]}"); return cur - buffer; }
/* fetch a new db tree on root */ static int fetch_db_tree(DB_NODE **p_root,struct mpd_connection *conn) { if (*p_root) return 1; /* create root */ DB_NODE *root = (DB_NODE*)malloc(sizeof(DB_NODE)); root->type = DB_DIRECTORY; /* use calloc for root->uri to ease free_db_tree() */ root->uri = (char *)calloc(2,sizeof(char)); strncpy(root->uri,"/",1); root->rating = 0; root->duration = 0; root->p = NULL; root->s = NULL; root->c = NULL; root->num_c = 0; /* set top node */ DB_NODE *top = root; if (!mpd_send_list_all_meta(conn,"/")) { clear_or_exit_on_error(conn); return 1; } /* add nodes recursively */ struct mpd_entity *entity; while ((entity = mpd_recv_entity(conn))) { DB_NODE *node = (DB_NODE*)malloc(sizeof(DB_NODE)); const char *name = NULL; switch (mpd_entity_get_type(entity)) { case MPD_ENTITY_TYPE_DIRECTORY: node->type = DB_DIRECTORY; name = mpd_directory_get_path(mpd_entity_get_directory(entity)); assert (name && strlen(name)); node->uri = (char *)calloc(strlen(name)+1,sizeof(char)); strncpy(node->uri,name,strlen(name)); node->rating = 0; node->duration = 0; break; case MPD_ENTITY_TYPE_SONG: node->type = DB_SONG; name = mpd_song_get_uri(mpd_entity_get_song(entity)); assert (name && strlen(name)); node->uri = (char *)calloc(strlen(name)+1,sizeof(char)); strncpy(node->uri,name,strlen(name)); node->rating = 0; node->duration = mpd_song_get_duration(mpd_entity_get_song(entity)); break; case MPD_ENTITY_TYPE_PLAYLIST: node->type = DB_PLAYLIST; name = mpd_playlist_get_path(mpd_entity_get_playlist(entity)); assert (name && strlen(name)); node->uri = (char *)calloc(strlen(name)+1,sizeof(char)); strncpy(node->uri,name,strlen(name)); node->rating = 0; node->duration = 0; break; case MPD_ENTITY_TYPE_UNKNOWN: break; } /* backtrace top until it's parent of node */ while (top != root && !(strstr(node->uri,top->uri) && node->uri[strlen(top->uri)] == '/')) top = top->p; /* if current top already has chlidren */ if (top->c) { DB_NODE *node2 = top->c; /* find the last child */ while (node2->s) node2 = node2->s; node2->s = node; node->p = node2->p; node->p->num_c++; } else { top->c = node; node->p = top; node->p->num_c++; } /* no child, no next sibling */ node->c = NULL; node->s = NULL; node->num_c = 0; /* update top node */ if (node->type == DB_DIRECTORY) top = node; mpd_entity_free(entity); } if (mpd_connection_get_error(conn) == MPD_ERROR_SUCCESS) mpd_response_finish(conn); else if (!mpd_connection_clear_error(conn)) exit_on_error(conn); *p_root = root; return 0; }
int main(int argc, char ** argv) { struct mpd_connection *conn; conn = mpd_connection_new(NULL, 0, 30000); if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) return handle_error(conn); { int i; for(i=0;i<3;i++) { printf("version[%i]: %i\n",i, mpd_connection_get_server_version(conn)[i]); } } if(argc==1) { struct mpd_status * status; struct mpd_song *song; const struct mpd_audio_format *audio_format; mpd_command_list_begin(conn, true); mpd_send_status(conn); mpd_send_current_song(conn); mpd_command_list_end(conn); status = mpd_recv_status(conn); if (status == NULL) return handle_error(conn); printf("volume: %i\n", mpd_status_get_volume(status)); printf("repeat: %i\n", mpd_status_get_repeat(status)); printf("queue version: %u\n", mpd_status_get_queue_version(status)); printf("queue length: %i\n", mpd_status_get_queue_length(status)); if (mpd_status_get_error(status) != NULL) printf("error: %s\n", mpd_status_get_error(status)); if (mpd_status_get_state(status) == MPD_STATE_PLAY || mpd_status_get_state(status) == MPD_STATE_PAUSE) { printf("song: %i\n", mpd_status_get_song_pos(status)); printf("elaspedTime: %i\n",mpd_status_get_elapsed_time(status)); printf("elasped_ms: %u\n", mpd_status_get_elapsed_ms(status)); printf("totalTime: %i\n", mpd_status_get_total_time(status)); printf("bitRate: %i\n", mpd_status_get_kbit_rate(status)); } audio_format = mpd_status_get_audio_format(status); if (audio_format != NULL) { printf("sampleRate: %i\n", audio_format->sample_rate); printf("bits: %i\n", audio_format->bits); printf("channels: %i\n", audio_format->channels); } mpd_status_free(status); if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) return handle_error(conn); mpd_response_next(conn); while ((song = mpd_recv_song(conn)) != NULL) { printf("uri: %s\n", mpd_song_get_uri(song)); print_tag(song, MPD_TAG_ARTIST, "artist"); print_tag(song, MPD_TAG_ALBUM, "album"); print_tag(song, MPD_TAG_TITLE, "title"); print_tag(song, MPD_TAG_TRACK, "track"); print_tag(song, MPD_TAG_NAME, "name"); print_tag(song, MPD_TAG_DATE, "date"); if (mpd_song_get_duration(song) > 0) { printf("time: %u\n", mpd_song_get_duration(song)); } printf("pos: %u\n", mpd_song_get_pos(song)); mpd_song_free(song); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } else if(argc==3 && strcmp(argv[1],"lsinfo")==0) { struct mpd_entity * entity; if (!mpd_send_list_meta(conn, argv[2])) return handle_error(conn); while ((entity = mpd_recv_entity(conn)) != NULL) { const struct mpd_song *song; const struct mpd_directory *dir; const struct mpd_playlist *pl; switch (mpd_entity_get_type(entity)) { case MPD_ENTITY_TYPE_UNKNOWN: break; case MPD_ENTITY_TYPE_SONG: song = mpd_entity_get_song(entity); printf("uri: %s\n", mpd_song_get_uri(song)); print_tag(song, MPD_TAG_ARTIST, "artist"); print_tag(song, MPD_TAG_ALBUM, "album"); print_tag(song, MPD_TAG_TITLE, "title"); print_tag(song, MPD_TAG_TRACK, "track"); break; case MPD_ENTITY_TYPE_DIRECTORY: dir = mpd_entity_get_directory(entity); printf("directory: %s\n", mpd_directory_get_path(dir)); break; case MPD_ENTITY_TYPE_PLAYLIST: pl = mpd_entity_get_playlist(entity); printf("playlist: %s\n", mpd_playlist_get_path(pl)); break; } mpd_entity_free(entity); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } else if(argc==2 && strcmp(argv[1],"artists")==0) { struct mpd_pair *pair; if (!mpd_search_db_tags(conn, MPD_TAG_ARTIST) || !mpd_search_commit(conn)) return handle_error(conn); while ((pair = mpd_recv_pair_tag(conn, MPD_TAG_ARTIST)) != NULL) { printf("%s\n", pair->value); mpd_return_pair(conn, pair); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } else if (argc == 2 && strcmp(argv[1], "playlists") == 0) { if (!mpd_send_list_playlists(conn)) return handle_error(conn); struct mpd_playlist *playlist; while ((playlist = mpd_recv_playlist(conn)) != NULL) { printf("%s\n", mpd_playlist_get_path(playlist)); mpd_playlist_free(playlist); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } else if (argc == 2 && strcmp(argv[1], "idle") == 0) { enum mpd_idle idle = mpd_run_idle(conn); if (idle == 0 && mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) return handle_error(conn); for (unsigned j = 0;; ++j) { enum mpd_idle i = 1 << j; const char *name = mpd_idle_name(i); if (name == NULL) break; if (idle & i) printf("%s\n", name); } } else if (argc == 3 && strcmp(argv[1], "subscribe") == 0) { /* subscribe to a channel and print all messages */ if (!mpd_run_subscribe(conn, argv[2])) return handle_error(conn); while (mpd_run_idle_mask(conn, MPD_IDLE_MESSAGE) != 0) { if (!mpd_send_read_messages(conn)) return handle_error(conn); struct mpd_message *msg; while ((msg = mpd_recv_message(conn)) != NULL) { printf("%s\n", mpd_message_get_text(msg)); mpd_message_free(msg); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } return handle_error(conn); } else if (argc == 2 && strcmp(argv[1], "channels") == 0) { /* print a list of channels */ if (!mpd_send_channels(conn)) return handle_error(conn); struct mpd_pair *pair; while ((pair = mpd_recv_channel_pair(conn)) != NULL) { printf("%s\n", pair->value); mpd_return_pair(conn, pair); } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(conn)) return handle_error(conn); } else if (argc == 4 && strcmp(argv[1], "message") == 0) { /* send a message to a channel */ if (!mpd_run_send_message(conn, argv[2], argv[3])) return handle_error(conn); } mpd_connection_free(conn); return 0; }