CoAT: cmd_dump: Say it with a return statement
[quvi-tool.git] / src / builtin / dump.c
blob81dbca852b249b4772e59bb07b1179b681e0e4b8
1 /* quvi
2 * Copyright (C) 2012,2013 Toni Gundogdu <legatvs@gmail.com>
4 * This file is part of quvi <http://quvi.sourceforge.net/>.
6 * This program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU Affero General Public
8 * License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
11 * This program 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
14 * GNU Affero General Public License for more details.
16 * You should have received a copy of the GNU Affero General
17 * Public License along with this program. If not, see
18 * <http://www.gnu.org/licenses/>.
21 #include "config.h"
23 #include <stdlib.h>
24 #include <string.h>
25 #include <glib/gi18n.h>
26 #include <quvi.h>
28 #include "linput.h"
29 #include "lprint.h"
30 #include "lopts.h"
31 #include "lutil.h"
32 #include "setup.h"
33 #include "opts.h"
34 #include "cmd.h"
36 static struct linput_s linput;
37 static struct lopts_s lopts;
38 extern struct opts_s opts;
39 static quvi_t q;
41 static void _foreach_playlist_url(gpointer p, gpointer userdata,
42 const gchar *url)
44 lprint_cb_playlist_print_buffer playlist_print_buffer;
45 lprint_cb_playlist_properties playlist_properties;
46 lprint_cb_playlist_free playlist_free;
47 lprint_cb_playlist_new playlist_new;
49 lutil_query_properties_t qps;
50 quvi_playlist_t qp;
51 gpointer h;
53 g_assert(userdata != NULL);
54 g_assert(p != NULL);
56 qps = (lutil_query_properties_t) p;
57 qp = (quvi_playlist_t) userdata;
59 if (qps->exit_status != EXIT_SUCCESS)
60 return;
62 /* default. */
64 playlist_print_buffer = lprint_rfc2483_playlist_print_buffer;
65 playlist_properties = lprint_rfc2483_playlist_properties;
66 playlist_free = lprint_rfc2483_playlist_free;
67 playlist_new = lprint_rfc2483_playlist_new;
69 if (g_strcmp0(opts.core.print_format, "enum") ==0)
71 playlist_print_buffer = lprint_enum_playlist_print_buffer;
72 playlist_properties = lprint_enum_playlist_properties;
73 playlist_free = lprint_enum_playlist_free;
74 playlist_new = lprint_enum_playlist_new;
77 #ifdef HAVE_JSON_GLIB
78 if (g_strcmp0(opts.core.print_format, "json") ==0)
80 playlist_print_buffer = lprint_json_playlist_print_buffer;
81 playlist_properties = lprint_json_playlist_properties;
82 playlist_free = lprint_json_playlist_free;
83 playlist_new = lprint_json_playlist_new;
85 #endif
87 #ifdef HAVE_LIBXML
88 if (g_strcmp0(opts.core.print_format, "xml") ==0)
90 playlist_print_buffer = lprint_xml_playlist_print_buffer;
91 playlist_properties = lprint_xml_playlist_properties;
92 playlist_free = lprint_xml_playlist_free;
93 playlist_new = lprint_xml_playlist_new;
95 #endif
97 qps->exit_status = playlist_new(qps->q, &h);
98 if (qps->exit_status != EXIT_SUCCESS)
99 return;
101 qps->exit_status = playlist_properties(qp, h);
102 if (qps->exit_status == EXIT_SUCCESS)
103 qps->exit_status = playlist_print_buffer(h);
105 playlist_free(h);
108 static gint _file_ext_from(const lutil_query_properties_t qps,
109 const quvi_http_metainfo_t qmi, gchar **dst)
111 gchar *s;
112 gint r;
114 *dst = NULL;
116 if (qmi == NULL)
117 return (EXIT_SUCCESS);
119 r = EXIT_SUCCESS;
120 s = NULL;
122 quvi_http_metainfo_get(qmi, QUVI_HTTP_METAINFO_PROPERTY_CONTENT_TYPE, &s);
123 if (quvi_ok(qps->q) == TRUE)
125 quvi_file_ext_t qfe = quvi_file_ext_new(qps->q, s);
126 if (quvi_ok(qps->q) == TRUE)
127 *dst = g_strdup(quvi_file_ext_get(qfe));
128 else
130 qps->xperr(_("libquvi: while creating file extension: %s"),
131 quvi_errmsg(qps->q));
132 r = EXIT_FAILURE;
134 quvi_file_ext_free(qfe);
136 else
138 qps->xperr(_("libquvi: while getting http metainfo property: %s"),
139 quvi_errmsg(qps->q));
140 r = EXIT_FAILURE;
142 return (r);
145 static gint _exec_cmd(const lutil_query_properties_t qps,
146 const quvi_http_metainfo_t qmi,
147 const quvi_media_t qm)
149 struct lutil_exec_opts_s xopts;
150 gchar *file_ext;
151 gint i, r;
153 if (opts.exec.external == NULL)
154 return (EXIT_SUCCESS);
156 if (_file_ext_from(qps, qmi, &file_ext) != EXIT_SUCCESS)
157 return (EXIT_FAILURE);
159 r = EXIT_SUCCESS;
160 i = 0;
162 while (opts.exec.external[i] != NULL && r == EXIT_SUCCESS)
164 memset(&xopts, 0, sizeof(struct lutil_exec_opts_s));
166 xopts.flags.discard_stderr = !opts.exec.enable_stderr;
167 xopts.flags.discard_stdout = !opts.exec.enable_stdout;
168 xopts.flags.dump_argv = opts.exec.dump_argv;
170 xopts.exec_arg = opts.exec.external[i];
171 xopts.xperr = qps->xperr;
173 xopts.file_ext = file_ext;
174 xopts.qm = qm;
176 r = lutil_exec_cmd(&xopts);
177 ++i;
179 g_free(file_ext);
180 return (r);
183 static gint _query_metainfo(const lutil_query_properties_t qps,
184 quvi_http_metainfo_t *qmi,
185 const quvi_media_t qm)
187 *qmi = NULL;
188 if (opts.dump.query_metainfo == FALSE)
189 return (EXIT_SUCCESS);
190 return (lutil_query_metainfo(qps->q, qm, qmi, qps->xperr));
193 static void _foreach_subtitle_url(gpointer p, gpointer userdata,
194 const gchar *url)
196 lprint_cb_subtitle_lang_properties subtitle_lang_properties;
197 lprint_cb_subtitle_print_buffer subtitle_print_buffer;
198 lprint_cb_subtitles_available subtitles_available;
199 lprint_cb_subtitle_free subtitle_free;
200 lprint_cb_subtitle_new subtitle_new;
202 lutil_query_properties_t qps;
203 quvi_subtitle_t qsub;
204 gpointer h;
206 g_assert(userdata != NULL);
207 g_assert(p != NULL);
209 qps = (lutil_query_properties_t) p;
210 qsub = (quvi_subtitle_t) userdata;
212 if (qps->exit_status != EXIT_SUCCESS)
213 return;
215 /* default. */
217 subtitle_lang_properties = lprint_rfc2483_subtitle_lang_properties;
218 subtitle_print_buffer = lprint_rfc2483_subtitle_print_buffer;
219 subtitles_available = lprint_rfc2483_subtitles_available;
220 subtitle_free = lprint_rfc2483_subtitle_free;
221 subtitle_new = lprint_rfc2483_subtitle_new;
223 if (g_strcmp0(opts.core.print_format, "enum") ==0)
225 subtitle_lang_properties = lprint_enum_subtitle_lang_properties;
226 subtitle_print_buffer = lprint_enum_subtitle_print_buffer;
227 subtitles_available = lprint_enum_subtitles_available;
228 subtitle_free = lprint_enum_subtitle_free;
229 subtitle_new = lprint_enum_subtitle_new;
232 #ifdef HAVE_JSON_GLIB
233 if (g_strcmp0(opts.core.print_format, "json") ==0)
235 subtitle_lang_properties = lprint_json_subtitle_lang_properties;
236 subtitle_print_buffer = lprint_json_subtitle_print_buffer;
237 subtitles_available = lprint_json_subtitles_available;
238 subtitle_free = lprint_json_subtitle_free;
239 subtitle_new = lprint_json_subtitle_new;
241 #endif
243 #ifdef HAVE_LIBXML
244 if (g_strcmp0(opts.core.print_format, "xml") ==0)
246 subtitle_lang_properties = lprint_xml_subtitle_lang_properties;
247 subtitle_print_buffer = lprint_xml_subtitle_print_buffer;
248 subtitles_available = lprint_xml_subtitles_available;
249 subtitle_free = lprint_xml_subtitle_free;
250 subtitle_new = lprint_xml_subtitle_new;
252 #endif
254 if (opts.core.print_subtitles == FALSE)
256 const gchar *lang;
257 quvi_subtitle_t l;
259 /* Choose the subtitle, otherwise use the default. */
261 lang = (opts.core.subtitle_language != NULL)
262 ? opts.core.subtitle_language
263 : "default"; /* Assumes nothing matches this in the array. */
265 qps->exit_status =
266 lutil_choose_subtitle(qps->q, qsub, lang, qps->xperr, &l, TRUE);
268 if (qps->exit_status != EXIT_SUCCESS)
269 return;
271 qps->exit_status = subtitle_new(qps->q, &h);
272 if (qps->exit_status != EXIT_SUCCESS)
273 return;
275 qps->exit_status = subtitle_lang_properties(l, h);
276 if (qps->exit_status == EXIT_SUCCESS)
277 qps->exit_status = subtitle_print_buffer(h);
279 subtitle_free(h);
281 else
282 qps->exit_status = subtitles_available(qps->q, qsub);
285 static void _foreach_media_url(gpointer p, gpointer userdata,
286 const gchar *url)
288 lprint_cb_media_streams_available media_streams_available;
289 lprint_cb_media_stream_properties media_stream_properties;
290 lprint_cb_media_print_buffer media_print_buffer;
291 lprint_cb_media_properties media_properties;
292 lprint_cb_media_free media_free;
293 lprint_cb_media_new media_new;
295 lutil_query_properties_t qps;
296 quvi_media_t qm;
298 g_assert(userdata != NULL);
299 g_assert(p != NULL);
301 qps = (lutil_query_properties_t) p;
302 qm = (quvi_media_t) userdata;
304 if (qps->exit_status != EXIT_SUCCESS)
305 return;
307 /* default. */
309 media_streams_available = lprint_enum_media_streams_available;
310 media_stream_properties = lprint_enum_media_stream_properties;
311 media_print_buffer = lprint_enum_media_print_buffer;
312 media_properties = lprint_enum_media_properties;
313 media_free = lprint_enum_media_free;
314 media_new = lprint_enum_media_new;
316 if (g_strcmp0(opts.core.print_format, "rfc2483") ==0)
318 media_streams_available = lprint_rfc2483_media_streams_available;
319 media_stream_properties = lprint_rfc2483_media_stream_properties;
320 media_print_buffer = lprint_rfc2483_media_print_buffer;
321 media_properties = lprint_rfc2483_media_properties;
322 media_free = lprint_rfc2483_media_free;
323 media_new = lprint_rfc2483_media_new;
326 #ifdef HAVE_JSON_GLIB
327 if (g_strcmp0(opts.core.print_format, "json") ==0)
329 media_streams_available = lprint_json_media_streams_available;
330 media_stream_properties = lprint_json_media_stream_properties;
331 media_print_buffer = lprint_json_media_print_buffer;
332 media_properties = lprint_json_media_properties;
333 media_free = lprint_json_media_free;
334 media_new = lprint_json_media_new;
336 #endif
338 #ifdef HAVE_LIBXML
339 if (g_strcmp0(opts.core.print_format, "xml") ==0)
341 media_streams_available = lprint_xml_media_streams_available;
342 media_stream_properties = lprint_xml_media_stream_properties;
343 media_print_buffer = lprint_xml_media_print_buffer;
344 media_properties = lprint_xml_media_properties;
345 media_free = lprint_xml_media_free;
346 media_new = lprint_xml_media_new;
348 #endif
350 if (opts.core.print_streams == FALSE)
352 quvi_http_metainfo_t qmi;
353 gpointer h;
355 qps->exit_status = media_new(qps->q, qm, &h);
356 if (qps->exit_status != EXIT_SUCCESS)
357 return;
359 qps->exit_status = media_properties(h);
360 if (qps->exit_status != EXIT_SUCCESS)
362 media_free(h);
363 return;
366 /* Choose the stream, otherwise use the default. */
368 if (opts.core.stream != NULL)
370 qps->exit_status = lutil_choose_stream(qps->q, qm, opts.core.stream,
371 qps->xperr);
373 if (qps->exit_status != EXIT_SUCCESS)
375 media_free(h);
376 return;
380 /* Query HTTP metainfo (if at all). */
382 qps->exit_status = _query_metainfo(qps, &qmi, qm);
383 if (qps->exit_status == EXIT_SUCCESS)
385 qps->exit_status = media_stream_properties(qmi, h);
386 if (qps->exit_status == EXIT_SUCCESS)
387 qps->exit_status = media_print_buffer(h);
390 if (qps->exit_status == EXIT_SUCCESS)
391 qps->exit_status = _exec_cmd(qps, qmi, qm);
393 quvi_http_metainfo_free(qmi);
394 media_free(h);
396 else
397 qps->exit_status = media_streams_available(qps->q, qm);
400 static gint _cleanup(const gint r)
402 linput_free(&linput);
403 quvi_free(q);
404 return (r);
407 gint cmd_dump(gint argc, gchar **argv)
409 lutil_cb_printerr xperr;
410 struct setup_query_s sq;
412 if (setup_opts(argc, argv, &lopts) != EXIT_SUCCESS)
413 return (EXIT_FAILURE);
415 if (lutil_parse_input(&linput, (const gchar**) opts.rargs) != EXIT_SUCCESS)
416 return (EXIT_FAILURE);
418 if (setup_quvi(&q) != EXIT_SUCCESS)
420 linput_free(&linput);
421 return (EXIT_FAILURE);
424 /* Check {media,playlist} URL support. */
426 xperr = lprint_enum_errmsg; /* rfc2483 uses this also. */
428 #ifdef HAVE_JSON_GLIB
429 if (g_strcmp0(opts.core.print_format, "json") ==0)
430 xperr = lprint_json_errmsg;
431 #endif
432 #ifdef HAVE_LIBXML
433 if (g_strcmp0(opts.core.print_format, "xml") ==0)
434 xperr = lprint_xml_errmsg;
435 #endif
437 memset(&sq, 0, sizeof(struct setup_query_s));
439 sq.force_subtitle_mode =
440 (opts.core.print_subtitles || opts.core.subtitle_language != NULL)
441 ? TRUE
442 : FALSE;
444 sq.activity.playlist = _foreach_playlist_url;
445 sq.activity.subtitle = _foreach_subtitle_url;
446 sq.activity.media = _foreach_media_url;
448 sq.perr = lutil_print_stderr_unless_quiet;
449 sq.xperr = xperr;
451 sq.linput = &linput;
452 sq.q = q;
454 return (_cleanup(setup_query(&sq)));
457 /* vim: set ts=2 sw=2 tw=72 expandtab: */