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