rbot 0.9.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. data/AUTHORS +16 -0
  2. data/COPYING +21 -0
  3. data/ChangeLog +418 -0
  4. data/INSTALL +8 -0
  5. data/README +44 -0
  6. data/REQUIREMENTS +34 -0
  7. data/TODO +5 -0
  8. data/Usage_en.txt +129 -0
  9. data/bin/rbot +81 -0
  10. data/data/rbot/contrib/plugins/figlet.rb +20 -0
  11. data/data/rbot/contrib/plugins/ri.rb +83 -0
  12. data/data/rbot/contrib/plugins/stats.rb +232 -0
  13. data/data/rbot/contrib/plugins/vandale.rb +49 -0
  14. data/data/rbot/languages/dutch.lang +73 -0
  15. data/data/rbot/languages/english.lang +75 -0
  16. data/data/rbot/languages/french.lang +39 -0
  17. data/data/rbot/languages/german.lang +67 -0
  18. data/data/rbot/plugins/autoop.rb +68 -0
  19. data/data/rbot/plugins/autorejoin.rb +16 -0
  20. data/data/rbot/plugins/cal.rb +15 -0
  21. data/data/rbot/plugins/dice.rb +81 -0
  22. data/data/rbot/plugins/eightball.rb +19 -0
  23. data/data/rbot/plugins/excuse.rb +470 -0
  24. data/data/rbot/plugins/fish.rb +61 -0
  25. data/data/rbot/plugins/fortune.rb +22 -0
  26. data/data/rbot/plugins/freshmeat.rb +98 -0
  27. data/data/rbot/plugins/google.rb +51 -0
  28. data/data/rbot/plugins/host.rb +14 -0
  29. data/data/rbot/plugins/httpd.rb.disabled +35 -0
  30. data/data/rbot/plugins/insult.rb +258 -0
  31. data/data/rbot/plugins/karma.rb +85 -0
  32. data/data/rbot/plugins/lart.rb +181 -0
  33. data/data/rbot/plugins/math.rb +122 -0
  34. data/data/rbot/plugins/nickserv.rb +89 -0
  35. data/data/rbot/plugins/nslookup.rb +43 -0
  36. data/data/rbot/plugins/opme.rb +19 -0
  37. data/data/rbot/plugins/quakeauth.rb +51 -0
  38. data/data/rbot/plugins/quotes.rb +321 -0
  39. data/data/rbot/plugins/remind.rb +228 -0
  40. data/data/rbot/plugins/roshambo.rb +54 -0
  41. data/data/rbot/plugins/rot13.rb +10 -0
  42. data/data/rbot/plugins/roulette.rb +147 -0
  43. data/data/rbot/plugins/rss.rb.disabled +414 -0
  44. data/data/rbot/plugins/seen.rb +89 -0
  45. data/data/rbot/plugins/slashdot.rb +94 -0
  46. data/data/rbot/plugins/spell.rb +36 -0
  47. data/data/rbot/plugins/tube.rb +71 -0
  48. data/data/rbot/plugins/url.rb +88 -0
  49. data/data/rbot/plugins/weather.rb +649 -0
  50. data/data/rbot/plugins/wserver.rb +71 -0
  51. data/data/rbot/plugins/xmlrpc.rb.disabled +52 -0
  52. data/data/rbot/templates/keywords.rbot +4 -0
  53. data/data/rbot/templates/lart/larts +98 -0
  54. data/data/rbot/templates/lart/praises +5 -0
  55. data/data/rbot/templates/levels.rbot +30 -0
  56. data/data/rbot/templates/users.rbot +1 -0
  57. data/lib/rbot/auth.rb +203 -0
  58. data/lib/rbot/channel.rb +54 -0
  59. data/lib/rbot/config.rb +363 -0
  60. data/lib/rbot/dbhash.rb +112 -0
  61. data/lib/rbot/httputil.rb +141 -0
  62. data/lib/rbot/ircbot.rb +808 -0
  63. data/lib/rbot/ircsocket.rb +185 -0
  64. data/lib/rbot/keywords.rb +433 -0
  65. data/lib/rbot/language.rb +69 -0
  66. data/lib/rbot/message.rb +256 -0
  67. data/lib/rbot/messagemapper.rb +262 -0
  68. data/lib/rbot/plugins.rb +291 -0
  69. data/lib/rbot/post-install.rb +8 -0
  70. data/lib/rbot/rbotconfig.rb +36 -0
  71. data/lib/rbot/registry.rb +271 -0
  72. data/lib/rbot/rfc2812.rb +1104 -0
  73. data/lib/rbot/timer.rb +201 -0
  74. data/lib/rbot/utils.rb +83 -0
  75. data/setup.rb +1360 -0
  76. metadata +129 -0
data/INSTALL ADDED
@@ -0,0 +1,8 @@
1
+ Just run rbot, it'll ask you for any core information it needs before it can
2
+ start, after that you can configure everything else online using the config
3
+ module.
4
+
5
+ You can maintain multiple configurations at once. Start rbot with the
6
+ location you want it to store runtime data in. By default, running rbot
7
+ uses the ~/.rbot config directory. If you run 'rbot /path/to/foo', then the
8
+ configuration will be stored to and read from there instead.
data/README ADDED
@@ -0,0 +1,44 @@
1
+ rbot README
2
+ ===========
3
+
4
+ rbot is a ruby IRC bot. Think of him as a ruby bot framework with a highly
5
+ modular design based around plugins.
6
+
7
+ rbot features
8
+ =============
9
+
10
+ * Runtime configuration via irc chat
11
+ * User authentication and access levels for using different bot features
12
+ * Built in infobot-style keywords. See example session below.
13
+ * Support for underlying fact database (infobot fact files), which can
14
+ be overridden or supplemented by runtime keyword controls
15
+ * Multi-language support - comes with english, dutch and german definitions
16
+ so far - more translations welcome
17
+ * Powerful plugin architecture, comes with plugins for:
18
+ o DNS queries
19
+ o Babelfish translation
20
+ o Google searching
21
+ o Excuse generation
22
+ o Insult generation
23
+ o Karma
24
+ o Checking the weather
25
+ o Querying slashdot
26
+ o Doing Math
27
+ o Per-channel quote storage, searching and retrieval
28
+ o Reminders
29
+ o rot13 translation
30
+ o Check the spelling of a word
31
+ o Webserver Server: header examination
32
+ o RPG dice rolling
33
+ o larting people
34
+ o conversation stats
35
+ o more...
36
+
37
+ Thanks are owed to the infobot developers - several of rbot's features are
38
+ inspired by infobot and so are some of the default plugins. Thanks are also
39
+ owed to RADKade1, as rbot's quote plugin is a direct reimplementation of his
40
+ "quotesaq" - simply because it's a great quote interface.
41
+
42
+ Mainly, rbot's fun to play with, although the plugin architecture can be used
43
+ to write very useful modules
44
+
@@ -0,0 +1,34 @@
1
+ Ruby modules needed for rbot
2
+ ============================
3
+
4
+ Core requirements
5
+ bdb (berkley db) http://www.ruby-lang.org/en/raa-list.rhtml?name=bdb
6
+ (which requires libdb2 or better, from
7
+ www.sleepycat.com)
8
+ net/http 1.1+
9
+ socket
10
+ uri
11
+
12
+ Plugin requirements
13
+ (these are all optional, if you don't have them, the plugins just won't
14
+ function)
15
+
16
+ babelfish, wserver:
17
+ net/http 1.2+
18
+
19
+ slashdot, freshmeat, rss:
20
+ REXML
21
+
22
+ External programs needed for rbot
23
+ =================================
24
+
25
+ Plugin requirements
26
+ (These are all optional)
27
+
28
+ host plugin:
29
+ host(1)
30
+
31
+ spell plugin:
32
+ ispell(1)
33
+
34
+
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ o freeze/thaw factoids (make them readonly) at higher auth
2
+ o respond to insults
3
+ o feed back errors from plugins (optional)
4
+ o Allow users to leave messages to named users.
5
+ o wtf plugin (bsdgames)
@@ -0,0 +1,129 @@
1
+ Installing Programs with setup.rb
2
+ =================================
3
+
4
+ Quick Start
5
+ -----------
6
+
7
+ Type this (You might needs super user previledge):
8
+
9
+ ($ su)
10
+ # ruby setup.rb
11
+
12
+ If you want to install a program in to your home directory
13
+ ($HOME), use following instead:
14
+
15
+ $ ruby setup.rb all --prefix=$HOME
16
+
17
+
18
+ Detailed Installtion Process
19
+ ----------------------------
20
+
21
+ setup.rb invokes installation by three steps. There are
22
+ "config", "setup" and "install". You can invoke each steps
23
+ separately as following:
24
+
25
+ $ ruby setup.rb config
26
+ $ ruby setup.rb setup
27
+ # ruby setup.rb install
28
+
29
+ You can controll installation process by giving detailed
30
+ options for each tasks. For example, --bin-dir=$HOME/bin
31
+ let setup.rb install commands in $HOME/bin.
32
+
33
+ For details, see "Task Options".
34
+
35
+ Global Options
36
+ --------------
37
+
38
+ "Global Option" is a command line option which you can use
39
+ for all tasks. You must give a global option before any task
40
+ name.
41
+
42
+ -q,--quiet
43
+ suppress message outputs
44
+ --verbose
45
+ output messages verbosely (default)
46
+ -h,--help
47
+ prints help and quit
48
+ -v,--version
49
+ prints version and quit
50
+ --copyright
51
+ prints copyright and quit
52
+
53
+ Tasks
54
+ -----
55
+ These are acceptable tasks:
56
+ all
57
+ Invokes `config', `setup', then `install'.
58
+ Task options for all is same with config.
59
+ config
60
+ Checks and saves configurations.
61
+ show
62
+ Prints current configurations.
63
+ setup
64
+ Compiles ruby extentions.
65
+ install
66
+ Installs files.
67
+ clean
68
+ Removes created files.
69
+ distclean
70
+ Removes all created files.
71
+
72
+ Task Options for CONFIG/ALL
73
+ ---------------------------
74
+
75
+ --prefix=PATH
76
+ a prefix of the installing directory path
77
+ --stdruby=PATH
78
+ the directory for standard ruby libraries
79
+ --siterubycommon=PATH
80
+ the directory for version-independent non-standard
81
+ ruby libraries
82
+ --siteruby=PATH
83
+ the directory for non-standard ruby libraries
84
+ --bindir=PATH
85
+ the directory for commands
86
+ --rbdir=PATH
87
+ the directory for ruby scripts
88
+ --sodir=PATH
89
+ the directory for ruby extentions
90
+ --datadir=PATH
91
+ the directory for shared data
92
+ --rubypath=PATH
93
+ path to set to #! line
94
+ --rubyprog=PATH
95
+ the ruby program using for installation
96
+ --makeprog=NAME
97
+ the make program to compile ruby extentions
98
+ --without-ext
99
+ forces to setup.rb never to compile/install
100
+ ruby extentions.
101
+ --rbconfig=PATH
102
+ your rbconfig.rb to load
103
+
104
+ You can view default values of these options by typing
105
+
106
+ $ ruby setup.rb --help
107
+
108
+
109
+ If there's the directory named "packages",
110
+ You can also use these options:
111
+ --with=NAME,NAME,NAME...
112
+ Package names which you want to install.
113
+ --without=NAME,NAME,NAME...
114
+ Package names which you do not want to install.
115
+
116
+ [NOTE] You can pass options for extconf.rb like this:
117
+
118
+ ruby setup.rb config -- --with-tklib=/usr/lib/libtk-ja.so.8.0
119
+
120
+
121
+ Task Options for INSTALL
122
+ ------------------------
123
+
124
+ --no-harm
125
+ prints what to do and done nothing really.
126
+ --prefix=PATH
127
+ The prefix of the installing directory path.
128
+ This option may help binary package maintainers.
129
+ A default value is an empty string.
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright (C) 2002 Tom Gilbert.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to
7
+ # deal in the Software without restriction, including without limitation the
8
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9
+ # sell copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies of the Software and its documentation and acknowledgment shall be
14
+ # given in the documentation and software packages that this Software was
15
+ # used.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
+ # THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ $VERBOSE=true
25
+
26
+ require 'etc'
27
+ require 'getoptlong'
28
+ require 'fileutils'
29
+
30
+ $version="0.9.9"
31
+ $opts = Hash.new
32
+
33
+ orig_opts = ARGV.dup
34
+
35
+ opts = GetoptLong.new(
36
+ ["--debug", "-d", GetoptLong::NO_ARGUMENT],
37
+ ["--help", "-h", GetoptLong::NO_ARGUMENT],
38
+ ["--trace", "-t", GetoptLong::REQUIRED_ARGUMENT],
39
+ ["--version", "-v", GetoptLong::NO_ARGUMENT]
40
+ )
41
+
42
+ $debug = false
43
+ opts.each {|opt, arg|
44
+ $debug = true if(opt == "--debug")
45
+ $opts[opt.sub(/^-+/, "")] = arg
46
+ }
47
+
48
+ if ($opts["trace"])
49
+ set_trace_func proc { |event, file, line, id, binding, classname|
50
+ if classname.to_s == $opts["trace"]
51
+ printf "TRACE: %8s %s:%-2d %10s %8s\n", event, File.basename(file), line, id, classname
52
+ end
53
+ }
54
+ end
55
+
56
+ begin
57
+ require 'rbot/ircbot'
58
+ rescue LoadError => e
59
+ puts "Error: couldn't find the rbot/ircbot module for loading\n - did you install rbot using install.rb?"
60
+ exit 2
61
+ end
62
+
63
+ if ($opts["version"])
64
+ puts "rbot #{$version}"
65
+ exit 0
66
+ end
67
+
68
+ if ($opts["help"])
69
+ puts "usage: rbot [options] [config directory]"
70
+ puts " -h, --help this message"
71
+ puts " -v, --version version information"
72
+ puts " -d, --debug enable debug messages"
73
+ puts "config directory defaults to ~/.rbot"
74
+ exit 0
75
+ end
76
+
77
+ if(bot = Irc::IrcBot.new(ARGV.shift, :argv => orig_opts))
78
+ # just run the bot
79
+ bot.mainloop
80
+ end
81
+
@@ -0,0 +1,20 @@
1
+ class FigletPlugin < Plugin
2
+ def help(plugin, topic="")
3
+ "figlet [<message>] => print using figlet"
4
+ end
5
+ def privmsg(m)
6
+ case m.params
7
+ when nil
8
+ m.reply "incorrect usage: " + help(m.plugin)
9
+ return
10
+ when (/^-/)
11
+ m.reply "incorrect usage: " + help(m.plugin)
12
+ return
13
+ else
14
+ m.reply Utils.safe_exec("/usr/bin/figlet", "-k", "-f", "mini", m.params)
15
+ return
16
+ end
17
+ end
18
+ end
19
+ plugin = FigletPlugin.new
20
+ plugin.register("figlet")
@@ -0,0 +1,83 @@
1
+ # Author: Michael Brailsford <brailsmt@yahoo.com>
2
+ # aka brailsmt
3
+ # Purpose: To respond to requests for information from the ri command line
4
+ # utility.
5
+
6
+ class RiPlugin < Plugin
7
+
8
+ @@handlers = {
9
+ "ri" => "ri_handler",
10
+ "msgri" => "msgri_handler"
11
+ }
12
+
13
+ #{{{
14
+ def initialize
15
+ super
16
+ @cache = Hash.new
17
+ end
18
+ #}}}
19
+ #{{{
20
+ def privmsg(m)
21
+ if not m.params
22
+ m.reply "uhmm... whatever"
23
+ return
24
+ end
25
+
26
+ meth = self.method(@@handlers[m.plugin])
27
+ meth.call(m)
28
+ end
29
+ #}}}
30
+ #{{{
31
+ def cleanup
32
+ @cache = nil
33
+ end
34
+ #}}}
35
+ #{{{
36
+ def ri_handler(m)
37
+ response = ""
38
+ if @cache[m.params]
39
+ response = @cache[m.params]
40
+ else
41
+ IO.popen("-") {|p|
42
+ if(p)
43
+ response = p.readlines.join "\n"
44
+ @cache[m.params] = response
45
+ else
46
+ $stderr = $stdout
47
+ exec("ri", m.params)
48
+ end
49
+ }
50
+ @cache[m.params] = response
51
+ end
52
+
53
+ @bot.say m.sourcenick, response
54
+ m.reply "Finished \"ri #{m.params}\""
55
+ end
56
+ #}}}
57
+ #{{{
58
+ def msgri_handler(m)
59
+ response = ""
60
+ tell_nick, query = m.params.split()
61
+ if @cache[query]
62
+ response = @cache[query]
63
+ else
64
+ IO.popen("-") {|p|
65
+ if(p)
66
+ response = p.readlines.join "\n"
67
+ @cache[m.params] = response
68
+ else
69
+ $stderr = $stdout
70
+ exec("ri", query)
71
+ end
72
+ }
73
+ @cache[query] = response
74
+ end
75
+
76
+ @bot.say tell_nick, response
77
+ m.reply "Finished telling #{tell_nick} about \"ri #{query}\""
78
+ end
79
+ #}}}
80
+ end
81
+ plugin = RiPlugin.new
82
+ plugin.register("ri")
83
+ plugin.register("msgri")
@@ -0,0 +1,232 @@
1
+ # Author: Michael Brailsford <brailsmt@yahoo.com>
2
+ # aka brailsmt
3
+ # Purpose: Provides the ability to track various tokens that are spoken in a
4
+ # channel.
5
+ # Copyright: 2002 Michael Brailsford. All rights reserved.
6
+ # License: This plugin is licensed under the BSD license. The terms of
7
+ # which follow.
8
+ #
9
+ # Redistribution and use in source and binary forms, with or without
10
+ # modification, are permitted provided that the following conditions
11
+ # are met:
12
+ #
13
+ # 1. Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ #
16
+ # 2. Redistributions in binary form must reproduce the above copyright
17
+ # notice, this list of conditions and the following disclaimer in the
18
+ # documentation and/or other materials provided with the distribution.
19
+
20
+ class StatsPlugin < Plugin
21
+
22
+ @@commands = {
23
+ "stats" => "handle_stats",
24
+ "track" => "handle_track",
25
+ "untrack" => "handle_untrack",
26
+ "listtokens" => "handle_listtokens",
27
+ "rmabuser" => "handle_rmabuser"
28
+ }
29
+
30
+ #{{{
31
+ def initialize
32
+ super
33
+ @listen = true
34
+ @channels = Hash.new
35
+ #check to see if a stats token file already exists for this channel...
36
+ Dir["#{@bot.botclass}/stats/*"].each { |fname|
37
+ channel = File.basename fname
38
+ tokens = Hash.new
39
+ IO.foreach(fname) { |line|
40
+ if line =~ /^(\S+)\s*<=>(.*)/
41
+ tokens[$1] = parse_token_stats $2
42
+ end
43
+ }
44
+ @channels[channel] = tokens
45
+ }
46
+ end
47
+ #}}}
48
+ #{{{
49
+ def cleanup
50
+ @channels = nil
51
+ end
52
+ #}}}
53
+ #{{{
54
+ def help(plugin, topic="")
55
+ "Stats: The stats plugin tracks various tokens from users in the channel. The tokens are only tracked if it is the only thing on a line.\nUsage: stats <token> -- lists the stats for <token>\n [un]track <token> -- Adds or deletes <token> from the list of tokens\n listtokens -- lists the tokens that are currently being tracked"
56
+ end
57
+ #}}}
58
+ #{{{
59
+ def privmsg(m)
60
+ if not m.params and not m.plugin =~ /listtokens/
61
+ m.reply "What a crazy fool! Did you mean |help stats?"
62
+ return
63
+ end
64
+
65
+ meth = self.method(@@commands[m.plugin])
66
+ meth.call(m)
67
+ end
68
+ #}}}
69
+ #{{{
70
+ def save
71
+ Dir.mkdir("#{@bot.botclass}/stats") if not FileTest.directory?("#{@bot.botclass}/stats")
72
+ #save the tokens to a file...
73
+ @channels.each_pair { |channel, tokens|
74
+ if not tokens.empty?
75
+ File.open("#{@bot.botclass}/stats/#{channel}", "w") { |f|
76
+ tokens.each { |token, datahash|
77
+ f.puts "#{token} <=> #{datahash_to_s(datahash)}"
78
+ }
79
+ }
80
+ else
81
+ File.delete "#{@bot.botclass}/stats/#{channel}"
82
+ end
83
+ }
84
+ end
85
+ #}}}
86
+ #{{{
87
+ def listen(m)
88
+ if not m.private?
89
+ tokens = @channels[m.target]
90
+ if not @@commands[m.plugin]
91
+ tokens.each_pair { |key, hsh|
92
+ if not m.message.scan(/#{Regexp.escape(key)}/).empty?
93
+ if hsh[m.sourcenick]
94
+ hsh[m.sourcenick] += 1
95
+ else
96
+ hsh[m.sourcenick] = 1
97
+ end
98
+ end
99
+ }
100
+ end
101
+ end
102
+ #This is the old code {{{
103
+ # if not m.private?
104
+ # tokens = @channels[m.target]
105
+ # hsh = tokens[m.message]
106
+ # if hsh
107
+ # if hsh[m.sourcenick]
108
+ # hsh[m.sourcenick] += 1
109
+ # else
110
+ # hsh[m.sourcenick] = 1
111
+ # end
112
+ # end
113
+ # end }}}
114
+ end
115
+ #}}}
116
+ #The following are helper functions for the plugin {{{
117
+ def datahash_to_s(dhash)
118
+ rv = ""
119
+ dhash.each { |key, val|
120
+ rv << "#{key}:#{val} "
121
+ }
122
+ rv.chomp
123
+ end
124
+
125
+ def parse_token_stats(stats)
126
+ rv = Hash.new
127
+ stats.split(" ").each { |nickstat|
128
+ nick, stat = nickstat.split ":"
129
+ rv[nick] = stat.to_i
130
+ }
131
+ rv
132
+ end
133
+ #}}}
134
+ #The following are handler methods for dealing with each command from IRC {{{
135
+ #{{{
136
+ def handle_stats(m)
137
+ if not m.private?
138
+ total = 0
139
+ tokens = @channels[m.target]
140
+ hsh = tokens[m.params]
141
+ msg1 = ""
142
+ if not hsh.empty?
143
+ sorted = hsh.sort { |i, j| j[1] <=> i[1] }
144
+ sorted.each { |a|
145
+ total += a[1]
146
+ }
147
+
148
+ msg = "Stats for #{m.params}. Said #{total} times. The top sayers are "
149
+ if sorted[0..2]
150
+ msg << "#{sorted[0].join ':'}" if sorted[0]
151
+ msg << ", #{sorted[1].join ':'}" if sorted[1]
152
+ msg << ", and #{sorted[2].join ':'}" if sorted[2]
153
+ msg << "."
154
+
155
+ msg1 << "#{m.sourcenick} has said it "
156
+ if hsh[m.sourcenick]
157
+ msg1 << "#{hsh[m.sourcenick]} times."
158
+ else
159
+ msg1 << "0 times."
160
+ end
161
+ else
162
+ msg << "#{m.params} has not been said yet!"
163
+ end
164
+ @bot.action m.replyto, msg
165
+ @bot.action m.replyto, msg1 if msg1
166
+ else
167
+ m.reply "#{m.params} is not currently being tracked."
168
+ end
169
+ end
170
+ end
171
+ #}}}
172
+ #{{{
173
+ def handle_track(m)
174
+ if not m.private?
175
+ if @channels[m.target]
176
+ tokens = @channels[m.target]
177
+ else
178
+ tokens = Hash.new
179
+ @channels[m.target] = tokens
180
+ end
181
+ tokens[m.params] = Hash.new
182
+ m.reply "now tracking #{m.params}"
183
+ end
184
+ end
185
+ #}}}
186
+ #{{{
187
+ def handle_untrack(m)
188
+ if not m.private?
189
+ toks = @channels[m.target]
190
+ if toks.has_key? m.params
191
+ toks.delete m.params
192
+ m.reply "no longer tracking #{m.params}"
193
+ else
194
+ m.reply "Are your signals crossed? Since when have I tracked that?"
195
+ end
196
+ end
197
+
198
+ toks = nil
199
+ end
200
+ #}}}
201
+ #{{{
202
+ def handle_listtokens(m)
203
+ if not m.private? and not @channels.empty?
204
+ tokens = @channels[m.target]
205
+ unless tokens.empty?
206
+ toks = ""
207
+ tokens.each_key { |k|
208
+ toks << "#{k} "
209
+ }
210
+ @bot.action m.replyto, "is currently keeping stats for: #{toks}"
211
+ else
212
+ @bot.action m.replyto, "is not currently keeping stats for anything"
213
+ end
214
+ elsif not m.private?
215
+ @bot.action m.replyto, "is not currently keeping stats for anything"
216
+ end
217
+ end
218
+ #}}}
219
+ #{{{
220
+ def handle_rmabuser(m)
221
+ m.reply "This feature has not yet been implemented"
222
+ end
223
+ #}}}
224
+ #}}}
225
+
226
+ end
227
+ plugin = StatsPlugin.new
228
+ plugin.register("stats")
229
+ plugin.register("track")
230
+ plugin.register("untrack")
231
+ plugin.register("listtokens")
232
+ #plugin.register("rmabuser")