Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[api] Working channels synchronization.
- Loading branch information
Showing
9 changed files
with
366 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
var util = require('utile'); | ||
Channel = require('./irc/channel').Channel; | ||
|
||
exports.name = 'irc-channels'; | ||
|
||
exports.attach = function () { | ||
|
||
var self = this, | ||
irc = this.irc, | ||
channels = {}; | ||
|
||
irc.on('self::joined', join); | ||
irc.on('self::parted', part); | ||
|
||
this.channels = { | ||
join: join, | ||
part: part, | ||
synchronize: synchronize | ||
}; | ||
|
||
function join(data) { | ||
if (!channels[data.channel]) { | ||
channels[data.channel] = new Channel(data); | ||
} | ||
channels[data.channel].join(); | ||
} | ||
|
||
function part(data) { | ||
channels[data.channel].part(); | ||
} | ||
|
||
function synchronize(cb) { | ||
irc.channels(function (err, reply) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
|
||
var chans = reply.channels; | ||
|
||
Object.keys(chans).forEach(function (chan) { | ||
chans[chan].channel = chan; | ||
join(chans[chan]); | ||
}); | ||
cb(); | ||
}); | ||
}; | ||
|
||
this.hook.on('**::irc::connected', function (data) { | ||
if (data.type == 'irc') { | ||
self.channels.synchronize(function (err) { | ||
if (err) { | ||
self.emit('error', err); | ||
} | ||
}); | ||
} | ||
}); | ||
|
||
}; | ||
|
||
exports.init = function (done) { | ||
var self = this, | ||
hook = this.hook; | ||
|
||
hook.on('hook::ready', function () { | ||
self.channels.synchronize(done); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Flatiron plugin that adds a vanilla hook. | ||
exports.name = 'hook.io'; | ||
|
||
var Hook = require('hook.io').Hook; | ||
|
||
exports.attach = function attachHook (options) { | ||
this.hook = new Hook(options); | ||
}; | ||
|
||
exports.init = function initHook (done) { | ||
this.hook.on('hook::ready', function (data) { | ||
done(null); | ||
}); | ||
this.hook.start(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
exports.name = 'kohai-base'; | ||
|
||
var hook = require('./hook'), | ||
irc = require('./irc-hook'), | ||
channels = require('./channels'); | ||
|
||
exports.attach = function (opts) { | ||
this.use(hook, {}); | ||
this.use(irc, {}); | ||
this.use(channels, {}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
exports.name = 'irc-hooks'; | ||
|
||
var util = require('utile'), | ||
EventEmitter2 = require('eventemitter2').EventEmitter2; | ||
|
||
// Core irc management functionality. Basically unpacks the api. | ||
var IRC = exports.IRC = function (hook) { | ||
EventEmitter2.call(this, { | ||
wildcard: true, | ||
delimiter: '::' | ||
}); | ||
|
||
this.hook = hook; | ||
|
||
this.hook.on('**::irc::joined', function (data) { | ||
if (data.nick) { | ||
this.emit('joined', data); | ||
} | ||
else { | ||
this.emit('self::joined', data); | ||
} | ||
}); | ||
|
||
this.hook.on('**::irc::parted', function (data) { | ||
if (data.nick) { | ||
this.emit('parted', data); | ||
} | ||
else { | ||
this.emit('self::parted', data); | ||
} | ||
}); | ||
}; | ||
util.inherits(IRC, EventEmitter2); | ||
|
||
IRC.prototype.join = function (channel) { | ||
this.hook.emit('irc::join', channel); | ||
}; | ||
|
||
IRC.prototype.part = function (channel) { | ||
this.hook.emit('irc::part', channel); | ||
}; | ||
|
||
IRC.prototype.say = function (to, msg) { | ||
this.hook.emit('irc::say', { | ||
to: to, | ||
msg: msg | ||
}); | ||
}; | ||
|
||
IRC.prototype.channels = function (cb) { | ||
try { | ||
this.hook.emit('irc::channels', {}, function (channels) { | ||
cb(null, channels); | ||
}); | ||
} | ||
catch (err) { | ||
cb(err); | ||
} | ||
}; | ||
|
||
// broadway attachments | ||
exports.attach = function (options) { | ||
this.irc = new IRC(this.hook); | ||
}; | ||
|
||
exports.init = function (done) { | ||
done(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* | ||
* channel.js - an object to hold various channel data | ||
* | ||
* (c) 2011 Nodejitsu Inc. | ||
* | ||
*/ | ||
|
||
var Channel = exports.Channel = function (options) { | ||
for (var o in options) { | ||
this[o] = options[o]; | ||
} | ||
}; | ||
|
||
Channel.prototype.part = function () { | ||
this.active = false; | ||
}; | ||
|
||
Channel.prototype.join = function () { | ||
this.active = true; | ||
}; | ||
|
||
Channel.prototype.startVolume = function () { | ||
this._ircRate(); | ||
this._twitRate(); | ||
}; | ||
|
||
Channel.prototype.stopVolume = function () { | ||
clearInterval(this.ircInterval); | ||
clearInterval(this.twitInterval); | ||
}; | ||
|
||
Channel.prototype.config = function (key, value) { | ||
if (typeof value === 'undefined') { | ||
return this[key]; | ||
} | ||
if (typeof key === 'string') { | ||
this[key] = value; | ||
return key + ' has been set to ' + value; | ||
} | ||
else { | ||
return false; | ||
} | ||
}; | ||
|
||
Channel.prototype._ircRate = function () { | ||
var self = this, | ||
timespan = 60; | ||
self.rateValues = []; | ||
self.ircInterval = setInterval(function () { | ||
var sum = 0; | ||
if (self.rateValues.length > timespan) { | ||
self.rateValues.shift(); | ||
} | ||
|
||
self.rateValues.push(self.messageCount); | ||
self.messageCount = 0; | ||
|
||
self.rateValues.forEach(function (value) { | ||
sum += Number(value); | ||
}); | ||
self.rate = sum; | ||
self._volumetrics(); | ||
}, 1000); | ||
|
||
}; | ||
|
||
Channel.prototype._volumetrics = function () { | ||
var self = this; | ||
|
||
if (self.autoVolume) { | ||
if (self.rate > 10) { | ||
self.rate = 10; | ||
} | ||
if ((self.volume < 0) || (typeof self.volume === 'undefined')) { | ||
self.volume = 0; | ||
} | ||
if ((10 - self.rate) <= self.volume) { | ||
self.volume = 10 - self.rate; | ||
self.lastVolume = self.volume; | ||
} | ||
else if ((10 - self.rate) > self.volume) { | ||
self.lastVolume += self.lastVolume +0.05; | ||
self.volume = Math.round(self.lastVolume); | ||
} | ||
} | ||
}; | ||
|
||
Channel.prototype._twitRate = function () { | ||
var self = this; | ||
|
||
self.twitInterval = setInterval(function () { | ||
if (self.currentTweetCount > 0) { | ||
self.currentTweetCount--; | ||
} | ||
}, self.twitPeriod * 1000); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* | ||
* | ||
* router.js - This should contain a director router or similar for handling | ||
* "triggers." | ||
* | ||
* (c) 2012 Nodejitsu Inc. | ||
* | ||
*/ | ||
|
||
// Mostly copy-pasted from the cli router from director core. | ||
var utile = require('utile'), | ||
director = require('director'); | ||
|
||
var Router = exports.Router = function (routes) { | ||
director.Router.call(this, routes); | ||
this.recurse = 'backward'; | ||
}; | ||
|
||
// | ||
// Inherit from `director.Router`. | ||
// | ||
utile.inherits(Router, director.Router); | ||
|
||
// | ||
// ### function configure (options) | ||
// #### @options {Object} **Optional** Options to configure this instance with | ||
// Configures this instance with the specified `options`. | ||
// | ||
Router.prototype.configure = function (options) { | ||
options = options || {}; | ||
director.Router.prototype.configure.call(this, options); | ||
|
||
// | ||
// Our delimiter here is a space. | ||
// e.g. `!foo bar baz` | ||
// | ||
this.delimiter = ' '; | ||
|
||
// This way, you can use a custom trigger symbol. | ||
// e.g. `@foo bar baz` | ||
this.trigger = options.trigger || '!'; | ||
|
||
return this; | ||
}; | ||
|
||
// | ||
// ### function dispatch (method, path) | ||
// #### @method {string} Method to dispatch | ||
// #### @path {string} Path to dispatch | ||
// Finds a set of functions on the traversal towards | ||
// `method` and `path` in the core routing table then | ||
// invokes them based on settings in this instance. | ||
// | ||
Router.prototype.dispatch = function (method, data, app, callback) { | ||
|
||
var path = data.text, | ||
trig = new RegExp('^' + this.trigger); | ||
|
||
// | ||
// Replace the trigger with a space so that the traversal | ||
// algorithm will recognize it. This is because we always assume | ||
// that the `path` begins with `this.delimiter`. | ||
// | ||
path = (path || '').replace(trig, this.delimiter); | ||
|
||
var fns = this.traverse(method, path, this.routes, ''); | ||
|
||
if (!fns || fns.length === 0) { | ||
|
||
if (callback) { | ||
|
||
callback(new Error( | ||
utile.format('IRC command router could not find cmd for: "%s"', path) | ||
)); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
if (this.recurse === 'forward') { | ||
fns = fns.reverse(); | ||
} | ||
|
||
// Second arg is set to "this" in the route handler. | ||
// Needs some helper fxns | ||
this.invoke(this.runlist(fns), { | ||
cmd: path.substring(1), | ||
data: data, | ||
app: app | ||
}, callback); | ||
return true; | ||
}; |
Oops, something went wrong.