rbot 0.9.9 → 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/AUTHORS +8 -0
  2. data/ChangeLog +51 -0
  3. data/INSTALL +4 -0
  4. data/README +1 -0
  5. data/REQUIREMENTS +11 -0
  6. data/TODO +2 -0
  7. data/bin/rbot +21 -2
  8. data/data/rbot/languages/german.lang +4 -1
  9. data/data/rbot/languages/russian.lang +75 -0
  10. data/data/rbot/plugins/autoop.rb +42 -51
  11. data/data/rbot/plugins/bans.rb +205 -0
  12. data/data/rbot/plugins/bash.rb +56 -0
  13. data/data/rbot/plugins/chucknorris.rb +74 -0
  14. data/data/rbot/plugins/chucknorris.yml.gz +0 -0
  15. data/data/rbot/plugins/deepthoughts.rb +95 -0
  16. data/data/rbot/plugins/demauro.rb +95 -0
  17. data/data/rbot/plugins/digg.rb +51 -0
  18. data/data/rbot/plugins/figlet.rb +24 -0
  19. data/data/rbot/plugins/forecast.rb +133 -0
  20. data/data/rbot/plugins/freshmeat.rb +13 -7
  21. data/data/rbot/plugins/google.rb +2 -0
  22. data/data/rbot/plugins/grouphug.rb +36 -0
  23. data/data/rbot/plugins/imdb.rb +92 -0
  24. data/data/rbot/plugins/insult.rb +8 -1
  25. data/data/rbot/plugins/iplookup.rb +227 -0
  26. data/data/rbot/plugins/karma.rb +2 -2
  27. data/data/rbot/plugins/keywords.rb +470 -0
  28. data/data/rbot/plugins/lart.rb +132 -146
  29. data/data/rbot/plugins/lastfm.rb +25 -0
  30. data/data/rbot/plugins/markov.rb +204 -0
  31. data/data/rbot/plugins/math.rb +5 -1
  32. data/data/rbot/plugins/nickserv.rb +71 -11
  33. data/data/rbot/plugins/opme.rb +19 -19
  34. data/data/rbot/plugins/quakeauth.rb +2 -2
  35. data/data/rbot/plugins/quotes.rb +40 -25
  36. data/data/rbot/plugins/remind.rb +1 -1
  37. data/data/rbot/plugins/rot13.rb +2 -2
  38. data/data/rbot/plugins/roulette.rb +49 -15
  39. data/data/rbot/plugins/rss.rb +585 -0
  40. data/data/rbot/plugins/rubyurl.rb +39 -0
  41. data/data/rbot/plugins/seen.rb +2 -1
  42. data/data/rbot/plugins/slashdot.rb +5 -5
  43. data/data/rbot/plugins/spell.rb +5 -0
  44. data/data/rbot/plugins/theyfightcrime.rb +121 -0
  45. data/data/rbot/plugins/threat.rb +55 -0
  46. data/data/rbot/plugins/tinyurl.rb +39 -0
  47. data/data/rbot/plugins/topic.rb +204 -0
  48. data/data/rbot/plugins/urban.rb +71 -0
  49. data/data/rbot/plugins/url.rb +399 -4
  50. data/data/rbot/plugins/wow.rb +123 -0
  51. data/data/rbot/plugins/wserver.rb +1 -1
  52. data/data/rbot/templates/levels.rbot +2 -0
  53. data/lib/rbot/auth.rb +207 -96
  54. data/lib/rbot/channel.rb +5 -5
  55. data/lib/rbot/config.rb +125 -24
  56. data/lib/rbot/dbhash.rb +87 -21
  57. data/lib/rbot/httputil.rb +181 -13
  58. data/lib/rbot/ircbot.rb +525 -179
  59. data/lib/rbot/ircsocket.rb +330 -54
  60. data/lib/rbot/message.rb +66 -23
  61. data/lib/rbot/messagemapper.rb +25 -17
  62. data/lib/rbot/plugins.rb +244 -115
  63. data/lib/rbot/post-clean.rb +1 -0
  64. data/lib/rbot/{post-install.rb → post-config.rb} +1 -1
  65. data/lib/rbot/rbotconfig.rb +29 -14
  66. data/lib/rbot/registry.rb +111 -72
  67. data/lib/rbot/rfc2812.rb +208 -197
  68. data/lib/rbot/timer.rb +4 -0
  69. data/lib/rbot/utils.rb +2 -2
  70. metadata +127 -104
  71. data/data/rbot/plugins/rss.rb.disabled +0 -414
  72. data/lib/rbot/keywords.rb +0 -433
@@ -18,157 +18,143 @@
18
18
 
19
19
  class LartPlugin < Plugin
20
20
 
21
- # Keep a 1:1 relation between commands and handlers
22
- @@handlers = {
23
- "lart" => "handle_lart",
24
- "praise" => "handle_praise",
25
- "addlart" => "handle_addlart",
26
- "rmlart" => "handle_rmlart",
27
- "addpraise" => "handle_addpraise",
28
- "rmpraise" => "handle_rmpraise"
29
- }
21
+ # Keep a 1:1 relation between commands and handlers
22
+ @@handlers = {
23
+ "lart" => "handle_lart",
24
+ "praise" => "handle_praise",
25
+ "addlart" => "handle_addlart",
26
+ "rmlart" => "handle_rmlart",
27
+ "addpraise" => "handle_addpraise",
28
+ "rmpraise" => "handle_rmpraise"
29
+ }
30
30
 
31
31
  def name
32
32
  "lart"
33
33
  end
34
34
 
35
- #{{{
36
- def initialize
37
- super
38
- @larts = Array.new
39
- @praises = Array.new
40
- #read in the lart and praise files
41
- if File.exists? "#{@bot.botclass}/lart/larts"
42
- IO.foreach("#{@bot.botclass}/lart/larts") { |line|
43
- @larts << line.chomp
44
- }
45
- end
46
- if File.exists? "#{@bot.botclass}/lart/praises"
47
- IO.foreach("#{@bot.botclass}/lart/praises") { |line|
48
- @praises << line.chomp
49
- }
50
- end
51
- end
52
- #}}}
53
- #{{{
54
- def cleanup
55
- end
56
- #}}}
57
- #{{{
58
- def save
59
- Dir.mkdir("#{@bot.botclass}/lart") if not FileTest.directory? "#{@bot.botclass}/lart"
60
- File.open("#{@bot.botclass}/lart/larts", "w") { |file|
61
- file.puts @larts
62
- }
63
- File.open("#{@bot.botclass}/lart/praises", "w") { |file|
64
- file.puts @praises
65
- }
66
- end
67
- #}}}
68
- #{{{
69
- def privmsg(m)
70
- if not m.params
71
- m.reply "What a crazy fool! Did you mean |help stats?"
72
- return
73
- end
74
-
75
- meth = self.method(@@handlers[m.plugin])
76
- meth.call(m) if(@bot.auth.allow?(m.plugin, m.source, m.replyto))
77
- end
78
- #}}}
79
- #{{{
80
- def help(plugin, topic="")
81
- "Lart: The lart plugin allows you to punish/praise someone in the channel. You can also add new punishments and new praises as well as delete them. For the curious, LART is an acronym for Luser Attitude Readjustment Tool.\nUsage: punish/lart <nick> <reason> -- punishes <nick> for <reason>. The reason is optional.\n praise <nick> <reason> -- praises <nick> for <reason>. The reason is optional.\n mod[lart|punish|praise] [add|remove] -- Add or remove a lart or praise."
82
- end
83
- #}}}
84
- # The following are command handlers {{{
85
- #{{{
86
- def handle_lart(m)
87
- for_idx = m.params =~ /\s+\bfor\b/
88
- if for_idx
89
- nick = m.params[0, for_idx]
90
- else
91
- nick = m.params
92
- end
93
- lart = @larts[get_msg_idx(@larts.length)]
94
- if lart == nil
95
- m.reply "I dunno any larts"
96
- return
97
- end
98
- if nick == @bot.nick
99
- lart = replace_who lart, m.sourcenick
100
- lart << " for trying to make me lart myself"
101
- else
102
- lart = replace_who lart, nick
103
- lart << m.params[for_idx, m.params.length] if for_idx
104
- end
105
-
106
- @bot.action m.replyto, lart
107
- end
108
- #}}}
109
- #{{{
110
- def handle_praise(m)
111
- for_idx = m.params =~ /\s+\bfor\b/
112
- if for_idx
113
- nick = m.params[0, for_idx]
114
- else
115
- nick = m.params
116
- end
117
- praise = @praises[get_msg_idx(@praises.length)]
118
- if not praise
119
- m.reply "I dunno any praises"
120
- return
121
- end
122
-
123
- if nick == m.sourcenick
124
- praise = @larts[get_msg_idx(@larts.length)]
125
- praise = replace_who praise, nick
126
- else
127
- praise = replace_who praise, nick
128
- praise << m.params.gsub(/#{nick}/, "")
129
- end
130
-
131
- @bot.action m.replyto, praise
132
- end
133
- #}}}
134
- #{{{
135
- def handle_addlart(m)
136
- @larts << m.params
137
- m.okay
138
- end
139
- #}}}
140
- #{{{
141
- def handle_rmlart(m)
142
- @larts.delete m.params
143
- m.okay
144
- end
145
- #}}}
146
- #{{{
147
- def handle_addpraise(m)
148
- @praises << m.params
149
- m.okay
150
- end
151
- #}}}
152
- #{{{
153
- def handle_rmpraise(m)
154
- @praises.delete m.params
155
- m.okay
156
- end
157
- #}}}
158
- #}}}
159
-
160
- # The following are utils for larts/praises {{{
161
- #{{{
162
- def replace_who(msg, nick)
163
- msg.gsub(/<who>/i, "#{nick}")
164
- end
165
- #}}}
166
- #{{{
167
- def get_msg_idx(max)
168
- idx = rand(max)
169
- end
170
- #}}}
171
- #}}}
35
+ def initialize
36
+ super
37
+ @larts = Array.new
38
+ @praises = Array.new
39
+ #read in the lart and praise files
40
+ if File.exists? "#{@bot.botclass}/lart/larts"
41
+ IO.foreach("#{@bot.botclass}/lart/larts") { |line|
42
+ @larts << line.chomp
43
+ }
44
+ end
45
+ if File.exists? "#{@bot.botclass}/lart/praises"
46
+ IO.foreach("#{@bot.botclass}/lart/praises") { |line|
47
+ @praises << line.chomp
48
+ }
49
+ end
50
+ end
51
+
52
+ def cleanup
53
+ end
54
+
55
+ def save
56
+ Dir.mkdir("#{@bot.botclass}/lart") if not FileTest.directory? "#{@bot.botclass}/lart"
57
+ # TODO implement safe saving here too
58
+ File.open("#{@bot.botclass}/lart/larts", "w") { |file|
59
+ file.puts @larts
60
+ }
61
+ File.open("#{@bot.botclass}/lart/praises", "w") { |file|
62
+ file.puts @praises
63
+ }
64
+ end
65
+
66
+ def privmsg(m)
67
+ if not m.params
68
+ m.reply "What a crazy fool! Did you mean |help stats?"
69
+ return
70
+ end
71
+
72
+ meth = self.method(@@handlers[m.plugin])
73
+ meth.call(m) if(@bot.auth.allow?(m.plugin, m.source, m.replyto))
74
+ end
75
+
76
+ def help(plugin, topic="")
77
+ "Lart: The lart plugin allows you to lart/praise someone in the channel. You can also add new larts and new praises as well as delete them. For the curious, LART is an acronym for Luser Attitude Readjustment Tool. Usage: lart <who> [<reason>] -- larts <who> for <reason>. praise <who> [<reason>] -- praises <who> for <reason>. [add|rm][lart|praise] -- Add or remove a lart or praise."
78
+ end
79
+
80
+ # The following are command handler
81
+
82
+ def handle_lart(m)
83
+ for_idx = m.params =~ /\s+\bfor\b/
84
+ if for_idx
85
+ nick = m.params[0, for_idx]
86
+ else
87
+ nick = m.params
88
+ end
89
+ lart = @larts[get_msg_idx(@larts.length)]
90
+ if lart == nil
91
+ m.reply "I dunno any larts"
92
+ return
93
+ end
94
+ if nick == @bot.nick
95
+ lart = replace_who lart, m.sourcenick
96
+ lart << " for trying to make me lart myself"
97
+ else
98
+ lart = replace_who lart, nick
99
+ lart << m.params[for_idx, m.params.length] if for_idx
100
+ end
101
+
102
+ @bot.action m.replyto, lart
103
+ end
104
+
105
+ def handle_praise(m)
106
+ for_idx = m.params =~ /\s+\bfor\b/
107
+ if for_idx
108
+ nick = m.params[0, for_idx]
109
+ else
110
+ nick = m.params
111
+ end
112
+ praise = @praises[get_msg_idx(@praises.length)]
113
+ if not praise
114
+ m.reply "I dunno any praises"
115
+ return
116
+ end
117
+
118
+ if nick == m.sourcenick
119
+ praise = @larts[get_msg_idx(@larts.length)]
120
+ praise = replace_who praise, nick
121
+ else
122
+ praise = replace_who praise, nick
123
+ praise << m.params.gsub("#{nick}", "")
124
+ end
125
+
126
+ @bot.action m.replyto, praise
127
+ end
128
+
129
+ def handle_addlart(m)
130
+ @larts << m.params
131
+ m.okay
132
+ end
133
+
134
+ def handle_rmlart(m)
135
+ @larts.delete m.params
136
+ m.okay
137
+ end
138
+
139
+ def handle_addpraise(m)
140
+ @praises << m.params
141
+ m.okay
142
+ end
143
+
144
+ def handle_rmpraise(m)
145
+ @praises.delete m.params
146
+ m.okay
147
+ end
148
+
149
+ # The following are utils for larts/praises
150
+ def replace_who(msg, nick)
151
+ msg.gsub(/<who>/i, "#{nick}")
152
+ end
153
+
154
+ def get_msg_idx(max)
155
+ idx = rand(max)
156
+ end
157
+
172
158
  end
173
159
  plugin = LartPlugin.new
174
160
  plugin.register("lart")
@@ -0,0 +1,25 @@
1
+ require 'open-uri'
2
+
3
+ # plugin submitted by Jeremy Voorhis (jvoorhis)
4
+
5
+ class LastFmPlugin < Plugin
6
+ def help(plugin, topic="")
7
+ "lastfm <function> <user> => lastfm data for <user> on last.fm where <function> in [recenttracks, topartists, topalbums, toptracks, tags, friends, neighbors]"
8
+ end
9
+
10
+ def do_lastfm (m, params)
11
+ begin
12
+ if params[:action] == "neighbors" || params[:action] == "neighbours" then
13
+ params[:action]="neighbours"
14
+ end
15
+ data = open("http://ws.audioscrobbler.com/1.0/user/#{params[:user]}/#{params[:action]}.txt")
16
+ m.reply "#{params[:action]} for #{params[:user]}:"
17
+ m.reply data.to_a[0..3].map{|l| l.split(',')[-1].chomp}.join(", ")
18
+ rescue
19
+ m.reply "could not find #{params[:action]} for #{params[:user]} (is #{params[:user]} a user?)"
20
+ end
21
+ end
22
+ end
23
+
24
+ plugin = LastFmPlugin.new
25
+ plugin.map 'lastfm :action :user', :action => 'do_lastfm'
@@ -0,0 +1,204 @@
1
+ class MarkovPlugin < Plugin
2
+ def initialize
3
+ super
4
+ @registry.set_default([])
5
+ @registry['enabled'] = false unless @registry.has_key?('enabled')
6
+ @lastline = false
7
+ end
8
+
9
+ def generate_string(word1, word2)
10
+ # limit to max of 50 words
11
+ output = word1 + " " + word2
12
+
13
+ # try to avoid :nonword in the first iteration
14
+ wordlist = @registry["#{word1} #{word2}"]
15
+ wordlist.delete(:nonword)
16
+ if not wordlist.empty?
17
+ word3 = wordlist[rand(wordlist.length)]
18
+ output = output + " " + word3
19
+ word1, word2 = word2, word3
20
+ end
21
+
22
+ 49.times do
23
+ wordlist = @registry["#{word1} #{word2}"]
24
+ break if wordlist.empty?
25
+ word3 = wordlist[rand(wordlist.length)]
26
+ break if word3 == :nonword
27
+ output = output + " " + word3
28
+ word1, word2 = word2, word3
29
+ end
30
+ return output
31
+ end
32
+
33
+ def help(plugin, topic="")
34
+ "markov plugin: listens to chat to build a markov chain, with which it can (perhaps) attempt to (inanely) contribute to 'discussion'. Sort of.. Will get a *lot* better after listening to a lot of chat. usage: 'markov' to attempt to say something relevant to the last line of chat, if it can. other options to markov: 'ignore' => ignore a hostmask (accept no input), 'status' => show current status, 'probability' => set the % chance of rbot responding to input, 'chat' => try and say something intelligent, 'chat about <foo> <bar>' => riff on a word pair (if possible)"
35
+ end
36
+
37
+ def clean_str(s)
38
+ str = s.dup
39
+ str.gsub!(/^\S+[:,;]/, "")
40
+ str.gsub!(/\s{2,}/, ' ') # fix for two or more spaces
41
+ return str.strip
42
+ end
43
+
44
+ def probability?
45
+ prob = @registry['probability']
46
+ prob = 25 if prob.kind_of? Array;
47
+ prob = 0 if prob < 0
48
+ prob = 100 if prob > 100
49
+ return prob
50
+ end
51
+
52
+ def status(m,params)
53
+ enabled = @registry['enabled']
54
+ if (enabled)
55
+ m.reply "markov is currently enabled, #{probability?}% chance of chipping in"
56
+ else
57
+ m.reply "markov is currently disabled"
58
+ end
59
+ end
60
+
61
+ def ignore?(user=nil)
62
+ @registry['ignore_users'].each do |mask|
63
+ return true if Irc.netmaskmatch mask, user
64
+ end
65
+ return false
66
+ end
67
+
68
+ def ignore(m, params)
69
+ if @registry['ignore_users'].nil?
70
+ @registry['ignore_users'] = []
71
+ end
72
+ action = params[:action]
73
+ user = params[:option]
74
+ case action
75
+ when 'remove':
76
+ if @registry['ignore_users'].include? user
77
+ s = @registry['ignore_users']
78
+ s.delete user
79
+ @registry['ignore_users'] = s
80
+ m.reply "#{user} removed"
81
+ else
82
+ m.reply "not found in list"
83
+ end
84
+ when 'add':
85
+ if user
86
+ if @registry['ignore_users'].include?(user)
87
+ m.reply "#{user} already in list"
88
+ else
89
+ @registry['ignore_users'] = @registry['ignore_users'].push user
90
+ m.reply "#{user} added to markov ignore list"
91
+ end
92
+ else
93
+ m.reply "give the name of a person to ignore"
94
+ end
95
+ when 'list':
96
+ m.reply "I'm ignoring #{@registry['ignore_users'].join(", ")}"
97
+ else
98
+ m.reply "have markov ignore the input from a hostmask. usage: markov ignore add <mask>; markov ignore remove <mask>; markov ignore list"
99
+ end
100
+ end
101
+
102
+ def enable(m, params)
103
+ @registry['enabled'] = true
104
+ m.okay
105
+ end
106
+
107
+ def probability(m, params)
108
+ @registry['probability'] = params[:probability].to_i
109
+ m.okay
110
+ end
111
+
112
+ def disable(m, params)
113
+ @registry['enabled'] = false
114
+ m.okay
115
+ end
116
+
117
+ def should_talk
118
+ return false unless @registry['enabled']
119
+ prob = probability?
120
+ return true if prob > rand(100)
121
+ return false
122
+ end
123
+
124
+ def delay
125
+ 1 + rand(5)
126
+ end
127
+
128
+ def random_markov(m, message)
129
+ return unless should_talk
130
+
131
+ word1, word2 = message.split(/\s+/)
132
+ line = generate_string(word1, word2)
133
+ return unless line
134
+ return if line == message
135
+ @bot.timer.add_once(delay, m) {|m|
136
+ m.reply line
137
+ }
138
+ end
139
+
140
+ def chat(m, params)
141
+ line = generate_string(params[:seed1], params[:seed2])
142
+ if line != "#{params[:seed1]} #{params[:seed2]}"
143
+ m.reply line
144
+ else
145
+ m.reply "I can't :("
146
+ end
147
+ end
148
+
149
+ def rand_chat(m, params)
150
+ # pick a random pair from the db and go from there
151
+ word1, word2 = :nonword, :nonword
152
+ output = Array.new
153
+ 50.times do
154
+ wordlist = @registry["#{word1} #{word2}"]
155
+ break if wordlist.empty?
156
+ word3 = wordlist[rand(wordlist.length)]
157
+ break if word3 == :nonword
158
+ output << word3
159
+ word1, word2 = word2, word3
160
+ end
161
+ if output.length > 1
162
+ m.reply output.join(" ")
163
+ else
164
+ m.reply "I can't :("
165
+ end
166
+ end
167
+
168
+ def listen(m)
169
+ return unless m.kind_of?(PrivMessage) && m.public?
170
+ return if m.address?
171
+ return if ignore? m.source
172
+
173
+ # in channel message, the kind we are interested in
174
+ message = clean_str m.message
175
+
176
+ if m.action?
177
+ message = "#{m.sourcenick} #{message}"
178
+ end
179
+
180
+ wordlist = message.split(/\s+/)
181
+ return unless wordlist.length >= 2
182
+ @lastline = message
183
+ word1, word2 = :nonword, :nonword
184
+ wordlist.each do |word3|
185
+ @registry["#{word1} #{word2}"] = @registry["#{word1} #{word2}"].push(word3)
186
+ word1, word2 = word2, word3
187
+ end
188
+ @registry["#{word1} #{word2}"] = @registry["#{word1} #{word2}"].push(:nonword)
189
+
190
+ return if m.replied?
191
+ random_markov(m, message)
192
+ end
193
+ end
194
+ plugin = MarkovPlugin.new
195
+ plugin.map 'markov ignore :action :option', :action => "ignore"
196
+ plugin.map 'markov ignore :action', :action => "ignore"
197
+ plugin.map 'markov ignore', :action => "ignore"
198
+ plugin.map 'markov enable', :action => "enable"
199
+ plugin.map 'markov disable', :action => "disable"
200
+ plugin.map 'markov status', :action => "status"
201
+ plugin.map 'chat about :seed1 :seed2', :action => "chat"
202
+ plugin.map 'chat', :action => "rand_chat"
203
+ plugin.map 'markov probability :probability', :action => "probability",
204
+ :requirements => {:probability => /^\d+%?$/}