From 016e2b04824b444aa8941544179b8fd801e83d67 Mon Sep 17 00:00:00 2001 From: Ricardo Mones Date: Sun, 28 Jun 2015 09:54:04 +0200 Subject: [PATCH] Libravatar: clean cache button --- src/plugins/libravatar/TODO | 1 - src/plugins/libravatar/libravatar_cache.c | 40 +++++++++++++ src/plugins/libravatar/libravatar_cache.h | 10 +++- src/plugins/libravatar/libravatar_prefs.c | 70 +++++++++++++++++++++-- 4 files changed, 114 insertions(+), 7 deletions(-) diff --git a/src/plugins/libravatar/TODO b/src/plugins/libravatar/TODO index 9149680ee..61667a6d8 100644 --- a/src/plugins/libravatar/TODO +++ b/src/plugins/libravatar/TODO @@ -6,7 +6,6 @@ Enhancements, possibilities and random ideas - Button for checking custom default URL is not 404 (!) check on apply (?) - Make it run in cache-less mode if cache dir cannot be created (??) - Only cache "mystery man" once for all hashes (what if changes) (?) -- Empty avatar/missing cache button(s) (?) - Run network retrieval in a separate thread started at header capture hook (??) - Alternate proxy support (send avatar requests through a proxy which diff --git a/src/plugins/libravatar/libravatar_cache.c b/src/plugins/libravatar/libravatar_cache.c index 3c8c0bc2e..df378f90f 100644 --- a/src/plugins/libravatar/libravatar_cache.c +++ b/src/plugins/libravatar/libravatar_cache.c @@ -124,3 +124,43 @@ AvatarCacheStats *libravatar_cache_stats() return stats; } + +static void cache_delete_item(gpointer filename, gpointer errors) +{ + const gchar *fname = (const gchar *) filename; + AvatarCleanupResult *acr = (AvatarCleanupResult *) errors; + + if (!is_dir_exist(fname)) { + if (claws_unlink(fname) < 0) { + g_warning("couldn't delete file %s\n", fname); + (acr->e_unlink)++; + } + else { + (acr->removed)++; + } + } +} + +AvatarCleanupResult *libravatar_cache_clean() +{ + gchar *rootdir; + AvatarCleanupResult *acr; + GSList *items = NULL; + guint errors = 0; + + acr = g_new0(AvatarCleanupResult, 1); + cm_return_val_if_fail(acr != NULL, NULL); + + rootdir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, + LIBRAVATAR_CACHE_DIR, G_DIR_SEPARATOR_S, + NULL); + cache_items_deep_first(rootdir, &items, &errors); + acr->e_stat = (gint) errors; + + g_slist_foreach(items, (GFunc) cache_delete_item, (gpointer) acr); + + slist_free_strings_full(items); + g_free(rootdir); + + return acr; +} diff --git a/src/plugins/libravatar/libravatar_cache.h b/src/plugins/libravatar/libravatar_cache.h index bebd4e5f0..2d97e9c36 100644 --- a/src/plugins/libravatar/libravatar_cache.h +++ b/src/plugins/libravatar/libravatar_cache.h @@ -24,12 +24,13 @@ #define LIBRAVATAR_CACHE_DIR "avatarcache" typedef struct _AvatarCacheStats AvatarCacheStats; +typedef struct _AvatarCleanupResult AvatarCleanupResult; gchar *libravatar_cache_init (const char *dirs[], gint start, gint end); AvatarCacheStats *libravatar_cache_stats (); - +AvatarCleanupResult *libravatar_cache_clean (); struct _AvatarCacheStats { @@ -40,4 +41,11 @@ struct _AvatarCacheStats gint errors; }; +struct _AvatarCleanupResult +{ + guint removed; + guint e_stat; + guint e_unlink; +}; + #endif diff --git a/src/plugins/libravatar/libravatar_prefs.c b/src/plugins/libravatar/libravatar_prefs.c index 766b838d6..9e0e6c999 100644 --- a/src/plugins/libravatar/libravatar_prefs.c +++ b/src/plugins/libravatar/libravatar_prefs.c @@ -34,6 +34,7 @@ #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 @@ -153,9 +154,56 @@ static gchar *avatar_stats_label_markup(AvatarCacheStats *stats) 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, FALSE, + NULL, ALERT_WARNING, G_ALERTDEFAULT); + if (val != G_ALERTALTERNATE) + return; + + debug_print("cleaning missing cache"); + misses = g_hash_table_size(libravatarmisses); + g_hash_table_remove_all(libravatarmisses); + + debug_print("cleaning disk cache"); + 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, + _("Icon cache succesfully cleared!")); + } + 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, + _("Error clearing icon cache.")); + } + 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, *label; + GtkWidget *vbox, *checkbox, *spinner, *hbox, *label, *button; GtkAdjustment *adj; AvatarCacheStats *stats; gchar *markup; @@ -188,12 +236,24 @@ static GtkWidget *p_create_frame_cache(struct LibravatarPrefsPage *page) gtk_widget_show(label); stats = libravatar_cache_stats(); markup = avatar_stats_label_markup(stats); - if (stats != NULL) - g_free(stats); gtk_label_set_markup(GTK_LABEL(label), markup); g_free(markup); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + + 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; } @@ -361,7 +421,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 │ + │ Using X KB in Y files and Z directories [Clear] │ └──────────────────────────────────────────────────────┘ ┌─Default missing icon mode────────────────────────────┐ │ (•) None │ -- 2.25.1