var _ = require('underscore')._, databank = require('databank'), uuid = require('node-uuid'); var commands = function(dbot) { var commands = { /*** Quote Addition ***/ // Add a quote to a category '~qadd': function(event) { var key = event.input[1].toLowerCase().trim(), quote = event.input[2]; this.api.addQuote(key, quote, event.user, function(newCount) { if(newCount) { dbot.api.event.emit('~qadd', [ key, quote ]); if(_.has(dbot.modules, 'web')) { event.reply(dbot.t('quote_saved', { 'category': key, 'count': newCount, 'link': dbot.api.web.getUrl('/quotes/' + key) })); } else { event.reply(dbot.t('quote_saved', { 'category': key, 'count': newCount })); } } else { event.reply(dbot.t('quote_exists')); } }); }, /*** Quote Retrieval ***/ // Alternative ~q syntax '~': function(event) { commands['~q'].bind(this)(event); }, // Retrieve quote from a category in the database. '~q': function(event) { var key = event.input[1]; this.api.getInterpolatedQuote(event.server, event.channel, event.user, key, function(quote) { if(quote) { event.reply(key + ': ' + quote); } else { event.reply(dbot.t('category_not_found', { 'category': key })); } }.bind(this)); }, // Choose a random quote category and a random quote from that // TODO: This is quite inefficient, but databank must evolve to do otherwise. '~rq': function(event) { var categories = []; this.db.scan('quote_category', function(result) { if(result) { categories.push(result); } }, function(err) { var cIndex = _.random(0, _.size(categories) -1); var qIndex = _.random(0, categories[cIndex].quotes.length - 1); event.reply(categories[cIndex].name + ': ' + categories[cIndex].quotes[qIndex]); }); }, /*** Quote Removal ***/ // Show number of quotes in removal cache '~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 })); } }, // Confirm removal of quote cache '~rmconfirm': function(event) { var rmCacheCount = this.rmCache.length; this.rmCache.length = 0; event.reply(dbot.t('quote_cache_cleared', { 'count': rmCacheCount })); }, // Reinstate all quotes in removal cache '~rmdeny': function(event) { var rmCache = this.rmCache; var rmCacheCount = rmCache.length; _.each(rmCache, function(quote, index) { this.api.addQuote(quote.key, quote.quote, event.user, function(newCount) { }); }.bind(this)); rmCache.length = 0; event.reply(dbot.t('quote_cache_reinstated', { 'count': rmCacheCount })); }, '~rmlast': function(event) { if(this.rmAllowed === true || _.include(dbot.config.admins, event.user)) { var key = event.input[1].trim().toLowerCase(), category = false, removedQuote; var quoteRemoved = function(err) { this.internalAPI.resetRemoveTimer(event, key, removedQuote); if(_.has(dbot.modules, 'web')) { event.reply(dbot.t('removed_from', { 'quote': removedQuote, 'category': key, 'link': dbot.api.web.getUrl('/quotes/' + key) })); } else { event.reply(dbot.t('removed_from', { 'quote': removedQuote, 'category': key })); } }.bind(this); this.db.search('quote_category', { 'name': key }, function(result) { category = result; }, function(err) { if(category) { removedQuote = category.quotes.pop(); if(category.quotes.length == 0) { this.db.del('quote_category', category.id, quoteRemoved); } else { this.db.save('quote_category', category.id, category, quoteRemoved); } } else { event.reply(dbot.t('category_not_found', { 'category': key })); } }.bind(this)); } else { event.reply(dbot.t('rmlast_spam')); } }, // Remove specific quote from category '~rm': function(event) { if(this.rmAllowed == true || _.include(dbot.config.admins, event.user)) { var key = event.input[1].trim().toLowerCase(); quote = event.input[2], category = false; var quoteRemoved = function(err) { this.internalAPI.resetRemoveTimer(event, key, quote); if(_.has(dbot.modules, 'web')) { event.reply(dbot.t('removed_from', { 'category': key, 'quote': quote, 'link': dbot.api.web.getUrl('/quotes/' + key) })); } else { event.reply(dbot.t('removed_from', { 'category': key, 'quote': quote })); } }.bind(this); this.db.search('quote_category', { 'name': key }, function(result) { category = result; }, function(err) { if(category) { if(category.quotes.indexOf(quote) != -1) { category.quotes = _.without(category.quotes, quote); if(category.quotes.length == 0) { this.db.del('quote_category', category.id, quoteRemoved); } else { this.db.save('quote_category', category.id, category, quoteRemoved); } } else { event.reply(dbot.t('q_not_exist_under', { 'category': key, 'quote': quote })); } } else { event.reply(dbot.t('category_not_found', { 'category': key })); } }.bind(this)); } else { event.reply(dbot.t('rmlast_spam')); } }, /*** Quote Statistics and Searching ***/ // Shows a list of the biggest categories '~qstats': function(event) { var quoteSizes = {}; this.db.scan('quote_category', function(category) { if(category) { quoteSizes[category.name] = category.quotes.length; } }.bind(this), function(err) { var qSizes = _.chain(quoteSizes) .pairs() .sortBy(function(category) { return category[1] }) .reverse() .first(10) .value(); var qString = dbot.t('large_categories'); for(var i=0;i 0) { event.reply(dbot.t('search_results', { 'category': matches[0].category, 'needle': needle, 'quote': matches[_.random(0, _.size(matches) -1)].quote, 'matches': matches.length })); } else { event.reply(dbot.t('no_results')); } }); } else { this.db.search('quote_category', { 'name': haystack }, function(result) { category = result; }, function(err) { if(category) { var matches = _.filter(category.quotes, function(quote) { return quote.indexOf(needle) != -1; }); if(matches.length == 0) { event.reply(dbot.t('no_results')); } else { event.reply(dbot.t('search_results', { 'category': haystack, 'needle': needle, 'quote': matches[_.random(0, _.size(matches) -1)], 'matches': matches.length })); } } else { event.reply(dbot.t('empty_category')); } }); } }, // Count quotes in a given category or total quotes overall '~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(), category = false; this.db.search('quote_category', { 'name': key }, function(result) { category = result; }, function(err) { if(category) { event.reply(dbot.t('quote_count', { 'category': key, 'count': category.quotes.length })); } else { event.reply(dbot.t('category_not_found', { 'category': key })); } }); } else { var quoteCount = 0; this.db.scan('quote_category', function(category) { if(category) { quoteCount += category.quotes.length; } }, function(err) { event.reply(dbot.t('total_quotes', { 'count': quoteCount })); }); } }, // Rename a quote category '~qrename': function(event) { var oldName = event.input[1], newName = event.input[2], oldCategory = false, newCategory = false; this.db.search('quote_category', { 'name': newName }, function(result) { newCategory = result; }, function(err) { if(!newCategory) { this.db.search('quote_category', { 'name': oldName }, function(result) { oldCategory = result; }, function(err) { oldCategory.name = newName; this.db.save('quote_category', oldCategory.id, oldCategory, function(err) { event.reply(dbot.t('category_renamed', { 'oldName': oldName, 'newName': newName })); }); }.bind(this)); } else { event.reply(dbot.t('newcat_exists', { 'newcat': newName })); } }.bind(this)); }, // Merge a quote category insto another '~qmerge': function(event) { var primaryName = event.input[1], secondName = event.input[2], primary = false, secondary = false; this.db.search('quote_category', { 'name': primaryName }, function(result) { primary = result; }, function(err) { if(primary) { this.db.search('quote_category', { 'name': secondName }, function(result) { secondary = result; }, function(err) { if(secondary) { primary.quotes = _.union(primary.quotes, secondary.quotes); this.db.save('quote_category', primary.id, primary, function(err) { this.db.del('quote_category', secondary.id, function(err) { event.reply(dbot.t('categories_merged', { 'from': secondName, 'into': primaryName })); }); }.bind(this)); } else { event.reply(dbot.t('category_not_found', { 'category': secondName })); } }.bind(this)); } else { event.reply(dbot.t('category_not_found', { 'category': primaryName })); } }.bind(this)); }, // Link to quote web page '~link': function(event) { var key = event.input[1].toLowerCase(), category = false; this.db.search('quote_category', { 'name': key }, function(result) { category = result; }, function(err) { if(category) { if(_.has(dbot.modules, 'web')) { event.reply(dbot.t('quote_link', { 'category': key, 'url': dbot.api.web.getUrl('/quotes/' + key) })); } else { event.reply(dbot.t('web_not_configured')); } } else { event.reply(dbot.t('category_not_found', { 'category': key })); } }); } }; commands['~'].regex = [/^q ([\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-]+[\d\w\s-]*)[ ]?=[ ]?(.+)$/, 3]; commands['~qrename'].regex = [/^qrename ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; commands['~qmerge'].regex = [/^qmerge ([\d\w\s-]+?)[ ]?=[ ]?(.+)$/, 3]; commands['~link'].regex = [/^link ([\d\w\s-]*)/, 2]; commands['~q'].access = 'user'; commands['~rmconfirm'].access = 'moderator'; commands['~rmdeny'].access = 'moderator'; commands['~qrename'].access = 'moderator'; commands['~qmerge'].access = 'moderator'; return commands; }; exports.fetch = function(dbot) { return commands(dbot); };