1 /******************************************************************************/
3 /* GPL license, Copyright (c) 2005-2006 by: */
6 /* Michael Dominic K. <michaldominik@gmail.com> */
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 */
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. */
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. */
22 /******************************************************************************/
24 #include "nflick-set-list-worker.h"
25 #include "nflick-set-list-worker-private.h"
27 GType nflick_set_list_worker_get_type (void)
29 static GType objecttype = 0;
33 static const GTypeInfo objectinfo = {
34 sizeof (NFlickSetListWorkerClass),
37 (GClassInitFunc) nflick_set_list_worker_class_init,
40 sizeof (NFlickSetListWorker),
42 (GInstanceInitFunc) nflick_set_list_worker_init,
44 objecttype = g_type_register_static (NFLICK_TYPE_WORKER, "NFlickSetListWorker",
50 static void nflick_set_list_worker_class_init (NFlickSetListWorkerClass *klass)
52 GObjectClass *gobjectclass = (GObjectClass *) klass;
53 NFlickWorkerClass *workerclass = (NFlickWorkerClass *) klass;
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;
59 workerclass->ThreadFunc = (NFlickWorkerThreadFunc) thread_func;
61 ParentClass = g_type_class_ref (NFLICK_TYPE_WORKER);
64 static void nflick_set_list_worker_init (NFlickSetListWorker *self)
66 g_return_if_fail (NFLICK_IS_SET_LIST_WORKER (self));
70 NFlickSetListWorkerPrivate *priv = g_new0 (NFlickSetListWorkerPrivate, 1);
71 g_return_if_fail (priv != NULL);
73 if (private_init (self, priv) == TRUE) {
75 nflick_worker_set_message ((NFlickWorker *) self, gettext ("Parsing photosets..."));
77 private_dispose (priv);
83 static gboolean private_init (NFlickSetListWorker *self, NFlickSetListWorkerPrivate *priv)
85 g_return_val_if_fail (NFLICK_IS_SET_LIST_WORKER (self), FALSE);
86 g_return_val_if_fail (priv != NULL, FALSE);
88 priv->UserNsid = NULL;
94 static void private_dispose (NFlickSetListWorkerPrivate *priv)
96 g_return_if_fail (priv != NULL);
98 if (priv->Token != NULL) {
103 if (priv->UserNsid != NULL) {
104 g_free (priv->UserNsid);
105 priv->UserNsid = NULL;
108 if (priv->PhotoSets != NULL) {
112 for (iterator = priv->PhotoSets; iterator; iterator = g_list_next (iterator))
113 if (iterator->data != NULL)
114 g_object_unref (iterator->data);
116 g_list_free (priv->PhotoSets);
117 priv->PhotoSets = NULL;
121 static void nflick_set_list_worker_dispose (NFlickSetListWorker *self)
123 g_return_if_fail (NFLICK_IS_SET_LIST_WORKER (self));
125 if (self->Private != NULL)
126 private_dispose (self->Private);
128 G_OBJECT_CLASS (ParentClass)->dispose (G_OBJECT (self));
131 static void nflick_set_list_worker_finalize (NFlickSetListWorker *self)
133 g_return_if_fail (NFLICK_IS_SET_LIST_WORKER (self));
135 if (self->Private != NULL) {
136 g_free (self->Private);
137 self->Private = NULL;
140 G_OBJECT_CLASS (ParentClass)->finalize (G_OBJECT (self));
143 static NFlickWorkerStatus thread_func (NFlickSetListWorker *self)
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 */
158 get_photosets_request = nflick_api_request_new (NFLICK_FLICKR_API_METHOD_PHOTOSETS_GET_LIST);
159 if (get_photosets_request == NULL)
162 nflick_api_request_add_parameter (get_photosets_request,
163 NFLICK_FLICKR_API_PARAM_TOKEN,
164 self->Private->Token);
166 nflick_api_request_add_parameter (get_photosets_request,
167 NFLICK_FLICKR_API_PARAM_USER_ID,
168 self->Private->UserNsid);
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);
176 if (nflick_worker_is_aborted ((NFlickWorker *) self) == TRUE)
179 set_list_response = nflick_api_response_new_from_request (NFLICK_TYPE_SET_LIST_RESPONSE, get_photosets_request);
180 if (set_list_response == NULL)
183 if (nflick_worker_parse_api_response ((NFlickWorker*) self, set_list_response) == FALSE)
186 self->Private->PhotoSets = nflick_set_list_response_take_list ((NFlickSetListResponse *) set_list_response);
188 /* Let's fetch information about the unsetted photos */
189 nflick_worker_set_message ((NFlickWorker *) self, gettext ("Parsing photos without set..."));
191 unsetted_request = nflick_api_request_new (NFLICK_FLICKR_API_METHOD_PHOTOS_NOT_IN_SET);
192 if (unsetted_request == NULL)
195 nflick_api_request_add_parameter (unsetted_request,
196 NFLICK_FLICKR_API_PARAM_TOKEN,
197 self->Private->Token);
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
203 nflick_api_request_add_parameter (unsetted_request,
204 NFLICK_FLICKR_API_PARAM_PER_PAGE,
207 nflick_api_request_sign (unsetted_request);
208 if (nflick_api_request_exec (unsetted_request) != TRUE) {
209 nflick_worker_set_network_error ((NFlickWorker *) self);
213 if (nflick_worker_is_aborted ((NFlickWorker *) self) == TRUE)
216 unsetted_response = nflick_api_response_new_from_request (NFLICK_TYPE_NO_SET_RESPONSE, unsetted_request);
217 if (unsetted_response == NULL)
220 if (nflick_worker_parse_api_response ((NFlickWorker*) self, unsetted_response) == FALSE)
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);
228 /* Append the set to our set list... */
229 self->Private->PhotoSets = g_list_append (self->Private->PhotoSets,
232 /* If the user has not sets, finish now */
233 if (self->Private->PhotoSets->data == (gpointer) unsetted_set) {
236 /* Now let's try fetching the photos for first photo set */
237 nflick_worker_set_message ((NFlickWorker *) self, gettext ("Loading photoset data..."));
239 GList *sets = self->Private->PhotoSets;
241 gint i = g_list_length (sets);
243 for (set = sets; set != NULL; set = set->next) {
244 first_set = (NFlickPhotoSet*)set->data;
246 g_object_get (G_OBJECT (first_set), "id", &first_id, NULL);
248 first_photolist_request = nflick_api_request_new
249 (NFLICK_FLICKR_API_METHOD_PHOTOSETS_GET_PHOTOS);
250 if (first_photolist_request == NULL)
253 nflick_api_request_add_parameter (first_photolist_request,
254 NFLICK_FLICKR_API_PARAM_TOKEN,
255 self->Private->Token);
257 nflick_api_request_add_parameter (first_photolist_request,
258 NFLICK_FLICKR_API_PARAM_PHOTOSET_ID,
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);
267 if (nflick_worker_is_aborted ((NFlickWorker *) self) == TRUE)
268 g_warning ("Abort : %s", first_id);
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);
275 if (nflick_worker_parse_api_response ((NFlickWorker*) self,
276 first_photo_list_response) == FALSE)
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);
288 status = NFLICK_WORKER_STATUS_ABORTED;
293 status = NFLICK_WORKER_STATUS_ERROR;
296 if (get_photosets_request != NULL)
297 g_object_unref (get_photosets_request);
299 if (set_list_response != NULL)
300 g_object_unref (set_list_response);
302 if (first_photolist_request != NULL)
303 g_object_unref (first_photolist_request);
305 if (unsetted_response != NULL)
306 g_object_unref (unsetted_response);
308 if (unsetted_request != NULL)
309 g_object_unref (unsetted_request);
311 if (first_photo_list_response != NULL)
312 g_object_unref (first_photo_list_response);
314 if (first_id != NULL)
320 NFlickSetListWorker* nflick_set_list_worker_new (const gchar *usernsid, const gchar *token)
322 g_return_val_if_fail (token != NULL, NULL);
323 g_return_val_if_fail (usernsid != NULL, NULL);
325 NFlickSetListWorker *self = g_object_new (NFLICK_TYPE_SET_LIST_WORKER, NULL);
326 g_return_val_if_fail (self != NULL, NULL);
328 if (self->Private == NULL) {
329 g_object_unref (self);
333 self->Private->Token = g_strdup (token);
334 self->Private->UserNsid = g_strdup (usernsid);
335 self->Private->PhotoSets = NULL;
340 GList* nflick_set_list_worker_take_list (NFlickSetListWorker *self)
342 g_return_val_if_fail (NFLICK_IS_SET_LIST_WORKER (self), NULL);
344 GList *lst = self->Private->PhotoSets;
345 self->Private->PhotoSets = NULL;
350 static void nflick_set_list_worker_get_property (NFlickSetListWorker *self, guint propid,
351 GValue *value, GParamSpec *pspec)
353 g_return_if_fail (NFLICK_IS_SET_LIST_WORKER (self));
354 g_assert (self->Private != NULL);
359 G_OBJECT_WARN_INVALID_PROPERTY_ID (G_OBJECT (self), propid, pspec);