commit 0d7ffcc1c142c28ac8d0769d5e33d3e92af78d7c
parent dda8551a22added0340e1ad7445d36279b5c82bb
Author: Simon Kornblith <simon@simonster.com>
Date: Tue, 28 Jun 2011 18:24:24 +0000
- Add preferences to connector. Debug logging does not yet work
- Add rudimentary connector API version checks, although I still need a good way of showing that the connector/server is out of date
- Throw new Error() in translate (so that we get a stack trace)
- Log errors in connector
Diffstat:
5 files changed, 136 insertions(+), 25 deletions(-)
diff --git a/chrome/content/zotero/xpcom/connector/connector.js b/chrome/content/zotero/xpcom/connector/connector.js
@@ -22,8 +22,10 @@
***** END LICENSE BLOCK *****
*/
+
Zotero.Connector = new function() {
const CONNECTOR_URI = "http://127.0.0.1:23119/";
+ const CONNECTOR_SERVER_API_VERSION = 1;
this.isOnline = true;
this.haveRefreshedData = false;
@@ -36,6 +38,18 @@ Zotero.Connector = new function() {
Zotero.Connector.getData();
}
+ /**
+ * Checks if Zotero is online and passes current status to callback
+ * @param {Function} callback
+ */
+ this.checkIsOnline = function(callback) {
+ if(Zotero.Connector.isOnline) {
+ callback(true);
+ } else {
+ Zotero.Connector.getData(callback);
+ }
+ }
+
function _getDataFile() {
var dataFile = Zotero.getZoteroDirectory();
dataFile.append("connector.json");
@@ -76,9 +90,10 @@ Zotero.Connector = new function() {
this.EXCEPTION_NOT_AVAILABLE = 0;
this.EXCEPTION_BAD_REQUEST = 400;
this.EXCEPTION_NO_ENDPOINT = 404;
+ this.EXCEPTION_INCOMPATIBLE_VERSION = 412;
this.EXCEPTION_CONNECTOR_INTERNAL = 500;
this.EXCEPTION_METHOD_NOT_IMPLEMENTED = 501;
- this.EXCEPTION_CODES = [0, 400, 404, 500, 501];
+ this.EXCEPTION_CODES = [0, 400, 404, 412, 500, 501];
/**
* Updates Zotero's status depending on the success or failure of a request
@@ -120,9 +135,9 @@ Zotero.Connector = new function() {
*/
this.getData = function(callback) {
Zotero.HTTP.doPost(CONNECTOR_URI+"connector/getData",
- JSON.stringify({"browser":Zotero.browser}),
+ JSON.stringify({"browser":Zotero.browser, "apiVersion":CONNECTOR_SERVER_API_VERSION}),
function(req) {
- var isOnline = req.status !== 0;
+ var isOnline = req.status !== 0 && req.status !== 412;
if(isOnline) {
// if request succeded, update data
@@ -172,7 +187,8 @@ Zotero.Connector = new function() {
this.callMethod = function(method, data, callback) {
Zotero.HTTP.doPost(CONNECTOR_URI+"connector/"+method, JSON.stringify(data),
function(req) {
- _checkState(req.status != 0, function() {
+ _checkState(req.status !== this.EXCEPTION_NOT_AVAILABLE
+ && req.status !== this.EXCEPTION_INCOMPATIBLE_VERSION, function() {
if(!callback) return;
if(Zotero.Connector.EXCEPTION_CODES.indexOf(req.status) !== -1) {
diff --git a/chrome/content/zotero/xpcom/connector/connector_debug.js b/chrome/content/zotero/xpcom/connector/connector_debug.js
@@ -0,0 +1,86 @@
+/*
+ ***** BEGIN LICENSE BLOCK *****
+
+ Copyright © 2009 Center for History and New Media
+ George Mason University, Fairfax, Virginia, USA
+ http://zotero.org
+
+ This file is part of Zotero.
+
+ Zotero is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Zotero is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Zotero. If not, see <http://www.gnu.org/licenses/>.
+
+ ***** END LICENSE BLOCK *****
+*/
+
+Zotero.Connector_Debug = new function() {
+ /**
+ * Call a callback depending upon whether debug output is being stored
+ */
+ this.storing = function(callback) {
+ callback(Zotero.Debug.storing);
+ }
+
+ /**
+ * Call a callback with the lines themselves
+ */
+ this.get = function(callback) {
+ callback(Zotero.Debug.get());
+ }
+
+ /**
+ * Call a callback with the number of lines of output
+ */
+ this.count = function(callback) {
+ callback(Zotero.Debug.count());
+ }
+
+ /**
+ * Submit data to the sserver
+ */
+ this.submitReport = function(callback) {
+ var uploadCallback = function (xmlhttp) {
+ var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+ if (!xmlhttp.responseXML) {
+ callback(false, 'Invalid response from server');
+ return;
+ }
+ var reported = xmlhttp.responseXML.getElementsByTagName('reported');
+ if (reported.length != 1) {
+ callback(false, 'The server returned an error. Please try again.');
+ return;
+ }
+
+ var reportID = reported[0].getAttribute('reportID');
+ callback(true, reportID);
+ }
+
+ Zotero.HTTP.doPost("http://www.zotero.org/repo/report?debug=1", output,
+ function(xmlhttp) {
+ if (!xmlhttp.responseXML) {
+ callback(false, 'Invalid response from server');
+ return;
+ }
+ var reported = xmlhttp.responseXML.getElementsByTagName('reported');
+ if (reported.length != 1) {
+ callback(false, 'The server returned an error. Please try again.');
+ return;
+ }
+
+ var reportID = reported[0].getAttribute('reportID');
+ callback(true, reportID);
+ }, {"Content-Type":"application/octet-stream"});
+ }
+}
+\ No newline at end of file
diff --git a/chrome/content/zotero/xpcom/server.js b/chrome/content/zotero/xpcom/server.js
@@ -31,6 +31,7 @@ Zotero.Server = new function() {
300:"Multiple Choices",
400:"Bad Request",
404:"Not Found",
+ 412:"Precondition Failed",
500:"Internal Server Error",
501:"Method Not Implemented"
};
diff --git a/chrome/content/zotero/xpcom/server_connector.js b/chrome/content/zotero/xpcom/server_connector.js
@@ -23,6 +23,8 @@
***** END LICENSE BLOCK *****
*/
+const CONNECTOR_SERVER_API_VERSION = 1;
+
Zotero.Server.Connector = function() {};
Zotero.Server.Connector._waitingForSelection = {};
Zotero.Server.Connector.Data = {};
@@ -227,6 +229,10 @@ Zotero.Server.Connector.GetData.prototype = {
* @param {Function} sendResponseCallback function to send HTTP response
*/
"init":function(data, sendResponseCallback) {
+ if(data.apiVersion !== CONNECTOR_SERVER_API_VERSION) {
+ sendResponseCallback(412);
+ }
+
// Translator data
var responseData = {"preferences":{}, "translators":[]};
diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js
@@ -122,7 +122,7 @@ Zotero.Translate.Sandbox = {
*/
"getOption":function(translate, option) {
if(typeof option !== "string") {
- throw("Translate: getOption: option must be a string");
+ throw(new Error("getOption: option must be a string"));
return;
}
@@ -149,7 +149,7 @@ Zotero.Translate.Sandbox = {
}
if(typeof type !== "string") {
- throw("Translate: loadTranslator: type must be a string");
+ throw(new Error("loadTranslator: type must be a string"));
return;
}
@@ -158,7 +158,7 @@ Zotero.Translate.Sandbox = {
translation._parentTranslator = translate;
if(translation instanceof Zotero.Translate.Export && !(translation instanceof Zotero.Translate.Export)) {
- throw("Translate: only export translators may call other export translators");
+ throw(new Error("Only export translators may call other export translators"));
}
/**
@@ -207,7 +207,7 @@ Zotero.Translate.Sandbox = {
safeTranslator.setTranslator = function(arg) {
var success = translation.setTranslator(arg);
if(!success) {
- throw "Translator "+translate.translator[0].translatorID+" attempted to call invalid translatorID "+arg;
+ throw new Error("Translator "+translate.translator[0].translatorID+" attempted to call invalid translatorID "+arg);
}
};
safeTranslator.getTranslators = function() { return translation.getTranslators() };
@@ -226,7 +226,7 @@ Zotero.Translate.Sandbox = {
if(callback) translate.incrementAsyncProcesses();
var haveTranslatorFunction = function(translator) {
translation.translator[0] = translator;
- if(!Zotero._loadTranslator(translator)) throw "Translator could not be loaded";
+ if(!Zotero._loadTranslator(translator)) throw new Error("Translator could not be loaded");
if(Zotero.isFx) {
// do same origin check
@@ -243,8 +243,8 @@ Zotero.Translate.Sandbox = {
try {
secMan.checkSameOriginURI(outerSandboxURI, innerSandboxURI, false);
} catch(e) {
- throw "Translate: getTranslatorObject() may not be called from web or search "+
- "translators to web or search translators from different origins.";
+ throw new Error("getTranslatorObject() may not be called from web or search "+
+ "translators to web or search translators from different origins.");
}
}
@@ -262,8 +262,8 @@ Zotero.Translate.Sandbox = {
return translation._sandboxManager.sandbox;
} else {
if(Zotero.isConnector && !callback) {
- throw "Translate: Translator must accept a callback to getTranslatorObject() to "+
- "operate in this translation environment.";
+ throw new Error("Translator must accept a callback to getTranslatorObject() to "+
+ "operate in this translation environment.");
}
Zotero.Translators.get(translation.translator[0], haveTranslatorFunction);
@@ -319,7 +319,7 @@ Zotero.Translate.Sandbox = {
*/
"selectItems":function(translate, items, callback) {
if(Zotero.Utilities.isEmpty(items)) {
- throw "Translate: translator called select items with no items";
+ throw new Error("Translator called select items with no items");
}
if(translate._selectedItems) {
@@ -423,7 +423,7 @@ Zotero.Translate.Sandbox = {
}
if(!item.title) {
- throw "No title specified for item";
+ throw new Error("No title specified for item");
}
// create short title
@@ -520,7 +520,7 @@ Zotero.Translate.Sandbox = {
*/
"nextCollection":function(translate) {
if(!translate.translator[0].configOptions.getCollections) {
- throw("Translate: getCollections configure option not set; cannot retrieve collection");
+ throw(new Error("getCollections configure option not set; cannot retrieve collection"));
}
return translate._itemGetter.nextCollection();
@@ -594,7 +594,7 @@ Zotero.Translate.Base.prototype = {
*/
"setTranslator":function(translator) {
if(!translator) {
- throw new Error("Zotero.Translate: no translator specified");
+ throw new Error("No translator specified");
}
this.translator = null;
@@ -604,7 +604,7 @@ Zotero.Translate.Base.prototype = {
if(translator.translatorID) {
this.translator = [translator];
} else {
- throw("No translatorID specified");
+ throw(new Error("No translatorID specified"));
}
} else {
this.translator = [translator];
@@ -748,7 +748,7 @@ Zotero.Translate.Base.prototype = {
*/
"getTranslators":function(getAllTranslators) {
// do not allow simultaneous instances of getTranslators
- if(this._currentState == "detect") throw "Translate: getTranslators: detection is already running";
+ if(this._currentState == "detect") throw new Error("getTranslators: detection is already running");
this._currentState = "detect";
this._getAllTranslators = getAllTranslators;
this._getTranslatorsGetPotentialTranslators();
@@ -832,7 +832,7 @@ Zotero.Translate.Base.prototype = {
this._currentState = "translate";
if(!this.translator || !this.translator.length) {
- throw("Translate: Failed: no translator specified");
+ throw new Error("Failed: no translator specified");
}
this._libraryID = libraryID;
@@ -1300,6 +1300,7 @@ Zotero.Translate.Web.prototype._translateRPCComplete = function(obj, failureCode
for(var i in obj.items) {
this._runHandler("itemDone", null, obj.items[i]);
}
+ this.newItems = obj.items;
this.complete(true);
}
}
@@ -1551,7 +1552,7 @@ Zotero.Translate.Export.prototype._prepareTranslation = function() {
var io = this._io = new Zotero.Translate.IO.String(null, this.path ? this.path : "", this.translator[0].configOptions["dataMode"]);
this.__defineGetter__("string", function() { return io.string; });
} else if(!Zotero.Translate.IO.Write) {
- throw "Translate: Writing to files is not supported in this build of Zotero.";
+ throw new Error("Writing to files is not supported in this build of Zotero.");
} else {
this._io = new Zotero.Translate.IO.Write(this.location,
this.translator[0].configOptions["dataMode"],
@@ -1687,7 +1688,7 @@ Zotero.Translate.IO = {
var dp = Components.classes["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Components.interfaces.nsIDOMParser);
} catch(e) {
- throw "DOMParser not supported";
+ throw new Error("DOMParser not supported");
}
}
@@ -1698,7 +1699,7 @@ Zotero.Translate.IO = {
}
if(nodes.getElementsByTagName("parsererror").length) {
- throw("DOMParser error: loading data into data store failed");
+ throw new Error("DOMParser error: loading data into data store failed");
}
return nodes;
@@ -1945,7 +1946,7 @@ Zotero.Translate.IO._RDFSandbox.prototype = {
type = type.toLowerCase();
if(!containerTypes[type]) {
- throw "Invalid container type in Zotero.RDF.newContainer";
+ throw new Error("Invalid container type in Zotero.RDF.newContainer");
}
var about = this._getResource(about);
@@ -2016,7 +2017,7 @@ Zotero.Translate.IO._RDFSandbox.prototype = {
"getResourceURI":function(resource) {
if(typeof(resource) == "string") return resource;
if(resource.uri) return resource.uri;
- if(resource.toNT == undefined) throw "Zotero.RDF: getResourceURI called on invalid resource";
+ if(resource.toNT == undefined) throw new Error("Zotero.RDF: getResourceURI called on invalid resource");
return resource.toNT();
},