Merge pull request #717 from aurimasv/api_syncing-677
[api_syncing] Merge 849803473a
This commit is contained in:
commit
f74d591883
2 changed files with 173 additions and 172 deletions
|
@ -92,6 +92,11 @@ Zotero.MIME = new function(){
|
||||||
'application/x-javascript': true
|
'application/x-javascript': true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var _webPageTypes = [
|
||||||
|
'text/html',
|
||||||
|
'application/xhtml+xml'
|
||||||
|
]
|
||||||
|
|
||||||
// MIME types handled natively by Gecko
|
// MIME types handled natively by Gecko
|
||||||
// DEBUG: There's definitely a better way of getting these
|
// DEBUG: There's definitely a better way of getting these
|
||||||
var _nativeMIMETypes = {
|
var _nativeMIMETypes = {
|
||||||
|
@ -122,6 +127,9 @@ Zotero.MIME = new function(){
|
||||||
return mimeType.substr(0, 5) == 'text/' || _textTypes[mimeType];
|
return mimeType.substr(0, 5) == 'text/' || _textTypes[mimeType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.isWebPageType = function(mimeType) {
|
||||||
|
return _webPageTypes.indexOf(mimeType) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our own wrapper around the MIME service's getPrimaryExtension() that
|
* Our own wrapper around the MIME service's getPrimaryExtension() that
|
||||||
|
|
|
@ -39,15 +39,6 @@ Zotero.Translate.ItemSaver = function(libraryID, attachmentMode, forceTagType, d
|
||||||
this._libraryID = libraryID;
|
this._libraryID = libraryID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine whether to save files and attachments
|
|
||||||
if (attachmentMode == Zotero.Translate.ItemSaver.ATTACHMENT_MODE_DOWNLOAD) {
|
|
||||||
this._saveAttachment = this._saveAttachmentDownload;
|
|
||||||
} else if(attachmentMode == Zotero.Translate.ItemSaver.ATTACHMENT_MODE_FILE) {
|
|
||||||
this._saveAttachment = this._saveAttachmentFile;
|
|
||||||
} else {
|
|
||||||
this._saveAttachment = function() {};
|
|
||||||
}
|
|
||||||
|
|
||||||
this._saveFiles = !(attachmentMode === 0);
|
this._saveFiles = !(attachmentMode === 0);
|
||||||
|
|
||||||
// If group filesEditable==false, don't save attachments
|
// If group filesEditable==false, don't save attachments
|
||||||
|
@ -216,14 +207,63 @@ Zotero.Translate.ItemSaver.prototype = {
|
||||||
return topLevelCollection;
|
return topLevelCollection;
|
||||||
},
|
},
|
||||||
|
|
||||||
"_saveAttachmentFile": Zotero.Promise.coroutine(function* (attachment, parentID, attachmentCallback) {
|
/**
|
||||||
Zotero.debug("Translate: Adding attachment", 4);
|
* Saves a translator attachment to the database
|
||||||
|
*
|
||||||
|
* @param {Translator Attachment} attachment
|
||||||
|
* @param {Integer} parentID Item to attach to
|
||||||
|
* @param {Function} attachmentCallback Callback function that takes three
|
||||||
|
* parameters: translator attachment object, percent completion (integer),
|
||||||
|
* and an optional error object
|
||||||
|
*
|
||||||
|
* @return {Zotero.Primise<Zotero.Item|False} Flase is returned if attachment
|
||||||
|
* was not saved due to error or user settings.
|
||||||
|
*/
|
||||||
|
"_saveAttachment": function(attachment, parentID, attachmentCallback) {
|
||||||
|
// determine whether to save files and attachments
|
||||||
|
let attachmentPromise;
|
||||||
|
if (attachmentMode == Zotero.Translate.ItemSaver.ATTACHMENT_MODE_DOWNLOAD) {
|
||||||
|
attachmentPromise = this._saveAttachmentDownload.apply(this, arguments);
|
||||||
|
} else if (attachmentMode == Zotero.Translate.ItemSaver.ATTACHMENT_MODE_FILE) {
|
||||||
|
attachmentPromise = this._saveAttachmentFile.apply(this, arguments);
|
||||||
|
} else {
|
||||||
|
Zotero.debug('Translate: Ignoring attachment due to ATTACHMENT_MODE_IGNORE');
|
||||||
|
return Zotero.Promise.resolve(false);
|
||||||
|
}
|
||||||
|
|
||||||
if(!attachment.url && !attachment.path) {
|
return attachmentPromise
|
||||||
let e = "Translate: Ignoring attachment: no path or URL specified";
|
.then(function(attachmentItem) {
|
||||||
|
if (!attachmentItem) return false; // attachmentCallback should not have been called in this case
|
||||||
|
|
||||||
|
// save fields
|
||||||
|
attachment.itemType = "attachment";
|
||||||
|
this._saveFields(attachment, attachmentItem);
|
||||||
|
|
||||||
|
// add note if necessary
|
||||||
|
if(attachment.note) {
|
||||||
|
attachmentItem.setNote(attachment.note);
|
||||||
|
}
|
||||||
|
|
||||||
|
return attachmentItem.save()
|
||||||
|
.then(function() {
|
||||||
|
Zotero.debug("Translate: Created attachment; id is " + attachmentItem.id, 4);
|
||||||
|
attachmentCallback(attachment, 100);
|
||||||
|
return attachmentItem;
|
||||||
|
})
|
||||||
|
}.bind(this))
|
||||||
|
.catch(function(e) {
|
||||||
Zotero.debug(e, 2);
|
Zotero.debug(e, 2);
|
||||||
attachmentCallback(attachment, false, e);
|
attachmentCallback(attachment, false, e);
|
||||||
return false;
|
return false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"_saveAttachmentFile": Zotero.Promise.coroutine(function* (attachment, parentID, attachmentCallback) {
|
||||||
|
Zotero.debug("Translate: Adding attachment", 4);
|
||||||
|
attachmentCallback(attachment, 0);
|
||||||
|
|
||||||
|
if(!attachment.url && !attachment.path) {
|
||||||
|
throw new Error("Translate: Ignoring attachment: no path or URL specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachment.path) {
|
if (attachment.path) {
|
||||||
|
@ -237,25 +277,24 @@ Zotero.Translate.ItemSaver.prototype = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let done = false;
|
let done = false,
|
||||||
|
newItem;
|
||||||
if (attachment.path) {
|
if (attachment.path) {
|
||||||
var file = this._parsePath(attachment.path);
|
var file = this._parsePath(attachment.path);
|
||||||
if(!file) {
|
if(!file) {
|
||||||
let asUrl = Zotero.Attachments.cleanAttachmentURI(attachment.path);
|
let asUrl = Zotero.Attachments.cleanAttachmentURI(attachment.path);
|
||||||
if (!attachment.url && !asUrl) {
|
if (!attachment.url && !asUrl) {
|
||||||
let e = "Translate: Could not parse attachment path <" + attachment.path + ">";
|
throw new Error("Translate: Could not parse attachment path <" + attachment.path + ">");
|
||||||
Zotero.debug(e, 2);
|
|
||||||
attachmentCallback(attachment, false, e);
|
|
||||||
return false;
|
|
||||||
} else if (!attachment.url && asUrl) {
|
} else if (!attachment.url && asUrl) {
|
||||||
Zotero.debug("Translate: attachment path looks like a URI: " + attachment.path);
|
Zotero.debug("Translate: attachment path looks like a URI: " + attachment.path);
|
||||||
attachment.url = asUrl;
|
attachment.url = asUrl;
|
||||||
delete attachment.path;
|
delete attachment.path;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let myID;
|
||||||
if (attachment.url) {
|
if (attachment.url) {
|
||||||
attachment.linkMode = "imported_url";
|
attachment.linkMode = "imported_url";
|
||||||
var myID = yield Zotero.Attachments.importSnapshotFromFile({
|
myID = yield Zotero.Attachments.importSnapshotFromFile({
|
||||||
file: file,
|
file: file,
|
||||||
url: attachment.url,
|
url: attachment.url,
|
||||||
title: attachment.title,
|
title: attachment.title,
|
||||||
|
@ -266,23 +305,20 @@ Zotero.Translate.ItemSaver.prototype = {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
attachment.linkMode = "imported_file";
|
attachment.linkMode = "imported_file";
|
||||||
var myID = yield Zotero.Attachments.importFromFile({
|
myID = yield Zotero.Attachments.importFromFile({
|
||||||
file: file,
|
file: file,
|
||||||
parentItemID: parentID
|
parentItemID: parentID
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
attachmentCallback(attachment, 100);
|
|
||||||
done = true;
|
done = true;
|
||||||
|
newItem = yield Zotero.Items.getAsync(myID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!done) {
|
if(!done) {
|
||||||
let url = Zotero.Attachments.cleanAttachmentURI(attachment.url);
|
let url = Zotero.Attachments.cleanAttachmentURI(attachment.url);
|
||||||
if (!url) {
|
if (!url) {
|
||||||
let e = "Translate: Invalid attachment.url specified <" + attachment.url + ">";
|
throw new Error("Translate: Invalid attachment.url specified <" + attachment.url + ">");
|
||||||
Zotero.debug(e, 2);
|
|
||||||
attachmentCallback(attachment, false, e);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attachment.url = url;
|
attachment.url = url;
|
||||||
|
@ -292,47 +328,21 @@ Zotero.Translate.ItemSaver.prototype = {
|
||||||
|
|
||||||
// see if this is actually a file URL
|
// see if this is actually a file URL
|
||||||
if(url.scheme == "file") {
|
if(url.scheme == "file") {
|
||||||
let e = "Translate: Local file attachments cannot be specified in attachment.url";
|
throw new Error("Translate: Local file attachments cannot be specified in attachment.url");
|
||||||
Zotero.debug(e, 2);
|
|
||||||
attachmentCallback(attachment, false, e);
|
|
||||||
return false;
|
|
||||||
} else if(url.scheme != "http" && url.scheme != "https") {
|
} else if(url.scheme != "http" && url.scheme != "https") {
|
||||||
let e = "Translate: " + url.scheme + " protocol is not allowed for attachments from translators.";
|
throw new Error("Translate: " + url.scheme + " protocol is not allowed for attachments from translators.");
|
||||||
Zotero.debug(e, 2);
|
|
||||||
attachmentCallback(attachment, false, e);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, must be a valid HTTP/HTTPS url
|
// At this point, must be a valid HTTP/HTTPS url
|
||||||
attachment.linkMode = "linked_file";
|
attachment.linkMode = "linked_file";
|
||||||
var newItem = yield Zotero.Attachments.linkFromURL({
|
newItem = yield Zotero.Attachments.linkFromURL({
|
||||||
url: attachment.url,
|
url: attachment.url,
|
||||||
parentItemID: parentID,
|
parentItemID: parentID,
|
||||||
contentType: attachment.mimeType ? attachment.mimeType : undefined,
|
contentType: attachment.mimeType || undefined,
|
||||||
title: attachment.title ? attachment.title : undefined
|
title: attachment.title || undefined
|
||||||
})
|
})
|
||||||
.catch(function (e) {
|
|
||||||
Zotero.debug("Translate: Error adding attachment "+attachment.url, 2);
|
|
||||||
attachmentCallback(attachment, false, e);
|
|
||||||
});
|
|
||||||
if (!newItem) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Zotero.debug("Translate: Created attachment; id is " + newItem.id, 4);
|
|
||||||
attachmentCallback(attachment, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// save fields
|
|
||||||
attachment.itemType = "attachment";
|
|
||||||
this._saveFields(attachment, newItem);
|
|
||||||
|
|
||||||
// add note if necessary
|
|
||||||
if(attachment.note) {
|
|
||||||
newItem.setNote(attachment.note);
|
|
||||||
}
|
|
||||||
|
|
||||||
yield newItem.save();
|
|
||||||
|
|
||||||
return newItem;
|
return newItem;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -465,128 +475,111 @@ Zotero.Translate.ItemSaver.prototype = {
|
||||||
Zotero.debug("Translate: Adding attachment", 4);
|
Zotero.debug("Translate: Adding attachment", 4);
|
||||||
|
|
||||||
if(!attachment.url && !attachment.document) {
|
if(!attachment.url && !attachment.document) {
|
||||||
Zotero.debug("Translate: Not adding attachment: no URL specified", 2);
|
Zotero.debug("Translate: Not adding attachment: no URL specified");
|
||||||
} else {
|
return false;
|
||||||
// Determine whether to save an attachment
|
}
|
||||||
if(attachment.snapshot !== false) {
|
|
||||||
if(attachment.document
|
// Determine whether to save an attachment
|
||||||
|| (attachment.mimeType &&
|
if(attachment.snapshot !== false) {
|
||||||
(attachment.mimeType === "text/html"
|
if(attachment.document || Zotero.MIME.isWebPageType(attachment.mimeType)) {
|
||||||
|| attachment.mimeType == "application/xhtml+xml"))) {
|
if(!Zotero.Prefs.get("automaticSnapshots")) {
|
||||||
if(!Zotero.Prefs.get("automaticSnapshots")) return;
|
Zotero.debug("Translate: Not adding attachment: automatic snapshots are disabled");
|
||||||
} else {
|
return false;
|
||||||
if(!Zotero.Prefs.get("downloadAssociatedFiles")) return;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var doc = undefined;
|
|
||||||
if(attachment.document) {
|
|
||||||
doc = new XPCNativeWrapper(Zotero.Translate.DOMWrapper.unwrap(attachment.document));
|
|
||||||
if(!attachment.title) attachment.title = doc.title;
|
|
||||||
}
|
|
||||||
var title = attachment.title || null;
|
|
||||||
if(!title) {
|
|
||||||
// If no title provided, use "Attachment" as title for progress UI (but not for item)
|
|
||||||
attachment.title = Zotero.getString("itemTypes.attachment");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(attachment.snapshot === false || !this._saveFiles) {
|
|
||||||
// if snapshot is explicitly set to false, attach as link
|
|
||||||
attachment.linkMode = "linked_url";
|
|
||||||
if(attachment.document) {
|
|
||||||
yield Zotero.Attachments.linkFromURL({
|
|
||||||
url: attachment.document.location.href,
|
|
||||||
parentItemID: parentID,
|
|
||||||
contentType: attachment.mimeType ? attachment.mimeType : attachment.document.contentType,
|
|
||||||
title: title
|
|
||||||
})
|
|
||||||
.catch(function (e) {
|
|
||||||
Zotero.debug("Translate: Error adding attachment "+attachment.url, 2);
|
|
||||||
attachmentCallback(attachment, false, e);
|
|
||||||
});
|
|
||||||
|
|
||||||
attachmentCallback(attachment, 100);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
if(!attachment.mimeType || !title) {
|
|
||||||
Zotero.debug("Translate: Either mimeType or title is missing; attaching file will be slower", 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
yield Zotero.Attachments.linkFromURL({
|
|
||||||
url: attachment.url,
|
|
||||||
parentItemID: parentID,
|
|
||||||
contentType: attachment.mimeType ? attachment.mimeType : undefined,
|
|
||||||
title: title
|
|
||||||
})
|
|
||||||
.catch(function (e) {
|
|
||||||
Zotero.debug("Translate: Error adding attachment "+attachment.url, 2);
|
|
||||||
attachmentCallback(attachment, false, e);
|
|
||||||
});
|
|
||||||
|
|
||||||
attachmentCallback(attachment, 100);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
// if snapshot is not explicitly set to false, retrieve snapshot
|
if(!Zotero.Prefs.get("downloadAssociatedFiles")) {
|
||||||
if(attachment.document) {
|
Zotero.debug("Translate: Not adding attachment: automatic file attachments are disabled");
|
||||||
attachment.linkMode = "imported_url";
|
return false;
|
||||||
|
|
||||||
attachmentCallback(attachment, 0);
|
|
||||||
|
|
||||||
yield Zotero.Attachments.importFromDocument({
|
|
||||||
libraryID: this._libraryID,
|
|
||||||
document: attachment.document,
|
|
||||||
parentItemID: parentID,
|
|
||||||
title: title
|
|
||||||
})
|
|
||||||
.then(function (attachmentItem) {
|
|
||||||
attachmentCallback(attachment, 100);
|
|
||||||
})
|
|
||||||
.catch(function (e) {
|
|
||||||
Zotero.debug("Translate: Error attaching document", 2);
|
|
||||||
attachmentCallback(attachment, false, e);
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
// Save attachment if snapshot pref enabled or not HTML
|
|
||||||
// (in which case downloadAssociatedFiles applies)
|
|
||||||
} else {
|
|
||||||
var mimeType = (attachment.mimeType ? attachment.mimeType : null);
|
|
||||||
let parentItem = yield Zotero.Items.getAsync(parentID);
|
|
||||||
var fileBaseName = Zotero.Attachments.getFileBaseNameFromItem(parentItem);
|
|
||||||
|
|
||||||
Zotero.debug('Importing attachment from URL');
|
|
||||||
attachment.linkMode = "imported_url";
|
|
||||||
|
|
||||||
attachmentCallback(attachment, 0);
|
|
||||||
|
|
||||||
yield Zotero.Attachments.importFromURL({
|
|
||||||
libraryID: this._libraryID,
|
|
||||||
url: attachment.url,
|
|
||||||
parentItemID: parentID,
|
|
||||||
title: title,
|
|
||||||
fileBaseName: fileBaseName,
|
|
||||||
contentType: mimeType,
|
|
||||||
cookieSandbox: this._cookieSandbox
|
|
||||||
})
|
|
||||||
.then(function (attachmentItem) {
|
|
||||||
// TODO: actually indicate progress during download
|
|
||||||
attachmentCallback(attachment, 100);
|
|
||||||
})
|
|
||||||
.catch(function (e) {
|
|
||||||
Zotero.debug("Translate: Error adding attachment "+attachment.url, 2);
|
|
||||||
attachmentCallback(attachment, false, e);
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
let doc = undefined;
|
||||||
|
if(attachment.document) {
|
||||||
|
doc = new XPCNativeWrapper(Zotero.Translate.DOMWrapper.unwrap(attachment.document));
|
||||||
|
if(!attachment.title) attachment.title = doc.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no title provided, use "Attachment" as title for progress UI (but not for item)
|
||||||
|
let title = attachment.title || null;
|
||||||
|
if(!attachment.title) {
|
||||||
|
attachment.title = Zotero.getString("itemTypes.attachment");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit to saving
|
||||||
|
attachmentCallback(attachment, 0);
|
||||||
|
|
||||||
|
if(attachment.snapshot === false || !this._saveFiles) {
|
||||||
|
// if snapshot is explicitly set to false, attach as link
|
||||||
|
attachment.linkMode = "linked_url";
|
||||||
|
let url, mimeType;
|
||||||
|
if(attachment.document) {
|
||||||
|
url = attachment.document.location.href;
|
||||||
|
mimeType = attachment.mimeType || attachment.document.contentType;
|
||||||
|
} else {
|
||||||
|
url = attachment.url
|
||||||
|
mimeType = attachment.mimeType || undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mimeType || !title) {
|
||||||
|
Zotero.debug("Translate: mimeType or title is missing; attaching link to URL will be slower");
|
||||||
|
}
|
||||||
|
|
||||||
|
let cleanURI = Zotero.Attachments.cleanAttachmentURI(url);
|
||||||
|
if (!cleanURI) {
|
||||||
|
throw new Error("Translate: Invalid attachment URL specified <" + url + ">");
|
||||||
|
}
|
||||||
|
url = Components.classes["@mozilla.org/network/io-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIIOService)
|
||||||
|
.newURI(cleanURI, null, null); // This cannot fail, since we check above
|
||||||
|
|
||||||
|
// Only HTTP/HTTPS links are allowed
|
||||||
|
if(url.scheme != "http" && url.scheme != "https") {
|
||||||
|
throw new Error("Translate: " + url.scheme + " protocol is not allowed for attachments from translators.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Zotero.Attachments.linkFromURL({
|
||||||
|
url: cleanURI,
|
||||||
|
parentItemID: parentID,
|
||||||
|
contentType: mimeType,
|
||||||
|
title: title
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snapshot is not explicitly set to false, import as file attachment
|
||||||
|
|
||||||
|
// Import from document
|
||||||
|
if(attachment.document) {
|
||||||
|
Zotero.debug('Importing attachment from document');
|
||||||
|
attachment.linkMode = "imported_url";
|
||||||
|
|
||||||
|
return Zotero.Attachments.importFromDocument({
|
||||||
|
libraryID: this._libraryID,
|
||||||
|
document: attachment.document,
|
||||||
|
parentItemID: parentID,
|
||||||
|
title: title
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import from URL
|
||||||
|
let mimeType = attachment.mimeType ? attachment.mimeType : null;
|
||||||
|
let parentItem = yield Zotero.Items.getAsync(parentID);
|
||||||
|
let fileBaseName = Zotero.Attachments.getFileBaseNameFromItem(parentItem);
|
||||||
|
|
||||||
|
Zotero.debug('Importing attachment from URL');
|
||||||
|
attachment.linkMode = "imported_url";
|
||||||
|
|
||||||
|
attachmentCallback(attachment, 0);
|
||||||
|
|
||||||
|
return Zotero.Attachments.importFromURL({
|
||||||
|
libraryID: this._libraryID,
|
||||||
|
url: attachment.url,
|
||||||
|
parentItemID: parentID,
|
||||||
|
title: title,
|
||||||
|
fileBaseName: fileBaseName,
|
||||||
|
contentType: mimeType,
|
||||||
|
cookieSandbox: this._cookieSandbox
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
|
|
||||||
"_saveFields":function(item, newItem) {
|
"_saveFields":function(item, newItem) {
|
||||||
|
|
Loading…
Reference in a new issue