<commit_before>"use strict";

//
// app.js
// Server-side code for the black Highlighter demo sandbox 
// Copyright (C) 2012-2014 HostileFork.com
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//   See http://blackhighlighter.hostilefork.com for documentation.
//



//
// UTILITY LIBRARIES
//

// Underscore contains common JavaScript helpers like you might find in a
// library like jQuery (forEach, isString, etc)...but without being tied
// into the presumption that you are running in a browser with a DOM, etc.
//
// http://documentcloud.github.com/underscore/
var _ = require('underscore')._;



// 
// BASIC HTTP SETUP
//
// The Virtual Cloud tells us our port and host, but if we are running
// locally we default to localhost and port 8080 (used by nodejitsu).
//

// JavaScriptOR (||) variable assignment:
// http://stackoverflow.com/questions/2100758/
var port = (process.env.PORT || 3000);
var host = (process.env.HOST || 'localhost');
var http = require('http');



//
// ERROR HANDLING
//
// Node is unusual because if its single-threaded-server crashes in any given
// handler, it will take down the whole server process.  A general error
// handling strategy is needed.  How do we deal with exceptions that are thrown
// on invalid inputs from the client, vs. internal errors.
//
// http://stackoverflow.com/questions/5816436/
//
// For now just strings, but we want the stack trace in there too
//
// http://www.devthought.com/2011/12/22/a-string-is-not-an-error/
//
// See note here about how arguments.callee is not to be used in strict mode:
//
// https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
//
function resSendJsonForErr(res, err) {

	if (!err) {
		// Legacy from Step; changing to not call this when there is no error
		throw Error("resSendJsonForErr called without an error parameter");
	} 

	if (err instanceof Error) {
		console.error(err.stack);
	} else {
		console.warn("Non-error subclass thrown, bad style...");
	}

	if (err instanceof blackhighlighter.ClientError) {
		console.error(err.message);
		res.json(400, { error: err.toString() });
	} else {
		res.json(500, { error: err.toString() });
	}
}


//
// EXPRESS AND SWIG SETUP
//
// Express is a layer which provides things like URL redirects and content 
// negotiation for the web ( http://expressjs.com/ ).  It does not prescribe
// any particular "templating engine", which lets you author web content as a
// hybrid of boilerplate with dynamic portions weaved in from code.  For that
// I use Swig ( http://paularmstrong.github.com/swig/ ).
//
// I chose Express because it seemed like the de facto standard.  I chose Swig
// because I was originally porting Blackhighlighter from Django, which Swig
// was designed to be (mostly) compatible with--due to shared philosophy:
//
// https://docs.djangoproject.com/en/dev/topics/templates/
//
// Swig also fares well in terms of metrics when compared with the competition
// (but do note this table was made by Swig's author):
//
// http://paularmstrong.github.io/node-templates/
//
// To get Swig integrated with Express I referred to this sample code:
//
// https://github.com/paularmstrong/swig/blob/master/examples/express/server.js
//

var express = require('express');
var app = express();
var swig = require('swig');

// Register the template engine
app.engine('html', swig.renderFile);
app.set('view engine', 'html');
app.set('views', __dirname + '/views');

// Initialize Swig default options, for full list of options see:
//     http://paularmstrong.github.io/swig/docs/api/#SwigOpts
swig.setDefaults({
	loader: swig.loaders.fs(__dirname + '/views'),

	// TURN CACHE BACK ON in deployment environments...
	cache: false
});

// Load custom template tags
//     http://paularmstrong.github.io/swig/docs/api/#setTag
//     http://paularmstrong.github.io/swig/docs/extending/#tags
var mytags = require('./mytags');
swig.setTag(
	'url'
	, mytags.url.parse
	, mytags.url.compile
	, mytags.url.ends
);
swig.setTag(
	'comment'
	, mytags.comment.parse
	, mytags.comment.compile
	, mytags.comment.ends
);


// These are provided to every template context by default
app.locals.LIBS_URL = '/public/js/';
app.locals.BLACKHIGHLIGHTER_MEDIA_URL = '/public/';
app.locals.PROJECT_MEDIA_URL = '/public/';
app.locals.NODE_VERSION = process.version;

// optionals, set in your environment somewhere...
/* app.locals.HOSTING_SERVICE: "string"; */

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

app.configure('production', function() {
	app.use(express.errorHandler());
	
	// Express is already set to cache templates in production, apparently
	// https://github.com/kof/node-jqtpl/pull/34
	// app.set('view cache', true);
});

// We need the "bodyParser" middleware to get the various fields out of form
// data passed to us in HTTP post requests
//    http://stackoverflow.com/a/5710916/211160
app.use(express.bodyParser());



//
// BLACKHIGHLIGHTER COMPONENT
//
// The Black Highlighter logic for doing commits, reveals, and storing<commit_msg>Kill app.configure (also deprecated in Express 4.x)<commit_after>"use strict";

//
// app.js
// Server-side code for the black Highlighter demo sandbox 
// Copyright (C) 2012-2014 HostileFork.com
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//   See http://blackhighlighter.hostilefork.com for documentation.
//



//
// UTILITY LIBRARIES
//

// Underscore contains common JavaScript helpers like you might find in a
// library like jQuery (forEach, isString, etc)...but without being tied
// into the presumption that you are running in a browser with a DOM, etc.
//
// http://documentcloud.github.com/underscore/
var _ = require('underscore')._;



// 
// BASIC HTTP SETUP
//
// The Virtual Cloud tells us our port and host, but if we are running
// locally we default to localhost and port 8080 (used by nodejitsu).
//

// JavaScriptOR (||) variable assignment:
// http://stackoverflow.com/questions/2100758/
var port = (process.env.PORT || 3000);
var host = (process.env.HOST || 'localhost');
var http = require('http');



//
// ERROR HANDLING
//
// Node is unusual because if its single-threaded-server crashes in any given
// handler, it will take down the whole server process.  A general error
// handling strategy is needed.  How do we deal with exceptions that are thrown
// on invalid inputs from the client, vs. internal errors.
//
// http://stackoverflow.com/questions/5816436/
//
// For now just strings, but we want the stack trace in there too
//
// http://www.devthought.com/2011/12/22/a-string-is-not-an-error/
//
// See note here about how arguments.callee is not to be used in strict mode:
//
// https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
//
function resSendJsonForErr(res, err) {

	if (!err) {
		// Legacy from Step; changing to not call this when there is no error
		throw Error("resSendJsonForErr called without an error parameter");
	} 

	if (err instanceof Error) {
		console.error(err.stack);
	} else {
		console.warn("Non-error subclass thrown, bad style...");
	}

	if (err instanceof blackhighlighter.ClientError) {
		console.error(err.message);
		res.json(400, { error: err.toString() });
	} else {
		res.json(500, { error: err.toString() });
	}
}


//
// EXPRESS AND SWIG SETUP
//
// Express is a layer which provides things like URL redirects and content 
// negotiation for the web ( http://expressjs.com/ ).  It does not prescribe
// any particular "templating engine", which lets you author web content as a
// hybrid of boilerplate with dynamic portions weaved in from code.  For that
// I use Swig ( http://paularmstrong.github.com/swig/ ).
//
// I chose Express because it seemed like the de facto standard.  I chose Swig
// because I was originally porting Blackhighlighter from Django, which Swig
// was designed to be (mostly) compatible with--due to shared philosophy:
//
// https://docs.djangoproject.com/en/dev/topics/templates/
//
// Swig also fares well in terms of metrics when compared with the competition
// (but do note this table was made by Swig's author):
//
// http://paularmstrong.github.io/node-templates/
//
// To get Swig integrated with Express I referred to this sample code:
//
// https://github.com/paularmstrong/swig/blob/master/examples/express/server.js
//

var express = require('express');
var app = express();
var swig = require('swig');

// Register the template engine
app.engine('html', swig.renderFile);
app.set('view engine', 'html');
app.set('views', __dirname + '/views');

// Initialize Swig default options, for full list of options see:
//     http://paularmstrong.github.io/swig/docs/api/#SwigOpts
swig.setDefaults({
	loader: swig.loaders.fs(__dirname + '/views'),

	// TURN CACHE BACK ON in deployment environments...
	cache: false
});

// Load custom template tags
//     http://paularmstrong.github.io/swig/docs/api/#setTag
//     http://paularmstrong.github.io/swig/docs/extending/#tags
var mytags = require('./mytags');
swig.setTag(
	'url'
	, mytags.url.parse
	, mytags.url.compile
	, mytags.url.ends
);
swig.setTag(
	'comment'
	, mytags.comment.parse
	, mytags.comment.compile
	, mytags.comment.ends
);


// These are provided to every template context by default
app.locals.LIBS_URL = '/public/js/';
app.locals.BLACKHIGHLIGHTER_MEDIA_URL = '/public/';
app.locals.PROJECT_MEDIA_URL = '/public/';
app.locals.NODE_VERSION = process.version;

// optionals, set in your environment somewhere...
/* app.locals.HOSTING_SERVICE: "string"; */


// We need the "bodyParser" middleware to get the various fields out of form
// data passed to us in HTTP post requests
//    http://stackoverflow.com/a/5710916/211160
app.use(express.bodyParser());



//
// BLACKHIGHLIGHTER COMPONENT
//
// The Black Highlighter logic for doing commits, reveals, and storing
{'fraction_non_alphanumeric': 0.12689804772234273, 'fraction_numerical': 0.010936370209689081, 'mean_word_length': 3.4118819776714515, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 7, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6102621', 'n_tokens_mistral': 3475, 'n_tokens_neox': 3278, 'n_words': 1183}