summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Carl <danielcarl@gmx.de>2017-04-20 22:45:31 +0200
committerDaniel Carl <danielcarl@gmx.de>2017-04-20 22:45:31 +0200
commit597a0acfd9e35f6516a6c5069fdf651416e9f11c (patch)
tree76454c378835df19e20446b2f9959df0f299599a
parent5c7059196850118f4e9435797cedd155661748af (diff)
Added :save command.
-rw-r--r--src/command.c9
-rw-r--r--src/main.c150
-rw-r--r--src/main.h3
-rw-r--r--src/util.c49
-rw-r--r--src/util.h2
5 files changed, 141 insertions, 72 deletions
diff --git a/src/command.c b/src/command.c
index 7fbc878..4913ddc 100644
--- a/src/command.c
+++ b/src/command.c
@@ -143,8 +143,8 @@ gboolean command_yank(Client *c, const Arg *arg, char buf)
gboolean command_save(Client *c, const Arg *arg)
{
-#if 0
const char *uri, *path = NULL;
+ WebKitDownload *download;
if (arg->i == COMMAND_SAVE_CURRENT) {
uri = c->state.uri;
@@ -159,10 +159,11 @@ gboolean command_save(Client *c, const Arg *arg)
if (!uri || !*uri) {
return FALSE;
}
-#endif
- /* TODO start the download to given path here */
- return TRUE;
+ /* Start the download to given path. */
+ download = webkit_web_view_download_uri(c->webview, uri);
+
+ return vb_download_set_destination(c, download, NULL, path);
}
#ifdef FEATURE_QUEUE
diff --git a/src/main.c b/src/main.c
index 67e3486..7b0f4ba 100644
--- a/src/main.c
+++ b/src/main.c
@@ -97,6 +97,86 @@ static void on_script_message_focus(WebKitUserContentManager *manager,
struct Vimb vb;
+/**
+ * Set the destination for a download according to suggested file name and
+ * possible given path.
+ */
+gboolean vb_download_set_destination(Client *c, WebKitDownload *download,
+ char *suggested_filename, const char *path)
+{
+ char *download_path, *dir, *file, *uri;
+ download_path = GET_CHAR(c, "download-path");
+
+ /* For unnamed downloads set default filename. */
+ if (!suggested_filename || !*suggested_filename) {
+ suggested_filename = "vimb-download";
+ }
+
+ /* Prepare the path to save the download. */
+ if (path && *path) {
+ file = util_build_path(c, path, download_path);
+
+ /* if file is an directory append a file name */
+ if (g_file_test(file, (G_FILE_TEST_IS_DIR))) {
+ dir = file;
+ file = g_build_filename(dir, suggested_filename, NULL);
+ g_free(dir);
+ }
+ } else {
+ file = util_build_path(c, suggested_filename, download_path);
+ }
+
+ /* If the filepath exists already insert numerical suffix before file
+ * extension. */
+ if (g_file_test(file, G_FILE_TEST_EXISTS)) {
+ const char *dot_pos;
+ char *num = NULL;
+ GString *tmp;
+ gssize suffix;
+ int i = 1;
+ suffix = 2;
+
+ /* position on .tar. (special case, extension with two dots),
+ * position on last dot (if any) otherwise */
+ if (!(dot_pos = strstr(file, ".tar."))) {
+ dot_pos = strrchr(file, '.');
+ }
+
+ /* the position to insert the suffix at */
+ if (dot_pos) {
+ suffix = dot_pos - file;
+ } else {
+ suffix = strlen(file);
+ }
+
+ tmp = g_string_new(NULL);
+ num = g_strdup_printf("%d", i++);
+
+ /* Construct a new complete odwnload filepath with suffic before the
+ * file extension. */
+ do {
+ num = g_strdup_printf("%d", i++);
+ g_string_assign(tmp, file);
+ g_string_insert(tmp, suffix, num);
+ g_free(num);
+ } while (g_file_test(tmp->str, G_FILE_TEST_EXISTS));
+
+ file = g_strdup(tmp->str);
+ g_string_free(tmp, TRUE);
+ }
+
+ /* Build URI from filepath. */
+ uri = g_filename_to_uri(file, NULL, NULL);
+ g_free(file);
+
+ /* configure download */
+ g_assert(uri);
+ webkit_download_set_allow_overwrite(download, FALSE);
+ webkit_download_set_destination(download, uri);
+ g_free(uri);
+
+ return TRUE;
+}
/**
* Write text to the inpubox if this isn't focused.
@@ -822,75 +902,11 @@ static void on_webctx_init_web_extension(WebKitWebContext *webctx, gpointer data
static gboolean on_webdownload_decide_destination(WebKitDownload *download,
gchar *suggested_filename, Client *c)
{
- g_assert(download);
- g_assert(suggested_filename);
- g_assert(c);
-
- char *path, *filename, *uri;
- GString *expanded, *filepath;
- const char *extension_dot;
- int suffix;
- gssize suffix_pos;
-
- /* get the download path from settings */
- path = GET_CHAR(c, "download-path");
- g_assert(path);
-
- /* expand any ~ or $VAR patterns in download path */
- expanded = g_string_new(NULL);
- util_parse_expansion(c, (const char**)&path, expanded, UTIL_EXP_TILDE|UTIL_EXP_DOLLAR, "");
- g_string_append(expanded, path + 1);
-
- /* for unnamed downloads set default filename */
- filename = strlen(suggested_filename) ? suggested_filename : "vimb-download";
-
- /* construct complete download filepath */
- filepath = g_string_new(NULL);
- g_string_printf(filepath, "%s%c%s", expanded->str, G_DIR_SEPARATOR, filename);
-
- /* if the filepath exists already
- * insert numerical suffix before file extension */
- if (g_file_test(filepath->str, G_FILE_TEST_EXISTS)) {
- suffix = 2;
-
- /* position on .tar. (special case, extension with two dots),
- * position on last dot (if any) otherwise */
- if (!(extension_dot = strstr(filename, ".tar."))) {
- extension_dot = strrchr(filename, '.');
- }
-
- /* the position to insert the suffix at */
- if (extension_dot) {
- suffix_pos = extension_dot - filename;
- } else {
- suffix_pos = strlen(filename);
- }
-
- /* construct a new complete download filepath and add the suffix before
- * the filename extension, keep incrementing the suffix value as long
- * as the filepath exists, stop on first unused filename. */
- do {
- g_string_printf(filepath, "%s%c%.*s_%i%s",
- expanded->str, G_DIR_SEPARATOR,
- (int)suffix_pos, filename,
- suffix++, filename + suffix_pos);
- } while (g_file_test(filepath->str, G_FILE_TEST_EXISTS));
+ if (webkit_download_get_destination(download)) {
+ return TRUE;
}
- /* build URI from filepath */
- uri = g_filename_to_uri(filepath->str, NULL, NULL);
- g_assert(uri);
-
- /* configure download */
- webkit_download_set_allow_overwrite(download, FALSE);
- webkit_download_set_destination(download, uri);
-
- /* cleanup */
- g_string_free(expanded, TRUE);
- g_string_free(filepath, TRUE);
- g_free(uri);
-
- return TRUE;
+ return vb_download_set_destination(c, download, suggested_filename, NULL);
}
/**
diff --git a/src/main.h b/src/main.h
index 9d016a5..e4b969d 100644
--- a/src/main.h
+++ b/src/main.h
@@ -263,7 +263,8 @@ struct Vimb {
GtkCssProvider *style_provider;
};
-
+gboolean vb_download_set_destination(Client *c, WebKitDownload *download,
+ char *suggested_filename, const char *path);
void vb_echo(Client *c, MessageType type, gboolean hide, const char *error, ...);
void vb_echo_force(Client *c, MessageType type, gboolean hide, const char *error, ...);
void vb_enter(Client *c, char id);
diff --git a/src/util.c b/src/util.c
index 3430a58..b392876 100644
--- a/src/util.c
+++ b/src/util.c
@@ -36,6 +36,48 @@ static struct {
static void create_dir_if_not_exists(const char *dirpath);
+/**
+ * Build the absolute file path of given path and possible given directory.
+ *
+ * Returned path must be freed.
+ */
+char *util_build_path(Client *c, const char *path, const char *dir)
+{
+ char *fullPath = NULL, *fexp, *dexp, *p;
+ int expflags = UTIL_EXP_TILDE|UTIL_EXP_DOLLAR;
+
+ /* if the path could be expanded */
+ if ((fexp = util_expand(c, path, expflags))) {
+ if (*fexp == '/') {
+ /* path is already absolute, no need to use given dir - there is
+ * no need to free fexp, bacuse this should be done by the caller
+ * on fullPath later */
+ fullPath = fexp;
+ } else if (dir && *dir) {
+ /* try to expand also the dir given - this may be ~/path */
+ if ((dexp = util_expand(c, dir, expflags))) {
+ /* use expanded dir and append expanded path */
+ fullPath = g_build_filename(dexp, fexp, NULL);
+ g_free(dexp);
+ }
+ g_free(fexp);
+ }
+ }
+
+ /* if full path not found use current dir */
+ if (!fullPath) {
+ fullPath = g_build_filename(g_get_current_dir(), path, NULL);
+ }
+
+ /* Create the directory part of the path if it does not exists. */
+ if ((p = strrchr(fullPath, '/'))) {
+ *p = '\0';
+ util_create_dir_if_not_exists(fullPath);
+ *p = '/';
+ }
+
+ return fullPath;
+}
/**
* Free memory for allocated path strings.
@@ -47,6 +89,13 @@ void util_cleanup(void)
}
}
+void util_create_dir_if_not_exists(const char *dirpath)
+{
+ if (!g_file_test(dirpath, G_FILE_TEST_IS_DIR)) {
+ g_mkdir_with_parents(dirpath, 0755);
+ }
+}
+
/**
* Expand ~user, ~/, $ENV and ${ENV} for given string into new allocated
* string.
diff --git a/src/util.h b/src/util.h
index a9fd042..63f5046 100644
--- a/src/util.h
+++ b/src/util.h
@@ -30,7 +30,9 @@ enum {
};
typedef void *(*Util_Content_Func)(const char*, const char*);
+char *util_build_path(Client *c, const char *path, const char *dir);
void util_cleanup(void);
+void util_create_dir_if_not_exists(const char *dirpath);
char *util_expand(Client *c, const char *src, int expflags);
gboolean util_file_append(const char *file, const char *format, ...);
gboolean util_file_prepend(const char *file, const char *format, ...);