Ignore:
Timestamp:
03/10/14 17:10:16 (11 years ago)
Author:
hendrikvanantwerpen
Message:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Dev/trunk/src/server/app.js

    r499 r501  
    136136    }
    137137   
     138    function identity(obj) { return obj; }
    138139    function stripAndReturnPrivates(obj) {
    139140        var priv = {};
     
    146147        return priv;
    147148    }
    148 
    149     function identity(obj) { return obj; }
     149    function areDocsUnique(docs) {
     150        return _.chain(docs)
     151                .map(function(doc){ return doc._id; })
     152                .uniq()
     153                .value().length === docs.length;
     154    }
     155    function areDocsPublished(docs) {
     156        return _.every(docs,isDocPublished);
     157    }
     158    function isDocPublished(doc) {
     159        return doc.publicationDate;
     160    }
     161
    150162    function handleUnknownResponse(status,error) {
    151163        return new HTTPResult(500,{error: error.reason});
     
    342354
    343355    // Questions
    344     function getQuestionsWithCode(code) {
    345         var url = '_design/questions/_view/by_code';
     356    function getQuestionsWithCode(code,sub) {
     357        var url = '_design/questions/_view/'+(sub||'all')+'_by_code';
    346358        var query = {include_docs:true,key:code};
     359        return HTTPResult.fromResponsePromise(couch.get(url,{query:query}).response,
     360                                              handleUnknownError)
     361        .handle({
     362            200: handleRowDocs,
     363            default: handleUnknownResponse
     364        });
     365    }
     366    function getQuestions(sub) {
     367        var url = '_design/questions/_view/'+(sub||'all');
     368        var query = {include_docs:true};
    347369        return HTTPResult.fromResponsePromise(couch.get(url,{query:query}).response,
    348370                                              handleUnknownError)
     
    362384        });
    363385    }
    364     function getQuestionsWithTopic(topic) {
    365         var url = '_design/questions/_view/all_topics';
     386    function getQuestionsWithTopic(topic,sub) {
     387        var url = '_design/questions/_view/'+(sub||'all')+'_topics';
    366388        var query = {reduce:false,include_docs:true,key:topic};
    367389        return HTTPResult.fromResponsePromise(couch.get(url,{query:query}).response,
     
    372394        });
    373395    }
    374     function getQuestionsWithCategoryAndTopic(category,topic) {
     396    function getQuestionsWithCategoryAndTopic(category,topic,sub) {
    375397        var hasTopic = typeof topic !== 'undefined';
    376         var url = '_design/questions/_view/all';
     398        var url = '_design/questions/_view/'+(sub||'all');
    377399        var query = {reduce:false,include_docs:true,
    378400                     startkey:hasTopic?[category,topic]:[category],
     
    389411        ensureMIME(JSON_MIME),
    390412        function(req,res) {
     413            var sub = 'published' in req.query && 'published';
    391414            var hr;
    392415            if ( 'category' in req.query ) {
    393                 hr = getQuestionsWithCategoryAndTopic(req.query.category,req.query.topic);
     416                hr = getQuestionsWithCategoryAndTopic(req.query.category,
     417                                                      req.query.topic,sub);
    394418            } else if ( 'topic' in req.query ) {
    395                 hr = getQuestionsWithTopic(req.query.topic);
     419                hr = getQuestionsWithTopic(req.query.topic,sub);
    396420            } else if ( 'code' in req.query ) {
    397                 hr = getQuestionsWithCode(req.query.code);
     421                hr = getQuestionsWithCode(req.query.code,sub);
     422            } else {
     423                hr = getQuestions(sub);
    398424            }
    399425            hr.handle(res.send.bind(res));
     
    444470        makeDocDel_id('Question'));
    445471
    446 
    447472    // Categories and topics
    448     function getTopicsWithCategory(category) {
    449         var url = '_design/questions/_view/all';
     473    function getTopics(sub) {
     474        var url = '_design/questions/_view/'+(sub||'all')+'_topics';
     475        return HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true}}).response,
     476                                            handleUnknownError)
     477        .handle({
     478            200: function(result) {
     479                return _.map(result.rows, function(item) { return {name:item.key, count:item.value}; });
     480            },
     481            default: handleUnknownResponse
     482        });
     483    }
     484    function getCategories(sub) {
     485        var url = '_design/questions/_view/'+(sub||'all');
     486        return HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true,group_level:1}}).response,
     487                                       handleUnknownError)
     488        .handle({
     489            200: function(result) {
     490                return _.map(result.rows, function(item) {
     491                    return { name:item.key[0], count:item.value };
     492                });
     493            },
     494            default: handleUnknownResponse
     495        });
     496    }
     497    function getTopicsWithCategory(category,sub) {
     498        var url = '_design/questions/_view/'+(sub||'all');
    450499        return HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true,group_level:2,startkey:[category],endkey:[category,{}]}}).response,
    451500                                       handleUnknownError)
     
    461510        ensureMIME(JSON_MIME),
    462511        function(req,res) {
    463             var url = '_design/questions/_view/all';
    464             HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true,group_level:1}}).response,
    465                                            handleUnknownError)
    466             .handle({
    467                 200: function(result) {
    468                     return _.map(result.rows, function(item) {
    469                         return { name:item.key[0], count:item.value };
    470                     });
    471                 },
    472                 default: handleUnknownResponse
    473             })
     512            var sub = 'published' in req.query && 'published';
     513            getCategories(sub)
    474514            .handle(res.send.bind(res));
    475515        });
     
    479519        function(req,res) {
    480520            var category = req.params.category;
    481             getTopicsWithCategory(category)
     521            var sub = 'published' in req.query && 'published';
     522            getTopicsWithCategory(category,sub)
    482523            .handle(res.send.bind(res));
    483524        });
     
    486527        ensureMIME(JSON_MIME),
    487528        function(req,res) {
    488             var url = '_design/questions/_view/all_topics';
     529            var sub = 'published' in req.query && 'published';
    489530            var hr;
    490531            if ( 'category' in req.query ) {
    491                 hr = getTopicsWithCategory(req.query.category);
    492             } else {
    493                 hr = HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true}}).response,
    494                                                     handleUnknownError)
    495                 .handle({
    496                     200: function(result) {
    497                         return _.map(result.rows, function(item) { return {name:item.key, count:item.value}; });
    498                     },
    499                     default: handleUnknownResponse
    500                 });
     532                hr = getTopicsWithCategory(req.query.category,sub);
     533            } else {
     534                hr = getTopics(sub);
    501535            }
    502536            hr.handle(res.send.bind(res));
     
    504538
    505539    // Surveys
    506     function areSurveyQuestionsUnique(survey) {
    507         return _.chain(survey.questions)
    508                 .map(function(q){ return q.code; })
    509                 .uniq()
    510                 .value().length === survey.questions.length;
    511     }
    512540    app.get('/api/surveys',
    513541        ensureAuthenticated,
     
    538566            var doc = req.body;
    539567            var hr;
    540             if ( !areSurveyQuestionsUnique(doc) ) {
     568            if ( !areDocsUnique(doc.questions) ) {
    541569                hr = new HTTPResult(400,{error:"Survey contains duplicate questions."});
     570            } else if ( !areDocsPublished(doc.questions) || isDocPublished(doc) ) {
     571                hr = new HTTPResult(400,{error:"Cannot publish Survey with unpublished questions."});
    542572            } else {
    543573                hr = postDocument('Survey',doc);
     
    557587            var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev);
    558588            var hr;
    559             if ( !areSurveyQuestionsUnique(doc) ) {
     589            if ( !areDocsUnique(doc.questions) ) {
    560590                new HTTPResult(400,{error:"Survey contains duplicate questions."})
    561591                .handle(res.send.bind(res));
     592            } else if ( !areDocsPublished(doc.questions) || isDocPublished(doc) ) {
     593                hr = new HTTPResult(400,{error:"Cannot publish Survey with unpublished questions."});
    562594            } else {
    563595                putDocument(id,rev,'Survey',doc)
     
    587619        function(req,res) {
    588620            var doc = req.body;
    589             randomToken()
    590             .handle({
    591                 201: function(token) {
    592                     doc.secret = token;
    593                     return postDocument('SurveyRun',doc);
    594                 }
    595             })
    596             .handle(res.send.bind(res));
     621            var hr;
     622            if ( !isDocPublished(doc.survey) ) {
     623                hr = new HTTPResult(400,{error:"Cannot run unpublished survey."});
     624            } else {
     625                hr = randomToken()
     626                .handle({
     627                    201: function(token) {
     628                        doc.secret = token;
     629                        return postDocument('SurveyRun',doc);
     630                    }
     631                });
     632            }
     633            hr.handle(res.send.bind(res));
    597634        });
    598635    app.get('/api/surveyRuns/:id',
     
    608645            var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev);
    609646            var hr;
    610             if ( typeof doc.secret === 'undefined' ) {
     647            if ( !isDocPublished(doc.survey) ) {
     648                hr = new HTTPResult(400,{error:"Cannot run unpublished survey."});
     649            } else if ( typeof doc.secret === 'undefined' ) {
    611650                hr = randomToken()
    612651                .handle({
Note: See TracChangeset for help on using the changeset viewer.