CSOL-site/controllers/program.js

444 строки
11 KiB
JavaScript
Исходник Обычный вид История

2013-05-28 23:46:24 +04:00
var async = require('async');
2013-05-31 18:25:04 +04:00
var aestimia = require('../aestimia');
2013-05-13 22:53:01 +04:00
var badger = require('../openbadger');
2013-05-22 18:37:54 +04:00
var db = require('../db');
2013-05-28 23:46:24 +04:00
var errors = require('../lib/errors');
var mime = require('mime');
var _ = require('underscore');
2013-05-22 18:37:54 +04:00
var applications = db.model('Application');
2013-05-28 23:46:24 +04:00
var evidence = db.model('Evidence');
2013-05-08 18:14:31 +04:00
2013-03-25 00:52:09 +04:00
module.exports = function (app) {
2013-03-28 17:14:16 +04:00
function getFilters() {
var filters = [],
requested;
2013-03-25 00:52:09 +04:00
2013-03-28 17:14:16 +04:00
if (arguments.length) {
requested = Array.prototype.splice.call(arguments, 0);
} else {
2013-03-28 20:42:32 +04:00
requested = ['categories', 'grouped_programs', 'ages'];
2013-03-28 17:14:16 +04:00
}
requested.forEach(function(filter) {
switch (filter) {
2013-03-28 20:42:32 +04:00
case 'categories':
case 'category':
2013-03-28 17:14:16 +04:00
filters.push({
2013-03-28 20:42:32 +04:00
name: 'category',
label: 'Category',
2013-03-28 17:14:16 +04:00
options: {
science: 'Science',
technology: 'Technology',
engineering: 'Engineering',
art: 'Art',
math: 'Math'
}
});
break;
case 'orgs':
case 'org':
filters.push({
name: 'org',
label: 'Organization',
2013-03-28 20:42:32 +04:00
options: {
'org1': 'Org 1',
'org2': 'Org 2',
'org3': 'Org 3',
}
});
break;
case 'programs':
case 'program':
filters.push({
name: 'program',
label: 'Program',
options: {
'p1': 'Program 1',
'p2': 'Program 2',
'p3': 'Program 3',
'p4': 'Program 4',
'p5': 'Program 5',
'p6': 'Program 6'
}
});
break;
case 'grouped_programs':
case 'grouped_program':
filters.push({
name: 'program',
label: 'Program',
options: {
'Org 1': {
'p1': 'Program 1',
'p2': 'Program 2'
},
'Org 2': {
'p3': 'Program 3',
'p4': 'Program 4'
},
'Org 3': {
'p5': 'Program 5',
'p6': 'Program 6'
}
},
is_grouped: true
2013-03-28 17:14:16 +04:00
});
break;
case 'ages':
case 'age':
filters.push({
name: 'age',
label: 'Age Group',
options: {
'lt-13': 'Under 13',
'13-14': '13 to 14',
'15-16': '15 to 16',
'17-18': '17 to 18',
'gt-18': 'Over 18'
}
});
break;
}
});
return filters;
}
app.param('programName', function (req, res, next, programName) {
badger.getProgram(programName, function(err, data) {
if (err)
2013-05-16 17:19:30 +04:00
return next(err);
2013-03-28 20:42:32 +04:00
req.params.program = data.program;
next();
});
});
2013-03-28 20:42:32 +04:00
2013-06-02 02:44:36 +04:00
app.get('/explore', badger.middleware('getPrograms'), function (req, res, next) {
var data = req.remote;
2013-03-28 20:42:32 +04:00
res.render('programs/list.html', {
filters: getFilters('categories', 'orgs', 'ages'),
items: data.programs,
page: data.page,
pages: data.pages
2013-03-28 20:42:32 +04:00
});
2013-03-25 00:52:09 +04:00
});
2013-06-02 02:44:36 +04:00
app.get('/explore/:programName', function (req, res, next) {
res.render('programs/single.html', {
program: req.params.program
});
2013-03-28 20:42:32 +04:00
});
2013-06-02 02:44:36 +04:00
app.get('/explore/:programName/favorite', function (req, res, next) {
2013-03-28 20:42:32 +04:00
return res.redirect('/login', 303);
});
2013-06-02 02:44:36 +04:00
app.get('/explore/:programName/unfavorite', function (req, res, next) {
2013-03-28 20:42:32 +04:00
return res.redirect('/login', 303);
});
2013-05-31 18:25:04 +04:00
app.post('/applications', function (req, res, next) {
function finish (err) {
if (err)
return res.json({status: err.message || err});
return res.json({status: 'ok'});
}
if (!req.body['_id'])
return finish('Could not find submission ID in request');
applications.find({where: {submissionId: req.body['_id']}})
.complete(function(err, application) {
if (err)
return finish(err);
aestimia.update(application);
finish();
});
});
2013-05-28 23:46:24 +04:00
app.param('evidenceSlug', function (req, res, next, slug) {
var parts = /^([a-z0-9]+?)(?:_(thumb))?$/.exec(slug);
var shouldAuthenticate = (req.method !== 'GET');
2013-05-28 23:46:24 +04:00
if (!parts)
return next(new errors.NotFound());
if (shouldAuthenticate && !req.session.user)
2013-05-28 23:46:24 +04:00
return next(new errors.Forbidden());
var key = parts[1],
thumb = !!parts[2];
evidence.find({where: {key: key}})
.complete(function (err, instance) {
if (err)
return next(err);
if (!instance)
return next(new errors.NotFound());
req.params.evidence = instance;
req.params.thumb = thumb;
instance.getApplication()
.complete(function (err, application) {
if (err)
return next(err);
req.params.application = application;
// We'll need to decide how to authenticate external services
// like, for example, Aestimia. For now, restrict access to either
// the learner who uploaded it, or their guardian
if (!shouldAuthenticate)
return next();
2013-05-28 23:46:24 +04:00
application.getLearner()
.complete(function (err, learner) {
if (err)
return next(err);
if (learner.id === req.session.user.id)
return next();
learner.getGuardian()
.complete(function (err, guardian) {
if (err)
return next(err);
if (!guardian || guardian.id !== req.session.user.id)
return next(new errors.Forbidden());
return next();
});
});
});
});
});
app.get('/evidence/:evidenceSlug', function (req, res, next) {
var evidence = req.params.evidence,
thumb = req.params.thumb;
res.type(evidence.mediaType);
res.header('Vary', 'Cookie');
res.header('Cache-Control', 'max-age=2419200'); // 4 weeks
res.header('Last-Modified', evidence.updatedAt);
evidence[thumb ? 'fetchThumb' : 'fetch'](function (remote) {
remote
.on('response', function(proxy) {
proxy.pipe(res);
})
.end();
});
});
app.post('/evidence/:evidenceSlug', function (req, res, next) {
var evidence = req.params.evidence,
application = req.params.application,
thumb = req.params.thumb;
if (thumb)
return next(new errors.NotAllowed());
if (!req.body.action || req.body.action !== 'delete')
return next(new errors.NotAllowed());
2013-05-29 15:24:36 +04:00
if (application.state !== 'open')
2013-05-28 23:46:24 +04:00
return next(new errors.NotAllowed());
evidence.destroy()
.complete(function (err) {
if (err)
return next(err);
evidence.getApplication()
.complete(function (err, application) {
if (err)
return next(err);
return res.redirect('/earn/' + application.badgeId + '/apply');
});
})
});
2013-03-28 17:14:16 +04:00
app.param('badgeName', function (req, res, next, badgeName) {
badger.getBadge(badgeName, function(err, data) {
2013-05-08 18:14:31 +04:00
if (err)
2013-05-16 17:19:30 +04:00
return next(err);
2013-05-08 18:14:31 +04:00
req.params.badge = data.badge;
next();
});
2013-03-28 17:14:16 +04:00
});
app.get('/earn', badger.middleware('getBadges'), function (req, res, next) {
2013-05-09 21:27:55 +04:00
var data = req.remote;
2013-05-08 18:14:31 +04:00
res.render('badges/list.html', {
filters: getFilters(),
2013-05-09 21:28:41 +04:00
items: data.badges,
page: data.page,
pages: data.pages
2013-05-08 18:14:31 +04:00
});
2013-03-28 17:14:16 +04:00
});
app.get('/earn/:badgeName', function (req, res, next) {
2013-05-08 18:14:31 +04:00
res.render('badges/single.html', {
badge: req.params.badge
});
2013-03-28 17:14:16 +04:00
});
2013-05-22 18:37:54 +04:00
app.get('/earn/:badgeName/apply', function (req, res, next) {
var badge = req.params.badge;
2013-05-30 16:41:08 +04:00
if (!req.session.user) {
req.session.afterLogin = '/earn/' + req.params.badgeName + '/apply';
2013-05-28 23:46:24 +04:00
return res.redirect('/login');
2013-05-30 16:41:08 +04:00
}
2013-05-22 18:37:54 +04:00
applications.findOrCreate({
badgeId: badge.id,
LearnerId: req.session.user.id
2013-05-22 18:37:54 +04:00
})
.complete(function(err, application) {
if (err || !application)
return next(err || new Error('There was a problem loading your application'));
application.getEvidence()
.complete(function(err, evidence) {
if (err)
return next(err);
var state = evidence.length ? application.state : 'new';
res.render('applications/' + state + '.html', {
evidence: evidence,
application: application,
badge: badge
})
});
});
});
app.post('/earn/:badgeName/apply', function (req, res, next) {
var badge = req.params.badge;
2013-05-28 23:46:24 +04:00
if (!req.session.user)
return res.redirect(badge.url);
function finish (err, evidence) {
if (req.xhr) {
return res.json({
status: err ? 'failed' : 'ok',
message: err || null,
evidence: evidence || []
});
}
if (err)
req.flash('error', err);
res.redirect(badge.url + '/apply');
}
2013-05-22 18:37:54 +04:00
applications.find({where: {
badgeId: badge.id,
2013-05-28 23:46:24 +04:00
LearnerId: req.session.user.id
2013-05-22 18:37:54 +04:00
}})
.complete(function(err, application) {
2013-05-28 23:46:24 +04:00
if (err || !application)
return finish(err);
if (req.body.action === 'apply')
return application.submit(finish);
2013-05-31 20:15:40 +04:00
if (req.body.action === 'reopen')
return application.reopen(finish);
2013-05-28 23:46:24 +04:00
if ('description' in req.body) {
application.updateAttributes({
description: req.body.description
});
2013-05-22 18:37:54 +04:00
}
2013-05-28 23:46:24 +04:00
var files = (req.files||{}).media;
if (!files)
return finish();
2013-05-22 18:37:54 +04:00
2013-05-28 23:46:24 +04:00
if (!_.isArray(files))
files = [files];
async.map(files, function (file, callback) {
application.process(file, function (err, item) {
if (err || !item)
return callback(err);
callback(null, {
type: item.mediaType,
thumbnail: item.getThumbnailUrl(),
location: item.getLocationUrl(),
original: item.original
});
});
}, finish);
2013-05-22 18:37:54 +04:00
});
});
app.get('/earn/:badgeName/claim', function (req, res, next) {
2013-03-28 17:14:16 +04:00
res.render('badges/claim.html');
});
app.get('/earn/:badgeName/favorite', function (req, res, next) {
2013-03-28 17:14:16 +04:00
return res.redirect('/login', 303);
});
app.get('/earn/:badgeName/unfavorite', function (req, res, next) {
2013-03-28 17:14:16 +04:00
return res.redirect('/favorites', 303);
2013-03-25 00:52:09 +04:00
});
app.get('/orgs', function (req, res, next) {
2013-03-28 17:14:16 +04:00
var orgs = [];
for (var i = 0; i < 12; ++i) {
orgs.push({
thumbnail: '/media/images/org.png',
description: 'Organization blah irure...',
url: '/orgs/some-organization'
2013-03-28 17:14:16 +04:00
});
}
res.render('orgs/list.html', {
2013-03-28 20:42:32 +04:00
filters: getFilters('categories', 'ages'),
2013-03-28 17:14:16 +04:00
items: orgs
});
2013-03-25 00:52:09 +04:00
});
app.param('orgName', function (req, res, next, orgName) {
// pull some stuff from the database probably
next();
});
2013-03-28 17:14:16 +04:00
app.get('/orgs/:orgName', function (req, res, next) {
res.render('orgs/single.html');
});
app.get('/orgs/:orgName/favorite', function (req, res, next) {
return res.redirect('/login', 303);
});
app.get('/orgs/:orgName/unfavorite', function (req, res, next) {
return res.redirect('/login', 303);
2013-03-25 00:52:09 +04:00
});
};