<commit_before>/*
 * Copyright (C) 2014 <NAME>, <NAME>
 *
 * This file is part of SBHS-Timetable-Node.
 *
 * 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/>.
 */

/* the gnustomp-forkbomb style guide:
 * Single tabs for indentation
 * Single quotes for strings
 * Opening braces on the same line as the statement
 * Spaces around operators
 * Empty line after a function defenition
 */

var all_start = Date.now();
console.log('[core] Loading...');
/* Requires */
var http = require('http'),
	fs = require('fs'),
	jade = require('jade'),
	url = require('url'),
	db = require('./lib/database.js'),
	auth = require('./lib/auth.js'),
	apis = require('./lib/api.js'),
	config = require('./config.js'),
	request = require('request');

/* Variables */
var secret = config.secret,
	clientID = config.clientID,
	redirectURI = config.redirectURI,
	forcedETagUpdateCounter = 0,
	cachedBells = {},
	index_cache, ipv4server, ipv6server, unixserver;
sessions = {}; // global

console.log('[core] Initialised in in ' + (Date.now() - all_start) + 'ms');

require('./variables.js'); // set globals appropriate to status - dev (DEBUG = true) or release (DEBUG = false and GIT_RV set)
if (!RELEASE) {
	GIT_RV = fs.readFileSync('.git/refs/heads/master').toString().trim();
	var watcher = fs.watch('.git/refs/heads/master', { persistent: false }, function() {
		'use strict';
		GIT_RV = fs.readFileSync('.git/refs/heads/master').toString().trim();
	});
}
fs.writeFile('.reload', '0');
var reloadWatcher = fs.watch('.reload', { persistent: false }, function() {
	'use strict';
	if (process.platform !== 'win32') {
		console.log('[core] reloading...');
		process.kill(process.pid, 'SIGHUP');
	} else {
		console.log('[core] reload not supported on Windows');
	}
});

var jade_opts = {
	pretty: DEBUG,
	compileDebug: DEBUG
};

function serverError() {
	'use strict';
	return fs.createReadStream('static/500.html');
}

function compile_jade(path) {
	'use strict';
	try {
		var mopts = jade_opts;
		mopts.filename = path;
		return jade.compile(fs.readFileSync(path), mopts);
	} catch (e) {
		console.error('!!! Failed to compile jade "'+path+'"!!! Stack trace:');
		console.error(e.stack);
		return serverError;
	}
}

function cache_index() {
	'use strict';
	console.log('[core] Caching index page... (hangup to re-cache)');
	var jade_comp = Date.now();
	var idx = compile_jade('dynamic/index.jade');
	index_cache = idx({title: ''});
	if (index_cache == serverError) {
		console.warn('WARNING: Encountered an error while caching index page. Fix errors, and then hangup to reload.');
	}
	console.log('[core] Index page cached in ' + (Date.now() - jade_comp) + 'ms');
}

function cleanSessions() {
	'use strict';
	var start = Date.now(),
		cleaned = 0;
	console.log('[core] Cleaning sessions...');
	for (var i in global.sessions) {
		if (global.sessions[i].expires < Date.now()) {
			delete global.sessions[i];
			cleaned++;
		}
		else if (Object.keys(global.sessions[i]).length < 2) { // not storing anything in the session, so it's just eating memory.
			delete global.sessions[i];
			cleaned++;
		}
	}
	console.log('[core] Cleaned ' + cleaned + ' sessions in ' + Date.now()-start + 'ms');
}

process.on('SIGHUP', function() {
	'use strict';
	cache_index();
	cleanSessions();
});

process.on('SIGINT', function() {
	'use strict';
	unixserver.close(function() { global.unixDone = true; });
	ipv4server.close(function() { global.ipv4Done = true; });
	ipv6server.close(function() { global.ipv6Done = true; });
	fs.writeFileSync('sessions.json', JSON.stringify(global.sessions));
	console.log('Saved sessions.');
});


function httpHeaders(res, response, contentType, dynamic, headers) {
	'use strict';
	var date;
	dynamic = dynamic || false;
	headers = headers || {};
	if (!('Set-Cookie' in headers) && 'SESSID' in res) {
		headers['Set-Cookie'] = 'SESSID='+res.SESSID+'; Max-Age=36000';<commit_msg>Windows is an os too[citation needed]<commit_after>/*
 * Copyright (C) 2014 <NAME>, <NAME>
 *
 * This file is part of SBHS-Timetable-Node.
 *
 * 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/>.
 */

/* the gnustomp-forkbomb style guide:
 * Single tabs for indentation
 * Single quotes for strings
 * Opening braces on the same line as the statement
 * Spaces around operators
 * Empty line after a function defenition
 */

var all_start = Date.now();
console.log('[core] Loading...');
/* Requires */
var http = require('http'),
	fs = require('fs'),
	jade = require('jade'),
	url = require('url'),
	db = require('./lib/database.js'),
	auth = require('./lib/auth.js'),
	apis = require('./lib/api.js'),
	config = require('./config.js'),
	request = require('request');

/* Variables */
var secret = config.secret,
	clientID = config.clientID,
	redirectURI = config.redirectURI,
	forcedETagUpdateCounter = 0,
	cachedBells = {},
	index_cache, ipv4server, ipv6server, unixserver;
sessions = {}; // global

console.log('[core] Initialised in in ' + (Date.now() - all_start) + 'ms');

require('./variables.js'); // set globals appropriate to status - dev (DEBUG = true) or release (DEBUG = false and GIT_RV set)
if (!RELEASE) {
	GIT_RV = fs.readFileSync('.git/refs/heads/master').toString().trim();
	var watcher = fs.watch('.git/refs/heads/master', { persistent: false }, function() {
		'use strict';
		GIT_RV = fs.readFileSync('.git/refs/heads/master').toString().trim();
	});
}
fs.writeFile('.reload', '0');


var jade_opts = {
	pretty: DEBUG,
	compileDebug: DEBUG
};

function serverError() {
	'use strict';
	return fs.createReadStream('static/500.html');
}

function compile_jade(path) {
	'use strict';
	try {
		var mopts = jade_opts;
		mopts.filename = path;
		return jade.compile(fs.readFileSync(path), mopts);
	} catch (e) {
		console.error('!!! Failed to compile jade "'+path+'"!!! Stack trace:');
		console.error(e.stack);
		return serverError;
	}
}

function cache_index() {
	'use strict';
	console.log('[core] Caching index page... (hangup to re-cache)');
	var jade_comp = Date.now();
	var idx = compile_jade('dynamic/index.jade');
	index_cache = idx({title: ''});
	if (index_cache == serverError) {
		console.warn('WARNING: Encountered an error while caching index page. Fix errors, and then hangup to reload.');
	}
	console.log('[core] Index page cached in ' + (Date.now() - jade_comp) + 'ms');
}

function cleanSessions() {
	'use strict';
	var start = Date.now(),
		cleaned = 0;
	console.log('[core] Cleaning sessions...');
	for (var i in global.sessions) {
		if (global.sessions[i].expires < Date.now()) {
			delete global.sessions[i];
			cleaned++;
		}
		else if (Object.keys(global.sessions[i]).length < 2) { // not storing anything in the session, so it's just eating memory.
			delete global.sessions[i];
			cleaned++;
		}
	}
	console.log('[core] Cleaned ' + cleaned + ' sessions in ' + Date.now()-start + 'ms');
}

var reloadWatcher = fs.watch('.reload', { persistent: false }, function() {
	'use strict';
	cache_index();
	cleanSessions();
});

process.on('SIGHUP', function() {
	'use strict';
	cache_index();
	cleanSessions();
});

process.on('SIGINT', function() {
	'use strict';
	unixserver.close(function() { global.unixDone = true; });
	ipv4server.close(function() { global.ipv4Done = true; });
	ipv6server.close(function() { global.ipv6Done = true; });
	fs.writeFileSync('sessions.json', JSON.stringify(global.sessions));
	console.log('Saved sessions.');
});


function httpHeaders(res, response, contentType, dynamic, headers) {
	'use strict';
	var date;
	dynamic = dynamic || false;
	headers = headers || {};
	if (!('Set-Cookie' in headers) && 'SESSID' in res) {
		headers['Set-Cookie'] = 'SESSID='+res.SESSID+'; Max-Age=36000';
{'fraction_non_alphanumeric': 0.16195750452079566, 'fraction_numerical': 0.0054249547920434, 'mean_word_length': 4.217570754716981, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '3035975', 'n_tokens_mistral': 2974, 'n_tokens_neox': 2862, 'n_words': 844}