2
* Copyright (C) 2014 Igalia S.L.
4
* Contact: Iago Toral Quiroga <itoral@igalia.com>
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public License
8
* as published by the Free Software Foundation; version 2.1 of
9
* the License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful, but
12
* 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.
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28
#define GRL_LOG_DOMAIN_DEFAULT grl_launch_log_domain
29
GRL_LOG_DOMAIN_STATIC(grl_launch_log_domain);
31
static GMainLoop *mainloop = NULL;
32
static GOptionContext *context = NULL;
33
static GrlMediaSerializeType serialize_type;
34
static GrlRegistry *registry = NULL;
36
static gboolean serialize;
37
static gboolean titles;
38
static gboolean version;
39
static gchar **operation_list = NULL;
40
static gchar *conffile = NULL;
41
static gchar *flags_parameter;
42
static gchar *keys_parameter;
43
static gint count = G_MAXINT;
44
static gint delay = 1;
47
static GOptionEntry entries[] = {
49
G_OPTION_ARG_STRING, &conffile,
50
"Configuration file to send to sources",
53
G_OPTION_ARG_INT, &count,
54
"Number of elements to return",
57
G_OPTION_ARG_INT, &delay,
58
"Wait some seconds before performing the operation (default 1 second)",
61
G_OPTION_ARG_STRING, &flags_parameter,
62
"List of comma-separated flags to use",
63
"full|fast_only|idle_relay" },
65
G_OPTION_ARG_NONE, &full,
69
G_OPTION_ARG_STRING, &keys_parameter,
70
"List of comma-separated keys to retrieve",
72
{ "serialize", 'S', 0,
73
G_OPTION_ARG_NONE, &serialize,
77
G_OPTION_ARG_INT, &skip,
78
"Number of elements to skip",
81
G_OPTION_ARG_NONE, &titles,
85
G_OPTION_ARG_NONE, &version,
88
{ G_OPTION_REMAINING, '\0', 0,
89
G_OPTION_ARG_STRING_ARRAY, &operation_list,
90
"<operation> <options>",
96
quit (gboolean print_help)
101
help = g_option_context_get_help (context, TRUE, NULL);
102
g_print ("%s", help);
106
g_main_loop_quit (mainloop);
113
g_print ("grl-launch-" GRL_MAJORMINOR " version " VERSION "\n");
114
g_print ("Grilo " VERSION "\n");
115
g_print ("https://wiki.gnome.org/Projects/Grilo\n");
119
print_key (GrlMedia *media,
122
GByteArray *binary_blob;
127
value = grl_data_get (GRL_DATA (media), key);
133
if (G_VALUE_HOLDS_STRING (value)) {
134
str_value = (gchar *) g_value_get_string (value);
135
has_comma = g_strstr_len (str_value, -1, ",") != NULL;
137
g_print ("\"%s\"", str_value);
139
g_print ("%s", str_value);
141
} else if (G_VALUE_HOLDS_INT (value)) {
142
g_print ("%d", g_value_get_int (value));
143
} else if (G_VALUE_HOLDS_FLOAT (value)) {
144
g_print ("%f", g_value_get_float (value));
145
} else if (G_VALUE_HOLDS_BOOLEAN (value)) {
146
g_print ("%s", g_value_get_boolean (value)? "true": "false");
147
} else if (G_VALUE_TYPE (value) == G_TYPE_BYTE_ARRAY) {
148
binary_blob = g_value_get_boxed (value);
149
str_value = g_base64_encode (binary_blob->data, binary_blob->len);
150
g_print ("%s", str_value);
152
} else if (G_VALUE_TYPE (value) == G_TYPE_DATE_TIME) {
153
str_value = g_date_time_format (g_value_get_boxed (value), "%FT%T");
154
g_print ("%s", str_value);
160
print_titles (GList *keys)
162
gboolean print_newline = FALSE;
168
if (serialize || keys) {
169
print_newline = TRUE;
180
g_print ("%s", grl_metadata_key_get_name (GRLPOINTER_TO_KEYID (keys->data)));
181
keys = g_list_next (keys);
193
print_result_cb (GrlSource *source,
201
GList *keys = (GList *) user_data;
202
gboolean print_newline = FALSE;
204
static guint total_results = 0;
207
g_print ("Error: %s\n", error->message);
211
if (serialize || keys) {
212
print_newline = TRUE;
217
media_serial = grl_media_serialize_extended (media, serialize_type);
218
g_print ("%s", media_serial);
219
g_free (media_serial);
226
print_key (media, GRLPOINTER_TO_KEYID (k->data));
233
g_object_unref (media);
240
if (remaining == 0) {
241
switch (total_results) {
243
g_print ("No results\n");
246
g_print ("1 result\n");
249
g_print ("%u results\n", total_results);
257
print_single_result_cb (GrlSource *source,
263
print_result_cb (source, operation_id, media, 0, user_data, error);
271
GrlRegistry *registry;
275
if (!keys_parameter) {
279
registry = grl_registry_get_default ();
280
keys_array = g_strsplit (keys_parameter, ",", -1);
282
for (i = 0; keys_array[i]; i++) {
283
if (g_strcmp0 (keys_array[i], "*") == 0) {
285
g_strfreev (keys_array);
286
return grl_registry_get_metadata_keys (registry);
289
key = grl_registry_lookup_metadata_key (registry, keys_array[i]);
290
if (key == GRL_METADATA_KEY_INVALID) {
291
g_print ("Unknown %s key\n", keys_array[i]);
293
keys = g_list_append (keys, GRLKEYID_TO_POINTER (key));
297
g_strfreev (keys_array);
302
static GrlResolutionFlags
305
GrlResolutionFlags flags = GRL_RESOLVE_NORMAL;
309
if (!flags_parameter) {
313
flags_array = g_strsplit (flags_parameter, ",", -1);
315
for (i = 0; flags_array[i]; i++) {
316
if (g_strcmp0 (flags_array[i], "full") == 0) {
317
flags |= GRL_RESOLVE_FULL;
318
} else if (g_strcmp0 (flags_array[i], "idle_relay") == 0) {
319
flags |= GRL_RESOLVE_IDLE_RELAY;
320
} else if (g_strcmp0 (flags_array[i], "fast_only") == 0) {
321
flags |= GRL_RESOLVE_FAST_ONLY;
323
g_print ("Unknown %s flag\n", flags_array[i]);
327
g_strfreev (flags_array);
333
get_source_and_media (const gchar *str,
337
GrlRegistry *registry = grl_registry_get_default();
339
/* Check if str is a source */
340
*source = grl_registry_lookup_source (registry, str);
344
/* Check then if this is a media */
345
*media = grl_media_unserialize (str);
347
*source = grl_registry_lookup_source (registry, grl_media_get_source (*media));
353
content_changed_cb (GrlSource *source,
354
GPtrArray *changed_medias,
355
GrlSourceChangeType change_type,
356
gboolean location_unknown,
362
for (i = 0; i < changed_medias->len; i++) {
363
media = (GrlMedia *) g_ptr_array_index (changed_medias, i);
364
switch (change_type) {
365
case GRL_CONTENT_CHANGED:
366
g_print ("changed,");
368
case GRL_CONTENT_ADDED:
371
case GRL_CONTENT_REMOVED:
372
g_print ("removed,");
376
if (location_unknown) {
382
if (serialize || data) {
384
print_result_cb (source, 0, g_object_ref (media), -1, data, NULL);
392
run_search (gchar **search_params)
395
GrlOperationOptions *options;
396
GrlRegistry *registry;
400
if (g_strv_length (search_params) != 2) {
404
/* Empty string means "search all" */
405
if (search_params[0][0] == '\0') {
408
term = search_params[0];
411
registry = grl_registry_get_default ();
412
source = grl_registry_lookup_source (registry, search_params[1]);
415
g_print ("%s is not a valid source\n", search_params[1]);
419
if (!(grl_source_supported_operations (source) & GRL_OP_SEARCH)) {
420
g_print ("%s do not support search\n", search_params[1]);
426
options = grl_operation_options_new (NULL);
427
grl_operation_options_set_flags (options, get_flags ());
428
grl_operation_options_set_count (options, count);
429
grl_operation_options_set_skip (options, skip);
433
grl_source_search (source, term, keys, options, print_result_cb, keys);
435
g_object_unref (options);
441
run_browse (gchar **browse_params)
445
GrlOperationOptions *options;
448
if (g_strv_length (browse_params) != 1) {
452
get_source_and_media (browse_params[0], &source, &media);
453
if (media && !GRL_IS_MEDIA_BOX (media)) {
454
g_print ("%s is not a media box\n", browse_params[0]);
459
g_print ("%s is not a valid source\n", browse_params[0]);
463
if (!(grl_source_supported_operations (source) & GRL_OP_BROWSE)) {
464
g_print ("%s do not support browse\n", grl_source_get_id (source));
470
options = grl_operation_options_new (NULL);
471
grl_operation_options_set_flags (options, get_flags ());
472
grl_operation_options_set_count (options, count);
473
grl_operation_options_set_skip (options, skip);
477
grl_source_browse (source, media, keys, options, print_result_cb, keys);
479
g_object_unref (options);
485
run_resolve (gchar **resolve_params)
490
GrlOperationOptions *options;
491
GrlRegistry *registry;
494
if (g_strv_length (resolve_params) > 2) {
498
get_source_and_media (resolve_params[0], &source, &media);
500
if (resolve_params[1]) {
501
/* Ask the other source */
502
registry = grl_registry_get_default ();
503
source = grl_registry_lookup_source (registry, resolve_params[1]);
507
g_print ("%s is not a valid source\n", resolve_params[1]? resolve_params[1]: resolve_params[0]);
512
if (!(grl_source_supported_operations (source) & GRL_OP_RESOLVE)) {
513
g_print ("%s do not support resolve\n", grl_source_get_id (source));
517
print_keys = get_keys();
520
search_keys = print_keys;
522
/* Resolve requires some key to resolve; let's use "id" */
523
search_keys = g_list_append (NULL, GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ID));
526
options = grl_operation_options_new (NULL);
527
grl_operation_options_set_flags (options, get_flags ());
529
print_titles (print_keys);
531
grl_source_resolve (source, media, search_keys, options, print_single_result_cb, print_keys);
533
g_object_unref (options);
539
run_may_resolve (gchar **may_resolve_params)
541
GList *required_keys = NULL;
542
GrlKeyID resolve_key;
544
GrlRegistry *registry;
548
if (g_strv_length (may_resolve_params) > 3) {
552
registry = grl_registry_get_default ();
553
resolve_key = grl_registry_lookup_metadata_key (registry, may_resolve_params[0]);
554
if (resolve_key == GRL_METADATA_KEY_INVALID) {
555
g_print ("Unknown %s key\n", may_resolve_params[0]);
559
get_source_and_media (may_resolve_params[1], &source, &media);
561
if (may_resolve_params[2]) {
562
/* Ask the other source */
563
registry = grl_registry_get_default ();
564
source = grl_registry_lookup_source (registry, may_resolve_params[2]);
568
g_print ("%s is not a valid source\n", may_resolve_params[2]? may_resolve_params[2]: may_resolve_params[1]);
573
if (!(grl_source_supported_operations (source) & GRL_OP_RESOLVE)) {
574
g_print ("%s do not support resolve\n", grl_source_get_id (source));
578
may = grl_source_may_resolve (source, media, resolve_key, &required_keys);
581
g_print ("%s can resolve %s key\n", grl_source_get_id (source), may_resolve_params[0]);
583
g_print ("%s cannot resolve %s key", grl_source_get_id (source), may_resolve_params[0]);
585
g_print (". It requires ");
586
while (required_keys) {
587
g_print ("%s", grl_metadata_key_get_name (GRLPOINTER_TO_KEYID (required_keys->data)));
588
required_keys = g_list_next (required_keys);
602
run_query (gchar **query_params)
605
GrlOperationOptions *options;
606
GrlRegistry *registry;
609
if (g_strv_length (query_params) != 2) {
613
registry = grl_registry_get_default ();
614
source = grl_registry_lookup_source (registry, query_params[1]);
617
g_print ("%s is not a valid source\n", query_params[1]);
621
if (!(grl_source_supported_operations (source) & GRL_OP_QUERY)) {
622
g_print ("%s do not support query\n", query_params[1]);
628
options = grl_operation_options_new (NULL);
629
grl_operation_options_set_flags (options, get_flags ());
630
grl_operation_options_set_count (options, count);
631
grl_operation_options_set_skip (options, skip);
635
grl_source_query (source, query_params[0], keys, options, print_result_cb, keys);
637
g_object_unref (options);
643
run_monitor (gchar **monitor_params)
645
GError *error = NULL;
647
GrlRegistry *registry;
650
if (g_strv_length (monitor_params) != 1) {
654
registry = grl_registry_get_default ();
655
source = grl_registry_lookup_source (registry, monitor_params[0]);
658
g_print ("%s is not a valid source\n", monitor_params[0]);
662
if (!(grl_source_supported_operations (source) & GRL_OP_NOTIFY_CHANGE)) {
663
g_print ("%s do not support changes monitoring\n", monitor_params[0]);
667
if (!grl_source_notify_change_start (source, &error)) {
668
g_print ("Cannot monitor on %s: %s\n", monitor_params[0], error->message);
669
g_error_free (error);
676
g_print ("change_type,location_unknown");
677
if (serialize || keys) {
685
g_signal_connect (source,
687
G_CALLBACK (content_changed_cb),
694
run_test_media_from_uri (gchar **test_params)
698
GrlRegistry *registry;
702
if (g_strv_length (test_params) > 2) {
706
if (!test_params[0]) {
710
registry = grl_registry_get_default ();
711
if (test_params[1]) {
712
source = grl_registry_lookup_source (registry, test_params[1]);
714
g_print ("%s is not a valid source\n", test_params[1]);
717
if (!(grl_source_supported_operations (source) & GRL_OP_MEDIA_FROM_URI)) {
718
g_print ("%s does not support test_media_from_uri operation\n", test_params[1]);
721
can_do = grl_source_test_media_from_uri (source, test_params[0]);
722
g_print ("%s\t%s\n", test_params[1], can_do? "yes": "no");
724
sources = grl_registry_get_sources_by_operations (registry, GRL_OP_MEDIA_FROM_URI, TRUE);
725
for (p = sources; p; p = g_list_next (p)) {
726
source = GRL_SOURCE (p->data);
727
can_do = grl_source_test_media_from_uri (source, test_params[0]);
729
g_print ("%s\t%s\n", grl_source_get_id (source), "yes");
732
g_list_free (sources);
739
run_media_from_uri (gchar **uri_params)
743
GrlOperationOptions *options;
744
GrlRegistry *registry;
747
if (g_strv_length (uri_params) != 2) {
751
registry = grl_registry_get_default ();
752
source = grl_registry_lookup_source (registry, uri_params[1]);
755
g_print ("%s is not a valid source\n", uri_params[1]);
759
if (!(grl_source_supported_operations (source) & GRL_OP_MEDIA_FROM_URI)) {
760
g_print ("%s does not support media_from_uri\n", uri_params[1]);
764
print_keys = get_keys ();
767
use_keys = print_keys;
769
/* Media_From_Uri requires some key to use; let's use "id" */
770
use_keys = g_list_append (NULL, GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ID));
773
options = grl_operation_options_new (NULL);
774
grl_operation_options_set_flags (options, get_flags ());
776
print_titles (print_keys);
778
grl_source_get_media_from_uri (source, uri_params[0], use_keys, options, print_single_result_cb, print_keys);
780
g_object_unref (options);
788
if (!operation_list) {
792
if (g_strcmp0 (operation_list[0], "search") == 0) {
793
return run_search (++operation_list);
794
} else if (g_strcmp0 (operation_list[0], "browse") == 0) {
795
return run_browse (++operation_list);
796
} else if (g_strcmp0 (operation_list[0], "resolve") == 0) {
797
return run_resolve (++operation_list);
798
} else if (g_strcmp0 (operation_list[0], "may_resolve") == 0) {
799
return run_may_resolve (++operation_list);
800
} else if (g_strcmp0 (operation_list[0], "query") == 0) {
801
return run_query (++operation_list);
802
} else if (g_strcmp0 (operation_list[0], "monitor") == 0) {
803
return run_monitor (++operation_list);
804
} else if (g_strcmp0 (operation_list[0], "test_media_from_uri") == 0){
805
return run_test_media_from_uri (++operation_list);
806
} else if (g_strcmp0 (operation_list[0], "media_from_uri") == 0){
807
return run_media_from_uri (++operation_list);
814
main (int argc, char *argv[])
816
GError *error = NULL;
818
context = g_option_context_new ("OPERATION PARAMETERS...");
819
g_option_context_add_main_entries (context, entries, NULL);
820
g_option_context_add_group (context, grl_init_get_option_group ());
821
g_option_context_set_summary (context,
822
"\tbrowse <source>|<media box>\n"
823
"\tmay_resolve <key> <source>|<media box> [<source>]\n"
824
"\tquery <expression> <source>\n"
825
"\tresolve <source>|<media> [<source>]\n"
826
"\tsearch <term> <source>\n"
827
"\tmonitor <source>\n"
828
"\ttest_media_from_uri <uri> [<source>]\n"
829
"\tmedia_from_uri <uri> <source>");
831
g_option_context_parse (context, &argc, &argv, &error);
834
g_printerr ("Invalid arguments, %s\n", error->message);
835
g_clear_error (&error);
844
serialize_type = full? GRL_MEDIA_SERIALIZE_FULL: GRL_MEDIA_SERIALIZE_BASIC;
846
grl_init (&argc, &argv);
848
GRL_LOG_DOMAIN_INIT (grl_launch_log_domain, "grl-launch");
850
registry = grl_registry_get_default ();
852
grl_registry_add_config_from_file (registry, conffile, &error);
854
GRL_WARNING ("Unable to load configuration: %s", error->message);
855
g_error_free (error);
859
mainloop = g_main_loop_new (NULL, FALSE);
861
grl_registry_load_all_plugins (registry, NULL);
863
g_timeout_add_seconds ((guint) delay, run, NULL);
865
g_main_loop_run (mainloop);
867
g_option_context_free (context);