From 950ba882b89750275874996863bd6c9f50434774 Mon Sep 17 00:00:00 2001 From: reality Date: Wed, 19 Dec 2012 21:03:03 +0000 Subject: [PATCH 001/347] Changed quote spam protection model [#72] --- modules/quotes/config.json | 3 +- modules/quotes/quotes.js | 72 +++++++++++++++++++++++++++++++++---- modules/quotes/strings.json | 15 ++++++++ timer.js | 16 +++++++-- 4 files changed, 96 insertions(+), 10 deletions(-) diff --git a/modules/quotes/config.json b/modules/quotes/config.json index 32c3324..3a7dc05 100644 --- a/modules/quotes/config.json +++ b/modules/quotes/config.json @@ -1,3 +1,4 @@ { - "dbKeys": [ "quoteArrs" ] + "dbKeys": [ "quoteArrs" ], + "rmLimit": 10 } diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index abcc073..6b8cdc8 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -3,6 +3,9 @@ var quotes = function(dbot) { var quotes = dbot.db.quoteArrs; var addStack = []; var rmAllowed = true; + dbot.sessionData.rmCache = []; + var rmCache = dbot.sessionData.rmCache; + var rmTimer; // Retrieve a random quote from a given category, interpolating any quote // references (~~QUOTE CATEGORY~~) within it @@ -32,12 +35,69 @@ var quotes = function(dbot) { return quoteString; }; + var resetRemoveTimer = function(event, key, quote) { + rmAllowed = false; + dbot.timers.addOnceTimer(5000, function() { + rmAllowed = true; + }); + + rmCache.push({'key': key, 'quote': quote}); + dbot.timers.clearTimeout(rmTimer); + if(rmCache.length < dbot.config.quotes.rmLimit) { + rmTimer = dbot.timers.addOnceTimer(600000, function() { + rmCache.length = 0; // lol what + }); + } else { + for(var i=0;i Date: Thu, 20 Dec 2012 13:27:56 +0100 Subject: [PATCH 002/347] Update modules/quotes/quotes.js Fix not found output --- modules/quotes/quotes.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index 6b8cdc8..7d8b1f3 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -185,7 +185,6 @@ var quotes = function(dbot) { if(!dbot.db.locks.include(key)) { var category = quotes[key]; var index = category.indexOf(quote); - var quote = category[index]; if(index !== -1) { category.splice(index, 1); if(category.length === 0) { From 81217ece50f93f044e9f995951510afa2027e1b5 Mon Sep 17 00:00:00 2001 From: reality Date: Sun, 23 Dec 2012 02:25:58 +0000 Subject: [PATCH 003/347] Add a debug mode that shows the error and the top of the stack trace in the case of an error if activated. --- config.json.sample | 3 ++- modules/command/command.js | 10 +++++++++- run.js | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/config.json.sample b/config.json.sample index 31c11f6..685eee6 100644 --- a/config.json.sample +++ b/config.json.sample @@ -13,5 +13,6 @@ }, "admins": [ "batman" ], "moduleNames": [ "ignore", "admin", "command", "dice", "js", "kick", "puns", "quotes", "spelling", "youare" ], - "language": "english" + "language": "english", + "debugMode": true } diff --git a/modules/command/command.js b/modules/command/command.js index 6342da2..ff530ff 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -79,7 +79,15 @@ var command = function(dbot) { } else { if(!isIgnoring(event.user, commandName)) { if(applyRegex(commandName, event)) { - dbot.commands[commandName](event); + try { + dbot.commands[commandName](event); + } catch(err) { + if(dbot.config.debugMode == true) { + event.reply('- Error in ' + commandName + ':'); + event.reply('- Message: ' + err); + event.reply('- Top of stack: ' + err.stack.split('\n')[1].trim()); + } + } dbot.save(); } else { if(commandName !== '~') { diff --git a/run.js b/run.js index e9e5132..187996d 100644 --- a/run.js +++ b/run.js @@ -5,7 +5,7 @@ require('./snippets'); var DBot = function(timers) { // Load external files - var requiredConfigKeys = [ 'name', 'servers', 'admins', 'moduleNames', 'language' ]; + var requiredConfigKeys = [ 'name', 'servers', 'admins', 'moduleNames', 'language', 'debugMode' ]; try { this.config = JSON.parse(fs.readFileSync('config.json', 'utf-8')); } catch(err) { From b1073e615ba877b79c8c68847585b6b99f091397 Mon Sep 17 00:00:00 2001 From: reality Date: Sun, 23 Dec 2012 14:25:34 +0000 Subject: [PATCH 004/347] Added Sams stats module --- .gitmodules | 3 +++ modules/stats | 1 + 2 files changed, 4 insertions(+) create mode 160000 modules/stats diff --git a/.gitmodules b/.gitmodules index 0d17ed4..49a4b35 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "jsbot"] path = jsbot url = git://github.com/reality/jsbot.git +[submodule "modules/stats"] + path = modules/stats + url = git://github.com/SamStudio8/stats.git diff --git a/modules/stats b/modules/stats new file mode 160000 index 0000000..72216aa --- /dev/null +++ b/modules/stats @@ -0,0 +1 @@ +Subproject commit 72216aa34d5bfae5e4734926e5a7fd52c89bae04 From 82132d776496e474d9af74b5dc267a63e8c318fe Mon Sep 17 00:00:00 2001 From: reality Date: Sun, 23 Dec 2012 14:45:28 +0000 Subject: [PATCH 005/347] update stats version --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 72216aa..367e93e 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 72216aa34d5bfae5e4734926e5a7fd52c89bae04 +Subproject commit 367e93e596e2f579509d23b6da2259c653fa8190 From 85e65339695f5eea3a716848eb3e2a753bcb5903 Mon Sep 17 00:00:00 2001 From: reality Date: Sun, 23 Dec 2012 14:49:49 +0000 Subject: [PATCH 006/347] updat ejsbot --- jsbot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsbot b/jsbot index dbd9875..4e5c470 160000 --- a/jsbot +++ b/jsbot @@ -1 +1 @@ -Subproject commit dbd987551bd8ce68655bbedb6bc5e98e90557708 +Subproject commit 4e5c470a20044416fc1a912b7a3c9ee42be942cb From fcf13daf435366259fbc7734a05be071a4a62048 Mon Sep 17 00:00:00 2001 From: Sam Nicholls Date: Sun, 23 Dec 2012 15:01:07 +0000 Subject: [PATCH 007/347] numberFormat snippet --- snippets.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/snippets.js b/snippets.js index e82f506..55c7fec 100644 --- a/snippets.js +++ b/snippets.js @@ -253,3 +253,13 @@ RegExp.prototype.url_regex = function() { ); return reg; } + +Number.prototype.numberFormat = function(dec_places){ + //TODO Possibly abstract this to some sort of localisation module in future? + var dec_point = '.'; + var sep = ','; + + var parts = this.toFixed(dec_places).toString().split(dec_point); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, sep); + return parts.join(dec_point); +} From 0f6aadc07b97b11ff2c07e2be2d96b02651341e8 Mon Sep 17 00:00:00 2001 From: reality Date: Sun, 23 Dec 2012 16:19:01 +0000 Subject: [PATCH 008/347] Add rudimentary users module to track known users in a channel --- jsbot | 2 +- modules/users/config.json | 3 +++ modules/users/users.js | 44 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 modules/users/config.json create mode 100644 modules/users/users.js diff --git a/jsbot b/jsbot index 4e5c470..00157e1 160000 --- a/jsbot +++ b/jsbot @@ -1 +1 @@ -Subproject commit 4e5c470a20044416fc1a912b7a3c9ee42be942cb +Subproject commit 00157e15c9f15e8fcb343c924978616bb6315ee7 diff --git a/modules/users/config.json b/modules/users/config.json new file mode 100644 index 0000000..bc208fb --- /dev/null +++ b/modules/users/config.json @@ -0,0 +1,3 @@ +{ + "dbKeys": [ "knownUsers" ] +} diff --git a/modules/users/users.js b/modules/users/users.js new file mode 100644 index 0000000..f953e1f --- /dev/null +++ b/modules/users/users.js @@ -0,0 +1,44 @@ +/** + * Name: Users + * Description: Track known users + */ +var users = function(dbot) { + var knownUsers = dbot.db.knownUsers; + var getChanUsers = function(event) { + if(!knownUsers.hasOwnProperty(event.server)) { + knownUsers[event.server] = {}; + } + var serverUsers = knownUsers[event.server]; + + if(!serverUsers.hasOwnProperty(event.channel.name)) { + serverUsers[event.channel.name] = []; + } + return serverUsers[event.channel.name]; + }; + + dbot.instance.addListener('366', 'users', function(event) { + var chanUsers = getChanUsers(event); + for(var nick in event.channel.nicks) { + if(!chanUsers.include(nick) && event.channel.nicks.hasOwnProperty(nick)) { + chanUsers.push(nick); + } + } + }); + + return { + 'name': 'users', + 'ignorable': false, + + 'listener': function(event) { + var chanusers = getChanUsers(event); + if(!chanUsers.include(event.user)) { + chanUsers.push(event.user); + } + }, + 'on': 'JOIN' + }; +}; + +exports.fetch = function(dbot) { + return users(dbot); +}; From 2bc0bbc439bc8a78daca70b955133feeabb7cb23 Mon Sep 17 00:00:00 2001 From: reality Date: Sun, 23 Dec 2012 16:46:33 +0000 Subject: [PATCH 009/347] trigger updateNickLists to update knownUsers on module load --- jsbot | 2 +- modules/users/users.js | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/jsbot b/jsbot index 00157e1..f050c93 160000 --- a/jsbot +++ b/jsbot @@ -1 +1 @@ -Subproject commit 00157e15c9f15e8fcb343c924978616bb6315ee7 +Subproject commit f050c93f22e56ad98f245f7ba8b444208c4de6f8 diff --git a/modules/users/users.js b/modules/users/users.js index f953e1f..5dfd216 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -35,7 +35,17 @@ var users = function(dbot) { chanUsers.push(event.user); } }, - 'on': 'JOIN' + 'on': 'JOIN', + + 'onLoad': function() { + // Trigger updateNickLists to stat current users in channel + var connections = dbot.instance.connections; + for(var conn in connections) { + if(connections.hasOwnProperty(conn)) { + connections[conn].updateNickLists(); + } + } + } }; }; From bd6c42d57e0ec3fabd11e40485ffd08c018d7f8f Mon Sep 17 00:00:00 2001 From: reality Date: Sun, 23 Dec 2012 16:54:30 +0000 Subject: [PATCH 010/347] Allow listeners to be attached to multiple event types. --- run.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/run.js b/run.js index 187996d..67911a1 100644 --- a/run.js +++ b/run.js @@ -169,7 +169,14 @@ DBot.prototype.reloadModules = function() { this.rawModules.push(rawModule); if(module.listener) { - this.instance.addListener(module.on, module.name, module.listener); + var listenOn = module.on; + if(!(listenOn instanceof Array)) { + listenOn = [listenOn]; + } + + listenOn.each(function(on) { + this.instance.addListener(on, module.name, module.listener); + }.bind(this)); } if(module.onLoad) { From 6db6c804e5347a92c3866b38f86414f11989b9b3 Mon Sep 17 00:00:00 2001 From: reality Date: Sun, 23 Dec 2012 17:11:56 +0000 Subject: [PATCH 011/347] nicks are server-wide, not channel-specific --- modules/users/users.js | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/modules/users/users.js b/modules/users/users.js index 5dfd216..623bb07 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -4,23 +4,18 @@ */ var users = function(dbot) { var knownUsers = dbot.db.knownUsers; - var getChanUsers = function(event) { - if(!knownUsers.hasOwnProperty(event.server)) { + var getServerUsers = function(event) { + if(!knownUsers.hasOwnProperty(event.server)) { knownUsers[event.server] = {}; } - var serverUsers = knownUsers[event.server]; - - if(!serverUsers.hasOwnProperty(event.channel.name)) { - serverUsers[event.channel.name] = []; - } - return serverUsers[event.channel.name]; + return knownUsers[event.server]; }; dbot.instance.addListener('366', 'users', function(event) { - var chanUsers = getChanUsers(event); + var knownUsers = getServerUsers(event); for(var nick in event.channel.nicks) { - if(!chanUsers.include(nick) && event.channel.nicks.hasOwnProperty(nick)) { - chanUsers.push(nick); + if(!knownUsers.hasOwnProperty(nick) && event.channel.nicks.hasOwnProperty(nick)) { + knownUsers[nick] = {}; } } }); @@ -30,9 +25,9 @@ var users = function(dbot) { 'ignorable': false, 'listener': function(event) { - var chanusers = getChanUsers(event); - if(!chanUsers.include(event.user)) { - chanUsers.push(event.user); + var knownUsers = getServerUsers(event); + if(!knownUsers.hasOwnProperty(event.user)) { + knownUsers[event.user] = {}; } }, 'on': 'JOIN', From f59c09f9ea8cb803a81d2f57057ac6a1c8141bcf Mon Sep 17 00:00:00 2001 From: reality Date: Mon, 24 Dec 2012 00:42:28 +0000 Subject: [PATCH 012/347] Rudimentary alias tracking with ~alias command [#73] --- modules/users/users.js | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/modules/users/users.js b/modules/users/users.js index 623bb07..d4f6afa 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -6,7 +6,7 @@ var users = function(dbot) { var knownUsers = dbot.db.knownUsers; var getServerUsers = function(event) { if(!knownUsers.hasOwnProperty(event.server)) { - knownUsers[event.server] = {}; + knownUsers[event.server] = { 'users': [], 'aliases': {} }; } return knownUsers[event.server]; }; @@ -14,8 +14,9 @@ var users = function(dbot) { dbot.instance.addListener('366', 'users', function(event) { var knownUsers = getServerUsers(event); for(var nick in event.channel.nicks) { - if(!knownUsers.hasOwnProperty(nick) && event.channel.nicks.hasOwnProperty(nick)) { - knownUsers[nick] = {}; + if(!knownUsers.users.include(nick) && !knownUsers.aliases.hasOwnProperty(nick) && + event.channel.nicks.hasOwnProperty(nick)) { + knownUsers.users.push(nick); } } }); @@ -23,14 +24,31 @@ var users = function(dbot) { return { 'name': 'users', 'ignorable': false, + + 'commands': { + '~alias': function(event) { + var knownUsers = getServerUsers(event); + var alias = event.params[1].trim(); + if(knownUsers.aliases.hasOwnProperty(alias)) { + event.reply(alias + ' is an alias of ' + knownUsers.aliases[alias]); + } else { + event.reply(alias + ' is not known as an alias to me.'); + } + } + }, 'listener': function(event) { var knownUsers = getServerUsers(event); - if(!knownUsers.hasOwnProperty(event.user)) { - knownUsers[event.user] = {}; + if(event.action == 'JOIN') { + if(!knownUsers.users.include(event.user)) { + knownUsers.users.push(event.user); + } + } else if(event.action == 'NICK') { + var newNick = event.params.substr(1); + knownUsers.aliases[newNick] = event.user; } }, - 'on': 'JOIN', + 'on': ['JOIN', 'NICK'], 'onLoad': function() { // Trigger updateNickLists to stat current users in channel From 3bfa3d58c3bbd323c027072f44e7c3023cf288f9 Mon Sep 17 00:00:00 2001 From: reality Date: Mon, 24 Dec 2012 01:49:15 +0000 Subject: [PATCH 013/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 367e93e..8867e35 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 367e93e596e2f579509d23b6da2259c653fa8190 +Subproject commit 8867e3592ea03b85093a5ab79017efb26c9156be From bea13e56f8ca603aece47ec8856068f134d60e3a Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Mon, 24 Dec 2012 03:08:36 +0000 Subject: [PATCH 014/347] Modified module error output --- run.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run.js b/run.js index 67911a1..8ebbdc5 100644 --- a/run.js +++ b/run.js @@ -229,7 +229,7 @@ DBot.prototype.reloadModules = function() { this.modules.push(module); } catch(err) { console.log(this.t('module_load_error', {'moduleName': name})); - console.log('MODULE ERROR: ' + name + ' ' + err); + console.log('MODULE ERROR (' + name + '): ' + err.stack ); } }.bind(this)); this.save(); From cf53413bfffd6d65c83cb9b0e07b801473f16460 Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Mon, 24 Dec 2012 03:13:41 +0000 Subject: [PATCH 015/347] Made stack trace dependant on dbot.config.debugMode --- run.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/run.js b/run.js index 8ebbdc5..26ddcea 100644 --- a/run.js +++ b/run.js @@ -229,7 +229,12 @@ DBot.prototype.reloadModules = function() { this.modules.push(module); } catch(err) { console.log(this.t('module_load_error', {'moduleName': name})); - console.log('MODULE ERROR (' + name + '): ' + err.stack ); + if(this.config.debugMode) { + console.log('MODULE ERROR (' + name + '): ' + err.stack ); + } + else { + console.log('MODULE ERROR (' + name + '): ' + err ); + } } }.bind(this)); this.save(); From 88d2abab58d5b2d44d1527fa4f5279f39449d0a1 Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Mon, 24 Dec 2012 04:06:04 +0000 Subject: [PATCH 016/347] Removed sass compiler usage from web.js, updated jade templates to use blocks --- modules/web/web.js | 3 +-- views/channels.jade | 17 +++++++------ views/connections.jade | 13 ++++++---- views/index.jade | 5 +++- views/layout.jade | 2 +- views/polllist.jade | 19 +++++++++------ views/quotelist.jade | 19 +++++++++------ views/quotes.jade | 55 ++++++++++++++++++++++-------------------- views/user.jade | 21 +++++++++------- views/users.jade | 17 +++++++------ 10 files changed, 97 insertions(+), 74 deletions(-) diff --git a/modules/web/web.js b/modules/web/web.js index 9f01c8d..9fc3f3c 100644 --- a/modules/web/web.js +++ b/modules/web/web.js @@ -2,9 +2,8 @@ var express = require('express'); var webInterface = function(dbot) { var pub = 'public'; - var app = express.createServer(); + var app = express(); - app.use(express.compiler({ src: pub, enable: ['sass'] })); app.use(express.static(pub)); app.set('view engine', 'jade'); diff --git a/views/channels.jade b/views/channels.jade index d0e3faa..7cebf54 100644 --- a/views/channels.jade +++ b/views/channels.jade @@ -1,7 +1,10 @@ -h3 Channels on #{connection} -div#backlink - a(href='/connections') « Connection List -ul#quotelist - -each channel in channels - a(href='/users/'+connection+'/'+channel.substr(1,channel.length)) - li.quotes #{channel} +extends layout + +block content + h3 Channels on #{connection} + div#backlink + a(href='/connections') « Connection List + ul#quotelist + -each channel in channels + a(href='/users/'+connection+'/'+channel.substr(1,channel.length)) + li.quotes #{channel} diff --git a/views/connections.jade b/views/connections.jade index f4e1531..dd1e63b 100644 --- a/views/connections.jade +++ b/views/connections.jade @@ -1,6 +1,9 @@ -h3 Current Connections -div#backlink - a(href='/') « Home +extends layout + +block content + h3 Current Connections + div#backlink + a(href='/') « Home #modulelinks - -each connection in connections - a.module(href='/channels/'+connection) #{connection} + -each connection in connections + a.module(href='/channels/'+connection) #{connection} diff --git a/views/index.jade b/views/index.jade index 4558fbf..05d931e 100644 --- a/views/index.jade +++ b/views/index.jade @@ -1,4 +1,7 @@ -#modulelinks +extends layout + +block content + #modulelinks a.module(href='/quotes') Quotes a.module(href='/polls') Polls a.module(href='/connections') Users diff --git a/views/layout.jade b/views/layout.jade index be03d24..7fc3c1d 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -9,5 +9,5 @@ html(lang='en') div#title a(href='/') #{name} web interface div#main - !{body} + block content script(type="text/javascript", src="/script.js") diff --git a/views/polllist.jade b/views/polllist.jade index 4de9297..128458a 100644 --- a/views/polllist.jade +++ b/views/polllist.jade @@ -1,9 +1,12 @@ -div#backlink - a(href='/') « Home -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} +extends layout + +block content + div#backlink + a(href='/') « Home + 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/quotelist.jade b/views/quotelist.jade index 9643069..df97c7b 100644 --- a/views/quotelist.jade +++ b/views/quotelist.jade @@ -1,9 +1,12 @@ -div#backlink - a(href='/') « Home -div#controls - input(type="text", name="search", id="search-text", oninput="search(this.value)") -ul#quotelist - -each quote in quotelist - a(href='/quotes/'+quote) - li.quotes #{quote} +extends layout + +block content + div#backlink + a(href='/') « Home + div#controls + input(type="text", name="search", id="search-text", oninput="search(this.value)") + ul#quotelist + -each quote in quotelist + a(href='/quotes/'+quote) + li.quotes #{quote} diff --git a/views/quotes.jade b/views/quotes.jade index 35dc519..38c73e1 100644 --- a/views/quotes.jade +++ b/views/quotes.jade @@ -1,26 +1,29 @@ -div#backlink - a(href='/quotes/') « Quote list -ul#quotelist - -var hasYouTubeVids=false - -each quote in quotes - -if(quote.match(locals.url_regex)) - li.quote - -if(quote.match(/(jpg|png|gif|jpeg|tiff)$/)) - a(href=quote) - img(src=quote) - -else if(quote.match(/youtube.com\/watch/)) - -hasYouTubeVids = true - span(class='ytplaceholder') - =quote - -else - a(href=quote) - =quote - -else if(quote.match(/~~([^~]+)~~/)) - -var res = quote.match(/~~([^~]+)~~/) - -if(res != null) - li.quote - a(href="/quotes/#{res[1]}") #{quote} - -else - li.quote #{quote} - -if(hasYouTubeVids) - script(src='/ytembed.js') +extends layout + +block content + div#backlink + a(href='/quotes/') « Quote list + ul#quotelist + -var hasYouTubeVids=false + -each quote in quotes + -if(quote.match(locals.url_regex)) + li.quote + -if(quote.match(/(jpg|png|gif|jpeg|tiff)$/)) + a(href=quote) + img(src=quote) + -else if(quote.match(/youtube.com\/watch/)) + -hasYouTubeVids = true + span(class='ytplaceholder') + =quote + -else + a(href=quote) + =quote + -else if(quote.match(/~~([^~]+)~~/)) + -var res = quote.match(/~~([^~]+)~~/) + -if(res != null) + li.quote + a(href="/quotes/#{res[1]}") #{quote} + -else + li.quote #{quote} + -if(hasYouTubeVids) + script(src='/ytembed.js') diff --git a/views/user.jade b/views/user.jade index 5ba3828..8d1a680 100644 --- a/views/user.jade +++ b/views/user.jade @@ -1,11 +1,14 @@ -h3 #{user}'s profile -div#backlink - a(href='/users/'+connection+'/'+channel.substr(1,channel.length)) « #{channel} Nick List +extends layout -div.quotecount - #{cleanUser} is filled with - a(href='/quotes/'+cleanUser) #{quotecount} quotes - . +block content + h3 #{user}'s profile + div#backlink + a(href='/users/'+connection+'/'+channel.substr(1,channel.length)) « #{channel} Nick List -div.kickcount - #{cleanUser} has kicked people #{kicked} times and has been kicked #{kicks} times. + div.quotecount + #{cleanUser} is filled with + a(href='/quotes/'+cleanUser) #{quotecount} quotes + . + + div.kickcount + #{cleanUser} has kicked people #{kicked} times and has been kicked #{kicks} times. diff --git a/views/users.jade b/views/users.jade index 89c6a11..d043702 100644 --- a/views/users.jade +++ b/views/users.jade @@ -1,7 +1,10 @@ -h3 Users currently in #{channel} on #{connection} -div#backlink - a(href='/channels/'+connection) « Channel List -ul#quotelist - -each nick in nicks - a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) - li.quotes #{nick} +extends layout + +block content + h3 Users currently in #{channel} on #{connection} + div#backlink + a(href='/channels/'+connection) « Channel List + ul#quotelist + -each nick in nicks + a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) + li.quotes #{nick} From e544c909ecd2f07c311500dfa475e605e65152c7 Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Mon, 24 Dec 2012 05:47:47 +0000 Subject: [PATCH 017/347] Modularised web routes and views --- modules/poll/poll.js | 28 ++++++- modules/quotes/quotes.js | 24 ++++++ modules/users/users.js | 61 ++++++++++++++ modules/web/web.js | 123 ++++++----------------------- run.js | 24 ++++++ views/{ => poll}/polllist.jade | 2 +- views/poll/polls.jade | 39 +++++++++ views/polls.jade | 36 --------- views/{ => quotes}/quotelist.jade | 2 +- views/{ => quotes}/quotes.jade | 2 +- views/{ => users}/channels.jade | 2 +- views/{ => users}/connections.jade | 2 +- views/{ => users}/user.jade | 2 +- views/{ => users}/users.jade | 2 +- 14 files changed, 204 insertions(+), 145 deletions(-) rename views/{ => poll}/polllist.jade (94%) create mode 100644 views/poll/polls.jade delete mode 100644 views/polls.jade rename views/{ => quotes}/quotelist.jade (94%) rename views/{ => quotes}/quotes.jade (98%) rename views/{ => users}/channels.jade (93%) rename views/{ => users}/connections.jade (91%) rename views/{ => users}/user.jade (95%) rename views/{ => users}/users.jade (94%) diff --git a/modules/poll/poll.js b/modules/poll/poll.js index 8c79a02..988664f 100644 --- a/modules/poll/poll.js +++ b/modules/poll/poll.js @@ -216,11 +216,37 @@ var poll = function(dbot) { commands['~vote'].regex = [/~vote ([^ ]+) ([^ ]+)/, 3]; commands['~pdesc'].regex = [/~pdesc ([^ ]+)/, 2]; commands['~count'].regex = [/~count ([^ ]+)/, 2]; + + var pages = { + // Shows the results of a poll + '/polls/:key': function(req, res) { + var key = req.params.key.toLowerCase(); + if(dbot.db.polls.hasOwnProperty(key) && dbot.db.polls[key].hasOwnProperty('description')) { + // 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.config.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.config.name, 'message': 'No polls under that key.' }); + } + }, + + // Lists all of the polls + '/polls': function(req, res) { + res.render('polllist', { 'name': dbot.config.name, 'polllist': Object.keys(dbot.db.polls) }); + }, + }; return { 'name': 'poll', 'ignorable': true, - 'commands': commands + 'commands': commands, + 'pages': pages }; }; diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index 7d8b1f3..aa77ad6 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -267,10 +267,34 @@ var quotes = function(dbot) { commands['~rmlast'].regex = [/^~rmlast ([\d\w\s-]*)/, 2]; commands['~qadd'].regex = [/^~qadd ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; + var pages = { + // Lists quotes in a category + '/quotes/:key': function(req, res) { + var key = req.params.key.toLowerCase(); + if(dbot.db.quoteArrs.hasOwnProperty(key)) { + res.render('quotes', { 'name': dbot.config.name, 'quotes': dbot.db.quoteArrs[key], locals: { 'url_regex': RegExp.prototype.url_regex() } }); + } else { + res.render('error', { 'name': dbot.config.name, 'message': 'No quotes under that key.' }); + } + }, + + // Show quote list. + '/quotes': function(req, res) { + res.render('quotelist', { 'name': dbot.config.name, 'quotelist': Object.keys(dbot.db.quoteArrs) }); + }, + + // Load random quote category page + '/rq': function(req, res) { + var rCategory = Object.keys(dbot.db.quoteArrs).random(); + res.render('quotes', { 'name': dbot.config.name, 'quotes': dbot.db.quoteArrs[rCategory], locals: { 'url_regex': RegExp.prototype.url_regex() } }); + }, + }; + return { 'name': 'quotes', 'ignorable': true, 'commands': commands, + 'pages': pages, 'listener': function(event) { // Reality Once listener diff --git a/modules/users/users.js b/modules/users/users.js index d4f6afa..8f1a217 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -21,6 +21,65 @@ var users = function(dbot) { } }); + var pages = { + '/connections': function(req, res) { + var connections = Object.keys(dbot.instance.connections); + res.render('connections', { 'name': dbot.config.name, 'connections': connections }); + }, + + '/channels/:connection': function(req, res) { + var connection = req.params.connection; + if(dbot.instance.connections.hasOwnProperty(connection)) { + var channels = Object.keys(dbot.instance.connections[connection].channels); + res.render('channels', { 'name': dbot.config.name, 'connection': connection, 'channels': channels}); + } else { + res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection.' }); + } + }, + + '/users/:connection/:channel': function(req, res) { + var connection = req.params.connection; + var channel = '#' + req.params.channel; + var connections = dbot.instance.connections; + + if(connections.hasOwnProperty(connection) && + connections[connection].channels.hasOwnProperty(channel)) { + var nicks = Object.keys(connections[connection].channels[channel].nicks); + res.render('users', { 'name': dbot.config.name, 'connection': connection, + 'channel': channel, 'nicks': nicks }); + } else { + res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection or channel.' }); + } + }, + + '/user/:connection/:channel/:user': function(req, res) { + var connection = req.params.connection; + var channel = '#' + req.params.channel; + var user = dbot.cleanNick(req.params.user); + + var quoteCount = 'no'; + if(dbot.db.quoteArrs.hasOwnProperty(user)) { + var quoteCount = dbot.db.quoteArrs[user].length; + } + + if(!dbot.db.kicks.hasOwnProperty(req.params.user)) { + var kicks = '0'; + } else { + var kicks = dbot.db.kicks[req.params.user]; + } + + if(!dbot.db.kickers.hasOwnProperty(req.params.user)) { + var kicked = '0'; + } else { + var kicked = dbot.db.kickers[req.params.user]; + } + + res.render('user', { 'name': dbot.config.name, 'user': req.params.user, + 'channel': channel, 'connection': connection, 'cleanUser': user, + 'quotecount': quoteCount, 'kicks': kicks, 'kicked': kicked }); + }, + }; + return { 'name': 'users', 'ignorable': false, @@ -36,6 +95,8 @@ var users = function(dbot) { } } }, + + 'pages': pages, 'listener': function(event) { var knownUsers = getServerUsers(event); diff --git a/modules/web/web.js b/modules/web/web.js index 9fc3f3c..3f3b897 100644 --- a/modules/web/web.js +++ b/modules/web/web.js @@ -1,4 +1,5 @@ -var express = require('express'); +var express = require('express'), + fs = require('fs'); var webInterface = function(dbot) { var pub = 'public'; @@ -11,112 +12,32 @@ var webInterface = function(dbot) { res.render('index', { 'name': dbot.config.name }); }); - app.get('/connections', function(req, res) { - var connections = Object.keys(dbot.instance.connections); - res.render('connections', { 'name': dbot.config.name, 'connections': connections }); - }); - - app.get('/channels/:connection', function(req, res) { - var connection = req.params.connection; - if(dbot.instance.connections.hasOwnProperty(connection)) { - var channels = Object.keys(dbot.instance.connections[connection].channels); - res.render('channels', { 'name': dbot.config.name, 'connection': connection, 'channels': channels}); - } else { - res.render('error', { 'name': dbot.config.name, 'message': 'No such connection.' }); - } - }); - - app.get('/users/:connection/:channel', function(req, res) { - var connection = req.params.connection; - var channel = '#' + req.params.channel; - var connections = dbot.instance.connections; - - if(connections.hasOwnProperty(connection) && - connections[connection].channels.hasOwnProperty(channel)) { - var nicks = Object.keys(connections[connection].channels[channel].nicks); - res.render('users', { 'name': dbot.config.name, 'connection': connection, - 'channel': channel, 'nicks': nicks }); - } else { - res.render('error', { 'name': dbot.config.name, 'message': 'No such connection or channel.' }); - } - }); - - app.get('/user/:connection/:channel/:user', function(req, res) { - var connection = req.params.connection; - var channel = '#' + req.params.channel; - var user = dbot.cleanNick(req.params.user); - - var quoteCount = 'no'; - if(dbot.db.quoteArrs.hasOwnProperty(user)) { - var quoteCount = dbot.db.quoteArrs[user].length; - } - - if(!dbot.db.kicks.hasOwnProperty(req.params.user)) { - var kicks = '0'; - } else { - var kicks = dbot.db.kicks[req.params.user]; - } - - if(!dbot.db.kickers.hasOwnProperty(req.params.user)) { - var kicked = '0'; - } else { - var kicked = dbot.db.kickers[req.params.user]; - } - - res.render('user', { 'name': dbot.config.name, 'user': req.params.user, - 'channel': channel, 'connection': connection, 'cleanUser': user, - 'quotecount': quoteCount, 'kicks': kicks, 'kicked': kicked }); - }); - - // Lists the quote categories - app.get('/quotes', function(req, res) { - res.render('quotelist', { 'name': dbot.config.name, 'quotelist': Object.keys(dbot.db.quoteArrs) }); - }); - - // Lists quotes in a category - app.get('/quotes/:key', function(req, res) { - var key = req.params.key.toLowerCase(); - if(dbot.db.quoteArrs.hasOwnProperty(key)) { - res.render('quotes', { 'name': dbot.config.name, 'quotes': dbot.db.quoteArrs[key], locals: { 'url_regex': RegExp.prototype.url_regex() } }); - } else { - res.render('error', { 'name': dbot.config.name, 'message': 'No quotes under that key.' }); - } - }); - - // Load random quote category page - app.get('/rq', function(req, res) { - var rCategory = Object.keys(dbot.db.quoteArrs).random(); - res.render('quotes', { 'name': dbot.config.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.config.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) && dbot.db.polls[key].hasOwnProperty('description')) { - // 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.config.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.config.name, 'message': 'No polls under that key.' }); - } - }); app.listen(dbot.config.web.webPort); + var reloadPages = function(pages) { + for(var p in pages) { + if( pages.hasOwnProperty(p) ) { + var func = pages[p]; + var mod = func.module; + app.get(p, (function(req, resp) { + // Crazy shim to seperate module views. + var shim = Object.create(resp); + shim.render = (function(view, one, two) { + // Render with express.js + resp.render(this.module.name + '/' + view, one, two); + }).bind(this); + shim.render_core = resp.render; + this.call(this.module, req, shim); + }).bind(func)); + } + } + }; + return { 'name': 'web', 'ignorable': false, + 'reloadPages': reloadPages, 'onDestroy': function() { app.close(); diff --git a/run.js b/run.js index 26ddcea..f773749 100644 --- a/run.js +++ b/run.js @@ -118,6 +118,7 @@ DBot.prototype.reloadModules = function() { this.rawModules = []; this.modules = []; + this.pages = {}; this.commands = {}; this.commandMap = {}; // Map of which commands belong to which modules this.usage = {}; @@ -168,6 +169,8 @@ DBot.prototype.reloadModules = function() { var module = rawModule.fetch(this); this.rawModules.push(rawModule); + module.name = name; + if(module.listener) { var listenOn = module.on; if(!(listenOn instanceof Array)) { @@ -194,6 +197,18 @@ DBot.prototype.reloadModules = function() { } } + // Load module web bits + if(module.pages) { + var newpages = module.pages; + for(var key in newpages) + { + if(newpages.hasOwnProperty(key) && Object.prototype.isFunction(newpages[key])) { + this.pages[key] = newpages[key]; + this.pages[key].module = module; + } + } + } + // Load the module usage data try { var usage = JSON.parse(fs.readFileSync(moduleDir + 'usage.json', 'utf-8')); @@ -237,9 +252,18 @@ DBot.prototype.reloadModules = function() { } } }.bind(this)); + this.reloadPages(); this.save(); }; +DBot.prototype.reloadPages = function() { + for( var m in this.modules ) { + if( Object.prototype.isFunction(this.modules[m].reloadPages)) { + this.modules[m].reloadPages(this.pages); + } + } +} + DBot.prototype.cleanNick = function(key) { key = key.toLowerCase(); while(key.endsWith("_")) { diff --git a/views/polllist.jade b/views/poll/polllist.jade similarity index 94% rename from views/polllist.jade rename to views/poll/polllist.jade index 128458a..1623492 100644 --- a/views/polllist.jade +++ b/views/poll/polllist.jade @@ -1,4 +1,4 @@ -extends layout +extends ../layout block content div#backlink diff --git a/views/poll/polls.jade b/views/poll/polls.jade new file mode 100644 index 0000000..80e25f6 --- /dev/null +++ b/views/poll/polls.jade @@ -0,0 +1,39 @@ +extends ../layout + +block content + div#backlink + a(href='/polls/') « Poll list + 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}%") + case votes + when 1: #{votes} vote + default: #{votes} votes + -if(!isNaN(percentage)) + |(#{percentage.toFixed(2)}%) + -if(hasYouTubeVids) + script(src='/ytembed.js') diff --git a/views/polls.jade b/views/polls.jade deleted file mode 100644 index 504f3d3..0000000 --- a/views/polls.jade +++ /dev/null @@ -1,36 +0,0 @@ -div#backlink - a(href='/polls/') « Poll list -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}%") - case votes - when 1: #{votes} vote - default: #{votes} votes - -if(!isNaN(percentage)) - |(#{percentage.toFixed(2)}%) - -if(hasYouTubeVids) - script(src='/ytembed.js') diff --git a/views/quotelist.jade b/views/quotes/quotelist.jade similarity index 94% rename from views/quotelist.jade rename to views/quotes/quotelist.jade index df97c7b..d038e0a 100644 --- a/views/quotelist.jade +++ b/views/quotes/quotelist.jade @@ -1,4 +1,4 @@ -extends layout +extends ../layout block content div#backlink diff --git a/views/quotes.jade b/views/quotes/quotes.jade similarity index 98% rename from views/quotes.jade rename to views/quotes/quotes.jade index 38c73e1..a40d12e 100644 --- a/views/quotes.jade +++ b/views/quotes/quotes.jade @@ -1,4 +1,4 @@ -extends layout +extends ../layout block content div#backlink diff --git a/views/channels.jade b/views/users/channels.jade similarity index 93% rename from views/channels.jade rename to views/users/channels.jade index 7cebf54..6315ab6 100644 --- a/views/channels.jade +++ b/views/users/channels.jade @@ -1,4 +1,4 @@ -extends layout +extends ../layout block content h3 Channels on #{connection} diff --git a/views/connections.jade b/views/users/connections.jade similarity index 91% rename from views/connections.jade rename to views/users/connections.jade index dd1e63b..0e7f06f 100644 --- a/views/connections.jade +++ b/views/users/connections.jade @@ -1,4 +1,4 @@ -extends layout +extends ../layout block content h3 Current Connections diff --git a/views/user.jade b/views/users/user.jade similarity index 95% rename from views/user.jade rename to views/users/user.jade index 8d1a680..072362e 100644 --- a/views/user.jade +++ b/views/users/user.jade @@ -1,4 +1,4 @@ -extends layout +extends ../layout block content h3 #{user}'s profile diff --git a/views/users.jade b/views/users/users.jade similarity index 94% rename from views/users.jade rename to views/users/users.jade index d043702..d20c9e2 100644 --- a/views/users.jade +++ b/views/users/users.jade @@ -1,4 +1,4 @@ -extends layout +extends ../layout block content h3 Users currently in #{channel} on #{connection} From 9b0cefe932e6e7a128b93701e8a65912266060a8 Mon Sep 17 00:00:00 2001 From: reality Date: Thu, 27 Dec 2012 23:18:41 +0000 Subject: [PATCH 018/347] auto title option for link --- modules/link/config.json | 3 +++ modules/link/link.js | 12 ++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 modules/link/config.json diff --git a/modules/link/config.json b/modules/link/config.json new file mode 100644 index 0000000..d1a8210 --- /dev/null +++ b/modules/link/config.json @@ -0,0 +1,3 @@ +{ + "autoTitle": false +} diff --git a/modules/link/link.js b/modules/link/link.js index b9c5eaf..d0bf2d9 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -41,6 +41,18 @@ var link = function(dbot) { var urlMatches = event.message.match(urlRegex); if(urlMatches !== null) { links[event.channel.name] = urlMatches[0]; + + if(dbot.config.link.autoTitle == true) { + request(urlMatches[0], function (error, response, body) { + if(!error && response.statusCode == 200) { + body = body.replace(/(\r\n|\n\r|\n)/gm, " "); + var title = body.valMatch(/(.*)<\/title>/, 2); + if(title) { + event.reply(title[1]); + } + } + }); + } } }, 'on': 'PRIVMSG' From 0af9ad1015744692a9f20ba8609c6e564c9ad99c Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 28 Dec 2012 15:42:27 +0000 Subject: [PATCH 019/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 8867e35..cb92651 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 8867e3592ea03b85093a5ab79017efb26c9156be +Subproject commit cb926510a9fc3b28f5c9489b13f1f3c3a78017b9 From 1cc83dc6bc78c102935c790a2e38728ac5e654e3 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 29 Dec 2012 14:34:24 +0000 Subject: [PATCH 020/347] update stats --- modules/stats | 2 +- modules/web/config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/stats b/modules/stats index cb92651..d1889c9 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit cb926510a9fc3b28f5c9489b13f1f3c3a78017b9 +Subproject commit d1889c920c3d69ce868ac34a1ad182229a2c5e41 diff --git a/modules/web/config.json b/modules/web/config.json index 981e0f7..60f35d1 100644 --- a/modules/web/config.json +++ b/modules/web/config.json @@ -1,4 +1,4 @@ { "webHost": "localhost", - "webPort": 8080 + "webPort": 8090 } From e7addd9ff47970a42c3461c90f2662f851d731e1 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Sat, 29 Dec 2012 16:01:03 +0100 Subject: [PATCH 021/347] Stop alias if already exists in user --- modules/users/users.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/users/users.js b/modules/users/users.js index d4f6afa..670c84d 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -45,7 +45,9 @@ var users = function(dbot) { } } else if(event.action == 'NICK') { var newNick = event.params.substr(1); - knownUsers.aliases[newNick] = event.user; + if(!knownUsers.users.include(newNick)) { + knownUsers.aliases[newNick] = event.user; + } } }, 'on': ['JOIN', 'NICK'], From 863e86273142e7d768138519ebf7176324404fdb Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sat, 29 Dec 2012 18:42:32 +0000 Subject: [PATCH 022/347] Escape snippet --- snippets.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/snippets.js b/snippets.js index 55c7fec..808ca4c 100644 --- a/snippets.js +++ b/snippets.js @@ -263,3 +263,8 @@ Number.prototype.numberFormat = function(dec_places){ parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, sep); return parts.join(dec_point); } + +// http://simonwillison.net/2006/Jan/20/escape/#p-6 +String.prototype.escape = function() { + return this.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); +} From 944b97e430c1998066e0dd15385902799d3ea093 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 29 Dec 2012 18:45:19 +0000 Subject: [PATCH 023/347] Add ~setaliasparent command [#83] --- modules/users/users.js | 58 +++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/modules/users/users.js b/modules/users/users.js index 670c84d..9190bcd 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -21,21 +21,55 @@ var users = function(dbot) { } }); + var commands = { + '~alias': function(event) { + var knownUsers = getServerUsers(event); + var alias = event.params[1].trim(); + if(knownUsers.aliases.hasOwnProperty(alias)) { + event.reply(alias + ' is an alias of ' + knownUsers.aliases[alias]); + } else { + event.reply(alias + ' is not known as an alias to me.'); + } + }, + + '~setaliasparent': function(event) { + if(dbot.config.admins.include(event.user)) { + var knownUsers = getServerUsers(event); + var newParent = event.params[1]; + + if(knownUsers.aliases.hasOwnProperty(newParent)) { + var newAlias = knownUsers.aliases[newParent]; + + // Replace users entry with new primary user + var usersIndex = knownUsers.users.indexOf(newAlias); + knownUsers.users[usersIndex] = newParent; + + // Remove alias for new parent & add alias for new alias + delete knownUsers.aliases[newParent]; + knownUsers.aliases[newAlias] = newParent; + + // Update aliases to point to new primary user + for(var alias in knownUsers.aliases) { + if(knownUsers.aliases.hasOwnProperty(alias)) { + if(knownUsers.aliases[alias] === newAlias) { + knownUsers.aliases[alias] = newParent; + } + } + } + + event.reply(newParent + ' is now the parent user, and ' + + newAlias + ' is an alias.'); + } else { + event.reply('Given new parent does not currently exist as an alias.'); + } + } + } + }; + return { 'name': 'users', 'ignorable': false, - - 'commands': { - '~alias': function(event) { - var knownUsers = getServerUsers(event); - var alias = event.params[1].trim(); - if(knownUsers.aliases.hasOwnProperty(alias)) { - event.reply(alias + ' is an alias of ' + knownUsers.aliases[alias]); - } else { - event.reply(alias + ' is not known as an alias to me.'); - } - } - }, + 'commands': commands, 'listener': function(event) { var knownUsers = getServerUsers(event); From 4ce43d3218046950c91bd7e3defd9a1be3e86ffd Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 29 Dec 2012 18:47:09 +0000 Subject: [PATCH 024/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index d1889c9..ab4a54f 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit d1889c920c3d69ce868ac34a1ad182229a2c5e41 +Subproject commit ab4a54ff2acac0ae5846e9434bb77137b3e7869d From 824e6fb3ff65cd550e835169f1485f9ec3655bab Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 29 Dec 2012 20:07:14 +0000 Subject: [PATCH 025/347] strings.json for users module --- modules/users/strings.json | 11 +++++++++++ modules/users/users.js | 11 ++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 modules/users/strings.json diff --git a/modules/users/strings.json b/modules/users/strings.json new file mode 100644 index 0000000..2a8b876 --- /dev/null +++ b/modules/users/strings.json @@ -0,0 +1,11 @@ +{ + "alias": { + "english": "{alias} is an alias of {user}" + }, + "unknown_alias": { + "english": "{alias} does not currently exist as an alias." + }, + "aliasparentset": { + "english": "{newParent} is now the parent user, and {newAlias} is an alias" + } +} diff --git a/modules/users/users.js b/modules/users/users.js index 9190bcd..683fd62 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -26,9 +26,10 @@ var users = function(dbot) { var knownUsers = getServerUsers(event); var alias = event.params[1].trim(); if(knownUsers.aliases.hasOwnProperty(alias)) { - event.reply(alias + ' is an alias of ' + knownUsers.aliases[alias]); + event.reply(dbot.t('alias', { 'alias': alias, + 'user': knownUsers.aliases[alias] })); } else { - event.reply(alias + ' is not known as an alias to me.'); + event.reply(dbot.t('unknown_alias', { 'alias': alias })); } }, @@ -57,10 +58,10 @@ var users = function(dbot) { } } - event.reply(newParent + ' is now the parent user, and ' + - newAlias + ' is an alias.'); + event.reply(dbot.t('aliasparentset', { 'newParent': newParent, + 'newAlias': newAlias })); } else { - event.reply('Given new parent does not currently exist as an alias.'); + event.reply(dbot.t('unknown_alias', { 'alias': newParent})); } } } From 30a5878b97306c8a81ac631b292b99a4a325a209 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 29 Dec 2012 21:08:45 +0000 Subject: [PATCH 026/347] fixStats call --- modules/users/users.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/users/users.js b/modules/users/users.js index 683fd62..46fe1e8 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -60,6 +60,8 @@ var users = function(dbot) { event.reply(dbot.t('aliasparentset', { 'newParent': newParent, 'newAlias': newAlias })); + + dbot.modules.stats.fixStats(event.server, newAlias); // :'( } else { event.reply(dbot.t('unknown_alias', { 'alias': newParent})); } From 8bd9f93632b411007f440dde3cfe94e0b1418b72 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 29 Dec 2012 23:05:16 +0000 Subject: [PATCH 027/347] add readme files for command and quotes [#75] --- README.md | 43 ++----------------------- modules/command/README.md | 14 ++++++++ modules/quotes/README.md | 68 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 40 deletions(-) create mode 100644 modules/command/README.md create mode 100644 modules/quotes/README.md diff --git a/README.md b/README.md index f9adc1c..861b725 100644 --- a/README.md +++ b/README.md @@ -18,53 +18,16 @@ Requirements: handles the IRC protocol. - Various modules have their own requirements also. -### JSBot +### External Modules -JSBot can be imported by running the following commands in the cloned repository: +JSBot and externally developed modules can be imported by running the following +commands in the cloned repository: git submodule init git submodule update ## Modules: -### Command - -This handles the command execution logic for DBot. - -1. Does the input match a command key in *dbot.commands* ? -2. Is there a quote category which matches the first part of the input - (*~category*)? -3. Is there a command name similar to to the first part of the input (*~name*) - in *dbot.commands*? - -This is the only module which is force loaded, even if it's not in the -configuration. - -### Quotes - -This is the original reason that DBot was created, stores and displays quotes. - -Commands: - -- _~q category_ - Display a random quote from a given category. -- _~qadd category=newquote_ - Add a new quote to the database. -- _~qstats_ - Show a list of the biggest quote categories. -- _~qsearch category needle_ - Search for a quote in a given category. -- _~rmlast [category]_ - Remove the last quote added to a given category, or the - last quote added. -- _~rm category quote_ - Remove a given quote from the given category. -- _~qcount category_ - Show the number of quotes stored in the given category. -- _~rq_ - Show a random quote from a random category. -- _~d_ - Show a quote from the category which matches the bot's name. -- _~link category_ - Create a link to the page on the web interface which displays the - given category's quotes. -- _~qprune_ - Delete empty quote categories. - -Unfortunately, this module is fairly highly coupled with certain other areas of -the program. I am working on this, but note, for example, that one can still -access quotes with the *~category* syntax even if the quotes module isn't -loaded. - ### Admin Various administration functionality such as banning users, hot-reloading the diff --git a/modules/command/README.md b/modules/command/README.md new file mode 100644 index 0000000..437f1e7 --- /dev/null +++ b/modules/command/README.md @@ -0,0 +1,14 @@ +## Command + +Handles the command execution logic for DBot. + +### Description + +1. Does the input match a command key in *dbot.commands* ? +2. Is there a quote category which matches the first part of the input + (*~category*)? +3. Is there a command name similar to to the first part of the input (*~name*) + in *dbot.commands*? + +This is the only module which is force loaded, even if it's not specified in +the configuration file. diff --git a/modules/quotes/README.md b/modules/quotes/README.md new file mode 100644 index 0000000..1f2536e --- /dev/null +++ b/modules/quotes/README.md @@ -0,0 +1,68 @@ +## Quotes + +Stores and displays quotes. + +### Description + +This is the original reason that DBot was created, stores and displays quotes. + +### Configuration + +#### rmLimit: 10 +Amount of quotes which can be removed before admin approval is required. + +### Commands + +#### ~q [category] +Display a random quote from a given category. + +#### ~qadd [category] = [quote] +Add a new quote to the database. + +#### ~qstats +Show a list of the biggest quote categories. + +#### ~qsearch [category] = [needle] +Search a category for quotes including the given text. + +#### ~rmlast [category] +Remove the last quote added to a given category. + +#### ~rmstatus +Show how many quotes are currently in the removal cache, and whether they will +be randomly removed. + +#### ~rm [category] = [quote] +Remove a given quote from the given category. + +#### ~qcount [category] +Show the number of quotes stored in the given category, or if called without a +category it will show the total number of quotes in the database. + +#### ~rq +Show a random quote from the database. + +#### ~link [category] +Show a link to the page on the web interface which shows this category's quotes. + +### Admin-only Commands + +#### ~rmconfirm +Confirm that the quotes currently in the removal cache are okay to be removed, +and permanently delete them. + +#### ~rmdeny +Re-instate the quotes that are currently in the removal cache back into the main +quote database. + +### Removal Spam Protection + +When quotes are removed using either the ~rm or ~rmlast commands, the quotes are +removed from the main database, but are stored in a removal cache which is cleared +out ten minutes from the last time a quote was removed from the database. If the +number of quotes removed from the database reaches a certain limit (as per rmLimit +in config, default 10) then the counter is removed and the cache will not be deleted +automatically. In such a case, a DBot admin needs to either run the ~rmconfim command +to have the removal cache cleared, or ~rmdeny to re-instate all of the quotes in +the removal cache back into the main quote database. This is to stop mass +removal from the database without limiting the user interface. From 9f3596aa6af8c62618c279407ebd8ec9ec588381 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 00:45:25 +0000 Subject: [PATCH 028/347] dbot.modules is now an object --- modules/ignore/ignore.js | 9 +++++---- run.js | 4 ++-- snippets.js | 10 +++++++++- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/modules/ignore/ignore.js b/modules/ignore/ignore.js index b7330b7..b6f78d0 100644 --- a/modules/ignore/ignore.js +++ b/modules/ignore/ignore.js @@ -8,11 +8,12 @@ var ignore = function(dbot) { var commands = { '~ignore': function(event) { var ignorableModules = []; - for(var i=0;i<dbot.modules.length;i++) { - if(dbot.modules[i].ignorable != null && dbot.modules[i].ignorable == true) { - ignorableModules.push(dbot.modules[i].name); + + dbot.modules.each(function(module) { + if(module.ignorable != null && module.ignorable == true) { + ignorableModules.push(module.name); } - } + }); var module = event.params[1]; if(module === undefined) { diff --git a/run.js b/run.js index 26ddcea..abeb17c 100644 --- a/run.js +++ b/run.js @@ -117,7 +117,7 @@ DBot.prototype.reloadModules = function() { } this.rawModules = []; - this.modules = []; + this.modules = {}; this.commands = {}; this.commandMap = {}; // Map of which commands belong to which modules this.usage = {}; @@ -226,7 +226,7 @@ DBot.prototype.reloadModules = function() { // Invalid or no string info } - this.modules.push(module); + this.modules[module.name] = module; } catch(err) { console.log(this.t('module_load_error', {'moduleName': name})); if(this.config.debugMode) { diff --git a/snippets.js b/snippets.js index 808ca4c..6f703cd 100644 --- a/snippets.js +++ b/snippets.js @@ -204,7 +204,15 @@ Object.prototype.filter = function(fun) { } } return filtered; -} +}; + +Object.prototype.each = function(fun) { + for(var key in this) { + if(this.hasOwnProperty(key)) { + fun(this[key]); + } + } +}; /*** Integer ***/ From 168d1335aa47c72188560c63bf0b263a57996b32 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 01:27:55 +0000 Subject: [PATCH 029/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index ab4a54f..57bcfae 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit ab4a54ff2acac0ae5846e9434bb77137b3e7869d +Subproject commit 57bcfaed7e73283747b7d2743f11b9176eb2a989 From 042f6b223652f9187fb32471ab322f07c4a8d488 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 16:33:25 +0000 Subject: [PATCH 030/347] Report module uses strings.json [#88] --- modules/report/report.js | 17 ++++++++++------- modules/report/strings.json | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 modules/report/strings.json diff --git a/modules/report/report.js b/modules/report/report.js index 1e6f03d..77100a7 100644 --- a/modules/report/report.js +++ b/modules/report/report.js @@ -21,18 +21,21 @@ var report = function(dbot) { } for(var i=0;i<ops.length;i++) { - dbot.say(event.server, ops[i], - 'Attention: ' + event.user + ' has reported ' + - nick + ' in ' + channelName + '. The reason ' + - 'given was: "' + reason + '."'); + dbot.say(event.server, ops[i], dbot.t('report', { + 'reporter': event.user, + 'reported': nick, + 'channel': channelName, + 'reason': reason + })); } - event.reply('Thank you, ' + nick + ' has been reported the channel administrators.'); + event.reply(dbot.t('reported', { 'reported': nick })); } else { - event.reply('User is not in that channel.'); + event.reply(dbot.t('user_not_found', { 'reported': nick, + 'channel': channelName })); } } else { - event.reply('I am not in that channel.'); + event.reply(dbot.t('not_in_channel', { 'channel': channelName })); } } diff --git a/modules/report/strings.json b/modules/report/strings.json new file mode 100644 index 0000000..27f58d6 --- /dev/null +++ b/modules/report/strings.json @@ -0,0 +1,14 @@ +{ + "report": { + "english": "Attention: {reporter} has reported {reported} in {channel}. The reason given was: \"{reason}.\"" + }, + "reported": { + "english": "Thank you, {reported} has been reported to the channel administrators." + }, + "user_not_found": { + "english": "{reported} does not appear to be in {channel}." + }, + "not_in_channel": { + "english": "I am not present in {channel}." + } +} From 49c7e045afdf7f6b9ce107be5a833c19658a063c Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 16:41:10 +0000 Subject: [PATCH 031/347] Complete strings.json usage in admin module [#88] --- modules/admin/admin.js | 6 +++--- modules/admin/strings.json | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/admin/admin.js b/modules/admin/admin.js index d51474b..a230c9f 100644 --- a/modules/admin/admin.js +++ b/modules/admin/admin.js @@ -13,7 +13,7 @@ var admin = function(dbot) { 'join': function(event) { var channel = event.params[1]; if(event.allChannels.hasOwnProperty(channel)) { - event.reply("I'm already in that channel."); + event.reply(dbot.t('already_in_channel', {'channel': channel})); } else { dbot.instance.join(event, channel); event.reply(dbot.t('join', {'channel': channel})); @@ -24,7 +24,7 @@ var admin = function(dbot) { 'part': function(event) { var channel = event.params[1]; if(!event.allChannels.hasOwnProperty(channel)) { - event.reply("I'm not in that channel."); + event.reply(dbot.t('not_in_channel', {'channel': channel})); } else { event.instance.part(event, channel); event.reply(dbot.t('part', {'channel': channel})); @@ -57,7 +57,7 @@ var admin = function(dbot) { event.reply(dbot.t('reload')); }, - // Say something in a channel (TODO probably doesn't work.) + // Say something in a channel 'say': function(event) { var channel = event.params[1]; if(event.params[1] === "@") { diff --git a/modules/admin/strings.json b/modules/admin/strings.json index 8ecacd0..1ca3ed4 100644 --- a/modules/admin/strings.json +++ b/modules/admin/strings.json @@ -64,5 +64,11 @@ "spanish": "Cerrado la categoría: {category}", "na'vi": "{category}ìri oel 'upxareti fmoli", "welsh": "Categori wedi cloi: {category}" + }, + "already_in_channel": { + "english": "I'm already in {channel}" + }, + "not_in_channel": { + "english": "I'm not in {channel}" } } From 56a7107b88c823ba11f913c5c713a3b02ea5c8a8 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 16:45:14 +0000 Subject: [PATCH 032/347] Complete strings.json usage in command [#88] --- modules/command/strings.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/command/strings.json b/modules/command/strings.json index 47e1b11..975c0ad 100644 --- a/modules/command/strings.json +++ b/modules/command/strings.json @@ -10,5 +10,8 @@ "spanish": "Sintaxis no válida. Iniciar incineración.", "na'vi": "Ngeyä pamrel keyawr lu. Nga skxawng lu.", "welsh": "Cystrawen annilys. Cychwyn orfflosgiad" + }, + "no_usage_info": { + "No usage information found for {command}." } } From 5bf5b257f802a27119e9de6ef12f96fb64a04d04 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 16:51:30 +0000 Subject: [PATCH 033/347] strings.json usage complete in link [#88] --- modules/link/link.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/link/link.js b/modules/link/link.js index d0bf2d9..b1ff7ac 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -25,7 +25,7 @@ var link = function(dbot) { if(title) { event.reply(title[1]); } else { - event.reply('no title found'); + event.reply(dbot.t('title_not_found')); } } }); From 1746a9c7b85f125d845f78a850b59cabf8a30e50 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 17:26:04 +0000 Subject: [PATCH 034/347] Module documentation for Admin module [#75] * Also removed lock functionality from quotes and admin modules. --- modules/admin/README.md | 57 +++++++++++++++++++++++++++++++++++++++ modules/admin/admin.js | 7 ----- modules/admin/config.json | 2 +- modules/quotes/quotes.js | 40 +++++++++++---------------- 4 files changed, 74 insertions(+), 32 deletions(-) create mode 100644 modules/admin/README.md diff --git a/modules/admin/README.md b/modules/admin/README.md new file mode 100644 index 0000000..0a0583c --- /dev/null +++ b/modules/admin/README.md @@ -0,0 +1,57 @@ +## Admin + +Administrator functionality. + +### Description + +Various administration functionality such as banning users, hot-reloading the +code and ordering him to talk. Note that commands added here are handled with +their own listener, rather than being part of the command logic which is handled +by the Command module. Functionality in this module can be slightly unsafe as +not everything is thoroughly sanity checked. + +### Commands + +#### join [#channel] +Join the given channel. + +#### part [#channel] +Leave the given channel. + +#### opme [#channel] +Gives the caller ops in a given channel if possible. If called without a +channel, it will attempt to give the caller ops in the current channel. + +#### greload +Perform a git pull, and then execute the 'reload' command. Saves a lot of time +updating! + +#### reload +Reload all of the modules currently in use by DBot. By using this, all module +functionality should be reloadable and replaceable without having to restart the +bot or interrupt the connection to the server. + +#### say [#channel] [message] +Have DBot post the given message in the given channel (uses the server from +which you are sending the message). You may replace channel with '@' to have him +post the message in the current channel. Channel may also be replaced with a +nick on the server. + +#### load [module] +Load a new module. This works by adding a module name to the roster and then +triggering a reload of all modules, at which point the new module is actually +loaded by the standard DBot process. + +#### unload [module] +Unload a currently loaded module. This removes the module, and then triggers a +reload of all modules. + +#### ban [user] [command] +Ban a user from using a command. Command may be replaced with '\*,' which will +ban a user from use of all commands. Users banned from all commands will still +be subject to module listeners. + +#### unban [user] [command] +Unban a user from using a given command. If a user was previously banned using +the '\*' wildcard, they may also be unbanned from such by replacing command with +an asterisk here as well. diff --git a/modules/admin/admin.js b/modules/admin/admin.js index a230c9f..1cc12f3 100644 --- a/modules/admin/admin.js +++ b/modules/admin/admin.js @@ -116,13 +116,6 @@ var admin = function(dbot) { } else { event.reply(dbot.t('unban_error', {'user': username})); } - }, - - // 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})); } }; diff --git a/modules/admin/config.json b/modules/admin/config.json index e1a07bb..1d1582a 100644 --- a/modules/admin/config.json +++ b/modules/admin/config.json @@ -1,3 +1,3 @@ { - "dbKeys": [ "bans", "locks" ] + "dbKeys": [ "bans" ] } diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index 7d8b1f3..7ece49c 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -157,17 +157,13 @@ var quotes = function(dbot) { if(rmAllowed == true || dbot.config.admins.include(event.user)) { var key = event.input[1].trim().toLowerCase(); if(quotes.hasOwnProperty(key)) { - if(!dbot.db.locks.include(key) || dbot.config.admins.include(event.user)) { - var quote = quotes[key].pop(); - if(quotes[key].length === 0) { - delete quotes[key]; - } - resetRemoveTimer(event, key, quote); - - event.reply(dbot.t('removed_from', {'quote': quote, 'category': key})); - } else { - event.reply(dbot.t('locked_category', {'category': q[1]})); + var quote = quotes[key].pop(); + if(quotes[key].length === 0) { + delete quotes[key]; } + resetRemoveTimer(event, key, quote); + + event.reply(dbot.t('removed_from', {'quote': quote, 'category': key})); } else { event.reply(dbot.t('no_quotes', {'category': q[1]})); } @@ -182,22 +178,18 @@ var quotes = function(dbot) { var quote = event.input[2]; if(quotes.hasOwnProperty(key)) { - if(!dbot.db.locks.include(key)) { - var category = quotes[key]; - var index = category.indexOf(quote); - if(index !== -1) { - category.splice(index, 1); - if(category.length === 0) { - delete quotes[key]; - } - resetRemoveTimer(event, key, quote); - - event.reply(dbot.t('removed_from', {'category': key, 'quote': quote})); - } else { - event.reply(dbot.t('q_not_exist_under', {'category': key, 'quote': quote})); + var category = quotes[key]; + var index = category.indexOf(quote); + if(index !== -1) { + category.splice(index, 1); + if(category.length === 0) { + delete quotes[key]; } + resetRemoveTimer(event, key, quote); + + event.reply(dbot.t('removed_from', {'category': key, 'quote': quote})); } else { - event.reply(dbot.t('locked_category', {'category': key})); + event.reply(dbot.t('q_not_exist_under', {'category': key, 'quote': quote})); } } else { event.reply(dbot.t('category_not_found', {'category': key})); From c9d78b99c9457c8954a875fb8945a3e889c990f7 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 17:31:06 +0000 Subject: [PATCH 035/347] Forgot to add the strings.json for link! --- modules/link/strings.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 modules/link/strings.json diff --git a/modules/link/strings.json b/modules/link/strings.json new file mode 100644 index 0000000..a4a0023 --- /dev/null +++ b/modules/link/strings.json @@ -0,0 +1,5 @@ +{ + "title_not_found": { + "english": "No page title found." + } +} From 5e8495c3bbe903662dde2a6cb80c5e60fe8b7526 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 17:36:52 +0000 Subject: [PATCH 036/347] Remove repeated title fetching code in Link module --- modules/link/link.js | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/modules/link/link.js b/modules/link/link.js index b1ff7ac..435c6ec 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -7,6 +7,19 @@ var request = require('request'); var link = function(dbot) { var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; var links = {}; + var fetchTitle = function(event, link) { + 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]); + } else { + event.reply(dbot.t('title_not_found')); + } + } + }); + }; var commands = { '~title': function(event) { @@ -17,18 +30,7 @@ var link = function(dbot) { link = urlMatches[0]; } } - - 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]); - } else { - event.reply(dbot.t('title_not_found')); - } - } - }); + fetchTitle(event, link); } }; @@ -43,15 +45,7 @@ var link = function(dbot) { links[event.channel.name] = urlMatches[0]; if(dbot.config.link.autoTitle == true) { - request(urlMatches[0], 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]); - } - } - }); + fetchTitle(event, urlMatches[0]); } } }, From 85fc4d6e6fd2627737f5ada72d94cf3de9f1466e Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 17:44:51 +0000 Subject: [PATCH 037/347] Documentation for the Ignore module [#75] --- modules/ignore/README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 modules/ignore/README.md diff --git a/modules/ignore/README.md b/modules/ignore/README.md new file mode 100644 index 0000000..816b059 --- /dev/null +++ b/modules/ignore/README.md @@ -0,0 +1,26 @@ +## Ignore + +Ignore modules. + +### Description + +Commands with which users can choose to ignore listeners and commands from +certain modules persistently, by storing their choices in the database. This is +an interface for the JSBot ignoreTag functionality which actually implements +the ignoration. + +### Configuration + +All modules may return with them an 'ignorable' property, which defines whether +or not their functionality may be ignored by users. + +### Commands + +#### ~ignore [module] +Ignore a given module. If the user does not specify a module, or provides an +invalid one a list of modules which are available to ignore will be given. + +#### ~unignore [module] +Unignore a previously ignored module. If the user does not specify a module, or +provides an invalid choice a list of modules which are currently ignored will be +given. From 078c4cf3e3f3630b537f179d88e64dd735238866 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 17:52:42 +0000 Subject: [PATCH 038/347] ignorableModules now built with filter, module.toString returns name --- modules/ignore/ignore.js | 6 ++---- run.js | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/ignore/ignore.js b/modules/ignore/ignore.js index b6f78d0..14fdd5a 100644 --- a/modules/ignore/ignore.js +++ b/modules/ignore/ignore.js @@ -7,11 +7,9 @@ var ignore = function(dbot) { var commands = { '~ignore': function(event) { - var ignorableModules = []; - - dbot.modules.each(function(module) { + var ignorableModules = dbot.modules.filter(function(module) { if(module.ignorable != null && module.ignorable == true) { - ignorableModules.push(module.name); + return true; } }); var module = event.params[1]; diff --git a/run.js b/run.js index abeb17c..da148d3 100644 --- a/run.js +++ b/run.js @@ -226,6 +226,9 @@ DBot.prototype.reloadModules = function() { // Invalid or no string info } + module.toString = function() { + return this.name; + } this.modules[module.name] = module; } catch(err) { console.log(this.t('module_load_error', {'moduleName': name})); From 9721d1c22fb8132856ad48abe250737c499d8480 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 18:00:50 +0000 Subject: [PATCH 039/347] Documentation for the JS module [#75] --- README.md | 40 ---------------------------------------- modules/js/README.md | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 40 deletions(-) create mode 100644 modules/js/README.md diff --git a/README.md b/README.md index 861b725..75e95e2 100644 --- a/README.md +++ b/README.md @@ -28,16 +28,6 @@ commands in the cloned repository: ## Modules: -### Admin - -Various administration functionality such as banning users, hot-reloading the -code and ordering him to talk. Note that commands added here are handled with -their own listener, rather than being part of the command logic which is handled -by the Command module. Functionality in this module can be slightly unsafe as -not much error checking on the input is performed. - -TODO: Add summaries for each command in this module. - ### Spelling Will attempt to correct a users' spelling by using the levenshtein distance @@ -56,33 +46,3 @@ to correct another users like so: > userone: I am a tutrle. > usertwo: userone: *turtle > usertwo thinks userone meant: I am a turtle. - -### JS - -This module provides two commands which allow the execution of Javascript code. -For regular users, there is the *~js* command, which is completely sandboxed, -but can still be used for calculation and the like. - - > ~js Array(16).join('wat'-1) + " Batman!"; - 'NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN Batman!' - -This feature is fairly safe as the user doesn't have access to anything -dangerous, and is safe from infinite loops or locking DBot up because the code -which is run is killed if it does not finish within a short amount of time. - -For administrators, the incredibly useful *~ajs* command is also available. The -input for this command is simply 'eval'-ed and therefore has full access to -DBot's memory. Of course, this is incredibly unsafe, but I find it rather fun; -remember to only give extremely trusted friends administrator access to DBot, as -there's nothing to stop them wiping the database or something similar - if -you're worried about that kind of thing, do not load this module. - -However, it's useful for many things, such as administrative activity for -which there isn't a command in the admin module. For example, you could hot-add -a new administrator like this: - - > ~ajs dbot.admin.push('batman'); - 2 - -You can also use this for debugging, or even adding new commands while DBot is -running. diff --git a/modules/js/README.md b/modules/js/README.md new file mode 100644 index 0000000..57f0afd --- /dev/null +++ b/modules/js/README.md @@ -0,0 +1,40 @@ +## JS + +Run JavaScript. + +### Description + +This module provides two commands which allow the execution of Javascript code +from the bot. + +### Commands + +#### ~js [code] +For regular users, there is the *~js* command, which is completely sandboxed, +but can still be used for calculation and the like. + + > ~js Array(16).join('wat'-1) + " Batman!"; + 'NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN Batman!' + +This feature is fairly safe as the user doesn't have access to anything +dangerous, and is safe from infinite loops or locking DBot up because the code +which is run is killed if it does not finish within a short amount of time. + +#### ~ajs [code] +For administrators, the incredibly useful *~ajs* command is also available. The +input for this command is simply 'eval'-ed and therefore has full access to +DBot's memory. Of course, this is incredibly unsafe, but I find it rather fun; +remember to only give extremely trusted friends administrator access to your +DBot instance, as there's nothing to stop them wiping the database or probably +even your hard drive - if you're worried about that kind of thing, do not load +this module. + +However, it's useful for many things, such as administrative activity for +which there isn't a command in the admin module. For example, you could hot-add +a new administrator like this: + + > ~ajs dbot.admin.push('batman'); + 2 + +You can also use it for debugging, or even adding new commands while DBot is +running. From 26e731697d08f3e8960b68549d5388b15d2bb154 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 18:06:38 +0000 Subject: [PATCH 040/347] Documentation for kick module. [#75] --- modules/kick/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 modules/kick/README.md diff --git a/modules/kick/README.md b/modules/kick/README.md new file mode 100644 index 0000000..b3aa217 --- /dev/null +++ b/modules/kick/README.md @@ -0,0 +1,17 @@ +## Kick + +Kicking and kicking-related accessories. + +### Description +This module counts the number of times people are kicked from and kick people +from channels, and provides commands for viewing this data. It also has the bot +attempt to rejoin the channel if it is kicked. + +### Commands + +#### ~kickcount [username] +Show the number of times a given user has been kicked and has kicked other +people. + +#### ~kickstats +Show a list of top kickers and kickees. From 6f5105e36c3f9bfb7517ceea44c668822d91718e Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 18:12:23 +0000 Subject: [PATCH 041/347] Module documentation for Link [#75] --- modules/link/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 modules/link/README.md diff --git a/modules/link/README.md b/modules/link/README.md new file mode 100644 index 0000000..5b83bce --- /dev/null +++ b/modules/link/README.md @@ -0,0 +1,21 @@ +## Link + +Retrieves page titles. + +### Description + +This module stores the last posted link in each channel, and provides a command +for retrieving the title of a given link or the last posted link in the channel. + +### Configuration + +#### autoTitle: false +If this is set to true, the bot will automatically post the titles of links as +they are posted in the channel. + +### Commands + +#### ~title [link] +If called with a link, the bot will attempt to find and return the title of that +page. If called without a link, the bot will attempt the same on the last link +which was posted in the current channel. From 887e8540126ee5ebf85b3890d99f4d9894e371f1 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 18:38:36 +0000 Subject: [PATCH 042/347] Documentation for polls [#75] --- modules/poll/README.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 modules/poll/README.md diff --git a/modules/poll/README.md b/modules/poll/README.md new file mode 100644 index 0000000..86d3faa --- /dev/null +++ b/modules/poll/README.md @@ -0,0 +1,35 @@ +## Poll + +Pollers gonna poll. + +### Description +This module allows creation of and voting in polls, with associated +functionality. + +Note that while in terms of the interface all votes are anonymous, users' +voting choices are stored in the database for the purpose of users being +able to change their votes. Therefore an admin can technically go delving in +the database to see users' voting choices. + +### Commands + +#### ~newpoll [pollname] options=[each,poll,option] [Poll Description] +Creates a new poll with the given name, options and descriptions. From this +point people will be able to use the ~vote command to cast their vote in the +poll. + +#### ~addoption [pollname] [newoption] +Using this command you can add a given option to a poll you are the creator of. + +#### ~rmoption [pollname] [optiontoremove] +Using this command you can remove a given option from a poll you are the creator +of. + +#### ~vote [pollname] [option] +Cast your vote for the given option in the given poll. If you have already cast +your vote in the given poll, your vote will be changed to the new option you +have provided. + +#### ~pdesc [pollname] +Show the full description for a given poll name along with its available voting +options. From ae902e3c21f47c01a4253ed4128e3ab647e3a9ae Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 18:53:20 +0000 Subject: [PATCH 043/347] Consolidate puns and quotes modules [#90] --- modules/puns/puns.js | 25 ------------------ modules/quotes/quotes.js | 55 ++++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 50 deletions(-) delete mode 100644 modules/puns/puns.js diff --git a/modules/puns/puns.js b/modules/puns/puns.js deleted file mode 100644 index 187a652..0000000 --- a/modules/puns/puns.js +++ /dev/null @@ -1,25 +0,0 @@ -var puns = function(dbot) { - var name = 'puns'; - var dbot = dbot; - - return { - 'name': name, - 'ignorable': true, - - 'listener': function(event) { - event.user = dbot.cleanNick(event.user); - if(dbot.config.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); - } - }, - 'on': 'JOIN' - }; -} - -exports.fetch = function(dbot) { - return puns(dbot); -}; diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index 7ece49c..800fe72 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -265,38 +265,43 @@ var quotes = function(dbot) { 'commands': commands, 'listener': function(event) { - // Reality Once listener - if((dbot.db.ignores.hasOwnProperty(event) && - dbot.db.ignores[event.user].include(name)) == false) { - if(event.user == 'reality') { - var once = event.message.valMatch(/^I ([\d\w\s,'-]* once)/, 2); - } else { - var once = event.message.valMatch(/^reality ([\d\w\s,'-]* once)/, 2); - } - - if(once) { - if((dbot.db.bans.hasOwnProperty('~qadd') && - dbot.db.bans['~qadd'].include(event.user)) || - dbot.db.bans['*'].include(event.user)) { - event.reply(dbot.t('command_ban', {'user': event.user})); + if(event.action == 'PRIVMSG') { + if((dbot.db.ignores.hasOwnProperty(event) && + dbot.db.ignores[event.user].include(name)) == false) { + if(event.user == 'reality') { + var once = event.message.valMatch(/^I ([\d\w\s,'-]* once)/, 2); } else { - if(!dbot.db.quoteArrs.hasOwnProperty('realityonce')) { - dbot.db.quoteArrs['realityonce'] = []; - } - if(dbot.db.quoteArrs['realityonce'].include('reality ' + once[1] + '.')) { - event.reply(event.user + ': reality has already done that once.'); + var once = event.message.valMatch(/^reality ([\d\w\s,'-]* once)/, 2); + } + + if(once) { + if((dbot.db.bans.hasOwnProperty('~qadd') && + dbot.db.bans['~qadd'].include(event.user)) || + dbot.db.bans['*'].include(event.user)) { + event.reply(dbot.t('command_ban', {'user': event.user})); } else { - dbot.db.quoteArrs['realityonce'].push('reality ' + once[1] + '.'); - addStack.push('realityonce'); - rmAllowed = true; - event.reply('\'reality ' + once[1] + '.\' saved.'); + if(!dbot.db.quoteArrs.hasOwnProperty('realityonce')) { + dbot.db.quoteArrs['realityonce'] = []; + } + if(dbot.db.quoteArrs['realityonce'].include('reality ' + once[1] + '.')) { + event.reply(event.user + ': reality has already done that once.'); + } else { + dbot.db.quoteArrs['realityonce'].push('reality ' + once[1] + '.'); + addStack.push('realityonce'); + rmAllowed = true; + event.reply('\'reality ' + once[1] + '.\' saved.'); + } } } } + } else if(event.action == 'JOIN') { + event.message = '~q ' + event.user; + event.action = 'PRIVMSG'; + event.params = event.message.split(' '); + dbot.instance.emit(event); } }, - - 'on': 'PRIVMSG' + 'on': ['PRIVMSG', 'JOIN'] }; }; From 11cfa5d40c831f925bf8f9b283d71ace016184e2 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 19:24:10 +0000 Subject: [PATCH 044/347] realityonce now just emits event. removed a lot of useless shit from there too --- modules/quotes/quotes.js | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index 800fe72..14b9467 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -266,34 +266,18 @@ var quotes = function(dbot) { 'listener': function(event) { if(event.action == 'PRIVMSG') { - if((dbot.db.ignores.hasOwnProperty(event) && - dbot.db.ignores[event.user].include(name)) == false) { - if(event.user == 'reality') { - var once = event.message.valMatch(/^I ([\d\w\s,'-]* once)/, 2); - } else { - var once = event.message.valMatch(/^reality ([\d\w\s,'-]* once)/, 2); - } - - if(once) { - if((dbot.db.bans.hasOwnProperty('~qadd') && - dbot.db.bans['~qadd'].include(event.user)) || - dbot.db.bans['*'].include(event.user)) { - event.reply(dbot.t('command_ban', {'user': event.user})); - } else { - if(!dbot.db.quoteArrs.hasOwnProperty('realityonce')) { - dbot.db.quoteArrs['realityonce'] = []; - } - if(dbot.db.quoteArrs['realityonce'].include('reality ' + once[1] + '.')) { - event.reply(event.user + ': reality has already done that once.'); - } else { - dbot.db.quoteArrs['realityonce'].push('reality ' + once[1] + '.'); - addStack.push('realityonce'); - rmAllowed = true; - event.reply('\'reality ' + once[1] + '.\' saved.'); - } - } - } + if(event.user == 'reality') { + var once = event.message.valMatch(/^I ([\d\w\s,'-]* once)/, 2); + } else { + var once = event.message.valMatch(/^reality ([\d\w\s,'-]* once)/, 2); } + + if(once) { + event.message = '~qadd realityonce=reality ' + once[1]; + event.action = 'PRIVMSG'; + event.params = event.message.split(' '); + dbot.instance.emit(event); + } } else if(event.action == 'JOIN') { event.message = '~q ' + event.user; event.action = 'PRIVMSG'; From 2e1de98df904e96121607bad1bef0447de684e48 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 19:47:53 +0000 Subject: [PATCH 045/347] Module documentation for Report [#75] --- modules/report/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 modules/report/README.md diff --git a/modules/report/README.md b/modules/report/README.md new file mode 100644 index 0000000..e0ca6ae --- /dev/null +++ b/modules/report/README.md @@ -0,0 +1,19 @@ +## Report + +Report users + +### Description +This module provides a command which allows users to report other users in a +channel to the operators of the channel, as well as posting an alert in the +administrative channel. It can be done either anonymously or publicly in the +channel. + +### Commands + +#### ~report [#channel] [username] [reason for reporting] +Report a user in a channel for a reason. This command can either be run publicly +in a channel or anonymously in a PM to the bot. The result of using this command +will be that all of the users which are currently marked as operators in the +reporting channel will receive a PM telling them a user has been reported, by +whom, in which channel and why. If there is an administrative channel for the +reporting channel (e.g. ##channel), the report will be posted there as well. From 2416a82f45a387216dd53c55e436380f064eec54 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 19:50:22 +0000 Subject: [PATCH 046/347] module documentation for spelling [#75] --- README.md | 21 --------------------- modules/spelling/README.md | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 21 deletions(-) create mode 100644 modules/spelling/README.md diff --git a/README.md b/README.md index 75e95e2..38a7493 100644 --- a/README.md +++ b/README.md @@ -25,24 +25,3 @@ commands in the cloned repository: git submodule init git submodule update - -## Modules: - -### Spelling - -Will attempt to correct a users' spelling by using the levenshtein distance -algorithm. One corrects the spelling of their previous message by simply posting -a message with their correction and an asterisk: - - > user: I am a tutrle. - > user: *turtle - user meant: I am a turtle. - -The regular expression for this module also accepts two asterisks at the -beginning of the correction, or at the end; it also accepts several words as the -correction and deals with these fairly intelligently. Users may also attempt -to correct another users like so: - - > userone: I am a tutrle. - > usertwo: userone: *turtle - > usertwo thinks userone meant: I am a turtle. diff --git a/modules/spelling/README.md b/modules/spelling/README.md new file mode 100644 index 0000000..73a2195 --- /dev/null +++ b/modules/spelling/README.md @@ -0,0 +1,22 @@ +## Spelling + +Fix your spelling. + +### Description + +Will attempt to correct a users' spelling by using the levenshtein distance +algorithm. One corrects the spelling of their previous message by simply posting +a message with their correction and an asterisk: + + > user: I am a tutrle. + > user: *turtle + user meant: I am a turtle. + +The regular expression for this module also accepts two asterisks at the +beginning of the correction, or at the end; it also accepts several words as the +correction and deals with these fairly intelligently. Users may also attempt +to correct another users like so: + + > userone: I am a tutrle. + > usertwo: userone: *turtle + > usertwo thinks userone meant: I am a turtle. From c06f754b8fe33a9a58f73e88c6dd9024c3f6e636 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 20:15:48 +0000 Subject: [PATCH 047/347] Added ~help command [#89] --- modules/command/command.js | 30 +++++++++++++++++++++++++++--- modules/command/strings.json | 11 ++++++++++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/modules/command/command.js b/modules/command/command.js index ff530ff..7c0dfcc 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -57,10 +57,34 @@ var command = function(dbot) { '~usage': function(event) { var commandName = event.params[1]; if(dbot.usage.hasOwnProperty(commandName)) { - event.reply('Usage for ' + commandName + ': ' + - dbot.usage[commandName]); + event.reply(dbot.t('usage', { + 'command': commandName, + 'usage': dbot.usage[commandName] + })); } else { - event.reply('No usage information for ' + commandName); + event.reply(dbot.t('no_usage_info', { + 'command': commandName + })); + } + }, + + '~help': function(event) { + var moduleName = event.params[1]; + if(!dbot.modules.hasOwnProperty(moduleName)) { + var moduleName = dbot.commandMap[moduleName]; + } + + if(moduleName && dbot.config[moduleName].hasOwnProperty('help')) { + var help = dbot.config[modulename].help; + event.reply(dbot.t('help_link', { + 'module': moduleName, + 'link': help + })); + } else { + if(!moduleName) { + moduleName = event.params[1]; + } + event.reply(dbot.t('no_help', { 'module': moduleName })) } } }, diff --git a/modules/command/strings.json b/modules/command/strings.json index 975c0ad..922eb63 100644 --- a/modules/command/strings.json +++ b/modules/command/strings.json @@ -11,7 +11,16 @@ "na'vi": "Ngeyä pamrel keyawr lu. Nga skxawng lu.", "welsh": "Cystrawen annilys. Cychwyn orfflosgiad" }, + "usage": { + "english": "Usage for {command}: {usage}." + }, "no_usage_info": { - "No usage information found for {command}." + "english": "No usage information found for {command}." + }, + "help_link": { + "english": "Help for {module}: {link}." + }, + "no_help": { + "english": "No help found for {module}." } } From 1ab1ff5319e89e42d2a2d9353b92277faad399a5 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 20:30:49 +0000 Subject: [PATCH 048/347] Help links added to config [#89] --- modules/admin/config.json | 3 ++- modules/command/command.js | 2 +- modules/command/config.json | 3 +++ modules/command/strings.json | 2 +- modules/ignore/config.json | 3 ++- modules/js/config.json | 3 +++ modules/kick/config.json | 3 ++- modules/link/config.json | 3 ++- modules/poll/config.json | 3 +++ modules/quotes/config.json | 3 ++- modules/report/config.json | 3 +++ modules/spelling/config.json | 3 +++ 12 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 modules/command/config.json create mode 100644 modules/js/config.json create mode 100644 modules/poll/config.json create mode 100644 modules/report/config.json create mode 100644 modules/spelling/config.json diff --git a/modules/admin/config.json b/modules/admin/config.json index 1d1582a..23a6701 100644 --- a/modules/admin/config.json +++ b/modules/admin/config.json @@ -1,3 +1,4 @@ { - "dbKeys": [ "bans" ] + "dbKeys": [ "bans" ], + "help": "http://github.com/reality/depressionbot/blob/master/modules/admin/README.md" } diff --git a/modules/command/command.js b/modules/command/command.js index 7c0dfcc..0ab8bf2 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -75,7 +75,7 @@ var command = function(dbot) { } if(moduleName && dbot.config[moduleName].hasOwnProperty('help')) { - var help = dbot.config[modulename].help; + var help = dbot.config[moduleName].help; event.reply(dbot.t('help_link', { 'module': moduleName, 'link': help diff --git a/modules/command/config.json b/modules/command/config.json new file mode 100644 index 0000000..857a504 --- /dev/null +++ b/modules/command/config.json @@ -0,0 +1,3 @@ +{ + "help": "http://github.com/reality/depressionbot/blob/master/modules/command/README.md" +} diff --git a/modules/command/strings.json b/modules/command/strings.json index 922eb63..d778c23 100644 --- a/modules/command/strings.json +++ b/modules/command/strings.json @@ -18,7 +18,7 @@ "english": "No usage information found for {command}." }, "help_link": { - "english": "Help for {module}: {link}." + "english": "Help for {module}: {link}" }, "no_help": { "english": "No help found for {module}." diff --git a/modules/ignore/config.json b/modules/ignore/config.json index 7a4c116..3f89c31 100644 --- a/modules/ignore/config.json +++ b/modules/ignore/config.json @@ -1,3 +1,4 @@ { - "dbKeys": [ "ignores" ] + "dbKeys": [ "ignores" ], + "help": "http://github.com/reality/depressionbot/blob/master/modules/ignore/README.md" } diff --git a/modules/js/config.json b/modules/js/config.json new file mode 100644 index 0000000..deddf40 --- /dev/null +++ b/modules/js/config.json @@ -0,0 +1,3 @@ +{ + "help": "http://github.com/reality/depressionbot/blob/master/modules/js/README.md" +} diff --git a/modules/kick/config.json b/modules/kick/config.json index 10e1e76..0fd9db2 100644 --- a/modules/kick/config.json +++ b/modules/kick/config.json @@ -1,3 +1,4 @@ { - "dbKeys": [ "kicks", "kickers" ] + "dbKeys": [ "kicks", "kickers" ], + "help": "http://github.com/reality/depressionbot/blob/master/modules/kick/README.md" } diff --git a/modules/link/config.json b/modules/link/config.json index d1a8210..580a315 100644 --- a/modules/link/config.json +++ b/modules/link/config.json @@ -1,3 +1,4 @@ { - "autoTitle": false + "autoTitle": false, + "help": "http://github.com/reality/depressionbot/blob/master/modules/link/README.md" } diff --git a/modules/poll/config.json b/modules/poll/config.json new file mode 100644 index 0000000..d3d8ca6 --- /dev/null +++ b/modules/poll/config.json @@ -0,0 +1,3 @@ +{ + "help": "http://github.com/reality/depressionbot/blob/master/modules/poll/README.md" +} diff --git a/modules/quotes/config.json b/modules/quotes/config.json index 3a7dc05..6aeedb0 100644 --- a/modules/quotes/config.json +++ b/modules/quotes/config.json @@ -1,4 +1,5 @@ { "dbKeys": [ "quoteArrs" ], - "rmLimit": 10 + "rmLimit": 10, + "help": "http://github.com/reality/depressionbot/blob/master/modules/quotes/README.md" } diff --git a/modules/report/config.json b/modules/report/config.json new file mode 100644 index 0000000..b219759 --- /dev/null +++ b/modules/report/config.json @@ -0,0 +1,3 @@ +{ + "help": "http://github.com/reality/depressionbot/blob/master/modules/report/README.md" +} diff --git a/modules/spelling/config.json b/modules/spelling/config.json new file mode 100644 index 0000000..d9d16eb --- /dev/null +++ b/modules/spelling/config.json @@ -0,0 +1,3 @@ +{ + "help": "http://github.com/reality/depressionbot/blob/master/modules/spelling/README.md" +} From 65ef72f19a3c2443ccdfaf3e086c8ee60a737199 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 30 Dec 2012 23:24:05 +0000 Subject: [PATCH 049/347] Protect against continued nick changes --- modules/users/users.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/users/users.js b/modules/users/users.js index 46fe1e8..17457e3 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -82,8 +82,12 @@ var users = function(dbot) { } } else if(event.action == 'NICK') { var newNick = event.params.substr(1); - if(!knownUsers.users.include(newNick)) { - knownUsers.aliases[newNick] = event.user; + if(knownUsers.aliases.hasOwnProperty(event.user)) { + knownUsers.aliases[newNick] = knownUsers.aliases[event.user]; + } else { + if(!knownUsers.users.include(newNick)) { + knownUsers.aliases[newNick] = event.user; + } } } }, From 9f04eb9b21f9254d2af0c8aa0ca7694e769bf87f Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 31 Dec 2012 01:36:57 +0000 Subject: [PATCH 050/347] License DBot under MIT [#87] --- LICENCE | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 LICENCE diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..89ad61e --- /dev/null +++ b/LICENCE @@ -0,0 +1,18 @@ +Copyright (c) 2012 Luke Slater (tinmachin3@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From c307cf984d0459bfb589b69bb1f66e04bbcb46b2 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Mon, 31 Dec 2012 04:18:15 +0000 Subject: [PATCH 051/347] Update README.md 04:07 <reality> dbot became at least 1% more pro today --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 38a7493..352d654 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ ## Introduction Depressionbot is an IRC bot which aims to be the fanciest IRC bot around - On -the general standard of software fanciness, dbot is rated as being '81% the same -as bathing in fine, fine grape juice.' +the general standard of software fanciness, dbot is statistically rated as being +'82% the same as bathing in fine, fine grape juice.' Please note that this documentation is not complete and is a work in progress, given I started it rather a long time after I began development of the project. From e044ec5d14c7eb0890ceef497bdc6ece8d87a702 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 31 Dec 2012 15:37:49 +0000 Subject: [PATCH 052/347] Finish off module docs [#75 --- modules/stats | 2 +- modules/web/README.md | 7 +++++++ modules/youare/README.md | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 modules/web/README.md create mode 100644 modules/youare/README.md diff --git a/modules/stats b/modules/stats index 57bcfae..cc3a044 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 57bcfaed7e73283747b7d2743f11b9176eb2a989 +Subproject commit cc3a044e753985846cdce00a06bdb6c1521616c5 diff --git a/modules/web/README.md b/modules/web/README.md new file mode 100644 index 0000000..4083416 --- /dev/null +++ b/modules/web/README.md @@ -0,0 +1,7 @@ +## Web + +Web interface + +### Description + +It's a web interface for DBot. What of it? diff --git a/modules/youare/README.md b/modules/youare/README.md new file mode 100644 index 0000000..09a9940 --- /dev/null +++ b/modules/youare/README.md @@ -0,0 +1,10 @@ +## youare + +You're a loser! + +### Description + +This module occasionally comes back and says "You're a x" when somebody goes "y +is x" or "y are x," with the intention of annoying people who are calling +something crap. Warning: this module occasionally causes the bot to be nice to +people. From 51298b83623e94d66fe3a2d79cf8093a177802fe Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 2 Jan 2013 19:00:44 +0000 Subject: [PATCH 053/347] Enhancements to ~alias as per [#95] --- modules/users/strings.json | 7 +++++-- modules/users/users.js | 8 +++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/users/strings.json b/modules/users/strings.json index 2a8b876..b334100 100644 --- a/modules/users/strings.json +++ b/modules/users/strings.json @@ -2,10 +2,13 @@ "alias": { "english": "{alias} is an alias of {user}" }, + "primary": { + "english": "{user} is a primary user with {count} aliases." + }, "unknown_alias": { - "english": "{alias} does not currently exist as an alias." + "english": "{alias} does not currently exist as an alias or known user." }, "aliasparentset": { - "english": "{newParent} is now the parent user, and {newAlias} is an alias" + "english": "{newParent} is now the parent user, and {newAlias} is an alias." } } diff --git a/modules/users/users.js b/modules/users/users.js index 17457e3..ab342a4 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -25,7 +25,13 @@ var users = function(dbot) { '~alias': function(event) { var knownUsers = getServerUsers(event); var alias = event.params[1].trim(); - if(knownUsers.aliases.hasOwnProperty(alias)) { + if(knownUsers.users.include(alias)) { + var aliasCount = 0; + knownUsers.aliases.each(function(primaryUser) { + if(primaryUser == alias) aliasCount += 1; + }.bind(this)); + event.reply(dbot.t('primary', { 'user': alias, 'count': aliasCount })); + } else if(knownUsers.aliases.hasOwnProperty(alias)) { event.reply(dbot.t('alias', { 'alias': alias, 'user': knownUsers.aliases[alias] })); } else { From f537b05493eb45bd8aaf80b4a4b1d380aaa37b53 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 2 Jan 2013 19:12:58 +0000 Subject: [PATCH 054/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index cc3a044..dadfe0e 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit cc3a044e753985846cdce00a06bdb6c1521616c5 +Subproject commit dadfe0ed5c1f9d436ff10bf94d4dd6e122af8a7f From b4e43381486de79aad2914c19645a70afc2271c9 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 2 Jan 2013 21:06:43 +0000 Subject: [PATCH 055/347] ~mergeusers command [#94] --- modules/users/strings.json | 6 ++++++ modules/users/users.js | 40 +++++++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/modules/users/strings.json b/modules/users/strings.json index b334100..3aaf5bb 100644 --- a/modules/users/strings.json +++ b/modules/users/strings.json @@ -10,5 +10,11 @@ }, "aliasparentset": { "english": "{newParent} is now the parent user, and {newAlias} is an alias." + }, + "unprimary_error": { + "english": "One of those users isn't currently recorded as a primary user." + }, + "merged_users": { + "english": "{old_user} and their aliases have been merged into {new_user}." } } diff --git a/modules/users/users.js b/modules/users/users.js index ab342a4..df95052 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -11,6 +11,17 @@ var users = function(dbot) { return knownUsers[event.server]; }; + var updateAliases = function(event, oldUser, newUser) { + var knownUsers = getServerUsers(event); + for(var alias in knownUsers.aliases) { + if(knownUsers.aliases.hasOwnProperty(alias)) { + if(knownUsers.aliases[alias] === oldUser) { + knownUsers.aliases[alias] = newUser; + } + } + } + } + dbot.instance.addListener('366', 'users', function(event) { var knownUsers = getServerUsers(event); for(var nick in event.channel.nicks) { @@ -56,13 +67,7 @@ var users = function(dbot) { knownUsers.aliases[newAlias] = newParent; // Update aliases to point to new primary user - for(var alias in knownUsers.aliases) { - if(knownUsers.aliases.hasOwnProperty(alias)) { - if(knownUsers.aliases[alias] === newAlias) { - knownUsers.aliases[alias] = newParent; - } - } - } + updateAliases(event, newAlias, newParent); event.reply(dbot.t('aliasparentset', { 'newParent': newParent, 'newAlias': newAlias })); @@ -72,6 +77,27 @@ var users = function(dbot) { event.reply(dbot.t('unknown_alias', { 'alias': newParent})); } } + }, + + '~mergeusers': function(event) { + if(dbot.config.admins.include(event.user)) { + var knownUsers = getServerUsers(event); + var primaryUser = event.params[1]; + var secondaryUser = event.params[2]; + + if(knownUsers.users.include(primaryUser) && knownUsers.users.include(secondaryUser)) { + knownUsers.users.splice(knownUsers.users.indexOf(secondaryUser), 1); + knownUsers.aliases[secondaryUser] = primaryUser; + updateAliases(event, secondaryUser, primaryUser); + + event.reply(dbot.t('merged_users', { + 'old_user': secondaryUser, + 'new_user': primaryUser + })); + } else { + event.reply(dbot.t('unprimary_error')); + } + } } }; From 97d9869f4de7e43a2c94c0c65418a74dcb823e9b Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 2 Jan 2013 21:50:45 +0000 Subject: [PATCH 056/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index dadfe0e..6fa1c0d 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit dadfe0ed5c1f9d436ff10bf94d4dd6e122af8a7f +Subproject commit 6fa1c0d28eebccc71519eaaf97260f950888e52d From f1d30c9df2079ca59dbf3f52438b025f7db0a000 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 2 Jan 2013 21:58:52 +0000 Subject: [PATCH 057/347] fix replace user entry --- modules/users/users.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/users/users.js b/modules/users/users.js index df95052..62dad13 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -60,7 +60,8 @@ var users = function(dbot) { // Replace users entry with new primary user var usersIndex = knownUsers.users.indexOf(newAlias); - knownUsers.users[usersIndex] = newParent; + knownUsers.splice(usersIndex, 1); + knownUsers.users.push(newParent); // Remove alias for new parent & add alias for new alias delete knownUsers.aliases[newParent]; From 7954f4e0804b6c966242a2daa8458f70cc5b0ac5 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 2 Jan 2013 22:08:31 +0000 Subject: [PATCH 058/347] i am a retard --- modules/users/users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/users.js b/modules/users/users.js index 62dad13..7468f6f 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -60,7 +60,7 @@ var users = function(dbot) { // Replace users entry with new primary user var usersIndex = knownUsers.users.indexOf(newAlias); - knownUsers.splice(usersIndex, 1); + knownUsers.users.splice(usersIndex, 1); knownUsers.users.push(newParent); // Remove alias for new parent & add alias for new alias From 4f49c13c9c32ed0f59516beb79793acf9d3cdf7d Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 2 Jan 2013 22:34:29 +0000 Subject: [PATCH 059/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 6fa1c0d..717ef42 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 6fa1c0d28eebccc71519eaaf97260f950888e52d +Subproject commit 717ef425198887413a332e55f204b73875c2ec00 From f59af39c9479c514d8cceb827cf41e4ebc3d8303 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 2 Jan 2013 22:54:37 +0000 Subject: [PATCH 060/347] update stats SAM --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 717ef42..15f05c4 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 717ef425198887413a332e55f204b73875c2ec00 +Subproject commit 15f05c4efcb624c119d36499556e661d7bb1d719 From 23ee0f3a8e8e90c28e0bee9b4b0a243b8ba607f7 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 2 Jan 2013 23:34:40 +0000 Subject: [PATCH 061/347] One does not even --- .gitmodules | 3 --- modules/stats | 1 - 2 files changed, 4 deletions(-) delete mode 160000 modules/stats diff --git a/.gitmodules b/.gitmodules index 49a4b35..0d17ed4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "jsbot"] path = jsbot url = git://github.com/reality/jsbot.git -[submodule "modules/stats"] - path = modules/stats - url = git://github.com/SamStudio8/stats.git diff --git a/modules/stats b/modules/stats deleted file mode 160000 index 15f05c4..0000000 --- a/modules/stats +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 15f05c4efcb624c119d36499556e661d7bb1d719 From 9a26c6bd748c0e4a5343af25281e53bf3f879478 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 2 Jan 2013 23:36:29 +0000 Subject: [PATCH 062/347] whatever --- .gitmodules | 3 +++ modules/stats | 1 + 2 files changed, 4 insertions(+) create mode 160000 modules/stats diff --git a/.gitmodules b/.gitmodules index 0d17ed4..49a4b35 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "jsbot"] path = jsbot url = git://github.com/reality/jsbot.git +[submodule "modules/stats"] + path = modules/stats + url = git://github.com/SamStudio8/stats.git diff --git a/modules/stats b/modules/stats new file mode 160000 index 0000000..15f05c4 --- /dev/null +++ b/modules/stats @@ -0,0 +1 @@ +Subproject commit 15f05c4efcb624c119d36499556e661d7bb1d719 From 62d3af17e1bb4ea31e72b7da0f1410d42d6d8fc6 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Wed, 2 Jan 2013 23:48:04 +0000 Subject: [PATCH 063/347] Stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 15f05c4..716e243 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 15f05c4efcb624c119d36499556e661d7bb1d719 +Subproject commit 716e2430877b1d6bd6a7a977eab7be13b600316d From 8ea910ee103f1fc4a579d4edf3d6cc4d46cd14f3 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 3 Jan 2013 01:08:08 +0000 Subject: [PATCH 064/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 716e243..7784cdf 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 716e2430877b1d6bd6a7a977eab7be13b600316d +Subproject commit 7784cdfcdedc6f6c2d5b132971e4c39054cdfb58 From a34946e54864df013be353072cfe80f32e033daa Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 3 Jan 2013 01:22:49 +0000 Subject: [PATCH 065/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 7784cdf..72922cb 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 7784cdfcdedc6f6c2d5b132971e4c39054cdfb58 +Subproject commit 72922cbe2f6a2367058c0ff8c975f5ac81025a34 From 99909e2dc5be28c5f5a82b395c56f0347231d099 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 3 Jan 2013 03:05:35 +0000 Subject: [PATCH 066/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 72922cb..3f45239 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 72922cbe2f6a2367058c0ff8c975f5ac81025a34 +Subproject commit 3f45239a81721dca06c0929f389142641a498078 From 078379b5f162d3045c4a8116d25695b7d12bfb04 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 3 Jan 2013 19:56:30 +0000 Subject: [PATCH 067/347] API functionality as per [#98] * Also resolveUser api function in user module [#98] --- modules/users/users.js | 33 +++++++++++++++++++++++---------- run.js | 6 ++++++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/modules/users/users.js b/modules/users/users.js index 7468f6f..cea4c3d 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -4,15 +4,15 @@ */ var users = function(dbot) { var knownUsers = dbot.db.knownUsers; - var getServerUsers = function(event) { - if(!knownUsers.hasOwnProperty(event.server)) { - knownUsers[event.server] = { 'users': [], 'aliases': {} }; + var getServerUsers = function(server) { + if(!knownUsers.hasOwnProperty(server)) { + knownUsers[server] = { 'users': [], 'aliases': {} }; } - return knownUsers[event.server]; + return knownUsers[server]; }; var updateAliases = function(event, oldUser, newUser) { - var knownUsers = getServerUsers(event); + var knownUsers = getServerUsers(event.server); for(var alias in knownUsers.aliases) { if(knownUsers.aliases.hasOwnProperty(alias)) { if(knownUsers.aliases[alias] === oldUser) { @@ -23,7 +23,7 @@ var users = function(dbot) { } dbot.instance.addListener('366', 'users', function(event) { - var knownUsers = getServerUsers(event); + var knownUsers = getServerUsers(event.server); for(var nick in event.channel.nicks) { if(!knownUsers.users.include(nick) && !knownUsers.aliases.hasOwnProperty(nick) && event.channel.nicks.hasOwnProperty(nick)) { @@ -32,9 +32,21 @@ var users = function(dbot) { } }); + var api = { + 'resolveUser': function(server, nick) { + var knownUsers = getServerUsers(server); + var user = nick; + if(!knownUsers.users.include(nick) && knownUsers.aliases.hasOwnProperty(nick)) { + user = knownUsers.aliases[nick]; + } + + return user; + } + }; + var commands = { '~alias': function(event) { - var knownUsers = getServerUsers(event); + var knownUsers = getServerUsers(event.server); var alias = event.params[1].trim(); if(knownUsers.users.include(alias)) { var aliasCount = 0; @@ -52,7 +64,7 @@ var users = function(dbot) { '~setaliasparent': function(event) { if(dbot.config.admins.include(event.user)) { - var knownUsers = getServerUsers(event); + var knownUsers = getServerUsers(event.server); var newParent = event.params[1]; if(knownUsers.aliases.hasOwnProperty(newParent)) { @@ -82,7 +94,7 @@ var users = function(dbot) { '~mergeusers': function(event) { if(dbot.config.admins.include(event.user)) { - var knownUsers = getServerUsers(event); + var knownUsers = getServerUsers(event.server); var primaryUser = event.params[1]; var secondaryUser = event.params[2]; @@ -106,9 +118,10 @@ var users = function(dbot) { 'name': 'users', 'ignorable': false, 'commands': commands, + 'api': api, 'listener': function(event) { - var knownUsers = getServerUsers(event); + var knownUsers = getServerUsers(event.server); if(event.action == 'JOIN') { if(!knownUsers.users.include(event.user)) { knownUsers.users.push(event.user); diff --git a/run.js b/run.js index da148d3..fa32c79 100644 --- a/run.js +++ b/run.js @@ -119,6 +119,7 @@ DBot.prototype.reloadModules = function() { this.rawModules = []; this.modules = {}; this.commands = {}; + this.api = {}; this.commandMap = {}; // Map of which commands belong to which modules this.usage = {}; this.timers.clearTimers(); @@ -194,6 +195,11 @@ DBot.prototype.reloadModules = function() { } } + // Load module API + if(module.api) { + this.api[module.name] = module.api; + } + // Load the module usage data try { var usage = JSON.parse(fs.readFileSync(moduleDir + 'usage.json', 'utf-8')); From 49528bb434a05687e6865ccdb4e9d9bc4e736612 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 3 Jan 2013 21:27:06 +0000 Subject: [PATCH 068/347] Made a getQuote API function [#98] --- modules/quotes/quotes.js | 47 +++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index 14b9467..2f8f696 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -55,6 +55,26 @@ var quotes = function(dbot) { } }; + var api = { + 'getQuote': function(category) { + var key = category.trim().toLowerCase(); + var altKey; + if(key.split(' ').length > 0) { + altKey = key.replace(/ /g, '_'); + } + + if(key.charAt(0) !== '_') { // lol + if(quotes.hasOwnProperty(key)) { + return interpolatedQuote(key); + } else if(quotes.hasOwnProperty(altKey)) { + return interpolatedQuote(altKey); + } else { + return false; + } + } + } + }; + var commands = { // Alternative syntax to ~q '~': function(event) { @@ -101,19 +121,11 @@ 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(key.charAt(0) !== '_') { // lol - if(quotes.hasOwnProperty(key)) { - event.reply(key + ': ' + interpolatedQuote(key)); - } else if(quotes.hasOwnProperty(altKey)) { - event.reply(altKey + ': ' + interpolatedQuote(altKey)); - } else { - event.reply(dbot.t('category_not_found', {'category': key})); - } + var quote = api.getQuote(event.input[1]); + if(quote) { + event.reply(key + ': ' + quote); + } else { + event.reply(dbot.t('category_not_found', {'category': key})); } }, @@ -263,6 +275,7 @@ var quotes = function(dbot) { 'name': 'quotes', 'ignorable': true, 'commands': commands, + 'api': api, 'listener': function(event) { if(event.action == 'PRIVMSG') { @@ -279,10 +292,10 @@ var quotes = function(dbot) { dbot.instance.emit(event); } } else if(event.action == 'JOIN') { - event.message = '~q ' + event.user; - event.action = 'PRIVMSG'; - event.params = event.message.split(' '); - dbot.instance.emit(event); + var userQuote = api.getQuote(event.user) + if(userQuote) { + event.reply(event.user + ': ' + api.getQuote(event.user)); + } } }, 'on': ['PRIVMSG', 'JOIN'] From fab79179212f98f4bbf5d08ac0d2f1ff5879a6d1 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Fri, 4 Jan 2013 14:27:39 +0000 Subject: [PATCH 069/347] Update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 3f45239..cedfdb0 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 3f45239a81721dca06c0929f389142641a498078 +Subproject commit cedfdb09ed857476298ba16eb90e3131f033ba60 From b50f4d25b843d779e99017b0231f74a142130bdf Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 4 Jan 2013 16:13:45 +0000 Subject: [PATCH 070/347] greload updates submodules [#100] --- modules/admin/admin.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/admin/admin.js b/modules/admin/admin.js index 1cc12f3..83eab08 100644 --- a/modules/admin/admin.js +++ b/modules/admin/admin.js @@ -44,9 +44,11 @@ var admin = function(dbot) { // Do a git pull and reload 'greload': function(event) { - var child = exec("git pull", function (error, stdout, stderr) { - event.reply(dbot.t('gpull')); - commands.reload(event); + exec("git pull", function (error, stdout, stderr) { + exec("git submodule update", function (error, stdout, stderr) { + event.reply(dbot.t('gpull')); + commands.reload(event); + }.bind(this)); }.bind(this)); }, From c1c8ffca699882b4eeab38a0c0c85c036efccfb4 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 4 Jan 2013 18:04:09 +0100 Subject: [PATCH 071/347] Update modules/users/users.js call api fixStats --- modules/users/users.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/users/users.js b/modules/users/users.js index cea4c3d..f5e3e9d 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -85,7 +85,7 @@ var users = function(dbot) { event.reply(dbot.t('aliasparentset', { 'newParent': newParent, 'newAlias': newAlias })); - dbot.modules.stats.fixStats(event.server, newAlias); // :'( + dbot.api.stats.fixStats(event.server, newAlias); } else { event.reply(dbot.t('unknown_alias', { 'alias': newParent})); } @@ -107,6 +107,8 @@ var users = function(dbot) { 'old_user': secondaryUser, 'new_user': primaryUser })); + + dbot.api.stats.fixStats(event.server, secondaryUser); } else { event.reply(dbot.t('unprimary_error')); } From 958c438a45cc1d8fb639573a1f19c7dea34bcdf9 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 4 Jan 2013 17:58:35 +0000 Subject: [PATCH 072/347] lowercase flag in resolveUser --- modules/users/users.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/users/users.js b/modules/users/users.js index f5e3e9d..1249901 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -40,6 +40,7 @@ var users = function(dbot) { user = knownUsers.aliases[nick]; } + if(useLowercase) user = user.toLowerCase(); return user; } }; From c5b489fd9d76ffc3ccd1918c8f779fe15bc133b5 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 4 Jan 2013 18:12:33 +0000 Subject: [PATCH 073/347] wat --- modules/users/users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/users.js b/modules/users/users.js index 1249901..01a01d1 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -33,7 +33,7 @@ var users = function(dbot) { }); var api = { - 'resolveUser': function(server, nick) { + 'resolveUser': function(server, nick, useLowercase) { var knownUsers = getServerUsers(server); var user = nick; if(!knownUsers.users.include(nick) && knownUsers.aliases.hasOwnProperty(nick)) { From b6365890145dfe9f7f96bc125cd081750c70db05 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 4 Jan 2013 19:47:33 +0000 Subject: [PATCH 074/347] update jsbot --- jsbot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsbot b/jsbot index f050c93..d9e1b2f 160000 --- a/jsbot +++ b/jsbot @@ -1 +1 @@ -Subproject commit f050c93f22e56ad98f245f7ba8b444208c4de6f8 +Subproject commit d9e1b2f879dbaf597e4cc0dead6e903114a66618 From 1d26789a9730842cfe7a18c181c1b6d7168637b4 Mon Sep 17 00:00:00 2001 From: Daniel Evans <danharibo@gmail.com> Date: Fri, 4 Jan 2013 20:50:26 +0000 Subject: [PATCH 075/347] Restored deprecated express usage --- modules/web/web.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/web/web.js b/modules/web/web.js index 3f3b897..28620b6 100644 --- a/modules/web/web.js +++ b/modules/web/web.js @@ -3,7 +3,7 @@ var express = require('express'), var webInterface = function(dbot) { var pub = 'public'; - var app = express(); + var app = express.createServer(); app.use(express.static(pub)); app.set('view engine', 'jade'); From 2e9535bba11975b0e818303b7c0b397ebd80d95b Mon Sep 17 00:00:00 2001 From: Daniel Evans <danharibo@gmail.com> Date: Fri, 4 Jan 2013 21:26:11 +0000 Subject: [PATCH 076/347] Updated web module for Express 3.0.x --- modules/web/web.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/web/web.js b/modules/web/web.js index 28620b6..3f3b897 100644 --- a/modules/web/web.js +++ b/modules/web/web.js @@ -3,7 +3,7 @@ var express = require('express'), var webInterface = function(dbot) { var pub = 'public'; - var app = express.createServer(); + var app = express(); app.use(express.static(pub)); app.set('view engine', 'jade'); From 046411f2c38900f236a864b4623fb281c93a8e2d Mon Sep 17 00:00:00 2001 From: Daniel Evans <danharibo@gmail.com> Date: Fri, 4 Jan 2013 21:43:40 +0000 Subject: [PATCH 077/347] Update views/users/connections.jade --- views/users/connections.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/users/connections.jade b/views/users/connections.jade index 0e7f06f..f6750fb 100644 --- a/views/users/connections.jade +++ b/views/users/connections.jade @@ -4,6 +4,6 @@ block content h3 Current Connections div#backlink a(href='/') « Home -#modulelinks + #modulelinks -each connection in connections a.module(href='/channels/'+connection) #{connection} From 49e5648519020ab135f94cdd1c5defff36174a1c Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 5 Jan 2013 00:22:06 +0000 Subject: [PATCH 078/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index cedfdb0..6d99949 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit cedfdb09ed857476298ba16eb90e3131f033ba60 +Subproject commit 6d99949fc1d93e1a93f11ceb31c507247d4ae1c1 From aa39fd7d4c147f39d4010fc21a30098ce3cbbc90 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 5 Jan 2013 00:51:20 +0000 Subject: [PATCH 079/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 6d99949..b8a3724 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 6d99949fc1d93e1a93f11ceb31c507247d4ae1c1 +Subproject commit b8a3724739bdf8d9d7b53839b36bfb742f48d281 From 91ba6854016235070a88498c629b82dece5781de Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 5 Jan 2013 01:36:36 +0000 Subject: [PATCH 080/347] fix express close for 3.0. you could document your shit guys --- modules/web/web.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/web/web.js b/modules/web/web.js index 3f3b897..234bfa3 100644 --- a/modules/web/web.js +++ b/modules/web/web.js @@ -11,9 +11,8 @@ var webInterface = function(dbot) { app.get('/', function(req, res) { res.render('index', { 'name': dbot.config.name }); }); - - app.listen(dbot.config.web.webPort); + var server = app.listen(dbot.config.web.webPort); var reloadPages = function(pages) { for(var p in pages) { @@ -40,7 +39,7 @@ var webInterface = function(dbot) { 'reloadPages': reloadPages, 'onDestroy': function() { - app.close(); + server.close(); } }; }; From c22b7a24da9635d5e5c23ebbd217e778f25d9614 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Sat, 5 Jan 2013 16:43:22 +0100 Subject: [PATCH 081/347] Update config.json.sample --- config.json.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json.sample b/config.json.sample index 685eee6..27342c0 100644 --- a/config.json.sample +++ b/config.json.sample @@ -12,7 +12,7 @@ } }, "admins": [ "batman" ], - "moduleNames": [ "ignore", "admin", "command", "dice", "js", "kick", "puns", "quotes", "spelling", "youare" ], + "moduleNames": [ "ignore", "admin", "command", "dice", "js", "kick", "quotes", "spelling", "youare" ], "language": "english", "debugMode": true } From bbe6a540be146738cdfa95ef97a070a1e04e52f5 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Sat, 5 Jan 2013 17:00:45 +0100 Subject: [PATCH 082/347] Update modules/link/link.js no title found shut up omg --- modules/link/link.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/link/link.js b/modules/link/link.js index 435c6ec..7b6d3b2 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -14,8 +14,6 @@ var link = function(dbot) { var title = body.valMatch(/<title>(.*)<\/title>/, 2); if(title) { event.reply(title[1]); - } else { - event.reply(dbot.t('title_not_found')); } } }); From 5429740eef78ca722297fd92b86598ba45434480 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 5 Jan 2013 18:53:27 +0000 Subject: [PATCH 083/347] add ignores to dbkeys in command so no fail if theres no ignore loaded --- modules/command/config.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/command/config.json b/modules/command/config.json index 857a504..934b815 100644 --- a/modules/command/config.json +++ b/modules/command/config.json @@ -1,3 +1,4 @@ { - "help": "http://github.com/reality/depressionbot/blob/master/modules/command/README.md" + "help": "http://github.com/reality/depressionbot/blob/master/modules/command/README.md", + "dbKeys": [ "ignores" ] } From 1785b89df00e358b458d04923838e41cb76bf5c4 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 5 Jan 2013 19:08:17 +0000 Subject: [PATCH 084/347] Store channel users as per [#106] --- modules/users/users.js | 55 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/modules/users/users.js b/modules/users/users.js index 1999495..5edca82 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -6,7 +6,7 @@ var users = function(dbot) { var knownUsers = dbot.db.knownUsers; var getServerUsers = function(server) { if(!knownUsers.hasOwnProperty(server)) { - knownUsers[server] = { 'users': [], 'aliases': {} }; + knownUsers[server] = { 'users': [], 'aliases': {}, 'channelUsers': {} }; } return knownUsers[server]; }; @@ -22,14 +22,34 @@ var users = function(dbot) { } } + var updateChannels = function(event, oldUser, newUser) { + var channelUsers = getServerUsers(event.server).channelUsers; + channelUsers.each(function(channel) { + if(channel.include(oldUser)) { + channel.splice(channel.indexOf(oldUser), 1); + channel.push(newUser); + } + }.bind(this)); + } + dbot.instance.addListener('366', 'users', function(event) { var knownUsers = getServerUsers(event.server); - for(var nick in event.channel.nicks) { - if(!knownUsers.users.include(nick) && !knownUsers.aliases.hasOwnProperty(nick) && - event.channel.nicks.hasOwnProperty(nick)) { + if(!knownUsers.channelUsers.hasOwnProperty(event.channel.name)) { + knownUsers.channelUsers[event.channel.name] = []; + } + var channelUsers = knownUsers.channelUsers[event.channel.name]; + + event.channel.nicks.each(function(nick) { + nick = nick.name; + if(api.isKnownUser(event.server, nick)) { + nick = api.resolveUser(nick); + } else { knownUsers.users.push(nick); } - } + if(!channelUsers.include(nick)) { + channelUsers.push(nick); + } + }.bind(this)); }); var pages = { @@ -101,6 +121,11 @@ var users = function(dbot) { if(useLowercase) user = user.toLowerCase(); return user; + }, + + 'isKnownUser': function(server, nick) { + var knownUsers = getServerUsers(server); + return (knownUsers.users.include(nick) || knownUsers.aliases.hasOwnProperty(nick)); } }; @@ -135,6 +160,9 @@ var users = function(dbot) { knownUsers.users.splice(usersIndex, 1); knownUsers.users.push(newParent); + // Replace channels entries with new primary user + updateChannels(event, newAlias, newParent); + // Remove alias for new parent & add alias for new alias delete knownUsers.aliases[newParent]; knownUsers.aliases[newAlias] = newParent; @@ -162,6 +190,7 @@ var users = function(dbot) { knownUsers.users.splice(knownUsers.users.indexOf(secondaryUser), 1); knownUsers.aliases[secondaryUser] = primaryUser; updateAliases(event, secondaryUser, primaryUser); + updateChannels(event, secondaryUser, primaryUser); event.reply(dbot.t('merged_users', { 'old_user': secondaryUser, @@ -185,9 +214,21 @@ var users = function(dbot) { 'listener': function(event) { var knownUsers = getServerUsers(event.server); + var nick = event.user; + if(event.action == 'JOIN') { - if(!knownUsers.users.include(event.user)) { - knownUsers.users.push(event.user); + if(!knownUsers.channelUsers.hasOwnProperty(event.channel.name)) { + knownUsers.channelUsers[event.channel.name] = []; + } + var channelUsers = knownUsers.channelUsers[event.channel.name]; + + if(api.isKnownUser(event.server, nick)) { + nick = api.resolveUser(nick); + } else { + knownUsers.users.push(nick); + } + if(!channelUsers.include(nick)) { + channelUsers.push(nick); } } else if(event.action == 'NICK') { var newNick = event.params.substr(1); From 7caa659017d987835dbc8dd264d282c8022bb210 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sat, 5 Jan 2013 22:04:59 +0000 Subject: [PATCH 085/347] version command [Close #96] --- modules/admin/admin.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/modules/admin/admin.js b/modules/admin/admin.js index 83eab08..ac2e7e6 100644 --- a/modules/admin/admin.js +++ b/modules/admin/admin.js @@ -50,6 +50,34 @@ var admin = function(dbot) { commands.reload(event); }.bind(this)); }.bind(this)); + + event.message = 'version'; + event.action = 'PRIVMSG'; + event.params = event.message.split(' '); + dbot.instance.emit(event); + }, + + // Display commit information for part of dbot + 'version': function(event){ + var cmd = "git log --pretty=format:'%h (%s): %ar' -n 1 -- "; + if(event.params[1]){ + var input = event.params[1].trim(); + if(dbot.modules.hasOwnProperty(input.split("/")[0])){ + cmd += "modules/"+input; + } + else{ + cmd += input; + } + } + + exec(cmd, function(error, stdout, stderr){ + if(stdout.length > 0){ + event.reply(stdout); + } + else{ + event.reply("No version information or queried module not loaded"); + } + }.bind(this)); }, // Reload DB, translations and modules. From ddc538b6a07aa88813c4b664ffbb4761a4eb000c Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sat, 5 Jan 2013 22:20:09 +0000 Subject: [PATCH 086/347] Report version after greload callbacks complete --- modules/admin/admin.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/admin/admin.js b/modules/admin/admin.js index ac2e7e6..962eda0 100644 --- a/modules/admin/admin.js +++ b/modules/admin/admin.js @@ -48,13 +48,12 @@ var admin = function(dbot) { exec("git submodule update", function (error, stdout, stderr) { event.reply(dbot.t('gpull')); commands.reload(event); + event.message = 'version'; + event.action = 'PRIVMSG'; + event.params = event.message.split(' '); + dbot.instance.emit(event); }.bind(this)); }.bind(this)); - - event.message = 'version'; - event.action = 'PRIVMSG'; - event.params = event.message.split(' '); - dbot.instance.emit(event); }, // Display commit information for part of dbot From 94a28e29f1d674038aa86cadba1f8bc582f44555 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sun, 6 Jan 2013 13:32:48 +0000 Subject: [PATCH 087/347] Update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index b8a3724..0c9e207 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit b8a3724739bdf8d9d7b53839b36bfb742f48d281 +Subproject commit 0c9e207dd2f6dc6a65efef82bc48dd68d7a9fb18 From 6c7e56be1afa32720f9c829bac1007f66f756b14 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 7 Jan 2013 12:27:24 +0000 Subject: [PATCH 088/347] load pages from closer in u/web.js --- modules/users/users.js | 62 ++-------------------------------------- modules/users/web.js | 64 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 59 deletions(-) create mode 100644 modules/users/web.js diff --git a/modules/users/users.js b/modules/users/users.js index 5edca82..2d57193 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -2,6 +2,8 @@ * Name: Users * Description: Track known users */ +var web = require('./web'); + var users = function(dbot) { var knownUsers = dbot.db.knownUsers; var getServerUsers = function(server) { @@ -52,64 +54,6 @@ var users = function(dbot) { }.bind(this)); }); - var pages = { - '/connections': function(req, res) { - var connections = Object.keys(dbot.instance.connections); - res.render('connections', { 'name': dbot.config.name, 'connections': connections }); - }, - - '/channels/:connection': function(req, res) { - var connection = req.params.connection; - if(dbot.instance.connections.hasOwnProperty(connection)) { - var channels = Object.keys(dbot.instance.connections[connection].channels); - res.render('channels', { 'name': dbot.config.name, 'connection': connection, 'channels': channels}); - } else { - res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection.' }); - } - }, - - '/users/:connection/:channel': function(req, res) { - var connection = req.params.connection; - var channel = '#' + req.params.channel; - var connections = dbot.instance.connections; - - if(connections.hasOwnProperty(connection) && - connections[connection].channels.hasOwnProperty(channel)) { - var nicks = Object.keys(connections[connection].channels[channel].nicks); - res.render('users', { 'name': dbot.config.name, 'connection': connection, - 'channel': channel, 'nicks': nicks }); - } else { - res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection or channel.' }); - } - }, - - '/user/:connection/:channel/:user': function(req, res) { - var connection = req.params.connection; - var channel = '#' + req.params.channel; - var user = dbot.cleanNick(req.params.user); - - var quoteCount = 'no'; - if(dbot.db.quoteArrs.hasOwnProperty(user)) { - var quoteCount = dbot.db.quoteArrs[user].length; - } - - if(!dbot.db.kicks.hasOwnProperty(req.params.user)) { - var kicks = '0'; - } else { - var kicks = dbot.db.kicks[req.params.user]; - } - - if(!dbot.db.kickers.hasOwnProperty(req.params.user)) { - var kicked = '0'; - } else { - var kicked = dbot.db.kickers[req.params.user]; - } - - res.render('user', { 'name': dbot.config.name, 'user': req.params.user, - 'channel': channel, 'connection': connection, 'cleanUser': user, - 'quotecount': quoteCount, 'kicks': kicks, 'kicked': kicked }); - }, - }; var api = { 'resolveUser': function(server, nick, useLowercase) { @@ -210,7 +154,7 @@ var users = function(dbot) { 'ignorable': false, 'commands': commands, 'api': api, - 'pages': pages, + 'pages': web.getPages(dbot), 'listener': function(event) { var knownUsers = getServerUsers(event.server); diff --git a/modules/users/web.js b/modules/users/web.js new file mode 100644 index 0000000..b6d4ad2 --- /dev/null +++ b/modules/users/web.js @@ -0,0 +1,64 @@ +var pages = function(dbot) { + return { + '/connections': function(req, res) { + var connections = Object.keys(dbot.instance.connections); + res.render('connections', { 'name': dbot.config.name, 'connections': connections }); + }, + + '/channels/:connection': function(req, res) { + var connection = req.params.connection; + if(dbot.instance.connections.hasOwnProperty(connection)) { + var channels = Object.keys(dbot.instance.connections[connection].channels); + res.render('channels', { 'name': dbot.config.name, 'connection': connection, 'channels': channels}); + } else { + res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection.' }); + } + }, + + '/users/:connection/:channel': function(req, res) { + var connection = req.params.connection; + var channel = '#' + req.params.channel; + var connections = dbot.instance.connections; + + if(connections.hasOwnProperty(connection) && + connections[connection].channels.hasOwnProperty(channel)) { + var nicks = Object.keys(connections[connection].channels[channel].nicks); + res.render('users', { 'name': dbot.config.name, 'connection': connection, + 'channel': channel, 'nicks': nicks }); + } else { + res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection or channel.' }); + } + }, + + '/user/:connection/:channel/:user': function(req, res) { + var connection = req.params.connection; + var channel = '#' + req.params.channel; + var user = dbot.cleanNick(req.params.user); + + var quoteCount = 'no'; + if(dbot.db.quoteArrs.hasOwnProperty(user)) { + var quoteCount = dbot.db.quoteArrs[user].length; + } + + if(!dbot.db.kicks.hasOwnProperty(req.params.user)) { + var kicks = '0'; + } else { + var kicks = dbot.db.kicks[req.params.user]; + } + + if(!dbot.db.kickers.hasOwnProperty(req.params.user)) { + var kicked = '0'; + } else { + var kicked = dbot.db.kickers[req.params.user]; + } + + res.render('user', { 'name': dbot.config.name, 'user': req.params.user, + 'channel': channel, 'connection': connection, 'cleanUser': user, + 'quotecount': quoteCount, 'kicks': kicks, 'kicked': kicked }); + } + }; +}; + +exports.getPages = function(dbot) { + return pages(dbot); +}; From eb526b18c5eb6059f280820d6120e2f2403cb473 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 7 Jan 2013 12:49:18 +0000 Subject: [PATCH 089/347] Delete the pages module cache for a module if it exists --- run.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/run.js b/run.js index 5efe12c..d8220fe 100644 --- a/run.js +++ b/run.js @@ -151,6 +151,14 @@ DBot.prototype.reloadModules = function() { var cacheKey = require.resolve(moduleDir + name); delete require.cache[cacheKey]; + try { + var webKey = require.resolve(moduleDir + 'web'); + } catch(err) { + } + if(webKey) { + delete require.cache[webKey]; + } + try { // Load the module config data try { From 5f563f6c2602a6e0a8d7a76ff2e19414c20906e6 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 8 Jan 2013 06:14:58 +0000 Subject: [PATCH 090/347] show online status of known users in web + nick tracking fixes --- modules/users/users.js | 5 +++-- modules/users/web.js | 19 +++++++++++++++++-- views/users/users.jade | 10 +++++++--- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/modules/users/users.js b/modules/users/users.js index 2d57193..d08c91f 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -38,13 +38,14 @@ var users = function(dbot) { var knownUsers = getServerUsers(event.server); if(!knownUsers.channelUsers.hasOwnProperty(event.channel.name)) { knownUsers.channelUsers[event.channel.name] = []; + event.reply('creating new chanusers') } var channelUsers = knownUsers.channelUsers[event.channel.name]; event.channel.nicks.each(function(nick) { nick = nick.name; if(api.isKnownUser(event.server, nick)) { - nick = api.resolveUser(nick); + nick = api.resolveUser(event.server, nick); } else { knownUsers.users.push(nick); } @@ -167,7 +168,7 @@ var users = function(dbot) { var channelUsers = knownUsers.channelUsers[event.channel.name]; if(api.isKnownUser(event.server, nick)) { - nick = api.resolveUser(nick); + nick = api.resolveUser(event.server, nick); } else { knownUsers.users.push(nick); } diff --git a/modules/users/web.js b/modules/users/web.js index b6d4ad2..ff7754b 100644 --- a/modules/users/web.js +++ b/modules/users/web.js @@ -22,9 +22,24 @@ var pages = function(dbot) { if(connections.hasOwnProperty(connection) && connections[connection].channels.hasOwnProperty(channel)) { - var nicks = Object.keys(connections[connection].channels[channel].nicks); + + var nicks = dbot.db.knownUsers[connection].channelUsers[channel]; + var channelUsers = {}; + for(var i=0;i<nicks.length;i++) { + channelUsers[nicks[i]] = { 'name': nicks[i], 'online': false }; + console.log(nicks[i]); + } + + var channelOnline = dbot.instance.connections[connection].channels[channel].nicks; + channelOnline.each(function(nick) { + var nick = dbot.api.users.resolveUser(connection, nick); + if(channelUsers.hasOwnProperty(nick)) { + channelUsers[nick].online = true; + } + }.bind(this)); + res.render('users', { 'name': dbot.config.name, 'connection': connection, - 'channel': channel, 'nicks': nicks }); + 'channel': channel, 'nicks': channelUsers }); } else { res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection or channel.' }); } diff --git a/views/users/users.jade b/views/users/users.jade index d20c9e2..e8f5ca1 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -1,10 +1,14 @@ extends ../layout block content - h3 Users currently in #{channel} on #{connection} + h3 Users of #{channel} on #{connection} div#backlink a(href='/channels/'+connection) « Channel List ul#quotelist -each nick in nicks - a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) - li.quotes #{nick} + if nicks.hasOwnProperty(nick.name) + a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) + if nick.online + li.quotes #{nick.name} (Online) + else + li.quotes #{nick.name} (Offline) From 4939446116a386af6e15540fc8631aee7fdfdd13 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 8 Jan 2013 19:00:51 +0000 Subject: [PATCH 091/347] update jsbot --- jsbot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsbot b/jsbot index d9e1b2f..55e5f9e 160000 --- a/jsbot +++ b/jsbot @@ -1 +1 @@ -Subproject commit d9e1b2f879dbaf597e4cc0dead6e903114a66618 +Subproject commit 55e5f9e918b94f1d23cbc1e10934e6ac6faeff93 From c28047efc191c1bcd0808aa3a1a2b6585b3c1c64 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 9 Jan 2013 05:53:45 +0000 Subject: [PATCH 092/347] Activity indicator [#111] --- modules/users/users.js | 1 - modules/users/web.js | 30 ++++++++++++++++++++---------- views/users/users.jade | 5 ++++- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/modules/users/users.js b/modules/users/users.js index d08c91f..6037f2a 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -38,7 +38,6 @@ var users = function(dbot) { var knownUsers = getServerUsers(event.server); if(!knownUsers.channelUsers.hasOwnProperty(event.channel.name)) { knownUsers.channelUsers[event.channel.name] = []; - event.reply('creating new chanusers') } var channelUsers = knownUsers.channelUsers[event.channel.name]; diff --git a/modules/users/web.js b/modules/users/web.js index ff7754b..6c4f516 100644 --- a/modules/users/web.js +++ b/modules/users/web.js @@ -1,4 +1,6 @@ var pages = function(dbot) { + var connections = dbot.instance.connections; + return { '/connections': function(req, res) { var connections = Object.keys(dbot.instance.connections); @@ -23,23 +25,31 @@ var pages = function(dbot) { if(connections.hasOwnProperty(connection) && connections[connection].channels.hasOwnProperty(channel)) { - var nicks = dbot.db.knownUsers[connection].channelUsers[channel]; - var channelUsers = {}; - for(var i=0;i<nicks.length;i++) { - channelUsers[nicks[i]] = { 'name': nicks[i], 'online': false }; - console.log(nicks[i]); + var channelUsers = dbot.db.knownUsers[connection].channelUsers[channel]; + var usersData = {}; + for(var i=0;i<channelUsers.length;i++) { + usersData[channelUsers[i]] = { + 'name': channelUsers[i], + 'online': false, + 'active': false + }; } - var channelOnline = dbot.instance.connections[connection].channels[channel].nicks; - channelOnline.each(function(nick) { + var onlineNicks = connections[connection].channels[channel].nicks; + onlineNicks.each(function(nick) { var nick = dbot.api.users.resolveUser(connection, nick); - if(channelUsers.hasOwnProperty(nick)) { - channelUsers[nick].online = true; + if(onlineNicks.hasOwnProperty(nick)) { + usersData[nick].online = true; } + /*usersData[nick].active = dbot.api.stats.isActive({ + 'server': connection, + 'user': nick, + 'channel': channel + });*/ }.bind(this)); res.render('users', { 'name': dbot.config.name, 'connection': connection, - 'channel': channel, 'nicks': channelUsers }); + 'channel': channel, 'nicks': usersData }); } else { res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection or channel.' }); } diff --git a/views/users/users.jade b/views/users/users.jade index e8f5ca1..67b005e 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -9,6 +9,9 @@ block content if nicks.hasOwnProperty(nick.name) a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) if nick.online - li.quotes #{nick.name} (Online) + if nick.active + li.quotes #{nick.name} (Online, Active) + else + li.quotes #{nick.name} (Online, Inactive) else li.quotes #{nick.name} (Offline) From 08f35f90f8f79b32dfad38694163a7c0eab980dd Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 9 Jan 2013 06:05:01 +0000 Subject: [PATCH 093/347] user pages now load again --- modules/users/web.js | 21 +++++++++++++-------- views/users/users.jade | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/modules/users/web.js b/modules/users/web.js index 6c4f516..48a8996 100644 --- a/modules/users/web.js +++ b/modules/users/web.js @@ -65,16 +65,21 @@ var pages = function(dbot) { var quoteCount = dbot.db.quoteArrs[user].length; } - if(!dbot.db.kicks.hasOwnProperty(req.params.user)) { - var kicks = '0'; - } else { - var kicks = dbot.db.kicks[req.params.user]; - } + if(dbot.config.moduleNames.include('kick')) { + if(!dbot.db.kicks.hasOwnProperty(req.params.user)) { + var kicks = '0'; + } else { + var kicks = dbot.db.kicks[req.params.user]; + } - if(!dbot.db.kickers.hasOwnProperty(req.params.user)) { - var kicked = '0'; + if(!dbot.db.kickers.hasOwnProperty(req.params.user)) { + var kicked = '0'; + } else { + var kicked = dbot.db.kickers[req.params.user]; + } } else { - var kicked = dbot.db.kickers[req.params.user]; + var kicks = 'N/A'; + var kicked = 'N/A'; } res.render('user', { 'name': dbot.config.name, 'user': req.params.user, diff --git a/views/users/users.jade b/views/users/users.jade index 67b005e..b197b23 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -7,7 +7,7 @@ block content ul#quotelist -each nick in nicks if nicks.hasOwnProperty(nick.name) - a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) + a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick.name) if nick.online if nick.active li.quotes #{nick.name} (Online, Active) From 03f58bf9067f026995928ba5f04ce7c98ac75755 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 9 Jan 2013 06:12:04 +0000 Subject: [PATCH 094/347] correct missing channel users --- modules/users/users.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/users/users.js b/modules/users/users.js index 6037f2a..0948719 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -10,6 +10,9 @@ var users = function(dbot) { if(!knownUsers.hasOwnProperty(server)) { knownUsers[server] = { 'users': [], 'aliases': {}, 'channelUsers': {} }; } + if(!knownUsers[server].hasOwnProperty('channelUsers')) { + knownUsers[server].channelUsers = {}; + } return knownUsers[server]; }; From f4b409bdd8495143def53fde924059f80a8f77bc Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 9 Jan 2013 06:23:19 +0000 Subject: [PATCH 095/347] corect users value --- modules/users/web.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/users/web.js b/modules/users/web.js index 48a8996..372f860 100644 --- a/modules/users/web.js +++ b/modules/users/web.js @@ -37,9 +37,9 @@ var pages = function(dbot) { var onlineNicks = connections[connection].channels[channel].nicks; onlineNicks.each(function(nick) { - var nick = dbot.api.users.resolveUser(connection, nick); + var user = dbot.api.users.resolveUser(connection, nick); if(onlineNicks.hasOwnProperty(nick)) { - usersData[nick].online = true; + usersData[user].online = true; } /*usersData[nick].active = dbot.api.stats.isActive({ 'server': connection, From b8c3ce5dde53bce4bbccd2a0cf845c39c41e3ea7 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 9 Jan 2013 19:28:52 +0000 Subject: [PATCH 096/347] active works! --- modules/users/web.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/users/web.js b/modules/users/web.js index 372f860..a40de06 100644 --- a/modules/users/web.js +++ b/modules/users/web.js @@ -37,15 +37,17 @@ var pages = function(dbot) { var onlineNicks = connections[connection].channels[channel].nicks; onlineNicks.each(function(nick) { + var nick = nick.name; var user = dbot.api.users.resolveUser(connection, nick); if(onlineNicks.hasOwnProperty(nick)) { usersData[user].online = true; } - /*usersData[nick].active = dbot.api.stats.isActive({ + console.log(user); + usersData[user].active = dbot.api.stats.isActive({ 'server': connection, - 'user': nick, + 'user': user, 'channel': channel - });*/ + }); }.bind(this)); res.render('users', { 'name': dbot.config.name, 'connection': connection, From 9b048d2d544cb16e50d99c92f74e55ea8d4479aa Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 9 Jan 2013 19:29:26 +0000 Subject: [PATCH 097/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 0c9e207..03bfd64 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 0c9e207dd2f6dc6a65efef82bc48dd68d7a9fb18 +Subproject commit 03bfd640e044ae91075614e9293f6b94f494088b From 8740b64cc966f32b8bc59e5802126ce43a56db59 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 9 Jan 2013 20:02:55 +0000 Subject: [PATCH 098/347] VERSION 0.1 --- VERSION | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 VERSION diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..d504a14 --- /dev/null +++ b/VERSION @@ -0,0 +1,3 @@ +depressionbot version 0.1 (respite) + +"He called his bot depressionbot, and that's when he was happy." From 6c946e2af07eb45f3505301df250f6f38fa11025 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 10 Jan 2013 06:56:02 +0000 Subject: [PATCH 099/347] commence 0.2-dev --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index d504a14..1f085f1 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ -depressionbot version 0.1 (respite) +depressionbot version 0.2-dev (respite) "He called his bot depressionbot, and that's when he was happy." From 012d6fa1a8e75b0d7cc1fbb276fb52c5bc5ebbbf Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 10 Jan 2013 17:09:39 +0000 Subject: [PATCH 100/347] Add bootstrap --- .gitmodules | 3 +++ public/bootstrap | 1 + 2 files changed, 4 insertions(+) create mode 160000 public/bootstrap diff --git a/.gitmodules b/.gitmodules index 49a4b35..e928e2b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "modules/stats"] path = modules/stats url = git://github.com/SamStudio8/stats.git +[submodule "public/bootstrap"] + path = public/bootstrap + url = git://github.com/twitter/bootstrap.git diff --git a/public/bootstrap b/public/bootstrap new file mode 160000 index 0000000..558bc52 --- /dev/null +++ b/public/bootstrap @@ -0,0 +1 @@ +Subproject commit 558bc52432840ea1b2f413438427164288f10350 From bb977e94e2bff70e6e7860f24536083b8a02ea8e Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 10 Jan 2013 17:44:01 +0000 Subject: [PATCH 101/347] dent module [#113] --- modules/dent/config.json | 4 ++++ modules/dent/dent.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 modules/dent/config.json create mode 100644 modules/dent/dent.js diff --git a/modules/dent/config.json b/modules/dent/config.json new file mode 100644 index 0000000..cb55dd8 --- /dev/null +++ b/modules/dent/config.json @@ -0,0 +1,4 @@ +{ + "username": "youruserhere", + "password": "yourpasswordhere" +} diff --git a/modules/dent/dent.js b/modules/dent/dent.js new file mode 100644 index 0000000..5ac7a5e --- /dev/null +++ b/modules/dent/dent.js @@ -0,0 +1,31 @@ +var request = require('request'); + +var dent = function(dbot) { + var username = dbot.config.dent.username; + var password = dbot.config.dent.password; + var commands = { + '~dent': function(event) { + var auth = "Basic " + + new Buffer(username + ":" + password).toString("base64"); + request.post({ + 'url': 'http://identi.ca/api/statuses/update.json?status=' + + event.input[1], + 'headers': { + 'Authorization': auth + } + }, + function(error, response, body) { + event.reply('Status posted (probably).'); + }); + } + }; + commands['~dent'].regex = [/^~dent (.+)$/, 2]; + + return { + 'commands': commands + }; +}; + +exports.fetch = function(dbot) { + return dent(dbot); +}; From 82fb3eacf81826605e2ac98f32753f4a6edbeace Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 10 Jan 2013 18:00:15 +0000 Subject: [PATCH 102/347] user pass in right place --- modules/dent/dent.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/dent/dent.js b/modules/dent/dent.js index 5ac7a5e..2361cfa 100644 --- a/modules/dent/dent.js +++ b/modules/dent/dent.js @@ -1,10 +1,10 @@ var request = require('request'); var dent = function(dbot) { - var username = dbot.config.dent.username; - var password = dbot.config.dent.password; var commands = { '~dent': function(event) { + var username = dbot.config.dent.username; + var password = dbot.config.dent.password; var auth = "Basic " + new Buffer(username + ":" + password).toString("base64"); request.post({ @@ -16,6 +16,7 @@ var dent = function(dbot) { }, function(error, response, body) { event.reply('Status posted (probably).'); + console.log(body); }); } }; From c64943994794342867bd88e1789a62aefcc22816 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Thu, 10 Jan 2013 22:23:51 +0000 Subject: [PATCH 103/347] Improve online users UI [REQ Bootstrap] --- modules/users/web.js | 53 +++++++++++++++++++++++++----------------- public/styles.css | 12 +++++----- views/layout.jade | 15 ++++++++---- views/users/users.jade | 37 ++++++++++++++++++++--------- 4 files changed, 74 insertions(+), 43 deletions(-) diff --git a/modules/users/web.js b/modules/users/web.js index a40de06..9028553 100644 --- a/modules/users/web.js +++ b/modules/users/web.js @@ -25,33 +25,44 @@ var pages = function(dbot) { if(connections.hasOwnProperty(connection) && connections[connection].channels.hasOwnProperty(channel)) { + var userData = { "active": [], "inactive": [], "offline": []}; var channelUsers = dbot.db.knownUsers[connection].channelUsers[channel]; - var usersData = {}; - for(var i=0;i<channelUsers.length;i++) { - usersData[channelUsers[i]] = { - 'name': channelUsers[i], - 'online': false, - 'active': false - }; - } var onlineNicks = connections[connection].channels[channel].nicks; - onlineNicks.each(function(nick) { - var nick = nick.name; - var user = dbot.api.users.resolveUser(connection, nick); - if(onlineNicks.hasOwnProperty(nick)) { - usersData[user].online = true; + for(var i=0;i<channelUsers.length;i++) { + if(channelUsers[i] == dbot.config.name){ + continue; } - console.log(user); - usersData[user].active = dbot.api.stats.isActive({ - 'server': connection, - 'user': user, - 'channel': channel - }); - }.bind(this)); + if(onlineNicks.hasOwnProperty(channelUsers[i])){ + var user = dbot.api.users.resolveUser(connection, channelUsers[i]); + if(dbot.api.stats.isActive({'server': connection, + 'user': user, + 'channel': channel + })){ + userData.active.push(channelUsers[i]); + } + else{ + userData.inactive.push(channelUsers[i]); + } + } + else{ + userData.offline.push(channelUsers[i]); + } + } + + var userSort = function(a, b){ + var x = a.toLowerCase(); + var y = b.toLowerCase(); + if(x > y) return 1; + if(x < y) return -1; + return 0; + } + userData.active.sort(userSort); + userData.inactive.sort(userSort); + userData.offline.sort(userSort); res.render('users', { 'name': dbot.config.name, 'connection': connection, - 'channel': channel, 'nicks': usersData }); + 'channel': channel, 'nicks': userData }); } else { res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection or channel.' }); } diff --git a/public/styles.css b/public/styles.css index fa45ded..f1c40eb 100644 --- a/public/styles.css +++ b/public/styles.css @@ -6,19 +6,19 @@ */ html { - background: url("background.jpg") no-repeat center center fixed; - -webkit-background-size: cover; - -moz-background-size: cover; - -o-background-size: cover; - background-size: cover; } body { padding: 25px; margin: 0; - font-family: "Lucida Grande"; + font-family: "Source Sans Pro", sans-serif; color: #444; text-shadow: 1px 1px 2px #2B2B2B; + background: url("background.jpg") no-repeat center center fixed; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; } h1,h2 { diff --git a/views/layout.jade b/views/layout.jade index 7fc3c1d..f895402 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -2,12 +2,17 @@ html(lang='en') head meta(charset='utf-8') + link(rel="stylesheet", type="text/css", href="http://fonts.googleapis.com/css?family=Source+Sans+Pro") + link(rel="stylesheet", type="text/css", href="/bootstrap/css/bootstrap.min.css") link(rel='stylesheet', type='text/css', href='/styles.css') title #{name} web interface body - div#page - div#title - a(href='/') #{name} web interface - div#main - block content + div.container + div#page + div#title + a(href='/') #{name} web interface + div#main + block content + script(type="text/javascript", src="/bootstrap/js/bootstrap.min.js") script(type="text/javascript", src="/script.js") + diff --git a/views/users/users.jade b/views/users/users.jade index b197b23..8770dcb 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -4,14 +4,29 @@ block content h3 Users of #{channel} on #{connection} div#backlink a(href='/channels/'+connection) « Channel List - ul#quotelist - -each nick in nicks - if nicks.hasOwnProperty(nick.name) - a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick.name) - if nick.online - if nick.active - li.quotes #{nick.name} (Online, Active) - else - li.quotes #{nick.name} (Online, Inactive) - else - li.quotes #{nick.name} (Offline) + div#row + table.table.table-striped + thead + tr: th Users + tbody + -each nick in nicks.active + tr + td + a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) + #{nick} + span + span.label.label-success Active + -each nick in nicks.inactive + tr + td + a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) + #{nick} + span + span.label.label-important Inactive + -each nick in nicks.offline + tr + td + a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) + #{nick} + span + span.label Offline From 34ebcd0aa28b8872c5c2d9392a4399199a638bd1 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Fri, 11 Jan 2013 12:29:22 +0000 Subject: [PATCH 104/347] Bootstrap requirement in web doc --- modules/web/README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/web/README.md b/modules/web/README.md index 4083416..1ce576b 100644 --- a/modules/web/README.md +++ b/modules/web/README.md @@ -1,7 +1,16 @@ -## Web +# Web Web interface -### Description +## Description It's a web interface for DBot. What of it? + +## Requirements +###Twitter Bootstrap +``` +cd depressionbot/public/ +wget http://twitter.github.com/bootstrap/assets/bootstrap.zip +unzip bootstrap.zip +rm bootstrap.zip +``` From 184236cebcf0fbdda7b42cd718f20de62c391958 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 11 Jan 2013 14:17:47 +0000 Subject: [PATCH 105/347] wtfux --- jsbot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsbot b/jsbot index 55e5f9e..f050c93 160000 --- a/jsbot +++ b/jsbot @@ -1 +1 @@ -Subproject commit 55e5f9e918b94f1d23cbc1e10934e6ac6faeff93 +Subproject commit f050c93f22e56ad98f245f7ba8b444208c4de6f8 From e36d99a6af12c0e746ec653548929782281da1bf Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 11 Jan 2013 14:21:08 +0000 Subject: [PATCH 106/347] update stats --- jsbot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsbot b/jsbot index f050c93..6d6186a 160000 --- a/jsbot +++ b/jsbot @@ -1 +1 @@ -Subproject commit f050c93f22e56ad98f245f7ba8b444208c4de6f8 +Subproject commit 6d6186ae0b96473d006faebe008c8af5aff8b56d From 292b9175275ba68952ec873c1e06c80d8a81f705 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Fri, 11 Jan 2013 22:39:32 +0000 Subject: [PATCH 107/347] Add stats to userlist [#117] --- modules/users/web.js | 15 +++++++------ modules/web/README.md | 9 ++++++++ views/layout.jade | 1 + views/users/users.jade | 50 ++++++++++++++++++++++++++++++++++++------ 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/modules/users/web.js b/modules/users/web.js index 9028553..4ea2e8a 100644 --- a/modules/users/web.js +++ b/modules/users/web.js @@ -33,26 +33,27 @@ var pages = function(dbot) { if(channelUsers[i] == dbot.config.name){ continue; } + + var user = dbot.api.stats.getUserStats(connection, channelUsers[i], channel); if(onlineNicks.hasOwnProperty(channelUsers[i])){ - var user = dbot.api.users.resolveUser(connection, channelUsers[i]); if(dbot.api.stats.isActive({'server': connection, - 'user': user, + 'user': channelUsers[i], 'channel': channel })){ - userData.active.push(channelUsers[i]); + userData.active.push(user); } else{ - userData.inactive.push(channelUsers[i]); + userData.inactive.push(user); } } else{ - userData.offline.push(channelUsers[i]); + userData.offline.push(user); } } var userSort = function(a, b){ - var x = a.toLowerCase(); - var y = b.toLowerCase(); + var x = a.display.toLowerCase(); + var y = b.display.toLowerCase(); if(x > y) return 1; if(x < y) return -1; return 0; diff --git a/modules/web/README.md b/modules/web/README.md index 1ce576b..86ebc10 100644 --- a/modules/web/README.md +++ b/modules/web/README.md @@ -14,3 +14,12 @@ wget http://twitter.github.com/bootstrap/assets/bootstrap.zip unzip bootstrap.zip rm bootstrap.zip ``` +###d3.js +``` +cd depressionbot/public/ +mkdir d3 +cd d3 +wget http://d3js.org/d3.v3.zip +unzip d3.v3.zip +rm d3.v3.zip +``` diff --git a/views/layout.jade b/views/layout.jade index f895402..cbc8ab2 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -14,5 +14,6 @@ html(lang='en') div#main block content script(type="text/javascript", src="/bootstrap/js/bootstrap.min.js") + script(type="text/javascript", src="/d3/d3.v3.min.js") script(type="text/javascript", src="/script.js") diff --git a/views/users/users.jade b/views/users/users.jade index 8770dcb..f0c345d 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -7,26 +7,62 @@ block content div#row table.table.table-striped thead - tr: th Users + tr + th Users + th Lines + th Words + th Lincent + th Verbosity + th Mentions tbody -each nick in nicks.active tr td - a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) - #{nick} + a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick.primary) + #{nick.display} span span.label.label-success Active + td + #{nick.total_lines} + td + #{nick.total_words} + td + #{nick.lincent} + td + #{nick.wpl} + td + #{nick.in_mentions} -each nick in nicks.inactive tr td - a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) - #{nick} + a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick.primary) + #{nick.display} span span.label.label-important Inactive + td + #{nick.total_lines} + td + #{nick.total_words} + td + #{nick.lincent} + td + #{nick.wpl} + td + #{nick.in_mentions} -each nick in nicks.offline tr td - a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick) - #{nick} + a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick.primary) + #{nick.display} span span.label Offline + td + #{nick.total_lines} + td + #{nick.total_words} + td + #{nick.lincent} + td + #{nick.wpl} + td + #{nick.in_mentions} From 5e8a5105ab4b2af225fdd679f73b2be3828b56d2 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 11 Jan 2013 22:42:48 +0000 Subject: [PATCH 108/347] update stats whatever fuck you it took me three tries to trype cd . --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 03bfd64..a803be3 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 03bfd640e044ae91075614e9293f6b94f494088b +Subproject commit a803be39a19a09bed1fcb0586a882b046ae29c99 From 04901cc0ba0d2c7ad8d5552e83ba383846dec64f Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 09:12:45 +0000 Subject: [PATCH 109/347] remove bootstrap submodule --- .gitmodules | 3 --- public/bootstrap | 1 - 2 files changed, 4 deletions(-) delete mode 160000 public/bootstrap diff --git a/.gitmodules b/.gitmodules index e928e2b..49a4b35 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,3 @@ [submodule "modules/stats"] path = modules/stats url = git://github.com/SamStudio8/stats.git -[submodule "public/bootstrap"] - path = public/bootstrap - url = git://github.com/twitter/bootstrap.git diff --git a/public/bootstrap b/public/bootstrap deleted file mode 160000 index 558bc52..0000000 --- a/public/bootstrap +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 558bc52432840ea1b2f413438427164288f10350 From f8d4896eb6e246a42f549172c99818bb763e670a Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 09:38:13 +0000 Subject: [PATCH 110/347] Moderator + admin access level for commands [#124] * May now add property 'access' to commands specifying 'moderator' or 'admin' level access * Add 'moderators' key to config * Convert commands in admin module to use command marshalling listener rather than its own --- config.json.sample | 1 + modules/admin/admin.js | 24 ++++++++++++------------ modules/command/command.js | 25 ++++++++++++++++++++++++- run.js | 2 +- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/config.json.sample b/config.json.sample index 27342c0..532460a 100644 --- a/config.json.sample +++ b/config.json.sample @@ -12,6 +12,7 @@ } }, "admins": [ "batman" ], + "moderators": [ "whatever" ], "moduleNames": [ "ignore", "admin", "command", "dice", "js", "kick", "quotes", "spelling", "youare" ], "language": "english", "debugMode": true diff --git a/modules/admin/admin.js b/modules/admin/admin.js index 962eda0..0401585 100644 --- a/modules/admin/admin.js +++ b/modules/admin/admin.js @@ -148,21 +148,21 @@ var admin = function(dbot) { } }; + commands['greload'].access = 'admin'; + commands['reload'].access = 'admin'; + commands['unload'].access = 'admin'; + commands['load'].access = 'admin'; + commands['join'].access = 'moderator'; + commands['part'].access = 'moderator'; + commands['opme'].access = 'moderator'; + commands['say'].access = 'moderator'; + commands['ban'].access = 'moderator'; + commands['unban'].access = 'moderator'; + return { 'name': 'admin', 'ignorable': false, - - /** - * Run the appropriate admin command given the input (and user). - */ - 'listener': function(event) { - var commandName = event.params[0]; - if(commands.hasOwnProperty(commandName) && dbot.config.admins.include(event.user)) { - commands[commandName](event); - dbot.save(); - } - }, - 'on': 'PRIVMSG' + 'commands': commands }; }; diff --git a/modules/command/command.js b/modules/command/command.js index 0ab8bf2..51d991b 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -18,6 +18,29 @@ var command = function(dbot) { return banned; }; + /** + * Does the user have the correct access level to use the command? + */ + var hasAccess = function(user, command) { + var access = true; + var accessNeeded = dbot.commands[command].access; + + if(accessNeeded == 'admin') { + if(!dbot.config.admins.include(user)) { + access = false; + } + } else if(accessNeeded == 'moderator') { + if(!dbot.config.moderators.include(user) && + !dbot.config.admins.include(user)) { + access = false; + } + } + console.log(accessNeeded); + console.log(user); + + return access; + }; + /** * Is user ignoring command? */ @@ -101,7 +124,7 @@ var command = function(dbot) { if(isBanned(event.user, commandName)) { event.reply(dbot.t('command_ban', {'user': event.user})); } else { - if(!isIgnoring(event.user, commandName)) { + if(!isIgnoring(event.user, commandName) && hasAccess(event.user, commandName)) { if(applyRegex(commandName, event)) { try { dbot.commands[commandName](event); diff --git a/run.js b/run.js index d8220fe..e83dbac 100644 --- a/run.js +++ b/run.js @@ -5,7 +5,7 @@ require('./snippets'); var DBot = function(timers) { // Load external files - var requiredConfigKeys = [ 'name', 'servers', 'admins', 'moduleNames', 'language', 'debugMode' ]; + var requiredConfigKeys = [ 'name', 'servers', 'admins', 'moderators', 'moduleNames', 'language', 'debugMode' ]; try { this.config = JSON.parse(fs.readFileSync('config.json', 'utf-8')); } catch(err) { From 6b903407ed8ab8d53129821307c760e4d68ad259 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 09:49:41 +0000 Subject: [PATCH 111/347] Used access parameter on all elevated access commadns I can think of [#124] --- modules/js/js.js | 10 ++--- modules/quotes/quotes.js | 33 ++++++++-------- modules/users/users.js | 83 ++++++++++++++++++++-------------------- 3 files changed, 62 insertions(+), 64 deletions(-) diff --git a/modules/js/js.js b/modules/js/js.js index 76d5f91..917e0a5 100644 --- a/modules/js/js.js +++ b/modules/js/js.js @@ -22,17 +22,17 @@ var js = function(dbot) { // Run JS code un-sandboxed, with access to DBot memory (admin-only). '~ajs': function(event) { - if(dbot.config.admins.include(event.user) ) { - var ret = eval(event.input[1]); - if(ret !== undefined) { - event.reply(ret); - } + var ret = eval(event.input[1]); + if(ret !== undefined) { + event.reply(ret); } } }; commands['~js'].regex = [/^~js (.*)/, 2]; commands['~ajs'].regex = [/^~ajs (.*)/, 2]; + commands['~ajs'].access = 'admin'; + return { 'name': 'js', 'ignorable': true, diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index c93307e..9d605f1 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -93,28 +93,24 @@ var quotes = function(dbot) { }, '~rmconfirm': function(event) { - if(dbot.config.admins.include(event.user)) { - var rmCacheCount = rmCache.length; - rmCache.length = 0; - event.reply(dbot.t('quote_cache_cleared', - { 'count': rmCacheCount })); - } + var rmCacheCount = rmCache.length; + rmCache.length = 0; + event.reply(dbot.t('quote_cache_cleared', + { 'count': rmCacheCount })); }, '~rmdeny': function(event) { - if(dbot.config.admins.include(event.user)) { - var rmCacheCount = rmCache.length; - for(var i=0;i<rmCacheCount;i++) { - if(!quotes.hasOwnProperty(rmCache[i].key)) { - quotes[rmCache[i].key] = []; - } - quotes[rmCache[i].key].push(rmCache[i].quote); + var rmCacheCount = rmCache.length; + for(var i=0;i<rmCacheCount;i++) { + if(!quotes.hasOwnProperty(rmCache[i].key)) { + quotes[rmCache[i].key] = []; } - rmCache.length = 0; - - event.reply(dbot.t('quote_cache_reinstated', - { 'count': rmCacheCount })); + quotes[rmCache[i].key].push(rmCache[i].quote); } + rmCache.length = 0; + + event.reply(dbot.t('quote_cache_reinstated', + { 'count': rmCacheCount })); }, @@ -271,6 +267,9 @@ var quotes = function(dbot) { commands['~rmlast'].regex = [/^~rmlast ([\d\w\s-]*)/, 2]; commands['~qadd'].regex = [/^~qadd ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; + commands['~rmconfirm'].access = 'moderator'; + commands['~rmdeny'].access = 'moderator'; + var pages = { // Lists quotes in a category '/quotes/:key': function(req, res) { diff --git a/modules/users/users.js b/modules/users/users.js index 0948719..b96f9c8 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -95,63 +95,62 @@ var users = function(dbot) { }, '~setaliasparent': function(event) { - if(dbot.config.admins.include(event.user)) { - var knownUsers = getServerUsers(event.server); - var newParent = event.params[1]; + var knownUsers = getServerUsers(event.server); + var newParent = event.params[1]; - if(knownUsers.aliases.hasOwnProperty(newParent)) { - var newAlias = knownUsers.aliases[newParent]; + if(knownUsers.aliases.hasOwnProperty(newParent)) { + var newAlias = knownUsers.aliases[newParent]; - // Replace users entry with new primary user - var usersIndex = knownUsers.users.indexOf(newAlias); - knownUsers.users.splice(usersIndex, 1); - knownUsers.users.push(newParent); + // Replace users entry with new primary user + var usersIndex = knownUsers.users.indexOf(newAlias); + knownUsers.users.splice(usersIndex, 1); + knownUsers.users.push(newParent); - // Replace channels entries with new primary user - updateChannels(event, newAlias, newParent); + // Replace channels entries with new primary user + updateChannels(event, newAlias, newParent); - // Remove alias for new parent & add alias for new alias - delete knownUsers.aliases[newParent]; - knownUsers.aliases[newAlias] = newParent; + // Remove alias for new parent & add alias for new alias + delete knownUsers.aliases[newParent]; + knownUsers.aliases[newAlias] = newParent; - // Update aliases to point to new primary user - updateAliases(event, newAlias, newParent); + // Update aliases to point to new primary user + updateAliases(event, newAlias, newParent); - event.reply(dbot.t('aliasparentset', { 'newParent': newParent, - 'newAlias': newAlias })); + event.reply(dbot.t('aliasparentset', { 'newParent': newParent, + 'newAlias': newAlias })); - dbot.api.stats.fixStats(event.server, newAlias); - } else { - event.reply(dbot.t('unknown_alias', { 'alias': newParent})); - } + dbot.api.stats.fixStats(event.server, newAlias); + } else { + event.reply(dbot.t('unknown_alias', { 'alias': newParent})); } }, '~mergeusers': function(event) { - if(dbot.config.admins.include(event.user)) { - var knownUsers = getServerUsers(event.server); - var primaryUser = event.params[1]; - var secondaryUser = event.params[2]; + var knownUsers = getServerUsers(event.server); + var primaryUser = event.params[1]; + var secondaryUser = event.params[2]; - if(knownUsers.users.include(primaryUser) && knownUsers.users.include(secondaryUser)) { - knownUsers.users.splice(knownUsers.users.indexOf(secondaryUser), 1); - knownUsers.aliases[secondaryUser] = primaryUser; - updateAliases(event, secondaryUser, primaryUser); - updateChannels(event, secondaryUser, primaryUser); + if(knownUsers.users.include(primaryUser) && knownUsers.users.include(secondaryUser)) { + knownUsers.users.splice(knownUsers.users.indexOf(secondaryUser), 1); + knownUsers.aliases[secondaryUser] = primaryUser; + updateAliases(event, secondaryUser, primaryUser); + updateChannels(event, secondaryUser, primaryUser); - event.reply(dbot.t('merged_users', { - 'old_user': secondaryUser, - 'new_user': primaryUser - })); - - dbot.api.stats.fixStats(event.server, secondaryUser); - } else { - event.reply(dbot.t('unprimary_error')); - } - } - } + event.reply(dbot.t('merged_users', { + 'old_user': secondaryUser, + 'new_user': primaryUser + })); + + dbot.api.stats.fixStats(event.server, secondaryUser); + } else { + event.reply(dbot.t('unprimary_error')); + } + } }; + commands['~setaliasparent'].access = 'moderator'; + commands['~mergeusers'].access = 'moderator'; + return { 'name': 'users', 'ignorable': false, From 20ef3b64322cd823785d23bd9584f413823e9ed0 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 10:07:39 +0000 Subject: [PATCH 112/347] Command properties may be specified in module config file [#125] --- run.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/run.js b/run.js index e83dbac..22e7e0b 100644 --- a/run.js +++ b/run.js @@ -161,6 +161,7 @@ DBot.prototype.reloadModules = function() { try { // Load the module config data + var config = {}; try { var config = JSON.parse(fs.readFileSync(moduleDir + 'config.json', 'utf-8')) this.config[name] = config; @@ -206,6 +207,17 @@ DBot.prototype.reloadModules = function() { } } + // Load module commands with properties specified in config + if(module.commands && config.commands) { + for(key in config.commands) { + if(newCommands.hasOwnProperty(key)) { + for(var prop in config.commands[key]) { + newCommands[key][prop] = config.commands[key][prop]; + } + } + } + } + // Load module web bits if(module.pages) { var newpages = module.pages; From 400169f9eea6b8a5c64dbb0215ef2b5c3d1e0158 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 10:12:56 +0000 Subject: [PATCH 113/347] Disable command config [#126] Disabled ~js (good example for [#125]) --- modules/command/command.js | 4 +++- modules/js/config.json | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/command/command.js b/modules/command/command.js index 51d991b..6373055 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -124,7 +124,9 @@ var command = function(dbot) { if(isBanned(event.user, commandName)) { event.reply(dbot.t('command_ban', {'user': event.user})); } else { - if(!isIgnoring(event.user, commandName) && hasAccess(event.user, commandName)) { + if(!isIgnoring(event.user, commandName) && + hasAccess(event.user, commandName) && + dbot.commands[commandName].disabled !== true) { if(applyRegex(commandName, event)) { try { dbot.commands[commandName](event); diff --git a/modules/js/config.json b/modules/js/config.json index deddf40..70bf0ec 100644 --- a/modules/js/config.json +++ b/modules/js/config.json @@ -1,3 +1,8 @@ { + "commands": { + "~js": { + "disabled": true + } + }, "help": "http://github.com/reality/depressionbot/blob/master/modules/js/README.md" } From e68cf45e65c7d5358c9fd3dc29ff4d37a6ccbcfe Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 10:38:40 +0000 Subject: [PATCH 114/347] Few tests and that --- run.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/run.js b/run.js index 22e7e0b..7f36b9b 100644 --- a/run.js +++ b/run.js @@ -1,6 +1,7 @@ -var fs = require('fs'); -var timers = require('./timer'); -var jsbot = require('./jsbot/jsbot'); +var fs = require('fs'), + _ = require('underscore')._, + timers = require('./timer'), + jsbot = require('./jsbot/jsbot'); require('./snippets'); var DBot = function(timers) { @@ -17,13 +18,13 @@ var DBot = function(timers) { process.exit(); } } - requiredConfigKeys.each(function(key) { - if(!this.config.hasOwnProperty(key)) { + _.each(requiredConfigKeys, function(key) { + if(!_.has(this.config, key)) { console.log('Error: Please set a value for ' + key + ' in ' + 'config.json. Stopping.'); process.exit(); } - }.bind(this)); + }, this); var rawDB; try { @@ -58,7 +59,7 @@ var DBot = function(timers) { // Create JSBot and connect to each server this.instance = jsbot.createJSBot(this.config.name); for(var name in this.config.servers) { - if(this.config.servers.hasOwnProperty(name)) { + if(_.has(this.config.servers, name)) { var server = this.config.servers[name]; this.instance.addConnection(name, server.server, server.port, this.config.admin, function(event) { From 9c4a3d46358009f17e2af9ea5c6d2ff97df36583 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 10:39:11 +0000 Subject: [PATCH 115/347] update jsbot --- jsbot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsbot b/jsbot index 6d6186a..cf62909 160000 --- a/jsbot +++ b/jsbot @@ -1 +1 @@ -Subproject commit 6d6186ae0b96473d006faebe008c8af5aff8b56d +Subproject commit cf6290902cfed0c8d698ce64df2ae0ae0a64b9f2 From 76733f46796835dd6c33915fe0d77ab6a429f3c6 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 11:30:39 +0000 Subject: [PATCH 116/347] Remove some debug output --- modules/command/command.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/command/command.js b/modules/command/command.js index 6373055..492358b 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -35,8 +35,6 @@ var command = function(dbot) { access = false; } } - console.log(accessNeeded); - console.log(user); return access; }; From 0f39a227f28d01d1188243a4ada44415c0f65702 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 11:39:17 +0000 Subject: [PATCH 117/347] -nicks- now picks random nick from channel [#105] --- modules/quotes/quotes.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index 9d605f1..a6baab7 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -9,7 +9,7 @@ var quotes = function(dbot) { // Retrieve a random quote from a given category, interpolating any quote // references (~~QUOTE CATEGORY~~) within it - var interpolatedQuote = function(key, quoteTree) { + var interpolatedQuote = function(event, key, quoteTree) { if(quoteTree !== undefined && quoteTree.indexOf(key) != -1) { return ''; } else if(quoteTree === undefined) { @@ -24,10 +24,14 @@ var quotes = function(dbot) { while(quoteRefs && (thisRef = quoteRefs.shift()) !== undefined) { var cleanRef = dbot.cleanNick(thisRef.replace(/^~~/,'').replace(/~~$/,'').trim()); - if (quotes.hasOwnProperty(cleanRef)) { + if(cleanRef === '-nicks-') { + var randomNick = Object.keys(event.channel.nicks).random(); + quoteString = quoteString.replace("~~" + cleanRef + "~~", randomNick); + quoteTree.pop(); + } else if(quotes.hasOwnProperty(cleanRef)) { quoteTree.push(key); quoteString = quoteString.replace("~~" + cleanRef + "~~", - interpolatedQuote(cleanRef, quoteTree.slice())); + interpolatedQuote(event, cleanRef, quoteTree.slice())); quoteTree.pop(); } } @@ -56,7 +60,7 @@ var quotes = function(dbot) { }; var api = { - 'getQuote': function(category) { + 'getQuote': function(event, category) { var key = category.trim().toLowerCase(); var altKey; if(key.split(' ').length > 0) { @@ -65,9 +69,9 @@ var quotes = function(dbot) { if(key.charAt(0) !== '_') { // lol if(quotes.hasOwnProperty(key)) { - return interpolatedQuote(key); + return interpolatedQuote(event, key); } else if(quotes.hasOwnProperty(altKey)) { - return interpolatedQuote(altKey); + return interpolatedQuote(event, altKey); } else { return false; } @@ -117,7 +121,7 @@ var quotes = function(dbot) { // Retrieve quote from a category in the database. '~q': function(event) { var key = event.input[1].trim().toLowerCase(); - var quote = api.getQuote(event.input[1]); + var quote = api.getQuote(event, event.input[1]); if(quote) { event.reply(key + ': ' + quote); } else { @@ -245,7 +249,7 @@ var quotes = function(dbot) { '~rq': function(event) { var rQuote = Object.keys(quotes).random(); - event.reply(rQuote + ': ' + interpolatedQuote(rQuote)); + event.reply(rQuote + ': ' + interpolatedQuote(event, rQuote)); }, '~link': function(event) { @@ -315,9 +319,9 @@ var quotes = function(dbot) { dbot.instance.emit(event); } } else if(event.action == 'JOIN') { - var userQuote = api.getQuote(event.user) + var userQuote = api.getQuote(event, event.user) if(userQuote) { - event.reply(event.user + ': ' + api.getQuote(event.user)); + event.reply(event.user + ': ' + api.getQuote(event, event.user)); } } }, From c71345a6937ea9a6b78ccc14bdcbf2e23ea875a6 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 12:36:23 +0000 Subject: [PATCH 118/347] update jsbot --- jsbot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsbot b/jsbot index cf62909..9477dc3 160000 --- a/jsbot +++ b/jsbot @@ -1 +1 @@ -Subproject commit cf6290902cfed0c8d698ce64df2ae0ae0a64b9f2 +Subproject commit 9477dc33ff1b940f8c07225f00d0648de2a41cb4 From 2245167cf302d6306e1e1ba363d7a3b45bdd03c8 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sat, 12 Jan 2013 13:01:43 +0000 Subject: [PATCH 119/347] Added patching info for Express --- modules/web/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/modules/web/README.md b/modules/web/README.md index 86ebc10..c00af25 100644 --- a/modules/web/README.md +++ b/modules/web/README.md @@ -7,6 +7,23 @@ Web interface It's a web interface for DBot. What of it? ## Requirements +###Express and Jade@0.25 +``` +npm install express +npm install jade@0.25 +``` +###Express Patch +Express currently needs to be patched, edit ~/node_modules/express/lib/express.js as thus; +``` + 52 for (var key in connect.middleware) { +**53 if( !Object.prototype.hasOwnProperty(key) ) { + 54 Object.defineProperty( + 55 exports + 56 , key + 57 , Object.getOwnPropertyDescriptor(connect.middleware, key)); +**58 } + 59 } +``` ###Twitter Bootstrap ``` cd depressionbot/public/ From 73ec2bb182fbbedce483545a8762b8fa2c661e23 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sat, 12 Jan 2013 13:17:31 +0000 Subject: [PATCH 120/347] Upgraded stats and users to core --- config.json.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json.sample b/config.json.sample index 532460a..05c37a4 100644 --- a/config.json.sample +++ b/config.json.sample @@ -13,7 +13,7 @@ }, "admins": [ "batman" ], "moderators": [ "whatever" ], - "moduleNames": [ "ignore", "admin", "command", "dice", "js", "kick", "quotes", "spelling", "youare" ], + "moduleNames": [ "ignore", "admin", "command", "dice", "js", "kick", "quotes", "spelling", "youare", "stats", "users" ], "language": "english", "debugMode": true } From d9f8ff0c1f19a85c77b936da19fdce5470f03898 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 14:58:54 +0000 Subject: [PATCH 121/347] lots of underscorisation in module loading --- run.js | 92 +++++++++++++++++++++------------------------------------- 1 file changed, 33 insertions(+), 59 deletions(-) diff --git a/run.js b/run.js index 7f36b9b..8e08e42 100644 --- a/run.js +++ b/run.js @@ -164,17 +164,19 @@ DBot.prototype.reloadModules = function() { // Load the module config data var config = {}; try { - var config = JSON.parse(fs.readFileSync(moduleDir + 'config.json', 'utf-8')) - this.config[name] = config; - for(var i=0;i<config.dbKeys.length;i++) { - if(!this.db.hasOwnProperty(config.dbKeys[i])) { - this.db[config.dbKeys[i]] = {}; - } - } + config = JSON.parse(fs.readFileSync(moduleDir + 'config.json', 'utf-8')) + } catch(err) { // Invalid or no config data } + this.config[name] = config; + _.each(config.dbKeys, function(dbKey) { + if(!_.has(this.db, dbKey( { + this.db[dbKey] = {}; + } + }, this); + // Load the module itself var rawModule = require(moduleDir + name); var module = rawModule.fetch(this); @@ -183,14 +185,13 @@ DBot.prototype.reloadModules = function() { module.name = name; if(module.listener) { - var listenOn = module.on; - if(!(listenOn instanceof Array)) { - listenOn = [listenOn]; + if(!_.isArray(module.on)) { + module.on = [ module.on ]; } - listenOn.each(function(on) { + _.each(module.on, function(on) { this.instance.addListener(on, module.name, module.listener); - }.bind(this)); + }, this); } if(module.onLoad) { @@ -199,36 +200,21 @@ DBot.prototype.reloadModules = function() { // Load module commands 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]; - this.commandMap[key] = name; + _.extend(this.commands, module.commands); + _.each(module.commands, function(command, commandName) { + command.module = name; + if(_.has(config, 'commands') && _.has(config.commands, commandName)) { + _.extend(command, config.commands[commandName]); } - } - } - - // Load module commands with properties specified in config - if(module.commands && config.commands) { - for(key in config.commands) { - if(newCommands.hasOwnProperty(key)) { - for(var prop in config.commands[key]) { - newCommands[key][prop] = config.commands[key][prop]; - } - } - } + }, this); } // Load module web bits if(module.pages) { - var newpages = module.pages; - for(var key in newpages) - { - if(newpages.hasOwnProperty(key) && Object.prototype.isFunction(newpages[key])) { - this.pages[key] = newpages[key]; - this.pages[key].module = module; - } - } + _.extend(this.pages, module.pages); + _.each(module.pages, function(page) { + page.module = name; + }, this); } // Load module API @@ -237,51 +223,39 @@ DBot.prototype.reloadModules = function() { } // Load the module usage data + var usage = {}; try { - var usage = JSON.parse(fs.readFileSync(moduleDir + 'usage.json', 'utf-8')); - for(key in usage) { - if(usage.hasOwnProperty(key)) { - if(this.usage.hasOwnProperty(key)) { - console.log('Usage key clash for ' + key + ' in ' + name); - } else { - this.usage[key] = usage[key]; - } - } - } + usage = JSON.parse(fs.readFileSync(moduleDir + 'usage.json', 'utf-8')); } catch(err) { // Invalid or no usage info } + _.extend(this.usage, usage); // Load the module string data + var strings = {}; try { - var strings = JSON.parse(fs.readFileSync(moduleDir + 'strings.json', 'utf-8')); - for(key in strings) { - if(strings.hasOwnProperty(key)) { - if(this.strings.hasOwnProperty(key)) { - console.log('Strings key clash for ' + key + ' in ' + name); - } else { - this.strings[key] = strings[key]; - } - } - } + strings = JSON.parse(fs.readFileSync(moduleDir + 'strings.json', 'utf-8')); } catch(err) { // Invalid or no string info } + _.extend(this.strings, strings); + // Provide toString for module name module.toString = function() { return this.name; } + this.modules[module.name] = module; } catch(err) { console.log(this.t('module_load_error', {'moduleName': name})); if(this.config.debugMode) { console.log('MODULE ERROR (' + name + '): ' + err.stack ); - } - else { + } else { console.log('MODULE ERROR (' + name + '): ' + err ); } } }.bind(this)); + this.reloadPages(); this.save(); }; From af20b5cbfb9daeae50d90d78f2cd56f15d10dd28 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 15:07:14 +0000 Subject: [PATCH 122/347] Load missing config directives from defaults file --- run.js | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/run.js b/run.js index 8e08e42..8e03fe9 100644 --- a/run.js +++ b/run.js @@ -5,26 +5,23 @@ var fs = require('fs'), require('./snippets'); var DBot = function(timers) { - // Load external files - var requiredConfigKeys = [ 'name', 'servers', 'admins', 'moderators', 'moduleNames', 'language', 'debugMode' ]; + // Load config try { this.config = JSON.parse(fs.readFileSync('config.json', 'utf-8')); } catch(err) { - console.log('Config file is screwed up. Attempting to load defaults.'); - try { - this.config = JSON.parse(fs.readFileSync('config.json.sample', 'utf-8')); - } catch(err) { - console.log('Error loading sample config. Bugger off. Stopping.'); - process.exit(); - } + console.log('Config file is invalid. Stopping'); + process.exit(); } - _.each(requiredConfigKeys, function(key) { - if(!_.has(this.config, key)) { - console.log('Error: Please set a value for ' + key + ' in ' + - 'config.json. Stopping.'); - process.exit(); - } - }, this); + + try { + var defaultConfig = JSON.parse(fs.readFileSync('config.json.sample', 'utf-8')); + } catch(err) { + console.log('Error loading sample config. Bugger off this should not even be edited. Stopping.'); + process.exit(); + } + + // Load missing config directives from sample file + _.defaults(this.config, defaultConfig); var rawDB; try { @@ -172,7 +169,7 @@ DBot.prototype.reloadModules = function() { this.config[name] = config; _.each(config.dbKeys, function(dbKey) { - if(!_.has(this.db, dbKey( { + if(!_.has(this.db, dbKey)) { this.db[dbKey] = {}; } }, this); From 0769d0bd69b6f20c9f9746d12b4c5ed46b68a429 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 16:14:17 +0000 Subject: [PATCH 123/347] Removed dependency on commandMap (I think ignore might still look at it for now). Underscorised command. [#81] --- modules/command/command.js | 29 +++++++++++++++-------------- run.js | 16 +++++++++------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/modules/command/command.js b/modules/command/command.js index 492358b..968e578 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -4,14 +4,15 @@ * command and then runs that command, given the user isn't banned from or * ignoring that command. */ +var _ = require('underscore')._; var command = function(dbot) { /** * Is user banned from using 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)) { + if(_.has(dbot.db.bans, command)) { + if(_.include(dbot.db.bans[command], user) || _.include(dbot.db.bans['*'], user)) { banned = true; } } @@ -26,12 +27,12 @@ var command = function(dbot) { var accessNeeded = dbot.commands[command].access; if(accessNeeded == 'admin') { - if(!dbot.config.admins.include(user)) { + if(!_.include(dbot.config.admins, user)) { access = false; } } else if(accessNeeded == 'moderator') { - if(!dbot.config.moderators.include(user) && - !dbot.config.admins.include(user)) { + if(!_.include(dbot.config.moderators, user) && + !_.include(dbot.config.admins, user)) { access = false; } } @@ -43,9 +44,9 @@ var command = function(dbot) { * Is user ignoring command? */ var isIgnoring = function(user, command) { - var module = dbot.commandMap[command]; + var module = dbot.commands[command].module; var ignoring = false; - if(dbot.db.ignores.hasOwnProperty(user) && dbot.db.ignores[user].include(module)) { + if(_.has(dbot.db.ignores, user) && _.include(dbot.db.ignores[user], module)) { ignoring = true; } return ignoring; @@ -57,7 +58,7 @@ var command = function(dbot) { */ var applyRegex = function(commandName, event) { var applies = false; - if(dbot.commands[commandName].hasOwnProperty('regex')) { + if(_.has(dbot.commands[commandName], 'regex')) { var cRegex = dbot.commands[commandName].regex; var q = event.message.valMatch(cRegex[0], cRegex[1]); if(q) { @@ -77,7 +78,7 @@ var command = function(dbot) { 'commands': { '~usage': function(event) { var commandName = event.params[1]; - if(dbot.usage.hasOwnProperty(commandName)) { + if(_.has(dbot.usage, commandName)) { event.reply(dbot.t('usage', { 'command': commandName, 'usage': dbot.usage[commandName] @@ -91,11 +92,11 @@ var command = function(dbot) { '~help': function(event) { var moduleName = event.params[1]; - if(!dbot.modules.hasOwnProperty(moduleName)) { - var moduleName = dbot.commandMap[moduleName]; + if(!_.has(dbot.modules, moduleName)) { + var moduleName = dbot.commands[moduleName].module; } - if(moduleName && dbot.config[moduleName].hasOwnProperty('help')) { + if(moduleName && _.has(dbot.config[moduleName], 'help')) { var help = dbot.config[moduleName].help; event.reply(dbot.t('help_link', { 'module': moduleName, @@ -115,7 +116,7 @@ var command = function(dbot) { */ 'listener': function(event) { var commandName = event.params[0]; - if(!dbot.commands.hasOwnProperty(commandName)) { + if(!_.has(dbot.commands, commandName)) { commandName = '~'; } @@ -138,7 +139,7 @@ var command = function(dbot) { dbot.save(); } else { if(commandName !== '~') { - if(dbot.usage.hasOwnProperty(commandName)){ + if(_.has(dbot.usage, commandName)) { event.reply('Usage: ' + dbot.usage[commandName]); } else { event.reply(dbot.t('syntax_error')); diff --git a/run.js b/run.js index 8e03fe9..def9a5a 100644 --- a/run.js +++ b/run.js @@ -81,9 +81,9 @@ DBot.prototype.say = function(server, channel, message) { // Format given stored string in config language DBot.prototype.t = function(string, formatData) { var formattedString; - if(this.strings.hasOwnProperty(string)) { + if(_.has(this.strings, string)) { var lang = this.config.language; - if(!this.strings[string].hasOwnProperty(lang)) { + if(!_.has(this.strings[string], lang)) { lang = "english"; } @@ -257,18 +257,20 @@ DBot.prototype.reloadModules = function() { this.save(); }; +// I honestly don't know what the fuck this is meant to do. Why is it getting a +// reference to all the pages? DBot.prototype.reloadPages = function() { - for( var m in this.modules ) { - if( Object.prototype.isFunction(this.modules[m].reloadPages)) { - this.modules[m].reloadPages(this.pages); + _.each(this.modules, function(module) { + if(_.isFunction(module.reloadPages)) { + module.reloadPages(this.pages); } - } + }, this); } DBot.prototype.cleanNick = function(key) { key = key.toLowerCase(); while(key.endsWith("_")) { - if(this.db.quoteArrs.hasOwnProperty(key)) { + if(_.has(this.db.quoteArrs, key)) { return key; } key = key.substring(0, key.length-1); From 39cab9c60d89e32526231e640ac501b1e83f7321 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 17:10:48 +0000 Subject: [PATCH 124/347] Disallow loading modules more than once, with a nice tribute to @samstudio8 if you try to load web [#116] --- modules/admin/admin.js | 14 +++++++++++--- modules/admin/strings.json | 6 ++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/modules/admin/admin.js b/modules/admin/admin.js index 0401585..30d9188 100644 --- a/modules/admin/admin.js +++ b/modules/admin/admin.js @@ -99,9 +99,17 @@ var admin = function(dbot) { // Load new module 'load': function(event) { var moduleName = event.params[1]; - dbot.config.moduleNames.push(moduleName); - dbot.reloadModules(); - event.reply(dbot.t('load_module', {'moduleName': moduleName})); + if(!dbot.config.moduleNames.include(moduleName)) { + dbot.config.moduleNames.push(moduleName); + dbot.reloadModules(); + event.reply(dbot.t('load_module', {'moduleName': moduleName})); + } else { + if(moduleName == 'web') { + event.reply(dbot.t('already_loaded_web')); + } else { + event.reply(dbot.t('already_loaded', {'moduleName': moduleName})); + } + } }, // Unload a loaded module diff --git a/modules/admin/strings.json b/modules/admin/strings.json index 1ca3ed4..7629aec 100644 --- a/modules/admin/strings.json +++ b/modules/admin/strings.json @@ -70,5 +70,11 @@ }, "not_in_channel": { "english": "I'm not in {channel}" + }, + "already_loaded_web": { + "english": "WHY CAN'T I LOAD ALL THIS WEB? (web already loaded)" + }, + "already_loaded": { + "english": "{moduleName} is already loaded." } } From abaa1e7fa24963d19760a38ad0db710945e50618 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 17:36:59 +0000 Subject: [PATCH 125/347] underscorise admin.js [#81] --- modules/admin/admin.js | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/modules/admin/admin.js b/modules/admin/admin.js index 30d9188..bb362ac 100644 --- a/modules/admin/admin.js +++ b/modules/admin/admin.js @@ -3,16 +3,17 @@ * 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 fs = require('fs'), + _ = require('underscore')._, + sys = require('sys'), + exec = require('child_process').exec; var admin = function(dbot) { var commands = { // Join a channel 'join': function(event) { var channel = event.params[1]; - if(event.allChannels.hasOwnProperty(channel)) { + if(_.has(event.allChannels, channel)) { event.reply(dbot.t('already_in_channel', {'channel': channel})); } else { dbot.instance.join(event, channel); @@ -23,7 +24,7 @@ var admin = function(dbot) { // Leave a channel 'part': function(event) { var channel = event.params[1]; - if(!event.allChannels.hasOwnProperty(channel)) { + if(!_.has(event.allChannels, channel)) { event.reply(dbot.t('not_in_channel', {'channel': channel})); } else { event.instance.part(event, channel); @@ -36,7 +37,7 @@ var admin = function(dbot) { var channel = event.params[1]; // If given channel isn't valid just op in current one. - if(!event.allChannels.hasOwnProperty(channel)) { + if(!_.has(event.allChannels, channel)) { channel = event.channel.name; } dbot.instance.mode(event, channel, ' +o ' + event.user); @@ -61,7 +62,7 @@ var admin = function(dbot) { var cmd = "git log --pretty=format:'%h (%s): %ar' -n 1 -- "; if(event.params[1]){ var input = event.params[1].trim(); - if(dbot.modules.hasOwnProperty(input.split("/")[0])){ + if(_.has(dbot.modules, input.split("/")[0])){ cmd += "modules/"+input; } else{ @@ -99,7 +100,7 @@ var admin = function(dbot) { // Load new module 'load': function(event) { var moduleName = event.params[1]; - if(!dbot.config.moduleNames.include(moduleName)) { + if(!_.include(dbot.config.moduleNames, moduleName)) { dbot.config.moduleNames.push(moduleName); dbot.reloadModules(); event.reply(dbot.t('load_module', {'moduleName': moduleName})); @@ -116,13 +117,15 @@ var admin = function(dbot) { 'unload': function(event) { var moduleNames = dbot.config.moduleNames; var moduleName = event.params[1]; - if(moduleNames.include(moduleName)) { + if(_.include(moduleNames, moduleName)) { var moduleDir = '../' + moduleName + '/'; var cacheKey = require.resolve(moduleDir + moduleName); delete require.cache[cacheKey]; - var moduleIndex = moduleNames.indexOf(moduleName); - moduleNames.splice(moduleIndex, 1); + dbot.config.moduleNames = _.reject(moduleNames, function(module) { + return module == moduleName; + }, this); + dbot.reloadModules(); event.reply(dbot.t('unload_module', {'moduleName': moduleName})); @@ -136,7 +139,7 @@ var admin = function(dbot) { var username = event.params[1]; var command = event.params[2]; - if(!dbot.db.bans.hasOwnProperty(command)) { + if(!_.has(dbot.db.bans, command)) { dbot.db.bans[command] = [ ]; } dbot.db.bans[command].push(username); @@ -147,8 +150,10 @@ var admin = function(dbot) { '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); + if(_.has(dbot.db.bans, command) && _.include(dbot.db.bans[command], username)) { + _.reject(dbot.db.bans[command], function(bans) { + return bans == username; + }, this); event.reply(dbot.t('unbanned', {'user': username, 'command': command})); } else { event.reply(dbot.t('unban_error', {'user': username})); From 08bd67f4f04d6a73e883a3d7beb7c5847348a9aa Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 21:40:16 +0000 Subject: [PATCH 126/347] incomplete underscorisation in quotes [#81] --- modules/quotes/quotes.js | 135 ++++++++++++++++++++++----------------- run.js | 21 +++--- 2 files changed, 87 insertions(+), 69 deletions(-) diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index a6baab7..96524c5 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -1,22 +1,24 @@ +var _ = require('underscore')._; + var quotes = function(dbot) { - var name = 'quotes'; - var quotes = dbot.db.quoteArrs; - var addStack = []; - var rmAllowed = true; + var quotes = dbot.db.quoteArrs, + addStack = [], + rmAllowed = true, + rmCache = dbot.sessionData.rmCache, + rmTimer; dbot.sessionData.rmCache = []; - var rmCache = dbot.sessionData.rmCache; - var rmTimer; // Retrieve a random quote from a given category, interpolating any quote // references (~~QUOTE CATEGORY~~) within it var interpolatedQuote = function(event, key, quoteTree) { - if(quoteTree !== undefined && quoteTree.indexOf(key) != -1) { + if(!_.isUndefined(quoteTree) && quoteTree.indexOf(key) != -1) { return ''; - } else if(quoteTree === undefined) { + } else if(_.isUndefined(quoteTree)) { quoteTree = []; } - var quoteString = quotes[key].random(); + var index = _.random(0, quotes[key].length - 1); + var quoteString = quotes[key][index]; // Parse quote interpolations var quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/g); @@ -25,10 +27,10 @@ var quotes = function(dbot) { while(quoteRefs && (thisRef = quoteRefs.shift()) !== undefined) { var cleanRef = dbot.cleanNick(thisRef.replace(/^~~/,'').replace(/~~$/,'').trim()); if(cleanRef === '-nicks-') { - var randomNick = Object.keys(event.channel.nicks).random(); + var randomNick = _.keys(event.channel.nicks)[_.random(0, _.size(event.channel.nicks) -1)]; quoteString = quoteString.replace("~~" + cleanRef + "~~", randomNick); quoteTree.pop(); - } else if(quotes.hasOwnProperty(cleanRef)) { + } else if(_.has(quotes, cleanRef)) { quoteTree.push(key); quoteString = quoteString.replace("~~" + cleanRef + "~~", interpolatedQuote(event, cleanRef, quoteTree.slice())); @@ -45,17 +47,20 @@ var quotes = function(dbot) { rmAllowed = true; }); - rmCache.push({'key': key, 'quote': quote}); + rmCache.push({ + 'key': key, + 'quote': quote + }); dbot.timers.clearTimeout(rmTimer); + if(rmCache.length < dbot.config.quotes.rmLimit) { rmTimer = dbot.timers.addOnceTimer(600000, function() { rmCache.length = 0; // lol what }); } else { - for(var i=0;i<dbot.config.admins.length;i++) { - dbot.say(event.server, dbot.config.admins[i], - dbot.t('rm_cache_limit')); - } + _.each(dbot.config.admins, function(admin) { + dbot.say(event.server, admin, dbot.t('rm_cache_limit')); + }); } }; @@ -68,9 +73,9 @@ var quotes = function(dbot) { } if(key.charAt(0) !== '_') { // lol - if(quotes.hasOwnProperty(key)) { + if(_.has(quotes, key)) { return interpolatedQuote(event, key); - } else if(quotes.hasOwnProperty(altKey)) { + } else if(_.has(quotes, altKey)) { return interpolatedQuote(event, altKey); } else { return false; @@ -106,7 +111,7 @@ var quotes = function(dbot) { '~rmdeny': function(event) { var rmCacheCount = rmCache.length; for(var i=0;i<rmCacheCount;i++) { - if(!quotes.hasOwnProperty(rmCache[i].key)) { + if(!_.has(quotes, rmCache[i].key)) { quotes[rmCache[i].key] = []; } quotes[rmCache[i].key].push(rmCache[i].quote); @@ -131,12 +136,16 @@ var quotes = function(dbot) { // Shows a list of the biggest categories '~qstats': function(event) { - var qSizes = Object.prototype.sort(quotes, function(key, obj) { return obj[key].length }); - qSizes = qSizes.slice(qSizes.length - 10).reverse(); + var qSizes = _.chain(quotes) + .pairs() + .sortBy(function(category) { return category[1].length }) + .reverse() + .first(10) + .value(); var qString = dbot.t('large_categories'); for(var i=0;i<qSizes.length;i++) { - qString += qSizes[i][0] + " (" + qSizes[i][1] + "), "; + qString += qSizes[i][0] + " (" + qSizes[i][1].length + "), "; } event.reply(qString.slice(0, -2)); @@ -146,19 +155,20 @@ var quotes = function(dbot) { '~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(_.has(quotes, haystack)) { + var matches = _.filter(quotes[haystack], function(quote) { + return _.indexOf(quote, needle) != -1; + }, 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})); + event.reply(dbot.t('search_results', { + 'category': haystack, + 'needle': needle, + 'quote': matches.random(), + 'matches': matches.length + })); } } else { event.reply(dbot.t('empty_category')); @@ -166,16 +176,19 @@ var quotes = function(dbot) { }, '~rmlast': function(event) { - if(rmAllowed == true || dbot.config.admins.include(event.user)) { + if(rmAllowed == true || _.include(dbot.config.admins, event.user)) { var key = event.input[1].trim().toLowerCase(); - if(quotes.hasOwnProperty(key)) { + if(_.has(quotes, key)) { var quote = quotes[key].pop(); if(quotes[key].length === 0) { delete quotes[key]; } resetRemoveTimer(event, key, quote); - event.reply(dbot.t('removed_from', {'quote': quote, 'category': key})); + event.reply(dbot.t('removed_from', { + 'quote': quote, + 'category': key + })); } else { event.reply(dbot.t('no_quotes', {'category': q[1]})); } @@ -185,11 +198,11 @@ var quotes = function(dbot) { }, '~rm': function(event) { - if(rmAllowed == true || dbot.config.admins.include(event.user)) { + if(rmAllowed == true || _.include(dbot.config.admins, event.user)) { var key = event.input[1].trim().toLowerCase(); var quote = event.input[2]; - if(quotes.hasOwnProperty(key)) { + if(_.has(quotes, key)) { var category = quotes[key]; var index = category.indexOf(quote); if(index !== -1) { @@ -215,51 +228,59 @@ var quotes = function(dbot) { 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)) { - event.reply(dbot.t('quote_count', {'category': key, 'count': quotes[key].length})); + if(_.has(quotes, key)) { + event.reply(dbot.t('quote_count', { + 'category': key, + 'count': quotes[key].length + })); } else { - event.reply(dbot.t('no_quotes', {'category': key})); + event.reply(dbot.t('no_quotes', { 'category': key })); } } else { // Give total quote count - var totalQuoteCount = 0; - for(var category in quotes) { - if(quotes.hasOwnProperty(category)) { - totalQuoteCount += quotes[category].length; - } - } - event.reply(dbot.t('total_quotes', {'count': totalQuoteCount})); + var totalQuoteCount = _.reduce(quotes, function(memo, category) { + return memo + category.length; + }, 0); + event.reply(dbot.t('total_quotes', { 'count': totalQuoteCount })); } }, '~qadd': function(event) { var key = event.input[1].toLowerCase(); var text = event.input[2]; - if(!Object.isArray(quotes[key])) { + if(!_.isArray(quotes[key])) { quotes[key] = []; } - if(quotes[key].include(text)) { + if(_.include(quotes[key], text)) { event.reply(dbot.t('quote_exists')); } else { quotes[key].push(text); rmAllowed = true; - event.reply(dbot.t('quote_saved', {'category': key, 'count': quotes[key].length})); + event.reply(dbot.t('quote_saved', { + 'category': key, + 'count': quotes[key].length + })); } }, '~rq': function(event) { - var rQuote = Object.keys(quotes).random(); - event.reply(rQuote + ': ' + interpolatedQuote(event, rQuote)); + var category = _.keys(quotes)[_.random(0, _.size(quotes) -1)]; + event.reply(category + ': ' + interpolatedQuote(event, category)); }, '~link': function(event) { var key = event.params[1].trim().toLowerCase(); - if(quotes.hasOwnProperty(key)) { - event.reply(dbot.t('quote_link', {'category': key, - 'url': dbot.t('url', {'host': dbot.config.web.webHost, - 'port': dbot.config.web.webPort, 'path': 'quotes/' + key})})); + if(_.has(quotes, key)) { + event.reply(dbot.t('quote_link', { + 'category': key, + 'url': dbot.t('url', { + 'host': dbot.config.web.webHost, + 'port': dbot.config.web.webPort, + 'path': 'quotes/' + key + }) + })); } else { - event.reply(dbot.t('category_not_found', {'category': key})); + event.reply(dbot.t('category_not_found', { 'category': key })); } }, }; @@ -278,7 +299,7 @@ var quotes = function(dbot) { // Lists quotes in a category '/quotes/:key': function(req, res) { var key = req.params.key.toLowerCase(); - if(dbot.db.quoteArrs.hasOwnProperty(key)) { + if(_.has(dbot.db.quoteArrs, key)) { res.render('quotes', { 'name': dbot.config.name, 'quotes': dbot.db.quoteArrs[key], locals: { 'url_regex': RegExp.prototype.url_regex() } }); } else { res.render('error', { 'name': dbot.config.name, 'message': 'No quotes under that key.' }); diff --git a/run.js b/run.js index def9a5a..f9418dd 100644 --- a/run.js +++ b/run.js @@ -55,18 +55,15 @@ var DBot = function(timers) { // Populate bot properties with config data // Create JSBot and connect to each server this.instance = jsbot.createJSBot(this.config.name); - for(var name in this.config.servers) { - if(_.has(this.config.servers, name)) { - var server = this.config.servers[name]; - this.instance.addConnection(name, server.server, server.port, - this.config.admin, function(event) { - var server = this.config.servers[event.server]; - for(var i=0;i<server.channels.length;i++) { - this.instance.join(event, server.channels[i]); - } - }.bind(this), server.nickserv, server.password); - } - } + _.each(this.config.servers, function(server, name) { + this.instance.addConnection(name, server.server, server.port, + this.config.admin, function(event) { + var server = this.config.servers[event.server]; + for(var i=0;i<server.channels.length;i++) { + this.instance.join(event, server.channels[i]); + } + }.bind(this), server.nickserv, server.password); + }, this); // Load the modules and connect to the server this.reloadModules(); From 3cc013635d67a857494c36d60feaa09938ad8600 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 21:54:02 +0000 Subject: [PATCH 127/347] Underscorisation of report module [#81] --- modules/report/report.js | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/modules/report/report.js b/modules/report/report.js index 77100a7..4a6b09c 100644 --- a/modules/report/report.js +++ b/modules/report/report.js @@ -1,3 +1,5 @@ +var _ = require('underscore')._; + var report = function(dbot) { var commands = { '~report': function(event) { @@ -5,29 +7,21 @@ var report = function(dbot) { var nick = event.input[2]; var reason = event.input[3]; - if(event.allChannels.hasOwnProperty(channelName)) { + if(_.has(event.allChannels, channelName)) { var channel = event.allChannels[channelName]; - if(channel.nicks.hasOwnProperty(nick)) { - var ops = []; - for(var possibOps in channel.nicks) { - if(channel.nicks[possibOps].op == true) { - ops.push(possibOps); - } - } + if(_.has(channel.nicks, nick)) { + var ops = _.filter(channel.nicks, function(user) { + return user.op; + }); - // Does the channel have an admin channel? - if(event.allChannels.hasOwnProperty('#' + channelName)) { - ops.push('#' + channelName); - } - - for(var i=0;i<ops.length;i++) { - dbot.say(event.server, ops[i], dbot.t('report', { + _.each(ops, function(user) { + dbot.say(event.server, user.name, dbot.t('report', { 'reporter': event.user, 'reported': nick, 'channel': channelName, 'reason': reason })); - } + }, this); event.reply(dbot.t('reported', { 'reported': nick })); } else { From ca8a8ca9c20e1858d192c07daf9a221d3e8adc44 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 22:19:48 +0000 Subject: [PATCH 128/347] underscorisation for dent and ignore [#81] --- modules/dent/dent.js | 1 - modules/ignore/ignore.js | 67 ++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/modules/dent/dent.js b/modules/dent/dent.js index 2361cfa..3d5844e 100644 --- a/modules/dent/dent.js +++ b/modules/dent/dent.js @@ -16,7 +16,6 @@ var dent = function(dbot) { }, function(error, response, body) { event.reply('Status posted (probably).'); - console.log(body); }); } }; diff --git a/modules/ignore/ignore.js b/modules/ignore/ignore.js index 14fdd5a..a3c99cd 100644 --- a/modules/ignore/ignore.js +++ b/modules/ignore/ignore.js @@ -4,54 +4,69 @@ * and commands from certain modules. It also populates the JSBot instance with * this information, since that actually performs the ignorance. */ +var _ = require('underscore')._; + var ignore = function(dbot) { var commands = { '~ignore': function(event) { - var ignorableModules = dbot.modules.filter(function(module) { - if(module.ignorable != null && module.ignorable == true) { - return true; - } - }); var module = event.params[1]; + var ignorableModules = _.chain(dbot.modules) + .filter(function(module) { + return module.ignorable !== null && module.ignorable === true; + }) + .pluck('name') + .value(); - if(module === undefined) { - event.reply(dbot.t('ignore_usage', {'user': event.user, 'modules': ignorableModules.join(', ')})); + if(_.isUndefined(module)) { + event.reply(dbot.t('ignore_usage', { + 'user': event.user, + 'modules': ignorableModules.join(', ') + })); } else { - if(ignorableModules.include(module)) { - if(dbot.db.ignores.hasOwnProperty(event.user) && dbot.db.ignores[event.user].include(module)) { - event.reply(dbot.t('already_ignoring', {'user': event.user})); + if(_.include(ignorableModules, module)) { + if(_.has(dbot.db.ignores, event.user) && _.include(dbot.db.ignores[event.user], module)) { + event.reply(dbot.t('already_ignoring', { 'user': event.user })); } else { - if(dbot.db.ignores.hasOwnProperty(module)) { + if(_.has(dbot.db.ignores, module)) { dbot.db.ignores[event.user].push(module); } else { dbot.db.ignores[event.user] = [module]; } dbot.instance.ignoreTag(event.user, module); - event.reply(dbot.t('ignored', {'user': event.user, 'module': module})); + event.reply(dbot.t('ignored', { + 'user': event.user, + 'module': module + })); } } else { - event.reply(dbot.t('invalid_ignore', {'user': event.user})); + event.reply(dbot.t('invalid_ignore', { 'user': event.user })); } } }, '~unignore': function(event) { var ignoredModules = []; - if(dbot.db.ignores.hasOwnProperty(event.user)) { + if(_.has(dbot.db.ignores, event.user)) { ignoredModules = dbot.db.ignores[event.user]; } var module = event.params[1]; - if(module === undefined) { - event.reply(dbot.t('unignore_usage', {'user': event.user, 'modules': ignoredModules.join(', ')})); + if(_.isUndefined(module)) { + event.reply(dbot.t('unignore_usage', { + 'user': event.user, + 'modules': ignoredModules.join(', ') + })); } else { - if(ignoredModules.include(module) == false) { - event.reply(dbot.t('invalid_unignore', {'user': event.user})); - } else { + if(_.include(ignoredModules, module)) { dbot.db.ignores[event.user].splice(dbot.db.ignores[event.user].indexOf(module), 1); dbot.instance.removeIgnore(event.user, module) - event.reply(dbot.t('unignored', {'user': event.user, 'module': module})); + event.reply(dbot.t('unignored', { + 'user': event.user, + 'module': module + })); + } else { + event.reply(dbot.t('invalid_unignore', { 'user': event.user })); } } } @@ -64,13 +79,11 @@ var ignore = function(dbot) { 'onLoad': function() { dbot.instance.clearIgnores(); - for(var user in dbot.db.ignores) { - if(dbot.db.ignores.hasOwnProperty(user)) { - for(var i=0;i<dbot.db.ignores[user].length;i++) { - dbot.instance.ignoreTag(user, dbot.db.ignores[user][i]); - } - } - } + _.each(dbot.db.ignores, function(ignores, user) { + _.each(ignores, function(ignore) { + dbot.instance.ignoreTag(user, ignore); + }, this); + }, this); } }; }; From f36e6c781b8e0e3401f5068aaab6be30161ca582 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 22:53:13 +0000 Subject: [PATCH 129/347] underscorisation of kick [#81] --- modules/kick/kick.js | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/modules/kick/kick.js b/modules/kick/kick.js index 150fb55..3480583 100644 --- a/modules/kick/kick.js +++ b/modules/kick/kick.js @@ -1,3 +1,5 @@ +var _ = require('underscore')._; + var kick = function(dbot) { var commands = { // Give the number of times a given user has been kicked and has kicked @@ -5,27 +7,35 @@ var kick = function(dbot) { '~kickcount': function(event) { var username = event.params[1]; - if(!dbot.db.kicks.hasOwnProperty(username)) { + if(!_.has(dbot.db.kicks, username)) { var kicks = '0'; } else { var kicks = dbot.db.kicks[username]; } - if(!dbot.db.kickers.hasOwnProperty(username)) { + if(!_.has(dbot.db.kickers, username)) { var kicked = '0'; } else { var kicked = dbot.db.kickers[username]; } - event.reply(dbot.t('user_kicks', {'user': username, '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(event) { var orderedKickLeague = function(list, topWhat) { - var kickArr = Object.prototype.sort(list, function(key, obj) { return obj[key]; }); - kickArr = kickArr.slice(kickArr.length - 10).reverse(); + var kickArr = _.chain(list) + .pairs() + .sortBy(function(kick) { return kick[1] }) + .reverse() + .first(10) + .value(); var kickString = "Top " + topWhat + ": "; for(var i=0;i<kickArr.length;i++) { @@ -48,23 +58,26 @@ var kick = function(dbot) { 'listener': function(event) { if(event.kickee == dbot.config.name) { dbot.instance.join(event, event.channel); - event.reply(dbot.t('kicked_dbot', {'botname': dbot.config.name})); + event.reply(dbot.t('kicked_dbot', { 'botname': dbot.config.name })); dbot.db.kicks[dbot.config.name] += 1; } else { - if(!dbot.db.kicks.hasOwnProperty(event.kickee)) { + if(!_.has(dbot.db.kicks, event.kickee)) { dbot.db.kicks[event.kickee] = 1; } else { dbot.db.kicks[event.kickee] += 1; } - if(!dbot.db.kickers.hasOwnProperty(event.user)) { + if(!_.has(dbot.db.kickers, event.user)) { dbot.db.kickers[event.user] = 1; } else { dbot.db.kickers[event.user] += 1; } - event.reply(event.kickee + '-- (' + dbot.t('user_kicks', - {'user': event.kickee, 'kicks': dbot.db.kicks[event.kickee], 'kicked': dbot.db.kickers[event.kickee]}) + ')'); + event.reply(event.kickee + '-- (' + dbot.t('user_kicks', { + 'user': event.kickee, + 'kicks': dbot.db.kicks[event.kickee], + 'kicked': dbot.db.kickers[event.kickee] + }) + ')'); } }, on: 'KICK' From 6b8b617e71af4c07a9084d28136d000181ebbc58 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 12 Jan 2013 23:31:53 +0000 Subject: [PATCH 130/347] Underscorise poll. Unfortunately some stuff went missing in the switch-over. Whoops. Oh I also fixed it. [#81] --- modules/poll/config.json | 3 +- modules/poll/poll.js | 287 ++++++++++++++++++--------------------- 2 files changed, 132 insertions(+), 158 deletions(-) diff --git a/modules/poll/config.json b/modules/poll/config.json index d3d8ca6..10db064 100644 --- a/modules/poll/config.json +++ b/modules/poll/config.json @@ -1,3 +1,4 @@ { - "help": "http://github.com/reality/depressionbot/blob/master/modules/poll/README.md" + "help": "http://github.com/reality/depressionbot/blob/master/modules/poll/README.md", + "dbKeys": [ "polls" ] } diff --git a/modules/poll/poll.js b/modules/poll/poll.js index 988664f..0ab8cda 100644 --- a/modules/poll/poll.js +++ b/modules/poll/poll.js @@ -1,68 +1,63 @@ +var _ = require('underscore')._; + var poll = function(dbot) { var polls = dbot.db.polls; var commands = { '~newpoll': function(event) { - var av = event.input[1] != undefined; - var name = event.input[2]; - var options = event.input[3].split(','); - var description = event.input[4]; + var name = event.input[1], + options = event.input[2].split(','), + description = event.input[3]; - if(name === undefined || name === 'help') { - event.reply(dbot.t('newpoll_usage')); + if(_.has(polls, name)) { + event.reply(dbot.t('poll_exists', { 'name': name })); } else { - if(polls.hasOwnProperty(name)) { - event.reply(dbot.t('poll_exists', {'name': name})); - } else { - if(av) { - polls[name] = { - 'av': av, - 'name': name, - 'description': description, - 'owner': event.user, - 'votes': {}, - 'options': [] - }; - for(var i=0;i<options.length;i++) { - polls[name].options.push(options[i]); - } - } else { - polls[name] = { - 'av': av, - 'name': name, - 'description': description, - 'owner': event.user, - 'votes': {}, - 'votees': {} - }; - for(var i=0;i<options.length;i++) { - polls[name]['votes'][options[i]] = 0; - } - } - - event.reply(dbot.t('poll_created', {'name': name, 'description': description, - 'url': dbot.t('url', {'host': dbot.config.web.webHost, - 'port': dbot.config.web.webPort, 'path': 'polls/' + name})})); + polls[name] = { + 'name': name, + 'description': description, + 'owner': event.user, + 'votes': {}, + 'votees': {} + }; + for(var i=0;i<options.length;i++) { + polls[name]['votes'][options[i]] = 0; } + event.reply(dbot.t('poll_created', { + 'name': name, + 'description': description, + 'url': dbot.t('url', { + 'host': dbot.config.web.webHost, + 'port': dbot.config.web.webPort, + 'path': 'polls/' + name + }) + })); } }, '~addoption': function(event) { - var name = event.input[1]; - var option = event.input[2]; + var name = event.input[1], + option = event.input[2]; - if(polls.hasOwnProperty(name)) { + if(_.has(polls, name)) { if(polls[name].owner === event.user) { - if(!polls[name].votes.hasOwnProperty(name)) { + if(!_.has(polls[name].votes, name)) { polls[name]['votes'][option] = 0; - event.reply(dbot.t('option_added', {'user': event.user, - 'name': name, 'option': option})); + event.reply(dbot.t('option_added', { + 'user': event.user, + 'name': name, + 'option': option + })); } else { - event.reply(dbot.t('option_exists', {'option': option, - 'name': name, 'user': event.user})); + event.reply(dbot.t('option_exists', { + 'option': option, + 'name': name, + 'user': event.user + })); } } else { - event.reply(dbot.t('not_poll_owner', {'user': event.user, - 'name': name})); + event.reply(dbot.t('not_poll_owner', { + 'user': event.user, + 'name': name + })); } } else { event.reply(dbot.t('poll_unexistent', {'name': name})); @@ -70,147 +65,114 @@ var poll = function(dbot) { }, '~rmoption': function(event) { - var name = event.input[1]; - var option = event.input[2]; + var name = event.input[1], + option = event.input[2]; - if(polls.hasOwnProperty(name)) { + if(_.has(polls, name)) { if(polls[name].owner === event.user) { - if(polls[name].votes.hasOwnProperty(option)) { + if(_.has(polls[name].votes, option)) { delete polls[name]['votes'][option]; - event.reply(dbot.t('option_removed', {'user': event.user, - 'name': name, 'option': option})); + event.reply(dbot.t('option_removed', { + 'user': event.user, + 'name': name, + 'option': option + })); } else { - event.reply(dbot.t('invalid_vote', {'vote': option})); + event.reply(dbot.t('invalid_vote', { 'vote': option })); } } else { - event.reply(dbot.t('not_poll_owner', {'name': name})); + event.reply(dbot.t('not_poll_owner', { 'name': name })); } } else { - event.reply(dbot.t('poll_unexistent', {'name': name})); + event.reply(dbot.t('poll_unexistent', { 'name': name })); } }, '~vote': function(event) { - var name = event.input[1]; - var vote = event.input[2]; + var name = event.input[1], + vote = event.input[2]; - if(polls.hasOwnProperty(name)) { - if(polls[name].av) { - var prefs = vote.split(','); - prefs = prefs.uniq(); - var valid = true; - - prefs.each(function(pref) { - valid = valid && polls[name].options.indexOf(pref) != -1; - }); - if(valid){ - if(polls[name].votes.hasOwnProperty(event.user)) { - polls[name].votes[event.user] = prefs; - event.reply(dbot.t('av_changed_vote', {'vote': prefs.join(','), 'poll': name, 'user': event.user})); - } else { - polls[name].votes[event.user] = prefs; - event.reply(dbot.t('av_voted', {'vote': prefs.join(','), 'poll': name, 'user': event.user})); - } - } else { - event.reply(dbot.t('invalid_vote', {'vote': vote})); - } - } else { - if(polls[name].votes.hasOwnProperty(vote)) { - if(polls[name].votees.hasOwnProperty(event.user)) { + if(_.has(polls, name)) { + if(_.has(polls[name].votes, vote)) { + if(_.has(polls[name].votees, event.user)) { var oldVote = polls[name].votees[event.user]; polls[name].votes[oldVote]--; 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], 'user': event.user})); + + event.reply(dbot.t('changed_vote', { + 'vote': vote, + 'poll': name, + '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], 'user': event.user})); + event.reply(dbot.t('voted', { + 'vote': vote, + 'poll': name, + 'count': polls[name].votes[vote], + 'user': event.user + })); } } else { - event.reply(dbot.t('invalid_vote', {'vote': vote})); + event.reply(dbot.t('invalid_vote', { 'vote': vote })); } - } } else { - event.reply(dbot.t('poll_unexistent', {'name': name})); + event.reply(dbot.t('poll_unexistent', { 'name': name })); } }, '~pdesc': function(event) { var name = event.input[1]; - if(polls.hasOwnProperty(name)) { - event.reply(dbot.t('poll_describe', {'name': name, 'description': polls[name].description, - 'url': dbot.t('url', {'host': dbot.config.web.webHost, 'port': - dbot.config.web.webPort, 'path': 'polls/' + name})})); + + if(_.has(polls, name)) { + event.reply(dbot.t('poll_describe', { + 'name': name, + 'description': polls[name].description, + 'url': dbot.t('url', { + 'host': dbot.config.web.webHost, + 'port': dbot.config.web.webPort, + 'path': 'polls/' + name + }) + })); } else { - event.reply(dbot.t('poll_unexistent', {'name': name})); + event.reply(dbot.t('poll_unexistent', { 'name': name })); } }, '~count': function(event) { var name = event.input[1]; - if(polls.hasOwnProperty(name)) { + if(_.has(polls, name)) { var order; - if(polls[name].av) { - var finished = false; - var rounds = []; - var eliminated = []; - var voted; - - for(var roundn = 0; roundn < polls[name].options.length; roundn++) { - var roundLoser; - - // Populate candidates for this round - rounds[roundn] = {}; - polls[name].options.each(function (option) { - if(eliminated.indexOf(option) == -1) - rounds[roundn][option] = 0; - }); - - // Count votes - polls[name].votes.withAll(function (name, vote) { - voted = false; - vote.each(function (pref) { - if(!voted && rounds[roundn].hasOwnProperty(pref)) { - rounds[roundn][pref]++; - voted = true; - } - }); - }); - - // Find the loser - var min = polls[name].votes.length() + 1; - rounds[roundn].withAll(function (option, count) { - if(count < min) { - roundLoser = option; - min = count; - } - }); - - // Eliminate loser - eliminated.push(roundLoser); - } - order = eliminated.reverse().join(', ') - } else { - var votesArr = []; - polls[name].votes.withAll(function(option, count) { - votesArr.push([option, count]); - }); + var votesArr = []; - votesArr = votesArr.sort(function(a, b) { return b[1] - a[1]; }); - - order = votesArr.map(function(vote) { return vote[0]; }); + var order = _.chain(polls[name].votes) + .pairs() + .sortBy(function(option) { return option[1] }) + .reverse() + .value(); + + var orderString = ""; + for(var i=0;i<order.length;i++) { + orderString += order[i][0] + + " (" + order[i][1] + "), "; } - event.reply(dbot.t('count', {'poll': name, 'description': polls[name].description, 'places': order})); + orderString = orderString.slice(0, -2); + + event.reply(dbot.t('count', { + 'poll': name, + 'description': polls[name].description, + 'places': orderString + })); } else { event.reply(dbot.t('poll_unexistent', {'name': name})); } } }; - commands['~newpoll'].regex = [/~newpoll (av )?([^ ]+) options=([^ ]+) (.+)/, 5]; + commands['~newpoll'].regex = [/~newpoll ([^ ]+) options=([^ ]+) (.+)/, 4]; commands['~addoption'].regex = [/~addoption ([^ ]+) ([^ ]+)/, 3]; commands['~rmoption'].regex = [/~rmoption ([^ ]+) ([^ ]+)/, 3]; commands['~vote'].regex = [/~vote ([^ ]+) ([^ ]+)/, 3]; @@ -221,24 +183,35 @@ var poll = function(dbot) { // Shows the results of a poll '/polls/:key': function(req, res) { var key = req.params.key.toLowerCase(); - if(dbot.db.polls.hasOwnProperty(key) && dbot.db.polls[key].hasOwnProperty('description')) { - // 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.config.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() } }); + if(_.has(dbot.db.polls, key)) { + var totalVotes = _.reduce(dbot.db.polls[key].votes, + function(memo, option) { + return memo += option; + }, 0); + res.render('polls', { + 'name': dbot.config.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.config.name, 'message': 'No polls under that key.' }); + res.render('error', { + 'name': dbot.config.name, + 'message': 'No polls under that key.' + }); } }, // Lists all of the polls '/polls': function(req, res) { - res.render('polllist', { 'name': dbot.config.name, 'polllist': Object.keys(dbot.db.polls) }); + res.render('polllist', { + 'name': dbot.config.name, + 'polllist': Object.keys(dbot.db.polls) + }); }, }; From e2cb5ea77dfd6bc8e10d93220e258429b20497ab Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 13 Jan 2013 15:26:44 +0000 Subject: [PATCH 131/347] Underscorise users module (was not pleasant) [#81] --- modules/admin/admin.js | 6 +-- modules/users/users.js | 104 +++++++++++++++++++++-------------------- 2 files changed, 54 insertions(+), 56 deletions(-) diff --git a/modules/admin/admin.js b/modules/admin/admin.js index bb362ac..d2cc575 100644 --- a/modules/admin/admin.js +++ b/modules/admin/admin.js @@ -121,11 +121,7 @@ var admin = function(dbot) { var moduleDir = '../' + moduleName + '/'; var cacheKey = require.resolve(moduleDir + moduleName); delete require.cache[cacheKey]; - - dbot.config.moduleNames = _.reject(moduleNames, function(module) { - return module == moduleName; - }, this); - + dbot.config.moduleNames = _.without(dbot.config.moduleNames, moduleName); dbot.reloadModules(); event.reply(dbot.t('unload_module', {'moduleName': moduleName})); diff --git a/modules/users/users.js b/modules/users/users.js index b96f9c8..3f82695 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -2,15 +2,16 @@ * Name: Users * Description: Track known users */ -var web = require('./web'); +var web = require('./web'), + _ = require('underscore')._; var users = function(dbot) { var knownUsers = dbot.db.knownUsers; var getServerUsers = function(server) { - if(!knownUsers.hasOwnProperty(server)) { + if(!_.has(knownUsers, server)) { knownUsers[server] = { 'users': [], 'aliases': {}, 'channelUsers': {} }; } - if(!knownUsers[server].hasOwnProperty('channelUsers')) { + if(!_.has(knownUsers[server], 'channelUsers')) { knownUsers[server].channelUsers = {}; } return knownUsers[server]; @@ -18,43 +19,39 @@ var users = function(dbot) { var updateAliases = function(event, oldUser, newUser) { var knownUsers = getServerUsers(event.server); - for(var alias in knownUsers.aliases) { - if(knownUsers.aliases.hasOwnProperty(alias)) { - if(knownUsers.aliases[alias] === oldUser) { - knownUsers.aliases[alias] = newUser; - } + _.each(knownUsers.aliases, function(user, alias) { + if(user == oldUser) { + knownUsers.aliases[alias] = newUser; } - } - } + }, this); + }; var updateChannels = function(event, oldUser, newUser) { var channelUsers = getServerUsers(event.server).channelUsers; - channelUsers.each(function(channel) { - if(channel.include(oldUser)) { - channel.splice(channel.indexOf(oldUser), 1); - channel.push(newUser); - } - }.bind(this)); - } + channelUsers = _.each(channelUsers, function(channel, channelName) { + channelUsers[channelName] = _.without(channel, oldUser); + channelUsers[channelName].push(newUser); + }, this); + }; dbot.instance.addListener('366', 'users', function(event) { var knownUsers = getServerUsers(event.server); - if(!knownUsers.channelUsers.hasOwnProperty(event.channel.name)) { + if(!_.has(knownUsers.channelUsers, event.channel.name)) { knownUsers.channelUsers[event.channel.name] = []; } var channelUsers = knownUsers.channelUsers[event.channel.name]; - event.channel.nicks.each(function(nick) { + _.each(event.channel.nicks, function(nick) { nick = nick.name; if(api.isKnownUser(event.server, nick)) { nick = api.resolveUser(event.server, nick); } else { knownUsers.users.push(nick); } - if(!channelUsers.include(nick)) { + if(!_.include(channelUsers, nick)) { channelUsers.push(nick); } - }.bind(this)); + }, this); }); @@ -62,7 +59,7 @@ var users = function(dbot) { 'resolveUser': function(server, nick, useLowercase) { var knownUsers = getServerUsers(server); var user = nick; - if(!knownUsers.users.include(nick) && knownUsers.aliases.hasOwnProperty(nick)) { + if(!_.include(knownUsers.users, nick) && _.has(knownUsers.aliases, nick)) { user = knownUsers.aliases[nick]; } @@ -72,23 +69,29 @@ var users = function(dbot) { 'isKnownUser': function(server, nick) { var knownUsers = getServerUsers(server); - return (knownUsers.users.include(nick) || knownUsers.aliases.hasOwnProperty(nick)); + return (_.include(knownUsers.users, nick) || _.has(knownUsers.aliases, nick)); } }; var commands = { '~alias': function(event) { - var knownUsers = getServerUsers(event.server); - var alias = event.params[1].trim(); - if(knownUsers.users.include(alias)) { - var aliasCount = 0; - knownUsers.aliases.each(function(primaryUser) { - if(primaryUser == alias) aliasCount += 1; - }.bind(this)); - event.reply(dbot.t('primary', { 'user': alias, 'count': aliasCount })); - } else if(knownUsers.aliases.hasOwnProperty(alias)) { - event.reply(dbot.t('alias', { 'alias': alias, - 'user': knownUsers.aliases[alias] })); + var knownUsers = getServerUsers(event.server), + alias = event.params[1].trim(); + + if(_.include(knownUsers.users, alias)) { + var aliasCount = _.reduce(knownUsers.aliases, function(memo, user) { + if(user == alias) return memo += 1; + }, 0, this); + + event.reply(dbot.t('primary', { + 'user': alias, + 'count': aliasCount + })); + } else if(_.has(knownUsers.aliases, alias)) { + event.reply(dbot.t('alias', { + 'alias': alias, + 'user': knownUsers.aliases[alias] + })); } else { event.reply(dbot.t('unknown_alias', { 'alias': alias })); } @@ -98,12 +101,11 @@ var users = function(dbot) { var knownUsers = getServerUsers(event.server); var newParent = event.params[1]; - if(knownUsers.aliases.hasOwnProperty(newParent)) { + if(_.has(knownUsers.aliases, newParent)) { var newAlias = knownUsers.aliases[newParent]; - // Replace users entry with new primary user - var usersIndex = knownUsers.users.indexOf(newAlias); - knownUsers.users.splice(usersIndex, 1); + // Replace user entry + knownUsers.users = _.without(knownUsers.users, newAlias); knownUsers.users.push(newParent); // Replace channels entries with new primary user @@ -116,12 +118,14 @@ var users = function(dbot) { // Update aliases to point to new primary user updateAliases(event, newAlias, newParent); - event.reply(dbot.t('aliasparentset', { 'newParent': newParent, - 'newAlias': newAlias })); + event.reply(dbot.t('aliasparentset', { + 'newParent': newParent, + 'newAlias': newAlias + })); dbot.api.stats.fixStats(event.server, newAlias); } else { - event.reply(dbot.t('unknown_alias', { 'alias': newParent})); + event.reply(dbot.t('unknown_alias', { 'alias': newParent })); } }, @@ -130,7 +134,7 @@ var users = function(dbot) { var primaryUser = event.params[1]; var secondaryUser = event.params[2]; - if(knownUsers.users.include(primaryUser) && knownUsers.users.include(secondaryUser)) { + if(_.include(knownUsers.users, primaryUser) && _.include(knownUsers.users, secondaryUser)) { knownUsers.users.splice(knownUsers.users.indexOf(secondaryUser), 1); knownUsers.aliases[secondaryUser] = primaryUser; updateAliases(event, secondaryUser, primaryUser); @@ -163,7 +167,7 @@ var users = function(dbot) { var nick = event.user; if(event.action == 'JOIN') { - if(!knownUsers.channelUsers.hasOwnProperty(event.channel.name)) { + if(!_.has(knownUsers.channelUsers, event.channel.name)) { knownUsers.channelUsers[event.channel.name] = []; } var channelUsers = knownUsers.channelUsers[event.channel.name]; @@ -173,15 +177,15 @@ var users = function(dbot) { } else { knownUsers.users.push(nick); } - if(!channelUsers.include(nick)) { + if(!_.include(channelUsers, nick)) { channelUsers.push(nick); } } else if(event.action == 'NICK') { var newNick = event.params.substr(1); - if(knownUsers.aliases.hasOwnProperty(event.user)) { + if(_.has(knownUsers.aliases, event.user)) { knownUsers.aliases[newNick] = knownUsers.aliases[event.user]; } else { - if(!knownUsers.users.include(newNick)) { + if(!_.include(knownUsers.users, newNick)) { knownUsers.aliases[newNick] = event.user; } } @@ -192,11 +196,9 @@ var users = function(dbot) { 'onLoad': function() { // Trigger updateNickLists to stat current users in channel var connections = dbot.instance.connections; - for(var conn in connections) { - if(connections.hasOwnProperty(conn)) { - connections[conn].updateNickLists(); - } - } + _.each(connections, function(connection) { + connection.updateNickLists(); + }); } }; }; From f6d69fe137af74a2d187daf4c77aa49564248fb7 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 13 Jan 2013 15:27:45 +0000 Subject: [PATCH 132/347] without instead o splice --- modules/users/users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/users.js b/modules/users/users.js index 3f82695..9ea6fdd 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -135,7 +135,7 @@ var users = function(dbot) { var secondaryUser = event.params[2]; if(_.include(knownUsers.users, primaryUser) && _.include(knownUsers.users, secondaryUser)) { - knownUsers.users.splice(knownUsers.users.indexOf(secondaryUser), 1); + knownUsers.users = _.without(knownUsers.users, secondaryUser); knownUsers.aliases[secondaryUser] = primaryUser; updateAliases(event, secondaryUser, primaryUser); updateChannels(event, secondaryUser, primaryUser); From 35e34874af3ac808356dfc04ee99270404cbd662 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 13 Jan 2013 15:30:53 +0000 Subject: [PATCH 133/347] link underscorised (easy) [#81] --- modules/link/link.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/link/link.js b/modules/link/link.js index 7b6d3b2..0c275eb 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -3,7 +3,9 @@ * Description: Stores recent channel links, with commands to retrieve * information about links. */ -var request = require('request'); +var request = require('request'), + _ = require('underscore')._; + var link = function(dbot) { var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; var links = {}; @@ -22,7 +24,7 @@ var link = function(dbot) { var commands = { '~title': function(event) { var link = links[event.channel.name]; - if(event.params[1] !== undefined) { + if(_.isUndefined(event.params[1])) { var urlMatches = event.params[1].match(urlRegex); if(urlMatches !== null) { link = urlMatches[0]; From cd5649a1e8b20ffea751989d0b0d99d7655f60a8 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 13 Jan 2013 15:45:07 +0000 Subject: [PATCH 134/347] underscorise spelling [#81] --- modules/spelling/spelling.js | 87 +++++++++++++++++++++++++++++++++--- snippets.js | 73 ------------------------------ 2 files changed, 81 insertions(+), 79 deletions(-) diff --git a/modules/spelling/spelling.js b/modules/spelling/spelling.js index 49b0403..5c955ef 100644 --- a/modules/spelling/spelling.js +++ b/modules/spelling/spelling.js @@ -1,8 +1,83 @@ +var _ = require('underscore')._; + +var allGroupings = function(arr) { + if (arr.length == 0) { + return []; /* short-circuit the empty-array case */ + } + var groupings = []; + for(var n=1;n<=arr.length;n++) { + for(var i=0;i<(arr.length-(n-1));i++) { + groupings.push(arr.slice(i, i+n)); + } + } + return groupings; +} +var distance = function(s1, s2) { + // Calculate Levenshtein distance between two strings + // + // version: 1109.2015 + // discuss at: http://phpjs.org/functions/levenshtein + // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com) + // + bugfixed by: Onno Marsman + // + revised by: Andrea Giammarchi (http://webreflection.blogspot.com) + // + reimplemented by: Brett Zamir (http://brett-zamir.me) + // + reimplemented by: Alexander M Beedie + if (s1 == s2) { + return 0; + } + var s1_len = s1.length; + var s2_len = s2.length; + if (s1_len === 0) { + return s2_len; } + if (s2_len === 0) { + return s1_len; + } + // BEGIN STATIC + var split = false; + try { + split = !('0')[0]; + } catch (e) { + split = true; // Earlier IE may not support access by string index + } + // END STATIC + if (split) { + s1 = s1.split(''); s2 = s2.split(''); + } + + var v0 = new Array(s1_len + 1); + var v1 = new Array(s1_len + 1); + var s1_idx = 0, + s2_idx = 0, + cost = 0; + for (s1_idx = 0; s1_idx < s1_len + 1; s1_idx++) { v0[s1_idx] = s1_idx; + } + var char_s1 = '', + char_s2 = ''; + for (s2_idx = 1; s2_idx <= s2_len; s2_idx++) { v1[0] = s2_idx; + char_s2 = s2[s2_idx - 1]; + + for (s1_idx = 0; s1_idx < s1_len; s1_idx++) { + char_s1 = s1[s1_idx]; cost = (char_s1 == char_s2) ? 0 : 1; + var m_min = v0[s1_idx + 1] + 1; + var b = v1[s1_idx] + 1; + var c = v0[s1_idx] + cost; + if (b < m_min) { m_min = b; + } + if (c < m_min) { + m_min = c; + } v1[s1_idx + 1] = m_min; + } + var v_tmp = v0; + v0 = v1; + v1 = v_tmp; } + return v0[s1_len]; +}; + var spelling = function(dbot) { var last = {}; - var correct = function (event, correction, candidate, output_callback) { - var rawCandidates = last[event.channel.name][candidate].split(' ').allGroupings(); + var rawCandidates = allGroupings(last[event.channel.name][candidate].split(' ')); + var candidates = []; for(var i=0;i<rawCandidates.length;i++) { candidates.push(rawCandidates[i].join(' ')); @@ -11,10 +86,10 @@ var spelling = function(dbot) { var winnerDistance = Infinity; for(var i=0;i<candidates.length;i++) { - var distance = String.prototype.distance(correction.toLowerCase(), candidates[i].toLowerCase()); - if((distance < winnerDistance) && (distance > 0)) { + var d = distance(correction.toLowerCase(), candidates[i].toLowerCase()); + if((d < winnerDistance) && (d > 0)) { winner = candidates[i]; - winnerDistance = distance; + winnerDistance = d; } } @@ -51,7 +126,7 @@ var spelling = function(dbot) { event.reply(dbot.t('spelling_other', e)); }); } else { - if(last.hasOwnProperty(event.channel.name)) { + if(_.has(last, event.channel.name)) { last[event.channel.name][event.user] = event.message; } else { last[event.channel.name] = { }; diff --git a/snippets.js b/snippets.js index 6f703cd..f8fcfe4 100644 --- a/snippets.js +++ b/snippets.js @@ -35,19 +35,6 @@ Array.prototype.sum = function() { return sum; }; -Array.prototype.allGroupings = function() { - if (this.length == 0) { - return []; /* short-circuit the empty-array case */ - } - var groupings = []; - for(var n=1;n<=this.length;n++) { - for(var i=0;i<(this.length-(n-1));i++) { - groupings.push(this.slice(i, i+n)); - } - } - return groupings; -} - Array.prototype.uniq = function() { var hash = {} var result = []; @@ -79,66 +66,6 @@ String.prototype.startsWith = function(needle) { return needle === this.slice(0, needle.length); }; -String.prototype.distance = function(s1, s2) { - // Calculate Levenshtein distance between two strings - // - // version: 1109.2015 - // discuss at: http://phpjs.org/functions/levenshtein // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com) - // + bugfixed by: Onno Marsman - // + revised by: Andrea Giammarchi (http://webreflection.blogspot.com) - // + reimplemented by: Brett Zamir (http://brett-zamir.me) - // + reimplemented by: Alexander M Beedie // * example 1: levenshtein('Kevin van Zonneveld', 'Kevin van Sommeveld'); - // * returns 1: 3 - if (s1 == s2) { - return 0; - } - var s1_len = s1.length; - var s2_len = s2.length; - if (s1_len === 0) { - return s2_len; } - if (s2_len === 0) { - return s1_len; - } - // BEGIN STATIC - var split = false; - try { - split = !('0')[0]; - } catch (e) { split = true; // Earlier IE may not support access by string index - } - // END STATIC - if (split) { - s1 = s1.split(''); s2 = s2.split(''); - } - - var v0 = new Array(s1_len + 1); - var v1 = new Array(s1_len + 1); - var s1_idx = 0, - s2_idx = 0, - cost = 0; - for (s1_idx = 0; s1_idx < s1_len + 1; s1_idx++) { v0[s1_idx] = s1_idx; - } - var char_s1 = '', - char_s2 = ''; - for (s2_idx = 1; s2_idx <= s2_len; s2_idx++) { v1[0] = s2_idx; - char_s2 = s2[s2_idx - 1]; - - for (s1_idx = 0; s1_idx < s1_len; s1_idx++) { - char_s1 = s1[s1_idx]; cost = (char_s1 == char_s2) ? 0 : 1; - var m_min = v0[s1_idx + 1] + 1; - var b = v1[s1_idx] + 1; - var c = v0[s1_idx] + cost; - if (b < m_min) { m_min = b; - } - if (c < m_min) { - m_min = c; - } v1[s1_idx + 1] = m_min; - } - var v_tmp = v0; - v0 = v1; - v1 = v_tmp; } - return v0[s1_len]; -} - String.prototype.format = function() { // format takes either multiple indexed arguments, or a single object, whose keys/values will be used var targetStr = this; var replacements = [].splice.call(arguments, 0); From b512cc7ee98078ad570a5e9bb51010e16a37be0c Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 13 Jan 2013 15:51:54 +0000 Subject: [PATCH 135/347] web underscorised [#81] --- modules/web/web.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/web/web.js b/modules/web/web.js index 234bfa3..b3e632b 100644 --- a/modules/web/web.js +++ b/modules/web/web.js @@ -1,4 +1,5 @@ var express = require('express'), + _ = require('underscore')._, fs = require('fs'); var webInterface = function(dbot) { @@ -16,7 +17,7 @@ var webInterface = function(dbot) { var reloadPages = function(pages) { for(var p in pages) { - if( pages.hasOwnProperty(p) ) { + if(_.has(pages, p)) { var func = pages[p]; var mod = func.module; app.get(p, (function(req, resp) { From 60fb7970ef9fce0a408d97478bf9912ec616a57f Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Sun, 13 Jan 2013 17:48:20 +0100 Subject: [PATCH 136/347] include underscore in dependencies --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 352d654..3b3264a 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,8 @@ Requirements: - Node JS - [JSBot](http://github.com/reality/JSBot "JSBot"), a Javascript library which - handles the IRC protocol. + handles the IRC protocol +- Underscore JS library - Various modules have their own requirements also. ### External Modules From a14fddc49d086baf3b67bd2634d6112f3acdc1d9 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 13 Jan 2013 17:01:50 +0000 Subject: [PATCH 137/347] isPrimaryUser and getAliases in users module --- modules/users/users.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/modules/users/users.js b/modules/users/users.js index 9ea6fdd..58035a0 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -70,6 +70,20 @@ var users = function(dbot) { 'isKnownUser': function(server, nick) { var knownUsers = getServerUsers(server); return (_.include(knownUsers.users, nick) || _.has(knownUsers.aliases, nick)); + }, + + 'isPrimaryUser': function(server, nick) { + return _.include(knownUsers.users, nick); + } + + 'getAliases': function(server, nick) { + var knownUsers = getServerUsers(server); + return _.chain(knownUsers.aliases) + .keys() + .filter(function(user) { + return knownUsers.aliases[user] == nick; + }, this) + .value(); } }; From f8ed6b04fc5ee0e7f2f0d542e75ce51c437100a3 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 13 Jan 2013 17:04:54 +0000 Subject: [PATCH 138/347] fix syntax error --- modules/users/users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/users.js b/modules/users/users.js index 58035a0..2cd8f07 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -74,7 +74,7 @@ var users = function(dbot) { 'isPrimaryUser': function(server, nick) { return _.include(knownUsers.users, nick); - } + }, 'getAliases': function(server, nick) { var knownUsers = getServerUsers(server); From dff5825bfe0b8ef6a0cf2b4309cc607a3c880e75 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 13 Jan 2013 17:18:30 +0000 Subject: [PATCH 139/347] web fix. dope --- modules/web/config.json | 2 +- run.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/web/config.json b/modules/web/config.json index 60f35d1..45cd275 100644 --- a/modules/web/config.json +++ b/modules/web/config.json @@ -1,4 +1,4 @@ { "webHost": "localhost", - "webPort": 8090 + "webPort": 9001 } diff --git a/run.js b/run.js index f9418dd..31c3adc 100644 --- a/run.js +++ b/run.js @@ -207,7 +207,7 @@ DBot.prototype.reloadModules = function() { if(module.pages) { _.extend(this.pages, module.pages); _.each(module.pages, function(page) { - page.module = name; + page.module = module; }, this); } From ba2ab323e30f4e3215a50921d454e370267ce803 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 13:10:16 +0000 Subject: [PATCH 140/347] Do the [#133] --- modules/dent/dent.js | 30 +++++++++++++++++++++--------- modules/quotes/quotes.js | 5 +++++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/modules/dent/dent.js b/modules/dent/dent.js index 3d5844e..120b082 100644 --- a/modules/dent/dent.js +++ b/modules/dent/dent.js @@ -1,28 +1,40 @@ var request = require('request'); + _ = require('underscore')._; var dent = function(dbot) { - var commands = { - '~dent': function(event) { - var username = dbot.config.dent.username; - var password = dbot.config.dent.password; - var auth = "Basic " + + var api = { + 'post': function(content) { + var username = dbot.config.dent.username, + password = dbot.config.dent.password, + info, + auth = "Basic " + new Buffer(username + ":" + password).toString("base64"); + request.post({ 'url': 'http://identi.ca/api/statuses/update.json?status=' + - event.input[1], + content, 'headers': { 'Authorization': auth } }, function(error, response, body) { - event.reply('Status posted (probably).'); - }); + console.log(body); + }.bind(this)); + } + }; + + var commands = { + '~dent': function(event) { + api.post(event.input[1]); + event.reply('Dent posted (probably).'); } }; commands['~dent'].regex = [/^~dent (.+)$/, 2]; return { - 'commands': commands + 'name': 'dent', + 'commands': commands, + 'api': api }; }; diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index 96524c5..70cb9c1 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -260,6 +260,11 @@ var quotes = function(dbot) { 'category': key, 'count': quotes[key].length })); + + // TODO hook + if(_.has(dbot.api, 'dent')) { + dbot.api.dent.post(key + ': ' + text); + } } }, From dc269b53b4c9ba2b14e1164ccc5409b90e7364c1 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 16:02:40 +0000 Subject: [PATCH 141/347] Here is an experimental look at how modules will have to be as per [#131] --- modules/command/api.js | 68 ++++++++++++++ modules/command/command.js | 180 ++++++++---------------------------- modules/command/commands.js | 39 ++++++++ run.js | 23 ++++- 4 files changed, 166 insertions(+), 144 deletions(-) create mode 100644 modules/command/api.js create mode 100644 modules/command/commands.js diff --git a/modules/command/api.js b/modules/command/api.js new file mode 100644 index 0000000..b264efa --- /dev/null +++ b/modules/command/api.js @@ -0,0 +1,68 @@ +var _ = require('underscore')._; + +var api = { + 'isBanned': function(user, command) { + var banned = false; + if(_.has(this.dbot.db.bans, command)) { + if(_.include(this.dbot.db.bans[command], user) || _.include(this.dbot.db.bans['*'], user)) { + banned = true; + } + } + return banned; + }, + + /** + * Does the user have the correct access level to use the command? + */ + 'hasAccess': function(user, command) { + var access = true; + var accessNeeded = this.dbot.commands[command].access; + + if(accessNeeded == 'admin') { + if(!_.include(this.dbot.config.admins, user)) { + access = false; + } + } else if(accessNeeded == 'moderator') { + if(!_.include(this.dbot.config.moderators, user) && + !_.include(this.dbot.config.admins, user)) { + access = false; + } + } + + return access; + }, + + /** + * Is user ignoring command? + */ + 'isIgnoring': function(user, command) { + var module = this.dbot.commands[command].module; + var ignoring = false; + if(_.has(this.dbot.db.ignores, user) && _.include(this.dbot.db.ignores[user], module)) { + ignoring = true; + } + return ignoring; + }, + + /** + * Apply Regex to event message, store result. Return false if it doesn't + * apply. + */ + 'applyRegex': function(commandName, event) { + var applies = false; + if(_.has(this.dbot.commands[commandName], 'regex')) { + var cRegex = this.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; + } +}; + +exports.fetch = api; + diff --git a/modules/command/command.js b/modules/command/command.js index 968e578..fb8b2b2 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -6,154 +6,52 @@ */ var _ = require('underscore')._; var command = function(dbot) { + this.name = 'command'; + this.ignorable = false; + this.dbot = dbot; + /** - * Is user banned from using command? + * Run the appropriate command given the input. */ - var isBanned = function(user, command) { - var banned = false; - if(_.has(dbot.db.bans, command)) { - if(_.include(dbot.db.bans[command], user) || _.include(dbot.db.bans['*'], user)) { - banned = true; - } - } - return banned; - }; - - /** - * Does the user have the correct access level to use the command? - */ - var hasAccess = function(user, command) { - var access = true; - var accessNeeded = dbot.commands[command].access; - - if(accessNeeded == 'admin') { - if(!_.include(dbot.config.admins, user)) { - access = false; - } - } else if(accessNeeded == 'moderator') { - if(!_.include(dbot.config.moderators, user) && - !_.include(dbot.config.admins, user)) { - access = false; - } + this.listener = function(event) { + console.log(Object.keys(this)); + var commandName = event.params[0]; + if(!_.has(this.dbot.commands, commandName)) { + commandName = '~'; } - return access; - }; - - /** - * Is user ignoring command? - */ - var isIgnoring = function(user, command) { - var module = dbot.commands[command].module; - var ignoring = false; - if(_.has(dbot.db.ignores, user) && _.include(dbot.db.ignores[user], 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(_.has(dbot.commands[commandName], 'regex')) { - var cRegex = dbot.commands[commandName].regex; - var q = event.message.valMatch(cRegex[0], cRegex[1]); - if(q) { - applies = true; - event.input = q; - } + if(this.api.isBanned(event.user, commandName)) { + event.reply(this.dbot.t('command_ban', {'user': event.user})); } else { - applies = true; + if(!this.api.isIgnoring(event.user, commandName) && + this.api.hasAccess(event.user, commandName) && + this.dbot.commands[commandName].disabled !== true) { + if(this.api.applyRegex(commandName, event)) { + try { + this.dbot.commands[commandName](event); + } catch(err) { + if(this.dbot.config.debugMode == true) { + event.reply('- Error in ' + commandName + ':'); + event.reply('- Message: ' + err); + event.reply('- Top of stack: ' + err.stack.split('\n')[1].trim()); + } + } + this.dbot.save(); + } else { + if(commandName !== '~') { + if(_.has(this.dbot.usage, commandName)) { + event.reply('Usage: ' + this.dbot.usage[commandName]); + } else { + event.reply(this.dbot.t('syntax_error')); + } + } + } + } } - return applies; - }; - - return { - 'name': 'command', - 'ignorable': false, - - 'commands': { - '~usage': function(event) { - var commandName = event.params[1]; - if(_.has(dbot.usage, commandName)) { - event.reply(dbot.t('usage', { - 'command': commandName, - 'usage': dbot.usage[commandName] - })); - } else { - event.reply(dbot.t('no_usage_info', { - 'command': commandName - })); - } - }, - - '~help': function(event) { - var moduleName = event.params[1]; - if(!_.has(dbot.modules, moduleName)) { - var moduleName = dbot.commands[moduleName].module; - } - - if(moduleName && _.has(dbot.config[moduleName], 'help')) { - var help = dbot.config[moduleName].help; - event.reply(dbot.t('help_link', { - 'module': moduleName, - 'link': help - })); - } else { - if(!moduleName) { - moduleName = event.params[1]; - } - event.reply(dbot.t('no_help', { 'module': moduleName })) - } - } - }, - - /** - * Run the appropriate command given the input. - */ - 'listener': function(event) { - var commandName = event.params[0]; - if(!_.has(dbot.commands, commandName)) { - commandName = '~'; - } - - if(isBanned(event.user, commandName)) { - event.reply(dbot.t('command_ban', {'user': event.user})); - } else { - if(!isIgnoring(event.user, commandName) && - hasAccess(event.user, commandName) && - dbot.commands[commandName].disabled !== true) { - if(applyRegex(commandName, event)) { - try { - dbot.commands[commandName](event); - } catch(err) { - if(dbot.config.debugMode == true) { - event.reply('- Error in ' + commandName + ':'); - event.reply('- Message: ' + err); - event.reply('- Top of stack: ' + err.stack.split('\n')[1].trim()); - } - } - dbot.save(); - } else { - if(commandName !== '~') { - if(_.has(dbot.usage, commandName)) { - event.reply('Usage: ' + dbot.usage[commandName]); - } else { - event.reply(dbot.t('syntax_error')); - } - } - } - } - } - }, - 'on': 'PRIVMSG' - }; + }.bind(this); + this.on = 'PRIVMSG'; }; exports.fetch = function(dbot) { - return command(dbot); + return new command(dbot); }; - diff --git a/modules/command/commands.js b/modules/command/commands.js new file mode 100644 index 0000000..36861cc --- /dev/null +++ b/modules/command/commands.js @@ -0,0 +1,39 @@ +var _ = require('underscore')._; + +var commands = { + '~usage': function(event) { + var commandName = event.params[1]; + if(_.has(this.dbot.usage, commandName)) { + event.reply(this.dbot.t('usage', { + 'command': commandName, + 'usage': this.dbot.usage[commandName] + })); + } else { + event.reply(this.dbot.t('no_usage_info', { + 'command': commandName + })); + } + }, + + '~help': function(event) { + var moduleName = event.params[1]; + if(!_.has(this.dbot.modules, moduleName)) { + var moduleName = this.dbot.commands[moduleName].module; + } + + if(moduleName && _.has(this.dbot.config[moduleName], 'help')) { + var help = this.dbot.config[moduleName].help; + event.reply(this.dbot.t('help_link', { + 'module': moduleName, + 'link': help + })); + } else { + if(!moduleName) { + moduleName = event.params[1]; + } + event.reply(this.dbot.t('no_help', { 'module': moduleName })) + } + } +}; + +exports.fetch = commands; diff --git a/run.js b/run.js index 31c3adc..8d33c85 100644 --- a/run.js +++ b/run.js @@ -158,8 +158,7 @@ DBot.prototype.reloadModules = function() { // Load the module config data var config = {}; try { - config = JSON.parse(fs.readFileSync(moduleDir + 'config.json', 'utf-8')) - + config = JSON.parse(fs.readFileSync(moduleDir + 'config.json', 'utf-8')); } catch(err) { // Invalid or no config data } @@ -174,9 +173,27 @@ DBot.prototype.reloadModules = function() { // Load the module itself var rawModule = require(moduleDir + name); var module = rawModule.fetch(this); + module.name = name; this.rawModules.push(rawModule); - module.name = name; + // Load the module with any addition objects we can find... + _.each([ 'commands', 'pages', 'api' ], function(property) { + try { + var propertyKey = require.resolve(moduleDir + property); + if(propertyKey) delete require.cache[propertyKey]; + var propertyObj = require(moduleDir + property).fetch; + } catch(err) { + console.log(err.stack); + return; + } + + module[property] = {}; + _.each(propertyObj, function(item, name) { + if(_.isFunction(item)) { + module[property][name] = item.bind(module); + } + }, this); + }, this); if(module.listener) { if(!_.isArray(module.on)) { From 5419a664dc136ca352c71534d3a0dde8fad4829b Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 16:24:38 +0000 Subject: [PATCH 142/347] Much better! [#131] --- modules/command/api.js | 113 ++++++++++++++++++------------------ modules/command/command.js | 19 +++--- modules/command/commands.js | 28 +++++---- run.js | 2 +- 4 files changed, 84 insertions(+), 78 deletions(-) diff --git a/modules/command/api.js b/modules/command/api.js index b264efa..60509e4 100644 --- a/modules/command/api.js +++ b/modules/command/api.js @@ -1,68 +1,71 @@ var _ = require('underscore')._; -var api = { - 'isBanned': function(user, command) { - var banned = false; - if(_.has(this.dbot.db.bans, command)) { - if(_.include(this.dbot.db.bans[command], user) || _.include(this.dbot.db.bans['*'], user)) { - banned = true; +var api = function(dbot) { + return { + 'isBanned': function(user, command) { + var banned = false; + if(_.has(dbot.db.bans, command)) { + if(_.include(dbot.db.bans[command], user) || _.include(dbot.db.bans['*'], user)) { + banned = true; + } } - } - return banned; - }, + return banned; + }, - /** - * Does the user have the correct access level to use the command? - */ - 'hasAccess': function(user, command) { - var access = true; - var accessNeeded = this.dbot.commands[command].access; + /** + * Does the user have the correct access level to use the command? + */ + 'hasAccess': function(user, command) { + var access = true; + var accessNeeded = dbot.commands[command].access; - if(accessNeeded == 'admin') { - if(!_.include(this.dbot.config.admins, user)) { - access = false; + if(accessNeeded == 'admin') { + if(!_.include(dbot.config.admins, user)) { + access = false; + } + } else if(accessNeeded == 'moderator') { + if(!_.include(dbot.config.moderators, user) && + !_.include(dbot.config.admins, user)) { + access = false; + } } - } else if(accessNeeded == 'moderator') { - if(!_.include(this.dbot.config.moderators, user) && - !_.include(this.dbot.config.admins, user)) { - access = false; + + return access; + }, + + /** + * Is user ignoring command? + */ + 'isIgnoring': function(user, command) { + var module = dbot.commands[command].module; + var ignoring = false; + if(_.has(dbot.db.ignores, user) && _.include(dbot.db.ignores[user], module)) { + ignoring = true; } - } + return ignoring; + }, - return access; - }, - - /** - * Is user ignoring command? - */ - 'isIgnoring': function(user, command) { - var module = this.dbot.commands[command].module; - var ignoring = false; - if(_.has(this.dbot.db.ignores, user) && _.include(this.dbot.db.ignores[user], module)) { - ignoring = true; - } - return ignoring; - }, - - /** - * Apply Regex to event message, store result. Return false if it doesn't - * apply. - */ - 'applyRegex': function(commandName, event) { - var applies = false; - if(_.has(this.dbot.commands[commandName], 'regex')) { - var cRegex = this.dbot.commands[commandName].regex; - var q = event.message.valMatch(cRegex[0], cRegex[1]); - if(q) { + /** + * Apply Regex to event message, store result. Return false if it doesn't + * apply. + */ + 'applyRegex': function(commandName, event) { + var applies = false; + if(_.has(dbot.commands[commandName], '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; - event.input = q; } - } else { - applies = true; + return applies; } - return applies; - } + }; }; -exports.fetch = api; - +exports.fetch = function(dbot) { + return api(dbot); +}; diff --git a/modules/command/command.js b/modules/command/command.js index fb8b2b2..c6690cf 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -14,35 +14,34 @@ var command = function(dbot) { * Run the appropriate command given the input. */ this.listener = function(event) { - console.log(Object.keys(this)); var commandName = event.params[0]; - if(!_.has(this.dbot.commands, commandName)) { + if(!_.has(dbot.commands, commandName)) { commandName = '~'; } if(this.api.isBanned(event.user, commandName)) { - event.reply(this.dbot.t('command_ban', {'user': event.user})); + event.reply(dbot.t('command_ban', {'user': event.user})); } else { if(!this.api.isIgnoring(event.user, commandName) && this.api.hasAccess(event.user, commandName) && - this.dbot.commands[commandName].disabled !== true) { + dbot.commands[commandName].disabled !== true) { if(this.api.applyRegex(commandName, event)) { try { - this.dbot.commands[commandName](event); + dbot.commands[commandName](event); } catch(err) { - if(this.dbot.config.debugMode == true) { + if(dbot.config.debugMode == true) { event.reply('- Error in ' + commandName + ':'); event.reply('- Message: ' + err); event.reply('- Top of stack: ' + err.stack.split('\n')[1].trim()); } } - this.dbot.save(); + dbot.save(); } else { if(commandName !== '~') { - if(_.has(this.dbot.usage, commandName)) { - event.reply('Usage: ' + this.dbot.usage[commandName]); + if(_.has(dbot.usage, commandName)) { + event.reply('Usage: ' + dbot.usage[commandName]); } else { - event.reply(this.dbot.t('syntax_error')); + event.reply(dbot.t('syntax_error')); } } } diff --git a/modules/command/commands.js b/modules/command/commands.js index 36861cc..96ac77a 100644 --- a/modules/command/commands.js +++ b/modules/command/commands.js @@ -1,15 +1,16 @@ var _ = require('underscore')._; -var commands = { +var commands = function(dbot) { + return { '~usage': function(event) { var commandName = event.params[1]; - if(_.has(this.dbot.usage, commandName)) { - event.reply(this.dbot.t('usage', { + if(_.has(dbot.usage, commandName)) { + event.reply(dbot.t('usage', { 'command': commandName, - 'usage': this.dbot.usage[commandName] + 'usage': dbot.usage[commandName] })); } else { - event.reply(this.dbot.t('no_usage_info', { + event.reply(dbot.t('no_usage_info', { 'command': commandName })); } @@ -17,13 +18,13 @@ var commands = { '~help': function(event) { var moduleName = event.params[1]; - if(!_.has(this.dbot.modules, moduleName)) { - var moduleName = this.dbot.commands[moduleName].module; + if(!_.has(dbot.modules, moduleName)) { + var moduleName = dbot.commands[moduleName].module; } - if(moduleName && _.has(this.dbot.config[moduleName], 'help')) { - var help = this.dbot.config[moduleName].help; - event.reply(this.dbot.t('help_link', { + if(moduleName && _.has(dbot.config[moduleName], 'help')) { + var help = dbot.config[moduleName].help; + event.reply(dbot.t('help_link', { 'module': moduleName, 'link': help })); @@ -31,9 +32,12 @@ var commands = { if(!moduleName) { moduleName = event.params[1]; } - event.reply(this.dbot.t('no_help', { 'module': moduleName })) + event.reply(dbot.t('no_help', { 'module': moduleName })) } } + }; }; -exports.fetch = commands; +exports.fetch = function(dbot) { + return commands(dbot); +}; diff --git a/run.js b/run.js index 8d33c85..fabfb67 100644 --- a/run.js +++ b/run.js @@ -181,7 +181,7 @@ DBot.prototype.reloadModules = function() { try { var propertyKey = require.resolve(moduleDir + property); if(propertyKey) delete require.cache[propertyKey]; - var propertyObj = require(moduleDir + property).fetch; + var propertyObj = require(moduleDir + property).fetch(this); } catch(err) { console.log(err.stack); return; From 0ff2a43c077a5ea44d4a15a12b442d6b165ea2b7 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 16:47:48 +0000 Subject: [PATCH 143/347] command can stand being run without quotes! --- modules/command/command.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/command/command.js b/modules/command/command.js index c6690cf..4812b4a 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -16,9 +16,13 @@ var command = function(dbot) { this.listener = function(event) { var commandName = event.params[0]; if(!_.has(dbot.commands, commandName)) { - commandName = '~'; - } - + if(_.has(dbot.modules, 'quotes')) { + commandName = '~'; + } else { + return; + } + } + if(this.api.isBanned(event.user, commandName)) { event.reply(dbot.t('command_ban', {'user': event.user})); } else { From 4b69aee3e93621f65214d3a601a363c7c5fff93a Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 16:56:34 +0000 Subject: [PATCH 144/347] Transformed admin [#131] --- modules/admin/admin.js | 172 +------------------------------------- modules/admin/commands.js | 171 +++++++++++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+), 168 deletions(-) create mode 100644 modules/admin/commands.js diff --git a/modules/admin/admin.js b/modules/admin/admin.js index d2cc575..5fab7a6 100644 --- a/modules/admin/admin.js +++ b/modules/admin/admin.js @@ -4,177 +4,13 @@ * administrator can run - as such, it has its own command execution listener. */ var fs = require('fs'), - _ = require('underscore')._, - sys = require('sys'), - exec = require('child_process').exec; + _ = require('underscore')._; var admin = function(dbot) { - var commands = { - // Join a channel - 'join': function(event) { - var channel = event.params[1]; - if(_.has(event.allChannels, channel)) { - event.reply(dbot.t('already_in_channel', {'channel': channel})); - } else { - dbot.instance.join(event, channel); - event.reply(dbot.t('join', {'channel': channel})); - } - }, - - // Leave a channel - 'part': function(event) { - var channel = event.params[1]; - if(!_.has(event.allChannels, channel)) { - event.reply(dbot.t('not_in_channel', {'channel': channel})); - } else { - event.instance.part(event, channel); - event.reply(dbot.t('part', {'channel': channel})); - } - }, - - // Op admin caller in given channel - 'opme': function(event) { - var channel = event.params[1]; - - // If given channel isn't valid just op in current one. - if(!_.has(event.allChannels, channel)) { - channel = event.channel.name; - } - dbot.instance.mode(event, channel, ' +o ' + event.user); - }, - - // Do a git pull and reload - 'greload': function(event) { - exec("git pull", function (error, stdout, stderr) { - exec("git submodule update", function (error, stdout, stderr) { - event.reply(dbot.t('gpull')); - commands.reload(event); - event.message = 'version'; - event.action = 'PRIVMSG'; - event.params = event.message.split(' '); - dbot.instance.emit(event); - }.bind(this)); - }.bind(this)); - }, - - // Display commit information for part of dbot - 'version': function(event){ - var cmd = "git log --pretty=format:'%h (%s): %ar' -n 1 -- "; - if(event.params[1]){ - var input = event.params[1].trim(); - if(_.has(dbot.modules, input.split("/")[0])){ - cmd += "modules/"+input; - } - else{ - cmd += input; - } - } - - exec(cmd, function(error, stdout, stderr){ - if(stdout.length > 0){ - event.reply(stdout); - } - else{ - event.reply("No version information or queried module not loaded"); - } - }.bind(this)); - }, - - // Reload DB, translations and modules. - 'reload': function(event) { - dbot.db = JSON.parse(fs.readFileSync('db.json', 'utf-8')); - dbot.reloadModules(); - event.reply(dbot.t('reload')); - }, - - // Say something in a channel - 'say': function(event) { - var channel = event.params[1]; - if(event.params[1] === "@") { - var channel = event.channel.name; - } - var message = event.params.slice(2).join(' '); - dbot.say(event.server, channel, message); - }, - - // Load new module - 'load': function(event) { - var moduleName = event.params[1]; - if(!_.include(dbot.config.moduleNames, moduleName)) { - dbot.config.moduleNames.push(moduleName); - dbot.reloadModules(); - event.reply(dbot.t('load_module', {'moduleName': moduleName})); - } else { - if(moduleName == 'web') { - event.reply(dbot.t('already_loaded_web')); - } else { - event.reply(dbot.t('already_loaded', {'moduleName': moduleName})); - } - } - }, - - // Unload a loaded module - 'unload': function(event) { - var moduleNames = dbot.config.moduleNames; - var moduleName = event.params[1]; - if(_.include(moduleNames, moduleName)) { - var moduleDir = '../' + moduleName + '/'; - var cacheKey = require.resolve(moduleDir + moduleName); - delete require.cache[cacheKey]; - dbot.config.moduleNames = _.without(dbot.config.moduleNames, moduleName); - dbot.reloadModules(); - - event.reply(dbot.t('unload_module', {'moduleName': moduleName})); - } else { - event.reply(dbot.t('unload_error', {'moduleName': moduleName})); - } - }, - - // Ban user from command or * - 'ban': function(event) { - var username = event.params[1]; - var command = event.params[2]; - - if(!_.has(dbot.db.bans, command)) { - dbot.db.bans[command] = [ ]; - } - dbot.db.bans[command].push(username); - event.reply(dbot.t('banned', {'user': username, 'command': command})); - }, - - // Unban a user from command or * - 'unban': function(event) { - var username = event.params[1]; - var command = event.params[2]; - if(_.has(dbot.db.bans, command) && _.include(dbot.db.bans[command], username)) { - _.reject(dbot.db.bans[command], function(bans) { - return bans == username; - }, this); - event.reply(dbot.t('unbanned', {'user': username, 'command': command})); - } else { - event.reply(dbot.t('unban_error', {'user': username})); - } - } - }; - - commands['greload'].access = 'admin'; - commands['reload'].access = 'admin'; - commands['unload'].access = 'admin'; - commands['load'].access = 'admin'; - commands['join'].access = 'moderator'; - commands['part'].access = 'moderator'; - commands['opme'].access = 'moderator'; - commands['say'].access = 'moderator'; - commands['ban'].access = 'moderator'; - commands['unban'].access = 'moderator'; - - return { - 'name': 'admin', - 'ignorable': false, - 'commands': commands - }; + this.name = 'admin'; + this.ignorable = false; }; exports.fetch = function(dbot) { - return admin(dbot); + return new admin(dbot); }; diff --git a/modules/admin/commands.js b/modules/admin/commands.js new file mode 100644 index 0000000..0cba001 --- /dev/null +++ b/modules/admin/commands.js @@ -0,0 +1,171 @@ +var fs = require('fs'), + _ = require('underscore')._, + sys = require('sys'), + exec = require('child_process').exec; + +var commands = function(dbot) { + var commands = { + // Join a channel + 'join': function(event) { + var channel = event.params[1]; + if(_.has(event.allChannels, channel)) { + event.reply(dbot.t('already_in_channel', {'channel': channel})); + } else { + dbot.instance.join(event, channel); + event.reply(dbot.t('join', {'channel': channel})); + } + }, + + // Leave a channel + 'part': function(event) { + var channel = event.params[1]; + if(!_.has(event.allChannels, channel)) { + event.reply(dbot.t('not_in_channel', {'channel': channel})); + } else { + event.instance.part(event, channel); + event.reply(dbot.t('part', {'channel': channel})); + } + }, + + // Op admin caller in given channel + 'opme': function(event) { + var channel = event.params[1]; + + // If given channel isn't valid just op in current one. + if(!_.has(event.allChannels, channel)) { + channel = event.channel.name; + } + dbot.instance.mode(event, channel, ' +o ' + event.user); + }, + + // Do a git pull and reload + 'greload': function(event) { + exec("git pull", function (error, stdout, stderr) { + exec("git submodule update", function (error, stdout, stderr) { + event.reply(dbot.t('gpull')); + commands.reload(event); + event.message = 'version'; + event.action = 'PRIVMSG'; + event.params = event.message.split(' '); + dbot.instance.emit(event); + }.bind(this)); + }.bind(this)); + }, + + // Display commit information for part of dbot + 'version': function(event){ + var cmd = "git log --pretty=format:'%h (%s): %ar' -n 1 -- "; + if(event.params[1]){ + var input = event.params[1].trim(); + if(_.has(dbot.modules, input.split("/")[0])){ + cmd += "modules/"+input; + } + else{ + cmd += input; + } + } + + exec(cmd, function(error, stdout, stderr){ + if(stdout.length > 0){ + event.reply(stdout); + } + else{ + event.reply("No version information or queried module not loaded"); + } + }.bind(this)); + }, + + // Reload DB, translations and modules. + 'reload': function(event) { + dbot.db = JSON.parse(fs.readFileSync('db.json', 'utf-8')); + dbot.reloadModules(); + event.reply(dbot.t('reload')); + }, + + // Say something in a channel + 'say': function(event) { + var channel = event.params[1]; + if(event.params[1] === "@") { + var channel = event.channel.name; + } + var message = event.params.slice(2).join(' '); + dbot.say(event.server, channel, message); + }, + + // Load new module + 'load': function(event) { + var moduleName = event.params[1]; + if(!_.include(dbot.config.moduleNames, moduleName)) { + dbot.config.moduleNames.push(moduleName); + dbot.reloadModules(); + event.reply(dbot.t('load_module', {'moduleName': moduleName})); + } else { + if(moduleName == 'web') { + event.reply(dbot.t('already_loaded_web')); + } else { + event.reply(dbot.t('already_loaded', {'moduleName': moduleName})); + } + } + }, + + // Unload a loaded module + 'unload': function(event) { + var moduleNames = dbot.config.moduleNames; + var moduleName = event.params[1]; + if(_.include(moduleNames, moduleName)) { + var moduleDir = '../' + moduleName + '/'; + var cacheKey = require.resolve(moduleDir + moduleName); + delete require.cache[cacheKey]; + dbot.config.moduleNames = _.without(dbot.config.moduleNames, moduleName); + dbot.reloadModules(); + + event.reply(dbot.t('unload_module', {'moduleName': moduleName})); + } else { + event.reply(dbot.t('unload_error', {'moduleName': moduleName})); + } + }, + + // Ban user from command or * + 'ban': function(event) { + var username = event.params[1]; + var command = event.params[2]; + + if(!_.has(dbot.db.bans, command)) { + dbot.db.bans[command] = [ ]; + } + dbot.db.bans[command].push(username); + event.reply(dbot.t('banned', {'user': username, 'command': command})); + }, + + // Unban a user from command or * + 'unban': function(event) { + var username = event.params[1]; + var command = event.params[2]; + if(_.has(dbot.db.bans, command) && _.include(dbot.db.bans[command], username)) { + _.reject(dbot.db.bans[command], function(bans) { + return bans == username; + }, this); + event.reply(dbot.t('unbanned', {'user': username, 'command': command})); + } else { + event.reply(dbot.t('unban_error', {'user': username})); + } + } + }; + + commands['greload'].access = 'admin'; + commands['reload'].access = 'admin'; + commands['unload'].access = 'admin'; + commands['load'].access = 'admin'; + commands['join'].access = 'moderator'; + commands['part'].access = 'moderator'; + commands['opme'].access = 'moderator'; + commands['say'].access = 'moderator'; + commands['ban'].access = 'moderator'; + commands['unban'].access = 'moderator'; + + return commands; +}; + +exports.fetch = function(dbot) { + return commands(dbot); +} From 3bde9e493055168f39e4dd8aea3a564611364699 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 17:45:53 +0000 Subject: [PATCH 145/347] Transformed dent module, changed module loader to give right scope. [#131] --- modules/command/command.js | 3 ++- modules/dent/dent.js | 19 ++++++++----------- run.js | 8 ++------ 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/modules/command/command.js b/modules/command/command.js index 4812b4a..60c9477 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -31,7 +31,8 @@ var command = function(dbot) { dbot.commands[commandName].disabled !== true) { if(this.api.applyRegex(commandName, event)) { try { - dbot.commands[commandName](event); + var command = dbot.commands[commandName]; + command.apply(dbot.modules[command.module], [event]); } catch(err) { if(dbot.config.debugMode == true) { event.reply('- Error in ' + commandName + ':'); diff --git a/modules/dent/dent.js b/modules/dent/dent.js index 120b082..81e56f0 100644 --- a/modules/dent/dent.js +++ b/modules/dent/dent.js @@ -2,7 +2,10 @@ var request = require('request'); _ = require('underscore')._; var dent = function(dbot) { - var api = { + this.name = 'dent'; + this.dbot = dbot; + + this.api = { 'post': function(content) { var username = dbot.config.dent.username, password = dbot.config.dent.password, @@ -23,21 +26,15 @@ var dent = function(dbot) { } }; - var commands = { + this.commands = { '~dent': function(event) { - api.post(event.input[1]); + this.api.post(event.input[1]); event.reply('Dent posted (probably).'); } }; - commands['~dent'].regex = [/^~dent (.+)$/, 2]; - - return { - 'name': 'dent', - 'commands': commands, - 'api': api - }; + this.commands['~dent'].regex = [/^~dent (.+)$/, 2]; }; exports.fetch = function(dbot) { - return dent(dbot); + return new dent(dbot); }; diff --git a/run.js b/run.js index fabfb67..1963790 100644 --- a/run.js +++ b/run.js @@ -187,12 +187,8 @@ DBot.prototype.reloadModules = function() { return; } - module[property] = {}; - _.each(propertyObj, function(item, name) { - if(_.isFunction(item)) { - module[property][name] = item.bind(module); - } - }, this); + if(!_.has(module, property)) module[property] = {}; + _.extend(module[property], propertyObj); }, this); if(module.listener) { From a0bec5b2f93df8ad2822096ead01415c630edf26 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 17:58:58 +0000 Subject: [PATCH 146/347] I must say... I am proud of this... [#131] --- run.js | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/run.js b/run.js index 1963790..9e0d60a 100644 --- a/run.js +++ b/run.js @@ -178,17 +178,24 @@ DBot.prototype.reloadModules = function() { // Load the module with any addition objects we can find... _.each([ 'commands', 'pages', 'api' ], function(property) { + var propertyObj = {}; try { var propertyKey = require.resolve(moduleDir + property); if(propertyKey) delete require.cache[propertyKey]; - var propertyObj = require(moduleDir + property).fetch(this); + propertyObj = require(moduleDir + property).fetch(this); } catch(err) { - console.log(err.stack); - return; + //console.log(err.stack); } if(!_.has(module, property)) module[property] = {}; _.extend(module[property], propertyObj); + _.each(module[property], function(item, itemName) { + item.module = name; + if(_.has(config, property) && _.has(config[property], itemName)) { + _.extend(item, config[property][itemName]); + } + }, this); + _.extend(this[property], module[property]); }, this); if(module.listener) { @@ -205,30 +212,6 @@ DBot.prototype.reloadModules = function() { module.onLoad(); } - // Load module commands - if(module.commands) { - _.extend(this.commands, module.commands); - _.each(module.commands, function(command, commandName) { - command.module = name; - if(_.has(config, 'commands') && _.has(config.commands, commandName)) { - _.extend(command, config.commands[commandName]); - } - }, this); - } - - // Load module web bits - if(module.pages) { - _.extend(this.pages, module.pages); - _.each(module.pages, function(page) { - page.module = module; - }, this); - } - - // Load module API - if(module.api) { - this.api[module.name] = module.api; - } - // Load the module usage data var usage = {}; try { From 8542ceb9e9db6f372140a5a205861e0a2ecc9ac4 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 18:15:07 +0000 Subject: [PATCH 147/347] Do the same for string data [#131] --- run.js | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/run.js b/run.js index 9e0d60a..ec8ebad 100644 --- a/run.js +++ b/run.js @@ -176,7 +176,7 @@ DBot.prototype.reloadModules = function() { module.name = name; this.rawModules.push(rawModule); - // Load the module with any addition objects we can find... + // Load the module data _.each([ 'commands', 'pages', 'api' ], function(property) { var propertyObj = {}; try { @@ -184,7 +184,7 @@ DBot.prototype.reloadModules = function() { if(propertyKey) delete require.cache[propertyKey]; propertyObj = require(moduleDir + property).fetch(this); } catch(err) { - //console.log(err.stack); + console.log('Module error (' + module.name + ') in ' + property + ': ' + err); } if(!_.has(module, property)) module[property] = {}; @@ -198,43 +198,34 @@ DBot.prototype.reloadModules = function() { _.extend(this[property], module[property]); }, this); + // Load the module listener if(module.listener) { if(!_.isArray(module.on)) { module.on = [ module.on ]; } - _.each(module.on, function(on) { this.instance.addListener(on, module.name, module.listener); }, this); } - if(module.onLoad) { - module.onLoad(); - } - - // Load the module usage data - var usage = {}; - try { - usage = JSON.parse(fs.readFileSync(moduleDir + 'usage.json', 'utf-8')); - } catch(err) { - // Invalid or no usage info - } - _.extend(this.usage, usage); - - // Load the module string data - var strings = {}; - try { - strings = JSON.parse(fs.readFileSync(moduleDir + 'strings.json', 'utf-8')); - } catch(err) { - // Invalid or no string info - } - _.extend(this.strings, strings); + // Load string data for the module + _.each([ 'usage', 'strings' ], function(property) { + var propertyData = {}; + try { + propertyData = JSON.parse(fs.readFileSync(moduleDir + property + '.json', 'utf-8')); + } catch(err) {}; + _.extend(this[property], propertyData); + }, this); // Provide toString for module name module.toString = function() { return this.name; } + if(module.onLoad) { + module.onLoad(); + } + this.modules[module.name] = module; } catch(err) { console.log(this.t('module_load_error', {'moduleName': name})); From 8b7953e9060ebc3514a37a1b9a79a3f8e16f85a0 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 21:03:47 +0000 Subject: [PATCH 148/347] tranform users, fix for bind in module loader [#131] --- modules/users/api.js | 42 +++++++ modules/users/commands.js | 91 +++++++++++++++ modules/users/users.js | 227 +++++++++----------------------------- run.js | 1 + 4 files changed, 188 insertions(+), 173 deletions(-) create mode 100644 modules/users/api.js create mode 100644 modules/users/commands.js diff --git a/modules/users/api.js b/modules/users/api.js new file mode 100644 index 0000000..7ba86f4 --- /dev/null +++ b/modules/users/api.js @@ -0,0 +1,42 @@ +var _ = require('underscore')._; + +var api = function(dbot) { + var api = { + 'resolveUser': function(server, nick, useLowercase) { + var knownUsers = this.getServerUsers(server); + var user = nick; + if(!_.include(knownUsers.users, nick) && _.has(knownUsers.aliases, nick)) { + user = knownUsers.aliases[nick]; + } + + if(useLowercase) user = user.toLowerCase(); + return user; + }, + + 'isKnownUser': function(server, nick) { + var knownUsers = this.getServerUsers(server); + return (_.include(knownUsers.users, nick) || _.has(knownUsers.aliases, nick)); + }, + + 'isPrimaryUser': function(server, nick) { + var knownUsers = this.getServerUsers(server); + return _.include(knownUsers.users, nick); + }, + + 'getAliases': function(server, nick) { + var knownUsers = this.getServerUsers(server); + return _.chain(knownUsers.aliases) + .keys() + .filter(function(user) { + return knownUsers.aliases[user] == nick; + }, this) + .value(); + } + }; + + return api; +}; + +exports.fetch = function(dbot) { + return api(dbot); +}; diff --git a/modules/users/commands.js b/modules/users/commands.js new file mode 100644 index 0000000..e1c5cd9 --- /dev/null +++ b/modules/users/commands.js @@ -0,0 +1,91 @@ +var _ = require('underscore')._; + +var commands = function(dbot) { + var commands = { + '~alias': function(event) { + var knownUsers = this.getServerUsers(event.server), + alias = event.params[1].trim(); + + if(_.include(knownUsers.users, alias)) { + var aliasCount = _.reduce(knownUsers.aliases, function(memo, user) { + if(user == alias) return memo += 1; + }, 0, this); + + event.reply(dbot.t('primary', { + 'user': alias, + 'count': aliasCount + })); + } else if(_.has(knownUsers.aliases, alias)) { + event.reply(dbot.t('alias', { + 'alias': alias, + 'user': knownUsers.aliases[alias] + })); + } else { + event.reply(dbot.t('unknown_alias', { 'alias': alias })); + } + }, + + '~setaliasparent': function(event) { + var knownUsers = this.getServerUsers(event.server); + var newParent = event.params[1]; + + if(_.has(knownUsers.aliases, newParent)) { + var newAlias = knownUsers.aliases[newParent]; + + // Replace user entry + knownUsers.users = _.without(knownUsers.users, newAlias); + knownUsers.users.push(newParent); + + // Replace channels entries with new primary user + this.updateChannels(event, newAlias, newParent); + + // Remove alias for new parent & add alias for new alias + delete knownUsers.aliases[newParent]; + knownUsers.aliases[newAlias] = newParent; + + // Update aliases to point to new primary user + this.updateAliases(event, newAlias, newParent); + + event.reply(dbot.t('aliasparentset', { + 'newParent': newParent, + 'newAlias': newAlias + })); + + dbot.api.stats.fixStats(event.server, newAlias); + } else { + event.reply(dbot.t('unknown_alias', { 'alias': newParent })); + } + }, + + '~mergeusers': function(event) { + var knownUsers = this.getServerUsers(event.server); + var primaryUser = event.params[1]; + var secondaryUser = event.params[2]; + + if(_.include(knownUsers.users, primaryUser) && _.include(knownUsers.users, secondaryUser)) { + knownUsers.users = _.without(knownUsers.users, secondaryUser); + knownUsers.aliases[secondaryUser] = primaryUser; + this.updateAliases(event, secondaryUser, primaryUser); + this.updateChannels(event, secondaryUser, primaryUser); + + event.reply(dbot.t('merged_users', { + 'old_user': secondaryUser, + 'new_user': primaryUser + })); + + dbot.api.stats.fixStats(event.server, secondaryUser); + } else { + event.reply(dbot.t('unprimary_error')); + } + } + }; + + commands['~setaliasparent'].access = 'moderator'; + commands['~mergeusers'].access = 'moderator'; + + return commands; +}; + +exports.fetch = function(dbot) { + return commands(dbot); +}; diff --git a/modules/users/users.js b/modules/users/users.js index 2cd8f07..ffca388 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -2,12 +2,12 @@ * Name: Users * Description: Track known users */ -var web = require('./web'), - _ = require('underscore')._; +var _ = require('underscore')._; var users = function(dbot) { - var knownUsers = dbot.db.knownUsers; - var getServerUsers = function(server) { + this.knownUsers = dbot.db.knownUsers; + this.getServerUsers = function(server) { + var knownUsers = this.knownUsers; if(!_.has(knownUsers, server)) { knownUsers[server] = { 'users': [], 'aliases': {}, 'channelUsers': {} }; } @@ -17,8 +17,8 @@ var users = function(dbot) { return knownUsers[server]; }; - var updateAliases = function(event, oldUser, newUser) { - var knownUsers = getServerUsers(event.server); + this.updateAliases = function(event, oldUser, newUser) { + var knownUsers = this.getServerUsers(event.server); _.each(knownUsers.aliases, function(user, alias) { if(user == oldUser) { knownUsers.aliases[alias] = newUser; @@ -26,197 +26,78 @@ var users = function(dbot) { }, this); }; - var updateChannels = function(event, oldUser, newUser) { - var channelUsers = getServerUsers(event.server).channelUsers; + this.updateChannels = function(event, oldUser, newUser) { + var channelUsers = this.getServerUsers(event.server).channelUsers; channelUsers = _.each(channelUsers, function(channel, channelName) { channelUsers[channelName] = _.without(channel, oldUser); channelUsers[channelName].push(newUser); }, this); }; - dbot.instance.addListener('366', 'users', function(event) { - var knownUsers = getServerUsers(event.server); - if(!_.has(knownUsers.channelUsers, event.channel.name)) { - knownUsers.channelUsers[event.channel.name] = []; - } - var channelUsers = knownUsers.channelUsers[event.channel.name]; + + this.name = 'users'; + this.ignorable = false; + + this.listener = function(event) { + var knownUsers = this.getServerUsers(event.server); + var nick = event.user; - _.each(event.channel.nicks, function(nick) { - nick = nick.name; - if(api.isKnownUser(event.server, nick)) { - nick = api.resolveUser(event.server, nick); + if(event.action == 'JOIN') { + if(!_.has(knownUsers.channelUsers, event.channel.name)) { + knownUsers.channelUsers[event.channel.name] = []; + } + var channelUsers = knownUsers.channelUsers[event.channel.name]; + + if(this.api.isKnownUser(event.server, nick)) { + nick = this.api.resolveUser(event.server, nick); } else { knownUsers.users.push(nick); } if(!_.include(channelUsers, nick)) { channelUsers.push(nick); } - }, this); - }); - - - var api = { - 'resolveUser': function(server, nick, useLowercase) { - var knownUsers = getServerUsers(server); - var user = nick; - if(!_.include(knownUsers.users, nick) && _.has(knownUsers.aliases, nick)) { - user = knownUsers.aliases[nick]; - } - - if(useLowercase) user = user.toLowerCase(); - return user; - }, - - 'isKnownUser': function(server, nick) { - var knownUsers = getServerUsers(server); - return (_.include(knownUsers.users, nick) || _.has(knownUsers.aliases, nick)); - }, - - 'isPrimaryUser': function(server, nick) { - return _.include(knownUsers.users, nick); - }, - - 'getAliases': function(server, nick) { - var knownUsers = getServerUsers(server); - return _.chain(knownUsers.aliases) - .keys() - .filter(function(user) { - return knownUsers.aliases[user] == nick; - }, this) - .value(); - } - }; - - var commands = { - '~alias': function(event) { - var knownUsers = getServerUsers(event.server), - alias = event.params[1].trim(); - - if(_.include(knownUsers.users, alias)) { - var aliasCount = _.reduce(knownUsers.aliases, function(memo, user) { - if(user == alias) return memo += 1; - }, 0, this); - - event.reply(dbot.t('primary', { - 'user': alias, - 'count': aliasCount - })); - } else if(_.has(knownUsers.aliases, alias)) { - event.reply(dbot.t('alias', { - 'alias': alias, - 'user': knownUsers.aliases[alias] - })); + } else if(event.action == 'NICK') { + var newNick = event.params.substr(1); + if(_.has(knownUsers.aliases, event.user)) { + knownUsers.aliases[newNick] = knownUsers.aliases[event.user]; } else { - event.reply(dbot.t('unknown_alias', { 'alias': alias })); - } - }, - - '~setaliasparent': function(event) { - var knownUsers = getServerUsers(event.server); - var newParent = event.params[1]; - - if(_.has(knownUsers.aliases, newParent)) { - var newAlias = knownUsers.aliases[newParent]; - - // Replace user entry - knownUsers.users = _.without(knownUsers.users, newAlias); - knownUsers.users.push(newParent); - - // Replace channels entries with new primary user - updateChannels(event, newAlias, newParent); - - // Remove alias for new parent & add alias for new alias - delete knownUsers.aliases[newParent]; - knownUsers.aliases[newAlias] = newParent; - - // Update aliases to point to new primary user - updateAliases(event, newAlias, newParent); - - event.reply(dbot.t('aliasparentset', { - 'newParent': newParent, - 'newAlias': newAlias - })); - - dbot.api.stats.fixStats(event.server, newAlias); - } else { - event.reply(dbot.t('unknown_alias', { 'alias': newParent })); - } - }, - - '~mergeusers': function(event) { - var knownUsers = getServerUsers(event.server); - var primaryUser = event.params[1]; - var secondaryUser = event.params[2]; - - if(_.include(knownUsers.users, primaryUser) && _.include(knownUsers.users, secondaryUser)) { - knownUsers.users = _.without(knownUsers.users, secondaryUser); - knownUsers.aliases[secondaryUser] = primaryUser; - updateAliases(event, secondaryUser, primaryUser); - updateChannels(event, secondaryUser, primaryUser); - - event.reply(dbot.t('merged_users', { - 'old_user': secondaryUser, - 'new_user': primaryUser - })); - - dbot.api.stats.fixStats(event.server, secondaryUser); - } else { - event.reply(dbot.t('unprimary_error')); - } - } - }; - - commands['~setaliasparent'].access = 'moderator'; - commands['~mergeusers'].access = 'moderator'; - - return { - 'name': 'users', - 'ignorable': false, - 'commands': commands, - 'api': api, - 'pages': web.getPages(dbot), - - 'listener': function(event) { - var knownUsers = getServerUsers(event.server); - var nick = event.user; - - if(event.action == 'JOIN') { - if(!_.has(knownUsers.channelUsers, event.channel.name)) { - knownUsers.channelUsers[event.channel.name] = []; + if(!_.include(knownUsers.users, newNick)) { + knownUsers.aliases[newNick] = event.user; } - var channelUsers = knownUsers.channelUsers[event.channel.name]; + } + } + }.bind(this); + this.on = ['JOIN', 'NICK']; + + this.onLoad = function() { + // Trigger updateNickLists to stat current users in channel + dbot.instance.addListener('366', 'users', function(event) { + var knownUsers = this.getServerUsers(event.server); + if(!_.has(knownUsers.channelUsers, event.channel.name)) { + knownUsers.channelUsers[event.channel.name] = []; + } + var channelUsers = knownUsers.channelUsers[event.channel.name]; - if(api.isKnownUser(event.server, nick)) { - nick = api.resolveUser(event.server, nick); + _.each(event.channel.nicks, function(nick) { + nick = nick.name; + if(this.api.isKnownUser(event.server, nick)) { + nick = this.api.resolveUser(event.server, nick); } else { knownUsers.users.push(nick); } if(!_.include(channelUsers, nick)) { channelUsers.push(nick); } - } else if(event.action == 'NICK') { - var newNick = event.params.substr(1); - if(_.has(knownUsers.aliases, event.user)) { - knownUsers.aliases[newNick] = knownUsers.aliases[event.user]; - } else { - if(!_.include(knownUsers.users, newNick)) { - knownUsers.aliases[newNick] = event.user; - } - } - } - }, - 'on': ['JOIN', 'NICK'], - - 'onLoad': function() { - // Trigger updateNickLists to stat current users in channel - var connections = dbot.instance.connections; - _.each(connections, function(connection) { - connection.updateNickLists(); - }); - } + }, this); + }.bind(this)); + + var connections = dbot.instance.connections; + _.each(connections, function(connection) { + connection.updateNickLists(); + }); }; }; exports.fetch = function(dbot) { - return users(dbot); + return new users(dbot); }; diff --git a/run.js b/run.js index ec8ebad..17b855d 100644 --- a/run.js +++ b/run.js @@ -194,6 +194,7 @@ DBot.prototype.reloadModules = function() { if(_.has(config, property) && _.has(config[property], itemName)) { _.extend(item, config[property][itemName]); } + module[property][itemName] = item.bind(module); }, this); _.extend(this[property], module[property]); }, this); From 96792d50087f425baaa009cdec23672c33d8b88f Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 22:03:58 +0000 Subject: [PATCH 149/347] Fixed doom function binding bug and transformed js module [#131] --- modules/js/js.js | 14 +++++--------- run.js | 3 ++- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/modules/js/js.js b/modules/js/js.js index 917e0a5..d6094ff 100644 --- a/modules/js/js.js +++ b/modules/js/js.js @@ -8,12 +8,11 @@ var vm = require('vm'); var sbox = require('sandbox'); var js = function(dbot) { - var s = new sbox(); - var commands = { // Run JS code sandboxed, return result to channel. '~js': function(event) { try { + var s = new sbox(); s.run(event.input[1], function(output) { event.reply(output.result); }.bind(this)); @@ -30,16 +29,13 @@ var js = function(dbot) { }; commands['~js'].regex = [/^~js (.*)/, 2]; commands['~ajs'].regex = [/^~ajs (.*)/, 2]; - commands['~ajs'].access = 'admin'; - return { - 'name': 'js', - 'ignorable': true, - 'commands': commands - }; + this.name = 'js'; + this.ignorable = true; + this.commands = commands; }; exports.fetch = function(dbot) { - return js(dbot); + return new js(dbot); }; diff --git a/run.js b/run.js index 17b855d..1141059 100644 --- a/run.js +++ b/run.js @@ -194,7 +194,8 @@ DBot.prototype.reloadModules = function() { if(_.has(config, property) && _.has(config[property], itemName)) { _.extend(item, config[property][itemName]); } - module[property][itemName] = item.bind(module); + module[property][itemName] = _.bind(item, module); + _.extend(module[property][itemName], item); }, this); _.extend(this[property], module[property]); }, this); From 1d5fcf2f401424923ccca932c209890f6d55b75b Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 22:34:47 +0000 Subject: [PATCH 150/347] Loads API functions into object according to module again. [#131] --- run.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/run.js b/run.js index 1141059..df3279e 100644 --- a/run.js +++ b/run.js @@ -197,7 +197,12 @@ DBot.prototype.reloadModules = function() { module[property][itemName] = _.bind(item, module); _.extend(module[property][itemName], item); }, this); - _.extend(this[property], module[property]); + + if(property == 'api') { + this[property][name] = module[property]; + } else { + _.extend(this[property], module[property]); + } }, this); // Load the module listener From 7a6cab841e12d4dd2dae97e762707ef414764cbe Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 23:00:16 +0000 Subject: [PATCH 151/347] fixed up kick [#131] --- modules/kick/kick.js | 58 +++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/modules/kick/kick.js b/modules/kick/kick.js index 3480583..ac5b792 100644 --- a/modules/kick/kick.js +++ b/modules/kick/kick.js @@ -50,40 +50,38 @@ var kick = function(dbot) { } }; - return { - 'name': 'kick', - 'ignorable': false, - 'commands': commands, - - 'listener': function(event) { - if(event.kickee == dbot.config.name) { - dbot.instance.join(event, event.channel); - event.reply(dbot.t('kicked_dbot', { 'botname': dbot.config.name })); - dbot.db.kicks[dbot.config.name] += 1; + this.name = 'kick'; + this.ignorable = false; + this.commands = commands; + + this.listener = function(event) { + if(event.kickee == dbot.config.name) { + dbot.instance.join(event, event.channel); + event.reply(dbot.t('kicked_dbot', { 'botname': dbot.config.name })); + dbot.db.kicks[dbot.config.name] += 1; + } else { + if(!_.has(dbot.db.kicks, event.kickee)) { + dbot.db.kicks[event.kickee] = 1; } else { - if(!_.has(dbot.db.kicks, event.kickee)) { - dbot.db.kicks[event.kickee] = 1; - } else { - dbot.db.kicks[event.kickee] += 1; - } - - if(!_.has(dbot.db.kickers, event.user)) { - dbot.db.kickers[event.user] = 1; - } else { - dbot.db.kickers[event.user] += 1; - } - - event.reply(event.kickee + '-- (' + dbot.t('user_kicks', { - 'user': event.kickee, - 'kicks': dbot.db.kicks[event.kickee], - 'kicked': dbot.db.kickers[event.kickee] - }) + ')'); + dbot.db.kicks[event.kickee] += 1; } - }, - on: 'KICK' + + if(!_.has(dbot.db.kickers, event.user)) { + dbot.db.kickers[event.user] = 1; + } else { + dbot.db.kickers[event.user] += 1; + } + + event.reply(event.kickee + '-- (' + dbot.t('user_kicks', { + 'user': event.kickee, + 'kicks': dbot.db.kicks[event.kickee], + 'kicked': dbot.db.kickers[event.kickee] + }) + ')'); + } }; + this.on = 'KICK'; }; exports.fetch = function(dbot) { - return kick(dbot); + return new kick(dbot); }; From f532aee4ab27e9df9a1f441feb27bcf9a08aafa5 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 23:02:55 +0000 Subject: [PATCH 152/347] fix up ignore [#131] --- modules/ignore/ignore.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/modules/ignore/ignore.js b/modules/ignore/ignore.js index a3c99cd..b224777 100644 --- a/modules/ignore/ignore.js +++ b/modules/ignore/ignore.js @@ -72,22 +72,20 @@ var ignore = function(dbot) { } }; - return { - 'name': 'ignore', - 'ignorable': false, - 'commands': commands, + this.name = 'ignore'; + this.ignorable = false; + this.commands = commands; - 'onLoad': function() { - dbot.instance.clearIgnores(); - _.each(dbot.db.ignores, function(ignores, user) { - _.each(ignores, function(ignore) { - dbot.instance.ignoreTag(user, ignore); - }, this); + this.onLoad = function() { + dbot.instance.clearIgnores(); + _.each(dbot.db.ignores, function(ignores, user) { + _.each(ignores, function(ignore) { + dbot.instance.ignoreTag(user, ignore); }, this); - } + }, this); }; }; exports.fetch = function(dbot) { - return ignore(dbot); + return new ignore(dbot); }; From b733564cb2e38bad6b4cace8d66b774101101d69 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 14 Jan 2013 23:11:50 +0000 Subject: [PATCH 153/347] fixt link [#131] --- modules/link/link.js | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/modules/link/link.js b/modules/link/link.js index 0c275eb..9965da6 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -7,9 +7,9 @@ var request = require('request'), _ = require('underscore')._; var link = function(dbot) { - var urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; - var links = {}; - var fetchTitle = function(event, link) { + this.urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; + this.links = {}; + this.fetchTitle = function(event, link) { request(link, function (error, response, body) { if(!error && response.statusCode == 200) { body = body.replace(/(\r\n|\n\r|\n)/gm, " "); @@ -23,36 +23,34 @@ var link = function(dbot) { var commands = { '~title': function(event) { - var link = links[event.channel.name]; - if(_.isUndefined(event.params[1])) { - var urlMatches = event.params[1].match(urlRegex); + var link = this.links[event.channel.name]; + if(!_.isUndefined(event.params[1])) { + var urlMatches = event.params[1].match(this.urlRegex); if(urlMatches !== null) { link = urlMatches[0]; } } - fetchTitle(event, link); + this.fetchTitle(event, link); } }; - return { - 'name': 'link', - 'ignorable': true, - 'commands': commands, + this.name = 'link'; + this.ignorable = true; + this.commands = commands; - 'listener': function(event) { - var urlMatches = event.message.match(urlRegex); - if(urlMatches !== null) { - links[event.channel.name] = urlMatches[0]; + this.listener = function(event) { + var urlMatches = event.message.match(this.urlRegex); + if(urlMatches !== null) { + this.links[event.channel.name] = urlMatches[0]; - if(dbot.config.link.autoTitle == true) { - fetchTitle(event, urlMatches[0]); - } + if(dbot.config.link.autoTitle == true) { + this.fetchTitle(event, urlMatches[0]); } - }, - 'on': 'PRIVMSG' - }; + } + }.bind(this); + this.on = 'PRIVMSG'; }; exports.fetch = function(dbot) { - return link(dbot); + return new link(dbot); }; From 0a3d1b6f9e9914e23aebe3e2248fdfd0330a003a Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 13:58:13 +0000 Subject: [PATCH 154/347] Fixed web loading and hot refresh of pages [#131] --- modules/users/{web.js => pages.js} | 2 +- modules/web/web.js | 26 ++++++++++++-------------- run.js | 13 ++----------- 3 files changed, 15 insertions(+), 26 deletions(-) rename modules/users/{web.js => pages.js} (99%) diff --git a/modules/users/web.js b/modules/users/pages.js similarity index 99% rename from modules/users/web.js rename to modules/users/pages.js index 4ea2e8a..015d7ba 100644 --- a/modules/users/web.js +++ b/modules/users/pages.js @@ -103,6 +103,6 @@ var pages = function(dbot) { }; }; -exports.getPages = function(dbot) { +exports.fetch = function(dbot) { return pages(dbot); }; diff --git a/modules/web/web.js b/modules/web/web.js index b3e632b..2bc7b28 100644 --- a/modules/web/web.js +++ b/modules/web/web.js @@ -3,6 +3,13 @@ var express = require('express'), fs = require('fs'); var webInterface = function(dbot) { + this.name = 'web'; + this.ignorable = false; + + this.onDestroy = function() { + server.close(); + } + var pub = 'public'; var app = express(); @@ -15,7 +22,8 @@ var webInterface = function(dbot) { var server = app.listen(dbot.config.web.webPort); - var reloadPages = function(pages) { + this.reloadPages = function() { + var pages = dbot.pages; for(var p in pages) { if(_.has(pages, p)) { var func = pages[p]; @@ -25,26 +33,16 @@ var webInterface = function(dbot) { var shim = Object.create(resp); shim.render = (function(view, one, two) { // Render with express.js - resp.render(this.module.name + '/' + view, one, two); + resp.render(this.module + '/' + view, one, two); }).bind(this); shim.render_core = resp.render; this.call(this.module, req, shim); }).bind(func)); } } - }; - - return { - 'name': 'web', - 'ignorable': false, - 'reloadPages': reloadPages, - - 'onDestroy': function() { - server.close(); - } - }; + }.bind(this); }; exports.fetch = function(dbot) { - return webInterface(dbot); + return new webInterface(dbot); }; diff --git a/run.js b/run.js index df3279e..156ba3b 100644 --- a/run.js +++ b/run.js @@ -244,20 +244,11 @@ DBot.prototype.reloadModules = function() { } }.bind(this)); - this.reloadPages(); + if(_.has(this.modules, 'web')) this.modules.web.reloadPages(); + this.save(); }; -// I honestly don't know what the fuck this is meant to do. Why is it getting a -// reference to all the pages? -DBot.prototype.reloadPages = function() { - _.each(this.modules, function(module) { - if(_.isFunction(module.reloadPages)) { - module.reloadPages(this.pages); - } - }, this); -} - DBot.prototype.cleanNick = function(key) { key = key.toLowerCase(); while(key.endsWith("_")) { From a9bae98ae8874bb87e1b47095b4a7e7803e989cd Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 14:47:46 +0000 Subject: [PATCH 155/347] transform quotes [#131] --- modules/quotes/commands.js | 235 +++++++++++++++++++++ modules/quotes/pages.js | 29 +++ modules/quotes/quotes.js | 416 ++++++++----------------------------- 3 files changed, 351 insertions(+), 329 deletions(-) create mode 100644 modules/quotes/commands.js create mode 100644 modules/quotes/pages.js diff --git a/modules/quotes/commands.js b/modules/quotes/commands.js new file mode 100644 index 0000000..c6061ad --- /dev/null +++ b/modules/quotes/commands.js @@ -0,0 +1,235 @@ +var _ = require('underscore')._; + +var commands = function(dbot) { + var commands = { + // Alternative syntax to ~q + '~': function(event) { + commands['~q'].bind(this)(event); + }, + + '~rmstatus': function(event) { + var rmCacheCount = this.rmCache.length; + if(rmCacheCount < dbot.config.quotes.rmLimit) { + event.reply(dbot.t('quote_cache_auto_remove', + { 'count': rmCacheCount })); + } else { + event.reply(dbot.t('quote_cache_manual_remove', + { 'count': rmCacheCount })); + } + }, + + '~rmconfirm': function(event) { + var rmCacheCount = this.rmCache.length; + this.rmCache.length = 0; + event.reply(dbot.t('quote_cache_cleared', + { 'count': rmCacheCount })); + }, + + '~rmdeny': function(event) { + var quotes = this.quotes; + var rmCache = this.rmCache; + var rmCacheCount = rmCache.length; + for(var i=0;i<rmCacheCount;i++) { + if(!_.has(quotes, rmCache[i].key)) { + quotes[rmCache[i].key] = []; + } + quotes[rmCache[i].key].push(rmCache[i].quote); + } + rmCache.length = 0; + + event.reply(dbot.t('quote_cache_reinstated', + { 'count': rmCacheCount })); + }, + + + // Retrieve quote from a category in the database. + '~q': function(event) { + var key = event.input[1].trim().toLowerCase(); + var quote = this.api.getQuote(event, event.input[1]); + if(quote) { + event.reply(key + ': ' + quote); + } else { + event.reply(dbot.t('category_not_found', {'category': key})); + } + }, + + // Shows a list of the biggest categories + '~qstats': function(event) { + var quotes = this.quotes; + var qSizes = _.chain(quotes) + .pairs() + .sortBy(function(category) { return category[1].length }) + .reverse() + .first(10) + .value(); + + var qString = dbot.t('large_categories'); + for(var i=0;i<qSizes.length;i++) { + qString += qSizes[i][0] + " (" + qSizes[i][1].length + "), "; + } + + event.reply(qString.slice(0, -2)); + }, + + // Search a given category for some text. + // TODO fix + '~qsearch': function(event) { + var quotes = this.quotes; + var haystack = event.input[1].trim().toLowerCase(); + var needle = event.input[2]; + if(_.has(quotes, haystack)) { + var matches = _.filter(quotes[haystack], function(quote) { + return _.indexOf(quote, needle) != -1; + }, 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(event) { + var quotes = this.quotes; + if(this.rmAllowed == true || _.include(dbot.config.admins, event.user)) { + var key = event.input[1].trim().toLowerCase(); + if(_.has(quotes, key)) { + var quote = quotes[key].pop(); + if(quotes[key].length === 0) { + delete quotes[key]; + } + this.internalAPI.resetRemoveTimer(event, key, quote); + + event.reply(dbot.t('removed_from', { + 'quote': quote, + 'category': key + })); + } else { + event.reply(dbot.t('no_quotes', {'category': q[1]})); + } + } else { + event.reply(dbot.t('rmlast_spam')); + } + }, + + '~rm': function(event) { + if(this.rmAllowed == true || _.include(dbot.config.admins, event.user)) { + var quotes = this.quotes; + var key = event.input[1].trim().toLowerCase(); + var quote = event.input[2]; + + if(_.has(quotes, key)) { + var category = quotes[key]; + var index = category.indexOf(quote); + if(index !== -1) { + category.splice(index, 1); + if(category.length === 0) { + delete quotes[key]; + } + this.internalAPI.resetRemoveTimer(event, key, quote); + + event.reply(dbot.t('removed_from', {'category': key, 'quote': quote})); + } else { + event.reply(dbot.t('q_not_exist_under', {'category': key, 'quote': quote})); + } + } else { + event.reply(dbot.t('category_not_found', {'category': key})); + } + } else { + event.reply(dbot.t('rmlast_spam')); + } + }, + + '~qcount': function(event) { + var input = event.message.valMatch(/^~qcount ([\d\w\s-]*)/, 2); + var quotes = this.quotes; + if(input) { // Give quote count for named category + var key = input[1].trim().toLowerCase(); + if(_.has(quotes, key)) { + event.reply(dbot.t('quote_count', { + 'category': key, + 'count': quotes[key].length + })); + } else { + event.reply(dbot.t('no_quotes', { 'category': key })); + } + } else { // Give total quote count + var totalQuoteCount = _.reduce(quotes, function(memo, category) { + return memo + category.length; + }, 0); + event.reply(dbot.t('total_quotes', { 'count': totalQuoteCount })); + } + }, + + '~qadd': function(event) { + var quotes = this.quotes; + var key = event.input[1].toLowerCase(); + var text = event.input[2]; + if(!_.isArray(quotes[key])) { + quotes[key] = []; + } + + if(_.include(quotes[key], text)) { + event.reply(dbot.t('quote_exists')); + } else { + quotes[key].push(text); + this.rmAllowed = true; + event.reply(dbot.t('quote_saved', { + 'category': key, + 'count': quotes[key].length + })); + + // TODO hook + if(_.has(dbot.api, 'dent')) { + dbot.api.dent.post(key + ': ' + text); + } + } + }, + + '~rq': function(event) { + var quotes = this.quotes; + var category = _.keys(quotes)[_.random(0, _.size(quotes) -1)]; + event.reply(category + ': ' + this.internalAPI.interpolatedQuote(event, category)); + }, + + '~link': function(event) { + var key = event.params[1].trim().toLowerCase(); + if(_.has(this.quotes, key)) { + event.reply(dbot.t('quote_link', { + 'category': key, + 'url': dbot.t('url', { + 'host': dbot.config.web.webHost, + 'port': dbot.config.web.webPort, + 'path': 'quotes/' + key + }) + })); + } else { + event.reply(dbot.t('category_not_found', { 'category': key })); + } + }, + }; + + commands['~'].regex = [/^~([\d\w\s-]*)/, 2]; + commands['~q'].regex = [/^~q ([\d\w\s-]*)/, 2]; + commands['~qsearch'].regex = [/^~qsearch ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; + commands['~rm'].regex = [/^~rm ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; + commands['~rmlast'].regex = [/^~rmlast ([\d\w\s-]*)/, 2]; + commands['~qadd'].regex = [/^~qadd ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; + + commands['~rmconfirm'].access = 'moderator'; + commands['~rmdeny'].access = 'moderator'; + + return commands; +}; + +exports.fetch = function(dbot) { + return commands(dbot); +}; diff --git a/modules/quotes/pages.js b/modules/quotes/pages.js new file mode 100644 index 0000000..7800cd0 --- /dev/null +++ b/modules/quotes/pages.js @@ -0,0 +1,29 @@ +var _ = require('underscore')._; +var pages = function(dbot) { + return { + // Lists quotes in a category + '/quotes/:key': function(req, res) { + var key = req.params.key.toLowerCase(); + if(_.has(dbot.db.quoteArrs, key)) { + res.render('quotes', { 'name': dbot.config.name, 'quotes': dbot.db.quoteArrs[key], locals: { 'url_regex': RegExp.prototype.url_regex() } }); + } else { + res.render('error', { 'name': dbot.config.name, 'message': 'No quotes under that key.' }); + } + }, + + // Show quote list. + '/quotes': function(req, res) { + res.render('quotelist', { 'name': dbot.config.name, 'quotelist': Object.keys(dbot.db.quoteArrs) }); + }, + + // Load random quote category page + '/rq': function(req, res) { + var rCategory = Object.keys(dbot.db.quoteArrs).random(); + res.render('quotes', { 'name': dbot.config.name, 'quotes': dbot.db.quoteArrs[rCategory], locals: { 'url_regex': RegExp.prototype.url_regex() } }); + } + } +}; + +exports.fetch = function(dbot) { + return pages(dbot); +}; diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index 70cb9c1..d6fca8c 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -1,70 +1,75 @@ var _ = require('underscore')._; var quotes = function(dbot) { - var quotes = dbot.db.quoteArrs, - addStack = [], - rmAllowed = true, - rmCache = dbot.sessionData.rmCache, - rmTimer; + this.name = 'quotes'; + this.ignorable = true; + + this.quotes = dbot.db.quoteArrs, + this.addStack = [], + this.rmAllowed = true, + this.rmCache = dbot.sessionData.rmCache, + this.rmTimer; dbot.sessionData.rmCache = []; - // Retrieve a random quote from a given category, interpolating any quote - // references (~~QUOTE CATEGORY~~) within it - var interpolatedQuote = function(event, key, quoteTree) { - if(!_.isUndefined(quoteTree) && quoteTree.indexOf(key) != -1) { - return ''; - } else if(_.isUndefined(quoteTree)) { - quoteTree = []; - } - - var index = _.random(0, quotes[key].length - 1); - var quoteString = quotes[key][index]; - - // Parse quote interpolations - var quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/g); - var thisRef; - - while(quoteRefs && (thisRef = quoteRefs.shift()) !== undefined) { - var cleanRef = dbot.cleanNick(thisRef.replace(/^~~/,'').replace(/~~$/,'').trim()); - if(cleanRef === '-nicks-') { - var randomNick = _.keys(event.channel.nicks)[_.random(0, _.size(event.channel.nicks) -1)]; - quoteString = quoteString.replace("~~" + cleanRef + "~~", randomNick); - quoteTree.pop(); - } else if(_.has(quotes, cleanRef)) { - quoteTree.push(key); - quoteString = quoteString.replace("~~" + cleanRef + "~~", - interpolatedQuote(event, cleanRef, quoteTree.slice())); - quoteTree.pop(); + this.internalAPI = { + // Retrieve a random quote from a given category, interpolating any quote + // references (~~QUOTE CATEGORY~~) within it + 'interpolatedQuote': function(event, key, quoteTree) { + if(!_.isUndefined(quoteTree) && quoteTree.indexOf(key) != -1) { + return ''; + } else if(_.isUndefined(quoteTree)) { + quoteTree = []; } - } - return quoteString; + var index = _.random(0, this.quotes[key].length - 1); + var quoteString = this.quotes[key][index]; + + // Parse quote interpolations + var quoteRefs = quoteString.match(/~~([\d\w\s-]*)~~/g); + var thisRef; + + while(quoteRefs && (thisRef = quoteRefs.shift()) !== undefined) { + var cleanRef = dbot.cleanNick(thisRef.replace(/^~~/,'').replace(/~~$/,'').trim()); + if(cleanRef === '-nicks-') { + var randomNick = _.keys(event.channel.nicks)[_.random(0, _.size(event.channel.nicks) -1)]; + quoteString = quoteString.replace("~~" + cleanRef + "~~", randomNick); + quoteTree.pop(); + } else if(_.has(this.quotes, cleanRef)) { + quoteTree.push(key); + quoteString = quoteString.replace("~~" + cleanRef + "~~", + interpolatedQuote(event, cleanRef, quoteTree.slice())); + quoteTree.pop(); + } + } + + return quoteString; + }.bind(this), + + 'resetRemoveTimer': function(event, key, quote) { + this.rmAllowed = false; + dbot.timers.addOnceTimer(5000, function() { + this.rmAllowed = true; + }); + + this.rmCache.push({ + 'key': key, + 'quote': quote + }); + dbot.timers.clearTimeout(this.rmTimer); + + if(this.rmCache.length < dbot.config.quotes.rmLimit) { + this.rmTimer = dbot.timers.addOnceTimer(600000, function() { + this.rmCache.length = 0; // lol what + }); + } else { + _.each(dbot.config.admins, function(admin) { + dbot.say(event.server, admin, dbot.t('rm_cache_limit')); + }); + } + }.bind(this) }; - var resetRemoveTimer = function(event, key, quote) { - rmAllowed = false; - dbot.timers.addOnceTimer(5000, function() { - rmAllowed = true; - }); - - rmCache.push({ - 'key': key, - 'quote': quote - }); - dbot.timers.clearTimeout(rmTimer); - - if(rmCache.length < dbot.config.quotes.rmLimit) { - rmTimer = dbot.timers.addOnceTimer(600000, function() { - rmCache.length = 0; // lol what - }); - } else { - _.each(dbot.config.admins, function(admin) { - dbot.say(event.server, admin, dbot.t('rm_cache_limit')); - }); - } - }; - - var api = { + this.api = { 'getQuote': function(event, category) { var key = category.trim().toLowerCase(); var altKey; @@ -73,288 +78,41 @@ var quotes = function(dbot) { } if(key.charAt(0) !== '_') { // lol - if(_.has(quotes, key)) { - return interpolatedQuote(event, key); - } else if(_.has(quotes, altKey)) { - return interpolatedQuote(event, altKey); + if(_.has(this.quotes, key)) { + return this.internalAPI.interpolatedQuote(event, key); + } else if(_.has(this.quotes, altKey)) { + return this.internalAPI.interpolatedQuote(event, altKey); } else { return false; } } } }; - - var commands = { - // Alternative syntax to ~q - '~': function(event) { - commands['~q'](event); - }, - - '~rmstatus': function(event) { - var rmCacheCount = rmCache.length; - if(rmCacheCount < dbot.config.quotes.rmLimit) { - event.reply(dbot.t('quote_cache_auto_remove', - { 'count': rmCacheCount })); + + this.listener = function(event) { + if(event.action == 'PRIVMSG') { + if(event.user == 'reality') { + var once = event.message.valMatch(/^I ([\d\w\s,'-]* once)/, 2); } else { - event.reply(dbot.t('quote_cache_manual_remove', - { 'count': rmCacheCount })); - } - }, - - '~rmconfirm': function(event) { - var rmCacheCount = rmCache.length; - rmCache.length = 0; - event.reply(dbot.t('quote_cache_cleared', - { 'count': rmCacheCount })); - }, - - '~rmdeny': function(event) { - var rmCacheCount = rmCache.length; - for(var i=0;i<rmCacheCount;i++) { - if(!_.has(quotes, rmCache[i].key)) { - quotes[rmCache[i].key] = []; - } - quotes[rmCache[i].key].push(rmCache[i].quote); - } - rmCache.length = 0; - - event.reply(dbot.t('quote_cache_reinstated', - { 'count': rmCacheCount })); - }, - - - // Retrieve quote from a category in the database. - '~q': function(event) { - var key = event.input[1].trim().toLowerCase(); - var quote = api.getQuote(event, event.input[1]); - if(quote) { - event.reply(key + ': ' + quote); - } else { - event.reply(dbot.t('category_not_found', {'category': key})); - } - }, - - // Shows a list of the biggest categories - '~qstats': function(event) { - var qSizes = _.chain(quotes) - .pairs() - .sortBy(function(category) { return category[1].length }) - .reverse() - .first(10) - .value(); - - var qString = dbot.t('large_categories'); - for(var i=0;i<qSizes.length;i++) { - qString += qSizes[i][0] + " (" + qSizes[i][1].length + "), "; + var once = event.message.valMatch(/^reality ([\d\w\s,'-]* once)/, 2); } - event.reply(qString.slice(0, -2)); - }, - - // Search a given category for some text. - '~qsearch': function(event) { - var haystack = event.input[1].trim().toLowerCase(); - var needle = event.input[2]; - if(_.has(quotes, haystack)) { - var matches = _.filter(quotes[haystack], function(quote) { - return _.indexOf(quote, needle) != -1; - }, 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')); + if(once) { + event.message = '~qadd realityonce=reality ' + once[1]; + event.action = 'PRIVMSG'; + event.params = event.message.split(' '); + dbot.instance.emit(event); + } + } else if(event.action == 'JOIN') { + var userQuote = this.api.getQuote(event, event.user) + if(userQuote) { + event.reply(event.user + ': ' + this.api.getQuote(event, event.user)); } - }, - - '~rmlast': function(event) { - if(rmAllowed == true || _.include(dbot.config.admins, event.user)) { - var key = event.input[1].trim().toLowerCase(); - if(_.has(quotes, key)) { - var quote = quotes[key].pop(); - if(quotes[key].length === 0) { - delete quotes[key]; - } - resetRemoveTimer(event, key, quote); - - event.reply(dbot.t('removed_from', { - 'quote': quote, - 'category': key - })); - } else { - event.reply(dbot.t('no_quotes', {'category': q[1]})); - } - } else { - event.reply(dbot.t('rmlast_spam')); - } - }, - - '~rm': function(event) { - if(rmAllowed == true || _.include(dbot.config.admins, event.user)) { - var key = event.input[1].trim().toLowerCase(); - var quote = event.input[2]; - - if(_.has(quotes, key)) { - var category = quotes[key]; - var index = category.indexOf(quote); - if(index !== -1) { - category.splice(index, 1); - if(category.length === 0) { - delete quotes[key]; - } - resetRemoveTimer(event, key, quote); - - event.reply(dbot.t('removed_from', {'category': key, 'quote': quote})); - } else { - event.reply(dbot.t('q_not_exist_under', {'category': key, 'quote': quote})); - } - } else { - event.reply(dbot.t('category_not_found', {'category': key})); - } - } else { - event.reply(dbot.t('rmlast_spam')); - } - }, - - '~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(_.has(quotes, key)) { - event.reply(dbot.t('quote_count', { - 'category': key, - 'count': quotes[key].length - })); - } else { - event.reply(dbot.t('no_quotes', { 'category': key })); - } - } else { // Give total quote count - var totalQuoteCount = _.reduce(quotes, function(memo, category) { - return memo + category.length; - }, 0); - event.reply(dbot.t('total_quotes', { 'count': totalQuoteCount })); - } - }, - - '~qadd': function(event) { - var key = event.input[1].toLowerCase(); - var text = event.input[2]; - if(!_.isArray(quotes[key])) { - quotes[key] = []; - } - - if(_.include(quotes[key], text)) { - event.reply(dbot.t('quote_exists')); - } else { - quotes[key].push(text); - rmAllowed = true; - event.reply(dbot.t('quote_saved', { - 'category': key, - 'count': quotes[key].length - })); - - // TODO hook - if(_.has(dbot.api, 'dent')) { - dbot.api.dent.post(key + ': ' + text); - } - } - }, - - '~rq': function(event) { - var category = _.keys(quotes)[_.random(0, _.size(quotes) -1)]; - event.reply(category + ': ' + interpolatedQuote(event, category)); - }, - - '~link': function(event) { - var key = event.params[1].trim().toLowerCase(); - if(_.has(quotes, key)) { - event.reply(dbot.t('quote_link', { - 'category': key, - 'url': dbot.t('url', { - 'host': dbot.config.web.webHost, - 'port': dbot.config.web.webPort, - 'path': 'quotes/' + key - }) - })); - } else { - event.reply(dbot.t('category_not_found', { 'category': key })); - } - }, - }; - - commands['~'].regex = [/^~([\d\w\s-]*)/, 2]; - commands['~q'].regex = [/^~q ([\d\w\s-]*)/, 2]; - commands['~qsearch'].regex = [/^~qsearch ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; - commands['~rm'].regex = [/^~rm ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; - commands['~rmlast'].regex = [/^~rmlast ([\d\w\s-]*)/, 2]; - commands['~qadd'].regex = [/^~qadd ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; - - commands['~rmconfirm'].access = 'moderator'; - commands['~rmdeny'].access = 'moderator'; - - var pages = { - // Lists quotes in a category - '/quotes/:key': function(req, res) { - var key = req.params.key.toLowerCase(); - if(_.has(dbot.db.quoteArrs, key)) { - res.render('quotes', { 'name': dbot.config.name, 'quotes': dbot.db.quoteArrs[key], locals: { 'url_regex': RegExp.prototype.url_regex() } }); - } else { - res.render('error', { 'name': dbot.config.name, 'message': 'No quotes under that key.' }); - } - }, - - // Show quote list. - '/quotes': function(req, res) { - res.render('quotelist', { 'name': dbot.config.name, 'quotelist': Object.keys(dbot.db.quoteArrs) }); - }, - - // Load random quote category page - '/rq': function(req, res) { - var rCategory = Object.keys(dbot.db.quoteArrs).random(); - res.render('quotes', { 'name': dbot.config.name, 'quotes': dbot.db.quoteArrs[rCategory], locals: { 'url_regex': RegExp.prototype.url_regex() } }); - }, - }; - - return { - 'name': 'quotes', - 'ignorable': true, - 'commands': commands, - 'pages': pages, - 'api': api, - - 'listener': function(event) { - if(event.action == 'PRIVMSG') { - if(event.user == 'reality') { - var once = event.message.valMatch(/^I ([\d\w\s,'-]* once)/, 2); - } else { - var once = event.message.valMatch(/^reality ([\d\w\s,'-]* once)/, 2); - } - - if(once) { - event.message = '~qadd realityonce=reality ' + once[1]; - event.action = 'PRIVMSG'; - event.params = event.message.split(' '); - dbot.instance.emit(event); - } - } else if(event.action == 'JOIN') { - var userQuote = api.getQuote(event, event.user) - if(userQuote) { - event.reply(event.user + ': ' + api.getQuote(event, event.user)); - } - } - }, - 'on': ['PRIVMSG', 'JOIN'] - }; + } + }.bind(this); + this.on = ['PRIVMSG', 'JOIN']; }; exports.fetch = function(dbot) { - return quotes(dbot); + return new quotes(dbot); }; From a591071b1a8579e9268519867270d4631b5403fc Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 14:51:07 +0000 Subject: [PATCH 156/347] qhoops! --- modules/quotes/quotes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index d6fca8c..c2145e1 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -4,12 +4,12 @@ var quotes = function(dbot) { this.name = 'quotes'; this.ignorable = true; + dbot.sessionData.rmCache = []; this.quotes = dbot.db.quoteArrs, this.addStack = [], this.rmAllowed = true, this.rmCache = dbot.sessionData.rmCache, this.rmTimer; - dbot.sessionData.rmCache = []; this.internalAPI = { // Retrieve a random quote from a given category, interpolating any quote From 44764cd2b34aaf2cfff20ab357f170d0b5f97710 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Tue, 15 Jan 2013 15:10:28 +0000 Subject: [PATCH 157/347] Modified users web to call new stats API [Close #137] --- modules/users/pages.js | 36 ++++++++++++++++-------------------- views/users/users.jade | 30 +++++++++++++++--------------- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/modules/users/pages.js b/modules/users/pages.js index 015d7ba..cbc14f6 100644 --- a/modules/users/pages.js +++ b/modules/users/pages.js @@ -1,4 +1,5 @@ var pages = function(dbot) { + var _ = require('underscore')._; var connections = dbot.instance.connections; return { @@ -26,30 +27,25 @@ var pages = function(dbot) { connections[connection].channels.hasOwnProperty(channel)) { var userData = { "active": [], "inactive": [], "offline": []}; - var channelUsers = dbot.db.knownUsers[connection].channelUsers[channel]; - - var onlineNicks = connections[connection].channels[channel].nicks; - for(var i=0;i<channelUsers.length;i++) { - if(channelUsers[i] == dbot.config.name){ - continue; - } - - var user = dbot.api.stats.getUserStats(connection, channelUsers[i], channel); - if(onlineNicks.hasOwnProperty(channelUsers[i])){ - if(dbot.api.stats.isActive({'server': connection, - 'user': channelUsers[i], - 'channel': channel - })){ - userData.active.push(user); + + var reply = dbot.api.stats.getChanUsersStats(connection, channel, [ + "lines", "words", "lincent", "wpl", "in_mentions" + ]); + _.each(reply.users, function(user, userName){ + if(userName != dbot.config.name){ + if(user.online){ + if(user.active){ + userData.active.push(user); + } + else{ + userData.inactive.push(user); + } } else{ - userData.inactive.push(user); + userData.offline.push(user); } } - else{ - userData.offline.push(user); - } - } + }); var userSort = function(a, b){ var x = a.display.toLowerCase(); diff --git a/views/users/users.jade b/views/users/users.jade index f0c345d..9a5da2a 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -23,15 +23,15 @@ block content span span.label.label-success Active td - #{nick.total_lines} + #{nick.fields.lines.data} td - #{nick.total_words} + #{nick.fields.words.data} td - #{nick.lincent} + #{nick.fields.lincent.data} td - #{nick.wpl} + #{nick.fields.wpl.data} td - #{nick.in_mentions} + #{nick.fields.in_mentions.data} -each nick in nicks.inactive tr td @@ -40,15 +40,15 @@ block content span span.label.label-important Inactive td - #{nick.total_lines} + #{nick.fields.lines.data} td - #{nick.total_words} + #{nick.fields.words.data} td - #{nick.lincent} + #{nick.fields.lincent.data} td - #{nick.wpl} + #{nick.fields.wpl.data} td - #{nick.in_mentions} + #{nick.fields.in_mentions.data} -each nick in nicks.offline tr td @@ -57,12 +57,12 @@ block content span span.label Offline td - #{nick.total_lines} + #{nick.fields.lines.data} td - #{nick.total_words} + #{nick.fields.words.data} td - #{nick.lincent} + #{nick.fields.lincent.data} td - #{nick.wpl} + #{nick.fields.wpl.data} td - #{nick.in_mentions} + #{nick.fields.in_mentions.data} From fbb60306d56effa650a2a0dab7317e25ca80c452 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 15:32:44 +0000 Subject: [PATCH 158/347] fix binding bug --- modules/quotes/quotes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index c2145e1..3cd13b2 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -60,7 +60,7 @@ var quotes = function(dbot) { if(this.rmCache.length < dbot.config.quotes.rmLimit) { this.rmTimer = dbot.timers.addOnceTimer(600000, function() { this.rmCache.length = 0; // lol what - }); + }.bind(this)); } else { _.each(dbot.config.admins, function(admin) { dbot.say(event.server, admin, dbot.t('rm_cache_limit')); From 126810f180c67735ddecb760e63769692dda87e5 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 15:34:47 +0000 Subject: [PATCH 159/347] update stats! A+ work @samstudio8 [#131] --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index a803be3..31781a9 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit a803be39a19a09bed1fcb0586a882b046ae29c99 +Subproject commit 31781a9e646028bc6872e7c39b6e3e31c6b2cbb1 From 6896536a3b1c2946c2621369afd04c395d7b11aa Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 15:43:02 +0000 Subject: [PATCH 160/347] redo youare [#131] --- modules/youare/youare.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/modules/youare/youare.js b/modules/youare/youare.js index ddb25e0..89fa4f3 100644 --- a/modules/youare/youare.js +++ b/modules/youare/youare.js @@ -1,19 +1,17 @@ var youAre = function(dbot) { - return { - 'name': 'youare', - 'ignorable': false, + this.name = 'youare'; + this.ignorable = false; - 'listener': function(event) { - var key = event.message.valMatch(/(\bis\b|\bare\b)\s+([\w\s\d]*?)(\s+)?(,|\.|\band\b|$)/, 5); + this.listener = function(event) { + 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] + '.'); - } - }, - 'on': 'PRIVMSG' - }; + if(key && key[2] != "" && Number.prototype.chanceIn(1, 100) && event.user != 'aisbot') { + event.reply(event.user + ': You\'re ' + key[2] + '.'); + } + }.bind(this); + this.on = 'PRIVMSG'; }; exports.fetch = function(dbot) { - return youAre(dbot); + return new youAre(dbot); }; From 478d344fe2ab4489223fd6ec8abc432c0b426c0b Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 16:05:04 +0000 Subject: [PATCH 161/347] Fix up spelling [#131] --- modules/spelling/spelling.js | 61 ++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/modules/spelling/spelling.js b/modules/spelling/spelling.js index 5c955ef..23db3cc 100644 --- a/modules/spelling/spelling.js +++ b/modules/spelling/spelling.js @@ -74,9 +74,13 @@ var distance = function(s1, s2) { }; var spelling = function(dbot) { - var last = {}; - var correct = function (event, correction, candidate, output_callback) { - var rawCandidates = allGroupings(last[event.channel.name][candidate].split(' ')); + this.name = 'spelling'; + this.ignorable = true; + + this.last = {}; + this.internalAPI = {}; + this.internalAPI.correct = function (event, correction, candidate, output_callback) { + var rawCandidates = allGroupings(this.last[event.channel.name][candidate].split(' ')); var candidates = []; for(var i=0;i<rawCandidates.length;i++) { @@ -95,11 +99,11 @@ var spelling = function(dbot) { if(winnerDistance < Math.ceil(winner.length * 1.33)) { if(winner !== correction) { - var fix = last[event.channel.name][candidate].replace(winner, correction); + var fix = this.last[event.channel.name][candidate].replace(winner, correction); if (/^.ACTION/.test(fix)) { fix = fix.replace(/^.ACTION/, '/me'); } - last[event.channel.name][candidate] = fix; + this.last[event.channel.name][candidate] = fix; var output = { 'fix': fix, 'correcter': event.user, @@ -108,36 +112,31 @@ var spelling = function(dbot) { output_callback(output); } } - } - - return { - 'name': 'spelling', - 'ignorable': true, + }.bind(this); - '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); - 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)); - }); + this.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); + if(q) { + this.internalAPI.correct(event, q[1] || q[2], event.user, function (e) { + event.reply(dbot.t('spelling_self', e)); + }); + } else if(otherQ) { + this.internalAPI.correct(event, otherQ[2] || otherQ[3], otherQ[1], function (e) { + event.reply(dbot.t('spelling_other', e)); + }); + } else { + if(_.has(this.last, event.channel.name)) { + this.last[event.channel.name][event.user] = event.message; } else { - if(_.has(last, event.channel.name)) { - last[event.channel.name][event.user] = event.message; - } else { - last[event.channel.name] = { }; - last[event.channel.name][event.user] = event.message; - } + this.last[event.channel.name] = { }; + this.last[event.channel.name][event.user] = event.message; } - }, - 'on': 'PRIVMSG' - } + } + }.bind(this); + this.on = 'PRIVMSG'; } exports.fetch = function(dbot) { - return spelling(dbot); + return new spelling(dbot); }; From 529194e4df15733608b1213ab6267c63a3d71277 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 16:09:57 +0000 Subject: [PATCH 162/347] transform dice [#131] --- modules/dice/dice.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/dice/dice.js b/modules/dice/dice.js index 172822b..e45385a 100644 --- a/modules/dice/dice.js +++ b/modules/dice/dice.js @@ -93,13 +93,11 @@ var dice = function(dbot) { } }; - return { - 'name': 'dice', - 'commands': commands, - 'ignorable': true - }; + this.name = 'dice'; + this.commands = commands; + this.ignorable = true; } exports.fetch = function(dbot) { - return dice(dbot); + return new dice(dbot); }; From 2e875e7434ea3c2135bb45107fc7e938dd3ccbc2 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 16:21:43 +0000 Subject: [PATCH 163/347] update poll [#131] --- modules/poll/commands.js | 187 ++++++++++++++++++++++++++++++++ modules/poll/pages.js | 45 ++++++++ modules/poll/poll.js | 226 +-------------------------------------- 3 files changed, 235 insertions(+), 223 deletions(-) create mode 100644 modules/poll/commands.js create mode 100644 modules/poll/pages.js diff --git a/modules/poll/commands.js b/modules/poll/commands.js new file mode 100644 index 0000000..0758f66 --- /dev/null +++ b/modules/poll/commands.js @@ -0,0 +1,187 @@ +var _ = require('underscore')._; + +var commands = function(dbot) { + var polls = dbot.db.polls; + var commands = { + '~newpoll': function(event) { + var name = event.input[1], + options = event.input[2].split(','), + description = event.input[3]; + + if(_.has(polls, name)) { + event.reply(dbot.t('poll_exists', { 'name': name })); + } else { + polls[name] = { + 'name': name, + 'description': description, + 'owner': event.user, + 'votes': {}, + 'votees': {} + }; + for(var i=0;i<options.length;i++) { + polls[name]['votes'][options[i]] = 0; + } + event.reply(dbot.t('poll_created', { + 'name': name, + 'description': description, + 'url': dbot.t('url', { + 'host': dbot.config.web.webHost, + 'port': dbot.config.web.webPort, + 'path': 'polls/' + name + }) + })); + } + }, + + '~addoption': function(event) { + var name = event.input[1], + option = event.input[2]; + + if(_.has(polls, name)) { + if(polls[name].owner === event.user) { + if(!_.has(polls[name].votes, option)) { + polls[name]['votes'][option] = 0; + event.reply(dbot.t('option_added', { + 'user': event.user, + 'name': name, + 'option': option + })); + } else { + event.reply(dbot.t('option_exists', { + 'option': option, + 'name': name, + 'user': event.user + })); + } + } else { + event.reply(dbot.t('not_poll_owner', { + 'user': event.user, + 'name': name + })); + } + } else { + event.reply(dbot.t('poll_unexistent', {'name': name})); + } + }, + + '~rmoption': function(event) { + var name = event.input[1], + option = event.input[2]; + + if(_.has(polls, name)) { + if(polls[name].owner === event.user) { + if(_.has(polls[name].votes, option)) { + delete polls[name]['votes'][option]; + event.reply(dbot.t('option_removed', { + 'user': event.user, + 'name': name, + 'option': option + })); + } else { + event.reply(dbot.t('invalid_vote', { 'vote': option })); + } + } else { + event.reply(dbot.t('not_poll_owner', { 'name': name })); + } + } else { + event.reply(dbot.t('poll_unexistent', { 'name': name })); + } + }, + + '~vote': function(event) { + var name = event.input[1], + vote = event.input[2]; + + if(_.has(polls, name)) { + if(_.has(polls[name].votes, vote)) { + if(_.has(polls[name].votees, event.user)) { + var oldVote = polls[name].votees[event.user]; + polls[name].votes[oldVote]--; + 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], + '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], + 'user': event.user + })); + } + } else { + event.reply(dbot.t('invalid_vote', { 'vote': vote })); + } + } else { + event.reply(dbot.t('poll_unexistent', { 'name': name })); + } + }, + + '~pdesc': function(event) { + var name = event.input[1]; + + if(_.has(polls, name)) { + event.reply(dbot.t('poll_describe', { + 'name': name, + 'description': polls[name].description, + 'url': dbot.t('url', { + 'host': dbot.config.web.webHost, + 'port': dbot.config.web.webPort, + 'path': 'polls/' + name + }) + })); + } else { + event.reply(dbot.t('poll_unexistent', { 'name': name })); + } + }, + + '~count': function(event) { + var name = event.input[1]; + + if(_.has(polls, name)) { + var order; + var votesArr = []; + + var order = _.chain(polls[name].votes) + .pairs() + .sortBy(function(option) { return option[1] }) + .reverse() + .value(); + + var orderString = ""; + for(var i=0;i<order.length;i++) { + orderString += order[i][0] + + " (" + order[i][1] + "), "; + } + orderString = orderString.slice(0, -2); + + event.reply(dbot.t('count', { + 'poll': name, + 'description': polls[name].description, + 'places': orderString + })); + } else { + event.reply(dbot.t('poll_unexistent', {'name': name})); + } + } + }; + commands['~newpoll'].regex = [/~newpoll ([^ ]+) options=([^ ]+) (.+)/, 4]; + commands['~addoption'].regex = [/~addoption ([^ ]+) ([^ ]+)/, 3]; + commands['~rmoption'].regex = [/~rmoption ([^ ]+) ([^ ]+)/, 3]; + commands['~vote'].regex = [/~vote ([^ ]+) ([^ ]+)/, 3]; + commands['~pdesc'].regex = [/~pdesc ([^ ]+)/, 2]; + commands['~count'].regex = [/~count ([^ ]+)/, 2]; + + return commands; +}; + +exports.fetch = function(dbot) { + return commands(dbot); +} diff --git a/modules/poll/pages.js b/modules/poll/pages.js new file mode 100644 index 0000000..0c8ea41 --- /dev/null +++ b/modules/poll/pages.js @@ -0,0 +1,45 @@ +var _ = require('underscore')._; + +var pages = function(dbot) { + var polls = dbot.db.polls; + var pages = { + // Shows the results of a poll + '/polls/:key': function(req, res) { + var key = req.params.key.toLowerCase(); + if(_.has(dbot.db.polls, key)) { + var totalVotes = _.reduce(dbot.db.polls[key].votes, + function(memo, option) { + return memo += option; + }, 0); + res.render('polls', { + 'name': dbot.config.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.config.name, + 'message': 'No polls under that key.' + }); + } + }, + + // Lists all of the polls + '/polls': function(req, res) { + res.render('polllist', { + 'name': dbot.config.name, + 'polllist': Object.keys(dbot.db.polls) + }); + }, + }; + return pages; +}; + +exports.fetch = function(dbot) { + return pages(dbot); +}; diff --git a/modules/poll/poll.js b/modules/poll/poll.js index 0ab8cda..f7f2d4b 100644 --- a/modules/poll/poll.js +++ b/modules/poll/poll.js @@ -1,228 +1,8 @@ -var _ = require('underscore')._; - var poll = function(dbot) { - var polls = dbot.db.polls; - var commands = { - '~newpoll': function(event) { - var name = event.input[1], - options = event.input[2].split(','), - description = event.input[3]; - - if(_.has(polls, name)) { - event.reply(dbot.t('poll_exists', { 'name': name })); - } else { - polls[name] = { - 'name': name, - 'description': description, - 'owner': event.user, - 'votes': {}, - 'votees': {} - }; - for(var i=0;i<options.length;i++) { - polls[name]['votes'][options[i]] = 0; - } - event.reply(dbot.t('poll_created', { - 'name': name, - 'description': description, - 'url': dbot.t('url', { - 'host': dbot.config.web.webHost, - 'port': dbot.config.web.webPort, - 'path': 'polls/' + name - }) - })); - } - }, - - '~addoption': function(event) { - var name = event.input[1], - option = event.input[2]; - - if(_.has(polls, name)) { - if(polls[name].owner === event.user) { - if(!_.has(polls[name].votes, name)) { - polls[name]['votes'][option] = 0; - event.reply(dbot.t('option_added', { - 'user': event.user, - 'name': name, - 'option': option - })); - } else { - event.reply(dbot.t('option_exists', { - 'option': option, - 'name': name, - 'user': event.user - })); - } - } else { - event.reply(dbot.t('not_poll_owner', { - 'user': event.user, - 'name': name - })); - } - } else { - event.reply(dbot.t('poll_unexistent', {'name': name})); - } - }, - - '~rmoption': function(event) { - var name = event.input[1], - option = event.input[2]; - - if(_.has(polls, name)) { - if(polls[name].owner === event.user) { - if(_.has(polls[name].votes, option)) { - delete polls[name]['votes'][option]; - event.reply(dbot.t('option_removed', { - 'user': event.user, - 'name': name, - 'option': option - })); - } else { - event.reply(dbot.t('invalid_vote', { 'vote': option })); - } - } else { - event.reply(dbot.t('not_poll_owner', { 'name': name })); - } - } else { - event.reply(dbot.t('poll_unexistent', { 'name': name })); - } - }, - - '~vote': function(event) { - var name = event.input[1], - vote = event.input[2]; - - if(_.has(polls, name)) { - if(_.has(polls[name].votes, vote)) { - if(_.has(polls[name].votees, event.user)) { - var oldVote = polls[name].votees[event.user]; - polls[name].votes[oldVote]--; - 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], - '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], - 'user': event.user - })); - } - } else { - event.reply(dbot.t('invalid_vote', { 'vote': vote })); - } - } else { - event.reply(dbot.t('poll_unexistent', { 'name': name })); - } - }, - - '~pdesc': function(event) { - var name = event.input[1]; - - if(_.has(polls, name)) { - event.reply(dbot.t('poll_describe', { - 'name': name, - 'description': polls[name].description, - 'url': dbot.t('url', { - 'host': dbot.config.web.webHost, - 'port': dbot.config.web.webPort, - 'path': 'polls/' + name - }) - })); - } else { - event.reply(dbot.t('poll_unexistent', { 'name': name })); - } - }, - - '~count': function(event) { - var name = event.input[1]; - - if(_.has(polls, name)) { - var order; - var votesArr = []; - - var order = _.chain(polls[name].votes) - .pairs() - .sortBy(function(option) { return option[1] }) - .reverse() - .value(); - - var orderString = ""; - for(var i=0;i<order.length;i++) { - orderString += order[i][0] + - " (" + order[i][1] + "), "; - } - orderString = orderString.slice(0, -2); - - event.reply(dbot.t('count', { - 'poll': name, - 'description': polls[name].description, - 'places': orderString - })); - } else { - event.reply(dbot.t('poll_unexistent', {'name': name})); - } - } - }; - commands['~newpoll'].regex = [/~newpoll ([^ ]+) options=([^ ]+) (.+)/, 4]; - commands['~addoption'].regex = [/~addoption ([^ ]+) ([^ ]+)/, 3]; - commands['~rmoption'].regex = [/~rmoption ([^ ]+) ([^ ]+)/, 3]; - commands['~vote'].regex = [/~vote ([^ ]+) ([^ ]+)/, 3]; - commands['~pdesc'].regex = [/~pdesc ([^ ]+)/, 2]; - commands['~count'].regex = [/~count ([^ ]+)/, 2]; - - var pages = { - // Shows the results of a poll - '/polls/:key': function(req, res) { - var key = req.params.key.toLowerCase(); - if(_.has(dbot.db.polls, key)) { - var totalVotes = _.reduce(dbot.db.polls[key].votes, - function(memo, option) { - return memo += option; - }, 0); - res.render('polls', { - 'name': dbot.config.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.config.name, - 'message': 'No polls under that key.' - }); - } - }, - - // Lists all of the polls - '/polls': function(req, res) { - res.render('polllist', { - 'name': dbot.config.name, - 'polllist': Object.keys(dbot.db.polls) - }); - }, - }; - - return { - 'name': 'poll', - 'ignorable': true, - 'commands': commands, - 'pages': pages - }; + this.name = poll; + this.ignorable = true; }; exports.fetch = function(dbot) { - return poll(dbot); + return new poll(dbot); } From 1bd1b5aa564ca4da5c8d8767bebfff9cb111530d Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 16:54:51 +0000 Subject: [PATCH 164/347] remove useless crap from modules [#136] --- modules/admin/admin.js | 2 -- modules/admin/config.json | 1 + modules/command/command.js | 2 -- modules/command/config.json | 1 + modules/dent/config.json | 3 ++- modules/dent/dent.js | 1 - modules/dice/config.json | 3 +++ modules/dice/dice.js | 3 --- modules/ignore/config.json | 1 + modules/ignore/ignore.js | 7 ++----- modules/js/config.json | 1 + modules/kick/config.json | 3 ++- modules/kick/kick.js | 3 --- modules/link/config.json | 1 + modules/link/link.js | 3 --- modules/poll/config.json | 3 ++- modules/poll/poll.js | 2 -- modules/quotes/config.json | 1 + modules/quotes/quotes.js | 3 --- modules/report/config.json | 1 + modules/report/report.js | 10 ++-------- modules/spelling/config.json | 1 + modules/spelling/spelling.js | 3 --- modules/users/config.json | 1 + modules/users/users.js | 4 ---- modules/web/config.json | 1 + modules/web/web.js | 11 ++++------- modules/youare/config.json | 3 +++ modules/youare/youare.js | 3 --- 29 files changed, 30 insertions(+), 52 deletions(-) create mode 100644 modules/dice/config.json create mode 100644 modules/youare/config.json diff --git a/modules/admin/admin.js b/modules/admin/admin.js index 5fab7a6..f1edaf3 100644 --- a/modules/admin/admin.js +++ b/modules/admin/admin.js @@ -7,8 +7,6 @@ var fs = require('fs'), _ = require('underscore')._; var admin = function(dbot) { - this.name = 'admin'; - this.ignorable = false; }; exports.fetch = function(dbot) { diff --git a/modules/admin/config.json b/modules/admin/config.json index 23a6701..dd2edcb 100644 --- a/modules/admin/config.json +++ b/modules/admin/config.json @@ -1,4 +1,5 @@ { + "ignorable": false, "dbKeys": [ "bans" ], "help": "http://github.com/reality/depressionbot/blob/master/modules/admin/README.md" } diff --git a/modules/command/command.js b/modules/command/command.js index 60c9477..57aa9a3 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -6,8 +6,6 @@ */ var _ = require('underscore')._; var command = function(dbot) { - this.name = 'command'; - this.ignorable = false; this.dbot = dbot; /** diff --git a/modules/command/config.json b/modules/command/config.json index 934b815..f7de9b5 100644 --- a/modules/command/config.json +++ b/modules/command/config.json @@ -1,4 +1,5 @@ { + "ignorable": false, "help": "http://github.com/reality/depressionbot/blob/master/modules/command/README.md", "dbKeys": [ "ignores" ] } diff --git a/modules/dent/config.json b/modules/dent/config.json index cb55dd8..a55d2eb 100644 --- a/modules/dent/config.json +++ b/modules/dent/config.json @@ -1,4 +1,5 @@ { "username": "youruserhere", - "password": "yourpasswordhere" + "password": "yourpasswordhere", + "ignorable": true } diff --git a/modules/dent/dent.js b/modules/dent/dent.js index 81e56f0..064b732 100644 --- a/modules/dent/dent.js +++ b/modules/dent/dent.js @@ -2,7 +2,6 @@ var request = require('request'); _ = require('underscore')._; var dent = function(dbot) { - this.name = 'dent'; this.dbot = dbot; this.api = { diff --git a/modules/dice/config.json b/modules/dice/config.json new file mode 100644 index 0000000..c945e96 --- /dev/null +++ b/modules/dice/config.json @@ -0,0 +1,3 @@ +{ + "ignorable": true +} diff --git a/modules/dice/dice.js b/modules/dice/dice.js index e45385a..82459b3 100644 --- a/modules/dice/dice.js +++ b/modules/dice/dice.js @@ -92,10 +92,7 @@ var dice = function(dbot) { } } }; - - this.name = 'dice'; this.commands = commands; - this.ignorable = true; } exports.fetch = function(dbot) { diff --git a/modules/ignore/config.json b/modules/ignore/config.json index 3f89c31..ef29f33 100644 --- a/modules/ignore/config.json +++ b/modules/ignore/config.json @@ -1,4 +1,5 @@ { + "ignorable": false, "dbKeys": [ "ignores" ], "help": "http://github.com/reality/depressionbot/blob/master/modules/ignore/README.md" } diff --git a/modules/ignore/ignore.js b/modules/ignore/ignore.js index b224777..c456fcb 100644 --- a/modules/ignore/ignore.js +++ b/modules/ignore/ignore.js @@ -11,8 +11,8 @@ var ignore = function(dbot) { '~ignore': function(event) { var module = event.params[1]; var ignorableModules = _.chain(dbot.modules) - .filter(function(module) { - return module.ignorable !== null && module.ignorable === true; + .filter(function(module, name) { + return dbot.config[module].ignorable === true; }) .pluck('name') .value(); @@ -71,9 +71,6 @@ var ignore = function(dbot) { } } }; - - this.name = 'ignore'; - this.ignorable = false; this.commands = commands; this.onLoad = function() { diff --git a/modules/js/config.json b/modules/js/config.json index 70bf0ec..a6df84c 100644 --- a/modules/js/config.json +++ b/modules/js/config.json @@ -4,5 +4,6 @@ "disabled": true } }, + "ignorable": true, "help": "http://github.com/reality/depressionbot/blob/master/modules/js/README.md" } diff --git a/modules/kick/config.json b/modules/kick/config.json index 0fd9db2..b73069a 100644 --- a/modules/kick/config.json +++ b/modules/kick/config.json @@ -1,4 +1,5 @@ { "dbKeys": [ "kicks", "kickers" ], - "help": "http://github.com/reality/depressionbot/blob/master/modules/kick/README.md" + "help": "http://github.com/reality/depressionbot/blob/master/modules/kick/README.md", + "ignorable": true } diff --git a/modules/kick/kick.js b/modules/kick/kick.js index ac5b792..b70bb61 100644 --- a/modules/kick/kick.js +++ b/modules/kick/kick.js @@ -49,9 +49,6 @@ var kick = function(dbot) { event.reply(orderedKickLeague(dbot.db.kickers, 'Kickers')); } }; - - this.name = 'kick'; - this.ignorable = false; this.commands = commands; this.listener = function(event) { diff --git a/modules/link/config.json b/modules/link/config.json index 580a315..ef7d7ff 100644 --- a/modules/link/config.json +++ b/modules/link/config.json @@ -1,4 +1,5 @@ { "autoTitle": false, + "ignorable": true, "help": "http://github.com/reality/depressionbot/blob/master/modules/link/README.md" } diff --git a/modules/link/link.js b/modules/link/link.js index 9965da6..cbd9c2a 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -33,9 +33,6 @@ var link = function(dbot) { this.fetchTitle(event, link); } }; - - this.name = 'link'; - this.ignorable = true; this.commands = commands; this.listener = function(event) { diff --git a/modules/poll/config.json b/modules/poll/config.json index 10db064..b7e55ae 100644 --- a/modules/poll/config.json +++ b/modules/poll/config.json @@ -1,4 +1,5 @@ { "help": "http://github.com/reality/depressionbot/blob/master/modules/poll/README.md", - "dbKeys": [ "polls" ] + "dbKeys": [ "polls" ], + "ignorable": true } diff --git a/modules/poll/poll.js b/modules/poll/poll.js index f7f2d4b..bda9b6d 100644 --- a/modules/poll/poll.js +++ b/modules/poll/poll.js @@ -1,6 +1,4 @@ var poll = function(dbot) { - this.name = poll; - this.ignorable = true; }; exports.fetch = function(dbot) { diff --git a/modules/quotes/config.json b/modules/quotes/config.json index 6aeedb0..cc5526a 100644 --- a/modules/quotes/config.json +++ b/modules/quotes/config.json @@ -1,5 +1,6 @@ { "dbKeys": [ "quoteArrs" ], "rmLimit": 10, + "ignorable": true, "help": "http://github.com/reality/depressionbot/blob/master/modules/quotes/README.md" } diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index 3cd13b2..85d9fb0 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -1,9 +1,6 @@ var _ = require('underscore')._; var quotes = function(dbot) { - this.name = 'quotes'; - this.ignorable = true; - dbot.sessionData.rmCache = []; this.quotes = dbot.db.quoteArrs, this.addStack = [], diff --git a/modules/report/config.json b/modules/report/config.json index b219759..831c099 100644 --- a/modules/report/config.json +++ b/modules/report/config.json @@ -1,3 +1,4 @@ { + "ignorable": true, "help": "http://github.com/reality/depressionbot/blob/master/modules/report/README.md" } diff --git a/modules/report/report.js b/modules/report/report.js index 4a6b09c..cf463f0 100644 --- a/modules/report/report.js +++ b/modules/report/report.js @@ -32,17 +32,11 @@ var report = function(dbot) { event.reply(dbot.t('not_in_channel', { 'channel': channelName })); } } - }; commands['~report'].regex = [/^~report ([^ ]+) ([^ ]+) (.+)$/, 4]; - - return { - 'name': 'report', - 'ignorable': true, - 'commands': commands - }; + this.commands = commands; }; exports.fetch = function(dbot) { - return report(dbot); + return new report(dbot); }; diff --git a/modules/spelling/config.json b/modules/spelling/config.json index d9d16eb..3a54ca9 100644 --- a/modules/spelling/config.json +++ b/modules/spelling/config.json @@ -1,3 +1,4 @@ { + "ignorable": true, "help": "http://github.com/reality/depressionbot/blob/master/modules/spelling/README.md" } diff --git a/modules/spelling/spelling.js b/modules/spelling/spelling.js index 23db3cc..7803c42 100644 --- a/modules/spelling/spelling.js +++ b/modules/spelling/spelling.js @@ -74,9 +74,6 @@ var distance = function(s1, s2) { }; var spelling = function(dbot) { - this.name = 'spelling'; - this.ignorable = true; - this.last = {}; this.internalAPI = {}; this.internalAPI.correct = function (event, correction, candidate, output_callback) { diff --git a/modules/users/config.json b/modules/users/config.json index bc208fb..e13da3a 100644 --- a/modules/users/config.json +++ b/modules/users/config.json @@ -1,3 +1,4 @@ { + "ignorable": false, "dbKeys": [ "knownUsers" ] } diff --git a/modules/users/users.js b/modules/users/users.js index ffca388..8bc6c68 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -33,10 +33,6 @@ var users = function(dbot) { channelUsers[channelName].push(newUser); }, this); }; - - - this.name = 'users'; - this.ignorable = false; this.listener = function(event) { var knownUsers = this.getServerUsers(event.server); diff --git a/modules/web/config.json b/modules/web/config.json index 45cd275..47a0b3a 100644 --- a/modules/web/config.json +++ b/modules/web/config.json @@ -1,4 +1,5 @@ { + "ignorable": false, "webHost": "localhost", "webPort": 9001 } diff --git a/modules/web/web.js b/modules/web/web.js index 2bc7b28..04823d3 100644 --- a/modules/web/web.js +++ b/modules/web/web.js @@ -3,13 +3,6 @@ var express = require('express'), fs = require('fs'); var webInterface = function(dbot) { - this.name = 'web'; - this.ignorable = false; - - this.onDestroy = function() { - server.close(); - } - var pub = 'public'; var app = express(); @@ -41,6 +34,10 @@ var webInterface = function(dbot) { } } }.bind(this); + + this.onDestroy = function() { + server.close(); + } }; exports.fetch = function(dbot) { diff --git a/modules/youare/config.json b/modules/youare/config.json new file mode 100644 index 0000000..c945e96 --- /dev/null +++ b/modules/youare/config.json @@ -0,0 +1,3 @@ +{ + "ignorable": true +} diff --git a/modules/youare/youare.js b/modules/youare/youare.js index 89fa4f3..2aa4ecd 100644 --- a/modules/youare/youare.js +++ b/modules/youare/youare.js @@ -1,7 +1,4 @@ var youAre = function(dbot) { - this.name = 'youare'; - this.ignorable = false; - this.listener = function(event) { var key = event.message.valMatch(/(\bis\b|\bare\b)\s+([\w\s\d]*?)(\s+)?(,|\.|\band\b|$)/, 5); From 921da917a4dd5465601571320bc8714b57288337 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 17:23:14 +0000 Subject: [PATCH 165/347] Command hooks [#86] * Command API function to addHook(command, callback) * Commands open to callbacks must return information or indicate failed completion by return false * Hooks to be added in module onLoad * Command loop checks for available hooks and return state, then applies with module scope. * onLoad running moved to end of all module loading to facilitate this without order problems * Added example for ~qadd dent --- modules/command/api.js | 10 ++++++++++ modules/command/command.js | 7 ++++++- modules/dent/dent.js | 6 ++++++ modules/quotes/commands.js | 6 ++---- run.js | 10 ++++++---- 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/modules/command/api.js b/modules/command/api.js index 60509e4..2347977 100644 --- a/modules/command/api.js +++ b/modules/command/api.js @@ -62,6 +62,16 @@ var api = function(dbot) { applies = true; } return applies; + }, + + 'addHook': function(command, callback) { + console.log('adding hook'); + if(_.has(dbot.commands, command)) { + if(!_.has(dbot.commands[command], 'hooks')) { + dbot.commands[command].hooks = []; + } + dbot.commands[command].hooks.push(callback); + } } }; }; diff --git a/modules/command/command.js b/modules/command/command.js index 57aa9a3..fd3606d 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -30,7 +30,12 @@ var command = function(dbot) { if(this.api.applyRegex(commandName, event)) { try { var command = dbot.commands[commandName]; - command.apply(dbot.modules[command.module], [event]); + var results = command.apply(dbot.modules[command.module], [event]); + if(_.has(command, 'hooks') && results !== false) { + _.each(command['hooks'], function(hook) { + hook.apply(hook.module, results); + }, this); + } } catch(err) { if(dbot.config.debugMode == true) { event.reply('- Error in ' + commandName + ':'); diff --git a/modules/dent/dent.js b/modules/dent/dent.js index 064b732..15d7639 100644 --- a/modules/dent/dent.js +++ b/modules/dent/dent.js @@ -32,6 +32,12 @@ var dent = function(dbot) { } }; this.commands['~dent'].regex = [/^~dent (.+)$/, 2]; + + this.onLoad = function() { + dbot.api.command.addHook('~qadd', function(key, text) { + this.api.post(key + ': ' + text); + }.bind(this)); + }.bind(this); }; exports.fetch = function(dbot) { diff --git a/modules/quotes/commands.js b/modules/quotes/commands.js index c6061ad..824dcb5 100644 --- a/modules/quotes/commands.js +++ b/modules/quotes/commands.js @@ -187,11 +187,9 @@ var commands = function(dbot) { 'count': quotes[key].length })); - // TODO hook - if(_.has(dbot.api, 'dent')) { - dbot.api.dent.post(key + ': ' + text); - } + return { 'key': key, 'text': text }; } + return false; }, '~rq': function(event) { diff --git a/run.js b/run.js index 156ba3b..0528cfc 100644 --- a/run.js +++ b/run.js @@ -229,10 +229,6 @@ DBot.prototype.reloadModules = function() { return this.name; } - if(module.onLoad) { - module.onLoad(); - } - this.modules[module.name] = module; } catch(err) { console.log(this.t('module_load_error', {'moduleName': name})); @@ -245,6 +241,12 @@ DBot.prototype.reloadModules = function() { }.bind(this)); if(_.has(this.modules, 'web')) this.modules.web.reloadPages(); + + _.each(this.modules, function(module, name) { + if(module.onLoad) { + module.onLoad(); + } + }, this); this.save(); }; From c783113cca5274730e08f11a7a269841fa1eb539 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 18:38:08 +0100 Subject: [PATCH 166/347] This should fix that undefined whatsit --- modules/command/command.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/command/command.js b/modules/command/command.js index fd3606d..0895a94 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -33,7 +33,7 @@ var command = function(dbot) { var results = command.apply(dbot.modules[command.module], [event]); if(_.has(command, 'hooks') && results !== false) { _.each(command['hooks'], function(hook) { - hook.apply(hook.module, results); + hook.apply(hook.module, _.values(results)); }, this); } } catch(err) { From 628ba5b569bae4ba4f7199f5f1e9c8730ed1bdd1 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 17:52:13 +0000 Subject: [PATCH 167/347] return data for user changes instead of calling stats --- modules/users/commands.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/users/commands.js b/modules/users/commands.js index e1c5cd9..49666ec 100644 --- a/modules/users/commands.js +++ b/modules/users/commands.js @@ -51,10 +51,14 @@ var commands = function(dbot) { 'newAlias': newAlias })); - dbot.api.stats.fixStats(event.server, newAlias); + return { + 'server': event.server, + 'alias': newAlias + }; } else { event.reply(dbot.t('unknown_alias', { 'alias': newParent })); } + return false; }, '~mergeusers': function(event) { @@ -73,10 +77,14 @@ var commands = function(dbot) { 'new_user': primaryUser })); - dbot.api.stats.fixStats(event.server, secondaryUser); + return { + 'server': event.server, + 'alias': newAlias + }; } else { event.reply(dbot.t('unprimary_error')); } + return false; } }; From be9ee61e13c6ccecdbca3fce34bf97ea05faa73e Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 19:09:54 +0000 Subject: [PATCH 168/347] isOnline and resolveUser checks lower case properly --- modules/users/api.js | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/modules/users/api.js b/modules/users/api.js index 7ba86f4..e56c2d4 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -2,14 +2,31 @@ var _ = require('underscore')._; var api = function(dbot) { var api = { - 'resolveUser': function(server, nick, useLowercase) { + 'resolveUser': function(server, nick, useLowerCase) { var knownUsers = this.getServerUsers(server); var user = nick; - if(!_.include(knownUsers.users, nick) && _.has(knownUsers.aliases, nick)) { - user = knownUsers.aliases[nick]; + + if(!useLowerCase) { + if(!_.include(knownUsers.users, nick) && _.has(knownUsers.aliases, nick)) { + user = knownUsers.aliases[nick]; + } + } else { + // this is retarded + user = user.toLowerCase(); + var resolvedUser = _.find(knownUsers.users, function(nick) { + var toMatch = new RegExp("/"+user+"/i").compile(); + return nick.match(toMatch); + }, this); + + if(!resolvedUser) { + resolvedUser = _.find(knownUsers.aliases, function(nick, alias) { + var toMatch = new RegExp("/"+user+"/i").compile(); + return alias.match(toMatch); + }, this); + user = knownUsers.aliases[resolvedUser]; + } } - if(useLowercase) user = user.toLowerCase(); return user; }, @@ -31,6 +48,22 @@ var api = function(dbot) { return knownUsers.aliases[user] == nick; }, this) .value(); + }, + + 'isOnline': function(server, user, channel, useLowerCase) { + var user = this.api.resolveUser(server, user, useLowerCase); + var possiNicks = [user].concat(this.api.getAliases(server, user)); + var onlineNicks = dbot.instance.connections[server].channels[channel].nicks; + if(useLowerCase) { + possiNicks = _.map(possiNicks, function(nick) { + return nick.toLowerCase(); + }); + } + + return _.any(onlineNicks, function(nick) { + nick = nick.name; + return _.include(possiNicks, nick); + }, this); } }; From 12db5c64e95ad6173d8c2a5981b3a990c0065dbe Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 19:27:21 +0000 Subject: [PATCH 169/347] lc fix for resolve user --- modules/users/api.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/modules/users/api.js b/modules/users/api.js index e56c2d4..6432773 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -24,6 +24,8 @@ var api = function(dbot) { return alias.match(toMatch); }, this); user = knownUsers.aliases[resolvedUser]; + } else { + user = resolvedUser; } } @@ -54,11 +56,6 @@ var api = function(dbot) { var user = this.api.resolveUser(server, user, useLowerCase); var possiNicks = [user].concat(this.api.getAliases(server, user)); var onlineNicks = dbot.instance.connections[server].channels[channel].nicks; - if(useLowerCase) { - possiNicks = _.map(possiNicks, function(nick) { - return nick.toLowerCase(); - }); - } return _.any(onlineNicks, function(nick) { nick = nick.name; From 76382a6daaff275eda0cfe07b76e325b9d08fc4d Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 19:44:34 +0000 Subject: [PATCH 170/347] and they told me no bru regex is cool u wil hav fun --- modules/users/api.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/users/api.js b/modules/users/api.js index 6432773..471fab6 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -14,14 +14,14 @@ var api = function(dbot) { // this is retarded user = user.toLowerCase(); var resolvedUser = _.find(knownUsers.users, function(nick) { - var toMatch = new RegExp("/"+user+"/i").compile(); - return nick.match(toMatch); + var toMatch = new RegExp(user, "i"); + return nick.match(toMatch) !== null; }, this); if(!resolvedUser) { resolvedUser = _.find(knownUsers.aliases, function(nick, alias) { - var toMatch = new RegExp("/"+user+"/i").compile(); - return alias.match(toMatch); + var toMatch = new RegExp(user, "i"); + return alias.match(toMatch) !== null; }, this); user = knownUsers.aliases[resolvedUser]; } else { From 078f3b943bbd5b8c3007eed6b6a2533e2e13a2fb Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Tue, 15 Jan 2013 20:44:15 +0000 Subject: [PATCH 171/347] Better users web --- modules/users/pages.js | 4 +++- views/users/users.jade | 44 ++++++++---------------------------------- 2 files changed, 11 insertions(+), 37 deletions(-) diff --git a/modules/users/pages.js b/modules/users/pages.js index cbc14f6..2708fd8 100644 --- a/modules/users/pages.js +++ b/modules/users/pages.js @@ -58,8 +58,10 @@ var pages = function(dbot) { userData.inactive.sort(userSort); userData.offline.sort(userSort); + var userDataSorted = (userData.active.concat(userData.inactive)).concat(userData.offline); + res.render('users', { 'name': dbot.config.name, 'connection': connection, - 'channel': channel, 'nicks': userData }); + 'channel': channel, 'nicks': userDataSorted }); } else { res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection or channel.' }); } diff --git a/views/users/users.jade b/views/users/users.jade index 9a5da2a..07dbe15 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -15,47 +15,19 @@ block content th Verbosity th Mentions tbody - -each nick in nicks.active + -each nick in nicks tr td a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick.primary) #{nick.display} span - span.label.label-success Active - td - #{nick.fields.lines.data} - td - #{nick.fields.words.data} - td - #{nick.fields.lincent.data} - td - #{nick.fields.wpl.data} - td - #{nick.fields.in_mentions.data} - -each nick in nicks.inactive - tr - td - a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick.primary) - #{nick.display} - span - span.label.label-important Inactive - td - #{nick.fields.lines.data} - td - #{nick.fields.words.data} - td - #{nick.fields.lincent.data} - td - #{nick.fields.wpl.data} - td - #{nick.fields.in_mentions.data} - -each nick in nicks.offline - tr - td - a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick.primary) - #{nick.display} - span - span.label Offline + if nick.online + if nick.active + span.label.label-success Active + else + span.label.label-important Inactive + else + span.label Offline td #{nick.fields.lines.data} td From 8ed4a3f088e5fd35595e0628b7494fb6f2ba3bb6 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 20:49:05 +0000 Subject: [PATCH 172/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 31781a9..6a72868 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 31781a9e646028bc6872e7c39b6e3e31c6b2cbb1 +Subproject commit 6a7286817d915203fe2da52ccf7c6c1ede59c0c6 From 4adfe634935c3d42e370011e499de0ee25ff358d Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 21:09:07 +0000 Subject: [PATCH 173/347] add api docs for command --- modules/command/README.md | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/modules/command/README.md b/modules/command/README.md index 437f1e7..d412fd9 100644 --- a/modules/command/README.md +++ b/modules/command/README.md @@ -12,3 +12,48 @@ Handles the command execution logic for DBot. This is the only module which is force loaded, even if it's not specified in the configuration file. + +### Commands + +#### ~usage [command] +Show usage information for a given command. + +#### ~help [command|module] +Link module help for a module given either the module name or the name of a +command belonging to a module. + +### API + +#### isBanned(user, command) +Return whether a user is currently banned from a given commands. + +#### hasAccess(user, command) +Return whether a user has the access level (moderator, admin) to run a given +command. + +#### isIgnoring(user, command) +Return whether a user is currently marked as ignoring a given command. + +#### addHook(command, callback) +This API function allows you to hook functions into DBot commands. For example, +you may add a hook to post on Identica when a new quote is added to the database +with the ~qadd command. As a less useful example, here is how you might add a +hook to log to the console every time someone uses the reload command: + + dbot.api.command.addHook('reload', function() { + console.log('Reload run!'); + }); + +Hook arguments are populated by the return values of the functions they are +hooked into, and command hooks are not run if the command explicitly returns +'false.' For example, the ~qadd command returns *[ key, quote ]*, and the hook +function will be called with these variables given in the order they were +returned, so you would retrieve the key and the quote from a hook to ~qadd like +this: + + dbot.api.command.addHook('~qadd', function(key, quote) { ... + +The best place to add hooks to commands is in the 'onLoad' function of your +module, as this ensures it will be run while all other modules are loaded. If +the target command does not exist (for example if its module was not loaded), +the hook will not be added and no errors will be thrown. From 69d9880519f01c3e89f67dc4e7b41258c25a90e3 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 21:14:52 +0000 Subject: [PATCH 174/347] update flow info for command --- modules/command/README.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/modules/command/README.md b/modules/command/README.md index d412fd9..6f52a18 100644 --- a/modules/command/README.md +++ b/modules/command/README.md @@ -4,11 +4,18 @@ Handles the command execution logic for DBot. ### Description -1. Does the input match a command key in *dbot.commands* ? -2. Is there a quote category which matches the first part of the input - (*~category*)? -3. Is there a command name similar to to the first part of the input (*~name*) - in *dbot.commands*? +Command flow: + +1. Does the input match a command key in the loaded commands? + * If command not found and quotes is loaded, attempt to print quote of given + command name +2. Is the user banned from running the given command? +3. Is the user ignoring the command? +3. Does the use have the access level to run the command? +4. Is the command set as disabled? +4. Apply regex to the command, pass into event object. + * If regex does not apply, show usage info. +5. Run the command. This is the only module which is force loaded, even if it's not specified in the configuration file. From 37a1027612c72ab66f84f31a04ec4ca1a335e760 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 21:20:25 +0000 Subject: [PATCH 175/347] Dent docs --- modules/dent/README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 modules/dent/README.md diff --git a/modules/dent/README.md b/modules/dent/README.md new file mode 100644 index 0000000..a13464a --- /dev/null +++ b/modules/dent/README.md @@ -0,0 +1,31 @@ +## Dent + +Post dents. + +### Description + +Allows the posting of dents to Identica. Easily abused for posting status +messages to Twitter by linking the Identica account. + +### Commands + +#### ~dent [text] +Post the given text to Identica. + +### Configuration + +#### username +Identica username to post with. + +#### password +Identica password to post with. + +### API + +#### post(content) +Post the given content to Identica. + +### Hooks + +#### ~qadd +Posts new quote additions. From 4e248ef248929cf28ddc1127ac147690907553cb Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 21:43:09 +0000 Subject: [PATCH 176/347] add readme for users --- modules/quotes/README.md | 5 +++++ modules/users/README.md | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 modules/users/README.md diff --git a/modules/quotes/README.md b/modules/quotes/README.md index 1f2536e..c397a6c 100644 --- a/modules/quotes/README.md +++ b/modules/quotes/README.md @@ -55,6 +55,11 @@ and permanently delete them. Re-instate the quotes that are currently in the removal cache back into the main quote database. +### API + +#### getQuote(event, category) +Returns a random quote from the given category. + ### Removal Spam Protection When quotes are removed using either the ~rm or ~rmlast commands, the quotes are diff --git a/modules/users/README.md b/modules/users/README.md new file mode 100644 index 0000000..5bc713e --- /dev/null +++ b/modules/users/README.md @@ -0,0 +1,48 @@ +## Users + +Track users. + +### Description + +This module tracks users and their aliases through nick changes and all that +kind of thing. It's mainly a utility module for other modules to use. It's +also totally !insaned. + +### Commands + +#### ~alias [user] +If an alias is provided, this command will return the primary user for which +this is an alias for. If a primary user is provided, it will return a +confirmation of this fact and a count of how many aliases belong to the user. + +#### ~setaliasparent [newparent] +Set a nick which is currently serving as an alias to the primary user, while +setting what was previously the primary user as an alias of the new primary +user. Requires moderator level access by default. + +#### ~mergeusers [primaryuser] [secondaryuser] +This command merges two nicks which are recorded as primary users into one user. +The secondary user and all of their aliases will be merged under primaryuser. +Requires moderator level access by default. + +### API + +#### resolveUser(server, nick, [useLowerCase]) +This resolves a given nick to its primary user and returns it. + +Note that if the useLowerCase argument is set to true, it will do a lower-case +search, however it will return the username in its properly capitalised form, so +remember to lower case the return value if you are using lower case values as +keys. + +#### resolveUser(server, user) +Return whether a user is known either as an alias or a primary user. + +#### isPrimaryUser(server, nick) +Return whether a nick is known as a primary user. + +#### getAliases(server, user) +Return a list of aliases for a given primary user. + +#### isOnline(server, user, channel, useLowerCase) +Return whether a user is online in a given channel on the given server. From 157fe71fc1ea728312e5998a40a0f883da2294d0 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 21:44:35 +0000 Subject: [PATCH 177/347] docs link for users --- modules/users/config.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/users/config.json b/modules/users/config.json index e13da3a..0e947cb 100644 --- a/modules/users/config.json +++ b/modules/users/config.json @@ -1,4 +1,5 @@ { "ignorable": false, - "dbKeys": [ "knownUsers" ] + "dbKeys": [ "knownUsers" ], + "help": "https://github.com/reality/depressionbot/blob/master/modules/users/README.md" } From a433b592c95df5878b5123196c6d345a4476e6b4 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 21:58:47 +0000 Subject: [PATCH 178/347] wat --- modules/users/api.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/users/api.js b/modules/users/api.js index 471fab6..e59c895 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -14,13 +14,13 @@ var api = function(dbot) { // this is retarded user = user.toLowerCase(); var resolvedUser = _.find(knownUsers.users, function(nick) { - var toMatch = new RegExp(user, "i"); + var toMatch = new RegExp(_.escape(user), "i"); return nick.match(toMatch) !== null; }, this); if(!resolvedUser) { resolvedUser = _.find(knownUsers.aliases, function(nick, alias) { - var toMatch = new RegExp(user, "i"); + var toMatch = new RegExp(_.escape(user), "i"); return alias.match(toMatch) !== null; }, this); user = knownUsers.aliases[resolvedUser]; From 5ce3c3dfb93a57509aef0106f3430a55fc549932 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 22:06:30 +0000 Subject: [PATCH 179/347] update jsbot --- jsbot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsbot b/jsbot index 9477dc3..296c5fc 160000 --- a/jsbot +++ b/jsbot @@ -1 +1 @@ -Subproject commit 9477dc33ff1b940f8c07225f00d0648de2a41cb4 +Subproject commit 296c5fc6b5d9040791fac9cb33e9aeaf7ce16686 From e403d1d7f12fd6fb611e4de9c4f09f5480ee1226 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 23:09:35 +0000 Subject: [PATCH 180/347] no idea how that was doing that but now it is fixed --- modules/users/api.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/users/api.js b/modules/users/api.js index e59c895..471fab6 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -14,13 +14,13 @@ var api = function(dbot) { // this is retarded user = user.toLowerCase(); var resolvedUser = _.find(knownUsers.users, function(nick) { - var toMatch = new RegExp(_.escape(user), "i"); + var toMatch = new RegExp(user, "i"); return nick.match(toMatch) !== null; }, this); if(!resolvedUser) { resolvedUser = _.find(knownUsers.aliases, function(nick, alias) { - var toMatch = new RegExp(_.escape(user), "i"); + var toMatch = new RegExp(user, "i"); return alias.match(toMatch) !== null; }, this); user = knownUsers.aliases[resolvedUser]; From 21f4bc4ad6302de475e8958cd5ec144cd96ca47a Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 15 Jan 2013 23:32:45 +0000 Subject: [PATCH 181/347] i hate computers --- modules/users/api.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/users/api.js b/modules/users/api.js index 471fab6..6ec0ce5 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -20,13 +20,13 @@ var api = function(dbot) { if(!resolvedUser) { resolvedUser = _.find(knownUsers.aliases, function(nick, alias) { + console.log(alias + ' -> ' + nick); var toMatch = new RegExp(user, "i"); - return alias.match(toMatch) !== null; + if(alias.match(toMatch) !== null) return nick; }, this); - user = knownUsers.aliases[resolvedUser]; - } else { - user = resolvedUser; } + + user = resolvedUser; } return user; From 5f59c7c352fe23a36adb31faf9da2a11f566a215 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 16 Jan 2013 16:31:13 +0000 Subject: [PATCH 182/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 6a72868..36e9194 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 6a7286817d915203fe2da52ccf7c6c1ede59c0c6 +Subproject commit 36e919477ff792183eef9c6340fd52980afaa963 From d99820ee3d99217778e0521d258c3a174fd02cf5 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 16 Jan 2013 16:37:57 +0000 Subject: [PATCH 183/347] update stats again --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 36e9194..422b211 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 36e919477ff792183eef9c6340fd52980afaa963 +Subproject commit 422b211ba3fb262d1c9acd1be7cd2f5940e126c0 From e2e1c0b6a9f88818bce5007dc6e058c09446d623 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 16 Jan 2013 20:21:28 +0000 Subject: [PATCH 184/347] that bug that somethjing --- modules/users/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/api.js b/modules/users/api.js index 6ec0ce5..5f6d515 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -24,9 +24,9 @@ var api = function(dbot) { var toMatch = new RegExp(user, "i"); if(alias.match(toMatch) !== null) return nick; }, this); + if(!_.isUndefined(resolvedUser)) user = resolvedUser; } - user = resolvedUser; } return user; From 389e8660b1e0ee47e3372b849d30527841ee62b8 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 16 Jan 2013 20:25:39 +0000 Subject: [PATCH 185/347] remove unused debug output --- modules/users/api.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/users/api.js b/modules/users/api.js index 5f6d515..1899981 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -20,7 +20,6 @@ var api = function(dbot) { if(!resolvedUser) { resolvedUser = _.find(knownUsers.aliases, function(nick, alias) { - console.log(alias + ' -> ' + nick); var toMatch = new RegExp(user, "i"); if(alias.match(toMatch) !== null) return nick; }, this); From 54c67cb6ff9afac12301de0bb7094e0652e5f5ea Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 16 Jan 2013 21:24:32 +0000 Subject: [PATCH 186/347] newstats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 422b211..d2facdf 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 422b211ba3fb262d1c9acd1be7cd2f5940e126c0 +Subproject commit d2facdfc2e15e428024fd5d1e9192ad6128e4670 From 47dec97e1b773a82460c6a3b5f2cb0088c657862 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Wed, 16 Jan 2013 21:55:14 +0000 Subject: [PATCH 187/347] Case insensitive doom continues --- modules/users/api.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/users/api.js b/modules/users/api.js index 1899981..4597513 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -25,9 +25,10 @@ var api = function(dbot) { }, this); if(!_.isUndefined(resolvedUser)) user = resolvedUser; } - + else{ + user = resolvedUser; + } } - return user; }, From f6371a7bbca2456fef6ffe16dbc512dc6fb366bf Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 17 Jan 2013 17:44:29 +0000 Subject: [PATCH 188/347] Fix [#142] by escaping regex, also improve efficiency by only compiling 1 regex --- modules/users/api.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/users/api.js b/modules/users/api.js index 1899981..232d5cd 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -1,6 +1,10 @@ var _ = require('underscore')._; var api = function(dbot) { + var escapeRegexen = function(str) { + return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); + }; + var api = { 'resolveUser': function(server, nick, useLowerCase) { var knownUsers = this.getServerUsers(server); @@ -13,14 +17,14 @@ var api = function(dbot) { } else { // this is retarded user = user.toLowerCase(); + var toMatch = new RegExp(escapeRegexen(user), "i"); + var resolvedUser = _.find(knownUsers.users, function(nick) { - var toMatch = new RegExp(user, "i"); return nick.match(toMatch) !== null; }, this); if(!resolvedUser) { resolvedUser = _.find(knownUsers.aliases, function(nick, alias) { - var toMatch = new RegExp(user, "i"); if(alias.match(toMatch) !== null) return nick; }, this); if(!_.isUndefined(resolvedUser)) user = resolvedUser; From 447baa0a798c6f81cca9c22b09a44abe68058099 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 17 Jan 2013 22:27:10 +0000 Subject: [PATCH 189/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index d2facdf..c4bdf6c 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit d2facdfc2e15e428024fd5d1e9192ad6128e4670 +Subproject commit c4bdf6c0370130960a8c44b74fe52a37bf90458e From 62419a363bd2a33331629c1543f5f33feb6f035d Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 17 Jan 2013 22:40:49 +0000 Subject: [PATCH 190/347] correct return object for mergeusers --- modules/users/commands.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/users/commands.js b/modules/users/commands.js index 49666ec..8581d77 100644 --- a/modules/users/commands.js +++ b/modules/users/commands.js @@ -79,7 +79,8 @@ var commands = function(dbot) { return { 'server': event.server, - 'alias': newAlias + 'primary': primaryUser, + 'secondary': secondaryUser }; } else { event.reply(dbot.t('unprimary_error')); From dcf7d0448d64570d5870bdb64b5c76ff09ab0d5f Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 17 Jan 2013 22:53:40 +0000 Subject: [PATCH 191/347] wonderrful stat changos --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index c4bdf6c..9046d4a 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit c4bdf6c0370130960a8c44b74fe52a37bf90458e +Subproject commit 9046d4a0a75895e4f949c10c5a5a338f49166007 From 6d442fd45c0d60add4f6163b1944eef228fe3f58 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Fri, 18 Jan 2013 15:34:04 +0100 Subject: [PATCH 192/347] Match full user string. Fix for [#151]. --- modules/users/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/api.js b/modules/users/api.js index 4d14a7c..c36e21e 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -17,7 +17,7 @@ var api = function(dbot) { } else { // this is retarded user = user.toLowerCase(); - var toMatch = new RegExp(escapeRegexen(user), "i"); + var toMatch = new RegExp("^" + escapeRegexen(user) + "$", "i"); var resolvedUser = _.find(knownUsers.users, function(nick) { return nick.match(toMatch) !== null; From 1fa4a4a27ef19b0838ebc5860521ae6a5373cd5e Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 18 Jan 2013 15:46:25 +0000 Subject: [PATCH 193/347] update stats to v0.2 --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 9046d4a..a601379 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 9046d4a0a75895e4f949c10c5a5a338f49166007 +Subproject commit a60137999d1a50543022c96056234dfdb25525e3 From fad3eda6019039cacd2fe342697272ded85c460e Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 18 Jan 2013 15:47:10 +0000 Subject: [PATCH 194/347] version 0.2! --- VERSION | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1f085f1..a71b32e 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,4 @@ -depressionbot version 0.2-dev (respite) +depressionbot version 0.2 (rescore) +_.each(dbot.modules, function(module) { "RESCORE EVERYTHING" }); "He called his bot depressionbot, and that's when he was happy." From 94363a6d8ff074088c02df2296d55ba8e9623b0a Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 19 Jan 2013 13:34:42 +0000 Subject: [PATCH 195/347] polls case insensitive [#155] --- modules/poll/commands.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/poll/commands.js b/modules/poll/commands.js index 0758f66..796b32b 100644 --- a/modules/poll/commands.js +++ b/modules/poll/commands.js @@ -4,8 +4,8 @@ var commands = function(dbot) { var polls = dbot.db.polls; var commands = { '~newpoll': function(event) { - var name = event.input[1], - options = event.input[2].split(','), + var name = event.input[1].toLowerCase(), + options = event.input[2].toLowerCase().split(','), description = event.input[3]; if(_.has(polls, name)) { @@ -34,8 +34,8 @@ var commands = function(dbot) { }, '~addoption': function(event) { - var name = event.input[1], - option = event.input[2]; + var name = event.input[1].toLowerCase(), + option = event.input[2].toLowerCase(); if(_.has(polls, name)) { if(polls[name].owner === event.user) { @@ -65,8 +65,8 @@ var commands = function(dbot) { }, '~rmoption': function(event) { - var name = event.input[1], - option = event.input[2]; + var name = event.input[1].toLowerCase(), + option = event.input[2].toLowerCase(); if(_.has(polls, name)) { if(polls[name].owner === event.user) { @@ -89,8 +89,8 @@ var commands = function(dbot) { }, '~vote': function(event) { - var name = event.input[1], - vote = event.input[2]; + var name = event.input[1].toLowerCase(), + vote = event.input[2].toLowerCase(); if(_.has(polls, name)) { if(_.has(polls[name].votes, vote)) { @@ -125,7 +125,7 @@ var commands = function(dbot) { }, '~pdesc': function(event) { - var name = event.input[1]; + var name = event.input[1].toLowerCase(); if(_.has(polls, name)) { event.reply(dbot.t('poll_describe', { @@ -143,7 +143,7 @@ var commands = function(dbot) { }, '~count': function(event) { - var name = event.input[1]; + var name = event.input[1].toLowerCase(); if(_.has(polls, name)) { var order; From a2ea1b8c33aa86c3b0c934e0fc1f5ca2dc624eeb Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 14:45:58 +0000 Subject: [PATCH 196/347] Load module config options from db store [#145] --- run.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/run.js b/run.js index 0528cfc..2faff6e 100644 --- a/run.js +++ b/run.js @@ -34,6 +34,9 @@ var DBot = function(timers) { if(!this.db) { // If it wasn't empty this.db = JSON.parse(rawDB); } + if(!_.has(this.db, 'config')) { + this.db.config = {}; + } } catch(err) { console.log('Syntax error in db.json. Stopping: ' + err); process.exit(); @@ -157,12 +160,19 @@ DBot.prototype.reloadModules = function() { try { // Load the module config data var config = {}; + + if(_.has(this.db.config, name)) { + config = this.db.config; + } + try { - config = JSON.parse(fs.readFileSync(moduleDir + 'config.json', 'utf-8')); + var defaultConfig = JSON.parse(fs.readFileSync(moduleDir + 'config.json', 'utf-8')); + config = _.defaults(config, defaultConfig); } catch(err) { // Invalid or no config data } + // Load module config this.config[name] = config; _.each(config.dbKeys, function(dbKey) { if(!_.has(this.db, dbKey)) { @@ -170,6 +180,8 @@ DBot.prototype.reloadModules = function() { } }, this); + // Override module config with any stored in the DB + // Load the module itself var rawModule = require(moduleDir + name); var module = rawModule.fetch(this); From f64c50a0c84257fd419a0e4268341ff7f9894617 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 15:17:44 +0000 Subject: [PATCH 197/347] setconfig command [#145] --- modules/admin/commands.js | 40 +++++++++++++++++++++++++++++++++++++++ run.js | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/modules/admin/commands.js b/modules/admin/commands.js index 0cba001..5ab67f9 100644 --- a/modules/admin/commands.js +++ b/modules/admin/commands.js @@ -149,6 +149,46 @@ var commands = function(dbot) { } else { event.reply(dbot.t('unban_error', {'user': username})); } + }, + + /*** Config options ***/ + + 'setconfig': function(event) { + var configKey = event.params[1]; + var newOption = event.params[2]; + + configKey = configKey.split('.'); + defaultConfigPath = dbot.config; + userConfigPath = dbot.db.config; + for(var i=0;i<configKey.length-1;i++) { + if(_.has(defaultConfigPath, configKey[i])) { + if(!_.has(userConfigPath, configKey[i])) { + userConfigPath[configKey[i]] = {}; + } + userConfigPath = userConfigPath[configKey[i]]; + defaultConfigPath = defaultConfigPath[configKey[i]]; + } else { + event.reply("Config path doesn't exist."); + return; + } + } + + var configItem = _.last(configKey); + var currentOption = defaultConfigPath[configItem]; + if(_.has(userConfigPath, configItem)) { + currentOption = userConfigPath[configItem]; + } + + // Convert to boolean type if config item boolean + if(_.isBoolean(currentOption)) { + newOption = (newOption == "true"); + } + + // TODO: Same for numbers and that I assume + + event.reply(event.params[1] + ": " + currentOption + " -> " + newOption); + userConfigPath[configItem] = newOption; + dbot.reloadModules(); } }; diff --git a/run.js b/run.js index 2faff6e..69fe227 100644 --- a/run.js +++ b/run.js @@ -162,7 +162,7 @@ DBot.prototype.reloadModules = function() { var config = {}; if(_.has(this.db.config, name)) { - config = this.db.config; + config = this.db.config[name]; } try { From b8b9081e3fa7047857ce68c2562bfc7a8a2d1a94 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 15:20:17 +0000 Subject: [PATCH 198/347] update version to 0.3-dev! --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a71b32e..29d455d 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ -depressionbot version 0.2 (rescore) +depressionbot version 0.3-dev _.each(dbot.modules, function(module) { "RESCORE EVERYTHING" }); "He called his bot depressionbot, and that's when he was happy." From 2607ce1e9307062708528aabfa811b3eb502c212 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 15:49:31 +0000 Subject: [PATCH 199/347] create getcurrentconfigpath for use by other commands --- modules/admin/commands.js | 64 +++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/modules/admin/commands.js b/modules/admin/commands.js index 5ab67f9..51e371e 100644 --- a/modules/admin/commands.js +++ b/modules/admin/commands.js @@ -4,6 +4,29 @@ var fs = require('fs'), exec = require('child_process').exec; var commands = function(dbot) { + var getCurrentConfigPath = function(configKey) { + var configKey = configKey.split('.'); + + defaultConfigPath = dbot.config; + userConfigPath = dbot.db.config; + for(var i=0;i<configKey.length-1;i++) { + if(_.has(defaultConfigPath, configKey[i])) { + if(!_.has(userConfigPath, configKey[i])) { + userConfigPath[configKey[i]] = {}; + } + userConfigPath = userConfigPath[configKey[i]]; + defaultConfigPath = defaultConfigPath[configKey[i]]; + } else { + return false; + } + } + + return { + 'user': userConfigPath, + 'default': defaultConfigPath + }; + }; + var commands = { // Join a channel 'join': function(event) { @@ -154,29 +177,19 @@ var commands = function(dbot) { /*** Config options ***/ 'setconfig': function(event) { - var configKey = event.params[1]; + var configPathString = event.params[1]; + var configKey = _.last(configPathString.split('.')); var newOption = event.params[2]; - configKey = configKey.split('.'); - defaultConfigPath = dbot.config; - userConfigPath = dbot.db.config; - for(var i=0;i<configKey.length-1;i++) { - if(_.has(defaultConfigPath, configKey[i])) { - if(!_.has(userConfigPath, configKey[i])) { - userConfigPath[configKey[i]] = {}; - } - userConfigPath = userConfigPath[configKey[i]]; - defaultConfigPath = defaultConfigPath[configKey[i]]; - } else { - event.reply("Config path doesn't exist."); - return; - } - } - - var configItem = _.last(configKey); - var currentOption = defaultConfigPath[configItem]; - if(_.has(userConfigPath, configItem)) { - currentOption = userConfigPath[configItem]; + var configPath = getCurrentConfigPath(configPathString); + var currentOption; + if(_.has(configPath['user'], configKey)) { + currentOption = configPath['user'][configKey]; + } else if(_.has(configPath['default'], configKey)) { + currentOption = configPath['default'][configKey]; + } else { + event.reply("Config key doesn't exist bro"); + return; } // Convert to boolean type if config item boolean @@ -184,10 +197,14 @@ var commands = function(dbot) { newOption = (newOption == "true"); } + if(_.isArray(currentOption)) { + event.reply("Config option is an array. Try 'pushconfig'."); + } + // TODO: Same for numbers and that I assume - event.reply(event.params[1] + ": " + currentOption + " -> " + newOption); - userConfigPath[configItem] = newOption; + event.reply(configPathString + ": " + currentOption + " -> " + newOption); + userConfigPath[configKey] = newOption; dbot.reloadModules(); } }; @@ -196,6 +213,7 @@ var commands = function(dbot) { commands['reload'].access = 'admin'; commands['unload'].access = 'admin'; commands['load'].access = 'admin'; + commands['setconfig'].access = 'admin'; commands['join'].access = 'moderator'; commands['part'].access = 'moderator'; commands['opme'].access = 'moderator'; From fedb9335a2c68230bdc1e4a8957d0d82800049e4 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 16:17:22 +0000 Subject: [PATCH 200/347] showconfig command [#145] --- modules/admin/commands.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/modules/admin/commands.js b/modules/admin/commands.js index 51e371e..02dd0af 100644 --- a/modules/admin/commands.js +++ b/modules/admin/commands.js @@ -206,6 +206,27 @@ var commands = function(dbot) { event.reply(configPathString + ": " + currentOption + " -> " + newOption); userConfigPath[configKey] = newOption; dbot.reloadModules(); + }, + + 'showconfig': function(event) { + var configPathString = event.params[1]; + var configKey = _.last(configPathString.split('.')); + var configPath = getCurrentConfigPath(configPathString); + + if(!_.has(configPath['default'], configKey)) { + event.reply("Config path doesn't exist"); + return + } + + if(_.isObject(configPath['default'][configKey])) { + event.reply('Config keys in ' + configPathString + ': ' + Object.keys(configPath['default'][configKey])); + } else { + var currentOption = configPath['default'][configKey]; + if(_.has(configPath['user'][configKey])) { + currentOption = configPath['user'][configKey]; + } + event.reply(configPathString + ': ' + currentOption); + } } }; @@ -214,6 +235,7 @@ var commands = function(dbot) { commands['unload'].access = 'admin'; commands['load'].access = 'admin'; commands['setconfig'].access = 'admin'; + commands['showconfig'].access = 'moderator'; commands['join'].access = 'moderator'; commands['part'].access = 'moderator'; commands['opme'].access = 'moderator'; From a80f00038d8c1b676aed4574d7f430a3c069b025 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 16:35:17 +0000 Subject: [PATCH 201/347] showconfig and setconfig for root config options [#145] --- modules/admin/commands.js | 57 ++++++++++++++++++++++----------------- modules/dent/dent.js | 4 +++ 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/modules/admin/commands.js b/modules/admin/commands.js index 02dd0af..4547aae 100644 --- a/modules/admin/commands.js +++ b/modules/admin/commands.js @@ -5,21 +5,23 @@ var fs = require('fs'), var commands = function(dbot) { var getCurrentConfigPath = function(configKey) { - var configKey = configKey.split('.'); + var defaultConfigPath = dbot.config; + var userConfigPath = dbot.db.config; - defaultConfigPath = dbot.config; - userConfigPath = dbot.db.config; - for(var i=0;i<configKey.length-1;i++) { - if(_.has(defaultConfigPath, configKey[i])) { - if(!_.has(userConfigPath, configKey[i])) { - userConfigPath[configKey[i]] = {}; + if(configKey) { + var configKey = configKey.split('.'); + for(var i=0;i<configKey.length-1;i++) { + if(_.has(defaultConfigPath, configKey[i])) { + if(!_.has(userConfigPath, configKey[i])) { + userConfigPath[configKey[i]] = {}; + } + userConfigPath = userConfigPath[configKey[i]]; + defaultConfigPath = defaultConfigPath[configKey[i]]; + } else { + return false; } - userConfigPath = userConfigPath[configKey[i]]; - defaultConfigPath = defaultConfigPath[configKey[i]]; - } else { - return false; } - } + } return { 'user': userConfigPath, @@ -210,22 +212,27 @@ var commands = function(dbot) { 'showconfig': function(event) { var configPathString = event.params[1]; - var configKey = _.last(configPathString.split('.')); var configPath = getCurrentConfigPath(configPathString); + + if(configPathString) { + var configKey = _.last(configPathString.split('.')); - if(!_.has(configPath['default'], configKey)) { - event.reply("Config path doesn't exist"); - return - } - - if(_.isObject(configPath['default'][configKey])) { - event.reply('Config keys in ' + configPathString + ': ' + Object.keys(configPath['default'][configKey])); - } else { - var currentOption = configPath['default'][configKey]; - if(_.has(configPath['user'][configKey])) { - currentOption = configPath['user'][configKey]; + if(!_.has(configPath['default'], configKey)) { + event.reply("Config path doesn't exist"); + return; } - event.reply(configPathString + ': ' + currentOption); + + if(_.isObject(configPath['default'][configKey])) { + event.reply('Config keys in ' + configPathString + ': ' + Object.keys(configPath['default'][configKey])); + } else { + var currentOption = configPath['default'][configKey]; + if(_.has(configPath['user'], configKey)) { + currentOption = configPath['user'][configKey]; + } + event.reply(configKey + ': ' + currentOption); + } + } else { + event.reply('Config keys in root: ' + Object.keys(configPath['default'])); } } }; diff --git a/modules/dent/dent.js b/modules/dent/dent.js index 15d7639..c6b1f8e 100644 --- a/modules/dent/dent.js +++ b/modules/dent/dent.js @@ -37,6 +37,10 @@ var dent = function(dbot) { dbot.api.command.addHook('~qadd', function(key, text) { this.api.post(key + ': ' + text); }.bind(this)); + + if(_.has(dbot.modules, 'quotes')) { + + } }.bind(this); }; From c4301c2ec383741a30c8ee4a660294baa1b8a446 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 17:02:00 +0000 Subject: [PATCH 202/347] correct userconfigpath --- modules/admin/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/admin/commands.js b/modules/admin/commands.js index 4547aae..8c82a6a 100644 --- a/modules/admin/commands.js +++ b/modules/admin/commands.js @@ -206,7 +206,7 @@ var commands = function(dbot) { // TODO: Same for numbers and that I assume event.reply(configPathString + ": " + currentOption + " -> " + newOption); - userConfigPath[configKey] = newOption; + configPath['user'][configKey] = newOption; dbot.reloadModules(); }, From 9cb07dbfba71ce2fe2403360dd57e56e65eb3370 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 17:55:46 +0000 Subject: [PATCH 203/347] Some provisional base functionality for [#160] --- modules/timers/timers.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 modules/timers/timers.js diff --git a/modules/timers/timers.js b/modules/timers/timers.js new file mode 100644 index 0000000..d231dc1 --- /dev/null +++ b/modules/timers/timers.js @@ -0,0 +1,38 @@ +/** + * Module Name: Timers + * Description: Persistent timers and shit + */ +var _ = require('underscore')._; + +var timers = function(dbot) { + this.timers = dbot.db.timers; + this.runningTimers = []; + + this.api = { + 'addTimer': function(callback, timeout, firstDate) { + var now = new Date().getTime(); + if(firstDate) { + console.log('Setting first timer to run at ' + firstDate); + timeout = firstDate.getTime() - now; + setTimeout(function(callback) { + console.log('Running first timer at ' + new Date().toUTCString()); + callback(); + this.api.addTimer(callback, timeout); + }.bind(this), timeout); + } else { + setInterval(function(callback) { + console.log('Running subsequent timer at ' + new Date().toUTCString()); + callback(); + }.bind(this), timeout); + } + } + }; + + this.onLoad = function() { + // TODO: Persist timers + }.bind(this); +}; + +exports.fetch = function(dbot) { + return new timers(dbot); +}; From f908db7b3b2b8017138598464367dc8694a82961 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 18:12:23 +0000 Subject: [PATCH 204/347] that should fix [#164] --- modules/users/commands.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/modules/users/commands.js b/modules/users/commands.js index 8581d77..c0cbc7b 100644 --- a/modules/users/commands.js +++ b/modules/users/commands.js @@ -7,10 +7,7 @@ var commands = function(dbot) { alias = event.params[1].trim(); if(_.include(knownUsers.users, alias)) { - var aliasCount = _.reduce(knownUsers.aliases, function(memo, user) { - if(user == alias) return memo += 1; - }, 0, this); - + var aliasCount = this.api.getAliases(event.server, alias).length; event.reply(dbot.t('primary', { 'user': alias, 'count': aliasCount From 05e6d084b51c060b4493b782919f3048c7ba8d59 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 18:19:44 +0000 Subject: [PATCH 205/347] add some including --- modules/users/commands.js | 13 +++++++++++-- modules/users/strings.json | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/users/commands.js b/modules/users/commands.js index c0cbc7b..87d3257 100644 --- a/modules/users/commands.js +++ b/modules/users/commands.js @@ -7,11 +7,20 @@ var commands = function(dbot) { alias = event.params[1].trim(); if(_.include(knownUsers.users, alias)) { - var aliasCount = this.api.getAliases(event.server, alias).length; + var aliases = this.api.getAliases(event.server, alias); + var aliasCount = aliases.length; + + var aliases = _.first(aliases, 10); + var including = 'including: '; + for(var i=0;i<aliases.length;i++) { + including += alises[i] + ', '; + } + including = including.slice(0, -2) + '.'; + event.reply(dbot.t('primary', { 'user': alias, 'count': aliasCount - })); + }) + including); } else if(_.has(knownUsers.aliases, alias)) { event.reply(dbot.t('alias', { 'alias': alias, diff --git a/modules/users/strings.json b/modules/users/strings.json index 3aaf5bb..e0ffa11 100644 --- a/modules/users/strings.json +++ b/modules/users/strings.json @@ -3,7 +3,7 @@ "english": "{alias} is an alias of {user}" }, "primary": { - "english": "{user} is a primary user with {count} aliases." + "english": "{user} is a primary user with {count} aliases, " }, "unknown_alias": { "english": "{alias} does not currently exist as an alias or known user." From bf40369352450cc77a668f6dab2fada85c70104c Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 18:22:17 +0000 Subject: [PATCH 206/347] typo --- modules/users/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/commands.js b/modules/users/commands.js index 87d3257..137d1de 100644 --- a/modules/users/commands.js +++ b/modules/users/commands.js @@ -13,7 +13,7 @@ var commands = function(dbot) { var aliases = _.first(aliases, 10); var including = 'including: '; for(var i=0;i<aliases.length;i++) { - including += alises[i] + ', '; + including += aliases[i] + ', '; } including = including.slice(0, -2) + '.'; From eb104f157b35fe36ad2b547fdfea5207082e29ae Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 18:26:07 +0000 Subject: [PATCH 207/347] dont show including if no aliases --- modules/users/commands.js | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/modules/users/commands.js b/modules/users/commands.js index 137d1de..32c5867 100644 --- a/modules/users/commands.js +++ b/modules/users/commands.js @@ -10,17 +10,24 @@ var commands = function(dbot) { var aliases = this.api.getAliases(event.server, alias); var aliasCount = aliases.length; - var aliases = _.first(aliases, 10); - var including = 'including: '; - for(var i=0;i<aliases.length;i++) { - including += aliases[i] + ', '; - } - including = including.slice(0, -2) + '.'; + if(aliasCount != 0) { + var aliases = _.first(aliases, 10); + var including = 'including: '; + for(var i=0;i<aliases.length;i++) { + including += aliases[i] + ', '; + } + including = including.slice(0, -2) + '.'; - event.reply(dbot.t('primary', { - 'user': alias, - 'count': aliasCount - }) + including); + event.reply(dbot.t('primary', { + 'user': alias, + 'count': aliasCount + }) + including); + } else { + event.reply(dbot.t('primary', { + 'user': alias, + 'count': aliasCount + })); + } } else if(_.has(knownUsers.aliases, alias)) { event.reply(dbot.t('alias', { 'alias': alias, From e048780cfcb15654c24a85df437d9e52251ee678 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 18:44:21 +0000 Subject: [PATCH 208/347] Fix for [#165]. Recommend deleting knownUsers db on running instances --- modules/users/users.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/users/users.js b/modules/users/users.js index 8bc6c68..c093cff 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -54,12 +54,8 @@ var users = function(dbot) { } } else if(event.action == 'NICK') { var newNick = event.params.substr(1); - if(_.has(knownUsers.aliases, event.user)) { - knownUsers.aliases[newNick] = knownUsers.aliases[event.user]; - } else { - if(!_.include(knownUsers.users, newNick)) { - knownUsers.aliases[newNick] = event.user; - } + if(!this.api.isKnownUser(newNick)) { + knownUsers.aliases[newNick] = this.api.resolveUser(event.server, event.user); } } }.bind(this); From 8a66f5b9c6040a11264bfa99b889f6f202426fe4 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 19:04:12 +0000 Subject: [PATCH 209/347] report uses known users api functionality [#158] --- modules/report/report.js | 3 ++- modules/report/strings.json | 2 +- modules/users/api.js | 10 ++++++++++ modules/users/users.js | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/report/report.js b/modules/report/report.js index cf463f0..2e9bbe9 100644 --- a/modules/report/report.js +++ b/modules/report/report.js @@ -9,7 +9,8 @@ var report = function(dbot) { if(_.has(event.allChannels, channelName)) { var channel = event.allChannels[channelName]; - if(_.has(channel.nicks, nick)) { + if(dbot.api.users.isChannelUser(event.server, nick, channelName, true)) { + var nick = dbot.api.users.resolveUser(event.server, nick, true); var ops = _.filter(channel.nicks, function(user) { return user.op; }); diff --git a/modules/report/strings.json b/modules/report/strings.json index 27f58d6..e5a467d 100644 --- a/modules/report/strings.json +++ b/modules/report/strings.json @@ -6,7 +6,7 @@ "english": "Thank you, {reported} has been reported to the channel administrators." }, "user_not_found": { - "english": "{reported} does not appear to be in {channel}." + "english": "{reported} isn't a known user in {channel}." }, "not_in_channel": { "english": "I am not present in {channel}." diff --git a/modules/users/api.js b/modules/users/api.js index c36e21e..f7571fc 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -65,6 +65,16 @@ var api = function(dbot) { nick = nick.name; return _.include(possiNicks, nick); }, this); + }, + + 'isChannelUser': function(server, user, channel, useLowerCase) { + var knownUsers = this.getServerUsers(server); + var user = this.api.resolveUser(server, user, useLowerCase); + + if(!_.has(knownUsers.channelUsers, channel)) { + return false; + } + return _.include(knownUsers.channelUsers[channel], user); } }; diff --git a/modules/users/users.js b/modules/users/users.js index c093cff..c480dd0 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -49,6 +49,7 @@ var users = function(dbot) { } else { knownUsers.users.push(nick); } + if(!_.include(channelUsers, nick)) { channelUsers.push(nick); } From f04621a5e9377f78e79352c9d56f86ad0bd41e61 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 19:12:34 +0000 Subject: [PATCH 210/347] poll uses knownUsers [#158] --- modules/poll/commands.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/modules/poll/commands.js b/modules/poll/commands.js index 796b32b..bcd8530 100644 --- a/modules/poll/commands.js +++ b/modules/poll/commands.js @@ -14,7 +14,7 @@ var commands = function(dbot) { polls[name] = { 'name': name, 'description': description, - 'owner': event.user, + 'owner': dbot.api.users.resolveUser(event.server, event.user), 'votes': {}, 'votees': {} }; @@ -35,10 +35,11 @@ var commands = function(dbot) { '~addoption': function(event) { var name = event.input[1].toLowerCase(), - option = event.input[2].toLowerCase(); + option = event.input[2].toLowerCase(), + user = dbot.api.users.resolveUser(event.server, event.user); if(_.has(polls, name)) { - if(polls[name].owner === event.user) { + if(polls[name].owner === user) { if(!_.has(polls[name].votes, option)) { polls[name]['votes'][option] = 0; event.reply(dbot.t('option_added', { @@ -66,10 +67,11 @@ var commands = function(dbot) { '~rmoption': function(event) { var name = event.input[1].toLowerCase(), - option = event.input[2].toLowerCase(); + option = event.input[2].toLowerCase(), + user = dbot.api.users.resolveUser(event.server, event.user); if(_.has(polls, name)) { - if(polls[name].owner === event.user) { + if(polls[name].owner === user) { if(_.has(polls[name].votes, option)) { delete polls[name]['votes'][option]; event.reply(dbot.t('option_removed', { @@ -90,15 +92,16 @@ var commands = function(dbot) { '~vote': function(event) { var name = event.input[1].toLowerCase(), - vote = event.input[2].toLowerCase(); + vote = event.input[2].toLowerCase(), + user = dbot.api.users.resolveUser(event.server, event.user); if(_.has(polls, name)) { if(_.has(polls[name].votes, vote)) { - if(_.has(polls[name].votees, event.user)) { + if(_.has(polls[name].votees, user)) { var oldVote = polls[name].votees[event.user]; polls[name].votes[oldVote]--; polls[name].votes[vote]++; - polls[name].votees[event.user] = vote; + polls[name].votees[user] = vote; event.reply(dbot.t('changed_vote', { 'vote': vote, @@ -108,7 +111,7 @@ var commands = function(dbot) { })); } else { polls[name].votes[vote]++; - polls[name].votees[event.user] = vote; + polls[name].votees[user] = vote; event.reply(dbot.t('voted', { 'vote': vote, 'poll': name, From 07656eddcde212f93ff0a9957beffb935333f932 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 20:22:27 +0000 Subject: [PATCH 211/347] hook for update poll nicks [#158][#166] also change mergeusers return api --- modules/poll/poll.js | 19 +++++++++++++++++++ modules/users/commands.js | 1 - 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/poll/poll.js b/modules/poll/poll.js index bda9b6d..1110faa 100644 --- a/modules/poll/poll.js +++ b/modules/poll/poll.js @@ -1,4 +1,23 @@ var poll = function(dbot) { + this.internalAPI = { + 'updatePollNicks': function(server, oldNick) { + var newNick = dbot.api.users.resolveUser(server, oldNick); + _.each(dbot.db.polls, function(poll) { + if(poll.owner === oldNick) { + poll.owner = newNick; + } + if(_.has(poll.votees, oldNick)) { + poll.votees[newNick] = poll.votees[oldNick]; + delete poll.votees[oldNick]; + } + }, this); + } + }; + + this.onLoad = function() { + dbot.api.command.addHook('~setaliasparent', this.internalAPI.updatePollNicks); + dbot.api.command.addHook('~mergeusers', this.internalAPI.updatePollNicks); + }.bind(this); }; exports.fetch = function(dbot) { diff --git a/modules/users/commands.js b/modules/users/commands.js index 32c5867..ed1d561 100644 --- a/modules/users/commands.js +++ b/modules/users/commands.js @@ -92,7 +92,6 @@ var commands = function(dbot) { return { 'server': event.server, - 'primary': primaryUser, 'secondary': secondaryUser }; } else { From d9bd2eb4924a8e49fae80f30e19a65d3b3d7ca9c Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 21:27:49 +0000 Subject: [PATCH 212/347] This should be a fully functional timers module [#160] --- modules/timers/timers.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/modules/timers/timers.js b/modules/timers/timers.js index d231dc1..d5676ee 100644 --- a/modules/timers/timers.js +++ b/modules/timers/timers.js @@ -6,30 +6,36 @@ var _ = require('underscore')._; var timers = function(dbot) { this.timers = dbot.db.timers; - this.runningTimers = []; + this.runningTimeouts = []; + this.runningIntervals = []; this.api = { 'addTimer': function(callback, timeout, firstDate) { var now = new Date().getTime(); if(firstDate) { console.log('Setting first timer to run at ' + firstDate); - timeout = firstDate.getTime() - now; + firstTimeout = firstDate.getTime() - now; setTimeout(function(callback) { console.log('Running first timer at ' + new Date().toUTCString()); + this.runningIntervals.push(this.api.addTimer(callback, timeout)); callback(); - this.api.addTimer(callback, timeout); - }.bind(this), timeout); + }.bind(this), firstTimeout); } else { - setInterval(function(callback) { + this.runningIntervals.push(setInterval(function(callback) { console.log('Running subsequent timer at ' + new Date().toUTCString()); callback(); - }.bind(this), timeout); + }.bind(this), timeout)); } } }; - this.onLoad = function() { - // TODO: Persist timers + this.onDestroy = function() { + for(var i=0;i<this.runningTimeouts;i++ { + clearTimeout(this.runningTimeouts[i]); + } + for(i=0;i<this.runningIntervals;i++ { + clearTimer(this.runningIntervals[i]); + } }.bind(this); }; From 4d7e9343a40aad8fa59683f1ca08e44562c454ba Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 21:28:44 +0000 Subject: [PATCH 213/347] syntax error in previous commit --- modules/timers/timers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/timers/timers.js b/modules/timers/timers.js index d5676ee..432ea1f 100644 --- a/modules/timers/timers.js +++ b/modules/timers/timers.js @@ -30,10 +30,10 @@ var timers = function(dbot) { }; this.onDestroy = function() { - for(var i=0;i<this.runningTimeouts;i++ { + for(var i=0;i<this.runningTimeouts;i++) { clearTimeout(this.runningTimeouts[i]); } - for(i=0;i<this.runningIntervals;i++ { + for(i=0;i<this.runningIntervals;i++) { clearTimer(this.runningIntervals[i]); } }.bind(this); From ff4d1f202165de91a1325e1369e322ba8df28b09 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 21:49:31 +0000 Subject: [PATCH 214/347] documentation for timers module [#160] --- modules/timers/README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 modules/timers/README.md diff --git a/modules/timers/README.md b/modules/timers/README.md new file mode 100644 index 0000000..e610390 --- /dev/null +++ b/modules/timers/README.md @@ -0,0 +1,32 @@ +## Timers + +Timers for fun and profit. + +### Description + +This is a utility module which allows other modules to more easily use timers to +execute functionality, as well as providing simple cron-type functionality for +timers. + +### API + +#### addTimer(callback, interval, [firstDate]) +Execute the given callback every time *interval* (in ms) passes. + +The firstDate parameter is a Date object used to sync a timer to a given point in +time, allowing for cron-type functionality. For example, if you wanted to call a +given function every day at 00:00, you would do the following: + + dbot.api.timers.addTimer(myCallback, 86400000, new Date([midnight tonight])); + +This works like so: + +1. Create a one-time timeout to be executed at the given firstDate (00:00, as +above). +2. Upon this timeout, your callback is executed. Then addTimer is called again +without the firstDate parameter, thus syncing a daily timer to be executed every +day at 00:00. + +The best place to create timers is in your module's onLoad function. Using this, +you may essentially create persistent jobs to be run at regular intervals while +your module is loaded.. From 4f0cfaab9376ce059a18b0d6754cd937e8484e7a Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 20 Jan 2013 21:57:14 +0000 Subject: [PATCH 215/347] change param order for timer --- modules/timers/timers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/timers/timers.js b/modules/timers/timers.js index 432ea1f..76f7aef 100644 --- a/modules/timers/timers.js +++ b/modules/timers/timers.js @@ -10,14 +10,14 @@ var timers = function(dbot) { this.runningIntervals = []; this.api = { - 'addTimer': function(callback, timeout, firstDate) { + 'addTimer': function(timeout, callback, firstDate) { var now = new Date().getTime(); if(firstDate) { console.log('Setting first timer to run at ' + firstDate); firstTimeout = firstDate.getTime() - now; setTimeout(function(callback) { console.log('Running first timer at ' + new Date().toUTCString()); - this.runningIntervals.push(this.api.addTimer(callback, timeout)); + this.runningIntervals.push(this.api.addTimer(timeout, callback)); callback(); }.bind(this), firstTimeout); } else { From 87841bd05123d53594587db4f3ed589d38ccaa36 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sun, 20 Jan 2013 23:07:33 +0000 Subject: [PATCH 216/347] DataTables [#140][#161] --- public/styles.css | 11 +++++++++++ views/layout.jade | 2 +- views/users/users.jade | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/public/styles.css b/public/styles.css index f1c40eb..d89d330 100644 --- a/public/styles.css +++ b/public/styles.css @@ -172,3 +172,14 @@ li.option-votes { box-shadow: inset 0px 0px 3px #444; } + +/** + * DataTables + * Based on http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css + */ +.sorting { background: url('http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_both.png') no-repeat center right; } +.sorting_asc { background: url('http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_asc.png') no-repeat center right; } +.sorting_desc { background: url('http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_desc.png') no-repeat center right; } + +.sorting_asc_disabled { background: url('http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_asc_disabled.png') no-repeat center right; } +.sorting_desc_disabled { background: url('http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_desc_disabled.png') no-repeat center right; } diff --git a/views/layout.jade b/views/layout.jade index cbc8ab2..321bb07 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -2,6 +2,7 @@ html(lang='en') head meta(charset='utf-8') + script(type="text/javascript", src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js") link(rel="stylesheet", type="text/css", href="http://fonts.googleapis.com/css?family=Source+Sans+Pro") link(rel="stylesheet", type="text/css", href="/bootstrap/css/bootstrap.min.css") link(rel='stylesheet', type='text/css', href='/styles.css') @@ -16,4 +17,3 @@ html(lang='en') script(type="text/javascript", src="/bootstrap/js/bootstrap.min.js") script(type="text/javascript", src="/d3/d3.v3.min.js") script(type="text/javascript", src="/script.js") - diff --git a/views/users/users.jade b/views/users/users.jade index 07dbe15..508ed47 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -1,11 +1,44 @@ extends ../layout block content + script(type="text/javascript", src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js") + + script + $(document).ready(function(){ + // Allowing forcing data such as lincent and wpl to sort as numeric + jQuery.extend( jQuery.fn.dataTableExt.oSort, { + "forcenum-pre": function ( a ) { + return parseFloat( a ); + }, + + "forcenum-asc": function ( a, b ) { + return a - b; + }, + + "forcenum-desc": function ( a, b ) { + return b - a; + } + } ); + + $('.data').dataTable({ + "aoColumnDefs": [ + { "sType": "forcenum", "aTargets": [ 3, 4 ] } + ], + "bPaginate": false, + "bLengthChange": false, + "oLanguage": { + "sInfo": "_TOTAL_ users", + "sInfoEmpty": "No users :(", + "sInfoFiltered": "filtered (_MAX_ total)" + }, + }); + }); + h3 Users of #{channel} on #{connection} div#backlink a(href='/channels/'+connection) « Channel List div#row - table.table.table-striped + table.table.table-hover.data thead tr th Users From b6c2c46f6af3526f81578613354c58c0e46a4a58 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sun, 20 Jan 2013 23:15:26 +0000 Subject: [PATCH 217/347] Fix for thousands seps [#140][#161] --- views/users/users.jade | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/views/users/users.jade b/views/users/users.jade index 508ed47..3aff2a3 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -5,9 +5,10 @@ block content script $(document).ready(function(){ - // Allowing forcing data such as lincent and wpl to sort as numeric + // Allowing forcing of string stats data to sort as numeric jQuery.extend( jQuery.fn.dataTableExt.oSort, { "forcenum-pre": function ( a ) { + a = a.replace("\,", ""); return parseFloat( a ); }, @@ -22,7 +23,7 @@ block content $('.data').dataTable({ "aoColumnDefs": [ - { "sType": "forcenum", "aTargets": [ 3, 4 ] } + { "sType": "forcenum", "aTargets": [ 1, 2, 3, 4, 5 ] } ], "bPaginate": false, "bLengthChange": false, From 0343da92d5c7c291420eeb5b1d2e6dfb618ba5a3 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sun, 20 Jan 2013 23:25:00 +0000 Subject: [PATCH 218/347] Disable initial sort [#140][#161] --- views/users/users.jade | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/views/users/users.jade b/views/users/users.jade index 3aff2a3..35b2dca 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -29,9 +29,10 @@ block content "bLengthChange": false, "oLanguage": { "sInfo": "_TOTAL_ users", - "sInfoEmpty": "No users :(", + "sInfoEmpty": "No users", "sInfoFiltered": "filtered (_MAX_ total)" }, + "aaSorting": [], // Disable initial sort }); }); From b24bd63cd0ba0ece0bf17ba2c2420e193ad2d7b8 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 00:05:42 +0000 Subject: [PATCH 219/347] load root config changes [#145] --- run.js | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/run.js b/run.js index 69fe227..7b6cdfc 100644 --- a/run.js +++ b/run.js @@ -5,24 +5,8 @@ var fs = require('fs'), require('./snippets'); var DBot = function(timers) { - // Load config - try { - this.config = JSON.parse(fs.readFileSync('config.json', 'utf-8')); - } catch(err) { - console.log('Config file is invalid. Stopping'); - process.exit(); - } - - try { - var defaultConfig = JSON.parse(fs.readFileSync('config.json.sample', 'utf-8')); - } catch(err) { - console.log('Error loading sample config. Bugger off this should not even be edited. Stopping.'); - process.exit(); - } - - // Load missing config directives from sample file - _.defaults(this.config, defaultConfig); - + + // Load DB var rawDB; try { var rawDB = fs.readFileSync('db.json', 'utf-8'); @@ -42,6 +26,25 @@ var DBot = function(timers) { process.exit(); } + // Load config + this.config = this.db.config; + try { + _.defaults(this.config, JSON.parse(fs.readFileSync('config.json', 'utf-8'))); + } catch(err) { + console.log('Config file is invalid. Stopping'); + process.exit(); + } + + try { + var defaultConfig = JSON.parse(fs.readFileSync('config.json.sample', 'utf-8')); + } catch(err) { + console.log('Error loading sample config. Bugger off this should not even be edited. Stopping.'); + process.exit(); + } + + // Load missing config directives from sample file + _.defaults(this.config, defaultConfig); + // Load Strings file try { this.strings = JSON.parse(fs.readFileSync('strings.json', 'utf-8')); @@ -122,6 +125,9 @@ DBot.prototype.reloadModules = function() { this.commandMap = {}; // Map of which commands belong to which modules this.usage = {}; this.timers.clearTimers(); + + // Load config changes + _.extend(this.config, this.db.config); try { this.strings = JSON.parse(fs.readFileSync('strings.json', 'utf-8')); From 2f05cba9603617d7ae8f0f494993c936c81fb696 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 00:10:01 +0000 Subject: [PATCH 220/347] set some config options not allowed to be changes [#145] --- modules/admin/commands.js | 52 ++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/modules/admin/commands.js b/modules/admin/commands.js index 8c82a6a..7015dd2 100644 --- a/modules/admin/commands.js +++ b/modules/admin/commands.js @@ -4,6 +4,8 @@ var fs = require('fs'), exec = require('child_process').exec; var commands = function(dbot) { + var noChangeConfig = [ 'servers', 'name', 'moduleNames' ]; + var getCurrentConfigPath = function(configKey) { var defaultConfigPath = dbot.config; var userConfigPath = dbot.db.config; @@ -183,31 +185,35 @@ var commands = function(dbot) { var configKey = _.last(configPathString.split('.')); var newOption = event.params[2]; - var configPath = getCurrentConfigPath(configPathString); - var currentOption; - if(_.has(configPath['user'], configKey)) { - currentOption = configPath['user'][configKey]; - } else if(_.has(configPath['default'], configKey)) { - currentOption = configPath['default'][configKey]; + if(!_.include(noChangeConfig, configKey)) { + var configPath = getCurrentConfigPath(configPathString); + var currentOption; + if(_.has(configPath['user'], configKey)) { + currentOption = configPath['user'][configKey]; + } else if(_.has(configPath['default'], configKey)) { + currentOption = configPath['default'][configKey]; + } else { + event.reply("Config key doesn't exist bro"); + return; + } + + // Convert to boolean type if config item boolean + if(_.isBoolean(currentOption)) { + newOption = (newOption == "true"); + } + + if(_.isArray(currentOption)) { + event.reply("Config option is an array. Try 'pushconfig'."); + } + + // TODO: Same for numbers and that I assume + + event.reply(configPathString + ": " + currentOption + " -> " + newOption); + configPath['user'][configKey] = newOption; + dbot.reloadModules(); } else { - event.reply("Config key doesn't exist bro"); - return; + event.reply("This config option cannot be altered while the bot is running."); } - - // Convert to boolean type if config item boolean - if(_.isBoolean(currentOption)) { - newOption = (newOption == "true"); - } - - if(_.isArray(currentOption)) { - event.reply("Config option is an array. Try 'pushconfig'."); - } - - // TODO: Same for numbers and that I assume - - event.reply(configPathString + ": " + currentOption + " -> " + newOption); - configPath['user'][configKey] = newOption; - dbot.reloadModules(); }, 'showconfig': function(event) { From 15eacfd446bc3ecb7e121d67e9770b367465fc86 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Mon, 21 Jan 2013 00:28:11 +0000 Subject: [PATCH 221/347] User column sorts only multi-sorts by [Active,A-z] --- views/users/users.jade | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/views/users/users.jade b/views/users/users.jade index 35b2dca..4ef3022 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -23,7 +23,9 @@ block content $('.data').dataTable({ "aoColumnDefs": [ - { "sType": "forcenum", "aTargets": [ 1, 2, 3, 4, 5 ] } + { "aDataSort": [ 1, 0 ], "asSorting": [ "asc" ], "aTargets": [ 0 ] }, + { "bVisible": false, "aTargets": [ 1 ] }, + { "sType": "forcenum", "aTargets": [ 2, 3, 4, 5, 6 ] } ], "bPaginate": false, "bLengthChange": false, @@ -32,7 +34,6 @@ block content "sInfoEmpty": "No users", "sInfoFiltered": "filtered (_MAX_ total)" }, - "aaSorting": [], // Disable initial sort }); }); @@ -44,6 +45,7 @@ block content thead tr th Users + th th Lines th Words th Lincent @@ -63,6 +65,14 @@ block content span.label.label-important Inactive else span.label Offline + td + if nick.online + if nick.active + -1 + else + 0 + else + 1 td #{nick.fields.lines.data} td From 1673c8846b12e861b8efbd2b44cf1b335fc7a211 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 17:39:21 +0000 Subject: [PATCH 222/347] basic dependencies as per [#85] --- modules/poll/config.json | 3 ++- run.js | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/modules/poll/config.json b/modules/poll/config.json index b7e55ae..7b0f48b 100644 --- a/modules/poll/config.json +++ b/modules/poll/config.json @@ -1,5 +1,6 @@ { "help": "http://github.com/reality/depressionbot/blob/master/modules/poll/README.md", "dbKeys": [ "polls" ], - "ignorable": true + "ignorable": true, + "dependencies": [ "users", "command" ] } diff --git a/run.js b/run.js index 7b6cdfc..9b41610 100644 --- a/run.js +++ b/run.js @@ -178,7 +178,22 @@ DBot.prototype.reloadModules = function() { // Invalid or no config data } - // Load module config + // Shit out if dependencies not met + if(_.has(config, 'dependencies')) { + var unmetDependencies = _.reduce(config.dependencies, function(memo, dependency) { + if(!_.include(moduleNames, dependency)) { + memo.push(dependency); + } + return memo; + }, [], this); + + if(unmetDependencies.length != 0) { + throw new Error("Dependencies not met: " + unmetDependencies); + return; + } + } + + // Generate missing DB keys this.config[name] = config; _.each(config.dbKeys, function(dbKey) { if(!_.has(this.db, dbKey)) { @@ -186,8 +201,6 @@ DBot.prototype.reloadModules = function() { } }, this); - // Override module config with any stored in the DB - // Load the module itself var rawModule = require(moduleDir + name); var module = rawModule.fetch(this); From d246293202f7fbb37b0a43bba4e2a2212b9c6dff Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 17:55:12 +0000 Subject: [PATCH 223/347] Fix [#186] --- run.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run.js b/run.js index 9b41610..6102988 100644 --- a/run.js +++ b/run.js @@ -27,7 +27,7 @@ var DBot = function(timers) { } // Load config - this.config = this.db.config; + this.config = _.clone(this.db.config); try { _.defaults(this.config, JSON.parse(fs.readFileSync('config.json', 'utf-8'))); } catch(err) { From c061109b55d2bdbb9c5f20aa1d43037815bfc83d Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 19:01:53 +0000 Subject: [PATCH 224/347] [#186] fix for modules too --- run.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run.js b/run.js index 6102988..6c782c8 100644 --- a/run.js +++ b/run.js @@ -168,7 +168,7 @@ DBot.prototype.reloadModules = function() { var config = {}; if(_.has(this.db.config, name)) { - config = this.db.config[name]; + config = _.clone(this.db.config[name]); } try { From 1958db6df1a6f5e8fc1a19d525d7750d8aa4b388 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 19:07:25 +0000 Subject: [PATCH 225/347] Denting quotes optional [#181] --- modules/dent/config.json | 3 ++- modules/dent/dent.js | 10 ++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/dent/config.json b/modules/dent/config.json index a55d2eb..527dc55 100644 --- a/modules/dent/config.json +++ b/modules/dent/config.json @@ -1,5 +1,6 @@ { "username": "youruserhere", "password": "yourpasswordhere", - "ignorable": true + "ignorable": true, + "dentQuotes": false } diff --git a/modules/dent/dent.js b/modules/dent/dent.js index c6b1f8e..4e3b425 100644 --- a/modules/dent/dent.js +++ b/modules/dent/dent.js @@ -34,12 +34,10 @@ var dent = function(dbot) { this.commands['~dent'].regex = [/^~dent (.+)$/, 2]; this.onLoad = function() { - dbot.api.command.addHook('~qadd', function(key, text) { - this.api.post(key + ': ' + text); - }.bind(this)); - - if(_.has(dbot.modules, 'quotes')) { - + if(dbot.config.dent.dentQuotes === true) { + dbot.api.command.addHook('~qadd', function(key, text) { + this.api.post(key + ': ' + text); + }.bind(this)); } }.bind(this); }; From dd9962d46541d2c62c30c41f85e58d5007d1cc87 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 19:22:52 +0000 Subject: [PATCH 226/347] Fix [#173] by encoding # in uri and unescaping --- modules/users/pages.js | 2 +- views/users/channels.jade | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/users/pages.js b/modules/users/pages.js index 2708fd8..4c6cf84 100644 --- a/modules/users/pages.js +++ b/modules/users/pages.js @@ -20,7 +20,7 @@ var pages = function(dbot) { '/users/:connection/:channel': function(req, res) { var connection = req.params.connection; - var channel = '#' + req.params.channel; + var channel = _.unescape(req.params.channel); var connections = dbot.instance.connections; if(connections.hasOwnProperty(connection) && diff --git a/views/users/channels.jade b/views/users/channels.jade index 6315ab6..bb3cac4 100644 --- a/views/users/channels.jade +++ b/views/users/channels.jade @@ -6,5 +6,5 @@ block content a(href='/connections') « Connection List ul#quotelist -each channel in channels - a(href='/users/'+connection+'/'+channel.substr(1,channel.length)) + a(href='/users/'+connection+'/'+encodeURIComponent(channel)) li.quotes #{channel} From 4d01187346ed57430ee85afc793286630e16affe Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 19:30:06 +0000 Subject: [PATCH 227/347] Show voting options in ~pdesc [#155] --- modules/poll/commands.js | 11 +++++++++-- modules/poll/strings.json | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/modules/poll/commands.js b/modules/poll/commands.js index bcd8530..ac36252 100644 --- a/modules/poll/commands.js +++ b/modules/poll/commands.js @@ -98,7 +98,7 @@ var commands = function(dbot) { if(_.has(polls, name)) { if(_.has(polls[name].votes, vote)) { if(_.has(polls[name].votees, user)) { - var oldVote = polls[name].votees[event.user]; + var oldVote = polls[name].votees[user]; polls[name].votes[oldVote]--; polls[name].votes[vote]++; polls[name].votees[user] = vote; @@ -131,6 +131,13 @@ var commands = function(dbot) { var name = event.input[1].toLowerCase(); if(_.has(polls, name)) { + var options = _.keys(polls[name].votes); + var optionString = " Choices: "; + for(var i=0;i<options.length;i++) { + optionString += options[i] + ', '; + } + optionString = optionString.slice(0, -2) + '.'; + event.reply(dbot.t('poll_describe', { 'name': name, 'description': polls[name].description, @@ -139,7 +146,7 @@ var commands = function(dbot) { 'port': dbot.config.web.webPort, 'path': 'polls/' + name }) - })); + }) + optionString); } else { event.reply(dbot.t('poll_unexistent', { 'name': name })); } diff --git a/modules/poll/strings.json b/modules/poll/strings.json index 459ea98..412c3ec 100644 --- a/modules/poll/strings.json +++ b/modules/poll/strings.json @@ -17,7 +17,7 @@ "na'vi": "sìpawm sna'o '{name}' ngìyop ({description}). Nga tìpe'unit Pe'eiun - {url}" }, "poll_describe": { - "english": "{name}: {description} - {url}" + "english": "{name}: {description} - {url}." }, "changed_vote": { "english": "{user} changed their vote in {poll} to '{vote}' ({count}).", From d8c133a7b36cab91fc796ffff00afa0e4481ddf8 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 19:42:51 +0000 Subject: [PATCH 228/347] Basic regex replace support [#154] --- modules/regex/config.json | 3 +++ modules/regex/regex.js | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 modules/regex/config.json create mode 100644 modules/regex/regex.js diff --git a/modules/regex/config.json b/modules/regex/config.json new file mode 100644 index 0000000..c945e96 --- /dev/null +++ b/modules/regex/config.json @@ -0,0 +1,3 @@ +{ + "ignorable": true +} diff --git a/modules/regex/regex.js b/modules/regex/regex.js new file mode 100644 index 0000000..9292951 --- /dev/null +++ b/modules/regex/regex.js @@ -0,0 +1,26 @@ +var _ = require('underscore')._; + +var regex = function(dbot) { + this.last = {}; + this.listener = function(event) { + var q = event.message.valMatch(/^s\/(.+)\/(.+)\/$/, 3); + if(q) { + var toMatch = new RegExp(q[1]); + var replaceWith = q[2]; + var last = this.last[event.channel.name][event.user]; + event.reply(event.user + " meant: " + last.replace(toMatch, replaceWith)); + } else { + if(_.has(this.last, event.channel.name)) { + this.last[event.channel.name][event.user] = event.message; + } else { + this.last[event.channel.name] = { }; + this.last[event.channel.name][event.user] = event.message; + } + } + }.bind(this); + this.on = [ 'PRIVMSG' ]; +}; + +exports.fetch = function(dbot) { + return new regex(dbot); +}; From 400d215734ef3076a246bf49d64650cae2523b72 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 19:57:45 +0000 Subject: [PATCH 229/347] Correct other people [#154] --- modules/regex/regex.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/regex/regex.js b/modules/regex/regex.js index 9292951..d693183 100644 --- a/modules/regex/regex.js +++ b/modules/regex/regex.js @@ -4,11 +4,18 @@ var regex = function(dbot) { this.last = {}; this.listener = function(event) { var q = event.message.valMatch(/^s\/(.+)\/(.+)\/$/, 3); + var otherQ = event.message.valMatch(/^([\d\w\s]*): s\/(.+)\/(.+)\/$/, 4); if(q) { var toMatch = new RegExp(q[1]); var replaceWith = q[2]; var last = this.last[event.channel.name][event.user]; event.reply(event.user + " meant: " + last.replace(toMatch, replaceWith)); + } else if(otherQ) { + var user = otherQ[1]; + var toMatch = new RegExp(otherQ[2]); + var replaceWith = otherQ[3]; + var last = this.last[event.channel.name][user]; + event.reply(event.user + " thinks " + user + " meant: " + last.replace(toMatch, replaceWith)); } else { if(_.has(this.last, event.channel.name)) { this.last[event.channel.name][event.user] = event.message; From 24bb198c5dc065c8007a59d1f8c84b6c305cd8aa Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 20:14:51 +0000 Subject: [PATCH 230/347] Bit more efficient. dont bother saying the replacement if replacement not made [#154] --- modules/regex/regex.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/modules/regex/regex.js b/modules/regex/regex.js index d693183..50dd5b6 100644 --- a/modules/regex/regex.js +++ b/modules/regex/regex.js @@ -3,19 +3,23 @@ var _ = require('underscore')._; var regex = function(dbot) { this.last = {}; this.listener = function(event) { - var q = event.message.valMatch(/^s\/(.+)\/(.+)\/$/, 3); - var otherQ = event.message.valMatch(/^([\d\w\s]*): s\/(.+)\/(.+)\/$/, 4); + var q = event.message.valMatch(/^([\d\w\s]*)?:? ?s\/(.+)\/(.+)\/$/, 4); if(q) { - var toMatch = new RegExp(q[1]); - var replaceWith = q[2]; - var last = this.last[event.channel.name][event.user]; - event.reply(event.user + " meant: " + last.replace(toMatch, replaceWith)); - } else if(otherQ) { - var user = otherQ[1]; - var toMatch = new RegExp(otherQ[2]); - var replaceWith = otherQ[3]; - var last = this.last[event.channel.name][user]; - event.reply(event.user + " thinks " + user + " meant: " + last.replace(toMatch, replaceWith)); + var toMatch = new RegExp(q[2]), + replaceWith = q[3], + last, + replacement; + + if(q[1] != null) { + var user = q[1]; + last = this.last[event.channel.name][user]; + replacement = last.replace(toMatch, replaceWith); + if(replacement != last) event.reply(event.user + " thinks " + user + " meant: " + replacement); + } else { + last = this.last[event.channel.name][event.user]; + replacement = last.replace(toMatch, replaceWith); + if(replacement != last) event.reply(event.user + " meant: " + replacement); + } } else { if(_.has(this.last, event.channel.name)) { this.last[event.channel.name][event.user] = event.message; From ed1b4bf7173218218f7ebeb28e8125c679604668 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 20:32:34 +0000 Subject: [PATCH 231/347] Allow flags on the regexen [#154] --- modules/regex/regex.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/regex/regex.js b/modules/regex/regex.js index 50dd5b6..42182aa 100644 --- a/modules/regex/regex.js +++ b/modules/regex/regex.js @@ -3,9 +3,10 @@ var _ = require('underscore')._; var regex = function(dbot) { this.last = {}; this.listener = function(event) { - var q = event.message.valMatch(/^([\d\w\s]*)?:? ?s\/(.+)\/(.+)\/$/, 4); + var q = event.message.valMatch(/^([\d\w\s]*)?:? ?s\/(.+)\/(.+)\/([ig]*)?$/, 5); if(q) { - var toMatch = new RegExp(q[2]), + var flags = q[4], + toMatch = new RegExp(q[2], flags), replaceWith = q[3], last, replacement; From 9ac8d3fd290fa96ee4a900a05cd31acc43ccac85 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 20:38:16 +0000 Subject: [PATCH 232/347] readme for regex [#154] --- modules/regex/README.md | 21 +++++++++++++++++++++ modules/regex/config.json | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 modules/regex/README.md diff --git a/modules/regex/README.md b/modules/regex/README.md new file mode 100644 index 0000000..2db1f02 --- /dev/null +++ b/modules/regex/README.md @@ -0,0 +1,21 @@ +## Regex + +Apply regex and that. + +### Description + +Allows you to run regex replaces on both your own and others messages. One may +run a regex on their own last message like so: + + > user: I like turtles + > user: s/turtles/pizza/ + +One may run a regex on another user's last message simple by hilighting the nick +before the pattern: + + > batman: I like TURTLES + > user: batman: s/turtles/pizza/i + +Note: As this is JS regex, the second part of the regex is actually just a +string and therefore some regex features aren't available (such as lookaheads). +On a related note, the regex flags available for use are limited to i and g. diff --git a/modules/regex/config.json b/modules/regex/config.json index c945e96..a2a42c7 100644 --- a/modules/regex/config.json +++ b/modules/regex/config.json @@ -1,3 +1,4 @@ { - "ignorable": true + "ignorable": true, + "help": "http://github.com/reality/depressionbot/blob/master/modules/regex/README.md" } From 2f2356f2fd7938a09b0292f30fbc56085f592d4e Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 21 Jan 2013 20:50:23 +0000 Subject: [PATCH 233/347] Add dependency info [#187] --- modules/admin/config.json | 1 + modules/dent/config.json | 1 + modules/dent/dent.js | 2 +- modules/dice/config.json | 3 ++- modules/ignore/config.json | 1 + modules/js/config.json | 1 + modules/kick/config.json | 1 + modules/link/config.json | 1 + modules/quotes/commands.js | 2 +- modules/quotes/config.json | 1 + modules/report/config.json | 1 + 11 files changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/admin/config.json b/modules/admin/config.json index dd2edcb..009fb85 100644 --- a/modules/admin/config.json +++ b/modules/admin/config.json @@ -1,5 +1,6 @@ { "ignorable": false, "dbKeys": [ "bans" ], + "dependencies": [ "command" ], "help": "http://github.com/reality/depressionbot/blob/master/modules/admin/README.md" } diff --git a/modules/dent/config.json b/modules/dent/config.json index 527dc55..4a48ea8 100644 --- a/modules/dent/config.json +++ b/modules/dent/config.json @@ -1,6 +1,7 @@ { "username": "youruserhere", "password": "yourpasswordhere", + "dependencies": [ "command" ], "ignorable": true, "dentQuotes": false } diff --git a/modules/dent/dent.js b/modules/dent/dent.js index 4e3b425..8ee57e0 100644 --- a/modules/dent/dent.js +++ b/modules/dent/dent.js @@ -34,7 +34,7 @@ var dent = function(dbot) { this.commands['~dent'].regex = [/^~dent (.+)$/, 2]; this.onLoad = function() { - if(dbot.config.dent.dentQuotes === true) { + if(dbot.config.dent.dentQuotes === true && _.has(dbot.modules, 'quotes')) { dbot.api.command.addHook('~qadd', function(key, text) { this.api.post(key + ': ' + text); }.bind(this)); diff --git a/modules/dice/config.json b/modules/dice/config.json index c945e96..3f82d9c 100644 --- a/modules/dice/config.json +++ b/modules/dice/config.json @@ -1,3 +1,4 @@ { - "ignorable": true + "ignorable": true, + "dependencies": [ "command" ] } diff --git a/modules/ignore/config.json b/modules/ignore/config.json index ef29f33..fa1961a 100644 --- a/modules/ignore/config.json +++ b/modules/ignore/config.json @@ -1,5 +1,6 @@ { "ignorable": false, + "dependencies": [ "command" ], "dbKeys": [ "ignores" ], "help": "http://github.com/reality/depressionbot/blob/master/modules/ignore/README.md" } diff --git a/modules/js/config.json b/modules/js/config.json index a6df84c..084df95 100644 --- a/modules/js/config.json +++ b/modules/js/config.json @@ -4,6 +4,7 @@ "disabled": true } }, + "dependencies": [ "command" ], "ignorable": true, "help": "http://github.com/reality/depressionbot/blob/master/modules/js/README.md" } diff --git a/modules/kick/config.json b/modules/kick/config.json index b73069a..558129d 100644 --- a/modules/kick/config.json +++ b/modules/kick/config.json @@ -1,5 +1,6 @@ { "dbKeys": [ "kicks", "kickers" ], + "dependencies": [ "command" ], "help": "http://github.com/reality/depressionbot/blob/master/modules/kick/README.md", "ignorable": true } diff --git a/modules/link/config.json b/modules/link/config.json index ef7d7ff..9c3dc3e 100644 --- a/modules/link/config.json +++ b/modules/link/config.json @@ -1,5 +1,6 @@ { "autoTitle": false, + "dependencies": [ "command" ], "ignorable": true, "help": "http://github.com/reality/depressionbot/blob/master/modules/link/README.md" } diff --git a/modules/quotes/commands.js b/modules/quotes/commands.js index 824dcb5..c9a54f4 100644 --- a/modules/quotes/commands.js +++ b/modules/quotes/commands.js @@ -103,7 +103,7 @@ var commands = function(dbot) { var key = event.input[1].trim().toLowerCase(); if(_.has(quotes, key)) { var quote = quotes[key].pop(); - if(quotes[key].length === 0) { + if(quotes[key].length == 0) { delete quotes[key]; } this.internalAPI.resetRemoveTimer(event, key, quote); diff --git a/modules/quotes/config.json b/modules/quotes/config.json index cc5526a..4318f50 100644 --- a/modules/quotes/config.json +++ b/modules/quotes/config.json @@ -1,5 +1,6 @@ { "dbKeys": [ "quoteArrs" ], + "dependencies": [ "command" ] "rmLimit": 10, "ignorable": true, "help": "http://github.com/reality/depressionbot/blob/master/modules/quotes/README.md" diff --git a/modules/report/config.json b/modules/report/config.json index 831c099..424160e 100644 --- a/modules/report/config.json +++ b/modules/report/config.json @@ -1,4 +1,5 @@ { "ignorable": true, + "dependencies": [ "command", "users" ], "help": "http://github.com/reality/depressionbot/blob/master/modules/report/README.md" } From b107f64efc9b4316c2cc470081f493ed57de06a9 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 00:00:11 +0000 Subject: [PATCH 234/347] getserverusers --- modules/ignore/ignore.js | 33 ++++++++++++++++++--------------- modules/users/api.js | 4 ++++ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/modules/ignore/ignore.js b/modules/ignore/ignore.js index c456fcb..64f1d27 100644 --- a/modules/ignore/ignore.js +++ b/modules/ignore/ignore.js @@ -9,13 +9,14 @@ var _ = require('underscore')._; var ignore = function(dbot) { var commands = { '~ignore': function(event) { - var module = event.params[1]; - var ignorableModules = _.chain(dbot.modules) - .filter(function(module, name) { - return dbot.config[module].ignorable === true; - }) - .pluck('name') - .value(); + var user = dbot.api.users.resolveUser(event.server, event.user), + module = event.params[1], + ignorableModules = _.chain(dbot.modules) + .filter(function(module, name) { + return dbot.config[module].ignorable === true; + }) + .pluck('name') + .value(); if(_.isUndefined(module)) { event.reply(dbot.t('ignore_usage', { @@ -24,13 +25,13 @@ var ignore = function(dbot) { })); } else { if(_.include(ignorableModules, module)) { - if(_.has(dbot.db.ignores, event.user) && _.include(dbot.db.ignores[event.user], module)) { + if(_.has(dbot.db.ignores, user) && _.include(dbot.db.ignores[user], module)) { event.reply(dbot.t('already_ignoring', { 'user': event.user })); } else { if(_.has(dbot.db.ignores, module)) { - dbot.db.ignores[event.user].push(module); + dbot.db.ignores[user].push(module); } else { - dbot.db.ignores[event.user] = [module]; + dbot.db.ignores[user] = [module]; } dbot.instance.ignoreTag(event.user, module); @@ -46,11 +47,13 @@ var ignore = function(dbot) { }, '~unignore': function(event) { - var ignoredModules = []; + var user = dbot.api.users.resolveUser(event.server, event.user), + module = event.params[1], + ignoredModules = []; + if(_.has(dbot.db.ignores, event.user)) { - ignoredModules = dbot.db.ignores[event.user]; + ignoredModules = dbot.db.ignores[user]; } - var module = event.params[1]; if(_.isUndefined(module)) { event.reply(dbot.t('unignore_usage', { @@ -59,8 +62,8 @@ var ignore = function(dbot) { })); } else { if(_.include(ignoredModules, module)) { - dbot.db.ignores[event.user].splice(dbot.db.ignores[event.user].indexOf(module), 1); - dbot.instance.removeIgnore(event.user, module) + dbot.db.ignores[user].splice(dbot.db.ignores[user].indexOf(module), 1); + dbot.instance.removeIgnore(user, module) event.reply(dbot.t('unignored', { 'user': event.user, 'module': module diff --git a/modules/users/api.js b/modules/users/api.js index f7571fc..9ecadc2 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -36,6 +36,10 @@ var api = function(dbot) { return user; }, + 'getServerUsers': function(server) { + return dbot.db.knownUsers[server].users; + }, + 'isKnownUser': function(server, nick) { var knownUsers = this.getServerUsers(server); return (_.include(knownUsers.users, nick) || _.has(knownUsers.aliases, nick)); From 3b3aa280e03a87f9275a82ff83622cb6087aa4c8 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 00:24:12 +0000 Subject: [PATCH 235/347] getAllUsers --- modules/users/api.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/users/api.js b/modules/users/api.js index 9ecadc2..349e3a2 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -40,6 +40,10 @@ var api = function(dbot) { return dbot.db.knownUsers[server].users; }, + 'getAllUsers': function() { + return _.pluck(dbot.db.knownUsers, 'users'); + }, + 'isKnownUser': function(server, nick) { var knownUsers = this.getServerUsers(server); return (_.include(knownUsers.users, nick) || _.has(knownUsers.aliases, nick)); From 5443752a8b26a7ddc1b0a0842d3c5eb68eaddadf Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 00:28:50 +0000 Subject: [PATCH 236/347] link this.config to module config --- run.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/run.js b/run.js index 6c782c8..9ace45c 100644 --- a/run.js +++ b/run.js @@ -201,6 +201,8 @@ DBot.prototype.reloadModules = function() { } }, this); + module.config = this.config[name]; + // Load the module itself var rawModule = require(moduleDir + name); var module = rawModule.fetch(this); From 80fec7b2128c5c44be959fbe5125e74958755373 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 00:39:04 +0000 Subject: [PATCH 237/347] do that in the righ tplace... --- run.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run.js b/run.js index 9ace45c..b2c8b81 100644 --- a/run.js +++ b/run.js @@ -201,14 +201,14 @@ DBot.prototype.reloadModules = function() { } }, this); - module.config = this.config[name]; - // Load the module itself var rawModule = require(moduleDir + name); var module = rawModule.fetch(this); module.name = name; this.rawModules.push(rawModule); + module.config = this.config[name]; + // Load the module data _.each([ 'commands', 'pages', 'api' ], function(property) { var propertyObj = {}; From b940b6f913fd97283a14b9c8207df5382fc71836 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 00:53:30 +0000 Subject: [PATCH 238/347] that should do it --- modules/users/api.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/users/api.js b/modules/users/api.js index 349e3a2..c523d0b 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -41,7 +41,9 @@ var api = function(dbot) { }, 'getAllUsers': function() { - return _.pluck(dbot.db.knownUsers, 'users'); + return _.reduce(dbot.db.knownUsers, function(memo, function(server, name) { + memo[name] = server.users; + }, {}, this); }, 'isKnownUser': function(server, nick) { From 909dd619828cce4a91c2285452e9147bac3b381d Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 00:56:05 +0000 Subject: [PATCH 239/347] whoops --- modules/users/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/api.js b/modules/users/api.js index c523d0b..bc34913 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -43,7 +43,7 @@ var api = function(dbot) { 'getAllUsers': function() { return _.reduce(dbot.db.knownUsers, function(memo, function(server, name) { memo[name] = server.users; - }, {}, this); + }, {}, this)); }, 'isKnownUser': function(server, nick) { From b8546358fb4f3ddd94f919bad820ae2965781e97 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 00:59:11 +0000 Subject: [PATCH 240/347] another whoops --- modules/users/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/api.js b/modules/users/api.js index bc34913..cf7745d 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -41,7 +41,7 @@ var api = function(dbot) { }, 'getAllUsers': function() { - return _.reduce(dbot.db.knownUsers, function(memo, function(server, name) { + return _.reduce(dbot.db.knownUsers, function(memo, server, name) { memo[name] = server.users; }, {}, this)); }, From d059732cb8ed8424d70e4736072098910c908fc9 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 01:00:56 +0000 Subject: [PATCH 241/347] ok fuck you --- modules/users/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/api.js b/modules/users/api.js index cf7745d..56fd209 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -43,7 +43,7 @@ var api = function(dbot) { 'getAllUsers': function() { return _.reduce(dbot.db.knownUsers, function(memo, server, name) { memo[name] = server.users; - }, {}, this)); + }, {}, this); }, 'isKnownUser': function(server, nick) { From 7d744ef8492c03045ba979aece31944a4821757a Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 01:06:29 +0000 Subject: [PATCH 242/347] f --- modules/users/api.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/users/api.js b/modules/users/api.js index 56fd209..3ef59be 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -43,6 +43,7 @@ var api = function(dbot) { 'getAllUsers': function() { return _.reduce(dbot.db.knownUsers, function(memo, server, name) { memo[name] = server.users; + return memo; }, {}, this); }, From 5b965657bba6c7de3d1f29033969b4658021fd89 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 12:21:14 +0100 Subject: [PATCH 243/347] second part of the regexen can be empty --- modules/regex/regex.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/regex/regex.js b/modules/regex/regex.js index 42182aa..0444950 100644 --- a/modules/regex/regex.js +++ b/modules/regex/regex.js @@ -3,7 +3,7 @@ var _ = require('underscore')._; var regex = function(dbot) { this.last = {}; this.listener = function(event) { - var q = event.message.valMatch(/^([\d\w\s]*)?:? ?s\/(.+)\/(.+)\/([ig]*)?$/, 5); + var q = event.message.valMatch(/^([\d\w\s]*)?:? ?s\/(.+)\/(.+)?\/([ig]*)?$/, 5); if(q) { var flags = q[4], toMatch = new RegExp(q[2], flags), From 6e08b184f67168d44ea135f38e51b7f0dc566a50 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 12:22:55 +0100 Subject: [PATCH 244/347] replaceWith empty if no q[3] --- modules/regex/regex.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/regex/regex.js b/modules/regex/regex.js index 0444950..48b8e21 100644 --- a/modules/regex/regex.js +++ b/modules/regex/regex.js @@ -10,6 +10,8 @@ var regex = function(dbot) { replaceWith = q[3], last, replacement; + + if(!replaceWith) replaceWith = ""; if(q[1] != null) { var user = q[1]; From f7acd2e01b5d4dffa62ad4120b06ac650e5b0393 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 19:33:22 +0000 Subject: [PATCH 245/347] revert to older, non-broken ignore. whoops! --- modules/ignore/ignore.js | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/modules/ignore/ignore.js b/modules/ignore/ignore.js index 64f1d27..c456fcb 100644 --- a/modules/ignore/ignore.js +++ b/modules/ignore/ignore.js @@ -9,14 +9,13 @@ var _ = require('underscore')._; var ignore = function(dbot) { var commands = { '~ignore': function(event) { - var user = dbot.api.users.resolveUser(event.server, event.user), - module = event.params[1], - ignorableModules = _.chain(dbot.modules) - .filter(function(module, name) { - return dbot.config[module].ignorable === true; - }) - .pluck('name') - .value(); + var module = event.params[1]; + var ignorableModules = _.chain(dbot.modules) + .filter(function(module, name) { + return dbot.config[module].ignorable === true; + }) + .pluck('name') + .value(); if(_.isUndefined(module)) { event.reply(dbot.t('ignore_usage', { @@ -25,13 +24,13 @@ var ignore = function(dbot) { })); } else { if(_.include(ignorableModules, module)) { - if(_.has(dbot.db.ignores, user) && _.include(dbot.db.ignores[user], module)) { + if(_.has(dbot.db.ignores, event.user) && _.include(dbot.db.ignores[event.user], module)) { event.reply(dbot.t('already_ignoring', { 'user': event.user })); } else { if(_.has(dbot.db.ignores, module)) { - dbot.db.ignores[user].push(module); + dbot.db.ignores[event.user].push(module); } else { - dbot.db.ignores[user] = [module]; + dbot.db.ignores[event.user] = [module]; } dbot.instance.ignoreTag(event.user, module); @@ -47,13 +46,11 @@ var ignore = function(dbot) { }, '~unignore': function(event) { - var user = dbot.api.users.resolveUser(event.server, event.user), - module = event.params[1], - ignoredModules = []; - + var ignoredModules = []; if(_.has(dbot.db.ignores, event.user)) { - ignoredModules = dbot.db.ignores[user]; + ignoredModules = dbot.db.ignores[event.user]; } + var module = event.params[1]; if(_.isUndefined(module)) { event.reply(dbot.t('unignore_usage', { @@ -62,8 +59,8 @@ var ignore = function(dbot) { })); } else { if(_.include(ignoredModules, module)) { - dbot.db.ignores[user].splice(dbot.db.ignores[user].indexOf(module), 1); - dbot.instance.removeIgnore(user, module) + dbot.db.ignores[event.user].splice(dbot.db.ignores[event.user].indexOf(module), 1); + dbot.instance.removeIgnore(event.user, module) event.reply(dbot.t('unignored', { 'user': event.user, 'module': module From fba8edef18a8b5b800002c3c9302750d9ef5f9a9 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 19:52:26 +0000 Subject: [PATCH 246/347] ~ud was surprisingly easy [#192] --- modules/link/link.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/link/link.js b/modules/link/link.js index cbd9c2a..0efbd02 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -10,7 +10,7 @@ var link = function(dbot) { this.urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; this.links = {}; this.fetchTitle = function(event, link) { - request(link, function (error, response, body) { + 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); @@ -31,6 +31,18 @@ var link = function(dbot) { } } this.fetchTitle(event, link); + }, + + '~ud': function(event) { + var reqUrl = 'http://api.urbandictionary.com/v0/define?term=' + event.params[1]; + request(reqUrl, function(error, response, body) { + var result = JSON.parse(body); + if(_.has(result, 'result_type') && result.result_type != 'no_results') { + event.reply(event.params[1] + ': ' + result.list[0].definition); + } else { + event.reply(event.user + ': No definition found.'); + } + }); } }; this.commands = commands; From 612171d28837d2a3613c02cd9ac29d62801330e1 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Tue, 22 Jan 2013 20:44:45 +0000 Subject: [PATCH 247/347] Preliminary Profiles [#183][#184][MADE BY @samstudio8 #185] --- modules/profile/api.js | 22 +++++++++++ modules/profile/commands.js | 28 +++++++++++++ modules/profile/config.json | 18 +++++++++ modules/profile/pages.js | 30 ++++++++++++++ modules/profile/profile.js | 40 +++++++++++++++++++ modules/users/pages.js | 32 --------------- views/profile/profile.jade | 79 +++++++++++++++++++++++++++++++++++++ views/users/users.jade | 6 ++- 8 files changed, 221 insertions(+), 34 deletions(-) create mode 100644 modules/profile/api.js create mode 100644 modules/profile/commands.js create mode 100644 modules/profile/config.json create mode 100644 modules/profile/pages.js create mode 100644 modules/profile/profile.js create mode 100644 views/profile/profile.jade diff --git a/modules/profile/api.js b/modules/profile/api.js new file mode 100644 index 0000000..e6b22c8 --- /dev/null +++ b/modules/profile/api.js @@ -0,0 +1,22 @@ +var _ = require('underscore')._; + +var api = function(dbot) { + return { + + /** + * Create a profile for a new primary user on a given server. + * If the server does not already exist, create it. + */ + "createProfile": function(server, primary){ + if(!_.has(this.profiles, server)){ + this.profiles[server] = {}; + } + this.profiles[server][primary] = {}; + _.defaults(this.profiles[server][primary], this.config.schema); + }, + } +}; + +exports.fetch = function(dbot) { + return api(dbot); +}; diff --git a/modules/profile/commands.js b/modules/profile/commands.js new file mode 100644 index 0000000..a836c2d --- /dev/null +++ b/modules/profile/commands.js @@ -0,0 +1,28 @@ +var _ = require('underscore')._; + +var commands = function(dbot){ + return { + + "~test_getprop": function(event){ + if(event.params[1]){ + var res = dbot.db.profiles[event.server][event.user.toLowerCase()].profile[event.params[1]]; + if(res){ + event.reply(res); + } + else{ + event.reply("Nope."); + } + } + }, + + "~test_setprop": function(event){ + if(event.params[1] && event.params[2]){ + dbot.db.profiles[event.server][event.user.toLowerCase()].profile[event.params[1]] = event.params[2]; + } + } + } +}; + +exports.fetch = function(dbot){ + return commands(dbot); +}; diff --git a/modules/profile/config.json b/modules/profile/config.json new file mode 100644 index 0000000..0082dd3 --- /dev/null +++ b/modules/profile/config.json @@ -0,0 +1,18 @@ +{ + "ignorable": false, + "dbKeys": [ "profiles" ], + "help": "https://github.com/reality/depressionbot/blob/master/modules/profile/README.md", + "schema": { + "profile": { + "primary": null, + "name": null, + "tagline": null, + "favourites": { + "colour": null + } + }, + "preferences": { + "timezone": null + } + } +} diff --git a/modules/profile/pages.js b/modules/profile/pages.js new file mode 100644 index 0000000..379892c --- /dev/null +++ b/modules/profile/pages.js @@ -0,0 +1,30 @@ +var pages = function(dbot) { + var _ = require('underscore')._; + var connections = dbot.instance.connections; + + return { + '/profile/:connection/:user': function(req, res) { + var connection = req.params.connection; + var user = dbot.cleanNick(req.params.user); + + var primary = dbot.api.users.resolveUser(connection, user, true); + //var profile = dbot.api.profile.getProfile(primary); + var profile = dbot.db.profiles[connection][primary.toLowerCase()].profile; + var stats = dbot.api.stats.getUserChansStats(connection, primary.toLowerCase(), [ + "lines", "words", "lincent", "wpl", "in_mentions"] + ); + + res.render('profile', { + 'name': dbot.config.name, + 'connection': connection, + 'primary': primary, + 'profile': profile, + 'stats': stats.channels, + }); + } + } +}; + +exports.fetch = function(dbot) { + return pages(dbot); +}; diff --git a/modules/profile/profile.js b/modules/profile/profile.js new file mode 100644 index 0000000..4c991b4 --- /dev/null +++ b/modules/profile/profile.js @@ -0,0 +1,40 @@ +var _ = require('underscore')._; + +var profile = function(dbot) { + + this.profiles = dbot.db.profiles; + + /** + * Iterate over known user profiles and ensure they contain all the + * required properties as defined in the configuation. + */ + this.onLoad = function(){ + var schema = this.config.schema; + + // Ensure all known users have a profile + _.each(dbot.api.users.getAllUsers(), function(server, serverName){ + if(!_.has(dbot.db.profiles, serverName)){ + dbot.db.profiles[serverName] = {} + } + _.each(server, function(userName){ + var primary = userName; + userName = userName.toLowerCase(); + if(!_.has(dbot.db.profiles[serverName], userName)){ + dbot.db.profiles[serverName][userName] = { + "profile": {}, + "preferences": {} + }; + } + //TODO(samstudio8) Currently only handles "top-level" + _.defaults(dbot.db.profiles[serverName][userName].profile, schema.profile); + _.defaults(dbot.db.profiles[serverName][userName].preferences, schema.preferences); + dbot.db.profiles[serverName][userName].profile.primary = primary; + }); + }); + dbot.save(); + }; +}; + +exports.fetch = function(dbot) { + return new profile(dbot); +}; diff --git a/modules/users/pages.js b/modules/users/pages.js index 4c6cf84..c3fad15 100644 --- a/modules/users/pages.js +++ b/modules/users/pages.js @@ -66,38 +66,6 @@ var pages = function(dbot) { res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection or channel.' }); } }, - - '/user/:connection/:channel/:user': function(req, res) { - var connection = req.params.connection; - var channel = '#' + req.params.channel; - var user = dbot.cleanNick(req.params.user); - - var quoteCount = 'no'; - if(dbot.db.quoteArrs.hasOwnProperty(user)) { - var quoteCount = dbot.db.quoteArrs[user].length; - } - - if(dbot.config.moduleNames.include('kick')) { - if(!dbot.db.kicks.hasOwnProperty(req.params.user)) { - var kicks = '0'; - } else { - var kicks = dbot.db.kicks[req.params.user]; - } - - if(!dbot.db.kickers.hasOwnProperty(req.params.user)) { - var kicked = '0'; - } else { - var kicked = dbot.db.kickers[req.params.user]; - } - } else { - var kicks = 'N/A'; - var kicked = 'N/A'; - } - - res.render('user', { 'name': dbot.config.name, 'user': req.params.user, - 'channel': channel, 'connection': connection, 'cleanUser': user, - 'quotecount': quoteCount, 'kicks': kicks, 'kicked': kicked }); - } }; }; diff --git a/views/profile/profile.jade b/views/profile/profile.jade new file mode 100644 index 0000000..4648573 --- /dev/null +++ b/views/profile/profile.jade @@ -0,0 +1,79 @@ +extends ../layout + +block content + script(type="text/javascript", src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js") + + script + $(document).ready(function(){ + // Allowing forcing of string stats data to sort as numeric + jQuery.extend( jQuery.fn.dataTableExt.oSort, { + "forcenum-pre": function ( a ) { + a = a.replace("\,", ""); + return parseFloat( a ); + }, + + "forcenum-asc": function ( a, b ) { + return a - b; + }, + + "forcenum-desc": function ( a, b ) { + return b - a; + } + } ); + + $('.data').dataTable({ + "aoColumnDefs": [ + { "sType": "forcenum", + "asSorting": [ "desc", "asc" ], + "aTargets": [ 1, 2, 3, 4, 5 ] } + ], + "bPaginate": false, + "bFilter": false, + "bLengthChange": false, + "oLanguage": { + "sInfo": "", + "sInfoEmpty": "", + "sInfoFiltered": "" + }, + }); + }); + + div.page-header + h1 + #{primary} + + div#row + table.table.table-hover.data + thead + tr + th Channel + th Lines + th Words + th Lincent + th Verbosity + th Mentions + tbody + for chan, key in stats + if stats.hasOwnProperty(key) + tr + td + a(href='/users/'+connection+'/'+encodeURIComponent(key)) + #{key} + span + if chan.online + if chan.active + span.label.label-success Active + else + span.label.label-important Inactive + else + span.label Offline + td + #{chan.fields.lines.data} + td + #{chan.fields.words.data} + td + #{chan.fields.lincent.data} + td + #{chan.fields.wpl.data} + td + #{chan.fields.in_mentions.data} diff --git a/views/users/users.jade b/views/users/users.jade index 4ef3022..23251a1 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -25,7 +25,9 @@ block content "aoColumnDefs": [ { "aDataSort": [ 1, 0 ], "asSorting": [ "asc" ], "aTargets": [ 0 ] }, { "bVisible": false, "aTargets": [ 1 ] }, - { "sType": "forcenum", "aTargets": [ 2, 3, 4, 5, 6 ] } + { "sType": "forcenum", + "asSorting": [ "desc", "asc" ], + "aTargets": [ 2, 3, 4, 5, 6 ] } ], "bPaginate": false, "bLengthChange": false, @@ -55,7 +57,7 @@ block content -each nick in nicks tr td - a(href='/user/'+connection+'/'+channel.substr(1,channel.length)+'/'+nick.primary) + a(href='/profile/'+connection+'/'+nick.primary) #{nick.display} span if nick.online From d5328377e5d0a09480b840880fe22fb8c05fdd13 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 20:47:15 +0000 Subject: [PATCH 248/347] bump stats version --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index a601379..fece199 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit a60137999d1a50543022c96056234dfdb25525e3 +Subproject commit fece19922340d94d48c6dc4c3f5692af9a1d00b1 From 82d0362ee375ae9eb7660b183c79d4b8211194a6 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 21:04:34 +0000 Subject: [PATCH 249/347] bump stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index fece199..52a4a74 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit fece19922340d94d48c6dc4c3f5692af9a1d00b1 +Subproject commit 52a4a74f53b99ade143d61b703a92bb37e5de4e0 From 1e70646ae5d62696a398f3290f29c7427ed3df22 Mon Sep 17 00:00:00 2001 From: Douglas Gardner <douglas@chippy.ch> Date: Tue, 22 Jan 2013 21:07:04 +0000 Subject: [PATCH 250/347] update documentation Added README to the dice module. Updated the README in the link module to reflect changes in fba8edef18a8b5b800002c3c9302750d9ef5f9a9 --- modules/dice/README.md | 9 +++++++++ modules/link/README.md | 2 ++ 2 files changed, 11 insertions(+) create mode 100644 modules/dice/README.md diff --git a/modules/dice/README.md b/modules/dice/README.md new file mode 100644 index 0000000..049d695 --- /dev/null +++ b/modules/dice/README.md @@ -0,0 +1,9 @@ +## Dice +Rolls virtual dice. + +### Description +Rolls a virtual die and outputs the result to the channel. +### Commands + +#### ~roll <die type> +Rolls a die. 1d6 will be rolled by default. diff --git a/modules/link/README.md b/modules/link/README.md index 5b83bce..24c52d0 100644 --- a/modules/link/README.md +++ b/modules/link/README.md @@ -19,3 +19,5 @@ they are posted in the channel. If called with a link, the bot will attempt to find and return the title of that page. If called without a link, the bot will attempt the same on the last link which was posted in the current channel. +#### ~ud [headword] +Returns the first [Urban Dictionary](http://www.urbandictionary.com) definition for the headword provided. From 4f530e5bc67e5200e76135a5954c84d7045ae695 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 23:27:02 +0000 Subject: [PATCH 251/347] fix db meltage. [#191] --- modules/web/web.js | 11 +++++++++++ run.js | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/web/web.js b/modules/web/web.js index 04823d3..6ec409e 100644 --- a/modules/web/web.js +++ b/modules/web/web.js @@ -12,6 +12,17 @@ var webInterface = function(dbot) { app.get('/', function(req, res) { res.render('index', { 'name': dbot.config.name }); }); + + console.log(Object.keys(app)); + + app.configure(function(){ + app.use(function(err, req, res, next) { + console.log('Web encountered an error: ' + err); + }); + }); + app.on('error', function(err) { + console.log('Web encountered an error: ' + err); + }); var server = app.listen(dbot.config.web.webPort); diff --git a/run.js b/run.js index b2c8b81..e63ccc7 100644 --- a/run.js +++ b/run.js @@ -104,7 +104,7 @@ DBot.prototype.t = function(string, formatData) { // Save the database file DBot.prototype.save = function() { - fs.writeFile('db.json', JSON.stringify(this.db, null, ' ')); + fs.writeFileSync('db.json', JSON.stringify(this.db, null, ' ')); }; // Hot-reload module files. From 27e79641d590e77bef26f7c9b2394bb20f34388f Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 22 Jan 2013 23:29:49 +0000 Subject: [PATCH 252/347] revert web shit --- modules/web/web.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/modules/web/web.js b/modules/web/web.js index 6ec409e..a71dac3 100644 --- a/modules/web/web.js +++ b/modules/web/web.js @@ -12,18 +12,7 @@ var webInterface = function(dbot) { app.get('/', function(req, res) { res.render('index', { 'name': dbot.config.name }); }); - - console.log(Object.keys(app)); - - app.configure(function(){ - app.use(function(err, req, res, next) { - console.log('Web encountered an error: ' + err); - }); - }); - app.on('error', function(err) { - console.log('Web encountered an error: ' + err); - }); - + var server = app.listen(dbot.config.web.webPort); this.reloadPages = function() { From b0752f779b42b18822eccd6321bafe7c96de3f78 Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Wed, 23 Jan 2013 10:36:46 +0100 Subject: [PATCH 253/347] Get mogglington his pony maybe [#193] --- modules/spelling/spelling.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/spelling/spelling.js b/modules/spelling/spelling.js index 7803c42..5078e29 100644 --- a/modules/spelling/spelling.js +++ b/modules/spelling/spelling.js @@ -113,7 +113,7 @@ var spelling = function(dbot) { this.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); + var otherQ = event.message.valMatch(/^([\d\w\s]*)[:|,] (?:\*\*?([\d\w\s']*)|([\d\w\s']*)\*\*?)$/, 4); if(q) { this.internalAPI.correct(event, q[1] || q[2], event.user, function (e) { event.reply(dbot.t('spelling_self', e)); From d7bbd573581954713269caeb2ef70ec4109ee747 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 23 Jan 2013 13:40:33 +0000 Subject: [PATCH 254/347] what a fool --- modules/command/command.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/command/command.js b/modules/command/command.js index 0895a94..a142bba 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -14,11 +14,11 @@ var command = function(dbot) { this.listener = function(event) { var commandName = event.params[0]; if(!_.has(dbot.commands, commandName)) { - if(_.has(dbot.modules, 'quotes')) { + /*if(_.has(dbot.modules, 'quotes')) { commandName = '~'; - } else { + } else {*/ return; - } + //} } if(this.api.isBanned(event.user, commandName)) { From b12259643abd66f93e8968e273c9ffe06e155d1b Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 23 Jan 2013 16:12:08 +0000 Subject: [PATCH 255/347] sometimes i think i might be retarded --- modules/quotes/commands.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/modules/quotes/commands.js b/modules/quotes/commands.js index c9a54f4..c3d0522 100644 --- a/modules/quotes/commands.js +++ b/modules/quotes/commands.js @@ -1,6 +1,7 @@ var _ = require('underscore')._; var commands = function(dbot) { + var quotes = dbot.db.quoteArrs; var commands = { // Alternative syntax to ~q '~': function(event) { @@ -26,7 +27,6 @@ var commands = function(dbot) { }, '~rmdeny': function(event) { - var quotes = this.quotes; var rmCache = this.rmCache; var rmCacheCount = rmCache.length; for(var i=0;i<rmCacheCount;i++) { @@ -55,7 +55,6 @@ var commands = function(dbot) { // Shows a list of the biggest categories '~qstats': function(event) { - var quotes = this.quotes; var qSizes = _.chain(quotes) .pairs() .sortBy(function(category) { return category[1].length }) @@ -74,7 +73,6 @@ var commands = function(dbot) { // Search a given category for some text. // TODO fix '~qsearch': function(event) { - var quotes = this.quotes; var haystack = event.input[1].trim().toLowerCase(); var needle = event.input[2]; if(_.has(quotes, haystack)) { @@ -98,7 +96,6 @@ var commands = function(dbot) { }, '~rmlast': function(event) { - var quotes = this.quotes; if(this.rmAllowed == true || _.include(dbot.config.admins, event.user)) { var key = event.input[1].trim().toLowerCase(); if(_.has(quotes, key)) { @@ -122,7 +119,6 @@ var commands = function(dbot) { '~rm': function(event) { if(this.rmAllowed == true || _.include(dbot.config.admins, event.user)) { - var quotes = this.quotes; var key = event.input[1].trim().toLowerCase(); var quote = event.input[2]; @@ -150,7 +146,6 @@ var commands = function(dbot) { '~qcount': function(event) { var input = event.message.valMatch(/^~qcount ([\d\w\s-]*)/, 2); - var quotes = this.quotes; if(input) { // Give quote count for named category var key = input[1].trim().toLowerCase(); if(_.has(quotes, key)) { @@ -170,7 +165,6 @@ var commands = function(dbot) { }, '~qadd': function(event) { - var quotes = this.quotes; var key = event.input[1].toLowerCase(); var text = event.input[2]; if(!_.isArray(quotes[key])) { @@ -193,14 +187,13 @@ var commands = function(dbot) { }, '~rq': function(event) { - var quotes = this.quotes; var category = _.keys(quotes)[_.random(0, _.size(quotes) -1)]; event.reply(category + ': ' + this.internalAPI.interpolatedQuote(event, category)); }, '~link': function(event) { var key = event.params[1].trim().toLowerCase(); - if(_.has(this.quotes, key)) { + if(_.has(quotes, key)) { event.reply(dbot.t('quote_link', { 'category': key, 'url': dbot.t('url', { From c77cb09f8722257eea467be17025b8e879fc02c4 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 23 Jan 2013 16:24:52 +0000 Subject: [PATCH 256/347] syntax error in quotes conf --- modules/quotes/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quotes/config.json b/modules/quotes/config.json index 4318f50..7530554 100644 --- a/modules/quotes/config.json +++ b/modules/quotes/config.json @@ -1,6 +1,6 @@ { "dbKeys": [ "quoteArrs" ], - "dependencies": [ "command" ] + "dependencies": [ "command" ], "rmLimit": 10, "ignorable": true, "help": "http://github.com/reality/depressionbot/blob/master/modules/quotes/README.md" From 098f19078d15de61c12f5fb35aa1870e1aea5f78 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Wed, 23 Jan 2013 18:00:27 +0000 Subject: [PATCH 257/347] Return last seen string in tooltip --- views/profile/profile.jade | 9 +++++---- views/users/users.jade | 11 ++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/views/profile/profile.jade b/views/profile/profile.jade index 4648573..191147b 100644 --- a/views/profile/profile.jade +++ b/views/profile/profile.jade @@ -21,6 +21,7 @@ block content } } ); + $('.tip').tooltip(); $('.data').dataTable({ "aoColumnDefs": [ { "sType": "forcenum", @@ -61,12 +62,12 @@ block content #{key} span if chan.online - if chan.active - span.label.label-success Active + if chan.active.active + span.label.label-success.tip(data-original-title="#{chan.active.ago}", data-placement="right") Active else - span.label.label-important Inactive + span.label.label-important.tip(data-original-title="#{chan.active.ago}", data-placement="right") Inactive else - span.label Offline + span.label.tip(data-original-title="#{chan.active.ago}", data-placement="right") Offline td #{chan.fields.lines.data} td diff --git a/views/users/users.jade b/views/users/users.jade index 23251a1..de9dae5 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -21,6 +21,7 @@ block content } } ); + $('.tip').tooltip(); $('.data').dataTable({ "aoColumnDefs": [ { "aDataSort": [ 1, 0 ], "asSorting": [ "asc" ], "aTargets": [ 0 ] }, @@ -61,15 +62,15 @@ block content #{nick.display} span if nick.online - if nick.active - span.label.label-success Active + if nick.active.active + span.label.label-success.tip(data-original-title="#{nick.active.ago}", data-placement="right") Active else - span.label.label-important Inactive + span.label.label-important.tip(data-original-title="#{nick.active.ago}", data-placement="right") Inactive else - span.label Offline + span.label.tip(data-original-title="#{nick.active.ago}", data-placement="right") Offline td if nick.online - if nick.active + if nick.active.active -1 else 0 From 29899adfc07733f4f61b7b09473a39dd3db626db Mon Sep 17 00:00:00 2001 From: Douglas Gardner <douglas@chippy.ch> Date: Wed, 23 Jan 2013 18:56:07 +0000 Subject: [PATCH 258/347] remove one-word restriction on ~ud There's undoubtedly a better way to do this, but it works. ~ud now allows more than one word to be sent to UD's servers. --- modules/link/link.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/link/link.js b/modules/link/link.js index 0efbd02..a44acc8 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -34,11 +34,12 @@ var link = function(dbot) { }, '~ud': function(event) { - var reqUrl = 'http://api.urbandictionary.com/v0/define?term=' + event.params[1]; + var query = event.params.join(" ").substring(4); + var reqUrl = 'http://api.urbandictionary.com/v0/define?term=' + encodeURI(query); request(reqUrl, function(error, response, body) { var result = JSON.parse(body); if(_.has(result, 'result_type') && result.result_type != 'no_results') { - event.reply(event.params[1] + ': ' + result.list[0].definition); + event.reply(query + ': ' + result.list[0].definition); } else { event.reply(event.user + ': No definition found.'); } From f3771240a329f104a66a3f0083711e81c7a2a69c Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Wed, 23 Jan 2013 19:13:10 +0000 Subject: [PATCH 259/347] Basic Profiles [#184] --- modules/profile/commands.js | 8 +++++++- modules/profile/config.json | 2 ++ public/styles.css | 18 ++++++++++++++---- views/layout.jade | 2 +- views/profile/profile.jade | 20 +++++++++++++++++--- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/modules/profile/commands.js b/modules/profile/commands.js index a836c2d..d92a4f4 100644 --- a/modules/profile/commands.js +++ b/modules/profile/commands.js @@ -17,7 +17,13 @@ var commands = function(dbot){ "~test_setprop": function(event){ if(event.params[1] && event.params[2]){ - dbot.db.profiles[event.server][event.user.toLowerCase()].profile[event.params[1]] = event.params[2]; + if(_.has(this.config.schema.profile, event.params[1])){ + dbot.db.profiles[event.server][event.user.toLowerCase()].profile[event.params[1]] = event.params[2]; + event.reply("Property set, maybe?"); + } + else{ + event.reply("Invalid property. Go home."); + } } } } diff --git a/modules/profile/config.json b/modules/profile/config.json index 0082dd3..48b297b 100644 --- a/modules/profile/config.json +++ b/modules/profile/config.json @@ -7,6 +7,8 @@ "primary": null, "name": null, "tagline": null, + "avatar": null, + "bio": null, "favourites": { "colour": null } diff --git a/public/styles.css b/public/styles.css index d89d330..900c548 100644 --- a/public/styles.css +++ b/public/styles.css @@ -31,7 +31,6 @@ p { } div#page { - width: 90%; margin: 0 auto 0 auto; } @@ -55,9 +54,8 @@ div#title a { } div#main { - position: relative; - padding: 15px 5px; - margin: 0px; + position: relative; + padding: 10px 5px; font-size: 21px; text-align:center; background: #FFF; @@ -183,3 +181,15 @@ li.option-votes { .sorting_asc_disabled { background: url('http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_asc_disabled.png') no-repeat center right; } .sorting_desc_disabled { background: url('http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/images/sort_desc_disabled.png') no-repeat center right; } + +/** + * Bootstrap Overrides + */ +.profile_page-header{ + margin: 5px 0 10px 0; +} + +.profile_row{ + text-align: left; + margin-bottom: 10px; +} diff --git a/views/layout.jade b/views/layout.jade index 321bb07..bb3cf2e 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -12,7 +12,7 @@ html(lang='en') div#page div#title a(href='/') #{name} web interface - div#main + div.container#main block content script(type="text/javascript", src="/bootstrap/js/bootstrap.min.js") script(type="text/javascript", src="/d3/d3.v3.min.js") diff --git a/views/profile/profile.jade b/views/profile/profile.jade index 191147b..04b018d 100644 --- a/views/profile/profile.jade +++ b/views/profile/profile.jade @@ -39,11 +39,25 @@ block content }); }); - div.page-header + div.page-header.profile_page-header h1 #{primary} - - div#row + small + "#{profile.tagline}" + + div.row.profile_row#profile_data + div.span3 + if profile.avatar + img.profile_avatar(src="#{profile.avatar}") + else + img.profile_avatar(src="http://placehold.it/270x180&text=Hello,%20World") + div.span9 + h4 Bio + p #{profile.bio} + + hr + h3 Channel Statistics + div#profile_datatable table.table.table-hover.data thead tr From 045ff8b9f80faae85abcff58c4b3c4535ff6f822 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 23 Jan 2013 22:32:17 +0000 Subject: [PATCH 260/347] status command and some basic error storing in module load [#198] --- modules/admin/commands.js | 21 ++++++++++++++++++++- run.js | 15 ++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/modules/admin/commands.js b/modules/admin/commands.js index 7015dd2..6c8c674 100644 --- a/modules/admin/commands.js +++ b/modules/admin/commands.js @@ -102,6 +102,21 @@ var commands = function(dbot) { }.bind(this)); }, + + 'status': function(event) { + var moduleName = event.params[1]; + if(_.has(dbot.status, moduleName)) { + var status = dbot.status[moduleName]; + if(status === true) { + event.reply(moduleName + ' status: Shit looks good.'); + } else { + event.reply(moduleName + ' status: Failed to load: ' + status); + } + } else { + event.reply('Either that module wasn\'t on the roster or shit is totally fucked.'); + } + }, + // Reload DB, translations and modules. 'reload': function(event) { dbot.db = JSON.parse(fs.readFileSync('db.json', 'utf-8')); @@ -125,7 +140,11 @@ var commands = function(dbot) { if(!_.include(dbot.config.moduleNames, moduleName)) { dbot.config.moduleNames.push(moduleName); dbot.reloadModules(); - event.reply(dbot.t('load_module', {'moduleName': moduleName})); + if(dbot.status[moduleName] === true) { + event.reply(dbot.t('load_module', {'moduleName': moduleName})); + } else { + event.reply('Failed to load ' + moduleName + '. See \'status ' + moduleName + '\'.'); + } } else { if(moduleName == 'web') { event.reply(dbot.t('already_loaded_web')); diff --git a/run.js b/run.js index e63ccc7..1807d04 100644 --- a/run.js +++ b/run.js @@ -5,7 +5,6 @@ var fs = require('fs'), require('./snippets'); var DBot = function(timers) { - // Load DB var rawDB; try { @@ -55,6 +54,7 @@ var DBot = function(timers) { // Initialise run-time resources this.usage = {}; + this.status = {}; this.sessionData = {}; this.timers = timers.create(); @@ -119,6 +119,7 @@ DBot.prototype.reloadModules = function() { this.rawModules = []; this.pages = {}; + this.status = {}; this.modules = {}; this.commands = {}; this.api = {}; @@ -151,6 +152,7 @@ DBot.prototype.reloadModules = function() { this.instance.removeListeners(); moduleNames.each(function(name) { + this.status[name] = true; var moduleDir = './modules/' + name + '/'; var cacheKey = require.resolve(moduleDir + name); delete require.cache[cacheKey]; @@ -172,7 +174,13 @@ DBot.prototype.reloadModules = function() { } try { - var defaultConfig = JSON.parse(fs.readFileSync(moduleDir + 'config.json', 'utf-8')); + var defaultConfig = fs.readFileSync(moduleDir + 'config.json', 'utf-8'); + try { + defaultConfig = JSON.parse(defaultConfig); + } catch(err) { // syntax error + this.status[name] = 'Error parsing config: ' + err + ' ' + err.stack.split('\n')[2].trim(); + return; + } config = _.defaults(config, defaultConfig); } catch(err) { // Invalid or no config data @@ -188,7 +196,7 @@ DBot.prototype.reloadModules = function() { }, [], this); if(unmetDependencies.length != 0) { - throw new Error("Dependencies not met: " + unmetDependencies); + this.status[name] = 'Dependencies not met: ' + unmetDependencies; return; } } @@ -265,6 +273,7 @@ DBot.prototype.reloadModules = function() { this.modules[module.name] = module; } catch(err) { console.log(this.t('module_load_error', {'moduleName': name})); + this.status[name] = err + ' - ' + err.stack.split('\n')[1].trim(); if(this.config.debugMode) { console.log('MODULE ERROR (' + name + '): ' + err.stack ); } else { From 3584831f843a3c89a71bfcc4e42b5b0c2bbc6ed9 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 23 Jan 2013 22:34:44 +0000 Subject: [PATCH 261/347] bump stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 52a4a74..616cc9f 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 52a4a74f53b99ade143d61b703a92bb37e5de4e0 +Subproject commit 616cc9f8f23afa6941c1c130626aeb851716c5aa From 2a59f20b608251bcfea77bb3004567234d424737 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Wed, 23 Jan 2013 22:55:06 +0000 Subject: [PATCH 262/347] Regex for ~test_setprop --- modules/profile/commands.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/profile/commands.js b/modules/profile/commands.js index d92a4f4..d7088c0 100644 --- a/modules/profile/commands.js +++ b/modules/profile/commands.js @@ -1,7 +1,7 @@ var _ = require('underscore')._; var commands = function(dbot){ - return { + var cmds = { "~test_getprop": function(event){ if(event.params[1]){ @@ -16,9 +16,9 @@ var commands = function(dbot){ }, "~test_setprop": function(event){ - if(event.params[1] && event.params[2]){ - if(_.has(this.config.schema.profile, event.params[1])){ - dbot.db.profiles[event.server][event.user.toLowerCase()].profile[event.params[1]] = event.params[2]; + if(event.input[1] && event.input[2]){ + if(_.has(this.config.schema.profile, event.input[1])){ + dbot.db.profiles[event.server][event.user.toLowerCase()].profile[event.input[1]] = event.input[2]; event.reply("Property set, maybe?"); } else{ @@ -26,7 +26,10 @@ var commands = function(dbot){ } } } - } + }; + cmds['~test_setprop'].regex = [/~test_setprop ([^ ]+) (.+)/, 3]; + + return cmds; }; exports.fetch = function(dbot){ From 5767634f422f1fe79ceda1a96b018296cdc60a8d Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Wed, 23 Jan 2013 23:05:09 +0000 Subject: [PATCH 263/347] call stats rename on nick listener --- modules/users/users.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/users/users.js b/modules/users/users.js index c480dd0..d4ad44a 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -57,6 +57,7 @@ var users = function(dbot) { var newNick = event.params.substr(1); if(!this.api.isKnownUser(newNick)) { knownUsers.aliases[newNick] = this.api.resolveUser(event.server, event.user); + if(_.has(dbot.modules, 'stats')) dbot.api.stats.renameStats(event.server, newNick); } } }.bind(this); From ed86f98427dd0eec5489ce5fedc2bd82045d3256 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Wed, 23 Jan 2013 23:32:50 +0000 Subject: [PATCH 264/347] Profile move and merge API [Untested] --- modules/profile/api.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/modules/profile/api.js b/modules/profile/api.js index e6b22c8..246b741 100644 --- a/modules/profile/api.js +++ b/modules/profile/api.js @@ -14,6 +14,41 @@ var api = function(dbot) { this.profiles[server][primary] = {}; _.defaults(this.profiles[server][primary], this.config.schema); }, + + /** + * Given a server and "new" alias, resolve this alias to the user's + * new primary name and move profile data pertaining to the alias to + * the new primary name. + */ + 'renameProfile': function(server, alias){ + if(!_.has(this.profiles, server)) return; + var profiles = dbot.db.profiles[server]; + + if(_.has(profiles, alias)){ + var primary = dbot.api.users.resolveUser(server, alias, true).toLowerCase(); + alias = alias.trim().toLowerCase(); + + profiles[primary] = profiles[alias]; + delete profiles[alias]; + } + }, + + /** + * Given a server and a primary username which has been converted to a + * secondary alias find and remove the profile for the alias. + */ + 'mergeProfile': function(server, mergeFromPrimary){ + if(!_.has(this.profiles, server)) return; + var profiles = dbot.db.profiles[server]; + + mergeFromPrimary = mergeFromPrimary.toLowerCase(); + var mergeToPrimary = dbot.api.users.resolveUser(server, mergeFromPrimary, true).toLowerCase(); + if(!_.has(profiles, mergeToPrimary) + || !_.has(profiles, mergeFromPrimary)) return; + + // Remove the profile of the alias + delete profiles[mergeFromPrimary]; + }, } }; From 6b6907fe7b79348b77eddf0783c9e270a67ab31d Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 00:39:42 +0100 Subject: [PATCH 265/347] re-add ~quote syntax --- modules/command/command.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/command/command.js b/modules/command/command.js index a142bba..0895a94 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -14,11 +14,11 @@ var command = function(dbot) { this.listener = function(event) { var commandName = event.params[0]; if(!_.has(dbot.commands, commandName)) { - /*if(_.has(dbot.modules, 'quotes')) { + if(_.has(dbot.modules, 'quotes')) { commandName = '~'; - } else {*/ + } else { return; - //} + } } if(this.api.isBanned(event.user, commandName)) { From 8be61b746d70544ce528a89e6d56a68d128fb954 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Thu, 24 Jan 2013 00:23:26 +0000 Subject: [PATCH 266/347] Stop nicks property error [#201] --- modules/users/api.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/users/api.js b/modules/users/api.js index 3ef59be..7357ab1 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -70,6 +70,8 @@ var api = function(dbot) { 'isOnline': function(server, user, channel, useLowerCase) { var user = this.api.resolveUser(server, user, useLowerCase); var possiNicks = [user].concat(this.api.getAliases(server, user)); + + if(!_.has(dbot.instance.connections[server].channels[channel], nicks)) return false; var onlineNicks = dbot.instance.connections[server].channels[channel].nicks; return _.any(onlineNicks, function(nick) { From 35c9975d4449d777c46680659d16160786349e4d Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Thu, 24 Jan 2013 00:25:54 +0000 Subject: [PATCH 267/347] Oops [#201] --- modules/users/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/api.js b/modules/users/api.js index 7357ab1..3141166 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -71,7 +71,7 @@ var api = function(dbot) { var user = this.api.resolveUser(server, user, useLowerCase); var possiNicks = [user].concat(this.api.getAliases(server, user)); - if(!_.has(dbot.instance.connections[server].channels[channel], nicks)) return false; + if(!_.has(dbot.instance.connections[server].channels[channel], "nicks")) return false; var onlineNicks = dbot.instance.connections[server].channels[channel].nicks; return _.any(onlineNicks, function(nick) { From e2073f557c8629aaf263228b9c2132ce0cab1947 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Thu, 24 Jan 2013 00:30:22 +0000 Subject: [PATCH 268/347] Check for channel not nick [#201] --- modules/users/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/users/api.js b/modules/users/api.js index 3141166..a5df678 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -71,7 +71,7 @@ var api = function(dbot) { var user = this.api.resolveUser(server, user, useLowerCase); var possiNicks = [user].concat(this.api.getAliases(server, user)); - if(!_.has(dbot.instance.connections[server].channels[channel], "nicks")) return false; + if(!_.has(dbot.instance.connections[server].channels, channel)) return false; var onlineNicks = dbot.instance.connections[server].channels[channel].nicks; return _.any(onlineNicks, function(nick) { From 278bc8b93cc2ed1cee418c92e3bacad3d6bd3bb0 Mon Sep 17 00:00:00 2001 From: Thomas Menari <tom@menari.eu> Date: Thu, 24 Jan 2013 01:02:50 +0000 Subject: [PATCH 269/347] add initial yearbook feature --- modules/profile/pages.js | 11 +++++++ views/profile/profile_grid.jade | 51 +++++++++++++++++++++++++++++++++ views/users/connections.jade | 1 + 3 files changed, 63 insertions(+) create mode 100644 views/profile/profile_grid.jade diff --git a/modules/profile/pages.js b/modules/profile/pages.js index 379892c..543567e 100644 --- a/modules/profile/pages.js +++ b/modules/profile/pages.js @@ -21,6 +21,17 @@ var pages = function(dbot) { 'profile': profile, 'stats': stats.channels, }); + }, + + '/grid/:connection': function(req, res) { + var connection = req.params.connection; + var profiles = dbot.db.profiles[connection]; + + res.render('profile_grid', { + 'name': dbot.config.name, + 'connection': connection, + 'profiles': profiles, + }); } } }; diff --git a/views/profile/profile_grid.jade b/views/profile/profile_grid.jade new file mode 100644 index 0000000..b462288 --- /dev/null +++ b/views/profile/profile_grid.jade @@ -0,0 +1,51 @@ +extends ../layout + +block content + script(type="text/javascript", src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js") + + script + $(document).ready(function(){ + // Allowing forcing of string stats data to sort as numeric + jQuery.extend( jQuery.fn.dataTableExt.oSort, { + "forcenum-pre": function ( a ) { + a = a.replace("\,", ""); + return parseFloat( a ); + }, + + "forcenum-asc": function ( a, b ) { + return a - b; + }, + + "forcenum-desc": function ( a, b ) { + return b - a; + } + } ); + + $('.tip').tooltip(); + $('.data').dataTable({ + "aoColumnDefs": [ + { "sType": "forcenum", + "asSorting": [ "desc", "asc" ], + "aTargets": [ 1, 2, 3, 4, 5 ] } + ], + "bPaginate": false, + "bFilter": false, + "bLengthChange": false, + "oLanguage": { + "sInfo": "", + "sInfoEmpty": "", + "sInfoFiltered": "" + }, + }); + }); + + div.page-header.profile_page-header + h1 + #{connection} + div.span9 + each profile, key in profiles + if profile.hasOwnProperty('profile') && profile.profile.avatar + div.span2 + a(href='/profile/'+connection+'/'+encodeURIComponent(key)) + h3= profile.profile.primary + img.profile_avatar(src="#{profile.profile.avatar}") diff --git a/views/users/connections.jade b/views/users/connections.jade index f6750fb..023376b 100644 --- a/views/users/connections.jade +++ b/views/users/connections.jade @@ -7,3 +7,4 @@ block content #modulelinks -each connection in connections a.module(href='/channels/'+connection) #{connection} + a.module(href='/grid/'+connection) #{connection} headshots From dbac28cad698fa169d0cb74a4d0737155f3e49dd Mon Sep 17 00:00:00 2001 From: Thomas Menari <t@menari.eu> Date: Thu, 24 Jan 2013 01:06:05 +0000 Subject: [PATCH 270/347] oops --- views/profile/profile_grid.jade | 58 ++++++--------------------------- 1 file changed, 10 insertions(+), 48 deletions(-) diff --git a/views/profile/profile_grid.jade b/views/profile/profile_grid.jade index b462288..df63fc5 100644 --- a/views/profile/profile_grid.jade +++ b/views/profile/profile_grid.jade @@ -1,51 +1,13 @@ extends ../layout block content - script(type="text/javascript", src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js") - - script - $(document).ready(function(){ - // Allowing forcing of string stats data to sort as numeric - jQuery.extend( jQuery.fn.dataTableExt.oSort, { - "forcenum-pre": function ( a ) { - a = a.replace("\,", ""); - return parseFloat( a ); - }, - - "forcenum-asc": function ( a, b ) { - return a - b; - }, - - "forcenum-desc": function ( a, b ) { - return b - a; - } - } ); - - $('.tip').tooltip(); - $('.data').dataTable({ - "aoColumnDefs": [ - { "sType": "forcenum", - "asSorting": [ "desc", "asc" ], - "aTargets": [ 1, 2, 3, 4, 5 ] } - ], - "bPaginate": false, - "bFilter": false, - "bLengthChange": false, - "oLanguage": { - "sInfo": "", - "sInfoEmpty": "", - "sInfoFiltered": "" - }, - }); - }); - - div.page-header.profile_page-header - h1 - #{connection} - div.span9 - each profile, key in profiles - if profile.hasOwnProperty('profile') && profile.profile.avatar - div.span2 - a(href='/profile/'+connection+'/'+encodeURIComponent(key)) - h3= profile.profile.primary - img.profile_avatar(src="#{profile.profile.avatar}") + div.page-header.profile_page-header + h1 + #{connection} + div.span9 + each profile, key in profiles + if profile.hasOwnProperty('profile') && profile.profile.avatar + div.span2 + a(href='/profile/'+connection+'/'+encodeURIComponent(key)) + h3= profile.profile.primary + img.profile_avatar(src="#{profile.profile.avatar}") From 68f78cad9c2ed138614c4b89829a80df9ab26eda Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 10:05:50 +0000 Subject: [PATCH 271/347] ~ud regex and only use first response line [#197] --- modules/link/link.js | 5 +++-- modules/poll/config.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/link/link.js b/modules/link/link.js index a44acc8..f3f39aa 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -34,18 +34,19 @@ var link = function(dbot) { }, '~ud': function(event) { - var query = event.params.join(" ").substring(4); + var query = event.input[1]; var reqUrl = 'http://api.urbandictionary.com/v0/define?term=' + encodeURI(query); request(reqUrl, function(error, response, body) { var result = JSON.parse(body); if(_.has(result, 'result_type') && result.result_type != 'no_results') { - event.reply(query + ': ' + result.list[0].definition); + event.reply(query + ': ' + result.list[0].definition.split('\n')[0]; } else { event.reply(event.user + ': No definition found.'); } }); } }; + commands['~ud'].regex = [/~ud (.+)/, 2]; this.commands = commands; this.listener = function(event) { diff --git a/modules/poll/config.json b/modules/poll/config.json index 7b0f48b..12dc9ae 100644 --- a/modules/poll/config.json +++ b/modules/poll/config.json @@ -1,6 +1,6 @@ { "help": "http://github.com/reality/depressionbot/blob/master/modules/poll/README.md", "dbKeys": [ "polls" ], - "ignorable": true, + "ignorable true, "dependencies": [ "users", "command" ] } From 2e8d25aea46459ea39add71f8e24b28f691528db Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 10:06:56 +0000 Subject: [PATCH 272/347] i am retard --- modules/link/link.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/link/link.js b/modules/link/link.js index f3f39aa..dfe5f70 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -39,7 +39,7 @@ var link = function(dbot) { request(reqUrl, function(error, response, body) { var result = JSON.parse(body); if(_.has(result, 'result_type') && result.result_type != 'no_results') { - event.reply(query + ': ' + result.list[0].definition.split('\n')[0]; + event.reply(query + ': ' + result.list[0].definition.split('\n')[0]); } else { event.reply(event.user + ': No definition found.'); } From 656024d87b7271322b8288840353d9a7163a6269 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 10:08:05 +0000 Subject: [PATCH 273/347] revert poll syntax error >.< --- modules/poll/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/poll/config.json b/modules/poll/config.json index 12dc9ae..7b0f48b 100644 --- a/modules/poll/config.json +++ b/modules/poll/config.json @@ -1,6 +1,6 @@ { "help": "http://github.com/reality/depressionbot/blob/master/modules/poll/README.md", "dbKeys": [ "polls" ], - "ignorable true, + "ignorable": true, "dependencies": [ "users", "command" ] } From 4376989df426e04d065610a8f8d8f690245e26bc Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 18:03:14 +0000 Subject: [PATCH 274/347] event majigger as per [#205] --- modules/event/event.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 modules/event/event.js diff --git a/modules/event/event.js b/modules/event/event.js new file mode 100644 index 0000000..83fb822 --- /dev/null +++ b/modules/event/event.js @@ -0,0 +1,28 @@ +/** + * Module Name: event + * Description: Allow other modules to emit events and that + */ +var _ = require('underscore')._; + +var event = function(dbot) { + this.dbot = dbot; + this.hooks = {}; + this.api = { + 'addHook': function(eventName, callback) { + if(!_.has(this.hooks, eventName)) this.hooks[eventName] = []; + this.hooks[eventName].push(callback); + }, + + 'emit': function(eventName, args) { + if(_.has(this.hooks, eventName)) { + _.each(this.hooks[eventName], function(callback) { + callback.apply(callback.module, args); + }); + } + } + }; +} + +exports.fetch = function(dbot) { + return new event(dbot); +}; From 37f5583d3159e960983d53a114865df79d2a34ce Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 18:55:28 +0000 Subject: [PATCH 275/347] event in users for nick rename --- modules/users/config.json | 1 + modules/users/users.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/users/config.json b/modules/users/config.json index 0e947cb..866deb7 100644 --- a/modules/users/config.json +++ b/modules/users/config.json @@ -1,5 +1,6 @@ { "ignorable": false, + "dependencies": [ "command", "event" ], "dbKeys": [ "knownUsers" ], "help": "https://github.com/reality/depressionbot/blob/master/modules/users/README.md" } diff --git a/modules/users/users.js b/modules/users/users.js index d4ad44a..8e934b7 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -57,7 +57,7 @@ var users = function(dbot) { var newNick = event.params.substr(1); if(!this.api.isKnownUser(newNick)) { knownUsers.aliases[newNick] = this.api.resolveUser(event.server, event.user); - if(_.has(dbot.modules, 'stats')) dbot.api.stats.renameStats(event.server, newNick); + dbot.api.event.emit('nick_change', [ event.server, newNick ]); } } }.bind(this); From 9d21b90b34f10ac9be56083223e71d46570efb92 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 18:55:59 +0000 Subject: [PATCH 276/347] update stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 616cc9f..42ce442 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 616cc9f8f23afa6941c1c130626aeb851716c5aa +Subproject commit 42ce44222f4ef4311cae5648438b872227c9b3bf From e1c332daefb9b5ca36800938fea767209357f5d3 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 19:11:22 +0000 Subject: [PATCH 277/347] dox --- modules/event/README.md | 30 ++++++++++++++++++++++++++++++ modules/users/README.md | 5 +++++ 2 files changed, 35 insertions(+) create mode 100644 modules/event/README.md diff --git a/modules/event/README.md b/modules/event/README.md new file mode 100644 index 0000000..7474288 --- /dev/null +++ b/modules/event/README.md @@ -0,0 +1,30 @@ +## Event + +Emit events for whatever you want man idk. + +### Description + +This is a library module designed for other modules to use to emit various +events at any point, and also to attach functions to said events. These are +similar to command hooks, however their advantage is that they may be called +anywhere in your code; they are particularly useful when you want to attach a +callback to a listener. + +### API + +#### addHook(eventName, callback) +This function will set a given callback to be executed every time the +emit API function is executed with the given event name. The arguments of your +callback are defined as an array in the emit call. + +The best place to add hooks to commands is in the 'onLoad' function of your +module, as this ensures it will be run while all other modules are loaded so +nothing will be missed. + +#### emit(eventName, [ arguments ]) +This function executes all of the functions associated with the given eventName, +passing your given array of arguments. + +For example, to emit an event when you detect a nick change: + + dbot.api.event.emit('nick_changed', [ event.server, newNick ]); diff --git a/modules/users/README.md b/modules/users/README.md index 5bc713e..34195c4 100644 --- a/modules/users/README.md +++ b/modules/users/README.md @@ -46,3 +46,8 @@ Return a list of aliases for a given primary user. #### isOnline(server, user, channel, useLowerCase) Return whether a user is online in a given channel on the given server. + +### Events + +#### nick_changed(server, newNick) +This is executed when a new alias is added for a user. From 447bcbabf8d0ed0e82de5f052c562082cb199c4f Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 19:29:13 +0000 Subject: [PATCH 278/347] users emit for new users --- modules/users/README.md | 3 +++ modules/users/users.js | 2 ++ 2 files changed, 5 insertions(+) diff --git a/modules/users/README.md b/modules/users/README.md index 34195c4..0a11e5b 100644 --- a/modules/users/README.md +++ b/modules/users/README.md @@ -51,3 +51,6 @@ Return whether a user is online in a given channel on the given server. #### nick_changed(server, newNick) This is executed when a new alias is added for a user. + +#### new_user(server, nick) +This is executed when a new primary user is added to the known users DB. diff --git a/modules/users/users.js b/modules/users/users.js index 8e934b7..205eb76 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -48,6 +48,7 @@ var users = function(dbot) { nick = this.api.resolveUser(event.server, nick); } else { knownUsers.users.push(nick); + dbot.api.emit('new_user', [ event.server, nick ]); } if(!_.include(channelUsers, nick)) { @@ -78,6 +79,7 @@ var users = function(dbot) { nick = this.api.resolveUser(event.server, nick); } else { knownUsers.users.push(nick); + dbot.api.emit('new_user', [ event.server, nick ]); } if(!_.include(channelUsers, nick)) { channelUsers.push(nick); From 3c4974d5efcbaf8d7b13963903b7b56fecfc38f9 Mon Sep 17 00:00:00 2001 From: Thomas Menari <t@menari.eu> Date: Thu, 24 Jan 2013 19:39:28 +0000 Subject: [PATCH 279/347] make more l33t --- modules/profile/pages.js | 2 +- public/styles.css | 31 +++++++++++++++++++++++++++++++ views/profile/profile.jade | 3 +++ views/profile/profile_grid.jade | 11 ++++++----- views/users/connections.jade | 2 +- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/modules/profile/pages.js b/modules/profile/pages.js index 543567e..96acbed 100644 --- a/modules/profile/pages.js +++ b/modules/profile/pages.js @@ -23,7 +23,7 @@ var pages = function(dbot) { }); }, - '/grid/:connection': function(req, res) { + '/profile/:connection': function(req, res) { var connection = req.params.connection; var profiles = dbot.db.profiles[connection]; diff --git a/public/styles.css b/public/styles.css index 900c548..671d5c3 100644 --- a/public/styles.css +++ b/public/styles.css @@ -193,3 +193,34 @@ li.option-votes { text-align: left; margin-bottom: 10px; } + +/** + * spaceinvader's thumbnails + */ +span.nicks { + display: none; + color: #fff; + text-decoration: none; + position: absolute; + left: 0px; + top: 10px; + width: 100%; +} +div.imgwrap { + background-color: #000; + position: relative; +} +div.imgwrap > img { + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +.thumbnail:hover > div.imgwrap > img { + opacity: 0.5; +} + +.thumbnail:hover > div.imgwrap > span.nicks { + display: inline; +} diff --git a/views/profile/profile.jade b/views/profile/profile.jade index 04b018d..414dee5 100644 --- a/views/profile/profile.jade +++ b/views/profile/profile.jade @@ -92,3 +92,6 @@ block content #{chan.fields.wpl.data} td #{chan.fields.in_mentions.data} + ul.pager + li.previous + a(href='/profile/'+connection) ← Back to #{connection}. diff --git a/views/profile/profile_grid.jade b/views/profile/profile_grid.jade index df63fc5..ad7a5a1 100644 --- a/views/profile/profile_grid.jade +++ b/views/profile/profile_grid.jade @@ -4,10 +4,11 @@ block content div.page-header.profile_page-header h1 #{connection} - div.span9 + ul.thumbnails each profile, key in profiles if profile.hasOwnProperty('profile') && profile.profile.avatar - div.span2 - a(href='/profile/'+connection+'/'+encodeURIComponent(key)) - h3= profile.profile.primary - img.profile_avatar(src="#{profile.profile.avatar}") + li.span2 + a.thumbnail(href='/profile/'+connection+'/'+encodeURIComponent(key)) + div.imgwrap + img(src="#{profile.profile.avatar}", alt="#{key}'s photo") + span.nicks #{profile.profile.primary} diff --git a/views/users/connections.jade b/views/users/connections.jade index 023376b..27681e9 100644 --- a/views/users/connections.jade +++ b/views/users/connections.jade @@ -7,4 +7,4 @@ block content #modulelinks -each connection in connections a.module(href='/channels/'+connection) #{connection} - a.module(href='/grid/'+connection) #{connection} headshots + a.module(href='/profile/'+connection) #{connection} headshots From c1aa8db8153459025851b6b64f734926ba0111c0 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 20:51:38 +0000 Subject: [PATCH 280/347] fix db loading logic and check the file exists before attempting to load [#163] --- run.js | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/run.js b/run.js index 1807d04..9d3deb4 100644 --- a/run.js +++ b/run.js @@ -6,23 +6,19 @@ require('./snippets'); var DBot = function(timers) { // Load DB - var rawDB; - try { - var rawDB = fs.readFileSync('db.json', 'utf-8'); - } catch(err) { - this.db = {}; // If no db file, make empty one + if(fs.existsSync('db.json')) { + try { + this.db = JSON.parse(fs.readFileSync('db.json', 'utf-8')); + } catch(err) { + console.log('Error loading db.json. Stopping: ' + err); + process.exit(); + } + } else { + this.db = {}; } - try { - if(!this.db) { // If it wasn't empty - this.db = JSON.parse(rawDB); - } - if(!_.has(this.db, 'config')) { - this.db.config = {}; - } - } catch(err) { - console.log('Syntax error in db.json. Stopping: ' + err); - process.exit(); + if(!_.has(this.db, 'config')) { + this.db.config = {}; } // Load config From 6f73fde865eddac6f6cfdef368edc57b146938eb Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 21:35:00 +0000 Subject: [PATCH 281/347] file existence checking for module property files and config.json [#163] --- modules/stats | 2 +- run.js | 34 +++++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/modules/stats b/modules/stats index 42ce442..33886df 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 42ce44222f4ef4311cae5648438b872227c9b3bf +Subproject commit 33886df41d84c160270b581f072e710e4c9d00e8 diff --git a/run.js b/run.js index 9d3deb4..9f18098 100644 --- a/run.js +++ b/run.js @@ -5,7 +5,9 @@ var fs = require('fs'), require('./snippets'); var DBot = function(timers) { - // Load DB + + /*** Load the DB ***/ + if(fs.existsSync('db.json')) { try { this.db = JSON.parse(fs.readFileSync('db.json', 'utf-8')); @@ -21,12 +23,18 @@ var DBot = function(timers) { this.db.config = {}; } - // Load config + /*** Load the Config ***/ + + if(!fs.existsSync('config.json')) { + console.log('Error: config.json file does not exist. Stopping'); + process.exit(); + } + this.config = _.clone(this.db.config); try { _.defaults(this.config, JSON.parse(fs.readFileSync('config.json', 'utf-8'))); } catch(err) { - console.log('Config file is invalid. Stopping'); + console.log('Config file is invalid. Stopping: ' + err); process.exit(); } @@ -40,7 +48,8 @@ var DBot = function(timers) { // Load missing config directives from sample file _.defaults(this.config, defaultConfig); - // Load Strings file + /*** Load main strings ***/ + try { this.strings = JSON.parse(fs.readFileSync('strings.json', 'utf-8')); } catch(err) { @@ -216,13 +225,16 @@ DBot.prototype.reloadModules = function() { // Load the module data _.each([ 'commands', 'pages', 'api' ], function(property) { var propertyObj = {}; - try { - var propertyKey = require.resolve(moduleDir + property); - if(propertyKey) delete require.cache[propertyKey]; - propertyObj = require(moduleDir + property).fetch(this); - } catch(err) { - console.log('Module error (' + module.name + ') in ' + property + ': ' + err); - } + + if(fs.existsSync(moduleDir + property + '.js')) { + try { + var propertyKey = require.resolve(moduleDir + property); + if(propertyKey) delete require.cache[propertyKey]; + propertyObj = require(moduleDir + property).fetch(this); + } catch(err) { + console.log('Module error (' + module.name + ') in ' + property + ': ' + err); + } + } if(!_.has(module, property)) module[property] = {}; _.extend(module[property], propertyObj); From e9480b6f6493bbc2220d269d6e30a888f2306ace Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 21:46:18 +0000 Subject: [PATCH 282/347] put onLoad in try/catch, add status message for failure. [#198] --- run.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/run.js b/run.js index 9f18098..15a110e 100644 --- a/run.js +++ b/run.js @@ -294,7 +294,11 @@ DBot.prototype.reloadModules = function() { _.each(this.modules, function(module, name) { if(module.onLoad) { - module.onLoad(); + try { + module.onLoad(); + } catch(err) { + this.status[name] = 'Error in onLoad: ' + err + ' ' + err.stack.split('\n')[1].trim(); + } } }, this); From 3138bc8367668331ec5051c159c43b02b844b467 Mon Sep 17 00:00:00 2001 From: Thomas Menari <t@menari.eu> Date: Thu, 24 Jan 2013 21:46:42 +0000 Subject: [PATCH 283/347] masonry --- views/profile/profile_grid.jade | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/views/profile/profile_grid.jade b/views/profile/profile_grid.jade index ad7a5a1..4c70495 100644 --- a/views/profile/profile_grid.jade +++ b/views/profile/profile_grid.jade @@ -1,6 +1,15 @@ extends ../layout block content + script(src='/public/jquery.masonry.min.js') + script + var $container = $('.thumbnails'); + $container.imagesLoaded(function(){ + $container.masonry({ + itemSelector : '.item', + columnWidth : 240 + }); + }); div.page-header.profile_page-header h1 #{connection} From 9f72be10d19d4d2677f10737517d64233acc9db7 Mon Sep 17 00:00:00 2001 From: Thomas Menari <t@menari.eu> Date: Thu, 24 Jan 2013 21:49:16 +0000 Subject: [PATCH 284/347] hotlink masonry --- views/profile/profile_grid.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/profile/profile_grid.jade b/views/profile/profile_grid.jade index 4c70495..3cca9cc 100644 --- a/views/profile/profile_grid.jade +++ b/views/profile/profile_grid.jade @@ -1,7 +1,7 @@ extends ../layout block content - script(src='/public/jquery.masonry.min.js') + script(src='http://masonry.desandro.com/jquery.masonry.min.js') script var $container = $('.thumbnails'); $container.imagesLoaded(function(){ From 3cad0ea3c7040af6262021d82ea30a9b0f9fb48e Mon Sep 17 00:00:00 2001 From: Thomas Menari <t@menari.eu> Date: Thu, 24 Jan 2013 21:52:38 +0000 Subject: [PATCH 285/347] Remove columnwidth --- views/profile/profile_grid.jade | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/views/profile/profile_grid.jade b/views/profile/profile_grid.jade index 3cca9cc..981b4d0 100644 --- a/views/profile/profile_grid.jade +++ b/views/profile/profile_grid.jade @@ -6,8 +6,7 @@ block content var $container = $('.thumbnails'); $container.imagesLoaded(function(){ $container.masonry({ - itemSelector : '.item', - columnWidth : 240 + itemSelector : '.item' }); }); div.page-header.profile_page-header From 18a079c4beb3d007da97323b34747c8700ff2bf1 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 21:53:24 +0000 Subject: [PATCH 286/347] error reporting in status for properties [#198] --- run.js | 1 + 1 file changed, 1 insertion(+) diff --git a/run.js b/run.js index 15a110e..a32c869 100644 --- a/run.js +++ b/run.js @@ -232,6 +232,7 @@ DBot.prototype.reloadModules = function() { if(propertyKey) delete require.cache[propertyKey]; propertyObj = require(moduleDir + property).fetch(this); } catch(err) { + this.status[name] = 'Error loading ' + propertyKey + ': ' + err + ' - ' + err.stack.split('\n')[1].trim(); console.log('Module error (' + module.name + ') in ' + property + ': ' + err); } } From 76ed899917c4d3c004ecba654ee230bf82551d00 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Thu, 24 Jan 2013 22:07:43 +0000 Subject: [PATCH 287/347] Moved back link on profile --- views/profile/profile.jade | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/views/profile/profile.jade b/views/profile/profile.jade index 414dee5..a719833 100644 --- a/views/profile/profile.jade +++ b/views/profile/profile.jade @@ -43,7 +43,10 @@ block content h1 #{primary} small - "#{profile.tagline}" + if(profile.tagline) + "#{profile.tagline}" + div#backlink + a(href='/profile/'+connection) « Profiles div.row.profile_row#profile_data div.span3 @@ -92,6 +95,3 @@ block content #{chan.fields.wpl.data} td #{chan.fields.in_mentions.data} - ul.pager - li.previous - a(href='/profile/'+connection) ← Back to #{connection}. From 1979ab15b093c67eab71ee8a6a3f5d3cd1bfcc89 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Thu, 24 Jan 2013 22:17:56 +0000 Subject: [PATCH 288/347] Initial channel activity 'graph' [#167][#184] --- modules/users/pages.js | 19 ++++++++++++--- views/users/users.jade | 54 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/modules/users/pages.js b/modules/users/pages.js index c3fad15..386f96b 100644 --- a/modules/users/pages.js +++ b/modules/users/pages.js @@ -26,8 +26,15 @@ var pages = function(dbot) { if(connections.hasOwnProperty(connection) && connections[connection].channels.hasOwnProperty(channel)) { + var chanData = dbot.api.stats.getChanStats(connection, channel, ["freq"]); + var chanFreq = []; + for(var i=0; i <= 6; i++){ + for(var j=0; j <= 23; j++){ + chanFreq.push(chanData.fields.freq.raw[i][j]); + } + } + var userData = { "active": [], "inactive": [], "offline": []}; - var reply = dbot.api.stats.getChanUsersStats(connection, channel, [ "lines", "words", "lincent", "wpl", "in_mentions" ]); @@ -60,8 +67,14 @@ var pages = function(dbot) { var userDataSorted = (userData.active.concat(userData.inactive)).concat(userData.offline); - res.render('users', { 'name': dbot.config.name, 'connection': connection, - 'channel': channel, 'nicks': userDataSorted }); + res.render('users', { + 'name': dbot.config.name, + 'connection': connection, + 'channel': channel, + 'userStats': userDataSorted, + 'chanFreq': chanFreq, + 'chanFreqLen': chanFreq.length }); + } else { res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection or channel.' }); } diff --git a/views/users/users.jade b/views/users/users.jade index de9dae5..3f9b3bc 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -2,9 +2,50 @@ extends ../layout block content script(type="text/javascript", src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js") + style + .chart rect { + fill: steelblue; + } + .chart rect:hover { + fill: #000; + } script $(document).ready(function(){ + // d3.js Graph + var w = 5.595; + var h = 120; + + var x = d3.scale.linear() + .domain([0,1]) + .range([0,w]); + + var y = d3.scale.linear() + .domain([0,100]) + .rangeRound([0,h]); + + var chart = d3.select($("#chanFreqChart")[0]).append("svg") + .attr("class", "chart") + .attr("width", w * #{chanFreqLen} - 1) + .attr("height", h); + + chart.selectAll("rect") + .data([#{chanFreq}]) + .enter().append("rect") + .attr("x", function(d, i) { return x(i) - .5; }) + .attr("y", function(d) { return h - y(d) - .5; }) + .attr("width", w) + .attr("height", function(d) { return y(d); }) + .attr("title", function(d){ return y(d); }); + + chart.append("line") + .attr("x1", 0) + .attr("x2", w * #{chanFreqLen}) + .attr("y1", h - .5) + .attr("y2", h - .5) + .style("stroke", "#000"); + + // Allowing forcing of string stats data to sort as numeric jQuery.extend( jQuery.fn.dataTableExt.oSort, { "forcenum-pre": function ( a ) { @@ -22,6 +63,8 @@ block content } ); $('.tip').tooltip(); + $('rect').tooltip({ + }); $('.data').dataTable({ "aoColumnDefs": [ { "aDataSort": [ 1, 0 ], "asSorting": [ "asc" ], "aTargets": [ 0 ] }, @@ -40,9 +83,16 @@ block content }); }); - h3 Users of #{channel} on #{connection} + div.page-header.profile_page-header + h1 + #{channel} + small + #{connection} div#backlink a(href='/channels/'+connection) « Channel List + div#row + div.barchart#chanFreqChart + hr div#row table.table.table-hover.data thead @@ -55,7 +105,7 @@ block content th Verbosity th Mentions tbody - -each nick in nicks + -each nick in userStats tr td a(href='/profile/'+connection+'/'+nick.primary) From 5796aed13e690c7e79d74447aebccf06fde254d8 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Thu, 24 Jan 2013 22:30:52 +0000 Subject: [PATCH 289/347] Back link to Connections --- views/profile/profile_grid.jade | 3 +++ 1 file changed, 3 insertions(+) diff --git a/views/profile/profile_grid.jade b/views/profile/profile_grid.jade index 3cca9cc..4f4f584 100644 --- a/views/profile/profile_grid.jade +++ b/views/profile/profile_grid.jade @@ -13,6 +13,9 @@ block content div.page-header.profile_page-header h1 #{connection} + div#backlink + a(href='../connections') « Connections + ul.thumbnails each profile, key in profiles if profile.hasOwnProperty('profile') && profile.profile.avatar From 114b0fd09cbc51c5b17a1410263a80b489b2012c Mon Sep 17 00:00:00 2001 From: Thomas Menari <t@menari.eu> Date: Thu, 24 Jan 2013 22:34:34 +0000 Subject: [PATCH 290/347] derp --- public/styles.css | 2 +- views/profile/profile_grid.jade | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/public/styles.css b/public/styles.css index 671d5c3..7d6fcc2 100644 --- a/public/styles.css +++ b/public/styles.css @@ -216,7 +216,7 @@ div.imgwrap > img { -o-transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out; } - + .thumbnail:hover > div.imgwrap > img { opacity: 0.5; } diff --git a/views/profile/profile_grid.jade b/views/profile/profile_grid.jade index 3cca9cc..2436b04 100644 --- a/views/profile/profile_grid.jade +++ b/views/profile/profile_grid.jade @@ -3,11 +3,12 @@ extends ../layout block content script(src='http://masonry.desandro.com/jquery.masonry.min.js') script - var $container = $('.thumbnails'); - $container.imagesLoaded(function(){ - $container.masonry({ - itemSelector : '.item', - columnWidth : 240 + $(function() { + var $container = $('.thumbnails'); + $container.imagesLoaded(function(){ + $container.masonry({ + itemSelector : '.thumbnails > li', + }); }); }); div.page-header.profile_page-header From 6156de73b1725ae45da3ce31c93a8952efba387c Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Thu, 24 Jan 2013 22:44:41 +0000 Subject: [PATCH 291/347] change test_setprop and test_setprop to not have test in them (or underscores) --- modules/profile/commands.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/profile/commands.js b/modules/profile/commands.js index d7088c0..efae49e 100644 --- a/modules/profile/commands.js +++ b/modules/profile/commands.js @@ -1,9 +1,9 @@ var _ = require('underscore')._; var commands = function(dbot){ - var cmds = { + var commands = { - "~test_getprop": function(event){ + "~getprop": function(event){ if(event.params[1]){ var res = dbot.db.profiles[event.server][event.user.toLowerCase()].profile[event.params[1]]; if(res){ @@ -15,7 +15,7 @@ var commands = function(dbot){ } }, - "~test_setprop": function(event){ + "~setprop": function(event){ if(event.input[1] && event.input[2]){ if(_.has(this.config.schema.profile, event.input[1])){ dbot.db.profiles[event.server][event.user.toLowerCase()].profile[event.input[1]] = event.input[2]; @@ -27,9 +27,9 @@ var commands = function(dbot){ } } }; - cmds['~test_setprop'].regex = [/~test_setprop ([^ ]+) (.+)/, 3]; + commands['~setprop'].regex = [/~setprop ([^ ]+) (.+)/, 3]; - return cmds; + return commands; }; exports.fetch = function(dbot){ From 8cd16c3296775d0c6f58ac7136ed3a32f8a8b566 Mon Sep 17 00:00:00 2001 From: Thomas Menari <t@menari.eu> Date: Thu, 24 Jan 2013 22:53:23 +0000 Subject: [PATCH 292/347] prettier bio picture --- views/profile/profile.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/profile/profile.jade b/views/profile/profile.jade index a719833..108dad7 100644 --- a/views/profile/profile.jade +++ b/views/profile/profile.jade @@ -51,7 +51,7 @@ block content div.row.profile_row#profile_data div.span3 if profile.avatar - img.profile_avatar(src="#{profile.avatar}") + img.profile_avatar.img-polaroid(src="#{profile.avatar}") else img.profile_avatar(src="http://placehold.it/270x180&text=Hello,%20World") div.span9 From b0db6051746ea727e89ed8dd6e9e9a38017b8a3f Mon Sep 17 00:00:00 2001 From: Thomas Menari <t@menari.eu> Date: Thu, 24 Jan 2013 23:14:41 +0000 Subject: [PATCH 293/347] wrap long nicks --- public/styles.css | 1 + 1 file changed, 1 insertion(+) diff --git a/public/styles.css b/public/styles.css index 7d6fcc2..50f73bd 100644 --- a/public/styles.css +++ b/public/styles.css @@ -205,6 +205,7 @@ span.nicks { left: 0px; top: 10px; width: 100%; + word-wrap: break-word; } div.imgwrap { background-color: #000; From 1c0e258c5808102ec61f41076063e631df42a241 Mon Sep 17 00:00:00 2001 From: Thomas Menari <t@menari.eu> Date: Thu, 24 Jan 2013 23:26:23 +0000 Subject: [PATCH 294/347] placeholder deserves img-polaroid too --- views/profile/profile.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/profile/profile.jade b/views/profile/profile.jade index 108dad7..8588105 100644 --- a/views/profile/profile.jade +++ b/views/profile/profile.jade @@ -53,7 +53,7 @@ block content if profile.avatar img.profile_avatar.img-polaroid(src="#{profile.avatar}") else - img.profile_avatar(src="http://placehold.it/270x180&text=Hello,%20World") + img.profile_avatar.img-polaroid(src="http://placehold.it/270x180&text=Hello,%20World") div.span9 h4 Bio p #{profile.bio} From f03dfd91118ade9a131fe829f743a38479746c1d Mon Sep 17 00:00:00 2001 From: Thomas Menari <t@menari.eu> Date: Fri, 25 Jan 2013 00:30:09 +0000 Subject: [PATCH 295/347] sort photos by primary --- modules/profile/pages.js | 14 ++++++++++++++ views/profile/profile_grid.jade | 13 ++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/modules/profile/pages.js b/modules/profile/pages.js index 96acbed..cac6a75 100644 --- a/modules/profile/pages.js +++ b/modules/profile/pages.js @@ -27,9 +27,23 @@ var pages = function(dbot) { var connection = req.params.connection; var profiles = dbot.db.profiles[connection]; + var nicks = []; + for (var p in profiles) { + if (profiles.hasOwnProperty(p) && profiles[p].profile.avatar) { + nicks.push(p); + } + } + nicks.sort(function(a, b) { + var x = profiles[a].profile.primary.toLowerCase(); + var y = profiles[b].profile.primary.toLowerCase(); + if(x > y) return 1; + if(x < y) return -1; + return 0; + }); res.render('profile_grid', { 'name': dbot.config.name, 'connection': connection, + 'nicks': nicks, 'profiles': profiles, }); } diff --git a/views/profile/profile_grid.jade b/views/profile/profile_grid.jade index 74a1693..ba7b108 100644 --- a/views/profile/profile_grid.jade +++ b/views/profile/profile_grid.jade @@ -18,10 +18,9 @@ block content a(href='../connections') « Connections ul.thumbnails - each profile, key in profiles - if profile.hasOwnProperty('profile') && profile.profile.avatar - li.span2 - a.thumbnail(href='/profile/'+connection+'/'+encodeURIComponent(key)) - div.imgwrap - img(src="#{profile.profile.avatar}", alt="#{key}'s photo") - span.nicks #{profile.profile.primary} + each nick in nicks + li.span2 + a.thumbnail(href='/profile/'+connection+'/'+encodeURIComponent(nick)) + div.imgwrap + img(src="#{profiles[nick].profile.avatar}", alt="#{profiles[nick].profile.primary}'s photo") + span.nicks #{profiles[nick].profile.primary} From 4f01cc29580e95364829a740f03e642f48bddfab Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 25 Jan 2013 00:40:42 +0000 Subject: [PATCH 296/347] sorry @samstudio8 ill clean it up --- modules/profile/config.json | 3 ++- modules/profile/pages.js | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/modules/profile/config.json b/modules/profile/config.json index 48b297b..109f7c0 100644 --- a/modules/profile/config.json +++ b/modules/profile/config.json @@ -16,5 +16,6 @@ "preferences": { "timezone": null } - } + }, + "dependencies": [ "quotes", "command" ] } diff --git a/modules/profile/pages.js b/modules/profile/pages.js index 96acbed..3288241 100644 --- a/modules/profile/pages.js +++ b/modules/profile/pages.js @@ -14,6 +14,8 @@ var pages = function(dbot) { "lines", "words", "lincent", "wpl", "in_mentions"] ); + + res.render('profile', { 'name': dbot.config.name, 'connection': connection, @@ -27,6 +29,17 @@ var pages = function(dbot) { var connection = req.params.connection; var profiles = dbot.db.profiles[connection]; + // TODO: Clean up + _.each(profiles, function(profile) { + if(_.has(dbot.db.quoteArrs, profile.profile.primary)) { + var category = dbot.db.quoteArrs[profile.profile.primary]; + var avatar = _.find(category, function(quote) { + return quote.match(/(\.jpg|\.png|\.jpeg)$/i); + }); + if(avatar) profile.profile.avatar = avatar; + } + }); + res.render('profile_grid', { 'name': dbot.config.name, 'connection': connection, From 687f35d51c8aca2f78f7d61b93ddb4d37b7f27ff Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 25 Jan 2013 00:41:35 +0000 Subject: [PATCH 297/347] whoops --- modules/profile/pages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/profile/pages.js b/modules/profile/pages.js index 3288241..5217110 100644 --- a/modules/profile/pages.js +++ b/modules/profile/pages.js @@ -31,7 +31,7 @@ var pages = function(dbot) { // TODO: Clean up _.each(profiles, function(profile) { - if(_.has(dbot.db.quoteArrs, profile.profile.primary)) { + if(_.has(dbot.db.quoteArrs, profile.profile.primary) && !profile.profile.avatar) { var category = dbot.db.quoteArrs[profile.profile.primary]; var avatar = _.find(category, function(quote) { return quote.match(/(\.jpg|\.png|\.jpeg)$/i); From 9d5785d41ee9789299948a1b43755d3b467fb6ff Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Fri, 25 Jan 2013 00:45:45 +0000 Subject: [PATCH 298/347] notes im just commiting for something else --- modules/profile/pages.js | 2 -- modules/profile/profile.js | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/profile/pages.js b/modules/profile/pages.js index 5217110..3deeb51 100644 --- a/modules/profile/pages.js +++ b/modules/profile/pages.js @@ -14,8 +14,6 @@ var pages = function(dbot) { "lines", "words", "lincent", "wpl", "in_mentions"] ); - - res.render('profile', { 'name': dbot.config.name, 'connection': connection, diff --git a/modules/profile/profile.js b/modules/profile/profile.js index 4c991b4..c1dc2cb 100644 --- a/modules/profile/profile.js +++ b/modules/profile/profile.js @@ -19,6 +19,7 @@ var profile = function(dbot) { _.each(server, function(userName){ var primary = userName; userName = userName.toLowerCase(); + // TODO why isn't this calling the profile create API function if(!_.has(dbot.db.profiles[serverName], userName)){ dbot.db.profiles[serverName][userName] = { "profile": {}, From 26a10513e03428eb1eba6f2ab4fd739390c8c5d7 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Fri, 25 Jan 2013 11:05:40 +0000 Subject: [PATCH 299/347] d3.max domain [#216][Untested] --- views/users/users.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/users/users.jade b/views/users/users.jade index 3f9b3bc..f89ef18 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -21,7 +21,7 @@ block content .range([0,w]); var y = d3.scale.linear() - .domain([0,100]) + .domain([0,d3.max([#{chanFreq}])]) .rangeRound([0,h]); var chart = d3.select($("#chanFreqChart")[0]).append("svg") From 55c490f50f794701b95550ae6b6ec59a8785d4ba Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Fri, 25 Jan 2013 11:08:35 +0000 Subject: [PATCH 300/347] Return non-scaled value as title, idiot [#216] --- views/users/users.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/users/users.jade b/views/users/users.jade index f89ef18..fbc66dd 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -36,7 +36,7 @@ block content .attr("y", function(d) { return h - y(d) - .5; }) .attr("width", w) .attr("height", function(d) { return y(d); }) - .attr("title", function(d){ return y(d); }); + .attr("title", function(d){ return d; }); chart.append("line") .attr("x1", 0) From 78e0e6008380460583e72cfbb35b2c0db1012c08 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Fri, 25 Jan 2013 15:13:12 +0000 Subject: [PATCH 301/347] Hook ~setaliasparent and ~mergeusers [Fix #218] --- modules/profile/profile.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/profile/profile.js b/modules/profile/profile.js index c1dc2cb..5d3b146 100644 --- a/modules/profile/profile.js +++ b/modules/profile/profile.js @@ -33,6 +33,10 @@ var profile = function(dbot) { }); }); dbot.save(); + + // Add API Hooks + dbot.api.command.addHook('~setaliasparent', this.api.renameProfile); + dbot.api.command.addHook('~mergeusers', this.api.mergeProfile); }; }; From e79888242039c46c626ecdb580d30b587f10e45c Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Fri, 25 Jan 2013 19:57:04 +0000 Subject: [PATCH 302/347] Add ~profile command [Close #219] --- modules/profile/api.js | 4 ++-- modules/profile/commands.js | 24 ++++++++++++++++++++++-- modules/profile/config.json | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/modules/profile/api.js b/modules/profile/api.js index 246b741..633c993 100644 --- a/modules/profile/api.js +++ b/modules/profile/api.js @@ -11,8 +11,8 @@ var api = function(dbot) { if(!_.has(this.profiles, server)){ this.profiles[server] = {}; } - this.profiles[server][primary] = {}; - _.defaults(this.profiles[server][primary], this.config.schema); + this.profiles[server][primary.toLowerCase()] = {}; + _.defaults(this.profiles[server][primary.toLowerCase()], this.config.schema); }, /** diff --git a/modules/profile/commands.js b/modules/profile/commands.js index efae49e..a402066 100644 --- a/modules/profile/commands.js +++ b/modules/profile/commands.js @@ -5,7 +5,8 @@ var commands = function(dbot){ "~getprop": function(event){ if(event.params[1]){ - var res = dbot.db.profiles[event.server][event.user.toLowerCase()].profile[event.params[1]]; + var primary = dbot.api.users.resolveUser(event.server, event.user); + var res = dbot.db.profiles[event.server][primary.toLowerCase()].profile[event.params[1]]; if(res){ event.reply(res); } @@ -18,13 +19,32 @@ var commands = function(dbot){ "~setprop": function(event){ if(event.input[1] && event.input[2]){ if(_.has(this.config.schema.profile, event.input[1])){ - dbot.db.profiles[event.server][event.user.toLowerCase()].profile[event.input[1]] = event.input[2]; + var primary = dbot.api.users.resolveUser(event.server, event.user); + dbot.db.profiles[event.server][primary.toLowerCase()].profile[event.input[1]] = event.input[2]; event.reply("Property set, maybe?"); } else{ event.reply("Invalid property. Go home."); } } + }, + + "~profile": function(event){ + if(event.params[1]){ + var primary = dbot.api.users.resolveUser(event.server, event.params[1]); + if(_.has(dbot.db.profiles[event.server], primary.toLowerCase())){ + event.reply("http://"+dbot.config.web.webHost+":"+dbot.config.web.webPort+"/profile/"+event.server+"/"+primary.toLowerCase()); + } + else{ + event.reply("No profile found for "+event.params[1]); + } + } + else{ + event.message = '~profile ' + event.user; + event.action = 'PRIVMSG'; + event.params = event.message.split(' '); + dbot.instance.emit(event); + } } }; commands['~setprop'].regex = [/~setprop ([^ ]+) (.+)/, 3]; diff --git a/modules/profile/config.json b/modules/profile/config.json index 109f7c0..24f5027 100644 --- a/modules/profile/config.json +++ b/modules/profile/config.json @@ -17,5 +17,5 @@ "timezone": null } }, - "dependencies": [ "quotes", "command" ] + "dependencies": [ "quotes", "users", "command" ] } From 97b27e4d78703ef9870b9cbb5389bf64feb5827a Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Fri, 25 Jan 2013 20:14:44 +0000 Subject: [PATCH 303/347] Prevent profile breaking if no stats are returned [Fix #81] --- views/profile/profile.jade | 49 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/views/profile/profile.jade b/views/profile/profile.jade index 8588105..8ea224b 100644 --- a/views/profile/profile.jade +++ b/views/profile/profile.jade @@ -71,27 +71,28 @@ block content th Verbosity th Mentions tbody - for chan, key in stats - if stats.hasOwnProperty(key) - tr - td - a(href='/users/'+connection+'/'+encodeURIComponent(key)) - #{key} - span - if chan.online - if chan.active.active - span.label.label-success.tip(data-original-title="#{chan.active.ago}", data-placement="right") Active - else - span.label.label-important.tip(data-original-title="#{chan.active.ago}", data-placement="right") Inactive - else - span.label.tip(data-original-title="#{chan.active.ago}", data-placement="right") Offline - td - #{chan.fields.lines.data} - td - #{chan.fields.words.data} - td - #{chan.fields.lincent.data} - td - #{chan.fields.wpl.data} - td - #{chan.fields.in_mentions.data} + if stats + for chan, key in stats + if stats.hasOwnProperty(key) + tr + td + a(href='/users/'+connection+'/'+encodeURIComponent(key)) + #{key} + span + if chan.online + if chan.active.active + span.label.label-success.tip(data-original-title="#{chan.active.ago}", data-placement="right") Active + else + span.label.label-important.tip(data-original-title="#{chan.active.ago}", data-placement="right") Inactive + else + span.label.tip(data-original-title="#{chan.active.ago}", data-placement="right") Offline + td + #{chan.fields.lines.data} + td + #{chan.fields.words.data} + td + #{chan.fields.lincent.data} + td + #{chan.fields.wpl.data} + td + #{chan.fields.in_mentions.data} From 3db80f908f2a3fce766f20c61ec550391ceed439 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Fri, 25 Jan 2013 21:39:13 +0000 Subject: [PATCH 304/347] X-Labels [#216] --- views/users/users.jade | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/views/users/users.jade b/views/users/users.jade index fbc66dd..2d7ba9d 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -13,6 +13,7 @@ block content script $(document).ready(function(){ // d3.js Graph + var xlab = 30; var w = 5.595; var h = 120; @@ -27,7 +28,7 @@ block content var chart = d3.select($("#chanFreqChart")[0]).append("svg") .attr("class", "chart") .attr("width", w * #{chanFreqLen} - 1) - .attr("height", h); + .attr("height", h + xlab); chart.selectAll("rect") .data([#{chanFreq}]) @@ -45,6 +46,26 @@ block content .attr("y2", h - .5) .style("stroke", "#000"); + chart.selectAll("text.times") + .data(["0", "6", "12", "18","0", "6", "12", "18","0", "6", "12", "18","0", "6", "12", "18" ,"0", "6", "12", "18" ,"0", "6", "12", "18" ,"0", "6", "12", "18"]) + .enter().append("text") + .attr("x", function(d, i){ return ((i * w * 6)+(w/2)); }) + .attr("y", h + 10) + .attr("text-anchor", "middle") + .attr('class', 'name') + .attr("font-size", 10) + .text(String); + + chart.selectAll("text.days") + .data(["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]) + .enter().append("text") + .attr("x", function(d, i){ return ((i+0.5) * w * 24); }) + .attr("y", h + 25) + .attr("text-anchor", "middle") + .attr('class', 'name') + .attr("font-size", 12) + .text(String); + // Allowing forcing of string stats data to sort as numeric jQuery.extend( jQuery.fn.dataTableExt.oSort, { From f34283a62d81d62065a251814c869f2d4c439d7a Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sat, 26 Jan 2013 00:51:48 +0000 Subject: [PATCH 305/347] Basic Y-Labels and Ticks [#216] --- views/users/users.jade | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/views/users/users.jade b/views/users/users.jade index 2d7ba9d..000dbff 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -9,11 +9,16 @@ block content .chart rect:hover { fill: #000; } + .yTicks { + stroke: #aaa; + stroke-width: 0.5; + } script $(document).ready(function(){ // d3.js Graph var xlab = 30; + var chartw = 940; var w = 5.595; var h = 120; @@ -30,6 +35,15 @@ block content .attr("width", w * #{chanFreqLen} - 1) .attr("height", h + xlab); + chart.selectAll(".yTicks") + .data(y.ticks(4).slice(0,5)) + .enter().append("svg:line") + .attr("class", "yTicks") + .attr("y1", function(d) { return y(d); }) + .attr("x1", 0) + .attr("y2", function(d) { return y(d); }) + .attr("x2", w * #{chanFreqLen}) + chart.selectAll("rect") .data([#{chanFreq}]) .enter().append("rect") @@ -39,6 +53,17 @@ block content .attr("height", function(d) { return y(d); }) .attr("title", function(d){ return d; }); + chart.selectAll(".rule") + .data(y.ticks(5).slice(1,5)) + .enter().append("text") + .attr("class", "rule") + .attr("y", function(d) { return -1 * y(d) + h; }) + .attr("x", (chartw / 2)+(w/2)) + .attr("text-anchor", "middle") + .attr("font-size", 10) + .attr("dy", 3) + .text(String); + chart.append("line") .attr("x1", 0) .attr("x2", w * #{chanFreqLen}) From 00f04a01a9d3a26d021492bab5e52135e6f82876 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sat, 26 Jan 2013 00:55:50 +0000 Subject: [PATCH 306/347] Fix Y-Ticks [#216] --- views/users/users.jade | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/views/users/users.jade b/views/users/users.jade index 000dbff..0a6df79 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -36,12 +36,12 @@ block content .attr("height", h + xlab); chart.selectAll(".yTicks") - .data(y.ticks(4).slice(0,5)) + .data(y.ticks(5).slice(1,5)) .enter().append("svg:line") .attr("class", "yTicks") - .attr("y1", function(d) { return y(d); }) + .attr("y1", function(d) { return -1 * y(d) + h; }) .attr("x1", 0) - .attr("y2", function(d) { return y(d); }) + .attr("y2", function(d) { return -1 * y(d) + h; }) .attr("x2", w * #{chanFreqLen}) chart.selectAll("rect") From fdd8ed7a6f1e35ec50b72f903d94f55754c43c72 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sat, 26 Jan 2013 18:11:28 +0000 Subject: [PATCH 307/347] Prevent profile break on no-stats bug --- modules/users/pages.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/users/pages.js b/modules/users/pages.js index 386f96b..b129338 100644 --- a/modules/users/pages.js +++ b/modules/users/pages.js @@ -28,11 +28,17 @@ var pages = function(dbot) { var chanData = dbot.api.stats.getChanStats(connection, channel, ["freq"]); var chanFreq = []; - for(var i=0; i <= 6; i++){ - for(var j=0; j <= 23; j++){ - chanFreq.push(chanData.fields.freq.raw[i][j]); + + if(chanData){ + for(var i=0; i <= 6; i++){ + for(var j=0; j <= 23; j++){ + chanFreq.push(chanData.fields.freq.raw[i][j]); + } } } + else{ + for (var i = 0; i < 168; i++) chanFreq[i] = 0; + } var userData = { "active": [], "inactive": [], "offline": []}; var reply = dbot.api.stats.getChanUsersStats(connection, channel, [ From e0cc4d07975fddb92b71d0a0a7d9a622d84e2115 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 26 Jan 2013 18:51:02 +0000 Subject: [PATCH 308/347] bump stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 33886df..24952cb 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 33886df41d84c160270b581f072e710e4c9d00e8 +Subproject commit 24952cb6d3514f93f636036b7c51944d498174cd From 188d90f0685d512589f4162d4fc75276582f4d83 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 26 Jan 2013 18:53:41 +0000 Subject: [PATCH 309/347] update statos --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 24952cb..3905ac9 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 24952cb6d3514f93f636036b7c51944d498174cd +Subproject commit 3905ac91add5bebbd9a4aa03e2777fd6c498e5c0 From e32553c23fb0968de0cc03c3fc2bdcfdae8fd279 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sat, 26 Jan 2013 18:57:33 +0000 Subject: [PATCH 310/347] Y-Axis Improvements [#216][Close #227] --- views/users/users.jade | 44 +++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/views/users/users.jade b/views/users/users.jade index 0a6df79..d1e9e7e 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -17,10 +17,12 @@ block content script $(document).ready(function(){ // d3.js Graph - var xlab = 30; + var ticks = 25; + var timelabels = 30; var chartw = 940; - var w = 5.595; - var h = 120; + var toppad = 10; + var w = (chartw - (ticks * 2)) / 168; + var h = 130; var x = d3.scale.linear() .domain([0,1]) @@ -28,45 +30,55 @@ block content var y = d3.scale.linear() .domain([0,d3.max([#{chanFreq}])]) - .rangeRound([0,h]); + .rangeRound([0,h-toppad]); var chart = d3.select($("#chanFreqChart")[0]).append("svg") .attr("class", "chart") - .attr("width", w * #{chanFreqLen} - 1) - .attr("height", h + xlab); + .attr("width", chartw) + .attr("height", h + timelabels); chart.selectAll(".yTicks") - .data(y.ticks(5).slice(1,5)) + .data(y.ticks(5).slice(1)) .enter().append("svg:line") .attr("class", "yTicks") .attr("y1", function(d) { return -1 * y(d) + h; }) .attr("x1", 0) .attr("y2", function(d) { return -1 * y(d) + h; }) - .attr("x2", w * #{chanFreqLen}) + .attr("x2", chartw) chart.selectAll("rect") .data([#{chanFreq}]) .enter().append("rect") - .attr("x", function(d, i) { return x(i) - .5; }) + .attr("x", function(d, i) { return x(i) - .5 + ticks; }) .attr("y", function(d) { return h - y(d) - .5; }) .attr("width", w) .attr("height", function(d) { return y(d); }) .attr("title", function(d){ return d; }); - chart.selectAll(".rule") + chart.selectAll(".l_rule") + .data(y.ticks(5).slice(1)) + .enter().append("text") + .attr("class", "rule") + .attr("y", function(d) { return -1 * y(d) + h; }) + .attr("x", 0) + .attr("text-anchor", "right") + .attr("font-size", 10) + .attr("dy", 3) + .text(String); + chart.selectAll(".r_rule") .data(y.ticks(5).slice(1,5)) .enter().append("text") .attr("class", "rule") .attr("y", function(d) { return -1 * y(d) + h; }) - .attr("x", (chartw / 2)+(w/2)) - .attr("text-anchor", "middle") + .attr("x", chartw) + .attr("text-anchor", "end") .attr("font-size", 10) .attr("dy", 3) .text(String); chart.append("line") - .attr("x1", 0) - .attr("x2", w * #{chanFreqLen}) + .attr("x1", 0 + ticks) + .attr("x2", chartw - ticks) .attr("y1", h - .5) .attr("y2", h - .5) .style("stroke", "#000"); @@ -74,7 +86,7 @@ block content chart.selectAll("text.times") .data(["0", "6", "12", "18","0", "6", "12", "18","0", "6", "12", "18","0", "6", "12", "18" ,"0", "6", "12", "18" ,"0", "6", "12", "18" ,"0", "6", "12", "18"]) .enter().append("text") - .attr("x", function(d, i){ return ((i * w * 6)+(w/2)); }) + .attr("x", function(d, i){ return ((i * w * 6)+(w/2)) + ticks; }) .attr("y", h + 10) .attr("text-anchor", "middle") .attr('class', 'name') @@ -84,7 +96,7 @@ block content chart.selectAll("text.days") .data(["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]) .enter().append("text") - .attr("x", function(d, i){ return ((i+0.5) * w * 24); }) + .attr("x", function(d, i){ return ((i+0.5) * w * 24) + ticks; }) .attr("y", h + 25) .attr("text-anchor", "middle") .attr('class', 'name') From 3103e84ddb271810d332a255f17008bbb1ccc138 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sat, 26 Jan 2013 18:59:57 +0000 Subject: [PATCH 311/347] Fix slice for both sets of axis rules, idiot. --- views/users/users.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/users/users.jade b/views/users/users.jade index d1e9e7e..85eba2d 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -66,7 +66,7 @@ block content .attr("dy", 3) .text(String); chart.selectAll(".r_rule") - .data(y.ticks(5).slice(1,5)) + .data(y.ticks(5).slice(1)) .enter().append("text") .attr("class", "rule") .attr("y", function(d) { return -1 * y(d) + h; }) From aa4a8b8527f5cab713442d67ff111fda8f2e8e5c Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 26 Jan 2013 19:21:09 +0000 Subject: [PATCH 312/347] users.api.getRandomChannelUser [#156] --- modules/users/api.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/users/api.js b/modules/users/api.js index a5df678..19c62a6 100644 --- a/modules/users/api.js +++ b/modules/users/api.js @@ -36,6 +36,15 @@ var api = function(dbot) { return user; }, + 'getRandomChannelUser': function(server, channel) { + var channelUsers = this.getServerUsers(server).channelUsers[channel]; + if(!_.isUndefined(channelUsers)) { + return channelUsers[_.random(0, channelUsers.length - 1)]; + } else { + return false; + } + }, + 'getServerUsers': function(server) { return dbot.db.knownUsers[server].users; }, From 4555e12eaa6a50a236e8c5017f4d3ca5e9002533 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 26 Jan 2013 20:08:09 +0000 Subject: [PATCH 313/347] Fix quote interpol + no need to pass event [#230][#156] --- modules/quotes/commands.js | 2 +- modules/quotes/config.json | 2 +- modules/quotes/quotes.js | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/quotes/commands.js b/modules/quotes/commands.js index c3d0522..c99fd01 100644 --- a/modules/quotes/commands.js +++ b/modules/quotes/commands.js @@ -188,7 +188,7 @@ var commands = function(dbot) { '~rq': function(event) { var category = _.keys(quotes)[_.random(0, _.size(quotes) -1)]; - event.reply(category + ': ' + this.internalAPI.interpolatedQuote(event, category)); + event.reply(category + ': ' + this.internalAPI.interpolatedQuote(event.server, event.channel.name, category)); }, '~link': function(event) { diff --git a/modules/quotes/config.json b/modules/quotes/config.json index 7530554..e8d0465 100644 --- a/modules/quotes/config.json +++ b/modules/quotes/config.json @@ -1,6 +1,6 @@ { "dbKeys": [ "quoteArrs" ], - "dependencies": [ "command" ], + "dependencies": [ "command", "users" ], "rmLimit": 10, "ignorable": true, "help": "http://github.com/reality/depressionbot/blob/master/modules/quotes/README.md" diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index 85d9fb0..b1b2639 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -11,7 +11,7 @@ var quotes = function(dbot) { this.internalAPI = { // Retrieve a random quote from a given category, interpolating any quote // references (~~QUOTE CATEGORY~~) within it - 'interpolatedQuote': function(event, key, quoteTree) { + 'interpolatedQuote': function(server, channel, key, quoteTree) { if(!_.isUndefined(quoteTree) && quoteTree.indexOf(key) != -1) { return ''; } else if(_.isUndefined(quoteTree)) { @@ -28,13 +28,13 @@ var quotes = function(dbot) { while(quoteRefs && (thisRef = quoteRefs.shift()) !== undefined) { var cleanRef = dbot.cleanNick(thisRef.replace(/^~~/,'').replace(/~~$/,'').trim()); if(cleanRef === '-nicks-') { - var randomNick = _.keys(event.channel.nicks)[_.random(0, _.size(event.channel.nicks) -1)]; + var randomNick = dbot.api.users.getRandomChannelUser(server, channel); quoteString = quoteString.replace("~~" + cleanRef + "~~", randomNick); quoteTree.pop(); } else if(_.has(this.quotes, cleanRef)) { quoteTree.push(key); quoteString = quoteString.replace("~~" + cleanRef + "~~", - interpolatedQuote(event, cleanRef, quoteTree.slice())); + this.internalAPI.interpolatedQuote(server, channel, cleanRef, quoteTree.slice())); quoteTree.pop(); } } @@ -76,9 +76,9 @@ var quotes = function(dbot) { if(key.charAt(0) !== '_') { // lol if(_.has(this.quotes, key)) { - return this.internalAPI.interpolatedQuote(event, key); + return this.internalAPI.interpolatedQuote(event.server, event.channel.name, key); } else if(_.has(this.quotes, altKey)) { - return this.internalAPI.interpolatedQuote(event, altKey); + return this.internalAPI.interpolatedQuote(event.server, event.channel.name, altKey); } else { return false; } From 55815702dcd521c01b92a21714551c8029b7010a Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 26 Jan 2013 21:51:57 +0000 Subject: [PATCH 314/347] Add basic install.sh script [#144] --- install.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100755 install.sh diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..42cf7ec --- /dev/null +++ b/install.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +git submodule init +git submodule update + +npm install underscore request sandbox express moment jade@0.25 + +cd public/ +wget http://twitter.github.com/bootstrap/assets/bootstrap.zip +unzip bootstrap.zip +rm bootstrap.zip + +mkdir d3 +cd d3 +wget http://d3js.org/d3.v3.zip +unzip d3.v3.zip +rm d3.v3.zip + +cd .. + +cp config.json.sample config.json + +echo 'Setup complete. Now edit config.json with your preferences and run the bot with "node run.js"' From 4b5aceea494722db0f9d7525b1beee9f9437b709 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sat, 26 Jan 2013 22:07:30 +0000 Subject: [PATCH 315/347] Try to satisfy dependencies automatically [#231] --- run.js | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/run.js b/run.js index a32c869..5ee0d3d 100644 --- a/run.js +++ b/run.js @@ -157,7 +157,6 @@ DBot.prototype.reloadModules = function() { this.instance.removeListeners(); moduleNames.each(function(name) { - this.status[name] = true; var moduleDir = './modules/' + name + '/'; var cacheKey = require.resolve(moduleDir + name); delete require.cache[cacheKey]; @@ -170,6 +169,8 @@ DBot.prototype.reloadModules = function() { delete require.cache[webKey]; } + this.status[name] = true; + try { // Load the module config data var config = {}; @@ -191,19 +192,14 @@ DBot.prototype.reloadModules = function() { // Invalid or no config data } - // Shit out if dependencies not met + // Don't shit out if dependencies not met if(_.has(config, 'dependencies')) { - var unmetDependencies = _.reduce(config.dependencies, function(memo, dependency) { + _.each(config.dependencies, function(dependency) { if(!_.include(moduleNames, dependency)) { - memo.push(dependency); + console.log('Warning: Automatically loading ' + dependency); + moduleNames.push(dependency); } - return memo; - }, [], this); - - if(unmetDependencies.length != 0) { - this.status[name] = 'Dependencies not met: ' + unmetDependencies; - return; - } + }, this); } // Generate missing DB keys From bd32a062760d7261928b7bcafc2a82d1b4e88d20 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 14:39:23 +0000 Subject: [PATCH 316/347] Fix docs for [#233] --- modules/timers/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/timers/README.md b/modules/timers/README.md index e610390..26845e6 100644 --- a/modules/timers/README.md +++ b/modules/timers/README.md @@ -10,7 +10,7 @@ timers. ### API -#### addTimer(callback, interval, [firstDate]) +#### addTimer(interval, callback, [firstDate]) Execute the given callback every time *interval* (in ms) passes. The firstDate parameter is a Date object used to sync a timer to a given point in From bd75519047fc907be620e3695bb8bf7258cc51fd Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 14:49:22 +0000 Subject: [PATCH 317/347] callback fix for [#233] --- modules/timers/timers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/timers/timers.js b/modules/timers/timers.js index 76f7aef..f70a576 100644 --- a/modules/timers/timers.js +++ b/modules/timers/timers.js @@ -15,13 +15,13 @@ var timers = function(dbot) { if(firstDate) { console.log('Setting first timer to run at ' + firstDate); firstTimeout = firstDate.getTime() - now; - setTimeout(function(callback) { + setTimeout(function() { console.log('Running first timer at ' + new Date().toUTCString()); this.runningIntervals.push(this.api.addTimer(timeout, callback)); callback(); }.bind(this), firstTimeout); } else { - this.runningIntervals.push(setInterval(function(callback) { + this.runningIntervals.push(setInterval(function() { console.log('Running subsequent timer at ' + new Date().toUTCString()); callback(); }.bind(this), timeout)); From 27e24a8173bff73258a87bd5d5cb35271d283c57 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 15:19:56 +0000 Subject: [PATCH 318/347] Fixes for [#232] --- modules/timers/timers.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/modules/timers/timers.js b/modules/timers/timers.js index f70a576..073114f 100644 --- a/modules/timers/timers.js +++ b/modules/timers/timers.js @@ -18,23 +18,31 @@ var timers = function(dbot) { setTimeout(function() { console.log('Running first timer at ' + new Date().toUTCString()); this.runningIntervals.push(this.api.addTimer(timeout, callback)); - callback(); + try { + callback(); + } catch(err) { + console.log('Callback failed: ' + err); + } }.bind(this), firstTimeout); } else { this.runningIntervals.push(setInterval(function() { console.log('Running subsequent timer at ' + new Date().toUTCString()); - callback(); + try { + callback(); + } catch(err) { + console.log('Callback failed: ' + err); + } }.bind(this), timeout)); } } }; this.onDestroy = function() { - for(var i=0;i<this.runningTimeouts;i++) { + for(var i=0;i<this.runningTimeouts.length;i++) { clearTimeout(this.runningTimeouts[i]); } - for(i=0;i<this.runningIntervals;i++) { - clearTimer(this.runningIntervals[i]); + for(i=0;i<this.runningIntervals.length;i++) { + clearInterval(this.runningIntervals[i]); } }.bind(this); }; From eb62212626525c410c0f0ca96383914095dab289 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 16:48:14 +0000 Subject: [PATCH 319/347] Add check for channel ignorance in command execution logic [#190] --- modules/command/README.md | 9 +++++---- modules/command/api.js | 11 ++++------- modules/command/command.js | 1 + 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/modules/command/README.md b/modules/command/README.md index 6f52a18..619fa04 100644 --- a/modules/command/README.md +++ b/modules/command/README.md @@ -11,11 +11,12 @@ Command flow: command name 2. Is the user banned from running the given command? 3. Is the user ignoring the command? -3. Does the use have the access level to run the command? -4. Is the command set as disabled? -4. Apply regex to the command, pass into event object. +4. Is the channel ignoring the command? +5. Does the use have the access level to run the command? +6. Is the command set as disabled? +7. Apply regex to the command, pass into event object. * If regex does not apply, show usage info. -5. Run the command. +8. Run the command. This is the only module which is force loaded, even if it's not specified in the configuration file. diff --git a/modules/command/api.js b/modules/command/api.js index 2347977..51202e9 100644 --- a/modules/command/api.js +++ b/modules/command/api.js @@ -34,15 +34,12 @@ var api = function(dbot) { }, /** - * Is user ignoring command? + * Is item (user or channel) ignoring command? */ - 'isIgnoring': function(user, command) { + 'isIgnoring': function(item, command) { var module = dbot.commands[command].module; - var ignoring = false; - if(_.has(dbot.db.ignores, user) && _.include(dbot.db.ignores[user], module)) { - ignoring = true; - } - return ignoring; + return (_.has(dbot.db.ignores, item) && + _.include(dbot.db.ignores[item], module)); }, /** diff --git a/modules/command/command.js b/modules/command/command.js index 0895a94..935f6e0 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -25,6 +25,7 @@ var command = function(dbot) { event.reply(dbot.t('command_ban', {'user': event.user})); } else { if(!this.api.isIgnoring(event.user, commandName) && + !this.api.isIgnoring(event.channel, commandName) && this.api.hasAccess(event.user, commandName) && dbot.commands[commandName].disabled !== true) { if(this.api.applyRegex(commandName, event)) { From 7cf2d051ad342097216dfa2ce117b10ed3d551e8 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 16:50:00 +0000 Subject: [PATCH 320/347] bump jsbot version --- jsbot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsbot b/jsbot index 296c5fc..35910d9 160000 --- a/jsbot +++ b/jsbot @@ -1 +1 @@ -Subproject commit 296c5fc6b5d9040791fac9cb33e9aeaf7ce16686 +Subproject commit 35910d9025fa3af15b24cecc3f6e7ee897aee4dc From 4a64928fd6199f84b41a09a985cb95d2f1fc8cbd Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 17:18:38 +0000 Subject: [PATCH 321/347] ~ignorechannel and ~unignorechannel commands in [#190] --- modules/ignore/ignore.js | 56 +++++++++++++++++++++++++++++++++++-- modules/ignore/strings.json | 15 ++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/modules/ignore/ignore.js b/modules/ignore/ignore.js index c456fcb..9e82f74 100644 --- a/modules/ignore/ignore.js +++ b/modules/ignore/ignore.js @@ -2,7 +2,8 @@ * 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. + * this information, since that actually performs the ignorance. Also provides + * commands for moderators to choose the bot to ignore certain channels. */ var _ = require('underscore')._; @@ -69,15 +70,64 @@ var ignore = function(dbot) { event.reply(dbot.t('invalid_unignore', { 'user': event.user })); } } + }, + + '~ignorechannel': function(event) { + var channel = ((event.params[1] == '@') ? event.channel.name : event.params[1]); + var module = event.params[2]; + + // Ignoring the value of 'ignorable' at the moment + if(_.include(dbot.config.moduleNames, module)) { + if(!_.has(dbot.db.ignores, channel)) dbot.db.ignores[channel] = []; + if(!_.include(dbot.db.ignores[channel], module)) { + dbot.db.ignores[channel].push(module); + dbot.instance.ignoreTag(channel, module); + event.reply(dbot.t('ignoring_channel', { + 'module': module, + 'channel': channel + })e; + } else { + event.reply(dbot.t('already_ignoring_channel', { + 'module': module, + 'channel': channel + })); + } + } else { + event.reply(dbot.t('module_not_exist', { 'module': module })); + } + }, + + '~unignorechannel': function(event) { + var channel = ((event.params[1] == '@') ? event.channel.name : event.params[1]); + var module = event.params[2]; + + if(!_.has(dbot.db.ignores, channel)) dbot.db.ignores[channel] = []; + if(_.include(dbot.db.ignores[channel], module)) { + dbot.db.ignores[channel] = _.without(dbot.db.ignores[channel], module); + dbot.instance.removeIgnore(channel, module); + event.reply(dbot.t('unignoring_channel', { + 'module': module, + 'channel': channel + })); + } else { + event.reply(dbot.t('not_ignoring_channel', { + 'module': module, + 'channel': channel + })); + } } }; + + commands['~ignorechannel'].access = 'moderator'; + commands['~unignorechannel'].access = 'moderator'; + this.commands = commands; this.onLoad = function() { dbot.instance.clearIgnores(); - _.each(dbot.db.ignores, function(ignores, user) { + _.each(dbot.db.ignores, function(ignores, item) { _.each(ignores, function(ignore) { - dbot.instance.ignoreTag(user, ignore); + dbot.instance.ignoreTag(item, ignore); }, this); }, this); }; diff --git a/modules/ignore/strings.json b/modules/ignore/strings.json index e926a7a..8a476a1 100644 --- a/modules/ignore/strings.json +++ b/modules/ignore/strings.json @@ -40,5 +40,20 @@ "spanish": "{user}: Ya no ignoras {module}.", "na'vi": "{user}: Nga terìng mikyun {module}ne set", "welsh": "{user}: Ddim yn anwybyddu {module} bellach" + }, + "ignoring_channel": { + "english": "Now ignoring {module} in {channel}" + }, + "already_ignoring_channel": { + "english": "Already ignoring {module} in {channel}" + }, + "module_not_exist": { + "english": "{module} isn't loaded or doesn't exist." + }, + "unignoring_channel": { + "english": "No longer ignoring {module} in {channel}" + }, + "not_ignoring_channel": { + "english": "{module} wasn't being ignored in {channel}" } } From 74d8fd9f943f89ba8729572a3bdbc2ffdb3dd872 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 17:53:50 +0000 Subject: [PATCH 322/347] getConfig now figures out value, appropriate changes for [#189] --- modules/admin/commands.js | 45 +++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/modules/admin/commands.js b/modules/admin/commands.js index 6c8c674..4cbaa14 100644 --- a/modules/admin/commands.js +++ b/modules/admin/commands.js @@ -6,7 +6,7 @@ var fs = require('fs'), var commands = function(dbot) { var noChangeConfig = [ 'servers', 'name', 'moduleNames' ]; - var getCurrentConfigPath = function(configKey) { + var getCurrentConfig = function(configKey) { var defaultConfigPath = dbot.config; var userConfigPath = dbot.db.config; @@ -25,9 +25,22 @@ var commands = function(dbot) { } } + var currentOption; + if(configKey.length != 1) { + configKey = _.last(configKey); + if(_.has(userConfigPath, configKey) && !_.isUndefined(userConfigPath[configKey])) { + currentOption = userConfigPath[configKey]; + } else if(_.has(defaultConfigPath, configKey)) { + currentOption = defaultConfigPath[configKey]; + } + } else { + currentOption = defaultConfigPath[configKey]; + } + return { 'user': userConfigPath, - 'default': defaultConfigPath + 'default': defaultConfigPath, + 'value': currentOption }; }; @@ -205,16 +218,13 @@ var commands = function(dbot) { var newOption = event.params[2]; if(!_.include(noChangeConfig, configKey)) { - var configPath = getCurrentConfigPath(configPathString); - var currentOption; - if(_.has(configPath['user'], configKey)) { - currentOption = configPath['user'][configKey]; - } else if(_.has(configPath['default'], configKey)) { - currentOption = configPath['default'][configKey]; - } else { + var configPath = getCurrentConfig(configPathString); + + if(configPath == false || _.isUndefined(configPath.value)) { event.reply("Config key doesn't exist bro"); return; } + var currentOption = configPath.value; // Convert to boolean type if config item boolean if(_.isBoolean(currentOption)) { @@ -224,8 +234,6 @@ var commands = function(dbot) { if(_.isArray(currentOption)) { event.reply("Config option is an array. Try 'pushconfig'."); } - - // TODO: Same for numbers and that I assume event.reply(configPathString + ": " + currentOption + " -> " + newOption); configPath['user'][configKey] = newOption; @@ -237,24 +245,19 @@ var commands = function(dbot) { 'showconfig': function(event) { var configPathString = event.params[1]; - var configPath = getCurrentConfigPath(configPathString); + var configPath = getCurrentConfig(configPathString); if(configPathString) { var configKey = _.last(configPathString.split('.')); - - if(!_.has(configPath['default'], configKey)) { + if(configKey == false) { event.reply("Config path doesn't exist"); return; } - if(_.isObject(configPath['default'][configKey])) { - event.reply('Config keys in ' + configPathString + ': ' + Object.keys(configPath['default'][configKey])); + if(_.isObject(configPath.value)) { + event.reply('Config keys in ' + configPathString + ': ' + Object.keys(configPath.value)); } else { - var currentOption = configPath['default'][configKey]; - if(_.has(configPath['user'], configKey)) { - currentOption = configPath['user'][configKey]; - } - event.reply(configKey + ': ' + currentOption); + event.reply(configKey + ': ' + configPath.value); } } else { event.reply('Config keys in root: ' + Object.keys(configPath['default'])); From a670faab211dbb43102af213dcc707cd60e9bb86 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 19:44:38 +0000 Subject: [PATCH 323/347] syntax fix --- modules/ignore/ignore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ignore/ignore.js b/modules/ignore/ignore.js index 9e82f74..832c7ce 100644 --- a/modules/ignore/ignore.js +++ b/modules/ignore/ignore.js @@ -85,7 +85,7 @@ var ignore = function(dbot) { event.reply(dbot.t('ignoring_channel', { 'module': module, 'channel': channel - })e; + }); } else { event.reply(dbot.t('already_ignoring_channel', { 'module': module, From c353069213013591225c4dc013c837a1bfbda165 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 19:45:56 +0000 Subject: [PATCH 324/347] syntax fix --- modules/ignore/ignore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ignore/ignore.js b/modules/ignore/ignore.js index 832c7ce..9fa9eac 100644 --- a/modules/ignore/ignore.js +++ b/modules/ignore/ignore.js @@ -85,7 +85,7 @@ var ignore = function(dbot) { event.reply(dbot.t('ignoring_channel', { 'module': module, 'channel': channel - }); + })); } else { event.reply(dbot.t('already_ignoring_channel', { 'module': module, From d3c3c2a5c18dae825173f05d236c74e5a4c3c513 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 20:26:14 +0000 Subject: [PATCH 325/347] pushconfig command [#189] --- modules/admin/commands.js | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/modules/admin/commands.js b/modules/admin/commands.js index 4cbaa14..a5d3719 100644 --- a/modules/admin/commands.js +++ b/modules/admin/commands.js @@ -213,9 +213,9 @@ var commands = function(dbot) { /*** Config options ***/ 'setconfig': function(event) { - var configPathString = event.params[1]; - var configKey = _.last(configPathString.split('.')); - var newOption = event.params[2]; + var configPathString = event.params[1], + configKey = _.last(configPathString.split('.')), + newOption = event.params[2]; if(!_.include(noChangeConfig, configKey)) { var configPath = getCurrentConfig(configPathString); @@ -243,6 +243,30 @@ var commands = function(dbot) { } }, + 'pushconfig': function(event) { + var configPathString = event.params[1], + configKey = _.last(configPathString.split('.')), + newOption = event.params[2]; + + if(!_.include(noChangeConfig, configKey)) { + var configPath = getCurrentConfig(configPathString); + if(configPath == false || _.isUndefined(configPath.value)) { + event.reply("Config key doesn't exist bro"); + return; + } + var currentArray = configPath.value; + + if(!_.isArray(currentArray)) { + event.reply("Config option is not an array. Try 'setconfig'."); + return + } + + event.reply(configPathString + ": " + currentArray + " << " + newOption); + currentArray.push(newOption); + dbot.reloadModules(); + } + }, + 'showconfig': function(event) { var configPathString = event.params[1]; var configPath = getCurrentConfig(configPathString); @@ -254,7 +278,9 @@ var commands = function(dbot) { return; } - if(_.isObject(configPath.value)) { + if(_.isArray(configPath.value)) { + event.reply(configKey + ': ' + configPath.value); + } else if(_.isObject(configPath.value)) { event.reply('Config keys in ' + configPathString + ': ' + Object.keys(configPath.value)); } else { event.reply(configKey + ': ' + configPath.value); From aeea3fc269b9c18eb5f7a52ac97c62d356af27e8 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 20:33:27 +0000 Subject: [PATCH 326/347] Quotes rm stuff no longer uses timers.js [#170] --- modules/quotes/quotes.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index b1b2639..cf6d5d4 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -44,7 +44,7 @@ var quotes = function(dbot) { 'resetRemoveTimer': function(event, key, quote) { this.rmAllowed = false; - dbot.timers.addOnceTimer(5000, function() { + setTimeout(5000, function() { this.rmAllowed = true; }); @@ -52,10 +52,10 @@ var quotes = function(dbot) { 'key': key, 'quote': quote }); - dbot.timers.clearTimeout(this.rmTimer); + clearTimeout(this.rmTimer); if(this.rmCache.length < dbot.config.quotes.rmLimit) { - this.rmTimer = dbot.timers.addOnceTimer(600000, function() { + this.rmTimer = setTimeout(600000, function() { this.rmCache.length = 0; // lol what }.bind(this)); } else { From a5cede8c921bdaa1448be2f3e942d08771766e00 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 20:52:11 +0000 Subject: [PATCH 327/347] remove timers.js [#170] --- modules/quotes/commands.js | 2 +- modules/quotes/quotes.js | 8 ++++---- run.js | 7 ++----- timer.js | 39 -------------------------------------- 4 files changed, 7 insertions(+), 49 deletions(-) delete mode 100644 timer.js diff --git a/modules/quotes/commands.js b/modules/quotes/commands.js index c99fd01..86cf45b 100644 --- a/modules/quotes/commands.js +++ b/modules/quotes/commands.js @@ -96,7 +96,7 @@ var commands = function(dbot) { }, '~rmlast': function(event) { - if(this.rmAllowed == true || _.include(dbot.config.admins, event.user)) { + if(this.rmAllowed === true || _.include(dbot.config.admins, event.user)) { var key = event.input[1].trim().toLowerCase(); if(_.has(quotes, key)) { var quote = quotes[key].pop(); diff --git a/modules/quotes/quotes.js b/modules/quotes/quotes.js index cf6d5d4..269e252 100644 --- a/modules/quotes/quotes.js +++ b/modules/quotes/quotes.js @@ -44,9 +44,9 @@ var quotes = function(dbot) { 'resetRemoveTimer': function(event, key, quote) { this.rmAllowed = false; - setTimeout(5000, function() { + setTimeout(function() { this.rmAllowed = true; - }); + }.bind(this), 5000); this.rmCache.push({ 'key': key, @@ -55,9 +55,9 @@ var quotes = function(dbot) { clearTimeout(this.rmTimer); if(this.rmCache.length < dbot.config.quotes.rmLimit) { - this.rmTimer = setTimeout(600000, function() { + this.rmTimer = setTimeout(function() { this.rmCache.length = 0; // lol what - }.bind(this)); + }.bind(this), 600000); } else { _.each(dbot.config.admins, function(admin) { dbot.say(event.server, admin, dbot.t('rm_cache_limit')); diff --git a/run.js b/run.js index 5ee0d3d..97667cb 100644 --- a/run.js +++ b/run.js @@ -1,10 +1,9 @@ var fs = require('fs'), _ = require('underscore')._, - timers = require('./timer'), jsbot = require('./jsbot/jsbot'); require('./snippets'); -var DBot = function(timers) { +var DBot = function() { /*** Load the DB ***/ @@ -61,7 +60,6 @@ var DBot = function(timers) { this.usage = {}; this.status = {}; this.sessionData = {}; - this.timers = timers.create(); // Populate bot properties with config data // Create JSBot and connect to each server @@ -130,7 +128,6 @@ DBot.prototype.reloadModules = function() { this.api = {}; this.commandMap = {}; // Map of which commands belong to which modules this.usage = {}; - this.timers.clearTimers(); // Load config changes _.extend(this.config, this.db.config); @@ -313,4 +310,4 @@ DBot.prototype.cleanNick = function(key) { return key; } -new DBot(timers); +new DBot(); diff --git a/timer.js b/timer.js deleted file mode 100644 index 3d74a80..0000000 --- a/timer.js +++ /dev/null @@ -1,39 +0,0 @@ -var timers = function() { - var timers = []; - var timeouts = []; - - return { - 'addTimer': function(interval, callback) { // Because who puts the callback first. Really. - var timer = setInterval(callback, interval); - timers.push(timer); - return timer; - }, - - 'addOnceTimer': function(delay, callback) { // Because who seriously puts the callback first here too? - var timeout = setTimeout(callback, delay); - timeouts.push(timeout); - return timeout; - }, - - 'clearTimers': function() { - for(var i;i<timers.length;i++) { - clearInterval(timers[i]); - } - for(var i;i<timeouts.length;i++) { - clearTimeout(timeouts[i]); - } - }, - - 'clearTimer': function(id) { - clearTimer(id); - }, - - 'clearTimeout': function(id) { - clearTimeout(id); - } - }; -}; - -exports.create = function() { - return timers(); -} From 13e24bbdbbc0d401b914bfc74dfc2f45d88bce36 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Sun, 27 Jan 2013 23:37:35 +0000 Subject: [PATCH 328/347] Testing rolling week [#216] --- modules/users/pages.js | 15 ++++++++++++--- views/users/users.jade | 3 ++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/modules/users/pages.js b/modules/users/pages.js index b129338..79924b1 100644 --- a/modules/users/pages.js +++ b/modules/users/pages.js @@ -26,18 +26,24 @@ var pages = function(dbot) { if(connections.hasOwnProperty(connection) && connections[connection].channels.hasOwnProperty(channel)) { - var chanData = dbot.api.stats.getChanStats(connection, channel, ["freq"]); + //TODO(samstudio8): Stats API Functionality + var chanData = dbot.api.stats.getChanStats(connection, channel, ["week"]); var chanFreq = []; + var chanFreqLabel = []; if(chanData){ + var cur_ptr; for(var i=0; i <= 6; i++){ + cur_ptr = ((i+1)+chanData.fields.week.raw.ptr) % 7; for(var j=0; j <= 23; j++){ - chanFreq.push(chanData.fields.freq.raw[i][j]); + chanFreq.push(chanData.fields.week.raw[cur_ptr][j]); } + chanFreqLabel.push("'"+chanData.fields.week.raw[cur_ptr].name+"'"); } } else{ for (var i = 0; i < 168; i++) chanFreq[i] = 0; + chanFreqLabel = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; } var userData = { "active": [], "inactive": [], "offline": []}; @@ -79,7 +85,10 @@ var pages = function(dbot) { 'channel': channel, 'userStats': userDataSorted, 'chanFreq': chanFreq, - 'chanFreqLen': chanFreq.length }); + 'chanFreqLen': chanFreq.length, + "locals": { + 'chanFreqLabel': chanFreqLabel, + }}); } else { res.render_core('error', { 'name': dbot.config.name, 'message': 'No such connection or channel.' }); diff --git a/views/users/users.jade b/views/users/users.jade index 85eba2d..2b97de5 100644 --- a/views/users/users.jade +++ b/views/users/users.jade @@ -94,7 +94,7 @@ block content .text(String); chart.selectAll("text.days") - .data(["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]) + .data([!{locals.chanFreqLabel}]) .enter().append("text") .attr("x", function(d, i){ return ((i+0.5) * w * 24) + ticks; }) .attr("y", h + 25) @@ -149,6 +149,7 @@ block content div#backlink a(href='/channels/'+connection) « Channel List div#row + h4 Seven Day Activity div.barchart#chanFreqChart hr div#row From dc82d0add0ac751bce9ef3e2d99b4d4901e775f6 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Sun, 27 Jan 2013 23:42:09 +0000 Subject: [PATCH 329/347] bump stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 3905ac9..706db54 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 3905ac91add5bebbd9a4aa03e2777fd6c498e5c0 +Subproject commit 706db54b718680dbc27a365839e4603f4feff4d5 From db4ea68bb958f652f015c296e60b6482bd65e858 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 28 Jan 2013 00:42:34 +0000 Subject: [PATCH 330/347] bump statos --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 706db54..8016eb1 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 706db54b718680dbc27a365839e4603f4feff4d5 +Subproject commit 8016eb138eaf5d47f2167ffc6b67659ab4ab9ae7 From 3112facd016b2154904a024d03dae0fa2b94e29c Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 28 Jan 2013 00:44:52 +0000 Subject: [PATCH 331/347] add zuzaks github module --- .gitmodules | 3 +++ modules/github | 1 + 2 files changed, 4 insertions(+) create mode 160000 modules/github diff --git a/.gitmodules b/.gitmodules index 49a4b35..365ed83 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "modules/stats"] path = modules/stats url = git://github.com/SamStudio8/stats.git +[submodule "modules/github"] + path = modules/github + url = git://github.com/zuzak/dbot-github.git diff --git a/modules/github b/modules/github new file mode 160000 index 0000000..ff4ac03 --- /dev/null +++ b/modules/github @@ -0,0 +1 @@ +Subproject commit ff4ac0388196bac7d83c5d891874fd8b19043359 From cb149531a5b6026793750e640d2533dde850be3b Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 28 Jan 2013 00:56:11 +0000 Subject: [PATCH 332/347] update github --- modules/github | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/github b/modules/github index ff4ac03..c557b7a 160000 --- a/modules/github +++ b/modules/github @@ -1 +1 @@ -Subproject commit ff4ac0388196bac7d83c5d891874fd8b19043359 +Subproject commit c557b7a6de089f81017574485a6b75c345cfc138 From b068f474757e1028e63a74f56b1778758a03faf0 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 28 Jan 2013 01:02:33 +0000 Subject: [PATCH 333/347] bump stats --- modules/github | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/github b/modules/github index c557b7a..d8f3039 160000 --- a/modules/github +++ b/modules/github @@ -1 +1 @@ -Subproject commit c557b7a6de089f81017574485a6b75c345cfc138 +Subproject commit d8f3039e4e636e0fc82f87028b26f1e622273dd5 From d123fa95c62528dc667b45c5854110f3b82fe3f8 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Mon, 28 Jan 2013 01:38:36 +0000 Subject: [PATCH 334/347] Profile onLoad to use own createProfile API [#220] --- modules/profile/api.js | 22 ++++++++++++++++++---- modules/profile/profile.js | 21 ++++----------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/modules/profile/api.js b/modules/profile/api.js index 633c993..b1c36d2 100644 --- a/modules/profile/api.js +++ b/modules/profile/api.js @@ -8,11 +8,23 @@ var api = function(dbot) { * If the server does not already exist, create it. */ "createProfile": function(server, primary){ + var primaryLower = primary.toLowerCase(); + if(!_.has(this.profiles, server)){ this.profiles[server] = {}; } - this.profiles[server][primary.toLowerCase()] = {}; - _.defaults(this.profiles[server][primary.toLowerCase()], this.config.schema); + if(!_.has(this.profiles[server], primaryLower)){ + this.profiles[server][primaryLower] = { + "profile": {}, + "preferences": {} + }; + this.profiles[server][primaryLower].profile.primary = primary; + } + + // Ensure all profiles have the keys specified by config.json + //TODO(samstudio8) Currently only handles "top-level" + _.defaults(this.profiles[server][primaryLower].profile, this.config.schema.profile); + _.defaults(this.profiles[server][primaryLower].preferences, this.config.schema.preferences); }, /** @@ -25,10 +37,12 @@ var api = function(dbot) { var profiles = dbot.db.profiles[server]; if(_.has(profiles, alias)){ - var primary = dbot.api.users.resolveUser(server, alias, true).toLowerCase(); + var primary = dbot.api.users.resolveUser(server, alias, true); + var primaryLower = primary.toLowerCase(); alias = alias.trim().toLowerCase(); - profiles[primary] = profiles[alias]; + profiles[primaryLower] = profiles[alias]; + profiles[primaryLower].profile.primary = primary; delete profiles[alias]; } }, diff --git a/modules/profile/profile.js b/modules/profile/profile.js index 5d3b146..5bcf3a1 100644 --- a/modules/profile/profile.js +++ b/modules/profile/profile.js @@ -9,27 +9,14 @@ var profile = function(dbot) { * required properties as defined in the configuation. */ this.onLoad = function(){ + var api = this.api; var schema = this.config.schema; // Ensure all known users have a profile _.each(dbot.api.users.getAllUsers(), function(server, serverName){ - if(!_.has(dbot.db.profiles, serverName)){ - dbot.db.profiles[serverName] = {} - } - _.each(server, function(userName){ - var primary = userName; - userName = userName.toLowerCase(); - // TODO why isn't this calling the profile create API function - if(!_.has(dbot.db.profiles[serverName], userName)){ - dbot.db.profiles[serverName][userName] = { - "profile": {}, - "preferences": {} - }; - } - //TODO(samstudio8) Currently only handles "top-level" - _.defaults(dbot.db.profiles[serverName][userName].profile, schema.profile); - _.defaults(dbot.db.profiles[serverName][userName].preferences, schema.preferences); - dbot.db.profiles[serverName][userName].profile.primary = primary; + _.each(server, function(primary, primaryi){ + console.log(primary); + api.createProfile(serverName, primary); }); }); dbot.save(); From fbd664668fbdc3819ffa1d6cdc83d1685c866050 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 28 Jan 2013 01:44:10 +0000 Subject: [PATCH 335/347] bump stats --- modules/stats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stats b/modules/stats index 8016eb1..ea795e4 160000 --- a/modules/stats +++ b/modules/stats @@ -1 +1 @@ -Subproject commit 8016eb138eaf5d47f2167ffc6b67659ab4ab9ae7 +Subproject commit ea795e4d17aa500923468366e73a10f6fbc94ade From 89834ecc43d79baef7806d64e81e8a9c269c527c Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 28 Jan 2013 01:47:57 +0000 Subject: [PATCH 336/347] version 0.3 bitches --- VERSION | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 29d455d..56c2180 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,5 @@ -depressionbot version 0.3-dev +depressionbot version 0.3 (relentless) +"the database is a grilled cheese" _.each(dbot.modules, function(module) { "RESCORE EVERYTHING" }); "He called his bot depressionbot, and that's when he was happy." From 3c6a594c322e4a3fba4da2130a71e5e99ac2b91b Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Mon, 28 Jan 2013 01:50:18 +0000 Subject: [PATCH 337/347] start 0.4 dev --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 56c2180..f593bdf 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ -depressionbot version 0.3 (relentless) +depressionbot version 0.4-dev "the database is a grilled cheese" _.each(dbot.modules, function(module) { "RESCORE EVERYTHING" }); From 53ef0288f56215b8e44392f6b88c8db67798c6c5 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Mon, 28 Jan 2013 01:54:39 +0000 Subject: [PATCH 338/347] LICENCE Housekeeping --- LICENCE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENCE b/LICENCE index 89ad61e..627898c 100644 --- a/LICENCE +++ b/LICENCE @@ -1,4 +1,4 @@ -Copyright (c) 2012 Luke Slater (tinmachin3@gmail.com) +Copyright (c) 2012-2013 Luke Slater (tinmachin3@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From f7f9037e4414df0b6373614f7134de8329bbdbb6 Mon Sep 17 00:00:00 2001 From: Sam Nicholls <sam.n@studio8media.co.uk> Date: Mon, 28 Jan 2013 23:40:32 +0000 Subject: [PATCH 339/347] Fixed new_user emit misfire --- modules/profile/profile.js | 2 +- modules/users/users.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/profile/profile.js b/modules/profile/profile.js index 5bcf3a1..740790c 100644 --- a/modules/profile/profile.js +++ b/modules/profile/profile.js @@ -15,7 +15,6 @@ var profile = function(dbot) { // Ensure all known users have a profile _.each(dbot.api.users.getAllUsers(), function(server, serverName){ _.each(server, function(primary, primaryi){ - console.log(primary); api.createProfile(serverName, primary); }); }); @@ -24,6 +23,7 @@ var profile = function(dbot) { // Add API Hooks dbot.api.command.addHook('~setaliasparent', this.api.renameProfile); dbot.api.command.addHook('~mergeusers', this.api.mergeProfile); + dbot.api.event.addHook('new_user', this.api.createProfile); }; }; diff --git a/modules/users/users.js b/modules/users/users.js index 205eb76..37dab11 100644 --- a/modules/users/users.js +++ b/modules/users/users.js @@ -48,7 +48,7 @@ var users = function(dbot) { nick = this.api.resolveUser(event.server, nick); } else { knownUsers.users.push(nick); - dbot.api.emit('new_user', [ event.server, nick ]); + dbot.api.event.emit('new_user', [ event.server, nick ]); } if(!_.include(channelUsers, nick)) { From c4a98c0df71eed288b1f46bf2c098273f71de04d Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 29 Jan 2013 00:53:37 +0000 Subject: [PATCH 340/347] fix #249 --- modules/timers/timers.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/timers/timers.js b/modules/timers/timers.js index 073114f..b1e968d 100644 --- a/modules/timers/timers.js +++ b/modules/timers/timers.js @@ -15,7 +15,7 @@ var timers = function(dbot) { if(firstDate) { console.log('Setting first timer to run at ' + firstDate); firstTimeout = firstDate.getTime() - now; - setTimeout(function() { + this.runningTimeouts.push(setTimeout(function() { console.log('Running first timer at ' + new Date().toUTCString()); this.runningIntervals.push(this.api.addTimer(timeout, callback)); try { @@ -23,7 +23,7 @@ var timers = function(dbot) { } catch(err) { console.log('Callback failed: ' + err); } - }.bind(this), firstTimeout); + }.bind(this), firstTimeout)); } else { this.runningIntervals.push(setInterval(function() { console.log('Running subsequent timer at ' + new Date().toUTCString()); @@ -39,9 +39,11 @@ var timers = function(dbot) { this.onDestroy = function() { for(var i=0;i<this.runningTimeouts.length;i++) { + console.log('destroying ' +this.runningTimeouts[i]); clearTimeout(this.runningTimeouts[i]); } for(i=0;i<this.runningIntervals.length;i++) { + console.log('destroying ' +this.runningIntervals[i]); clearInterval(this.runningIntervals[i]); } }.bind(this); From a8e8120a5ccba84edada83fdf48dcd8e05ef5b9c Mon Sep 17 00:00:00 2001 From: Jessica T <xray7224@googlemail.com> Date: Tue, 29 Jan 2013 14:47:37 +0000 Subject: [PATCH 341/347] =?UTF-8?q?reality=C3=ACri=20oel=20pamrel=20soli?= =?UTF-8?q?=20f=C3=AC'ur=20mipa=20upxare=20leNa'vi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/admin/strings.json | 12 ++++++++---- modules/command/strings.json | 12 ++++++++---- modules/ignore/strings.json | 15 ++++++++++----- modules/link/strings.json | 3 ++- modules/quotes/strings.json | 17 +++++++++++------ modules/report/strings.json | 12 ++++++++---- modules/users/strings.json | 18 ++++++++++++------ 7 files changed, 59 insertions(+), 30 deletions(-) diff --git a/modules/admin/strings.json b/modules/admin/strings.json index 7629aec..272b72a 100644 --- a/modules/admin/strings.json +++ b/modules/admin/strings.json @@ -66,15 +66,19 @@ "welsh": "Categori wedi cloi: {category}" }, "already_in_channel": { - "english": "I'm already in {channel}" + "english": "I'm already in {channel}", + "na'vi": "Oel {channel}it tok li" }, "not_in_channel": { - "english": "I'm not in {channel}" + "english": "I'm not in {channel}", + "na'vi": "Oel {channel}it ke tok" }, "already_loaded_web": { - "english": "WHY CAN'T I LOAD ALL THIS WEB? (web already loaded)" + "english": "WHY CAN'T I LOAD ALL THIS WEB? (web already loaded)", + "na'vi": "PELUN OEL KE TSUN OMUM FÌWETIT NÌWOTX (wetìri oe omum li)" }, "already_loaded": { - "english": "{moduleName} is already loaded." + "english": "{moduleName} is already loaded.", + "na'vi": "Oel omum teri {moduleName}it li." } } diff --git a/modules/command/strings.json b/modules/command/strings.json index d778c23..511c51e 100644 --- a/modules/command/strings.json +++ b/modules/command/strings.json @@ -12,15 +12,19 @@ "welsh": "Cystrawen annilys. Cychwyn orfflosgiad" }, "usage": { - "english": "Usage for {command}: {usage}." + "english": "Usage for {command}: {usage}.", + "na'vi": "Nga tsun sivar ìlä {command}: {usage}." }, "no_usage_info": { - "english": "No usage information found for {command}." + "english": "No usage information found for {command}.", + "na'vi": "Oel ke tsun sivar {comamnd}it" }, "help_link": { - "english": "Help for {module}: {link}" + "english": "Help for {module}: {link}", + "na'vi": "{module}ä srungìl {link} it tok" }, "no_help": { - "english": "No help found for {module}." + "english": "No help found for {module}.", + "na'vi": "Fì{module}ìri oel ke tsun run srungit" } } diff --git a/modules/ignore/strings.json b/modules/ignore/strings.json index 8a476a1..7b31d66 100644 --- a/modules/ignore/strings.json +++ b/modules/ignore/strings.json @@ -42,18 +42,23 @@ "welsh": "{user}: Ddim yn anwybyddu {module} bellach" }, "ignoring_channel": { - "english": "Now ignoring {module} in {channel}" + "english": "Now ignoring {module} in {channel}", + "na'vi": "Oe ke stayawm {module}ur mì {channel}" }, "already_ignoring_channel": { - "english": "Already ignoring {module} in {channel}" + "english": "Already ignoring {module} in {channel}", + "na'vi": "Oe ke stayawm {module}ur mì {channel} li" }, "module_not_exist": { - "english": "{module} isn't loaded or doesn't exist." + "english": "{module} isn't loaded or doesn't exist.", + "na'vi": "Oel ke omum teri {module}it fu {module} ke fkeytok" }, "unignoring_channel": { - "english": "No longer ignoring {module} in {channel}" + "english": "No longer ignoring {module} in {channel}", + "na'vi": "Oel stayawm {module}ur mì {channel} set." }, "not_ignoring_channel": { - "english": "{module} wasn't being ignored in {channel}" + "english": "{module} wasn't being ignored in {channel}", + "na'vi": "Oel stayawm {module}ur mì {channel} li." } } diff --git a/modules/link/strings.json b/modules/link/strings.json index a4a0023..2709f1d 100644 --- a/modules/link/strings.json +++ b/modules/link/strings.json @@ -1,5 +1,6 @@ { "title_not_found": { - "english": "No page title found." + "english": "No page title found.", + "na'vi": "Oel ke tsun run 'upxare atxin." } } diff --git a/modules/quotes/strings.json b/modules/quotes/strings.json index 94d1b14..c82d6d5 100644 --- a/modules/quotes/strings.json +++ b/modules/quotes/strings.json @@ -105,21 +105,26 @@ "english": "{category} ({needle}): '{quote}' [{matches} results]", "spanish" : "{category} ({needle}): '{quote}' [{matches} resultados]", "na'vi": "{category} ({needle}): '{quote}' [kum a{matches}]", - "welsh": "{category} ({needle}): '{quote}' [{matches} canlyniad]" + "welsh": "{category} ({needle}): '{quote}' [{matches} canlyniad]", }, "quote_cache_auto_remove": { - "english": "There are {count} quotes in the removal cache, which will be automatically cleared." + "english": "There are {count} quotes in the removal cache, which will be automatically cleared.", + "na'vi": "{count}a 'upxarel sngelit tok, Oel 'ayku sngelit lukenga." }, "quote_cache_manual_remove": { - "english": "There are {count} quotes in the removal cache, which must be manually cleared." + "english": "There are {count} quotes in the removal cache, which must be manually cleared.", + "na'vi": "{count}a 'upxarel sngelit tok slä oel ke 'ayku sngelit tafral nga zene 'aivku" }, "quote_cache_cleared": { - "english": "{count} quotes cleared from the removal cache." + "english": "{count} quotes cleared from the removal cache.", + "na'vi": "Oel 'aìmku {count}a 'upxareti ta sngel." }, "quote_cache_reinstated": { - "english": "{count} quotes reinstated from the removal cache." + "english": "{count} quotes reinstated from the removal cache.", + "na'vi": "{count}a 'upxare tolätxaw ta sngel." }, "rm_cache_limit": { - "english": "Attention: Too many quotes removed, rmCache must be cleared or reinstated manually with ~rmconfirm or ~rmdeny." + "english": "Attention: Too many quotes removed, rmCache must be cleared or reinstated manually with ~rmconfirm or ~rmdeny.", + "na'vi": "Oel zerok 'upxareti apxay set, sweylu txo nga 'aivku upxareti ìlä ~rmconfirm fu ~rmdeny." } } diff --git a/modules/report/strings.json b/modules/report/strings.json index e5a467d..3b0393d 100644 --- a/modules/report/strings.json +++ b/modules/report/strings.json @@ -1,14 +1,18 @@ { "report": { - "english": "Attention: {reporter} has reported {reported} in {channel}. The reason given was: \"{reason}.\"" + "english": "Attention: {reporter} has reported {reported} in {channel}. The reason given was: \"{reason}.\"", + "na'vi": "{reporter}ìl fpìl futa {reported} fe' lu taluna {reason}." }, "reported": { - "english": "Thank you, {reported} has been reported to the channel administrators." + "english": "Thank you, {reported} has been reported to the channel administrators.", + "na'vi": "Irayo si ngari, fìtsengìri ayeyktan omum teri {reported}it set." }, "user_not_found": { - "english": "{reported} isn't a known user in {channel}." + "english": "{reported} isn't a known user in {channel}.", + "na'vi": "Oel ke omum {reported}it mì {channel}." }, "not_in_channel": { - "english": "I am not present in {channel}." + "english": "I am not present in {channel}.", + "na'vi": "Oel {channel}it ke tok." } } diff --git a/modules/users/strings.json b/modules/users/strings.json index e0ffa11..b3d7a52 100644 --- a/modules/users/strings.json +++ b/modules/users/strings.json @@ -1,20 +1,26 @@ { "alias": { - "english": "{alias} is an alias of {user}" + "english": "{alias} is an alias of {user}", + "na'vi": "ayfko syaw {user} {alias} nìteng" }, "primary": { - "english": "{user} is a primary user with {count} aliases, " + "english": "{user} is a primary user with {count} aliases, ", + "na'vi": "{user} lu txin ulte {count}a stxo lu poru, " }, "unknown_alias": { - "english": "{alias} does not currently exist as an alias or known user." + "english": "{alias} does not currently exist as an alias or known user.", + "na'vi": "{alias} ke fkeytok nìfkrr" }, "aliasparentset": { - "english": "{newParent} is now the parent user, and {newAlias} is an alias." + "english": "{newParent} is now the parent user, and {newAlias} is an alias.", + "na'vi": "{newParent} lu sa'sem set ulte {newAlias} lu stxo set nìteng." }, "unprimary_error": { - "english": "One of those users isn't currently recorded as a primary user." + "english": "One of those users isn't currently recorded as a primary user.", + "na'vi": "fo sute txin ke lu." }, "merged_users": { - "english": "{old_user} and their aliases have been merged into {new_user}." + "english": "{old_user} and their aliases have been merged into {new_user}.", + "na'vi": "{old_user} ulte stxo alahe {new_user} lu set." } } From b9ad35b21f3c59621e05b7ea7799977797b9c8c8 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 29 Jan 2013 15:05:34 +0000 Subject: [PATCH 342/347] fix syntax --- modules/quotes/strings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quotes/strings.json b/modules/quotes/strings.json index c82d6d5..3d3a9c1 100644 --- a/modules/quotes/strings.json +++ b/modules/quotes/strings.json @@ -105,7 +105,7 @@ "english": "{category} ({needle}): '{quote}' [{matches} results]", "spanish" : "{category} ({needle}): '{quote}' [{matches} resultados]", "na'vi": "{category} ({needle}): '{quote}' [kum a{matches}]", - "welsh": "{category} ({needle}): '{quote}' [{matches} canlyniad]", + "welsh": "{category} ({needle}): '{quote}' [{matches} canlyniad]" }, "quote_cache_auto_remove": { "english": "There are {count} quotes in the removal cache, which will be automatically cleared.", From 1a7825d8c60ba610961e626acc1267a90b1de3e6 Mon Sep 17 00:00:00 2001 From: reality <tinmachin3@gmail.com> Date: Tue, 29 Jan 2013 16:11:07 +0000 Subject: [PATCH 343/347] bump github --- modules/github | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/github b/modules/github index d8f3039..ca25f8f 160000 --- a/modules/github +++ b/modules/github @@ -1 +1 @@ -Subproject commit d8f3039e4e636e0fc82f87028b26f1e622273dd5 +Subproject commit ca25f8f94e205e2a6e3119227a6255eb80cd26df From e3074d8054af0a37e267774b7e1c8bdd57937671 Mon Sep 17 00:00:00 2001 From: Douglas Gardner <douglas@chippy.ch> Date: Wed, 30 Jan 2013 01:37:28 +0000 Subject: [PATCH 344/347] implement xkcd functionality The strings.json file is extensible; other fields that can be placed in the xkcd string include the {year}, {month} and {day} of the comic; the {alt} text; and links to the {img}. A {transcript} is also available. --- modules/link/link.js | 18 ++++++++++++++++++ modules/link/strings.json | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/modules/link/link.js b/modules/link/link.js index dfe5f70..201d364 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -32,6 +32,24 @@ var link = function(dbot) { } this.fetchTitle(event, link); }, + + '~xkcd': function(event) { + var comicId = event.params[1]; + if(comicId){ + comicId = comicId + "/"; + } else { + comicId = ""; + } + var link = "http://xkcd.com/"+comicId+"info.0.json"; + request(link, function(error, response, body) { + if (response.statusCode == "200") { + data = JSON.parse(body); + event.reply(dbot.t("xkcd",data)); + } else { + event.reply(dbot.t("no-hits")); + } + }); + }, '~ud': function(event) { var query = event.input[1]; diff --git a/modules/link/strings.json b/modules/link/strings.json index 2709f1d..935e635 100644 --- a/modules/link/strings.json +++ b/modules/link/strings.json @@ -2,5 +2,11 @@ "title_not_found": { "english": "No page title found.", "na'vi": "Oel ke tsun run 'upxare atxin." + }, + "xkcd": { + "english": "xkcd {num}: {title} https://xkcd.com/{num}" + }, + "no-hits": { + "english": "No hits." } } From 4f24e6db4a6398b2227c6ad5410a97f141c69089 Mon Sep 17 00:00:00 2001 From: Douglas Gardner <douglas@chippy.ch> Date: Wed, 30 Jan 2013 01:39:50 +0000 Subject: [PATCH 345/347] update documentation --- modules/link/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/link/README.md b/modules/link/README.md index 24c52d0..21de8ef 100644 --- a/modules/link/README.md +++ b/modules/link/README.md @@ -21,3 +21,5 @@ page. If called without a link, the bot will attempt the same on the last link which was posted in the current channel. #### ~ud [headword] Returns the first [Urban Dictionary](http://www.urbandictionary.com) definition for the headword provided. +#### ~xkcd <comic ID> +Returns a link to the [xkcd](http://xkcd.com) comic specified, or the latest one if a comic is not given. From eb7a9583529c259f2362873305e89d7a1ba992ff Mon Sep 17 00:00:00 2001 From: Luke Slater <tinmachin3@gmail.com> Date: Wed, 30 Jan 2013 09:56:56 +0100 Subject: [PATCH 346/347] Don't pork up if UD is down --- modules/link/link.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/link/link.js b/modules/link/link.js index 201d364..d684cf3 100644 --- a/modules/link/link.js +++ b/modules/link/link.js @@ -52,15 +52,17 @@ var link = function(dbot) { }, '~ud': function(event) { - var query = event.input[1]; + var query = event.input[1]; var reqUrl = 'http://api.urbandictionary.com/v0/define?term=' + encodeURI(query); request(reqUrl, function(error, response, body) { - var result = JSON.parse(body); - if(_.has(result, 'result_type') && result.result_type != 'no_results') { - event.reply(query + ': ' + result.list[0].definition.split('\n')[0]); - } else { - event.reply(event.user + ': No definition found.'); - } + try { + var result = JSON.parse(body); + if(_.has(result, 'result_type') && result.result_type != 'no_results') { + event.reply(query + ': ' + result.list[0].definition.split('\n')[0]); + } else { + event.reply(event.user + ': No definition found.'); + } + } catch(err) { } }); } }; From a130c3e744fd22231d52227374e984c30d13fd07 Mon Sep 17 00:00:00 2001 From: Douglas Gardner <douglas@chippy.ch> Date: Wed, 30 Jan 2013 14:57:36 +0000 Subject: [PATCH 347/347] Further automate the install script * config.json is now created in the correct location * config.json is only created if it doesn't already exist * vim launches to edit config.json on first install * User is prompted to run depressionbot directly from the script --- install.sh | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/install.sh b/install.sh index 42cf7ec..8a8d85d 100755 --- a/install.sh +++ b/install.sh @@ -1,5 +1,5 @@ #!/bin/bash - +cat LICENCE git submodule init git submodule update @@ -16,8 +16,20 @@ wget http://d3js.org/d3.v3.zip unzip d3.v3.zip rm d3.v3.zip -cd .. +cd ../.. -cp config.json.sample config.json +if [ ! -f config.json ]; +then + echo 'Creating configuration file...' + cp config.json.sample config.json + vim config.json +fi + +read -p "Setup complete. Run depressionbot now? [y/N]" +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + echo 'Okay. To run the bot, use "node run.js"' + exit +fi +node run.js -echo 'Setup complete. Now edit config.json with your preferences and run the bot with "node run.js"'