Added :clearcache by :cleardata command.
authorDaniel Carl <danielcarl@gmx.de>
Wed, 9 Oct 2019 00:15:57 +0000 (02:15 +0200)
committerDaniel Carl <danielcarl@gmx.de>
Wed, 9 Oct 2019 00:15:57 +0000 (02:15 +0200)
Allow to clear different types of website data base on the last update
time.

CHANGELOG.md
doc/vimb.1
src/ex.c
src/util.c
src/util.h
tests/test-util.c

index 77b6fc7..3edb230 100644 (file)
@@ -7,9 +7,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 
 ## [Unreleased]
 ### Added
+* `:cleardata [timeSpan] [listOfDataTypes]` command to clear various types of
+  stored website data modified in the last _timeSpan_.
 ### Changed
 ### Fixed
 ### Removed
+* `:clearcache` was removed in favor of more advanced `:cleardata` command.
+  The previous behaviour of `:clearcache` could be replaces by
+  `:cleardata - memory-cache,disk-cache`.
 
 ## [3.5.0] - 2019-07-29
 ### Added
index e86d561..8b7ffa9 100644 (file)
@@ -807,9 +807,93 @@ Example:
 .EE
 .SS Misc
 .TP
-.B :cl[earcache]
-Clears all resources currently cached by webkit.
+.BI ":cl[eardata] [" timespan "] [" dataTypes "]"
+Asynchronously clears the website data of the given list of\fIdataTypes\fP
+modified in the past \fItimespan\fP.
+If \fItimespan\fP is 0, all website data will be removed.
 Note that this effects all running instances of vimb.
+.RS
+.PP
+.PD 0
+The \fItimespan\fP is given as sequence of '[multiplier]\fIunit\fP' tupels.
+with following units.
+.TP
+.B y
+year (365 days)
+.TP
+.B w
+week (7 days)
+.TP
+.B d
+day
+.TP
+.B h
+hour
+.TP
+.B m
+minute
+.TP
+.B s
+second
+.TP
+.B -
+can be used to clear data without timespan restriction
+.PD
+.RE
+.RS
+.PP
+.PD 0
+The \fIdataTypes\fP is a comma separated list of following types.
+.TP
+.B memory-cache
+Memory cache.
+.TP
+.B disk-cache
+HTTP disk cache.
+.TP
+.B offline-cache
+Offline web application cache.
+.TP
+.B session-storage
+Session storage data.
+.TP
+.B local-storage
+Local storage data.
+.TP
+.B indexeddb-databases
+IndexedDB databases.
+.TP
+.B plugin-data
+Plugin data.
+.TP
+.B cookies
+Cookies. Note that the cookies are not cleared in case a \fItimespan\fP is
+given.
+.TP
+.B hsts-cache
+HTTP Strict Transport Security cache.
+.sp
+.PP
+.I Example:
+.PD 0
+.IP ":cleardata"
+to clear all known website data types without any timespan restriction.
+.IP ":cleardata - local-storage,session-storage,cookies"
+to completely clear the cookies, local- and session-storage without time
+restrictions.
+.IP ":cleardata 2d4h disk-cache"
+to clear the disk cache that was modified in the past two days and four hours.
+.PD
+.RE
+.TP
+.BI ":sh[ellcmd]! " cmd
+Like :sh[ellcmd] but asynchronous.
+.sp
+Example:
+.EX
+:sh! /bin/sh -c 'echo "`date` $VIMB_URI" >> myhistory.txt'
+.EE
+.TP
 .TP
 .BI ":sh[ellcmd] " cmd
 Runs the given shell \fIcmd\fP syncron and print the output into inputbox.
index 2cc96ea..9a3d224 100644 (file)
--- a/src/ex.c
+++ b/src/ex.c
@@ -42,6 +42,7 @@
 #include "util.h"
 #include "ext-proxy.h"
 #include "autocmd.h"
+#include "util.h"
 
 typedef enum {
 #ifdef FEATURE_AUTOCMD
@@ -52,7 +53,7 @@ typedef enum {
     EX_BMR,
     EX_EVAL,
     EX_HARDCOPY,
-    EX_CLEARCACHE,
+    EX_CLEARDATA,
     EX_CMAP,
     EX_CNOREMAP,
     EX_HANDADD,
@@ -138,7 +139,7 @@ static VbCmdResult ex_autocmd(Client *c, const ExArg *arg);
 static VbCmdResult ex_bookmark(Client *c, const ExArg *arg);
 static VbCmdResult ex_eval(Client *c, const ExArg *arg);
 static void on_eval_script_finished(GDBusProxy *proxy, GAsyncResult *result, Client *c);
-static VbCmdResult ex_clearcache(Client *c, const ExArg *arg);
+static VbCmdResult ex_cleardata(Client *c, const ExArg *arg);
 static VbCmdResult ex_hardcopy(Client *c, const ExArg *arg);
 static void print_failed_cb(WebKitPrintOperation* op, GError *err, Client *c);
 static VbCmdResult ex_map(Client *c, const ExArg *arg);
@@ -179,7 +180,7 @@ static ExInfo commands[] = {
     {"cmap",             EX_CMAP,        ex_map,        EX_FLAG_LHS|EX_FLAG_CMD},
     {"cnoremap",         EX_CNOREMAP,    ex_map,        EX_FLAG_LHS|EX_FLAG_CMD},
     {"cunmap",           EX_CUNMAP,      ex_unmap,      EX_FLAG_LHS},
-    {"clearcache",       EX_CLEARCACHE,  ex_clearcache, EX_FLAG_NONE},
+    {"cleardata",        EX_CLEARDATA,   ex_cleardata,  EX_FLAG_LHS|EX_FLAG_RHS},
     {"hardcopy",         EX_HARDCOPY,    ex_hardcopy,   EX_FLAG_NONE},
     {"handler-add",      EX_HANDADD,     ex_handlers,   EX_FLAG_RHS},
     {"handler-remove",   EX_HANDREM,     ex_handlers,   EX_FLAG_RHS},
@@ -853,10 +854,76 @@ static void on_eval_script_finished(GDBusProxy *proxy, GAsyncResult *result, Cli
     }
 }
 
-static VbCmdResult ex_clearcache(Client *c, const ExArg *arg)
+/**
+ * Clear website data by ':cleardata {time} {dataTypeList}'.
+ */
+static VbCmdResult ex_cleardata(Client *c, const ExArg *arg)
 {
-    webkit_web_context_clear_cache(webkit_web_context_get_default());
-    return CMD_SUCCESS;
+    unsigned int data_types = 0;
+    WebKitWebsiteDataManager *manager;
+    VbCmdResult result = CMD_SUCCESS;
+    GTimeSpan timespan = 0;
+
+    if (arg->lhs->len) {
+        timespan = util_string_to_timespan(arg->lhs->str);
+    }
+    if (!arg->rhs->len) {
+        /* No special type given - clear all known types. */
+        data_types = WEBKIT_WEBSITE_DATA_ALL;
+    } else {
+        GString *str;
+        char **types;
+        char *value;
+        unsigned int len, i, t;
+        gboolean found;
+        static const Arg type_map[] = {
+            {WEBKIT_WEBSITE_DATA_MEMORY_CACHE,              "memory-cache"},
+            {WEBKIT_WEBSITE_DATA_DISK_CACHE,                "disk-cache"},
+            {WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE, "offline-cache"},
+            {WEBKIT_WEBSITE_DATA_SESSION_STORAGE,           "session-storage"},
+            {WEBKIT_WEBSITE_DATA_LOCAL_STORAGE,             "local-storage"},
+            {WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES,       "indexeddb-databases"},
+            {WEBKIT_WEBSITE_DATA_PLUGIN_DATA,               "plugin-data"},
+            {WEBKIT_WEBSITE_DATA_COOKIES,                   "cookies"},
+#if WEBKIT_CHECK_VERSION(2, 26, 0)
+            {WEBKIT_WEBSITE_DATA_HSTS_CACHE,                "hsts-cache"},
+#endif
+            {0, ""},
+        };
+
+        /* Walk through list of data types given as rhs. */
+        types = g_strsplit(arg->rhs->str, ",", -1);
+        len   = g_strv_length(types);
+        str   = g_string_new(NULL);
+
+        /* Loop over given types and collect the type values into bitmap. */
+        for (i = 0; i < len; i++) {
+            value = types[i];
+            found = FALSE;
+            for (t = 0; type_map[t].i; t++) {
+                if (!strcmp(value, type_map[t].s)) {
+                    data_types |= type_map[t].i;
+                    found       = TRUE;
+                    break;
+                }
+            }
+
+            if (!found) {
+                /* collect unknown types to be shown in error message. */
+                g_string_append_printf(str, "%s ", value);
+            }
+        }
+        if (*str->str) {
+            vb_echo(c, MSG_ERROR, TRUE, "unknown data type(s): %s", str->str);
+            result = CMD_ERROR|CMD_KEEPINPUT;
+        }
+        g_string_free(str, TRUE);
+        g_strfreev(types);
+    }
+    manager = webkit_web_context_get_website_data_manager(webkit_web_view_get_context(c->webview));
+    webkit_website_data_manager_clear(manager, data_types, timespan, NULL, NULL, NULL);
+
+    return result;
 }
 
 /**
index 94c9800..fb3052a 100644 (file)
@@ -1110,3 +1110,39 @@ static gboolean match_list(const char *pattern, int patlen, const char *subject)
     }
 }
 
+/**
+ * Get the time span to given string like '1y5dh' (one year and five days and
+ * one hour).
+ */
+GTimeSpan util_string_to_timespan(const char *input)
+{
+    unsigned int multiplier = 0;
+    GTimeSpan sum           = 0;
+    gboolean hasmultiplier  = FALSE;
+
+    while (*input) {
+        if (VB_IS_DIGIT(*input)) {
+            multiplier    = multiplier * 10 + (*input - '0');
+            /* Use separate variable to differentiate between no multiplier
+             * set (is same as 1) or ultiplier of '0'. */
+            hasmultiplier = TRUE;
+        } else {
+            GTimeSpan s = 0;
+            switch (*input) {
+                case 'y': s = 365 * G_TIME_SPAN_DAY; break;
+                case 'w': s = 7 * G_TIME_SPAN_DAY; break;
+                case 'd': s = G_TIME_SPAN_DAY; break;
+                case 'h': s = G_TIME_SPAN_HOUR; break;
+                case 'm': s = G_TIME_SPAN_MINUTE; break;
+                case 's': s = G_TIME_SPAN_SECOND; break;
+            }
+            sum += s * (hasmultiplier ? multiplier : 1);
+            /* Unset multiplier for th epossible next multiplier in input */
+            multiplier    = 0;
+            hasmultiplier = FALSE;
+        }
+        input++;
+    }
+
+    return sum;
+}
index 7edea55..1a70305 100644 (file)
@@ -58,5 +58,6 @@ char *util_strcasestr(const char *haystack, const char *needle);
 char *util_str_replace(const char* search, const char* replace, const char* string);
 char *util_strescape(const char *source, const char *exceptions);
 gboolean util_wildmatch(const char *pattern, const char *subject);
+GTimeSpan util_string_to_timespan(const char *input);
 
 #endif /* end of include guard: _UTIL_H */
index 35cf08d..779a16b 100644 (file)
@@ -298,6 +298,32 @@ static void test_strescape(void)
     }
 }
 
+static void test_string_to_timespan(void)
+{
+    g_assert_cmpuint(util_string_to_timespan("d"), ==, G_TIME_SPAN_DAY);
+    g_assert_cmpuint(util_string_to_timespan("h"), ==, G_TIME_SPAN_HOUR);
+    g_assert_cmpuint(util_string_to_timespan("m"), ==, G_TIME_SPAN_MINUTE);
+    g_assert_cmpuint(util_string_to_timespan("s"), ==, G_TIME_SPAN_SECOND);
+
+    g_assert_cmpuint(util_string_to_timespan("y"), ==, G_TIME_SPAN_DAY * 365);
+    g_assert_cmpuint(util_string_to_timespan("w"), ==, G_TIME_SPAN_DAY * 7);
+
+    /* use counters */
+    g_assert_cmpuint(util_string_to_timespan("1s"), ==, G_TIME_SPAN_SECOND);
+    g_assert_cmpuint(util_string_to_timespan("2s"), ==, 2 * G_TIME_SPAN_SECOND);
+    g_assert_cmpuint(util_string_to_timespan("34s"), ==, 34 * G_TIME_SPAN_SECOND);
+    g_assert_cmpuint(util_string_to_timespan("0s"), ==, 0);
+
+    /* combine counters and different units */
+    g_assert_cmpuint(util_string_to_timespan("ds"), ==, G_TIME_SPAN_DAY + G_TIME_SPAN_SECOND);
+    g_assert_cmpuint(util_string_to_timespan("2dh0s"), ==, (2 * G_TIME_SPAN_DAY) + G_TIME_SPAN_HOUR);
+
+    /* unparsabel values */
+    g_assert_cmpuint(util_string_to_timespan(""), ==, 0);
+    g_assert_cmpuint(util_string_to_timespan("-"), ==, 0);
+    g_assert_cmpuint(util_string_to_timespan("5-"), ==, 0);
+}
+
 int main(int argc, char *argv[])
 {
     g_test_init(&argc, &argv, NULL);
@@ -316,6 +342,7 @@ int main(int argc, char *argv[])
     g_test_add_func("/test-util/wildmatch-complete", test_wildmatch_complete);
     g_test_add_func("/test-util/wildmatch-multi", test_wildmatch_multi);
     g_test_add_func("/test-util/strescape", test_strescape);
+    g_test_add_func("/test-util/string_to_timespan", test_string_to_timespan);
 
     return g_test_run();
 }