Zotero.ZotFile = {
prefs: null,
fileMap: {}, //maps collections to their file objects
mergeObserver: {
observe: function(a, b, c){
//this should get called when the dynamic overlay loading in createUI is complete.
//we adjust UI stuff according to preferences here.
document.getElementById("zotfile-usetags").setAttribute("checked",
Zotero.ZotFile.prefs.getBoolPref("useTags").toString());
}
},
createUI: function() {
// Coment from lytero "I can't reference the node where I want to add stuff directly in an overlay because it has no ID,
// so I'll create the minimum here and dynamically load the overlay."
var lmenu = document.createElement("toolbarbutton");
lmenu.setAttribute("id", "zotfile-menu");
var parentn = document.getElementById("zotero-collections-pane").firstChild.firstChild;
parentn = document.getElementById("zotero-items-pane").firstChild;
var zfb = document.createElement("toolbarbutton");
zfb.setAttribute("id", "zf-button");
siblingn = document.getElementById("zotero-tb-advanced-search");
// add the button to start action
parentn.insertBefore(zfb, siblingn);
parentn.insertBefore(document.createElement("toolbarseparator"),siblingn);
//load the overlay
document.loadOverlay("chrome://zotfile/content/zotfile-menu.xul", this.mergeObserver);
},
getpara: function (para) {
// Initially this function
var filetypes=/pdf|doc|txt|rtf/;
if(para=="filetypes") return(filetypes);
},
init: function () {
//set up preferences
this.prefs = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService);
this.prefs = this.prefs.getBranch("extensions.zotfile.");
//Register event listener to process also automatically attached files
this.createUI()
},
infoWindow: function(main, message, time){
var pw = new (Zotero.ProgressWindow);
pw.changeHeadline(main);
if (main=="error") pw.changeHeadline(Zotero.getString("general.errorHasOccurred")); pw.addDescription(message);
pw.show();
pw.startCloseTimer(time);
},
createFilename: function(zitem, rule){
// get title of selected item
var title = zitem.getField('title');
// truncnate title after : . and ?
var truncate = title.search(/:|\.|\?/);
if(truncate!=-1) var title = title.substr(0,truncate);
var title_length = title.length;
if (title_length>this.prefs.getIntPref("max_titlelength")) var title = title.substr(0,this.prefs.getIntPref("max_titlelength"));
// get journal
var journal = zitem.getField('publicationTitle');
// get publisher
var publisher = zitem.getField('publisher');
// get creator and create authors string
var add_etal=this.prefs.getBoolPref("add_etal");
var author = "";
var creators = zitem.getCreators();
var numauthors = creators.length;
for (var i=0; i < creators.length; i++) {
if(creators[i].creatorTypeID!=1) var numauthors=numauthors-1;
}
if (numauthors<=this.prefs.getIntPref("max_authors")) var add_etal=0;
if (numauthors>this.prefs.getIntPref("max_authors")) var numauthors = 1;
var j=0;
for (var i=0; i < creators.length; i++) {
if (j<numauthors & creators[i].creatorTypeID==1) {
if (author!="") var author = author + "_" + creators[i].ref.lastName;
if (author=="") var author = creators[i].ref.lastName;
var j=j+1;
}
}
if (add_etal==1) var author = author + " et al";
// date
var year = zitem.getField('date', true).substr(0,4);
// create filename from rule
var field=0;
var filename='';
for (var i=0; i<rule.length; i++) {
var char=rule.charAt(i);
switch (char) {
case '%':
var field=1;
break;
case 'a':
if (field==1) var filename = filename + author;
var field=0;
break;
case 't':
if (field==1) var filename = filename + title;
var field=0;
break;
case 'y':
if (field==1) var filename = filename + year;
var field=0;
break;
case 'j':
if (field==1) var filename = filename + journal;
var field=0;
break;
case 'p':
if (field==1) var filename = filename + publisher;
var field=0;
break;
case 'w':
if (field==1) {
var filename = filename + journal;
if(journal=="") var filename = filename + publisher;
}
var field=0;
break;
default: var filename = filename + char;
}
}
//var filename = author + "_" + year + "_" + title;
// Strip potentially invalid characters
// (code line adopted from Zotero)
var filename = filename.replace(/[\/\\\?\*:|"<>\.]/g, '');
return(filename);
},
getFiletype: function(fname){
var temp = new Array();
temp = fname.split('.');
return(temp[temp.length-1].toLowerCase());
},
lastFileInDir: function(dir_path, rule){
// create a nslFile Object for the dir
try {
var dir = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
dir.initWithPath(dir_path);
var lastfile_date=0;
var lastfile_path="";
var success=0;
// go through all the files in the dir
var i=0;
var files = dir.directoryEntries;
while (files.hasMoreElements()) {
// get one after the other file
var file = files.getNext();
file.QueryInterface(Components.interfaces.nsIFile);
// only look at files which are neither folders not hidden
if(!file.isDirectory() & !file.isHidden()) {
// now we want to check which filetype we are looking at
// we only want to consider pdfs, docs, ...
var filetype=this.getFiletype(file.leafName);
// for whatever reason, rule is not really passed to the function so I just call getpara directly in the line above...
var type=filetype.search(this.getpara("filetypes"));
if (type>=0) {
var modtime = file.lastModifiedTime;
var i=i+1;
// finally, we set lastfile to the file with the most recent modification
if (modtime>lastfile_date){
var lastfile_date=modtime;
lastfile=file;
var success=1;
}
}
}
}
if (success==1) return(lastfile);
else return(-1);
} catch (e) {
Components.utils.reportError(e);
return (-2);
}
},
moveFile: function(file, destination, filename){
// create a nslFile Object of the destination folder
var dir = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
dir.initWithPath(destination);
// move file to new location
file.moveTo(dir, filename);
},
zotfileAction: function(){
var items = ZoteroPane.getSelectedItems();
var item = items[0];
//check whether it really is an bibliographic item (no Attachment, note or collection)
if (!item.isAttachment() & !item.isCollection() & !item.isNote()) {
// create the new filename from the selected item
var rename_rule=this.prefs.getCharPref("renameFormat");
filename=this.createFilename(item, rename_rule);
// get the last modified file from a directory
lastfile=this.lastFileInDir(this.prefs.getCharPref("source_dir"), this.getpara("filetypes"));
if(lastfile!=-1 & lastfile!=-2 ) {
var lastfile_oldpath=lastfile.leafName;
// complete filename with extension and then move the file to destination
var filetype=this.getFiletype(lastfile.leafName);
var filename = filename + "." + filetype;
if(confirm("Do you want to rename and link file \'" + lastfile_oldpath + "\' to the currently selected Zotero item?")){
this.moveFile(lastfile, this.prefs.getCharPref("source_dir"), filename)
// recreate the lastfile nslFile Object
// (for some reason the Attachment is linked to the wrong location without recreation)
var lastfile_path=lastfile.path;
var lastfile = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
lastfile.initWithPath(lastfile_path);
// Attach last file to selected Zotero item
Zotero.Attachments.importFromFile(lastfile, item.itemID);
//Delete the old file that is not longer needed
lastfile.remove(false)
// Show message
this.infoWindow("Zotfile","File \'" + lastfile_oldpath + "\' changed to \'" + lastfile.leafName + "\' and added as an attachment.",8000);
//output("\nFile " + lastfile.leafName + " moved to " + dest_dir + filename + " and added as Zotero attachment.\n\n");
}
}
else this.infoWindow("Zotfile Error","Unable to find file in " + this.prefs.getCharPref("source_dir"),8000);
}
else this.infoWindow("Zotfile Error","Selected item is either an attachment, a note, or a collection.",8000);
}
};
// Initialize the utility
window.addEventListener('load', function(e) { Zotero.ZotFile.init(); }, false);