4 * This file is part of maevies
5 * Copyright (C) 2010 Simón Pena <spenap@gmail.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
19 #include "mvs-minfo-provider.h"
21 #include <libxml/parser.h>
22 #include <libxml/xpath.h>
24 #define TMDB_API_KEY "249e1a42df9bee09fac5e92d3a51396b"
25 #define TMDB_LANGUAGE "en"
26 #define TMDB_FORMAT "xml"
27 #define TMDB_METHOD "Movie.search"
28 #define TMDB_BASE_URL "http://api.themoviedb.org/2.1/%s/%s/%s/%s/%s"
29 #define TMDB_MOVIE_XPATH "/OpenSearchDescription/movies/movie"
31 G_DEFINE_TYPE (MvsMInfoProvider, mvs_minfo_provider, G_TYPE_OBJECT)
38 #define GET_PRIVATE(o) \
39 (G_TYPE_INSTANCE_GET_PRIVATE ((o), MVS_TYPE_MINFO_PROVIDER, MvsMInfoProviderPrivate))
41 struct _MvsMInfoProviderPrivate {
51 signals[LAST_SIGNAL] = { 0 };
55 mvs_minfo_provider_get_property (GObject *object, guint property_id,
56 GValue *value, GParamSpec *pspec)
58 MvsMInfoProvider *self = MVS_MINFO_PROVIDER (object);
60 switch (property_id) {
62 g_value_set_string (value, self->priv->format);
65 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
70 mvs_minfo_provider_set_property (GObject *object, guint property_id,
71 const GValue *value, GParamSpec *pspec)
73 MvsMInfoProvider *self = MVS_MINFO_PROVIDER (object);
75 switch (property_id) {
77 mvs_minfo_provider_set_format (self,
78 g_value_get_string (value));
81 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
86 mvs_minfo_provider_finalize (GObject *object)
88 MvsMInfoProvider *self = MVS_MINFO_PROVIDER (object);
90 g_free (self->priv->format);
92 G_OBJECT_CLASS (mvs_minfo_provider_parent_class)->finalize (object);
96 mvs_minfo_provider_class_init (MvsMInfoProviderClass *klass)
98 GObjectClass *object_class = G_OBJECT_CLASS (klass);
100 g_type_class_add_private (klass, sizeof (MvsMInfoProviderPrivate));
102 object_class->get_property = mvs_minfo_provider_get_property;
103 object_class->set_property = mvs_minfo_provider_set_property;
104 object_class->finalize = mvs_minfo_provider_finalize;
106 g_object_class_install_property
107 (object_class, PROP_FORMAT,
108 g_param_spec_string ("format", "The format", "The format",
110 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
112 signals[RESPONSE_RECEIVED] = g_signal_new ("response-received", MVS_TYPE_MINFO_PROVIDER,
117 g_cclosure_marshal_VOID__VOID,
124 mvs_minfo_provider_init (MvsMInfoProvider *self)
126 self->priv = GET_PRIVATE (self);
127 self->priv->format = NULL;
131 mvs_minfo_provider_new (void)
133 return g_object_new (MVS_TYPE_MINFO_PROVIDER, NULL);
137 display_movie_info (xmlNodePtr node)
139 xmlNodePtr cur_node = NULL;
141 for (cur_node = node; cur_node; cur_node = cur_node->next) {
142 if (cur_node->type == XML_ELEMENT_NODE) {
143 gchar *value = xmlNodeGetContent (cur_node);
144 g_print ("[%s] = %s\n", cur_node->name, value);
150 iterate_list (xmlNodeSetPtr node_set)
154 for (i = 0; i < node_set->nodeNr; i++) {
155 xmlNodePtr node = node_set->nodeTab[i];
156 if (node->type == XML_ELEMENT_NODE) {
157 display_movie_info (node->children);
163 parse_xml (const char *xml_data, goffset length)
165 xmlDocPtr document = xmlReadMemory (xml_data, length,
168 XML_PARSE_NOBLANKS | XML_PARSE_RECOVER);
169 g_return_if_fail (document);
171 xmlXPathContextPtr context_ptr = xmlXPathNewContext (document);
173 xmlXPathObjectPtr xpath_obj =
174 xmlXPathEvalExpression (TMDB_MOVIE_XPATH, context_ptr);
176 xmlNodeSetPtr nodeset = xpath_obj->nodesetval;
178 if (nodeset->nodeNr > 0) {
179 iterate_list (nodeset);
182 xmlXPathFreeNodeSetList (xpath_obj);
183 xmlXPathFreeContext (context_ptr);
184 xmlFreeDoc (document);
188 response_callback (SoupSession *session, SoupMessage *message,
191 MvsMInfoProvider *self = MVS_MINFO_PROVIDER (user_data);
192 const gchar *mime = NULL;
194 if (!SOUP_STATUS_IS_SUCCESSFUL (message->status_code) ||
195 message->response_body->length <= 0) {
197 g_print ("%s\n", message->reason_phrase);
201 mime = soup_message_headers_get_content_type
202 (message->response_headers, NULL);
204 parse_xml (message->response_body->data,
205 message->response_body->length);
208 g_signal_emit (self, signals[RESPONSE_RECEIVED], 0);
212 get_query_uri (MvsMInfoProvider *self, const char *query)
214 /* METHOD/LANGUAGE/FORMAT/APIKEY/MOVIENAME */
215 gchar *uri = g_strdup_printf (TMDB_BASE_URL, TMDB_METHOD,
225 mvs_minfo_provider_query (MvsMInfoProvider *self,
228 g_return_val_if_fail (MVS_IS_MINFO_PROVIDER (self), FALSE);
230 SoupSession *session = NULL;
231 SoupMessage *message = NULL;
232 gboolean message_queued = FALSE;
234 gchar *uri = get_query_uri (self, query);
236 g_return_val_if_fail (uri, FALSE);
238 session = soup_session_async_new ();
239 message = soup_message_new ("GET", uri);
242 soup_session_queue_message (session, message,
243 response_callback, self);
244 message_queued = TRUE;
249 return message_queued;
253 mvs_minfo_provider_set_format (MvsMInfoProvider *self,
256 g_return_val_if_fail (MVS_IS_MINFO_PROVIDER (self), FALSE);
258 g_free (self->priv->format);
260 self->priv->format = g_strdup (format);