<commit_before>// server.js
//
// main function for activity pump application
//
// Copyright 2011-2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var connect = require('connect'),
    bcrypt  = require('bcrypt'),
    api = require('./routes/api'),
    web = require('./routes/web'),
    databank = require('databank'),
    config = require('./config'),
    express = require('express'),
    _ = require('underscore'),
    schema = require('schema'),
    params,
    Databank = databank.Databank,
    DatabankObject = databank.DatabankObject,
    db,
    app,
    port,
    hostname;

port = config.port || process.env.PORT || 8001,
hostname = config.hostname || process.env.HOSTNAME || 'localhost';

// Initiate the DB

params = config.params;

if (_(params).has('schema')) {
    _.extend(params.schema, schema);
} else {
    params.schema = schema;
}

db = Databank.get(config.driver, params);

// Connect...

db.connect({}, function(err) {

    var server;
    var app = module.exports = express.createServer();

    if (err) {
        console.log("Couldn't connect to JSON store: " + err.message);
	process.exit(1);
    }

    // Configuration

    app.configure(function() {

	// Templates are in public
	app.set('views', __dirname + '/public/template');
	app.set('view engine', 'utml');
	app.use(express.logger());
	app.use(express.bodyParser());
	app.use(express.cookieParser());
	app.use(express.query());
	app.use(express.methodOverride());
	app.use(express.favicon());
	app.use(express.session({secret: (config.secret || "activitypump")}));

	app.use(app.router);

	app.use(express.static(__dirname + '/public'));

    });

    app.configure('development', function() {
	app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
    });

    app.configure('production', function() {
	app.use(express.errorHandler());
    });

    // Routes

    api.addRoutes(app);

    // Use "noweb" to disable Web site (API engine only)

    if (!_(config).has('noweb') || !config.noweb) {
	web.addRoutes(app);
    }

    api.setBank(db);

    app.listen(port);
});
<commit_msg>rearrange dependencies<commit_after>// server.js
//
// main function for activity pump application
//
// Copyright 2011-2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var connect = require('connect'),
    bcrypt  = require('bcrypt'),
    databank = require('databank'),
    express = require('express'),
    _ = require('underscore'),
    api = require('./routes/api'),
    web = require('./routes/web'),
    schema = require('lib/schema'),
    config = require('./config'),
    params,
    Databank = databank.Databank,
    DatabankObject = databank.DatabankObject,
    db,
    app,
    port,
    hostname;

port = config.port || process.env.PORT || 8001,
hostname = config.hostname || process.env.HOSTNAME || 'localhost';

// Initiate the DB

params = config.params;

if (_(params).has('schema')) {
    _.extend(params.schema, schema);
} else {
    params.schema = schema;
}

db = Databank.get(config.driver, params);

// Connect...

db.connect({}, function(err) {

    var server;
    var app = module.exports = express.createServer();

    if (err) {
        console.log("Couldn't connect to JSON store: " + err.message);
	process.exit(1);
    }

    // Configuration

    app.configure(function() {

	// Templates are in public
	app.set('views', __dirname + '/public/template');
	app.set('view engine', 'utml');
	app.use(express.logger());
	app.use(express.bodyParser());
	app.use(express.cookieParser());
	app.use(express.query());
	app.use(express.methodOverride());
	app.use(express.favicon());
	app.use(express.session({secret: (config.secret || "activitypump")}));

	app.use(app.router);

	app.use(express.static(__dirname + '/public'));

    });

    app.configure('development', function() {
	app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
    });

    app.configure('production', function() {
	app.use(express.errorHandler());
    });

    // Routes

    api.addRoutes(app);

    // Use "noweb" to disable Web site (API engine only)

    if (!_(config).has('noweb') || !config.noweb) {
	web.addRoutes(app);
    }

    api.setBank(db);

    app.listen(port);
});
<|endoftext|>


<commit_before><commit_msg>Create express server that serves middleware, webpage, auth, and API routing<commit_after>// Node modules
const bodyParser   = require('body-parser');
const cookieParser = require('cookie-parser');
const express	   = require('express');
const session	   = require('express-session');
// Custom Middleware
const passport	   = require('./auth/');
const configRoutes = require('./routes');
const exhbs		   = require('./views');

let app = express();
// Log incoming requests
app.use((req, res, next) => {
	console.log(`${req.method} ${req.path}`);
	next();
});
// Parse cookies and POST body
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Enable Cookie session
app.use(session({
	secret: 'keyboard cat',
	resave: false,
	saveUninitialized: false,
	cookie: { maxAge : 3600000 },
}));
// Enable Passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Serve static files
exhbs(app, express.static(__dirname + '/public'));
// API routing
configRoutes(app);

// Enable API Server
const server = app.listen(3000, (err) => {
	if (err) {
		throw err;
	}
	const server_ip = server.address().address;
	const server_port = server.address().port;
	console.log(`Server running on ${server_ip}:${server_port}`);
});
<|endoftext|>


<commit_before>var express=require('express'),
	path= require('path'),//Concatena rutas estaticas
	logger = require('morgan'),//inspector registro de actividad
	favicon=require('serve-favicon'),
	jade=require('jade'),
	login=require('./routes/login'), //----Rutas de routing
	map=require('./routes/map'),
	invitado=require('./routes/invitado'),
	user=require('./routes/modificarusuario'),
	puntos=require('./routes/agregarpuntos'),
	manual=require('./routes/manual'),
	about=require('./routes/about'), //---
	publicDir=path.join(__dirname, 'public'),
	viewsDir=path.join(__dirname, 'views'),
	iconoURL=path.join(publicDir,'images', 'icono.ico'),
	port=(process.env.PORT || 3000),//obtener el puerto del proceso, si no el 3000
	ipAddress = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1',
	app=express(),
	pgp = require("pg-promise")(/*options*/),//--------Conexion con DB
	db=require('./controllers/conexion.js'),
	bodyParser=require("body-parser"),
	cookieParser = require('cookie-parser'),
	cookieSession = require('cookie-session');

app
	.use(bodyParser.urlencoded({ extended: true }))
	.use(bodyParser.json())
	//Configurando app
	.set('views',viewsDir)
	.set('view engine', 'jade')
	.set('port',port)
	//ejecutando middlewares
	.use(cookieParser())
	.use(cookieSession({secret: 'abcd1234'}))
	.use(express.static(publicDir))
	.use(favicon(iconoURL))
	.use('/',login)
	.use('/map',map)
	.use('/invitado',invitado)
	.use('/manual',manual)
	.use('/user',user)
	.use('/punto',puntos)
	//.use('/about',about);

module.exports=app;<commit_msg>version para openshift con variable IP<commit_after>var express=require('express'),
	path= require('path'),//Concatena rutas estaticas
	logger = require('morgan'),//inspector registro de actividad
	favicon=require('serve-favicon'),
	jade=require('jade'),
	login=require('./routes/login'), //----Rutas de routing
	map=require('./routes/map'),
	invitado=require('./routes/invitado'),
	user=require('./routes/modificarusuario'),
	puntos=require('./routes/agregarpuntos'),
	manual=require('./routes/manual'),
	about=require('./routes/about'), //---
	publicDir=path.join(__dirname, 'public'),
	viewsDir=path.join(__dirname, 'views'),
	iconoURL=path.join(publicDir,'images', 'icono.ico'),
	port=(process.env.PORT || 3000),//obtener el puerto del proceso, si no el 3000
	ipAddress = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1',
	app=express(),
	pgp = require("pg-promise")(/*options*/),//--------Conexion con DB
	db=require('./controllers/conexion.js'),
	bodyParser=require("body-parser"),
	cookieParser = require('cookie-parser'),
	cookieSession = require('cookie-session');

app
	.use(bodyParser.urlencoded({ extended: true }))
	.use(bodyParser.json())
	//Configurando app
	.set('views',viewsDir)
	.set('view engine', 'jade')
	.set('port',port)
	.set('ipAddress',ipAddress)
	//ejecutando middlewares
	.use(cookieParser())
	.use(cookieSession({secret: 'abcd1234'}))
	.use(express.static(publicDir))
	.use(favicon(iconoURL))
	.use('/',login)
	.use('/map',map)
	.use('/invitado',invitado)
	.use('/manual',manual)
	.use('/user',user)
	.use('/punto',puntos)
	//.use('/about',about);

module.exports=app;<|endoftext|>


<commit_before>/**
* Module dependencies.
*/

  var UNIQUE_KEY = 'unique-key-here';
  var PORT = '3007';

// Core Dependencies
  var bodyParser      = require('body-parser');
  var compress        = require('compression');
  var colour          = require('colour');
  var cookieParser    = require('cookie-parser');
  var csrf            = require('csurf');
  var errorHandler    = require('errorhandler');
  var express         = require('express');
  var enforce_ssl    = require('express-enforces-ssl');
  var helmet          = require('helmet');
  var http            = require('http');
  var methodOverride  = require('method-override');
  var logger          = require('morgan');
  var multer          = require('multer');
  var path            = require('path');
  var api             = require('rebound-api');
  var favicon         = require('serve-favicon');
  var ghost           = require('ghost');

// Session Manageent
  var session         = require('express-session');
  var RedisStore      = require('connect-redis')(session);

// Dev Flag
  var devEnv = (process.env.NODE_ENV == 'production') ? false : true;

// Init Core
  var app = express();
      app.set('port', PORT);
      app.use(compress()); // Compress everything we send
      app.use(favicon(__dirname + '/assets/images/favicon.png')); // Deliver favicon
      app.use(logger('dev')); // Dev level logging
      app.use(bodyParser.json()); // Parse received json values
      app.use(bodyParser.urlencoded({extended: true})); // Parse URL encoded values
      app.use(methodOverride()); // enable DELETE and PUT
      app.use(cookieParser(UNIQUE_KEY)); // Use cookie parser, required before session.

// Development Logging
  if(devEnv) app.use(errorHandler());

// Set Helmet Security Headers
  app.use(helmet.xframe()); // frame busting
  app.use(helmet.xssFilter()); // ie9+ and chrome xss busting
  app.use(helmet.csp({
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "'unsafe-eval'", "'unsafe-inline'"],
    styleSrc: ["'self'", "'unsafe-inline'"],
    imgSrc: ["'self'", 'data:'],
    connectSrc: ["'self'"],
    fontSrc: ["'self'"],
    objectSrc: ["'self'"],
    mediaSrc: ["'self'"],
    frameSrc: ["'self'"],
    reportUri: '/put-xss-logging-uri-here',
    reportOnly: false, // set to true if you only want to report errors
    setAllHeaders: true, // 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
  }));
  var ninetyDaysInMilliseconds = 7776000000;
  app.use(helmet.hsts({ maxAge: ninetyDaysInMilliseconds })); // force https
  app.use(helmet.hidePoweredBy({ setTo: 'PHP 4.2.0' })); // throw off attackers by saying we're using php instead of express
  app.use(helmet.ienoopen()); // obscure old ie xss html inject bug
  app.use(helmet.nosniff()); // only accept files of correct mime type

// Force https if in production environment
  // if(!devEnv){
  //   app.set('trust proxy', 1);
  //   app.use(enforce_ssl());
  // }

// Set Static Content Locations
  app.use(express.static(path.join(__dirname, 'dist')));

// Initiate Sessions.
  app.use(session({
    secret: UNIQUE_KEY,
    resave: false,
    saveUninitialized: false,
    cookie: {
      secure: !devEnv,
      maxAge: (3600000 * 3),
      httpOnly: true
    }
  }));

// // Enable csrf
//   app.use(csrf());
//
// // csrf error handler
//   app.use(function (err, req, res, next) {
//     if (err.code !== 'EBADCSRFTOKEN'){ return next(err); }
//     res.status(403);
//     res.json({status: 'error', message: 'Session has expired or form tampered with'});
//   });
//
// // Set our csrf cookie for the session on first load
  // app.use(function(req, res, next){
  //   // Create a csrf token for this session, or use the existing one
  //   req.session.csrf || (req.session.csrf = req.csrfToken());
  //   // Save it in a cookie. Browser sends this in the x-csrf-token header.
  //   res.cookie('csrf', req.session.csrf, {
  //     maxAge: (1000 * 10),
  //     signed: false
  //   });
  //   next();
  // });

// Get Ghost Config
  ghost({
    config: path.join(__dirname, 'ghost/config.js')
  }).then(function (ghostServer) {
      // Start the ghost server
        app.use(ghostServer.config._config.paths.subdir, ghostServer.rootApp);
        ghostServer.start();

      // Enable Uploads
        app.use(multer({ dest: './dist/tmp/uploads/' }));

      // Automatically discover API in /api. Must be last middleware.
        app.use(api(express));
  });

// Start Server
  http.createServer(app).listen(app.get('port'), function(){
    console.log(('✔ Express server listening on port ' + app.get('port')).green.bold);
    // If user id and group id are set, force process to run with those permissions
    if(process.env.GID && process.env.UID){
      process.setgid(process.env.GID);
      process.setuid(process.env.UID);
    }
  });
<commit_msg>Update csp<commit_after>/**
* Module dependencies.
*/

  var UNIQUE_KEY = 'unique-key-here';
  var PORT = '3007';

// Core Dependencies
  var bodyParser      = require('body-parser');
  var compress        = require('compression');
  var colour          = require('colour');
  var cookieParser    = require('cookie-parser');
  var csrf            = require('csurf');
  var errorHandler    = require('errorhandler');
  var express         = require('express');
  var enforce_ssl    = require('express-enforces-ssl');
  var helmet          = require('helmet');
  var http            = require('http');
  var methodOverride  = require('method-override');
  var logger          = require('morgan');
  var multer          = require('multer');
  var path            = require('path');
  var api             = require('rebound-api');
  var favicon         = require('serve-favicon');
  var ghost           = require('ghost');

// Session Manageent
  var session         = require('express-session');
  var RedisStore      = require('connect-redis')(session);

// Dev Flag
  var devEnv = (process.env.NODE_ENV == 'production') ? false : true;

// Init Core
  var app = express();
      app.set('port', PORT);
      app.use(compress()); // Compress everything we send
      app.use(favicon(__dirname + '/assets/images/favicon.png')); // Deliver favicon
      app.use(logger('dev')); // Dev level logging
      app.use(bodyParser.json()); // Parse received json values
      app.use(bodyParser.urlencoded({extended: true})); // Parse URL encoded values
      app.use(methodOverride()); // enable DELETE and PUT
      app.use(cookieParser(UNIQUE_KEY)); // Use cookie parser, required before session.

// Development Logging
  if(devEnv) app.use(errorHandler());

// Set Helmet Security Headers
  app.use(helmet.xframe()); // frame busting
  app.use(helmet.xssFilter()); // ie9+ and chrome xss busting
  app.use(helmet.csp({
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "'unsafe-eval'", "'unsafe-inline'", 'code.jquery.com'],
    styleSrc: ["'self'", "'unsafe-inline'", 'fonts.googleapis.com'],
    imgSrc: ["'self'", 'data:'],
    connectSrc: ["'self'"],
    fontSrc: ["'self'", 'fonts.gstatic.com'],
    objectSrc: ["'self'"],
    mediaSrc: ["'self'"],
    frameSrc: ["'self'", 'groups.google.com'],
    reportUri: '/put-xss-logging-uri-here',
    reportOnly: false, // set to true if you only want to report errors
    setAllHeaders: true, // 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
  }));
  var ninetyDaysInMilliseconds = 7776000000;
  app.use(helmet.hsts({ maxAge: ninetyDaysInMilliseconds })); // force https
  app.use(helmet.hidePoweredBy({ setTo: 'PHP 4.2.0' })); // throw off attackers by saying we're using php instead of express
  app.use(helmet.ienoopen()); // obscure old ie xss html inject bug
  app.use(helmet.nosniff()); // only accept files of correct mime type

// Force https if in production environment
  // if(!devEnv){
  //   app.set('trust proxy', 1);
  //   app.use(enforce_ssl());
  // }

// Set Static Content Locations
  app.use(express.static(path.join(__dirname, 'dist')));

// Initiate Sessions.
  app.use(session({
    secret: UNIQUE_KEY,
    resave: false,
    saveUninitialized: false,
    cookie: {
      secure: !devEnv,
      maxAge: (3600000 * 3),
      httpOnly: true
    }
  }));

// // Enable csrf
//   app.use(csrf());
//
// // csrf error handler
//   app.use(function (err, req, res, next) {
//     if (err.code !== 'EBADCSRFTOKEN'){ return next(err); }
//     res.status(403);
//     res.json({status: 'error', message: 'Session has expired or form tampered with'});
//   });
//
// // Set our csrf cookie for the session on first load
  // app.use(function(req, res, next){
  //   // Create a csrf token for this session, or use the existing one
  //   req.session.csrf || (req.session.csrf = req.csrfToken());
  //   // Save it in a cookie. Browser sends this in the x-csrf-token header.
  //   res.cookie('csrf', req.session.csrf, {
  //     maxAge: (1000 * 10),
  //     signed: false
  //   });
  //   next();
  // });

// Get Ghost Config
  ghost({
    config: path.join(__dirname, 'ghost/config.js')
  }).then(function (ghostServer) {
      // Start the ghost server
        app.use(ghostServer.config._config.paths.subdir, ghostServer.rootApp);
        ghostServer.start();

      // Enable Uploads
        app.use(multer({ dest: './dist/tmp/uploads/' }));

      // Automatically discover API in /api. Must be last middleware.
        app.use(api(express));
  });

// Start Server
  http.createServer(app).listen(app.get('port'), function(){
    console.log(('✔ Express server listening on port ' + app.get('port')).green.bold);
    // If user id and group id are set, force process to run with those permissions
    if(process.env.GID && process.env.UID){
      process.setgid(process.env.GID);
      process.setuid(process.env.UID);
    }
  });
<|endoftext|>


<commit_before>'use strict';

// create & initialize variable to track user points
var userPoints = 0;

function funcQuestion0(){
// greet user and ask for their name
  var user = prompt('Welcome to my profile! What\'s your name?');
  console.log('The user\'s name is ' + user);
  alert('Hi, ' + user + '! I\'m glad you\'re here to checkout my page!');

  // ask if user wants to play guessing game
  var startGame = prompt('If you\'re interested in learning more about me, how about a quick game? (Yes or No)').toLowerCase();
  console.log(user + 'answered ' + startGame);
  if (startGame === 'yes') {
    alert('Awesome, ' + user + '! Let\'s get started!');
  }
  else {
    alert('Sorry to hear that ' + user + '. But, unfortunately, you still have to play...enjoy :-)');
  }
}
funcQuestion0();

function askBirthPlace(){
// Question #1 - Where was I born?
  var answer1 = prompt('Alright ' + user + ', first question: Was I born in Washington, DC? (Yes or No)').toLowerCase();
  console.log(user + ' answered ' + answer1 + ' for Question 1');
  if (answer1 === 'yes') {
    userPoints ++;
    alert('That\'s right, ' + user + '! You now have ' + userPoints + ' point.');
  }
  else {
    alert('Oooh, sorry ' + user + ', that\'s incorrect! You still have ' + userPoints + ' points, but keep going!');
  }
}
askBirthPlace();

function howManyCountries(){
// Question #2 - How many countries/places have I visited?
  var answer2 = prompt('Okay, second question ' + user + '. Have I traveled to more than 10 countries? (Yes or No)').toLowerCase();
  console.log(user + ' answered ' + answer2 + ' for Question 2');
  if (answer2 === 'yes') {
    userPoints ++;
    alert('Correct, ' + user + '! I\'ve been to 15 different countries! You now have ' + userPoints + ' points. Keep it up!');
  }
  else {
    alert('Nope! That\'s incorrect! You currently have ' + userPoints + ' points, but don\'t give up now ' + user + '!');
  }
}
howManyCountries();

function askFaveFood(){
// Question #3 - My favorite food?
  var answer3 = prompt('Third question for you ' + user + ': Are "tacos" my favorite food ? (Yes or No)').toLowerCase();
  console.log(user + ' answered ' + answer3 + ' for Question 3');
  if (answer3 === 'yes') {
    alert('Although tacos are great ' + user + ', unfortunately, they\'re not my favorite! You have ' + userPoints + ' points.');
  }
  else {
    userPoints++;
    alert('Guess there\'s no stumping you, huh ' + user + '? Spaghetti is my favorite, and you now have ' + userPoints + ' points.');
  }
}
askFaveFood();

function askProfession(){
// Question #4 - What is my professional background?
  var answer4 = prompt('You made it to the fourth question ' + user + '...you\'re doing great. Now, would you bet on me being an aerospace engineer? (Yes or No)' ).toLowerCase();
  console.log(user + ' answered ' + answer4 + ' for Question 4');
  if (answer4 === 'yes') {
    userPoints ++;
    alert('You got it, ' + user + '! Thanks for believing in me...you\'ve got ' + userPoints + ' points!');
  }
  else {
    alert('Aww, c\'mon ' + user + '! Why didn\'t you bet on me?!...Points: ' + userPoints);
  }
}
askProfession();

function askFunFact(){
// Question #5 - Fun or inconspicuous fact about me
  var answer5 = prompt('Hey ' + user + '! Did I ever play keyboard in a band? (Yes or No)').toLowerCase();
  console.log(user + ' answered ' + answer5 + ' for Question 5');
  if (answer5 === 'yes') {
    userPoints++;
    alert('That\'s right ' + user + '! Nice job! You currently have ' + userPoints + ' points.');
  }
  else {
    alert('Sorry ' + user + ', that\'s wrong. Great try though! You scored a total of ' + userPoints + ' points.');
  }
}
askFunFact();

//Question #6 - Guess the number I am thinking of!(Generate random number; user will have four attempts)
var guessNum = Math.floor((Math.random() * 5) + 1); // creates random integer between 1 and 5 inclusively
var answer6 = parseInt(prompt('Okay ' + user + ', I\'m thinking of a number between 1 and 5...can you guess which number? (Enter integer between 1 and 5)')); //converts user's number response to an integer

console.log(user + ' answered ' + answer6 + ' for Question 6');
var numTries = 0; //initialize counter for number of user guesses
var maxTries = 4; //set maximum number of user guesses

// user must enter an integer to continue guessing
while (isNaN(parseInt(answer6))) {
  alert('You must enter an integer!');
}

// give user 3 attempts to guess number
while (numTries < 3) {
  if (answer6 === guessNum) {
    userPoints++;
    alert('Wow! Way to go, ' + user + '! You read my mind! You have ' + userPoints + ' points.');
    break;
  }

  else {
    numTries++;
    var remainingTries = maxTries - numTries;
    alert('Nope, guess again ' + user + '! You still have ' + remainingTries + ' left.');
    answer6 = prompt('Number between 1 and 5? (Enter integer between 1 and 5):\n Tries left: ' + remainingTries);
  }
}

if (numTries === 3) {
  alert('Don\'t beat yourself up about it, ' + user + ' :-) On to the final question!');
}

//Question #7 - Guess one of my favorite countries to visit
var answer7 = prompt('You\'ve made it to the final question, ' + user + '. Ready? Can you guess one of the many countries I\'ve explored?');
console.log(user + ' answered ' + answer7 + ' for Question 7');
var countryArray = ['South Africa', 'China', 'Jamaica', 'Dubai', 'France', 'Germany', 'England', 'Luxembourg'];
var numAttempts = 0; // initialize counter for number of user guesses
var maxAttempts = 6; // maximum number of user guesses
var guessCorrect = false;

while(numAttempts < 5) {
  // loop through array of countries to check user's answer against all array items
  for (var i = 0; i < countryArray.length; i++) {
    // convert user's guess to lower case
    if (answer7.toLowerCase() === countryArray[i].toLowerCase()) {
      userPoints++;
      alert('Awesome, you got it, ' + user + '! ' + answer7 + ' is an amazing place!');
      alert('You scored ' + userPoints + ' out of 7 points, ' + user + '!');
      guessCorrect = true; //Boolean value to confirm correct user guess
      break; // break out of for loop if user guesses correctly
    }

    else {
      guessCorrect = false;
      continue;
    }
  }

  // break out of while loop if user guesses correctly
  if (guessCorrect === true) {
    break;
  }

  // give user 5 more attempts if initial guess is incorrect
  else {
    numAttempts++;
    var remainingAttempts = maxAttempts - numAttempts;
    alert('Nope, great place, but that one wasn\'t on the list. Try again!');
    answer7 = prompt('Guess another country: \n Tries Left: ' + remainingAttempts);
  }
}

if (numAttempts === 5) {
  alert('You scored ' + userPoints + ' out of 7 points!');
}

// thank user; end guessing game
alert('Thanks for playing and visiting my page ' + user + '!');
<commit_msg>Functionized guessNumber<commit_after>'use strict';

// create & initialize variable to track user points
var userPoints = 0;

function funcQuestion0(){
// greet user and ask for their name
  var user = prompt('Welcome to my profile! What\'s your name?');
  console.log('The user\'s name is ' + user);
  alert('Hi, ' + user + '! I\'m glad you\'re here to checkout my page!');

  // ask if user wants to play guessing game
  var startGame = prompt('If you\'re interested in learning more about me, how about a quick game? (Yes or No)').toLowerCase();
  console.log(user + 'answered ' + startGame);
  if (startGame === 'yes') {
    alert('Awesome, ' + user + '! Let\'s get started!');
  }
  else {
    alert('Sorry to hear that ' + user + '. But, unfortunately, you still have to play...enjoy :-)');
  }
}
funcQuestion0();

function askBirthPlace(){
// Question #1 - Where was I born?
  var answer1 = prompt('Alright ' + user + ', first question: Was I born in Washington, DC? (Yes or No)').toLowerCase();
  console.log(user + ' answered ' + answer1 + ' for Question 1');
  if (answer1 === 'yes') {
    userPoints ++;
    alert('That\'s right, ' + user + '! You now have ' + userPoints + ' point.');
  }
  else {
    alert('Oooh, sorry ' + user + ', that\'s incorrect! You still have ' + userPoints + ' points, but keep going!');
  }
}
askBirthPlace();

function howManyCountries(){
// Question #2 - How many countries/places have I visited?
  var answer2 = prompt('Okay, second question ' + user + '. Have I traveled to more than 10 countries? (Yes or No)').toLowerCase();
  console.log(user + ' answered ' + answer2 + ' for Question 2');
  if (answer2 === 'yes') {
    userPoints ++;
    alert('Correct, ' + user + '! I\'ve been to 15 different countries! You now have ' + userPoints + ' points. Keep it up!');
  }
  else {
    alert('Nope! That\'s incorrect! You currently have ' + userPoints + ' points, but don\'t give up now ' + user + '!');
  }
}
howManyCountries();

function askFaveFood(){
// Question #3 - My favorite food?
  var answer3 = prompt('Third question for you ' + user + ': Are "tacos" my favorite food ? (Yes or No)').toLowerCase();
  console.log(user + ' answered ' + answer3 + ' for Question 3');
  if (answer3 === 'yes') {
    alert('Although tacos are great ' + user + ', unfortunately, they\'re not my favorite! You have ' + userPoints + ' points.');
  }
  else {
    userPoints++;
    alert('Guess there\'s no stumping you, huh ' + user + '? Spaghetti is my favorite, and you now have ' + userPoints + ' points.');
  }
}
askFaveFood();

function askProfession(){
// Question #4 - What is my professional background?
  var answer4 = prompt('You made it to the fourth question ' + user + '...you\'re doing great. Now, would you bet on me being an aerospace engineer? (Yes or No)' ).toLowerCase();
  console.log(user + ' answered ' + answer4 + ' for Question 4');
  if (answer4 === 'yes') {
    userPoints ++;
    alert('You got it, ' + user + '! Thanks for believing in me...you\'ve got ' + userPoints + ' points!');
  }
  else {
    alert('Aww, c\'mon ' + user + '! Why didn\'t you bet on me?!...Points: ' + userPoints);
  }
}
askProfession();

function askFunFact(){
// Question #5 - Fun or inconspicuous fact about me
  var answer5 = prompt('Hey ' + user + '! Did I ever play keyboard in a band? (Yes or No)').toLowerCase();
  console.log(user + ' answered ' + answer5 + ' for Question 5');
  if (answer5 === 'yes') {
    userPoints++;
    alert('That\'s right ' + user + '! Nice job! You currently have ' + userPoints + ' points.');
  }
  else {
    alert('Sorry ' + user + ', that\'s wrong. Great try though! You scored a total of ' + userPoints + ' points.');
  }
}
askFunFact();

function guessNumber(){
//Question #6 - Guess the number I am thinking of!(Generate random number; user will have four attempts)
  var guessNum = Math.floor((Math.random() * 5) + 1); // creates random integer between 1 and 5 inclusively
  var answer6 = parseInt(prompt('Okay ' + user + ', I\'m thinking of a number between 1 and 5...can you guess which number? (Enter integer between 1 and 5)')); //converts user's number response to an integer

  console.log(user + ' answered ' + answer6 + ' for Question 6');
  var numTries = 0; //initialize counter for number of user guesses
  var maxTries = 4; //set maximum number of user guesses

  // user must enter an integer to continue guessing
  while (isNaN(parseInt(answer6))) {
    alert('You must enter an integer!');
  }

  // give user 3 attempts to guess number
  while (numTries < 3) {
    if (answer6 === guessNum) {
      userPoints++;
      alert('Wow! Way to go, ' + user + '! You read my mind! You have ' + userPoints + ' points.');
      break;
    }

    else {
      numTries++;
      var remainingTries = maxTries - numTries;
      alert('Nope, guess again ' + user + '! You still have ' + remainingTries + ' left.');
      answer6 = prompt('Number between 1 and 5? (Enter integer between 1 and 5):\n Tries left: ' + remainingTries);
    }
  }

  if (numTries === 3) {
    alert('Don\'t beat yourself up about it, ' + user + ' :-) On to the final question!');
  }
}
guessNumber();

//Question #7 - Guess one of my favorite countries to visit
var answer7 = prompt('You\'ve made it to the final question, ' + user + '. Ready? Can you guess one of the many countries I\'ve explored?');
console.log(user + ' answered ' + answer7 + ' for Question 7');
var countryArray = ['South Africa', 'China', 'Jamaica', 'Dubai', 'France', 'Germany', 'England', 'Luxembourg'];
var numAttempts = 0; // initialize counter for number of user guesses
var maxAttempts = 6; // maximum number of user guesses
var guessCorrect = false;

while(numAttempts < 5) {
  // loop through array of countries to check user's answer against all array items
  for (var i = 0; i < countryArray.length; i++) {
    // convert user's guess to lower case
    if (answer7.toLowerCase() === countryArray[i].toLowerCase()) {
      userPoints++;
      alert('Awesome, you got it, ' + user + '! ' + answer7 + ' is an amazing place!');
      alert('You scored ' + userPoints + ' out of 7 points, ' + user + '!');
      guessCorrect = true; //Boolean value to confirm correct user guess
      break; // break out of for loop if user guesses correctly
    }

    else {
      guessCorrect = false;
      continue;
    }
  }

  // break out of while loop if user guesses correctly
  if (guessCorrect === true) {
    break;
  }

  // give user 5 more attempts if initial guess is incorrect
  else {
    numAttempts++;
    var remainingAttempts = maxAttempts - numAttempts;
    alert('Nope, great place, but that one wasn\'t on the list. Try again!');
    answer7 = prompt('Guess another country: \n Tries Left: ' + remainingAttempts);
  }
}

if (numAttempts === 5) {
  alert('You scored ' + userPoints + ' out of 7 points!');
}

// thank user; end guessing game
alert('Thanks for playing and visiting my page ' + user + '!');
<|endoftext|>


<commit_before>var express = require('express');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var njwt = require('njwt');

var loginRoute = require('./routes/login');
var userRoute = require('./routes/user');

var app = express();

//TODO read from config file
var signingKey = "PLACEHOLDER";

app.use(logger('dev'));
app.use(bodyParser.json({strict: false}));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

//validate JWTs here
app.use(function(req,res,next) {
  //TODO are cookies where the token is?
  var token = req.cookies.token;
  if(token){
    nJwt.verify(token,signingKey,function(err,ver){
      if(err){
        req.expired = true;
        next();
      }else{
        req.user = ver.body;
        next();
      }
    });
  } else{
    next();
  }
});

app.use('/api/login', loginRoute);
app.use('/api/user', userRoute);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.send({
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.send({ message: err.message });
});

module.exports = app;
<commit_msg>uses headers not cookies<commit_after>var express = require('express');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var njwt = require('njwt');

var loginRoute = require('./routes/login');
var userRoute = require('./routes/user');

var app = express();

//TODO read from config file
var signingKey = "PLACEHOLDER";

app.use(logger('dev'));
app.use(bodyParser.json({strict: false}));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

//validate JWTs here
app.use(function(req,res,next) {
  //TODO is headers correct location for token?
  var token = req.headers.token;
  if(token){
    njwt.verify(token,signingKey,function(err,ver){
      if(err){
        req.expired = true;
        next();
      }else{
        req.user = ver.body;
        next();
      }
    });
  } else{
    next();
  }
});

app.use('/api/login', loginRoute);
app.use('/api/user', userRoute);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.send({
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.send({ message: err.message });
});

module.exports = app;
<|endoftext|>


<commit_before>var request = require("request");
var poster = require("./postissue");

var util = require("util");
var bodyParser = require("body-parser");
var express = require("express");
var app = express();
var router = express.Router();

console.log("Getting settings");
var settings = {};
settings.circleCiAccount = process.env["CIRCLE_CI_ACCOUNT"];
settings.circleCiToken = process.env["CIRCLE_CI_TOKEN"];
settings.githubUsername = process.env["GITHUB_USERNAME"];
settings.githubApiKey = process.env["GITHUB_APIKEY"];
settings.orgName = process.env["GITHUB_ORGNAME"];

router.use(function(req, res, next) {
	console.log("Incoming: %s %s", req.method, req.url);
	next();
});
router.get("/", function(req, res) {
	res.send("Ready when you are");
});

router.get("/pr-build-completion/:project/:pull/:build", function(req, res) {
	console.log("Build completion: %s pr# %s build# %s", req.params.project, req.params.pull, req.params.build);

	console.log("Requesting build artifacts payload");
	var url = "https://circleci.com/api/v1/project/" + settings.circleCiAccount + "/" + req.params.project + "/" + req.params.build + "/artifacts?circle-token=" + settings.circleCiToken;

	request({url: url, headers: { "Accept": "application/json"} }, function(err, response, body) {
		console.log("Retrieved the artifacts payload");
		var payload = JSON.parse(body);
		var screenshots = payload.map(theUrl).filter(forImages);
		console.log(screenshots);

		console.log("Posting to Github PR");
		settings.prNumber = req.params.pull;
		settings.repoName = req.params.project;

		poster.postImagesToIssue(settings, screenshots, function() {
			res.type("json");
			res.json({completum: "yep"});
		});
	});
});

router.post("/pr-build-completion", bodyParser.json(), function(req, res) {
	console.log("POST build completion");
	var project = req.body.payload.reponame;
	var build = req.body.payload.build_num;
	var pull = req.body.payload.pull_request_urls[0];
	pull = pull.substring(pull.lastIndexOf("/") + 1);
	console.log("--for build %s of pull %s in the %s project", build, pull, project);

	var url = "https://circleci.com/api/v1/project/" + settings.circleCiAccount + "/" + project + "/" + build + "/artifacts?circle-token=" + settings.circleCiToken;

	// DRY you say? Yeah I know SOLID. Right now just learning nodejs, so it's https://www.youtube.com/watch?v=s8MDNFaGfT4
	request({url: url, headers: { "Accept": "application/json"} }, function(err, response, body) {
		console.log("Retrieved the artifacts payload");
		var payload = JSON.parse(body);
		var screenshots = payload.map(theUrl).filter(forImages);
		console.log(screenshots);

		console.log("Posting to Github PR");
		settings.prNumber = pull;
		settings.repoName = project;

		poster.postImagesToIssue(settings, screenshots, function() {
			res.type("json");
			res.json({completum: "yep"});
		});
	});
});

app.use("/", router);

var port = process.env["PORT"] || 8080;
var ipaddress = "127.0.0.1";

console.log("Preparing to listen on %s:%d", ipaddress, port);
var server = app.listen(port, function() {
	console.log('%s: Node server started on %s:%d ...',
							Date(Date.now() ), ipaddress, port);
});

function theUrl(artifact) {
	return { url: artifact.url,
		name: artifact.url.substring(artifact.url.lastIndexOf("/") + 1, artifact.url.lastIndexOf("-"))
	};
}

function forImages(image) {
	return image.url.substring(image.url.length - 3) == "png";
}
<commit_msg>Remove unneeded code<commit_after>var request = require("request");
var poster = require("./postissue");

var bodyParser = require("body-parser");
var express = require("express");
var app = express();
var router = express.Router();

console.log("Getting settings");
var settings = {};
settings.circleCiAccount = process.env["CIRCLE_CI_ACCOUNT"];
settings.circleCiToken = process.env["CIRCLE_CI_TOKEN"];
settings.githubUsername = process.env["GITHUB_USERNAME"];
settings.githubApiKey = process.env["GITHUB_APIKEY"];
settings.orgName = process.env["GITHUB_ORGNAME"];

router.use(function(req, res, next) {
	console.log("Incoming: %s %s", req.method, req.url);
	next();
});
router.get("/", function(req, res) {
	res.send("Ready when you are");
});

router.post("/pr-build-completion", bodyParser.json(), function(req, res) {
	console.log("POST build completion");
	var project = req.body.payload.reponame;
	var build = req.body.payload.build_num;
	var pull = req.body.payload.pull_request_urls[0];
	pull = pull.substring(pull.lastIndexOf("/") + 1);
	console.log("--for build %s of pull %s in the %s project", build, pull, project);

	var url = "https://circleci.com/api/v1/project/" + settings.circleCiAccount + "/" + project + "/" + build + "/artifacts?circle-token=" + settings.circleCiToken;

	request({url: url, headers: { "Accept": "application/json"} }, function(err, response, body) {
		console.log("Retrieved the artifacts payload");
		var payload = JSON.parse(body);
		var screenshots = payload.map(theUrl).filter(forImages);
		console.log(screenshots);

		console.log("Posting to Github PR");
		settings.prNumber = pull;
		settings.repoName = project;

		poster.postImagesToIssue(settings, screenshots, function() {
			res.type("json");
			res.json({completum: "yep"});
		});
	});
});

app.use("/", router);

var port = process.env["PORT"] || 8080;

console.log("Preparing to listen on %s:%d", ipaddress, port);
var server = app.listen(port, function() {
	console.log('%s: Node server started on port %d ...',
							Date(Date.now() ), port);
});

function theUrl(artifact) {
	return { url: artifact.url,
		name: artifact.url.substring(artifact.url.lastIndexOf("/") + 1, artifact.url.lastIndexOf("-"))
	};
}

function forImages(image) {
	return image.url.substring(image.url.length - 3) == "png";
}
<|endoftext|>


<commit_before>/*
 * decaffeinate suggestions:
 * DS207: Consider shorter variations of null checks
 * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
 */
const Metrics = require('metrics-sharelatex')
Metrics.initialize('doc-updater')

const express = require('express')
const Settings = require('settings-sharelatex')
const logger = require('logger-sharelatex')
logger.initialize('document-updater')

logger.logger.addSerializers(require('./app/js/LoggerSerializers'))

if ((Settings.sentry != null ? Settings.sentry.dsn : undefined) != null) {
  logger.initializeErrorReporting(Settings.sentry.dsn)
}

const RedisManager = require('./app/js/RedisManager')
const DispatchManager = require('./app/js/DispatchManager')
const DeleteQueueManager = require('./app/js/DeleteQueueManager')
const Errors = require('./app/js/Errors')
const HttpController = require('./app/js/HttpController')
const mongojs = require('./app/js/mongojs')
const async = require('async')

const Path = require('path')
const bodyParser = require('body-parser')

Metrics.mongodb.monitor(
  Path.resolve(__dirname, '/node_modules/mongojs/node_modules/mongodb'),
  logger
)
Metrics.event_loop.monitor(logger, 100)

const app = express()
app.use(Metrics.http.monitor(logger))
app.use(bodyParser.json({ limit: Settings.max_doc_length + 64 * 1024 }))
Metrics.injectMetricsRoute(app)

DispatchManager.createAndStartDispatchers(Settings.dispatcherCount || 10)

app.param('project_id', (req, res, next, projectId) => {
  if (projectId != null ? projectId.match(/^[0-9a-f]{24}$/) : undefined) {
    return next()
  } else {
    return next(new Error('invalid project id'))
  }
})

app.param('doc_id', (req, res, next, docId) => {
  if (docId != null ? docId.match(/^[0-9a-f]{24}$/) : undefined) {
    return next()
  } else {
    return next(new Error('invalid doc id'))
  }
})

app.get('/project/:project_id/doc/:doc_id', HttpController.getDoc)
// temporarily keep the GET method for backwards compatibility
app.get('/project/:project_id/doc', HttpController.getProjectDocsAndFlushIfOld)
// will migrate to the POST method of get_and_flush_if_old instead
app.post(
  '/project/:project_id/get_and_flush_if_old',
  HttpController.getProjectDocsAndFlushIfOld
)
app.post('/project/:project_id/clearState', HttpController.clearProjectState)
app.post('/project/:project_id/doc/:doc_id', HttpController.setDoc)
app.post(
  '/project/:project_id/doc/:doc_id/flush',
  HttpController.flushDocIfLoaded
)
app.delete('/project/:project_id/doc/:doc_id', HttpController.deleteDoc)
app.delete('/project/:project_id', HttpController.deleteProject)
app.delete('/project', HttpController.deleteMultipleProjects)
app.post('/project/:project_id', HttpController.updateProject)
app.post(
  '/project/:project_id/history/resync',
  HttpController.resyncProjectHistory
)
app.post('/project/:project_id/flush', HttpController.flushProject)
app.post(
  '/project/:project_id/doc/:doc_id/change/:change_id/accept',
  HttpController.acceptChanges
)
app.post(
  '/project/:project_id/doc/:doc_id/change/accept',
  HttpController.acceptChanges
)
app.delete(
  '/project/:project_id/doc/:doc_id/comment/:comment_id',
  HttpController.deleteComment
)

app.get('/flush_all_projects', HttpController.flushAllProjects)
app.get('/flush_queued_projects', HttpController.flushQueuedProjects)

app.get('/total', (req, res, next) => {
  const timer = new Metrics.Timer('http.allDocList')
  RedisManager.getCountOfDocsInMemory((err, count) => {
    if (err) {
      return next(err)
    }
    timer.done()
    res.send({ total: count })
  })
})

app.get('/status', (req, res) => {
  if (Settings.shuttingDown) {
    return res.sendStatus(503) // Service unavailable
  } else {
    return res.send('document updater is alive')
  }
})

const pubsubClient = require('redis-sharelatex').createClient(
  Settings.redis.pubsub
)
app.get('/health_check/redis', (req, res, next) => {
  pubsubClient.healthCheck((error) => {
    if (error != null) {
      logger.err({ err: error }, 'failed redis health check')
      return res.sendStatus(500)
    } else {
      return res.sendStatus(200)
    }
  })
})

const docUpdaterRedisClient = require('redis-sharelatex').createClient(
  Settings.redis.documentupdater
)
app.get('/health_check/redis_cluster', (req, res, next) => {
  docUpdaterRedisClient.healthCheck((error) => {
    if (error != null) {
      logger.err({ err: error }, 'failed redis cluster health check')
      return res.sendStatus(500)
    } else {
      return res.sendStatus(200)
    }
  })
})

app.get('/health_check', (req, res, next) => {
  async.series(
    [
      (cb) => {
        pubsubClient.healthCheck((error) => {
          if (error != null) {
            logger.err({ err: error }, 'failed redis health check')
          }
          cb(error)
        })
      },
      (cb) => {
        docUpdaterRedisClient.healthCheck((error) => {
          if (error != null) {
            logger.err({ err: error }, 'failed redis cluster health check')
          }
          cb(error)
        })
      },
      (cb) => {
        mongojs.healthCheck((error) => {
          if (error != null) {
            logger.err({ err: error }, 'failed mongo health check')
          }
          cb(error)
        })
      }
    ],
    (error) => {
      if (error != null) {
        return res.sendStatus(500)
      } else {
        return res.sendStatus(200)
      }
    }
  )
})

app.use((error, req, res, next) => {
  if (error instanceof Errors.NotFoundError) {
    return res.sendStatus(404)
  } else if (error instanceof Errors.OpRangeNotAvailableError) {
    return res.sendStatus(422) // Unprocessable Entity
  } else if (error.statusCode === 413) {
    return res.status(413).send('request entity too large')
  } else {
    logger.error({ err: error, req }, 'request errored')
    return res.status(500).send('Oops, something went wrong')
  }
})

const shutdownCleanly = (signal) => () => {
  logger.log({ signal }, 'received interrupt, cleaning up')
  Settings.shuttingDown = true
  setTimeout(() => {
    logger.log({ signal }, 'shutting down')
    process.exit()
  }, 10000)
}

const watchForEvent = (eventName) => {
  docUpdaterRedisClient.on(eventName, (e) => {
    console.log(`redis event: ${eventName} ${e}`) // eslint-disable-line no-console
  })
}

const events = ['connect', 'ready', 'error', 'close', 'reconnecting', 'end']
for (const eventName of events) {
  watchForEvent(eventName)
}

const port =
  Settings.internal.documentupdater.port ||
  (Settings.api &&
    Settings.api.documentupdater &&
    Settings.api.documentupdater.port) ||
  3003
const host = Settings.internal.documentupdater.host || 'localhost'

if (!module.parent) {
  // Called directly
  app.listen(port, host, () => {
    logger.info(`Document-updater starting up, listening on ${host}:${port}`)
    if (Settings.continuousBackgroundFlush) {
      logger.info('Starting continuous background flush')
      DeleteQueueManager.startBackgroundFlush()
    }
  })
}

module.exports = app

for (const signal of [
  'SIGINT',
  'SIGHUP',
  'SIGQUIT',
  'SIGUSR1',
  'SIGUSR2',
  'SIGTERM',
  'SIGABRT'
]) {
  process.on(signal, shutdownCleanly(signal))
}
<commit_msg>Decaf cleanup: simplify null checks<commit_after>const Metrics = require('metrics-sharelatex')
Metrics.initialize('doc-updater')

const express = require('express')
const Settings = require('settings-sharelatex')
const logger = require('logger-sharelatex')
logger.initialize('document-updater')

logger.logger.addSerializers(require('./app/js/LoggerSerializers'))

if (Settings.sentry != null && Settings.sentry.dsn != null) {
  logger.initializeErrorReporting(Settings.sentry.dsn)
}

const RedisManager = require('./app/js/RedisManager')
const DispatchManager = require('./app/js/DispatchManager')
const DeleteQueueManager = require('./app/js/DeleteQueueManager')
const Errors = require('./app/js/Errors')
const HttpController = require('./app/js/HttpController')
const mongojs = require('./app/js/mongojs')
const async = require('async')

const Path = require('path')
const bodyParser = require('body-parser')

Metrics.mongodb.monitor(
  Path.resolve(__dirname, '/node_modules/mongojs/node_modules/mongodb'),
  logger
)
Metrics.event_loop.monitor(logger, 100)

const app = express()
app.use(Metrics.http.monitor(logger))
app.use(bodyParser.json({ limit: Settings.max_doc_length + 64 * 1024 }))
Metrics.injectMetricsRoute(app)

DispatchManager.createAndStartDispatchers(Settings.dispatcherCount || 10)

app.param('project_id', (req, res, next, projectId) => {
  if (projectId != null && projectId.match(/^[0-9a-f]{24}$/)) {
    return next()
  } else {
    return next(new Error('invalid project id'))
  }
})

app.param('doc_id', (req, res, next, docId) => {
  if (docId != null && docId.match(/^[0-9a-f]{24}$/)) {
    return next()
  } else {
    return next(new Error('invalid doc id'))
  }
})

app.get('/project/:project_id/doc/:doc_id', HttpController.getDoc)
// temporarily keep the GET method for backwards compatibility
app.get('/project/:project_id/doc', HttpController.getProjectDocsAndFlushIfOld)
// will migrate to the POST method of get_and_flush_if_old instead
app.post(
  '/project/:project_id/get_and_flush_if_old',
  HttpController.getProjectDocsAndFlushIfOld
)
app.post('/project/:project_id/clearState', HttpController.clearProjectState)
app.post('/project/:project_id/doc/:doc_id', HttpController.setDoc)
app.post(
  '/project/:project_id/doc/:doc_id/flush',
  HttpController.flushDocIfLoaded
)
app.delete('/project/:project_id/doc/:doc_id', HttpController.deleteDoc)
app.delete('/project/:project_id', HttpController.deleteProject)
app.delete('/project', HttpController.deleteMultipleProjects)
app.post('/project/:project_id', HttpController.updateProject)
app.post(
  '/project/:project_id/history/resync',
  HttpController.resyncProjectHistory
)
app.post('/project/:project_id/flush', HttpController.flushProject)
app.post(
  '/project/:project_id/doc/:doc_id/change/:change_id/accept',
  HttpController.acceptChanges
)
app.post(
  '/project/:project_id/doc/:doc_id/change/accept',
  HttpController.acceptChanges
)
app.delete(
  '/project/:project_id/doc/:doc_id/comment/:comment_id',
  HttpController.deleteComment
)

app.get('/flush_all_projects', HttpController.flushAllProjects)
app.get('/flush_queued_projects', HttpController.flushQueuedProjects)

app.get('/total', (req, res, next) => {
  const timer = new Metrics.Timer('http.allDocList')
  RedisManager.getCountOfDocsInMemory((err, count) => {
    if (err) {
      return next(err)
    }
    timer.done()
    res.send({ total: count })
  })
})

app.get('/status', (req, res) => {
  if (Settings.shuttingDown) {
    return res.sendStatus(503) // Service unavailable
  } else {
    return res.send('document updater is alive')
  }
})

const pubsubClient = require('redis-sharelatex').createClient(
  Settings.redis.pubsub
)
app.get('/health_check/redis', (req, res, next) => {
  pubsubClient.healthCheck((error) => {
    if (error) {
      logger.err({ err: error }, 'failed redis health check')
      return res.sendStatus(500)
    } else {
      return res.sendStatus(200)
    }
  })
})

const docUpdaterRedisClient = require('redis-sharelatex').createClient(
  Settings.redis.documentupdater
)
app.get('/health_check/redis_cluster', (req, res, next) => {
  docUpdaterRedisClient.healthCheck((error) => {
    if (error) {
      logger.err({ err: error }, 'failed redis cluster health check')
      return res.sendStatus(500)
    } else {
      return res.sendStatus(200)
    }
  })
})

app.get('/health_check', (req, res, next) => {
  async.series(
    [
      (cb) => {
        pubsubClient.healthCheck((error) => {
          if (error) {
            logger.err({ err: error }, 'failed redis health check')
          }
          cb(error)
        })
      },
      (cb) => {
        docUpdaterRedisClient.healthCheck((error) => {
          if (error) {
            logger.err({ err: error }, 'failed redis cluster health check')
          }
          cb(error)
        })
      },
      (cb) => {
        mongojs.healthCheck((error) => {
          if (error) {
            logger.err({ err: error }, 'failed mongo health check')
          }
          cb(error)
        })
      }
    ],
    (error) => {
      if (error) {
        return res.sendStatus(500)
      } else {
        return res.sendStatus(200)
      }
    }
  )
})

app.use((error, req, res, next) => {
  if (error instanceof Errors.NotFoundError) {
    return res.sendStatus(404)
  } else if (error instanceof Errors.OpRangeNotAvailableError) {
    return res.sendStatus(422) // Unprocessable Entity
  } else if (error.statusCode === 413) {
    return res.status(413).send('request entity too large')
  } else {
    logger.error({ err: error, req }, 'request errored')
    return res.status(500).send('Oops, something went wrong')
  }
})

const shutdownCleanly = (signal) => () => {
  logger.log({ signal }, 'received interrupt, cleaning up')
  Settings.shuttingDown = true
  setTimeout(() => {
    logger.log({ signal }, 'shutting down')
    process.exit()
  }, 10000)
}

const watchForEvent = (eventName) => {
  docUpdaterRedisClient.on(eventName, (e) => {
    console.log(`redis event: ${eventName} ${e}`) // eslint-disable-line no-console
  })
}

const events = ['connect', 'ready', 'error', 'close', 'reconnecting', 'end']
for (const eventName of events) {
  watchForEvent(eventName)
}

const port =
  Settings.internal.documentupdater.port ||
  (Settings.api &&
    Settings.api.documentupdater &&
    Settings.api.documentupdater.port) ||
  3003
const host = Settings.internal.documentupdater.host || 'localhost'

if (!module.parent) {
  // Called directly
  app.listen(port, host, () => {
    logger.info(`Document-updater starting up, listening on ${host}:${port}`)
    if (Settings.continuousBackgroundFlush) {
      logger.info('Starting continuous background flush')
      DeleteQueueManager.startBackgroundFlush()
    }
  })
}

module.exports = app

for (const signal of [
  'SIGINT',
  'SIGHUP',
  'SIGQUIT',
  'SIGUSR1',
  'SIGUSR2',
  'SIGTERM',
  'SIGABRT'
]) {
  process.on(signal, shutdownCleanly(signal))
}
<|endoftext|>


<commit_before>// ==========================================================================
// UnorderedList
// ==========================================================================
'use strict';

// Config
// --------------------------------------------------------------------------

var express        = require('express'),
    app            = express(),
    parser         = require('body-parser').json(),
    server         = require('http').createServer(app),
    io             = require('socket.io').listen(server),
    favicon        = require('serve-favicon'),
    mongoose       = require('mongoose'),
    List           = require('./models/list.js'),
    env            = process.env.NODE_ENV || 'development',
    port           = process.env.PORT || 3000;

// Connect
// --------------------------------------------------------------------------

server.listen(port);

if (env === 'development') {
  mongoose.connect('mongodb://localhost/ul');
} else if (env === 'test') {
  mongoose.connect('mongodb://' + process.env.TEST_MONGOLAB_HOST + '/ul');
} else if (env === 'production') {
  mongoose.connect('mongodb://' + process.env.MONGOLAB_URI + '/ul');
}

// Routes
// --------------------------------------------------------------------------

// default
app.get('/', function (req, res) {
  res.sendFile(__dirname + '/public/index.html');
});

// test
if (env === 'development') {

  // spec runner
  app.get('/test', function (req, res) {
    res.sendFile(__dirname + '/_SpecRunner.html');
  });

  // spec fixtures
  app.get('/tmpl/inc/:filename', function (req, res) {
    res.sendFile(__dirname + '/tmpl/inc/' + req.params.filename);
  });

  app.use('/.grunt', express.static(__dirname + '/.grunt'));
  app.use('/spec', express.static(__dirname + '/spec'));
}

// load list
app.get('/:list', function (req, res) {
  res.sendFile(__dirname + '/public/index.html');
});

// get latest list item (<30min TODO make user setting)
app.get('/get/:list', function (req, res) {
  List.aggregate(
    { $match: { name: req.params.list }},
    { $unwind: '$items' },
    { $match: { 'items.active': true }},
    { $sort: { 'items.added': -1 }},
    { $limit: 1 }, function (err, result) {
      if (err) {
        res.status(500);
        res.send(err);

      } else {
        var item_added = result[0].items.added,
            item_body  = result[0].items.body;

        if (get_item_timer(item_added)) {
          res.send(item_body);

        } else {
          res.send('NO_RECENT_ITEM');
        }
      }
  });
});

// post item
app.post('/:list', parser, function (req, res) {
  List.findOne({ name: req.params.list }, function (err, result) {
    if (err || !result) {
      res.status(500);
      res.send('ERROR');

    } else {
      insert_item(req.body.item, result);
      res.send('ITEM_ADDED');
    }
  });
});

app.use('/public', express.static(__dirname + '/public'));
app.use(favicon(__dirname + '/public/favicon.ico'));

// Sockets
// --------------------------------------------------------------------------

io.sockets.on('connection', function (socket) {

  // user connected
  console.log('User Connected - ' + new Date());

  // load list
  socket.on('load list', function (list_name) {
    List.find({ name : list_name }, function (err, doc) {
      if (err) {
        console.error(err);

      // create new
      } else if (!doc.length) {
        var new_list = new List({ name: list_name });

        new_list.save( function (err) {
          if (err) {
            console.error(err);

          } else {
            socket.list_name = list_name;
            socket.emit('new list', socket.list_name);
          }
        });

      // load history
      } else {
        socket.list_name = list_name;
        List.find({ name: socket.list_name }, function (err, docs) {
          if (err) {
            console.error(err);

          } else {
            var list_items = [],
                i, max = docs[0].items.length;

            // only send active list items
            for(i = 0; i < max; i++) {
              if(docs[0].items[i].active === true) {
                list_items.push(docs[0].items[i]);
              }
            }
            socket.emit('load list', socket.list_name, list_items);
          }
        });
      }
    });
  });

  // add item
  socket.on('add item', function (item) {
    List.findOne({ name: socket.list_name }, function (err, doc) {
      if (err) {
        console.error(err);

      } else {
        insert_item(item, doc);
      }
    });
  });

  // remove item (set inactive)
  socket.on('remove item', function (id) {
    List.update({ 'items._id': id }, { '$set': { 'items.$.active': false } }, function (err) {
      if (err) {
        console.error(err);

      } else {
        io.sockets.emit('item deleted', id);
      }
    });
  });

  // user disconnected
  socket.on('disconnect', function () {
    console.log('User Disconnected - ' + new Date());
  });
});

// Helpers
// --------------------------------------------------------------------------

// get item timer (30min TODO make user setting)
function get_item_timer(added) {

  var now   = new Date,
      elaps = (now.getTime() - added.getTime()) / 1000 / 60;

  return elaps < 30 ? true : false;
}

// insert list item
function insert_item(item, list) {

  var data = {
    body: item,
    active: true,
    _id: new mongoose.Types.ObjectId,
    added: new Date
  };

  list.items.push(data);
  list.save( function (err) {
    if (err) {
      console.error('err');

    } else {
      io.sockets.emit('item added', data, list.name);
    }
  });
}
<commit_msg>remove timer & update GET service to send JSON response data<commit_after>// ==========================================================================
// UnorderedList
// ==========================================================================
'use strict';

// Init
// --------------------------------------------------------------------------

var express        = require('express'),
    app            = express(),
    parser         = require('body-parser').json(),
    server         = require('http').createServer(app),
    io             = require('socket.io').listen(server),
    favicon        = require('serve-favicon'),
    mongoose       = require('mongoose'),
    List           = require('./models/list.js'),
    env            = process.env.NODE_ENV || 'development',
    port           = process.env.PORT || 3000;

    server.listen(port);

    if (env === 'development') {
      mongoose.connect('mongodb://localhost/ul');
    } else if (env === 'test') {
      mongoose.connect('mongodb://' + process.env.TEST_MONGOLAB_HOST + '/ul');
    } else if (env === 'production') {
      mongoose.connect('mongodb://' + process.env.MONGOLAB_URI + '/ul');
    }

// Routes
// --------------------------------------------------------------------------

// default
app.get('/', function (req, res) {
  res.sendFile(__dirname + '/public/index.html');
});

// testing
if (env === 'test' || env === 'development') {
  // spec runner
  app.get('/test', function (req, res) {
    res.sendFile(__dirname + '/_SpecRunner.html');
  });
  // spec fixtures
  app.get('/tmpl/inc/:filename', function (req, res) {
    res.sendFile(__dirname + '/tmpl/inc/' + req.params.filename);
  });
  // test assets
  app.use('/.grunt', express.static(__dirname + '/.grunt'));
  app.use('/spec', express.static(__dirname + '/spec'));
}

// load list
app.get('/:list', function (req, res) {
  res.sendFile(__dirname + '/public/index.html');
});

// get item
app.get('/get/:list', function (req, res) {
  List.aggregate(
    { $match: { name: req.params.list } },
    { $unwind: '$items' },
    { $match: { 'items.active': true } },
    { $sort:  { 'items.added': -1 } },
    { $limit: 1 }, function (err, list) {
      if (err) {
        res.status(500);
        res.send(err);
      } else {
        res.send(list[0].items);
      }
  });
});

// post item
app.post('/:list', parser, function (req, res) {
  List.findOne({ name: req.params.list }, function (err, list) {
    if (err || !list) {
      res.status(500);
      res.send('ERROR');
    } else {
      insert_item(req.body.item, list);
      res.send('ITEM_ADDED');
    }
  });
});

// public assets
app.use('/public', express.static(__dirname + '/public'));
app.use(favicon(__dirname + '/public/favicon.ico'));

// Sockets
// --------------------------------------------------------------------------

io.sockets.on('connection', function (socket) {

  // user connected
  console.log('User Connected - ' + new Date());

  // load list
  socket.on('load list', function (list_name) {
    List.find({ name : list_name }, function (err, doc) {
      if (err) {
        console.error(err);
      // create new
      } else if (!doc.length) {
        var new_list = new List({ name: list_name });
        new_list.save( function (err) {
          if (err) {
            console.error(err);

          } else {
            socket.list_name = list_name;
            socket.emit('new list', socket.list_name);
          }
        });
      // load history
      } else {
        socket.list_name = list_name;
        List.find({ name: socket.list_name }, function (err, docs) {
          if (err) {
            console.error(err);
          // send active items
          } else {
            var list_items = [],
                i, max = docs[0].items.length;
            for(i = 0; i < max; i++) {
              if(docs[0].items[i].active === true) {
                list_items.push(docs[0].items[i]);
              }
            }
            socket.emit('load list', socket.list_name, list_items);
          }
        });
      }
    });
  });

  // add item
  socket.on('add item', function (item) {
    List.findOne({ name: socket.list_name }, function (err, doc) {
      if (err) {
        console.error(err);
      } else {
        insert_item(item, doc);
      }
    });
  });

  // remove item (set inactive)
  socket.on('remove item', function (id) {
    List.update({ 'items._id': id }, { '$set': { 'items.$.active': false } }, function (err) {
      if (err) {
        console.error(err);
      } else {
        io.sockets.emit('item deleted', id);
      }
    });
  });

  // user disconnected
  socket.on('disconnect', function () {
    console.log('User Disconnected - ' + new Date());
  });
});

// Helpers
// --------------------------------------------------------------------------

// get item timer (TODO make user setting)
// function get_item_timer(added) {
//
//   var now   = new Date,
//       elaps = (now.getTime() - added.getTime()) / 1000 / 60;
//
//   return elaps < 30 ? true : false;
// }

// insert list item
function insert_item(item, list) {

  var data = {
    body: item,
    active: true,
    _id: new mongoose.Types.ObjectId,
    added: new Date
  };

  list.items.push(data);
  list.save( function (err) {
    if (err) {
      console.error('err');
    } else {
      io.sockets.emit('item added', data, list.name);
    }
  });
}
<|endoftext|>


<commit_before>var restify = require('restify');
var request = require('request');
var Rx = require('rx');
var rootUrl = 'https://hacker-news.firebaseio.com';
var version = '/v0'
var get = Rx.Observable.fromNodeCallback(request);

function getTopStories(req, res, next){
    var topStories = [];
    var fromStory = req.query.fromStory;
    var toStory = req.query.toStory;
    if(!fromStory){
        fromStory = 0;
    }

    if(!toStory){
        toStory = 100;
    }

    get(rootUrl + version + '/topstories.json')
    .map(function(res){
        return res[1];  // get the body
     })
    .map(function(res){
        return JSON.parse(res);     //turn it into a object
    })
    .flatMap(function(res) {
        return Rx.Observable.fromArray(res);    //map each of the story item ids into an observable
    })
    .skip(fromStory)
    .take(toStory)       //take the max
    .flatMap(function(res){
        return get(rootUrl + version + '/item/' + res + '.json');   // make the details call on each response
    })
    .map(function(res){
        return res[1];  // get the body
     })
    .map(function(res){
        return JSON.parse(res);     //turn it into a object
    })
    .subscribe(
            function (x) {
                topStories[topStories.length] = x;
            },
            function (err) {
                console.log('Error:  ' + err);
            },
            function () {
                res.send(topStories);
            }
    );
}

/*var server = restify.createServer({
  name: 'myapp',
  version: '1.0.0'
});
server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());*/

function getComments(parentStoryID, arr, startDepth, endDepth){
	// request parent story
	// grab 'kids' field from parent story response
	// the field from part 2 contains depth 0 comments
	// for each kid, request the item and recurse as far as endDepth param specifies
	return getItemKids(parentStoryID)
		.flatMap(function(item){
			return getItem(item)
		})
		.expand(function(item){
			if (!arr[item.id])
				arr[item.id]=item
			return getComments(item.id, arr, startDepth, endDepth)
		})
}

function getItemKids(itemID){
	return getItem(itemID)
			.map(function(parsedJSON){
				var kids = parsedJSON['kids']
				return (kids) ? kids : []
			})
			.flatMap(function(kids){
				return Rx.Observable.fromArray(kids)
			})
}

function getItem(itemID){
	return get(rootUrl+version+'/item/'+itemID+'.json')
		.map(function(res){
			return res[1]
		})
		.map(function(rawJSON){
			return JSON.parse(rawJSON)
		})
}
var arr = []
getComments('8863', arr, 0, 2)
    .subscribe(
    	function(onNextValue){

    	},
    	function(error){
    		console.log("Error: "+error)
    	},
    	function(){
    		console.log("Complete")
    		var unsparseArray = []
    		arr.map(function(validItem){
    			unsparseArray[unsparseArray.length]=validItem
    		})
    		console.log("unsparseArray Length: " + unsparseArray.length)
    	}
    )
//server.get('/getTopStories', getTopStories);
//var port = process.env.PORT || 5000;
//server.listen(port, function () {
//  console.log('%s listening at %s', server.name, server.url);
//});
<commit_msg>Some more incremental commits to last commit<commit_after>var restify = require('restify');
var request = require('request');
var Rx = require('rx');
var rootUrl = 'https://hacker-news.firebaseio.com';
var version = '/v0'
var get = Rx.Observable.fromNodeCallback(request);

function getTopStories(req, res, next){
    var topStories = [];
    var fromStory = req.query.fromStory;
    var toStory = req.query.toStory;
    if(!fromStory){
        fromStory = 0;
    }

    if(!toStory){
        toStory = 100;
    }

    get(rootUrl + version + '/topstories.json')
    .map(function(res){
        return res[1];  // get the body
     })
    .map(function(res){
        return JSON.parse(res);     //turn it into a object
    })
    .flatMap(function(res) {
        return Rx.Observable.fromArray(res);    //map each of the story item ids into an observable
    })
    .skip(fromStory)
    .take(toStory)       //take the max
    .flatMap(function(res){
        return get(rootUrl + version + '/item/' + res + '.json');   // make the details call on each response
    })
    .map(function(res){
        return res[1];  // get the body
     })
    .map(function(res){
        return JSON.parse(res);     //turn it into a object
    })
    .subscribe(
            function (x) {
                topStories[topStories.length] = x;
            },
            function (err) {
                console.log('Error:  ' + err);
            },
            function () {
                res.send(topStories);
            }
    );
}

/*var server = restify.createServer({
  name: 'myapp',
  version: '1.0.0'
});
server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());*/

function getComments(parentStoryID, arr, startDepth, endDepth){
	// request parent story
	// grab 'kids' field from parent story response
	// the field from part 2 contains depth 0 comments
	// for each kid, request the item and recurse as far as endDepth param specifies
	return getItemKids(parentStoryID)
		.flatMap(function(item){
			return getItem(item)
		})
		.flatMap(function(item){
			if (!arr[item.id])
				arr[item.id]=item
			return getComments(item.id, arr, startDepth, endDepth)
		})
}

function getItemKids(itemID){
	return getItem(itemID)
			.map(function(parsedJSON){
				var kids = parsedJSON['kids']
				return (kids) ? kids : []
			})
			.flatMap(function(kids){
				return Rx.Observable.fromArray(kids)
			})
}

function getItem(itemID){
	return get(rootUrl+version+'/item/'+itemID+'.json')
		.map(function(res){
			return res[1]
		})
		.map(function(rawJSON){
			return JSON.parse(rawJSON)
		})
}
var arr = []
getComments('8863', arr, 0, 2)
    .subscribe(
    	function(onNextValue){

    	},
    	function(error){
    		console.log("Error: "+error)
    	},
    	function(){
    		console.log("Complete")
    		var unsparseArray = []
    		arr.map(function(validItem){
    			unsparseArray[unsparseArray.length]=validItem
    		})
    		console.log("unsparseArray Length: " + unsparseArray.length)
    	}
    )
//server.get('/getTopStories', getTopStories);
//var port = process.env.PORT || 5000;
//server.listen(port, function () {
//  console.log('%s listening at %s', server.name, server.url);
//});
<|endoftext|>


<commit_before>var fs = require('fs'),
    path = require('path'),
    express = require('express'),
    passport = require('passport'),
    async = require('async'),
    marked = require('marked');

/**
 * Loads in the configuration then extends and updates it based on the view
 * and application overrides.d
 * @private
 */
var configure = function(config) {
  // load and extend the various config files
  this.config = require(__dirname + '/config');

  var appConfig = path.resolve('./config.json');
  if(fs.existsSync(appConfig)) {
    this.config = this.util.extend(this.config, require(appConfig));
  }

  this.config = this.util.extend(this.config, (config || {}));

  // base application path
  this.config.__path = process.cwd();

  if(!this.config.view.hasOwnProperty('module')) {
    throw 'No view layer found.';
  }

  this.config.view.path = __dirname +
    '/node_modules/' + this.config.view.module;

  this.config.view = this.util.extend(
    this.config.view,
    require(this.config.view.module)(this)
  );
};

/**
 * Initializes the server.
 * @private
 */
var initialize = function() {
  // load the express extentions/shims
  require('./lib/express_ext')(this.app);

  this.app.use(require('static-favicon')(this.config.favicon));

  // load some required/common middleware
  this.app.use(require('body-parser')());
  this.app.use(passport.initialize());

  // set up the view configuration
  var view = this.config.view;
  this.app.use(express.static('./public'));             // application
  this.app.use(express.static(view.path + '/public')); // theme

  this.app.engine(view.ext, view.engine);
  this.app.set('view engine', view.ext);
  this.app.set('views', [
    './views',             // application
    view.path + '/views', // theme
  ]);

  // set up passport to use basic auth
  var BasicStrategy = require('passport-http').BasicStrategy;

  passport.use(new BasicStrategy(
    function(username, password, done) {
      done(null, (username === this.username && password === this.password));
    }.bind(this.config.authentication)
  ));

  // convenience for passport digest authentication
  this.restrict = passport.authenticate('basic', {session:false});
};

/**
 * Scroll Core Class
 * @class
 * @name Scroll
 * @param [config] {object} - base configuration for the Scroll server.
 */
var Scroll = function(config) {
  // utilities
  this.util = require('./lib/util');

  // express applicaiton
  this.app = express();

  // convenience access to the router object
  this.Router = express.Router;

  // a few proxies for convenience
  this.post = this.app.post.bind(this.app);
  this.put = this.app.put.bind(this.app);
  this.delete = this.app.delete.bind(this.app);
  this.use = this.app.use.bind(this.app);
  this.locals = this.app.locals;

  // set up a few options
  if(typeof config === 'object') {
    // set up the scroll body parsing
    this.parse = config.parse || this.parse;
  }

  // configure the applicaiton
  configure.call(this, config);

  // loads the controllers
  this.controllers = require('./controllers/controllers')(this);

  // initialize the server
  initialize.call(this);
};

/**
 * Convenience function to add a GET route to the server, which binds the
 * handler to the server and checks for a view override.
 * @memberof Scroll
 * @param route {string} - The route definition.
 * @param [middleware] {mixed} - The express-compatible middleware to use
 * with the route.
 * @param handler {function(req, res)} - The handler for the route.
 * @param [view] {string} - The view used for the route. Used to allow
 * views and applications to override the route handler.
 */
Scroll.prototype.get = function(route, middleware, handler, view) {
  var hasMiddleware = false;

  // if a middleware and a handler is provided
  if(typeof middleware === 'function' && typeof handler === 'function') {
    hasMiddleware = true;
  }

  // if only a route and handler were provided
  if(typeof middleware === 'function' && typeof handler === 'undefined') {
    handler = middleware;
  }

  // if a handler and a view is provided
  if(typeof middleware === 'function' && typeof handler === 'string') {
    view = handler;
    handler = middleware;
  }

  // check if the handler for the view has been overridden
  if(view && this.config.view.views.hasOwnProperty(view)) {
    // allows the configuration to prevent adding a view-based route
    if(this.config.view.views[view].override) {
      return;
    }

    handler = this.config.view.views[view].handler || handler;
  }

  handler = handler.bind(this);

  if(hasMiddleware) {
    this.app.get(route, middleware, handler);
  } else {
    this.app.get(route, handler);
  }
};

/**
 * Loads and returns a plugin
 * @memberof Scroll
 * @param name {string} - The node module name of the plugin to load.
 */
Scroll.prototype.plugin = function(name) {
  return require(name)(this);
};

/**
 * Parses a scroll's content. Defaults to markdown parsing.
 * @param content {string} - The text to parse.
 */
Scroll.prototype.parse = function(scroll) {
  scroll.raw = scroll.body;
  scroll.body = marked(scroll.body);

  return scroll;
};

/**
 * Helper that renders a view, but passes the view config along with the
 * base data to the view.
 * @param res {object} - The response object from the route handler.
 * @param view {string} - The name of the view to render.
 * @param data {object} - The data to pass along with the view configuration.
 */
Scroll.prototype.render = function(res, view, data) {
  var config = this.config.view.views[view];
  res.render(config.view, this.util.extend(config, data));
};

/**
 * Starts the Scroll server.
 * @memberof Scroll
 * @param port - The port the server should listen on.
 * @param callback {startCallback} - Callback called when the server has
 * started.
 */
Scroll.prototype.start = function(port, callback) {
  // add the server routes
  require('./routes/routes')(this);

  this.app.listen(port, null, null, function() {
    console.log('Scroll Server listening on port %s', port);

    if(typeof callback === 'function') {
      callback();
    }
  });
};

/**
 * Scroll factory
 * @param [config] {object} - Configuration based to the scroll server
 * created.
 */
module.exports = function(config) {
  return new Scroll(config);
};
<commit_msg>Added a proxy to view configuration via app.view.<commit_after>var fs = require('fs'),
    path = require('path'),
    express = require('express'),
    passport = require('passport'),
    async = require('async'),
    marked = require('marked');

/**
 * Loads in the configuration then extends and updates it based on the view
 * and application overrides.d
 * @private
 */
var configure = function(config) {
  // load and extend the various config files
  this.config = require(__dirname + '/config');

  var appConfig = path.resolve('./config.json');
  if(fs.existsSync(appConfig)) {
    this.config = this.util.extend(this.config, require(appConfig));
  }

  this.config = this.util.extend(this.config, (config || {}));

  // base application path
  this.config.__path = process.cwd();

  if(!this.config.view.hasOwnProperty('module')) {
    throw 'No view layer found.';
  }

  this.config.view.path = __dirname +
    '/node_modules/' + this.config.view.module;

  this.config.view = app.view = this.util.extend(
    this.config.view,
    require(this.config.view.module)(this)
  );
};

/**
 * Initializes the server.
 * @private
 */
var initialize = function() {
  // load the express extentions/shims
  require('./lib/express_ext')(this.app);

  this.app.use(require('static-favicon')(this.config.favicon));

  // load some required/common middleware
  this.app.use(require('body-parser')());
  this.app.use(passport.initialize());

  // set up the view configuration
  var view = this.config.view;
  this.app.use(express.static('./public'));             // application
  this.app.use(express.static(view.path + '/public')); // theme

  this.app.engine(view.ext, view.engine);
  this.app.set('view engine', view.ext);
  this.app.set('views', [
    './views',             // application
    view.path + '/views', // theme
  ]);

  // set up passport to use basic auth
  var BasicStrategy = require('passport-http').BasicStrategy;

  passport.use(new BasicStrategy(
    function(username, password, done) {
      done(null, (username === this.username && password === this.password));
    }.bind(this.config.authentication)
  ));

  // convenience for passport digest authentication
  this.restrict = passport.authenticate('basic', {session:false});
};

/**
 * Scroll Core Class
 * @class
 * @name Scroll
 * @param [config] {object} - base configuration for the Scroll server.
 */
var Scroll = function(config) {
  // utilities
  this.util = require('./lib/util');

  // express applicaiton
  this.app = express();

  // convenience access to the router object
  this.Router = express.Router;

  // a few proxies for convenience
  this.post = this.app.post.bind(this.app);
  this.put = this.app.put.bind(this.app);
  this.delete = this.app.delete.bind(this.app);
  this.use = this.app.use.bind(this.app);
  this.locals = this.app.locals;

  // set up a few options
  if(typeof config === 'object') {
    // set up the scroll body parsing
    this.parse = config.parse || this.parse;
  }

  // configure the applicaiton
  configure.call(this, config);

  // loads the controllers
  this.controllers = require('./controllers/controllers')(this);

  // initialize the server
  initialize.call(this);
};

/**
 * Convenience function to add a GET route to the server, which binds the
 * handler to the server and checks for a view override.
 * @memberof Scroll
 * @param route {string} - The route definition.
 * @param [middleware] {mixed} - The express-compatible middleware to use
 * with the route.
 * @param handler {function(req, res)} - The handler for the route.
 * @param [view] {string} - The view used for the route. Used to allow
 * views and applications to override the route handler.
 */
Scroll.prototype.get = function(route, middleware, handler, view) {
  var hasMiddleware = false;

  // if a middleware and a handler is provided
  if(typeof middleware === 'function' && typeof handler === 'function') {
    hasMiddleware = true;
  }

  // if only a route and handler were provided
  if(typeof middleware === 'function' && typeof handler === 'undefined') {
    handler = middleware;
  }

  // if a handler and a view is provided
  if(typeof middleware === 'function' && typeof handler === 'string') {
    view = handler;
    handler = middleware;
  }

  // check if the handler for the view has been overridden
  if(view && this.config.view.views.hasOwnProperty(view)) {
    // allows the configuration to prevent adding a view-based route
    if(this.config.view.views[view].override) {
      return;
    }

    handler = this.config.view.views[view].handler || handler;
  }

  handler = handler.bind(this);

  if(hasMiddleware) {
    this.app.get(route, middleware, handler);
  } else {
    this.app.get(route, handler);
  }
};

/**
 * Loads and returns a plugin
 * @memberof Scroll
 * @param name {string} - The node module name of the plugin to load.
 */
Scroll.prototype.plugin = function(name) {
  return require(name)(this);
};

/**
 * Parses a scroll's content. Defaults to markdown parsing.
 * @param content {string} - The text to parse.
 */
Scroll.prototype.parse = function(scroll) {
  scroll.raw = scroll.body;
  scroll.body = marked(scroll.body);

  return scroll;
};

/**
 * Helper that renders a view, but passes the view config along with the
 * base data to the view.
 * @param res {object} - The response object from the route handler.
 * @param view {string} - The name of the view to render.
 * @param data {object} - The data to pass along with the view configuration.
 */
Scroll.prototype.render = function(res, view, data) {
  var config = this.config.view.views[view];
  res.render(config.view, this.util.extend(config, data));
};

/**
 * Starts the Scroll server.
 * @memberof Scroll
 * @param port - The port the server should listen on.
 * @param callback {startCallback} - Callback called when the server has
 * started.
 */
Scroll.prototype.start = function(port, callback) {
  // add the server routes
  require('./routes/routes')(this);

  this.app.listen(port, null, null, function() {
    console.log('Scroll Server listening on port %s', port);

    if(typeof callback === 'function') {
      callback();
    }
  });
};

/**
 * Scroll factory
 * @param [config] {object} - Configuration based to the scroll server
 * created.
 */
module.exports = function(config) {
  return new Scroll(config);
};
<|endoftext|>