From bbc8f7812c78ed64357ec04b1dda47afe24f71b2 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Fri, 6 Aug 2010 17:42:14 +0000 Subject: [PATCH] Add ability to create Zotero Commons buckets via the UI - "zc-test-" is currently prepended to bucket names --- chrome/content/zotero/overlay.js | 113 ++++++++++++++++- chrome/content/zotero/overlay.xul | 1 + chrome/content/zotero/xpcom/commons.js | 160 ++++++++++--------------- 3 files changed, 173 insertions(+), 101 deletions(-) diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js index 54d6d422d..f09a2b567 100644 --- a/chrome/content/zotero/overlay.js +++ b/chrome/content/zotero/overlay.js @@ -1466,7 +1466,111 @@ var ZoteroPane = new function() Zotero.purgeDataObjects(true); } } - + + this.createCommonsBucket = function () { + var prompt = Components.classes["@mozilla.org/network/default-prompt;1"] + .createInstance(Components.interfaces.nsIPrompt); + + var invalid = false; + + while (true) { + if (invalid) { + // TODO: localize + prompt.alert("", "Invalid title. Please try again."); + invalid = false; + } + + var newTitle = {}; + var result = prompt.prompt( + "", + // TODO: localize + "Enter a title for this Zotero Commons collection:", + newTitle, + "", {} + ); + + if (!result) { + return; + } + + var title = Zotero.Utilities.prototype.trim(newTitle.value); + + if (!title) { + return; + } + + if (!Zotero.Commons.isValidBucketTitle(title)) { + invalid = true; + continue; + } + + break; + } + + invalid = false; + + var origName = title.toLowerCase(); + origName = origName.replace(/[^a-z0-9 ._-]/g, ''); + origName = origName.replace(/ /g, '-'); + origName = origName.substr(0, 32); + + while (true) { + if (invalid) { + // TODO: localize + var msg = "'" + name + "' is not a valid Zotero Commons collection identifier.\n\n" + + "Collection identifiers can contain basic Latin letters, numbers," + + "hyphens, and underscores. Spaces and other characters are not allowed."; + prompt.alert("", msg); + invalid = false; + } + + var newName = { value: origName }; + var result = prompt.prompt( + "", + // TODO: localize + "Enter an identifier for the collection '" + title + "'.\n\n" + + "The identifier will form the collection's URL " + + "(e.g., http://www.archive.org/details/" + origName + ") " + + "and can contain basic Latin letters, numbers, hyphens, and underscores. " + + "Spaces and other characters are not allowed.", + newName, + "", {} + ); + + if (!result) { + return; + } + + var name = Zotero.Utilities.prototype.trim(newName.value); + + if (!name) { + return; + } + + if (!Zotero.Commons.isValidBucketName(name)) { + invalid = true; + continue; + } + + break; + } + + // TEMP + var name = "zc-test-" + name; + + // TODO: localize + var progressWin = new Zotero.ProgressWindow(); + progressWin.changeHeadline("Creating Zotero Commons Collection"); + var icon = this.collectionsView.getImageSrc(this.collectionsView.selection.currentIndex); + progressWin.addLines(title, icon) + progressWin.show(); + + Zotero.Commons.createBucket(name, title, function () { + progressWin.startCloseTimer(); + }); + } + + this.refreshCommonsBucket = function() { if (!this.collectionsView || !this.collectionsView.selection @@ -1776,7 +1880,8 @@ var ZoteroPane = new function() exportFile: 9, loadReport: 10, emptyTrash: 11, - refreshCommonsBucket: 12 + createCommonsBucket: 12, + refreshCommonsBucket: 13 }; var itemGroup = this.collectionsView._getItemAtRow(this.collectionsView.selection.currentIndex); @@ -1845,7 +1950,9 @@ var ZoteroPane = new function() show = [m.emptyTrash]; } else if (itemGroup.isHeader()) { - // Don't show menu for headers + if (itemGroup.ref.id == 'commons-header') { + show = [m.createCommonsBucket]; + } } else if (itemGroup.isBucket()) { show = [m.refreshCommonsBucket]; diff --git a/chrome/content/zotero/overlay.xul b/chrome/content/zotero/overlay.xul index 18c4f139d..6c894b2c4 100644 --- a/chrome/content/zotero/overlay.xul +++ b/chrome/content/zotero/overlay.xul @@ -107,6 +107,7 @@ + diff --git a/chrome/content/zotero/xpcom/commons.js b/chrome/content/zotero/xpcom/commons.js index e271ffe17..8330ef1f0 100644 --- a/chrome/content/zotero/xpcom/commons.js +++ b/chrome/content/zotero/xpcom/commons.js @@ -173,8 +173,30 @@ Zotero.Commons = new function() { }; - // outdated - this.createBucket = function (item, onBucketQueued, onBucketCreated, waitForCreation) { + this.isValidBucketTitle = function (title) { + if (!title) { + return false; + } + if (title.constructor.name != 'String') { + return false; + } + return title.length <= 255; + } + + + this.isValidBucketName = function (name) { + if (!name) { + return false; + } + if (name.constructor.name != 'String') { + return false; + } + + return name.match(/^[a-z0-9_-]{0,32}$/); // TODO: check IA pattern + } + + + this.createBucket = function (name, title, onBucketCreated) { var headers = { "x-archive-auto-make-bucket":"1", "x-archive-meta01-collection":"zoterocommons", @@ -183,111 +205,49 @@ Zotero.Commons = new function() { "x-archive-meta01-language":"eng" }; - var itemTitle = item.getDisplayTitle(); - if (itemTitle) { - headers["x-archive-meta-title"] = itemTitle; + if (!this.isValidBucketName(name)) { + throw ("Bucket name '" + name + "' must be ASCII in Zotero.Commons.createBucket()"); } - var itemLanguage = item.getField('language'); + if (!title) { + title = name; + } + + if (!this.isValidBucketTitle(title)) { + throw ("Invalid title '" + title + "' in Zotero.Commons.createBucket()"); + } + + headers["x-archive-meta-title"] = title; + // TODO: use proper language code? - if (itemLanguage) { - headers["x-archive-meta01-language"] = itemLanguage; - } + //if (itemLanguage) { + // headers["x-archive-meta01-language"] = itemLanguage; + //} - var itemType = Zotero.ItemTypes.getName(item.itemTypeID); - switch (itemType) { - case 'artwork': - case 'map': - headers["x-archive-meta-mediatype"] = "image"; - break; - - case 'radioBroadcast': - case 'audioRecording': - headers["x-archive-meta-mediatype"] = "audio"; - break; - - case 'tvBroadcast': - case 'videoRecording': - headers["x-archive-meta-mediatype"] = "movies"; - break; - - default: - headers["x-archive-meta-mediatype"] = "texts"; - } + headers["x-archive-meta-mediatype"] = "texts"; - var requestCallback = function (req, id, tries) { - Zotero.debug(req.status); - - if (req.status == 201) { - var bucket = new Zotero.Commons.Bucket(id); + Zotero.Commons.createAuthenticatedRequest( + "PUT", "/" + name, headers, this.accessKey, this.secretKey, + function (req) { + Zotero.debug(req.status); - if (waitForCreation) { - Zotero.debug('Waiting for bucket creation'); + if (req.status == 201) { + var bucket = new Zotero.Commons.Bucket(name); + _buckets[name] = bucket; - setTimeout(function () { - var tries = 15; - bucket.exists(function (found) { - if (found == 1) { - onBucketCreated(bucket); - } - else if (!found) { - alert("Commons: Bucket " + bucket.name + " not found after creation"); - } - else { - alert("Commons: Error checking for bucket " + bucket.name + " after creation"); - } - }, tries); - }, Zotero.Commons.postCreateBucketDelay); + Zotero.Notifier.trigger('add', 'bucket', [name]); - if (onBucketQueued) { - onBucketQueued(); - } - } - else { - if (onBucketQueued) { - onBucketQueued(); - } if (onBucketCreated) { - onBucketCreated(bucket); + onBucketCreated(); } } - } - else { - Zotero.debug(req.responseText); - - // DEBUG: What is this for? - if (req.status == 409) { - tries++; - // Max tries - if (tries > 3) { - alert("Upload failed"); - return; - } - - id = Zotero.Commons.getNewBucketName(); - Zotero.Commons.createAuthenticatedRequest( - "PUT", "/" + id, headers, this.accessKey, this.secretKey, - function (req) { - requestCallback(req, id, tries); - } - ); - - } else { Zotero.debug(req.status); Zotero.debug(req.responseText); - alert("Upload failed"); + Zotero.Commons.error("Error creating bucket '" + name + "'"); } } - }; - - var id = Zotero.Commons.getNewBucketName(); - Zotero.Commons.createAuthenticatedRequest( - "PUT", "/" + id, headers, this.accessKey, this.secretKey, - function (req) { - requestCallback(req, id, 1); - } ); } @@ -358,11 +318,11 @@ Zotero.Commons = new function() { var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"] .createInstance(Components.interfaces.nsIXMLHttpRequest); req.open(method, Zotero.Commons.apiUrl + resource, false); - + for(var header in headers) { req.setRequestHeader(header, headers[header]); } - + return req; } @@ -396,8 +356,11 @@ Zotero.Commons = new function() { } - this.debug = function (message, level) { - Zotero.debug("Commons: " + message, level); + this.error = function (message) { + Components.utils.reportError(message); + var prompt = Components.classes["@mozilla.org/network/default-prompt;1"] + .createInstance(Components.interfaces.nsIPrompt); + prompt.alert("Zotero Commons Error", message); } } @@ -591,7 +554,7 @@ Zotero.Commons.Bucket.prototype.getItems = function (callback) { var rdfURI = self.downloadURI + '/' // Strip characters IA strips - + zip.key.replace(/[^-A-Za-z0-9_.]/g, '-').replace(/-+/g, '-'); + + zip.key.replace(/[^-A-Za-z0-9_\.]/g, '-').replace(/-+/g, '-'); rdfURI = rdfURI.replace(/\.zip$/, "_zotero.rdf"); Zotero.Utilities.HTTP.doGet(rdfURI, function (xmlhttp) { @@ -673,14 +636,15 @@ Zotero.Commons.Bucket.prototype.getItems = function (callback) { Zotero.debug("Downloading OCRed PDF " + iaFileName); - var title = Zotero.localeJoin([child.title, '(OCR)']); - var baseName = child.key; + var baseName = child.title.replace(/\.pdf$/, '') + baseName += ' (OCR)'; + var title = baseName + '.pdf'; if (!progressWin) { progressWin = new Zotero.ProgressWindow(); progressWin.changeHeadline("Downloading OCRed PDFs"); // TODO: localize } - progressWin.addLines([child.title], [progressWinIcon]); + progressWin.addLines([title], [progressWinIcon]); progressWin.show(); progressWin.startCloseTimer(8000);