You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
doushio/curfew/server.js

134 lines
3.7 KiB

var _ = require('../lib/underscore'),
caps = require('../server/caps'),
config = require('../config'),
db = require('../db'),
hooks = require('../hooks'),
web = require('../server/web'),
winston = require('winston');
var RES = require('../server/state').resources;
hooks.hook_sync('temporalAccessCheck', function (info) {
if (under_curfew(info.ident, info.board))
info.access = false;
});
hooks.hook_sync('boardDiversion', function (info) {
if (info.diverted)
return;
if (under_curfew(info.ident, info.board)) {
info.diverted = true;
var resp = info.resp;
resp.writeHead(200, web.noCacheHeaders);
resp.write(RES.curfewTmpl[0]);
resp.write('/' + info.board + '/');
resp.write(RES.curfewTmpl[1]);
var ending = curfew_ending_time(info.board);
resp.write(ending ? ''+ending.getTime() : 'null');
resp.end(RES.curfewTmpl[2]);
}
});
function under_curfew(ident, board) {
if (caps.can_administrate(ident))
return false;
var curfew = config.CURFEW_HOURS;
if (!curfew || (config.CURFEW_BOARDS || []).indexOf(board) < 0)
return false;
var hour = new Date().getUTCHours();
return curfew.indexOf(hour) < 0;
}
function curfew_ending_time(board) {
var curfew = config.CURFEW_HOURS;
if (!curfew || (config.CURFEW_BOARDS || []).indexOf(board) < 0)
return null;
var now = new Date();
var tomorrow = day_after(now);
var makeToday = hour_date_maker(now);
var makeTomorrow = hour_date_maker(tomorrow);
/* Dumb brute-force algorithm */
var candidates = [];
config.CURFEW_HOURS.forEach(function (hour) {
candidates.push(makeToday(hour), makeTomorrow(hour));
});
candidates.sort(compare_dates);
for (var i = 0; i < candidates.length; i++)
if (candidates[i] > now)
return candidates[i];
return null;
}
function curfew_starting_time(board) {
var curfew = config.CURFEW_HOURS;
if (!curfew || (config.CURFEW_BOARDS || []).indexOf(board) < 0)
return null;
var now = new Date();
var tomorrow = day_after(now);
var makeToday = hour_date_maker(now);
var makeTomorrow = hour_date_maker(tomorrow);
/* Even dumber brute-force algorithm */
var candidates = [];
config.CURFEW_HOURS.forEach(function (hour) {
hour = (hour + 1) % 24;
if (config.CURFEW_HOURS.indexOf(hour) < 0)
candidates.push(makeToday(hour), makeTomorrow(hour));
});
candidates.sort(compare_dates);
for (var i = 0; i < candidates.length; i++)
if (candidates[i] > now)
return candidates[i];
return null;
};
function compare_dates(a, b) {
return a.getTime() - b.getTime();
}
function day_after(today) {
/* Leap shenanigans? This is probably broken somehow. Yay dates. */
var tomorrow = new Date(today.getTime() + 24*3600*1000);
if (tomorrow.getUTCDate() == today.getUTCDate())
tomorrow = new Date(tomorrow.getTime() + 12*3600*1000);
return tomorrow;
}
function hour_date_maker(date) {
var prefix = date.getUTCFullYear() + '/' + (date.getUTCMonth()+1)
+ '/' + date.getUTCDate() + ' ';
return (function (hour) {
return new Date(prefix + hour + ':00:00 GMT');
});
}
/* DAEMON */
function shutdown(board, cb) {
var yaku = new db.Yakusoku(board, db.UPKEEP_IDENT);
yaku.teardown(board, function (err) {
yaku.disconnect();
cb(err);
});
}
function at_next_curfew_start(board, func) {
var when = curfew_starting_time(board);
winston.info('Next curfew for ' + board + ' at ' + when.toUTCString());
setTimeout(func, when.getTime() - Date.now());
}
function enforce(board) {
at_next_curfew_start(board, function () {
winston.info('Curfew ' + board + ' at ' +
new Date().toUTCString());
shutdown(board, function (err) {
if (err)
winston.error(err);
});
setTimeout(enforce.bind(null, board), 30 * 1000);
});
}
if (config.CURFEW_BOARDS && config.CURFEW_HOURS)
config.CURFEW_BOARDS.forEach(enforce);