refactor challenges

now only queries challenges on start up
use default scheduler for array manipulation
This commit is contained in:
Berkeley Martinez
2015-08-19 23:11:21 -07:00
parent 6d1d8a3e28
commit eaca9ef495

View File

@ -1,6 +1,6 @@
import _ from 'lodash';
import moment from 'moment';
import { Observable } from 'rx';
import { Observable, Scheduler } from 'rx';
import assign from 'object.assign';
import debugFactory from 'debug';
import utils from '../utils';
@ -18,11 +18,16 @@ import {
} from '../utils/middleware';
const debug = debugFactory('freecc:challenges');
const challengeMapWithNames = utils.getChallengeMapWithNames();
const challengeMapWithIds = utils.getChallengeMapWithIds();
const challengeMapWithDashedNames = utils.getChallengeMapWithDashedNames();
const challengesRegex = /^(bonfire|waypoint|zipline|basejump)/i;
const firstChallenge = 'waypoint-say-hello-to-html-elements';
const challengeView = {
0: 'coursewares/showHTML',
1: 'coursewares/showJS',
2: 'coursewares/showVideo',
3: 'coursewares/showZiplineOrBasejump',
4: 'coursewares/showZiplineOrBasejump',
5: 'coursewares/showBonfire'
};
const dasherize = utils.dasherize;
const unDasherize = utils.unDasherize;
@ -64,7 +69,12 @@ module.exports = function(app) {
// create a stream of all the challenges
const challenge$ = findChallenge$(challengesQuery)
.doOnNext(() => debug('query challenges'))
.flatMap(challenges => Observable.from(challenges))
.flatMap(challenges => Observable.from(
challenges,
null,
null,
Scheduler.default
))
.shareReplay();
// create a stream of challenge blocks
@ -162,7 +172,12 @@ module.exports = function(app) {
.elementAt(blockIndex)
.flatMap(block => {
// find where our challenge lies in the block
const challengeIndex$ = Observable.from(block.challenges)
const challengeIndex$ = Observable.from(
block.challenges,
null,
null,
Scheduler.default
)
.findIndex(({ id }) => id === challengeId);
// grab next challenge in this block
@ -201,44 +216,53 @@ module.exports = function(app) {
res.redirect('/challenges/' + nextChallengeName);
}
);
}
function returnCurrentChallenge(req, res, next) {
if (!req.user.currentChallenge) {
req.user.currentChallenge = {};
req.user.currentChallenge.challengeId = challengeMapWithIds['0'][0];
req.user.currentChallenge.challengeName = challengeMapWithNames['0'][0];
req.user.currentChallenge.dashedName =
challengeMapWithDashedNames['0'][0];
}
var nameString = req.user.currentChallenge.dashedName;
saveUser(req.user)
Observable.just(req.user)
.flatMap(user => {
if (!req.user.currentChallenge) {
return challenge$
.first()
.flatMap(challenge => {
user.currentChallenge = {
challengeId: challenge.id,
challengeName: challenge.name,
dashedName: challenge.dashedName
};
return saveUser(user);
});
}
return Observable.just(user);
})
.map(user => user.currentChallenge.dashedName)
.subscribe(
function() {},
function(challengeName) {
res.redirect('/challenges/' + challengeName);
},
next,
function() {
res.redirect('/challenges/' + nameString);
}
);
}
function returnIndividualChallenge(req, res, next) {
var origChallengeName = req.params.challengeName;
var unDashedName = unDasherize(origChallengeName);
const origChallengeName = req.params.challengeName;
const unDashedName = unDasherize(origChallengeName);
var challengeName = challengesRegex.test(unDashedName) ?
const challengeName = challengesRegex.test(unDashedName) ?
// remove first word if matches
unDashedName.split(' ').slice(1).join(' ') :
unDashedName;
debug('looking for ', challengeName);
Challenge.findOne(
{ where: { name: { like: challengeName, options: 'i' } } },
function(err, challenge) {
if (err) { return next(err); }
const testChallengeName = new RegExp(challengeName, 'i');
debug('looking for %s', testChallengeName);
challenge$
.filter((challenge) => {
return testChallengeName.test(challenge.name);
})
.lastOrDefault(null)
.flatMap(challenge => {
// Handle not found
if (!challenge) {
@ -249,65 +273,60 @@ module.exports = function(app) {
origChallengeName +
'` Please double check the name.'
});
return res.redirect('/challenges');
return Observable.just('/challenges');
}
// Redirect to full name if the user only entered a partial
if (dasherize(challenge.name) !== origChallengeName) {
debug('redirecting to fullname');
return res.redirect('/challenges/' + dasherize(challenge.name));
return Observable.just('/challenges/' + dasherize(challenge.name));
}
if (req.user) {
req.user.currentChallenge = {
challengeId: challenge.id,
challengeName: challenge.name,
dashedName: challenge.dashedName
};
if (challenge) {
if (req.user) {
req.user.currentChallenge = {
challengeId: challenge.id,
challengeName: challenge.name,
dashedName: challenge.dashedName
};
}
// save user does nothing if user does not exist
return saveUser(req.user)
.map(() => ({
title: challenge.name,
dashedName: origChallengeName,
name: challenge.name,
details: challenge.description,
tests: challenge.tests,
challengeSeed: challenge.challengeSeed,
verb: utils.randomVerb(),
phrase: utils.randomPhrase(),
compliment: utils.randomCompliment(),
challengeId: challenge.id,
challengeType: challenge.challengeType,
// video challenges
video: challenge.challengeSeed[0],
// bonfires specific
difficulty: Math.floor(+challenge.difficulty),
bonfires: challenge,
MDNkeys: challenge.MDNlinks,
MDNlinks: getMDNLinks(challenge.MDNlinks),
// htmls specific
environment: utils.whichEnvironment()
}));
}
var commonLocals = {
title: challenge.name,
dashedName: origChallengeName,
name: challenge.name,
details: challenge.description,
tests: challenge.tests,
challengeSeed: challenge.challengeSeed,
verb: utils.randomVerb(),
phrase: utils.randomPhrase(),
compliment: utils.randomCompliment(),
challengeId: challenge.id,
challengeType: challenge.challengeType,
// video challenges
video: challenge.challengeSeed[0],
// bonfires specific
difficulty: Math.floor(+challenge.difficulty),
bonfires: challenge,
MDNkeys: challenge.MDNlinks,
MDNlinks: getMDNLinks(challenge.MDNlinks),
// htmls specific
environment: utils.whichEnvironment()
};
// TODO Berkeley
var challengeView = {
0: 'coursewares/showHTML',
1: 'coursewares/showJS',
2: 'coursewares/showVideo',
3: 'coursewares/showZiplineOrBasejump',
4: 'coursewares/showZiplineOrBasejump',
5: 'coursewares/showBonfire'
};
saveUser(req.user)
.subscribe(
function() {},
next,
function() {
var view = challengeView[challenge.challengeType];
res.render(view, commonLocals);
}
);
});
})
.subscribe(
function(data) {
if (typeof data === 'string') {
debug('redirecting to %s', data);
return res.redirect(data);
}
var view = challengeView[data.challengeType];
res.render(view, data);
},
next,
function() {}
);
}
function completedBonfire(req, res, next) {
@ -359,7 +378,7 @@ module.exports = function(app) {
challengeData
);
})
// not iterate users
// iterate users
.flatMap(function(dats) {
debug('flatmap');
return Observable.from([dats.user, dats.pairedWith]);