Movie Info Provider: Added suport for WATC
authorSimón Pena <spenap@gmail.com>
Mon, 17 May 2010 13:50:57 +0000 (15:50 +0200)
committerSimón Pena <spenap@gmail.com>
Mon, 17 May 2010 14:17:28 +0000 (16:17 +0200)
The Movie Info Provider gets updated so that it takes into account
queries to the WATC service.

A MvsService enum is added, letting choose between both services.

Support for json parsing is added both to the provider and the project,
so that we can extract the information sent from the service.

configure.ac
src/mvs-minfo-provider.c
src/mvs-minfo-provider.h

index 45fba89..03317c8 100644 (file)
@@ -15,7 +15,8 @@ AC_PROG_LIBTOOL
 
 AC_HEADER_STDC
 
-PKG_CHECK_MODULES([DEPS],  [glib-2.0 gobject-2.0 rest-0.6 >= 0.6])
+PKG_CHECK_MODULES([DEPS],  [glib-2.0 gobject-2.0 libsoup-2.4 \
+       libxml-2.0 json-glib-1.0 rest-0.6 >= 0.6])
 
 AC_CONFIG_FILES([
        Makefile
index f98f47b..d51149c 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <libxml/parser.h>
 #include <libxml/xpath.h>
+#include <json-glib/json-glib.h>
 
 #include "mvs-tmdb-movie.h"
 
 #define TMDB_BASE_URL "http://api.themoviedb.org/2.1/%s/%s/%s/%s/%s"
 #define TMDB_MOVIE_XPATH "/OpenSearchDescription/movies/movie"
 
+#define WATC_BASE_URL "http://whatsafterthecredits.com/api.php?action=%s&format=%s&search=%s"
+#define WATC_ACTION "opensearch"
+#define WATC_FORMAT "json"
+
 G_DEFINE_TYPE (MvsMInfoProvider, mvs_minfo_provider, G_TYPE_OBJECT)
 
 enum {
@@ -42,6 +47,7 @@ enum {
 
 struct _MvsMInfoProviderPrivate {
         gchar *format;
+        MvsService service;
 };
 
 enum {
@@ -127,6 +133,7 @@ mvs_minfo_provider_init (MvsMInfoProvider *self)
 {
         self->priv = GET_PRIVATE (self);
         self->priv->format = NULL;
+        self->priv->service = MVS_SERVICE_TMDB;
 }
 
 MvsMInfoProvider*
@@ -136,7 +143,7 @@ mvs_minfo_provider_new (void)
 }
 
 static MvsTmdbMovie*
-generate_movie_info (xmlNodePtr node)
+create_tmdb_movie (xmlNodePtr node)
 {
         xmlNodePtr cur_node = NULL;
         MvsTmdbMovie *movie_info = mvs_tmdb_movie_new ();
@@ -161,7 +168,7 @@ generate_list (xmlNodeSetPtr node_set)
                 xmlNodePtr node = node_set->nodeTab[i];
                 if (node->type == XML_ELEMENT_NODE) {
                         MvsTmdbMovie *movie_info =
-                                        generate_movie_info (node->children);
+                                        create_tmdb_movie (node->children);
                         if (movie_info)
                                 list = g_list_prepend (list, movie_info);
                 }
@@ -201,6 +208,59 @@ parse_xml (const char *xml_data, goffset length)
         return list;
 }
 
+static GList *
+parse_json (const char *json_data, goffset length)
+{
+        JsonParser *parser = NULL;
+        JsonNode *root = NULL;
+        GError *error = NULL;
+        GList *list = NULL;
+
+        parser = json_parser_new ();
+
+        json_parser_load_from_data (parser, json_data, length, &error);
+        if (error)
+        {
+                g_warning ("Unable to parse data '%s': %s\n",
+                                json_data, error->message);
+                g_error_free (error);
+                g_object_unref (parser);
+                return list;
+        }
+
+        /* Don't free */
+        root = json_parser_get_root (parser);
+        JsonArray *response = json_node_get_array (root);
+
+        /* The response is expected with the following format:
+         * [ SEARCH_TERM ,[ SEARCH_RESULT_1, SEARCH_RESULT_N]] */
+
+        if (json_array_get_length (response) != 2) {
+
+                g_warning ("Wrong response format: %s\n", json_data);
+
+                g_object_unref (parser);
+                return list;
+        }
+
+        const gchar *search_term = json_array_get_string_element (response, 0);
+        g_message ("Searched for: %s\n", search_term);
+
+        JsonArray *results = json_array_get_array_element (response, 1);
+        int i;
+        int array_length = json_array_get_length (results);
+
+        for (i = 0; i < array_length; i++) {
+                const gchar *result =
+                                json_array_get_string_element (results, i);
+                g_message ("Result %d: %s\n", i, result);
+        }
+
+        g_object_unref (parser);
+
+        return list;
+}
+
 static void
 process_response (SoupSession *session, SoupMessage *message,
                     gpointer user_data)
@@ -218,9 +278,14 @@ process_response (SoupSession *session, SoupMessage *message,
 
                 mime = soup_message_headers_get_content_type
                                 (message->response_headers, NULL);
-
-                list = parse_xml (message->response_body->data,
-                                message->response_body->length);
+                g_message ("Mime type: %s\n", mime);
+
+                if (g_strcmp0 (mime, "text/xml") == 0)
+                        list = parse_xml (message->response_body->data,
+                                        message->response_body->length);
+                else if (g_strcmp0 (mime, "application/json") == 0)
+                        list = parse_json (message->response_body->data,
+                                        message->response_body->length);
         }
 
         g_signal_emit (self, signals[RESPONSE_RECEIVED], 0, list);
@@ -229,22 +294,39 @@ process_response (SoupSession *session, SoupMessage *message,
 static gchar *
 get_query_uri (MvsMInfoProvider *self, const char *query)
 {
-        /* METHOD/LANGUAGE/FORMAT/APIKEY/MOVIENAME */
-        gchar *uri = g_strdup_printf (TMDB_BASE_URL, TMDB_METHOD,
-                        TMDB_LANGUAGE,
-                        self->priv->format,
-                        TMDB_API_KEY,
-                        query);
+        gchar *uri = NULL;
+
+        if (self->priv->service == MVS_SERVICE_TMDB) {
+                /* METHOD/LANGUAGE/FORMAT/APIKEY/MOVIENAME */
+                uri = g_strdup_printf (TMDB_BASE_URL, TMDB_METHOD,
+                                TMDB_LANGUAGE,
+                                self->priv->format,
+                                TMDB_API_KEY,
+                                query);
+
+        }
+        else if (self->priv->service == MVS_SERVICE_WATC) {
+                /* WATCBASE_URL/ACTION/FORMAT/QUERY */
+                uri = g_strdup_printf (WATC_BASE_URL,
+                                WATC_ACTION,
+                                WATC_FORMAT,
+                                query);
+        }
+        else {
+                g_warning ("Service unsupported\n");
+        }
 
         return uri;
 }
 
 gboolean
-mvs_minfo_provider_query (MvsMInfoProvider *self,
+mvs_minfo_provider_query (MvsMInfoProvider *self, MvsService service,
                           const gchar *query)
 {
         g_return_val_if_fail (MVS_IS_MINFO_PROVIDER (self), FALSE);
 
+        self->priv->service = service;
+
         SoupSession *session = NULL;
         SoupMessage *message = NULL;
         gboolean message_queued = FALSE;
index 896c0f2..921990c 100644 (file)
 
 G_BEGIN_DECLS
 
+typedef enum {
+        MVS_SERVICE_TMDB,
+        MVS_SERVICE_WATC
+} MvsService;
+
 #define MVS_TYPE_MINFO_PROVIDER mvs_minfo_provider_get_type()
 #define MVS_MINFO_PROVIDER(obj) \
   (G_TYPE_CHECK_INSTANCE_CAST ((obj), MVS_TYPE_MINFO_PROVIDER, MvsMInfoProvider))
@@ -53,9 +58,11 @@ typedef struct {
 } MvsMInfoProviderClass;
 
 GType mvs_minfo_provider_get_type (void);
+
 MvsMInfoProvider* mvs_minfo_provider_new (void);
 
 gboolean mvs_minfo_provider_query (MvsMInfoProvider *self,
+                                   MvsService service,
                                    const gchar *query);
 
 gboolean mvs_minfo_provider_set_format (MvsMInfoProvider *self,