Initial Import
[profile/ivi/clutter-toys.git] / attic / fluttr / libnflick / nflick-set-list-worker.c
1 /******************************************************************************/
2 /*                                                                            */
3 /* GPL license, Copyright (c) 2005-2006 by:                                   */
4 /*                                                                            */
5 /* Authors:                                                                   */
6 /*      Michael Dominic K. <michaldominik@gmail.com>                          */
7 /*                                                                            */
8 /* This program is free software; you can redistribute it and/or modify it    */
9 /* under the terms of the GNU General Public License as published by the      */
10 /* Free Software Foundation; either version 2, or (at your option) any later  */
11 /* version.                                                                   */
12 /*                                                                            */
13 /* This program is distributed in the hope that it will be useful, but        */
14 /* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY */
15 /* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License   */
16 /* for more details.                                                          */
17 /*                                                                            */
18 /* You should have received a copy of the GNU General Public License along    */
19 /* with this program; if not, write to the Free Software Foundation, Inc., 59 */
20 /* Temple Place - Suite 330, Boston, MA 02111-1307, USA.                      */
21 /*                                                                            */
22 /******************************************************************************/
23
24 #include "nflick-set-list-worker.h"
25 #include "nflick-set-list-worker-private.h"
26
27 GType                           nflick_set_list_worker_get_type (void)
28 {
29         static GType objecttype = 0;
30
31         if (!objecttype) {
32
33                 static const GTypeInfo objectinfo = {
34                         sizeof (NFlickSetListWorkerClass), 
35                         NULL, 
36                         NULL,
37                         (GClassInitFunc) nflick_set_list_worker_class_init,
38                         NULL,
39                         NULL, 
40                         sizeof (NFlickSetListWorker), 
41                         4, 
42                         (GInstanceInitFunc) nflick_set_list_worker_init,
43                 };
44                 objecttype = g_type_register_static (NFLICK_TYPE_WORKER, "NFlickSetListWorker",
45                                                      &objectinfo, 0);
46         }
47         return objecttype;
48 }
49
50 static void                     nflick_set_list_worker_class_init (NFlickSetListWorkerClass *klass)
51 {
52         GObjectClass *gobjectclass = (GObjectClass *) klass;
53         NFlickWorkerClass *workerclass = (NFlickWorkerClass *) klass;
54
55         gobjectclass->dispose = (gpointer) nflick_set_list_worker_dispose;
56         gobjectclass->finalize = (gpointer) nflick_set_list_worker_finalize;
57         gobjectclass->get_property = (gpointer) nflick_set_list_worker_get_property;
58         
59         workerclass->ThreadFunc = (NFlickWorkerThreadFunc) thread_func;
60
61         ParentClass = g_type_class_ref (NFLICK_TYPE_WORKER);
62 }
63
64 static void                     nflick_set_list_worker_init (NFlickSetListWorker *self)
65 {
66         g_return_if_fail (NFLICK_IS_SET_LIST_WORKER (self));
67
68         self->Private = NULL;
69
70         NFlickSetListWorkerPrivate *priv = g_new0 (NFlickSetListWorkerPrivate, 1);
71         g_return_if_fail (priv != NULL);
72         
73         if (private_init (self, priv) == TRUE) {
74                 self->Private = priv;
75                 nflick_worker_set_message ((NFlickWorker *) self, gettext ("Parsing photosets..."));
76         } else {
77                 private_dispose (priv);
78                 g_free (priv);
79                 self->Private = NULL;
80         }
81 }
82
83 static gboolean                 private_init (NFlickSetListWorker *self, NFlickSetListWorkerPrivate *priv)
84 {
85         g_return_val_if_fail (NFLICK_IS_SET_LIST_WORKER (self), FALSE);
86         g_return_val_if_fail (priv != NULL, FALSE);
87
88         priv->UserNsid = NULL;
89         priv->Token = NULL;
90
91         return TRUE;
92 }
93
94 static void                     private_dispose (NFlickSetListWorkerPrivate *priv)
95 {
96         g_return_if_fail (priv != NULL);
97
98         if (priv->Token != NULL) {
99                 g_free (priv->Token);
100                 priv->Token = NULL;
101         }
102
103         if (priv->UserNsid != NULL) {
104                 g_free (priv->UserNsid);
105                 priv->UserNsid = NULL;
106         }
107
108         if (priv->PhotoSets != NULL) {
109
110                 GList *iterator;
111         
112                 for (iterator = priv->PhotoSets; iterator; iterator = g_list_next (iterator))
113                         if (iterator->data != NULL)
114                                 g_object_unref (iterator->data);
115                 
116                 g_list_free (priv->PhotoSets);
117                 priv->PhotoSets = NULL;
118         }
119 }
120
121 static void                     nflick_set_list_worker_dispose (NFlickSetListWorker *self)
122 {
123         g_return_if_fail (NFLICK_IS_SET_LIST_WORKER (self));
124
125         if (self->Private != NULL)
126                 private_dispose (self->Private);
127
128         G_OBJECT_CLASS (ParentClass)->dispose (G_OBJECT (self));
129 }
130
131 static void                     nflick_set_list_worker_finalize (NFlickSetListWorker *self)
132 {
133         g_return_if_fail (NFLICK_IS_SET_LIST_WORKER (self));
134         
135         if (self->Private != NULL) {
136                 g_free (self->Private);
137                 self->Private = NULL;
138         }
139
140         G_OBJECT_CLASS (ParentClass)->finalize (G_OBJECT (self));
141 }
142
143 static NFlickWorkerStatus       thread_func (NFlickSetListWorker *self)
144 {
145         NFlickApiRequest *get_photosets_request = NULL; 
146         NFlickWorkerStatus status = NFLICK_WORKER_STATUS_OK;
147         NFlickApiResponse *set_list_response = NULL;
148         gchar *first_id = NULL;
149         NFlickPhotoSet *first_set = NULL; /* Do not dispose, it's not reffed */
150         NFlickApiRequest *first_photolist_request = NULL; 
151         NFlickApiResponse *first_photo_list_response = NULL;
152         GList *first_list = NULL;
153         NFlickApiRequest *unsetted_request = NULL; 
154         NFlickApiResponse *unsetted_response = NULL;
155         GList *unsetted_list = NULL;
156         NFlickPhotoSet *unsetted_set = NULL; /* Do not dispose, it's not reffed */
157
158         get_photosets_request = nflick_api_request_new (NFLICK_FLICKR_API_METHOD_PHOTOSETS_GET_LIST);
159         if (get_photosets_request == NULL)
160                 goto Error;
161         
162         nflick_api_request_add_parameter (get_photosets_request, 
163                                           NFLICK_FLICKR_API_PARAM_TOKEN, 
164                                           self->Private->Token);
165
166         nflick_api_request_add_parameter (get_photosets_request, 
167                                           NFLICK_FLICKR_API_PARAM_USER_ID, 
168                                           self->Private->UserNsid);
169
170         nflick_api_request_sign (get_photosets_request);
171         if (nflick_api_request_exec (get_photosets_request) != TRUE) {
172                 nflick_worker_set_network_error ((NFlickWorker *) self);
173                 goto Error;
174         }
175
176         if (nflick_worker_is_aborted ((NFlickWorker *) self) == TRUE)
177                 goto Abort;
178
179         set_list_response = nflick_api_response_new_from_request (NFLICK_TYPE_SET_LIST_RESPONSE, get_photosets_request);
180         if (set_list_response == NULL)
181                 goto Error;
182
183         if (nflick_worker_parse_api_response ((NFlickWorker*) self, set_list_response) == FALSE)
184                 goto Error;
185
186         self->Private->PhotoSets = nflick_set_list_response_take_list ((NFlickSetListResponse *) set_list_response);
187
188         /* Let's fetch information about the unsetted photos */
189         nflick_worker_set_message ((NFlickWorker *) self, gettext ("Parsing photos without set..."));
190
191         unsetted_request = nflick_api_request_new (NFLICK_FLICKR_API_METHOD_PHOTOS_NOT_IN_SET);
192         if (unsetted_request == NULL)
193                 goto Error;
194         
195         nflick_api_request_add_parameter (unsetted_request, 
196                                           NFLICK_FLICKR_API_PARAM_TOKEN, 
197                                           self->Private->Token);
198
199         /* We try to get 500 photos per page. 500 is a maximum value. 
200          * FIXME: We should check if 500 is enough. Someone might have more than 
201          * 500 photos */
202
203         nflick_api_request_add_parameter (unsetted_request, 
204                                           NFLICK_FLICKR_API_PARAM_PER_PAGE,
205                                           "500");
206
207         nflick_api_request_sign (unsetted_request);
208         if (nflick_api_request_exec (unsetted_request) != TRUE) {
209                 nflick_worker_set_network_error ((NFlickWorker *) self);
210                 goto Error;
211         }
212
213         if (nflick_worker_is_aborted ((NFlickWorker *) self) == TRUE)
214                 goto Abort;
215
216         unsetted_response = nflick_api_response_new_from_request (NFLICK_TYPE_NO_SET_RESPONSE, unsetted_request);
217         if (unsetted_response == NULL)
218                 goto Error;
219
220         if (nflick_worker_parse_api_response ((NFlickWorker*) self, unsetted_response) == FALSE)
221                 goto Error;
222
223         unsetted_list = nflick_no_set_response_take_list ((NFlickNoSetResponse *) unsetted_response);
224         /* FIXME: Here we could expose the "count" property on the PhotoSetResponse and NoSetResponse */
225         unsetted_set = nflick_photo_set_new_no_set (g_list_length (unsetted_list)); 
226         nflick_photo_set_give_list (unsetted_set, unsetted_list);
227
228         /* Append the set to our set list... */
229         self->Private->PhotoSets = g_list_append (self->Private->PhotoSets, 
230                                                    unsetted_set);
231
232         /* If the user has not sets, finish now */
233         if (self->Private->PhotoSets->data == (gpointer) unsetted_set) {
234                 goto Done;
235         }
236         /* Now let's try fetching the photos for first photo set */
237         nflick_worker_set_message ((NFlickWorker *) self, gettext ("Loading photoset data..."));
238         
239         GList *sets = self->Private->PhotoSets;
240         GList *set;
241         gint i = g_list_length (sets);
242         
243         for (set = sets; set != NULL; set = set->next) {
244                 first_set = (NFlickPhotoSet*)set->data;
245         
246                 g_object_get (G_OBJECT (first_set), "id", &first_id, NULL);
247
248                 first_photolist_request = nflick_api_request_new
249                                  (NFLICK_FLICKR_API_METHOD_PHOTOSETS_GET_PHOTOS);
250                 if (first_photolist_request == NULL)
251                         goto Error;
252         
253                 nflick_api_request_add_parameter (first_photolist_request, 
254                                           NFLICK_FLICKR_API_PARAM_TOKEN, 
255                                           self->Private->Token);
256
257                 nflick_api_request_add_parameter (first_photolist_request, 
258                                           NFLICK_FLICKR_API_PARAM_PHOTOSET_ID, 
259                                           first_id);
260
261                 nflick_api_request_sign (first_photolist_request);
262                 if (nflick_api_request_exec (first_photolist_request) != TRUE) {
263                         nflick_worker_set_network_error ((NFlickWorker *) self);
264                         g_warning ("Error : %s", first_id);
265                 }
266
267                 if (nflick_worker_is_aborted ((NFlickWorker *) self) == TRUE)
268                         g_warning ("Abort : %s", first_id);
269
270                 first_photo_list_response = nflick_api_response_new_from_request 
271                      (NFLICK_TYPE_PHOTO_LIST_RESPONSE, first_photolist_request);
272                 if (first_photo_list_response == NULL)
273                         g_warning ("No photos : %s", first_id);
274
275                 if (nflick_worker_parse_api_response ((NFlickWorker*) self, 
276                                         first_photo_list_response) == FALSE)
277                         ;
278
279                 first_list = nflick_photo_list_response_take_list
280                         ((NFlickPhotoListResponse *) first_photo_list_response);
281                 nflick_photo_set_give_list (first_set, first_list);
282         }
283
284         /* All ok */
285         goto Done;
286
287 Abort:
288         status = NFLICK_WORKER_STATUS_ABORTED;
289         g_print ("Abort\n");
290         goto Done;
291
292 Error:
293         status = NFLICK_WORKER_STATUS_ERROR;
294         g_print ("Error\n");
295 Done:
296         if (get_photosets_request != NULL) 
297                 g_object_unref (get_photosets_request);
298
299         if (set_list_response != NULL) 
300                 g_object_unref (set_list_response);
301
302         if (first_photolist_request != NULL) 
303                 g_object_unref (first_photolist_request);
304
305         if (unsetted_response != NULL) 
306                 g_object_unref (unsetted_response);
307
308         if (unsetted_request != NULL) 
309                 g_object_unref (unsetted_request);
310
311         if (first_photo_list_response != NULL) 
312                 g_object_unref (first_photo_list_response);
313
314         if (first_id != NULL)
315                 g_free (first_id);
316
317         return status;
318 }
319
320 NFlickSetListWorker*            nflick_set_list_worker_new (const gchar *usernsid, const gchar *token)
321 {
322         g_return_val_if_fail (token != NULL, NULL);
323         g_return_val_if_fail (usernsid != NULL, NULL);
324
325         NFlickSetListWorker *self = g_object_new (NFLICK_TYPE_SET_LIST_WORKER, NULL);
326         g_return_val_if_fail (self != NULL, NULL);
327
328         if (self->Private == NULL) {
329                 g_object_unref (self);
330                 return NULL;
331         }
332
333         self->Private->Token = g_strdup (token);
334         self->Private->UserNsid = g_strdup (usernsid);
335         self->Private->PhotoSets = NULL;
336
337         return self;
338 }
339
340 GList*                          nflick_set_list_worker_take_list (NFlickSetListWorker *self)
341 {
342         g_return_val_if_fail (NFLICK_IS_SET_LIST_WORKER (self), NULL);
343
344         GList *lst = self->Private->PhotoSets;
345         self->Private->PhotoSets = NULL;
346
347         return lst;
348 }
349
350 static void                     nflick_set_list_worker_get_property (NFlickSetListWorker *self, guint propid, 
351                                                                  GValue *value, GParamSpec *pspec)
352 {
353         g_return_if_fail (NFLICK_IS_SET_LIST_WORKER (self));
354         g_assert (self->Private != NULL);
355                 
356         switch (propid) {
357                 
358                 default:
359                         G_OBJECT_WARN_INVALID_PROPERTY_ID (G_OBJECT (self), propid, pspec);
360                 break;
361         }
362 }