56a3e38eef7d7000ca5e1ff919e38d3e0a2c16da
[maevies] / src / mvs-minfo-provider-service.c
1 /*
2  * mvs-minfo-provider-service.c
3  *
4  * This file is part of maevies
5  * Copyright (C) 2010 Simón Pena <spenap@gmail.com>
6  *
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.
11  *
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.
16  *
17  */
18
19 #include <dbus/dbus-glib-bindings.h>
20
21 #include "mvs-minfo-provider-service.h"
22 #include "mvs-minfo-provider.h"
23 #include "mvs-tmdb-movie-service.h"
24 #include "mvs-tmdb-movie.h"
25 #include "mvs-marshal.h"
26
27 #define MINFO_PROVIDER_SERVICE_OBJECT_PATH "/MInfoProvider"
28 #define MINFO_PROVIDER_SERVICE_NAME "com.simonpena.maevies.minfoprovider"
29 #define TMDB_MOVIE_INTERFACE "com.simonpena.maevies.tmdbmovie"
30
31 G_DEFINE_TYPE (MvsMInfoProviderService, mvs_minfo_provider_service, G_TYPE_OBJECT)
32
33 enum {
34         PROP_0,
35         PROP_DBUSGCONN,
36 };
37
38 enum {
39         RESPONSE_RECEIVED,
40         LAST_SIGNAL
41 };
42
43 static guint
44 mvs_minfo_provider_service_signals[LAST_SIGNAL] = { 0 };
45
46 #define GET_PRIVATE(o) \
47         (G_TYPE_INSTANCE_GET_PRIVATE ((o), MVS_TYPE_MINFO_PROVIDER_SERVICE, MvsMInfoProviderServicePrivate))
48
49 struct _MvsMInfoProviderServicePrivate {
50         MvsMInfoProvider *minfo_provider;
51         DBusGConnection *connection;
52         guint search_id;
53 };
54
55 gboolean
56 mvs_minfo_provider_service_query (MvsMInfoProviderService *self,
57                                   MvsService service,
58                                   const gchar *query,
59                                   GError **error)
60 {
61         return mvs_minfo_provider_query (self->priv->minfo_provider,
62                         service, query);
63 }
64
65 #include "mvs-minfo-provider-service-glue.h"
66
67 static void
68 response_received_cb (MvsMInfoProvider *provider, GList *list,
69                       gpointer user_data)
70 {
71         MvsMInfoProviderService *self = MVS_MINFO_PROVIDER_SERVICE (user_data);
72         MvsTmdbMovieService *movie = NULL;
73         GError *error = NULL;
74         GList *iter = NULL;
75         gchar  **object_paths= g_new0 (gchar*, g_list_length (list) + 1);
76         gchar *movie_interface = g_strdup (TMDB_MOVIE_INTERFACE);
77         guint i = 0;
78
79         for (iter = list; iter; iter = iter->next) {
80                 if (MVS_IS_TMDB_MOVIE (iter->data)) {
81                         MvsTmdbMovie *tmdb_movie = MVS_TMDB_MOVIE (iter->data);
82                         gchar *uid_suffix = g_strdup_printf ("%d_%s",
83                                         self->priv->search_id,
84                                         mvs_tmdb_movie_get_id (tmdb_movie));
85
86                         movie = mvs_tmdb_movie_service_new (self->priv->connection,
87                                         tmdb_movie, uid_suffix);
88                         object_paths[i] = g_strdup_printf ("/TMDBMovie/%s",
89                                         uid_suffix);
90                         g_free (uid_suffix);
91                 }
92                 i++;
93         }
94         object_paths[i] = NULL;
95
96         g_signal_emit (self, mvs_minfo_provider_service_signals[RESPONSE_RECEIVED],
97                        0, movie_interface, object_paths);
98         g_strfreev (object_paths);
99         g_free (movie_interface);
100         self->priv->search_id++;
101 }
102
103 static void
104 setup_dbus (MvsMInfoProviderService *self)
105 {
106         DBusGProxy *proxy;
107         guint request_name_result;
108         GError *error = NULL;
109
110         proxy = dbus_g_proxy_new_for_name (self->priv->connection,
111                                            DBUS_SERVICE_DBUS,
112                                            DBUS_PATH_DBUS,
113                                            DBUS_INTERFACE_DBUS);
114
115         if (!org_freedesktop_DBus_request_name (proxy,
116                                                 MINFO_PROVIDER_SERVICE_NAME,
117                                                 0, &request_name_result,
118                                                 &error)) {
119                 g_warning ("Unable to register service: %s", error->message);
120                 g_error_free (error);
121         }
122
123         dbus_g_connection_register_g_object (self->priv->connection,
124                                              MINFO_PROVIDER_SERVICE_OBJECT_PATH,
125                                              G_OBJECT (self));
126
127         g_object_unref (proxy);
128 }
129
130 static void
131 mvs_minfo_provider_service_set_property (GObject *object, guint property_id,
132                                   const GValue *value, GParamSpec *pspec)
133 {
134         MvsMInfoProviderService *self = MVS_MINFO_PROVIDER_SERVICE (object);
135
136         switch (property_id) {
137         case PROP_DBUSGCONN:
138                 if (!self->priv->connection) {
139                         DBusGConnection *tmp = g_value_get_pointer (value);
140                         if (tmp) {
141                                 self->priv->connection =
142                                         dbus_g_connection_ref (tmp);
143                                 setup_dbus (self);
144                         }
145                 }
146                 g_assert (self->priv->connection);
147                 break;
148         default:
149                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
150         }
151 }
152
153 static void
154 mvs_minfo_provider_service_finalize (GObject *object)
155 {
156         MvsMInfoProviderService *self = MVS_MINFO_PROVIDER_SERVICE (object);
157
158         if (self->priv->connection) {
159                 dbus_g_connection_unref (self->priv->connection);
160         }
161         g_object_unref (self->priv->minfo_provider);
162         G_OBJECT_CLASS (mvs_minfo_provider_service_parent_class)->finalize (object);
163 }
164
165 static void
166 mvs_minfo_provider_service_class_init (MvsMInfoProviderServiceClass *klass)
167 {
168         GObjectClass *object_class = G_OBJECT_CLASS (klass);
169
170         g_type_class_add_private (klass, sizeof (MvsMInfoProviderServicePrivate));
171
172         object_class->set_property = mvs_minfo_provider_service_set_property;
173         object_class->finalize = mvs_minfo_provider_service_finalize;
174
175         g_object_class_install_property
176                 (object_class, PROP_DBUSGCONN,
177                  g_param_spec_pointer ("connection", "DBusGConnection",
178                                        "DBus GConnection",
179                                        G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
180
181          dbus_g_object_type_install_info (MVS_TYPE_MINFO_PROVIDER_SERVICE,
182                                           &dbus_glib_mvs_minfo_provider_service_object_info);
183
184          mvs_minfo_provider_service_signals[RESPONSE_RECEIVED] =
185                          g_signal_new ("response-received",
186                          G_TYPE_FROM_CLASS (klass),
187                          G_SIGNAL_RUN_LAST,
188                          0,
189                          NULL,
190                          NULL,
191                          mvs_marshal_VOID__STRING_POINTER,
192                          G_TYPE_NONE,
193                          2,
194                          G_TYPE_STRING,
195                          G_TYPE_STRV,
196                          NULL);
197 }
198
199 static void
200 mvs_minfo_provider_service_init (MvsMInfoProviderService *self)
201 {
202         self->priv = GET_PRIVATE (self);
203         self->priv->minfo_provider = mvs_minfo_provider_new ();
204         self->priv->connection = NULL;
205         self->priv->search_id = 0;
206
207         g_signal_connect (self->priv->minfo_provider, "response-received",
208                           G_CALLBACK (response_received_cb), self);
209 }
210
211 MvsMInfoProviderService*
212 mvs_minfo_provider_service_new (DBusGConnection *connection)
213 {
214         return g_object_new (MVS_TYPE_MINFO_PROVIDER_SERVICE,
215                              "connection", connection, NULL);
216 }