refactor all boot to export func and use loopback

This commit is contained in:
Berkeley Martinez
2015-06-03 16:19:23 -07:00
parent 65cde59f0d
commit 8165105b29
9 changed files with 2028 additions and 1951 deletions

View File

@ -79,6 +79,7 @@
"passport-twitter": "~1.0.2", "passport-twitter": "~1.0.2",
"ramda": "~0.10.0", "ramda": "~0.10.0",
"request": "~2.53.0", "request": "~2.53.0",
"rx": "^2.5.3",
"sanitize-html": "~1.6.1", "sanitize-html": "~1.6.1",
"sitemap": "~0.7.4", "sitemap": "~0.7.4",
"twit": "~1.1.20", "twit": "~1.1.20",

View File

@ -1,122 +1,126 @@
var R = require('ramda'), var R = require('ramda'),
express = require('express'), // Rx = require('rx'),
// debug = require('debug')('freecc:fieldguides'), // debug = require('debug')('freecc:fieldguides'),
resources = require('../resources/resources'); resources = require('../resources/resources');
var router = express.Router(); module.exports = function(app) {
var router = app.Router();
var FieldGuide = app.models.FieldGuide;
router.get('/field-guide/all-articles', showAllFieldGuides); router.get('/field-guide/all-articles', showAllFieldGuides);
router.get('/field-guide/:fieldGuideName', returnIndividualFieldGuide); router.get('/field-guide/:fieldGuideName', returnIndividualFieldGuide);
router.get('/field-guide/', returnNextFieldGuide); router.get('/field-guide/', returnNextFieldGuide);
router.post('/completed-field-guide/', completedFieldGuide); router.post('/completed-field-guide/', completedFieldGuide);
function returnIndividualFieldGuide(req, res, next) { function returnIndividualFieldGuide(req, res, next) {
var dashedName = req.params.fieldGuideName; var dashedName = req.params.fieldGuideName;
if (req.user) { if (req.user) {
var completed = req.user.completedFieldGuides; var completed = req.user.completedFieldGuides;
var uncompletedFieldGuides = resources.allFieldGuideIds() var uncompletedFieldGuides = resources.allFieldGuideIds()
.filter(function (elem) { .filter(function (elem) {
if (completed.indexOf(elem) === -1) { if (completed.indexOf(elem) === -1) {
return elem; return elem;
} }
});
req.user.uncompletedFieldGuides = uncompletedFieldGuides;
// TODO(berks): handle callback properly
req.user.save(function(err) {
if (err) { return next(err); }
}); });
req.user.uncompletedFieldGuides = uncompletedFieldGuides; }
// TODO(berks): handle callback properly
req.user.save(); // NOTE(berks): loopback might have issue with regex here.
FieldGuide.find(
{ dashedName: new RegExp(dashedName, 'i') },
function(err, fieldGuideFromMongo) {
if (err) {
return next(err);
}
if (fieldGuideFromMongo.length < 1) {
req.flash('errors', {
msg: "404: We couldn't find a field guide entry with that name. " +
'Please double check the name.'
});
return res.redirect('/field-guide');
}
var fieldGuide = R.head(fieldGuideFromMongo);
fieldGuide.name.toLowerCase().replace(/\s/g, '-').replace(/\?/g, '');
if (fieldGuide.dashedName !== dashedName) {
return res.redirect('../field-guide/' + fieldGuide.dashedName);
}
res.render('field-guide/show', {
title: fieldGuide.name,
fieldGuideId: fieldGuide._id,
description: fieldGuide.description.join('')
});
}
);
} }
FieldGuide.find( function showAllFieldGuides(req, res) {
{ dashedName: new RegExp(dashedName, 'i') }, var allFieldGuideNamesAndIds = resources.allFieldGuideNamesAndIds();
function(err, fieldGuideFromMongo) {
var completedFieldGuides = [];
if (req.user && req.user.completedFieldGuides) {
completedFieldGuides = req.user.completedFieldGuides;
}
res.render('field-guide/all-articles', {
allFieldGuideNamesAndIds: allFieldGuideNamesAndIds,
completedFieldGuides: completedFieldGuides
});
}
function returnNextFieldGuide(req, res, next) {
if (!req.user) {
return res.redirect('/field-guide/how-do-i-use-this-guide');
}
var displayedFieldGuides =
FieldGuide.find({'_id': req.user.uncompletedFieldGuides[0]});
displayedFieldGuides.exec(function(err, fieldGuide) {
if (err) { return next(err); }
fieldGuide = fieldGuide.pop();
if (typeof fieldGuide === 'undefined') {
if (req.user.completedFieldGuides.length > 0) {
req.flash('success', {
msg: [
"You've read all our current Field Guide entries. You can ",
'contribute to our Field Guide ',
"<a href='https://github.com/FreeCodeCamp/freecodecamp/blob/",
"staging/seed/field-guides.json'>here</a>."
].join('')
});
}
return res.redirect('../field-guide/how-do-i-use-this-guide');
}
var nameString = fieldGuide.name.toLowerCase().replace(/\s/g, '-');
return res.redirect('../field-guide/' + nameString);
});
}
function completedFieldGuide(req, res, next) {
var fieldGuideId = req.body.fieldGuideInfo.fieldGuideId;
req.user.completedFieldGuides.push(fieldGuideId);
var index = req.user.uncompletedFieldGuides.indexOf(fieldGuideId);
if (index > -1) {
req.user.progressTimestamps.push(Date.now());
req.user.uncompletedFieldGuides.splice(index, 1);
}
req.user.save(function (err) {
if (err) { if (err) {
return next(err); return next(err);
} }
res.send(true);
if (fieldGuideFromMongo.length < 1) { });
req.flash('errors', {
msg: "404: We couldn't find a field guide entry with that name. " +
'Please double check the name.'
});
return res.redirect('/field-guide');
}
var fieldGuide = R.head(fieldGuideFromMongo);
fieldGuide.name.toLowerCase().replace(/\s/g, '-').replace(/\?/g, '');
if (fieldGuide.dashedName !== dashedName) {
return res.redirect('../field-guide/' + fieldGuide.dashedName);
}
res.render('field-guide/show', {
title: fieldGuide.name,
fieldGuideId: fieldGuide._id,
description: fieldGuide.description.join('')
});
}
);
}
function showAllFieldGuides(req, res) {
var allFieldGuideNamesAndIds = resources.allFieldGuideNamesAndIds();
var completedFieldGuides = [];
if (req.user && req.user.completedFieldGuides) {
completedFieldGuides = req.user.completedFieldGuides;
} }
res.render('field-guide/all-articles', { };
allFieldGuideNamesAndIds: allFieldGuideNamesAndIds,
completedFieldGuides: completedFieldGuides
});
}
function returnNextFieldGuide(req, res, next) {
if (!req.user) {
return res.redirect('/field-guide/how-do-i-use-this-guide');
}
var displayedFieldGuides =
FieldGuide.find({'_id': req.user.uncompletedFieldGuides[0]});
displayedFieldGuides.exec(function(err, fieldGuide) {
if (err) { return next(err); }
fieldGuide = fieldGuide.pop();
if (typeof fieldGuide === 'undefined') {
if (req.user.completedFieldGuides.length > 0) {
req.flash('success', {
msg: [
"You've read all our current Field Guide entries. You can ",
'contribute to our Field Guide ',
"<a href='https://github.com/FreeCodeCamp/freecodecamp/blob/",
"staging/seed/field-guides.json'>here</a>."
].join('')
});
}
return res.redirect('../field-guide/how-do-i-use-this-guide');
}
var nameString = fieldGuide.name.toLowerCase().replace(/\s/g, '-');
return res.redirect('../field-guide/' + nameString);
});
}
function completedFieldGuide(req, res, next) {
var fieldGuideId = req.body.fieldGuideInfo.fieldGuideId;
req.user.completedFieldGuides.push(fieldGuideId);
var index = req.user.uncompletedFieldGuides.indexOf(fieldGuideId);
if (index > -1) {
req.user.progressTimestamps.push(Date.now());
req.user.uncompletedFieldGuides.splice(index, 1);
}
req.user.save(function (err) {
if (err) {
return next(err);
}
res.send(true);
});
}
module.exports = router;

View File

@ -1,22 +1,21 @@
var express = require('express');
var router = express.Router();
var message = var message =
'Learn to Code JavaScript and get a Coding Job by Helping Nonprofits'; 'Learn to Code JavaScript and get a Coding Job by Helping Nonprofits';
router.get('/', index); module.exports = function(app) {
var router = app.Router();
router.get('/', index);
function index(req, res, next) { function index(req, res, next) {
if (req.user && !req.user.profile.picture) { if (req.user && !req.user.profile.picture) {
req.user.profile.picture = req.user.profile.picture =
'https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png'; 'https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png';
req.user.save(function(err) { req.user.save(function(err) {
if (err) { return next(err); } if (err) { return next(err); }
res.render('home', { title: message });
});
} else {
res.render('home', { title: message }); res.render('home', { title: message });
}); }
} else {
res.render('home', { title: message });
} }
} };
module.exports = router;

View File

@ -1,126 +1,128 @@
var express = require('express'),
Nonprofit = require('../../common/models/Nonprofit');
var router = express.Router(); module.exports = function(app) {
var router = app.Router();
var Nonprofit = app.models.Nonprofit;
router.get('/nonprofits/directory', nonprofitsDirectory); router.get('/nonprofits/directory', nonprofitsDirectory);
router.get('/nonprofits/:nonprofitName', returnIndividualNonprofit); router.get('/nonprofits/:nonprofitName', returnIndividualNonprofit);
function nonprofitsDirectory(req, res, next) { function nonprofitsDirectory(req, res, next) {
Nonprofit.find({ estimatedHours: { $gt: 0 } }, function(err, nonprofits) { Nonprofit.find(
if (err) { return next(err); } { where: { estimatedHours: { $gt: 0 } } },
function(err, nonprofits) {
res.render('nonprofits/directory', {
title: 'Nonprofits we help',
nonprofits: nonprofits
});
});
}
function returnIndividualNonprofit(req, res, next) {
var dashedName = req.params.nonprofitName;
var nonprofitName = dashedName.replace(/\-/g, ' ');
Nonprofit.find(
{ name: new RegExp(nonprofitName, 'i') },
function(err, nonprofit) {
if (err) {
return next(err);
}
if (nonprofit.length < 1) {
req.flash('errors', {
msg: "404: We couldn't find a nonprofit with that name. " +
'Please double check the name.'
});
return res.redirect('/nonprofits');
}
nonprofit = nonprofit.pop();
var dashedNameFull = nonprofit.name.toLowerCase().replace(/\s/g, '-');
if (dashedNameFull !== dashedName) {
return res.redirect('../nonprofit/' + dashedNameFull);
}
var buttonActive = false;
if (req.user) {
if (req.user.uncompletedBonfires.length === 0) {
if (req.user.completedCoursewares.length > 63) {
var hasShownInterest =
nonprofit.interestedCampers.filter(function ( obj ) {
return obj.username === req.user.profile.username;
});
if (hasShownInterest.length === 0) {
buttonActive = true;
}
}
}
}
res.render('nonprofits/show', {
dashedName: dashedNameFull,
title: nonprofit.name,
logoUrl: nonprofit.logoUrl,
estimatedHours: nonprofit.estimatedHours,
projectDescription: nonprofit.projectDescription,
approvedOther:
nonprofit.approvedDeliverables.indexOf('other') > -1,
approvedWebsite:
nonprofit.approvedDeliverables.indexOf('website') > -1,
approvedDonor:
nonprofit.approvedDeliverables.indexOf('donor') > -1,
approvedInventory:
nonprofit.approvedDeliverables.indexOf('inventory') > -1,
approvedVolunteer:
nonprofit.approvedDeliverables.indexOf('volunteer') > -1,
approvedForm:
nonprofit.approvedDeliverables.indexOf('form') > -1,
approvedCommunity:
nonprofit.approvedDeliverables.indexOf('community') > -1,
approvedELearning:
nonprofit.approvedDeliverables.indexOf('eLearning') > -1,
websiteLink: nonprofit.websiteLink,
imageUrl: nonprofit.imageUrl,
whatDoesNonprofitDo: nonprofit.whatDoesNonprofitDo,
interestedCampers: nonprofit.interestedCampers,
assignedCampers: nonprofit.assignedCampers,
buttonActive: buttonActive,
currentStatus: nonprofit.currentStatus
});
}
);
}
/*
function interestedInNonprofit(req, res, next) {
if (req.user) {
Nonprofit.findOne(
{ name: new RegExp(req.params.nonprofitName.replace(/-/, ' '), 'i') },
function(err, nonprofit) {
if (err) { return next(err); } if (err) { return next(err); }
nonprofit.interestedCampers.push({
username: req.user.profile.username, res.render('nonprofits/directory', {
picture: req.user.profile.picture, title: 'Nonprofits we help',
timeOfInterest: Date.now() nonprofits: nonprofits
});
nonprofit.save(function(err) {
if (err) { return next(err); }
req.flash('success', {
msg: 'Thanks for expressing interest in this nonprofit project! ' +
"We've added you to this project as an interested camper!"
});
res.redirect('back');
}); });
} }
); );
} }
}
*/
module.exports = router; function returnIndividualNonprofit(req, res, next) {
var dashedName = req.params.nonprofitName;
var nonprofitName = dashedName.replace(/\-/g, ' ');
Nonprofit.find(
{ where: { name: new RegExp(nonprofitName, 'i') } },
function(err, nonprofit) {
if (err) {
return next(err);
}
if (nonprofit.length < 1) {
req.flash('errors', {
msg: "404: We couldn't find a nonprofit with that name. " +
'Please double check the name.'
});
return res.redirect('/nonprofits');
}
nonprofit = nonprofit.pop();
var dashedNameFull = nonprofit.name.toLowerCase().replace(/\s/g, '-');
if (dashedNameFull !== dashedName) {
return res.redirect('../nonprofit/' + dashedNameFull);
}
var buttonActive = false;
if (req.user) {
if (req.user.uncompletedBonfires.length === 0) {
if (req.user.completedCoursewares.length > 63) {
var hasShownInterest =
nonprofit.interestedCampers.filter(function ( obj ) {
return obj.username === req.user.profile.username;
});
if (hasShownInterest.length === 0) {
buttonActive = true;
}
}
}
}
res.render('nonprofits/show', {
dashedName: dashedNameFull,
title: nonprofit.name,
logoUrl: nonprofit.logoUrl,
estimatedHours: nonprofit.estimatedHours,
projectDescription: nonprofit.projectDescription,
approvedOther:
nonprofit.approvedDeliverables.indexOf('other') > -1,
approvedWebsite:
nonprofit.approvedDeliverables.indexOf('website') > -1,
approvedDonor:
nonprofit.approvedDeliverables.indexOf('donor') > -1,
approvedInventory:
nonprofit.approvedDeliverables.indexOf('inventory') > -1,
approvedVolunteer:
nonprofit.approvedDeliverables.indexOf('volunteer') > -1,
approvedForm:
nonprofit.approvedDeliverables.indexOf('form') > -1,
approvedCommunity:
nonprofit.approvedDeliverables.indexOf('community') > -1,
approvedELearning:
nonprofit.approvedDeliverables.indexOf('eLearning') > -1,
websiteLink: nonprofit.websiteLink,
imageUrl: nonprofit.imageUrl,
whatDoesNonprofitDo: nonprofit.whatDoesNonprofitDo,
interestedCampers: nonprofit.interestedCampers,
assignedCampers: nonprofit.assignedCampers,
buttonActive: buttonActive,
currentStatus: nonprofit.currentStatus
});
}
);
}
/*
function interestedInNonprofit(req, res, next) {
if (req.user) {
Nonprofit.findOne(
{ name: new RegExp(req.params.nonprofitName.replace(/-/, ' '), 'i') },
function(err, nonprofit) {
if (err) { return next(err); }
nonprofit.interestedCampers.push({
username: req.user.profile.username,
picture: req.user.profile.picture,
timeOfInterest: Date.now()
});
nonprofit.save(function(err) {
if (err) { return next(err); }
req.flash('success', {
msg: 'Thanks for expressing interest in this nonprofit project! ' +
"We've added you to this project as an interested camper!"
});
res.redirect('back');
});
}
);
}
}
*/
};

View File

@ -1,68 +1,67 @@
var express = require('express'), var passport = require('passport'),
passport = require('passport'),
passportConf = require('../../config/passport'); passportConf = require('../../config/passport');
var router = express.Router(); module.exports = function(app) {
var passportOptions = { var router = app.Router();
successRedirect: '/', var passportOptions = {
failureRedirect: '/login'
};
router.all('/account', passportConf.isAuthenticated);
router.get('/auth/twitter', passport.authenticate('twitter'));
router.get(
'/auth/twitter/callback',
passport.authenticate('twitter', {
successRedirect: '/', successRedirect: '/',
failureRedirect: '/login' failureRedirect: '/login'
}) };
);
router.get( router.all('/account', passportConf.isAuthenticated);
'/auth/linkedin',
passport.authenticate('linkedin', {
state: 'SOME STATE'
})
);
router.get( router.get('/auth/twitter', passport.authenticate('twitter'));
'/auth/linkedin/callback',
passport.authenticate('linkedin', passportOptions)
);
router.get( router.get(
'/auth/facebook', '/auth/twitter/callback',
passport.authenticate('facebook', {scope: ['email', 'user_location']}) passport.authenticate('twitter', {
); successRedirect: '/',
failureRedirect: '/login'
})
);
router.get( router.get(
'/auth/facebook/callback', '/auth/linkedin',
passport.authenticate('facebook', passportOptions), function (req, res) { passport.authenticate('linkedin', {
res.redirect(req.session.returnTo || '/'); state: 'SOME STATE'
} })
); );
router.get('/auth/github', passport.authenticate('github')); router.get(
'/auth/linkedin/callback',
passport.authenticate('linkedin', passportOptions)
);
router.get( router.get(
'/auth/github/callback', '/auth/facebook',
passport.authenticate('github', passportOptions), function (req, res) { passport.authenticate('facebook', {scope: ['email', 'user_location']})
res.redirect(req.session.returnTo || '/'); );
}
);
router.get( router.get(
'/auth/google', '/auth/facebook/callback',
passport.authenticate('google', {scope: 'profile email'}) passport.authenticate('facebook', passportOptions), function (req, res) {
); res.redirect(req.session.returnTo || '/');
}
);
router.get( router.get('/auth/github', passport.authenticate('github'));
'/auth/google/callback',
passport.authenticate('google', passportOptions), function (req, res) {
res.redirect(req.session.returnTo || '/');
}
);
module.exports = router; router.get(
'/auth/github/callback',
passport.authenticate('github', passportOptions), function (req, res) {
res.redirect(req.session.returnTo || '/');
}
);
router.get(
'/auth/google',
passport.authenticate('google', {scope: 'profile email'})
);
router.get(
'/auth/google/callback',
passport.authenticate('google', passportOptions), function (req, res) {
res.redirect(req.session.returnTo || '/');
}
);
};

View File

@ -1,47 +1,48 @@
var express = require('express'); module.exports = function(app) {
var router = express.Router(); var router = app.Router();
router.get('/nonprofit-project-instructions', function(req, res) { router.get('/nonprofit-project-instructions', function(req, res) {
res.redirect( res.redirect(
301, 301,
'/field-guide/how-do-free-code-camp\'s-nonprofit-projects-work' '/field-guide/how-do-free-code-camp\'s-nonprofit-projects-work'
); );
}); });
router.get('/agile', function(req, res) { router.get('/agile', function(req, res) {
res.redirect(301, '/pmi-acp-agile-project-managers'); res.redirect(301, '/pmi-acp-agile-project-managers');
}); });
router.get('/live-pair-programming', function(req, res) { router.get('/live-pair-programming', function(req, res) {
res.redirect(301, '/field-guide/live-stream-pair-programming-on-twitch.tv'); res.redirect(301, '/field-guide/live-stream-pair-programming-on-twitch.tv');
}); });
router.get('/install-screenhero', function(req, res) { router.get('/install-screenhero', function(req, res) {
res.redirect(301, '/field-guide/install-screenhero'); res.redirect(301, '/field-guide/install-screenhero');
}); });
router.get('/guide-to-our-nonprofit-projects', function(req, res) { router.get('/guide-to-our-nonprofit-projects', function(req, res) {
res.redirect(301, '/field-guide/a-guide-to-our-nonprofit-projects'); res.redirect(301, '/field-guide/a-guide-to-our-nonprofit-projects');
}); });
router.get('/chromebook', function(req, res) { router.get('/chromebook', function(req, res) {
res.redirect(301, '/field-guide/chromebook'); res.redirect(301, '/field-guide/chromebook');
}); });
router.get('/deploy-a-website', function(req, res) { router.get('/deploy-a-website', function(req, res) {
res.redirect(301, '/field-guide/deploy-a-website'); res.redirect(301, '/field-guide/deploy-a-website');
}); });
router.get('/gmail-shortcuts', function(req, res) { router.get('/gmail-shortcuts', function(req, res) {
res.redirect(301, '/field-guide/gmail-shortcuts'); res.redirect(301, '/field-guide/gmail-shortcuts');
}); });
router.get('/nodeschool-challenges', function(req, res) { router.get('/nodeschool-challenges', function(req, res) {
res.redirect(301, '/field-guide/nodeschool-challenges'); res.redirect(301, '/field-guide/nodeschool-challenges');
}); });
router.get('/privacy', function(req, res) { router.get('/privacy', function(req, res) {
res.redirect(301, '/field-guide/what-is-the-free-code-camp-privacy-policy?'); res.redirect(
}); 301, '/field-guide/what-is-the-free-code-camp-privacy-policy?'
);
module.exports = router; });
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,254 +1,302 @@
var express = require('express'), var Rx = require('rx'),
Twit = require('twit'),
async = require('async'), async = require('async'),
moment = require('moment'), moment = require('moment'),
Twit = require('twit'),
Slack = require('node-slack'), Slack = require('node-slack'),
request = require('request'), request = require('request'),
debug = require('debug')('freecc:cntr:resources'), debug = require('debug')('freecc:cntr:resources'),
constantStrings = require('../resources/constantStrings.json'),
User = require('../../common/models/User'), constantStrings = require('../resources/constantStrings.json'),
Challenge = require('../../common/models/Challenge'),
Story = require('../../common/models/Story'),
FieldGuide = require('../../common/models/FieldGuide'),
Nonprofit = require('../../common/models/Nonprofit'),
secrets = require('../../config/secrets'); secrets = require('../../config/secrets');
var slack = new Slack(secrets.slackHook); var slack = new Slack(secrets.slackHook);
var router = express.Router(); module.exports = function(app) {
var router = app.Router();
var User = app.models.User;
var Challenge = app.models.Challenge;
var Story = app.models.Store;
var FieldGuide = app.models.FieldGuide;
var Nonprofit = app.models.Nonprofit;
router.get('/api/github', githubCalls); router.get('/api/github', githubCalls);
router.get('/api/blogger', bloggerCalls); router.get('/api/blogger', bloggerCalls);
router.get('/api/trello', trelloCalls); router.get('/api/trello', trelloCalls);
router.get('/api/codepen/twitter/:screenName', twitter); router.get('/api/codepen/twitter/:screenName', twitter);
router.get('/sitemap.xml', sitemap); router.get('/sitemap.xml', sitemap);
router.post('/get-help', getHelp); router.post('/get-help', getHelp);
router.post('/get-pair', getPair); router.post('/get-pair', getPair);
router.get('/chat', chat); router.get('/chat', chat);
router.get('/twitch', twitch); router.get('/twitch', twitch);
router.get('/pmi-acp-agile-project-managers', agileProjectManagers); router.get('/pmi-acp-agile-project-managers', agileProjectManagers);
router.get('/pmi-acp-agile-project-managers-form', agileProjectManagersForm); router.get('/pmi-acp-agile-project-managers-form', agileProjectManagersForm);
router.get('/nonprofits', nonprofits); router.get('/nonprofits', nonprofits);
router.get('/nonprofits-form', nonprofitsForm); router.get('/nonprofits-form', nonprofitsForm);
router.get('/jobs-form', jobsForm); router.get('/jobs-form', jobsForm);
router.get('/submit-cat-photo', catPhotoSubmit); router.get('/submit-cat-photo', catPhotoSubmit);
router.get('/unsubscribe/:email', unsubscribe); router.get('/unsubscribe/:email', unsubscribe);
router.get('/unsubscribed', unsubscribed); router.get('/unsubscribed', unsubscribed);
router.get('/cats.json', getCats); router.get('/cats.json', getCats);
router.get('/api/slack', slackInvite); router.get('/api/slack', slackInvite);
function slackInvite(req, res, next) { function slackInvite(req, res, next) {
if (req.user) { if (req.user) {
if (req.user.email) { if (req.user.email) {
var invite = { var invite = {
'email': req.user.email, 'email': req.user.email,
'token': process.env.SLACK_KEY, 'token': process.env.SLACK_KEY,
'set_active': true 'set_active': true
}; };
var headers = { var headers = {
'User-Agent': 'Node Browser/0.0.1', 'User-Agent': 'Node Browser/0.0.1',
'Content-Type': 'application/x-www-form-urlencoded' 'Content-Type': 'application/x-www-form-urlencoded'
}; };
var options = { var options = {
url: 'https://freecodecamp.slack.com/api/users.admin.invite', url: 'https://freecodecamp.slack.com/api/users.admin.invite',
method: 'POST', method: 'POST',
headers: headers, headers: headers,
form: invite form: invite
}; };
request(options, function (error, response) { request(options, function (error, response) {
if (!error && response.statusCode === 200) { if (!error && response.statusCode === 200) {
req.flash('success', { req.flash('success', {
msg: 'We\'ve successfully requested an invite for you.' + msg: 'We\'ve successfully requested an invite for you.' +
' Please check your email and follow the instructions from Slack.' ' Please check your email and follow the ' +
}); 'instructions from Slack.'
req.user.sentSlackInvite = true; });
req.user.save(function(err) { req.user.sentSlackInvite = true;
if (err) { req.user.save(function(err) {
return next(err); if (err) {
} return next(err);
}
return res.redirect('back');
});
} else {
req.flash('errors', {
msg: 'The invitation email did not go through for some reason.' +
' Please try again or <a href=\'mailto:team@' +
'freecodecamp.com?subject=' +
'slack%20invite%20failed%20to%20send\'>' +
'email us</a>.'
});
return res.redirect('back'); return res.redirect('back');
}); }
} else { });
req.flash('errors', { } else {
msg: 'The invitation email did not go through for some reason.' + req.flash('notice', {
' Please try again or <a href=\'mailto:team@' + msg: 'Before we can send your Slack invite, we need your email ' +
'freecodecamp.com?subject=' + 'address. Please update your profile information here.'
'slack%20invite%20failed%20to%20send\'>' + });
'email us</a>.' return res.redirect('/account');
}); }
return res.redirect('back');
}
});
} else { } else {
req.flash('notice', { req.flash('notice', {
msg: 'Before we can send your Slack invite, we need your email ' + msg: 'You need to sign in to Free Code Camp before ' +
'address. Please update your profile information here.' 'we can send you a Slack invite.'
}); });
return res.redirect('/account'); return res.redirect('/account');
} }
} else { }
req.flash('notice', {
msg: 'You need to sign in to Free Code Camp before ' + function twitter(req, res, next) {
'we can send you a Slack invite.' // sends out random tweets about javascript
var T = new Twit({
'consumer_key': secrets.twitter.consumerKey,
'consumer_secret': secrets.twitter.consumerSecret,
'access_token': secrets.twitter.token,
'access_token_secret': secrets.twitter.tokenSecret
}); });
return res.redirect('/account');
}
}
function twitter(req, res, next) { var screenName;
// sends out random tweets about javascript if (req.params.screenName) {
var T = new Twit({ screenName = req.params.screenName;
'consumer_key': secrets.twitter.consumerKey, } else {
'consumer_secret': secrets.twitter.consumerSecret, screenName = 'freecodecamp';
'access_token': secrets.twitter.token,
'access_token_secret': secrets.twitter.tokenSecret
});
var screenName;
if (req.params.screenName) {
screenName = req.params.screenName;
} else {
screenName = 'freecodecamp';
}
T.get(
'statuses/user_timeline',
{
'screen_name': screenName,
count: 10
},
function(err, data) {
if (err) { return next(err); }
return res.json(data);
} }
);
}
T.get(
function getHelp(req, res) { 'statuses/user_timeline',
var userName = req.user.profile.username; {
var code = req.body.payload.code ? '\n```\n' + 'screen_name': screenName,
req.body.payload.code + '\n```\n' count: 10
: '';
var challenge = req.body.payload.challenge;
slack.send({
text: '*@' + userName + '* wants help with ' + challenge + '. ' +
code + 'Hey, *@' + userName + '*, if no one helps you right ' +
'away, try typing out your problem in detail to me. Like this: ' +
'http://en.wikipedia.org/wiki/Rubber_duck_debugging',
channel: '#help',
username: 'Debuggy the Rubber Duck',
'icon_url': 'https://pbs.twimg.com/profile_images/' +
'3609875545/569237541c920fa78d78902069615caf.jpeg'
});
return res.sendStatus(200);
}
function getPair(req, res) {
var userName = req.user.profile.username;
var challenge = req.body.payload.challenge;
slack.send({
text: [
'Anyone want to pair with *@',
userName,
'* on ',
challenge,
'?\nMake sure you install Screen Hero here: ',
'http://freecodecamp.com/field-guide/how-do-i-install-screenhero\n',
'Then start your pair program session with *@',
userName,
'* by typing \"/hero @',
userName,
'\" into Slack.\n And *@',
userName,
'*, be sure to launch Screen Hero, then keep coding. ',
'Another camper may pair with you soon.'
].join(''),
channel: '#letspair',
username: 'Companion Cube',
'icon_url': 'https://lh3.googleusercontent.com/-f6xDPDV2rPE/AAAAAAAAAAI/' +
'AAAAAAAAAAA/mdlESXQu11Q/photo.jpg'
});
return res.sendStatus(200);
}
function sitemap(req, res, next) {
var appUrl = 'http://www.freecodecamp.com';
var now = moment(new Date()).format('YYYY-MM-DD');
async.parallel({
users: function(callback) {
User.aggregate()
.group({_id: 1, usernames: { $addToSet: '$profile.username'}})
.match({'profile.username': { $ne: ''}})
.exec(function(err, users) {
if (err) {
debug('User err: ', err);
callback(err);
} else {
callback(null, users[0].usernames);
}
});
}, },
function(err, data) {
challenges: function (callback) { if (err) { return next(err); }
Challenge.aggregate() return res.json(data);
.group({_id: 1, names: { $addToSet: '$name'}})
.exec(function (err, challenges) {
if (err) {
debug('Challenge err: ', err);
callback(err);
} else {
callback(null, challenges[0].names);
}
});
},
stories: function (callback) {
Story.aggregate()
.group({_id: 1, links: {$addToSet: '$link'}})
.exec(function (err, stories) {
if (err) {
debug('Story err: ', err);
callback(err);
} else {
callback(null, stories[0].links);
}
});
},
nonprofits: function (callback) {
Nonprofit.aggregate()
.group({_id: 1, names: { $addToSet: '$name'}})
.exec(function (err, nonprofits) {
if (err) {
debug('User err: ', err);
callback(err);
} else {
callback(null, nonprofits[0].names);
}
});
},
fieldGuides: function (callback) {
FieldGuide.aggregate()
.group({_id: 1, names: { $addToSet: '$name'}})
.exec(function (err, fieldGuides) {
if (err) {
debug('User err: ', err);
callback(err);
} else {
callback(null, fieldGuides[0].names);
}
});
} }
}, function (err, results) { );
if (err) { }
return next(err);
} else {
function getHelp(req, res) {
var userName = req.user.profile.username;
var code = req.body.payload.code ? '\n```\n' +
req.body.payload.code + '\n```\n'
: '';
var challenge = req.body.payload.challenge;
slack.send({
text: '*@' + userName + '* wants help with ' + challenge + '. ' +
code + 'Hey, *@' + userName + '*, if no one helps you right ' +
'away, try typing out your problem in detail to me. Like this: ' +
'http://en.wikipedia.org/wiki/Rubber_duck_debugging',
channel: '#help',
username: 'Debuggy the Rubber Duck',
'icon_url': 'https://pbs.twimg.com/profile_images/' +
'3609875545/569237541c920fa78d78902069615caf.jpeg'
});
return res.sendStatus(200);
}
function getPair(req, res) {
var userName = req.user.profile.username;
var challenge = req.body.payload.challenge;
slack.send({
text: [
'Anyone want to pair with *@',
userName,
'* on ',
challenge,
'?\nMake sure you install Screen Hero here: ',
'http://freecodecamp.com/field-guide/how-do-i-install-screenhero\n',
'Then start your pair program session with *@',
userName,
'* by typing \"/hero @',
userName,
'\" into Slack.\n And *@',
userName,
'*, be sure to launch Screen Hero, then keep coding. ',
'Another camper may pair with you soon.'
].join(''),
channel: '#letspair',
username: 'Companion Cube',
'icon_url':
'https://lh3.googleusercontent.com/-f6xDPDV2rPE/AAAAAAAAAAI/' +
'AAAAAAAAAAA/mdlESXQu11Q/photo.jpg'
});
return res.sendStatus(200);
}
function sitemap(req, res, next) {
var appUrl = 'http://www.freecodecamp.com';
var now = moment(new Date()).format('YYYY-MM-DD');
// TODO(berks): refactor async to rx
async.parallel({
users: function(callback) {
User.find(
{
where: { 'profile.username': { nlike: '' } },
fields: { 'profile.username': true }
},
function(err, users) {
if (err) {
debug('User err: ', err);
callback(err);
} else {
Rx.Observable.from(users)
.map(function(user) {
return user.profile.username;
})
.toArray()
.subscribe(
function(usernames) {
callback(null, usernames);
},
callback
);
}
});
},
challenges: function (callback) {
Challenge.find(
{ fields: { name: true } },
function (err, challenges) {
if (err) {
debug('Challenge err: ', err);
callback(err);
} else {
Rx.Observable.from(challenges)
.map(function(challenge) {
return challenge.name;
})
.toArray()
.subscribe(
callback.bind(callback, null),
callback
);
}
});
},
stories: function (callback) {
Story.find(
{ field: { link: true } },
function (err, stories) {
if (err) {
debug('Story err: ', err);
callback(err);
} else {
Rx.Observable.from(stories)
.map(function(story) {
return story.link;
})
.toArray()
.subscribe(
callback.bind(callback, null),
callback
);
}
}
);
},
nonprofits: function (callback) {
Nonprofit.find(
{ field: { name: true } },
function(err, nonprofits) {
if (err) {
debug('User err: ', err);
callback(err);
} else {
Rx.Observable.from(nonprofits)
.map(function(nonprofit) {
return nonprofit.name;
})
.toArray()
.subscribe(
callback.bind(callback, null),
callback
);
}
});
},
fieldGuides: function(callback) {
FieldGuide.find(
{ field: { name: true } },
function(err, fieldGuides) {
if (err) {
debug('User err: ', err);
callback(err);
} else {
Rx.Observable.from(fieldGuides)
.map(function(fieldGuide) {
return fieldGuide.name;
})
.toArray()
.subscribe(
callback.bind(callback, null),
callback
);
}
});
}
}, function(err, results) {
if (err) {
return next(err);
}
setTimeout(function() { setTimeout(function() {
res.header('Content-Type', 'application/xml'); res.header('Content-Type', 'application/xml');
res.render('resources/sitemap', { res.render('resources/sitemap', {
@ -262,185 +310,183 @@ function sitemap(req, res, next) {
}); });
}, 0); }, 0);
} }
} );
); }
}
function chat(req, res) { function chat(req, res) {
if (req.user && req.user.progressTimestamps.length > 5) { if (req.user && req.user.progressTimestamps.length > 5) {
res.redirect('http://freecodecamp.slack.com'); res.redirect('http://freecodecamp.slack.com');
} else { } else {
res.render('resources/chat', { res.render('resources/chat', {
title: 'Watch us code live on Twitch.tv' title: 'Watch us code live on Twitch.tv'
});
}
}
function jobsForm(req, res) {
res.render('resources/jobs-form', {
title: 'Employer Partnership Form for Job Postings,' +
' Recruitment and Corporate Sponsorships'
}); });
} }
}
function jobsForm(req, res) { function catPhotoSubmit(req, res) {
res.render('resources/jobs-form', { res.send(
title: 'Employer Partnership Form for Job Postings,' + 'Success! You have submitted your cat photo. Return to your website ' +
' Recruitment and Corporate Sponsorships' 'by typing any letter into your code editor.'
}); );
} }
function catPhotoSubmit(req, res) { function nonprofits(req, res) {
res.send( res.render('resources/nonprofits', {
'Success! You have submitted your cat photo. Return to your website ' + title: 'A guide to our Nonprofit Projects'
'by typing any letter into your code editor.' });
); }
}
function nonprofits(req, res) { function nonprofitsForm(req, res) {
res.render('resources/nonprofits', { res.render('resources/nonprofits-form', {
title: 'A guide to our Nonprofit Projects' title: 'Nonprofit Projects Proposal Form'
}); });
} }
function nonprofitsForm(req, res) { function agileProjectManagers(req, res) {
res.render('resources/nonprofits-form', { res.render('resources/pmi-acp-agile-project-managers', {
title: 'Nonprofit Projects Proposal Form' title: 'Get Agile Project Management Experience for the PMI-ACP'
}); });
} }
function agileProjectManagers(req, res) { function agileProjectManagersForm(req, res) {
res.render('resources/pmi-acp-agile-project-managers', { res.render('resources/pmi-acp-agile-project-managers-form', {
title: 'Get Agile Project Management Experience for the PMI-ACP' title: 'Agile Project Management Program Application Form'
}); });
} }
function agileProjectManagersForm(req, res) { function twitch(req, res) {
res.render('resources/pmi-acp-agile-project-managers-form', { res.render('resources/twitch', {
title: 'Agile Project Management Program Application Form' title: 'Enter Free Code Camp\'s Chat Rooms'
}); });
} }
function twitch(req, res) { function unsubscribe(req, res, next) {
res.render('resources/twitch', { User.findOne({ email: req.params.email }, function(err, user) {
title: 'Enter Free Code Camp\'s Chat Rooms' if (user) {
});
}
function unsubscribe(req, res, next) {
User.findOne({ email: req.params.email }, function(err, user) {
if (user) {
if (err) {
return next(err);
}
user.sendMonthlyEmail = false;
user.save(function () {
if (err) { if (err) {
return next(err); return next(err);
} }
user.sendMonthlyEmail = false;
user.save(function () {
if (err) {
return next(err);
}
res.redirect('/unsubscribed');
});
} else {
res.redirect('/unsubscribed'); res.redirect('/unsubscribed');
});
} else {
res.redirect('/unsubscribed');
}
});
}
function unsubscribed(req, res) {
res.render('resources/unsubscribed', {
title: 'You have been unsubscribed'
});
}
function githubCalls(req, res, next) {
var githubHeaders = {
headers: {
'User-Agent': constantStrings.gitHubUserAgent
},
port: 80
};
request(
[
'https://api.github.com/repos/freecodecamp/',
'freecodecamp/pulls?client_id=',
secrets.github.clientID,
'&client_secret=',
secrets.github.clientSecret
].join(''),
githubHeaders,
function(err, status1, pulls) {
if (err) { return next(err); }
pulls = pulls ?
Object.keys(JSON.parse(pulls)).length :
'Can\'t connect to github';
request(
[
'https://api.github.com/repos/freecodecamp/',
'freecodecamp/issues?client_id=',
secrets.github.clientID,
'&client_secret=',
secrets.github.clientSecret
].join(''),
githubHeaders,
function (err, status2, issues) {
if (err) { return next(err); }
issues = ((pulls === parseInt(pulls, 10)) && issues) ?
Object.keys(JSON.parse(issues)).length - pulls :
"Can't connect to GitHub";
res.send({
issues: issues,
pulls: pulls
});
}
);
}
);
}
function trelloCalls(req, res, next) {
request(
'https://trello.com/1/boards/BA3xVpz9/cards?key=' +
secrets.trello.key,
function(err, status, trello) {
if (err) { return next(err); }
trello = (status && status.statusCode === 200) ?
(JSON.parse(trello)) :
'Can\'t connect to to Trello';
res.end(JSON.stringify(trello));
});
}
function bloggerCalls(req, res, next) {
request(
'https://www.googleapis.com/blogger/v3/blogs/2421288658305323950/' +
'posts?key=' +
secrets.blogger.key,
function (err, status, blog) {
if (err) { return next(err); }
blog = (status && status.statusCode === 200) ?
JSON.parse(blog) :
'Can\'t connect to Blogger';
res.end(JSON.stringify(blog));
}
);
}
function getCats(req, res) {
res.send(
[
{
'name': 'cute',
'imageLink': 'https://encrypted-tbn3.gstatic.com/images' +
'?q=tbn:ANd9GcRaP1ecF2jerISkdhjr4R9yM9-8ClUy-TA36MnDiFBukd5IvEME0g'
},
{
'name': 'grumpy',
'imageLink': 'http://cdn.grumpycats.com/wp-content/uploads/' +
'2012/09/GC-Gravatar-copy.png'
},
{
'name': 'mischievous',
'imageLink': 'http://www.kittenspet.com/wp-content' +
'/uploads/2012/08/cat_with_funny_face_3-200x200.jpg'
} }
] });
); }
}
module.exports = router; function unsubscribed(req, res) {
res.render('resources/unsubscribed', {
title: 'You have been unsubscribed'
});
}
function githubCalls(req, res, next) {
var githubHeaders = {
headers: {
'User-Agent': constantStrings.gitHubUserAgent
},
port: 80
};
request(
[
'https://api.github.com/repos/freecodecamp/',
'freecodecamp/pulls?client_id=',
secrets.github.clientID,
'&client_secret=',
secrets.github.clientSecret
].join(''),
githubHeaders,
function(err, status1, pulls) {
if (err) { return next(err); }
pulls = pulls ?
Object.keys(JSON.parse(pulls)).length :
'Can\'t connect to github';
request(
[
'https://api.github.com/repos/freecodecamp/',
'freecodecamp/issues?client_id=',
secrets.github.clientID,
'&client_secret=',
secrets.github.clientSecret
].join(''),
githubHeaders,
function (err, status2, issues) {
if (err) { return next(err); }
issues = ((pulls === parseInt(pulls, 10)) && issues) ?
Object.keys(JSON.parse(issues)).length - pulls :
"Can't connect to GitHub";
res.send({
issues: issues,
pulls: pulls
});
}
);
}
);
}
function trelloCalls(req, res, next) {
request(
'https://trello.com/1/boards/BA3xVpz9/cards?key=' +
secrets.trello.key,
function(err, status, trello) {
if (err) { return next(err); }
trello = (status && status.statusCode === 200) ?
(JSON.parse(trello)) :
'Can\'t connect to to Trello';
res.end(JSON.stringify(trello));
});
}
function bloggerCalls(req, res, next) {
request(
'https://www.googleapis.com/blogger/v3/blogs/2421288658305323950/' +
'posts?key=' +
secrets.blogger.key,
function (err, status, blog) {
if (err) { return next(err); }
blog = (status && status.statusCode === 200) ?
JSON.parse(blog) :
'Can\'t connect to Blogger';
res.end(JSON.stringify(blog));
}
);
}
function getCats(req, res) {
res.send(
[
{
'name': 'cute',
'imageLink': 'https://encrypted-tbn3.gstatic.com/images' +
'?q=tbn:ANd9GcRaP1ecF2jerISkdhjr4R9yM9-8ClUy-TA36MnDiFBukd5IvEME0g'
},
{
'name': 'grumpy',
'imageLink': 'http://cdn.grumpycats.com/wp-content/uploads/' +
'2012/09/GC-Gravatar-copy.png'
},
{
'name': 'mischievous',
'imageLink': 'http://www.kittenspet.com/wp-content' +
'/uploads/2012/08/cat_with_funny_face_3-200x200.jpg'
}
]
);
}
};