diff --git a/lib/tkellem/bouncer_connection.rb b/lib/tkellem/bouncer_connection.rb index 57de6ea..07443e6 100644 --- a/lib/tkellem/bouncer_connection.rb +++ b/lib/tkellem/bouncer_connection.rb @@ -56,7 +56,7 @@ def connect_to_irc_server end def msg_tkellem(msg) - TkellemBot.run_command(msg.args.join(' '), @user) do |response| + TkellemBot.run_command(msg.args.join(' '), @bouncer) do |response| say_as_tkellem(response) end end diff --git a/lib/tkellem/plugins/backlog.rb b/lib/tkellem/plugins/backlog.rb index 7459150..d19e092 100644 --- a/lib/tkellem/plugins/backlog.rb +++ b/lib/tkellem/plugins/backlog.rb @@ -4,6 +4,7 @@ require 'active_support/core_ext/class/attribute_accessors' require 'tkellem/irc_message' +require 'tkellem/tkellem_bot' module Tkellem @@ -166,4 +167,40 @@ def parse_line(line, ctx_name) end end +class TkellemBot + class Search < Command + register 'search' + + def execute(args, bouncer) + ctx = args[:rest].shift + query = args[:rest].join " " + + unless ctx.present? && query.present? + r "Please specify a #room and a string to search for." + return + end + + backlog = Backlog.get_instance(bouncer) + + filename = backlog.stream_filename(ctx) + unless File.exists?(filename) + r "Can't find backlog for #{ctx}." + return + end + + r "Searching #{ctx} for \"#{query}\"" + + # TODO: implement a smarter, reverse search, as this can be expensive on very long backlogs. + # TODO: keep some state after a search and let the user get context around one of the results. + result = %x{grep #{query.shellescape} #{filename} | tail -n 10} + if result.empty? + r "No results. Sorry." + else + r "Results:" + r result + end + end + end +end + end diff --git a/lib/tkellem/tkellem_bot.rb b/lib/tkellem/tkellem_bot.rb index 34a3a38..9aeba6e 100644 --- a/lib/tkellem/tkellem_bot.rb +++ b/lib/tkellem/tkellem_bot.rb @@ -6,7 +6,7 @@ module Tkellem class TkellemBot # careful here -- if no user is given, it's assumed the command is running as # an admin - def self.run_command(line, user, &block) + def self.run_command(line, bouncer, &block) args = Shellwords.shellwords(line.downcase) command_name = args.shift.upcase command = commands[command_name] @@ -16,7 +16,7 @@ def self.run_command(line, user, &block) return end - command.run(args, user, block) + command.run(args, bouncer, block) end class Command @@ -58,7 +58,8 @@ def self.admin_only? false end - def self.run(args_arr, user, block) + def self.run(args_arr, bouncer, block) + user = bouncer.user if admin_only? && !admin_user?(user) block.call "You can only run #{name} as an admin." return @@ -67,7 +68,7 @@ def self.run(args_arr, user, block) options.cmd = cmd options.parse!(args_arr) cmd.args[:rest] = args_arr - cmd.execute(cmd.args, user) + cmd.execute(cmd.args, bouncer) rescue ArgumentError => e cmd.respond e.to_s cmd.show_help @@ -98,7 +99,7 @@ def self.admin_user?(user) class Help < Command register 'help' - def execute(args, user) + def execute(args, bouncer) name = args[:rest].first r "**** tkellem help ****" if name.nil? @@ -108,7 +109,7 @@ def execute(args, user) r "The following commands are available:" TkellemBot.commands.keys.sort.each do |name| command = TkellemBot.commands[name] - next if command.admin_only? && user && !user.admin? + next if command.admin_only? && bouncer && bouncer.user && !bouncer.user.admin? r "#{name}#{' ' * (25-name.length)}" end elsif (command = TkellemBot.commands[name.upcase]) @@ -165,13 +166,13 @@ def add(args, user) end end - def execute(args, user) + def execute(args, bouncer) if args['list'] - list(args, user) + list(args, bouncer.user) elsif args['remove'] - remove(args, user) + remove(args, bouncer.user) elsif args['add'] - add(args, user) + add(args, bouncer.user) else raise Command::ArgumentError, "Unknown sub-command" end @@ -230,7 +231,8 @@ class PasswordCommand < Command options.set('username', '--user=username', '-u', 'Change password for other username') - def execute(args, user) + def execute(args, bouncer) + user = bouncer.user if args['username'] if Command.admin_user?(user) user = User.first(:conditions => { :username => args['username'] })