[Commits] [SCM] claws branch, master, updated. 3.14.0-115-ge62c01e
mones at claws-mail.org
mones at claws-mail.org
Mon Oct 17 14:11:47 CEST 2016
The branch, master has been updated
via e62c01edd0c6bfc6c9c2e7b9645497603b8f8e83 (commit)
from abbf2f8a104fcb5e72226a2edf0ecd1cd5d29b93 (commit)
Summary of changes:
src/plugins/libravatar/Makefile.am | 1 +
src/plugins/libravatar/libravatar.c | 88 +++-------
src/plugins/libravatar/libravatar_image.c | 168 ++++++++++++++++++++
...{libravatar_federation.h => libravatar_image.h} | 19 ++-
4 files changed, 210 insertions(+), 66 deletions(-)
create mode 100644 src/plugins/libravatar/libravatar_image.c
copy src/plugins/libravatar/{libravatar_federation.h => libravatar_image.h} (68%)
- Log -----------------------------------------------------------------
commit e62c01edd0c6bfc6c9c2e7b9645497603b8f8e83
Author: Ricardo Mones <ricardo at mones.org>
Date: Mon Oct 17 14:09:25 2016 +0200
Libravatar: refactor image retrieval
And use a synchronous thread for fetching, in preparation
of a future asynchronous fetching. Thanks Andrej for the
ideas.
diff --git a/src/plugins/libravatar/Makefile.am b/src/plugins/libravatar/Makefile.am
index 7edf1f5..4fcc57c 100644
--- a/src/plugins/libravatar/Makefile.am
+++ b/src/plugins/libravatar/Makefile.am
@@ -79,6 +79,7 @@ libravatar_la_SOURCES = \
libravatar.c libravatar.h \
libravatar_prefs.c libravatar_prefs.h \
libravatar_cache.c libravatar_cache.h \
+ libravatar_image.c libravatar_image.h \
libravatar_missing.c libravatar_missing.h \
libravatar_federation.c libravatar_federation.h
diff --git a/src/plugins/libravatar/libravatar.c b/src/plugins/libravatar/libravatar.c
index e36829e..7ce4341 100644
--- a/src/plugins/libravatar/libravatar.c
+++ b/src/plugins/libravatar/libravatar.c
@@ -30,6 +30,7 @@
#include "libravatar.h"
#include "libravatar_prefs.h"
#include "libravatar_cache.h"
+#include "libravatar_image.h"
#include "libravatar_missing.h"
#include "libravatar_federation.h"
#include "prefs_common.h"
@@ -96,9 +97,21 @@ default_url:
return g_strdup(libravatarprefs.base_url);
}
-static GtkWidget *image_widget_from_filename(const gchar *filename)
+static GtkWidget *image_widget_from_pixbuf(GdkPixbuf *picture)
{
GtkWidget *image = NULL;
+
+ if (picture) {
+ image = gtk_image_new_from_pixbuf(picture);
+ g_object_unref(picture);
+ } else
+ g_warning("null picture returns null widget");
+
+ return image;
+}
+
+static GtkWidget *image_widget_from_filename(const gchar *filename)
+{
GdkPixbuf *picture = NULL;
GError *error = NULL;
gint w, h;
@@ -115,15 +128,10 @@ static GtkWidget *image_widget_from_filename(const gchar *filename)
if (error != NULL) {
g_warning("failed to load image '%s': %s", filename, error->message);
g_error_free(error);
- } else {
- if (picture) {
- image = gtk_image_new_from_pixbuf(picture);
- g_object_unref(picture);
- } else
- g_warning("failed to load image '%s': no error returned!", filename);
+ return NULL;
}
- return image;
+ return image_widget_from_pixbuf(picture);
}
static gchar *cache_name_for_md5(const gchar *md5)
@@ -149,61 +157,17 @@ static size_t write_image_data_cb(void *ptr, size_t size, size_t nmemb, void *st
static GtkWidget *image_widget_from_url(const gchar *url, const gchar *md5)
{
GtkWidget *image = NULL;
- gchar *filename;
- FILE *file;
- CURL *curl;
-
- curl = curl_easy_init();
- if (curl == NULL) {
- g_warning("could not initialize curl to get image from URL");
- return NULL;
+ AvatarImageFetch aif;
+
+ aif.url = url;
+ aif.md5 = md5;
+ aif.filename = cache_name_for_md5(md5);
+ libravatar_image_fetch(&aif);
+ if (aif.pixbuf) {
+ image = gtk_image_new_from_pixbuf(aif.pixbuf);
+ g_object_unref(aif.pixbuf);
}
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_image_data_cb);
- /* make sure timeout is less than general IO timeout */
- curl_easy_setopt(curl, CURLOPT_TIMEOUT,
- (libravatarprefs.timeout == 0
- || libravatarprefs.timeout
- > prefs_common_get_prefs()->io_timeout_secs)
- ? prefs_common_get_prefs()->io_timeout_secs
- : libravatarprefs.timeout);
- curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
-
- filename = cache_name_for_md5(md5);
- file = fopen(filename, "wb");
- if (file != NULL) {
- long filesize;
-
- if (libravatarprefs.allow_redirects) {
- long maxredirs = (libravatarprefs.default_mode == DEF_MODE_URL)? 3L
- : ((libravatarprefs.default_mode == DEF_MODE_MM)? 2L: 1L);
-
- curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl, CURLOPT_MAXREDIRS, maxredirs);
- }
- curl_easy_setopt(curl, CURLOPT_FILE, file);
- debug_print("retrieving URL to file: %s -> %s\n", url, filename);
- curl_easy_perform(curl);
- filesize = ftell(file);
- fclose(file);
-
- if (filesize < MIN_PNG_SIZE)
- debug_print("not enough data for an avatar image: %ld bytes\n", filesize);
- else
- image = image_widget_from_filename(filename);
-
- if (!libravatarprefs.cache_icons || filesize == 0) {
- if (g_unlink(filename) < 0)
- g_warning("failed to delete cache file '%s'", filename);
- }
-
- if (filesize == 0)
- missing_add_md5(libravatarmisses, md5);
- } else {
- g_warning("could not open '%s' for writing", filename);
- }
- curl_easy_cleanup(curl);
- g_free(filename);
+ g_free(aif.filename);
return image;
}
diff --git a/src/plugins/libravatar/libravatar_image.c b/src/plugins/libravatar/libravatar_image.c
new file mode 100644
index 0000000..fa1f78a
--- /dev/null
+++ b/src/plugins/libravatar/libravatar_image.c
@@ -0,0 +1,168 @@
+/*
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2016 Ricardo Mones and the Claws Mail Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#include "claws-features.h"
+#endif
+
+#include <glib.h>
+#include <curl/curl.h>
+#include <pthread.h>
+
+#include <common/claws.h>
+#include <prefs_common.h>
+
+#include "libravatar.h"
+#include "libravatar_prefs.h"
+#include "libravatar_missing.h"
+#include "libravatar_image.h"
+
+static size_t write_image_data_cb(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
+ debug_print("received %zu bytes from avatar server\n", written);
+
+ return written;
+}
+
+static GdkPixbuf *image_pixbuf_from_filename(const gchar *filename)
+{
+ GdkPixbuf *picture = NULL;
+ GError *error = NULL;
+ gint w, h;
+
+ gdk_pixbuf_get_file_info(filename, &w, &h);
+
+ if (w != AVATAR_SIZE || h != AVATAR_SIZE)
+ /* server can provide a different size from the requested in URL */
+ picture = gdk_pixbuf_new_from_file_at_scale(
+ filename, AVATAR_SIZE, AVATAR_SIZE, TRUE, &error);
+ else /* exact size */
+ picture = gdk_pixbuf_new_from_file(filename, &error);
+
+ if (error != NULL) {
+ g_warning("failed to load image '%s': %s", filename, error->message);
+ g_error_free(error);
+ } else {
+ if (!picture)
+ g_warning("failed to load image '%s': no error returned!", filename);
+ }
+
+ return picture;
+}
+
+static GdkPixbuf *pixbuf_from_url(const gchar *url, const gchar *md5, const gchar *filename) {
+ GdkPixbuf *image = NULL;
+ FILE *file;
+ CURL *curl;
+ long filesize;
+
+ file = fopen(filename, "wb");
+ if (file == NULL) {
+ g_warning("could not open '%s' for writing", filename);
+ return NULL;
+ }
+ curl = curl_easy_init();
+ if (curl == NULL) {
+ g_warning("could not initialize curl to get image from URL");
+ return NULL;
+ }
+
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_image_data_cb);
+ /* make sure timeout is less than general IO timeout */
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT,
+ (libravatarprefs.timeout == 0
+ || libravatarprefs.timeout
+ > prefs_common_get_prefs()->io_timeout_secs)
+ ? prefs_common_get_prefs()->io_timeout_secs
+ : libravatarprefs.timeout);
+ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+
+ if (libravatarprefs.allow_redirects) {
+ long maxredirs = (libravatarprefs.default_mode == DEF_MODE_URL)? 3L
+ : ((libravatarprefs.default_mode == DEF_MODE_MM)? 2L: 1L);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl, CURLOPT_MAXREDIRS, maxredirs);
+ }
+ curl_easy_setopt(curl, CURLOPT_FILE, file);
+ debug_print("retrieving URL to file: %s -> %s\n", url, filename);
+ curl_easy_perform(curl);
+ filesize = ftell(file);
+ fclose(file);
+ if (filesize < MIN_PNG_SIZE)
+ debug_print("not enough data for an avatar image: %ld bytes\n", filesize);
+ else
+ image = image_pixbuf_from_filename(filename);
+
+ if (!libravatarprefs.cache_icons || filesize == 0) {
+ if (g_unlink(filename) < 0)
+ g_warning("failed to delete cache file '%s'", filename);
+ }
+
+ if (filesize == 0)
+ missing_add_md5(libravatarmisses, md5);
+
+ curl_easy_cleanup(curl);
+
+ return image;
+}
+
+static void *get_image_thread(void *arg) {
+ AvatarImageFetch *ctx = (AvatarImageFetch *)arg;
+
+ /* get image */
+ ctx->pixbuf = pixbuf_from_url(ctx->url, ctx->md5, ctx->filename);
+ /* done here */
+ ctx->ready = TRUE;
+
+ return arg;
+}
+
+GdkPixbuf *libravatar_image_fetch(AvatarImageFetch *ctx)
+{
+#ifdef USE_PTHREAD
+ pthread_t pt;
+#endif
+
+ g_return_if_fail(ctx != NULL);
+
+#ifdef USE_PTHREAD
+ if (pthread_create(&pt, PTHREAD_CREATE_JOINABLE, get_image_thread, (void *)ctx) != 0) {
+ debug_print("synchronous image fetching (couldn't create thread)\n");
+ get_image_thread(ctx);
+ } else {
+ debug_print("waiting for thread completion\n");
+ /*
+ while (!ctx->ready ) {
+ claws_do_idle();
+ }
+ */
+ pthread_join(pt, NULL);
+ debug_print("thread completed\n");
+ }
+#else
+ debug_print("synchronous image fetching (pthreads unavailable)\n");
+ get_image_thread(ctx);
+#endif
+ if (ctx->pixbuf == NULL) {
+ g_warning("could not get image");
+ }
+ return ctx->pixbuf;
+}
diff --git a/src/plugins/libravatar/libravatar_image.h b/src/plugins/libravatar/libravatar_image.h
new file mode 100644
index 0000000..dc298b7
--- /dev/null
+++ b/src/plugins/libravatar/libravatar_image.h
@@ -0,0 +1,37 @@
+/*
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2016 Ricardo Mones and the Claws Mail Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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 __LIBRAVATAR_IMAGE_H
+#define __LIBRAVATAR_IMAGE_H
+
+#include <glib.h>
+
+typedef struct _AvatarImageFetch AvatarImageFetch;
+
+GdkPixbuf *libravatar_image_fetch(AvatarImageFetch *ctx);
+
+struct _AvatarImageFetch
+{
+ const gchar *url;
+ const gchar *md5;
+ gchar *filename;
+ GdkPixbuf *pixbuf;
+ gboolean ready;
+};
+
+#endif
-----------------------------------------------------------------------
hooks/post-receive
--
Claws Mail
More information about the Commits
mailing list