From 90a27f8d4b540eddb30ff64c2422dca17746aa40 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Fri, 19 May 2017 08:09:32 -0400 Subject: [PATCH] Add Zotero.URI.getURIItemLibraryKeyFromDB() Allows getting libraryID and key without relying on library data being loaded (e.g., at startup) --- chrome/content/zotero/xpcom/uri.js | 92 ++++++++++++++++++++++++++++++ test/tests/uriTest.js | 37 ++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 test/tests/uriTest.js diff --git a/chrome/content/zotero/xpcom/uri.js b/chrome/content/zotero/xpcom/uri.js index 19a2584910..d2191fa287 100644 --- a/chrome/content/zotero/xpcom/uri.js +++ b/chrome/content/zotero/xpcom/uri.js @@ -249,6 +249,17 @@ Zotero.URI = new function () { return this._getURIObject(itemURI, 'item'); } + + /** + * Convert an item URI into a libraryID and key from the database, without relying on global state + * + * Note that while the URI must point to a valid library, the item doesn't need to exist + */ + this.getURIItemLibraryKeyFromDB = function (itemURI) { + return this._getURIObjectLibraryKeyFromDB(itemURI, 'item'); + } + + /** * @param {String} itemURI * @return {Integer|FALSE} - itemID of matching item, or FALSE if none @@ -345,6 +356,7 @@ Zotero.URI = new function () { return retObj; }; + /** * Convert an object URI into a Zotero.Library that the object is in * @@ -381,4 +393,84 @@ Zotero.URI = new function () { return library; } + + + /** + * Convert an object URI into a libraryID from the database, without relying on global state + * + * @param {String} objectURI + * @return {Promise} - A promise for either a libraryID or FALSE if a matching + * library couldn't be found + */ + this._getURIObjectLibraryID = Zotero.Promise.coroutine(function* (objectURI) { + let uri = objectURI.replace(/\/+$/, ''); // Drop trailing "/" + let uriParts = uri.match(uriPartsRe); + + let libraryID; + if (uriParts[1] == 'users') { + let type = uriParts[4]; + // Personal library + if (!type || type == 'publications') { + libraryID = yield Zotero.DB.valueQueryAsync( + "SELECT libraryID FROM libraries WHERE type='user'" + ); + } + // Feed libraries + else { + libraryID = type.split('/')[1]; + } + } + // Group libraries + else { + libraryID = yield Zotero.DB.valueQueryAsync( + "SELECT libraryID FROM groups WHERE groupID=?", uriParts[3] + ); + } + + if (!libraryID) { + Zotero.debug("Could not find a library for URI " + objectURI, 2, true); + return false; + } + + return libraryID; + }); + + + + /** + * Convert an object URI into a libraryID and key from the database, without relying on global state + * + * Note that while the URI must point to a valid library, the object doesn't need to exist + * + * @param {String} objectURI - Object URI + * @param {String} type - Object type + * @return {Promise} - A promise for an object with 'objectType', 'libraryID', 'key' + * or FALSE if library didn't exist + */ + this._getURIObjectLibraryKeyFromDB = Zotero.Promise.coroutine(function* (objectURI, type) { + let uri = objectURI.replace(/\/+$/, ''); // Drop trailing / + let uriParts = uri.match(uriPartsRe); + + if (!uriParts) { + throw new Error("Could not parse object URI " + uri); + } + + let libraryID = yield this._getURIObjectLibraryID(uri); + if (!libraryID) { + return false; + } + + let retObj = { libraryID }; + if (!uriParts[5]) { + // References the library itself + return false; + } + + retObj.objectType = uriParts[5] == 'items' ? 'item' : 'collection'; + retObj.key = uriParts[6]; + + if (type && type != retObj.objectType) return false; + + return retObj; + }); } diff --git a/test/tests/uriTest.js b/test/tests/uriTest.js new file mode 100644 index 0000000000..4543eccba9 --- /dev/null +++ b/test/tests/uriTest.js @@ -0,0 +1,37 @@ +describe("Zotero.URI", function() { + describe("#getURIItemLibraryKeyFromDB()", function () { + it("should handle user library", function* () { + var key = 'ABCD2345'; + var uri = `http://zotero.org/users/5/items/${key}`; + var obj = yield Zotero.URI.getURIItemLibraryKeyFromDB(uri); + assert.propertyVal(obj, 'libraryID', Zotero.Libraries.userLibraryID); + assert.propertyVal(obj, 'key', key); + }); + + it("should handle user library with local user key", function* () { + var key = 'ABCD2345'; + var uri = `http://zotero.org/users/local/aaaaaaaa/items/${key}`; + var obj = yield Zotero.URI.getURIItemLibraryKeyFromDB(uri); + assert.propertyVal(obj, 'libraryID', Zotero.Libraries.userLibraryID); + assert.propertyVal(obj, 'key', key); + }); + + it("should handle publications URI", function* () { + var key = 'ABCD2345'; + var uri = `http://zotero.org/users/5/publications/items/${key}`; + var obj = yield Zotero.URI.getURIItemLibraryKeyFromDB(uri); + assert.propertyVal(obj, 'libraryID', Zotero.Libraries.userLibraryID); + assert.propertyVal(obj, 'key', key); + }); + + it("should handle group URI", function* () { + var group = yield getGroup(); + + var key = 'ABCD2345'; + var uri = `http://zotero.org/groups/${group.id}/items/${key}`; + var obj = yield Zotero.URI.getURIItemLibraryKeyFromDB(uri); + assert.propertyVal(obj, 'libraryID', group.libraryID); + assert.propertyVal(obj, 'key', key); + }); + }); +});