/*
* Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2014 Hiroyuki Yamamoto and the Claws Mail Team
- * Copyright (C) 2014 Ricardo Mones
+ * Copyright (C) 2014-2015 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
#include "version.h"
#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"
#include "procheader.h"
#include "procmsg.h"
"retro"
};
-static guint update_hook_id;
-static guint render_hook_id;
+static gulong update_hook_id = HOOK_NONE;
+static gulong render_hook_id = HOOK_NONE;
static gchar *cache_dir = NULL; /* dir-separator terminated */
static gboolean libravatar_header_update_hook(gpointer source, gpointer data)
debug_print("libravatar avatar_header_update invoked\n");
if (!strcmp(acd->header, "From:")) {
- gchar *a = g_strdup(acd->content);
+ gchar *a, *lower;
+
+ a = g_strdup(acd->content);
extract_address(a);
+
+ /* string to lower */
+ for (lower = a; *lower; lower++)
+ *lower = g_ascii_tolower(*lower);
+
debug_print("libravatar added '%s'\n", a);
procmsg_msginfo_add_avatar(acd->msginfo, AVATAR_LIBRAVATAR, a);
+ g_free(a);
}
return FALSE; /* keep getting */
static gchar *federated_base_url_from_address(const gchar *address)
{
- /*
- TODO: no federation supported right now
- Details on http://wiki.libravatar.org/running_your_own/
- */
+#if defined USE_GNUTLS
+ gchar *base_url = NULL;
+
+ if (!libravatarprefs.allow_federated) {
+ debug_print("federated domains disabled by configuration\n");
+ goto default_url;
+ }
+
+ base_url = federated_url_for_address(address);
+ if (base_url != NULL) {
+ return base_url;
+ }
+
+default_url:
+#endif
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;
picture = gdk_pixbuf_new_from_file(filename, &error);
if (error != NULL) {
- g_warning("Failed to load image '%s': %s\n", filename, error->message);
+ 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!\n", filename);
+ return NULL;
}
- return image;
+ return image_widget_from_pixbuf(picture);
}
static gchar *cache_name_for_md5(const gchar *md5)
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\n");
- 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);
-
- 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_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) {
- if (g_unlink(filename) < 0)
- g_warning("failed to delete cache file %s\n", filename);
- }
-
- if (filesize == 0)
- missing_add_md5(libravatarmisses, md5);
- } else {
- g_warning("could not open '%s' for writting\n", filename);
- }
- curl_easy_cleanup(curl);
- g_free(filename);
+ g_free(aif.filename);
return image;
}
static gboolean is_recent_enough(const gchar *filename)
{
- struct stat s;
+ GStatBuf s;
time_t t;
if (libravatarprefs.cache_icons) {
base, md5, AVATAR_SIZE);
}
- g_warning("invalid libravatar default mode: %d\n", libravatarprefs.default_mode);
+ g_warning("invalid libravatar default mode: %d", libravatarprefs.default_mode);
return NULL;
}
if (ar->image) /* previous plugin set one */
gtk_widget_destroy(ar->image);
ar->image = image;
+ ar->type = AVATAR_LIBRAVATAR;
return FALSE;
}
/* not cached copy: try network */
- if (prefs_common.work_offline) {
+ if (prefs_common_get_prefs()->work_offline) {
debug_print("working off-line: libravatar network retrieval skipped\n");
return FALSE;
}
if (ar->image) /* previous plugin set one */
gtk_widget_destroy(ar->image);
ar->image = image;
+ ar->type = AVATAR_LIBRAVATAR;
}
}
g_free(base);
static gint cache_dir_init()
{
- gchar *subdir;
- int i;
-
- cache_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- LIBRAVATAR_CACHE_DIR, G_DIR_SEPARATOR_S,
- NULL);
- if (!is_dir_exist(cache_dir)) {
- if (make_dir(cache_dir) < 0) {
- g_free(cache_dir);
- return -1;
- }
- }
- for (i = DEF_MODE_MM; i <= DEF_MODE_RETRO; ++i) {
- subdir = g_strconcat(cache_dir, def_mode[i - 10], NULL);
- if (!is_dir_exist(subdir)) {
- if (make_dir(subdir) < 0) {
- g_warning("cannot create directory %s\n", subdir);
- g_free(subdir);
- return -1;
- }
- }
- g_free(subdir);
- }
+ cache_dir = libravatar_cache_init(def_mode, DEF_MODE_MM - 10, DEF_MODE_RETRO - 10);
+ cm_return_val_if_fail (cache_dir != NULL, -1);
return 0;
}
}
}
+static void unregister_hooks()
+{
+ if (render_hook_id != HOOK_NONE) {
+ hooks_unregister_hook(AVATAR_IMAGE_RENDER_HOOKLIST,
+ render_hook_id);
+ render_hook_id = HOOK_NONE;
+ }
+ if (update_hook_id != HOOK_NONE) {
+ hooks_unregister_hook(AVATAR_HEADER_UPDATE_HOOKLIST,
+ update_hook_id);
+ update_hook_id = HOOK_NONE;
+ }
+}
+
/**
* Initialize plugin.
*
update_hook_id = hooks_register_hook(AVATAR_HEADER_UPDATE_HOOKLIST,
libravatar_header_update_hook,
NULL);
- if (update_hook_id == -1) {
+ if (update_hook_id == HOOK_NONE) {
*error = g_strdup(_("Failed to register avatar header update hook"));
return -1;
}
render_hook_id = hooks_register_hook(AVATAR_IMAGE_RENDER_HOOKLIST,
libravatar_image_render_hook,
NULL);
- if (render_hook_id == -1) {
+ if (render_hook_id == HOOK_NONE) {
+ unregister_hooks();
*error = g_strdup(_("Failed to register avatar image render hook"));
return -1;
}
/* cache dir */
if (cache_dir_init() == -1) {
+ unregister_hooks();
*error = g_strdup(_("Failed to create avatar image cache directory"));
return -1;
}
curl_global_init(CURL_GLOBAL_DEFAULT);
/* missing cache */
if (missing_cache_init() == -1) {
+ unregister_hooks();
*error = g_strdup(_("Failed to load missing items cache"));
return -1;
}
*/
gboolean plugin_done(void)
{
- if (render_hook_id != -1) {
- hooks_unregister_hook(AVATAR_IMAGE_RENDER_HOOKLIST,
- render_hook_id);
- render_hook_id = -1;
- }
- if (update_hook_id != -1) {
- hooks_unregister_hook(AVATAR_HEADER_UPDATE_HOOKLIST,
- update_hook_id);
- update_hook_id = -1;
- }
+ unregister_hooks();
libravatar_prefs_done();
missing_cache_done();
if (cache_dir != NULL)
*/
const gchar *plugin_desc(void)
{
- return _("Get and display libravatar images for mail messages.\n\n"
- "Info about libravatar at http://www.libravatar.org/\n\n"
+ return _("Display libravatar profiles' images for mail messages. More\n"
+ "info about libravatar at http://www.libravatar.org/. If you have\n"
+ "a gravatar.com profile but not a libravatar one, those will also\n"
+ "be retrieved (when redirections are allowed in plugin config).\n"
+ "Plugin config page is available from main window at:\n"
+ "/Configuration/Preferences/Plugins/Libravatar.\n\n"
+ "This plugin uses libcurl to retrieve images, so if you're behind a\n"
+ "proxy please refer to curl(1) manpage for details on 'http_proxy'\n"
+ "configuration. More details about this and others on README file.\n\n"
"Feedback to <ricardo@mones.org> is welcome.\n");
}