talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 6aa8971eda52a8d08b551762710a525e0603575b
parent eb9beace00cd9d94fdd8f4950c24251f9e862acf
Author: Ricardo Mones <ricardo@mones.org>
Date:   Sun, 28 Jun 2015 09:53:19 +0200

Libravatar: cache usage info label

Diffstat:
Msrc/plugins/libravatar/TODO | 1-
Msrc/plugins/libravatar/libravatar_cache.c | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/plugins/libravatar/libravatar_cache.h | 19++++++++++++++++---
Msrc/plugins/libravatar/libravatar_prefs.c | 41++++++++++++++++++++++++++++++++++++++++-
4 files changed, 131 insertions(+), 5 deletions(-)

diff --git 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) (?) -- Cache information label (size on disk/# of avatars/missing cached) (?) - Empty avatar/missing cache button(s) (?) - Run network retrieval in a separate thread started at header capture hook (??) diff --git a/src/plugins/libravatar/libravatar_cache.c b/src/plugins/libravatar/libravatar_cache.c @@ -16,6 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <sys/stat.h> + #include "libravatar_cache.h" #include "utils.h" @@ -49,3 +51,76 @@ gchar *libravatar_cache_init(const char *dirs[], gint start, gint end) return rootdir; } + +static void cache_stat_item(gpointer filename, gpointer data) +{ + struct stat s; + const gchar *fname = (const gchar *) filename; + AvatarCacheStats *stats = (AvatarCacheStats *) data; + + if (0 == g_stat(fname, &s)) { + if (S_ISDIR(s.st_mode) != 0) { + stats->dirs++; + } + else if (S_ISREG(s.st_mode) != 0) { + stats->files++; + stats->bytes += s.st_size; + } + else { + stats->others++; + } + } + else { + g_warning("cannot stat %s\n", fname); + stats->errors++; + } +} + +static void cache_items_deep_first(const gchar *dir, GSList **items, guint *failed) +{ + struct dirent *d; + DIR *dp; + + cm_return_if_fail(dir != NULL); + + if ((dp = opendir(dir)) == NULL) { + g_warning("cannot open directory %s\n", dir); + (*failed)++; + return; + } + while ((d = readdir(dp)) != NULL) { + if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) { + continue; + } + else { + const gchar *fname = g_strconcat(dir, G_DIR_SEPARATOR_S, + d->d_name, NULL); + if (is_dir_exist(fname)) + cache_items_deep_first(fname, items, failed); + *items = g_slist_append(*items, (gpointer) fname); + } + } + closedir(dp); +} + +AvatarCacheStats *libravatar_cache_stats() +{ + gchar *rootdir; + AvatarCacheStats *stats; + GSList *items = NULL; + guint errors = 0; + + stats = g_new0(AvatarCacheStats, 1); + cm_return_val_if_fail(stats != 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); + stats->errors += errors; + g_slist_foreach(items, (GFunc) cache_stat_item, (gpointer) stats); + slist_free_strings_full(items); + g_free(rootdir); + + return stats; +} diff --git a/src/plugins/libravatar/libravatar_cache.h b/src/plugins/libravatar/libravatar_cache.h @@ -23,8 +23,21 @@ #define LIBRAVATAR_CACHE_DIR "avatarcache" -gchar *libravatar_cache_init (const char *dirs[], - gint start, - gint end); +typedef struct _AvatarCacheStats AvatarCacheStats; + +gchar *libravatar_cache_init (const char *dirs[], + gint start, + gint end); +AvatarCacheStats *libravatar_cache_stats (); + + +struct _AvatarCacheStats +{ + gint bytes; + gint files; + gint dirs; + gint others; + gint errors; +}; #endif diff --git a/src/plugins/libravatar/libravatar_prefs.c b/src/plugins/libravatar/libravatar_prefs.c @@ -31,6 +31,7 @@ #include "defs.h" #include "libravatar_prefs.h" +#include "libravatar_cache.h" #include "prefs_common.h" #include "prefs_gtk.h" @@ -128,10 +129,36 @@ 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( + _("<span color=\"red\">Error reading cache stats</span>")); + + if (stats->errors > 0) + return g_markup_printf_escaped( + _("<span color=\"red\">Using %s in %d files, %d " + "directories, %d others and %d errors</span>"), + 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 GtkWidget *p_create_frame_cache(struct LibravatarPrefsPage *page) { - GtkWidget *vbox, *checkbox, *spinner, *hbox; + GtkWidget *vbox, *checkbox, *spinner, *hbox, *label; GtkAdjustment *adj; + AvatarCacheStats *stats; + gchar *markup; vbox = gtk_vbox_new(FALSE, 6); @@ -157,6 +184,17 @@ 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); + 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); + return vbox; } @@ -323,6 +361,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 │ └──────────────────────────────────────────────────────┘ ┌─Default missing icon mode────────────────────────────┐ │ (•) None │