New implementation of a download function #2216
This resolves a problem where, in certain scenarios, Zotero.file.download throws an exception even though file is successfully downloaded. Furthermore this new download function should be more memory-efficient, improving performance when dealing with large files.
This commit is contained in:
parent
a08c3dee14
commit
a745cde2cf
1 changed files with 45 additions and 25 deletions
|
@ -446,8 +446,7 @@ Zotero.File = new function(){
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
this.download = Zotero.Promise.coroutine(function* (uri, path) {
|
||||
this.download = async function (uri, path) {
|
||||
var uriStr = uri.spec || uri;
|
||||
|
||||
Zotero.debug(`Saving ${uriStr} to ${path.pathQueryRef || path}`);
|
||||
|
@ -459,7 +458,24 @@ Zotero.File = new function(){
|
|||
}
|
||||
|
||||
var deferred = Zotero.Promise.defer();
|
||||
NetUtil.asyncFetch(uri, function (is, status, request) {
|
||||
const uri_ = NetUtil.ioService.newURI(uri);
|
||||
const inputChannel = NetUtil.ioService.newChannelFromURI(uri_);
|
||||
const outputChannel = FileUtils.openSafeFileOutputStream(new FileUtils.File(path));
|
||||
const pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
|
||||
pipe.init(true, true, 0, 0xffffffff, null);
|
||||
|
||||
let listener = Cc[
|
||||
"@mozilla.org/network/simple-stream-listener;1"
|
||||
].createInstance(Ci.nsISimpleStreamListener);
|
||||
|
||||
listener.init(pipe.outputStream, {
|
||||
onStartRequest(request) {
|
||||
// NOTE: This noop callback is required, do not remove.
|
||||
},
|
||||
onStopRequest(request, status) {
|
||||
const responseStatus = 'responseStatus' in request ? request.responseStatus : null;
|
||||
pipe.outputStream.close();
|
||||
|
||||
if (!Components.isSuccessCode(status)) {
|
||||
Zotero.logError(status);
|
||||
let msg = Zotero.getString('sync.error.checkConnection');
|
||||
|
@ -472,18 +488,22 @@ Zotero.File = new function(){
|
|||
deferred.reject(new Error(msg));
|
||||
return;
|
||||
}
|
||||
if (request.responseStatus != 200) {
|
||||
let msg = `Download failed with response code ${request.responseStatus}`;
|
||||
if (responseStatus != 200) {
|
||||
let msg = `Download failed with response code ${responseStatus}`;
|
||||
Zotero.logError(msg);
|
||||
deferred.reject(new Error(msg));
|
||||
return;
|
||||
}
|
||||
deferred.resolve(is);
|
||||
});
|
||||
var is = yield deferred.promise;
|
||||
yield Zotero.File.putContentsAsync(path, is);
|
||||
}
|
||||
});
|
||||
|
||||
NetUtil.asyncCopy(pipe.inputStream, outputChannel, function(aResult) {
|
||||
deferred.resolve();
|
||||
});
|
||||
inputChannel.asyncOpen(listener, null);
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Rename file within its parent directory
|
||||
|
|
Loading…
Reference in a new issue