From: Daniel Carl Date: Wed, 9 Oct 2019 00:15:57 +0000 (+0200) Subject: Added :clearcache by :cleardata command. X-Git-Url: https://git.owens.tech/assets/favicon.png/assets/favicon.png/git?a=commitdiff_plain;h=1072026d60569248ecfcba7fd8ed4bf9eedffd9b;p=vimb.git Added :clearcache by :cleardata command. Allow to clear different types of website data base on the last update time. --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 77b6fc7..3edb230 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/doc/vimb.1 b/doc/vimb.1 index e86d561..8b7ffa9 100644 --- a/doc/vimb.1 +++ b/doc/vimb.1 @@ -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. diff --git a/src/ex.c b/src/ex.c index 2cc96ea..9a3d224 100644 --- 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; } /** diff --git a/src/util.c b/src/util.c index 94c9800..fb3052a 100644 --- a/src/util.c +++ b/src/util.c @@ -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; +} diff --git a/src/util.h b/src/util.h index 7edea55..1a70305 100644 --- a/src/util.h +++ b/src/util.h @@ -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 */ diff --git a/tests/test-util.c b/tests/test-util.c index 35cf08d..779a16b 100644 --- a/tests/test-util.c +++ b/tests/test-util.c @@ -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(); }