Fix bug 4325 "Following redirects when retrieving image"
[claws.git] / src / plugins / libravatar / libravatar_prefs.c
index 4c015451af2535a62190d22fbd692a61ae243cd4..3a097001b54a14c84a6f8a623614abdb4c43ecd6 100644 (file)
@@ -1,7 +1,6 @@
 /*
  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2015 Hiroyuki Yamamoto and the Claws Mail Team
- * Copyright (C) 2015 Ricardo Mones
+ * Copyright (C) 2014-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
 
 #include "defs.h"
 #include "libravatar_prefs.h"
+#include "libravatar_cache.h"
 #include "prefs_common.h"
 #include "prefs_gtk.h"
+#include "alertpanel.h"
 
 #define PREFS_BLOCK_NAME "Libravatar"
 #define NUM_DEF_BUTTONS 7
@@ -57,7 +58,7 @@ struct LibravatarPrefsPage
        GtkWidget *defm_radio[NUM_DEF_BUTTONS];
        GtkWidget *defm_url_text;
        GtkWidget *allow_redirects_check;
-#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+#if defined USE_GNUTLS
        GtkWidget *allow_federated_check;
 #endif
        GtkWidget *timeout;
@@ -84,7 +85,7 @@ static PrefParam param[] = {
        { "allow_redirects", "TRUE",
          &libravatarprefs.allow_redirects,
           P_BOOL, NULL, NULL, NULL },
-#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+#if defined USE_GNUTLS
        { "allow_federated", "TRUE",
          &libravatarprefs.allow_federated,
           P_BOOL, NULL, NULL, NULL },
@@ -92,6 +93,15 @@ static PrefParam param[] = {
        { "timeout", "0",
          &libravatarprefs.timeout,
           P_INT, NULL, NULL, NULL },
+       { "max_redirects_url", "7",
+         &libravatarprefs.max_redirects_url,
+          P_INT, NULL, NULL, NULL },
+       { "max_redirects_mm", "5",
+         &libravatarprefs.max_redirects_mm,
+          P_INT, NULL, NULL, NULL },
+       { "max_redirects", "3",
+         &libravatarprefs.max_redirects,
+          P_INT, NULL, NULL, NULL },
        {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
 };
 
@@ -129,10 +139,83 @@ static GtkWidget *labeled_spinner_box(gchar *label, GtkWidget *spinner, gchar *u
        return hbox;
 }
 
+static gchar *avatar_stats_label_markup(AvatarCacheStats *stats)
+{
+       if (stats == NULL)
+               return g_strdup(g_strconcat("<span color=\"red\">",
+                       _("Error reading cache stats"), "</span>", NULL));
+
+       if (stats->errors > 0)
+               return g_markup_printf_escaped(g_strconcat("<span color=\"red\">",
+                       _("Using %s in %d files, %d "
+                       "directories, %d others and %d errors"), "</span>", NULL),
+                       to_human_readable((goffset) stats->bytes),
+                       stats->files,
+                       stats->dirs,
+                       stats->others,
+                       stats->errors);
+
+       return g_strdup_printf(
+               _("Using %s in %d files, %d directories and %d others"),
+               to_human_readable((goffset) stats->bytes),
+               stats->files,
+               stats->dirs,
+               stats->others);
+}
+
+static void cache_clean_button_clicked_cb(GtkButton *button, gpointer data)
+{
+       GtkLabel *label = (GtkLabel *) data;
+       gint val = 0;
+       AvatarCleanupResult *acr;
+       guint misses;
+
+       val = alertpanel_full(_("Clear icon cache"),
+                       _("Are you sure you want to remove all cached avatar icons?"),
+                       GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_FIRST, FALSE,
+                       NULL, ALERT_WARNING);
+       if (val != G_ALERTALTERNATE)
+               return;
+
+       debug_print("cleaning missing cache\n");
+       misses = g_hash_table_size(libravatarmisses);
+       g_hash_table_remove_all(libravatarmisses);
+
+       debug_print("cleaning disk cache\n");
+       acr = libravatar_cache_clean();
+       if (acr == NULL) {
+               alertpanel_error(_("Not enough memory for operation"));
+               return;
+       }
+
+       if (acr->e_stat == 0 && acr->e_unlink == 0) {
+               alertpanel_notice(_("Icon cache successfully cleared:\n"
+                       "• %u missing entries removed.\n"
+                       "• %u files removed."),
+                       misses, acr->removed);
+               gtk_label_set_markup(label, g_strconcat("<span color=\"#006400\">",
+                       _("Icon cache successfully cleared!"), "</span>", NULL));
+       }
+       else {
+               alertpanel_warning(_("Errors clearing icon cache:\n"
+                       "• %u missing entries removed.\n"
+                       "• %u files removed.\n"
+                       "• %u files failed to be read.\n"
+                       "• %u files couldn't be removed."),
+                       misses, acr->removed, acr->e_stat, acr->e_unlink);
+               gtk_label_set_markup(label, g_strconcat("<span color=\"red\">",
+                       _("Error clearing icon cache."), "</span>", NULL));
+       }
+       gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
+       g_free(acr);
+}
+
 static GtkWidget *p_create_frame_cache(struct LibravatarPrefsPage *page)
 {
-       GtkWidget *vbox, *checkbox, *spinner, *hbox;
+       GtkWidget *vbox, *checkbox, *spinner, *hbox, *label, *button;
        GtkAdjustment *adj;
+       AvatarCacheStats *stats;
+       gchar *markup;
 
        vbox =  gtk_vbox_new(FALSE, 6);
 
@@ -158,6 +241,29 @@ static GtkWidget *p_create_frame_cache(struct LibravatarPrefsPage *page)
        gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
+       label = gtk_label_new(NULL);
+       gtk_widget_show(label);
+       stats = libravatar_cache_stats();
+       markup = avatar_stats_label_markup(stats);
+       gtk_label_set_markup(GTK_LABEL(label), markup);
+       g_free(markup);
+       gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+       button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
+       gtk_widget_show(button);
+       g_signal_connect(button, "clicked",
+               G_CALLBACK(cache_clean_button_clicked_cb), label);
+       gtk_widget_set_sensitive(button, (stats != NULL && stats->bytes > 0));
+
+       hbox = gtk_hbox_new(FALSE, 6);
+       gtk_widget_show(hbox);
+       gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+       gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+       gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+
+       if (stats != NULL)
+               g_free(stats);
+
        return vbox;
 }
 
@@ -179,10 +285,10 @@ static void default_mode_radio_button_cb(GtkToggleButton *button, gpointer data)
                        TRUE);
 
        if (mode == DEF_MODE_NONE) {
-               prefs_common.enable_avatars = AVATARS_ENABLE_BOTH;
+               prefs_common_get_prefs()->enable_avatars = AVATARS_ENABLE_BOTH;
        } else {
                /* don't waste time with headers that won't be displayed */
-               prefs_common.enable_avatars = AVATARS_DISABLE;
+               prefs_common_get_prefs()->enable_avatars = AVATARS_DISABLE;
                /* empty missing cache when switching to generated */
                g_hash_table_remove_all(libravatarmisses);
        }
@@ -263,8 +369,9 @@ static GtkWidget *p_create_frame_missing(struct LibravatarPrefsPage *page)
                libravatarprefs.default_mode = DEF_MODE_NONE;
        }
        /* don't waste time with headers that won't be displayed */
-       prefs_common.enable_avatars = (libravatarprefs.default_mode == DEF_MODE_NONE)
-                                               ? AVATARS_ENABLE_BOTH: AVATARS_DISABLE;
+       prefs_common_get_prefs()->enable_avatars =
+               (libravatarprefs.default_mode == DEF_MODE_NONE)
+               ? AVATARS_ENABLE_BOTH: AVATARS_DISABLE;
 
 
 
@@ -275,7 +382,7 @@ static GtkWidget *p_create_frame_network(struct LibravatarPrefsPage *page)
 {
        GtkWidget *vbox, *chk_redirects, *spinner, *hbox;
        GtkAdjustment *adj;
-#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+#if defined USE_GNUTLS
        GtkWidget *chk_federated;
 #endif
 
@@ -290,7 +397,7 @@ static GtkWidget *p_create_frame_network(struct LibravatarPrefsPage *page)
        page->allow_redirects_check = chk_redirects;
        gtk_box_pack_start(GTK_BOX(vbox), chk_redirects, FALSE, FALSE, 0);
 
-#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+#if defined USE_GNUTLS
        chk_federated = create_checkbox(_("_Enable federated servers"),
                                _("Try to get avatar from sender's domain "
                                  "libravatar server"));
@@ -309,7 +416,7 @@ static GtkWidget *p_create_frame_network(struct LibravatarPrefsPage *page)
                                        1.0, 0.0, 0.0);
        spinner = gtk_spin_button_new(adj, 1.0, 0);
        gtk_widget_show(spinner);
-       hbox = labeled_spinner_box(_("Request timeout"), spinner, _("seconds"),
+       hbox = labeled_spinner_box(_("Request timeout"), spinner, _("second(s)"),
                _("Set to 0 to use global socket I/O timeout. "
                   "Maximum value must be also less than global socket "
                   "I/O timeout."));
@@ -323,6 +430,7 @@ static GtkWidget *p_create_frame_network(struct LibravatarPrefsPage *page)
   ┌─Icon cache───────────────────────────────────────────┐
   │ [✔] Use cached icons                                 │
   │ Cache refresh interval [ 24 |⬘] hours                │
+  │ Using X KB in Y files and Z directories [Clear]      │
   └──────────────────────────────────────────────────────┘
   ┌─Default missing icon mode────────────────────────────┐
   │ (•) None                                             │
@@ -388,7 +496,7 @@ static void libravatar_save_config(void)
                return;
 
        if (prefs_write_param(param, pfile->fp) < 0) {
-               g_warning("Failed to write Libravatar configuration to file\n");
+               g_warning("failed to write Libravatar configuration to file");
                prefs_file_close_revert(pfile);
                return;
        }
@@ -427,7 +535,7 @@ static void libravatar_prefs_save_func(PrefsPage * _page)
        libravatarprefs.allow_redirects = gtk_toggle_button_get_active(
                GTK_TOGGLE_BUTTON(page->allow_redirects_check));
        /* federation */
-#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+#if defined USE_GNUTLS
        libravatarprefs.allow_federated = gtk_toggle_button_get_active(
                GTK_TOGGLE_BUTTON(page->allow_federated_check));
 #endif
@@ -456,6 +564,7 @@ void libravatar_prefs_init(void)
        libravatarprefs_page.page.create_widget = libravatar_prefs_create_widget_func;
        libravatarprefs_page.page.destroy_widget = libravatar_prefs_destroy_widget_func;
        libravatarprefs_page.page.save_page = libravatar_prefs_save_func;
+       libravatarprefs_page.page.weight = 40.0;
 
        prefs_gtk_register_page((PrefsPage *) &libravatarprefs_page);
 }