[Conkeror] [PATCH] save_uri: optionally use a temporary download file

David Kettler kettler at internode.on.net
Wed Feb 11 03:24:20 PST 2009


This is useful when it is undesirable for some other tool to attempt
to open the downloaded file before it is complete.

If $temp_file is specified then the uri is downloaded to that file and
then renamed to the output_file when the download is finished.  If
$temp_file is the value true then a new temporary file in the same
directory as output_file is used.

The download manager indicates this by showing the output_file name
parenthetically.

Note that this save_uri usage of the term "temporary" is different to
the download-manager usage; in that case the file is deleted, not
renamed.
---

In particular this addresses problem (1a) discussed in "[PATCH v2] New
module to define webjumps for git repository summaries".

I added another property, finished_function, to download_info.  It
would be possible to use download_finished_hook, but that's probably
inappropriate for internal functionality like this.  It would be
possible to subsume the shell_command stuff into finished_function.

The file rename will foil download-delete-target.  I was undecided as
to whether that should be fixed or if it's better as is.  The deletion uses
  download_manager_service.removeDownload(this.id);
so it will either need to be handled separately, or the state of the
nsIDownloadManager will need fiddling.
---
 modules/download-manager.js |   14 +++++++++++++-
 modules/save.js             |   17 +++++++++++++++--
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/modules/download-manager.js b/modules/download-manager.js
index dda61b7..bc1f292 100644
--- a/modules/download-manager.js
+++ b/modules/download-manager.js
@@ -181,6 +181,8 @@ download_info.prototype = {
         download_added_hook.run(this);
     },
 
+    finished_function : null,
+
     shell_command : null,
 
     shell_command_cwd : null,
@@ -203,6 +205,7 @@ download_info.prototype = {
     // Reflectors to properties of nsIDownload
     get state () { return this.mozilla_info.state; },
     get target_file () { return this.mozilla_info.targetFile; },
+    get display_name () { return this.mozilla_info.displayName; },
     get amount_transferred () { return this.mozilla_info.amountTransferred; },
     get percent_complete () { return this.mozilla_info.percentComplete; },
     get size () {
@@ -428,6 +431,9 @@ var download_progress_listener = {
                 if (info.state == DOWNLOAD_FINISHED) {
                     download_finished_hook.run(info);
 
+                    if (info.finished_function != null)
+                        info.finished_function();
+
                     if (info.shell_command != null) {
                         info.running_shell_command = true;
                         co_call(function () {
@@ -719,7 +725,13 @@ download_buffer.prototype = {
             target_label = "Target:";
         g.text(target_label, label);
         value = g.element("div", div, "class", "download-value");
-        g.text(info.target_file.path, value);
+        {
+            let target = info.target_file.path;
+            let display = info.display_name;
+            if (target.indexOf(display, target.length - display.length) == -1)
+                target = target + " (" + display + ")";
+            g.text(target, value);
+        }
 
         div = g.element("div", d.body, "class", "download-info", "id", "download-mime-type");
         label = g.element("div", div, "class", "download-label");
diff --git a/modules/save.js b/modules/save.js
index 23e7115..3228411 100644
--- a/modules/save.js
+++ b/modules/save.js
@@ -12,7 +12,7 @@ require("load-spec.js");
 require("suggest-file-name.js");
 
 /* buffer is used only to associate with the download */
-define_keywords("$use_cache", "$buffer", "$prepare_download");
+define_keywords("$use_cache", "$buffer", "$prepare_download", "$temp_file");
 function save_uri(lspec, output_file) {
     keywords(arguments, $use_cache = true);
 
@@ -22,6 +22,15 @@ function save_uri(lspec, output_file) {
 
     var prepare_download = arguments.$prepare_download;
 
+    var temp_file = arguments.$temp_file;
+    if (temp_file == true) {
+        temp_file = Cc["@mozilla.org/file/local;1"]
+            .createInstance(Ci.nsILocalFile);
+        temp_file.initWithFile(output_file);
+        temp_file.leafName = "temp";
+        temp_file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
+    }
+
     var cache_key = null;
     var uri = load_spec_uri(lspec);
     var referrer_uri = load_spec_referrer(lspec);
@@ -29,7 +38,7 @@ function save_uri(lspec, output_file) {
     if (use_cache)
         cache_key = load_spec_cache_key(lspec);
 
-    var file_uri = make_uri(output_file);
+    var file_uri = make_uri(temp_file || output_file);
 
     var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
         .createInstance(Ci.nsIWebBrowserPersist);
@@ -45,6 +54,10 @@ function save_uri(lspec, output_file) {
         persist.persistFlags |= Ci.nsIWebBrowserPersist.PERSIST_FLAGS_BYPASS_CACHE;
 
     var info = register_download(buffer, uri);
+    if (temp_file)
+        info.finished_function = function() {
+            temp_file.moveTo(null, output_file.leafName);
+        };
     if (prepare_download)
         prepare_download(info);
 
-- 
1.5.6.5



More information about the Conkeror mailing list