|
/*jslint node:true,esnext:true*/ |
|
"use strict"; |
|
var needle = require('needle'), |
|
redis = require('redis'), |
|
moment = require('moment'), |
|
ws = require('ws'), |
|
net = require('net'); |
|
|
|
console.log('~ buttond v2.5 by η (eeeeeta) ~'); |
|
console.log('INIT: Requesting http://reddit.com/r/thebutton'); |
|
needle.get('http://reddit.com/r/thebutton', {follow: 5}, function(err, res) { |
|
if (err) { |
|
console.error('ERROR: Failed to get thebutton html'); |
|
throw err; |
|
} |
|
if (res.statusCode != 200) { |
|
console.error('ERROR: Got code ' + res.statusCode + ' instead of 200'); |
|
return; |
|
} |
|
let addrRegexp = /"thebutton_websocket": "([^\,]+)",/i; |
|
if (!res.body.match(addrRegexp)) { |
|
console.error('ERROR: Failed to retrieve thebutton websocket URL'); |
|
return; |
|
} |
|
let URL = res.body.match(addrRegexp)[1]; |
|
console.log('INIT: got button websocket URL as ' + URL); |
|
console.log('INIT: connecting to redis (on localhost)'); |
|
var rd = redis.createClient(); |
|
rd.on('ready', function() { |
|
console.log('INIT: redis connection successful'); |
|
console.log('INIT: getting record from redis'); |
|
var record = 60; |
|
rd.get('record', function(err, rec) { |
|
if (err) throw err; |
|
if (!rec) { |
|
rd.set('record', record); |
|
console.log('INIT: no record set, set it to 60'); |
|
} |
|
else { |
|
record = Number(rec); |
|
console.log('INIT: got record of ' + record); |
|
} |
|
console.log('INIT: connecting to thebutton websocket'); |
|
var btn = new ws(URL); |
|
var cur = 60; |
|
var verbose = false; |
|
var lagms = 0; |
|
var microtime = false; |
|
var participants = 'error'; |
|
btn.on('open', function() { |
|
console.log('INIT: connected to thebutton websocket'); |
|
var tid = setTimeout(function() { |
|
console.error('ERROR: no message from thebutton since 5 seconds'); |
|
process.exit(1); |
|
}, 5000); |
|
btn.on('message', function(data) { |
|
clearTimeout(tid); |
|
tid = setTimeout(function() { |
|
console.error('ERROR: no message from thebutton since 5 seconds'); |
|
process.exit(1); |
|
}, 5000); |
|
data = JSON.parse(data); |
|
if (data.type != 'ticking') { |
|
console.log('Unidentified socket object: '); |
|
return console.dir(data); |
|
} |
|
let servertime = moment(data.payload.now_str + " 0000", "YYYY-MM-DD-HH-mm-ss Z"); // shameless ripoff from the button monitor |
|
lagms = moment() - servertime; |
|
if (verbose) console.log('[V] Server lag: ' + lagms + 'ms'); |
|
if (data.payload.seconds_left > cur || (cur == 60 && data.payload.seconds_left == 60)) { |
|
// it's a click! |
|
if (verbose) console.log('[V] Click at ' + cur + 's (' + data.payload.participants_text + ' participants)'); |
|
rd.publish('thebutton.clicks', cur); |
|
rd.hset('clicks', data.payload.participants_text, cur, function(err, reply) { |
|
if (err) { |
|
return console.warn('WARNING: failed to update database with click'); |
|
} |
|
}); |
|
} |
|
rd.publish('thebutton.ticks', data.payload.seconds_left); |
|
cur = data.payload.seconds_left; |
|
participants = data.payload.participants_text; |
|
if (data.payload.seconds_left < record) { |
|
record = data.payload.seconds_left; |
|
rd.publish('thebutton.records', record); |
|
rd.set('record', record, function(err, reply) { |
|
if (err) throw err; |
|
if (reply != 'OK') { |
|
return console.error('ERROR: got reply ' + reply + ' instead of "OK" setting new record'); |
|
} |
|
console.log('[!] Set new button record: ' + data.payload.seconds_left + 's'); |
|
}); |
|
rd.hset('rectimes', record, servertime.unix(), function(err, reply) { |
|
if (err) throw err; |
|
console.log('[+] First ' + record + 's: ' + servertime.format("dddd, MMMM Do YYYY, h:mm:ss a")); |
|
}); |
|
} |
|
}); |
|
process.on('SIGUSR2', function() { |
|
verbose = !verbose; |
|
console.log('[+] Verbose mode ' + (verbose ? 'enabled' : 'disabled')); |
|
}); |
|
net.createServer(function(sock) { |
|
console.log('[+] server connection from ' + sock.remoteAddress + ':' + sock.remotePort); |
|
sock.write('\n\nbuttond v2 by η (eeeeeta)\n'); |
|
sock.write('\nCurrent record: ' + record + 's'); |
|
sock.write('\nSeconds left: ' + cur + 's'); |
|
sock.write('\nParticipants: ' + participants + ' filthy pressers'); |
|
sock.write('\n\nHave a good day.\n\n'); |
|
sock.end(); |
|
}).listen(5432); |
|
console.log('INIT: server listening on port 5432'); |
|
console.log('Tip: send me a SIGUSR2 to enable verbose mode'); |
|
console.log('~ buttond ready ~'); |
|
}); |
|
}); |
|
}); |
|
}); |