summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--src/bin/extra_main.c116
-rw-r--r--src/lib/Makefile.am5
-rw-r--r--src/lib/extra.c167
-rw-r--r--src/lib/extra.h3
m---------src/lib/jsmn0
6 files changed, 262 insertions, 32 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..70a5e90
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
1[submodule "src/lib/jsmn"]
2 path = src/lib/jsmn
3 url = git@github.com:zserge/jsmn.git
diff --git a/src/bin/extra_main.c b/src/bin/extra_main.c
index 5f413c3..1fb8ee3 100644
--- a/src/bin/extra_main.c
+++ b/src/bin/extra_main.c
@@ -17,9 +17,38 @@
17 17
18#define COPYRIGHT "Copyright © 2016 Andy Williams <andy@andywilliams.me> and various contributors (see AUTHORS)." 18#define COPYRIGHT "Copyright © 2016 Andy Williams <andy@andywilliams.me> and various contributors (see AUTHORS)."
19 19
20typedef struct {
21 Evas_Object *title;
22 Evas_Object *screenshot;
23 Evas_Object *author;
24 Evas_Object *description;
25 Evas_Object *progress;
26} Theme_Ui;
27
20static Elm_Genlist_Item_Class _theme_class; 28static Elm_Genlist_Item_Class _theme_class;
21static Extra_Progress _sync_progress; 29static Extra_Progress _sync_progress;
22static Evas_Object *_sync_popup, *_theme_list; 30static Evas_Object *_sync_popup, *_theme_list;
31static Extra_Theme *selected_theme;
32static Theme_Ui ui;
33
34static void
35extra_win_show(Extra_Theme *theme)
36{
37 char title[1024], author[1024];
38 selected_theme = theme;
39
40 snprintf(title, sizeof(title), "<title>%s</title>", theme->name);
41 elm_object_text_set(ui.title, title);
42
43 snprintf(author, sizeof(author), "<link>%s</link>", theme->author);
44 elm_object_text_set(ui.author, author);
45
46 elm_object_text_set(ui.description, theme->description);
47
48 elm_progressbar_value_set(ui.progress, 0.0);
49 elm_photocam_file_set(ui.screenshot, theme->online_screenshot);
50 evas_object_show(ui.progress);
51}
23 52
24static void 53static void
25_extra_win_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 54_extra_win_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
@@ -44,7 +73,7 @@ _theme_select(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UN
44 73
45 theme = (Extra_Theme *)data; 74 theme = (Extra_Theme *)data;
46 75
47 printf("SELECTED %s\n", theme->id); 76 extra_win_show(theme);
48} 77}
49 78
50static void 79static void
@@ -99,10 +128,41 @@ extra_win_sync(Evas_Object *win)
99 extra_sync(&_sync_progress); 128 extra_sync(&_sync_progress);
100} 129}
101 130
131static void
132_download_progress_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
133{
134 Elm_Photocam_Progress *prog = event_info;
135
136 elm_progressbar_value_set(ui.progress, prog->now / prog->total);
137}
138
139static void
140_download_done(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
141{
142 evas_object_hide(ui.progress);
143}
144
145static void
146_theme_download_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
147{
148 Eina_Strbuf *path;
149
150 path = eina_strbuf_new();
151
152 eina_strbuf_append(path, elm_theme_user_dir_get());
153 eina_strbuf_append(path, "/");
154 eina_strbuf_append(path, selected_theme->id);
155 eina_strbuf_append(path, "-");
156 eina_strbuf_append_printf(path, "%d", selected_theme->version);
157 eina_strbuf_append(path, ".edj");
158
159 ecore_file_download(selected_theme->download_url, eina_strbuf_string_steal(path), NULL, NULL, NULL, NULL);
160}
161
102static Evas_Object * 162static Evas_Object *
103extra_win_setup(void) 163extra_win_setup(void)
104{ 164{
105 Evas_Object *win, *list, *pane, *box, *frame; 165 Evas_Object *win, *list, *pane, *box, *frame, *table, *btn, *icon;
106 166
107 win = elm_win_util_standard_add("main", "Extra!"); 167 win = elm_win_util_standard_add("main", "Extra!");
108 if (!win) return NULL; 168 if (!win) return NULL;
@@ -132,12 +192,62 @@ extra_win_setup(void)
132 _theme_list = list; 192 _theme_list = list;
133 193
134 frame = elm_frame_add(pane); 194 frame = elm_frame_add(pane);
135 elm_object_text_set(frame, "Description"); 195 elm_object_text_set(frame, "Theme info");
136 evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 196 evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
137 evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL); 197 evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL);
138 evas_object_show(frame); 198 evas_object_show(frame);
139 elm_object_part_content_set(pane, "right", frame); 199 elm_object_part_content_set(pane, "right", frame);
140 200
201 table = elm_table_add(frame);
202 evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
203 evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
204 elm_object_content_set(frame, table);
205 evas_object_show(table);
206
207 ui.title = elm_entry_add(table);
208 elm_entry_editable_set(ui.title, EINA_FALSE);
209 evas_object_size_hint_weight_set(ui.title, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
210 evas_object_size_hint_align_set(ui.title, EVAS_HINT_FILL, EVAS_HINT_FILL);
211 elm_table_pack(table, ui.title, 0, 0, 1, 1);
212 evas_object_show(ui.title);
213
214 btn = elm_button_add(table);
215 icon = elm_icon_add(table);
216 elm_icon_standard_set(icon, "emblem-downloads");
217 elm_object_part_content_set(btn, "icon", icon);
218 elm_table_pack(table, btn, 1, 0, 1, 1);
219 evas_object_show(btn);
220 evas_object_smart_callback_add(btn, "clicked", _theme_download_cb, NULL);
221 evas_object_show(icon);
222
223 ui.screenshot = elm_photocam_add(table);
224 evas_object_smart_callback_add(ui.screenshot, "download,progress", _download_progress_cb, NULL);
225 evas_object_smart_callback_add(ui.screenshot, "download,done", _download_done, NULL);
226 elm_photocam_zoom_mode_set(ui.screenshot, ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT);
227 evas_object_size_hint_weight_set(ui.screenshot, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
228 evas_object_size_hint_align_set(ui.screenshot, EVAS_HINT_FILL, EVAS_HINT_FILL);
229 elm_table_pack(table, ui.screenshot, 0, 1, 2, 2);
230 evas_object_show(ui.screenshot);
231
232 ui.progress = elm_progressbar_add(table);
233 evas_object_size_hint_weight_set(ui.progress, EVAS_HINT_EXPAND, 0.0);
234 evas_object_size_hint_align_set(ui.progress, EVAS_HINT_FILL, 0.0);
235 elm_table_pack(table, ui.progress, 0, 2, 2, 1);
236
237 ui.author = elm_entry_add(table);
238 elm_entry_editable_set(ui.author, EINA_FALSE);
239 evas_object_size_hint_weight_set(ui.author, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
240 evas_object_size_hint_align_set(ui.author, EVAS_HINT_FILL, EVAS_HINT_FILL);
241 elm_table_pack(table, ui.author, 0, 3, 2, 1);
242 evas_object_show(ui.author);
243
244 ui.description = elm_entry_add(table);
245 elm_entry_editable_set(ui.description, EINA_FALSE);
246 evas_object_size_hint_weight_set(ui.description, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
247 evas_object_size_hint_align_set(ui.description, EVAS_HINT_FILL, EVAS_HINT_FILL);
248 elm_table_pack(table, ui.description, 0, 4, 2, 1);
249 evas_object_show(ui.description);
250
141 evas_object_resize(win, 360 * elm_config_scale_get(), 251 evas_object_resize(win, 360 * elm_config_scale_get(),
142 240 * elm_config_scale_get()); 252 240 * elm_config_scale_get());
143 253
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 13d41b2..07f765f 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -13,6 +13,9 @@ lib_LTLIBRARIES = libextra.la
13includes_HEADERS = extra.h 13includes_HEADERS = extra.h
14includesdir = $(includedir)/extra-@VMAJ@ 14includesdir = $(includedir)/extra-@VMAJ@
15 15
16libextra_la_SOURCES = extra.c 16libextra_la_SOURCES = extra.c \
17 jsmn/jsmn.c \
18 jsmn/jsmn.h
19
17libextra_la_LIBADD = @EFL_LIBS@ -lm 20libextra_la_LIBADD = @EFL_LIBS@ -lm
18libextra_la_LDFLAGS = -no-undefined @EFL_LTLIBRARY_FLAGS@ 21libextra_la_LDFLAGS = -no-undefined @EFL_LTLIBRARY_FLAGS@
diff --git a/src/lib/extra.c b/src/lib/extra.c
index 12996a6..3e96127 100644
--- a/src/lib/extra.c
+++ b/src/lib/extra.c
@@ -3,7 +3,7 @@
3#endif 3#endif
4 4
5#include "extra.h" 5#include "extra.h"
6 6#include "jsmn/jsmn.h"
7#include "extra_private.h" 7#include "extra_private.h"
8 8
9static int _extra_init = 0; 9static int _extra_init = 0;
@@ -11,18 +11,27 @@ int _extra_lib_log_dom = -1;
11 11
12Eina_List *_theme_list; 12Eina_List *_theme_list;
13 13
14#define sec_strdup(v) v ? eina_strbuf_string_steal(v) : NULL
15
14static void 16static void
15_extra_theme_add(const char *id, const char *name, const char *author, 17_extra_theme_add(Eina_Strbuf *id, Eina_Strbuf *name,
18 Eina_Strbuf *author, Eina_Strbuf *description,
19 Eina_Strbuf *online_ss, Eina_Strbuf *download_url,
16 int version) 20 int version)
17{ 21{
18 Extra_Theme *theme; 22 Extra_Theme *theme;
19 23
20 theme = malloc(sizeof(*theme)); 24 theme = malloc(sizeof(*theme));
21 theme->id = strdup(id); 25 theme->id = sec_strdup(id);
22 theme->name = strdup(name); 26 theme->name = sec_strdup(name);
23 theme->author = strdup(author); 27 theme->author = sec_strdup(author);
28 theme->description = sec_strdup(description);
29 theme->online_screenshot = sec_strdup(online_ss);
30 theme->download_url = sec_strdup(download_url);
24 theme->version = version; 31 theme->version = version;
25 32
33 printf("VERSION %d\n", version);
34
26 _theme_list = eina_list_append(_theme_list, theme); 35 _theme_list = eina_list_append(_theme_list, theme);
27} 36}
28 37
@@ -74,50 +83,151 @@ extra_shutdown(void)
74 return _extra_init; 83 return _extra_init;
75} 84}
76 85
77static void 86static Eina_Bool
78_url_data_line_cb(char *buf, int len) 87_url_data_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event_info)
79{ 88{
80 buf[len] = '\0'; 89 Ecore_Con_Event_Url_Data *url_data = event_info;
81 if (buf[0] == '"') 90 Eina_Strbuf *buf = ecore_con_url_data_get(url_data->url_con);
91
92 eina_strbuf_append_n(buf, url_data->data, url_data->size);
93
94 return EINA_TRUE;
95}
96
97static int
98_string_tuple_get(Eina_Strbuf *c, jsmntok_t *array, int i, Eina_Strbuf **name, Eina_Strbuf **value)
99{
100 if (array[i].type != JSMN_STRING || array[i].size != 1)
101 {
102 printf("expected string type with children\n");
103 return 0;
104 }
105
106 *name = eina_strbuf_substr_get(c, array[i].start, array[i].end - array[i].start);
107
108 if ((array[i + 1].type != JSMN_STRING && array[i + 1].type != JSMN_PRIMITIVE) || array[i + 1].size != 0)
82 { 109 {
83 buf[len-1] = '\0'; 110 printf("Expected string type without children\n");
84 _extra_theme_add(buf+1, buf+1, "", 0); 111 return 0;
85 } 112 }
86 else 113 *value = eina_strbuf_substr_get(c, array[i + 1].start, array[i + 1].end - array[i + 1].start);
87 _extra_theme_add(buf, buf, "", 0); 114
115 return 2;
88} 116}
89 117
90static Eina_Bool 118static Eina_Bool
91_url_data_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event_info) 119_fill_themes(Eina_Strbuf *buf)
92{ 120{
93 Ecore_Con_Event_Url_Data *url_data = event_info; 121 jsmn_parser parser;
94 char buf[1024]; 122 jsmntok_t parts[201];
95 int i, start = 0, end = 0; 123 int n, c = 0;
124
125 jsmn_init(&parser);
96 126
97 for (i = 0; i < url_data->size; i++) 127 const char *string = eina_strbuf_string_get(buf);
128 n = jsmn_parse(&parser, string, strlen(string), parts, 201);
129
130 if (n == 0)
131 {
132 printf("No themes received\n");
133 return EINA_FALSE;
134 }
135
136 if (parts[0].type != JSMN_OBJECT)
98 { 137 {
99 if (url_data->data[i] == '\r' || url_data->data[i] == '\n') 138 printf("Root node should be a object\n");
139 return EINA_FALSE;
140 }
141
142 c += 1;
143
144 for (int i = 0; i < parts[0].size; ++i)
145 {
146 Eina_Strbuf *id = NULL, *name = NULL, *version = NULL, *description = NULL, *author = NULL, *download_path = NULL, *online_ss = NULL;
147 int versionNumb;
148 //expect string object tuple
149 if (parts[c].type != JSMN_STRING || parts[c].size != 1)
100 { 150 {
101 if (end == start) 151 printf("Expected String type with one child\n");
102 continue; 152 return EINA_FALSE;
153 }
103 154
104 _url_data_line_cb(buf + start, end - start); 155 c += 1;
105 start = end; 156
157 if (parts[c].type != JSMN_OBJECT || parts[c].size <= 0)
158 {
159 printf("Expected Object type with more than 0 children\n");
160 return EINA_FALSE;
106 } 161 }
107 else 162
163 int max = parts[c].size;
164 c+=1;
165 for (int i2 = 0; i2 < max; ++i2)
108 { 166 {
109 buf[end] = url_data->data[i]; 167 Eina_Strbuf *value = NULL, *property = NULL;
110 end++; 168 const char *v;
169 int j = _string_tuple_get(buf, parts, c, &value, &property);
170
171 if (!j) return EINA_FALSE;
172 c += j;
173
174 v = eina_strbuf_string_steal(value);
175
176 if (!strcmp(v, "description"))
177 description = property;
178 else if (!strcmp(v, "author"))
179 author = property;
180 else if (!strcmp(v, "name"))
181 name = property;
182 else if (!strcmp(v, "version"))
183 version = property;
184 else if (!strcmp(v, "theme_id"))
185 id = property;
186 else
187 eina_strbuf_free(property);
188 eina_strbuf_free(value);
189
111 } 190 }
191
192 download_path = eina_strbuf_new();
193 online_ss = eina_strbuf_new();
194
195 eina_strbuf_append(download_path, "http://" HOSTNAME"/themes/");
196 eina_strbuf_append_buffer(download_path, id);
197 eina_strbuf_append(download_path, "-");
198 eina_strbuf_append_buffer(download_path, version);
199 eina_strbuf_append(download_path, ".edj");
200
201 eina_strbuf_append(online_ss, "http://" HOSTNAME "/themes/preview/");
202 eina_strbuf_append_buffer(online_ss, id);
203 eina_strbuf_append(online_ss, ".png");
204
205 versionNumb = atoi(eina_strbuf_string_steal(version));
206
207 _extra_theme_add(id, name, author, description, online_ss, download_path, versionNumb);
208
209 eina_strbuf_free(id);
210 eina_strbuf_free(name);
211 eina_strbuf_free(author);
212 eina_strbuf_free(description);
213 eina_strbuf_free(version);
214 eina_strbuf_free(download_path);
215 eina_strbuf_free(online_ss);
112 } 216 }
113 217
114 return EINA_TRUE; 218 return EINA_TRUE;
115} 219}
116 220
117static Eina_Bool 221static Eina_Bool
118_url_complete_cb(void *data, int type EINA_UNUSED, void *event_info EINA_UNUSED) 222_url_complete_cb(void *data, int type EINA_UNUSED, void *event_info)
119{ 223{
120 Extra_Progress *progress = data;; 224 Extra_Progress *progress = data;;
225 Ecore_Con_Event_Url_Complete *complete = event_info;
226 Eina_Strbuf *buf;
227
228 buf = ecore_con_url_data_get(complete->url_con);
229
230 _fill_themes(buf);
121 231
122 if (progress->done_cb) 232 if (progress->done_cb)
123 progress->done_cb(); 233 progress->done_cb();
@@ -132,7 +242,8 @@ extra_sync(Extra_Progress *progress)
132 Ecore_Con_Url *url; 242 Ecore_Con_Url *url;
133 243
134 url = ecore_con_url_custom_new("http://" HOSTNAME "/v1/themes/", "GET"); 244 url = ecore_con_url_custom_new("http://" HOSTNAME "/v1/themes/", "GET");
135 ecore_con_url_additional_header_add(url, "Accept", "text/csv"); 245 ecore_con_url_additional_header_add(url, "Accept", "text/json");
246 ecore_con_url_data_set(url, eina_strbuf_new());
136 247
137 progress->url = url; 248 progress->url = url;
138 ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA, _url_data_cb, NULL); 249 ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA, _url_data_cb, NULL);
diff --git a/src/lib/extra.h b/src/lib/extra.h
index 597262c..2981051 100644
--- a/src/lib/extra.h
+++ b/src/lib/extra.h
@@ -43,6 +43,9 @@ typedef struct _Extra_Theme
43 const char *id; 43 const char *id;
44 const char *name; 44 const char *name;
45 const char *author; 45 const char *author;
46 const char *description;
47 const char *online_screenshot;
48 const char *download_url;
46 int version; 49 int version;
47} Extra_Theme; 50} Extra_Theme;
48 51
diff --git a/src/lib/jsmn b/src/lib/jsmn
new file mode 160000
Subproject 1682c32e9ae5990ddd0f0e907270a0f6dde5cbe