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
@@ -0,0 +1,71 @@
1
+ require 'cgi'
2
+ begin
3
+ require 'rubyful_soup'
4
+ rescue
5
+ warning "could not load rubyful_soup, urban dictionary disabled"
6
+ warning "please get it from http://www.crummy.com/software/RubyfulSoup/"
7
+ warning "or install it via gem"
8
+ return
9
+ end
10
+ require 'uri/common'
11
+
12
+ class UrbanPlugin < Plugin
13
+
14
+ def help( plugin, topic="")
15
+ "urban [word] [n]. Give the [n]th definition of [word] from urbandictionary.com."
16
+ end
17
+
18
+ def privmsg( m )
19
+
20
+ unless(m.params && m.params.length > 0)
21
+ m.reply "incorrect usage: " + help(m.plugin)
22
+ return
23
+ end
24
+
25
+ paramArray = m.params.split(' ')
26
+ definitionN = 0
27
+ if m.params == 'random' then
28
+ uri = URI.parse( "http://www.urbandictionary.com/random.php" )
29
+ else
30
+ if( paramArray.last.to_i != 0 ) then
31
+ definitionN = paramArray.last.to_i - 1
32
+ query = m.params.chomp( paramArray.last )
33
+ query.rstrip!
34
+ else
35
+ query = m.params
36
+ end
37
+ uri = URI.parse( "http://www.urbandictionary.com/define.php?term=#{ URI.escape query}" )
38
+ end
39
+
40
+ soup = BeautifulSoup.new( @bot.httputil.get_cached( uri ) )
41
+ if titleNavi = soup.find_all( 'td', :attrs => { 'class' => 'def_word' } )[0] then
42
+ title = titleNavi.contents
43
+ results = soup.find_all( 'div', :attrs => { 'class' => 'def_p' } )
44
+ # debug PP.pp(results,'')
45
+ output = Array.new
46
+ if results[definitionN] then
47
+ results[definitionN].p.contents.each { |s| output.push( strip_tags( s.to_s ) ) }
48
+ m.reply "\002#{title}\002 - #{output}"
49
+ else
50
+ m.reply "#{query} does not have #{definitionN + 1} definitions."
51
+ end
52
+ else
53
+ m.reply "#{m.params} not found."
54
+ end
55
+
56
+ end
57
+
58
+ def strip_tags(html)
59
+ html.gsub(/<.+?>/,'').
60
+ gsub(/&amp;/,'&').
61
+ gsub(/&quot;/,'"').
62
+ gsub(/&lt;/,'<').
63
+ gsub(/&gt;/,'>').
64
+ gsub(/&ellip;/,'...').
65
+ gsub(/&apos;/, "'").
66
+ gsub("\n",'')
67
+ end
68
+ end
69
+
70
+ plugin = UrbanPlugin.new
71
+ plugin.register( "urban" )
@@ -1,17 +1,401 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'cgi'
4
+
1
5
  Url = Struct.new("Url", :channel, :nick, :time, :url)
6
+ TITLE_RE = /<\s*?title\s*?>(.+?)<\s*?\/title\s*?>/im
7
+
8
+ UNESCAPE_TABLE = {
9
+ 'raquo' => '>>',
10
+ 'quot' => '"',
11
+ 'micro' => 'u',
12
+ 'copy' => '(c)',
13
+ 'trade' => '(tm)',
14
+ 'reg' => '(R)',
15
+ '#174' => '(R)',
16
+ '#8220' => '"',
17
+ '#8221' => '"',
18
+ '#8212' => '--',
19
+ '#39' => '\'',
20
+ =begin
21
+ # extras codes, for future use...
22
+ 'zwnj' => '&#8204;',
23
+ 'aring' => '\xe5',
24
+ 'gt' => '>',
25
+ 'yen' => '\xa5',
26
+ 'ograve' => '\xf2',
27
+ 'Chi' => '&#935;',
28
+ 'bull' => '&#8226;',
29
+ 'Egrave' => '\xc8',
30
+ 'Ntilde' => '\xd1',
31
+ 'upsih' => '&#978;',
32
+ 'Yacute' => '\xdd',
33
+ 'asymp' => '&#8776;',
34
+ 'radic' => '&#8730;',
35
+ 'otimes' => '&#8855;',
36
+ 'nabla' => '&#8711;',
37
+ 'aelig' => '\xe6',
38
+ 'oelig' => '&#339;',
39
+ 'equiv' => '&#8801;',
40
+ 'Psi' => '&#936;',
41
+ 'auml' => '\xe4',
42
+ 'circ' => '&#710;',
43
+ 'Acirc' => '\xc2',
44
+ 'Epsilon' => '&#917;',
45
+ 'Yuml' => '&#376;',
46
+ 'Eta' => '&#919;',
47
+ 'lt' => '<',
48
+ 'Icirc' => '\xce',
49
+ 'Upsilon' => '&#933;',
50
+ 'ndash' => '&#8211;',
51
+ 'there4' => '&#8756;',
52
+ 'Prime' => '&#8243;',
53
+ 'prime' => '&#8242;',
54
+ 'psi' => '&#968;',
55
+ 'Kappa' => '&#922;',
56
+ 'rsaquo' => '&#8250;',
57
+ 'Tau' => '&#932;',
58
+ 'darr' => '&#8595;',
59
+ 'ocirc' => '\xf4',
60
+ 'lrm' => '&#8206;',
61
+ 'zwj' => '&#8205;',
62
+ 'cedil' => '\xb8',
63
+ 'Ecirc' => '\xca',
64
+ 'not' => '\xac',
65
+ 'amp' => '&',
66
+ 'AElig' => '\xc6',
67
+ 'oslash' => '\xf8',
68
+ 'acute' => '\xb4',
69
+ 'lceil' => '&#8968;',
70
+ 'laquo' => '\xab',
71
+ 'shy' => '\xad',
72
+ 'rdquo' => '&#8221;',
73
+ 'ge' => '&#8805;',
74
+ 'Igrave' => '\xcc',
75
+ 'Ograve' => '\xd2',
76
+ 'euro' => '&#8364;',
77
+ 'dArr' => '&#8659;',
78
+ 'sdot' => '&#8901;',
79
+ 'nbsp' => '\xa0',
80
+ 'lfloor' => '&#8970;',
81
+ 'lArr' => '&#8656;',
82
+ 'Auml' => '\xc4',
83
+ 'larr' => '&#8592;',
84
+ 'Atilde' => '\xc3',
85
+ 'Otilde' => '\xd5',
86
+ 'szlig' => '\xdf',
87
+ 'clubs' => '&#9827;',
88
+ 'diams' => '&#9830;',
89
+ 'agrave' => '\xe0',
90
+ 'Ocirc' => '\xd4',
91
+ 'Iota' => '&#921;',
92
+ 'Theta' => '&#920;',
93
+ 'Pi' => '&#928;',
94
+ 'OElig' => '&#338;',
95
+ 'Scaron' => '&#352;',
96
+ 'frac14' => '\xbc',
97
+ 'egrave' => '\xe8',
98
+ 'sub' => '&#8834;',
99
+ 'iexcl' => '\xa1',
100
+ 'frac12' => '\xbd',
101
+ 'sbquo' => '&#8218;',
102
+ 'ordf' => '\xaa',
103
+ 'sum' => '&#8721;',
104
+ 'prop' => '&#8733;',
105
+ 'Uuml' => '\xdc',
106
+ 'ntilde' => '\xf1',
107
+ 'sup' => '&#8835;',
108
+ 'theta' => '&#952;',
109
+ 'prod' => '&#8719;',
110
+ 'nsub' => '&#8836;',
111
+ 'hArr' => '&#8660;',
112
+ 'rlm' => '&#8207;',
113
+ 'THORN' => '\xde',
114
+ 'infin' => '&#8734;',
115
+ 'yuml' => '\xff',
116
+ 'Mu' => '&#924;',
117
+ 'le' => '&#8804;',
118
+ 'Eacute' => '\xc9',
119
+ 'thinsp' => '&#8201;',
120
+ 'ecirc' => '\xea',
121
+ 'bdquo' => '&#8222;',
122
+ 'Sigma' => '&#931;',
123
+ 'fnof' => '&#402;',
124
+ 'Aring' => '\xc5',
125
+ 'tilde' => '&#732;',
126
+ 'frac34' => '\xbe',
127
+ 'emsp' => '&#8195;',
128
+ 'mdash' => '&#8212;',
129
+ 'uarr' => '&#8593;',
130
+ 'permil' => '&#8240;',
131
+ 'Ugrave' => '\xd9',
132
+ 'rarr' => '&#8594;',
133
+ 'Agrave' => '\xc0',
134
+ 'chi' => '&#967;',
135
+ 'forall' => '&#8704;',
136
+ 'eth' => '\xf0',
137
+ 'rceil' => '&#8969;',
138
+ 'iuml' => '\xef',
139
+ 'gamma' => '&#947;',
140
+ 'lambda' => '&#955;',
141
+ 'harr' => '&#8596;',
142
+ 'rang' => '&#9002;',
143
+ 'xi' => '&#958;',
144
+ 'dagger' => '&#8224;',
145
+ 'divide' => '\xf7',
146
+ 'Ouml' => '\xd6',
147
+ 'image' => '&#8465;',
148
+ 'alefsym' => '&#8501;',
149
+ 'igrave' => '\xec',
150
+ 'otilde' => '\xf5',
151
+ 'Oacute' => '\xd3',
152
+ 'sube' => '&#8838;',
153
+ 'alpha' => '&#945;',
154
+ 'frasl' => '&#8260;',
155
+ 'ETH' => '\xd0',
156
+ 'lowast' => '&#8727;',
157
+ 'Nu' => '&#925;',
158
+ 'plusmn' => '\xb1',
159
+ 'Euml' => '\xcb',
160
+ 'real' => '&#8476;',
161
+ 'sup1' => '\xb9',
162
+ 'sup2' => '\xb2',
163
+ 'sup3' => '\xb3',
164
+ 'Oslash' => '\xd8',
165
+ 'Aacute' => '\xc1',
166
+ 'cent' => '\xa2',
167
+ 'oline' => '&#8254;',
168
+ 'Beta' => '&#914;',
169
+ 'perp' => '&#8869;',
170
+ 'Delta' => '&#916;',
171
+ 'loz' => '&#9674;',
172
+ 'pi' => '&#960;',
173
+ 'iota' => '&#953;',
174
+ 'empty' => '&#8709;',
175
+ 'euml' => '\xeb',
176
+ 'brvbar' => '\xa6',
177
+ 'iacute' => '\xed',
178
+ 'para' => '\xb6',
179
+ 'micro' => '\xb5',
180
+ 'cup' => '&#8746;',
181
+ 'weierp' => '&#8472;',
182
+ 'uuml' => '\xfc',
183
+ 'part' => '&#8706;',
184
+ 'icirc' => '\xee',
185
+ 'delta' => '&#948;',
186
+ 'omicron' => '&#959;',
187
+ 'upsilon' => '&#965;',
188
+ 'Iuml' => '\xcf',
189
+ 'Lambda' => '&#923;',
190
+ 'Xi' => '&#926;',
191
+ 'kappa' => '&#954;',
192
+ 'ccedil' => '\xe7',
193
+ 'Ucirc' => '\xdb',
194
+ 'cap' => '&#8745;',
195
+ 'mu' => '&#956;',
196
+ 'scaron' => '&#353;',
197
+ 'lsquo' => '&#8216;',
198
+ 'isin' => '&#8712;',
199
+ 'Zeta' => '&#918;',
200
+ 'supe' => '&#8839;',
201
+ 'deg' => '\xb0',
202
+ 'and' => '&#8743;',
203
+ 'tau' => '&#964;',
204
+ 'pound' => '\xa3',
205
+ 'hellip' => '&#8230;',
206
+ 'curren' => '\xa4',
207
+ 'int' => '&#8747;',
208
+ 'ucirc' => '\xfb',
209
+ 'rfloor' => '&#8971;',
210
+ 'ensp' => '&#8194;',
211
+ 'crarr' => '&#8629;',
212
+ 'ugrave' => '\xf9',
213
+ 'notin' => '&#8713;',
214
+ 'exist' => '&#8707;',
215
+ 'uArr' => '&#8657;',
216
+ 'cong' => '&#8773;',
217
+ 'Dagger' => '&#8225;',
218
+ 'oplus' => '&#8853;',
219
+ 'times' => '\xd7',
220
+ 'atilde' => '\xe3',
221
+ 'piv' => '&#982;',
222
+ 'ni' => '&#8715;',
223
+ 'Phi' => '&#934;',
224
+ 'lsaquo' => '&#8249;',
225
+ 'Uacute' => '\xda',
226
+ 'Omicron' => '&#927;',
227
+ 'ang' => '&#8736;',
228
+ 'ne' => '&#8800;',
229
+ 'iquest' => '\xbf',
230
+ 'eta' => '&#951;',
231
+ 'yacute' => '\xfd',
232
+ 'Rho' => '&#929;',
233
+ 'uacute' => '\xfa',
234
+ 'Alpha' => '&#913;',
235
+ 'zeta' => '&#950;',
236
+ 'Omega' => '&#937;',
237
+ 'nu' => '&#957;',
238
+ 'sim' => '&#8764;',
239
+ 'sect' => '\xa7',
240
+ 'phi' => '&#966;',
241
+ 'sigmaf' => '&#962;',
242
+ 'macr' => '\xaf',
243
+ 'minus' => '&#8722;',
244
+ 'Ccedil' => '\xc7',
245
+ 'ordm' => '\xba',
246
+ 'epsilon' => '&#949;',
247
+ 'beta' => '&#946;',
248
+ 'rArr' => '&#8658;',
249
+ 'rho' => '&#961;',
250
+ 'aacute' => '\xe1',
251
+ 'eacute' => '\xe9',
252
+ 'omega' => '&#969;',
253
+ 'middot' => '\xb7',
254
+ 'Gamma' => '&#915;',
255
+ 'Iacute' => '\xcd',
256
+ 'lang' => '&#9001;',
257
+ 'spades' => '&#9824;',
258
+ 'rsquo' => '&#8217;',
259
+ 'uml' => '\xa8',
260
+ 'thorn' => '\xfe',
261
+ 'ouml' => '\xf6',
262
+ 'thetasym' => '&#977;',
263
+ 'or' => '&#8744;',
264
+ 'raquo' => '\xbb',
265
+ 'acirc' => '\xe2',
266
+ 'ldquo' => '&#8220;',
267
+ 'hearts' => '&#9829;',
268
+ 'sigma' => '&#963;',
269
+ 'oacute' => '\xf3',
270
+ =end
271
+ }
2
272
 
3
273
  class UrlPlugin < Plugin
4
274
  BotConfig.register BotConfigIntegerValue.new('url.max_urls',
5
275
  :default => 100, :validate => Proc.new{|v| v > 0},
6
276
  :desc => "Maximum number of urls to store. New urls replace oldest ones.")
277
+ BotConfig.register BotConfigBooleanValue.new('url.display_link_info',
278
+ :default => false,
279
+ :desc => "Get the title of any links pasted to the channel and display it (also tells if the link is broken or the site is down)")
7
280
 
8
281
  def initialize
9
282
  super
10
283
  @registry.set_default(Array.new)
11
284
  end
285
+
12
286
  def help(plugin, topic="")
13
287
  "urls [<max>=4] => list <max> last urls mentioned in current channel, urls search [<max>=4] <regexp> => search for matching urls. In a private message, you must specify the channel to query, eg. urls <channel> [max], urls search <channel> [max] <regexp>"
14
288
  end
289
+
290
+ def unescape_title(htmldata)
291
+ # first pass -- let CGI try to attack it...
292
+ htmldata = CGI::unescapeHTML htmldata
293
+
294
+ # second pass -- destroy the remaining bits...
295
+ htmldata.gsub(/(&(.+?);)/) {
296
+ symbol = $2
297
+
298
+ # remove the 0-paddng from unicode integers
299
+ if symbol =~ /#(.+)/
300
+ symbol = "##{$1.to_i.to_s}"
301
+ end
302
+
303
+ # output the symbol's irc-translated character, or a * if it's unknown
304
+ UNESCAPE_TABLE[symbol] || '*'
305
+ }
306
+ end
307
+
308
+ def get_title_from_html(pagedata)
309
+ return unless TITLE_RE.match(pagedata)
310
+ title = $1.strip.gsub(/\s*\n+\s*/, " ")
311
+ title = unescape_title title
312
+ title = title[0..255] if title.length > 255
313
+ "[Link Info] title: #{title}"
314
+ end
315
+
316
+ def read_data_from_response(response, amount)
317
+
318
+ amount_read = 0
319
+ chunks = []
320
+
321
+ response.read_body do |chunk| # read body now
322
+
323
+ amount_read += chunk.length
324
+
325
+ if amount_read > amount
326
+ amount_of_overflow = amount_read - amount
327
+ chunk = chunk[0...-amount_of_overflow]
328
+ end
329
+
330
+ chunks << chunk
331
+
332
+ break if amount_read >= amount
333
+
334
+ end
335
+
336
+ chunks.join('')
337
+
338
+ end
339
+
340
+
341
+ def get_title_for_url(uri_str, depth=10)
342
+ # This god-awful mess is what the ruby http library has reduced me to.
343
+ # Python's HTTP lib is so much nicer. :~(
344
+
345
+ if depth == 0
346
+ raise "Error: Maximum redirects hit."
347
+ end
348
+
349
+ debug "+ Getting #{uri_str}"
350
+ url = URI.parse(uri_str)
351
+ return if url.scheme !~ /https?/
352
+
353
+ title = nil
354
+
355
+ debug "+ connecting to #{url.host}:#{url.port}"
356
+ http = @bot.httputil.get_proxy(url)
357
+ http.start { |http|
358
+ url.path = '/' if url.path == ''
359
+
360
+ http.request_get(url.path, "User-Agent" => "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)") { |response|
361
+
362
+ case response
363
+ when Net::HTTPRedirection, Net::HTTPMovedPermanently then
364
+ # call self recursively if this is a redirect
365
+ redirect_to = response['location'] || './'
366
+ debug "+ redirect location: #{redirect_to.inspect}"
367
+ url = URI.join url.to_s, redirect_to
368
+ debug "+ whee, redirecting to #{url.to_s}!"
369
+ return get_title_for_url(url.to_s, depth-1)
370
+ when Net::HTTPSuccess then
371
+ if response['content-type'] =~ /^text\//
372
+ # since the content is 'text/*' and is small enough to
373
+ # be a webpage, retrieve the title from the page
374
+ debug "+ getting #{url.request_uri}"
375
+ data = read_data_from_response(response, 50000)
376
+ return get_title_from_html(data)
377
+ else
378
+ # content doesn't have title, just display info.
379
+ size = response['content-length'].gsub(/(\d)(?=\d{3}+(?:\.|$))(\d{3}\..*)?/,'\1,\2')
380
+ return "[Link Info] type: #{response['content-type']}#{size ? ", size: #{size} bytes" : ""}"
381
+ end
382
+ when Net::HTTPClientError then
383
+ return "[Link Info] Error getting link (#{response.code} - #{response.message})"
384
+ when Net::HTTPServerError then
385
+ return "[Link Info] Error getting link (#{response.code} - #{response.message})"
386
+ else
387
+ return nil
388
+ end # end of "case response"
389
+
390
+ } # end of request block
391
+ } # end of http start block
392
+
393
+ return title
394
+
395
+ rescue SocketError => e
396
+ return "[Link Info] Error connecting to site (#{e.message})"
397
+ end
398
+
15
399
  def listen(m)
16
400
  return unless m.kind_of?(PrivMessage)
17
401
  return if m.address?
@@ -20,10 +404,21 @@ class UrlPlugin < Plugin
20
404
  if m.message =~ /((f|ht)tps?:\/\/.*?)(?:\s+|$)/
21
405
  urlstr = $1
22
406
  list = @registry[m.target]
407
+
408
+ if @bot.config['url.display_link_info']
409
+ debug "Getting title for #{urlstr}..."
410
+ title = get_title_for_url urlstr
411
+ if title
412
+ m.reply title
413
+ debug "Title found!"
414
+ else
415
+ debug "Title not found!"
416
+ end
417
+ end
418
+
23
419
  # check to see if this url is already listed
24
- return if list.find {|u|
25
- u.url == urlstr
26
- }
420
+ return if list.find {|u| u.url == urlstr }
421
+
27
422
  url = Url.new(m.target, m.sourcenick, Time.new, urlstr)
28
423
  debug "#{list.length} urls so far"
29
424
  if list.length > @bot.config['url.max_urls']
@@ -58,7 +453,7 @@ class UrlPlugin < Plugin
58
453
  string = params[:string]
59
454
  max = 10 if max > 10
60
455
  max = 1 if max < 1
61
- regex = Regexp.new(string)
456
+ regex = Regexp.new(string, Regexp::IGNORECASE)
62
457
  list = @registry[channel].find_all {|url|
63
458
  regex.match(url.url) || regex.match(url.nick)
64
459
  }