commit 7756620490b7b44fe812372e87cd57f26b3142e1
parent dec907569aac0df94d6c75deb1af90ec219fbb55
Author: Simon Kornblith <simon@simonster.com>
Date: Tue, 16 Aug 2011 15:31:18 +0000
- Customizable attachment export, thanks to DBrickShaw
- Fix an issue importing collections
Diffstat:
2 files changed, 122 insertions(+), 43 deletions(-)
diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js
@@ -563,12 +563,12 @@ Zotero.Translate.Sandbox = {
* @param {SandboxCollection} collection
*/
"_collectionDone":function(translate, collection) {
- if(this._libraryID == false) {
- this.newCollections.push(collection);
+ if(translate._libraryID == false) {
+ translate.newCollections.push(collection);
translate._runHandler("collectionDone", collection);
} else {
var newCollection = translate._itemSaver.saveCollection(collection);
- this.newCollections.push(newCollection);
+ translate.newCollections.push(newCollection);
translate._runHandler("collectionDone", newCollection);
}
},
diff --git a/chrome/content/zotero/xpcom/translation/translate_item.js b/chrome/content/zotero/xpcom/translation/translate_item.js
@@ -572,9 +572,9 @@ Zotero.Translate.ItemGetter.prototype = {
"exportFiles":function(dir, extension) {
// generate directory
- var directory = Components.classes["@mozilla.org/file/local;1"].
+ this._exportFileDirectory = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
- directory.initWithFile(dir.parent);
+ this._exportFileDirectory.initWithFile(dir.parent);
// delete this file if it exists
if(dir.exists()) {
@@ -583,25 +583,18 @@ Zotero.Translate.ItemGetter.prototype = {
// get name
var name = dir.leafName;
- directory.append(name);
+ this._exportFileDirectory.append(name);
// create directory
- directory.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0700);
+ this._exportFileDirectory.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0700);
// generate a new location for the exported file, with the appropriate
// extension
var location = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
- location.initWithFile(directory);
+ location.initWithFile(this._exportFileDirectory);
location.append(name+"."+extension);
-
- // create files directory
- this._exportFileDirectory = Components.classes["@mozilla.org/file/local;1"].
- createInstance(Components.interfaces.nsILocalFile);
- this._exportFileDirectory.initWithFile(directory);
- this._exportFileDirectory.append("files");
- this._exportFileDirectory.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0700);
-
+
return location;
},
@@ -610,40 +603,126 @@ Zotero.Translate.ItemGetter.prototype = {
*/
"_attachmentToArray":function(attachment) {
var attachmentArray = this._itemToArray(attachment);
-
var linkMode = attachment.attachmentLinkMode;
- // get mime type
+ // Get mime type
attachmentArray.mimeType = attachmentArray.uniqueFields.mimeType = attachment.attachmentMIMEType;
- // get charset
+ // Get charset
attachmentArray.charset = attachmentArray.uniqueFields.charset = attachment.attachmentCharset;
if(linkMode != Zotero.Attachments.LINK_MODE_LINKED_URL && this._exportFileDirectory) {
- // add path and filename if not an internet link
- var file = attachment.getFile();
- attachmentArray.path = "files/"+attachmentArray.itemID+"/"+file.leafName;
+ var exportDir = this._exportFileDirectory;
- if(linkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE) {
- // create a new directory
- var directory = Components.classes["@mozilla.org/file/local;1"].
- createInstance(Components.interfaces.nsILocalFile);
- directory.initWithFile(this._exportFileDirectory);
- directory.append(attachmentArray.itemID);
- // copy file
- try {
- directory.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0700);
- file.copyTo(directory, attachmentArray.filename);
- } catch(e) {
- attachmentArray.path = undefined;
- }
- } else {
- // copy imported files from the Zotero directory
- var directory = file.parent;
- try {
- directory.copyTo(this._exportFileDirectory, attachmentArray.itemID);
- } catch(e) {
- attachmentArray.path = undefined;
- }
+ // Add path and filename if not an internet link
+ var attachFile = attachment.getFile();
+ if(attachFile) {
+ attachmentArray.defaultPath = "files/" + attachmentArray.itemID + "/" + attachFile.leafName;
+ attachmentArray.filename = attachFile.leafName;
+
+ /**
+ * Copies the attachment file to the specified relative path from the
+ * export directory.
+ * @param {String} attachPath The path to which the file should be exported
+ * including the filename. If supporting files are included, they will be
+ * copied as well without any renaming.
+ * @param {Boolean} overwriteExisting Optional - If this is set to false, the
+ * function will throw an error when exporting a file would require an existing
+ * file to be overwritten. If true, the file will be silently overwritten.
+ * defaults to false if not provided.
+ */
+ attachmentArray.saveFile = function(attachPath, overwriteExisting) {
+ // Ensure a valid path is specified
+ if(attachPath === undefined || attachPath == "") {
+ throw new Error("ERROR_EMPTY_PATH");
+ }
+
+ // Set the default value of overwriteExisting if it was not provided
+ if (overwriteExisting === undefined) {
+ overwriteExisting = false;
+ }
+
+ // Separate the path into a list of subdirectories and the attachment filename,
+ // and initialize the required file objects
+ var targetFile = Components.classes["@mozilla.org/file/local;1"].
+ createInstance(Components.interfaces.nsILocalFile);
+ targetFile.initWithFile(exportDir);
+ targetFile.appendRelativePath(attachPath);
+
+ // First, check that we have not gone lower than exportDir in the hierarchy
+ var parent = targetFile, inExportFileDirectory;
+ while((parent = parent.parent)) {
+ if(exportDir.equals(parent)) {
+ inExportFileDirectory = true;
+ break;
+ }
+ }
+
+ if(!inExportFileDirectory) {
+ throw new Error("Invalid path; attachment cannot be placed above export "+
+ "directory in the file hirarchy");
+ }
+
+ // Create intermediate directories if they don't exist
+ parent = targetFile;
+ while((parent = parent.parent) && !parent.exists()) {
+ parent.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0700);
+ }
+
+ // Delete any existing file if overwriteExisting is set, or throw an exception
+ // if it is not
+ if(targetFile.exists()) {
+ if(overwriteExisting) {
+ targetFile.remove(false);
+ } else {
+ throw new Error("ERROR_FILE_EXISTS " + targetFile.leafName);
+ }
+ }
+
+ var directory = targetFile.parent;
+
+ // The only attachments that can have multiple supporting files are of mime type
+ // text/html (specified in Attachments.getNumFiles())
+ if(attachment.attachmentMIMEType == "text/html"
+ && Zotero.Attachments.getNumFiles(attachment) > 1) {
+ // Attachment is a snapshot with supporting files. Check if any of the
+ // supporting files would cause a name conflict, and build a list of transfers
+ // that should be performed
+ var copySrcs = [];
+ var files = attachment.getFile().parent.directoryEntries;
+ while (files.hasMoreElements()) {
+ file = files.getNext();
+ file.QueryInterface(Components.interfaces.nsIFile);
+
+ // Ignore the main attachment file (has already been checked for name conflict)
+ if(attachFile.equals(file)) {
+ continue;
+ }
+
+ // Remove any existing files in the target destination if overwriteExisting
+ // is set, or throw an exception if it is not
+ var targetSupportFile = targetFile.parent.clone();
+ targetSupportFile.append(file.leafName);
+ if(targetSupportFile.exists()) {
+ if(overwriteExisting) {
+ targetSupportFile.remove(false);
+ } else {
+ throw new Error("ERROR_FILE_EXISTS " + targetSupportFile.leafName);
+ }
+ }
+ copySrcs.push(file.clone());
+ }
+
+ // No conflicts were detected or all conflicts were resolved, perform the copying
+ attachFile.copyTo(directory, targetFile.leafName);
+ for(var i = 0; i < copySrcs.length; i++) {
+ copySrcs[i].copyTo(directory, copySrcs[i].leafName);
+ }
+ } else {
+ // Attachment is a single file
+ // Copy the file to the specified location
+ attachFile.copyTo(directory, targetFile.leafName);
+ }
+ };
}
}