2 * Authored By Neil Jagdish Patel <njp@o-hand.com>
4 * Copyright (C) 2007 OpenedHand
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include <libaaina/aaina-photo.h>
23 #include <libnflick/nflick-photo-search-worker.h>
24 #include <libnflick/nflick-info-worker.h>
25 #include <libnflick/nflick.h>
26 #include "aaina-source-flickr.h"
28 G_DEFINE_TYPE (AainaSourceFlickr, aaina_source_flickr, AAINA_TYPE_SOURCE);
30 #define AAINA_SOURCE_FLICKR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
31 AAINA_TYPE_SOURCE_FLICKR, \
32 AainaSourceFlickrPrivate))
34 #define CHECK_TIMEOUT 60000
35 #define MAX_PHOTOS 100
37 struct _AainaSourceFlickrPrivate
39 AainaLibrary *library;
42 /* table of already downloaded photos */
45 /* Queue of photos to download */
48 NFlickWorker *pix_worker;
54 /* Queue of photos to add to library */
59 static GQuark worker_quark = 0;
61 static gboolean get_photos (AainaSourceFlickr *source);
62 static gboolean get_pixbuf (AainaSourceFlickr *source);
66 on_info_thread_abort (AainaPhoto *photo)
73 on_info_thread_error (AainaPhoto *photo)
76 worker = (NFlickWorker*)g_object_get_qdata (G_OBJECT (photo), worker_quark);
79 g_object_get (G_OBJECT (worker), "error", &error, NULL);
82 g_warning ("%s\n", error);
86 g_object_unref (G_OBJECT (worker));
92 on_info_thread_ok (AainaPhoto *photo)
95 gchar *rotation = NULL;
97 gchar *realname = NULL;
100 worker = (NFlickWorker*)g_object_get_qdata (G_OBJECT (photo), worker_quark);
102 nflick_info_worker_get ((NFlickInfoWorker*)worker,
106 /* find the rotation */
107 rot = atoi (rotation);
110 g_object_get (G_OBJECT (photo), "author", &realname, NULL);
111 g_object_set (G_OBJECT (photo),
117 g_object_unref (G_OBJECT (worker));
122 manage_queue (AainaSourceFlickr *source)
124 AainaSourceFlickrPrivate *priv;
126 g_return_if_fail (AAINA_IS_SOURCE_FLICKR (source));
129 /* Now we do the work for the next one */
130 if (g_queue_get_length (priv->queue))
132 priv->current = AAINA_PHOTO (g_queue_pop_head (priv->queue));
133 g_timeout_add (100, (GSourceFunc)get_pixbuf, (gpointer)source);
135 priv->running = TRUE;
136 aaina_library_set_pending (priv->library, TRUE);
140 priv->running = FALSE;
141 aaina_library_set_pending (priv->library, FALSE);
147 on_pixbuf_thread_abort (AainaSourceFlickr *source)
150 manage_queue (source);
156 on_pixbuf_thread_error (AainaSourceFlickr *source)
158 AainaSourceFlickrPrivate *priv;
161 g_return_val_if_fail (AAINA_IS_SOURCE_FLICKR (source), FALSE);
164 g_object_get (G_OBJECT (priv->pix_worker), "error", &error, NULL);
167 g_warning ("%s\n", error);
172 manage_queue (source);
177 add_to_library (AainaSourceFlickr *source)
179 AainaSourceFlickrPrivate *priv;
180 AainaPhoto *photo = NULL;
182 g_return_val_if_fail (AAINA_IS_SOURCE (source), FALSE);
185 if (aaina_library_is_full (priv->library))
187 aaina_library_set_pending (priv->library, TRUE);
190 photo = AAINA_PHOTO (g_queue_pop_head (priv->add_queue));
194 aaina_library_append_photo (priv->library, (gpointer)photo);
199 aaina_library_set_pending (priv->library, FALSE);
200 priv->add_running = FALSE;
206 on_pixbuf_thread_ok (AainaSourceFlickr *source)
209 AainaSourceFlickrPrivate *priv;
212 g_return_val_if_fail (AAINA_IS_SOURCE_FLICKR (source), FALSE);
215 g_object_get (G_OBJECT (priv->pix_worker), "pixbuf", &pixbuf, NULL);
217 /* Set the current photo's pixbuf and add it to the library */
220 aaina_photo_set_pixbuf (priv->current, pixbuf);
222 if (priv->add_running || aaina_library_is_full (priv->library))
224 g_queue_push_tail (priv->add_queue, (gpointer)priv->current);
226 if (!priv->add_running)
228 g_timeout_add (1000, (GSourceFunc)add_to_library, (gpointer)source);
229 priv->add_running = TRUE;
230 aaina_library_set_pending (priv->library, TRUE);
234 aaina_library_append_photo (priv->library, priv->current);
236 priv->current = NULL;
239 manage_queue (source);
247 get_pixbuf (AainaSourceFlickr *source)
250 AainaSourceFlickrPrivate *priv;
251 NFlickWorker *worker;
255 g_return_val_if_fail (AAINA_IS_SOURCE_FLICKR (source), FALSE);
258 if (priv->current == NULL)
261 photo = priv->current;
262 g_object_get (G_OBJECT (photo), "id", &id, NULL);
264 worker = (NFlickWorker*)nflick_show_worker_new (id,
265 CLUTTER_STAGE_WIDTH ()/2,
266 CLUTTER_STAGE_HEIGHT ()/2,
268 if (G_IS_OBJECT (priv->pix_worker))
269 g_object_unref (G_OBJECT (priv->pix_worker));
270 priv->pix_worker = worker;
272 nflick_worker_set_custom_data (worker, source);
273 nflick_worker_set_aborted_idle (worker,
274 (NFlickWorkerIdleFunc)on_pixbuf_thread_abort);
275 nflick_worker_set_error_idle (worker,
276 (NFlickWorkerIdleFunc)on_pixbuf_thread_error);
277 nflick_worker_set_ok_idle (worker,
278 (NFlickWorkerIdleFunc)on_pixbuf_thread_ok);
280 nflick_worker_start (worker);
283 worker = (NFlickWorker*)nflick_info_worker_new (id, 22, 22, " ");
284 nflick_worker_start (worker);
286 priv->running = TRUE;
288 nflick_worker_set_custom_data (worker, photo);
289 nflick_worker_set_aborted_idle (worker,
290 (NFlickWorkerIdleFunc)on_info_thread_abort);
291 nflick_worker_set_error_idle (worker,
292 (NFlickWorkerIdleFunc)on_info_thread_error);
293 nflick_worker_set_ok_idle (worker,
294 (NFlickWorkerIdleFunc)on_info_thread_ok);
296 g_object_set_qdata (G_OBJECT (photo), worker_quark, (gpointer)worker);
304 on_thread_abort (AainaSourceFlickr *source)
311 on_thread_error (AainaSourceFlickr *source)
318 on_thread_ok (AainaSourceFlickr *source)
320 AainaSourceFlickrPrivate *priv;
321 GList *list = NULL, *l;
323 g_return_val_if_fail (AAINA_IS_SOURCE_FLICKR (source), FALSE);
326 /* Grab the list of photos from the worker */
327 list = nflick_photo_search_worker_take_list (NFLICK_PHOTO_SEARCH_WORKER
329 for (l = list; l != NULL; l = l->next)
331 FlickrPhoto *photo = (FlickrPhoto*)l->data;
332 ClutterActor *aphoto = NULL;
338 /* If the photo is already present, return */
339 if (g_hash_table_lookup (priv->table, photo->id) != NULL)
342 /* Insert into the hash table */
343 g_hash_table_insert (priv->table,
344 g_strdup (photo->id),
345 GINT_TO_POINTER (1));
347 /* Create a aaina photo objec, but don't add it to the library yet */
348 aphoto = aaina_photo_new ();
349 g_object_set (G_OBJECT (aphoto),
351 "title", photo->title,
352 "author", photo->user,
355 /* Add the photo to the download queue */
356 g_queue_push_tail (priv->queue, (gpointer)aphoto);
358 /* Free the the photo struct and its data */
360 g_free (photo->title);
361 g_free (photo->user);
368 g_timeout_add (CHECK_TIMEOUT, (GSourceFunc)get_photos, (gpointer)source);
371 priv->current = AAINA_PHOTO (g_queue_pop_head (priv->queue));
372 g_timeout_add (200, (GSourceFunc)get_pixbuf, (gpointer)source);
378 get_photos (AainaSourceFlickr *source)
380 NFlickWorker *worker;
381 NFlickWorkerStatus *status;
383 worker = (NFlickWorker*)nflick_photo_search_worker_new (source->priv->tags,
385 if (G_IS_OBJECT (source->priv->worker))
386 g_object_unref (G_OBJECT (source->priv->worker));
388 source->priv->worker = worker;
390 nflick_worker_set_custom_data (worker, source);
391 nflick_worker_set_aborted_idle (worker,
392 (NFlickWorkerIdleFunc)on_thread_abort);
393 nflick_worker_set_error_idle (worker,
394 (NFlickWorkerIdleFunc)on_thread_error);
395 nflick_worker_set_ok_idle (worker,
396 (NFlickWorkerIdleFunc)on_thread_ok);
398 nflick_worker_start (worker);
405 aaina_source_flickr_class_init (AainaSourceFlickrClass *klass)
407 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
409 g_type_class_add_private (gobject_class, sizeof (AainaSourceFlickrPrivate));
415 aaina_source_flickr_init (AainaSourceFlickr *source_flickr)
417 AainaSourceFlickrPrivate *priv;
419 priv = source_flickr->priv = AAINA_SOURCE_FLICKR_GET_PRIVATE (source_flickr);
421 priv->table = g_hash_table_new ((GHashFunc)g_str_hash,
422 (GEqualFunc)g_str_equal);
424 priv->queue = g_queue_new ();
425 priv->running = FALSE;
427 priv->add_queue = g_queue_new ();
428 priv->add_running = FALSE;
430 worker_quark = g_quark_from_string ("aaina.flickr.worker");
434 aaina_source_flickr_new (AainaLibrary *library, const gchar *tags)
436 AainaSourceFlickr *source_flickr;
438 source_flickr = g_object_new (AAINA_TYPE_SOURCE_FLICKR,
441 source_flickr->priv->tags = g_strdup (tags);
442 source_flickr->priv->library = library;
443 get_photos (source_flickr);
445 return AAINA_SOURCE (source_flickr);