Move models to common/models

closes #795
This commit is contained in:
Berkeley Martinez
2015-06-02 15:05:26 -07:00
parent e8a2060e60
commit 279f953628
28 changed files with 354 additions and 1772 deletions

706
app.js
View File

@ -1,706 +0,0 @@
require('dotenv').load();
// handle uncaught exceptions. Forever will restart process on shutdown
process.on('uncaughtException', function (err) {
console.error(
(new Date()).toUTCString() + ' uncaughtException:',
err.message
);
console.error(err.stack);
/* eslint-disable no-process-exit */
process.exit(1);
/* eslint-enable no-process-exit */
});
var express = require('express'),
accepts = require('accepts'),
cookieParser = require('cookie-parser'),
compress = require('compression'),
session = require('express-session'),
logger = require('morgan'),
errorHandler = require('errorhandler'),
methodOverride = require('method-override'),
bodyParser = require('body-parser'),
helmet = require('helmet'),
frameguard = require('frameguard'),
csp = require('helmet-csp'),
MongoStore = require('connect-mongo')(session),
flash = require('express-flash'),
path = require('path'),
mongoose = require('mongoose'),
passport = require('passport'),
expressValidator = require('express-validator'),
request = require('request'),
forceDomain = require('forcedomain'),
lessMiddleware = require('less-middleware'),
/**
* Controllers (route handlers).
*/
homeController = require('./controllers/home'),
resourcesController = require('./controllers/resources'),
userController = require('./controllers/user'),
nonprofitController = require('./controllers/nonprofits'),
fieldGuideController = require('./controllers/fieldGuide'),
challengeMapController = require('./controllers/challengeMap'),
challengeController = require('./controllers/challenge'),
jobsController = require('./controllers/jobs'),
/**
* Stories
*/
storyController = require('./controllers/story'),
/**
* API keys and Passport configuration.
*/
secrets = require('./config/secrets'),
passportConf = require('./config/passport');
/**
* Create Express server.
*/
var app = express();
/**
* Connect to MongoDB.
*/
mongoose.connect(secrets.db);
mongoose.connection.on('error', function () {
console.error(
'MongoDB Connection Error. Please make sure that MongoDB is running.'
);
});
/**
* Express configuration.
*/
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
if (process.env.NODE_ENV === 'production') {
app.use(forceDomain({
hostname: 'www.freecodecamp.com'
}));
}
app.use(compress());
app.use(lessMiddleware(__dirname + '/public'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(expressValidator({
customValidators: {
matchRegex: function (param, regex) {
return regex.test(param);
}
}
}));
app.use(methodOverride());
app.use(cookieParser());
app.use(session({
resave: true,
saveUninitialized: true,
secret: secrets.sessionSecret,
store: new MongoStore({
url: secrets.db,
'autoReconnect': true
})
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.disable('x-powered-by');
app.use(helmet.xssFilter());
app.use(helmet.noSniff());
app.use(helmet.frameguard());
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept'
);
next();
});
var trusted = [
"'self'",
'blob:',
'*.freecodecamp.com',
'http://www.freecodecamp.com',
'ws://freecodecamp.com/',
'ws://www.freecodecamp.com/',
'*.gstatic.com',
'*.google-analytics.com',
'*.googleapis.com',
'*.google.com',
'*.gstatic.com',
'*.doubleclick.net',
'*.twitter.com',
'*.twitch.tv',
'*.twimg.com',
"'unsafe-eval'",
"'unsafe-inline'",
'*.bootstrapcdn.com',
'*.cloudflare.com',
'https://*.cloudflare.com',
'localhost:3001',
'ws://localhost:3001/',
'http://localhost:3001',
'localhost:3000',
'ws://localhost:3000/',
'http://localhost:3000',
'*.ionicframework.com',
'https://syndication.twitter.com',
'*.youtube.com',
'*.jsdelivr.net',
'https://*.jsdelivr.net',
'*.ytimg.com',
'*.bitly.com',
'http://cdn.inspectlet.com/',
'wss://inspectletws.herokuapp.com/',
'http://hn.inspectlet.com/'
];
app.use(helmet.csp({
defaultSrc: trusted,
scriptSrc: [
'*.optimizely.com',
'*.aspnetcdn.com',
'*.d3js.org'
].concat(trusted),
'connect-src': [
].concat(trusted),
styleSrc: trusted,
imgSrc: [
/* allow all input since we have user submitted images for public profile*/
'*'
].concat(trusted),
fontSrc: ['*.googleapis.com'].concat(trusted),
mediaSrc: [
'*.amazonaws.com',
'*.twitter.com'
].concat(trusted),
frameSrc: [
'*.gitter.im',
'*.gitter.im https:',
'*.vimeo.com',
'*.twitter.com',
'*.ghbtns.com'
].concat(trusted),
reportOnly: false, // set to true if you only want to report errors
setAllHeaders: false, // set to true if you want to set all headers
safari5: false // set to true if you want to force buggy CSP in Safari 5
}));
app.use(function (req, res, next) {
// Make user object available in templates.
res.locals.user = req.user;
next();
});
app.use(express.static(__dirname + '/public', {maxAge: 86400000 }));
app.use(function (req, res, next) {
// Remember original destination before login.
var path = req.path.split('/')[1];
if (/auth|login|logout|signin|signup|fonts|favicon/i.test(path)) {
return next();
} else if (/\/stories\/comments\/\w+/i.test(req.path)) {
return next();
}
req.session.returnTo = req.path;
next();
});
/**
* Main routes.
*/
app.get('/', homeController.index);
app.get('/nonprofit-project-instructions', function(req, res) {
res.redirect(301, '/field-guide/how-do-free-code-camp\'s-nonprofit-projects-work');
});
app.post('/get-help', resourcesController.getHelp);
app.post('/get-pair', resourcesController.getPair);
app.get('/chat', resourcesController.chat);
app.get('/twitch', resourcesController.twitch);
app.get('/cats.json', function(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"
}
]
)
});
// Agile Project Manager Onboarding
app.get('/pmi-acp-agile-project-managers',
resourcesController.agileProjectManagers);
app.get('/agile', function(req, res) {
res.redirect(301, '/pmi-acp-agile-project-managers');
});
app.get('/pmi-acp-agile-project-managers-form',
resourcesController.agileProjectManagersForm);
// Nonprofit Onboarding
app.get('/nonprofits', resourcesController.nonprofits);
app.get('/nonprofits-form', resourcesController.nonprofitsForm);
app.get('/map',
userController.userMigration,
challengeMapController.challengeMap
);
app.get('/live-pair-programming', function(req, res) {
res.redirect(301, '/field-guide/live-stream-pair-programming-on-twitch.tv');
});
app.get('/install-screenhero', function(req, res) {
res.redirect(301, '/field-guide/install-screenhero');
});
app.get('/guide-to-our-nonprofit-projects', function(req, res) {
res.redirect(301, '/field-guide/a-guide-to-our-nonprofit-projects');
});
app.get('/chromebook', function(req, res) {
res.redirect(301, '/field-guide/chromebook');
});
app.get('/deploy-a-website', function(req, res) {
res.redirect(301, '/field-guide/deploy-a-website');
});
app.get('/gmail-shortcuts', function(req, res) {
res.redirect(301, '/field-guide/gmail-shortcuts');
});
app.get('/nodeschool-challenges', function(req, res) {
res.redirect(301, '/field-guide/nodeschool-challenges');
});
app.get('/learn-to-code', challengeMapController.challengeMap);
app.get('/about', function(req, res) {
res.redirect(301, '/map');
});
app.get('/signin', userController.getSignin);
app.get('/login', function(req, res) {
res.redirect(301, '/signin');
});
app.post('/signin', userController.postSignin);
app.get('/signout', userController.signout);
app.get('/logout', function(req, res) {
res.redirect(301, '/signout');
});
app.get('/forgot', userController.getForgot);
app.post('/forgot', userController.postForgot);
app.get('/reset/:token', userController.getReset);
app.post('/reset/:token', userController.postReset);
app.get('/email-signup', userController.getEmailSignup);
app.get('/email-signin', userController.getEmailSignin);
app.post('/email-signup', userController.postEmailSignup);
app.post('/email-signin', userController.postSignin);
/**
* Nonprofit Project routes.
*/
app.get('/nonprofits/directory', nonprofitController.nonprofitsDirectory);
app.get(
'/nonprofits/:nonprofitName',
nonprofitController.returnIndividualNonprofit
);
app.get(
'/jobs',
jobsController.jobsDirectory
);
app.get(
'/jobs-form',
resourcesController.jobsForm
);
app.get('/privacy', function(req, res) {
res.redirect(301, '/field-guide/what-is-the-free-code-camp-privacy-policy?');
});
app.get('/submit-cat-photo', resourcesController.catPhotoSubmit);
app.get('/api/slack', function(req, res) {
if (req.user) {
if (req.user.email) {
var invite = {
'email': req.user.email,
'token': process.env.SLACK_KEY,
'set_active': true
};
var headers = {
'User-Agent': 'Node Browser/0.0.1',
'Content-Type': 'application/x-www-form-urlencoded'
};
var options = {
url: 'https://freecodecamp.slack.com/api/users.admin.invite',
method: 'POST',
headers: headers,
form: invite
};
request(options, function (error, response, body) {
if (!error && response.statusCode === 200) {
req.flash('success', {
msg: "We've successfully requested an invite for you. Please check your email and follow the instructions from Slack."
});
req.user.sentSlackInvite = true;
req.user.save(function(err, user) {
if (err) {
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');
}
});
} else {
req.flash('notice', {
msg: "Before we can send your Slack invite, we need your email address. Please update your profile information here."
});
return res.redirect('/account');
}
} else {
req.flash('notice', {
msg: "You need to sign in to Free Code Camp before we can send you a Slack invite."
});
return res.redirect('/account');
}
});
/**
* Camper News routes.
*/
app.get(
'/stories/hotStories',
storyController.hotJSON
);
app.get(
'/stories/recentStories',
storyController.recentJSON
);
app.get(
'/stories/comments/:id',
storyController.comments
);
app.post(
'/stories/comment/',
storyController.commentSubmit
);
app.post(
'/stories/comment/:id/comment',
storyController.commentOnCommentSubmit
);
app.put(
'/stories/comment/:id/edit',
storyController.commentEdit
);
app.get(
'/stories/submit',
storyController.submitNew
);
app.get(
'/stories/submit/new-story',
storyController.preSubmit
);
app.post(
'/stories/preliminary',
storyController.newStory
);
app.post(
'/stories/',
storyController.storySubmission
);
app.get(
'/news/',
storyController.hot
);
app.post(
'/stories/search',
storyController.getStories
);
app.get(
'/news/:storyName',
storyController.returnIndividualStory
);
app.post(
'/stories/upvote/',
storyController.upvote
);
app.get(
'/unsubscribe/:email',
resourcesController.unsubscribe
);
app.get(
'/unsubscribed',
resourcesController.unsubscribed
);
app.all('/account', passportConf.isAuthenticated);
app.get('/account/api', userController.getAccountAngular);
/**
* API routes
*/
app.get('/api/github', resourcesController.githubCalls);
app.get('/api/blogger', resourcesController.bloggerCalls);
app.get('/api/trello', resourcesController.trelloCalls);
app.get('/api/codepen/twitter/:screenName', resourcesController.codepenResources.twitter);
/**
* Field Guide related routes
*/
app.get('/field-guide/all-articles', fieldGuideController.showAllFieldGuides);
app.get('/field-guide/:fieldGuideName',
fieldGuideController.returnIndividualFieldGuide
);
app.get('/field-guide/', fieldGuideController.returnNextFieldGuide);
app.post('/completed-field-guide/', fieldGuideController.completedFieldGuide);
/**
* Challenge related routes
*/
app.get('/challenges/next-challenge',
userController.userMigration,
challengeController.returnNextChallenge
);
app.get(
'/challenges/:challengeName',
userController.userMigration,
challengeController.returnIndividualChallenge
);
app.get('/challenges/',
userController.userMigration,
challengeController.returnCurrentChallenge);
// todo refactor these routes
app.post('/completed-challenge/', challengeController.completedChallenge);
app.post('/completed-zipline-or-basejump',
challengeController.completedZiplineOrBasejump);
app.post('/completed-bonfire', challengeController.completedBonfire);
// Unique Check API route
app.get('/api/checkUniqueUsername/:username',
userController.checkUniqueUsername
);
app.get('/api/checkExistingUsername/:username',
userController.checkExistingUsername
);
app.get('/api/checkUniqueEmail/:email', userController.checkUniqueEmail);
app.get('/account', userController.getAccount);
app.post('/account/profile', userController.postUpdateProfile);
app.post('/account/password', userController.postUpdatePassword);
app.post('/account/delete', userController.postDeleteAccount);
app.get('/account/unlink/:provider', userController.getOauthUnlink);
app.get('/sitemap.xml', resourcesController.sitemap);
/**
* OAuth sign-in routes.
*/
var passportOptions = {
successRedirect: '/',
failureRedirect: '/login'
};
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get(
'/auth/twitter/callback',
passport.authenticate('twitter', {
successRedirect: '/',
failureRedirect: '/login'
})
);
app.get(
'/auth/linkedin',
passport.authenticate('linkedin', {
state: 'SOME STATE'
})
);
app.get(
'/auth/linkedin/callback',
passport.authenticate('linkedin', passportOptions)
);
app.get(
'/auth/facebook',
passport.authenticate('facebook', {scope: ['email', 'user_location']})
);
app.get(
'/auth/facebook/callback',
passport.authenticate('facebook', passportOptions), function (req, res) {
res.redirect(req.session.returnTo || '/');
}
);
app.get('/auth/github', passport.authenticate('github'));
app.get(
'/auth/github/callback',
passport.authenticate('github', passportOptions), function (req, res) {
res.redirect(req.session.returnTo || '/');
}
);
app.get(
'/auth/google',
passport.authenticate('google', {scope: 'profile email'})
);
app.get(
'/auth/google/callback',
passport.authenticate('google', passportOptions), function (req, res) {
res.redirect(req.session.returnTo || '/');
}
);
// put this route last
app.get(
'/:username',
userController.returnUser
);
/**
* 500 Error Handler.
*/
if (process.env.NODE_ENV === 'development') {
app.use(errorHandler({ log: true }));
} else {
// error handling in production
app.use(function(err, req, res, next) {
// respect err.status
if (err.status) {
res.statusCode = err.status;
}
// default status code to 500
if (res.statusCode < 400) {
res.statusCode = 500;
}
// parse res type
var accept = accepts(req);
var type = accept.type('html', 'json', 'text');
var message = 'opps! Something went wrong. Please try again later';
if (type === 'html') {
req.flash('errors', { msg: message });
return res.redirect('/');
// json
} else if (type === 'json') {
res.setHeader('Content-Type', 'application/json');
return res.send({ message: message });
// plain text
} else {
res.setHeader('Content-Type', 'text/plain');
return res.send(message);
}
});
}
/**
* Start Express server.
*/
app.listen(app.get('port'), function () {
console.log(
'FreeCodeCamp server listening on port %d in %s mode',
app.get('port'),
app.get('env')
);
});
module.exports = app;

View File

@ -1,12 +1,9 @@
var mongoose = require('mongoose');
var secrets = require('../config/secrets');
/**
*
* @type {exports.Schema}
*/
var bonfireSchema = new mongoose.Schema({
name: {
type: String,

View File

@ -1,5 +1,4 @@
var mongoose = require('mongoose');
var secrets = require('../config/secrets');
/**
*
@ -15,7 +14,8 @@ var challengeSchema = new mongoose.Schema({
description: Array,
tests: Array,
challengeSeed: Array,
challengeType: Number, // 0 = html, 1 = javascript only, 2 = video, 3 = zipline, 4 = basejump
// 0 = html, 1 = javascript only, 2 = video, 3 = zipline, 4 = basejump
challengeType: Number,
MDNlinks: Array,
nameCn: String,
descriptionCn: Array,

View File

@ -1,5 +1,4 @@
var mongoose = require('mongoose');
var secrets = require('../config/secrets');
var commentSchema = new mongoose.Schema({
associatedPost: {
@ -38,10 +37,3 @@ var commentSchema = new mongoose.Schema({
});
module.exports = mongoose.model('Comment', commentSchema);
/*
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
*/

View File

@ -0,0 +1,21 @@
var mongoose = require('mongoose');
/**
*
* @type {exports.Schema}
*/
var coursewareSchema = new mongoose.Schema({
name: {
type: String,
unique: true
},
difficulty: String,
description: Array,
tests: Array,
challengeSeed: Array,
// 0 = html, 1 = javascript only, 2 = video, 3 = zipline, 4 = basejump
challengeType: Number
});
module.exports = mongoose.model('Courseware', coursewareSchema);

View File

@ -0,0 +1,18 @@
var mongoose = require('mongoose');
var fieldGuideSchema = new mongoose.Schema({
name: {
type: String,
unique: false
},
dashedName: {
type: String,
unique: false
},
description: {
type: Array,
unique: false
}
});
module.exports = mongoose.model('FieldGuide', fieldGuideSchema);

View File

@ -1,12 +1,10 @@
var mongoose = require('mongoose');
var secrets = require('../config/secrets');
/**
*
* @type {exports.Schema}
*/
var Long = mongoose.Types.Long;
var jobSchema = new mongoose.Schema({
position: String,
company: String,

View File

@ -0,0 +1,27 @@
var mongoose = require('mongoose');
/**
*
* @type {exports.Schema}
*/
var nonprofitSchema = new mongoose.Schema({
name: String,
requestedDeliverables: Array,
whatDoesNonprofitDo: String,
websiteLink: String,
stakeholderName: String,
stakeholderEmail: String,
endUser: String,
approvedDeliverables: Array,
projectDescription: String,
logoUrl: String,
imageUrl: String,
estimatedHours: 0,
interestedCampers: [],
confirmedCampers: [],
// "confirmed", "started", "completed", "aborted"
currentStatus: String
});
module.exports = mongoose.model('Nonprofit', nonprofitSchema);

52
common/models/Story.js Normal file
View File

@ -0,0 +1,52 @@
var mongoose = require('mongoose');
var storySchema = new mongoose.Schema({
headline: {
type: String,
unique: false
},
timePosted: {
type: Number,
default: 0
},
link: {
type: String,
unique: false
},
metaDescription: {
type: String,
default: '',
unique: false
},
description: {
type: String,
unique: false
},
originalStoryAuthorEmail: {
type: String,
default: ''
},
rank: {
type: Number,
default: -Infinity
},
upVotes: {
type: Array,
default: []
},
author: {},
comments: {
type: Array,
default: []
},
image: {
type: String,
default: ''
},
storyLink: {
type: String,
default: ''
}
});
module.exports = mongoose.model('Story', storySchema);

204
common/models/User.js Normal file
View File

@ -0,0 +1,204 @@
var bcrypt = require('bcrypt-nodejs');
var mongoose = require('mongoose');
require('mongoose-long')(mongoose);
var Long = mongoose.Types.Long;
var userSchema = new mongoose.Schema({
email: {
type: String,
lowercase: true,
trim: true,
sparse: true
},
password: String,
facebook: String,
twitter: String,
google: String,
github: String,
linkedin: String,
tokens: Array,
progressTimestamps: {
type: Array,
default: []
},
profile: {
username: {
type: String,
sparse: true,
lowercase: true,
trim: true
},
bio: {
type: String,
default: ''
},
name: {
type: String,
default: ''
},
gender: {
type: String,
default: ''
},
location: {
type: String,
default: ''
},
picture: {
type: String,
default: ''
},
linkedinProfile: {
type: String,
default: ''
},
githubProfile: {
type: String,
default: ''
},
codepenProfile: {
type: String,
default: ''
},
twitterHandle: {
type: String,
default: ''
},
facebookProfile: {
type: String,
default: ''
}
},
portfolio: {
website1Link: {
type: String,
default: ''
},
website1Title: {
type: String,
default: ''
},
website1Image: {
type: String,
default: ''
},
website2Link: {
type: String,
default: ''
},
website2Title: {
type: String,
default: ''
},
website2Image: {
type: String,
default: ''
},
website3Link: {
type: String,
default: ''
},
website3Title: {
type: String,
default: ''
},
website3Image: {
type: String,
default: ''
}
},
resetPasswordToken: String,
sentSlackInvite: false,
resetPasswordExpires: Date,
uncompletedBonfires: Array,
completedBonfires: [{
_id: String,
name: String,
completedWith: String,
completedDate: Long,
solution: String
}],
uncompletedCoursewares: Array,
completedCoursewares: [{
completedDate: {
type: Long,
default: Date.now()
},
_id: String,
name: String,
completedWith: String,
solution: String,
githubLink: String,
verified: Boolean
}],
completedFieldGuides: [],
uncompletedFieldGuides: [],
currentStreak: {
type: Number,
default: 0
},
longestStreak: {
type: Number,
default: 0
},
needsSomeDataModeled: { type: Boolean, default: false},
// needsMigration has been deprecated, use needsSomeDataModeled
needsMigration: {
type: Boolean,
default: true
},
sendMonthlyEmail: {
type: Boolean,
default: true
},
challengesHash: {},
currentChallenge: {},
completedChallenges: [{
completedDate: Long,
_id: String,
name: String,
completedWith: String,
solution: String,
githubLink: String,
verified: Boolean,
challengeType: {
type: Number,
default: 0
}
}],
uncompletedChallenges: Array
});
/**
* Password hashing Mongoose middleware.
*/
userSchema.pre('save', function(next) {
var user = this;
if (!user.isModified('password')) { return next(); }
bcrypt.genSalt(5, function(err, salt) {
if (err) { return next(err); }
bcrypt.hash(user.password, salt, null, function(err, hash) {
if (err) { return next(err); }
user.password = hash;
next();
});
});
});
/**
* Helper method for validationg user's password.
*/
userSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) { return cb(err); }
cb(null, isMatch);
});
};
module.exports = mongoose.model('User', userSchema);

View File

@ -6,9 +6,9 @@ var _ = require('lodash'),
GitHubStrategy = require('passport-github').Strategy,
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
LinkedInStrategy = require('passport-linkedin-oauth2').Strategy,
OAuthStrategy = require('passport-oauth').OAuthStrategy,
OAuth2Strategy = require('passport-oauth').OAuth2Strategy,
User = require('../models/User'),
// OAuthStrategy = require('passport-oauth').OAuthStrategy,
// OAuth2Strategy = require('passport-oauth').OAuth2Strategy,
User = require('../common/models/User'),
nodemailer = require('nodemailer'),
secrets = require('./secrets');

View File

@ -1,59 +0,0 @@
var R = require('ramda'),
debug = require('debug')('freecc:cntr:challengeMap'),
User = require('../models/User'),
resources = require('./resources');
var challengeTypes = {
'HTML_CSS_JQ': 0,
'JAVASCRIPT': 1,
'VIDEO': 2,
'ZIPLINE': 3,
'BASEJUMP': 4,
'BONFIRE': 5
};
module.exports = {
challengeMap: function challengeMap(req, res, next) {
var completedList = [];
if (req.user) {
completedList = req.user.completedChallenges;
}
var noDuplicatedChallenges = R.uniq(completedList);
var completedChallengeList = noDuplicatedChallenges
.map(function(challenge) {
return challenge._id;
});
var challengeList = resources.getChallengeMapForDisplay();
Object.keys(challengeList).forEach(function(key) {
challengeList[key].completed = challengeList[key].challenges.filter(function(elem) {
return completedChallengeList.indexOf(elem._id) > -1;
});
});
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
var date1 = new Date('10/15/2014');
var date2 = new Date();
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
var daysRunning = Math.ceil(timeDiff / (1000 * 3600 * 24));
challengeList[0].completed[0] +=
User.count({}, function (err, camperCount) {
if (err) {
return next(err);
}
res.render('challengeMap/show', {
daysRunning: daysRunning,
camperCount: numberWithCommas(camperCount),
title: "A map of all Free Code Camp's Challenges",
challengeList: challengeList,
completedChallengeList: completedChallengeList
});
});
}
};

View File

@ -1,636 +0,0 @@
var async = require('async'),
path = require('path'),
moment = require('moment'),
Twit = require('twit'),
debug = require('debug')('freecc:cntr:resources'),
cheerio = require('cheerio'),
request = require('request'),
R = require('ramda'),
_ = require('lodash'),
fs = require('fs'),
constantStrings = require('./constantStrings.json'),
User = require('../models/User'),
Challenge = require('./../models/Challenge'),
Story = require('./../models/Story'),
FieldGuide = require('./../models/FieldGuide'),
Nonprofit = require('./../models/Nonprofit'),
Comment = require('./../models/Comment'),
resources = require('./resources.json'),
secrets = require('./../config/secrets'),
nonprofits = require('../seed_data/nonprofits.json'),
fieldGuides = require('../seed_data/field-guides.json'),
Slack = require('node-slack'),
slack = new Slack(secrets.slackHook);
/**
* Cached values
*/
var allFieldGuideIds, allFieldGuideNames, allNonprofitNames,
challengeMap, challengeMapForDisplay, challengeMapWithIds,
challengeMapWithNames, allChallengeIds, allChallenges;
/**
* GET /
* Resources.
*/
Array.zip = function(left, right, combinerFunction) {
var counter,
results = [];
for (counter = 0; counter < Math.min(left.length, right.length); counter++) {
results.push(combinerFunction(left[counter], right[counter]));
}
return results;
};
(function() {
if (!challengeMap) {
var localChallengeMap = {};
var files = fs.readdirSync(
path.join(__dirname, '/../seed_data/challenges')
);
var keyCounter = 0;
files = files.map(function (file) {
return require(
path.join(__dirname, '/../seed_data/challenges/' + file)
);
});
files = files.sort(function (a, b) {
return a.order - b.order;
});
files.forEach(function (file) {
localChallengeMap[keyCounter++] = file;
});
challengeMap = _.cloneDeep(localChallengeMap);
}
})();
module.exports = {
getChallengeMapForDisplay: function() {
if (!challengeMapForDisplay) {
challengeMapForDisplay = {};
Object.keys(challengeMap).forEach(function(key) {
challengeMapForDisplay[key] = {
name: challengeMap[key].name,
dashedName: challengeMap[key].name.replace(/\s/g, '-'),
challenges: challengeMap[key].challenges
}
});
}
return challengeMapForDisplay;
},
getChallengeMapWithIds: function() {
if (!challengeMapWithIds) {
challengeMapWithIds = {};
Object.keys(challengeMap).forEach(function (key) {
var onlyIds = challengeMap[key].challenges.map(function (elem) {
return elem._id;
});
challengeMapWithIds[key] = onlyIds;
});
}
return challengeMapWithIds;
},
allChallengeIds: function() {
if (!allChallengeIds) {
allChallengeIds = [];
Object.keys(this.getChallengeMapWithIds()).forEach(function(key) {
allChallengeIds.push(challengeMapWithIds[key]);
});
allChallengeIds = R.flatten(allChallengeIds);
}
return allChallengeIds;
},
allChallenges: function() {
if (!allChallenges) {
allChallenges = [];
Object.keys(this.getChallengeMapWithNames()).forEach(function(key) {
allChallenges.push(challengeMap[key].challenges);
});
allChallenges = R.flatten(allChallenges);
}
return allChallenges;
},
getChallengeMapWithNames: function() {
if (!challengeMapWithNames) {
challengeMapWithNames = {};
Object.keys(challengeMap).
forEach(function (key) {
var onlyNames = challengeMap[key].challenges.map(function (elem) {
return elem.name;
});
challengeMapWithNames[key] = onlyNames;
});
}
return challengeMapWithNames;
},
sitemap: 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);
}
});
},
challenges: function (callback) {
Challenge.aggregate()
.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 {
setTimeout(function() {
res.header('Content-Type', 'application/xml');
res.render('resources/sitemap', {
appUrl: appUrl,
now: now,
users: results.users,
challenges: results.challenges,
stories: results.stories,
nonprofits: results.nonprofits,
fieldGuides: results.fieldGuides
});
}, 0);
}
}
);
},
chat: function chat(req, res) {
if (req.user && req.user.progressTimestamps.length > 5) {
res.redirect('http://freecodecamp.slack.com');
} else {
res.render('resources/chat', {
title: 'Watch us code live on Twitch.tv'
});
}
},
jobsForm: function jobsForm(req, res) {
res.render('resources/jobs-form', {
title: 'Employer Partnership Form for Job Postings, Recruitment and Corporate Sponsorships'
});
},
catPhotoSubmit: function catPhotoSubmit(req, res) {
res.send(
'Success! You have submitted your cat photo. Return to your website ' +
'by typing any letter into your code editor.'
);
},
nonprofits: function nonprofits(req, res) {
res.render('resources/nonprofits', {
title: 'A guide to our Nonprofit Projects'
});
},
nonprofitsForm: function nonprofitsForm(req, res) {
res.render('resources/nonprofits-form', {
title: 'Nonprofit Projects Proposal Form'
});
},
agileProjectManagers: function agileProjectManagers(req, res) {
res.render('resources/pmi-acp-agile-project-managers', {
title: 'Get Agile Project Management Experience for the PMI-ACP'
});
},
agileProjectManagersForm: function agileProjectManagersForm(req, res) {
res.render('resources/pmi-acp-agile-project-managers-form', {
title: 'Agile Project Management Program Application Form'
});
},
twitch: function twitch(req, res) {
res.render('resources/twitch', {
title: "Enter Free Code Camp's Chat Rooms"
});
},
unsubscribe: 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) {
return next(err);
}
res.redirect('/unsubscribed');
});
} else {
res.redirect('/unsubscribed');
}
});
},
unsubscribed: function unsubscribed(req, res) {
res.render('resources/unsubscribed', {
title: 'You have been unsubscribed'
});
},
githubCalls: function(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
});
}
);
}
);
},
trelloCalls: function(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));
});
},
bloggerCalls: function(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));
}
);
},
about: function(req, res, next) {
if (req.user) {
if (
!req.user.profile.picture ||
req.user.profile.picture.indexOf('apple-touch-icon-180x180.png') !== -1
) {
req.user.profile.picture =
'https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png';
// TODO(berks): unhandled callback
req.user.save();
}
}
var date1 = new Date('10/15/2014');
var date2 = new Date();
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
var daysRunning = Math.ceil(timeDiff / (1000 * 3600 * 24));
var announcements = resources.announcements;
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
User.count({}, function (err, c3) {
if (err) {
debug('User err: ', err);
return next(err);
}
res.render('resources/learn-to-code', {
title: 'About Free Code Camp',
daysRunning: daysRunning,
c3: numberWithCommas(c3),
announcements: announcements
});
});
},
randomPhrase: function() {
return resources.phrases[
Math.floor(Math.random() * resources.phrases.length)
];
},
randomVerb: function() {
return resources.verbs[
Math.floor(Math.random() * resources.verbs.length)
];
},
randomCompliment: function() {
return resources.compliments[
Math.floor(Math.random() * resources.compliments.length)
];
},
allFieldGuideIds: function() {
if (allFieldGuideIds) {
return allFieldGuideIds;
} else {
allFieldGuideIds = fieldGuides.map(function (elem) {
return elem._id;
});
return allFieldGuideIds;
}
},
allFieldGuideNamesAndIds: function() {
if (allFieldGuideNames) {
return allFieldGuideNames;
} else {
allFieldGuideNames = fieldGuides.map(function (elem) {
return {
name: elem.name,
dashedName: elem.dashedName,
id: elem._id };
});
return allFieldGuideNames;
}
},
allNonprofitNames: function() {
if (allNonprofitNames) {
return allNonprofitNames;
} else {
allNonprofitNames = nonprofits.map(function (elem) {
return { name: elem.name };
});
return allNonprofitNames;
}
},
whichEnvironment: function() {
return process.env.NODE_ENV;
},
getURLTitle: function(url, callback) {
(function () {
var result = {title: '', image: '', url: '', description: ''};
request(url, function (error, response, body) {
if (!error && response.statusCode === 200) {
var $ = cheerio.load(body);
var metaDescription = $("meta[name='description']");
var metaImage = $("meta[property='og:image']");
var urlImage = metaImage.attr('content') ?
metaImage.attr('content') :
'';
var metaTitle = $('title');
var description = metaDescription.attr('content') ?
metaDescription.attr('content') :
'';
result.title = metaTitle.text().length < 90 ?
metaTitle.text() :
metaTitle.text().slice(0, 87) + '...';
result.image = urlImage;
result.description = description;
callback(null, result);
} else {
callback(new Error('failed'));
}
});
})();
},
updateUserStoryPictures: function(userId, picture, username, cb) {
var counter = 0,
foundStories,
foundComments;
Story.find({'author.userId': userId}, function(err, stories) {
if (err) {
return cb(err);
}
foundStories = stories;
counter++;
saveStoriesAndComments();
});
Comment.find({'author.userId': userId}, function(err, comments) {
if (err) {
return cb(err);
}
foundComments = comments;
counter++;
saveStoriesAndComments();
});
function saveStoriesAndComments() {
if (counter !== 2) {
return;
}
var tasks = [];
R.forEach(function(comment) {
comment.author.picture = picture;
comment.author.username = username;
comment.markModified('author');
tasks.push(function(cb) {
comment.save(cb);
});
}, foundComments);
R.forEach(function(story) {
story.author.picture = picture;
story.author.username = username;
story.markModified('author');
tasks.push(function(cb) {
story.save(cb);
});
}, foundStories);
async.parallel(tasks, function(err) {
if (err) {
return cb(err);
}
cb();
});
}
},
codepenResources: {
twitter: function(req, res, next) {
// 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
});
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);
}
);
},
twitterFCCStream: function() {
// sends out a tweet stream from FCC's account
},
twitch: function() {
// exports information from the twitch account
},
slack: function() {
}
},
getHelp: function(req, res, next) {
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);
},
getPair: function(req, res, next) {
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.",
channel: '#letspair',
username: "Companion Cube",
icon_url: "https://lh3.googleusercontent.com/-f6xDPDV2rPE/AAAAAAAAAAI/AAAAAAAAAAA/mdlESXQu11Q/photo.jpg"
});
return res.sendStatus(200);
}
};

View File

@ -1,21 +0,0 @@
var mongoose = require('mongoose');
var secrets = require('../config/secrets');
/**
*
* @type {exports.Schema}
*/
var coursewareSchema = new mongoose.Schema({
name: {
type: String,
unique: true
},
difficulty: String,
description: Array,
tests: Array,
challengeSeed: Array,
challengeType: Number // 0 = html, 1 = javascript only, 2 = video, 3 = zipline, 4 = basejump
});
module.exports = mongoose.model('Courseware', coursewareSchema);

View File

@ -1,19 +0,0 @@
var mongoose = require('mongoose');
var secrets = require('../config/secrets');
var fieldGuideSchema = new mongoose.Schema({
name: {
type: String,
unique: false
},
dashedName: {
type: String,
unique: false
},
description: {
type: Array,
unique: false
}
});
module.exports = mongoose.model('FieldGuide', fieldGuideSchema);

View File

@ -1,28 +0,0 @@
var mongoose = require('mongoose');
var secrets = require('../config/secrets');
/**
*
* @type {exports.Schema}
*/
var Long = mongoose.Types.Long;
var nonprofitSchema = new mongoose.Schema({
name: String,
requestedDeliverables: Array,
whatDoesNonprofitDo: String,
websiteLink: String,
stakeholderName: String,
stakeholderEmail: String,
endUser: String,
approvedDeliverables: Array,
projectDescription: String,
logoUrl: String,
imageUrl: String,
estimatedHours: 0,
interestedCampers: [],
confirmedCampers: [],
currentStatus: String // "confirmed", "started", "completed", "aborted"
});
module.exports = mongoose.model('Nonprofit', nonprofitSchema);

View File

@ -1,53 +0,0 @@
var mongoose = require('mongoose');
var secrets = require('../config/secrets');
var storySchema = new mongoose.Schema({
headline: {
type: String,
unique: false
},
timePosted: {
type: Number,
default: 0
},
link: {
type: String,
unique: false
},
metaDescription: {
type: String,
default: '',
unique: false
},
description: {
type: String,
unique: false
},
originalStoryAuthorEmail: {
type: String,
default: ''
},
rank: {
type: Number,
default: -Infinity
},
upVotes: {
type: Array,
default: []
},
author: {},
comments: {
type: Array,
default: []
},
image: {
type: String,
default: ''
},
storyLink: {
type: String,
default: ''
}
});
module.exports = mongoose.model('Story', storySchema);

View File

@ -1,205 +0,0 @@
var bcrypt = require('bcrypt-nodejs');
var crypto = require('crypto');
var mongoose = require('mongoose');
require('mongoose-long')(mongoose);
var Long = mongoose.Types.Long;
var userSchema = new mongoose.Schema({
email: {
type: String,
lowercase: true,
trim: true,
sparse: true
},
password: String,
facebook: String,
twitter: String,
google: String,
github: String,
linkedin: String,
tokens: Array,
progressTimestamps: {
type: Array,
default: []
},
profile: {
username: {
type: String,
sparse: true,
lowercase: true,
trim: true
},
bio: {
type: String,
default: ''
},
name: {
type: String,
default: ''
},
gender: {
type: String,
default: ''
},
location: {
type: String,
default: ''
},
picture: {
type: String,
default: ''
},
linkedinProfile: {
type: String,
default: ''
},
githubProfile: {
type: String,
default: ''
},
codepenProfile: {
type: String,
default: ''
},
twitterHandle: {
type: String,
default: ''
},
facebookProfile: {
type: String,
default: ''
}
},
portfolio: {
website1Link: {
type: String,
default: ''
},
website1Title: {
type: String,
default: ''
},
website1Image: {
type: String,
default: ''
},
website2Link: {
type: String,
default: ''
},
website2Title: {
type: String,
default: ''
},
website2Image: {
type: String,
default: ''
},
website3Link: {
type: String,
default: ''
},
website3Title: {
type: String,
default: ''
},
website3Image: {
type: String,
default: ''
}
},
resetPasswordToken: String,
sentSlackInvite: false,
resetPasswordExpires: Date,
uncompletedBonfires: Array,
completedBonfires: [
{
_id: String,
name: String,
completedWith: String,
completedDate: Long,
solution: String
}
],
uncompletedCoursewares: Array,
completedCoursewares: [
{
completedDate: {
type: Long,
default: Date.now()
},
_id: String,
name: String,
completedWith: String,
solution: String,
githubLink: String,
verified: Boolean
}
],
completedFieldGuides: [],
uncompletedFieldGuides: [],
currentStreak: {
type: Number,
default: 0
},
longestStreak: {
type: Number,
default: 0
},
needsSomeDataModeled: { type: Boolean, default: false},
// needsMigration has been deprecated, use needsSomeDataModeled
needsMigration: { type: Boolean, default: true },
sendMonthlyEmail: { type: Boolean, default: true },
challengesHash: {},
currentChallenge: {},
completedChallenges: [
{
completedDate: Long,
_id: String,
name: String,
completedWith: String,
solution: String,
githubLink: String,
verified: Boolean,
challengeType: {
type: Number,
default: 0
}
}
],
uncompletedChallenges: Array,
});
/**
* Password hashing Mongoose middleware.
*/
userSchema.pre('save', function(next) {
var user = this;
if (!user.isModified('password')) { return next(); }
bcrypt.genSalt(5, function(err, salt) {
if (err) { return next(err); }
bcrypt.hash(user.password, salt, null, function(err, hash) {
if (err) { return next(err); }
user.password = hash;
next();
});
});
});
/**
* Helper method for validationg user's password.
*/
userSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) { return cb(err); }
cb(null, isMatch);
});
};
module.exports = mongoose.model('User', userSchema);

View File

@ -32,11 +32,11 @@
var R = require('ramda'),
express = require('express'),
Challenge = require('./../../models/Challenge'),
User = require('./../../models/User'),
resources = require('./../resources/resources'),
Challenge = require('../../common/models/Challenge'),
User = require('../../common/models/User'),
resources = require('../resources/resources'),
userMigration = require('../resources/middleware').userMigration,
MDNlinks = require('./../../seed_data/bonfireMDNlinks');
MDNlinks = require('../../seed_data/bonfireMDNlinks');
var router = express.Router();
var challengeMapWithNames = resources.getChallengeMapWithNames();

View File

@ -1,9 +1,9 @@
var R = require('ramda'),
express = require('express'),
// debug = require('debug')('freecc:cntr:challengeMap'),
User = require('../../models/User'),
User = require('../../common/models/User'),
resources = require('./../resources/resources'),
middleware = require('../resources/middleware'),
express = require('express'),
router = express.Router();
router.get('/map', middleware.userMigration, challengeMap);

View File

@ -1,8 +1,8 @@
var R = require('ramda'),
express = require('express'),
// debug = require('debug')('freecc:fieldguides'),
FieldGuide = require('./../../models/FieldGuide'),
resources = require('./../resources/resources');
FieldGuide = require('../../common/models/FieldGuide'),
resources = require('../resources/resources');
var router = express.Router();

View File

@ -1,7 +1,7 @@
var message =
'Learn to Code JavaScript and get a Coding Job by Helping Nonprofits';
var express = require('express');
var router = express.Router();
var message =
'Learn to Code JavaScript and get a Coding Job by Helping Nonprofits';
router.get('/', index);

View File

@ -1,5 +1,5 @@
var express = require('express');
var Job = require('./../../models/Job');
var Job = require('../../common/models/Job');
var router = express.Router();
router.get('/jobs', jobsDirectory);

View File

@ -1,5 +1,5 @@
var express = require('express'),
Nonprofit = require('./../../models/Nonprofit');
Nonprofit = require('../../common/models/Nonprofit');
var router = express.Router();

View File

@ -2,12 +2,12 @@ var nodemailer = require('nodemailer'),
sanitizeHtml = require('sanitize-html'),
express = require('express'),
moment = require('moment'),
// debug = require('debug')('freecc:cntr:story'),
Story = require('./../../models/Story'),
Comment = require('./../../models/Comment'),
User = require('./../../models/User'),
resources = require('./../resources/resources'),
mongodb = require('mongodb'),
// debug = require('debug')('freecc:cntr:story'),
Story = require('../../common/models/Story'),
Comment = require('../../common/models/Comment'),
User = require('../../common/models/User'),
resources = require('../resources/resources'),
MongoClient = mongodb.MongoClient,
secrets = require('../../config/secrets'),
router = express.Router();

View File

@ -8,7 +8,7 @@ var _ = require('lodash'),
express = require('express'),
debug = require('debug')('freecc:cntr:userController'),
User = require('../../models/User'),
User = require('../../common/models/User'),
secrets = require('../../config/secrets'),
resources = require('./../resources/resources');

View File

@ -7,12 +7,12 @@ var express = require('express'),
debug = require('debug')('freecc:cntr:resources'),
constantStrings = require('../resources/constantStrings.json'),
User = require('../../models/User'),
Challenge = require('./../../models/Challenge'),
Story = require('./../../models/Story'),
FieldGuide = require('./../../models/FieldGuide'),
Nonprofit = require('./../../models/Nonprofit'),
secrets = require('./../../config/secrets');
User = require('../../common/models/User'),
Challenge = require('../../common/models/Challenge'),
Story = require('../../common/models/Story'),
FieldGuide = require('../../common/models/FieldGuide'),
Nonprofit = require('../../common/models/Nonprofit'),
secrets = require('../../config/secrets');
var slack = new Slack(secrets.slackHook);
var router = express.Router();

View File

@ -1,6 +1,6 @@
var async = require('async'),
path = require('path'),
debug = require('debug')('freecc:cntr:resources'), // eslint-disable-line
// debug = require('debug')('freecc:cntr:resources'),
cheerio = require('cheerio'),
request = require('request'),
R = require('ramda'),
@ -8,8 +8,8 @@ var async = require('async'),
fs = require('fs'),
Story = require('./../../models/Story'),
Comment = require('./../../models/Comment'),
Story = require('../../common/models/Story'),
Comment = require('../../common/models/Comment'),
resources = require('./resources.json'),
nonprofits = require('../../seed_data/nonprofits.json'),
fieldGuides = require('../../seed_data/field-guides.json');