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
)
488 MpdData
*data
= NULL
;
489 mpd_InfoEntity
*ent
= NULL
;
490 if(!mpd_check_connected(mi
))
492 debug_printf(DEBUG_WARNING
,"not connected\n");
495 if(!mpd_server_check_version(mi
, 0,12,0))
497 debug_printf(DEBUG_WARNING
, "only works with mpd higher then 0.12.0");
500 if(mpd_server_check_command_allowed(mi
, "listplaylistinfo") != MPD_SERVER_COMMAND_ALLOWED
)
502 debug_printf(DEBUG_WARNING
, "Listing playlist content not supported or allowed");
505 if(mpd_lock_conn(mi
))
507 debug_printf(DEBUG_WARNING
,"lock failed\n");
510 mpd_sendListPlaylistInfoCommand(mi
->connection
, playlist
);
511 while (( ent
= mpd_getNextInfoEntity(mi
->connection
)) != NULL
)
513 if (ent
->type
== MPD_INFO_ENTITY_TYPE_SONG
)
515 data
= mpd_new_data_struct_append( data
);
516 data
->type
= MPD_DATA_TYPE_SONG
;
517 data
->song
= ent
->info
.song
;
519 ent
->info
.song
= NULL
;
522 mpd_freeInfoEntity(ent
);
524 mpd_finishCommand(mi
->connection
);
526 if(mi
->connection
->error
== MPD_ERROR_ACK
&& mi
->connection
->errorCode
== MPD_ACK_ERROR_NO_EXIST
)
528 mpd_clearError(mi
->connection
);
536 return mpd_data_get_first(data
);
539 * @param mi A #MpdObj
540 * @param path an Path to a file
542 * Grabs the song info for a single file. Make sure you pass an url to a song
543 * and not a directory, that might result in strange behauviour.
545 * @returns a #mpd_Song
547 mpd_Song
* mpd_database_get_fileinfo(MpdObj
*mi
,const char *path
)
549 mpd_Song
*song
= NULL
;
550 mpd_InfoEntity
*ent
= NULL
;
552 * Check path for availibility and length
554 if(path
== NULL
|| path
[0] == '\0')
556 debug_printf(DEBUG_ERROR
, "path == NULL || strlen(path) == 0");
559 if(!mpd_check_connected(mi
))
561 debug_printf(DEBUG_ERROR
, "Not Connected\n");
564 /* lock, so we can work on mi->connection */
565 if(mpd_lock_conn(mi
) != MPD_OK
)
567 debug_printf(DEBUG_ERROR
, "Failed to lock connection");
570 /* send the request */
571 mpd_sendListallInfoCommand(mi
->connection
, path
);
572 /* get the first (and only) result */
573 ent
= mpd_getNextInfoEntity(mi
->connection
);
574 /* finish and clean up libmpdclient */
575 mpd_finishCommand(mi
->connection
);
577 if(mpd_unlock_conn(mi
))
579 if(ent
) mpd_freeInfoEntity(ent
);
580 debug_printf(DEBUG_ERROR
, "Failed to unlock");
586 debug_printf(DEBUG_ERROR
, "Failed to grab song from mpd\n");
590 if(ent
->type
!= MPD_INFO_ENTITY_TYPE_SONG
)
592 mpd_freeInfoEntity(ent
);
593 debug_printf(DEBUG_ERROR
, "Failed to grab correct song type from mpd, path might not be a file\n");
597 song
= ent
->info
.song
;
598 /* remove reference to song from the entity */
599 ent
->info
.song
= NULL
;
600 /* free the entity */
601 mpd_freeInfoEntity(ent
);
607 void mpd_database_search_field_start(MpdObj
*mi
, mpd_TagItems field
)
612 if(mi
== NULL
|| field
>= MPD_TAG_NUM_OF_ITEM_TYPES
|| field
< 0)
614 debug_printf(DEBUG_ERROR
, "Argument error");
617 if(!mpd_check_connected(mi
))
619 debug_printf(DEBUG_ERROR
, "Not Connected\n");
622 if(!mpd_server_check_version(mi
, 0,12,0))
624 debug_printf(DEBUG_ERROR
, "Advanced field list requires mpd 0.12.0 or higher");
627 /* lock, so we can work on mi->connection */
628 if(mpd_lock_conn(mi
) != MPD_OK
)
630 debug_printf(DEBUG_ERROR
, "Failed to lock connection");
633 mpd_startFieldSearch(mi
->connection
, field
);
634 /* Set search type */
635 mi
->search_type
= MPD_SEARCH_TYPE_LIST
;
636 mi
->search_field
= field
;
637 /* unlock, let the error handler handle any possible error.
650 * @param mi A #MpdObj
651 * @param exact a boolean indicating if the search is fuzzy or exact
653 * Starts a search, you can add "constraints" by calling mpd_database_search_add_constraint
655 * This function requires mpd 0.12.0 or higher
658 void mpd_database_search_start(MpdObj
*mi
, int exact
)
663 if(mi
== NULL
|| exact
> 1 || exact
< 0)
665 debug_printf(DEBUG_ERROR
, "Argument error");
668 if(!mpd_check_connected(mi
))
670 debug_printf(DEBUG_ERROR
, "Not Connected\n");
673 if(!mpd_server_check_version(mi
, 0,12,0))
675 debug_printf(DEBUG_ERROR
, "Advanced search requires mpd 0.12.0 or higher");
678 /* lock, so we can work on mi->connection */
679 if(mpd_lock_conn(mi
) != MPD_OK
)
681 debug_printf(DEBUG_ERROR
, "Failed to lock connection");
684 mpd_startSearch(mi
->connection
, exact
);
685 /* Set search type */
686 mi
->search_type
= (exact
)? MPD_SEARCH_TYPE_FIND
:MPD_SEARCH_TYPE_SEARCH
;
687 /* unlock, let the error handler handle any possible error.
693 * @param mi A #MpdObj
694 * @param field A #mpd_TagItems
696 * Adds a constraint to the search
698 void mpd_database_search_add_constraint(MpdObj
*mi
, mpd_TagItems field
, const char *value
)
702 debug_printf(DEBUG_ERROR
,"Failed to parse arguments");
705 if(mi
->search_type
== MPD_SEARCH_TYPE_NONE
)
707 debug_printf(DEBUG_ERROR
, "No search to constraint");
710 if(!mpd_check_connected(mi
))
712 debug_printf(DEBUG_ERROR
, "Not Connected\n");
715 if(!mpd_server_check_version(mi
, 0,12,0))
717 debug_printf(DEBUG_ERROR
, "Advanced search requires mpd 0.12.0 or higher");
720 /* lock, so we can work on mi->connection */
721 if(mpd_lock_conn(mi
) != MPD_OK
)
723 debug_printf(DEBUG_ERROR
, "Failed to lock connection");
726 mpd_addConstraintSearch(mi
->connection
, field
, (value
)?value
:"");
727 /* unlock, let the error handler handle any possible error.
733 MpdData
* mpd_database_search_commit(MpdObj
*mi
)
735 mpd_InfoEntity
*ent
= NULL
;
736 MpdData
*data
= NULL
;
737 if(!mpd_check_connected(mi
))
739 debug_printf(DEBUG_WARNING
,"not connected\n");
742 if(mi
->search_type
== MPD_SEARCH_TYPE_NONE
)
744 debug_printf(DEBUG_ERROR
, "no search in progress to commit");
747 if(mpd_lock_conn(mi
))
749 debug_printf(DEBUG_ERROR
,"lock failed\n");
752 mpd_commitSearch(mi
->connection
);
753 if(mi
->search_type
== MPD_SEARCH_TYPE_LIST
)
756 while((string
= mpd_getNextTag(mi
->connection
, mi
->search_field
)))
758 data
= mpd_new_data_struct_append(data
);
759 data
->type
= MPD_DATA_TYPE_TAG
;
760 data
->tag_type
= mi
->search_field
;
766 while (( ent
= mpd_getNextInfoEntity(mi
->connection
)) != NULL
)
768 if(ent
->type
== MPD_INFO_ENTITY_TYPE_SONG
)
770 data
= mpd_new_data_struct_append(data
);
771 data
->type
= MPD_DATA_TYPE_SONG
;
772 data
->song
= ent
->info
.song
;
773 ent
->info
.song
= NULL
;
775 mpd_freeInfoEntity(ent
);
778 mpd_finishCommand(mi
->connection
);
782 mi
->search_type
= MPD_SEARCH_TYPE_NONE
;
783 mi
->search_field
= MPD_TAG_ITEM_ARTIST
;
785 if(mpd_unlock_conn(mi
))
787 debug_printf(DEBUG_ERROR
, "Failed to unlock connection");
788 if(data
)mpd_data_free(data
);
795 return mpd_data_get_first(data
);
799 * @param mi A #MpdObj
801 * Starts a search, you can add "constraints" by calling mpd_database_search_add_constraint
802 * to get the result call mpd_database_search_stats_commit
804 * This function requires mpd 0.13.0 or higher
807 void mpd_database_search_stats_start(MpdObj
*mi
)
814 debug_printf(DEBUG_ERROR
, "Argument error");
817 if(!mpd_check_connected(mi
))
819 debug_printf(DEBUG_ERROR
, "Not Connected\n");
822 if(!mpd_server_check_version(mi
, 0,13,0))
824 debug_printf(DEBUG_ERROR
, "Advanced search requires mpd 0.13.0 or higher");
827 /* lock, so we can work on mi->connection */
828 if(mpd_lock_conn(mi
) != MPD_OK
)
830 debug_printf(DEBUG_ERROR
, "Failed to lock connection");
833 mpd_startStatsSearch(mi
->connection
);
834 /* Set search type */
835 mi
->search_type
= MPD_SEARCH_TYPE_STATS
;
836 /* unlock, let the error handler handle any possible error.
842 MpdDBStats
* mpd_database_search_stats_commit(MpdObj
*mi
)
844 MpdDBStats
*data
= NULL
;
845 if(!mpd_check_connected(mi
))
847 debug_printf(DEBUG_WARNING
,"not connected\n");
850 if(mi
->search_type
!= MPD_SEARCH_TYPE_STATS
)
852 debug_printf(DEBUG_ERROR
, "no/wrong search in progress to commit");
855 if(mpd_lock_conn(mi
))
857 debug_printf(DEBUG_ERROR
,"lock failed\n");
860 mpd_commitSearch(mi
->connection
);
862 data
= (MpdDBStats
*) mpd_getSearchStats(mi
->connection
);
864 if(mpd_unlock_conn(mi
))
866 debug_printf(DEBUG_ERROR
, "Failed to unlock connection");
867 if(data
)mpd_freeSearchStats((mpd_SearchStats
*)data
);
877 void mpd_database_search_free_stats(MpdDBStats
*data
)
879 mpd_freeSearchStats(data
);
882 void mpd_database_playlist_clear(MpdObj
*mi
, const char *path
)
886 if (!mpd_check_connected(mi
)) {
887 debug_printf(DEBUG_WARNING
, "not connected\n");
890 if (mpd_status_check(mi
) != MPD_OK
) {
891 debug_printf(DEBUG_WARNING
, "Failed to get status\n");
894 if(mpd_lock_conn(mi
))
899 mpd_sendPlaylistClearCommand(mi
->connection
, (char *)path
);
900 mpd_finishCommand(mi
->connection
);
910 void mpd_database_playlist_list_delete(MpdObj
*mi
, const char *path
, int pos
)
914 if (!mpd_check_connected(mi
)) {
915 debug_printf(DEBUG_WARNING
, "not connected\n");
918 if (mpd_status_check(mi
) != MPD_OK
) {
919 debug_printf(DEBUG_WARNING
, "Failed to get status\n");
922 if(mpd_lock_conn(mi
))
927 mpd_sendPlaylistDeleteCommand(mi
->connection
, (char *)path
,pos
);
928 mpd_finishCommand(mi
->connection
);
932 void mpd_database_playlist_list_add(MpdObj
*mi
, const char *path
, const char *file
)
936 if (!mpd_check_connected(mi
)) {
937 debug_printf(DEBUG_WARNING
, "not connected\n");
940 if (mpd_status_check(mi
) != MPD_OK
) {
941 debug_printf(DEBUG_WARNING
, "Failed to get status\n");
944 if(mpd_lock_conn(mi
))
949 mpd_sendPlaylistAddCommand(mi
->connection
, (char *)path
,(char *)file
);
950 mpd_finishCommand(mi
->connection
);
955 MpdData
* mpd_database_get_directory_recursive(MpdObj
*mi
, const char *path
)
957 MpdData
*data
= NULL
;
958 mpd_InfoEntity
*ent
= NULL
;
959 if(!mpd_check_connected(mi
))
961 debug_printf(DEBUG_WARNING
,"not connected\n");
964 if(path
== '\0' || path
[0] == '\0')
966 debug_printf(DEBUG_ERROR
, "argumant invalid\n");
969 if(mpd_lock_conn(mi
))
971 debug_printf(DEBUG_ERROR
,"lock failed\n");
974 mpd_sendListallInfoCommand(mi
->connection
,path
);
975 while (( ent
= mpd_getNextInfoEntity(mi
->connection
)) != NULL
)
978 if (ent
->type
== MPD_INFO_ENTITY_TYPE_SONG
)
980 data
= mpd_new_data_struct_append(data
);
981 data
->type
= MPD_DATA_TYPE_SONG
;
982 data
->song
= ent
->info
.song
;
983 ent
->info
.song
= NULL
;
985 mpd_freeInfoEntity(ent
);
987 mpd_finishCommand(mi
->connection
);
995 return mpd_data_get_first(data
);
997 void mpd_database_playlist_rename(MpdObj
*mi
, const char *old_name
, const char *new_name
)
999 if(!new_name
|| !old_name
)
1001 debug_printf(DEBUG_ERROR
, "old != NULL && new != NULL failed");
1004 if (!mpd_check_connected(mi
)) {
1005 debug_printf(DEBUG_WARNING
, "not connected\n");
1008 if (mpd_status_check(mi
) != MPD_OK
) {
1009 debug_printf(DEBUG_WARNING
, "Failed to get status\n");
1012 if(mpd_lock_conn(mi
))
1017 mpd_sendRenameCommand(mi
->connection
, (char *)old_name
,(char *)new_name
);
1018 mpd_finishCommand(mi
->connection
);
1020 mpd_unlock_conn(mi
);
1023 int mpd_database_playlist_move(MpdObj
*mi
, const char *playlist
, int old_pos
, int new_pos
)
1025 if(!mpd_check_connected(mi
))
1027 debug_printf(DEBUG_WARNING
,"not connected\n");
1028 return MPD_NOT_CONNECTED
;
1030 if(mpd_lock_conn(mi
))
1032 debug_printf(DEBUG_ERROR
,"lock failed\n");
1033 return MPD_LOCK_FAILED
;
1036 mpd_sendPlaylistMoveCommand(mi
->connection
,(char *)playlist
,old_pos
, new_pos
);
1037 mpd_finishCommand(mi
->connection
);
1040 mpd_unlock_conn(mi
);
1045 MpdData
* mpd_database_playlist_list(MpdObj
*mi
)
1047 MpdData
*data
= NULL
;
1048 mpd_InfoEntity
*ent
= NULL
;
1049 if(!mpd_check_connected(mi
))
1051 debug_printf(DEBUG_WARNING
,"not connected\n");
1054 if(mpd_lock_conn(mi
))
1056 debug_printf(DEBUG_ERROR
,"lock failed\n");
1059 if(mpd_server_check_command_allowed(mi
, "listplaylists") == MPD_SERVER_COMMAND_ALLOWED
)
1061 mpd_sendListPlaylistsCommand(mi
->connection
);
1065 mpd_sendLsInfoCommand (mi
->connection
,"/");
1067 while (( ent
= mpd_getNextInfoEntity(mi
->connection
)) != NULL
)
1070 if (ent
->type
== MPD_INFO_ENTITY_TYPE_PLAYLISTFILE
)
1072 data
= mpd_new_data_struct_append(data
);
1073 data
->type
= MPD_DATA_TYPE_PLAYLIST
;
1074 data
->playlist
= ent
->info
.playlistFile
;
1075 ent
->info
.playlistFile
= NULL
;
1077 mpd_freeInfoEntity(ent
);
1079 mpd_finishCommand(mi
->connection
);
1082 mpd_unlock_conn(mi
);
1087 return mpd_data_get_first(data
);