Hey everyone,

because I hit a nasty bug with https and the wget
downloader("Not authorized") I ported the internal
downloader patch to surf 0.5. I tried to improve
the interface a bit and add a progress bar.

Feel free to improve the code. Some ideas would include
- cancel button (a bit tricky I suppose)
- /one/ window for all downloads
- when multiple downloads are open only some of them
  recieve callbacks for some reason
- fix frontend for <1K files. The download is finished,
  before the window is rendered. The JS misses the
  finish signal.
- reasonable default window sizes for non-tiling WM?
- further improve layout


v4hn
diff --git a/config.def.h b/config.def.h
index 1cba4d7..3065c73 100644
--- a/config.def.h
+++ b/config.def.h
@@ -11,6 +11,7 @@ static char *progress_proxy_untrust = "#FF6600";
 static char *stylefile      = "~/.surf/style.css";
 static char *scriptfile     = "~/.surf/script.js";
 static char *cookiefile     = "~/.surf/cookies.txt";
+static char *downdir        = "/tmp";
 static time_t sessiontime   = 3600;
 static char *cafile         = "/etc/ssl/certs/ca-certificates.crt";
 static char *strictssl      = FALSE; /* Refuse untrusted SSL connections */
diff --git a/surf.c b/surf.c
index c9fa08d..6c95f6e 100644
--- a/surf.c
+++ b/surf.c
@@ -114,6 +114,7 @@ static void destroyclient(Client *c);
 static void destroywin(GtkWidget* w, Client *c);
 static void die(const char *errstr, ...);
 static void drawindicator(Client *c);
+static void download(WebKitDownload *o, GParamSpec *pspec, Client *c);
 static void eval(Client *c, const Arg *arg);
 static gboolean exposeindicator(GtkWidget *w, GdkEventExpose *e, Client *c);
 static void find(Client *c, const Arg *arg);
@@ -290,6 +291,29 @@ cookiejar_set_property(GObject *self, guint prop_id, const 
GValue *value,
 }
 
 static void
+download(WebKitDownload *o, GParamSpec *pspec, Client *c) {
+       WebKitDownloadStatus status;
+       char script[2048]; char* s= script;
+
+       status = webkit_download_get_status(o);
+       if(status == WEBKIT_DOWNLOAD_STATUS_STARTED || status == 
WEBKIT_DOWNLOAD_STATUS_CREATED) {
+               snprintf(script, 2048, "u(%d, %d, %d)",
+                        (gint)webkit_download_get_current_size(o),
+                        (gint)webkit_download_get_total_size(o),
+                        (gint)(webkit_download_get_progress(o) * 100));
+               const Arg a= {.v = (void*) &s};
+               eval(c, &a);
+       }
+       else if (status == WEBKIT_DOWNLOAD_STATUS_FINISHED){
+               snprintf(script, 2048, "c(%d, %d)",
+                        (gint)webkit_download_get_current_size(o),
+                        (gint)webkit_download_get_total_size(o));
+               const Arg a= {.v = (void*) &s};
+               eval(c, &a);
+       }
+}
+
+static void
 evalscript(JSContextRef js, char *script, char* scriptname) {
        JSStringRef jsscript, jsscriptname;
        JSValueRef exception = NULL;
@@ -496,12 +520,104 @@ geturi(Client *c) {
 
 static gboolean
 initdownload(WebKitWebView *view, WebKitDownload *o, Client *c) {
-       Arg arg;
+       gchar *uri, *path;
+       const gchar *filename;
+       Client *n;
+       const char template[] =
+"<html>" \
+"<head>" \
+"<title>Download - %s</title>" \
+"<script>" \
+"function formText(x){" \
+"  if(x >= 1073741824)  { return (Math.floor(x/10737418.24)/100) + \"G\"; }" \
+"  else if(x >= 1048576){ return (Math.floor(x/10485.76)/100) + \"M\"; }" \
+"  else if(x >= 1024)   { return (Math.floor(x/10.24)/100) + \"k\"; }" \
+"  else                 { return x+\"b\"; }" \
+"}" \
+"function updateText(c,t){" \
+"  txt= formText(c) + \"/\" + formText(t);" \
+"  DLTEXT.textContent= txt;" \
+"  /* center text in bar */" \
+"  DLTEXT.setAttribute('x', 102-4.4*txt.length)" \
+"}" \
+"function c(c, t){" \
+"  DLGRAD.setAttribute('x2', 230);" \
+"  DLGRAD.setAttribute('x1', 205);" \
+"  updateText(c,t);" \
+"  document.getElementById('stop1').setAttribute('style', 
\"stop-color:#2020ff;\");" \
+"}" \
+"function u(c,t,p){" \
+"  DLGRAD.setAttribute('x2', Math.floor(p*205/100) + 25);" \
+"  DLGRAD.setAttribute('x1', Math.floor(p*205/100));" \
+"  updateText(c,t);" \
+"}" \
+"</script>" \
+"</head>" \
+"<body>" \
+"<center>" \
+"<h2>Downloading</h2>" \
+"<h3>%s</h3>" \
+"to %s<br/>" \
+"<svg" \
+"   xmlns:cc=\"http://creativecommons.org/ns#\""; \
+"   xmlns:svg=\"http://www.w3.org/2000/svg\""; \
+"   xmlns=\"http://www.w3.org/2000/svg\""; \
+"   xmlns:xlink=\"http://www.w3.org/1999/xlink\""; \
+"   width=\"210\"" \
+"   height=\"60\"" \
+"   id=\"download\">" \
+"  <defs>" \
+"    <linearGradient" \
+"       id=\"dlgradient\"" \
+"       x1=\"0\"" \
+"       y1=\"0\"" \
+"       x2=\"25\"" \
+"       y2=\"0\"" \
+"       gradientUnits=\"userSpaceOnUse\">" \
+"      <stop style=\"stop-color:#00ff00;\" offset=\"0\" id=\"stop1\" />" \
+"      <stop style=\"stop-color:#00ff00;stop-opacity:0;\" offset=\"1\" 
id=\"stop2\" />" \
+"    </linearGradient>" \
+"  </defs>" \
+"    <rect" \
+"       style=\"fill:url(#dlgradient);stroke:#000000;stroke-width:3\"" \
+"       id=\"rect2985\"" \
+"       width=\"200\"" \
+"       height=\"50\"" \
+"       x=\"5\"" \
+"       y=\"5\"" \
+"       ry=\"25\" />" \
+"    <text id=\"dltext\" x=\"92\" y=\"35\">0/0</text>" \
+"</svg>" \
+"</center>" \
+"<script>" \
+"DLGRAD= document.getElementById('dlgradient');" \
+"DLTEXT= document.getElementById('dltext');" \
+"</script>" \
+"</body>" \
+"</html>";
+       char html[sizeof(template)+2048];
+       n = newclient();
+       filename = webkit_download_get_suggested_filename(o);
+
+       path = g_build_filename(downdir, filename, NULL);
+       uri = g_filename_to_uri(path, NULL, NULL);
+
+       snprintf(html, sizeof(template)+2048, template, filename, filename, 
path);
+       webkit_web_view_load_string(n->view, html, NULL, NULL, NULL);
+
+       g_signal_connect(o, "notify::progress", G_CALLBACK(download), n);
+       g_signal_connect(o, "notify::status", G_CALLBACK(download), n);
+       n->title = g_strdup_printf("Downloading %s", filename);
+       n->progress = 0;
+       update(n);
+
+       webkit_download_set_destination_uri(o, uri);
+       g_free(path);
+       g_free(uri);
 
-       updatewinid(c);
-       arg = (Arg)DOWNLOAD((char *)webkit_download_get_uri(o), geturi(c));
-       spawn(c, &arg);
-       return FALSE;
+       webkit_download_start(o);
+
+       return TRUE;
 }
 
 static void

Attachment: pgpgS43LCdKuF.pgp
Description: PGP signature

Reply via email to