ethumb: reduce number of generate.
[framework/uifw/ethumb.git] / src / bin / ethumbd_client.c
1 /**
2  * @file
3  *
4  * Copyright (C) 2009 by ProFUSION embedded systems
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library;
18  * if not, see <http://www.gnu.org/licenses/>.
19  *
20  * @author Rafael Antognolli <antognolli@profusion.mobi>
21  */
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
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 _exists(Ethumb_Client *c, __UNUSED__ Ethumb_Exists *thread, Eina_Bool exists, void *data)
161 {
162    struct options *opts = data;
163    const char *thumb_path, *thumb_key;
164    long id;
165
166    if (exists)
167      {
168         ethumb_client_thumb_path_get(c, &thumb_path, &thumb_key);
169         _thumb_report
170           ("EXISTS", opts->src_path, opts->src_key, thumb_path, thumb_key);
171         ecore_main_loop_quit();
172         return;
173      }
174
175    id = ethumb_client_generate(c, _finished_thumb, NULL, NULL);
176    if (id < 0)
177      {
178         fputs("ERROR: could not request thumbnail to be generated.\n", stderr);
179         ecore_main_loop_quit();
180         return;
181      }
182    printf("request id=%ld, file='%s', key='%s'\n",
183           id, opts->src_path, opts->src_key ? opts->src_key : "");
184
185 }
186
187 static void
188 _connected(void *data, Ethumb_Client *c, Eina_Bool success)
189 {
190    struct options *opts = data;
191
192    if (!success)
193      {
194         fputs("ERROR: could not connect to DBus server.\n", stderr);
195         ecore_main_loop_quit();
196         return;
197      }
198
199    fputs("connected to DBus server, setup parameters...\n", stdout);
200
201    ethumb_client_format_set(c, opts->format);
202    ethumb_client_aspect_set(c, opts->aspect);
203
204    if (opts->directory) ethumb_client_dir_path_set(c, opts->directory);
205    if (opts->category) ethumb_client_category_set(c, opts->category);
206    if (opts->geometry.w > 0 && opts->geometry.h > 0)
207      ethumb_client_size_set(c, opts->geometry.w, opts->geometry.h);
208    if (opts->frame.file)
209      ethumb_client_frame_set
210        (c, opts->frame.file, opts->frame.group, opts->frame.swallow);
211    if (opts->video_time > 0)
212      ethumb_client_video_time_set(c, opts->video_time);
213    if (opts->page > 0)
214      ethumb_client_document_page_set(c, opts->page);
215
216    if (!ethumb_client_file_set(c, opts->src_path, opts->src_key))
217      {
218         fprintf(stderr, "ERROR: could not set file '%s', key '%s'\n",
219                 opts->src_path, opts->src_key ? opts->src_key : "");
220         ecore_main_loop_quit();
221         return;
222      }
223
224    ethumb_client_thumb_path_set(c, opts->thumb_path, opts->thumb_key);
225    ethumb_client_thumb_exists(c, _exists, opts);
226 }
227
228 int
229 main(int argc, char *argv[])
230 {
231    Ethumb_Client *c;
232    Eina_Bool quit_option = 0;
233    const char *format_str = NULL, *aspect_str;
234    struct options opts = {
235      {-1, -1, -1, -1},
236      0, 0,
237      NULL, NULL, NULL, NULL,
238      {NULL, NULL, NULL},
239      NULL, NULL, NULL, NULL,
240      0.0,
241      0
242    };
243    int arg_index;
244    int i, ret = 0;
245
246    ethumb_client_init();
247    ecore_init();
248
249    Ecore_Getopt_Value values[] = {
250      ECORE_GETOPT_VALUE_PTR_CAST(opts.geometry),
251      ECORE_GETOPT_VALUE_PTR_CAST(format_str),
252      ECORE_GETOPT_VALUE_PTR_CAST(aspect_str),
253      ECORE_GETOPT_VALUE_STR(opts.directory),
254      ECORE_GETOPT_VALUE_STR(opts.category),
255      ECORE_GETOPT_VALUE_PTR_CAST(opts.frame),
256      ECORE_GETOPT_VALUE_STR(opts.src_key),
257      ECORE_GETOPT_VALUE_DOUBLE(opts.video_time),
258      ECORE_GETOPT_VALUE_INT(opts.page),
259      ECORE_GETOPT_VALUE_BOOL(quit_option),
260      ECORE_GETOPT_VALUE_BOOL(quit_option),
261      ECORE_GETOPT_VALUE_BOOL(quit_option),
262      ECORE_GETOPT_VALUE_BOOL(quit_option),
263      ECORE_GETOPT_VALUE_NONE
264    };
265
266    arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
267    if ((arg_index < 0) || (arg_index == argc))
268      {
269         if (arg_index < 0)
270           fprintf(stderr, "Could not parse arguments.\n");
271         else
272           fprintf(stderr, "Missing source file to thumbnail.\n");
273
274         ret = 1;
275         goto end;
276      }
277
278    if (quit_option)
279      {
280         ret = 0;
281         goto end;
282      }
283
284    for (i = 0; i < 3; i++)
285      if (format_opt[i] == format_str)
286        {
287           opts.format = i;
288           break;
289        }
290
291    for (i = 0; i < 3; i++)
292      if (aspect_opt[i] == aspect_str)
293        {
294           opts.aspect = i;
295           break;
296        }
297
298    opts.src_path = argv[arg_index++];
299    if (arg_index < argc)
300      {
301         opts.thumb_path = argv[arg_index++];
302         if (arg_index < argc)
303           opts.thumb_key = argv[arg_index];
304      }
305
306    c = ethumb_client_connect(_connected, &opts, NULL);
307    if (!c)
308      {
309         fputs("ERROR: could not connect to server.\n", stderr);
310         ret = 2;
311         goto end;
312      }
313
314    ecore_main_loop_begin();
315    ethumb_client_disconnect(c);
316
317  end:
318    if (opts.frame.file)
319      {
320         eina_stringshare_del(opts.frame.file);
321         eina_stringshare_del(opts.frame.group);
322         eina_stringshare_del(opts.frame.swallow);
323      }
324    ecore_shutdown();
325    ethumb_client_shutdown();
326
327    return ret;
328 }