[gthumb] Flickr: fixed import of photosets greater then 500
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] Flickr: fixed import of photosets greater then 500
- Date: Sun, 11 Sep 2011 14:31:54 +0000 (UTC)
commit 96d90a9d517262a9e7e178624c3322af8cba7ce0
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Sep 10 18:39:55 2011 +0200
Flickr: fixed import of photosets greater then 500
The method flickr.photosets.getPhotos returns a max of 500 photos, call the method multiple times if the photoset contains
more then 500 photos.
[bug #648701]
extensions/flicker/dlg-import-from-flickr.c | 2 -
extensions/flicker/flickr-connection.c | 2 +-
extensions/flicker/flickr-service.c | 173 +++++++++++++++++++--------
extensions/flicker/flickr-service.h | 2 -
gthumb/dom.c | 17 +++
gthumb/dom.h | 48 ++++----
6 files changed, 167 insertions(+), 77 deletions(-)
---
diff --git a/extensions/flicker/dlg-import-from-flickr.c b/extensions/flicker/dlg-import-from-flickr.c
index 628bdbc..fb6c7e9 100644
--- a/extensions/flicker/dlg-import-from-flickr.c
+++ b/extensions/flicker/dlg-import-from-flickr.c
@@ -407,8 +407,6 @@ photoset_combobox_changed_cb (GtkComboBox *widget,
flickr_service_list_photos (data->service,
data->photoset,
"original_format, url_sq, url_t, url_s, url_m, url_o",
- 0,
- 0,
data->cancellable,
list_photos_ready_cb,
data);
diff --git a/extensions/flicker/flickr-connection.c b/extensions/flicker/flickr-connection.c
index d3c3d77..d2a5c63 100644
--- a/extensions/flicker/flickr-connection.c
+++ b/extensions/flicker/flickr-connection.c
@@ -215,7 +215,7 @@ flickr_connection_send_message (FlickrConnection *self,
self->priv->cancellable = _g_object_ref (cancellable);
_g_object_unref (self->priv->result);
- self->priv->result = g_simple_async_result_new (G_OBJECT (soup_session_cb_data),
+ self->priv->result = g_simple_async_result_new (G_IS_OBJECT (soup_session_cb_data) ? G_OBJECT (soup_session_cb_data) : NULL,
callback,
user_data,
source_tag);
diff --git a/extensions/flicker/flickr-service.c b/extensions/flicker/flickr-service.c
index ae050c5..372d16d 100644
--- a/extensions/flicker/flickr-service.c
+++ b/extensions/flicker/flickr-service.c
@@ -31,6 +31,9 @@
#include "flickr-user.h"
+#define IMAGES_PER_PAGE 500
+
+
typedef struct {
FlickrPrivacyType privacy_level;
FlickrSafetyType safety_level;
@@ -974,16 +977,45 @@ flickr_service_post_photos_finish (FlickrService *self,
/* -- flickr_service_list_photos -- */
+typedef struct {
+ FlickrService *self;
+ FlickrPhotoset *photoset;
+ char *extras;
+ GCancellable *cancellable;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+ GList *photos;
+ int position;
+} FlickrListPhotosData;
+
+
static void
-list_photos_ready_cb (SoupSession *session,
- SoupMessage *msg,
- gpointer user_data)
+flickr_list_photos_data_free (FlickrListPhotosData *data)
{
- FlickrService *self = user_data;
- GSimpleAsyncResult *result;
- SoupBuffer *body;
- DomDocument *doc = NULL;
- GError *error = NULL;
+ _g_object_unref (data->self);
+ _g_object_unref (data->photoset);
+ g_free (data->extras);
+ _g_object_unref (data->cancellable);
+ g_free (data);
+}
+
+
+static void
+flickr_service_list_photoset_page (FlickrListPhotosData *data,
+ int page);
+
+
+static void
+flickr_service_list_photoset_paged_ready_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ FlickrListPhotosData *data = user_data;
+ FlickrService *self = data->self;
+ GSimpleAsyncResult *result;
+ SoupBuffer *body;
+ DomDocument *doc = NULL;
+ GError *error = NULL;
result = flickr_connection_get_result (self->priv->conn);
@@ -994,6 +1026,7 @@ list_photos_ready_cb (SoupSession *session,
"%s",
soup_status_get_phrase (msg->status_code));
g_simple_async_result_complete_in_idle (result);
+ flickr_list_photos_data_free (data);
return;
}
@@ -1001,90 +1034,132 @@ list_photos_ready_cb (SoupSession *session,
if (flickr_utils_parse_response (body, &doc, &error)) {
DomElement *response;
DomElement *node;
- GList *photos = NULL;
+ int pages = 0;
+ int page = 0;
response = DOM_ELEMENT (doc)->first_child;
for (node = response->first_child; node; node = node->next_sibling) {
if (g_strcmp0 (node->tag_name, "photoset") == 0) {
DomElement *child;
- int position;
- position = 0;
for (child = node->first_child; child; child = child->next_sibling) {
if (g_strcmp0 (child->tag_name, "photo") == 0) {
FlickrPhoto *photo;
- photo = flickr_photo_new ();
+ photo = flickr_photo_new (self->priv->conn->server);
dom_domizable_load_from_element (DOM_DOMIZABLE (photo), child);
- photo->position = position++;
- photos = g_list_prepend (photos, photo);
+ photo->position = data->position++;
+ data->photos = g_list_prepend (data->photos, photo);
}
}
+
+ pages = dom_element_get_attribute_as_int (node, "pages");
+ page = dom_element_get_attribute_as_int (node, "page");
}
}
- photos = g_list_reverse (photos);
- g_simple_async_result_set_op_res_gpointer (result, photos, (GDestroyNotify) _g_object_list_unref);
+ if (page > pages) {
+ g_simple_async_result_set_error (result,
+ SOUP_HTTP_ERROR,
+ 0,
+ "%s",
+ "Invalid data");
+ g_simple_async_result_complete_in_idle (result);
+ flickr_list_photos_data_free (data);
+ }
+ else if (page < pages) {
+ /* read the next page */
+ flickr_service_list_photoset_page (data, page + 1);
+ }
+ else { /* page == pages */
+ data->photos = g_list_reverse (data->photos);
+ g_simple_async_result_set_op_res_gpointer (result,
+ _g_object_list_ref (data->photos),
+ (GDestroyNotify) _g_object_list_unref);
+ g_simple_async_result_complete_in_idle (result);
+ flickr_list_photos_data_free (data);
+ }
g_object_unref (doc);
}
- else
+ else {
g_simple_async_result_set_from_error (result, error);
-
- g_simple_async_result_complete_in_idle (result);
+ g_simple_async_result_complete_in_idle (result);
+ }
soup_buffer_free (body);
}
-void
-flickr_service_list_photos (FlickrService *self,
- FlickrPhotoset *photoset,
- const char *extras,
- int per_page,
- int page,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+static void
+flickr_service_list_photoset_page (FlickrListPhotosData *data,
+ int n_page)
{
- GHashTable *data_set;
- char *s;
- SoupMessage *msg;
+ FlickrService *self = data->self;
+ GHashTable *data_set;
+ char *page = NULL;
+ char *per_page = NULL;
+ SoupMessage *msg;
- g_return_if_fail (photoset != NULL);
+ g_return_if_fail (data->photoset != NULL);
gth_task_progress (GTH_TASK (self->priv->conn), _("Getting the photo list"), NULL, TRUE, 0.0);
data_set = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (data_set, "method", "flickr.photosets.getPhotos");
- g_hash_table_insert (data_set, "photoset_id", photoset->id);
- if (extras != NULL)
- g_hash_table_insert (data_set, "extras", (char *) extras);
- if (per_page > 0) {
- s = g_strdup_printf ("%d", per_page);
- g_hash_table_insert (data_set, "per_page", s);
- g_free (s);
- }
- if (page > 0) {
- s = g_strdup_printf ("%d", page);
- g_hash_table_insert (data_set, "page", s);
- g_free (s);
+ g_hash_table_insert (data_set, "photoset_id", data->photoset->id);
+ if (data->extras != NULL)
+ g_hash_table_insert (data_set, "extras", (char *) data->extras);
+
+ if (n_page > 0) {
+ page = g_strdup_printf ("%d", IMAGES_PER_PAGE);
+ g_hash_table_insert (data_set, "per_page", page);
+
+ per_page = g_strdup_printf ("%d", n_page);
+ g_hash_table_insert (data_set, "page", per_page);
}
+
flickr_connection_add_api_sig (self->priv->conn, data_set);
msg = soup_form_request_new_from_hash ("GET", self->priv->conn->server->rest_url, data_set);
flickr_connection_send_message (self->priv->conn,
msg,
- cancellable,
- callback,
- user_data,
+ data->cancellable,
+ data->callback,
+ data->user_data,
flickr_service_list_photos,
- list_photos_ready_cb,
- self);
+ flickr_service_list_photoset_paged_ready_cb,
+ data);
+ g_free (per_page);
+ g_free (page);
g_hash_table_destroy (data_set);
}
+void
+flickr_service_list_photos (FlickrService *self,
+ FlickrPhotoset *photoset,
+ const char *extras,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ FlickrListPhotosData *data;
+
+ data = g_new0 (FlickrListPhotosData, 1);
+ data->self = _g_object_ref (self);
+ data->photoset = _g_object_ref (photoset);
+ data->extras = g_strdup (extras);
+ data->cancellable = _g_object_ref (cancellable);
+ data->callback = callback;
+ data->user_data = user_data;
+ data->photos = NULL;
+ data->position = 0;
+
+ flickr_service_list_photoset_page (data, 1);
+}
+
+
GList *
flickr_service_list_photos_finish (FlickrService *self,
GAsyncResult *result,
diff --git a/extensions/flicker/flickr-service.h b/extensions/flicker/flickr-service.h
index fb20bbe..558c261 100644
--- a/extensions/flicker/flickr-service.h
+++ b/extensions/flicker/flickr-service.h
@@ -112,8 +112,6 @@ GList * flickr_service_post_photos_finish (FlickrService
void flickr_service_list_photos (FlickrService *self,
FlickrPhotoset *photoset,
const char *extras,
- int per_page,
- int page,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
diff --git a/gthumb/dom.c b/gthumb/dom.c
index 60c1c20..0a317a1 100644
--- a/gthumb/dom.c
+++ b/gthumb/dom.c
@@ -20,6 +20,7 @@
*/
#include <config.h>
+#include <stdlib.h>
#include <string.h>
#include "dom.h"
@@ -310,6 +311,22 @@ dom_element_get_attribute (DomElement *self,
}
+int
+dom_element_get_attribute_as_int (DomElement *self,
+ const char *name)
+{
+ const char *value;
+ int i;
+
+ i = 0;
+ value = dom_element_get_attribute (self, name);
+ if (value != NULL)
+ i = atoi (value);
+
+ return i;
+}
+
+
gboolean
dom_element_has_attribute (DomElement *self,
const char *name)
diff --git a/gthumb/dom.h b/gthumb/dom.h
index 341d054..7294660 100644
--- a/gthumb/dom.h
+++ b/gthumb/dom.h
@@ -18,7 +18,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
+
#ifndef DOM_H
#define DOM_H
@@ -77,7 +77,7 @@ typedef struct _DomDomizableIface DomDomizableIface;
struct _DomElement {
GInitiallyUnowned parent_instance;
DomElementPrivate *priv;
-
+
char *tag_name;
char *prefix;
GHashTable *attributes;
@@ -91,15 +91,15 @@ struct _DomElement {
struct _DomElementClass {
GInitiallyUnownedClass parent_class;
-
- char * (*dump) (DomElement *self,
+
+ char * (*dump) (DomElement *self,
int level);
};
struct _DomTextNode {
DomElement parent_instance;
DomTextNodePrivate *priv;
-
+
char *data;
};
@@ -118,10 +118,10 @@ struct _DomDocumentClass {
struct _DomDomizableIface {
GTypeInterface parent_iface;
-
- DomElement * (*create_element) (DomDomizable *self,
+
+ DomElement * (*create_element) (DomDomizable *self,
DomDocument *doc);
- void (*load_from_element) (DomDomizable *self,
+ void (*load_from_element) (DomDomizable *self,
DomElement *e);
};
@@ -130,22 +130,24 @@ GQuark dom_error_quark (void);
/* DomElement */
GType dom_element_get_type (void);
-void dom_element_append_child (DomElement *self,
+void dom_element_append_child (DomElement *self,
DomElement *child);
-const char * dom_element_get_attribute (DomElement *self,
+const char * dom_element_get_attribute (DomElement *self,
const char *name);
-gboolean dom_element_has_attribute (DomElement *self,
+int dom_element_get_attribute_as_int (DomElement *self,
+ const char *name);
+gboolean dom_element_has_attribute (DomElement *self,
const char *name);
gboolean dom_element_has_child_nodes (DomElement *self);
-void dom_element_remove_attribute (DomElement *self,
+void dom_element_remove_attribute (DomElement *self,
const char *name);
-DomElement * dom_element_remove_child (DomElement *self,
+DomElement * dom_element_remove_child (DomElement *self,
DomElement *node);
-void dom_element_replace_child (DomElement *self,
- DomElement *new_child,
+void dom_element_replace_child (DomElement *self,
+ DomElement *new_child,
DomElement *old_child);
-void dom_element_set_attribute (DomElement *self,
- const char *name,
+void dom_element_set_attribute (DomElement *self,
+ const char *name,
const char *value);
const char * dom_element_get_inner_text (DomElement *self);
@@ -157,20 +159,20 @@ GType dom_text_node_get_type (void);
GType dom_document_get_type (void);
DomDocument * dom_document_new (void);
-DomElement * dom_document_create_element (DomDocument *self,
+DomElement * dom_document_create_element (DomDocument *self,
const char *tag_name,
const char *first_attr,
...);
-DomElement * dom_document_create_text_node (DomDocument *self,
+DomElement * dom_document_create_text_node (DomDocument *self,
const char *data);
DomElement * dom_document_create_element_with_text (DomDocument *self,
- const char *text,
+ const char *text,
const char *tag_name,
const char *first_attr,
...);
char * dom_document_dump (DomDocument *self,
gsize *len);
-gboolean dom_document_load (DomDocument *self,
+gboolean dom_document_load (DomDocument *self,
const char *xml,
gssize len,
GError **error);
@@ -178,9 +180,9 @@ gboolean dom_document_load (DomDocument *self,
/* DomDomizable */
GType dom_domizable_get_type (void);
-DomElement * dom_domizable_create_element (DomDomizable *self,
+DomElement * dom_domizable_create_element (DomDomizable *self,
DomDocument *doc);
-void dom_domizable_load_from_element (DomDomizable *self,
+void dom_domizable_load_from_element (DomDomizable *self,
DomElement *e);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]