int mpd_database_update_dir(MpdObj *mi, char *path) { if(path == NULL || !strlen(path)) { debug_printf(DEBUG_ERROR, "path != NULL and strlen(path) > 0 failed"); return MPD_ARGS_ERROR; } if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } mpd_sendUpdateCommand(mi->connection,path); mpd_finishCommand(mi->connection); /* I have no idea why do this ?? it even makes gmpc very very unhappy. * Because it doesnt trigger an signal anymore when updating starts * mi->CurrentState.updatingDb = mpd_getUpdateId(mi->connection); */ /* unlock */ mpd_unlock_conn(mi); /* What I think you should do is to force a direct status updated */ mpd_status_update(mi); return MPD_OK; }
void mpd_database_search_field_start(MpdObj *mi, mpd_TagItems field) { /* * Check argument */ if(mi == NULL || field >= MPD_TAG_NUM_OF_ITEM_TYPES || field < 0) { debug_printf(DEBUG_ERROR, "Argument error"); return ; } if(!mpd_check_connected(mi)) { debug_printf(DEBUG_ERROR, "Not Connected\n"); return ; } if(!mpd_server_check_version(mi, 0,12,0)) { debug_printf(DEBUG_ERROR, "Advanced field list requires mpd 0.12.0 or higher"); return ; } /* lock, so we can work on mi->connection */ if(mpd_lock_conn(mi) != MPD_OK) { debug_printf(DEBUG_ERROR, "Failed to lock connection"); return ; } mpd_startFieldSearch(mi->connection, field); /* Set search type */ mi->search_type = MPD_SEARCH_TYPE_LIST; mi->search_field = field; /* unlock, let the error handler handle any possible error. */ mpd_unlock_conn(mi); return; }
int mpd_database_delete_playlist(MpdObj *mi,char *path) { if(path == NULL) { debug_printf(DEBUG_WARNING, "path == NULL"); return MPD_ARGS_ERROR; } if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } mpd_sendRmCommand(mi->connection,path); mpd_finishCommand(mi->connection); /* unlock */ mpd_unlock_conn(mi); return MPD_OK; }
MpdData *mpd_database_get_playlist_content(MpdObj *mi,char *playlist) { MpdData *data = NULL; mpd_InfoEntity *ent = NULL; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return NULL; } if(!mpd_server_check_version(mi, 0,12,0)) { debug_printf(DEBUG_WARNING, "only works with mpd higher then 0.12.0"); return NULL; } if(mpd_server_check_command_allowed(mi, "listplaylistinfo") != MPD_SERVER_COMMAND_ALLOWED) { debug_printf(DEBUG_WARNING, "Listing playlist content not supported or allowed"); return NULL; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_WARNING,"lock failed\n"); return NULL; } mpd_sendListPlaylistInfoCommand(mi->connection, playlist); while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL) { data = mpd_new_data_struct_append( data ); if(ent->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) { data->type = MPD_DATA_TYPE_DIRECTORY; data->directory = ent->info.directory->path; ent->info.directory->path = NULL; } else if (ent->type == MPD_INFO_ENTITY_TYPE_SONG) { data->type = MPD_DATA_TYPE_SONG; data->song = ent->info.song; ent->info.song = NULL; } else if (ent->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) { data->type = MPD_DATA_TYPE_PLAYLIST; data->playlist = ent->info.playlistFile->path; ent->info.playlistFile->path = NULL; } mpd_freeInfoEntity(ent); } mpd_finishCommand(mi->connection); /* unlock */ mpd_unlock_conn(mi); if(data == NULL) { return NULL; } return mpd_data_get_first(data); }
int mpd_playlist_queue_commit(MpdObj *mi) { if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return MPD_NOT_CONNECTED; } if(mi->queue == NULL) { debug_printf(DEBUG_WARNING,"mi->queue is empty"); return MPD_PLAYLIST_QUEUE_EMPTY; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_WARNING,"lock failed\n"); return MPD_LOCK_FAILED; } mpd_sendCommandListBegin(mi->connection); /* get first item */ mi->queue = mi->queue->first; while(mi->queue != NULL) { if(mi->queue->type == MPD_QUEUE_ADD) { if(mi->queue->path != NULL) { mpd_sendAddCommand(mi->connection, mi->queue->path); } } else if(mi->queue->type == MPD_QUEUE_LOAD) { if(mi->queue->path != NULL) { mpd_sendLoadCommand(mi->connection, mi->queue->path); } } else if (mi->queue->type == MPD_QUEUE_DELETE_ID) { if(mi->queue->id >= 0) { mpd_sendDeleteIdCommand(mi->connection, mi->queue->id); } } else if (mi->queue->type == MPD_QUEUE_DELETE_POS) { if(mi->queue->id >= 0) { mpd_sendDeleteCommand(mi->connection, mi->queue->id); } } mpd_queue_get_next(mi); } mpd_sendCommandListEnd(mi->connection); mpd_finishCommand(mi->connection); mpd_unlock_conn(mi); mpd_status_update(mi); return MPD_OK; }
/** * @param mi A #MpdObj * @param path an Path to a file * * Grabs the song info for a single file. Make sure you pass an url to a song * and not a directory, that might result in strange behauviour. * * @returns a #mpd_Song */ mpd_Song * mpd_database_get_fileinfo(MpdObj *mi,const char *path) { mpd_Song *song = NULL; mpd_InfoEntity *ent = NULL; /* * Check path for availibility and length */ if(path == NULL || path[0] == '\0') { debug_printf(DEBUG_ERROR, "path == NULL || strlen(path) == 0"); return NULL; } if(!mpd_check_connected(mi)) { debug_printf(DEBUG_ERROR, "Not Connected\n"); return NULL; } /* lock, so we can work on mi->connection */ if(mpd_lock_conn(mi) != MPD_OK) { debug_printf(DEBUG_ERROR, "Failed to lock connection"); return NULL; } /* send the request */ mpd_sendListallInfoCommand(mi->connection, path); /* get the first (and only) result */ ent = mpd_getNextInfoEntity(mi->connection); /* finish and clean up libmpdclient */ mpd_finishCommand(mi->connection); /* unlock again */ if(mpd_unlock_conn(mi)) { if(ent) mpd_freeInfoEntity(ent); debug_printf(DEBUG_ERROR, "Failed to unlock"); return NULL; } if(ent == NULL) { debug_printf(DEBUG_ERROR, "Failed to grab song from mpd\n"); return NULL; } if(ent->type != MPD_INFO_ENTITY_TYPE_SONG) { mpd_freeInfoEntity(ent); debug_printf(DEBUG_ERROR, "Failed to grab correct song type from mpd, path might not be a file\n"); return NULL; } /* get the song */ song = ent->info.song; /* remove reference to song from the entity */ ent->info.song = NULL; /* free the entity */ mpd_freeInfoEntity(ent); return song; }
MpdData * mpd_database_get_directory(MpdObj *mi,char *path) { MpdData *data = NULL; mpd_InfoEntity *ent = NULL; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return NULL; } if(path == NULL) { path = "/"; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_WARNING,"lock failed\n"); return NULL; } mpd_sendLsInfoCommand(mi->connection,path); while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL) { data = mpd_new_data_struct_append(data); if(ent->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) { data->type = MPD_DATA_TYPE_DIRECTORY; data->directory = ent->info.directory->path; ent->info.directory->path = NULL; } else if (ent->type == MPD_INFO_ENTITY_TYPE_SONG) { data->type = MPD_DATA_TYPE_SONG; data->song = ent->info.song; ent->info.song = NULL; } else if (ent->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) { data->type = MPD_DATA_TYPE_PLAYLIST; data->playlist = ent->info.playlistFile->path; ent->info.playlistFile->path = NULL; } mpd_freeInfoEntity(ent); } mpd_finishCommand(mi->connection); /* unlock */ mpd_unlock_conn(mi); if(data == NULL) { return NULL; } return mpd_data_get_first(data); }
int mpd_server_get_allowed_commands(MpdObj *mi) { char *temp = NULL; int num_commands = 0; if(!mi){ debug_printf(DEBUG_ERROR, "mi != NULL failed\n"); return MPD_ARGS_ERROR; } if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING, "Not Connected"); return MPD_NOT_CONNECTED; } if(!mpd_server_check_version(mi,0,12,0)){ debug_printf(DEBUG_INFO, "Not supported by mpd"); return MPD_SERVER_NOT_SUPPORTED; } mpd_server_free_commands(mi); if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR, "lock failed"); return MPD_LOCK_FAILED; } mpd_sendCommandsCommand(mi->connection); while((temp = mpd_getNextCommand(mi->connection))) { num_commands++; mi->commands = realloc(mi->commands, (num_commands+1)*sizeof(MpdCommand)); mi->commands[num_commands-1].command_name = temp; mi->commands[num_commands-1].enabled = TRUE; mi->commands[num_commands].command_name = NULL; mi->commands[num_commands].enabled = FALSE; } mpd_finishCommand(mi->connection); mpd_sendNotCommandsCommand(mi->connection); while((temp = mpd_getNextCommand(mi->connection))) { num_commands++; mi->commands = realloc(mi->commands, (num_commands+1)*sizeof(MpdCommand)); mi->commands[num_commands-1].command_name = temp; mi->commands[num_commands-1].enabled = FALSE; mi->commands[num_commands].command_name = NULL; mi->commands[num_commands].enabled = FALSE; } mpd_finishCommand(mi->connection); if(mpd_unlock_conn(mi)) { return MPD_LOCK_FAILED; } return MPD_OK; }
MpdData * mpd_playlist_get_changes_posid(MpdObj *mi,int old_playlist_id) { MpdData *data = NULL; mpd_InfoEntity *ent = NULL; debug_printf(DEBUG_INFO, "Fetching using new plchangesposid command"); if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return NULL; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_WARNING,"lock failed\n"); return NULL; } if(old_playlist_id == -1) { debug_printf(DEBUG_INFO,"get fresh playlist\n"); mpd_sendPlChangesPosIdCommand (mi->connection, 0); /* mpd_sendPlaylistIdCommand(mi->connection, -1); */ } else { mpd_sendPlChangesPosIdCommand (mi->connection, old_playlist_id); } while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL) { if(ent->type == MPD_INFO_ENTITY_TYPE_SONG) { data = mpd_new_data_struct_append(data); data->type = MPD_DATA_TYPE_SONG; data->song = ent->info.song; ent->info.song = NULL; } mpd_freeInfoEntity(ent); } mpd_finishCommand(mi->connection); /* unlock */ if(mpd_unlock_conn(mi)) { debug_printf(DEBUG_WARNING,"mpd_playlist_get_changes: unlock failed.\n"); mpd_data_free(data); return NULL; } if(data == NULL) { return NULL; } return mpd_data_get_first(data); }
int mpd_stats_update_real(MpdObj *mi, ChangedStatusType* what_changed) { ChangedStatusType what_changed_here = 0; if ( what_changed == NULL ) { /* we need to save the current state, because we're called standalone */ memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState)); } if(!mpd_check_connected(mi)) { debug_printf(DEBUG_INFO,"not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } if(mi->stats != NULL) { mpd_freeStats(mi->stats); } mpd_sendStatsCommand(mi->connection); mi->stats = mpd_getStats(mi->connection); if(mi->stats == NULL) { debug_printf(DEBUG_ERROR,"Failed to grab stats from mpd\n"); } else if(mi->stats->dbUpdateTime != mi->OldState.dbUpdateTime) { debug_printf(DEBUG_INFO, "database updated\n"); what_changed_here |= MPD_CST_DATABASE; mi->CurrentState.dbUpdateTime = mi->stats->dbUpdateTime; } if (what_changed) { (*what_changed) |= what_changed_here; } else { if((mi->the_status_changed_callback != NULL) & what_changed_here) { mi->the_status_changed_callback(mi, what_changed_here, mi->the_status_changed_signal_userdata); } } if(mpd_unlock_conn(mi)) { debug_printf(DEBUG_ERROR, "unlock failed"); return MPD_LOCK_FAILED; } return MPD_OK; }
MpdData * mpd_playlist_search_commit(MpdObj *mi) { mpd_InfoEntity *ent = NULL; MpdData *data = NULL; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return NULL; } if(mi->search_type < MPD_SEARCH_TYPE_PLAYLIST_FIND ) { debug_printf(DEBUG_ERROR, "no or wrong search in progress to commit"); return NULL; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return NULL; } mpd_commitSearch(mi->connection); while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL) { if(ent->type == MPD_INFO_ENTITY_TYPE_SONG) { data = mpd_new_data_struct_append(data); data->type = MPD_DATA_TYPE_SONG; data->song = ent->info.song; ent->info.song = NULL; } mpd_freeInfoEntity(ent); } mpd_finishCommand(mi->connection); /* * reset search type */ mi->search_type = MPD_SEARCH_TYPE_NONE; mi->search_field = MPD_TAG_ITEM_ARTIST; /* unlock */ if(mpd_unlock_conn(mi)) { debug_printf(DEBUG_ERROR, "Failed to unlock connection"); if(data)mpd_data_free(data); return NULL; } if(data == NULL) { return NULL; } return mpd_data_get_first(data); }
MpdData * mpd_playlist_get_song_from_pos_range(MpdObj *mi, int start, int stop) { MpdData *data = NULL; int i; mpd_InfoEntity *ent = NULL; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_ERROR, "Not Connected\n"); return NULL; } if(mpd_status_check(mi) != MPD_OK) { debug_printf(DEBUG_ERROR,"Failed grabbing status\n"); return NULL; } if(mpd_lock_conn(mi)) { return NULL; } /* Don't check outside playlist length */ if(!(stop < mi->status->playlistLength)) { stop = mi->status->playlistLength -1; } mpd_sendCommandListBegin(mi->connection); for(i=start; i <= stop; i++){ mpd_sendPlaylistInfoCommand(mi->connection, i); } mpd_sendCommandListEnd(mi->connection); while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL) { if(ent->type == MPD_INFO_ENTITY_TYPE_SONG) { data = mpd_new_data_struct_append(data); data->type = MPD_DATA_TYPE_SONG; data->song = ent->info.song; ent->info.song = NULL; } mpd_freeInfoEntity(ent); } mpd_finishCommand(mi->connection); if(mpd_unlock_conn(mi)) { /*TODO free entity. for now this can never happen */ return NULL; } return data; }
/******************************************************************************* * PLAYLIST */ mpd_Song * mpd_playlist_get_song(MpdObj *mi, int songid) { mpd_Song *song = NULL; mpd_InfoEntity *ent = NULL; if(songid < 0){ debug_printf(DEBUG_ERROR, "songid < 0 Failed"); return NULL; } if(!mpd_check_connected(mi)) { debug_printf(DEBUG_ERROR, "Not Connected\n"); return NULL; } if(mpd_lock_conn(mi)) { return NULL; } debug_printf(DEBUG_INFO, "Trying to grab song with id: %i\n", songid); mpd_sendPlaylistIdCommand(mi->connection, songid); ent = mpd_getNextInfoEntity(mi->connection); mpd_finishCommand(mi->connection); if(mpd_unlock_conn(mi)) { if(ent) mpd_freeInfoEntity(ent); return NULL; } if(ent == NULL) { debug_printf(DEBUG_ERROR, "Failed to grab song from mpd\n"); return NULL; } if(ent->type != MPD_INFO_ENTITY_TYPE_SONG) { mpd_freeInfoEntity(ent); debug_printf(DEBUG_ERROR, "Failed to grab correct song type from mpd\n"); return NULL; } song = ent->info.song; ent->info.song = NULL; mpd_freeInfoEntity(ent); return song; }
int mpd_player_set_random(MpdObj * mi, int random) { if (!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING, "not connected\n"); return MPD_NOT_CONNECTED; } if (mpd_lock_conn(mi)) { debug_printf(DEBUG_WARNING, "lock failed\n"); return MPD_LOCK_FAILED; } mpd_sendRandomCommand(mi->connection, random); mpd_finishCommand(mi->connection); mpd_unlock_conn(mi); mpd_status_queue_update(mi); return MPD_OK; }
int mpd_status_set_crossfade(MpdObj *mi,int crossfade_time) { if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } mpd_sendCrossfadeCommand(mi->connection, crossfade_time); mpd_finishCommand(mi->connection); mpd_unlock_conn(mi); mpd_status_queue_update(mi); return MPD_OK; }
int mpd_playlist_swap_id (MpdObj *mi, int old_id, int new_id) { if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } mpd_sendSwapIdCommand(mi->connection,old_id, new_id); mpd_finishCommand(mi->connection); /* unlock */ mpd_unlock_conn(mi); return MPD_OK; }
MpdData * mpd_database_get_directory_recursive(MpdObj *mi, const char *path) { MpdData *data = NULL; mpd_InfoEntity *ent = NULL; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return NULL; } if(path == '\0' || path[0] == '\0') { debug_printf(DEBUG_ERROR, "argumant invalid\n"); return NULL; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return NULL; } mpd_sendListallInfoCommand(mi->connection,path); while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL) { if (ent->type == MPD_INFO_ENTITY_TYPE_SONG) { data = mpd_new_data_struct_append(data); data->type = MPD_DATA_TYPE_SONG; data->song = ent->info.song; ent->info.song = NULL; } mpd_freeInfoEntity(ent); } mpd_finishCommand(mi->connection); /* unlock */ mpd_unlock_conn(mi); if(data == NULL) { return NULL; } return mpd_data_get_first(data); }
int mpd_playlist_shuffle(MpdObj *mi) { if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } mpd_sendShuffleCommand(mi->connection); mpd_finishCommand(mi->connection); /* unlock */ mpd_unlock_conn(mi); return FALSE; }
int mpd_player_prev(MpdObj * mi) { if (!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING, "not connected\n"); return MPD_NOT_CONNECTED; } if (mpd_lock_conn(mi)) { debug_printf(DEBUG_WARNING, "lock failed\n"); return MPD_LOCK_FAILED; } mpd_sendPrevCommand(mi->connection); mpd_finishCommand(mi->connection); mpd_unlock_conn(mi); if (mpd_status_update(mi)) { return MPD_STATUS_FAILED; } return MPD_OK; }
char * mpd_sticker_song_get(MpdObj *mi, const char *path, const char *tag) { char *retv_value = NULL; char *retv = NULL; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_INFO,"not connected\n"); return NULL; } if(mpd_server_check_command_allowed(mi, "sticker") != MPD_SERVER_COMMAND_ALLOWED) { debug_printf(DEBUG_WARNING, "Command not allowed\n"); return NULL; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return NULL; } mpd_sendGetSongSticker(mi->connection,path, tag); retv_value = mpd_getNextSticker(mi->connection); mpd_finishCommand(mi->connection); if(retv_value && strlen(retv_value) > strlen(tag)){ retv = g_strdup(&retv_value[strlen(tag)]+1); } free(retv_value); if(mi->connection->error == MPD_ERROR_ACK && mi->connection->errorCode == MPD_ACK_ERROR_NO_EXIST) { mpd_clearError(mi->connection); g_free(retv); retv = NULL; } if(mpd_unlock_conn(mi)) { debug_printf(DEBUG_ERROR, "Failed to unlock"); g_free(retv); return NULL; } return retv; }
void mpd_database_playlist_clear(MpdObj *mi, const char *path) { if(!path ) return; if (!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING, "not connected\n"); return; } if (mpd_status_check(mi) != MPD_OK) { debug_printf(DEBUG_WARNING, "Failed to get status\n"); return; } if(mpd_lock_conn(mi)) { return ; } mpd_sendPlaylistClearCommand(mi->connection, (char *)path); mpd_finishCommand(mi->connection); mpd_unlock_conn(mi); }
int mpd_player_play_id(MpdObj * mi, int id) { debug_printf(DEBUG_INFO, "trying to play id: %i\n", id); if (!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING, "not connected\n"); return MPD_NOT_CONNECTED; } if (mpd_lock_conn(mi)) { debug_printf(DEBUG_WARNING, "lock failed\n"); return MPD_LOCK_FAILED; } mpd_sendPlayIdCommand(mi->connection, id); mpd_finishCommand(mi->connection); mpd_unlock_conn(mi); if (mpd_status_update(mi)) { return MPD_STATUS_FAILED; } return MPD_OK; }
int mpd_playlist_clear(MpdObj *mi) { if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_WARNING,"lock failed\n"); return MPD_LOCK_FAILED; } mpd_sendClearCommand(mi->connection); mpd_finishCommand(mi->connection); /* hack to make it update correctly when replacing 1 song */ mi->CurrentState.songid = -1; /* unlock */ mpd_unlock_conn(mi); mpd_status_update(mi); return FALSE; }
int mpd_playlist_set_priority(MpdObj *mi, int song_id, int priority) { if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_server_check_command_allowed(mi, "prioid") != MPD_SERVER_COMMAND_ALLOWED) { return MPD_SERVER_NOT_SUPPORTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } mpd_sendSetPrioId(mi->connection,priority, song_id); mpd_finishCommand(mi->connection); /* unlock */ mpd_unlock_conn(mi); return MPD_OK; }
int mpd_playlist_add_get_id(MpdObj *mi,const char *path) { int songid = -1; if(mi == NULL || path == NULL) { debug_printf(DEBUG_ERROR, "mi == NULL || path == NULL failed"); return MPD_ARGS_ERROR; } if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"mpd_playlist_add: not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_WARNING,"lock failed\n"); return MPD_LOCK_FAILED; } songid = mpd_sendAddIdCommand(mi->connection, path); mpd_finishCommand(mi->connection); mpd_unlock_conn(mi); return songid; }
int mpd_set_connection_timeout(MpdObj *mi, float timeout) { if(mi == NULL) { debug_printf(DEBUG_ERROR, "mi == NULL\n"); return MPD_ARGS_ERROR; } mi->connection_timeout = timeout; if(mpd_check_connected(mi)) { /*TODO: set timeout */ if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } mpd_setConnectionTimeout(mi->connection, timeout); mpd_finishCommand(mi->connection); mpd_unlock_conn(mi); } return MPD_OK; }
int mpd_connect_real(MpdObj *mi,mpd_Connection *connection) { int retv; if(mi == NULL) { /* should return some spiffy error here */ debug_printf(DEBUG_ERROR, "mi != NULL failed"); return MPD_ARGS_ERROR; } /* reset errors */ mi->error = 0; mi->error_mpd_code = 0; if(mi->error_msg != NULL) { free(mi->error_msg); } mi->error_msg = NULL; debug_printf(DEBUG_INFO, "connecting\n"); mpd_init_MpdServerState(&(mi->CurrentState)); memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState)); if(mi->connected) { /* disconnect */ mpd_disconnect(mi); } if(mi->hostname == NULL) { mpd_set_hostname(mi, "localhost"); } /* make sure this is locked */ if(!mi->connection_lock) { mpd_lock_conn(mi); } if(connection) { mi->connection = connection; } else { /* make timeout configurable */ mi->connection = mpd_newConnection(mi->hostname,mi->port,mi->connection_timeout); } if(mi->connection == NULL) { /* TODO: make seperate error message? */ return MPD_NOT_CONNECTED; } if(mpd_check_error(mi) != MPD_OK) { /* TODO: make seperate error message? */ return MPD_NOT_CONNECTED; } /* set connected state */ mi->connected = TRUE; if(mpd_unlock_conn(mi)) { return MPD_LOCK_FAILED; } /* get the commands we are allowed to use */ retv = mpd_server_get_allowed_commands(mi); if(retv!= MPD_OK) { return retv; } if(mi->the_connection_changed_callback != NULL) { mi->the_connection_changed_callback( mi, TRUE, mi->the_connection_changed_signal_userdata ); } debug_printf(DEBUG_INFO, "Connected to mpd"); return MPD_OK; }
/* should be called mpd_database_find */ MpdData * mpd_database_find(MpdObj *mi, int table, char *string, int exact) { MpdData *data = NULL; /* MpdData *artist = NULL; MpdData *album = NULL; */ mpd_InfoEntity *ent = NULL; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return NULL; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_WARNING,"lock failed\n"); return NULL; } if(exact) { mpd_sendFindCommand(mi->connection,table,string); } else { mpd_sendSearchCommand(mi->connection, table,string); } while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL) { data = mpd_new_data_struct_append(data); /* mpd_sendSearch|Find only returns songs */ /* if(ent->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) { data->type = MPD_DATA_TYPE_DIRECTORY; data->directory = ent->info.directory->path; ent->info.directory->path = NULL; } else*/ if (ent->type == MPD_INFO_ENTITY_TYPE_SONG) { data->type = MPD_DATA_TYPE_SONG; data->song = ent->info.song; ent->info.song = NULL; /* This is something the client can and should do */ /* if(data->song->artist != NULL) { int found = FALSE; if(artist != NULL) { MpdData *fartist = mpd_data_get_first(artist); do{ if( (fartist->type == MPD_DATA_TYPE_TAG) && (fartist->tag_type == MPD_TAG_ITEM_ARTIST)) { if(fartist->tag == NULL) { printf("crap this should'nt be \n"); } if(!strcmp(fartist->tag, data->song->artist)) { found = TRUE; } } fartist = mpd_data_get_next_real(fartist, FALSE); }while(fartist && !found); } if(!found) { artist= mpd_new_data_struct_append(artist); artist->type = MPD_DATA_TYPE_TAG; artist->tag_type = MPD_TAG_ITEM_ARTIST; artist->tag = strdup(data->song->artist); } } if(data->song->album != NULL) { int found = FALSE; if(album != NULL) { MpdData *falbum = mpd_data_get_first(album); do{ if( (falbum->type == MPD_DATA_TYPE_TAG) && (falbum->tag_type == MPD_TAG_ITEM_ALBUM)) { if(falbum->tag == NULL) { printf("crap this should'nt be \n"); } if(!strcmp(falbum->tag, data->song->album)) { found = TRUE; } } falbum = mpd_data_get_next_real(falbum, FALSE); }while(falbum && !found); } if(!found) { album = mpd_new_data_struct_append(album); album->type = MPD_DATA_TYPE_TAG; album->tag_type = MPD_TAG_ITEM_ALBUM; album->tag = strdup(data->song->album); } } */ } /* else if (ent->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) { data->type = MPD_DATA_TYPE_PLAYLIST; data->playlist = ent->info.playlistFile->path; ent->info.playlistFile->path = NULL; } */ mpd_freeInfoEntity(ent); } mpd_finishCommand(mi->connection); /* unlock */ mpd_unlock_conn(mi); if(data == NULL) { return NULL; } data = mpd_data_get_first(data); /* prepend the album then artists*/ /* if(album != NULL) { if(data){ data = mpd_data_concatenate( album, data); }else{ data = album; } } if(artist != NULL) { if(data) { album = mpd_data_concatenate( artist, data ); }else{ data = artist; } } */ return mpd_data_get_first(data); }
int mpd_status_update(MpdObj *mi) { ChangedStatusType what_changed=0; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_INFO,"Where not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } if(mi->status != NULL) { mpd_freeStatus(mi->status); mi->status = NULL; } mpd_sendStatusCommand(mi->connection); mi->status = mpd_getStatus(mi->connection); if(mi->status == NULL) { debug_printf(DEBUG_ERROR,"Failed to grab status from mpd\n"); mpd_unlock_conn(mi); return MPD_STATUS_FAILED; } if(mpd_unlock_conn(mi)) { debug_printf(DEBUG_ERROR, "Failed to unlock"); return MPD_LOCK_FAILED; } /* * check for changes */ /* first save the old status */ memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState)); /* playlist change */ if(mi->CurrentState.playlistid != mi->status->playlist) { /* print debug message */ debug_printf(DEBUG_INFO, "Playlist has changed!"); /* We can't trust the current song anymore. so we remove it */ /* tags might have been updated */ if(mi->CurrentSong != NULL) { mpd_freeSong(mi->CurrentSong); mi->CurrentSong = NULL; } /* set MPD_CST_PLAYLIST to be changed */ what_changed |= MPD_CST_PLAYLIST; /* save new id */ mi->CurrentState.playlistid = mi->status->playlist; } /* state change */ if(mi->CurrentState.state != mi->status->state) { what_changed |= MPD_CST_STATE; mi->CurrentState.state = mi->status->state; } if(mi->CurrentState.songid != mi->status->songid) { /* print debug message */ debug_printf(DEBUG_INFO, "Song has changed %i %i!", mi->OldState.songid, mi->status->songid); what_changed |= MPD_CST_SONGID; /* save new songid */ mi->CurrentState.songid = mi->status->songid; } if(mi->CurrentState.songpos != mi->status->song) { /* print debug message */ debug_printf(DEBUG_INFO, "Song has changed %i %i!", mi->OldState.songpos, mi->status->song); what_changed |= MPD_CST_SONGPOS; /* save new songid */ mi->CurrentState.songpos = mi->status->song; } if(mi->CurrentState.repeat != mi->status->repeat) { what_changed |= MPD_CST_REPEAT; mi->CurrentState.repeat = mi->status->repeat; } if(mi->CurrentState.random != mi->status->random) { what_changed |= MPD_CST_RANDOM; mi->CurrentState.random = mi->status->random; } if(mi->CurrentState.volume != mi->status->volume) { what_changed |= MPD_CST_VOLUME; mi->CurrentState.volume = mi->status->volume; } if(mi->CurrentState.xfade != mi->status->crossfade) { what_changed |= MPD_CST_CROSSFADE; mi->CurrentState.xfade = mi->status->crossfade; } if(mi->CurrentState.totaltime != mi->status->totalTime) { what_changed |= MPD_CST_TOTAL_TIME; mi->CurrentState.totaltime = mi->status->totalTime; } if(mi->CurrentState.elapsedtime != mi->status->elapsedTime) { what_changed |= MPD_CST_ELAPSED_TIME; mi->CurrentState.elapsedtime = mi->status->elapsedTime; } /* Check if bitrate changed, happens with vbr encodings. */ if(mi->CurrentState.bitrate != mi->status->bitRate) { what_changed |= MPD_CST_BITRATE; mi->CurrentState.bitrate = mi->status->bitRate; } /* The following 3 probly only happen on a song change, or is it possible in one song/stream? */ /* Check if the sample rate changed */ if(mi->CurrentState.samplerate != mi->status->sampleRate) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.samplerate = mi->status->sampleRate; } /* check if the sampling depth changed */ if(mi->CurrentState.bits != mi->status->bits) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.bits = mi->status->bits; } /* Check if the amount of audio channels changed */ if(mi->CurrentState.channels != mi->status->channels) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.channels = mi->status->channels; } /* Check if the updating changed, * If it stopped, also update the stats for the new db-time. */ if(mi->CurrentState.updatingDb != mi->status->updatingDb ) { what_changed |= MPD_CST_UPDATING; if(!mi->status->updatingDb) { mpd_stats_update_real(mi, &what_changed); } mi->CurrentState.updatingDb = mi->status->updatingDb; } /* Run the callback */ if((mi->the_status_changed_callback != NULL) && what_changed) { mi->the_status_changed_callback( mi, what_changed, mi->the_status_changed_signal_userdata ); } /* We could have lost connection again during signal handling... so before we return check again if we are connected */ if(!mpd_check_connected(mi)) { return MPD_NOT_CONNECTED; } return MPD_OK; }
int mpd_status_update(MpdObj *mi) { ChangedStatusType what_changed=0; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_INFO,"not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } if(mi->status != NULL) { mpd_freeStatus(mi->status); mi->status = NULL; } mpd_sendStatusCommand(mi->connection); mi->status = mpd_getStatus(mi->connection); if(mi->status == NULL) { debug_printf(DEBUG_ERROR,"Failed to grab status from mpd\n"); mpd_unlock_conn(mi); return MPD_STATUS_FAILED; } if(mpd_unlock_conn(mi)) { debug_printf(DEBUG_ERROR, "Failed to unlock"); return MPD_LOCK_FAILED; } /* * check for changes */ /* first save the old status */ memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState)); /* playlist change */ if(mi->CurrentState.playlistid != mi->status->playlist) { /* print debug message */ debug_printf(DEBUG_INFO, "Playlist has changed!"); /* We can't trust the current song anymore. so we remove it */ /* tags might have been updated */ if(mi->CurrentSong != NULL) { mpd_freeSong(mi->CurrentSong); mi->CurrentSong = NULL; } /* set MPD_CST_PLAYLIST to be changed */ what_changed |= MPD_CST_PLAYLIST; if(mi->CurrentState.playlistLength == mi->status->playlistLength) { // what_changed |= MPD_CST_SONGID; } /* save new id */ mi->CurrentState.playlistid = mi->status->playlist; } if(mi->CurrentState.storedplaylistid != mi->status->storedplaylist) { /* set MPD_CST_QUEUE to be changed */ what_changed |= MPD_CST_STORED_PLAYLIST; /* save new id */ mi->CurrentState.storedplaylistid = mi->status->storedplaylist; } /* state change */ if(mi->CurrentState.state != mi->status->state) { what_changed |= MPD_CST_STATE; mi->CurrentState.state = mi->status->state; } if(mi->CurrentState.songid != mi->status->songid) { /* print debug message */ debug_printf(DEBUG_INFO, "Songid has changed %i %i!", mi->OldState.songid, mi->status->songid); what_changed |= MPD_CST_SONGID; /* save new songid */ mi->CurrentState.songid = mi->status->songid; } if(mi->CurrentState.songpos != mi->status->song) { /* print debug message */ debug_printf(DEBUG_INFO, "Songpos has changed %i %i!", mi->OldState.songpos, mi->status->song); what_changed |= MPD_CST_SONGPOS; /* save new songid */ mi->CurrentState.songpos = mi->status->song; } if(mi->CurrentState.nextsongid != mi->status->nextsongid || mi->CurrentState.nextsongpos != mi->status->nextsong) { what_changed |= MPD_CST_NEXTSONG; /* save new songid */ mi->CurrentState.nextsongpos = mi->status->nextsong; mi->CurrentState.nextsongid = mi->status->nextsongid; } if(mi->CurrentState.single != mi->status->single) { what_changed |= MPD_CST_SINGLE_MODE; mi->CurrentState.single = mi->status->single; } if(mi->CurrentState.consume != mi->status->consume) { what_changed |= MPD_CST_CONSUME_MODE; mi->CurrentState.consume = mi->status->consume; } if(mi->CurrentState.repeat != mi->status->repeat) { what_changed |= MPD_CST_REPEAT; mi->CurrentState.repeat = mi->status->repeat; } if(mi->CurrentState.random != mi->status->random) { what_changed |= MPD_CST_RANDOM; mi->CurrentState.random = mi->status->random; } if(mi->CurrentState.volume != mi->status->volume) { what_changed |= MPD_CST_VOLUME; mi->CurrentState.volume = mi->status->volume; } if(mi->CurrentState.xfade != mi->status->crossfade) { what_changed |= MPD_CST_CROSSFADE; mi->CurrentState.xfade = mi->status->crossfade; } if(mi->CurrentState.totaltime != mi->status->totalTime) { what_changed |= MPD_CST_TOTAL_TIME; mi->CurrentState.totaltime = mi->status->totalTime; } if(mi->CurrentState.elapsedtime != mi->status->elapsedTime) { what_changed |= MPD_CST_ELAPSED_TIME; mi->CurrentState.elapsedtime = mi->status->elapsedTime; } /* Check if bitrate changed, happens with vbr encodings. */ if(mi->CurrentState.bitrate != mi->status->bitRate) { what_changed |= MPD_CST_BITRATE; mi->CurrentState.bitrate = mi->status->bitRate; } /* The following 3 probly only happen on a song change, or is it possible in one song/stream? */ /* Check if the sample rate changed */ if(mi->CurrentState.samplerate != mi->status->sampleRate) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.samplerate = mi->status->sampleRate; } /* check if the sampling depth changed */ if(mi->CurrentState.bits != mi->status->bits) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.bits = mi->status->bits; } /* Check if the amount of audio channels changed */ if(mi->CurrentState.channels != mi->status->channels) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.channels = mi->status->channels; } if(mi->status->error) { what_changed |= MPD_CST_SERVER_ERROR; strcpy(mi->CurrentState.error,mi->status->error); mpd_sendClearErrorCommand(mi->connection); mpd_finishCommand(mi->connection); } else { mi->CurrentState.error[0] ='\0'; } /* Check if the updating changed, * If it stopped, also update the stats for the new db-time. */ if(mi->CurrentState.updatingDb != mi->status->updatingDb ) { what_changed |= MPD_CST_UPDATING; if(!mi->status->updatingDb) { mpd_stats_update_real(mi, &what_changed); } mi->CurrentState.updatingDb = mi->status->updatingDb; } mi->CurrentState.playlistLength = mi->status->playlistLength; /* Detect changed outputs */ if(!mi->has_idle) { if(mi->num_outputs >0 ) { mpd_OutputEntity *output = NULL; mpd_sendOutputsCommand(mi->connection); while (( output = mpd_getNextOutput(mi->connection)) != NULL) { if(mi->num_outputs < output->id) { mi->num_outputs++; mi->output_states = realloc(mi->output_states,mi->num_outputs*sizeof(int)); mi->output_states[mi->num_outputs] = output->enabled; what_changed |= MPD_CST_OUTPUT; } if(mi->output_states[output->id] != output->enabled) { mi->output_states[output->id] = output->enabled; what_changed |= MPD_CST_OUTPUT; } mpd_freeOutputElement(output); } mpd_finishCommand(mi->connection); } else { /* if no outputs, lets fetch them */ mpd_server_update_outputs(mi); if(mi->num_outputs == 0) { assert("No outputs defined? that cannot be\n"); } what_changed |= MPD_CST_OUTPUT; } }else { char *name; int update_stats = 0; mpd_sendGetEventsCommand(mi->connection); while((name = mpd_getNextEvent(mi->connection))){ if(strcmp(name, "output") == 0){ what_changed |= MPD_CST_OUTPUT; }else if (strcmp(name, "database") == 0) { if((what_changed&MPD_CST_DATABASE) == 0) { update_stats = 1; } what_changed |= MPD_CST_DATABASE; }else if (strcmp(name, "stored_playlist")==0) { what_changed |= MPD_CST_STORED_PLAYLIST; }else if (strcmp(name, "tag") == 0) { what_changed |= MPD_CST_PLAYLIST; }else if (strcmp (name, "sticker") == 0) { what_changed |= MPD_CST_STICKER; } free(name); } mpd_finishCommand(mi->connection); if(update_stats) { mpd_stats_update_real(mi, &what_changed); } } /* Run the callback */ if((mi->the_status_changed_callback != NULL) && what_changed) { mi->the_status_changed_callback( mi, what_changed, mi->the_status_changed_signal_userdata ); } /* We could have lost connection again during signal handling... so before we return check again if we are connected */ if(!mpd_check_connected(mi)) { return MPD_NOT_CONNECTED; } return MPD_OK; }