зеркало из https://github.com/mozilla/CSOL-site.git
211 строки
6.8 KiB
JavaScript
211 строки
6.8 KiB
JavaScript
const Api = require('./api');
|
|
const async = require('async');
|
|
const errors = require('./lib/errors');
|
|
const openbadger = require('./openbadger');
|
|
const _ = require('underscore');
|
|
|
|
const ENDPOINT = process.env['CSOL_AESTIMIA_URL'];
|
|
const SECRET = process.env['CSOL_AESTIMIA_SECRET'];
|
|
const CSOL_HOST = process.env['CSOL_HOST'];
|
|
|
|
if (!ENDPOINT)
|
|
throw new Error('Must specify CSOL_AESTIMIA_URL in the environment');
|
|
|
|
if (!SECRET)
|
|
throw new Error('Must specify CSOL_AESTIMIA_SECRET in the environment');
|
|
|
|
if (!CSOL_HOST)
|
|
throw new Error('Must specify CSOL_HOST in the environment');
|
|
|
|
var aestimia = new Api(ENDPOINT, {
|
|
|
|
submit: function (application, callback) {
|
|
var api = this;
|
|
var description = application.description.trim().replace(/[^a-z0-9\s]/ig, '');
|
|
var wordcount = !!description ? description.split(/\s+/).length : 0;
|
|
var minWordCount = 10;
|
|
|
|
application.getLearner()
|
|
.complete(function (err, learner) {
|
|
if (err)
|
|
return callback(err);
|
|
|
|
application.getEvidence()
|
|
.complete(function (err, evidence) {
|
|
if (err)
|
|
return callback(err);
|
|
|
|
evidence = evidence || [];
|
|
|
|
if (!evidence.length && wordcount < minWordCount)
|
|
return callback('Insufficient evidence for this application');
|
|
|
|
openbadger.getBadge(application.badgeId, function (err, data) {
|
|
var badge = data.badge;
|
|
|
|
// console.log('Application:', application);
|
|
// console.log('Learner:', learner);
|
|
// console.log('Evidence:', evidence);
|
|
// console.log('Badge:', badge);
|
|
|
|
var submission = {
|
|
criteriaUrl: api.getFullUrl(CSOL_HOST, badge.url),
|
|
onChangeUrl: api.getFullUrl(CSOL_HOST, '/applications'),
|
|
achievement: {
|
|
name: badge.name,
|
|
description: badge.description,
|
|
imageUrl: badge.image
|
|
},
|
|
classifications: badge.categories || [],
|
|
evidence: [],
|
|
rubric: badge.rubric || {items: [{text: 'Has done some work', required: true}]}
|
|
};
|
|
|
|
if (learner.email)
|
|
submission.learner = learner.email;
|
|
|
|
if (learner.underage)
|
|
submission.cannedResponses = [
|
|
'You did a great job!',
|
|
'You went above and beyond.',
|
|
'Keep up the good work!',
|
|
'Good job.',
|
|
'You met all the criteria needed to earn this badge.',
|
|
'Creative and thoughtful work.',
|
|
'Nice reflection of your work.',
|
|
'You didn\'t submit relevant evidence.',
|
|
'Your evidence did not properly reflect the criteria.',
|
|
'Good work! But you still have a few criteria to meet to earn this badge. Make sure you take a look at all the criteria before reapplying.'
|
|
];
|
|
|
|
if (application.description) {
|
|
submission.evidence.push({
|
|
url: api.getFullUrl(CSOL_HOST, '/evidence/' + application.id + '/' + application.getHash()),
|
|
mediaType: 'link',
|
|
reflection: application.description
|
|
})
|
|
}
|
|
|
|
evidence.forEach(function(item, index) {
|
|
var type = item.mediaType.split('/')[0];
|
|
if (type !== 'image') type = 'link';
|
|
|
|
var obj = {
|
|
url: api.getFullUrl(CSOL_HOST, item.getLocationUrl()),
|
|
mediaType: type
|
|
};
|
|
|
|
submission.evidence.push(obj);
|
|
});
|
|
|
|
api.post('/submission', {json:submission}, function (err, rsp) {
|
|
if (err)
|
|
return callback(err);
|
|
|
|
callback(null, (rsp||{}).id);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
},
|
|
|
|
update: function (application, callback) {
|
|
var api = this;
|
|
|
|
var submissionId = application.submissionId;
|
|
var latestReview = application.getReview();
|
|
|
|
if (!submissionId)
|
|
return callback('Application has not yet been submitted');
|
|
|
|
this.get('/submissions/' + submissionId, function (err, submission) {
|
|
var rubrics = submission.rubric.items;
|
|
var reviews = submission.reviews;
|
|
|
|
// Bail early, if there are no reviews
|
|
if (!reviews.length)
|
|
return callback(null, application);
|
|
|
|
// Sort the reviews by (ascending) date, if required
|
|
if (reviews.length > 1) {
|
|
reviews.sort(function(a, b) {
|
|
if (a.date === b.date)
|
|
return 0;
|
|
return a.date < b.date;
|
|
});
|
|
}
|
|
|
|
// Take the most recent review
|
|
var review = reviews.pop();
|
|
|
|
// If we've already seen it, bail
|
|
if (review._id === latestReview._id)
|
|
return callback(null, application);
|
|
|
|
var satisfiedRubrics = review.satisfiedRubrics;
|
|
var satisfied = false;
|
|
|
|
// If something is satisfied, see if it's enough to award the badge
|
|
if (satisfiedRubrics.length) {
|
|
satisfied = true;
|
|
|
|
rubrics.forEach(function (rubric, index) {
|
|
var rubricSatisfied = !rubric.required || (satisfiedRubrics.indexOf(index) >= 0);
|
|
satisfied &= rubricSatisfied;
|
|
});
|
|
}
|
|
|
|
var state = satisfied ? 'accepted' : 'rejected';
|
|
|
|
if (state !== application.state)
|
|
if (state === 'accepted')
|
|
application.getLearner()
|
|
.complete(function (err, learner) {
|
|
if (err || !learner) return;
|
|
|
|
openbadger.awardBadge({
|
|
learner: learner,
|
|
badge: application.badgeId
|
|
}, function (err, assertionUrl) {
|
|
if (err)
|
|
return console.log(err); // Should probably log this
|
|
|
|
// TO DO - email applicant about change of application state
|
|
|
|
// console.log('Badge awarded:', assertionUrl);
|
|
});
|
|
});
|
|
|
|
application.updateAttributes({
|
|
state: state,
|
|
latestReview: JSON.stringify(review)
|
|
})
|
|
.complete(function(err) {
|
|
if (err)
|
|
return callback(err, application);
|
|
|
|
callback(null, application);
|
|
});
|
|
});
|
|
}
|
|
|
|
});
|
|
|
|
aestimia.defaultOptions = {
|
|
auth: {
|
|
username: 'api',
|
|
password: SECRET,
|
|
sendImmediately: false
|
|
}
|
|
};
|
|
|
|
module.exports = aestimia;
|
|
module.exports.healthCheck = function(meta, cb) {
|
|
// A random email should guarantee we bust through any caches.
|
|
var email = 'healthCheck_test_' +
|
|
Math.floor(Math.random() * 100000) + '@mozilla.org';
|
|
|
|
meta.notes = ENDPOINT;
|
|
aestimia.get('/submissions?learner=' + encodeURIComponent(email), cb);
|
|
};
|