- Fix encoding issues with uploaded files
- Use a more reliable method of generating the file list that doesn't depend on IA filename sanity
- Get user display name from and prepend slugify()'ed version to bucket names (still including "zc-test-" for now)
This commit is contained in:
Dan Stillman 2010-09-03 20:22:32 +00:00
parent 32c4ea1a6b
commit 3ce6e429ed
3 changed files with 168 additions and 134 deletions

View file

@ -1510,105 +1510,105 @@ var ZoteroPane = new function()
} }
this.createCommonsBucket = function () { this.createCommonsBucket = function () {
var prompt = Components.classes["@mozilla.org/network/default-prompt;1"] Zotero.Commons.getBuckets(function () {
.createInstance(Components.interfaces.nsIPrompt); var prompt = Components.classes["@mozilla.org/network/default-prompt;1"]
.createInstance(Components.interfaces.nsIPrompt);
var invalid = false;
var invalid = false;
while (true) {
if (invalid) { while (true) {
// TODO: localize if (invalid) {
prompt.alert("", "Invalid title. Please try again."); // TODO: localize
invalid = false; 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;
} }
var newTitle = {}; invalid = false;
var result = prompt.prompt(
"",
// TODO: localize
"Enter a title for this Zotero Commons collection:",
newTitle,
"", {}
);
if (!result) { var origName = title.toLowerCase();
return; 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 on archive.org "
+ "and can contain basic Latin letters, numbers, hyphens, and underscores. "
+ "Spaces and other characters are not allowed.\n\n"
+ '"zc-test-' + Zotero.Commons.userNameSlug + '-" '
+ "will be automatically prepended to your entry.",
newName,
"", {}
);
if (!result) {
return;
}
var name = Zotero.Utilities.prototype.trim(newName.value);
if (!name) {
return;
}
if (!Zotero.Commons.isValidBucketName(name)) {
invalid = true;
continue;
}
break;
} }
var title = Zotero.Utilities.prototype.trim(newTitle.value); // 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();
if (!title) { Zotero.Commons.createBucket(name, title, function () {
return; progressWin.startCloseTimer();
} });
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();
}); });
} }

View file

@ -257,12 +257,16 @@ Zotero.CollectionTreeView.prototype.refresh = function()
id: "commons-header", id: "commons-header",
label: "Commons", // TODO: localize label: "Commons", // TODO: localize
expand: function (buckets) { expand: function (buckets) {
if (!buckets) { var show = function (buckets) {
var buckets = Zotero.Commons.getBuckets(); for each(var bucket in buckets) {
self._showItem(new Zotero.ItemGroup('bucket', bucket), 1);
}
} }
if (buckets) {
for each(var bucket in buckets) { show(buckets);
self._showItem(new Zotero.ItemGroup('bucket', bucket), 1); }
else {
Zotero.Commons.getBuckets(show);
} }
} }
}; };

View file

@ -58,6 +58,13 @@ Zotero.Commons = new function() {
return Zotero.Prefs.set("commons.secretKey", val); return Zotero.Prefs.set("commons.secretKey", val);
}); });
this.__defineGetter__('userNameSlug', function () {
if (!_userNameSlug) {
throw ("Username not set in Zotero.Commons.userNameSlug getter");
}
return _userNameSlug;
});
this.RDF_TRANSLATOR = { this.RDF_TRANSLATOR = {
'label': 'Zotero RDF', 'label': 'Zotero RDF',
'target': 'rdf', 'target': 'rdf',
@ -76,6 +83,8 @@ Zotero.Commons = new function() {
this.refreshNeeded = true; this.refreshNeeded = true;
var _userName;
var _userNameSlug;
var _buckets = {}; var _buckets = {};
var _bucketsLoading = false; var _bucketsLoading = false;
var _bucketsLoaded = false; var _bucketsLoaded = false;
@ -84,19 +93,28 @@ Zotero.Commons = new function() {
this.getBuckets = function (callback) { this.getBuckets = function (callback) {
if (!this.enabled) { if (!this.enabled) {
return _buckets; if (callback) {
callback(_buckets);
}
return;
} }
var accessKey = this.accessKey; var accessKey = this.accessKey;
var secretKey = this.secretKey; var secretKey = this.secretKey;
if (_bucketsLoaded) { if (_bucketsLoaded) {
return _buckets; if (callback) {
callback(_buckets);
}
return;
} }
if (_bucketsLoading) { if (_bucketsLoading) {
Zotero.debug("Already loading buckets"); Zotero.debug("Already loading buckets");
return _buckets; if (callback) {
callback(_buckets);
}
return;
} }
_bucketsLoading = true; _bucketsLoading = true;
@ -121,6 +139,9 @@ Zotero.Commons = new function() {
Zotero.debug(req.responseText); Zotero.debug(req.responseText);
_userName = req.responseXML.getElementsByTagName('DisplayName')[0].textContent;
_userNameSlug = Zotero.Commons.slugify(_userName);
var currentBuckets = []; var currentBuckets = [];
var IABuckets = []; var IABuckets = [];
@ -174,15 +195,13 @@ Zotero.Commons = new function() {
} }
if (callback) { if (callback) {
callback(); callback(_buckets);
} }
}; };
var req = this.createAuthenticatedRequest( this.createAuthenticatedRequest(
"GET", "/", {}, accessKey, secretKey, syncCallback, null, false, true "GET", "/", {}, accessKey, secretKey, syncCallback, null, false, true
); );
return _buckets;
}; };
@ -210,12 +229,16 @@ Zotero.Commons = new function() {
this.createBucket = function (name, title, onBucketCreated) { this.createBucket = function (name, title, onBucketCreated) {
if (!_userName) {
throw new Exception("Username not set in Zotero.Commons.createBucket()");
}
name = "zc-test-" + this.userSlug + "-" + name;
var headers = { var headers = {
"x-archive-auto-make-bucket":"1", "x-archive-auto-make-bucket":"1",
"x-archive-meta01-collection":"zoterocommons", "x-archive-meta01-collection":"zoterocommons",
"x-archive-meta02-collection":"scholarworkspaces", "x-archive-meta02-collection":"scholarworkspaces",
"x-archive-meta-sponsor":"Andrew W. Mellon Foundation", "x-archive-meta-sponsor":"Andrew W. Mellon Foundation"
"x-archive-meta01-language":"eng"
}; };
if (!this.isValidBucketName(name)) { if (!this.isValidBucketName(name)) {
@ -231,12 +254,6 @@ Zotero.Commons = new function() {
} }
headers["x-archive-meta-title"] = title; headers["x-archive-meta-title"] = title;
// TODO: use proper language code?
//if (itemLanguage) {
// headers["x-archive-meta01-language"] = itemLanguage;
//}
headers["x-archive-meta-mediatype"] = "texts"; headers["x-archive-meta-mediatype"] = "texts";
Zotero.Commons.createAuthenticatedRequest( Zotero.Commons.createAuthenticatedRequest(
@ -266,7 +283,8 @@ Zotero.Commons = new function() {
this.createAuthenticatedRequest = function (method, resource, headers, accessKey, secretKey, callback, data, sendAsBinary, noCache) { this.createAuthenticatedRequest = function (method, resource, headers, accessKey, secretKey, callback, data, sendAsBinary, noCache) {
var url = Zotero.Commons.apiUrl + resource; var apiURL = Zotero.Commons.apiUrl;
var url = apiURL + resource;
Zotero.debug("Commons HTTP " + method + ": " + url); Zotero.debug("Commons HTTP " + method + ": " + url);
@ -291,7 +309,8 @@ Zotero.Commons = new function() {
} }
signatureData += amz.sort().join(''); signatureData += amz.sort().join('');
signatureData += resource; signatureData += req.channel.URI.spec.substr(apiURL.length);
var signature = Zotero.Commons.SHA1.b64_hmac_sha1(secretKey, signatureData) + '='; var signature = Zotero.Commons.SHA1.b64_hmac_sha1(secretKey, signatureData) + '=';
headers["Authorization"] = "AWS " + accessKey + ":" + signature; headers["Authorization"] = "AWS " + accessKey + ":" + signature;
//headers["Authorization"] = "LOW " + accessKey + ":" + secretKey; //headers["Authorization"] = "LOW " + accessKey + ":" + secretKey;
@ -369,17 +388,22 @@ Zotero.Commons = new function() {
} }
this.encodeURIComponent = function (str) {
return encodeURIComponent(str).replace("'", '%27');
}
this.error = function (message) { this.error = function (message) {
Components.utils.reportError(message); Components.utils.reportError(message);
var prompt = Components.classes["@mozilla.org/network/default-prompt;1"] var prompt = Components.classes["@mozilla.org/network/default-prompt;1"]
.createInstance(Components.interfaces.nsIPrompt); .createInstance(Components.interfaces.nsIPrompt);
prompt.alert("Zotero Commons Error", message); prompt.alert("Zotero Commons Error", message);
} }
this.slugify = function (input) {
var slug = Zotero.Utilities.prototype.trim(input)
.toLowerCase()
.replace(/[^a-z0-9 ._-]/g, "")
//.replace(/ /g, "_");
.replace(/ /g, "-");
return slug;
}
} }
@ -404,19 +428,19 @@ Zotero.Commons.Bucket = function (name) {
Zotero.Commons.Bucket.prototype.__defineGetter__('uri', function () { Zotero.Commons.Bucket.prototype.__defineGetter__('uri', function () {
return 'http://www.archive.org/details/' + encodeURIComponent(this.name); return 'http://www.archive.org/details/' + this.name;
}); });
Zotero.Commons.Bucket.prototype.__defineGetter__('downloadURI', function () { Zotero.Commons.Bucket.prototype.__defineGetter__('downloadURI', function () {
return 'http://www.archive.org/download/' + encodeURIComponent(this.name); return 'http://www.archive.org/download/' + this.name;
}); });
Zotero.Commons.Bucket.prototype.__defineGetter__('metadataURI', function () { Zotero.Commons.Bucket.prototype.__defineGetter__('metadataURI', function () {
return this.downloadURI + '/' + encodeURIComponent(this.name) + '_meta.xml'; return this.downloadURI + '/' + this.name + '_meta.xml';
}); });
Zotero.Commons.Bucket.prototype.__defineGetter__('apiPath', function() { Zotero.Commons.Bucket.prototype.__defineGetter__('apiPath', function() {
return '/' + encodeURIComponent(this.name); return '/' + this.name;
}); });
Zotero.Commons.Bucket.prototype.__defineGetter__('apiURI', function() { Zotero.Commons.Bucket.prototype.__defineGetter__('apiURI', function() {
@ -521,7 +545,7 @@ Zotero.Commons.Bucket.prototype.getItems = function (callback) {
var zips = []; var zips = [];
// Generate a list of extracted PDFs with OCRed equivalents // Parse files XML to get RDF and OCRed PDFs
var ocrOriginals = {}; var ocrOriginals = {};
var ocrPDFXML = xml.file.(@source == 'derivative').(format == 'Additional Text PDF').@name; var ocrPDFXML = xml.file.(@source == 'derivative').(format == 'Additional Text PDF').@name;
for each(var pdf in ocrPDFXML) { for each(var pdf in ocrPDFXML) {
@ -533,10 +557,18 @@ Zotero.Commons.Bucket.prototype.getItems = function (callback) {
var key = zipXML.@name.toString(); var key = zipXML.@name.toString();
var title = zipXML.title.toString(); var title = zipXML.title.toString();
var childrenXML = xml.file.(typeof zipsource != 'undefined').(zipsource == key).(format != 'Zotero RDF'); var childrenXML = xml.file.(typeof zipsource != 'undefined').(zipsource == key);
var rdf;
var children = []; var children = [];
for each(var childXML in childrenXML) { for each(var childXML in childrenXML) {
var childKey = childXML.@name.toString(); var childKey = childXML.@name.toString();
// Pull out RDF filename
if (childXML.format == 'Zotero RDF') {
rdf = childKey;
continue;
}
children.push({ children.push({
key: childKey, key: childKey,
title: childXML.title.toString(), title: childXML.title.toString(),
@ -553,6 +585,7 @@ Zotero.Commons.Bucket.prototype.getItems = function (callback) {
zips.push({ zips.push({
key: key, key: key,
title: title, title: title,
rdf: rdf,
children: children children: children
}); });
} }
@ -585,10 +618,7 @@ Zotero.Commons.Bucket.prototype.getItems = function (callback) {
return; return;
} }
var rdfURI = self.downloadURI + '/' var rdfURI = self.downloadURI + '/' + zip.rdf;
// Strip characters IA strips
+ zip.key.replace(/[^-A-Za-z0-9_\.]/g, '-').replace(/-+/g, '-');
rdfURI = rdfURI.replace(/\.zip$/, "_zotero.rdf");
Zotero.Utilities.HTTP.doGet(rdfURI, function (xmlhttp) { Zotero.Utilities.HTTP.doGet(rdfURI, function (xmlhttp) {
// If RDF not available, skip item // If RDF not available, skip item
@ -945,7 +975,7 @@ Zotero.Commons.Bucket.prototype.deleteItems = function (ids) {
var bucket = this; var bucket = this;
for each(let key in keysToDelete) { for each(let key in keysToDelete) {
let path = resource + '/' + Zotero.Commons.encodeURIComponent(key); let path = resource + '/' + key;
Zotero.Commons.createAuthenticatedRequest( Zotero.Commons.createAuthenticatedRequest(
method, path, headers, this.accessKey, this.secretKey, function (req) { method, path, headers, this.accessKey, this.secretKey, function (req) {
@ -1076,7 +1106,7 @@ Zotero.Commons.Bucket.prototype.putFile = function (file, mimeType, callback) {
var fileName = file.leafName; var fileName = file.leafName;
var fileNameHyphened = fileName.replace(/ /g,'-'); var fileNameHyphened = fileName.replace(/ /g,'-');
var method = "PUT"; var method = "PUT";
var resource = this.apiPath + '/' + Zotero.Commons.encodeURIComponent(fileNameHyphened); var resource = this.apiPath + '/' + fileName;
var content = Zotero.File.getBinaryContents(file); var content = Zotero.File.getBinaryContents(file);
var headers = {}; var headers = {};
var self = this; var self = this;
@ -1086,7 +1116,7 @@ Zotero.Commons.Bucket.prototype.putFile = function (file, mimeType, callback) {
// Success // Success
if (req.status == 201) { if (req.status == 201) {
Zotero.debug("Commons: " + fileNameHyphened + " was uploaded successfully."); Zotero.debug("Commons: " + fileName + " was uploaded successfully.");
if (callback) { if (callback) {
callback(req.channel.URI.spec); callback(req.channel.URI.spec);
@ -1119,7 +1149,7 @@ Zotero.Commons.Bucket.prototype.putFile = function (file, mimeType, callback) {
Zotero.Commons.Bucket.prototype.getItemURI = function (item) { Zotero.Commons.Bucket.prototype.getItemURI = function (item) {
return this.uri + '#' + Zotero.Commons.encodeURIComponent(item.getField('title')); return this.uri + '#' + encodeURIComponent(item.getField('title'));
} }