diff --git a/chrome/content/zotero/xpcom/schema.js b/chrome/content/zotero/xpcom/schema.js index be1746cc9..31669e5ad 100644 --- a/chrome/content/zotero/xpcom/schema.js +++ b/chrome/content/zotero/xpcom/schema.js @@ -663,6 +663,7 @@ Zotero.Schema = new function(){ // var sql = "SELECT version FROM version WHERE schema=?"; var lastModTime = yield Zotero.DB.valueQueryAsync(sql, mode); + var cache = {}; // XPI installation if (!isUnpacked) { @@ -880,6 +881,9 @@ Zotero.Schema = new function(){ else if (mode == 'translators') { newObj = yield Zotero.Translators.loadFromFile(entry.path); } + else { + throw new Error("Invalid mode '" + mode + "'"); + } let existingObj = Zotero[Mode].get(newObj[modeType + "ID"]); if (!existingObj) { Zotero.debug("Installing " + modeType + " '" + newObj[titleField] + "'"); @@ -902,19 +906,16 @@ Zotero.Schema = new function(){ } try { - let destFile = OS.Path.join(destDir, fileName); + let destFile; + if (!existingObj || !existingObj.hidden) { + destFile = OS.Path.join(destDir, fileName); + } + else { + destFile = OS.Path.join(hiddenDir, fileName) + } try { - if (!existingObj || !existingObj.hidden) { - yield OS.File.copy(entry.path, destFile, { - noOverwrite: true - }); - } - else { - yield OS.File.copy(entry.path, OS.Path.join(hiddenDir, fileName), { - noOverwrite: true - }); - } + yield OS.File.copy(entry.path, destFile, { noOverwrite: true }); } catch (e) { if (e instanceof OS.File.Error && e.becauseExists) { @@ -923,17 +924,16 @@ Zotero.Schema = new function(){ + "'" + fileName + "'"; Zotero.debug(msg, 1); Components.utils.reportError(msg); - if (!existingObj || !existingObj.hidden) { - yield OS.File.copy(entry.path, destFile); - } - else { - yield OS.File.copy(entry.path, OS.Path.join(hiddenDir, fileName)); - } + yield OS.File.copy(entry.path, destFile); } else { throw e; } } + + if (mode == 'translators') { + cache[fileName] = newObj.metadata; + } } catch (e) { Components.utils.reportError("Error copying file " + fileName + ": " + e); @@ -956,7 +956,7 @@ Zotero.Schema = new function(){ } }); - yield Zotero[Mode].reinit(); + yield Zotero[Mode].reinit(cache); return true; }); diff --git a/chrome/content/zotero/xpcom/translation/translator.js b/chrome/content/zotero/xpcom/translation/translator.js index 88ba12d3b..ab98c32d9 100644 --- a/chrome/content/zotero/xpcom/translation/translator.js +++ b/chrome/content/zotero/xpcom/translation/translator.js @@ -59,6 +59,7 @@ var TRANSLATOR_SAVE_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES.concat(["browser * @property {Object} hiddenPrefs Hidden preferences configurable through about:config * @property {Boolean} inRepository Whether the translator may be found in the repository * @property {String} lastUpdated SQL-style date and time of translator's last update + * @property {Object} metadata - Metadata block as object * @property {String} code The executable JavaScript for the translator * @property {Boolean} cacheCode Whether to cache code for this session (non-connector only) * @property {String} [path] File path corresponding to this translator (non-connector only) @@ -129,6 +130,11 @@ Zotero.Translator.prototype.init = function(info) { } else if(this.hasOwnProperty("code")) { delete this.code; } + // Save a copy of the metadata block + delete info.path; + delete info.code; + this.metadata = info; + } /** @@ -192,6 +198,7 @@ Zotero.Translator.prototype.logError = function(message, type, line, lineNumber, var ios = Components.classes["@mozilla.org/network/io-service;1"]. getService(Components.interfaces.nsIIOService); Zotero.log(message, type ? type : "error", ios.newFileURI(file).spec); + Zotero.debug(message, 1); } else { Zotero.logError(message); } diff --git a/chrome/content/zotero/xpcom/translation/translators.js b/chrome/content/zotero/xpcom/translation/translators.js index 91c2cd046..e32ef58e3 100644 --- a/chrome/content/zotero/xpcom/translation/translators.js +++ b/chrome/content/zotero/xpcom/translation/translators.js @@ -23,6 +23,8 @@ ***** END LICENSE BLOCK ***** */ +"use strict"; + // Enumeration of types of translators const TRANSLATOR_TYPES = {"import":1, "export":2, "web":4, "search":8}; @@ -36,8 +38,11 @@ Zotero.Translators = new function() { /** * Initializes translator cache, loading all translator metadata into memory + * + * @param {Object} [memCache] - Translator metadata keyed by filename, if already available + * (e.g., in updateBundledFiles()), to avoid unnecesary file reads */ - this.reinit = Zotero.Promise.coroutine(function* () { + this.reinit = Zotero.Promise.coroutine(function* (memCache) { Zotero.debug("Initializing translators"); var start = new Date; _initialized = true; @@ -76,7 +81,14 @@ Zotero.Translators = new function() { lastModifiedTime = (yield OS.File.stat(path)).lastModificationDate.getTime(); } - var dbCacheEntry = false; + // Check passed cache for metadata + let memCacheJSON = false; + if (memCache && memCache[fileName]) { + memCacheJSON = memCache[fileName]; + } + + // Check DB cache + let dbCacheEntry = false; if (dbCache[fileName]) { filesInCache[fileName] = true; if (dbCache[fileName].lastModifiedTime == lastModifiedTime) { @@ -85,8 +97,10 @@ Zotero.Translators = new function() { } // Get JSON from cache if possible - if(dbCacheEntry) { - var translator = Zotero.Translators.load(dbCacheEntry.metadataJSON, path); + if (memCacheJSON || dbCacheEntry) { + var translator = Zotero.Translators.load( + memCacheJSON || dbCacheEntry.metadataJSON, path + ); } // Otherwise, load from file else { @@ -175,9 +189,13 @@ Zotero.Translators = new function() { /** * Loads a translator from JSON, with optional code + * + * @param {String|Object} json - Metadata JSON + * @param {String} path + * @param {String} [code] */ this.load = function (json, path, code) { - var info = JSON.parse(json); + var info = typeof json == 'string' ? JSON.parse(json) : json; info.path = path; info.code = code; return new Zotero.Translator(info);