CSOL-site/controllers/program.js

388 строки
10 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-06-03 00:00:15 +04:00
function getFilters(query, subset) {
var all = badger.getFilters(),
filters = [];
2013-03-28 17:14:16 +04:00
2013-06-03 00:00:15 +04:00
query = query || {};
if (!subset || !subset.length)
subset = _.keys(all);
if (subset && !_.isArray(subset))
subset = [subset];
_.each(subset, function (item) {
var filter = all[item] || {name:item, label: item, options: []};
filter.selected = query[filter.name];
filters.push(filter);
2013-03-28 17:14:16 +04:00
});
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', {
2013-06-03 00:00:15 +04:00
filters: getFilters(req.query, ['categories', 'orgs', 'ageRanges', 'activityTypes']),
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', {
2013-06-03 00:00:15 +04:00
filters: getFilters(req.query, ['categories', 'ageRanges', 'badgeTypes', 'activityTypes']),
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', badger.middleware('getBadgeRecommendations', {limit:4}), function (req, res, next) {
var data = req.remote;
2013-05-08 18:14:31 +04:00
res.render('badges/single.html', {
badge: req.params.badge,
relatedBadges: data.badges
2013-05-08 18:14:31 +04:00
});
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-06-05 07:38:07 +04:00
var mimeTypes = evidence.getMimeTypes();
2013-05-22 18:37:54 +04:00
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
function render (state, context) {
context = _.defaults(context || {}, {
application: applications.build({
badgeId: badge.id,
state: 'open'
}),
2013-06-05 07:38:07 +04:00
mimeTypes: mimeTypes,
evidence: [],
badge: badge
});
res.render('applications/' + state + '.html', context);
}
applications.find({where: {
2013-05-22 18:37:54 +04:00
badgeId: badge.id,
LearnerId: req.session.user.id
}})
2013-05-22 18:37:54 +04:00
.complete(function(err, application) {
if (err)
return next(err);
if (!application)
return render('new');
2013-05-22 18:37:54 +04:00
application.getEvidence()
.complete(function(err, evidence) {
if (err)
return next(err);
var state = evidence.length ? application.state : 'new';
render(state, {
2013-05-22 18:37:54 +04:00
evidence: evidence,
application: application
});
2013-05-22 18:37:54 +04:00
});
});
});
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.findOrCreate({
2013-05-22 18:37:54 +04:00
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
});
};