Add storage API.
[platform/core/api/media-content.git] / src / media_playlist.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 #include <media_filter.h>
19 #include <media_info.h>
20 #include <media_info_private.h>
21 #include <media_playlist.h>
22
23 #define PLAYLIST_ARRAY_SIZE                             20
24 #define PLAYLIST_ARRAY_EXPAND                   10
25 #define MAX_TMP_STR                                             2048
26
27 static __thread GList *g_playlist_item_list = NULL;
28
29 static void __media_playlist_item_add(media_playlist_item_s *item_s);
30 static void __media_playlist_item_release(void);
31 static int __media_playlist_insert_playlist_record(const char *playlist_name, int *playlist_id);
32 static int __media_playlist_insert_item_to_playlist(int playlist_id, const char *media_id);
33 static int __media_playlist_remove_item_from_playlist(int playlist_id, int playlist_member_id);
34 static int __media_playlist_update_playlist_name(int playlist_id, const char *playlist_name);
35 static int __media_playlist_update_thumbnail_path(int playlist_id, const char *path);
36 static int __media_playlist_update_play_order(int playlist_id, int playlist_member_id, int play_order);
37 static int __media_playlist_reset_file(const char* playlist_path);
38 static int __media_playlist_append_to_file(const char* playlist_path, const char* path);
39 static int __media_playlist_import_item_from_file(const char* playlist_path, char*** const item_list, int* item_count);
40 static int __media_playlist_destroy_import_item(char** item_list, int item_count);
41 static void __media_playlist_destroy_export_item(gpointer data);
42
43 static void __media_playlist_item_add(media_playlist_item_s *item_s)
44 {
45         g_playlist_item_list = g_list_append(g_playlist_item_list, item_s);
46 }
47
48 static void __media_playlist_item_release(void)
49 {
50         int idx = 0;
51         int list_cnt = 0;
52         media_playlist_item_s *item = NULL;
53
54         list_cnt = g_list_length(g_playlist_item_list);
55
56         media_content_debug("list_cnt : [%d]", list_cnt);
57
58         for(idx = 0; idx < list_cnt; idx++)
59         {
60                 item = (media_playlist_item_s*)g_list_nth_data(g_playlist_item_list, idx);
61                 if(item != NULL)
62                 {
63                         SAFE_FREE(item->media_id);
64                         SAFE_FREE(item->playlist_name);
65                         SAFE_FREE(item->thumbnail_path);
66                         SAFE_FREE(item);
67                 }
68         }
69
70         g_list_free(g_playlist_item_list);
71         g_playlist_item_list = NULL;
72
73 }
74
75 static int __media_playlist_insert_playlist_record(const char *playlist_name, int *playlist_id)
76 {
77         int ret = MEDIA_CONTENT_ERROR_NONE;
78         char *query_str = NULL;
79         char *select_query = NULL;
80         sqlite3_stmt *stmt = NULL;
81
82         query_str = sqlite3_mprintf(INSERT_PLAYLIST_TO_PLAYLIST, playlist_name);
83
84         ret = _content_query_sql(query_str);
85         sqlite3_free(query_str);
86         media_content_retv_if(ret != MEDIA_CONTENT_ERROR_NONE, ret);
87
88         select_query = sqlite3_mprintf(SELECT_PLAYLIST_ID_FROM_PLAYLIST, playlist_name);
89
90         ret = _content_query_prepare(&stmt, select_query, NULL, NULL);
91         sqlite3_free(select_query);
92         media_content_retv_if(ret != MEDIA_CONTENT_ERROR_NONE, ret);
93
94         while(sqlite3_step(stmt) == SQLITE_ROW)
95         {
96                 *playlist_id = (int)sqlite3_column_int(stmt,0);
97         }
98
99         SQLITE3_FINALIZE(stmt);
100
101         return MEDIA_CONTENT_ERROR_NONE;
102 }
103
104 static int __media_playlist_insert_item_to_playlist(int playlist_id, const char *media_id)
105 {
106         int ret = MEDIA_CONTENT_ERROR_NONE;
107         sqlite3_stmt *stmt = NULL;
108         char select_query[DEFAULT_QUERY_SIZE];
109         char *query_str = NULL;
110         int play_order = 0;
111
112         memset(select_query, 0x00, sizeof(select_query));
113
114         snprintf(select_query, sizeof(select_query), SELECT_MAX_PLAY_ORDER_FROM_PLAYLIST_VIEW, playlist_id);
115
116         /* get the max play_order */
117         ret = _content_query_prepare(&stmt, select_query, NULL, NULL);
118         media_content_retv_if(ret != MEDIA_CONTENT_ERROR_NONE, ret);
119
120         while(sqlite3_step(stmt) == SQLITE_ROW)
121         {
122                 play_order = (int)sqlite3_column_int(stmt, 0);
123         }
124
125         SQLITE3_FINALIZE(stmt);
126
127         ++play_order;
128
129         query_str = sqlite3_mprintf("INSERT INTO %q (playlist_id, media_uuid, play_order) values (%d, '%q', %d)",
130                         DB_TABLE_PLAYLIST_MAP, playlist_id, media_id, play_order);
131         ret = _content_query_sql(query_str);
132         sqlite3_free(query_str);
133
134         return ret;
135 }
136
137 static int __media_playlist_remove_item_from_playlist(int playlist_id, int playlist_member_id)
138 {
139         int ret = MEDIA_CONTENT_ERROR_NONE;
140         char *query_str = NULL;
141
142         query_str = sqlite3_mprintf(REMOVE_PLAYLIST_ITEM_FROM_PLAYLIST_MAP, playlist_id, playlist_member_id);
143
144         ret = _content_query_sql(query_str);
145         sqlite3_free(query_str);
146
147         return ret;
148 }
149
150 static int __media_playlist_update_playlist_name(int playlist_id, const char *playlist_name)
151 {
152         int ret = MEDIA_CONTENT_ERROR_NONE;
153         char *query_str = NULL;
154
155         query_str = sqlite3_mprintf(UPDATE_PLAYLIST_NAME_FROM_PLAYLIST, playlist_name, playlist_id);
156
157         ret = _content_query_sql(query_str);
158         sqlite3_free(query_str);
159
160         return ret;
161 }
162
163 static int __media_playlist_update_thumbnail_path(int playlist_id, const char *path)
164 {
165         int ret = MEDIA_CONTENT_ERROR_NONE;
166         char *query_str = NULL;
167
168         query_str = sqlite3_mprintf(UPDATE_PLAYLIST_THUMBNAIL_FROM_PLAYLIST, path, playlist_id);
169
170         ret = _content_query_sql(query_str);
171         sqlite3_free(query_str);
172
173         return ret;
174 }
175
176 static int __media_playlist_update_play_order(int playlist_id, int playlist_member_id, int play_order)
177 {
178         int ret = MEDIA_CONTENT_ERROR_NONE;
179         char *query_str = NULL;
180
181         query_str = sqlite3_mprintf(UPDATE_PLAYLIST_ORDER_FROM_PLAYLIST_MAP, play_order, playlist_id, playlist_member_id);
182
183         ret = _content_query_sql(query_str);
184         sqlite3_free(query_str);
185
186         return ret;
187 }
188
189 static bool __media_playlist_media_info_cb(media_info_h media, void *user_data)
190 {
191         int ret = MEDIA_CONTENT_ERROR_NONE;
192         char **media_id = (char**)user_data;
193
194         ret = media_info_get_media_id(media, media_id);
195         media_content_retvm_if(ret != MEDIA_CONTENT_ERROR_NONE, FALSE, "media_info_get_media_id fail");
196
197         return TRUE;
198 }
199
200 static bool __media_playlist_member_cb(int playlist_member_id, media_info_h media, void *user_data)
201 {
202         int ret = MEDIA_CONTENT_ERROR_NONE;
203         GList **list = (GList**)user_data;
204         char *path = NULL;
205
206         ret = media_info_get_file_path(media, &path);
207         media_content_retvm_if(ret != MEDIA_CONTENT_ERROR_NONE, FALSE, "media_info_get_file_path fail");
208
209         *list = g_list_append(*list, path);
210
211         return TRUE;
212 }
213
214 static int __media_playlist_reset_file(const char* playlist_path)
215 {
216         FILE *fp = NULL;
217
218         fp = fopen(playlist_path, "wb");
219         media_content_retvm_if(fp == NULL, MEDIA_CONTENT_ERROR_INVALID_OPERATION, "fopen fail");
220
221         fputs("", fp);  // remove previous playlist
222
223         fclose(fp);
224
225         return MEDIA_CONTENT_ERROR_NONE;
226 }
227
228 static int __media_playlist_append_to_file(const char* playlist_path, const char* path)
229 {
230         FILE *fp = NULL;
231
232         fp = fopen(playlist_path, "a"); // append only
233         media_content_retvm_if(fp == NULL, MEDIA_CONTENT_ERROR_INVALID_OPERATION, "fopen fail");
234
235         fputs(path, fp);
236
237         fputs("\n", fp);
238
239         fclose(fp);
240
241         return MEDIA_CONTENT_ERROR_NONE;
242 }
243
244 static int __media_playlist_import_item_from_file(const char* playlist_path, char*** const item_list, int* item_count)
245 {
246         int current_index = 0;                                          // Current record number
247         int current_max_size = PLAYLIST_ARRAY_SIZE;     // Current max number of records in array
248         int tmp_str_len = 0;                                            // Length of the string
249         char *buf = NULL;
250         char *tmp_buf = NULL;
251         char *tmp_str = NULL;                                           // Next line from buffer, this string is used for parsing
252
253         FILE *fp = NULL;
254         long int file_size = 0;
255
256         *item_list = NULL; *item_count = 0;
257
258         fp = fopen(playlist_path, "rb");                // Open as binary for precise estimation of file length
259         media_content_retvm_if(fp == NULL, MEDIA_CONTENT_ERROR_INVALID_OPERATION, "fopen fail");
260
261         fseek(fp, 0, SEEK_END);                                 // Move to the end of file
262         file_size = ftell(fp);                          // Here we can find the size of file
263         fseek(fp, 0 , SEEK_SET);                                        // Return to the beginning of file
264
265         if(file_size == 0) {
266                 media_content_debug("file is empty.");
267                 fclose(fp);
268                 return MEDIA_CONTENT_ERROR_NONE;
269         }
270         // Allocate the memory and copy file content there
271         if(file_size > 0)
272                 buf = malloc(file_size + 1);
273
274         if(buf == NULL)
275         {
276                 media_content_error("Out of Memory");
277                 fclose(fp);
278                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
279         }
280
281         tmp_buf = buf;
282
283         if(fread(buf, file_size, 1, fp) != 1) {
284                 fclose(fp);
285                 SAFE_FREE(buf);
286                 media_content_stderror("fread fail");
287                 return MEDIA_CONTENT_ERROR_INVALID_OPERATION;
288         }
289         buf[file_size] = 0;
290         fclose(fp);
291
292         // Preliminary memory allocation
293         *item_list = calloc(current_max_size, sizeof(char*));
294         tmp_str = malloc(MAX_TMP_STR);
295         if (tmp_str == NULL || *item_list == NULL) {
296                 SAFE_FREE(*item_list);
297                 SAFE_FREE(buf);
298                 SAFE_FREE(tmp_str);
299                 media_content_error("Out of Memory");
300                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
301         }
302         // Here we create format string for sscanf(...) that allows to get a line from buffer
303         char format[25];
304         snprintf(format, 25, "%%%d[^\n]", MAX_TMP_STR);
305
306         // This cycle gets lines one by one from buffer till the end of buffer. Empty line ("\n") must be treated specifically
307         while((sscanf(tmp_buf, format, tmp_str) == 1) || (*tmp_buf == '\n')) {
308                 if(*tmp_buf == '\n') {// Check if there is an empty line, skip '\n' symbol
309                         tmp_buf += 1;
310
311                         if(tmp_buf < (buf + file_size))
312                                 continue;                       // We are still in buffer
313                         else
314                                 break;                          // Empty line was in the end of buffer
315                 }
316
317                 tmp_str_len = strlen(tmp_str);          // Save the length of line
318
319                 if(tmp_str[0] != '#') {                 // Check that the line is not a comment
320                         if(!(current_index < (current_max_size - 1))) {                         // Check if we have completely filled record array
321                                 // Expand array size and relocate the array (records will be copied into new one)
322                                 current_max_size += PLAYLIST_ARRAY_EXPAND;
323                                 char **tmp_ptr = calloc(current_max_size, sizeof(char*));
324                                 if (tmp_ptr == NULL) {
325                                         __media_playlist_destroy_import_item(*item_list, current_index);
326                                         SAFE_FREE(buf);
327                                         SAFE_FREE(tmp_str);
328                                         media_content_error("Out of Memory");
329                                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
330                                 }
331                                 memmove(tmp_ptr, *item_list, sizeof(char*) * current_index);
332                                 SAFE_FREE(*item_list);
333                                 *item_list = tmp_ptr;
334                         }
335
336                         // Save new file path (current string in tmp_str)
337                         (*item_list)[current_index] = malloc(tmp_str_len + 1);
338                         if ((*item_list)[current_index] == NULL) {
339                                 __media_playlist_destroy_import_item(*item_list, current_index);
340                                 SAFE_FREE(buf);
341                                 SAFE_FREE(tmp_str);
342                                 media_content_error("Out of Memory");
343                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
344                         }
345                         memmove((*item_list)[current_index], tmp_str, tmp_str_len + 1);
346
347                         // Increase the index of buffer
348                         current_index += 1;
349                 }
350
351                 tmp_buf += (tmp_str_len + 1);                           // Move position in buffer after the string that was parsed
352         }
353
354         *item_count = current_index;                                            // Now we need to save the number of records in array
355
356         SAFE_FREE(buf);
357         SAFE_FREE(tmp_str);                                             // Free temporary variables
358
359         return MEDIA_CONTENT_ERROR_NONE;
360 }
361
362 static int __media_playlist_destroy_import_item(char** item_list, int item_count)
363 {
364         int i;
365
366         for(i = 0; i < item_count; ++i) {
367                 SAFE_FREE(item_list[i]);
368                 item_list[i] = NULL;
369         }
370
371         if (item_list != NULL) {
372                 SAFE_FREE(item_list);
373                 item_list = NULL;
374         }
375
376         return MEDIA_CONTENT_ERROR_NONE;
377 }
378
379 static void __media_playlist_destroy_export_item(gpointer data)
380 {
381         SAFE_FREE(data);
382         data = NULL;
383 }
384
385 int media_playlist_insert_to_db(const char *name, media_playlist_h *playlist)
386 {
387         int ret = MEDIA_CONTENT_ERROR_NONE;
388         int playlist_id = 0;
389
390         if(!STRING_VALID(name))
391         {
392                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
393                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
394         }
395
396         media_playlist_s *_playlist = (media_playlist_s*)calloc(1, sizeof(media_playlist_s));
397         media_content_retvm_if(_playlist == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
398
399         ret = __media_playlist_insert_playlist_record(name, &playlist_id);
400
401         if(ret != MEDIA_CONTENT_ERROR_NONE)
402         {
403                 SAFE_FREE(_playlist);
404                 return ret;
405         }
406
407         _playlist->playlist_id = playlist_id;
408         _playlist->name = strdup(name);
409
410         if(_playlist->name == NULL)
411         {
412                 SAFE_FREE(_playlist);
413                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
414                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
415         }
416
417         *playlist = (media_playlist_h)_playlist;
418
419         return ret;
420 }
421
422 int media_playlist_delete_from_db(int playlist_id)
423 {
424         int ret = MEDIA_CONTENT_ERROR_NONE;
425         char *query_str = NULL;
426
427         if(playlist_id < 0)
428         {
429                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
430                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
431         }
432
433         query_str = sqlite3_mprintf(DELETE_PLAYLIST_FROM_PLAYLIST, playlist_id);
434
435         ret = _content_query_sql(query_str);
436
437         sqlite3_free(query_str);
438
439         return ret;
440 }
441
442 int media_playlist_get_playlist_count_from_db(filter_h filter, int *playlist_count)
443 {
444         int ret = MEDIA_CONTENT_ERROR_NONE;
445
446         if(playlist_count != NULL)
447         {
448                 ret = _media_db_get_group_count(filter, MEDIA_GROUP_PLAYLIST, playlist_count);
449         }
450         else
451         {
452                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
453                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
454         }
455
456         return ret;
457 }
458
459 int media_playlist_foreach_playlist_from_db(filter_h filter, media_playlist_cb callback, void *user_data)
460 {
461         int ret = MEDIA_CONTENT_ERROR_NONE;
462
463         if(callback == NULL)
464         {
465                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
466                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
467         }
468
469         ret = _media_db_get_playlist(filter, callback, user_data);
470
471         return ret;
472 }
473
474 int media_playlist_get_media_count_from_db(int playlist_id, filter_h filter, int *media_count)
475 {
476         int ret = MEDIA_CONTENT_ERROR_NONE;
477
478         if((playlist_id > 0) && (media_count != NULL))
479         {
480                 ret = _media_db_get_group_item_count_by_id(playlist_id, filter, MEDIA_GROUP_PLAYLIST, media_count);
481         }
482         else
483         {
484                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
485                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
486         }
487
488         return ret;
489 }
490
491 int media_playlist_foreach_media_from_db(int playlist_id, filter_h filter, playlist_member_cb callback, void *user_data)
492 {
493         int ret = MEDIA_CONTENT_ERROR_NONE;
494
495         if((playlist_id > 0) && (callback != NULL))
496         {
497                 ret = _media_db_get_playlist_item(playlist_id, filter, callback, user_data);
498         }
499         else
500         {
501                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
502                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
503         }
504
505         return ret;
506 }
507
508 int media_playlist_destroy(media_playlist_h playlist)
509 {
510         int ret = MEDIA_CONTENT_ERROR_NONE;
511         media_playlist_s *_playlist = (media_playlist_s*)playlist;
512
513         if(_playlist)
514         {
515                 SAFE_FREE(_playlist->name);
516                 SAFE_FREE(_playlist->thumbnail_path);
517                 SAFE_FREE(_playlist);
518
519                 ret = MEDIA_CONTENT_ERROR_NONE;
520         }
521         else
522         {
523                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
524                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
525         }
526
527         return ret;
528 }
529
530 int media_playlist_clone(media_playlist_h *dst, media_playlist_h src)
531 {
532         int ret = MEDIA_CONTENT_ERROR_NONE;
533         media_playlist_s *_src = (media_playlist_s*)src;
534
535         if(_src != NULL)
536         {
537                 media_playlist_s *_dst = (media_playlist_s*)calloc(1, sizeof(media_playlist_s));
538                 media_content_retvm_if(_dst == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
539
540                 _dst->playlist_id = _src->playlist_id;
541
542                 if(STRING_VALID(_src->name))
543                 {
544                         _dst->name = strdup(_src->name);
545                         if(_dst->name == NULL)
546                         {
547                                 media_playlist_destroy((media_playlist_h)_dst);
548                                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
549                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
550                         }
551                 }
552
553                 *dst = (media_playlist_h)_dst;
554
555                 ret = MEDIA_CONTENT_ERROR_NONE;
556         }
557         else
558         {
559                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
560                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
561         }
562
563         return ret;
564 }
565
566 int media_playlist_get_playlist_from_db(int playlist_id, media_playlist_h *playlist)
567 {
568         int ret = MEDIA_CONTENT_ERROR_NONE;
569         sqlite3_stmt *stmt = NULL;
570         char select_query[DEFAULT_QUERY_SIZE];
571
572         if(playlist_id > 0)
573         {
574                 memset(select_query, 0x00, sizeof(select_query));
575
576                 snprintf(select_query, sizeof(select_query), SELECT_PLAYLIST_FROM_PLAYLIST, playlist_id);
577
578                 ret = _content_query_prepare(&stmt, select_query, NULL, NULL);
579                 media_content_retv_if(ret != MEDIA_CONTENT_ERROR_NONE, ret);
580
581                 media_playlist_s *_playlist = NULL;
582
583                 while(sqlite3_step(stmt) == SQLITE_ROW)
584                 {
585                         if(_playlist)
586                                 media_playlist_destroy((media_playlist_h)_playlist);
587
588                         _playlist = (media_playlist_s*)calloc(1, sizeof(media_playlist_s));
589                         if(_playlist == NULL)
590                         {
591                                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
592                                 SQLITE3_FINALIZE(stmt);
593                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
594                         }
595
596                         _playlist->playlist_id = (int)sqlite3_column_int(stmt, 0);
597                         if(STRING_VALID((const char *)sqlite3_column_text(stmt, 1)))
598                                 _playlist->name = strdup((const char *)sqlite3_column_text(stmt, 1));
599                         if(STRING_VALID((const char *)sqlite3_column_text(stmt, 3)))
600                                 _playlist->thumbnail_path = strdup((const char *)sqlite3_column_text(stmt, 3));
601
602                         *playlist = (media_playlist_h)_playlist;
603                 }
604
605                 SQLITE3_FINALIZE(stmt);
606         }
607         else
608         {
609                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
610                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
611         }
612
613         return ret;
614 }
615
616 int media_playlist_get_playlist_id(media_playlist_h playlist, int *playlist_id)
617 {
618         int ret = MEDIA_CONTENT_ERROR_NONE;
619
620         media_playlist_s *_playlist = (media_playlist_s*)playlist;
621
622         if((_playlist != NULL) && (playlist_id != NULL))
623         {
624                 *playlist_id = _playlist->playlist_id;
625         }
626         else
627         {
628                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
629                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
630         }
631
632         return ret;
633 }
634
635 int media_playlist_get_name(media_playlist_h playlist, char **name)
636 {
637         int ret = MEDIA_CONTENT_ERROR_NONE;
638         media_playlist_s *_playlist = (media_playlist_s*)playlist;
639         if(_playlist)
640         {
641                 if(STRING_VALID(_playlist->name))
642                 {
643                         *name = strdup(_playlist->name);
644                         media_content_retvm_if(*name == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
645                 }
646                 else
647                 {
648                         *name = NULL;
649                 }
650
651                 ret = MEDIA_CONTENT_ERROR_NONE;
652         }
653         else
654         {
655                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
656                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
657         }
658
659         return ret;
660 }
661
662 int media_playlist_get_thumbnail_path(media_playlist_h playlist, char **path)
663 {
664         int ret = MEDIA_CONTENT_ERROR_NONE;
665         media_playlist_s *_playlist = (media_playlist_s*)playlist;
666         if(_playlist)
667         {
668                 if(STRING_VALID(_playlist->thumbnail_path))
669                 {
670                         *path = strdup(_playlist->thumbnail_path);
671                         media_content_retvm_if(*path == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
672                 }
673                 else
674                 {
675                         *path = NULL;
676                 }
677
678                 ret = MEDIA_CONTENT_ERROR_NONE;
679         }
680         else
681         {
682                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
683                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
684         }
685
686         return ret;
687 }
688
689 int media_playlist_get_play_order(media_playlist_h playlist, int playlist_member_id, int *play_order)
690 {
691         int ret = MEDIA_CONTENT_ERROR_NONE;
692         media_playlist_s *_playlist = (media_playlist_s*)playlist;
693         int playlist_id = 0;
694         sqlite3_stmt *stmt = NULL;
695         char select_query[DEFAULT_QUERY_SIZE];
696
697         if((_playlist == NULL) || (playlist_member_id < 0) || (play_order == NULL))
698         {
699                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
700                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
701         }
702
703         playlist_id = _playlist->playlist_id;
704
705         memset(select_query, 0x00, sizeof(select_query));
706
707         snprintf(select_query, sizeof(select_query), SELECT_PLAY_ORDER_FROM_PLAYLIST_VIEW, playlist_id, playlist_member_id);
708
709         ret = _content_query_prepare(&stmt, select_query, NULL, NULL);
710         media_content_retv_if(ret != MEDIA_CONTENT_ERROR_NONE, ret);
711
712         while(sqlite3_step(stmt) == SQLITE_ROW)
713         {
714                 *play_order = (int)sqlite3_column_int(stmt, 0);
715         }
716
717         SQLITE3_FINALIZE(stmt);
718
719         return ret;
720 }
721
722 int media_playlist_set_name(media_playlist_h playlist, const char *playlist_name)
723 {
724         int ret = MEDIA_CONTENT_ERROR_NONE;
725         media_playlist_s *_playlist = (media_playlist_s*)playlist;
726
727         if(_playlist != NULL && STRING_VALID(playlist_name))
728         {
729                 SAFE_FREE(_playlist->name);
730
731                 media_playlist_item_s *item = (media_playlist_item_s*)calloc(1, sizeof(media_playlist_item_s));
732                 media_content_retvm_if(item == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
733
734                 item->playlist_name = strdup(playlist_name);
735                 item->function = MEDIA_PLAYLIST_UPDATE_PLAYLIST_NAME;
736                 if(item->playlist_name == NULL)
737                 {
738                         SAFE_FREE(item);
739                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
740                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
741                 }
742
743                 _playlist->name = strdup(playlist_name);
744                 if(_playlist->name == NULL)
745                 {
746                         SAFE_FREE(item->playlist_name);
747                         SAFE_FREE(item);
748                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
749                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
750                 }
751
752                 __media_playlist_item_add(item);
753         }
754         else
755         {
756                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
757                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
758         }
759
760         return ret;
761 }
762
763 int media_playlist_set_thumbnail_path(media_playlist_h playlist, const char *path)
764 {
765         int ret = MEDIA_CONTENT_ERROR_NONE;
766         media_playlist_s *_playlist = (media_playlist_s*)playlist;
767
768         if(_playlist != NULL && STRING_VALID(path))
769         {
770                 SAFE_FREE(_playlist->thumbnail_path);
771
772                 media_playlist_item_s *item = (media_playlist_item_s*)calloc(1, sizeof(media_playlist_item_s));
773                 media_content_retvm_if(item == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
774
775                 item->thumbnail_path = strdup(path);
776                 item->function = MEDIA_PLAYLIST_UPDATE_THUMBNAIL_PATH;
777                 if(item->thumbnail_path == NULL)
778                 {
779                         SAFE_FREE(item);
780                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
781                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
782                 }
783
784                 _playlist->thumbnail_path = strdup(path);
785                 if(_playlist->thumbnail_path == NULL)
786                 {
787                         SAFE_FREE(item->thumbnail_path);
788                         SAFE_FREE(item);
789                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
790                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
791                 }
792
793                 __media_playlist_item_add(item);
794         }
795         else
796         {
797                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
798                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
799         }
800
801         return ret;
802 }
803
804 int media_playlist_set_play_order(media_playlist_h playlist, int playlist_member_id, int play_order)
805 {
806         int ret = MEDIA_CONTENT_ERROR_NONE;
807         media_playlist_s *_playlist = (media_playlist_s*)playlist;
808
809         if((_playlist != NULL) && (playlist_member_id > 0) && (play_order >= 0))
810         {
811                 media_playlist_item_s *item = (media_playlist_item_s*)calloc(1, sizeof(media_playlist_item_s));
812                 media_content_retvm_if(item == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
813
814                 item->playlist_member_id = playlist_member_id;
815                 item->function = MEDIA_PLAYLIST_UPDATE_PLAY_ORDER;
816                 item->play_order = play_order;
817
818                 __media_playlist_item_add(item);
819         }
820         else
821         {
822                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
823                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
824         }
825
826         return ret;
827 }
828
829 int media_playlist_add_media(media_playlist_h playlist, const char *media_id)
830 {
831         int ret = MEDIA_CONTENT_ERROR_NONE;
832         media_playlist_s *_playlist = (media_playlist_s*)playlist;
833
834         if(_playlist != NULL && STRING_VALID(media_id))
835         {
836                 media_playlist_item_s *item = (media_playlist_item_s*)calloc(1, sizeof(media_playlist_item_s));
837                 media_content_retvm_if(item == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
838
839                 item->media_id = strdup(media_id);
840                 item->function = MEDIA_PLAYLIST_ADD;
841
842                 if(item->media_id == NULL)
843                 {
844                         SAFE_FREE(item);
845                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
846                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
847                 }
848
849                 __media_playlist_item_add(item);
850         }
851         else
852         {
853                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
854                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
855         }
856
857         return ret;
858 }
859
860
861 int media_playlist_remove_media(media_playlist_h playlist, int playlist_member_id)
862 {
863         int ret = MEDIA_CONTENT_ERROR_NONE;
864         media_playlist_s *_playlist = (media_playlist_s*)playlist;
865
866         if((_playlist != NULL) && (playlist_member_id > 0))
867         {
868                 media_playlist_item_s *item = (media_playlist_item_s*)calloc(1, sizeof(media_playlist_item_s));
869                 media_content_retvm_if(item == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
870
871                 item->playlist_member_id = playlist_member_id;
872                 item->function = MEDIA_PLAYLIST_REMOVE;
873
874                 __media_playlist_item_add(item);
875         }
876         else
877         {
878                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
879                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
880         }
881
882         return ret;
883 }
884
885 int media_playlist_update_to_db(media_playlist_h playlist)
886 {
887         int ret = MEDIA_CONTENT_ERROR_NONE;
888         media_playlist_s *_playlist = (media_playlist_s*)playlist;
889         int idx = 0;
890         int length = 0;
891         media_playlist_item_s *_playlist_item = NULL;
892
893         if(_playlist == NULL)
894         {
895                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
896                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
897         }
898
899         length = g_list_length(g_playlist_item_list);
900
901         for (idx = 0; idx < length; idx++) {
902                 _playlist_item = (media_playlist_item_s*)g_list_nth_data(g_playlist_item_list, idx);
903                 if(_playlist_item != NULL) {
904                         switch(_playlist_item->function) {
905                                 case MEDIA_PLAYLIST_ADD:
906                                 {
907                                         ret = __media_playlist_insert_item_to_playlist(_playlist->playlist_id, _playlist_item->media_id);
908                                 }
909                                 break;
910
911                                 case MEDIA_PLAYLIST_REMOVE:
912                                 {
913                                         ret = __media_playlist_remove_item_from_playlist(_playlist->playlist_id, _playlist_item->playlist_member_id);
914                                 }
915                                 break;
916
917                                 case MEDIA_PLAYLIST_UPDATE_PLAYLIST_NAME:
918                                 {
919                                         ret = __media_playlist_update_playlist_name(_playlist->playlist_id, _playlist_item->playlist_name);
920                                 }
921                                 break;
922
923                                 case MEDIA_PLAYLIST_UPDATE_THUMBNAIL_PATH:
924                                 {
925                                         ret = __media_playlist_update_thumbnail_path(_playlist->playlist_id, _playlist_item->thumbnail_path);
926                                 }
927                                 break;
928
929                                 case MEDIA_PLAYLIST_UPDATE_PLAY_ORDER:
930                                 {
931                                         ret = __media_playlist_update_play_order(_playlist->playlist_id, _playlist_item->playlist_member_id, _playlist_item->play_order);
932                                 }
933                                 break;
934
935                                 default :
936                                 break;
937                         }
938                 }
939         }
940
941         __media_playlist_item_release();
942
943         return ret;
944 }
945
946 int media_playlist_import_from_file(const char *path, const char *playlist_name, media_playlist_h *playlist)
947 {
948         int ret = MEDIA_CONTENT_ERROR_NONE;
949         char** import_item_list = NULL;
950         int import_item_count = 0;
951         int idx;
952
953         media_content_retvm_if(!STRING_VALID(path), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid path");
954         media_content_retvm_if(!STRING_VALID(playlist_name), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid playlist_name");
955
956         ret = media_playlist_insert_to_db(playlist_name, playlist);
957         media_content_retvm_if(ret != MEDIA_CONTENT_ERROR_NONE, ret, "media_playlist_insert_to_db fail");
958
959         ret = __media_playlist_import_item_from_file(path, &import_item_list, &import_item_count);
960         if(ret != MEDIA_CONTENT_ERROR_NONE)
961         {
962                 __media_playlist_destroy_import_item(import_item_list, import_item_count);
963                 media_content_error("Fail to get playlist from file");
964                 return ret;
965         }
966
967         if (import_item_count == 0)
968         {
969                 media_content_debug("The playlist from file is empty");
970         }
971
972         for (idx=0; idx < import_item_count; idx++)
973         {
974                 filter_h filter = NULL;
975                 char *media_id = NULL;
976                 char *condition = NULL;
977
978                 ret = media_filter_create(&filter);
979                 if(ret != MEDIA_CONTENT_ERROR_NONE)
980                 {
981                         __media_playlist_destroy_import_item(import_item_list, import_item_count);
982                         media_filter_destroy(filter);
983                         media_content_error("error media_filter_create");
984                         return ret;
985                 }
986                 condition = sqlite3_mprintf("path = '%q'", import_item_list[idx]);
987                 ret = media_filter_set_condition(filter, condition, MEDIA_CONTENT_COLLATE_DEFAULT);
988                 if(ret != MEDIA_CONTENT_ERROR_NONE)
989                 {
990                         __media_playlist_destroy_import_item(import_item_list, import_item_count);
991                         media_filter_destroy(filter);
992                         sqlite3_free(condition);
993                         media_content_error("error media_filter_set_condition");
994                         return ret;
995                 }
996                 ret = _media_db_get_group_item(NULL, filter, __media_playlist_media_info_cb, &media_id, MEDIA_GROUP_NONE);
997                 if(ret != MEDIA_CONTENT_ERROR_NONE)
998                 {
999                         __media_playlist_destroy_import_item(import_item_list, import_item_count);
1000                         media_filter_destroy(filter);
1001                         SAFE_FREE(media_id);
1002                         sqlite3_free(condition);
1003                         media_content_error("error media_info_foreach_media_from_db");
1004                         return ret;
1005                 }
1006                 ret = media_playlist_add_media((media_playlist_h)*playlist, media_id);
1007                 if(ret != MEDIA_CONTENT_ERROR_NONE)
1008                 {
1009                         __media_playlist_destroy_import_item(import_item_list, import_item_count);
1010                         media_filter_destroy(filter);
1011                         SAFE_FREE(media_id);
1012                         sqlite3_free(condition);
1013                         media_content_error("error media_playlist_add_media");
1014                         return ret;
1015                 }
1016                 media_filter_destroy(filter);
1017                 SAFE_FREE(media_id);
1018                 sqlite3_free(condition);
1019         }
1020
1021         ret = media_playlist_update_to_db(*playlist);
1022         if(ret != MEDIA_CONTENT_ERROR_NONE)
1023         {
1024                 __media_playlist_destroy_import_item(import_item_list, import_item_count);
1025                 media_content_error("Fail to update playlist to db");
1026                 return ret;
1027         }
1028         __media_playlist_destroy_import_item(import_item_list, import_item_count);
1029
1030         return ret;
1031 }
1032
1033 int media_playlist_export_to_file(media_playlist_h playlist, const char* path)
1034 {
1035         int ret = MEDIA_CONTENT_ERROR_NONE;
1036         media_playlist_s *_playlist = (media_playlist_s*)playlist;
1037         GList *item_list = NULL;
1038         unsigned int idx = 0;
1039
1040         media_content_retvm_if(!STRING_VALID(path), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid path");
1041         media_content_retvm_if(_playlist == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid playlist");
1042         media_content_retvm_if(_playlist->playlist_id <= 0, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid playlist_id");
1043
1044         ret = _media_db_get_playlist_item(_playlist->playlist_id, NULL, __media_playlist_member_cb, &item_list);
1045         media_content_retvm_if(ret != MEDIA_CONTENT_ERROR_NONE, ret, "_media_db_get_playlist_item fail");
1046
1047         ret = __media_playlist_reset_file(path);
1048         if(ret != MEDIA_CONTENT_ERROR_NONE)
1049         {
1050                 g_list_free_full(item_list, __media_playlist_destroy_export_item);
1051                 media_content_error("Fail to init playlist file");
1052                 return ret;
1053         }
1054
1055         for (idx=0; idx < g_list_length(item_list); idx++)
1056         {
1057                 char *item = g_list_nth_data(item_list, idx);
1058                 ret = __media_playlist_append_to_file(path, item);
1059                 if(ret != MEDIA_CONTENT_ERROR_NONE)
1060                 {
1061                         g_list_free_full(item_list, __media_playlist_destroy_export_item);
1062                         media_content_error("Fail to export paths into file");
1063                         return ret;
1064                 }
1065         }
1066
1067         g_list_free_full(item_list, __media_playlist_destroy_export_item);
1068
1069         return ret;
1070 }