UNPKG

pomeloes-robot

Version:

A fully modernized pomelo-robot, upgraded with ES6+ and latest dependencies. Now supports standalone mode.

193 lines (171 loc) 5.86 kB
// ------------------------------------ // Statistics Manager // ------------------------------------ // // This file defines qputs, qprint, and extends the util namespace. // // Extends node.js util.js with other common functions. // var BUILD_AS_SINGLE_FILE; if (!BUILD_AS_SINGLE_FILE) { var util = require('util'); var EventEmitter = require('events').EventEmitter; } var fs = require('fs'); util.getPath = function() { var path = "./"; if (__filename.indexOf('node_modules')==-1) { path = __filename.substring(0,__filename.lastIndexOf('/')) + '/../../log'; } else { path = __filename.substring(0,__filename.lastIndexOf('node_modules')) + 'log'; } return path; }; util.createPath = function() { var path = util.getPath(); if (!require('fs').existsSync(path)) { fs.mkdirSync(path); } }; util.deleteLog = function() { var logPath = util.getPath(); var detailLog = logPath + '/detail'; var mainLog = logPath + '/.log'; // Safely delete logs by checking for existence before unlinking. // This prevents a crash if the logs don't exist (e.g., on first run). if (fs.existsSync(detailLog)) { fs.unlinkSync(detailLog); } if (fs.existsSync(mainLog)) { fs.unlinkSync(mainLog); } } // A few common global functions so we can access them with as few keystrokes as possible // var qputs = util.qputs = function(s) { console.log(s); }; var qprint = util.qprint = function(s) { util.print(s); }; // Static utility methods // util.uid = function() { exports.lastUid_ = exports.lastUid_ || 0; return exports.lastUid_++; }; util.defaults = function(obj, defaults) { for (var i in defaults) { if (obj[i] === undefined) { obj[i] = defaults[i]; } } return obj; }; util.extend = function(obj, extension) { for (var i in extension) { if (extension.hasOwnProperty(i)) { obj[i] = extension[i]; } } return obj; }; util.forEach = function(obj, f) { for (var i in obj) { if (obj.hasOwnProperty(i)) { f(i, obj[i]); } } }; util.every = function(obj, f) { for (var i in obj) { if (obj.hasOwnProperty(i)) { if (!f(i, obj[i])) { return false; } } } return true; }; util.argarray = function(args) { return Array.prototype.slice.call(args); }; util.readStream = function(stream, callback) { var data = []; stream.on('data', function(chunk) { data.push(chunk.toString()); }); stream.on('end', function() { callback(data.join('')); }); }; /** Make an object a PeriodicUpdater by adding PeriodicUpdater.call(this) to the constructor. The object will call this.update() every interval. */ util.PeriodicUpdater = function(updateIntervalMs) { var self = this, updateTimeoutId; this.__defineGetter__('updateInterval', function() { return updateIntervalMs; }); this.__defineSetter__('updateInterval', function(milliseconds) { clearInterval(updateTimeoutId); if (milliseconds > 0 && milliseconds < Infinity) { updateTimeoutId = setInterval(self.update.bind(self), milliseconds); } updateIntervalMs = milliseconds; }); this.updateInterval = updateIntervalMs; }; /** Same arguments as http.createClient. Returns an wrapped http.Client object that will reconnect when connection errors are detected. In the current implementation of http.Client (11/29/10), calls to request() fail silently after the initial 'error' event. */ util.createReconnectingClient = function() { var http = require('http'), clientArgs = arguments, events = {}, client, wrappedClient = {}, clientMethod = function(method) { return function() { return client[method].apply(client, arguments); }; }, clientGetter = function(member) { return function() { return client[member]; };}, clientSetter = function(member) { return function(val) { client[member] = val; };}, reconnect = function() { var oldclient = client; if (oldclient) { oldclient.destroy(); } client = http.createClient.apply(http, clientArgs); client._events = util.extend(events, client._events); // EventEmitter._events stores event handlers client.emit('reconnect', oldclient); }; // Create initial http.Client reconnect(); client.on('error', function(err) { reconnect(); }); // Wrap client so implementation can be swapped out when there are connection errors for (var j in client) { if (typeof client[j] === 'function') { wrappedClient[j] = clientMethod(j); } else { wrappedClient.__defineGetter__(j, clientGetter(j)); wrappedClient.__defineSetter__(j, clientSetter(j)); } } wrappedClient.impl = client; return wrappedClient; }; /** Accepts an EventEmitter object that emits text data. LineReader buffers the text and emits a 'data' event each time a newline is encountered. For example, */ util.LineReader = function(eventEmitter, event) { EventEmitter.call(this); event = event || 'data'; var self = this, buffer = ''; var emitLine = function(buffer) { var lineEnd = buffer.indexOf("\n"); var line = (lineEnd === -1) ? buffer : buffer.substring(0, lineEnd); if (line) { self.emit('data', line); } return buffer.substring(line.length + 1, buffer.length); }; var readloop = function(data) { if (data) { buffer += data.toString(); } if (buffer.indexOf("\n") > -1) { buffer = emitLine(buffer); process.nextTick(readloop.bind(this)); } }; eventEmitter.on(event, readloop.bind(this)); } util.inherits(util.LineReader, EventEmitter); util.extend(exports, util);