1 /* libmpd (high level libmpdclient library)
2 * Copyright (C) 2004-2009 Qball Cow <qball@sarine.nl>
3 * Project homepage: http://gmpcwiki.sarine.nl/
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "debug_printf.h"
29 #include "libmpd-internal.h"
31 int mpd_database_update_dir(MpdObj
*mi
,const char *path
)
33 if(path
== NULL
|| !strlen(path
))
35 debug_printf(DEBUG_ERROR
, "path != NULL and strlen(path) > 0 failed");
36 return MPD_ARGS_ERROR
;
38 if(!mpd_check_connected(mi
))
40 debug_printf(DEBUG_WARNING
,"not connected\n");
41 return MPD_NOT_CONNECTED
;
45 debug_printf(DEBUG_ERROR
,"lock failed\n");
46 return MPD_LOCK_FAILED
;
49 mpd_sendUpdateCommand(mi
->connection
,path
);
50 mpd_finishCommand(mi
->connection
);
51 /* I have no idea why do this ?? it even makes gmpc very very unhappy.
52 * Because it doesnt trigger an signal anymore when updating starts
53 * mi->CurrentState.updatingDb = mpd_getUpdateId(mi->connection);
58 /* What I think you should do is to force a direct status updated
60 mpd_status_update(mi
);
64 MpdData
* mpd_database_get_artists(MpdObj
*mi
)
68 if(!mpd_check_connected(mi
))
70 debug_printf(DEBUG_WARNING
,"not connected\n");
75 debug_printf(DEBUG_ERROR
,"lock failed\n");
79 mpd_sendListCommand(mi
->connection
,MPD_TABLE_ARTIST
,NULL
);
80 while (( string
= mpd_getNextArtist(mi
->connection
)) != NULL
)
82 data
= mpd_new_data_struct_append(data
);
83 data
->type
= MPD_DATA_TYPE_TAG
;
84 data
->tag_type
= MPD_TAG_ITEM_ARTIST
;
87 mpd_finishCommand(mi
->connection
);
95 /* data = mpd_misc_sort_tag_list(data);*/
96 return mpd_data_get_first(data
);
99 MpdData
* mpd_database_get_albums(MpdObj
*mi
,const char *artist
)
102 MpdData
*data
= NULL
;
103 if(!mpd_check_connected(mi
))
105 debug_printf(DEBUG_WARNING
,"not connected\n");
108 if(mpd_lock_conn(mi
))
110 debug_printf(DEBUG_ERROR
,"lock failed\n");
114 mpd_sendListCommand(mi
->connection
,MPD_TABLE_ALBUM
,artist
);
115 while (( string
= mpd_getNextAlbum(mi
->connection
)) != NULL
)
117 data
= mpd_new_data_struct_append(data
);
118 data
->type
= MPD_DATA_TYPE_TAG
;
119 data
->tag_type
= MPD_TAG_ITEM_ALBUM
;
122 mpd_finishCommand(mi
->connection
);
130 return mpd_data_get_first(data
);
133 MpdData
* mpd_database_get_complete(MpdObj
*mi
)
135 MpdData
*data
= NULL
;
136 mpd_InfoEntity
*ent
= NULL
;
137 if(!mpd_check_connected(mi
))
139 debug_printf(DEBUG_WARNING
,"not connected\n");
142 if(mpd_lock_conn(mi
))
144 debug_printf(DEBUG_ERROR
,"lock failed\n");
147 mpd_sendListallInfoCommand(mi
->connection
, "/");
148 while (( ent
= mpd_getNextInfoEntity(mi
->connection
)) != NULL
)
151 if (ent
->type
== MPD_INFO_ENTITY_TYPE_SONG
)
153 data
= mpd_new_data_struct_append(data
);
154 data
->type
= MPD_DATA_TYPE_SONG
;
155 data
->song
= ent
->info
.song
;
156 ent
->info
.song
= NULL
;
158 mpd_freeInfoEntity(ent
);
160 mpd_finishCommand(mi
->connection
);
168 return mpd_data_get_first(data
);
171 int mpd_database_delete_playlist(MpdObj
*mi
,const char *path
)
175 debug_printf(DEBUG_WARNING
, "path == NULL");
176 return MPD_ARGS_ERROR
;
178 if(!mpd_check_connected(mi
))
180 debug_printf(DEBUG_WARNING
,"not connected\n");
181 return MPD_NOT_CONNECTED
;
183 if(mpd_lock_conn(mi
))
185 debug_printf(DEBUG_ERROR
,"lock failed\n");
186 return MPD_LOCK_FAILED
;
189 mpd_sendRmCommand(mi
->connection
,path
);
190 mpd_finishCommand(mi
->connection
);
197 int mpd_database_save_playlist(MpdObj
*mi
,const char *name
)
199 if(name
== NULL
|| !strlen(name
))
201 debug_printf(DEBUG_WARNING
, "mpd_playlist_save: name != NULL and strlen(name) > 0 failed");
202 return MPD_ARGS_ERROR
;
204 if(!mpd_check_connected(mi
))
206 debug_printf(DEBUG_WARNING
,"mpd_playlist_save: not connected\n");
207 return MPD_NOT_CONNECTED
;
209 if(mpd_lock_conn(mi
))
211 debug_printf(DEBUG_ERROR
,"mpd_playlist_save: lock failed\n");
212 return MPD_LOCK_FAILED
;
215 mpd_sendSaveCommand(mi
->connection
,name
);
216 mpd_finishCommand(mi
->connection
);
217 if(mi
->connection
->error
== MPD_ERROR_ACK
&& mi
->connection
->errorCode
== MPD_ACK_ERROR_EXIST
)
219 mpd_clearError(mi
->connection
);
221 return MPD_DATABASE_PLAYLIST_EXIST
;
229 /* "hack" to keep the compiler happy */
230 typedef int (* QsortCompare
)(const void *a
, const void *b
);
232 static int compa(char **a
,const char **b
)
236 #ifndef NO_SMART_SORT
237 if(!strncasecmp(c
, "The ",4) && strlen(c
) > 4)
241 if(!strncasecmp(d
, "The ",4) && strlen(d
) > 4)
247 return strcasecmp(c
,d
);
250 MpdData
*mpd_misc_sort_tag_list(MpdData
*data
)
256 test
= data
= mpd_data_get_first(data
);
260 test
= mpd_data_get_next_real(test
, FALSE
);
261 }while(test
!= NULL
);
262 array
= malloc(length
*sizeof(char*));
267 array
[i
] = test
->tag
;
268 test
= mpd_data_get_next_real(test
, FALSE
);
270 }while(test
!= NULL
);
272 qsort(array
,length
,sizeof(char *),(QsortCompare
)compa
);
275 test
= mpd_data_get_first(data
);
279 test
->tag
= array
[i
];
280 test
= mpd_data_get_next_real(test
, FALSE
);
282 }while(test
!= NULL
);
284 return mpd_data_get_first(data
);
287 /* should be called mpd_database_find */
288 MpdData
* mpd_database_find(MpdObj
*mi
, int table
,const char *string
, int exact
)
290 MpdData
*data
= NULL
;
291 /* MpdData *artist = NULL;
292 MpdData *album = NULL;
293 */ mpd_InfoEntity
*ent
= NULL
;
294 if(!mpd_check_connected(mi
))
296 debug_printf(DEBUG_WARNING
,"not connected\n");
299 if(mpd_lock_conn(mi
))
301 debug_printf(DEBUG_WARNING
,"lock failed\n");
306 mpd_sendFindCommand(mi
->connection
,table
,string
);
310 mpd_sendSearchCommand(mi
->connection
, table
,string
);
312 while (( ent
= mpd_getNextInfoEntity(mi
->connection
)) != NULL
)
314 data
= mpd_new_data_struct_append(data
);
315 /* mpd_sendSearch|Find only returns songs */
317 if(ent->type == MPD_INFO_ENTITY_TYPE_DIRECTORY)
319 data->type = MPD_DATA_TYPE_DIRECTORY;
320 data->directory = ent->info.directory->path;
321 ent->info.directory->path = NULL;
323 else*/ if (ent
->type
== MPD_INFO_ENTITY_TYPE_SONG
)
325 data
->type
= MPD_DATA_TYPE_SONG
;
326 data
->song
= ent
->info
.song
;
327 ent
->info
.song
= NULL
;
328 /* This is something the client can and should do */
329 /* if(data->song->artist != NULL)
334 MpdData *fartist = mpd_data_get_first(artist);
336 if( (fartist->type == MPD_DATA_TYPE_TAG) && (fartist->tag_type == MPD_TAG_ITEM_ARTIST))
338 if(fartist->tag == NULL)
340 printf("crap this should'nt be \n");
342 if(!strcmp(fartist->tag, data->song->artist))
347 fartist = mpd_data_get_next_real(fartist, FALSE);
348 }while(fartist && !found);
352 artist= mpd_new_data_struct_append(artist);
353 artist->type = MPD_DATA_TYPE_TAG;
354 artist->tag_type = MPD_TAG_ITEM_ARTIST;
355 artist->tag = strdup(data->song->artist);
358 if(data->song->album != NULL)
363 MpdData *falbum = mpd_data_get_first(album);
365 if( (falbum->type == MPD_DATA_TYPE_TAG) && (falbum->tag_type == MPD_TAG_ITEM_ALBUM))
367 if(falbum->tag == NULL)
369 printf("crap this should'nt be \n");
371 if(!strcmp(falbum->tag, data->song->album))
376 falbum = mpd_data_get_next_real(falbum, FALSE);
377 }while(falbum && !found);
381 album = mpd_new_data_struct_append(album);
382 album->type = MPD_DATA_TYPE_TAG;
383 album->tag_type = MPD_TAG_ITEM_ALBUM;
384 album->tag = strdup(data->song->album);
390 else if (ent->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE)
392 data->type = MPD_DATA_TYPE_PLAYLIST;
393 data->playlist = ent->info.playlistFile->path;
394 ent->info.playlistFile->path = NULL;
398 mpd_freeInfoEntity(ent
);
400 mpd_finishCommand(mi
->connection
);
408 data
= mpd_data_get_first(data
);
409 /* prepend the album then artists*/
413 data = mpd_data_concatenate( album, data);
421 album = mpd_data_concatenate( artist, data );
427 return mpd_data_get_first(data
);
430 MpdData
* mpd_database_get_directory(MpdObj
*mi
,const char *path
)
432 MpdData
*data
= NULL
;
433 mpd_InfoEntity
*ent
= NULL
;
434 if(!mpd_check_connected(mi
))
436 debug_printf(DEBUG_WARNING
,"not connected\n");
443 if(mpd_lock_conn(mi
))
445 debug_printf(DEBUG_WARNING
,"lock failed\n");
449 mpd_sendLsInfoCommand(mi
->connection
,path
);
450 while (( ent
= mpd_getNextInfoEntity(mi
->connection
)) != NULL
)
452 data
= mpd_new_data_struct_append(data
);
453 if(ent
->type
== MPD_INFO_ENTITY_TYPE_DIRECTORY
)
455 data
->type
= MPD_DATA_TYPE_DIRECTORY
;
456 data
->directory
= ent
->info
.directory
->path
;
457 ent
->info
.directory
->path
= NULL
;
459 else if (ent
->type
== MPD_INFO_ENTITY_TYPE_SONG
)
461 data
->type
= MPD_DATA_TYPE_SONG
;
462 data
->song
= ent
->info
.song
;
463 ent
->info
.song
= NULL
;
465 else if (ent
->type
== MPD_INFO_ENTITY_TYPE_PLAYLISTFILE
)
467 data
->type
= MPD_DATA_TYPE_PLAYLIST
;
468 data
->playlist
= ent
->info
.playlistFile
;
469 ent
->info
.playlistFile
= NULL
;
472 mpd_freeInfoEntity(ent
);
474 mpd_finishCommand(mi
->connection
);
482 return mpd_data_get_first(data
);
485 MpdData
*mpd_database_get_playlist_content(MpdObj
*mi
,const char *playlist
)
487 MpdData
*data
= NULL
;
488 mpd_InfoEntity
*ent
= NULL
;
489 if(!mpd_check_connected(mi
))
491 debug_printf(DEBUG_WARNING
,"not connected\n");
494 if(!mpd_server_check_version(mi
, 0,12,0))
496 debug_printf(DEBUG_WARNING
, "only works with mpd higher then 0.12.0");
499 if(mpd_server_check_command_allowed(mi
, "listplaylistinfo") != MPD_SERVER_COMMAND_ALLOWED
)
501 debug_printf(DEBUG_WARNING
, "Listing playlist content not supported or allowed");
504 if(mpd_lock_conn(mi
))
506 debug_printf(DEBUG_WARNING
,"lock failed\n");
509 mpd_sendListPlaylistInfoCommand(mi
->connection
, playlist
);
510 while (( ent
= mpd_getNextInfoEntity(mi
->connection
)) != NULL
)
512 data
= mpd_new_data_struct_append( data
);
513 if(ent
->type
== MPD_INFO_ENTITY_TYPE_DIRECTORY
)
515 data
->type
= MPD_DATA_TYPE_DIRECTORY
;
516 data
->directory
= ent
->info
.directory
->path
;
517 ent
->info
.directory
->path
= NULL
;
519 else if (ent
->type
== MPD_INFO_ENTITY_TYPE_SONG
)
521 data
->type
= MPD_DATA_TYPE_SONG
;
522 data
->song
= ent
->info
.song
;
523 ent
->info
.song
= NULL
;
525 else if (ent
->type
== MPD_INFO_ENTITY_TYPE_PLAYLISTFILE
)
527 data
->type
= MPD_DATA_TYPE_PLAYLIST
;
528 data
->playlist
= ent
->info
.playlistFile
;
529 ent
->info
.playlistFile
= NULL
;
532 mpd_freeInfoEntity(ent
);
534 mpd_finishCommand(mi
->connection
);
542 return mpd_data_get_first(data
);
545 * @param mi A #MpdObj
546 * @param path an Path to a file
548 * Grabs the song info for a single file. Make sure you pass an url to a song
549 * and not a directory, that might result in strange behauviour.
551 * @returns a #mpd_Song
553 mpd_Song
* mpd_database_get_fileinfo(MpdObj
*mi
,const char *path
)
555 mpd_Song
*song
= NULL
;
556 mpd_InfoEntity
*ent
= NULL
;
558 * Check path for availibility and length
560 if(path
== NULL
|| path
[0] == '\0')
562 debug_printf(DEBUG_ERROR
, "path == NULL || strlen(path) == 0");
565 if(!mpd_check_connected(mi
))
567 debug_printf(DEBUG_ERROR
, "Not Connected\n");
570 /* lock, so we can work on mi->connection */
571 if(mpd_lock_conn(mi
) != MPD_OK
)
573 debug_printf(DEBUG_ERROR
, "Failed to lock connection");
576 /* send the request */
577 mpd_sendListallInfoCommand(mi
->connection
, path
);
578 /* get the first (and only) result */
579 ent
= mpd_getNextInfoEntity(mi
->connection
);
580 /* finish and clean up libmpdclient */
581 mpd_finishCommand(mi
->connection
);
583 if(mpd_unlock_conn(mi
))
585 if(ent
) mpd_freeInfoEntity(ent
);
586 debug_printf(DEBUG_ERROR
, "Failed to unlock");
592 debug_printf(DEBUG_ERROR
, "Failed to grab song from mpd\n");
596 if(ent
->type
!= MPD_INFO_ENTITY_TYPE_SONG
)
598 mpd_freeInfoEntity(ent
);
599 debug_printf(DEBUG_ERROR
, "Failed to grab correct song type from mpd, path might not be a file\n");
603 song
= ent
->info
.song
;
604 /* remove reference to song from the entity */
605 ent
->info
.song
= NULL
;
606 /* free the entity */
607 mpd_freeInfoEntity(ent
);
613 void mpd_database_search_field_start(MpdObj
*mi
, mpd_TagItems field
)
618 if(mi
== NULL
|| field
>= MPD_TAG_NUM_OF_ITEM_TYPES
|| field
< 0)
620 debug_printf(DEBUG_ERROR
, "Argument error");
623 if(!mpd_check_connected(mi
))
625 debug_printf(DEBUG_ERROR
, "Not Connected\n");
628 if(!mpd_server_check_version(mi
, 0,12,0))
630 debug_printf(DEBUG_ERROR
, "Advanced field list requires mpd 0.12.0 or higher");
633 /* lock, so we can work on mi->connection */
634 if(mpd_lock_conn(mi
) != MPD_OK
)
636 debug_printf(DEBUG_ERROR
, "Failed to lock connection");
639 mpd_startFieldSearch(mi
->connection
, field
);
640 /* Set search type */
641 mi
->search_type
= MPD_SEARCH_TYPE_LIST
;
642 mi
->search_field
= field
;
643 /* unlock, let the error handler handle any possible error.
656 * @param mi A #MpdObj
657 * @param exact a boolean indicating if the search is fuzzy or exact
659 * Starts a search, you can add "constraints" by calling mpd_database_search_add_constraint
661 * This function requires mpd 0.12.0 or higher
664 void mpd_database_search_start(MpdObj
*mi
, int exact
)
669 if(mi
== NULL
|| exact
> 1 || exact
< 0)
671 debug_printf(DEBUG_ERROR
, "Argument error");
674 if(!mpd_check_connected(mi
))
676 debug_printf(DEBUG_ERROR
, "Not Connected\n");
679 if(!mpd_server_check_version(mi
, 0,12,0))
681 debug_printf(DEBUG_ERROR
, "Advanced search requires mpd 0.12.0 or higher");
684 /* lock, so we can work on mi->connection */
685 if(mpd_lock_conn(mi
) != MPD_OK
)
687 debug_printf(DEBUG_ERROR
, "Failed to lock connection");
690 mpd_startSearch(mi
->connection
, exact
);
691 /* Set search type */
692 mi
->search_type
= (exact
)? MPD_SEARCH_TYPE_FIND
:MPD_SEARCH_TYPE_SEARCH
;
693 /* unlock, let the error handler handle any possible error.
699 * @param mi A #MpdObj
700 * @param field A #mpd_TagItems
702 * Adds a constraint to the search
704 void mpd_database_search_add_constraint(MpdObj
*mi
, mpd_TagItems field
, const char *value
)
706 if(mi
== NULL
|| value
== NULL
)
708 debug_printf(DEBUG_ERROR
,"Failed to parse arguments");
711 if(mi
->search_type
== MPD_SEARCH_TYPE_NONE
)
713 debug_printf(DEBUG_ERROR
, "No search to constraint");
716 if(!mpd_check_connected(mi
))
718 debug_printf(DEBUG_ERROR
, "Not Connected\n");
721 if(!mpd_server_check_version(mi
, 0,12,0))
723 debug_printf(DEBUG_ERROR
, "Advanced search requires mpd 0.12.0 or higher");
726 /* lock, so we can work on mi->connection */
727 if(mpd_lock_conn(mi
) != MPD_OK
)
729 debug_printf(DEBUG_ERROR
, "Failed to lock connection");
732 mpd_addConstraintSearch(mi
->connection
, field
, value
);
733 /* unlock, let the error handler handle any possible error.
739 MpdData
* mpd_database_search_commit(MpdObj
*mi
)
741 mpd_InfoEntity
*ent
= NULL
;
742 MpdData
*data
= NULL
;
743 if(!mpd_check_connected(mi
))
745 debug_printf(DEBUG_WARNING
,"not connected\n");
748 if(mi
->search_type
== MPD_SEARCH_TYPE_NONE
)
750 debug_printf(DEBUG_ERROR
, "no search in progress to commit");
753 if(mpd_lock_conn(mi
))
755 debug_printf(DEBUG_ERROR
,"lock failed\n");
758 mpd_commitSearch(mi
->connection
);
759 if(mi
->search_type
== MPD_SEARCH_TYPE_LIST
)
762 while((string
= mpd_getNextTag(mi
->connection
, mi
->search_field
)))
764 data
= mpd_new_data_struct_append(data
);
765 data
->type
= MPD_DATA_TYPE_TAG
;
766 data
->tag_type
= mi
->search_field
;
772 while (( ent
= mpd_getNextInfoEntity(mi
->connection
)) != NULL
)
774 if(ent
->type
== MPD_INFO_ENTITY_TYPE_SONG
)
776 data
= mpd_new_data_struct_append(data
);
777 data
->type
= MPD_DATA_TYPE_SONG
;
778 data
->song
= ent
->info
.song
;
779 ent
->info
.song
= NULL
;
781 mpd_freeInfoEntity(ent
);
784 mpd_finishCommand(mi
->connection
);
788 mi
->search_type
= MPD_SEARCH_TYPE_NONE
;
789 mi
->search_field
= MPD_TAG_ITEM_ARTIST
;
791 if(mpd_unlock_conn(mi
))
793 debug_printf(DEBUG_ERROR
, "Failed to unlock connection");
794 if(data
)mpd_data_free(data
);
801 return mpd_data_get_first(data
);
805 * @param mi A #MpdObj
807 * Starts a search, you can add "constraints" by calling mpd_database_search_add_constraint
808 * to get the result call mpd_database_search_stats_commit
810 * This function requires mpd 0.13.0 or higher
813 void mpd_database_search_stats_start(MpdObj
*mi
)
820 debug_printf(DEBUG_ERROR
, "Argument error");
823 if(!mpd_check_connected(mi
))
825 debug_printf(DEBUG_ERROR
, "Not Connected\n");
828 if(!mpd_server_check_version(mi
, 0,13,0))
830 debug_printf(DEBUG_ERROR
, "Advanced search requires mpd 0.13.0 or higher");
833 /* lock, so we can work on mi->connection */
834 if(mpd_lock_conn(mi
) != MPD_OK
)
836 debug_printf(DEBUG_ERROR
, "Failed to lock connection");
839 mpd_startStatsSearch(mi
->connection
);
840 /* Set search type */
841 mi
->search_type
= MPD_SEARCH_TYPE_STATS
;
842 /* unlock, let the error handler handle any possible error.
848 MpdDBStats
* mpd_database_search_stats_commit(MpdObj
*mi
)
850 MpdDBStats
*data
= NULL
;
851 if(!mpd_check_connected(mi
))
853 debug_printf(DEBUG_WARNING
,"not connected\n");
856 if(mi
->search_type
!= MPD_SEARCH_TYPE_STATS
)
858 debug_printf(DEBUG_ERROR
, "no/wrong search in progress to commit");
861 if(mpd_lock_conn(mi
))
863 debug_printf(DEBUG_ERROR
,"lock failed\n");
866 mpd_commitSearch(mi
->connection
);
868 data
= (MpdDBStats
*) mpd_getSearchStats(mi
->connection
);
870 if(mpd_unlock_conn(mi
))
872 debug_printf(DEBUG_ERROR
, "Failed to unlock connection");
873 if(data
)mpd_freeSearchStats((mpd_SearchStats
*)data
);
883 void mpd_database_search_free_stats(MpdDBStats
*data
)
885 mpd_freeSearchStats(data
);
888 void mpd_database_playlist_clear(MpdObj
*mi
, const char *path
)
892 if (!mpd_check_connected(mi
)) {
893 debug_printf(DEBUG_WARNING
, "not connected\n");
896 if (mpd_status_check(mi
) != MPD_OK
) {
897 debug_printf(DEBUG_WARNING
, "Failed to get status\n");
900 if(mpd_lock_conn(mi
))
905 mpd_sendPlaylistClearCommand(mi
->connection
, (char *)path
);
906 mpd_finishCommand(mi
->connection
);
916 void mpd_database_playlist_list_delete(MpdObj
*mi
, const char *path
, int pos
)
920 if (!mpd_check_connected(mi
)) {
921 debug_printf(DEBUG_WARNING
, "not connected\n");
924 if (mpd_status_check(mi
) != MPD_OK
) {
925 debug_printf(DEBUG_WARNING
, "Failed to get status\n");
928 if(mpd_lock_conn(mi
))
933 mpd_sendPlaylistDeleteCommand(mi
->connection
, (char *)path
,pos
);
934 mpd_finishCommand(mi
->connection
);
938 void mpd_database_playlist_list_add(MpdObj
*mi
, const char *path
, const char *file
)
942 if (!mpd_check_connected(mi
)) {
943 debug_printf(DEBUG_WARNING
, "not connected\n");
946 if (mpd_status_check(mi
) != MPD_OK
) {
947 debug_printf(DEBUG_WARNING
, "Failed to get status\n");
950 if(mpd_lock_conn(mi
))
955 mpd_sendPlaylistAddCommand(mi
->connection
, (char *)path
,(char *)file
);
956 mpd_finishCommand(mi
->connection
);
961 MpdData
* mpd_database_get_directory_recursive(MpdObj
*mi
, const char *path
)
963 MpdData
*data
= NULL
;
964 mpd_InfoEntity
*ent
= NULL
;
965 if(!mpd_check_connected(mi
))
967 debug_printf(DEBUG_WARNING
,"not connected\n");
970 if(path
== '\0' || path
[0] == '\0')
972 debug_printf(DEBUG_ERROR
, "argumant invalid\n");
975 if(mpd_lock_conn(mi
))
977 debug_printf(DEBUG_ERROR
,"lock failed\n");
980 mpd_sendListallInfoCommand(mi
->connection
,path
);
981 while (( ent
= mpd_getNextInfoEntity(mi
->connection
)) != NULL
)
984 if (ent
->type
== MPD_INFO_ENTITY_TYPE_SONG
)
986 data
= mpd_new_data_struct_append(data
);
987 data
->type
= MPD_DATA_TYPE_SONG
;
988 data
->song
= ent
->info
.song
;
989 ent
->info
.song
= NULL
;
991 mpd_freeInfoEntity(ent
);
993 mpd_finishCommand(mi
->connection
);
1001 return mpd_data_get_first(data
);
1003 void mpd_database_playlist_rename(MpdObj
*mi
, const char *old_name
, const char *new_name
)
1005 if(!new_name
|| !old_name
)
1007 debug_printf(DEBUG_ERROR
, "old != NULL && new != NULL failed");
1010 if (!mpd_check_connected(mi
)) {
1011 debug_printf(DEBUG_WARNING
, "not connected\n");
1014 if (mpd_status_check(mi
) != MPD_OK
) {
1015 debug_printf(DEBUG_WARNING
, "Failed to get status\n");
1018 if(mpd_lock_conn(mi
))
1023 mpd_sendRenameCommand(mi
->connection
, (char *)old_name
,(char *)new_name
);
1024 mpd_finishCommand(mi
->connection
);
1026 mpd_unlock_conn(mi
);
1029 int mpd_database_playlist_move(MpdObj
*mi
, const char *playlist
, int old_pos
, int new_pos
)
1031 if(!mpd_check_connected(mi
))
1033 debug_printf(DEBUG_WARNING
,"not connected\n");
1034 return MPD_NOT_CONNECTED
;
1036 if(mpd_lock_conn(mi
))
1038 debug_printf(DEBUG_ERROR
,"lock failed\n");
1039 return MPD_LOCK_FAILED
;
1042 mpd_sendPlaylistMoveCommand(mi
->connection
,(char *)playlist
,old_pos
, new_pos
);
1043 mpd_finishCommand(mi
->connection
);
1046 mpd_unlock_conn(mi
);
1051 MpdData
* mpd_database_playlist_list(MpdObj
*mi
)
1053 MpdData
*data
= NULL
;
1054 mpd_InfoEntity
*ent
= NULL
;
1055 if(!mpd_check_connected(mi
))
1057 debug_printf(DEBUG_WARNING
,"not connected\n");
1060 if(mpd_lock_conn(mi
))
1062 debug_printf(DEBUG_ERROR
,"lock failed\n");
1065 if(mpd_server_check_command_allowed(mi
, "listplaylists") == MPD_SERVER_COMMAND_ALLOWED
)
1067 mpd_sendListPlaylistsCommand(mi
->connection
);
1071 mpd_sendLsInfoCommand (mi
->connection
,"/");
1073 while (( ent
= mpd_getNextInfoEntity(mi
->connection
)) != NULL
)
1076 if (ent
->type
== MPD_INFO_ENTITY_TYPE_PLAYLISTFILE
)
1078 data
= mpd_new_data_struct_append(data
);
1079 data
->type
= MPD_DATA_TYPE_PLAYLIST
;
1080 data
->playlist
= ent
->info
.playlistFile
;
1081 ent
->info
.playlistFile
= NULL
;
1083 mpd_freeInfoEntity(ent
);
1085 mpd_finishCommand(mi
->connection
);
1088 mpd_unlock_conn(mi
);
1093 return mpd_data_get_first(data
);