Ignore:
Timestamp:
09/07/12 16:59:14 (13 years ago)
Author:
hendrikvanantwerpen
Message:

Next steps to actually make taking surveys possible.

Split Controller in Router and Content. Updated the view.html to work
with the new app/Content mechanism. Include view page in build profile.

Rearranged Couch design documents per type. Changed config tool so the
docs.js can be more readable, functions don't have to be on one line
anymore but are serialized later. Because the .htaccess proxy is limited
to the rft database for security reasons, the config tool has to be run
on Node.js, to be able to access the Couch port (which is limited by
cross domain security in the browser).

Added elastic search to .htaccess proxy as well. Seperated CouchStore?
from rft/store, which contains application specific data.

Removed some old API files that were hanging around still.

Introduced preview mode for viewSurvey page. Changed survey page to
only show published questions to be included. The surveys page has
three categories: drafts, published and runs. Creating survey runs is
not yet implemented.

Location:
Dev/branches/rest-dojo-ui/client/config
Files:
1 added
1 deleted
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • Dev/branches/rest-dojo-ui/client/config/db.js

    r408 r410  
    1 require([
    2          'dojo/_base/json',
    3          'dojo/_base/lang',
    4          'dojo/_base/xhr',
    5          'dojo/parser',
    6          'dojo/query',
    7          'dijit/registry',
    8          'dojo/domReady!'
    9 ],function(json,lang,xhr,parser,query,registry){
    10     var logNode;
    11     var usernameInput, passwordInput, resetInput, configButton;
    12     var defaultUsername = "", defaultPassword = "";
    13     var dbUrl = "../data/";
     1define([
     2     'dojo/_base/json',
     3     'dojo/_base/lang',
     4     'dojo/Deferred',
     5     'dojo/request',
     6     'dojox/lang/functional',
     7     './docs'
     8],function(json,lang,Deferred,request,func,docs){
     9    var dbUrl = "http://localhost:5984/";
    1410
    15     parser.parse()
    16     .then(function(){
    17         query("#log").forEach(function(n){logNode = n;});
    18         usernameInput = registry.byId('username');
    19         passwordInput = registry.byId('password');
    20         resetInput = registry.byId('reset');
    21         configButton = registry.byId('configure');
    22 
    23         usernameInput.set('value',defaultUsername);
    24         passwordInput.set('value',defaultPassword);
    25         configButton.on('click',configure);
    26 
    27         log("Give CouchDB admin username & password and click 'Configure' to start.\nIf the database already exists, rft_admin password will suffice.",true);
    28     });
    29 
    30     function configure(){
    31         var docs;
    32 
    33         log("Configuring CouchDB for RFT:",true);
    34 
    35         var username = usernameInput.get('value');
    36         var password = passwordInput.get('value');
    37         var reset = resetInput.get('value');
    38 
    39         log("Downloading most recent configuration.");
    40         xhr('GET',{
    41             url: 'docs.json',
    42             handleAs: 'json',
    43             sync: true
    44         },true)
    45         .then(function(result){
    46             docs = result;
    47         });
    48 
    49         function req(method,url,body) {
    50             var args = {
    51                 url: dbUrl+url,
    52                 contentType: 'application/json',
    53                 handleAs: 'json',
    54                 sync: true
    55             };
    56             if ( !body || lang.isObject(body) ) {
    57                 body = json.toJson(body || {});
    58             }
    59             args.rawBody = body;
    60             if ( username ) {
    61                 args.user = username;
    62                 args.password = password;
    63             }
    64             return xhr(method,args,true);
     11    function serializeFunctions(value) {
     12        if ( value === null ) {
     13            return null;
     14        } else if ( lang.isArray(value) ) {
     15            return value;
     16        } else if ( lang.isFunction(value) ) {
     17            return value.toString();
     18        } else if ( lang.isObject(value) ) {
     19            return func.mapIn(value,serializeFunctions);
     20        } else {
     21            return value;
    6522        }
    66 
    67         log("Checking CouchDB version");
    68         req('GET','/')
    69         .then(function(res){
    70             if (res.version !== "1.2.0" ) {
    71                 log("Found "+res.version+", only tested with CouchDB 1.2.0")
    72             } else {
    73                 log("CouchDB 1.2.0 found")
    74             }
    75         });
    76 
    77         var exists = false;
    78         log("Checking database 'rft'");
    79         req('GET','/rft')
    80         .then(function(db){
    81             log("Database 'rft' found.")
    82             exists = true;
    83         });
    84         if ( exists && reset ) {
    85             req('DELETE','/rft');
    86             exists = false;
    87         }
    88         if ( !exists ) {
    89             log("Creating database 'rft'")
    90             req('PUT','/rft')
    91         };
    92 
    93         function processDoc(docUrl,doc){
    94             var configAction = doc.__configAction;
    95             delete doc.__configAction;
    96             switch (configAction) {
    97                 case "ignore":
    98                     log(docUrl+" ignored.");
    99                     return false;
    100                 case "update":
    101                     log(docUrl+" updating.");
    102                     return req('GET',docUrl)
    103                     .then(function(oldDoc){
    104                         lang.mixin(oldDoc,doc);
    105                         return req('PUT',docUrl,oldDoc);
    106                     },function(){
    107                         return req('PUT',docUrl,doc);
    108                     });
    109                 case "replace":
    110                 default:
    111                     log(docUrl+" replacing.");
    112                     return req('GET',docUrl)
    113                     .then(function(oldDoc){
    114                         doc['_rev'] = oldDoc['_rev'];
    115                         return req('PUT',docUrl,doc);
    116                     },function(){
    117                         return req('PUT',docUrl,doc);
    118                     });
    119             }
    120         }
    121 
    122         for (var docUrl in docs) {
    123             processDoc(docUrl,docs[docUrl]);
    124         }
    125 
    126         log("Done!");
    12723    }
    12824
    129     function log(text,overwrite) {
    130         if ( overwrite ) logNode.innerHTML = text
    131         else logNode.innerHTML = logNode.innerHTML + '\n' + text;
     25    function req(method,path,body) {
     26        var args = {
     27            contentType: 'application/json',
     28            handleAs: 'json',
     29            data: json.toJson(body || {})
     30        };
     31        return request[method](dbUrl+path,args);
    13232    }
    13333
     34    function asyncSeq(functions) {
     35        var d = new Deferred();
     36        (function stepper(fs,arg) {
     37            if ( fs.length > 0 ) {
     38                try {
     39                    var f = fs.shift();
     40                    var ret = f(arg);
     41                    if ( ret && ret.then ) {
     42                        ret.then(function(ret){
     43                            stepper(fs,ret);
     44                        });
     45                    } else {
     46                        stepper(fs,ret);
     47                    }
     48                } catch(err) {
     49                    d.reject(err);
     50                }
     51            } else {
     52                d.resolve();
     53            }
     54        })(functions);
     55        return d.promise;
     56    }
     57
     58    function asyncFor(list,callback,ctx) {
     59        var d = new Deferred();
     60        (function stepper(list,idx){
     61            if ( list.length > 0 ) {
     62                var el = list.shift();
     63                var ret = callback.call(ctx,el,idx);
     64                if ( ret && ret.then ) {
     65                    ret.then(function(){
     66                        stepper(list,idx+1);
     67                    });
     68                } else {
     69                    stepper(list,idx+1);
     70                }
     71            } else {
     72                d.resolve();
     73            }
     74        })(list,0);
     75        return d.promise;
     76    }
     77
     78    asyncSeq([
     79        function(){
     80            console.log("Configuring CouchDB for RFT:");
     81        },
     82        function(){
     83            console.log("Checking CouchDB version");
     84            return req('get','')
     85            .then(function(res){
     86                if (res.version !== "1.2.0" ) {
     87                    console.log("Found "+res.version+", only tested with CouchDB 1.2.0")
     88                } else {
     89                    console.log("CouchDB 1.2.0 found");
     90                }
     91            });
     92        },function(){
     93            console.log("Checking database 'rft'");
     94            return req('get','rft')
     95            .then(function(){
     96                console.log("Database 'rft' found.");
     97            },function(){
     98                console.log("Creating database 'rft'");
     99                return req('put','/rft');
     100            });
     101        },function(){
     102            return serializeFunctions(docs);
     103        },function(docs){
     104            console.log("Putting documents in database.");
     105            return asyncFor(func.keys(docs),function(docUrl){
     106                var doc = docs[docUrl];
     107                var configAction = doc.__configAction;
     108                delete doc.__configAction;
     109                switch (configAction) {
     110                    case "ignore":
     111                        console.log(docUrl+" ignored.");
     112                    case "update":
     113                        console.log(docUrl+" updating.");
     114                        return req('get',docUrl)
     115                        .then(function(oldDoc){
     116                            lang.mixin(oldDoc,doc);
     117                            return req('put',docUrl,oldDoc);
     118                        },function(){
     119                            return req('put',docUrl,doc);
     120                        });
     121                    case "replace":
     122                    default:
     123                        console.log(docUrl+" replacing.");
     124                        return req('get',docUrl)
     125                        .then(function(oldDoc){
     126                            doc['_rev'] = oldDoc['_rev'];
     127                            return req('put',docUrl,doc);
     128                        },function(){
     129                            return req('put',docUrl,doc);
     130                        });
     131                }
     132            });
     133        },function(){
     134            console.log("Done!");
     135        }
     136    ]);
     137
     138
    134139});
  • Dev/branches/rest-dojo-ui/client/config/docs.js

    r409 r410  
    1 {
    2     "_users/rft_admin": {
    3         "__configAction": "ignore",
    4         "_id": "org.couchdb.user:rft_admin",
    5         "name": "rft_admin",
    6         "password": "Welkom01",
    7         "roles": [ "rft_admin" ],
    8         "type": "user"
    9     },
    10     "rft/_security": {
    11         "__configAction": "ignore",
    12         "admins" : {
    13             "names" : [],
    14             "roles" : ["rft_admin"]
     1define([],function(){
     2    return {
     3        "_users/rft_admin": {
     4            __configAction: "ignore",
     5            _id: "org.couchdb.user:rft_admin",
     6            name: "rft_admin",
     7            password: "Welkom01",
     8            roles: [ "rft_admin" ],
     9            type: "user"
    1510        },
    16         "readers" : {
    17             "names" : [],
    18             "roles" : ["rft_user"]
    19         }
    20     },
    21     "rft/_design/default": {
    22         "__configAction": "replace",
    23         "_id": "_design/default",
    24         "language": "javascript",
    25         "validate_doc_update": "function(newDoc, oldDoc, userCtx, secObj) { if(oldDoc&&oldDoc.published){throw({forbidden:'Published documents cannot be modified.'});} if (!newDoc.type){throw({forbidden:'Documents must have a type field.'});} }",
    26         "views": {
    27             "by_type": {
    28                 "map": "function(doc){ emit(doc.type, doc); }"
     11        "rft/_security": {
     12            __configAction: "ignore",
     13            admins: {
     14                names: [],
     15                roles: ["rft_admin"]
    2916            },
    30             "unpublished": {
    31                 "map": "function(doc){ if ( doc.type === 'Survey' && !doc.published ) { emit(doc._id, doc); } }"
     17            readers: {
     18                names: [],
     19                roles: ["rft_user"]
     20            }
     21        },
     22        "rft/_design/default": {
     23            __configAction: "replace",
     24            _id: "_design/default",
     25            language: "javascript",
     26            validate_doc_update: function(newDoc, oldDoc, userCtx, secObj) {
     27                if ( oldDoc && oldDoc.publicationDate ) { throw({forbidden:'Published documents cannot be modified.'}); }
     28                if ( !newDoc._deleted && !newDoc.type ) { throw({forbidden:'Documents must have a type field.'}); }
    3229            },
    33             "questions": {
    34                 "map": "function(doc){ if ( doc.type === 'Question' ) { if ( doc.categories && doc.categories.length > 0 ) { for (var i = 0; i < doc.categories.length; i++) { emit([doc.categories[i],doc.topic || null],1); } } else { emit([null,null],1); } } }",
    35                 "reduce": "function(keys,values) { return sum(values); }"
     30            views: {
     31                by_type: {
     32                    map: function(doc){
     33                        emit(doc.type, doc);
     34                    }
     35                }
     36            }
     37        },
     38        "rft/_design/questions": {
     39            __configAction: "replace",
     40            _id: "_design/questions",
     41            language: "javascript",
     42            validate_doc_update: function(newDoc, oldDoc, userCtx, secObj) {
     43                if( newDoc._deleted || newDoc.type!=='Question' ){ return; }
     44                if( !newDoc.code ){ throw({forbidden:'Question must have a code field.'});}
    3645            },
    37             "topics": {
    38                 "map": "function(doc){ if ( doc.type === 'Question' ) { emit(doc.topic, 1); } }",
    39                 "reduce":   "function(keys, values) { return null; }"
     46            views: {
     47                all: {
     48                    map: function(doc){
     49                        if ( doc.type !== 'Question' ) { return; }
     50                        if ( doc.categories && doc.categories.length > 0 ) {
     51                            for ( var i = 0; i < doc.categories.length; i++ ) {
     52                                emit([doc.categories[i],doc.topic||null],1);
     53                            }
     54                        } else {
     55                            emit([null,null],1);
     56                        }
     57                    },
     58                    reduce: function(keys,values){ return sum(values); }
     59                },
     60                published: {
     61                    map: function(doc){
     62                        if ( doc.type!=='Question' || !doc.publicationDate ) { return; }
     63                        if ( doc.categories && doc.categories.length > 0 ) {
     64                            for ( var i = 0; i < doc.categories.length; i++ ) {
     65                                emit([doc.categories[i],doc.topic||null],1);
     66                            }
     67                        } else {
     68                            emit([null,null],1);
     69                        }
     70                    },
     71                    reduce: function(keys,values){ return sum(values); }
     72                },
     73                all_topics: {
     74                    map: function(doc){
     75                        if( doc.type !== 'Question' ){ return; }
     76                        emit(doc.topic);
     77                    }
     78                },
     79                published_topics: {
     80                    map: function(doc){
     81                        if ( doc.type !== 'Question' || !doc.publicationDate ) { return; }
     82                        emit(doc.topic);
     83                    }
     84                }
     85            }
     86        },
     87        "rft/_design/surveys": {
     88            __configAction: "replace",
     89            _id: "_design/surveys",
     90            language: "javascript",
     91            views: {
     92                drafts: {
     93                    map: function(doc){
     94                        if ( doc.type !== 'Survey' || doc.publicationDate ) { return; }
     95                        emit(doc._id,doc);
     96                    }
     97                },
     98                published: {
     99                    map: function(doc){
     100                        if ( doc.type !== 'Survey' || !doc.publicationDate ) { return; }
     101                        emit(doc._id,doc);
     102                    }
     103                }
    40104            }
    41105        }
    42     }
    43 }
     106    };
     107});
Note: See TracChangeset for help on using the changeset viewer.