Add new API(image meta/storage/playlist).
[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         ret = media_info_get_media_id(media, media_id);
194         if(ret != MEDIA_CONTENT_ERROR_NONE)
195         {
196                 media_content_error("Fail to get file path");
197                 return FALSE;
198         }
199         return TRUE;
200 }
201
202 static bool __media_playlist_member_cb(int playlist_member_id, media_info_h media, void *user_data)
203 {
204         int ret = MEDIA_CONTENT_ERROR_NONE;
205         GList **list = (GList**)user_data;
206         char *path = NULL;
207
208         ret = media_info_get_file_path(media, &path);
209         if(ret != MEDIA_CONTENT_ERROR_NONE)
210         {
211                 media_content_error("Fail to get file path");
212                 return FALSE;
213         }
214
215         *list = g_list_append(*list, path);
216
217         return TRUE;
218 }
219
220 static int __media_playlist_reset_file(const char* playlist_path)
221 {
222         FILE *fp = NULL;
223
224         fp = fopen(playlist_path, "wb");
225         if(fp == NULL)
226         {
227                 media_content_stderror("fopen fail");
228                 return MEDIA_CONTENT_ERROR_INVALID_OPERATION;
229         }
230
231         fputs("", fp);  // remove previous playlist
232
233         fclose(fp);
234
235         return MEDIA_CONTENT_ERROR_NONE;
236 }
237
238 static int __media_playlist_append_to_file(const char* playlist_path, const char* path)
239 {
240         FILE *fp = NULL;
241
242         fp = fopen(playlist_path, "a"); // append only
243         if(fp == NULL)
244         {
245                 media_content_stderror("fopen fail");
246                 return MEDIA_CONTENT_ERROR_INVALID_OPERATION;
247         }
248
249         fputs(path, fp);
250
251         fputs("\n", fp);
252
253         fclose(fp);
254
255         return MEDIA_CONTENT_ERROR_NONE;
256 }
257
258 static int __media_playlist_import_item_from_file(const char* playlist_path, char*** const item_list, int* item_count)
259 {
260         int current_index = 0;                                          // Current record number
261         int current_max_size = PLAYLIST_ARRAY_SIZE;     // Current max number of records in array
262         int tmp_str_len = 0;                                            // Length of the string
263         char *buf = NULL;
264         char *tmp_buf = NULL;
265         char *tmp_str = NULL;                                           // Next line from buffer, this string is used for parsing
266
267         FILE *fp = NULL;
268         long int file_size = 0;
269
270         *item_list = NULL; *item_count = 0;
271
272         fp = fopen(playlist_path, "rb");                // Open as binary for precise estimation of file length
273         if(fp == NULL)
274         {
275                 media_content_stderror("fopen fail");
276                 return MEDIA_CONTENT_ERROR_INVALID_OPERATION;
277         }
278
279         fseek(fp, 0, SEEK_END);                                 // Move to the end of file
280         file_size = ftell(fp);                          // Here we can find the size of file
281         fseek(fp, 0 , SEEK_SET);                                        // Return to the beginning of file
282
283         if(file_size == 0) {
284                 media_content_debug("file is empty.");
285                 fclose(fp);
286                 return MEDIA_CONTENT_ERROR_NONE;
287         }
288         // Allocate the memory and copy file content there
289         if(file_size > 0)
290                 buf = malloc(file_size + 1);
291
292         if(buf == NULL)
293         {
294                 media_content_error("Out of Memory");
295                 fclose(fp);
296                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
297         }
298
299         tmp_buf = buf;
300
301         if(fread(buf, file_size, 1, fp) != 1) {
302                 fclose(fp);
303                 SAFE_FREE(buf);
304                 media_content_stderror("fread fail");
305                 return MEDIA_CONTENT_ERROR_INVALID_OPERATION;
306         }
307         buf[file_size] = 0;
308         fclose(fp);
309
310         // Preliminary memory allocation
311         *item_list = calloc(current_max_size, sizeof(char*));
312         tmp_str = malloc(MAX_TMP_STR);
313         if (tmp_str == NULL || *item_list == NULL) {
314                 SAFE_FREE(*item_list);
315                 SAFE_FREE(buf);
316                 SAFE_FREE(tmp_str);
317                 media_content_error("Out of Memory");
318                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
319         }
320         // Here we create format string for sscanf(...) that allows to get a line from buffer
321         char format[25];
322         snprintf(format, 25, "%%%d[^\n]", MAX_TMP_STR);
323
324         // This cycle gets lines one by one from buffer till the end of buffer. Empty line ("\n") must be treated specifically
325         while((sscanf(tmp_buf, format, tmp_str) == 1) || (*tmp_buf == '\n')) {
326                 if(*tmp_buf == '\n') {// Check if there is an empty line, skip '\n' symbol
327                         tmp_buf += 1;
328
329                         if(tmp_buf < (buf + file_size))
330                                 continue;                       // We are still in buffer
331                         else
332                                 break;                          // Empty line was in the end of buffer
333                 }
334
335                 tmp_str_len = strlen(tmp_str);          // Save the length of line
336
337                 if(tmp_str[0] != '#') {                 // Check that the line is not a comment
338                         if(!(current_index < (current_max_size - 1))) {                         // Check if we have completely filled record array
339                                 // Expand array size and relocate the array (records will be copied into new one)
340                                 current_max_size += PLAYLIST_ARRAY_EXPAND;
341                                 char **tmp_ptr = calloc(current_max_size, sizeof(char*));
342                                 if (tmp_ptr == NULL) {
343                                         __media_playlist_destroy_import_item(*item_list, current_index);
344                                         SAFE_FREE(buf);
345                                         SAFE_FREE(tmp_str);
346                                         media_content_error("Out of Memory");
347                                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
348                                 }
349                                 memmove(tmp_ptr, *item_list, sizeof(char*) * current_index);
350                                 SAFE_FREE(*item_list);
351                                 *item_list = tmp_ptr;
352                         }
353
354                         // Save new file path (current string in tmp_str)
355                         (*item_list)[current_index] = malloc(tmp_str_len + 1);
356                         if ((*item_list)[current_index] == NULL) {
357                                 __media_playlist_destroy_import_item(*item_list, current_index);
358                                 SAFE_FREE(buf);
359                                 SAFE_FREE(tmp_str);
360                                 media_content_error("Out of Memory");
361                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
362                         }
363                         memmove((*item_list)[current_index], tmp_str, tmp_str_len + 1);
364
365                         // Increase the index of buffer
366                         current_index += 1;
367                 }
368
369                 tmp_buf += (tmp_str_len + 1);                           // Move position in buffer after the string that was parsed
370         }
371
372         *item_count = current_index;                                            // Now we need to save the number of records in array
373
374         SAFE_FREE(buf);
375         SAFE_FREE(tmp_str);                                             // Free temporary variables
376
377         return MEDIA_CONTENT_ERROR_NONE;
378 }
379
380 static int __media_playlist_destroy_import_item(char** item_list, int item_count)
381 {
382         int i;
383
384         for(i = 0; i < item_count; ++i) {
385                 SAFE_FREE(item_list[i]);
386                 item_list[i] = NULL;
387         }
388
389         if (item_list != NULL) {
390                 SAFE_FREE(item_list);
391                 item_list = NULL;
392         }
393
394         return MEDIA_CONTENT_ERROR_NONE;
395 }
396
397 static void __media_playlist_destroy_export_item(gpointer data)
398 {
399         SAFE_FREE(data);
400         data = NULL;
401 }
402
403 int media_playlist_insert_to_db(const char *name, media_playlist_h *playlist)
404 {
405         int ret = MEDIA_CONTENT_ERROR_NONE;
406         int playlist_id = 0;
407
408         if(!STRING_VALID(name))
409         {
410                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
411                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
412         }
413
414         media_playlist_s *_playlist = (media_playlist_s*)calloc(1, sizeof(media_playlist_s));
415         if(_playlist == NULL)
416         {
417                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
418                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
419         }
420
421         ret = __media_playlist_insert_playlist_record(name, &playlist_id);
422
423         if(ret != MEDIA_CONTENT_ERROR_NONE)
424         {
425                 SAFE_FREE(_playlist);
426                 return ret;
427         }
428
429         _playlist->playlist_id = playlist_id;
430         _playlist->name = strdup(name);
431
432         if(_playlist->name == NULL)
433         {
434                 SAFE_FREE(_playlist);
435                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
436                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
437         }
438
439         *playlist = (media_playlist_h)_playlist;
440
441         return ret;
442 }
443
444 int media_playlist_delete_from_db(int playlist_id)
445 {
446         int ret = MEDIA_CONTENT_ERROR_NONE;
447         char *query_str = NULL;
448
449         if(playlist_id < 0)
450         {
451                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
452                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
453         }
454
455         query_str = sqlite3_mprintf(DELETE_PLAYLIST_FROM_PLAYLIST, playlist_id);
456
457         ret = _content_query_sql(query_str);
458
459         sqlite3_free(query_str);
460
461         return ret;
462 }
463
464 int media_playlist_get_playlist_count_from_db(filter_h filter, int *playlist_count)
465 {
466         int ret = MEDIA_CONTENT_ERROR_NONE;
467
468         if(playlist_count != NULL)
469         {
470                 ret = _media_db_get_group_count(filter, MEDIA_GROUP_PLAYLIST, playlist_count);
471         }
472         else
473         {
474                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
475                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
476         }
477
478         return ret;
479 }
480
481 int media_playlist_foreach_playlist_from_db(filter_h filter, media_playlist_cb callback, void *user_data)
482 {
483         int ret = MEDIA_CONTENT_ERROR_NONE;
484
485         if(callback == NULL)
486         {
487                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
488                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
489         }
490
491         ret = _media_db_get_playlist(filter, callback, user_data);
492
493         return ret;
494 }
495
496 int media_playlist_get_media_count_from_db(int playlist_id, filter_h filter, int *media_count)
497 {
498         int ret = MEDIA_CONTENT_ERROR_NONE;
499
500         if((playlist_id > 0) && (media_count != NULL))
501         {
502                 ret = _media_db_get_group_item_count_by_id(playlist_id, filter, MEDIA_GROUP_PLAYLIST, media_count);
503         }
504         else
505         {
506                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
507                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
508         }
509
510         return ret;
511 }
512
513 int media_playlist_foreach_media_from_db(int playlist_id, filter_h filter, playlist_member_cb callback, void *user_data)
514 {
515         int ret = MEDIA_CONTENT_ERROR_NONE;
516
517         if((playlist_id > 0) && (callback != NULL))
518         {
519                 ret = _media_db_get_playlist_item(playlist_id, filter, callback, user_data);
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_destroy(media_playlist_h playlist)
531 {
532         int ret = MEDIA_CONTENT_ERROR_NONE;
533         media_playlist_s *_playlist = (media_playlist_s*)playlist;
534
535         if(_playlist)
536         {
537                 SAFE_FREE(_playlist->name);
538                 SAFE_FREE(_playlist->thumbnail_path);
539                 SAFE_FREE(_playlist);
540
541                 ret = MEDIA_CONTENT_ERROR_NONE;
542         }
543         else
544         {
545                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
546                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
547         }
548
549         return ret;
550 }
551
552 int media_playlist_clone(media_playlist_h *dst, media_playlist_h src)
553 {
554         int ret = MEDIA_CONTENT_ERROR_NONE;
555         media_playlist_s *_src = (media_playlist_s*)src;
556
557         if(_src != NULL)
558         {
559                 media_playlist_s *_dst = (media_playlist_s*)calloc(1, sizeof(media_playlist_s));
560                 if(_dst == NULL)
561                 {
562                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
563                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
564                 }
565
566                 _dst->playlist_id = _src->playlist_id;
567
568                 if(STRING_VALID(_src->name))
569                 {
570                         _dst->name = strdup(_src->name);
571                         if(_dst->name == NULL)
572                         {
573                                 media_playlist_destroy((media_playlist_h)_dst);
574                                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
575                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
576                         }
577                 }
578
579                 *dst = (media_playlist_h)_dst;
580
581                 ret = MEDIA_CONTENT_ERROR_NONE;
582         }
583         else
584         {
585                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
586                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
587         }
588
589         return ret;
590 }
591
592 int media_playlist_get_playlist_from_db(int playlist_id, media_playlist_h *playlist)
593 {
594         int ret = MEDIA_CONTENT_ERROR_NONE;
595         sqlite3_stmt *stmt = NULL;
596         char select_query[DEFAULT_QUERY_SIZE];
597
598         if(playlist_id > 0)
599         {
600                 memset(select_query, 0x00, sizeof(select_query));
601
602                 snprintf(select_query, sizeof(select_query), SELECT_PLAYLIST_FROM_PLAYLIST, playlist_id);
603
604                 ret = _content_query_prepare(&stmt, select_query, NULL, NULL);
605                 media_content_retv_if(ret != MEDIA_CONTENT_ERROR_NONE, ret);
606
607                 while(sqlite3_step(stmt) == SQLITE_ROW)
608                 {
609                         media_playlist_s *_playlist = (media_playlist_s*)calloc(1, sizeof(media_playlist_s));
610                         if(_playlist == NULL)
611                         {
612                                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
613                                 SQLITE3_FINALIZE(stmt);
614                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
615                         }
616
617                         _playlist->playlist_id = (int)sqlite3_column_int(stmt, 0);
618                         if(STRING_VALID((const char *)sqlite3_column_text(stmt, 1)))
619                                 _playlist->name = strdup((const char *)sqlite3_column_text(stmt, 1));
620                         if(STRING_VALID((const char *)sqlite3_column_text(stmt, 3)))
621                                 _playlist->thumbnail_path = strdup((const char *)sqlite3_column_text(stmt, 3));
622
623                         *playlist = (media_playlist_h)_playlist;
624                 }
625
626                 SQLITE3_FINALIZE(stmt);
627         }
628         else
629         {
630                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
631                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
632         }
633
634         return ret;
635 }
636
637 int media_playlist_get_playlist_id(media_playlist_h playlist, int *playlist_id)
638 {
639         int ret = MEDIA_CONTENT_ERROR_NONE;
640
641         media_playlist_s *_playlist = (media_playlist_s*)playlist;
642
643         if((_playlist != NULL) && (playlist_id != NULL))
644         {
645                 *playlist_id = _playlist->playlist_id;
646         }
647         else
648         {
649                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
650                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
651         }
652
653         return ret;
654 }
655
656 int media_playlist_get_name(media_playlist_h playlist, char **name)
657 {
658         int ret = MEDIA_CONTENT_ERROR_NONE;
659         media_playlist_s *_playlist = (media_playlist_s*)playlist;
660         if(_playlist)
661         {
662                 if(STRING_VALID(_playlist->name))
663                 {
664                         *name = strdup(_playlist->name);
665                         if(*name == NULL)
666                         {
667                                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
668                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
669                         }
670                 }
671                 else
672                 {
673                         *name = NULL;
674                 }
675
676                 ret = MEDIA_CONTENT_ERROR_NONE;
677         }
678         else
679         {
680                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
681                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
682         }
683
684         return ret;
685 }
686
687 int media_playlist_get_thumbnail_path(media_playlist_h playlist, char **path)
688 {
689         int ret = MEDIA_CONTENT_ERROR_NONE;
690         media_playlist_s *_playlist = (media_playlist_s*)playlist;
691         if(_playlist)
692         {
693                 if(STRING_VALID(_playlist->thumbnail_path))
694                 {
695                         *path = strdup(_playlist->thumbnail_path);
696                         if(*path == NULL)
697                         {
698                                 media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
699                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
700                         }
701                 }
702                 else
703                 {
704                         *path = NULL;
705                 }
706
707                 ret = MEDIA_CONTENT_ERROR_NONE;
708         }
709         else
710         {
711                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
712                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
713         }
714
715         return ret;
716 }
717
718 int media_playlist_get_play_order(media_playlist_h playlist, int playlist_member_id, int *play_order)
719 {
720         int ret = MEDIA_CONTENT_ERROR_NONE;
721         media_playlist_s *_playlist = (media_playlist_s*)playlist;
722         int playlist_id = 0;
723         sqlite3_stmt *stmt = NULL;
724         char select_query[DEFAULT_QUERY_SIZE];
725
726         if((_playlist == NULL) || (playlist_member_id < 0) || (play_order == NULL))
727         {
728                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
729                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
730         }
731
732         playlist_id = _playlist->playlist_id;
733
734         memset(select_query, 0x00, sizeof(select_query));
735
736         snprintf(select_query, sizeof(select_query), SELECT_PLAY_ORDER_FROM_PLAYLIST_VIEW, playlist_id, playlist_member_id);
737
738         ret = _content_query_prepare(&stmt, select_query, NULL, NULL);
739         media_content_retv_if(ret != MEDIA_CONTENT_ERROR_NONE, ret);
740
741         while(sqlite3_step(stmt) == SQLITE_ROW)
742         {
743                 *play_order = (int)sqlite3_column_int(stmt, 0);
744         }
745
746         SQLITE3_FINALIZE(stmt);
747
748         return ret;
749 }
750
751 int media_playlist_set_name(media_playlist_h playlist, const char *playlist_name)
752 {
753         int ret = MEDIA_CONTENT_ERROR_NONE;
754         media_playlist_s *_playlist = (media_playlist_s*)playlist;
755
756         if(_playlist != NULL && STRING_VALID(playlist_name))
757         {
758                 SAFE_FREE(_playlist->name);
759
760                 media_playlist_item_s *item = (media_playlist_item_s*)calloc(1, sizeof(media_playlist_item_s));
761                 if(item == NULL)
762                 {
763                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
764                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
765                 }
766
767                 item->playlist_name = strdup(playlist_name);
768                 item->function = MEDIA_PLAYLIST_UPDATE_PLAYLIST_NAME;
769                 if(item->playlist_name == NULL)
770                 {
771                         SAFE_FREE(item);
772                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
773                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
774                 }
775
776                 _playlist->name = strdup(playlist_name);
777                 if(_playlist->name == NULL)
778                 {
779                         SAFE_FREE(item->playlist_name);
780                         SAFE_FREE(item);
781                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
782                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
783                 }
784
785                 __media_playlist_item_add(item);
786         }
787         else
788         {
789                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
790                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
791         }
792
793         return ret;
794 }
795
796 int media_playlist_set_thumbnail_path(media_playlist_h playlist, const char *path)
797 {
798         int ret = MEDIA_CONTENT_ERROR_NONE;
799         media_playlist_s *_playlist = (media_playlist_s*)playlist;
800
801         if(_playlist != NULL && STRING_VALID(path))
802         {
803                 SAFE_FREE(_playlist->thumbnail_path);
804
805                 media_playlist_item_s *item = (media_playlist_item_s*)calloc(1, sizeof(media_playlist_item_s));
806                 if(item == NULL)
807                 {
808                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
809                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
810                 }
811
812                 item->thumbnail_path = strdup(path);
813                 item->function = MEDIA_PLAYLIST_UPDATE_THUMBNAIL_PATH;
814                 if(item->thumbnail_path == NULL)
815                 {
816                         SAFE_FREE(item);
817                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
818                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
819                 }
820
821                 _playlist->thumbnail_path = strdup(path);
822                 if(_playlist->thumbnail_path == NULL)
823                 {
824                         SAFE_FREE(item->thumbnail_path);
825                         SAFE_FREE(item);
826                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
827                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
828                 }
829
830                 __media_playlist_item_add(item);
831         }
832         else
833         {
834                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
835                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
836         }
837
838         return ret;
839 }
840
841 int media_playlist_set_play_order(media_playlist_h playlist, int playlist_member_id, int play_order)
842 {
843         int ret = MEDIA_CONTENT_ERROR_NONE;
844         media_playlist_s *_playlist = (media_playlist_s*)playlist;
845
846         if((_playlist != NULL) && (playlist_member_id > 0) && (play_order >= 0))
847         {
848                 media_playlist_item_s *item = (media_playlist_item_s*)calloc(1, sizeof(media_playlist_item_s));
849                 if(item == NULL)
850                 {
851                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
852                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
853                 }
854
855                 item->playlist_member_id = playlist_member_id;
856                 item->function = MEDIA_PLAYLIST_UPDATE_PLAY_ORDER;
857                 item->play_order = play_order;
858
859                 __media_playlist_item_add(item);
860         }
861         else
862         {
863                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
864                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
865         }
866
867         return ret;
868 }
869
870 int media_playlist_add_media(media_playlist_h playlist, const char *media_id)
871 {
872         int ret = MEDIA_CONTENT_ERROR_NONE;
873         media_playlist_s *_playlist = (media_playlist_s*)playlist;
874
875         if(_playlist != NULL && STRING_VALID(media_id))
876         {
877                 media_playlist_item_s *item = (media_playlist_item_s*)calloc(1, sizeof(media_playlist_item_s));
878                 if(item == NULL)
879                 {
880                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
881                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
882                 }
883
884                 item->media_id = strdup(media_id);
885                 item->function = MEDIA_PLAYLIST_ADD;
886
887                 if(item->media_id == NULL)
888                 {
889                         SAFE_FREE(item);
890                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
891                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
892                 }
893
894                 __media_playlist_item_add(item);
895         }
896         else
897         {
898                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
899                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
900         }
901
902         return ret;
903 }
904
905
906 int media_playlist_remove_media(media_playlist_h playlist, int playlist_member_id)
907 {
908         int ret = MEDIA_CONTENT_ERROR_NONE;
909         media_playlist_s *_playlist = (media_playlist_s*)playlist;
910
911         if((_playlist != NULL) && (playlist_member_id > 0))
912         {
913                 media_playlist_item_s *item = (media_playlist_item_s*)calloc(1, sizeof(media_playlist_item_s));
914                 if(item == NULL)
915                 {
916                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
917                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
918                 }
919
920                 item->playlist_member_id = playlist_member_id;
921                 item->function = MEDIA_PLAYLIST_REMOVE;
922
923                 __media_playlist_item_add(item);
924         }
925         else
926         {
927                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
928                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
929         }
930
931         return ret;
932 }
933
934 int media_playlist_update_to_db(media_playlist_h playlist)
935 {
936         int ret = MEDIA_CONTENT_ERROR_NONE;
937         media_playlist_s *_playlist = (media_playlist_s*)playlist;
938         int idx = 0;
939         int length = 0;
940         media_playlist_item_s *_playlist_item = NULL;
941
942         if(_playlist == NULL)
943         {
944                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
945                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
946         }
947
948         length = g_list_length(g_playlist_item_list);
949
950         for (idx = 0; idx < length; idx++) {
951                 _playlist_item = (media_playlist_item_s*)g_list_nth_data(g_playlist_item_list, idx);
952                 if(_playlist_item != NULL) {
953                         switch(_playlist_item->function) {
954                                 case MEDIA_PLAYLIST_ADD:
955                                 {
956                                         ret = __media_playlist_insert_item_to_playlist(_playlist->playlist_id, _playlist_item->media_id);
957                                 }
958                                 break;
959
960                                 case MEDIA_PLAYLIST_REMOVE:
961                                 {
962                                         ret = __media_playlist_remove_item_from_playlist(_playlist->playlist_id, _playlist_item->playlist_member_id);
963                                 }
964                                 break;
965
966                                 case MEDIA_PLAYLIST_UPDATE_PLAYLIST_NAME:
967                                 {
968                                         ret = __media_playlist_update_playlist_name(_playlist->playlist_id, _playlist_item->playlist_name);
969                                 }
970                                 break;
971
972                                 case MEDIA_PLAYLIST_UPDATE_THUMBNAIL_PATH:
973                                 {
974                                         ret = __media_playlist_update_thumbnail_path(_playlist->playlist_id, _playlist_item->thumbnail_path);
975                                 }
976                                 break;
977
978                                 case MEDIA_PLAYLIST_UPDATE_PLAY_ORDER:
979                                 {
980                                         ret = __media_playlist_update_play_order(_playlist->playlist_id, _playlist_item->playlist_member_id, _playlist_item->play_order);
981                                 }
982                                 break;
983                         }
984                 }
985         }
986
987         __media_playlist_item_release();
988
989         return ret;
990 }
991
992 int media_playlist_import_from_file(const char *path, const char *playlist_name, media_playlist_h *playlist)
993 {
994         int ret = MEDIA_CONTENT_ERROR_NONE;
995         char** import_item_list = NULL;
996         int import_item_count = 0;
997         int idx;
998
999         if(!STRING_VALID(path))
1000         {
1001                 media_content_error("Invalid path");
1002                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1003         }
1004
1005         if(!STRING_VALID(playlist_name))
1006         {
1007                 media_content_error("Invalid playlist_name");
1008                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1009         }
1010
1011         ret = media_playlist_insert_to_db(playlist_name, playlist);
1012         if(ret != MEDIA_CONTENT_ERROR_NONE)
1013         {
1014                 media_content_error("Fail to insert playlist to db");
1015                 return ret;
1016         }
1017
1018         ret = __media_playlist_import_item_from_file(path, &import_item_list, &import_item_count);
1019         if(ret != MEDIA_CONTENT_ERROR_NONE)
1020         {
1021                 __media_playlist_destroy_import_item(import_item_list, import_item_count);
1022                 media_content_error("Fail to get playlist from file");
1023                 return ret;
1024         }
1025
1026         if (import_item_count == 0)
1027         {
1028                 media_content_debug("The playlist from file is empty");
1029         }
1030
1031         for (idx=0; idx < import_item_count; idx++)
1032         {
1033                 filter_h filter = NULL;
1034                 char *media_id = NULL;
1035                 char *condition = NULL;
1036
1037                 ret = media_filter_create(&filter);
1038                 if(ret != MEDIA_CONTENT_ERROR_NONE)
1039                 {
1040                         __media_playlist_destroy_import_item(import_item_list, import_item_count);
1041                         media_filter_destroy(filter);
1042                         media_content_error("error media_filter_create");
1043                         return ret;
1044                 }
1045                 condition = sqlite3_mprintf("path = '%q'", import_item_list[idx]);
1046                 ret = media_filter_set_condition(filter, condition, MEDIA_CONTENT_COLLATE_DEFAULT);
1047                 if(ret != MEDIA_CONTENT_ERROR_NONE)
1048                 {
1049                         __media_playlist_destroy_import_item(import_item_list, import_item_count);
1050                         media_filter_destroy(filter);
1051                         sqlite3_free(condition);
1052                         media_content_error("error media_filter_set_condition");
1053                         return ret;
1054                 }
1055                 ret = _media_db_get_group_item(NULL, filter, __media_playlist_media_info_cb, &media_id, MEDIA_GROUP_NONE);
1056                 if(ret != MEDIA_CONTENT_ERROR_NONE)
1057                 {
1058                         __media_playlist_destroy_import_item(import_item_list, import_item_count);
1059                         media_filter_destroy(filter);
1060                         SAFE_FREE(media_id);
1061                         sqlite3_free(condition);
1062                         media_content_error("error media_info_foreach_media_from_db");
1063                         return ret;
1064                 }
1065                 ret = media_playlist_add_media((media_playlist_h)*playlist, media_id);
1066                 if(ret != MEDIA_CONTENT_ERROR_NONE)
1067                 {
1068                         __media_playlist_destroy_import_item(import_item_list, import_item_count);
1069                         media_filter_destroy(filter);
1070                         SAFE_FREE(media_id);
1071                         sqlite3_free(condition);
1072                         media_content_error("error media_playlist_add_media");
1073                         return ret;
1074                 }
1075                 media_filter_destroy(filter);
1076                 SAFE_FREE(media_id);
1077                 sqlite3_free(condition);
1078         }
1079
1080         ret = media_playlist_update_to_db(*playlist);
1081         if(ret != MEDIA_CONTENT_ERROR_NONE)
1082         {
1083                 __media_playlist_destroy_import_item(import_item_list, import_item_count);
1084                 media_content_error("Fail to update playlist to db");
1085                 return ret;
1086         }
1087         __media_playlist_destroy_import_item(import_item_list, import_item_count);
1088
1089         return ret;
1090 }
1091
1092 int media_playlist_export_to_file(media_playlist_h playlist, const char* path)
1093 {
1094         int ret = MEDIA_CONTENT_ERROR_NONE;
1095         media_playlist_s *_playlist = (media_playlist_s*)playlist;
1096         GList *item_list = NULL;
1097         int idx;
1098
1099         if(!STRING_VALID(path))
1100         {
1101                 media_content_error("Invalid path");
1102                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1103         }
1104
1105         if(_playlist == NULL)
1106         {
1107                 media_content_error("Invalid playlist");
1108                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1109         }
1110
1111         if(_playlist->playlist_id <= 0)
1112         {
1113                 media_content_error("Invalid playlist id");
1114                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1115         }
1116
1117         ret = _media_db_get_playlist_item(_playlist->playlist_id, NULL, __media_playlist_member_cb, &item_list);
1118         if(ret != MEDIA_CONTENT_ERROR_NONE)
1119         {
1120                 media_content_error("Fail to get playlist from db");
1121                 return ret;
1122         }
1123
1124         ret = __media_playlist_reset_file(path);
1125         if(ret != MEDIA_CONTENT_ERROR_NONE)
1126         {
1127                 g_list_free_full(item_list, __media_playlist_destroy_export_item);
1128                 media_content_error("Fail to init playlist file");
1129                 return ret;
1130         }
1131
1132         for (idx=0; idx < g_list_length(item_list); idx++)
1133         {
1134                 char *item = g_list_nth_data(item_list, idx);
1135                 ret = __media_playlist_append_to_file(path, item);
1136                 if(ret != MEDIA_CONTENT_ERROR_NONE)
1137                 {
1138                         g_list_free_full(item_list, __media_playlist_destroy_export_item);
1139                         media_content_error("Fail to export paths into file");
1140                         return ret;
1141                 }
1142         }
1143
1144         g_list_free_full(item_list, __media_playlist_destroy_export_item);
1145
1146         return ret;
1147 }