folderdata: add to get folder media list 75/49275/2
authorJehun Lim <jehun.lim@samsung.com>
Mon, 12 Oct 2015 08:23:43 +0000 (17:23 +0900)
committerJehun Lim <jehun.lim@samsung.com>
Mon, 12 Oct 2015 09:12:25 +0000 (18:12 +0900)
Change-Id: I9c0a1553cd2105d2d69ee4f184fbb8d7e80f0724
Signed-off-by: Jehun Lim <jehun.lim@samsung.com>
include/data/folderdata.h
src/data/folderdata.c

index af1af0a..79a6894 100644 (file)
 struct data_ops;
 
 enum folder_group_type {
-       E_GROUP_FOLDER_NAME,
+       E_GROUP_FOLDER_MEDIA_NAME,
        E_GROUP_FOLDER_MAX
 };
 
+enum folder_list_type {
+       E_LIST_FOLDER = 0,
+};
+
 struct folder_info {
        char *id;
        char *name;
index 6a9ee00..d9ef0e4 100644 (file)
 #include <Elementary.h>
 #include <media_content.h>
 #include <app_debug.h>
+#include <app_media.h>
 
 #include "data/datamgr.h"
 
+struct folderdata;
+
+typedef bool (*get_media_list)(struct folderdata *fd, void *data);
+typedef int (*media_compare)(struct group_info *gi, app_media_info *info);
+typedef void *(*media_compare_data_get)(app_media_info *info);
+typedef char *(*group_name_get)(app_media_info *info);
+
+static bool _get_media_name_list(struct folderdata *fd, void *data);
+static int _compare_cb_name(const void *, const void *);
+static int _compare_title(struct group_info *, app_media_info *);
+static char *_get_title(app_media_info *);
+static void *_get_data_title(app_media_info *info);
+
 enum _filter_type {
        E_FILTER_FOLDER = 0,
        E_FILTER_MEDIA
@@ -27,6 +41,7 @@ enum _filter_type {
 
 struct folderdata {
        Eina_List *folder_list;
+       Eina_List *media_list;
 
        char *parent_id;
 
@@ -34,6 +49,25 @@ struct folderdata {
        int source_type;
 };
 
+struct _list_info {
+       get_media_list get_list;
+
+       Eina_Compare_Cb sort_cmp_cb;
+       media_compare media_cmp;
+       media_compare_data_get data_get;
+       group_name_get name_get;
+};
+
+static struct _list_info g_group_info[E_GROUP_FOLDER_MAX] = {
+       [E_GROUP_FOLDER_MEDIA_NAME] = {
+               .get_list = _get_media_name_list,
+               .sort_cmp_cb = _compare_cb_name,
+               .media_cmp = _compare_title,
+               .name_get = _get_title,
+               .data_get = _get_data_title,
+       },
+};
+
 static bool _create_filter(struct folderdata *fd, filter_h *filter,
                        const char *cond, int filter_type)
 {
@@ -47,43 +81,91 @@ static bool _create_filter(struct folderdata *fd, filter_h *filter,
                return false;
        }
 
-       snprintf(buf, sizeof(buf), "%s", fd->media_type);
+       if (filter_type == E_FILTER_FOLDER) {
+               if (cond)
+                       snprintf(buf, sizeof(buf), "%s", cond);
 
-       if (fd->source_type != E_SOURCE_ALL) {
-               char s1[256];
+               media_filter_set_order(tmp_filter, MEDIA_CONTENT_ORDER_ASC,
+                               FOLDER_NAME, MEDIA_CONTENT_COLLATE_DEFAULT);
+       } else {
+               snprintf(buf, sizeof(buf), "%s", fd->media_type);
 
-               snprintf(s1, sizeof(s1), " AND MEDIA_STORAGE_TYPE=%d",
-                                       fd->source_type);
+               if (fd->source_type != E_SOURCE_ALL) {
+                       char s1[256];
 
-               strcat(buf, s1);
-       }
+                       snprintf(s1, sizeof(s1), " AND MEDIA_STORAGE_TYPE=%d",
+                                               fd->source_type);
 
-       if (cond) {
-               char s2[256];
+                       strcat(buf, s1);
+               }
 
-               snprintf(s2, sizeof(s2), " AND %s", cond);
+               if (cond) {
+                       char s2[256];
 
-               strcat(buf, s2);
-       }
+                       snprintf(s2, sizeof(s2), " AND %s", cond);
 
-       media_filter_set_condition(tmp_filter, buf,
-                       MEDIA_CONTENT_COLLATE_DEFAULT);
+                       strcat(buf, s2);
+               }
 
-       if (filter_type == E_FILTER_FOLDER) {
                media_filter_set_order(tmp_filter, MEDIA_CONTENT_ORDER_ASC,
-                               FOLDER_NAME, MEDIA_CONTENT_COLLATE_DEFAULT);
+                                       MEDIA_TITLE,
+                                       MEDIA_CONTENT_COLLATE_DEFAULT);
        }
 
+       media_filter_set_condition(tmp_filter, buf,
+                       MEDIA_CONTENT_COLLATE_DEFAULT);
+
        *filter = tmp_filter;
 
        return true;
 }
 
-static void _destroy_folder_list(struct folderdata *fd)
+static int _compare_cb_name(const void *data1, const void *data2)
+{
+       app_media *am1, *am2;
+       app_media_info *mi1, *mi2;
+
+       am1 = (app_media *)data1;
+       am2 = (app_media *)data2;
+
+       mi1 = app_media_get_info(am1);
+       mi2 = app_media_get_info(am2);
+
+       if (!mi1 || !mi2 || !mi1->title || !mi2->title)
+               return -1;
+
+       return strcasecmp(mi1->title, mi2->title);
+}
+
+static int _compare_title(struct group_info *gi, app_media_info *mi)
+{
+       if (!gi || !gi->data || !mi->title)
+               return -1;
+
+       return strncasecmp(gi->data, mi->title, 1);
+}
+
+static void *_get_data_title(app_media_info *mi)
+{
+       if (!mi->title)
+               return NULL;
+
+       return strdup(mi->title);
+}
+
+static char *_get_title(app_media_info *mi)
+{
+       if (!mi->title)
+               return NULL;
+
+       return strndup(mi->title, 1);
+}
+
+static void _destroy_folder_list(Eina_List *list)
 {
        struct folder_info *fi;
 
-       EINA_LIST_FREE(fd->folder_list, fi) {
+       EINA_LIST_FREE(list, fi) {
                free(fi->id);
                free(fi->name);
                free(fi->path);
@@ -91,8 +173,14 @@ static void _destroy_folder_list(struct folderdata *fd)
 
                free(fi);
        }
+}
+
+static void _destroy_media_list(Eina_List *list)
+{
+       app_media *am;
 
-       fd->folder_list = NULL;
+       EINA_LIST_FREE(list, am)
+               app_media_destroy(am);
 }
 
 static bool _get_folder_id(media_folder_h folder, void *data)
@@ -179,6 +267,27 @@ static bool _get_each_folder_info(media_folder_h folder, void *data)
        return true;
 }
 
+static bool _get_each_media_info(media_info_h media_h, void *data)
+{
+       struct folderdata *fd;
+       app_media *am;
+
+       if (!data)
+               return false;
+
+       fd = data;
+
+       am = app_media_create(media_h);
+       if (!am) {
+               _ERR("failed to create app media");
+               return false;
+       }
+
+       fd->media_list = eina_list_append(fd->media_list, am);
+
+       return true;
+}
+
 static bool _find_folder_id(struct folderdata *fd, const char *path)
 {
        filter_h filter;
@@ -205,16 +314,12 @@ static bool _find_folder_id(struct folderdata *fd, const char *path)
        return true;
 }
 
-static bool _get_sub_folder_list(struct folderdata *fd)
+static bool _get_sub_folder_list(struct folderdata *fd, const char *cond)
 {
        filter_h filter;
        int ret;
-       char buf[1024];
-
-       snprintf(buf, sizeof(buf), "FOLDER_PARENT_FOLDER_ID=\"%s\"",
-                               fd->parent_id);
 
-       if (!_create_filter(fd, &filter, buf, E_FILTER_FOLDER)) {
+       if (!_create_filter(fd, &filter, cond, E_FILTER_FOLDER)) {
                _ERR("failed to create filter");
                return false;
        }
@@ -223,7 +328,7 @@ static bool _get_sub_folder_list(struct folderdata *fd)
                                _get_each_folder_info, fd);
        if (ret != MEDIA_CONTENT_ERROR_NONE) {
                _ERR("failed to get folder info");
-               _destroy_folder_list(fd);
+               _destroy_folder_list(fd->folder_list);
                media_filter_destroy(filter);
                return false;
        }
@@ -233,6 +338,104 @@ static bool _get_sub_folder_list(struct folderdata *fd)
        return true;
 }
 
+static bool _get_folder_list(struct folderdata *fd, char **path)
+{
+       int ret;
+       int i;
+       char buf[1024] = {0,};
+
+       ret = media_content_connect();
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               _ERR("failed to connect to media content");
+               return false;
+       }
+
+       i = 0;
+       while (path[i++]) {
+               char s[128];
+
+               if (!_find_folder_id(fd, path[i])) {
+                       _ERR("failed to find folder id");
+                       media_content_disconnect();
+                       return false;
+               }
+
+               if (strlen(buf)) {
+                       snprintf(s, sizeof(s),
+                                       " OR FOLDER_PARENT_FOLDER_ID=\"%s\"",
+                                       fd->parent_id);
+               } else {
+                       snprintf(s, sizeof(s), "FOLDER_PARENT_FOLDER_ID=\"%s\"",
+                                       fd->parent_id);
+               }
+
+               strcat(buf, s);
+       }
+
+       if (!_get_sub_folder_list(fd, buf)) {
+               _ERR("failed to get child folder list");
+               media_content_disconnect();
+               return false;
+       }
+
+       media_content_disconnect();
+
+       return true;
+}
+
+static bool _get_media_name_list(struct folderdata *fd, void *data)
+{
+       filter_h filter;
+       int ret;
+       int i;
+       char **path;
+
+       path = data;
+
+       if (fd->media_list) {
+               _destroy_media_list(fd->media_list);
+               fd->media_list = NULL;
+       }
+
+       ret = media_content_connect();
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               _ERR("failed to connect to media content");
+               return false;
+       }
+
+       if (!_create_filter(fd, &filter, NULL, E_FILTER_MEDIA)) {
+               _ERR("failed to create filter");
+               media_content_disconnect();
+               return false;
+       }
+
+       i = 0;
+       while (path[i++]) {
+               if (!_find_folder_id(fd, path[i])) {
+                       _ERR("failed to find folder id");
+                       media_filter_destroy(filter);
+                       media_content_disconnect();
+                       return false;
+               }
+
+               ret = media_folder_foreach_media_from_db(fd->parent_id, filter,
+                                       _get_each_media_info, fd);
+               if (ret != MEDIA_CONTENT_ERROR_NONE) {
+                       _ERR("failed to get media info");
+                       _destroy_media_list(fd->media_list);
+                       media_filter_destroy(filter);
+                       media_content_disconnect();
+                       return false;
+               }
+       }
+
+       media_filter_destroy(filter);
+
+       media_content_disconnect();
+
+       return true;
+}
+
 static void *_create(const char *media_type, int source_type)
 {
        struct folderdata *fd;
@@ -265,7 +468,8 @@ static void _destroy(void *handle)
 
        fd = handle;
 
-       _destroy_folder_list(fd);
+       _destroy_folder_list(fd->folder_list);
+       _destroy_media_list(fd->media_list);
 
        free(fd->parent_id);
        free(fd);
@@ -274,6 +478,7 @@ static void _destroy(void *handle)
 static Eina_List *_get_list(void *handle, int type, void *data)
 {
        struct folderdata *fd;
+       char **path;
 
        if (!handle) {
                _ERR("failed to get folderdata handle");
@@ -282,7 +487,17 @@ static Eina_List *_get_list(void *handle, int type, void *data)
 
        fd = handle;
 
-       return fd->folder_list;
+       switch (type) {
+       case E_LIST_FOLDER:
+               path = data;
+               _get_folder_list(fd, path);
+
+               return fd->folder_list;
+       default:
+               break;
+       }
+
+       return NULL;
 }
 
 static int _get_count(void *handle, int type)
@@ -299,15 +514,40 @@ static int _get_count(void *handle, int type)
        return eina_list_count(fd->folder_list);
 }
 
+static void _free_group_list(Eina_List *list)
+{
+       struct group_info *gi;
+
+       EINA_LIST_FREE(list, gi) {
+               free(gi->name);
+               free(gi->data);
+               _destroy_media_list(gi->list);
+
+               free(gi);
+       }
+}
+
 static void _free_group(Eina_List *list)
 {
-       eina_list_free(list);
+       _free_group_list(list);
+}
+
+static Eina_List *_sort_list(Eina_List *list, int sort)
+{
+       Eina_List *sorted_list;
+
+       sorted_list = eina_list_sort(list, 0, g_group_info[sort].sort_cmp_cb);
+
+       return sorted_list;
 }
 
 static Eina_List *_get_group(void *handle, int type, void *data)
 {
+       Eina_List *list, *l;
        struct folderdata *fd;
-       int ret;
+       struct group_info *gi;
+       app_media *am;
+       app_media_info *mi;
 
        if (!handle) {
                _ERR("failed to get folderdata handle");
@@ -321,32 +561,41 @@ static Eina_List *_get_group(void *handle, int type, void *data)
 
        fd = handle;
 
-       if (fd->folder_list) {
-               _destroy_folder_list(fd);
-               free(fd->parent_id);
-       }
-
-       ret = media_content_connect();
-       if (ret != MEDIA_CONTENT_ERROR_NONE) {
-               _ERR("failed to connect to media content");
-               return false;
-       }
-
-       if (!_find_folder_id(fd, data)) {
-               _ERR("failed to find folder id");
-               media_content_disconnect();
-               return false;
+       if (!g_group_info[type].get_list(fd, data)) {
+               _ERR("failed to get list");
+               return NULL;
        }
 
-       if (!_get_sub_folder_list(fd)) {
-               _ERR("failed to get child folder list");
-               media_content_disconnect();
-               return false;
+       fd->media_list = _sort_list(fd->media_list, type);
+
+       gi = NULL;
+       list = NULL;
+       EINA_LIST_FOREACH(fd->media_list, l, am) {
+               mi = app_media_get_info(am);
+               if (!mi) {
+                       _ERR("failed to get media info");
+                       _free_group_list(list);
+                       return NULL;
+               }
+
+               if (g_group_info[type].media_cmp(gi, mi)) {
+                       gi = calloc(1, sizeof(*gi));
+                       if (!gi) {
+                               _ERR("failed to create group info");
+                               _free_group_list(list);
+                               return NULL;
+                       }
+
+                       gi->name = g_group_info[type].name_get(mi);
+                       gi->data = g_group_info[type].data_get(mi);
+
+                       list = eina_list_append(list, gi);
+               }
+
+               gi->list = eina_list_append(gi->list, am);
        }
 
-       media_content_disconnect();
-
-       return eina_list_clone(fd->folder_list);
+       return list;
 }
 
 static struct data_ops _ops = {