Welcome Ethumb, it's ready to get out of PROTO.
[framework/uifw/ethumb.git] / src / bin / ethumbd_client.c
1 /**
2  * @file
3  *
4  * Copyright (C) 2009 by ProFUSION embedded systems
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,  but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License
14  * for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  *
21  * @author Rafael Antognolli <antognolli@profusion.mobi>
22  * @author Gustavo Sverzut Barbieri <barbieri@profusion.mobi>
23  */
24 #include <config.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <limits.h>
29 #include <Ethumb_Client.h>
30 #include <Eina.h>
31 #include <Ecore_Getopt.h>
32 #include <Ecore.h>
33
34 const char *aspect_opt[] = { "keep", "ignore", "crop", NULL };
35 const char *format_opt[] = { "png", "jpg", "eet", NULL };
36 struct frame
37 {
38    const char *file;
39    const char *group;
40    const char *swallow;
41 };
42
43 struct options
44 {
45    Eina_Rectangle geometry;
46    unsigned int format, aspect;
47    char *format_str;
48    char *aspect_str;
49    char *directory;
50    char *category;
51    struct frame frame;
52    char *src_path;
53    char *src_key;
54    const char *thumb_path;
55    const char *thumb_key;
56    double video_time;
57    int page;
58 };
59
60 static unsigned char
61 _ethumb_getopt_callback_frame_parse(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc __UNUSED__, const char *str, void *data __UNUSED__, Ecore_Getopt_Value *storage)
62 {
63    struct frame *f = (struct frame *)storage->ptrp;
64    const char *tfile, *tgroup, *tswallow, *base, *sep;
65
66    base = str;
67    sep = strchr(base, ':');
68    if (!sep)
69         goto error;
70    tfile = eina_stringshare_add_length(base, sep - base);
71    base = sep + 1;
72
73    sep = strchr(base, ':');
74    if (!sep)
75      {
76         eina_stringshare_del(tfile);
77         goto error;
78      }
79    tgroup = eina_stringshare_add_length(base, sep - base);
80    base = sep + 1;
81    if (base[0] == '\0')
82      {
83         eina_stringshare_del(tfile);
84         eina_stringshare_del(tgroup);
85         goto error;
86      }
87    tswallow = eina_stringshare_add(base);
88
89    f->file = tfile;
90    f->group = tgroup;
91    f->swallow = tswallow;
92    return 1;
93
94  error:
95    fprintf(stderr,
96            "ERROR: invalid theme, not in format "
97            "'file:group:swallow_part': '%s'\n",
98            str);
99    return 0;
100 }
101
102 const Ecore_Getopt optdesc = {
103   "ethumbd_client",
104   NULL,
105   PACKAGE_VERSION,
106   "(C) 2009 - ProFUSION embedded systems",
107   "LGPL v3 - GNU Lesser General Public License",
108   "Thumbnails generator client using DBus and ethumbd.\n"
109   "\n"
110   "This program uses ethumbd server to create thumbnails from pictures. "
111   "It's an example of use and a test for ethumbd.\n",
112   0,
113   {
114      ECORE_GETOPT_CALLBACK_ARGS
115      ('s', "size", "thumbnail size expected.",
116       "WxH", ecore_getopt_callback_size_parse, NULL),
117      ECORE_GETOPT_CHOICE
118      ('f', "format", "file format to save.", format_opt),
119      ECORE_GETOPT_CHOICE
120      ('a', "aspect", "original image aspect ratio.", aspect_opt),
121      ECORE_GETOPT_STORE_STR
122      ('d', "directory", "directory to save thumbnails."),
123      ECORE_GETOPT_STORE_STR
124      ('c', "category", "thumbnails category."),
125      ECORE_GETOPT_CALLBACK_ARGS
126      ('t', "theme", "path to theme file, group and swallow part.",
127       "file:group:swallow_part", _ethumb_getopt_callback_frame_parse, NULL),
128      ECORE_GETOPT_STORE_STR
129      ('k', "key", "key inside eet file to read image from."),
130      ECORE_GETOPT_STORE_DOUBLE
131      ('v', "video_time", "time of video frame to use as thumbnail."),
132      ECORE_GETOPT_STORE_INT
133      ('p', "document_page", "document page to use as thumbnail."),
134      ECORE_GETOPT_LICENSE('L', "license"),
135      ECORE_GETOPT_COPYRIGHT('C', "copyright"),
136      ECORE_GETOPT_VERSION('V', "version"),
137      ECORE_GETOPT_HELP('h', "help"),
138      ECORE_GETOPT_SENTINEL
139   }
140 };
141
142 static void
143 _thumb_report(const char *mode, const char *src_path, const char *src_key, const char *thumb_path, const char *thumb_key)
144 {
145    printf("%s '%s' '%s' => '%s' '%s'\n",
146           mode,
147           src_path, src_key ? src_key : "",
148           thumb_path, thumb_key ? thumb_key : "");
149 }
150
151 static void
152 _finished_thumb(void *data __UNUSED__, Ethumb_Client *client __UNUSED__, int id __UNUSED__, const char *src_path, const char *src_key, const char *thumb_path, const char *thumb_key, Eina_Bool success)
153 {
154    const char *mode = success ? "GENERATED" : "FAILED";
155    _thumb_report(mode, src_path, src_key, thumb_path, thumb_key);
156    ecore_main_loop_quit();
157 }
158
159 static void
160 _connected(void *data, Ethumb_Client *c, Eina_Bool success)
161 {
162    struct options *opts = data;
163    const char *thumb_path, *thumb_key;
164    long id;
165
166    if (!success)
167      {
168         fputs("ERROR: could not connect to DBus server.\n", stderr);
169         ecore_main_loop_quit();
170         return;
171      }
172
173    fputs("connected to DBus server, setup parameters...\n", stdout);
174
175    ethumb_client_format_set(c, opts->format);
176    ethumb_client_aspect_set(c, opts->aspect);
177
178    if (opts->directory) ethumb_client_dir_path_set(c, opts->directory);
179    if (opts->category) ethumb_client_category_set(c, opts->category);
180    if (opts->geometry.w > 0 && opts->geometry.h > 0)
181      ethumb_client_size_set(c, opts->geometry.w, opts->geometry.h);
182    if (opts->frame.file)
183      ethumb_client_frame_set
184        (c, opts->frame.file, opts->frame.group, opts->frame.swallow);
185    if (opts->video_time > 0)
186      ethumb_client_video_time_set(c, opts->video_time);
187    if (opts->page > 0)
188      ethumb_client_document_page_set(c, opts->page);
189
190    if (!ethumb_client_file_set(c, opts->src_path, opts->src_key))
191      {
192         fprintf(stderr, "ERROR: could not set file '%s', key '%s'\n",
193                 opts->src_path, opts->src_key ? opts->src_key : "");
194         ecore_main_loop_quit();
195         return;
196      }
197
198    ethumb_client_thumb_path_set(c, opts->thumb_path, opts->thumb_key);
199    ethumb_client_thumb_path_get(c, &thumb_path, &thumb_key);
200    if (ethumb_client_thumb_exists(c))
201      {
202         _thumb_report
203           ("EXISTS", opts->src_path, opts->src_key, thumb_path, thumb_key);
204         ecore_main_loop_quit();
205         return;
206      }
207
208    id = ethumb_client_generate(c, _finished_thumb, NULL, NULL);
209    if (id < 0)
210      {
211         fputs("ERROR: could not request thumbnail to be generated.\n", stderr);
212         ecore_main_loop_quit();
213         return;
214      }
215    printf("request id=%ld, file='%s', key='%s'\n",
216           id, opts->src_path, opts->src_key ? opts->src_key : "");
217 }
218
219 int
220 main(int argc, char *argv[])
221 {
222    Ethumb_Client *c;
223    Eina_Bool quit_option = 0;
224    const char *format_str, *aspect_str;
225    struct options opts = {
226      {-1, -1, -1, -1},
227      0, 0,
228      NULL, NULL, NULL, NULL,
229      {NULL, NULL, NULL},
230      NULL, NULL, NULL, NULL,
231      0.0,
232      0
233    };
234    int arg_index;
235    int i, ret = 0;
236
237    ethumb_client_init();
238    ecore_init();
239
240    Ecore_Getopt_Value values[] = {
241      ECORE_GETOPT_VALUE_PTR_CAST(opts.geometry),
242      ECORE_GETOPT_VALUE_PTR_CAST(format_str),
243      ECORE_GETOPT_VALUE_PTR_CAST(aspect_str),
244      ECORE_GETOPT_VALUE_STR(opts.directory),
245      ECORE_GETOPT_VALUE_STR(opts.category),
246      ECORE_GETOPT_VALUE_PTR_CAST(opts.frame),
247      ECORE_GETOPT_VALUE_STR(opts.src_key),
248      ECORE_GETOPT_VALUE_DOUBLE(opts.video_time),
249      ECORE_GETOPT_VALUE_INT(opts.page),
250      ECORE_GETOPT_VALUE_BOOL(quit_option),
251      ECORE_GETOPT_VALUE_BOOL(quit_option),
252      ECORE_GETOPT_VALUE_BOOL(quit_option),
253      ECORE_GETOPT_VALUE_BOOL(quit_option),
254      ECORE_GETOPT_VALUE_NONE
255    };
256
257    arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
258    if ((arg_index < 0) || (arg_index == argc))
259      {
260         if (arg_index < 0)
261           fprintf(stderr, "Could not parse arguments.\n");
262         else
263           fprintf(stderr, "Missing source file to thumbnail.\n");
264
265         ret = 1;
266         goto end;
267      }
268
269    if (quit_option)
270      {
271         ret = 0;
272         goto end;
273      }
274
275    for (i = 0; i < 3; i++)
276      if (format_opt[i] == format_str)
277        {
278           opts.format = i;
279           break;
280        }
281
282    for (i = 0; i < 3; i++)
283      if (aspect_opt[i] == aspect_str)
284        {
285           opts.aspect = i;
286           break;
287        }
288
289    opts.src_path = argv[arg_index++];
290    if (arg_index < argc)
291      {
292         opts.thumb_path = argv[arg_index++];
293         if (arg_index < argc)
294           opts.thumb_key = argv[arg_index];
295      }
296
297    c = ethumb_client_connect(_connected, &opts, NULL);
298    if (!c)
299      {
300         fputs("ERROR: could not connect to server.\n", stderr);
301         ret = 2;
302         goto end;
303      }
304
305    ecore_main_loop_begin();
306    ethumb_client_disconnect(c);
307
308  end:
309    if (opts.frame.file)
310      {
311         eina_stringshare_del(opts.frame.file);
312         eina_stringshare_del(opts.frame.group);
313         eina_stringshare_del(opts.frame.swallow);
314      }
315    ecore_shutdown();
316    ethumb_client_shutdown();
317
318    return ret;
319 }