1 /* libmpd (high level libmpdclient library)
2 * Copyright (C) 2004-2009 Qball Cow <qball@sarine.nl>
3 * Project homepage: http://gmpcwiki.sarine.nl/
4
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.
9
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.
14
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.
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #define __USE_GNU
23
24 #include <string.h>
25 #include <stdarg.h>
26 #include <config.h>
27 #include "debug_printf.h"
28 #include "libmpd.h"
29 #include "libmpd-internal.h"
30
31
mpd_playlist_get_playlist_length(MpdObj * mi)32 int mpd_playlist_get_playlist_length(MpdObj *mi)
33 {
34 if(!mpd_check_connected(mi))
35 {
36 debug_printf(DEBUG_WARNING,"not connected\n");
37 return MPD_NOT_CONNECTED;
38 }
39 if(mpd_status_check(mi) != MPD_OK)
40 {
41 debug_printf(DEBUG_ERROR,"Failed grabbing status\n");
42 return MPD_STATUS_FAILED;
43 }
44 return mi->status->playlistLength;
45 }
46
mpd_playlist_get_old_playlist_id(MpdObj * mi)47 long long mpd_playlist_get_old_playlist_id(MpdObj *mi)
48 {
49 return mi->OldState.playlistid;
50 }
51
mpd_playlist_get_playlist_id(MpdObj * mi)52 long long mpd_playlist_get_playlist_id(MpdObj *mi)
53 {
54 if(!mpd_check_connected(mi))
55 {
56 debug_printf(DEBUG_WARNING,"not connected\n");
57 return MPD_NOT_CONNECTED;
58 }
59 if(mpd_status_check(mi) != MPD_OK)
60 {
61 debug_printf(DEBUG_WARNING,"Failed grabbing status\n");
62 return MPD_STATUS_FAILED;
63 }
64 return mi->status->playlist;
65 }
mpd_playlist_add(MpdObj * mi,const char * path)66 int mpd_playlist_add(MpdObj *mi,const char *path)
67 {
68 int retv = mpd_playlist_queue_add(mi, path);
69 if(retv != MPD_OK) return retv;
70 return mpd_playlist_queue_commit(mi);
71 }
72
mpd_playlist_delete_id(MpdObj * mi,int songid)73 int mpd_playlist_delete_id(MpdObj *mi, int songid)
74 {
75 int retv = mpd_playlist_queue_delete_id(mi, songid);
76 if(retv != MPD_OK) return retv;
77 return mpd_playlist_queue_commit(mi);
78 }
79
mpd_playlist_delete_pos(MpdObj * mi,int songpos)80 int mpd_playlist_delete_pos(MpdObj *mi, int songpos)
81 {
82 int retv = mpd_playlist_queue_delete_pos(mi, songpos);
83 if(retv != MPD_OK) return retv;
84 return mpd_playlist_queue_commit(mi);
85 }
86 /*******************************************************************************
87 * PLAYLIST
88 */
mpd_playlist_get_song(MpdObj * mi,int songid)89 mpd_Song * mpd_playlist_get_song(MpdObj *mi, int songid)
90 {
91 mpd_Song *song = NULL;
92 mpd_InfoEntity *ent = NULL;
93 if(songid < 0){
94 debug_printf(DEBUG_ERROR, "songid < 0 Failed");
95 return NULL;
96 }
97 if(!mpd_check_connected(mi))
98 {
99 debug_printf(DEBUG_ERROR, "Not Connected\n");
100 return NULL;
101 }
102
103 if(mpd_lock_conn(mi))
104 {
105 return NULL;
106 }
107 debug_printf(DEBUG_INFO, "Trying to grab song with id: %i\n", songid);
108 mpd_sendPlaylistIdCommand(mi->connection, songid);
109 ent = mpd_getNextInfoEntity(mi->connection);
110 mpd_finishCommand(mi->connection);
111
112 if(mpd_unlock_conn(mi))
113 {
114 if(ent) mpd_freeInfoEntity(ent);
115 return NULL;
116 }
117
118 if(ent == NULL)
119 {
120 debug_printf(DEBUG_ERROR, "Failed to grab song from mpd\n");
121 return NULL;
122 }
123
124 if(ent->type != MPD_INFO_ENTITY_TYPE_SONG)
125 {
126 mpd_freeInfoEntity(ent);
127 debug_printf(DEBUG_ERROR, "Failed to grab correct song type from mpd\n");
128 return NULL;
129 }
130 song = ent->info.song;
131 ent->info.song = NULL;
132
133 mpd_freeInfoEntity(ent);
134
135 return song;
136 }
137
mpd_playlist_get_song_from_pos(MpdObj * mi,int songpos)138 mpd_Song * mpd_playlist_get_song_from_pos(MpdObj *mi, int songpos)
139 {
140 mpd_Song *song = NULL;
141 mpd_InfoEntity *ent = NULL;
142 if(songpos < 0){
143 debug_printf(DEBUG_ERROR, "songpos < 0 Failed");
144 return NULL;
145 }
146 if(!mpd_check_connected(mi))
147 {
148 debug_printf(DEBUG_ERROR, "Not Connected\n");
149 return NULL;
150 }
151
152 if(mpd_lock_conn(mi))
153 {
154 return NULL;
155 }
156 debug_printf(DEBUG_INFO, "Trying to grab song with id: %i\n", songpos);
157 mpd_sendPlaylistInfoCommand(mi->connection, songpos);
158 ent = mpd_getNextInfoEntity(mi->connection);
159 mpd_finishCommand(mi->connection);
160
161 if(mpd_unlock_conn(mi))
162 {
163 /*TODO free entity. for now this can never happen */
164 return NULL;
165 }
166
167 if(ent == NULL)
168 {
169 debug_printf(DEBUG_ERROR, "Failed to grab song from mpd\n");
170 return NULL;
171 }
172
173 if(ent->type != MPD_INFO_ENTITY_TYPE_SONG)
174 {
175 mpd_freeInfoEntity(ent);
176 debug_printf(DEBUG_ERROR, "Failed to grab corect song type from mpd\n");
177 return NULL;
178 }
179 song = ent->info.song;
180 ent->info.song = NULL;
181
182 mpd_freeInfoEntity(ent);
183
184 return song;
185 }
186
mpd_playlist_get_song_from_pos_range(MpdObj * mi,int start,int stop)187 MpdData * mpd_playlist_get_song_from_pos_range(MpdObj *mi, int start, int stop)
188 {
189 MpdData *data = NULL;
190 int i;
191 mpd_InfoEntity *ent = NULL;
192 if(!mpd_check_connected(mi))
193 {
194 debug_printf(DEBUG_ERROR, "Not Connected\n");
195 return NULL;
196 }
197 if(mpd_status_check(mi) != MPD_OK)
198 {
199 debug_printf(DEBUG_ERROR,"Failed grabbing status\n");
200 return NULL;
201 }
202
203 if(mpd_lock_conn(mi))
204 {
205 return NULL;
206 }
207 /* Don't check outside playlist length */
208 if(!(stop < mi->status->playlistLength)) {
209 stop = mi->status->playlistLength -1;
210 }
211 mpd_sendCommandListBegin(mi->connection);
212 for(i=start; i <= stop; i++){
213 mpd_sendPlaylistInfoCommand(mi->connection, i);
214 }
215 mpd_sendCommandListEnd(mi->connection);
216 while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
217 {
218 if(ent->type == MPD_INFO_ENTITY_TYPE_SONG)
219 {
220 data = mpd_new_data_struct_append(data);
221 data->type = MPD_DATA_TYPE_SONG;
222 data->song = ent->info.song;
223 ent->info.song = NULL;
224 }
225 mpd_freeInfoEntity(ent);
226 }
227 mpd_finishCommand(mi->connection);
228
229 if(mpd_unlock_conn(mi))
230 {
231 /*TODO free entity. for now this can never happen */
232 return NULL;
233 }
234 return data;
235 }
236
mpd_playlist_get_current_song(MpdObj * mi)237 mpd_Song * mpd_playlist_get_current_song(MpdObj *mi)
238 {
239 if(!mpd_check_connected(mi))
240 {
241 debug_printf(DEBUG_WARNING, "Not Connected\n");
242 return NULL;
243 }
244
245 if(mpd_status_check(mi) != MPD_OK)
246 {
247 debug_printf(DEBUG_ERROR, "Failed to check status\n");
248 return NULL;
249 }
250
251 if(mi->CurrentSong != NULL && mi->CurrentSong->id != mi->status->songid)
252 {
253 debug_printf(DEBUG_WARNING, "Current song not up2date, updating\n");
254 mpd_freeSong(mi->CurrentSong);
255 mi->CurrentSong = NULL;
256 }
257 /* only update song when playing/pasing */
258 if(mi->CurrentSong == NULL &&
259 (mpd_player_get_state(mi) != MPD_PLAYER_STOP && mpd_player_get_state(mi) != MPD_PLAYER_UNKNOWN))
260 {
261 /* TODO: this to use the geT_current_song_id function */
262 mi->CurrentSong = mpd_playlist_get_song(mi, mpd_player_get_current_song_id(mi));
263 if(mi->CurrentSong == NULL)
264 {
265 debug_printf(DEBUG_ERROR, "Failed to grab song\n");
266 return NULL;
267 }
268 }
269 return mi->CurrentSong;
270 }
271
mpd_playlist_clear(MpdObj * mi)272 int mpd_playlist_clear(MpdObj *mi)
273 {
274 if(!mpd_check_connected(mi))
275 {
276 debug_printf(DEBUG_WARNING,"not connected\n");
277 return MPD_NOT_CONNECTED;
278 }
279 if(mpd_lock_conn(mi))
280 {
281 debug_printf(DEBUG_WARNING,"lock failed\n");
282 return MPD_LOCK_FAILED;
283 }
284
285 mpd_sendClearCommand(mi->connection);
286 mpd_finishCommand(mi->connection);
287 /* hack to make it update correctly when replacing 1 song */
288 mi->CurrentState.songid = -1;
289 /* unlock */
290 mpd_unlock_conn(mi);
291 mpd_status_update(mi);
292 return FALSE;
293 }
294
mpd_playlist_shuffle(MpdObj * mi)295 int mpd_playlist_shuffle(MpdObj *mi)
296 {
297 if(!mpd_check_connected(mi))
298 {
299 debug_printf(DEBUG_WARNING,"not connected\n");
300 return MPD_NOT_CONNECTED;
301 }
302 if(mpd_lock_conn(mi))
303 {
304 debug_printf(DEBUG_ERROR,"lock failed\n");
305 return MPD_LOCK_FAILED;
306 }
307
308 mpd_sendShuffleCommand(mi->connection);
309 mpd_finishCommand(mi->connection);
310
311 /* unlock */
312 mpd_unlock_conn(mi);
313 return FALSE;
314
315 }
316
317
mpd_playlist_move_id(MpdObj * mi,int old_id,int new_id)318 int mpd_playlist_move_id(MpdObj *mi, int old_id, int new_id)
319 {
320 if(!mpd_check_connected(mi))
321 {
322 debug_printf(DEBUG_WARNING,"not connected\n");
323 return MPD_NOT_CONNECTED;
324 }
325 if(mpd_lock_conn(mi))
326 {
327 debug_printf(DEBUG_ERROR,"lock failed\n");
328 return MPD_LOCK_FAILED;
329 }
330
331 mpd_sendMoveIdCommand(mi->connection,old_id, new_id);
332 mpd_finishCommand(mi->connection);
333
334 /* unlock */
335 mpd_unlock_conn(mi);
336 return MPD_OK;
337 }
338
mpd_playlist_move_pos(MpdObj * mi,int old_pos,int new_pos)339 int mpd_playlist_move_pos(MpdObj *mi, int old_pos, int new_pos)
340 {
341 if(!mpd_check_connected(mi))
342 {
343 debug_printf(DEBUG_WARNING,"not connected\n");
344 return MPD_NOT_CONNECTED;
345 }
346 if(mpd_lock_conn(mi))
347 {
348 debug_printf(DEBUG_ERROR,"lock failed\n");
349 return MPD_LOCK_FAILED;
350 }
351
352 mpd_sendMoveCommand(mi->connection,old_pos, new_pos);
353 mpd_finishCommand(mi->connection);
354
355 /* unlock */
356 mpd_unlock_conn(mi);
357 return MPD_OK;
358 }
359
mpd_playlist_get_changes(MpdObj * mi,int old_playlist_id)360 MpdData * mpd_playlist_get_changes(MpdObj *mi,int old_playlist_id)
361 {
362 MpdData *data = NULL;
363 mpd_InfoEntity *ent = NULL;
364 if(!mpd_check_connected(mi))
365 {
366 debug_printf(DEBUG_WARNING,"not connected\n");
367 return NULL;
368 }
369 if(mpd_lock_conn(mi))
370 {
371 debug_printf(DEBUG_WARNING,"lock failed\n");
372 return NULL;
373 }
374
375 if(old_playlist_id == -1)
376 {
377 debug_printf(DEBUG_INFO,"get fresh playlist\n");
378 mpd_sendPlChangesCommand (mi->connection, 0);
379 /* mpd_sendPlaylistIdCommand(mi->connection, -1); */
380 }
381 else
382 {
383 mpd_sendPlChangesCommand (mi->connection, old_playlist_id);
384 }
385
386 while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
387 {
388 if(ent->type == MPD_INFO_ENTITY_TYPE_SONG)
389 {
390 data = mpd_new_data_struct_append(data);
391 data->type = MPD_DATA_TYPE_SONG;
392 data->song = ent->info.song;
393 ent->info.song = NULL;
394 }
395 mpd_freeInfoEntity(ent);
396 }
397 mpd_finishCommand(mi->connection);
398
399 /* unlock */
400 if(mpd_unlock_conn(mi))
401 {
402 debug_printf(DEBUG_WARNING,"mpd_playlist_get_changes: unlock failed.\n");
403 mpd_data_free(data);
404 return NULL;
405 }
406 if(data == NULL)
407 {
408 return NULL;
409 }
410 return mpd_data_get_first(data);
411 }
412
413
414
mpd_playlist_get_changes_posid(MpdObj * mi,int old_playlist_id)415 MpdData * mpd_playlist_get_changes_posid(MpdObj *mi,int old_playlist_id)
416 {
417 MpdData *data = NULL;
418 mpd_InfoEntity *ent = NULL;
419 debug_printf(DEBUG_INFO, "Fetching using new plchangesposid command");
420 if(!mpd_check_connected(mi))
421 {
422 debug_printf(DEBUG_WARNING,"not connected\n");
423 return NULL;
424 }
425 if(mpd_lock_conn(mi))
426 {
427 debug_printf(DEBUG_WARNING,"lock failed\n");
428 return NULL;
429 }
430
431 if(old_playlist_id == -1)
432 {
433 debug_printf(DEBUG_INFO,"get fresh playlist\n");
434 mpd_sendPlChangesPosIdCommand (mi->connection, 0);
435 /* mpd_sendPlaylistIdCommand(mi->connection, -1); */
436 }
437 else
438 {
439 mpd_sendPlChangesPosIdCommand (mi->connection, old_playlist_id);
440 }
441
442 while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
443 {
444 if(ent->type == MPD_INFO_ENTITY_TYPE_SONG)
445 {
446 data = mpd_new_data_struct_append(data);
447 data->type = MPD_DATA_TYPE_SONG;
448 data->song = ent->info.song;
449 ent->info.song = NULL;
450 }
451 mpd_freeInfoEntity(ent);
452 }
453 mpd_finishCommand(mi->connection);
454
455 /* unlock */
456 if(mpd_unlock_conn(mi))
457 {
458 debug_printf(DEBUG_WARNING,"mpd_playlist_get_changes: unlock failed.\n");
459 mpd_data_free(data);
460 return NULL;
461 }
462 if(data == NULL)
463 {
464 return NULL;
465 }
466 return mpd_data_get_first(data);
467 }
468
mpd_playlist_queue_add(MpdObj * mi,const char * path)469 int mpd_playlist_queue_add(MpdObj *mi,const char *path)
470 {
471 if(!mpd_check_connected(mi))
472 {
473 debug_printf(DEBUG_WARNING,"not connected\n");
474 return MPD_NOT_CONNECTED;
475 }
476 if(path == NULL)
477 {
478 debug_printf(DEBUG_ERROR, "path != NULL Failed");
479 return MPD_ARGS_ERROR;
480 }
481
482 if(mi->queue == NULL)
483 {
484 mi->queue = mpd_new_queue_struct();
485 mi->queue->first = mi->queue;
486 mi->queue->next = NULL;
487 mi->queue->prev = NULL;
488 }
489 else
490 {
491 mi->queue->next = mpd_new_queue_struct();
492 mi->queue->next->first = mi->queue->first;
493 mi->queue->next->prev = mi->queue;
494 mi->queue = mi->queue->next;
495 mi->queue->next = NULL;
496 }
497 mi->queue->type = MPD_QUEUE_ADD;
498 mi->queue->path = strdup(path);
499 return MPD_OK;
500 }
501
mpd_playlist_queue_load(MpdObj * mi,const char * path)502 int mpd_playlist_queue_load(MpdObj *mi,const char *path)
503 {
504 if(!mpd_check_connected(mi))
505 {
506 debug_printf(DEBUG_WARNING,"not connected\n");
507 return MPD_NOT_CONNECTED;
508 }
509 if(path == NULL)
510 {
511 debug_printf(DEBUG_ERROR, "path != NULL Failed");
512 return MPD_ARGS_ERROR;
513 }
514
515 if(mi->queue == NULL)
516 {
517 mi->queue = mpd_new_queue_struct();
518 mi->queue->first = mi->queue;
519 mi->queue->next = NULL;
520 mi->queue->prev = NULL;
521 }
522 else
523 {
524 mi->queue->next = mpd_new_queue_struct();
525 mi->queue->next->first = mi->queue->first;
526 mi->queue->next->prev = mi->queue;
527 mi->queue = mi->queue->next;
528 mi->queue->next = NULL;
529 }
530 mi->queue->type = MPD_QUEUE_LOAD;
531 mi->queue->path = strdup(path);
532 return MPD_OK;
533 }
534
535
mpd_playlist_queue_commit(MpdObj * mi)536 int mpd_playlist_queue_commit(MpdObj *mi)
537 {
538 if(!mpd_check_connected(mi))
539 {
540 debug_printf(DEBUG_WARNING,"not connected\n");
541 return MPD_NOT_CONNECTED;
542 }
543 if(mi->queue == NULL)
544 {
545 debug_printf(DEBUG_WARNING,"mi->queue is empty");
546 return MPD_PLAYLIST_QUEUE_EMPTY;
547 }
548 if(mpd_lock_conn(mi))
549 {
550 debug_printf(DEBUG_WARNING,"lock failed\n");
551 return MPD_LOCK_FAILED;
552 }
553 mpd_sendCommandListBegin(mi->connection);
554 /* get first item */
555 mi->queue = mi->queue->first;
556 while(mi->queue != NULL)
557 {
558 if(mi->queue->type == MPD_QUEUE_ADD)
559 {
560 if(mi->queue->path != NULL)
561 {
562 mpd_sendAddCommand(mi->connection, mi->queue->path);
563 }
564 }
565 else if(mi->queue->type == MPD_QUEUE_LOAD)
566 {
567 if(mi->queue->path != NULL)
568 {
569 mpd_sendLoadCommand(mi->connection, mi->queue->path);
570 }
571 }
572 else if (mi->queue->type == MPD_QUEUE_DELETE_ID)
573 {
574 if(mi->queue->id >= 0)
575 {
576 mpd_sendDeleteIdCommand(mi->connection, mi->queue->id);
577 }
578 }
579 else if (mi->queue->type == MPD_QUEUE_DELETE_POS)
580 {
581 if(mi->queue->id >= 0)
582 {
583 mpd_sendDeleteCommand(mi->connection, mi->queue->id);
584 }
585 }
586
587 mpd_queue_get_next(mi);
588 }
589 mpd_sendCommandListEnd(mi->connection);
590 mpd_finishCommand(mi->connection);
591
592
593
594 mpd_unlock_conn(mi);
595 mpd_status_update(mi);
596 return MPD_OK;
597 }
mpd_playlist_queue_delete_id(MpdObj * mi,int id)598 int mpd_playlist_queue_delete_id(MpdObj *mi,int id)
599 {
600 if(!mpd_check_connected(mi))
601 {
602 debug_printf(DEBUG_WARNING,"not connected\n");
603 return MPD_NOT_CONNECTED;
604 }
605
606 if(mi->queue == NULL)
607 {
608 mi->queue = mpd_new_queue_struct();
609 mi->queue->first = mi->queue;
610 mi->queue->next = NULL;
611 mi->queue->prev = NULL;
612 }
613 else
614 {
615 mi->queue->next = mpd_new_queue_struct();
616 mi->queue->next->first = mi->queue->first;
617 mi->queue->next->prev = mi->queue;
618 mi->queue = mi->queue->next;
619 mi->queue->next = NULL;
620 }
621 mi->queue->type = MPD_QUEUE_DELETE_ID;
622 mi->queue->id = id;
623 mi->queue->path = NULL;
624 return MPD_OK;
625 }
626
mpd_playlist_queue_delete_pos(MpdObj * mi,int songpos)627 int mpd_playlist_queue_delete_pos(MpdObj *mi,int songpos)
628 {
629 if(!mpd_check_connected(mi))
630 {
631 debug_printf(DEBUG_WARNING,"mpd_playlist_add: not connected\n");
632 return MPD_NOT_CONNECTED;
633 }
634
635 if(mi->queue == NULL)
636 {
637 mi->queue = mpd_new_queue_struct();
638 mi->queue->first = mi->queue;
639 mi->queue->next = NULL;
640 mi->queue->prev = NULL;
641 }
642 else
643 {
644 mi->queue->next = mpd_new_queue_struct();
645 mi->queue->next->first = mi->queue->first;
646 mi->queue->next->prev = mi->queue;
647 mi->queue = mi->queue->next;
648 mi->queue->next = NULL;
649 }
650 mi->queue->type = MPD_QUEUE_DELETE_POS;
651 mi->queue->id = songpos;
652 mi->queue->path = NULL;
653 return MPD_OK;
654 }
655
mpd_playlist_add_get_id(MpdObj * mi,const char * path)656 int mpd_playlist_add_get_id(MpdObj *mi,const char *path)
657 {
658 int songid = -1;
659 if(mi == NULL || path == NULL)
660 {
661 debug_printf(DEBUG_ERROR, "mi == NULL || path == NULL failed");
662 return MPD_ARGS_ERROR;
663 }
664 if(!mpd_check_connected(mi))
665 {
666 debug_printf(DEBUG_WARNING,"mpd_playlist_add: not connected\n");
667 return MPD_NOT_CONNECTED;
668 }
669 if(mpd_lock_conn(mi))
670 {
671 debug_printf(DEBUG_WARNING,"lock failed\n");
672 return MPD_LOCK_FAILED;
673 }
674 songid = mpd_sendAddIdCommand(mi->connection, path);
675 mpd_finishCommand(mi->connection);
676
677 mpd_unlock_conn(mi);
678 return songid;
679 }
680
mpd_playlist_search_start(MpdObj * mi,int exact)681 void mpd_playlist_search_start(MpdObj *mi, int exact)
682 {
683 /*
684 * Check argument
685 */
686 if(mi == NULL || exact > 1 || exact < 0)
687 {
688 debug_printf(DEBUG_ERROR, "Argument error");
689 return ;
690 }
691 if(!mpd_check_connected(mi))
692 {
693 debug_printf(DEBUG_ERROR, "Not Connected\n");
694 return ;
695 }
696 if(!mpd_server_check_version(mi, 0,12,1))
697 {
698 debug_printf(DEBUG_ERROR, "Advanced search requires mpd 0.12.2 or higher");
699 return ;
700 }
701 /* lock, so we can work on mi->connection */
702 if(mpd_lock_conn(mi) != MPD_OK)
703 {
704 debug_printf(DEBUG_ERROR, "Failed to lock connection");
705 return ;
706 }
707 mpd_startPlaylistSearch(mi->connection, exact);
708 /* Set search type */
709 mi->search_type = (exact)? MPD_SEARCH_TYPE_PLAYLIST_FIND:MPD_SEARCH_TYPE_PLAYLIST_SEARCH;
710 /* unlock, let the error handler handle any possible error.
711 */
712 mpd_unlock_conn(mi);
713 return;
714 }
715
mpd_playlist_search_add_constraint(MpdObj * mi,mpd_TagItems field,const char * value)716 void mpd_playlist_search_add_constraint(MpdObj *mi, mpd_TagItems field,const char *value)
717 {
718 mpd_database_search_add_constraint(mi, field, value);
719 }
mpd_playlist_search_commit(MpdObj * mi)720 MpdData * mpd_playlist_search_commit(MpdObj *mi)
721 {
722 mpd_InfoEntity *ent = NULL;
723 MpdData *data = NULL;
724 if(!mpd_check_connected(mi))
725 {
726 debug_printf(DEBUG_WARNING,"not connected\n");
727 return NULL;
728 }
729 if(mi->search_type < MPD_SEARCH_TYPE_PLAYLIST_FIND )
730 {
731 debug_printf(DEBUG_ERROR, "no or wrong search in progress to commit");
732 return NULL;
733 }
734 if(mpd_lock_conn(mi))
735 {
736 debug_printf(DEBUG_ERROR,"lock failed\n");
737 return NULL;
738 }
739 mpd_commitSearch(mi->connection);
740 while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
741 {
742 if(ent->type == MPD_INFO_ENTITY_TYPE_SONG)
743 {
744 data = mpd_new_data_struct_append(data);
745 data->type = MPD_DATA_TYPE_SONG;
746 data->song = ent->info.song;
747 ent->info.song = NULL;
748 }
749 mpd_freeInfoEntity(ent);
750 }
751 mpd_finishCommand(mi->connection);
752 /*
753 * reset search type
754 */
755 mi->search_type = MPD_SEARCH_TYPE_NONE;
756 mi->search_field = MPD_TAG_ITEM_ARTIST;
757 /* unlock */
758 if(mpd_unlock_conn(mi))
759 {
760 debug_printf(DEBUG_ERROR, "Failed to unlock connection");
761 if(data)mpd_data_free(data);
762 return NULL;
763 }
764 if(data == NULL)
765 {
766 return NULL;
767 }
768 return mpd_data_get_first(data);
769 }
770
771
mpd_playlist_load(MpdObj * mi,const char * path)772 int mpd_playlist_load(MpdObj *mi, const char *path)
773 {
774 int retv = MPD_OK;
775 if(!mpd_check_connected(mi))
776 {
777 debug_printf(DEBUG_WARNING,"mpd_playlist_load: not connected\n");
778 return MPD_NOT_CONNECTED;
779 }
780 if(mpd_lock_conn(mi))
781 {
782 debug_printf(DEBUG_ERROR,"lock failed\n");
783 return NULL;
784 }
785 mpd_sendLoadCommand(mi->connection,path);
786 mpd_finishCommand(mi->connection);
787 if(mi->connection->errorCode == MPD_ACK_ERROR_NO_EXIST)
788 {
789 debug_printf(DEBUG_WARNING, "mpd_playlist_load: failed to load playlist\n");
790 mpd_clearError(mi->connection);
791 retv = MPD_PLAYLIST_LOAD_FAILED;
792 }
793
794 if(mpd_unlock_conn(mi))
795 {
796 debug_printf(DEBUG_ERROR, "Failed to unlock connection");
797 return MPD_LOCK_FAILED;
798 }
799 return retv;
800 }
801