- 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
This commit is contained in:
parent
dda8551a22
commit
0d7ffcc1c1
5 changed files with 135 additions and 25 deletions
|
@ -22,8 +22,10 @@
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Zotero.Connector = new function() {
|
Zotero.Connector = new function() {
|
||||||
const CONNECTOR_URI = "http://127.0.0.1:23119/";
|
const CONNECTOR_URI = "http://127.0.0.1:23119/";
|
||||||
|
const CONNECTOR_SERVER_API_VERSION = 1;
|
||||||
|
|
||||||
this.isOnline = true;
|
this.isOnline = true;
|
||||||
this.haveRefreshedData = false;
|
this.haveRefreshedData = false;
|
||||||
|
@ -36,6 +38,18 @@ Zotero.Connector = new function() {
|
||||||
Zotero.Connector.getData();
|
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() {
|
function _getDataFile() {
|
||||||
var dataFile = Zotero.getZoteroDirectory();
|
var dataFile = Zotero.getZoteroDirectory();
|
||||||
dataFile.append("connector.json");
|
dataFile.append("connector.json");
|
||||||
|
@ -76,9 +90,10 @@ Zotero.Connector = new function() {
|
||||||
this.EXCEPTION_NOT_AVAILABLE = 0;
|
this.EXCEPTION_NOT_AVAILABLE = 0;
|
||||||
this.EXCEPTION_BAD_REQUEST = 400;
|
this.EXCEPTION_BAD_REQUEST = 400;
|
||||||
this.EXCEPTION_NO_ENDPOINT = 404;
|
this.EXCEPTION_NO_ENDPOINT = 404;
|
||||||
|
this.EXCEPTION_INCOMPATIBLE_VERSION = 412;
|
||||||
this.EXCEPTION_CONNECTOR_INTERNAL = 500;
|
this.EXCEPTION_CONNECTOR_INTERNAL = 500;
|
||||||
this.EXCEPTION_METHOD_NOT_IMPLEMENTED = 501;
|
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
|
* 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) {
|
this.getData = function(callback) {
|
||||||
Zotero.HTTP.doPost(CONNECTOR_URI+"connector/getData",
|
Zotero.HTTP.doPost(CONNECTOR_URI+"connector/getData",
|
||||||
JSON.stringify({"browser":Zotero.browser}),
|
JSON.stringify({"browser":Zotero.browser, "apiVersion":CONNECTOR_SERVER_API_VERSION}),
|
||||||
function(req) {
|
function(req) {
|
||||||
var isOnline = req.status !== 0;
|
var isOnline = req.status !== 0 && req.status !== 412;
|
||||||
|
|
||||||
if(isOnline) {
|
if(isOnline) {
|
||||||
// if request succeded, update data
|
// if request succeded, update data
|
||||||
|
@ -172,7 +187,8 @@ Zotero.Connector = new function() {
|
||||||
this.callMethod = function(method, data, callback) {
|
this.callMethod = function(method, data, callback) {
|
||||||
Zotero.HTTP.doPost(CONNECTOR_URI+"connector/"+method, JSON.stringify(data),
|
Zotero.HTTP.doPost(CONNECTOR_URI+"connector/"+method, JSON.stringify(data),
|
||||||
function(req) {
|
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(!callback) return;
|
||||||
|
|
||||||
if(Zotero.Connector.EXCEPTION_CODES.indexOf(req.status) !== -1) {
|
if(Zotero.Connector.EXCEPTION_CODES.indexOf(req.status) !== -1) {
|
||||||
|
|
86
chrome/content/zotero/xpcom/connector/connector_debug.js
Normal file
86
chrome/content/zotero/xpcom/connector/connector_debug.js
Normal file
|
@ -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"});
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ Zotero.Server = new function() {
|
||||||
300:"Multiple Choices",
|
300:"Multiple Choices",
|
||||||
400:"Bad Request",
|
400:"Bad Request",
|
||||||
404:"Not Found",
|
404:"Not Found",
|
||||||
|
412:"Precondition Failed",
|
||||||
500:"Internal Server Error",
|
500:"Internal Server Error",
|
||||||
501:"Method Not Implemented"
|
501:"Method Not Implemented"
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const CONNECTOR_SERVER_API_VERSION = 1;
|
||||||
|
|
||||||
Zotero.Server.Connector = function() {};
|
Zotero.Server.Connector = function() {};
|
||||||
Zotero.Server.Connector._waitingForSelection = {};
|
Zotero.Server.Connector._waitingForSelection = {};
|
||||||
Zotero.Server.Connector.Data = {};
|
Zotero.Server.Connector.Data = {};
|
||||||
|
@ -227,6 +229,10 @@ Zotero.Server.Connector.GetData.prototype = {
|
||||||
* @param {Function} sendResponseCallback function to send HTTP response
|
* @param {Function} sendResponseCallback function to send HTTP response
|
||||||
*/
|
*/
|
||||||
"init":function(data, sendResponseCallback) {
|
"init":function(data, sendResponseCallback) {
|
||||||
|
if(data.apiVersion !== CONNECTOR_SERVER_API_VERSION) {
|
||||||
|
sendResponseCallback(412);
|
||||||
|
}
|
||||||
|
|
||||||
// Translator data
|
// Translator data
|
||||||
var responseData = {"preferences":{}, "translators":[]};
|
var responseData = {"preferences":{}, "translators":[]};
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ Zotero.Translate.Sandbox = {
|
||||||
*/
|
*/
|
||||||
"getOption":function(translate, option) {
|
"getOption":function(translate, option) {
|
||||||
if(typeof option !== "string") {
|
if(typeof option !== "string") {
|
||||||
throw("Translate: getOption: option must be a string");
|
throw(new Error("getOption: option must be a string"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ Zotero.Translate.Sandbox = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(typeof type !== "string") {
|
if(typeof type !== "string") {
|
||||||
throw("Translate: loadTranslator: type must be a string");
|
throw(new Error("loadTranslator: type must be a string"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ Zotero.Translate.Sandbox = {
|
||||||
translation._parentTranslator = translate;
|
translation._parentTranslator = translate;
|
||||||
|
|
||||||
if(translation instanceof Zotero.Translate.Export && !(translation instanceof Zotero.Translate.Export)) {
|
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) {
|
safeTranslator.setTranslator = function(arg) {
|
||||||
var success = translation.setTranslator(arg);
|
var success = translation.setTranslator(arg);
|
||||||
if(!success) {
|
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() };
|
safeTranslator.getTranslators = function() { return translation.getTranslators() };
|
||||||
|
@ -226,7 +226,7 @@ Zotero.Translate.Sandbox = {
|
||||||
if(callback) translate.incrementAsyncProcesses();
|
if(callback) translate.incrementAsyncProcesses();
|
||||||
var haveTranslatorFunction = function(translator) {
|
var haveTranslatorFunction = function(translator) {
|
||||||
translation.translator[0] = 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) {
|
if(Zotero.isFx) {
|
||||||
// do same origin check
|
// do same origin check
|
||||||
|
@ -243,8 +243,8 @@ Zotero.Translate.Sandbox = {
|
||||||
try {
|
try {
|
||||||
secMan.checkSameOriginURI(outerSandboxURI, innerSandboxURI, false);
|
secMan.checkSameOriginURI(outerSandboxURI, innerSandboxURI, false);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
throw "Translate: getTranslatorObject() may not be called from web or search "+
|
throw new Error("getTranslatorObject() may not be called from web or search "+
|
||||||
"translators to web or search translators from different origins.";
|
"translators to web or search translators from different origins.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,8 +262,8 @@ Zotero.Translate.Sandbox = {
|
||||||
return translation._sandboxManager.sandbox;
|
return translation._sandboxManager.sandbox;
|
||||||
} else {
|
} else {
|
||||||
if(Zotero.isConnector && !callback) {
|
if(Zotero.isConnector && !callback) {
|
||||||
throw "Translate: Translator must accept a callback to getTranslatorObject() to "+
|
throw new Error("Translator must accept a callback to getTranslatorObject() to "+
|
||||||
"operate in this translation environment.";
|
"operate in this translation environment.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.Translators.get(translation.translator[0], haveTranslatorFunction);
|
Zotero.Translators.get(translation.translator[0], haveTranslatorFunction);
|
||||||
|
@ -319,7 +319,7 @@ Zotero.Translate.Sandbox = {
|
||||||
*/
|
*/
|
||||||
"selectItems":function(translate, items, callback) {
|
"selectItems":function(translate, items, callback) {
|
||||||
if(Zotero.Utilities.isEmpty(items)) {
|
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) {
|
if(translate._selectedItems) {
|
||||||
|
@ -423,7 +423,7 @@ Zotero.Translate.Sandbox = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!item.title) {
|
if(!item.title) {
|
||||||
throw "No title specified for item";
|
throw new Error("No title specified for item");
|
||||||
}
|
}
|
||||||
|
|
||||||
// create short title
|
// create short title
|
||||||
|
@ -520,7 +520,7 @@ Zotero.Translate.Sandbox = {
|
||||||
*/
|
*/
|
||||||
"nextCollection":function(translate) {
|
"nextCollection":function(translate) {
|
||||||
if(!translate.translator[0].configOptions.getCollections) {
|
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();
|
return translate._itemGetter.nextCollection();
|
||||||
|
@ -594,7 +594,7 @@ Zotero.Translate.Base.prototype = {
|
||||||
*/
|
*/
|
||||||
"setTranslator":function(translator) {
|
"setTranslator":function(translator) {
|
||||||
if(!translator) {
|
if(!translator) {
|
||||||
throw new Error("Zotero.Translate: no translator specified");
|
throw new Error("No translator specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.translator = null;
|
this.translator = null;
|
||||||
|
@ -604,7 +604,7 @@ Zotero.Translate.Base.prototype = {
|
||||||
if(translator.translatorID) {
|
if(translator.translatorID) {
|
||||||
this.translator = [translator];
|
this.translator = [translator];
|
||||||
} else {
|
} else {
|
||||||
throw("No translatorID specified");
|
throw(new Error("No translatorID specified"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.translator = [translator];
|
this.translator = [translator];
|
||||||
|
@ -748,7 +748,7 @@ Zotero.Translate.Base.prototype = {
|
||||||
*/
|
*/
|
||||||
"getTranslators":function(getAllTranslators) {
|
"getTranslators":function(getAllTranslators) {
|
||||||
// do not allow simultaneous instances of getTranslators
|
// 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._currentState = "detect";
|
||||||
this._getAllTranslators = getAllTranslators;
|
this._getAllTranslators = getAllTranslators;
|
||||||
this._getTranslatorsGetPotentialTranslators();
|
this._getTranslatorsGetPotentialTranslators();
|
||||||
|
@ -832,7 +832,7 @@ Zotero.Translate.Base.prototype = {
|
||||||
this._currentState = "translate";
|
this._currentState = "translate";
|
||||||
|
|
||||||
if(!this.translator || !this.translator.length) {
|
if(!this.translator || !this.translator.length) {
|
||||||
throw("Translate: Failed: no translator specified");
|
throw new Error("Failed: no translator specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
this._libraryID = libraryID;
|
this._libraryID = libraryID;
|
||||||
|
@ -1300,6 +1300,7 @@ Zotero.Translate.Web.prototype._translateRPCComplete = function(obj, failureCode
|
||||||
for(var i in obj.items) {
|
for(var i in obj.items) {
|
||||||
this._runHandler("itemDone", null, obj.items[i]);
|
this._runHandler("itemDone", null, obj.items[i]);
|
||||||
}
|
}
|
||||||
|
this.newItems = obj.items;
|
||||||
this.complete(true);
|
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"]);
|
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; });
|
this.__defineGetter__("string", function() { return io.string; });
|
||||||
} else if(!Zotero.Translate.IO.Write) {
|
} 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 {
|
} else {
|
||||||
this._io = new Zotero.Translate.IO.Write(this.location,
|
this._io = new Zotero.Translate.IO.Write(this.location,
|
||||||
this.translator[0].configOptions["dataMode"],
|
this.translator[0].configOptions["dataMode"],
|
||||||
|
@ -1687,7 +1688,7 @@ Zotero.Translate.IO = {
|
||||||
var dp = Components.classes["@mozilla.org/xmlextras/domparser;1"]
|
var dp = Components.classes["@mozilla.org/xmlextras/domparser;1"]
|
||||||
.createInstance(Components.interfaces.nsIDOMParser);
|
.createInstance(Components.interfaces.nsIDOMParser);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
throw "DOMParser not supported";
|
throw new Error("DOMParser not supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1698,7 +1699,7 @@ Zotero.Translate.IO = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nodes.getElementsByTagName("parsererror").length) {
|
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;
|
return nodes;
|
||||||
|
@ -1945,7 +1946,7 @@ Zotero.Translate.IO._RDFSandbox.prototype = {
|
||||||
|
|
||||||
type = type.toLowerCase();
|
type = type.toLowerCase();
|
||||||
if(!containerTypes[type]) {
|
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);
|
var about = this._getResource(about);
|
||||||
|
@ -2016,7 +2017,7 @@ Zotero.Translate.IO._RDFSandbox.prototype = {
|
||||||
"getResourceURI":function(resource) {
|
"getResourceURI":function(resource) {
|
||||||
if(typeof(resource) == "string") return resource;
|
if(typeof(resource) == "string") return resource;
|
||||||
if(resource.uri) return resource.uri;
|
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();
|
return resource.toNT();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue