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