DataPaper is a Web service that links publications and authors to external resources available on the Web, added by their authors, so that DataConf users can view links pointing to these resources while browsing publications. DataPaper relies on a CouchDB V-1.2 NoSQL database. It's backoffice interface is also provided as a WordNet plugin.
Configuration
Before continuing, you must have installed CouchDB on your server. Create a user and use this user to proceed with the following steps:
Create a database, for instance: “datapaper” (you can change this name)
Create a new document in “_design” and name it “public”
In this document, create 3 views and one validation function, with the following code:
First view: name=“by_all2”:
function(doc) {
emit(doc._id, doc);
}
Second view: name=“by_all”
function(doc) {
for(var key in doc.public)
emit(doc._id, doc.public[key]);
}
Third view: name=“by_type”
function(doc) {
var infoUser=new RegExp("user");
for(var key in doc.public){
if(infoUser.test(doc.public[key].type)){
emit([doc._id,'user-information'], doc.public[key]);
}else{
emit([doc._id,'document'], doc.public[key]);
}
}
}
Validation function: name=“validate_doc_update”
function(newDoc, oldDoc, userCtx, secObj) {
if (newDoc._deleted === true) {
if ((userCtx.roles.indexOf('_admin') !== -1) ||
(userCtx.name == oldDoc.name)) {
return;
} else {
throw({forbidden: 'Only admins may delete other user docs.'});
}
}
if (!newDoc._id) {
throw({forbidden: 'doc.name is required'});
}
if(!secObj){
throw({forbidden: 'You dont have the session for make a change.'});
}
if (!newDoc.private) {
throw({forbidden: 'you dont have private, and is required'});
} else {
//for put more type of document please change this objet
if(newDoc.hasOwnProperty("edit_by")){
var documentPrivate = "name, url";
for (var key in newDoc.private) {
if (!(documentPrivate.indexOf(key) > -1)) {
throw({forbidden: key + ' private is required'});
}
}
}
}
if (!newDoc.public) {
throw({forbidden: 'you dont have public, and is required'});
} else {
for (j=0; j < newDoc.public.length; j++) {
for (i = 0; i < newDoc.public[j].length; i++) {
if (!newDoc.public[key][i].description) {
throw({forbidden: 'in ' + key + 'you dont have description, and is required'});
}
if (!newDoc.public[key][i].url) {
throw({forbidden: 'in ' + key + 'you dont have url, and is required'});
}
if (!newDoc.public[key][i].type) {
throw({forbidden: 'in ' + key + 'you dont have url, and is required'});
}
}
}
}
if (newDoc.roles && !isArray(newDoc.roles)) {
throw({forbidden: 'doc.roles must be an array'});
}
}
Here is the whole document:
{
"_id": "_design/public",
"language": "javascript",
"views": {
"by_all2": {
"map": "function(doc) {
emit(doc._id, doc);
}"
},
"by_all": {
"map": "function(doc) {
for(var key in doc.public)
emit(doc._id, doc.public[key]);
}"
},
"by_type": {
"map": "function(doc) {
var infoUser=new RegExp(\"user\");
for(var key in doc.public){
if(infoUser.test(doc.public[key].type)){
emit([doc._id,'user-information'], doc.public[key]);
}else{
emit([doc._id,'document'], doc.public[key]);
}
}
}"
}
},
"validate_doc_update": "function(newDoc, oldDoc, userCtx, secObj) {
if (newDoc._deleted === true) {
if ((userCtx.roles.indexOf('_admin') !== -1) || (userCtx.name == oldDoc.name)) {
return;
} else {
throw({forbidden: 'Only admins may delete other user docs.'});
}
}
if (!newDoc._id) {
throw({forbidden: 'doc.name is required'});
}
if(!secObj){
throw({forbidden: 'You dont have the session for make a change.'});
}
if (!newDoc.private) {
throw({forbidden: 'you dont have private, and is required'});
} else {
//to put more types of document please change this objet
if(newDoc.hasOwnProperty(\"edit_by\")){
var documentPrivate = \"name, url\";
for (var key in newDoc.private) {
if (!(documentPrivate.indexOf(key) > -1)) {
throw({forbidden: key + ' private is required'});
}
}
}
}
if (!newDoc.public) {
throw({forbidden: 'you dont have public, and is required'});
} else {
//to put more types of document please change this objet
for (j=0; j < newDoc.public.length; j++) {
for (i = 0; i < newDoc.public[j].length; i++) {
if (!newDoc.public[key][i].description) {
throw({forbidden: 'in ' + key + 'you dont have description, and is required'});
}
if (!newDoc.public[key][i].url) {
throw({forbidden: 'in ' + key + 'you dont have url, and is required'});
}
if (!newDoc.public[key][i].type) {
throw({forbidden: 'in ' + key + 'you dont have url, and is required'});
}
}
}
}
if (newDoc.roles && !isArray(newDoc.roles)) {
throw({forbidden: 'doc.roles must be an array'});
}
}"
}
The last configuration step is accept CORS and JSONP requests. For this, in the CouchDB configuration file, you must set to “true” the values of allow_jsonp and enable_cors.