-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
122 lines (109 loc) · 3.57 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
var async = require("async");
var http = require("http");
var fs = require("fs");
var util = require("util");
var path = require("path");
//var url = require("url");
var dust = require("dustjs-linkedin");
var p = util.log;
String.prototype.toSanitizedArray = function() {
return this
.split("\n")
.map(Function.prototype.call, String.prototype.trim)
.filter(function(item) {
return item.length && ! /^#/.test(item);
});
};
var excuses = {};
var lastexcuses = [];
var maxlastexcuses = 5;
// Picks a random excuse, avoiding the most recent 5 picked.
function randomExcuse() {
while ( lastexcuses.length >= maxlastexcuses ) {
lastexcuses.shift();
}
var rand = Math.floor(Math.random() * ( Object.keys(excuses).length - Object.keys(lastexcuses).length));
var counter = 0;
var key;
for (key in excuses) {
if ( lastexcuses.indexOf(key) < 0 && counter++ === rand ) {
break;
}
}
lastexcuses.push(key);
return excuses[key];
}
function coerceAndThrow(error) {
if ( ! error instanceof Error ) {
error = new Error(error);
}
throw error;
}
function maybeError (cb) {
return function(error) { // ...and an arbitrary number of other args.
if ( error instanceof Error || ( arguments.length === 1 && error) ) {
coerceAndThrow(error);
}
cb.apply(null, Array.prototype.slice.call(arguments, 1));
};
}
function parseShellScript() {
var canned = [];
fs.readFileSync("programmingexcuses.sh/programmingexcuses", "utf8")
.toSanitizedArray()
.forEach(function(item, index, array) {
if ( ! canned.length ) {
item = item.replace(/^\s*echo\s*["]/, "");
} else if ( index === array.length - 1 ) {
item = item.replace(/["]\s*[|].*$/, "");
}
canned.push(item);
});
fs.appendFileSync("sources/excuses1.txt", canned.sort().join("\n"));
}
function refreshExcuses() {
p("Refreshing excuses.");
async.waterfall([
function(cb) {
fs.readdir("sources", cb);
},
function(result, cb) {
async.map(result, function(item, cb) {
var fullpath = path.join("sources", item);
async.waterfall([
function(cb) { fs.stat(fullpath, cb); },
function(stat, cb) {
if ( stat.isFile() ) {
fs.readFile(fullpath, "utf8", cb);
}
}
], cb);
}, cb);
}
], maybeError(function(result) {
tempexcuses = {};
result.forEach(function(item) {
item.toSanitizedArray().forEach(function(item) {
tempexcuses[item.toUpperCase()] = item;
});
});
excuses = tempexcuses;
p("Refreshed excuses");
}));
}
var watcher = fs.watch("sources", { persistent: true, recursive: true });
watcher.on("error", coerceAndThrow);
watcher.on("change", refreshExcuses);
p("Installed watcher on sources directory");
parseShellScript();
p("Generated excuse source from programmingexcuses.sh");
dust.loadSource(dust.compile(fs.readFileSync("excuse.dust", "utf8"), "excuse"));
p("Compiled templates");
http.createServer(function(request, response) {
response.writeHead(200);
dust.render("excuse", { excuse: randomExcuse() }, maybeError(function(rendered) {
response.end(rendered);
}));
}).listen(8081, function(){
p("Server listening on: http://localhost:%s", 8081);
});