From ccc36d67a7534dd5c860440dd60bc62412c4c0ef Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Fri, 20 Apr 2012 14:14:28 +0100 Subject: [PATCH 01/51] Transformed config file to accept multiple servers and changed dbot constructors to reflect this --- config.json.sample | 17 +++++++++++----- run.js | 49 ++++++++++++++++++++++++++++++---------------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/config.json.sample b/config.json.sample index b41f0f7..78dd1cc 100644 --- a/config.json.sample +++ b/config.json.sample @@ -1,8 +1,15 @@ { - "name": "depressionbot", - "password": "fishes", + "name": "testressionbot", + "servers": { + "freenode": { + "server": "irc.freenode.net", + "port": 6667, + "nickserv": "nickserv", + "password": "lolturtles", + "channels": [ + "#realitest" + ] + } + }, "admin": [ "batman" ], - "channels": [ - "#42" - ] } diff --git a/run.js b/run.js index d8e93a7..6b02d0a 100644 --- a/run.js +++ b/run.js @@ -43,34 +43,49 @@ var DBot = function(timers) { this.db.ignores = {}; } - // Load the strings file + // Load Strings file this.strings = JSON.parse(fs.readFileSync('strings.json', 'utf-8')); + // Initialise run-time resources + this.sessionData = {}; + this.timers = timers.create(); + // Populate bot properties with config data this.name = this.config.name || 'dbox'; this.admin = this.config.admin || [ 'reality' ]; - this.password = this.config.password || 'lolturtles'; - this.nickserv = this.config.nickserv || 'zippy'; - this.server = this.config.server || 'elara.ivixor.net'; - this.port = this.config.port || 6667; - this.webPort = this.config.webPort || 443; - this.moduleNames = this.config.modules || [ 'command', 'js', 'admin', 'kick', 'modehate', 'quotes', 'puns', 'spelling', 'web', 'youare', 'autoshorten' ]; + this.moduleNames = this.config.modules || [ 'command', 'js' ]; this.language = this.config.language || 'english'; - this.sessionData = {}; - this.timers = timers.create(); - - this.instance = jsbot.createJSBot(this.name, this.server, this.port, this, function() { - if(this.config.hasOwnProperty('channels')) { - this.config.channels.each(function(channel) { - this.instance.join(channel); - }.bind(this)); + // It's the user's responsibility to fill this data structure up properly in + // the config file. They can d-d-d-deal with it if they have problems. + this.servers = this.config.servers || { + 'freenode': { + 'server': 'irc.freenode.net', + 'port': 6667, + 'nickserv': 'nickserv', + 'password': 'lolturtles', + 'channels': [ + '#realitest' + ]; } - }.bind(this), this.nickserv, this.password); + }; + + // Create JSBot and connect to each server + this.instance = jsbot.createJSBot(this.name); + for(var name in this.servers) { + if(this.servers.hasOwnProperty(name)) { + var server = this.servers[name]; + this.instance.addConnection(name, server.server, server.port, this.admin, function(event) { + server.channels.each(function(channel) { + instance.join(event, channel) + }.bind(this)); + }.bind(this), server.nickserv, server.password); + } + } // Load the modules and connect to the server this.reloadModules(); - this.instance.connect(); + this.instance.connectAll(); }; // Say something in a channel From ec34a861f48140477afc72ecb0be793dcb9800a1 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 19 May 2012 17:47:35 +0100 Subject: [PATCH 02/51] Now connects! Woo! --- run.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run.js b/run.js index 58d372b..f6f9829 100644 --- a/run.js +++ b/run.js @@ -66,7 +66,7 @@ var DBot = function(timers) { 'password': 'lolturtles', 'channels': [ '#realitest' - ]; + ] } }; @@ -77,7 +77,7 @@ var DBot = function(timers) { var server = this.servers[name]; this.instance.addConnection(name, server.server, server.port, this.admin, function(event) { server.channels.each(function(channel) { - instance.join(event, channel) + this.instance.join(event, channel) }.bind(this)); }.bind(this), server.nickserv, server.password); } From 1f02e29a8594293a2afb96acad5c10e093b2a8e5 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Sat, 19 May 2012 19:14:07 +0100 Subject: [PATCH 03/51] Made DBot load listeners in The New Way. Massively simplified Command module, converted to new format. Converted JS module to new format. All working. Moved ~ignore functionality away for now as it needs to be combined with jsbot. --- modules/command.js | 150 +++++++++++++-------------------------------- modules/js.js | 13 ++-- modules/quotes.js | 13 ++++ run.js | 2 +- 4 files changed, 64 insertions(+), 114 deletions(-) diff --git a/modules/command.js b/modules/command.js index 1da6b65..300fedc 100644 --- a/modules/command.js +++ b/modules/command.js @@ -1,122 +1,58 @@ -// Module which handles the command execution syntax for DBot. Not much is going -// to work without this. +/** + * Module Name: Command + * Description: An essential module which maps PRIVMSG input to an appropriate + * command and then runs that command, given the user isn't banned from or + * ignoring that command. + */ var command = function(dbot) { var dbot = dbot; + /** + * Is user banned from using command? + */ + var is_banned = function(user, command) { + var banned = false; + if(dbot.db.bans.hasOwnProperty(command)) { + if(dbot.db.bans[command].include(user) || dbot.db.bans['*'].include(user)) { + banned = true; + } + } + return banned; + } + + /** + * Is user ignoring command? + */ + var is_ignoring = function(user, command) { + var module = dbot.commandMap[command]; + var ignoring = false; + if(dbot.db.ignores.hasOwnProperty(user) && dbot.db.ignores[user].include(module)) { + ignoring = true; + } + return ignoring; + } + return { - 'onLoad': function() { - return { - '~ignore': function(data, params) { - var ignorableModules = []; - for(var i=0;i Date: Wed, 23 May 2012 15:45:09 +0100 Subject: [PATCH 04/51] Apply regex in command.js module and add results in input property on event object. --- modules/command.js | 45 +++++++++++++++++++++++++++++++++------------ modules/js.js | 29 +++++++++++++++++------------ 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/modules/command.js b/modules/command.js index 300fedc..15586b5 100644 --- a/modules/command.js +++ b/modules/command.js @@ -5,12 +5,10 @@ * ignoring that command. */ var command = function(dbot) { - var dbot = dbot; - /** * Is user banned from using command? */ - var is_banned = function(user, command) { + var isBanned = function(user, command) { var banned = false; if(dbot.db.bans.hasOwnProperty(command)) { if(dbot.db.bans[command].include(user) || dbot.db.bans['*'].include(user)) { @@ -18,19 +16,38 @@ var command = function(dbot) { } } return banned; - } + }; /** * Is user ignoring command? */ - var is_ignoring = function(user, command) { + var isIgnoring = function(user, command) { var module = dbot.commandMap[command]; var ignoring = false; if(dbot.db.ignores.hasOwnProperty(user) && dbot.db.ignores[user].include(module)) { ignoring = true; } return ignoring; - } + }; + + /** + * Apply Regex to event message, store result. Return false if it doesn't + * apply. + */ + var applyRegex = function(commandName, event) { + var applies = false; + if(dbot.commands[commandName].hasOwnProperty(regex)) { + var cRegex = dbot.commands[commandName].regex; + var q = event.message.valMatch(cRegex[0], cRegex[1]); + if(q) { + applies = true; + event.input = q; + } + } else { + applies = true; + } + return applies; + }; return { 'name': 'command', @@ -39,14 +56,18 @@ var command = function(dbot) { * Run the appropriate command given the input. */ 'listener': function(event) { - var command_name = event.params[0]; - if(dbot.commands.hasOwnProperty(command_name)) { - if(is_banned(event.user, command_name)) { + var commandName = event.params[0]; + if(dbot.commands.hasOwnProperty(commandName)) { + if(isBanned(event.user, commandName)) { event.reply(dbot.t('command_ban', {'user': event.user})); } else { - if(!is_ignoring(event.user, command_name)) { - dbot.commands[command_name](event); - dbot.save(); + if(!isIgnoring(event.user, commandName)) { + if(applyRegex(commandName, event)) { + dbot.commands[commandName](event); + dbot.save(); + } else { + event.reply(dbot.t('syntax_error')); + } } } } diff --git a/modules/js.js b/modules/js.js index b4efb78..408a40b 100644 --- a/modules/js.js +++ b/modules/js.js @@ -1,38 +1,43 @@ +/** + * Module Name: JS + * Description: Allows users to run sandboxed JS code, printing the result in + * the channel. Also allows admins to run un-sandboxed Javascript code with + * access to the DepressionBot instance memory. + */ var vm = require('vm'); var sbox = require('sandbox'); var js = function(dbot) { - var dbot = dbot; var s = new sbox(); var commands = { + // Run JS code sandboxed, return result to channel. '~js': function(event) { - console.log('hello'); - var q = event.message.valMatch(/^~js (.*)/, 2); - s.run(q[1], function(output) { + s.run(event.input[1], function(output) { event.reply(output.result); }.bind(this)); }, + // Run JS code un-sandboxed, with access to DBot memory (admin-only). '~ajs': function(event) { - var q = data.message.valMatch(/^~ajs (.*)/, 2); if(dbot.admin.include(data.user) ) { - var ret = eval(q[1]); - if(ret != undefined) { + var ret = eval(event.input[1]); + if(ret !== undefined) { event.reply(ret); } } } }; + commands['~js'].regex = [/^~js (.*)/, 2]; + commands['~ajs'].regex = [/^~ajs (.*)/, 2]; return { + 'name': 'js', + 'ignorable': true, + 'onLoad': function() { return commands; - }, - - 'name': 'js', - - 'ignorable': true + } }; }; From 2088ee9da3b7fc37ee2341a466bb2bdf5ac7e5bb Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Wed, 23 May 2012 15:56:13 +0100 Subject: [PATCH 05/51] Should be event rather than data. --- modules/js.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/js.js b/modules/js.js index 408a40b..3aee828 100644 --- a/modules/js.js +++ b/modules/js.js @@ -20,7 +20,7 @@ var js = function(dbot) { // Run JS code un-sandboxed, with access to DBot memory (admin-only). '~ajs': function(event) { - if(dbot.admin.include(data.user) ) { + if(dbot.admin.include(event.user) ) { var ret = eval(event.input[1]); if(ret !== undefined) { event.reply(ret); From c3832c209f1425a5eb7d6b8cca7c9f48029e00d6 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Wed, 23 May 2012 18:01:28 +0100 Subject: [PATCH 06/51] Converted quotes module to new format. Everything seems to be working --- modules/command.js | 28 +++--- modules/quotes.js | 238 +++++++++++++++++---------------------------- 2 files changed, 102 insertions(+), 164 deletions(-) diff --git a/modules/command.js b/modules/command.js index 15586b5..49a51f4 100644 --- a/modules/command.js +++ b/modules/command.js @@ -36,7 +36,7 @@ var command = function(dbot) { */ var applyRegex = function(commandName, event) { var applies = false; - if(dbot.commands[commandName].hasOwnProperty(regex)) { + if(dbot.commands[commandName].hasOwnProperty('regex')) { var cRegex = dbot.commands[commandName].regex; var q = event.message.valMatch(cRegex[0], cRegex[1]); if(q) { @@ -57,20 +57,22 @@ var command = function(dbot) { */ 'listener': function(event) { var commandName = event.params[0]; - if(dbot.commands.hasOwnProperty(commandName)) { - if(isBanned(event.user, commandName)) { - event.reply(dbot.t('command_ban', {'user': event.user})); - } else { - if(!isIgnoring(event.user, commandName)) { - if(applyRegex(commandName, event)) { - dbot.commands[commandName](event); - dbot.save(); - } else { - event.reply(dbot.t('syntax_error')); - } + if(!dbot.commands.hasOwnProperty(commandName)) { + commandName = '~'; + } + + if(isBanned(event.user, commandName)) { + event.reply(dbot.t('command_ban', {'user': event.user})); + } else { + if(!isIgnoring(event.user, commandName)) { + if(applyRegex(commandName, event)) { + dbot.commands[commandName](event); + dbot.save(); + } else { + event.reply(dbot.t('syntax_error')); } } - } + } }, 'on': 'PRIVMSG', diff --git a/modules/quotes.js b/modules/quotes.js index 5bd37b8..64829ed 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -4,7 +4,8 @@ var quotes = function(dbot) { var addStack = []; var rmAllowed = true; - // Retrieve a random quote from a given category, interpolating any quote references (~~QUOTE CATEGORY~~) within it + // Retrieve a random quote from a given category, interpolating any quote + // references (~~QUOTE CATEGORY~~) within it var interpolatedQuote = function(key, quoteTree) { if(quoteTree !== undefined && quoteTree.indexOf(key) != -1) { return ''; @@ -28,52 +29,27 @@ var quotes = function(dbot) { } } - // Parse quote parameters - /* - var paramRefs = quoteString.match(/~~\$([1-9])~~/g); - var thisParam; - - while(paramRefs && (thisParam = paramRefs.shift()) !== undefined) { - thisParam = thisParam[1]; - console.log(thisParam); - if(thisParam < params.length) { - quoteString = quoteString.replace("~~$" + thisParam + "~~", params[thisParam]); - } - } - */ - return quoteString; }; var commands = { - '~': function(data, params) { - var q = data.message.valMatch(/^~([\d\w\s-]*)/, 2); - if(q) { - q[1] = q[1].trim(); - key = q[1].toLowerCase(); - if(quotes.hasOwnProperty(key)) { - dbot.say(data.channel, q[1] + ': ' + interpolatedQuote(key)); - } else { - dbot.say(data.channel, dbot.t('category_not_found', {'category': q[1]})); - } + // Alternative syntax to ~q + '~': function(event) { + commands['~q'](event); + }, + + // Retrieve quote from a category in the database. + '~q': function(event) { + var key = event.input[1].trim().toLowerCase(); + if(quotes.hasOwnProperty(key)) { + event.reply(key + ': ' + interpolatedQuote(key)); + } else { + event.reply(dbot.t('category_not_found', {'category': key})); } }, - '~q': function(data, params) { - var q = data.message.valMatch(/^~q ([\d\w\s-]*)/, 2); - if(q) { - q[1] = q[1].trim(); - key = q[1].toLowerCase(); - if(quotes.hasOwnProperty(key)) { - dbot.say(data.channel, q[1] + ': ' + interpolatedQuote(key)); - } else { - dbot.say(data.channel, dbot.t('category_not_found', {'category': q[1]})); - } - } - }, - - // shows the biggest categories - '~qstats': function(data, params) { + // Shows a list of the biggest categories + '~qstats': function(event) { var qSizes = []; for(var cat in quotes) { if(quotes[cat].length != 0) { @@ -90,76 +66,55 @@ var quotes = function(dbot) { qString += qSizes[i][0] + " (" + qSizes[i][1] + "), "; } - dbot.say(data.channel, qString.slice(0, -2)); + event.reply(qString.slice(0, -2)); }, - '~qsearch': function(data, params) { - if(params[2] === undefined) { - dbot.say(data.channel, dbot.t('syntax_error')); - } else { - params[1].trim(); - key = params[1].toLowerCase(); - if(!quotes.hasOwnProperty(key)) { - dbot.say(data.channel, dbot.t('empty_category')); - } else { - var matches = []; - - quotes[key].each(function(quote) { - if(quote.indexOf(params[2]) != -1) { - matches.push(quote); - } - }.bind(this)); - - if(matches.length == 0) { - dbot.say(data.channel, dbot.t('no_results')); - } else { - dbot.say(data.channel, params[1] + ' (' + params[2] + '): ' + matches.random() + ' [' + matches.length + ' results]'); + // Search a given category for some text. + '~qsearch': function(event) { + var haystack = event.input[1].trim().toLowerCase(); + var needle = event.input[2]; + if(quotes.hasOwnProperty(haystack)) { + var matches = []; + quotes[haystack].each(function(quote) { + if(quote.indexOf(needle) != -1) { + matches.push(quote); } + }.bind(this)); + + if(matches.length == 0) { + event.reply(dbot.t('no_results')); + } else { + event.reply(dbot.t('search_results', {'category': haystack, 'needle': needle, + 'quote': matches.random(), 'matches': matches.length})); } + } else { + event.reply(dbot.t('empty_category')); } }, - '~rmlast': function(data, params) { - if(rmAllowed == true || dbot.admin.include(data.user)) { - var q = data.message.valMatch(/^~rmlast ([\d\w\s-]*)/, 2); - if(q) { - q[1] = q[1].trim() - key = q[1].toLowerCase(); - if(quotes.hasOwnProperty(q[1])) { - if(!dbot.db.locks.include(q[1]) || dbot.admin.include(data.user)) { - var quote = quotes[key].pop(); - if(quotes[key].length === 0) { - delete quotes[key]; - } - rmAllowed = false; - dbot.say(data.channel, '\'' + quote + '\'' + - dbot.t('removed_from') + q[1]); - } else { - dbot.say(data.channel, dbot.t('locked_category', {'category': q[1]})); + '~rmlast': function(event) { + if(rmAllowed == true || dbot.admin.include(event.user)) { + var key = event.input[1].trim().toLowerCase(); + if(quotes.hasOwnProperty(key)) { + if(!dbot.db.locks.include(key) || dbot.admin.include(event.user)) { + var quote = quotes[key].pop(); + if(quotes[key].length === 0) { + delete quotes[key]; } + rmAllowed = false; + event.reply(dbot.t('removed_from', {'quote': quote, 'category': key})); } else { - dbot.say(data.channel, dbot.t('no_quotes', {'category': q[1]})); + event.reply(dbot.t('locked_category', {'category': q[1]})); } } else { - var last = addStack.pop(); - if(last) { - if(!dbot.db.locks.include(last)) { - quotes[last].pop(); - rmAllowed = false; - dbot.say(data.channel, dbot.t('last_removed', {'category': last})); - } else { - dbot.say(data.channel, dbot.t('locked_category', {'category': last})); - } - } else { - dbot.say(data.channel, dbot.t('no_recent_adds')); - } + event.reply(dbot.t('no_quotes', {'category': q[1]})); } } else { - dbot.say(data.channel, dbot.t('rmlast_spam')); + event.reply(dbot.t('rmlast_spam')); } }, - '~rm': function(data, params) { + /*'~rm': function(data, params) { if(rmAllowed == true || dbot.admin.include(data.user)) { var q = data.message.valMatch(/^~rm ([\d\w\s-]*) (.+)$/, 3); if(q) { @@ -188,82 +143,57 @@ var quotes = function(dbot) { } else { dbot.say(data.channel, dbot.t('rmlast_spam')); } - }, + },*/ - '~qcount': function(data, params) { - var q = data.message.valMatch(/^~qcount ([\d\w\s-]*)/, 2); - if(q) { - q[1] = q[1].trim(); - key = q[1].toLowerCase(); + '~qcount': function(event) { + var input = event.message.valMatch(/^~qcount ([\d\w\s-]*)/, 2); + if(input) { // Give quote count for named category + var key = input[1].trim().toLowerCase(); if(quotes.hasOwnProperty(key)) { - dbot.say(data.channel, dbot.t('quote_count', {'category': q[1], 'count': quotes[key].length})); + event.reply(dbot.t('quote_count', {'category': key, 'count': quotes[key].length})); } else { - dbot.say(data.channel, dbot.t('no_quotes', {'category': q[1]})); + event.reply(dbot.t('no_quotes', {'category': key})); } } else { // Give total quote count var totalQuoteCount = 0; for(var category in quotes) { totalQuoteCount += category.length; } - dbot.say(data.channel, dbot.t('total_quotes', {'count': totalQuoteCount})); + event.reply(dbot.t('total_quotes', {'count': totalQuoteCount})); } }, - '~qadd': function(data, params) { - var q = data.message.valMatch(/^~qadd ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3); - if(q) { - key = q[1].toLowerCase(); - if(!Object.isArray(quotes[key])) { - quotes[key] = []; - } else { - if (quotes[key].include(q[2])) { - dbot.say(data.channel, dbot.t('quote_exists')); - return; - } - } - quotes[key].push(q[2]); - addStack.push(q[1]); - rmAllowed = true; - dbot.say(data.channel, dbot.t('quote_saved', {'category': q[1], 'count': quotes[key].length})); + '~qadd': function(event) { + var key = event.input[1].toLowerCase(); + var text = event.input[2]; + if(!Object.isArray(quotes[key])) { + quotes[key] = []; + } + + if(quotes[key].include(text)) { + event.reply(dbot.t('quote_exists')); } else { - dbot.say(data.channel, dbot.t('syntax_error')); + quotes[key].push(text); + rmAllowed = true; + event.reply(dbot.t('quote_saved', {'category': key, 'count': quotes[key].length})); } }, - '~qset': function(data, params) { - var q = data.message.valMatch(/^~qset ([\d\w\s-]*)=(.+)$/, 3); - if(q) { - q[1] = q[1].trim(); - key = q[1].toLowerCase(); - if(!quotes.hasOwnProperty(key) || (quotes.hasOwnProperty(key) && - quotes[key].length == 1)) { - quotes[key] = [q[2]]; - dbot.say(data.channel, dbot.t('quote_saved', {'category': q[1], 'count': 1})); - } else { - dbot.say(data.channel, dbot.t('quote_replace')); - } - } - }, - - '~rq': function(data, params) { + '~rq': function(event) { var rQuote = Object.keys(quotes).random(); - dbot.say(data.channel, rQuote + ': ' + interpolatedQuote(rQuote)); - }, - - '~d': function(data, params) { - dbot.say(data.channel, data.user + ': ' + interpolatedQuote(dbot.name)); + event.reply(rQuote + ': ' + interpolatedQuote(rQuote)); }, - '~link': function(data, params) { - if(params[1] === undefined || !quotes.hasOwnProperty(params[1].toLowerCase())) { - dbot.say(data.channel, dbot.t('syntax_error')); + '~link': function(event) { + var key = event.params[1].trim().toLowerCase(); + if(quotes.hasOwnProperty(key)) { + event.reply(dbot.t('quote_link', {'category': key}) + ' - http://nc.no.de:443/quotes/' + key); } else { - dbot.say(data.channel, dbot.t('quote_link', {'category': params[1]}) + - ' - http://nc.no.de:443/quotes/' + params[1]); + event.reply(dbot.t('category_not_found')); } }, - '~qprune': function(data) { + '~qprune': function(event) { var pruned = [] for(key in quotes) { if(quotes.hasOwnProperty(key)) { @@ -274,13 +204,19 @@ var quotes = function(dbot) { } } if(pruned.length > 0) { - dbot.say(data.channel, dbot.t('prune', {'categories': pruned.join(", ")})); + event.reply(dbot.t('prune', {'categories': pruned.join(", ")})); } else { - dbot.say(data.channel, dbot.t('no_prune')); + event.reply(dbot.t('no_prune')); } } }; + commands['~'].regex = [/^~([\d\w\s-]*)/, 2]; + commands['~q'].regex = [/^~q ([\d\w\s-]*)/, 2]; + commands['~qsearch'].regex = [/^~qsearch ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; + commands['~rmlast'].regex = [/^~rmlast ([\d\w\s-]*)/, 2]; + commands['~qadd'].regex = [/^~qadd ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; + return { 'onLoad': function() { dbot.timers.addTimer(1000 * 60 * 3, function() { @@ -289,7 +225,7 @@ var quotes = function(dbot) { return commands; }, - // For automatic quote retrieval + /* For automatic quote retrieval 'listener': function(data, params) { if((dbot.db.ignores.hasOwnProperty(data.user) && dbot.db.ignores[data.user].include(name)) == false) { @@ -317,7 +253,7 @@ var quotes = function(dbot) { } }, - 'on': 'PRIVMSG', + 'on': 'PRIVMSG',*/ 'name': name, From 55dec1232416fdf49fdd7277291a8ba481e2046d Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Wed, 23 May 2012 18:02:02 +0100 Subject: [PATCH 07/51] Fixed output on module load, added a new translation for search results. --- run.js | 4 ++-- strings.json | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/run.js b/run.js index f58eec4..d0fbbc4 100644 --- a/run.js +++ b/run.js @@ -53,7 +53,7 @@ var DBot = function(timers) { // Populate bot properties with config data this.name = this.config.name || 'dbox'; this.admin = this.config.admin || [ 'reality' ]; - this.moduleNames = this.config.modules || [ 'command', 'js' ]; + this.moduleNames = this.config.modules || [ 'command', 'js', 'quotes' ]; this.language = this.config.language || 'english'; // It's the user's responsibility to fill this data structure up properly in @@ -167,7 +167,7 @@ DBot.prototype.reloadModules = function() { this.modules.push(module); } catch(err) { - console.log(this.strings[this.language].module_load_error.format({'moduleName': name})); + console.log(this.t('module_load_error', {'moduleName': name})); console.log(err); } }.bind(this)); diff --git a/strings.json b/strings.json index 493d62b..6761598 100644 --- a/strings.json +++ b/strings.json @@ -186,5 +186,8 @@ "kicked_dbot": { "english": "Thou shalt not kick {botname}", "spanish": "No expulsás {botname}" + }, + "search_results": { + "english": "{category} ({needle}): '{quote}' [{matches} results]" } } From aa72af38678535bed0db56255e4daa5a2920c768 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Wed, 23 May 2012 18:50:21 +0100 Subject: [PATCH 08/51] Don't error if regex syntax is invalid for ~ default. --- modules/command.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/command.js b/modules/command.js index 49a51f4..6c6c118 100644 --- a/modules/command.js +++ b/modules/command.js @@ -69,7 +69,9 @@ var command = function(dbot) { dbot.commands[commandName](event); dbot.save(); } else { - event.reply(dbot.t('syntax_error')); + if(commandName !== '~') { + event.reply(dbot.t('syntax_error')); + } } } } From 464e0f11e35371bde4cd660e787af84049721250 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Wed, 23 May 2012 19:38:10 +0100 Subject: [PATCH 09/51] Converted admin.js. Added a few more translations. Removed modehate functionality. Changed some stuff in run.js to facilitate changes. --- modules/admin.js | 171 +++++++++++++++++++++----------------------- modules/modehate.js | 23 ------ run.js | 10 +-- strings.json | 6 ++ 4 files changed, 91 insertions(+), 119 deletions(-) delete mode 100644 modules/modehate.js diff --git a/modules/admin.js b/modules/admin.js index 36e3c1e..3c15948 100644 --- a/modules/admin.js +++ b/modules/admin.js @@ -1,147 +1,136 @@ +/** + * Module Name: Admin + * Description: Set of commands which only one who is a DepressionBot + * administrator can run - as such, it has its own command execution listener. + */ var fs = require('fs'); var sys = require('sys') var exec = require('child_process').exec; -var adminCommands = function(dbot) { - var dbot = dbot; - +var admin = function(dbot) { var commands = { - 'join': function(data, params) { - dbot.instance.join(params[1]); - dbot.say(data.channel, 'Joined ' + params[1]); + // Join a channel + 'join': function(event) { + var channel = event.params[1]; + dbot.instance.join(event, channel); + event.reply(dbot.t('join', {'channel': channel})); }, - 'opme': function(data, params) { - dbot.instance.send('MODE ' + params[1] + ' +o ', data.user); + // Leave a channel + 'part': function(event) { + var channel = event.params[1]; + event.instance.part(event, channel); + event.reply(dbot.t('part', {'channel': channel})); }, - 'part': function(data, params) { - dbot.instance.part(params[1]); + // Op admin caller in given channel + 'opme': function(event) { + event.channel = event.params[1]; + dbot.instance.mode(event, '+o ' + event.user); }, // Do a git pull and reload - 'greload': function(data, params) { - var child; - - child = exec("git pull", function (error, stdout, stderr) { - console.log(stderr); - dbot.say(data.channel, dbot.t('gpull')); - commands.reload(data, params); + 'greload': function(event) { + var child = exec("git pull", function (error, stdout, stderr) { + event.reply(dbot.t('gpull')); + commands.reload(event); }.bind(this)); }, - 'reload': function(data, params) { + // Reload DB, translations and modules. + 'reload': function(event) { dbot.db = JSON.parse(fs.readFileSync('db.json', 'utf-8')); dbot.strings = JSON.parse(fs.readFileSync('strings.json', 'utf-8')); dbot.reloadModules(); - dbot.say(data.channel, dbot.t('reload')); + event.reply(dbot.t('reload')); }, - 'say': function(data, params) { - if (params[1] === "@") { - var c = data.channel; - } else { - var c = params[1]; - } - var m = params.slice(2).join(' '); - dbot.say(c, m); + // Say something in a channel (TODO probably doesn't work.) + 'say': function(event) { + var channel = event.params[1]; + if(event.params[1] === "@") { + var channel = event.channel; + } + var message = event.params.slice(2).join(' '); + dbot.say(event.server, channel, message); }, - 'act': function(data, params) { - if (params[1] === "@") { - var c = data.channel; - } else { - var c = params[1]; - } - var m = params.slice(2).join(' '); - dbot.act(c, m); - }, - - 'load': function(data, params) { - dbot.moduleNames.push(params[1]); + // Load new module + 'load': function(event) { + var moduleName = event.params[1]; + dbot.moduleNames.push(moduleName); dbot.reloadModules(); - dbot.say(data.channel, dbot.t('load_module', {'moduleName': params[1]})); + event.reply(dbot.t('load_module', {'moduleName': moduleName})); }, - 'unload': function(data, params) { - if(dbot.moduleNames.include(params[1])) { - var cacheKey = require.resolve('../modules/' + params[1]); + // Unload a loaded module + 'unload': function(event) { + var moduleName = event.params[1]; + if(dbot.moduleNames.include(moduleName)) { + var cacheKey = require.resolve('../modules/' + moduleName); delete require.cache[cacheKey]; - var moduleIndex = dbot.moduleNames.indexOf(params[1]); + var moduleIndex = dbot.moduleNames.indexOf(moduleName); dbot.moduleNames.splice(moduleIndex, 1); - dbot.reloadModules(); - dbot.say(data.channel, dbot.t('unload_module', {'moduleName': params[1]})); + + event.reply(dbot.t('unload_module', {'moduleName': moduleName})); } else { - dbot.say(data.channel, dbot.t('unload_error', {'moduleName': params[1]})); + event.reply(dbot.t('unload_error', {'moduleName': moduleName})); } }, - 'ban': function(data, params) { - if(dbot.db.bans.hasOwnProperty(params[2])) { - dbot.db.bans[params[2]].push(params[1]); - } else { - dbot.db.bans[params[2]] = [ params[1] ]; + // Ban user from command or * + 'ban': function(event) { + var username = event.params[1]; + var command = event.params[2]; + + if(!dbot.db.bans.hasOwnProperty(command)) { + dbot.db.bans[command] = [ ]; } - dbot.say(data.channel, dbot.t('banned', {'user': params[1], 'command': params[2]})); + dbot.db.bans[command].push(username); + event.reply(dbot.t('banned', {'user': username, 'command': command})); }, - 'unban': function(data, params) { - if(dbot.db.bans.hasOwnProperty(params[2]) && dbot.db.bans[params[2]].include(params[1])) { - dbot.db.bans[params[2]].splice(dbot.db.bans[params[2]].indexOf(params[1]), 1); - dbot.say(data.channel, dbot.t('unbanned', {'user': params[1], 'command': params[2]})); + // Unban a user from command or * + 'unban': function(event) { + var username = event.params[1]; + var command = event.params[2]; + if(dbot.db.bans.hasOwnProperty(command) && dbot.db.bans[command].include(username)) { + dbot.db.bans[command].splice(dbot.db.bans[command].indexOf(username), 1); + event.reply(dbot.t('unbanned', {'user': username, 'command': command})); } else { - dbot.say(data.channel, dbot.t('unban_error', {'user': params[1]})); + event.reply(dbot.t('unban_error', {'user': username})); } }, - 'modehate': function(data, params) { - dbot.db.modehate.push(params[1]); - dbot.say(data.channel, dbot.t('modehate', {'user': params[1]})); - }, - - 'unmodehate': function(data, params) { - dbot.db.modehate.splice(dbot.db.modehate.indexOf(params[1]), 1); - dbot.say(data.channel, dbot.t('unmodehate', {'user': params[1]})); - }, - - 'lock': function(data, params) { - dbot.db.locks.push(params[1]); - dbot.say(data.channel, dbot.t('qlock', {'category': params[1]})); + // Lock quote category so quotes can't be removed + 'lock': function(event) { + var category = event.params[1]; + dbot.db.locks.push(category); + event.reply(dbot.t('qlock', {'category': category})); } }; return { - // These commands are implemented as their own listener so it can easily - // check whether the user is the admin, and so that the admin can't ban - // themselves and then not be able to rectify it... - 'listener': function(data) { - if(data.channel == dbot.name) data.channel = data.user; + 'name': 'admin', - params = data.message.split(' '); - if(commands.hasOwnProperty(params[0]) && dbot.admin.include(data.user)) { - commands[params[0]](data, params); + /** + * Run the appropriate admin command given the input (and user). + */ + 'listener': function(event) { + var commandName = event.params[0]; + if(commands.hasOwnProperty(commandName) && dbot.admin.include(event.user)) { + commands[commandName](event); dbot.save(); } }, - 'onLoad': function() { - return { - '~resetadmin': function(data, params) { - dbot.admin = dbot.config.admin; - } - } - }, - 'on': 'PRIVMSG', - - 'name': 'admin', - 'ignorable': false }; }; exports.fetch = function(dbot) { - return adminCommands(dbot); + return admin(dbot); }; diff --git a/modules/modehate.js b/modules/modehate.js deleted file mode 100644 index 4bc25eb..0000000 --- a/modules/modehate.js +++ /dev/null @@ -1,23 +0,0 @@ -var modehate = function(dbot) { - var dbot = dbot; - - return { - 'listener': function(data, params) { - if(data.raw[0].indexOf('-oooo') != -1) { - dbot.instance.send('KICK #42 ' + data.user + ' :gtfo - mass deop protection'); - } else if(dbot.db.modehate.include(data.user) && data.raw[0].indexOf('-o') != -1) { - dbot.instance.send('KICK ' + data.channel + ' ' + data.user + ' :gtfo'); - } - }, - - 'on': 'MODE', - - 'name': 'modehate', - - 'ignorable': false - }; -}; - -exports.fetch = function(dbot) { - return modehate(dbot); -}; diff --git a/run.js b/run.js index d0fbbc4..3f7af54 100644 --- a/run.js +++ b/run.js @@ -53,7 +53,7 @@ var DBot = function(timers) { // Populate bot properties with config data this.name = this.config.name || 'dbox'; this.admin = this.config.admin || [ 'reality' ]; - this.moduleNames = this.config.modules || [ 'command', 'js', 'quotes' ]; + this.moduleNames = this.config.modules || [ 'command', 'js', 'quotes', 'admin' ]; this.language = this.config.language || 'english'; // It's the user's responsibility to fill this data structure up properly in @@ -89,8 +89,8 @@ var DBot = function(timers) { }; // Say something in a channel -DBot.prototype.say = function(channel, data) { - this.instance.say(channel, data); +DBot.prototype.say = function(server, channel, message) { + this.instance.say(server, channel, message); }; // Format given stored string in config language @@ -103,9 +103,9 @@ DBot.prototype.t = function(string, formatData) { return this.strings[string][lang].format(formatData); }; -DBot.prototype.act = function(channel, data) { +/*DBot.prototype.act = function(channel, data) { this.instance.send('PRIVMSG', channel, ':\001ACTION ' + data + '\001'); -} +}*/ // Save the database file DBot.prototype.save = function() { diff --git a/strings.json b/strings.json index 6761598..e624319 100644 --- a/strings.json +++ b/strings.json @@ -189,5 +189,11 @@ }, "search_results": { "english": "{category} ({needle}): '{quote}' [{matches} results]" + }, + "join": { + "english": "Joined {channel}" + }, + "part": { + "english": "Left {channel}" } } From 9a9f9a662bc6503b9f9e532e605a29cc75ed7a8d Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Wed, 23 May 2012 19:39:10 +0100 Subject: [PATCH 10/51] removed badwords module --- modules/badwords.js | 56 --------------------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 modules/badwords.js diff --git a/modules/badwords.js b/modules/badwords.js deleted file mode 100644 index d53dab0..0000000 --- a/modules/badwords.js +++ /dev/null @@ -1,56 +0,0 @@ -// Find which badwords are currently enacted in the current channel -var badwords = function(dbot) { - var name = 'badwords'; - var dbot = dbot; - var badWordLock = false; - - var commands = { - '~badwords': function(data, params) { - if(badWordLock == true) { - dbot.say('reality', 'Another badwords query is in action. Try again in a few seconds.'); - } else { - data.channel = '#42'; - badWordLock = true; - - dbot.sessionData.badwords.waiting = true; - - dbot.say('bots', 'badwords ' + data.channel + ' list'); - dbot.instance.addListener('PRIVMSG', - dbot.sessionData.badwords = {}; - badWordLock = false; - } - } - }; - - return { - 'onLoad': function() { - if(!dbot.sessionData.hasOwnProperty('badwords')) { - dbot.sessionData.badwords = {}; - } - - return commands; - }, - - 'listener': function(data) { - if(data.channel === 'bots') { - if(data.message.indexOf('bad words list is empty') != -1) { - dbot.sessionData.badwords.count = 0; - dbot.sessionData.badwords.finished = true; - } else { - var wordMatch = data.message.valMatch(/\w([1-10])\w(.*)/, 2); - dbot.say('reality', wordMatch[1]); - } - } - }, - - 'on': 'PRIVMSG', - - 'name': name, - - 'ignorable': true - }; -}; - -exports.fetch = function(dbot) { - return badwords(dbot); -}; From 74369c5de649f202e26fddfcb104fd0ce43a0ec3 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Wed, 23 May 2012 19:45:14 +0100 Subject: [PATCH 11/51] converted autoshorten and dice to new format --- modules/autoshorten.js | 17 ++++++++++------- modules/dice.js | 18 +++++++++--------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/modules/autoshorten.js b/modules/autoshorten.js index ff4fc90..9574142 100644 --- a/modules/autoshorten.js +++ b/modules/autoshorten.js @@ -1,3 +1,8 @@ +/** + * Module Name: AutoShorten + * Description: Automatically shorten link over a certain length and post the + * short link to the channel. + */ var http = require('http'); var autoshorten = function(dbot) { @@ -5,11 +10,11 @@ var autoshorten = function(dbot) { var dbot = dbot; return { - 'listener': function(data) { - if((dbot.db.ignores.hasOwnProperty(data.user) && - dbot.db.ignores[data.user].include(name)) == false) { + 'listener': function(event) { + if((dbot.db.ignores.hasOwnProperty(event.user) && + dbot.db.ignores[event.user].include(name)) == false) { var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; - var urlMatches = data.message.match(urlRegex); + var urlMatches = event.message.match(urlRegex); if(urlMatches !== null && urlMatches[0].length > 80) { var url = urlMatches[0]; // Only doing one, screw you. @@ -24,7 +29,7 @@ var autoshorten = function(dbot) { http.get(options, function(res) { res.setEncoding('utf8'); res.on('data', function (response) { - dbot.say(data.channel, dbot.t('shorten_link', {'user': data.user}) + JSON.parse(response).surl); + event.reply(dbot.t('shorten_link', {'user': event.user}) + JSON.parse(response).surl); }); }); } @@ -32,9 +37,7 @@ var autoshorten = function(dbot) { }, 'on': 'PRIVMSG', - 'name': name, - 'ignorable': true }; } diff --git a/modules/dice.js b/modules/dice.js index 847a257..613b455 100644 --- a/modules/dice.js +++ b/modules/dice.js @@ -42,19 +42,19 @@ var normalizeDiceSpec = function (specString) { var dice = function(dbot) { var commands = { - '~roll': function (data, params) { + '~roll': function (event) { var rolls = []; - if (params.length === 1) { - params.push("d6"); + if (event.params.length === 1) { + event.params.push("d6"); } - for (var i = 1; i < params.length; i++) { - var diceSpec = parseDiceSpec(params[i]); + for (var i = 1; i < event.params.length; i++) { + var diceSpec = parseDiceSpec(event.params[i]); if (diceSpec === false) { - rolls.push([params[i], false]); + rolls.push([event.params[i], false]); } else { - rolls.push([normalizeDiceSpec(params[i]), [], diceSpec["modifier"]]); + rolls.push([normalizeDiceSpec(event.params[i]), [], diceSpec["modifier"]]); for (var j = 0; j < diceSpec["count"] ; j++) { rolls[rolls.length-1][1].push(Math.ceil(Math.random() * diceSpec["sides"])); } @@ -63,7 +63,7 @@ var dice = function(dbot) { for (var i = 0; i < rolls.length; i++) { if (rolls[i][1] === false) { - dbot.say(data.channel, rolls[i][0] + ": invalid dice spec"); + event.reply(rolls[i][0] + ": invalid dice spec"); } else { if (rolls[i][1].length > 1) { var total = " (total " + rolls[i][1].sum(); @@ -79,7 +79,7 @@ var dice = function(dbot) { } else { var total = ""; } - dbot.say(data.channel, rolls[i][0] + ": " + rolls[i][1].join(" ") + total); + event.reply(rolls[i][0] + ": " + rolls[i][1].join(" ") + total); } } } From 979399de462936cc07f289da240708009161d377 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Wed, 23 May 2012 20:05:23 +0100 Subject: [PATCH 12/51] Converted drama kicks and puns to new format. Quite tired now. --- modules/drama.js | 54 ++++++++++++++++++++++++--------------------- modules/kick.js | 57 +++++++++++++++++++----------------------------- modules/puns.js | 8 +++---- 3 files changed, 56 insertions(+), 63 deletions(-) diff --git a/modules/drama.js b/modules/drama.js index 27949b5..51e82e7 100644 --- a/modules/drama.js +++ b/modules/drama.js @@ -1,3 +1,7 @@ +/** + * Module Name: Drama + * Description: Experimental, you probably don't want it. + */ var brain = require('brain'); var drama = function(dbot) { @@ -25,29 +29,29 @@ var drama = function(dbot) { var bayes = new brain.BayesianClassifier(options); var commands = { - '~train': function(data, params) { - if(dbot.admin.include(data.user)) { - bayes.train(last[params[1]][params[2]], params[3]); - dbot.say(data.channel, 'Last thing ' + params[2] + ' said in ' + - params[1] + ' (' + last[params[1]][params[2]] + ') classified as \'' + params[3] + '\''); + '~train': function(event) { + if(dbot.admin.include(event.user)) { + bayes.train(last[event.params[1]][event.params[2]], event.params[3]); + event.reply('Last thing ' + event.params[2] + ' said in ' + + event.params[1] + ' (' + last[event.params[1]][event.params[2]] + ') classified as \'' + event.params[3] + '\''); } }, - '~rtrain': function(data, params) { - if(dbot.admin.include(data.user)) { - var category = params[1]; - params.splice(0, 2); - var msg = params.join(' '); + '~rtrain': function(event) { + if(dbot.admin.include(event.user)) { + var category = event.params[1]; + event.params.splice(0, 2); + var msg = event.params.join(' '); bayes.train(msg, category); - dbot.say(data.channel, '\'' + msg + '\' classified as \'' + category + '\''); + event.reply('\'' + msg + '\' classified as \'' + category + '\''); } }, - '~classify': function(data, params) { - params.splice(0, 1); - var msg = params.join(' '); + '~classify': function(event) { + event.params.splice(0, 1); + var msg = event.params.join(' '); bayes.classify(msg, function(category) { - dbot.say(data.channel, 'Classified as: ' + category + '!'); + event.reply('Classified as: ' + category + '!'); }.bind(this)); } } @@ -61,26 +65,26 @@ var drama = function(dbot) { var category = bayes.classify(data.message, function(category) { if(category !== 'normal') { if(category === 'beinganasshole') { - if(dbot.db.drama.beinganasshole.hasOwnProperty(data.user)) { - dbot.db.drama.beinganasshole[data.user]++; + if(dbot.db.drama.beinganasshole.hasOwnProperty(event.user)) { + dbot.db.drama.beinganasshole[event.user]++; } else { - dbot.db.drama.beinganasshole[data.user] = 1; + dbot.db.drama.beinganasshole[event.user] = 1; } } else if(category === 'sd') { - if(dbot.db.drama.sd.hasOwnProperty(data.user)) { - dbot.db.drama.sd[data.user]++; + if(dbot.db.drama.sd.hasOwnProperty(event.user)) { + dbot.db.drama.sd[event.user]++; } else { - dbot.db.drama.sd[data.user] = 1; + dbot.db.drama.sd[event.user] = 1; } } } }.bind(this)); - if(last.hasOwnProperty(data.channel)) { - last[data.channel][data.user] = data.message; + if(last.hasOwnProperty(event.channel)) { + last[event.channel][event.user] = data.message; } else { - last[data.channel] = { }; - last[data.channel][data.user] = data.message; + last[event.channel] = { }; + last[event.channel][event.user] = data.message; } }, diff --git a/modules/kick.js b/modules/kick.js index 75d8c6f..05711dd 100644 --- a/modules/kick.js +++ b/modules/kick.js @@ -4,25 +4,27 @@ var kick = function(dbot) { var commands = { // Give the number of times a given user has been kicked and has kicked // other people. - '~kickcount': function(data, params) { - if(!dbot.db.kicks.hasOwnProperty(params[1])) { + '~kickcount': function(event) { + var username = event.params[1]; + + if(!dbot.db.kicks.hasOwnProperty(username)) { var kicks = '0'; } else { - var kicks = dbot.db.kicks[params[1]]; + var kicks = dbot.db.kicks[username]; } - if(!dbot.db.kickers.hasOwnProperty(params[1])) { + if(!dbot.db.kickers.hasOwnProperty(username)) { var kicked = '0'; } else { - var kicked = dbot.db.kickers[params[1]]; + var kicked = dbot.db.kickers[username]; } - dbot.say(data.channel, dbot.t('user_kicks', {'user': params[1], 'kicks': kicks, 'kicked': kicked})); + event.reply(dbot.t('user_kicks', {'user': username, 'kicks': kicks, 'kicked': kicked})); }, // Output a list of the people who have been kicked the most and those // who have kicked other people the most. - '~kickstats': function(data, params) { + '~kickstats': function(event) { var orderedKickLeague = function(list, topWhat) { var kickArr = []; for(var kickUser in list) { @@ -42,45 +44,32 @@ var kick = function(dbot) { return kickString.slice(0, -2); }; - dbot.say(data.channel, orderedKickLeague(dbot.db.kicks, 'Kicked')); - dbot.say(data.channel, orderedKickLeague(dbot.db.kickers, 'Kickers')); + event.reply(orderedKickLeague(dbot.db.kicks, 'Kicked')); + event.reply(orderedKickLeague(dbot.db.kickers, 'Kickers')); } }; return { - // Counts kicks - 'listener': function(data) { - if(data.kickee == dbot.name) { - dbot.instance.join(data.channel); - dbot.say(data.channel, dbot.t('kicked_dbot', {'botname': dbot.name})); + 'listener': function(event) { + if(event.kickee == dbot.name) { + dbot.instance.join(event, event.channel); + event.reply(dbot.t('kicked_dbot', {'botname': dbot.name})); dbot.db.kicks[dbot.name] += 1; } else { - - if(dbot.db.modehate.include(data.user)) { - dbot.instance.send('KICK ' + data.channel + ' ' + data.user + ' :gtfo (MODEHATE)'); - - if(!dbot.db.kicks.hasOwnProperty(data.user)) { - dbot.db.kicks[data.user] = 1; - } else { - dbot.db.kicks[data.user] += 1; - } - } - - if(!dbot.db.kicks.hasOwnProperty(data.kickee)) { - dbot.db.kicks[data.kickee] = 1; + if(!dbot.db.kicks.hasOwnProperty(event.kickee)) { + dbot.db.kicks[event.kickee] = 1; } else { - dbot.db.kicks[data.kickee] += 1; + dbot.db.kicks[event.kickee] += 1; } - if(!dbot.db.kickers.hasOwnProperty(data.user)) { - dbot.db.kickers[data.user] = 1; + if(!dbot.db.kickers.hasOwnProperty(event.user)) { + dbot.db.kickers[event.user] = 1; } else { - dbot.db.kickers[data.user] += 1; + dbot.db.kickers[event.user] += 1; } - dbot.say(data.channel, data.kickee + '-- (' + - dbot.t('user_kicks', {'user': data.kickee, 'kicks': dbot.db.kicks[data.kickee], - 'kicked': dbot.db.kickers[data.kickee]}) + ')'); + event.reply(event.kickee + '-- (' + dbot.t('user_kicks', + {'user': event.kickee, 'kicks': dbot.db.kicks[event.kickee], 'kicked': dbot.db.kickers[event.kickee]}) + ')'); } }, diff --git a/modules/puns.js b/modules/puns.js index ebe5b5d..00c70bc 100644 --- a/modules/puns.js +++ b/modules/puns.js @@ -3,11 +3,11 @@ var puns = function(dbot) { var dbot = dbot; return { - 'listener': function(data) { - data.user = dbot.cleanNick(data.user); + 'listener': function(event) { + event.user = dbot.cleanNick(data.user); - if((dbot.db.ignores.hasOwnProperty(data.user) && - dbot.db.ignores[data.user].include(name)) == false) { + if((dbot.db.ignores.hasOwnProperty(event.user) && + dbot.db.ignores[event.user].include(name)) == false) { if(dbot.moduleNames.include('quotes') && dbot.db.quoteArrs.hasOwnProperty(data.user)) { data.message = '~q ' + data.user.toLowerCase(); From d6b56db06e4b69ed0b48b6485b087771d852e0f9 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Fri, 25 May 2012 16:03:36 +0100 Subject: [PATCH 13/51] Fix puns by faking an event and calling it straight in jsbot --- modules/puns.js | 11 ++++++----- run.js | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/puns.js b/modules/puns.js index 00c70bc..1693c5f 100644 --- a/modules/puns.js +++ b/modules/puns.js @@ -4,15 +4,16 @@ var puns = function(dbot) { return { 'listener': function(event) { - event.user = dbot.cleanNick(data.user); + event.user = dbot.cleanNick(event.user); if((dbot.db.ignores.hasOwnProperty(event.user) && dbot.db.ignores[event.user].include(name)) == false) { if(dbot.moduleNames.include('quotes') && - dbot.db.quoteArrs.hasOwnProperty(data.user)) { - data.message = '~q ' + data.user.toLowerCase(); - var params = data.message.split(' '); - dbot.commands[params[0]](data, params); + dbot.db.quoteArrs.hasOwnProperty(event.user)) { + event.message = '~q ' + event.user; + event.action = 'PRIVMSG'; + event.params = event.message.split(' '); + dbot.instance.emit(event) } } }, diff --git a/run.js b/run.js index 3f7af54..cdf1fa1 100644 --- a/run.js +++ b/run.js @@ -53,7 +53,7 @@ var DBot = function(timers) { // Populate bot properties with config data this.name = this.config.name || 'dbox'; this.admin = this.config.admin || [ 'reality' ]; - this.moduleNames = this.config.modules || [ 'command', 'js', 'quotes', 'admin' ]; + this.moduleNames = this.config.modules || [ 'admin', 'command', 'dice', 'js', 'kick', 'puns', 'quotes', 'spelling', 'youare' ]; this.language = this.config.language || 'english'; // It's the user's responsibility to fill this data structure up properly in From 4c72bd327cf03dd416a03e9ba6e848519fee73b1 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Fri, 25 May 2012 16:11:07 +0100 Subject: [PATCH 14/51] fixed spelling module and youare --- modules/spelling.js | 36 ++++++++++++++++++------------------ modules/youare.js | 12 ++++++------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/modules/spelling.js b/modules/spelling.js index 37f3d51..1e9cec3 100644 --- a/modules/spelling.js +++ b/modules/spelling.js @@ -3,8 +3,8 @@ var spelling = function(dbot) { var dbot = dbot; var last = {}; - var correct = function (data, correction, candidate, output_callback) { - var rawCandidates = last[data.channel][candidate].split(' ').allGroupings(); + var correct = function (event, correction, candidate, output_callback) { + var rawCandidates = last[event.channel][candidate].split(' ').allGroupings(); var candidates = []; for(var i=0;i Date: Fri, 25 May 2012 16:45:47 +0100 Subject: [PATCH 15/51] Use jsbot ignore instead of having it build into the modules --- modules/autoshorten.js | 35 ++++++++++++++++------------------- modules/puns.js | 16 ++++++---------- modules/spelling.js | 33 +++++++++++++++------------------ modules/youare.js | 9 +++------ run.js | 2 +- 5 files changed, 41 insertions(+), 54 deletions(-) diff --git a/modules/autoshorten.js b/modules/autoshorten.js index 9574142..9ad8a86 100644 --- a/modules/autoshorten.js +++ b/modules/autoshorten.js @@ -11,28 +11,25 @@ var autoshorten = function(dbot) { return { 'listener': function(event) { - if((dbot.db.ignores.hasOwnProperty(event.user) && - dbot.db.ignores[event.user].include(name)) == false) { - var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; - var urlMatches = event.message.match(urlRegex); + var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; + var urlMatches = event.message.match(urlRegex); - if(urlMatches !== null && urlMatches[0].length > 80) { - var url = urlMatches[0]; // Only doing one, screw you. - - // TODO: Make this use a decent URL shortener. Mine is shit. - var options = { - 'host': 'nc.no.de', - 'port': 80, - 'path': '/mkurl?url=' + escape(url) - }; + if(urlMatches !== null && urlMatches[0].length > 80) { + var url = urlMatches[0]; // Only doing one, screw you. + + // TODO: Make this use a decent URL shortener. Mine is shit. + var options = { + 'host': 'nc.no.de', + 'port': 80, + 'path': '/mkurl?url=' + escape(url) + }; - http.get(options, function(res) { - res.setEncoding('utf8'); - res.on('data', function (response) { - event.reply(dbot.t('shorten_link', {'user': event.user}) + JSON.parse(response).surl); - }); + http.get(options, function(res) { + res.setEncoding('utf8'); + res.on('data', function (response) { + event.reply(dbot.t('shorten_link', {'user': event.user}) + JSON.parse(response).surl); }); - } + }); } }, diff --git a/modules/puns.js b/modules/puns.js index 1693c5f..099d31a 100644 --- a/modules/puns.js +++ b/modules/puns.js @@ -5,16 +5,12 @@ var puns = function(dbot) { return { 'listener': function(event) { event.user = dbot.cleanNick(event.user); - - if((dbot.db.ignores.hasOwnProperty(event.user) && - dbot.db.ignores[event.user].include(name)) == false) { - if(dbot.moduleNames.include('quotes') && - dbot.db.quoteArrs.hasOwnProperty(event.user)) { - event.message = '~q ' + event.user; - event.action = 'PRIVMSG'; - event.params = event.message.split(' '); - dbot.instance.emit(event) - } + if(dbot.moduleNames.include('quotes') && + dbot.db.quoteArrs.hasOwnProperty(event.user)) { + event.message = '~q ' + event.user; + event.action = 'PRIVMSG'; + event.params = event.message.split(' '); + dbot.instance.emit(event) } }, diff --git a/modules/spelling.js b/modules/spelling.js index 1e9cec3..e52e2fe 100644 --- a/modules/spelling.js +++ b/modules/spelling.js @@ -39,25 +39,22 @@ var spelling = function(dbot) { return { 'listener': function(event) { - if((dbot.db.ignores.hasOwnProperty(event.user) && - dbot.db.ignores[event.user].include(name)) == false) { - var q = event.message.valMatch(/^(?:\*\*?([\d\w\s']*)|([\d\w\s']*)\*\*?)$/, 3); - var otherQ = event.message.valMatch(/^([\d\w\s]*): (?:\*\*?([\d\w\s']*)|([\d\w\s']*)\*\*?)$/, 4); - if(q) { - correct(event, q[1] || q[2], event.user, function (e) { - event.reply(dbot.t('spelling_self', e)); - }); - } else if(otherQ) { - correct(event, otherQ[2] || otherQ[3], otherQ[1], function (e) { - event.reply(dbot.t('spelling_other', e)); - }); + var q = event.message.valMatch(/^(?:\*\*?([\d\w\s']*)|([\d\w\s']*)\*\*?)$/, 3); + var otherQ = event.message.valMatch(/^([\d\w\s]*): (?:\*\*?([\d\w\s']*)|([\d\w\s']*)\*\*?)$/, 4); + if(q) { + correct(event, q[1] || q[2], event.user, function (e) { + event.reply(dbot.t('spelling_self', e)); + }); + } else if(otherQ) { + correct(event, otherQ[2] || otherQ[3], otherQ[1], function (e) { + event.reply(dbot.t('spelling_other', e)); + }); + } else { + if(last.hasOwnProperty(event.channel)) { + last[event.channel][event.user] = event.message; } else { - if(last.hasOwnProperty(event.channel)) { - last[event.channel][event.user] = event.message; - } else { - last[event.channel] = { }; - last[event.channel][event.user] = event.message; - } + last[event.channel] = { }; + last[event.channel][event.user] = event.message; } } }, diff --git a/modules/youare.js b/modules/youare.js index bc7f553..3627b28 100644 --- a/modules/youare.js +++ b/modules/youare.js @@ -3,13 +3,10 @@ var youAre = function(dbot) { return { 'listener': function(event) { - if((dbot.db.ignores.hasOwnProperty(event.user) && - dbot.db.ignores[event.user].include(name)) == false) { - var key = event.message.valMatch(/(\bis\b|\bare\b)\s+([\w\s\d]*?)(\s+)?(,|\.|\band\b|$)/, 5); + var key = event.message.valMatch(/(\bis\b|\bare\b)\s+([\w\s\d]*?)(\s+)?(,|\.|\band\b|$)/, 5); - if(key && key[2] != "" && Number.prototype.chanceIn(1, 100) && event.user != 'aisbot') { - event.reply(event.user + ': You\'re ' + key[2] + '.'); - } + if(key && key[2] != "" && Number.prototype.chanceIn(1, 100) && event.user != 'aisbot') { + event.reply(event.user + ': You\'re ' + key[2] + '.'); } }, diff --git a/run.js b/run.js index cdf1fa1..5a633ad 100644 --- a/run.js +++ b/run.js @@ -53,7 +53,7 @@ var DBot = function(timers) { // Populate bot properties with config data this.name = this.config.name || 'dbox'; this.admin = this.config.admin || [ 'reality' ]; - this.moduleNames = this.config.modules || [ 'admin', 'command', 'dice', 'js', 'kick', 'puns', 'quotes', 'spelling', 'youare' ]; + this.moduleNames = this.config.modules || [ 'ignore', 'admin', 'command', 'dice', 'js', 'kick', 'puns', 'quotes', 'spelling', 'youare' ]; this.language = this.config.language || 'english'; // It's the user's responsibility to fill this data structure up properly in From 13892f3a1fc35d76ce81fdd3f27f94c1ef90685b Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Fri, 25 May 2012 16:49:45 +0100 Subject: [PATCH 16/51] Whoops, forgot to commit the actual ignore module. --- modules/ignore.js | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 modules/ignore.js diff --git a/modules/ignore.js b/modules/ignore.js new file mode 100644 index 0000000..60d75cc --- /dev/null +++ b/modules/ignore.js @@ -0,0 +1,81 @@ +/** + * Module Name: Ignore + * Description: Handles commands in which users can choose to ignore listeners + * and commands from certain modules. It also populates the JSBot instance with + * this information, since that actually performs the ignorance. + */ +var ignore = function(dbot) { + var commands = { + '~ignore': function(event) { + var ignorableModules = []; + for(var i=0;i Date: Fri, 25 May 2012 21:00:38 +0100 Subject: [PATCH 17/51] webPort default --- modules/web.js | 3 --- run.js | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/web.js b/modules/web.js index c11c516..c2bc7bf 100644 --- a/modules/web.js +++ b/modules/web.js @@ -1,9 +1,6 @@ var express = require('express'); -// Web interface module using the express framework var webInterface = function(dbot) { - var dbot = dbot; - var pub = 'public'; var app = express.createServer(); diff --git a/run.js b/run.js index 5a633ad..3b9fb68 100644 --- a/run.js +++ b/run.js @@ -55,6 +55,7 @@ var DBot = function(timers) { this.admin = this.config.admin || [ 'reality' ]; this.moduleNames = this.config.modules || [ 'ignore', 'admin', 'command', 'dice', 'js', 'kick', 'puns', 'quotes', 'spelling', 'youare' ]; this.language = this.config.language || 'english'; + this.webPort = this.config.webPort || 80; // It's the user's responsibility to fill this data structure up properly in // the config file. They can d-d-d-deal with it if they have problems. From 1e23e188071ecc81135eabb700a5483ea64204b3 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Fri, 25 May 2012 21:15:06 +0100 Subject: [PATCH 18/51] debugon server join --- run.js | 1 + 1 file changed, 1 insertion(+) diff --git a/run.js b/run.js index 3b9fb68..dc5ba08 100644 --- a/run.js +++ b/run.js @@ -78,6 +78,7 @@ var DBot = function(timers) { var server = this.servers[name]; this.instance.addConnection(name, server.server, server.port, this.admin, function(event) { server.channels.each(function(channel) { + console.log('joining ' + channel + ' on ' + server.server); this.instance.join(event, channel) }.bind(this)); }.bind(this), server.nickserv, server.password); From 40ddb682fa25436a0cc177b31406e05c02c7f462 Mon Sep 17 00:00:00 2001 From: Luke Slater Date: Fri, 25 May 2012 21:36:13 +0100 Subject: [PATCH 19/51] fix channel joins on multi server --- run.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/run.js b/run.js index dc5ba08..9973c64 100644 --- a/run.js +++ b/run.js @@ -77,10 +77,10 @@ var DBot = function(timers) { if(this.servers.hasOwnProperty(name)) { var server = this.servers[name]; this.instance.addConnection(name, server.server, server.port, this.admin, function(event) { - server.channels.each(function(channel) { - console.log('joining ' + channel + ' on ' + server.server); - this.instance.join(event, channel) - }.bind(this)); + var server = this.servers[event.server]; + for(var i=0;i Date: Sat, 26 May 2012 22:28:34 +0100 Subject: [PATCH 20/51] Links module which can retrieve titles --- modules/link.js | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 modules/link.js diff --git a/modules/link.js b/modules/link.js new file mode 100644 index 0000000..6eeaf88 --- /dev/null +++ b/modules/link.js @@ -0,0 +1,55 @@ +/** + * Module Name: Link + * Description: Stores recent channel links, with commands to retrieve + * information about links. + */ +var request = require('request'); +var link = function(dbot) { + var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; + var links = {}; + + var commands = { + '~title': function(event) { + var link = links[event.channel]; + if(event.params[1] !== undefined) { + var urlMatches = event.params[1].match(urlRegex); + if(urlMatches !== null) { + link = urlMatches[0]; + } + } + + request(link, function (error, response, body) { + if(!error && response.statusCode == 200) { + var title = body.valMatch(/(.*)<\/title>/, 2); + if(title) { + event.reply(title[1]); + } else { + event.reply('no title found'); + } + } + }); + } + }; + + return { + 'name': 'js', + 'ignorable': true, + + 'onLoad': function() { + return commands; + }, + + 'listener': function(event) { + var urlMatches = event.message.match(urlRegex); + if(urlMatches !== null) { + links[event.channel] = urlMatches[0]; + } + }, + + 'on': 'PRIVMSG' + }; +}; + +exports.fetch = function(dbot) { + return link(dbot); +}; From 181c3a2628d07e7a4357c73c4f73921f2fcac5ad Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Sat, 26 May 2012 23:32:26 +0100 Subject: [PATCH 21/51] Change the name metadata from js to link... --- modules/link.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/link.js b/modules/link.js index 6eeaf88..82df1c4 100644 --- a/modules/link.js +++ b/modules/link.js @@ -32,7 +32,7 @@ var link = function(dbot) { }; return { - 'name': 'js', + 'name': 'link', 'ignorable': true, 'onLoad': function() { From e5a9142384644b93030f17532d6515711db9d7b1 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Sun, 3 Jun 2012 21:17:25 +0100 Subject: [PATCH 22/51] read title even when over multiple lines --- modules/link.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/link.js b/modules/link.js index 82df1c4..dacb36a 100644 --- a/modules/link.js +++ b/modules/link.js @@ -20,6 +20,7 @@ var link = function(dbot) { request(link, function (error, response, body) { if(!error && response.statusCode == 200) { + body = body.replace(/(\r\n|\n\r|\n)/gm, " "); var title = body.valMatch(/<title>(.*)<\/title>/, 2); if(title) { event.reply(title[1]); From 3f38356717b401df6680aa867d95c5036819cd4a Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Mon, 4 Jun 2012 01:19:35 +0100 Subject: [PATCH 23/51] no rmlast limit --- modules/quotes.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/quotes.js b/modules/quotes.js index 64829ed..eb02105 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -93,7 +93,7 @@ var quotes = function(dbot) { }, '~rmlast': function(event) { - if(rmAllowed == true || dbot.admin.include(event.user)) { + //if(rmAllowed == true || dbot.admin.include(event.user)) { var key = event.input[1].trim().toLowerCase(); if(quotes.hasOwnProperty(key)) { if(!dbot.db.locks.include(key) || dbot.admin.include(event.user)) { @@ -109,9 +109,9 @@ var quotes = function(dbot) { } else { event.reply(dbot.t('no_quotes', {'category': q[1]})); } - } else { + /*} else { event.reply(dbot.t('rmlast_spam')); - } + }*/ }, /*'~rm': function(data, params) { From 034525e601541aa7768575be125602f0f84b83a6 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Mon, 4 Jun 2012 03:03:51 +0100 Subject: [PATCH 24/51] readd rmlast limit --- modules/quotes.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/quotes.js b/modules/quotes.js index eb02105..64829ed 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -93,7 +93,7 @@ var quotes = function(dbot) { }, '~rmlast': function(event) { - //if(rmAllowed == true || dbot.admin.include(event.user)) { + if(rmAllowed == true || dbot.admin.include(event.user)) { var key = event.input[1].trim().toLowerCase(); if(quotes.hasOwnProperty(key)) { if(!dbot.db.locks.include(key) || dbot.admin.include(event.user)) { @@ -109,9 +109,9 @@ var quotes = function(dbot) { } else { event.reply(dbot.t('no_quotes', {'category': q[1]})); } - /*} else { + } else { event.reply(dbot.t('rmlast_spam')); - }*/ + } }, /*'~rm': function(data, params) { From 54dc7f2236502609a5ac6cb14ade4a9b058ab26d Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Tue, 5 Jun 2012 00:17:51 +0100 Subject: [PATCH 25/51] Changed commands to property rather than object to be returned by onLoad functionality --- modules/admin.js | 5 ++--- modules/autoshorten.js | 11 ++++------- modules/command.js | 5 ++--- modules/drama.js | 13 ++++--------- modules/ignore.js | 2 +- modules/js.js | 5 +---- modules/kick.js | 15 +++++---------- modules/link.js | 6 +----- modules/puns.js | 12 +++++------- modules/quotes.js | 9 ++++----- modules/spelling.js | 12 ++++-------- modules/web.js | 9 ++++----- modules/youare.js | 12 ++++-------- run.js | 6 +++++- 14 files changed, 46 insertions(+), 76 deletions(-) diff --git a/modules/admin.js b/modules/admin.js index 3c15948..2a79884 100644 --- a/modules/admin.js +++ b/modules/admin.js @@ -114,6 +114,7 @@ var admin = function(dbot) { return { 'name': 'admin', + 'ignorable': false, /** * Run the appropriate admin command given the input (and user). @@ -125,9 +126,7 @@ var admin = function(dbot) { dbot.save(); } }, - - 'on': 'PRIVMSG', - 'ignorable': false + 'on': 'PRIVMSG' }; }; diff --git a/modules/autoshorten.js b/modules/autoshorten.js index 9ad8a86..426941a 100644 --- a/modules/autoshorten.js +++ b/modules/autoshorten.js @@ -6,10 +6,10 @@ var http = require('http'); var autoshorten = function(dbot) { - var name = 'autoshorten'; - var dbot = dbot; - return { + 'name': 'autoshorten', + 'ignorable': true, + 'listener': function(event) { var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; var urlMatches = event.message.match(urlRegex); @@ -32,10 +32,7 @@ var autoshorten = function(dbot) { }); } }, - - 'on': 'PRIVMSG', - 'name': name, - 'ignorable': true + 'on': 'PRIVMSG' }; } diff --git a/modules/command.js b/modules/command.js index 6c6c118..5f78d8e 100644 --- a/modules/command.js +++ b/modules/command.js @@ -51,6 +51,7 @@ var command = function(dbot) { return { 'name': 'command', + 'ignorable': false, /** * Run the appropriate command given the input. @@ -76,9 +77,7 @@ var command = function(dbot) { } } }, - - 'on': 'PRIVMSG', - 'ignorable': false + 'on': 'PRIVMSG' }; }; diff --git a/modules/drama.js b/modules/drama.js index 51e82e7..fc9aa3a 100644 --- a/modules/drama.js +++ b/modules/drama.js @@ -57,9 +57,9 @@ var drama = function(dbot) { } return { - 'onLoad': function() { - return commands; - }, + 'name': 'drama', + 'ignorable': false, + 'commands': commands, 'listener': function(data) { var category = bayes.classify(data.message, function(category) { @@ -87,12 +87,7 @@ var drama = function(dbot) { last[event.channel][event.user] = data.message; } }, - - 'on': 'PRIVMSG', - - 'name': 'drama', - - 'ignorable': false + 'on': 'PRIVMSG' }; } diff --git a/modules/ignore.js b/modules/ignore.js index 60d75cc..b7330b7 100644 --- a/modules/ignore.js +++ b/modules/ignore.js @@ -61,6 +61,7 @@ var ignore = function(dbot) { return { 'name': 'ignore', 'ignorable': false, + 'commands': commands, 'onLoad': function() { dbot.instance.clearIgnores(); @@ -71,7 +72,6 @@ var ignore = function(dbot) { } } } - return commands; } }; }; diff --git a/modules/js.js b/modules/js.js index 3aee828..024f763 100644 --- a/modules/js.js +++ b/modules/js.js @@ -34,10 +34,7 @@ var js = function(dbot) { return { 'name': 'js', 'ignorable': true, - - 'onLoad': function() { - return commands; - } + 'commands': commands }; }; diff --git a/modules/kick.js b/modules/kick.js index 05711dd..ff1e42d 100644 --- a/modules/kick.js +++ b/modules/kick.js @@ -50,6 +50,10 @@ var kick = function(dbot) { }; return { + 'name': 'kick', + 'ignorable': false, + 'commands': commands, + 'listener': function(event) { if(event.kickee == dbot.name) { dbot.instance.join(event, event.channel); @@ -72,16 +76,7 @@ var kick = function(dbot) { {'user': event.kickee, 'kicks': dbot.db.kicks[event.kickee], 'kicked': dbot.db.kickers[event.kickee]}) + ')'); } }, - - on: 'KICK', - - 'onLoad': function() { - return commands; - }, - - 'name': 'kick', - - 'ignorable': false + on: 'KICK' }; }; diff --git a/modules/link.js b/modules/link.js index 82df1c4..9d37459 100644 --- a/modules/link.js +++ b/modules/link.js @@ -34,10 +34,7 @@ var link = function(dbot) { return { 'name': 'link', 'ignorable': true, - - 'onLoad': function() { - return commands; - }, + 'commands': commands, 'listener': function(event) { var urlMatches = event.message.match(urlRegex); @@ -45,7 +42,6 @@ var link = function(dbot) { links[event.channel] = urlMatches[0]; } }, - 'on': 'PRIVMSG' }; }; diff --git a/modules/puns.js b/modules/puns.js index 099d31a..7144932 100644 --- a/modules/puns.js +++ b/modules/puns.js @@ -3,6 +3,9 @@ var puns = function(dbot) { var dbot = dbot; return { + 'name': name, + 'ignorable': true, + 'listener': function(event) { event.user = dbot.cleanNick(event.user); if(dbot.moduleNames.include('quotes') && @@ -10,15 +13,10 @@ var puns = function(dbot) { event.message = '~q ' + event.user; event.action = 'PRIVMSG'; event.params = event.message.split(' '); - dbot.instance.emit(event) + dbot.instance.emit(event); } }, - - 'on': 'JOIN', - - 'name': name, - - 'ignorable': true + 'on': 'JOIN' }; } diff --git a/modules/quotes.js b/modules/quotes.js index 64829ed..0a044a3 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -218,11 +218,14 @@ var quotes = function(dbot) { commands['~qadd'].regex = [/^~qadd ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; return { + 'name': 'quotes', + 'ignorable': true, + 'commands': commands, + 'onLoad': function() { dbot.timers.addTimer(1000 * 60 * 3, function() { rmAllowed = true; }); - return commands; }, /* For automatic quote retrieval @@ -254,10 +257,6 @@ var quotes = function(dbot) { }, 'on': 'PRIVMSG',*/ - - 'name': name, - - 'ignorable': true }; }; diff --git a/modules/spelling.js b/modules/spelling.js index e52e2fe..28d6006 100644 --- a/modules/spelling.js +++ b/modules/spelling.js @@ -1,6 +1,4 @@ var spelling = function(dbot) { - var name = 'spelling'; - var dbot = dbot; var last = {}; var correct = function (event, correction, candidate, output_callback) { @@ -38,6 +36,9 @@ var spelling = function(dbot) { } return { + 'name': 'spelling', + 'ignorable': true, + 'listener': function(event) { var q = event.message.valMatch(/^(?:\*\*?([\d\w\s']*)|([\d\w\s']*)\*\*?)$/, 3); var otherQ = event.message.valMatch(/^([\d\w\s]*): (?:\*\*?([\d\w\s']*)|([\d\w\s']*)\*\*?)$/, 4); @@ -58,12 +59,7 @@ var spelling = function(dbot) { } } }, - - 'on': 'PRIVMSG', - - 'name': name, - - 'ignorable': true + 'on': 'PRIVMSG' } } diff --git a/modules/web.js b/modules/web.js index c2bc7bf..911e88f 100644 --- a/modules/web.js +++ b/modules/web.js @@ -37,13 +37,12 @@ var webInterface = function(dbot) { app.listen(dbot.webPort); return { + 'name': 'web', + 'ignorable': false, + 'onDestroy': function() { app.close(); - }, - - 'name': 'web', - - 'ignorable': false + } }; }; diff --git a/modules/youare.js b/modules/youare.js index 3627b28..ddb25e0 100644 --- a/modules/youare.js +++ b/modules/youare.js @@ -1,7 +1,8 @@ var youAre = function(dbot) { - var name = 'youare'; - return { + 'name': 'youare', + 'ignorable': false, + 'listener': function(event) { var key = event.message.valMatch(/(\bis\b|\bare\b)\s+([\w\s\d]*?)(\s+)?(,|\.|\band\b|$)/, 5); @@ -9,12 +10,7 @@ var youAre = function(dbot) { event.reply(event.user + ': You\'re ' + key[2] + '.'); } }, - - 'on': 'PRIVMSG', - - 'name': name, - - 'ignorable': false + 'on': 'PRIVMSG' }; }; diff --git a/run.js b/run.js index 9973c64..e6505a5 100644 --- a/run.js +++ b/run.js @@ -158,7 +158,11 @@ DBot.prototype.reloadModules = function() { } if(module.onLoad) { - var newCommands = module.onLoad(); + module.onLoad(); + } + + if(module.commands) { + var newCommands = module.commands; for(key in newCommands) { if(newCommands.hasOwnProperty(key) && Object.prototype.isFunction(newCommands[key])) { this.commands[key] = newCommands[key]; From 0a2b94fa654969e7d55d9cc3f46864f78ad41d5e Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Wed, 13 Jun 2012 21:11:00 +0100 Subject: [PATCH 26/51] newpoll test --- modules/poll.js | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 modules/poll.js diff --git a/modules/poll.js b/modules/poll.js new file mode 100644 index 0000000..ff2e3ba --- /dev/null +++ b/modules/poll.js @@ -0,0 +1,48 @@ +var poll = function(dbot) { + var polls = dbot.db.polls; + var commands = { + '~newpoll': function(event) { + var name = event.input[1]; + if(name === undefined || name === 'help') { + event.reply(dbot.t('newpoll_usage')); + } else { + if(polls.hasOwnProperty(name)) { + event.reply(dbot.t('poll_exists')); + } else { + polls[name] = { + 'name': name, + 'owner': event.user + }; + + var options = event.input[2].split(','); + for(var i=0;i<options.length;i++) { + polls[name]['votes'][options[i]] = 0; + } + } + } + }, + + '~vote': function(event) { + + }, + + '~rmpoll': function(event) { + + }, + + '~results': function(event) { + + } + }; + commands['~newpoll'].regex = [/~newpoll ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; + + return { + 'name': 'poll', + 'ignorable': true, + 'commands': commands + }; +}; + +exports.fetch = function(dbot) { + return poll(dbot); +} From cf8da90c6b457ffaaf2c139863065d9e8dba8739 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Wed, 13 Jun 2012 21:16:29 +0100 Subject: [PATCH 27/51] whoops --- modules/poll.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/poll.js b/modules/poll.js index ff2e3ba..52beeab 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -11,7 +11,8 @@ var poll = function(dbot) { } else { polls[name] = { 'name': name, - 'owner': event.user + 'owner': event.user, + 'votes': {} }; var options = event.input[2].split(','); From 66554605e7926a9cac5da92d6387dd254db3aa07 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Thu, 14 Jun 2012 23:32:16 +0100 Subject: [PATCH 28/51] poll changed --- modules/poll.js | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/modules/poll.js b/modules/poll.js index 52beeab..31700ae 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -3,6 +3,9 @@ var poll = function(dbot) { var commands = { '~newpoll': function(event) { var name = event.input[1]; + var options = event.input[2].split(','); + var description = event.input[3]; + if(name === undefined || name === 'help') { event.reply(dbot.t('newpoll_usage')); } else { @@ -11,20 +14,40 @@ var poll = function(dbot) { } else { polls[name] = { 'name': name, + 'description': description, 'owner': event.user, - 'votes': {} + 'votes': {}, + 'votees': [] }; - var options = event.input[2].split(','); for(var i=0;i<options.length;i++) { polls[name]['votes'][options[i]] = 0; } + + event.reply(dbot.t('poll_created', {'name': name, 'options': options.join(' ')})); } } }, '~vote': function(event) { + var name = event.input[1]; + var vote = event.input[2]; + if(polls.hasOwnProperty(name)) { + if(event.user in polls[name].votees) { + event.reply(dbot.t('alread_voted')); + } else { + if(polls[name].votes.hasOwnProperty(vote)) { + polls[name].votes[vote]++; + polls[name].votees.push(event.user); + event.reply(dbot.t('voted', {'vote': vote})); + } else { + event.reply(dbot.t('invalid_vote', {'vote': vote})); + } + } + } else { + event.reply(dbot.t('poll_unexistent')); + } }, '~rmpoll': function(event) { @@ -35,7 +58,8 @@ var poll = function(dbot) { } }; - commands['~newpoll'].regex = [/~newpoll ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; + commands['~newpoll'].regex = [/~newpoll ([^ ]+) \[options=(\[^ ]+)\] (.+)/, 4]; + commands['~vote'].regex = [/~vote ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; return { 'name': 'poll', From 30cd5d499dda5a612e9d05732ae079532b91bc4d Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Thu, 14 Jun 2012 23:36:52 +0100 Subject: [PATCH 29/51] fixed the regex on ~newpoll --- modules/poll.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/poll.js b/modules/poll.js index 31700ae..ee602eb 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -58,7 +58,7 @@ var poll = function(dbot) { } }; - commands['~newpoll'].regex = [/~newpoll ([^ ]+) \[options=(\[^ ]+)\] (.+)/, 4]; + commands['~newpoll'].regex = [/~newpoll ([^ ]+) \[options=([^ ]+)\] (.+)/, 4]; commands['~vote'].regex = [/~vote ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; return { From ffd383365ea26083e6db4dc2e889da7b2dfa79d6 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Thu, 14 Jun 2012 23:42:06 +0100 Subject: [PATCH 30/51] Fixed regex for vote --- modules/poll.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/poll.js b/modules/poll.js index ee602eb..073181f 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -59,7 +59,7 @@ var poll = function(dbot) { } }; commands['~newpoll'].regex = [/~newpoll ([^ ]+) \[options=([^ ]+)\] (.+)/, 4]; - commands['~vote'].regex = [/~vote ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; + commands['~vote'].regex = [/~vote ([^ ]+) ([^ ]+)/, 3]; return { 'name': 'poll', From d012ff4394ed61e5b683c42fe87045b4114dbf55 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Thu, 14 Jun 2012 23:57:07 +0100 Subject: [PATCH 31/51] wrote some of viewpoll. Hello dan. --- modules/poll.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/poll.js b/modules/poll.js index 073181f..13a65f7 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -34,7 +34,7 @@ var poll = function(dbot) { var vote = event.input[2]; if(polls.hasOwnProperty(name)) { - if(event.user in polls[name].votees) { + if(polls[name].votees.include(event.user)) { event.reply(dbot.t('alread_voted')); } else { if(polls[name].votes.hasOwnProperty(vote)) { @@ -50,16 +50,18 @@ var poll = function(dbot) { } }, - '~rmpoll': function(event) { - - }, - - '~results': function(event) { + '~viewpoll': function(event) { + var name = event.input[1]; + if(polls.hasOwnProperty(name)) { + } else { + event.reply(dbot.t('poll_unexistent')); + } } }; commands['~newpoll'].regex = [/~newpoll ([^ ]+) \[options=([^ ]+)\] (.+)/, 4]; commands['~vote'].regex = [/~vote ([^ ]+) ([^ ]+)/, 3]; + commands['~viewpoll'].regex = [/~viewpoll ([^ ]+)/, 2]; return { 'name': 'poll', From 333e3c592d216a65155ff180c77071d78be22259 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 00:07:15 +0100 Subject: [PATCH 32/51] wrote strings for polls --- modules/poll.js | 8 ++++---- strings.json | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/modules/poll.js b/modules/poll.js index 13a65f7..7fa3c6c 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -10,7 +10,7 @@ var poll = function(dbot) { event.reply(dbot.t('newpoll_usage')); } else { if(polls.hasOwnProperty(name)) { - event.reply(dbot.t('poll_exists')); + event.reply(dbot.t('poll_exists', {'name': name})); } else { polls[name] = { 'name': name, @@ -24,7 +24,7 @@ var poll = function(dbot) { polls[name]['votes'][options[i]] = 0; } - event.reply(dbot.t('poll_created', {'name': name, 'options': options.join(' ')})); + event.reply(dbot.t('poll_created', {'name': name, 'description': description})); } } }, @@ -46,7 +46,7 @@ var poll = function(dbot) { } } } else { - event.reply(dbot.t('poll_unexistent')); + event.reply(dbot.t('poll_unexistent', {'name': name})); } }, @@ -55,7 +55,7 @@ var poll = function(dbot) { if(polls.hasOwnProperty(name)) { } else { - event.reply(dbot.t('poll_unexistent')); + event.reply(dbot.t('poll_unexistent', {'name': name})); } } }; diff --git a/strings.json b/strings.json index e624319..7be0fa8 100644 --- a/strings.json +++ b/strings.json @@ -195,5 +195,26 @@ }, "part": { "english": "Left {channel}" + }, + "newpoll_usage": { + "english": "Usage: ~newpoll name [options=opt1,opt2,opt3] description" + }, + "poll_exists": { + "english": "Poll '{name}' already exists." + }, + "poll_created": { + "english": "Poll '{name}' created ({description}). Cast thy votations!" + }, + "already_voted": { + "english": "You've already voted in this poll!" + }, + "voted": { + "english": "Voted for {vote}" + }, + "invalid_vote": { + "english": "Invalid vote: {vote}" + }, + "poll_unexistent": { + "english": "Poll '{name}' doesn't exist." } } From b9b5d9913d9d656ed04e1bc56d0ca59bfde5b814 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 10:52:11 +0100 Subject: [PATCH 33/51] Automatically replace spaces in quotes with underscores, then use that quote if the originally given quote can't be found --- modules/quotes.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/quotes.js b/modules/quotes.js index 0a044a3..5bc9bf3 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -41,8 +41,15 @@ var quotes = function(dbot) { // Retrieve quote from a category in the database. '~q': function(event) { var key = event.input[1].trim().toLowerCase(); + var altKey; + if(key.split(' ').length > 0) { + altKey = key.replace(/ /g, '_'); + } + if(quotes.hasOwnProperty(key)) { event.reply(key + ': ' + interpolatedQuote(key)); + } else if(quotes.hasOwnProperty(altKey)) { + event.reply(key + ': ' + interpolatedQuote(altKey)); } else { event.reply(dbot.t('category_not_found', {'category': key})); } From 7124798398b19d6ebfcf50c9100f3c348a3acadb Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 10:53:45 +0100 Subject: [PATCH 34/51] Make it show the new key for the previous change --- modules/quotes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quotes.js b/modules/quotes.js index 5bc9bf3..a85ebf0 100644 --- a/modules/quotes.js +++ b/modules/quotes.js @@ -49,7 +49,7 @@ var quotes = function(dbot) { if(quotes.hasOwnProperty(key)) { event.reply(key + ': ' + interpolatedQuote(key)); } else if(quotes.hasOwnProperty(altKey)) { - event.reply(key + ': ' + interpolatedQuote(altKey)); + event.reply(altKey + ': ' + interpolatedQuote(altKey)); } else { event.reply(dbot.t('category_not_found', {'category': key})); } From f70c92c16d70255059c5933709916e3fc65cfe14 Mon Sep 17 00:00:00 2001 From: Daniel Evans <danharibo@gmail.com> Date: Fri, 15 Jun 2012 16:15:02 +0100 Subject: [PATCH 35/51] Web display for poll module --- modules/poll.js | 3 +++ modules/web.js | 23 +++++++++++++++++++++++ public/styles.css | 40 ++++++++++++++++++++++++++++++++++++++++ run.js | 2 +- views/polllist.jade | 7 +++++++ views/polls.jade | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 views/polllist.jade create mode 100644 views/polls.jade diff --git a/modules/poll.js b/modules/poll.js index 7fa3c6c..73a9c6e 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -1,4 +1,7 @@ var poll = function(dbot) { + if(!dbot.db.hasOwnProperty('polls')) { + dbot.db.polls = {}; + } var polls = dbot.db.polls; var commands = { '~newpoll': function(event) { diff --git a/modules/web.js b/modules/web.js index 911e88f..9c88f69 100644 --- a/modules/web.js +++ b/modules/web.js @@ -33,6 +33,29 @@ var webInterface = function(dbot) { var rCategory = Object.keys(dbot.db.quoteArrs).random(); res.render('quotes', { 'name': dbot.name, 'quotes': dbot.db.quoteArrs[rCategory], locals: { 'url_regex': RegExp.prototype.url_regex() } }); }); + + // Lists all of the polls + app.get('/polls', function(req, res) { + res.render('polllist', { 'name': dbot.name, 'polllist': Object.keys(dbot.db.polls) }); + }); + + // Shows the results of a poll + app.get('/polls/:key', function(req, res) { + var key = req.params.key.toLowerCase(); + if(dbot.db.polls.hasOwnProperty(key)) { + // tally the votes + var totalVotes = 0; + for( var v in dbot.db.polls[key].votes ) { + var N = Number(dbot.db.polls[key].votes[v]); + if( !isNaN(N) ) { + totalVotes += N; + } + } + res.render('polls', { 'name': dbot.name, 'description': dbot.db.polls[key].description, 'votees': dbot.db.polls[key].votees, 'options': dbot.db.polls[key].votes, locals: { 'totalVotes': totalVotes, 'url_regex': RegExp.prototype.url_regex() } }); + } else { + res.render('error', { 'name': dbot.name, 'message': 'No polls under that key.' }); + } + }); app.listen(dbot.webPort); diff --git a/public/styles.css b/public/styles.css index 600520d..6d08800 100644 --- a/public/styles.css +++ b/public/styles.css @@ -21,6 +21,15 @@ body { text-shadow: 1px 1px 2px #2B2B2B; } +h1,h2 { + margin: 0; + padding: 0; +} + +p { + margin: 15px 5px; +} + div#page { width: 90%; margin: 0 auto 0 auto; @@ -105,3 +114,34 @@ li.quote { img { max-width: 100%; } + +/* Polls */ +#votelist { + margin: 10px 0; + padding: 0 40px; +} + +li.option { + list-style: none; + text-align: left; + font-size: 1.2em; +} + +li.option-votes { + list-style: none; + text-align: left; + margin-bottom: 10px; +} + +.vote-percentage { + height: 20px; + background: #444; +} +.vote-track { + height: 20px; + width: 100%; + background: #EEE; + margin: 2px 0; + + box-shadow: inset 0px 0px 3px #444; +} diff --git a/run.js b/run.js index e6505a5..ca207e6 100644 --- a/run.js +++ b/run.js @@ -53,7 +53,7 @@ var DBot = function(timers) { // Populate bot properties with config data this.name = this.config.name || 'dbox'; this.admin = this.config.admin || [ 'reality' ]; - this.moduleNames = this.config.modules || [ 'ignore', 'admin', 'command', 'dice', 'js', 'kick', 'puns', 'quotes', 'spelling', 'youare' ]; + this.moduleNames = this.config.modules || [ 'ignore', 'admin', 'command', 'dice', 'js', 'kick', 'puns', 'quotes', 'spelling', 'youare', 'web', 'poll' ]; this.language = this.config.language || 'english'; this.webPort = this.config.webPort || 80; diff --git a/views/polllist.jade b/views/polllist.jade new file mode 100644 index 0000000..5f0e73b --- /dev/null +++ b/views/polllist.jade @@ -0,0 +1,7 @@ +div#controls + input(type="text", name="search", id="search-text", oninput="search(this.value)") +ul#quotelist + -each poll in polllist + a(href='/polls/'+poll) + li.quotes #{poll} + diff --git a/views/polls.jade b/views/polls.jade new file mode 100644 index 0000000..aed4c0f --- /dev/null +++ b/views/polls.jade @@ -0,0 +1,35 @@ +h2 #{description} +p Voters (#{locals.totalVotes}): + -each voter in votees + | #{voter} +ul#votelist + -var hasYouTubeVids=false + -each votes,option in options + -var percentage = votes/locals.totalVotes*100 + -if(options.hasOwnProperty(option)) + -if(option.match(locals.url_regex)) + li.option + -if(option.match(/(jpg|png|gif|jpeg|tiff)$/)) + a(href=option) + img(src=option) + -else if(option.match(/youtube.com\/watch/)) + -hasYouTubeVids = true + span(class='ytplaceholder') + =option + -else + a(href=option) + =option + -else + li.option #{option} + li.option-votes + .vote-track + -if(!isNaN(percentage)) + .vote-percentage(style="width: #{percentage}%") + -if(votes == 1) + |#{votes} vote + -else + |#{votes} votes + -if(!isNaN(percentage)) + |(#{percentage.toFixed(2)}%) + -if(hasYouTubeVids) + script(src='/ytembed.js') From a409af06fd13791275bd165d5279e9543eb24819 Mon Sep 17 00:00:00 2001 From: Daniel Evans <danharibo@gmail.com> Date: Fri, 15 Jun 2012 17:17:58 +0200 Subject: [PATCH 36/51] Undoing my commit. --- run.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run.js b/run.js index ca207e6..e6505a5 100644 --- a/run.js +++ b/run.js @@ -53,7 +53,7 @@ var DBot = function(timers) { // Populate bot properties with config data this.name = this.config.name || 'dbox'; this.admin = this.config.admin || [ 'reality' ]; - this.moduleNames = this.config.modules || [ 'ignore', 'admin', 'command', 'dice', 'js', 'kick', 'puns', 'quotes', 'spelling', 'youare', 'web', 'poll' ]; + this.moduleNames = this.config.modules || [ 'ignore', 'admin', 'command', 'dice', 'js', 'kick', 'puns', 'quotes', 'spelling', 'youare' ]; this.language = this.config.language || 'english'; this.webPort = this.config.webPort || 80; From 0eb051eef9e6c8b5f19e8584a1a7c90770d4c6e6 Mon Sep 17 00:00:00 2001 From: Daniel Evans <danharibo@gmail.com> Date: Fri, 15 Jun 2012 17:18:36 +0200 Subject: [PATCH 37/51] Fixed formatting. --- modules/poll.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/poll.js b/modules/poll.js index 73a9c6e..8b883c1 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -1,7 +1,7 @@ var poll = function(dbot) { - if(!dbot.db.hasOwnProperty('polls')) { - dbot.db.polls = {}; - } + if(!dbot.db.hasOwnProperty('polls')) { + dbot.db.polls = {}; + } var polls = dbot.db.polls; var commands = { '~newpoll': function(event) { From 800faf5a880abfe9e9d5a42d38ff740dd38ae4ac Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 16:26:13 +0100 Subject: [PATCH 38/51] nother space in thing? --- views/polls.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/polls.jade b/views/polls.jade index aed4c0f..95f6d73 100644 --- a/views/polls.jade +++ b/views/polls.jade @@ -1,7 +1,7 @@ h2 #{description} p Voters (#{locals.totalVotes}): -each voter in votees - | #{voter} + | #{voter} ul#votelist -var hasYouTubeVids=false -each votes,option in options From 2e27d7deceffc465eff38b74c8ebeadcdcda4ea5 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 17:20:05 +0100 Subject: [PATCH 39/51] votees stores vote, can change vote --- modules/poll.js | 22 ++++++++++++++-------- modules/web.js | 2 +- strings.json | 6 +++--- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/modules/poll.js b/modules/poll.js index 8b883c1..75a55f5 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -20,7 +20,7 @@ var poll = function(dbot) { 'description': description, 'owner': event.user, 'votes': {}, - 'votees': [] + 'votees': {} }; for(var i=0;i<options.length;i++) { @@ -37,16 +37,22 @@ var poll = function(dbot) { var vote = event.input[2]; if(polls.hasOwnProperty(name)) { - if(polls[name].votees.include(event.user)) { - event.reply(dbot.t('alread_voted')); - } else { - if(polls[name].votes.hasOwnProperty(vote)) { + if(polls[name].votes.hasOwnProperty(vote)) { + if(polls[name].votees.hasOwnProperty(event.user)) { + var oldVote = polls[name].votees[event.user]; + polls[name].votes[oldVote]--; polls[name].votes[vote]++; - polls[name].votees.push(event.user); - event.reply(dbot.t('voted', {'vote': vote})); + polls[name].votees[event.user] = vote; + event.reply(dbot.t('changed_voted', {'vote': vote, 'poll': name, + 'count': polls[name].votes[vote]})); } else { - event.reply(dbot.t('invalid_vote', {'vote': vote})); + polls[name].votes[vote]++; + polls[name].votees[event.user] = vote; + event.reply(dbot.t('voted', {'vote': vote, 'poll': name, + 'count': polls[name].votes[vote]})); } + } else { + event.reply(dbot.t('invalid_vote', {'vote': vote})); } } else { event.reply(dbot.t('poll_unexistent', {'name': name})); diff --git a/modules/web.js b/modules/web.js index 9c88f69..5f0fa8a 100644 --- a/modules/web.js +++ b/modules/web.js @@ -51,7 +51,7 @@ var webInterface = function(dbot) { totalVotes += N; } } - res.render('polls', { 'name': dbot.name, 'description': dbot.db.polls[key].description, 'votees': dbot.db.polls[key].votees, 'options': dbot.db.polls[key].votes, locals: { 'totalVotes': totalVotes, 'url_regex': RegExp.prototype.url_regex() } }); + res.render('polls', { 'name': dbot.name, 'description': dbot.db.polls[key].description, 'votees': Object.keys(dbot.db.polls[key].votees), 'options': dbot.db.polls[key].votes, locals: { 'totalVotes': totalVotes, 'url_regex': RegExp.prototype.url_regex() } }); } else { res.render('error', { 'name': dbot.name, 'message': 'No polls under that key.' }); } diff --git a/strings.json b/strings.json index 7be0fa8..b37672a 100644 --- a/strings.json +++ b/strings.json @@ -205,11 +205,11 @@ "poll_created": { "english": "Poll '{name}' created ({description}). Cast thy votations!" }, - "already_voted": { - "english": "You've already voted in this poll!" + "changed_vote": { + "english": "Changed vote in {poll} to '{vote}' ({count})" }, "voted": { - "english": "Voted for {vote}" + "english": "Voted for '{vote}' in {poll} ({count})" }, "invalid_vote": { "english": "Invalid vote: {vote}" From cfb00d3588f4e31e6706d162ca76f1812fedcf87 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 17:29:38 +0100 Subject: [PATCH 40/51] fucking typo --- modules/poll.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/poll.js b/modules/poll.js index 75a55f5..22e687e 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -37,7 +37,7 @@ var poll = function(dbot) { var vote = event.input[2]; if(polls.hasOwnProperty(name)) { - if(polls[name].votes.hasOwnProperty(vote)) { + if(polls[name].votees.hasOwnProperty(vote)) { if(polls[name].votees.hasOwnProperty(event.user)) { var oldVote = polls[name].votees[event.user]; polls[name].votes[oldVote]--; From 881834978d09fe0968d43b8dd77f9eec91801ff0 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 17:30:54 +0100 Subject: [PATCH 41/51] fucking typo --- modules/poll.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/poll.js b/modules/poll.js index 22e687e..867ed2a 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -37,7 +37,7 @@ var poll = function(dbot) { var vote = event.input[2]; if(polls.hasOwnProperty(name)) { - if(polls[name].votees.hasOwnProperty(vote)) { + if(!polls[name].votes.hasOwnProperty(vote)) { if(polls[name].votees.hasOwnProperty(event.user)) { var oldVote = polls[name].votees[event.user]; polls[name].votes[oldVote]--; From c018e338dc67bcf9a34a86ca6e154963941a5260 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 17:32:02 +0100 Subject: [PATCH 42/51] fucking typo --- modules/poll.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/poll.js b/modules/poll.js index 867ed2a..75a55f5 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -37,7 +37,7 @@ var poll = function(dbot) { var vote = event.input[2]; if(polls.hasOwnProperty(name)) { - if(!polls[name].votes.hasOwnProperty(vote)) { + if(polls[name].votes.hasOwnProperty(vote)) { if(polls[name].votees.hasOwnProperty(event.user)) { var oldVote = polls[name].votees[event.user]; polls[name].votes[oldVote]--; From 5904708d6b10beaeac3d7cce0d14e308e8205f75 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 17:39:26 +0100 Subject: [PATCH 43/51] fucking typo --- modules/poll.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/poll.js b/modules/poll.js index 75a55f5..86766e5 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -43,7 +43,7 @@ var poll = function(dbot) { polls[name].votes[oldVote]--; polls[name].votes[vote]++; polls[name].votees[event.user] = vote; - event.reply(dbot.t('changed_voted', {'vote': vote, 'poll': name, + event.reply(dbot.t('changed_vote', {'vote': vote, 'poll': name, 'count': polls[name].votes[vote]})); } else { polls[name].votes[vote]++; From 8ce80a1d94ae08c9f0c1f4140d4d9d513008dbfa Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 17:46:14 +0100 Subject: [PATCH 44/51] output changes --- modules/poll.js | 4 ++-- strings.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/poll.js b/modules/poll.js index 86766e5..36f72b7 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -44,12 +44,12 @@ var poll = function(dbot) { polls[name].votes[vote]++; polls[name].votees[event.user] = vote; event.reply(dbot.t('changed_vote', {'vote': vote, 'poll': name, - 'count': polls[name].votes[vote]})); + 'count': polls[name].votes[vote], 'user': event.user})); } else { polls[name].votes[vote]++; polls[name].votees[event.user] = vote; event.reply(dbot.t('voted', {'vote': vote, 'poll': name, - 'count': polls[name].votes[vote]})); + 'count': polls[name].votes[vote], 'user': event.user})); } } else { event.reply(dbot.t('invalid_vote', {'vote': vote})); diff --git a/strings.json b/strings.json index b37672a..ed43d97 100644 --- a/strings.json +++ b/strings.json @@ -206,10 +206,10 @@ "english": "Poll '{name}' created ({description}). Cast thy votations!" }, "changed_vote": { - "english": "Changed vote in {poll} to '{vote}' ({count})" + "english": "{user} changed their vote in {poll} to '{vote}' ({count})" }, "voted": { - "english": "Voted for '{vote}' in {poll} ({count})" + "english": "{user} voted for '{vote}' in {poll} ({count})" }, "invalid_vote": { "english": "Invalid vote: {vote}" From 52984d9b41d788f89a1017e391e924c75446a7a0 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 17:51:45 +0100 Subject: [PATCH 45/51] pdesc and output change --- modules/poll.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/poll.js b/modules/poll.js index 36f72b7..cebeed9 100644 --- a/modules/poll.js +++ b/modules/poll.js @@ -27,7 +27,8 @@ var poll = function(dbot) { polls[name]['votes'][options[i]] = 0; } - event.reply(dbot.t('poll_created', {'name': name, 'description': description})); + event.reply(dbot.t('poll_created', {'name': name, 'description': description}) + + ' - http://nc.no.de:443/polls/' + name); } } }, @@ -59,10 +60,10 @@ var poll = function(dbot) { } }, - '~viewpoll': function(event) { + '~pdesc': function(event) { var name = event.input[1]; if(polls.hasOwnProperty(name)) { - + event.reply(name + ': ' + polls[name].description + ' - http://nc.no.de:443/polls/' + name); } else { event.reply(dbot.t('poll_unexistent', {'name': name})); } @@ -70,7 +71,7 @@ var poll = function(dbot) { }; commands['~newpoll'].regex = [/~newpoll ([^ ]+) \[options=([^ ]+)\] (.+)/, 4]; commands['~vote'].regex = [/~vote ([^ ]+) ([^ ]+)/, 3]; - commands['~viewpoll'].regex = [/~viewpoll ([^ ]+)/, 2]; + commands['~pdesc'].regex = [/~pdesc ([^ ]+)/, 2]; return { 'name': 'poll', From 11f7e91ba9b1df9c079bca739f1dd8af1f0d7397 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 17:54:44 +0100 Subject: [PATCH 46/51] link back to poll list --- views/polls.jade | 1 + 1 file changed, 1 insertion(+) diff --git a/views/polls.jade b/views/polls.jade index 95f6d73..3724fbd 100644 --- a/views/polls.jade +++ b/views/polls.jade @@ -1,3 +1,4 @@ +a(href='/polls/') <- Poll List h2 #{description} p Voters (#{locals.totalVotes}): -each voter in votees From 75b627b3eee4a611f216197c25bddecb91713d81 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 17:57:47 +0100 Subject: [PATCH 47/51] style on backlink --- public/styles.css | 4 ++++ views/polls.jade | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/public/styles.css b/public/styles.css index 6d08800..e928d12 100644 --- a/public/styles.css +++ b/public/styles.css @@ -35,6 +35,10 @@ div#page { margin: 0 auto 0 auto; } +div#backlink { + text-align: left; +} + div#title { font-size: 42px; font-weight: bold; diff --git a/views/polls.jade b/views/polls.jade index 3724fbd..c7f193c 100644 --- a/views/polls.jade +++ b/views/polls.jade @@ -1,4 +1,4 @@ -a(href='/polls/') <- Poll List +div#backlink a(href='/polls/') <- Poll List h2 #{description} p Voters (#{locals.totalVotes}): -each voter in votees From ad9a65375be6a8a6acc2402d88b00767087e6578 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 15 Jun 2012 17:58:33 +0100 Subject: [PATCH 48/51] fix link? --- views/polls.jade | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/views/polls.jade b/views/polls.jade index c7f193c..878bf2c 100644 --- a/views/polls.jade +++ b/views/polls.jade @@ -1,4 +1,5 @@ -div#backlink a(href='/polls/') <- Poll List +div#backlink + a(href='/polls/') <- Poll List h2 #{description} p Voters (#{locals.totalVotes}): -each voter in votees From 806f9556bfea63751be42a401bc14f2cad10284d Mon Sep 17 00:00:00 2001 From: Daniel Evans <danharibo@gmail.com> Date: Fri, 15 Jun 2012 18:23:36 +0100 Subject: [PATCH 49/51] Updated backlinks --- public/styles.css | 7 ++++++- views/polls.jade | 2 +- views/quotes.jade | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/public/styles.css b/public/styles.css index e928d12..aca5116 100644 --- a/public/styles.css +++ b/public/styles.css @@ -36,7 +36,11 @@ div#page { } div#backlink { + position: absolute; + top: 10px; + left: 15px; text-align: left; + font-size: 0.8em; } div#title { @@ -51,7 +55,8 @@ div#title a { } div#main { - padding: 25px 0px; + position: relative; + padding: 15px 5px; margin: 0px; font-size: 21px; text-align:center; diff --git a/views/polls.jade b/views/polls.jade index 878bf2c..59378d8 100644 --- a/views/polls.jade +++ b/views/polls.jade @@ -1,5 +1,5 @@ div#backlink - a(href='/polls/') <- Poll List + a(href='/polls/') « Poll list h2 #{description} p Voters (#{locals.totalVotes}): -each voter in votees diff --git a/views/quotes.jade b/views/quotes.jade index b0aedd5..208754f 100644 --- a/views/quotes.jade +++ b/views/quotes.jade @@ -1,3 +1,5 @@ +div#backlink + a(href='/quotes/') « Quote list ul#quotelist -var hasYouTubeVids=false -each quote in quotes From befc20e71363914c4df77ac04121ec7e28bb1d77 Mon Sep 17 00:00:00 2001 From: Daniel Evans <danharibo@gmail.com> Date: Fri, 15 Jun 2012 18:57:47 +0100 Subject: [PATCH 50/51] Index page --- modules/web.js | 4 ++-- public/styles.css | 18 ++++++++++++++++++ views/index.jade | 6 +++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/modules/web.js b/modules/web.js index 5f0fa8a..3d9ad87 100644 --- a/modules/web.js +++ b/modules/web.js @@ -9,8 +9,8 @@ var webInterface = function(dbot) { app.set('view engine', 'jade'); app.get('/', function(req, res) { - res.redirect('/quotes'); - //res.render('index', { }); + //res.redirect('/quotes'); + res.render('index', { 'name': dbot.name }); }); // Lists the quote categories diff --git a/public/styles.css b/public/styles.css index aca5116..fa45ded 100644 --- a/public/styles.css +++ b/public/styles.css @@ -77,6 +77,24 @@ a,a:active,a:visited { text-decoration: none; } +/* Index Page */ +#modulelinks { + margin: 0; + padding: 0; +} + +.module { + display: inline-block; + width: 45%; + padding: 15px 0; + margin: 0 2%; + background: #F5F5F5; + border-radius: 15px; +} +.module:hover { + background: #BBB; +} + ul#quotelist { padding: 0; margin: 0; diff --git a/views/index.jade b/views/index.jade index 178ddc3..8372429 100644 --- a/views/index.jade +++ b/views/index.jade @@ -1,3 +1,3 @@ -div#main - p - a(href: '/quotes') Quotes +#modulelinks + a.module(href='/quotes') Quotes + a.module(href='/polls') Polls From f7851f1ddbf0708fe8cd2ae00767db3aa9ab55f3 Mon Sep 17 00:00:00 2001 From: Daniel Evans <danharibo@gmail.com> Date: Fri, 15 Jun 2012 19:04:10 +0100 Subject: [PATCH 51/51] More links --- views/polllist.jade | 2 ++ views/quotelist.jade | 2 ++ 2 files changed, 4 insertions(+) diff --git a/views/polllist.jade b/views/polllist.jade index 5f0e73b..4de9297 100644 --- a/views/polllist.jade +++ b/views/polllist.jade @@ -1,3 +1,5 @@ +div#backlink + a(href='/') « Home div#controls input(type="text", name="search", id="search-text", oninput="search(this.value)") ul#quotelist diff --git a/views/quotelist.jade b/views/quotelist.jade index 154fb1a..9643069 100644 --- a/views/quotelist.jade +++ b/views/quotelist.jade @@ -1,3 +1,5 @@ +div#backlink + a(href='/') « Home div#controls input(type="text", name="search", id="search-text", oninput="search(this.value)") ul#quotelist