Add external download command #543 #348.
authorDaniel Carl <danielcarl@gmx.de>
Sat, 18 May 2019 22:29:23 +0000 (00:29 +0200)
committerDaniel Carl <danielcarl@gmx.de>
Sat, 18 May 2019 22:41:00 +0000 (00:41 +0200)
Added 'download-command' setting to configure a command/script that
handles the download of an uri. With the new setting flag
'download-use-external' can be decided if the external download command
is used to download an uri or the built in downloader.

doc/vimb.1
src/main.c
src/setting.c

index b5d854e..e2bebaa 100644 (file)
@@ -1044,6 +1044,29 @@ Default Full-Content zoom level in percent. Default is 100.
 .B dns-prefetching (bool)
 Indicates if Vimb prefetches domain names.
 .TP
+.B download-command (string)
+A command with placeholder '%s' that will be invoked to download a URI in
+case 'download-use-external' is enabled.
+.RS
+.TP
+The following additional environment variable are available:
+.PD 0
+.TP
+.B $VIMB_URI
+The URI of the current opened page, normally the page where the download was
+started from, also known as referer.
+.TP
+.B $VIMB_DOWNLOAD_PATH
+Setting value of 'dowanload-path' which would be used normally for downloads.
+.PD
+.PP
+Example:
+.PD 0
+.IP ":set download-command=/bin/sh -c ""cd '$VIMB_DOWNLOAD_PATH' \
+&& curl -sLJOC - -e '$VIMB_URI' %s"""
+.PD
+.RE
+.TP
 .B download-path (string)
 Path to the default download directory.
 If no download directory is set, download will be written into current
@@ -1051,6 +1074,11 @@ directory.
 The following pattern will be expanded if the download is
 started '~/', '~user', '$VAR' and '${VAR}'.
 .TP
+.B download-use-external (bool)
+Indicates if the external download tool set as 'download-command' should be
+used to handle downloads.
+If this is disabled Vimb will handle the download.
+.TP
 .B editor-command (string)
 Command with placeholder '%s' called if form field is opened with $EDITOR to
 spawn the editor-like `x-terminal-emulator -e vim %s'.
index e5193c8..26735e6 100644 (file)
@@ -63,6 +63,9 @@ static void on_webctx_download_started(WebKitWebContext *webctx,
 static void on_webctx_init_web_extension(WebKitWebContext *webctx, gpointer data);
 static gboolean on_webdownload_decide_destination(WebKitDownload *download,
         gchar *suggested_filename, Client *c);
+static void on_webdownload_response_received(WebKitDownload *download,
+        GParamSpec *ps, Client *c);
+static void spawn_download_command(Client *c, WebKitURIResponse *response);
 static void on_webdownload_failed(WebKitDownload *download,
         GError *error, Client *c);
 static void on_webdownload_finished(WebKitDownload *download, Client *c);
@@ -1070,15 +1073,19 @@ static void on_webctx_download_started(WebKitWebContext *webctx,
     autocmd_run(c, AU_DOWNLOAD_STARTED, uri, NULL);
 #endif
 
-    g_signal_connect(download, "decide-destination", G_CALLBACK(on_webdownload_decide_destination), c);
-    g_signal_connect(download, "failed", G_CALLBACK(on_webdownload_failed), c);
-    g_signal_connect(download, "finished", G_CALLBACK(on_webdownload_finished), c);
-    g_signal_connect(download, "received-data", G_CALLBACK(on_webdownload_received_data), c);
+    if (GET_BOOL(c, "download-use-external")) {
+        g_signal_connect(download, "notify::response", G_CALLBACK(on_webdownload_response_received), c);
+    } else {
+        g_signal_connect(download, "decide-destination", G_CALLBACK(on_webdownload_decide_destination), c);
+        g_signal_connect(download, "failed", G_CALLBACK(on_webdownload_failed), c);
+        g_signal_connect(download, "finished", G_CALLBACK(on_webdownload_finished), c);
+        g_signal_connect(download, "received-data", G_CALLBACK(on_webdownload_received_data), c);
 
-    c->state.downloads = g_list_append(c->state.downloads, download);
+        c->state.downloads = g_list_append(c->state.downloads, download);
 
-    /* to reflect the correct download count */
-    vb_statusbar_update(c);
+        /* to reflect the correct download count */
+        vb_statusbar_update(c);
+    }
 }
 
 /**
@@ -1120,6 +1127,48 @@ static gboolean on_webdownload_decide_destination(WebKitDownload *download,
     return vb_download_set_destination(c, download, suggested_filename, NULL);
 }
 
+static void on_webdownload_response_received(WebKitDownload *download,
+        GParamSpec *ps, Client *c)
+{
+    spawn_download_command(c, webkit_download_get_response(download));
+       webkit_download_cancel(download);
+}
+
+static void spawn_download_command(Client *c, WebKitURIResponse *response)
+{
+    char *cmd;
+    char **argv, **envp;
+    int argc;
+    GError *error = NULL;
+
+    cmd = g_strdup_printf(GET_CHAR(c, "download-command"),
+            webkit_uri_response_get_uri(response));
+
+    if (!g_shell_parse_argv(cmd, &argc, &argv, &error)) {
+        g_warning("Could not parse download-command '%s': %s",
+                cmd,
+                error->message);
+        g_error_free(error);
+        g_free(cmd);
+        return;
+    }
+
+    envp = g_get_environ();
+    envp = g_environ_setenv(envp, "VIMB_DOWNLOAD_PATH",
+            GET_CHAR(c, "download-path"), TRUE);
+
+    if (g_spawn_async(NULL, argv, envp, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) {
+        vb_echo(c, MSG_NORMAL, FALSE, "Download started");
+    } else {
+        vb_echo(c, MSG_ERROR, TRUE, "Could not start download");
+        g_warning("%s", error->message);
+        g_clear_error(&error);
+    }
+    g_free(cmd);
+    g_strfreev(envp);
+    g_strfreev(argv);
+}
+
 /**
  * Callback for the webkit download failed signal.
  * This signal is emitted when an error occurs during the download operation.
index 51883ee..07218ba 100644 (file)
@@ -150,6 +150,8 @@ void setting_init(Client *c)
     i = 100;
     setting_add(c, "default-zoom", TYPE_INTEGER, &i, default_zoom, 0, NULL);
     setting_add(c, "download-path", TYPE_CHAR, &"~/", NULL, 0, NULL);
+    setting_add(c, "download-command", TYPE_CHAR, &"/bin/sh -c \"curl -sLJOC - -e '$VIMB_URI' %s\"", NULL, 0, NULL);
+    setting_add(c, "download-use-external", TYPE_BOOLEAN, &off, NULL, 0, NULL);
     setting_add(c, "incsearch", TYPE_BOOLEAN, &off, internal, 0, &c->config.incsearch);
     i = 10;
     /* TODO should be global and not overwritten by a new client */
@@ -158,7 +160,7 @@ void setting_init(Client *c)
     setting_add(c, "spell-checking", TYPE_BOOLEAN, &off, webkit_spell_checking, 0, NULL);
     setting_add(c, "spell-checking-languages", TYPE_CHAR, &"en_US", webkit_spell_checking_language, FLAG_LIST|FLAG_NODUP, NULL);
 
-    /* gui style settings vimb3 */
+    /* gui style settings vimb */
     setting_add(c, "completion-css", TYPE_CHAR, &"color:#fff;background-color:#656565;font:" SETTING_GUI_FONT_NORMAL, gui_style, 0, NULL);
     setting_add(c, "completion-hover-css", TYPE_CHAR, &"background-color:#777;", gui_style, 0, NULL);
     setting_add(c, "completion-selected-css", TYPE_CHAR, &"color:#f6f3e8;background-color:#888;", gui_style, 0, NULL);