summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan A. Suarez Romero <jasuarez@igalia.com>2011-06-09 15:11:12 +0000
committerJuan A. Suarez Romero <jasuarez@igalia.com>2011-06-10 08:56:18 +0000
commit62b05b33408669f9f3bd748db5351cb9f8c7201c (patch)
tree4d94ef5f6fdef7f361211a3fdf0626f4dba3a563
parentf3bbda716318865ccc9cabebdb9613158f7b48bd (diff)
downloadgrilo-62b05b33408669f9f3bd748db5351cb9f8c7201c.tar.gz
doc: Split code examples from documentation
Put examples in a separated directory, so user can easily compile them, and embed those files in the documentation. Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac1
-rw-r--r--doc/grilo/quick-start-using-grilo.xml664
-rw-r--r--examples/Makefile.am20
-rw-r--r--examples/browsing.c128
-rw-r--r--examples/configuring-plugins.c69
-rw-r--r--examples/efficient-metadata-resolution.c149
-rw-r--r--examples/loading-plugins.c71
-rw-r--r--examples/multivalues.c123
-rw-r--r--examples/searching.c105
10 files changed, 698 insertions, 634 deletions
diff --git a/Makefile.am b/Makefile.am
index bb1290b..e364cc2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,7 +7,7 @@
ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = src libs bindings tools
+SUBDIRS = src libs bindings tools examples
if ENABLE_TESTS
SUBDIRS += tests
diff --git a/configure.ac b/configure.ac
index 5bee9af..8f84fdd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -279,6 +279,7 @@ AC_CONFIG_FILES([
doc/Makefile
doc/grilo/Makefile
doc/libs/Makefile
+ examples/Makefile
])
AC_OUTPUT
diff --git a/doc/grilo/quick-start-using-grilo.xml b/doc/grilo/quick-start-using-grilo.xml
index c2d019a..4567754 100644
--- a/doc/grilo/quick-start-using-grilo.xml
+++ b/doc/grilo/quick-start-using-grilo.xml
@@ -23,7 +23,7 @@ $ cd grilo-plugins
$ ./autogen.sh --prefix=/usr
$ make
$ sudo make install
- </programlisting>
+ </programlisting>
<para>
You should now see the grilo libraries installed under /usr/lib and the
@@ -38,8 +38,8 @@ $ sudo make install
<programlisting>
# Execute Grilo's test GUI
$ /usr/bin/grilo-test-ui
- </programlisting>
-
+ </programlisting>
+
<para>
This is a simple playground application that you can use to test
the framework and its plugins.
@@ -50,87 +50,23 @@ $ /usr/bin/grilo-test-ui
<title>Compiling Grilo based programs</title>
<programlisting>
gcc -o example `pkg-config --cflags --libs grilo-x.y` example.c
- </programlisting>
+ </programlisting>
</section>
<section id="programming-with-grilo-loading-plugins">
<title>Programming with Grilo: Loading plugins</title>
<para>Here is a small program illustrating how you can load plugins:</para>
<programlisting role="C">
-<![CDATA[
-#include <grilo.h>
-
-#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
-GRL_LOG_DOMAIN_STATIC(example_log_domain);
-
-static void
-source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
-{
- g_debug ("Detected new source available: '%s'",
- grl_metadata_source_get_name (GRL_METADATA_SOURCE (user_data)));
-
- /* Usually you may add the new service to the user interface so the user
- can interact with it (browse, search, etc) */
-}
-
-static void
-source_removed_cb (GrlPluginRegistry *registry, gpointer user_data)
-{
- g_debug ("Source '%s' is gone",
- grl_metadata_source_get_name (GRL_METADATA_SOURCE (user_data)));
-
- /* Usually you would inform the user that this service is no longer
- available (for example a UPnP server was shutdown) and remove it
- from the user interface. */
-}
-
-static void
-load_plugins (void)
-{
- GrlPluginRegistry *registry;
- GError *error = NULL;
-
- registry = grl_plugin_registry_get_default ();
-
- /* These callback will be invoked when media providers
- are loaded/unloaded */
- g_signal_connect (registry, "source-added",
- G_CALLBACK (source_added_cb), NULL);
- g_signal_connect (registry, "source-removed",
- G_CALLBACK (source_removed_cb), NULL);
-
- /* Command the registry to load all available plugins.
- The registry will look for plugins in the default
- plugin path and directories specified using the
- GRL_PLUGIN_PATH environment variable */
- if (!grl_plugin_registry_load_all (registry, &error)) {
- g_error ("Failed to load plugins: %s", error->message);
- }
-}
-
-gint
-main (int argc, gchar *argv[])
-{
- GMainLoop *loop;
-
- grl_init (&argc, &argv);
- GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
- load_plugins (); /* Load Grilo plugins */
-
- /* Run the main loop */
- loop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (loop);
-
- return 0;
-}
-]]>
+ <xi:include href="../../examples/loading-plugins.c"
+ parse="text"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
</programlisting>
<para>
For more information on how to operate with plugins and media
providers (sources), please check the
<link linkend="GrlPluginRegistry">GrlPluginRegistry</link>
- API reference.
+ API reference.
</para>
</section>
@@ -163,78 +99,16 @@ main (int argc, gchar *argv[])
application:
</para>
<programlisting role="C">
-<![CDATA[
-#include <grilo.h>
-
-#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
-GRL_LOG_DOMAIN_STATIC(example_log_domain);
-
-static void
-source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
-{
- /* If the Youtube plugin is installed, you should see it here now! */
- g_debug ("Detected new source available: '%s'",
- grl_metadata_source_get_name (GRL_METADATA_SOURCE (user_data)));
-}
-
-static void
-load_plugins (void)
-{
- GrlPluginRegistry *registry;
- GError *error = NULL;
-
- registry = grl_plugin_registry_get_default ();
-
- g_signal_connect (registry, "source-added",
- G_CALLBACK (source_added_cb), NULL);
-
- if (!grl_plugin_registry_load_all (registry, &error)) {
- g_error ("Failed to load plugins: %s", error->message);
- }
-}
-
-static void
-configure_plugins (void)
-{
- GrlConfig *config;
- GrlPluginRegistry *registry;
-
- /* Let's configure only the Youtube plugin (only requires an API key) */
- config = grl_config_new ("grl-youtube", NULL);
- grl_config_set_api_key (config,
- "AI39si4EfscPllSfUy1IwexMf__kntTL_G5dfSr2iUEVN45RHG"
- "q92Aq0lX25OlnOkG6KTN-4soVAkAf67fWYXuHfVADZYr7S1A");
- registry = grl_plugin_registry_get_default ();
- grl_plugin_registry_add_config (registry, config, NULL);
-
- /* When the plugin is loaded, the framework will provide
- this configuration for it */
-}
-
-gint
-main (int argc, gchar *argv[])
-{
- GMainLoop *loop;
-
- grl_init (&argc, &argv);
- GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
- configure_plugins (); /* Configure plugins */
- load_plugins (); /* Load Grilo plugins */
-
- /* Run the main loop */
- loop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (loop);
-
- return 0;
-}
-]]>
+ <xi:include href="../../examples/configuring-plugins.c"
+ parse="text"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
</programlisting>
<para>
For more information on how to configure plugins
plase check the
<link linkend="GrlConfig">GrlConfig</link>
- API reference.
+ API reference.
</para>
</section>
@@ -244,137 +118,16 @@ main (int argc, gchar *argv[])
content from a particular media source (a similar approach
can be used for searching content instead of browsing):</para>
<programlisting role="C">
-<![CDATA[
-#include <grilo.h>
-
-#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
-GRL_LOG_DOMAIN_STATIC(example_log_domain);
-
-/* This callback is invoked for each result that matches our
- browse operation. The arguments are:
- 1) The source we obtained the content from.
- 2) The operation identifier this result relates to.
- 3) A media object representing content that matched the browse operation.
- 4) Estimation of the number of remaining media objects that will be sent
- after this one as part of the same resultset (0 means that the browse
- operation is finished).
- 5) User data passed to the grl_media_source_browse method.
- 6) A GError if an error happened, NULL otherwise */
-static void
-browse_cb (GrlMediaSource *source,
- guint browse_id,
- GrlMedia *media,
- guint remaining,
- gpointer user_data,
- const GError *error)
-{
- /* First we check if the operation failed for some reason */
- if (error) {
- g_error ("Browse operation failed. Reason: %s", error->message);
- }
-
- /* Check if we got a valid media object as some plugins may call the callback
- with a NULL media under certain circumstances (for example when they
- cannot estimate the number of remaining results and they find suddenly they
- don't have any more results to send) */
- if (media) {
- /* Get the metadata we are interested in */
- const gchar *title = grl_media_get_title (media);
-
- /* If the media is a container (box) that means we could
- browse it again (that is, we could use it as the second parameter
- of the grl_media_source_browse method) */
- if (GRL_IS_MEDIA_BOX (media)) {
- guint childcount = grl_media_box_get_childcount (GRL_MEDIA_BOX (media));
- g_debug ("\t Got '%s' (container with %d elements)", title, childcount);
- } else {
- guint seconds = grl_media_get_duration (media);
- const gchar *url = grl_media_get_url (media);
- g_debug ("\t Got '%s' (media - length: %d seconds)", title, seconds);
- g_debug ("\t\t URL: %s", url);
- }
- g_object_unref (media);
- }
-
- /* Check if this was the last result */
- if (remaining == 0) {
- g_debug ("Browse operation finished!");
- }
-}
-
-static void
-source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
-{
- static gboolean first = TRUE;
- GrlMetadataSource *source = GRL_METADATA_SOURCE (user_data);
- GList * keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
- GRL_METADATA_KEY_DURATION,
- GRL_METADATA_KEY_URL,
- GRL_METADATA_KEY_CHILDCOUNT,
- NULL);
- g_debug ("Detected new source available: '%s'",
- grl_metadata_source_get_name (source));
-
- /* We will just issue a browse operation on the first browseble
- source we find */
- if (first &&
- grl_metadata_source_supported_operations (source) & GRL_OP_BROWSE) {
- first = FALSE;
- g_debug ("Browsing source: %s", grl_metadata_source_get_name (source));
- /* Here is how you can browse a source, you have to provide:
- 1) The source you want to browse contents from.
- 2) The container object you want to browse (NULL for the root container)
- 3) A list of metadata keys we are interested in.
- 4) Flags to control certain aspects of the browse operation.
- 5) A callback that the framework will invoke for each available result
- 6) User data for the callback
- It returns an operation identifier that you can use to match results
- with the corresponding request (we ignore it here) */
- grl_media_source_browse (GRL_MEDIA_SOURCE (source),
- NULL,
- keys,
- 0, 5,
- GRL_RESOLVE_IDLE_RELAY,
- browse_cb,
- NULL);
- }
-
- g_list_free (keys);
-}
-
-static void
-load_plugins (void)
-{
- GrlPluginRegistry *registry;
- GError *error = NULL;
-
- registry = grl_plugin_registry_get_default ();
- g_signal_connect (registry, "source-added",
- G_CALLBACK (source_added_cb), NULL);
- if (!grl_plugin_registry_load_all (registry, &error)) {
- g_error ("Failed to load plugins: %s", error->message);
- }
-}
-
-gint
-main (int argc, gchar *argv[])
-{
- GMainLoop *loop;
- grl_init (&argc, &argv);
- GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
- load_plugins ();
- loop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (loop);
- return 0;
-}
-]]>
- </programlisting>
+ <xi:include href="../../examples/browsing.c"
+ parse="text"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ </programlisting>
<para>
For more information on how to operate media sources
plase check the
<link linkend="GrlMediaSource">GrlMediaSource</link>
- API reference.
+ API reference.
</para>
</section>
@@ -384,114 +137,16 @@ main (int argc, gchar *argv[])
content by text from a particular media source (Jamendo
in this example):</para>
<programlisting role="C">
-<![CDATA[
-#include <grilo.h>
-#include <string.h>
-
-#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
-GRL_LOG_DOMAIN_STATIC(example_log_domain);
-
-static void
-search_cb (GrlMediaSource *source,
- guint browse_id,
- GrlMedia *media,
- guint remaining,
- gpointer user_data,
- const GError *error)
-{
- if (error) {
- g_error ("Search operation failed. Reason: %s", error->message);
- }
-
- if (media) {
- const gchar *title = grl_media_get_title (media);
- if (GRL_IS_MEDIA_BOX (media)) {
- guint childcount = grl_media_box_get_childcount (GRL_MEDIA_BOX (media));
- g_debug ("\t Got '%s' (container with %d elements)", title, childcount);
- } else {
- guint seconds = grl_media_get_duration (media);
- const gchar *url = grl_media_get_url (media);
- g_debug ("\t Got '%s' (media - length: %d seconds)", title, seconds);
- g_debug ("\t\t URL: %s", url);
- }
- }
-
- if (remaining == 0) {
- g_debug ("Search operation finished!");
- } else {
- g_debug ("\t%d results remaining!", remaining);
- }
-
- g_object_unref (media);
-}
-
-static void
-source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
-{
- const gchar *id;
- GrlMetadataSource *source = GRL_METADATA_SOURCE (user_data);
- GList * keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
- GRL_METADATA_KEY_DURATION,
- GRL_METADATA_KEY_CHILDCOUNT,
- NULL);
-
- /* Not interested if not searchable */
- if (!(grl_metadata_source_supported_operations (source) & GRL_OP_SEARCH))
- return;
-
- g_debug ("Detected new searchable source available: '%s'",
- grl_metadata_source_get_name (source));
-
- /* Only interested in Jamendo */
- id = grl_metadata_source_get_id (source);
- if (strcmp (id, "grl-jamendo"))
- return;
-
- g_debug ("Searching \"rock\" in Jamendo");
- grl_media_source_search (GRL_MEDIA_SOURCE (source),
- "rock",
- keys,
- 0, 5,
- GRL_RESOLVE_IDLE_RELAY,
- search_cb,
- NULL);
-
- g_list_free (keys);
-}
-
-static void
-load_plugins (void)
-{
- GrlPluginRegistry *registry;
- GError *error = NULL;
-
- registry = grl_plugin_registry_get_default ();
- g_signal_connect (registry, "source-added",
- G_CALLBACK (source_added_cb), NULL);
- if (!grl_plugin_registry_load_all (registry, &error)) {
- g_error ("Failed to load plugins: %s", error->message);
- }
-}
-
-gint
-main (int argc, gchar *argv[])
-{
- GMainLoop *loop;
- grl_init (&argc, &argv);
- GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
- load_plugins ();
- loop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (loop);
- return 0;
-}
-]]>
- </programlisting>
+ <xi:include href="../../examples/searching.c"
+ parse="text"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ </programlisting>
<para>
For more information on how to operate media sources
plase check the
<link linkend="GrlMediaSource">GrlMediaSource</link>
- API reference.
+ API reference.
</para>
</section>
@@ -507,7 +162,7 @@ main (int argc, gchar *argv[])
to handle multi-valued properties.
</para>
<para>
- One issue concerning multi-valued properties are their relations with
+ One issue concerning multi-valued properties are their relations with
other properties. Following the example of the video resource with
multiple URIs, each of these URIs should have its own mime-type associated,
as well as its own width and height values. When dealing with multi-valued
@@ -535,131 +190,16 @@ main (int argc, gchar *argv[])
to illustrate how to use it:
</para>
<programlisting role="C">
-<![CDATA[
-#include <grilo.h>
-#include <string.h>
-
-#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
-GRL_LOG_DOMAIN_STATIC(example_log_domain);
-
-static void
-search_cb (GrlMediaSource *source,
- guint browse_id,
- GrlMedia *media,
- guint remaining,
- gpointer user_data,
- const GError *error)
-{
- guint i;
- GrlRelatedKeys *url_info;
-
- if (error) {
- g_error ("Search operation failed. Reason: %s", error->message);
- }
-
- if (media) {
- /* Look through all available URLs for this video resource */
- for (i = 0; i < grl_data_length (GRL_DATA (media), GRL_METADATA_KEY_URL); i++) {
- /* Here we use the low-level GrlRelatedKeys API for demonstration purposes only,
- but we could have just used the more convenient
- grl_media_video_get_url_data_nth() API instead in this case */
- url_info = grl_data_get_related_keys (GRL_DATA (media), GRL_METADATA_KEY_URL, i);
- g_debug ("\t [%s] Got url '%s' and mime-type '%s'",
- grl_media_get_id (media),
- grl_related_keys_get_string (url_info, GRL_METADATA_KEY_URL),
- grl_related_keys_get_string (url_info, GRL_METADATA_KEY_MIME));
- }
- }
-
- if (remaining == 0) {
- g_debug ("Search operation finished!");
- }
-
- g_object_unref (media);
-}
-
-static void
-source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
-{
- const gchar *id;
- GrlMetadataSource *source = GRL_METADATA_SOURCE (user_data);
- GList * keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
- GRL_METADATA_KEY_URL,
- GRL_METADATA_KEY_MIME,
- NULL);
-
- /* Not interested if not searchable */
- if (!(grl_metadata_source_supported_operations (source) & GRL_OP_SEARCH))
- return;
-
- g_debug ("Detected new searchable source available: '%s'",
- grl_metadata_source_get_name (source));
-
- /* Only interested in Youtube */
- id = grl_metadata_source_get_id (source);
- if (strcmp (id, "grl-youtube"))
- return;
-
- g_debug ("Searching \"rock\" in Youtube");
- grl_media_source_search (GRL_MEDIA_SOURCE (source),
- "rock",
- keys,
- 0, 5,
- GRL_RESOLVE_IDLE_RELAY,
- search_cb,
- NULL);
-
- g_list_free (keys);
-}
-
-static void
-load_plugins (void)
-{
- GrlPluginRegistry *registry;
- GError *error = NULL;
-
- registry = grl_plugin_registry_get_default ();
- g_signal_connect (registry, "source-added",
- G_CALLBACK (source_added_cb), NULL);
- if (!grl_plugin_registry_load_all (registry, &error)) {
- g_error ("Failed to load plugins: %s", error->message);
- }
-}
-
-static void
-configure_plugins (void)
-{
- GrlConfig *config;
- GrlPluginRegistry *registry;
-
- config = grl_config_new ("grl-youtube", NULL);
- grl_config_set_api_key (config,
- "AI39si4EfscPllSfUy1IwexMf__kntTL_G5dfSr2iUEVN45RHG"
- "q92Aq0lX25OlnOkG6KTN-4soVAkAf67fWYXuHfVADZYr7S1A");
- registry = grl_plugin_registry_get_default ();
- grl_plugin_registry_add_config (registry, config, NULL);
-}
-
-gint
-main (int argc, gchar *argv[])
-{
- GMainLoop *loop;
- grl_init (&argc, &argv);
- GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
- configure_plugins ();
- load_plugins ();
- loop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (loop);
- return 0;
-}
-]]>
+ <xi:include href="../../examples/multivalues.c"
+ parse="text"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
</programlisting>
<para>
For more information on how to operate with media objects
plase check the
<link linkend="GrlData">GrlData</link> hierarchy
- API reference.
+ API reference.
</para>
</section>
@@ -747,152 +287,10 @@ main (int argc, gchar *argv[])
be an acceptable delay.
</para>
<programlisting role="C">
-<![CDATA[
-#include <grilo.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
-GRL_LOG_DOMAIN_STATIC(example_log_domain);
-
-const gchar *target_source_id = NULL;
-
-static void
-metadata_cb (GrlMediaSource *source,
- guint metadata_id,
- GrlMedia *media,
- gpointer user_data,
- const GError *error)
-{
- if (error)
- g_error ("Metadata operation failed. Reason: %s", error->message);
-
- const gchar *url = grl_media_get_url (media);
- g_debug ("\tURL: %s", url);
- g_object_unref (media);
- exit (0);
-}
-
-static void
-search_cb (GrlMediaSource *source,
- guint browse_id,
- GrlMedia *media,
- guint remaining,
- gpointer user_data,
- const GError *error)
-{
- if (error)
- g_error ("Search operation failed. Reason: %s", error->message);
-
- if (!media) {
- g_error ("No media items found matching the text \"rock\"!");
- return;
- }
-
- g_debug ("Got matching media from %s. Details:", target_source_id);
- const gchar *title = grl_media_get_title (media);
- g_debug ("\tTitle: %s", title);
- const gchar *url = grl_media_get_url (media);
- if (url) {
- g_debug ("\tURL: %s:", url);
- g_object_unref (media);
- exit (0);
- } else {
- g_debug ("URL no available, trying with slow keys now");
- GList *keys = grl_metadata_key_list_new (GRL_METADATA_KEY_URL, NULL);
- grl_media_source_metadata (source,
- media,
- keys,
- GRL_RESOLVE_IDLE_RELAY,
- metadata_cb,
- NULL);
- g_list_free (keys);
- }
-}
-
-static void
-source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
-{
- GrlMetadataSource *source = GRL_METADATA_SOURCE (user_data);
- const gchar *source_id = grl_metadata_source_get_id (source);
-
- /* We are looking for one source in particular */
- if (strcmp (source_id, target_source_id))
- return;
-
- GList *keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
- GRL_METADATA_KEY_URL,
- NULL);
-
- /* The source must be searchable */
- if (!(grl_metadata_source_supported_operations (source) & GRL_OP_SEARCH))
- g_error ("Source %s is not searchable!", source_id);
-
- /* Retrieve the first media from the source matching the text "rock" */
- g_debug ("Searching \"rock\" in \"%s\"", source_id);
- grl_media_source_search (GRL_MEDIA_SOURCE (source),
- "rock",
- keys,
- 0, 1,
- GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FAST_ONLY,
- search_cb,
- NULL);
- g_list_free (keys);
-}
-
-static void
-configure_plugins (void)
-{
- GrlConfig *config;
- GrlPluginRegistry *registry;
-
- /* Let's configure only the Youtube plugin (only requires an API key) */
- config = grl_config_new ("grl-youtube", NULL);
- grl_config_set_api_key (config,
- "AI39si4EfscPllSfUy1IwexMf__kntTL_G5dfSr2iUEVN45RHG"
- "q92Aq0lX25OlnOkG6KTN-4soVAkAf67fWYXuHfVADZYr7S1A");
- registry = grl_plugin_registry_get_default ();
- grl_plugin_registry_add_config (registry, config, NULL);
-}
-
-static void
-load_plugins (void)
-{
- GrlPluginRegistry *registry;
- GError *error = NULL;
-
- registry = grl_plugin_registry_get_default ();
- g_signal_connect (registry, "source-added",
- G_CALLBACK (source_added_cb), NULL);
- if (!grl_plugin_registry_load_all (registry, &error)) {
- g_error ("Failed to load plugins: %s", error->message);
- }
-}
-
-gint
-main (int argc, gchar *argv[])
-{
- GMainLoop *loop;
- grl_init (&argc, &argv);
-
- if (argc != 2) {
- g_print ("Please specify id of the source to search " \
- "(example: grl-youtube)\n");
- exit (1);
- } else {
- target_source_id = argv[1];
- }
-
- GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
- configure_plugins ();
- load_plugins ();
- loop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (loop);
-
- return 0;
-}
-]]>
- </programlisting>
+ <xi:include href="../../examples/efficient-metadata-resolution.c"
+ parse="text"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ </programlisting>
</section>
</section>
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 0000000..6e8e8c7
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,20 @@
+AM_CFLAGS = $(DEPS_CFLAGS) -I$(top_srcdir)/src -I$(top_srcdir)/src/data
+LDADD = $(DEPS_LIBS) $(top_builddir)/src/lib@GRL_NAME@.la
+
+noinst_PROGRAMS = browsing configuring-plugins efficient-metadata-resolution \
+ loading-plugins multivalues searching
+
+browsing_SOURCES = browsing.c
+
+configuring_plugins_SOURCES = configuring-plugins.c
+
+efficient_metadata_resolution_SOURCES = efficient-metadata-resolution.c
+
+loading_plugins_SOURCES = loading-plugins.c
+
+multivalues_SOURCES = multivalues.c
+
+searching_SOURCES = searching.c
+
+MAINTAINERCLEANFILES = Makefile.in *~
+DISTCLEANFILES = $(MAINTAINERCLEANFILES)
diff --git a/examples/browsing.c b/examples/browsing.c
new file mode 100644
index 0000000..bd88bd2
--- /dev/null
+++ b/examples/browsing.c
@@ -0,0 +1,128 @@
+
+/*
+ * Browsing in Grilo.
+ * Shows the first 5 elements of each browsable source
+ */
+
+#include <grilo.h>
+
+#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
+GRL_LOG_DOMAIN_STATIC(example_log_domain);
+
+/* This callback is invoked for each result that matches our
+ browse operation. The arguments are:
+ 1) The source we obtained the content from.
+ 2) The operation identifier this result relates to.
+ 3) A media object representing content that matched the browse operation.
+ 4) Estimation of the number of remaining media objects that will be sent
+ after this one as part of the same resultset (0 means that the browse
+ operation is finished).
+ 5) User data passed to the grl_media_source_browse method.
+ 6) A GError if an error happened, NULL otherwise */
+static void
+browse_cb (GrlMediaSource *source,
+ guint browse_id,
+ GrlMedia *media,
+ guint remaining,
+ gpointer user_data,
+ const GError *error)
+{
+ /* First we check if the operation failed for some reason */
+ if (error) {
+ g_error ("Browse operation failed. Reason: %s", error->message);
+ }
+
+ /* Check if we got a valid media object as some plugins may call the callback
+ with a NULL media under certain circumstances (for example when they
+ cannot estimate the number of remaining results and they find suddenly they
+ don't have any more results to send) */
+ if (media) {
+ /* Get the metadata we are interested in */
+ const gchar *title = grl_media_get_title (media);
+
+ /* If the media is a container (box) that means we could
+ browse it again (that is, we could use it as the second parameter
+ of the grl_media_source_browse method) */
+ if (GRL_IS_MEDIA_BOX (media)) {
+ guint childcount = grl_media_box_get_childcount (GRL_MEDIA_BOX (media));
+ g_debug ("\t Got '%s' (container with %d elements)", title, childcount);
+ } else {
+ guint seconds = grl_media_get_duration (media);
+ const gchar *url = grl_media_get_url (media);
+ g_debug ("\t Got '%s' (media - length: %d seconds)", title, seconds);
+ g_debug ("\t\t URL: %s", url);
+ }
+ g_object_unref (media);
+ }
+
+ /* Check if this was the last result */
+ if (remaining == 0) {
+ g_debug ("Browse operation finished!");
+ }
+}
+
+static void
+source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
+{
+ static gboolean first = TRUE;
+ GrlMetadataSource *source = GRL_METADATA_SOURCE (user_data);
+ GList * keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
+ GRL_METADATA_KEY_DURATION,
+ GRL_METADATA_KEY_URL,
+ GRL_METADATA_KEY_CHILDCOUNT,
+ NULL);
+ g_debug ("Detected new source available: '%s'",
+ grl_metadata_source_get_name (source));
+
+ /* We will just issue a browse operation on the first browseble
+ source we find */
+ if (first &&
+ grl_metadata_source_supported_operations (source) & GRL_OP_BROWSE) {
+ first = FALSE;
+ g_debug ("Browsing source: %s", grl_metadata_source_get_name (source));
+ /* Here is how you can browse a source, you have to provide:
+ 1) The source you want to browse contents from.
+ 2) The container object you want to browse (NULL for the root container)
+ 3) A list of metadata keys we are interested in.
+ 4) Flags to control certain aspects of the browse operation.
+ 5) A callback that the framework will invoke for each available result
+ 6) User data for the callback
+ It returns an operation identifier that you can use to match results
+ with the corresponding request (we ignore it here) */
+ grl_media_source_browse (GRL_MEDIA_SOURCE (source),
+ NULL,
+ keys,
+ 0, 5,
+ GRL_RESOLVE_IDLE_RELAY,
+ browse_cb,
+ NULL);
+ }
+
+ g_list_free (keys);
+}
+
+static void
+load_plugins (void)
+{
+ GrlPluginRegistry *registry;
+ GError *error = NULL;
+
+ registry = grl_plugin_registry_get_default ();
+ g_signal_connect (registry, "source-added",
+ G_CALLBACK (source_added_cb), NULL);
+ if (!grl_plugin_registry_load_all (registry, &error)) {
+ g_error ("Failed to load plugins: %s", error->message);
+ }
+}
+
+gint
+main (int argc, gchar *argv[])
+{
+ GMainLoop *loop;
+ grl_init (&argc, &argv);
+ GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
+ load_plugins ();
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+ return 0;
+}
diff --git a/examples/configuring-plugins.c b/examples/configuring-plugins.c
new file mode 100644
index 0000000..6e75427
--- /dev/null
+++ b/examples/configuring-plugins.c
@@ -0,0 +1,69 @@
+
+/*
+ * Configuring plugins in Grilo.
+ * Shows how to configure the Youtube plugin.
+ */
+
+#include <grilo.h>
+
+#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
+GRL_LOG_DOMAIN_STATIC(example_log_domain);
+
+static void
+source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
+{
+ /* If the Youtube plugin is installed, you should see it here now! */
+ g_debug ("Detected new source available: '%s'",
+ grl_metadata_source_get_name (GRL_METADATA_SOURCE (user_data)));
+}
+
+static void
+load_plugins (void)
+{
+ GrlPluginRegistry *registry;
+ GError *error = NULL;
+
+ registry = grl_plugin_registry_get_default ();
+
+ g_signal_connect (registry, "source-added",
+ G_CALLBACK (source_added_cb), NULL);
+
+ if (!grl_plugin_registry_load_all (registry, &error)) {
+ g_error ("Failed to load plugins: %s", error->message);
+ }
+}
+
+static void
+configure_plugins (void)
+{
+ GrlConfig *config;
+ GrlPluginRegistry *registry;
+
+ /* Let's configure only the Youtube plugin (only requires an API key) */
+ config = grl_config_new ("grl-youtube", NULL);
+ grl_config_set_api_key (config,
+ "AI39si4EfscPllSfUy1IwexMf__kntTL_G5dfSr2iUEVN45RHG"
+ "q92Aq0lX25OlnOkG6KTN-4soVAkAf67fWYXuHfVADZYr7S1A");
+ registry = grl_plugin_registry_get_default ();
+ grl_plugin_registry_add_config (registry, config, NULL);
+
+ /* When the plugin is loaded, the framework will provide
+ this configuration for it */
+}
+
+gint
+main (int argc, gchar *argv[])
+{
+ GMainLoop *loop;
+
+ grl_init (&argc, &argv);
+ GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
+ configure_plugins (); /* Configure plugins */
+ load_plugins (); /* Load Grilo plugins */
+
+ /* Run the main loop */
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+
+ return 0;
+}
diff --git a/examples/efficient-metadata-resolution.c b/examples/efficient-metadata-resolution.c
new file mode 100644
index 0000000..3dd578e
--- /dev/null
+++ b/examples/efficient-metadata-resolution.c
@@ -0,0 +1,149 @@
+
+/*
+ * Shows how to get content in an efficient way.
+ * Search 'rock' content in all searchable sources.
+ */
+
+#include <grilo.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
+GRL_LOG_DOMAIN_STATIC(example_log_domain);
+
+const gchar *target_source_id = NULL;
+
+static void
+metadata_cb (GrlMediaSource *source,
+ guint metadata_id,
+ GrlMedia *media,
+ gpointer user_data,
+ const GError *error)
+{
+ if (error)
+ g_error ("Metadata operation failed. Reason: %s", error->message);
+
+ const gchar *url = grl_media_get_url (media);
+ g_debug ("\tURL: %s", url);
+ g_object_unref (media);
+ exit (0);
+}
+
+static void
+search_cb (GrlMediaSource *source,
+ guint browse_id,
+ GrlMedia *media,
+ guint remaining,
+ gpointer user_data,
+ const GError *error)
+{
+ if (error)
+ g_error ("Search operation failed. Reason: %s", error->message);
+
+ if (!media) {
+ g_error ("No media items found matching the text \"rock\"!");
+ return;
+ }
+
+ g_debug ("Got matching media from %s. Details:", target_source_id);
+ const gchar *title = grl_media_get_title (media);
+ g_debug ("\tTitle: %s", title);
+ const gchar *url = grl_media_get_url (media);
+ if (url) {
+ g_debug ("\tURL: %s:", url);
+ g_object_unref (media);
+ exit (0);
+ } else {
+ g_debug ("URL no available, trying with slow keys now");
+ GList *keys = grl_metadata_key_list_new (GRL_METADATA_KEY_URL, NULL);
+ grl_media_source_metadata (source,
+ media,
+ keys,
+ GRL_RESOLVE_IDLE_RELAY,
+ metadata_cb,
+ NULL);
+ g_list_free (keys);
+ }
+}
+
+static void
+source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
+{
+ GrlMetadataSource *source = GRL_METADATA_SOURCE (user_data);
+ const gchar *source_id = grl_metadata_source_get_id (source);
+
+ /* We are looking for one source in particular */
+ if (strcmp (source_id, target_source_id))
+ return;
+
+ GList *keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
+ GRL_METADATA_KEY_URL,
+ NULL);
+
+ /* The source must be searchable */
+ if (!(grl_metadata_source_supported_operations (source) & GRL_OP_SEARCH))
+ g_error ("Source %s is not searchable!", source_id);
+
+ /* Retrieve the first media from the source matching the text "rock" */
+ g_debug ("Searching \"rock\" in \"%s\"", source_id);
+ grl_media_source_search (GRL_MEDIA_SOURCE (source),
+ "rock",
+ keys,
+ 0, 1,
+ GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FAST_ONLY,
+ search_cb,
+ NULL);
+ g_list_free (keys);
+}
+
+static void
+configure_plugins (void)
+{
+ GrlConfig *config;
+ GrlPluginRegistry *registry;
+
+ /* Let's configure only the Youtube plugin (only requires an API key) */
+ config = grl_config_new ("grl-youtube", NULL);
+ grl_config_set_api_key (config,
+ "AI39si4EfscPllSfUy1IwexMf__kntTL_G5dfSr2iUEVN45RHG"
+ "q92Aq0lX25OlnOkG6KTN-4soVAkAf67fWYXuHfVADZYr7S1A");
+ registry = grl_plugin_registry_get_default ();
+ grl_plugin_registry_add_config (registry, config, NULL);
+}
+
+static void
+load_plugins (void)
+{
+ GrlPluginRegistry *registry;
+ GError *error = NULL;
+
+ registry = grl_plugin_registry_get_default ();
+ g_signal_connect (registry, "source-added",
+ G_CALLBACK (source_added_cb), NULL);
+ if (!grl_plugin_registry_load_all (registry, &error)) {
+ g_error ("Failed to load plugins: %s", error->message);
+ }
+}
+
+gint
+main (int argc, gchar *argv[])
+{
+ GMainLoop *loop;
+ grl_init (&argc, &argv);
+
+ if (argc != 2) {
+ g_print ("Please specify id of the source to search " \
+ "(example: grl-youtube)\n");
+ exit (1);
+ } else {
+ target_source_id = argv[1];
+ }
+
+ GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
+ configure_plugins ();
+ load_plugins ();
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+
+ return 0;
+}
diff --git a/examples/loading-plugins.c b/examples/loading-plugins.c
new file mode 100644
index 0000000..b23e04d
--- /dev/null
+++ b/examples/loading-plugins.c
@@ -0,0 +1,71 @@
+
+/*
+ * Loading plugins in Grilo.
+ * Tracks sources adding and removing
+ */
+
+#include <grilo.h>
+
+#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
+GRL_LOG_DOMAIN_STATIC(example_log_domain);
+
+static void
+source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
+{
+ g_debug ("Detected new source available: '%s'",
+ grl_metadata_source_get_name (GRL_METADATA_SOURCE (user_data)));
+
+ /* Usually you may add the new service to the user interface so the user
+ can interact with it (browse, search, etc) */
+}
+
+static void
+source_removed_cb (GrlPluginRegistry *registry, gpointer user_data)
+{
+ g_debug ("Source '%s' is gone",
+ grl_metadata_source_get_name (GRL_METADATA_SOURCE (user_data)));
+
+ /* Usually you would inform the user that this service is no longer
+ available (for example a UPnP server was shutdown) and remove it
+ from the user interface. */
+}
+
+static void
+load_plugins (void)
+{
+ GrlPluginRegistry *registry;
+ GError *error = NULL;
+
+ registry = grl_plugin_registry_get_default ();
+
+ /* These callback will be invoked when media providers
+ are loaded/unloaded */
+ g_signal_connect (registry, "source-added",
+ G_CALLBACK (source_added_cb), NULL);
+ g_signal_connect (registry, "source-removed",
+ G_CALLBACK (source_removed_cb), NULL);
+
+ /* Command the registry to load all available plugins.
+ The registry will look for plugins in the default
+ plugin path and directories specified using the
+ GRL_PLUGIN_PATH environment variable */
+ if (!grl_plugin_registry_load_all (registry, &error)) {
+ g_error ("Failed to load plugins: %s", error->message);
+ }
+}
+
+gint
+main (int argc, gchar *argv[])
+{
+ GMainLoop *loop;
+
+ grl_init (&argc, &argv);
+ GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
+ load_plugins (); /* Load Grilo plugins */
+
+ /* Run the main loop */
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+
+ return 0;
+}
diff --git a/examples/multivalues.c b/examples/multivalues.c
new file mode 100644
index 0000000..ed5e17c
--- /dev/null
+++ b/examples/multivalues.c
@@ -0,0 +1,123 @@
+
+/*
+ * Handling multivalued elements in Grilo.
+ * Search all 'rock' content in Youtube, and for each one prints the available
+ * URLs.
+ */
+
+#include <grilo.h>
+#include <string.h>
+
+#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
+GRL_LOG_DOMAIN_STATIC(example_log_domain);
+
+static void
+search_cb (GrlMediaSource *source,
+ guint browse_id,
+ GrlMedia *media,
+ guint remaining,
+ gpointer user_data,
+ const GError *error)
+{
+ guint i;
+ GrlRelatedKeys *url_info;
+
+ if (error) {
+ g_error ("Search operation failed. Reason: %s", error->message);
+ }
+
+ if (media) {
+ /* Look through all available URLs for this video resource */
+ for (i = 0; i < grl_data_length (GRL_DATA (media), GRL_METADATA_KEY_URL); i++) {
+ /* Here we use the low-level GrlRelatedKeys API for demonstration purposes only,
+ but we could have just used the more convenient
+ grl_media_video_get_url_data_nth() API instead in this case */
+ url_info = grl_data_get_related_keys (GRL_DATA (media), GRL_METADATA_KEY_URL, i);
+ g_debug ("\t [%s] Got url '%s' and mime-type '%s'",
+ grl_media_get_id (media),
+ grl_related_keys_get_string (url_info, GRL_METADATA_KEY_URL),
+ grl_related_keys_get_string (url_info, GRL_METADATA_KEY_MIME));
+ }
+ }
+
+ if (remaining == 0) {
+ g_debug ("Search operation finished!");
+ }
+
+ g_object_unref (media);
+}
+
+static void
+source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
+{
+ const gchar *id;
+ GrlMetadataSource *source = GRL_METADATA_SOURCE (user_data);
+ GList * keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
+ GRL_METADATA_KEY_URL,
+ GRL_METADATA_KEY_MIME,
+ NULL);
+
+ /* Not interested if not searchable */
+ if (!(grl_metadata_source_supported_operations (source) & GRL_OP_SEARCH))
+ return;
+
+ g_debug ("Detected new searchable source available: '%s'",
+ grl_metadata_source_get_name (source));
+
+ /* Only interested in Youtube */
+ id = grl_metadata_source_get_id (source);
+ if (strcmp (id, "grl-youtube"))
+ return;
+
+ g_debug ("Searching \"rock\" in Youtube");
+ grl_media_source_search (GRL_MEDIA_SOURCE (source),
+ "rock",
+ keys,
+ 0, 5,
+ GRL_RESOLVE_IDLE_RELAY,
+ search_cb,
+ NULL);
+
+ g_list_free (keys);
+}
+
+static void
+load_plugins (void)
+{
+ GrlPluginRegistry *registry;
+ GError *error = NULL;
+
+ registry = grl_plugin_registry_get_default ();
+ g_signal_connect (registry, "source-added",
+ G_CALLBACK (source_added_cb), NULL);
+ if (!grl_plugin_registry_load_all (registry, &error)) {
+ g_error ("Failed to load plugins: %s", error->message);
+ }
+}
+
+static void
+configure_plugins (void)
+{
+ GrlConfig *config;
+ GrlPluginRegistry *registry;
+
+ config = grl_config_new ("grl-youtube", NULL);
+ grl_config_set_api_key (config,
+ "AI39si4EfscPllSfUy1IwexMf__kntTL_G5dfSr2iUEVN45RHG"
+ "q92Aq0lX25OlnOkG6KTN-4soVAkAf67fWYXuHfVADZYr7S1A");
+ registry = grl_plugin_registry_get_default ();
+ grl_plugin_registry_add_config (registry, config, NULL);
+}
+
+gint
+main (int argc, gchar *argv[])
+{
+ GMainLoop *loop;
+ grl_init (&argc, &argv);
+ GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
+ configure_plugins ();
+ load_plugins ();
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+ return 0;
+}
diff --git a/examples/searching.c b/examples/searching.c
new file mode 100644
index 0000000..c9804ee
--- /dev/null
+++ b/examples/searching.c
@@ -0,0 +1,105 @@
+
+/*
+ * Searching in Grilo.
+ * Search all media in Jamendo with the word 'rock'.
+ */
+
+#include <grilo.h>
+#include <string.h>
+
+#define GRL_LOG_DOMAIN_DEFAULT example_log_domain
+GRL_LOG_DOMAIN_STATIC(example_log_domain);
+
+static void
+search_cb (GrlMediaSource *source,
+ guint browse_id,
+ GrlMedia *media,
+ guint remaining,
+ gpointer user_data,
+ const GError *error)
+{
+ if (error) {
+ g_error ("Search operation failed. Reason: %s", error->message);
+ }
+
+ if (media) {
+ const gchar *title = grl_media_get_title (media);
+ if (GRL_IS_MEDIA_BOX (media)) {
+ guint childcount = grl_media_box_get_childcount (GRL_MEDIA_BOX (media));
+ g_debug ("\t Got '%s' (container with %d elements)", title, childcount);
+ } else {
+ guint seconds = grl_media_get_duration (media);
+ const gchar *url = grl_media_get_url (media);
+ g_debug ("\t Got '%s' (media - length: %d seconds)", title, seconds);
+ g_debug ("\t\t URL: %s", url);
+ }
+ }
+
+ if (remaining == 0) {
+ g_debug ("Search operation finished!");
+ } else {
+ g_debug ("\t%d results remaining!", remaining);
+ }
+
+ g_object_unref (media);
+}
+
+static void
+source_added_cb (GrlPluginRegistry *registry, gpointer user_data)
+{
+ const gchar *id;
+ GrlMetadataSource *source = GRL_METADATA_SOURCE (user_data);
+ GList * keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
+ GRL_METADATA_KEY_DURATION,
+ GRL_METADATA_KEY_CHILDCOUNT,
+ NULL);
+
+ /* Not interested if not searchable */
+ if (!(grl_metadata_source_supported_operations (source) & GRL_OP_SEARCH))
+ return;
+
+ g_debug ("Detected new searchable source available: '%s'",
+ grl_metadata_source_get_name (source));
+
+ /* Only interested in Jamendo */
+ id = grl_metadata_source_get_id (source);
+ if (strcmp (id, "grl-jamendo"))
+ return;
+
+ g_debug ("Searching \"rock\" in Jamendo");
+ grl_media_source_search (GRL_MEDIA_SOURCE (source),
+ "rock",
+ keys,
+ 0, 5,
+ GRL_RESOLVE_IDLE_RELAY,
+ search_cb,
+ NULL);
+
+ g_list_free (keys);
+}
+
+static void
+load_plugins (void)
+{
+ GrlPluginRegistry *registry;
+ GError *error = NULL;
+
+ registry = grl_plugin_registry_get_default ();
+ g_signal_connect (registry, "source-added",
+ G_CALLBACK (source_added_cb), NULL);
+ if (!grl_plugin_registry_load_all (registry, &error)) {
+ g_error ("Failed to load plugins: %s", error->message);
+ }
+}
+
+gint
+main (int argc, gchar *argv[])
+{
+ GMainLoop *loop;
+ grl_init (&argc, &argv);
+ GRL_LOG_DOMAIN_INIT (example_log_domain, "example");
+ load_plugins ();
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+ return 0;
+}