User Tools

Site Tools


datapaper

DataPaper homepage

DataPaper allows conference actors (chairs and authors) to link entities (events, authors and publications) of a conference dataset with external resources available on the Web. For this, it exposes the URIs of these resources in a Web service that can be queried using the conference entitiy URIs, so that DataConf users can view links pointing to these resources while browsing publications.

Technically, DataPaper stores the URIs, description texts and format of these resources in a NoSQL database (currently: CouchDB V-1.2 NoSQL), using entity URIs as storage keys.

DataPaper provides a backoffice interface as an unofficial WordPress plugin. Using this interface, conference actors can feed this database with links to resources related to the entities associated to their profile in the conference dataset. Publication authors can add URIs related to their own description (eg. contact info) and publications (eg. project homepages). Conference chairs can also add URIs related to conference events (eg. event homepages).

Developer

DataPaper is developed by Nicolas Armando.

Web access

The DataPaper instance used in current DataConf instances is available at http://dataconf.liris.cnrs.fr/datapaper. Conference chairs and authors can (soon) get their accounts created and enrich the entities they are responsible of.

Installation

DataPaper sources are available at https://github.com/nicearma/datapaper.

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.
datapaper.txt · Last modified: 2013/05/24 11:41 by lmedini