1 /*
2  * Copyright (C) 2010, 2011 Igalia S.L.
3  *
4  * Contact: Iago Toral Quiroga <itoral@igalia.com>
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 License
8  * as published by the Free Software Foundation; version 2.1 of
9  * the License, or (at your option) any later version.
10  *
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.
15  *
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
19  * 02110-1301 USA
20  *
21  */
22 
23 /**
24  * SECTION:grilo
25  * @short_description: Metadata library supporting several services
26  *
27  * Grilo is a metadata retrieval library. Given a search or browse operation,
28  * the library will retrieve a set of metadata related to the operation from a
29  * set of on-line services.
30  *
31  * The Grilo library should be initialized with grl_init() before it can be used.
32  * You should pass pointers to the main argc and argv variables so that Grilo can
33  * process its own command line options.
34  *
35  * After using it, in order to close cleanly all the resources opened either by
36  * the core library or the sources, call grl_deinit().
37  */
38 
39 #include "grilo.h"
40 #include "grl-metadata-key-priv.h"
41 #include "grl-operation-priv.h"
42 #include "grl-registry-priv.h"
43 #include "grl-log-priv.h"
44 #include "config.h"
45 
46 #include <glib/gi18n-lib.h>
47 
48 static gboolean grl_initialized = FALSE;
49 static const gchar *plugin_path = NULL;
50 static const gchar *plugin_list = NULL;
51 
52 static const gchar *
get_default_plugin_dir(void)53 get_default_plugin_dir (void)
54 {
55 #ifdef G_OS_WIN32
56   static gchar *plugin_dir = NULL;
57   gchar *run_directory;
58 
59   if (plugin_dir)
60     return plugin_dir;
61 
62   run_directory = g_win32_get_package_installation_directory_of_module (NULL);
63   plugin_dir = g_build_filename (run_directory,
64                                  "lib", GRL_NAME,
65                                  NULL);
66   g_free (run_directory);
67   return plugin_dir;
68 #else
69   return GRL_PLUGINS_DIR;
70 #endif
71 }
72 
73 static gboolean
pre_parse_hook_cb(GOptionContext * context,GOptionGroup * group,gpointer data,GError ** error)74 pre_parse_hook_cb (GOptionContext  *context,
75                    GOptionGroup    *group,
76                    gpointer         data,
77                    GError         **error)
78 {
79   /* Initialize i18n */
80   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
81   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
82 
83   /* Initialize operations */
84   grl_operation_init ();
85 
86   return TRUE;
87 }
88 
89 static gboolean
post_parse_hook_cb(GOptionContext * context,GOptionGroup * group,gpointer data,GError ** error)90 post_parse_hook_cb (GOptionContext  *context,
91                     GOptionGroup    *group,
92                     gpointer         data,
93                     GError         **error)
94 {
95   GrlRegistry *registry;
96   gchar **split_element;
97   gchar **split_list;
98 
99   /* Initialize GModule */
100   if (!g_module_supported ()) {
101     GRL_ERROR ("GModule not supported in this system");
102   }
103 
104   /* Setup core log domains */
105   _grl_log_init_core_domains ();
106 
107   /* Register default metadata keys */
108   registry = grl_registry_get_default ();
109   grl_metadata_key_setup_system_keys (registry);
110 
111   /* Set default plugin directories */
112   if (!plugin_path) {
113     plugin_path = g_getenv (GRL_PLUGIN_PATH_VAR);
114   }
115 
116   if (!plugin_path) {
117     plugin_path = get_default_plugin_dir ();
118   }
119 
120   split_list = g_strsplit (plugin_path, G_SEARCHPATH_SEPARATOR_S, 0);
121   for (split_element = split_list; *split_element; split_element++) {
122     grl_registry_add_directory (registry, *split_element);
123   }
124   g_strfreev (split_list);
125 
126   /* Restrict plugins to load */
127   if (!plugin_list) {
128     plugin_list = g_getenv (GRL_PLUGIN_LIST_VAR);
129   }
130 
131   if (plugin_list) {
132     split_list = g_strsplit (plugin_list, ":", 0);
133     grl_registry_restrict_plugins (registry, split_list);
134     g_strfreev (split_list);
135   }
136 
137   grl_initialized = TRUE;
138 
139   return TRUE;
140 }
141 
142 /**
143  * grl_init:
144  * @argc: (inout) (allow-none): number of input arguments, length of @argv
145  * @argv: (inout) (element-type utf8) (array length=argc) (allow-none) (transfer none): list of arguments
146  *
147  * Initializes the Grilo library
148  *
149  * Since: 0.1.6
150  */
151 void
grl_init(gint * argc,gchar ** argv[])152 grl_init (gint *argc,
153           gchar **argv[])
154 {
155   GOptionContext *ctx;
156   GOptionGroup *group;
157 
158   if (grl_initialized) {
159     GRL_DEBUG ("already initialized grl");
160     return;
161   }
162 
163   /* Check options */
164   ctx = g_option_context_new ("- Grilo initialization");
165   g_option_context_set_ignore_unknown_options (ctx, TRUE);
166   group = grl_init_get_option_group ();
167   g_option_context_add_group (ctx, group);
168   g_option_context_parse (ctx, argc, argv, NULL);
169   g_option_context_free (ctx);
170 }
171 
172 /**
173  * grl_deinit:
174  *
175  * Deinitializes the Grilo library.
176  *
177  * Call this function after finalizing using Grilo, in order to free and clean
178  * up all the resources created.
179  *
180  * Since: 0.2.8
181  */
182 void
grl_deinit(void)183 grl_deinit (void)
184 {
185   GrlRegistry *registry;
186 
187   if (!grl_initialized) {
188     GRL_WARNING ("Grilo has not been initialized");
189     return;
190   }
191 
192   registry = grl_registry_get_default ();
193   grl_registry_shutdown (registry);
194   grl_initialized = FALSE;
195 }
196 
197 /**
198  * grl_init_get_option_group:
199  *
200  * Returns a #GOptionGroup with Grilo's argument specifications.
201  *
202  * This function is useful if you want to integrate Grilo with other
203  * libraries that use the GOption commandline parser
204  * (see g_option_context_add_group() ).
205  *
206  * Returns: a pointer to Grilo's option group. Should be dereferenced
207  * after use.
208  *
209  * Since: 0.1.6
210  */
211 GOptionGroup *
grl_init_get_option_group(void)212 grl_init_get_option_group (void)
213 {
214   GOptionGroup *group;
215   static const GOptionEntry grl_args[] = {
216     { "grl-plugin-path", 0, 0, G_OPTION_ARG_STRING, &plugin_path,
217 #ifdef G_OS_WIN32
218       N_("Semicolon-separated paths containing Grilo plugins"), NULL },
219 #else
220       N_("Colon-separated paths containing Grilo plugins"), NULL },
221 #endif
222     { "grl-plugin-use", 0, 0, G_OPTION_ARG_STRING, &plugin_list,
223       N_("Colon-separated list of Grilo plugins to use"), NULL },
224     { NULL }
225   };
226 
227   group = g_option_group_new ("grl",
228                               _("Grilo Options"),
229                               _("Show Grilo Options"),
230                               NULL,
231                               NULL);
232   g_option_group_add_entries (group, grl_args);
233   g_option_group_set_parse_hooks (group, pre_parse_hook_cb, post_parse_hook_cb);
234 
235   return group;
236 }
237