rbot 0.9.14 → 0.9.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (368) hide show
  1. data/AUTHORS +6 -2
  2. data/REQUIREMENTS +7 -1
  3. data/Rakefile +10 -32
  4. data/bin/rbot +6 -1
  5. data/bin/svnwatch-postcommit-hook +68 -0
  6. data/data/rbot/contrib/plugins/stats.rb +3 -3
  7. data/data/rbot/contrib/plugins/vandale.rb +1 -1
  8. data/data/rbot/filters/rss.rb +72 -0
  9. data/data/rbot/languages/finnish.lang +50 -0
  10. data/data/rbot/plugins/alias.rb +6 -6
  11. data/data/rbot/plugins/autorejoin.rb +41 -2
  12. data/data/rbot/plugins/bans.rb +100 -6
  13. data/data/rbot/plugins/bash.rb +9 -4
  14. data/data/rbot/plugins/cal.rb +1 -1
  15. data/data/rbot/plugins/chucknorris.rb +6 -6
  16. data/data/rbot/plugins/debugger.rb +7 -3
  17. data/data/rbot/plugins/deepthoughts.rb +1 -1
  18. data/data/rbot/plugins/delicious.rb +6 -2
  19. data/data/rbot/plugins/dice.rb +7 -7
  20. data/data/rbot/plugins/dict.rb +4 -3
  21. data/data/rbot/plugins/dictclient.rb +17 -13
  22. data/data/rbot/plugins/digg.rb +3 -3
  23. data/data/rbot/plugins/eightball.rb +1 -1
  24. data/data/rbot/plugins/factoids.rb +13 -4
  25. data/data/rbot/plugins/figlet.rb +4 -4
  26. data/data/rbot/plugins/forecast.rb +3 -3
  27. data/data/rbot/plugins/fortune.rb +14 -8
  28. data/data/rbot/plugins/freshmeat.rb +2 -2
  29. data/data/rbot/plugins/games/azgame.rb +72 -19
  30. data/data/rbot/plugins/games/hangman.rb +499 -0
  31. data/data/rbot/plugins/games/quiz.rb +15 -13
  32. data/data/rbot/plugins/games/roshambo.rb +1 -1
  33. data/data/rbot/plugins/games/roulette.rb +4 -4
  34. data/data/rbot/plugins/games/shiritori.rb +31 -31
  35. data/data/rbot/plugins/games/uno.rb +28 -6
  36. data/data/rbot/plugins/games/wheelfortune.rb +1 -3
  37. data/data/rbot/plugins/geoip.rb +83 -28
  38. data/data/rbot/plugins/googlefight.rb +64 -0
  39. data/data/rbot/plugins/greet.rb +45 -0
  40. data/data/rbot/plugins/grouphug.rb +40 -12
  41. data/data/rbot/plugins/imdb.rb +4 -4
  42. data/data/rbot/plugins/insult.rb +2 -2
  43. data/data/rbot/plugins/karma.rb +6 -5
  44. data/data/rbot/plugins/keywords.rb +26 -22
  45. data/data/rbot/plugins/lart.rb +5 -6
  46. data/data/rbot/plugins/lastfm.rb +488 -125
  47. data/data/rbot/plugins/lib_spotify.rb +84 -0
  48. data/data/rbot/plugins/linkbot.rb +1 -1
  49. data/data/rbot/plugins/markov.rb +567 -78
  50. data/data/rbot/plugins/math.rb +3 -3
  51. data/data/rbot/plugins/modes.rb +1 -1
  52. data/data/rbot/plugins/nickrecover.rb +1 -1
  53. data/data/rbot/plugins/nickserv.rb +7 -7
  54. data/data/rbot/plugins/note.rb +55 -0
  55. data/data/rbot/plugins/nslookup.rb +2 -2
  56. data/data/rbot/plugins/quakeauth.rb +4 -4
  57. data/data/rbot/plugins/quotes.rb +53 -19
  58. data/data/rbot/plugins/reaction.rb +76 -19
  59. data/data/rbot/plugins/remind.rb +3 -96
  60. data/data/rbot/plugins/ri.rb +1 -1
  61. data/data/rbot/plugins/rot13.rb +1 -1
  62. data/data/rbot/plugins/rss.rb +296 -190
  63. data/data/rbot/plugins/salut.rb +8 -8
  64. data/data/rbot/plugins/script.rb +48 -11
  65. data/data/rbot/plugins/search.rb +124 -28
  66. data/data/rbot/plugins/seen.rb +162 -31
  67. data/data/rbot/plugins/shortenurls.rb +1 -1
  68. data/data/rbot/plugins/slashdot.rb +19 -6
  69. data/data/rbot/plugins/spotify.rb +78 -0
  70. data/data/rbot/plugins/theyfightcrime.rb +10 -10
  71. data/data/rbot/plugins/time.rb +2 -2
  72. data/data/rbot/plugins/translator.rb +161 -85
  73. data/data/rbot/plugins/tube.rb +2 -2
  74. data/data/rbot/plugins/tumblr.rb +143 -0
  75. data/data/rbot/plugins/twitter.rb +25 -6
  76. data/data/rbot/plugins/urban.rb +6 -4
  77. data/data/rbot/plugins/url.rb +49 -10
  78. data/data/rbot/plugins/weather.rb +6 -6
  79. data/data/rbot/plugins/wserver.rb +5 -5
  80. data/data/rbot/plugins/youtube.rb +12 -12
  81. data/data/rbot/templates/lart/larts-italian +1 -1
  82. data/launch_here.rb +68 -0
  83. data/lib/rbot/botuser.rb +1 -1
  84. data/lib/rbot/compat19.rb +70 -0
  85. data/lib/rbot/config.rb +8 -6
  86. data/lib/rbot/core/auth.rb +37 -21
  87. data/lib/rbot/core/basics.rb +33 -2
  88. data/lib/rbot/core/config.rb +24 -17
  89. data/lib/rbot/core/filters_ui.rb +2 -2
  90. data/lib/rbot/core/irclog.rb +20 -11
  91. data/lib/rbot/core/remote.rb +9 -9
  92. data/lib/rbot/core/unicode.rb +4 -0
  93. data/lib/rbot/core/userdata.rb +16 -1
  94. data/lib/rbot/core/utils/extends.rb +76 -0
  95. data/lib/rbot/core/utils/filters.rb +47 -0
  96. data/lib/rbot/core/utils/httputil.rb +36 -26
  97. data/lib/rbot/core/utils/parse_time.rb +193 -0
  98. data/lib/rbot/core/utils/utils.rb +81 -56
  99. data/lib/rbot/core/utils/wordlist.rb +66 -0
  100. data/lib/rbot/core/wordlist_ui.rb +27 -0
  101. data/lib/rbot/irc.rb +59 -19
  102. data/lib/rbot/ircbot.rb +190 -58
  103. data/lib/rbot/ircsocket.rb +14 -8
  104. data/lib/rbot/language.rb +4 -3
  105. data/lib/rbot/load-gettext.rb +22 -9
  106. data/lib/rbot/message.rb +89 -18
  107. data/lib/rbot/messagemapper.rb +71 -19
  108. data/lib/rbot/plugins.rb +112 -44
  109. data/lib/rbot/{registry.rb → registry/bdb.rb} +226 -22
  110. data/lib/rbot/registry/tc.rb +531 -0
  111. data/lib/rbot/rfc2812.rb +33 -8
  112. data/lib/rbot/timer.rb +12 -20
  113. data/po/en_US/rbot-autorejoin.po +3 -0
  114. data/po/en_US/rbot-azgame.po +51 -43
  115. data/po/en_US/rbot-bash.po +15 -0
  116. data/po/en_US/rbot-dictclient.po +20 -20
  117. data/po/en_US/rbot-factoids.po +9 -9
  118. data/po/en_US/rbot-geoip.po +0 -0
  119. data/po/en_US/rbot-googlefight.po +24 -0
  120. data/po/en_US/rbot-grouphug.po +4 -4
  121. data/po/en_US/rbot-hangman.po +114 -0
  122. data/po/en_US/rbot-keywords.po +3 -3
  123. data/po/en_US/rbot-lastfm.po +268 -70
  124. data/po/en_US/rbot-markov.po +73 -2
  125. data/po/en_US/rbot-quotes.po +21 -21
  126. data/po/en_US/rbot-rss.po +6 -2
  127. data/po/en_US/rbot-script.po +3 -0
  128. data/po/en_US/rbot-seen.po +72 -0
  129. data/po/en_US/rbot-spell.po +2 -2
  130. data/po/en_US/rbot-translator.po +13 -13
  131. data/po/en_US/rbot-twitter.po +3 -3
  132. data/po/en_US/rbot-uno.po +131 -114
  133. data/po/en_US/rbot-wall.po +12 -13
  134. data/po/en_US/rbot-wheelfortune.po +41 -41
  135. data/po/en_US/rbot.po +254 -194
  136. data/po/fi/rbot-alias.po +82 -0
  137. data/po/fi/rbot-autoop.po +0 -0
  138. data/po/fi/rbot-autorejoin.po +20 -0
  139. data/po/fi/rbot-azgame.po +194 -0
  140. data/po/fi/rbot-bans.po +0 -0
  141. data/po/fi/rbot-bash.po +32 -0
  142. data/po/fi/rbot-botsnack.po +0 -0
  143. data/po/fi/rbot-cal.po +20 -0
  144. data/po/fi/rbot-chanserv.po +0 -0
  145. data/po/fi/rbot-chucknorris.po +0 -0
  146. data/po/fi/rbot-debugger.po +0 -0
  147. data/po/fi/rbot-deepthoughts.po +0 -0
  148. data/po/fi/rbot-delicious.po +0 -0
  149. data/po/fi/rbot-dice.po +0 -0
  150. data/po/fi/rbot-dict.po +0 -0
  151. data/po/fi/rbot-dictclient.po +111 -0
  152. data/po/fi/rbot-digg.po +0 -0
  153. data/po/fi/rbot-eightball.po +0 -0
  154. data/po/fi/rbot-excuse.po +0 -0
  155. data/po/fi/rbot-factoids.po +107 -0
  156. data/po/fi/rbot-figlet.po +36 -0
  157. data/po/fi/rbot-fish.po +0 -0
  158. data/po/fi/rbot-forecast.po +0 -0
  159. data/po/fi/rbot-fortune.po +0 -0
  160. data/po/fi/rbot-freshmeat.po +0 -0
  161. data/po/fi/rbot-geoip.po +0 -0
  162. data/po/fi/rbot-googlefight.po +24 -0
  163. data/po/fi/rbot-grouphug.po +35 -0
  164. data/po/fi/rbot-hangman.po +121 -0
  165. data/po/fi/rbot-hl2.po +0 -0
  166. data/po/fi/rbot-host.po +20 -0
  167. data/po/fi/rbot-imdb.po +0 -0
  168. data/po/fi/rbot-insult.po +0 -0
  169. data/po/fi/rbot-iplookup.po +0 -0
  170. data/po/fi/rbot-karma.po +0 -0
  171. data/po/fi/rbot-keywords.po +24 -0
  172. data/po/fi/rbot-lart.po +0 -0
  173. data/po/fi/rbot-lastfm.po +377 -0
  174. data/po/fi/rbot-linkbot.po +0 -0
  175. data/po/fi/rbot-markov.po +91 -0
  176. data/po/fi/rbot-math.po +0 -0
  177. data/po/fi/rbot-modes.po +0 -0
  178. data/po/fi/rbot-nickrecover.po +36 -0
  179. data/po/fi/rbot-nickserv.po +104 -0
  180. data/po/fi/rbot-nslookup.po +0 -0
  181. data/po/fi/rbot-quakeauth.po +0 -0
  182. data/po/fi/rbot-quiz.po +0 -0
  183. data/po/fi/rbot-quotes.po +108 -0
  184. data/po/fi/rbot-reaction.po +0 -0
  185. data/po/fi/rbot-remind.po +0 -0
  186. data/po/fi/rbot-remotectl.po +0 -0
  187. data/po/fi/rbot-ri.po +0 -0
  188. data/po/fi/rbot-roshambo.po +0 -0
  189. data/po/fi/rbot-rot13.po +0 -0
  190. data/po/fi/rbot-roulette.po +0 -0
  191. data/po/fi/rbot-rss.po +24 -0
  192. data/po/fi/rbot-salut.po +0 -0
  193. data/po/fi/rbot-script.po +20 -0
  194. data/po/fi/rbot-search.po +0 -0
  195. data/po/fi/rbot-seen.po +92 -0
  196. data/po/fi/rbot-shiritori.po +102 -0
  197. data/po/fi/rbot-shortenurls.po +0 -0
  198. data/po/fi/rbot-slashdot.po +0 -0
  199. data/po/fi/rbot-spell.po +54 -0
  200. data/po/fi/rbot-theyfightcrime.po +0 -0
  201. data/po/fi/rbot-threat.po +0 -0
  202. data/po/fi/rbot-time.po +0 -0
  203. data/po/fi/rbot-topic.po +0 -0
  204. data/po/fi/rbot-translator.po +77 -0
  205. data/po/fi/rbot-tube.po +0 -0
  206. data/po/fi/rbot-twitter.po +24 -0
  207. data/po/fi/rbot-uno.po +529 -0
  208. data/po/fi/rbot-urban.po +0 -0
  209. data/po/fi/rbot-url.po +0 -0
  210. data/po/fi/rbot-usermodes.po +0 -0
  211. data/po/fi/rbot-wall.po +32 -0
  212. data/po/fi/rbot-weather.po +0 -0
  213. data/po/fi/rbot-wheelfortune.po +205 -0
  214. data/po/fi/rbot-wow.po +0 -0
  215. data/po/fi/rbot-wserver.po +0 -0
  216. data/po/fi/rbot-youtube.po +58 -0
  217. data/po/fi/rbot.po +1152 -0
  218. data/po/fr/rbot-autorejoin.po +3 -0
  219. data/po/fr/rbot-azgame.po +51 -43
  220. data/po/fr/rbot-bash.po +15 -0
  221. data/po/fr/rbot-dictclient.po +20 -20
  222. data/po/fr/rbot-factoids.po +9 -9
  223. data/po/fr/rbot-geoip.po +0 -0
  224. data/po/fr/rbot-googlefight.po +24 -0
  225. data/po/fr/rbot-grouphug.po +4 -4
  226. data/po/fr/rbot-hangman.po +114 -0
  227. data/po/fr/rbot-keywords.po +3 -3
  228. data/po/fr/rbot-lastfm.po +268 -70
  229. data/po/fr/rbot-markov.po +74 -2
  230. data/po/fr/rbot-quotes.po +21 -21
  231. data/po/fr/rbot-rss.po +6 -2
  232. data/po/fr/rbot-script.po +3 -0
  233. data/po/fr/rbot-seen.po +72 -0
  234. data/po/fr/rbot-spell.po +2 -2
  235. data/po/fr/rbot-translator.po +13 -13
  236. data/po/fr/rbot-twitter.po +3 -3
  237. data/po/fr/rbot-uno.po +132 -114
  238. data/po/fr/rbot-wall.po +8 -9
  239. data/po/fr/rbot-wheelfortune.po +41 -41
  240. data/po/fr/rbot.po +268 -197
  241. data/po/it/rbot-autorejoin.po +3 -0
  242. data/po/it/rbot-azgame.po +50 -42
  243. data/po/it/rbot-bash.po +15 -0
  244. data/po/it/rbot-dictclient.po +20 -20
  245. data/po/it/rbot-factoids.po +9 -9
  246. data/po/it/rbot-geoip.po +0 -0
  247. data/po/it/rbot-googlefight.po +24 -0
  248. data/po/it/rbot-grouphug.po +4 -4
  249. data/po/it/rbot-hangman.po +114 -0
  250. data/po/it/rbot-keywords.po +3 -3
  251. data/po/it/rbot-lastfm.po +268 -70
  252. data/po/it/rbot-markov.po +75 -3
  253. data/po/it/rbot-quotes.po +21 -21
  254. data/po/it/rbot-rss.po +7 -3
  255. data/po/it/rbot-script.po +19 -0
  256. data/po/it/rbot-seen.po +72 -0
  257. data/po/it/rbot-spell.po +2 -2
  258. data/po/it/rbot-translator.po +13 -13
  259. data/po/it/rbot-twitter.po +3 -3
  260. data/po/it/rbot-uno.po +137 -116
  261. data/po/it/rbot-wall.po +8 -9
  262. data/po/it/rbot-wheelfortune.po +41 -41
  263. data/po/it/rbot.po +265 -208
  264. data/po/ja/rbot-autorejoin.po +3 -0
  265. data/po/ja/rbot-azgame.po +51 -43
  266. data/po/ja/rbot-bash.po +15 -0
  267. data/po/ja/rbot-dictclient.po +20 -20
  268. data/po/ja/rbot-factoids.po +9 -9
  269. data/po/ja/rbot-geoip.po +0 -0
  270. data/po/ja/rbot-googlefight.po +24 -0
  271. data/po/ja/rbot-grouphug.po +4 -4
  272. data/po/ja/rbot-hangman.po +114 -0
  273. data/po/ja/rbot-keywords.po +3 -3
  274. data/po/ja/rbot-lastfm.po +268 -70
  275. data/po/ja/rbot-markov.po +73 -2
  276. data/po/ja/rbot-quotes.po +21 -21
  277. data/po/ja/rbot-rss.po +6 -2
  278. data/po/ja/rbot-script.po +3 -0
  279. data/po/ja/rbot-seen.po +72 -0
  280. data/po/ja/rbot-spell.po +2 -2
  281. data/po/ja/rbot-translator.po +13 -13
  282. data/po/ja/rbot-twitter.po +3 -3
  283. data/po/ja/rbot-uno.po +131 -114
  284. data/po/ja/rbot-wall.po +8 -9
  285. data/po/ja/rbot-wheelfortune.po +41 -41
  286. data/po/ja/rbot.po +248 -192
  287. data/po/rbot-alias.pot +2 -2
  288. data/po/rbot-autorejoin.pot +21 -0
  289. data/po/rbot-azgame.pot +51 -43
  290. data/po/rbot-bash.pot +33 -0
  291. data/po/rbot-cal.pot +2 -2
  292. data/po/rbot-dictclient.pot +21 -21
  293. data/po/rbot-factoids.pot +10 -10
  294. data/po/rbot-figlet.pot +2 -2
  295. data/po/rbot-geoip.pot +0 -0
  296. data/po/rbot-googlefight.pot +25 -0
  297. data/po/rbot-grouphug.pot +6 -6
  298. data/po/rbot-hangman.pot +115 -0
  299. data/po/rbot-host.pot +2 -2
  300. data/po/rbot-keywords.pot +4 -4
  301. data/po/rbot-lastfm.pot +270 -72
  302. data/po/rbot-markov.pot +74 -3
  303. data/po/rbot-nickrecover.pot +2 -2
  304. data/po/rbot-nickserv.pot +2 -2
  305. data/po/rbot-quotes.pot +22 -22
  306. data/po/rbot-rss.pot +7 -3
  307. data/po/rbot-script.pot +21 -0
  308. data/po/rbot-seen.pot +90 -0
  309. data/po/rbot-shiritori.pot +2 -2
  310. data/po/rbot-spell.pot +3 -3
  311. data/po/rbot-translator.pot +14 -14
  312. data/po/rbot-twitter.pot +4 -4
  313. data/po/rbot-uno.pot +132 -115
  314. data/po/rbot-wall.pot +2 -2
  315. data/po/rbot-wheelfortune.pot +42 -42
  316. data/po/rbot-youtube.pot +2 -2
  317. data/po/rbot.pot +249 -193
  318. data/po/zh_CN/rbot-autorejoin.po +3 -0
  319. data/po/zh_CN/rbot-azgame.po +50 -42
  320. data/po/zh_CN/rbot-bash.po +15 -0
  321. data/po/zh_CN/rbot-dictclient.po +20 -20
  322. data/po/zh_CN/rbot-factoids.po +9 -9
  323. data/po/zh_CN/rbot-geoip.po +0 -0
  324. data/po/zh_CN/rbot-googlefight.po +24 -0
  325. data/po/zh_CN/rbot-grouphug.po +4 -4
  326. data/po/zh_CN/rbot-hangman.po +114 -0
  327. data/po/zh_CN/rbot-keywords.po +3 -3
  328. data/po/zh_CN/rbot-lastfm.po +268 -70
  329. data/po/zh_CN/rbot-markov.po +73 -2
  330. data/po/zh_CN/rbot-quotes.po +21 -21
  331. data/po/zh_CN/rbot-rss.po +6 -2
  332. data/po/zh_CN/rbot-script.po +3 -0
  333. data/po/zh_CN/rbot-seen.po +72 -0
  334. data/po/zh_CN/rbot-spell.po +2 -2
  335. data/po/zh_CN/rbot-translator.po +13 -13
  336. data/po/zh_CN/rbot-twitter.po +3 -3
  337. data/po/zh_CN/rbot-uno.po +131 -114
  338. data/po/zh_CN/rbot-wall.po +7 -8
  339. data/po/zh_CN/rbot-wheelfortune.po +41 -41
  340. data/po/zh_CN/rbot.po +248 -192
  341. data/po/zh_TW/rbot-autorejoin.po +3 -0
  342. data/po/zh_TW/rbot-azgame.po +50 -42
  343. data/po/zh_TW/rbot-bash.po +15 -0
  344. data/po/zh_TW/rbot-dictclient.po +20 -20
  345. data/po/zh_TW/rbot-factoids.po +9 -9
  346. data/po/zh_TW/rbot-geoip.po +0 -0
  347. data/po/zh_TW/rbot-googlefight.po +24 -0
  348. data/po/zh_TW/rbot-grouphug.po +4 -4
  349. data/po/zh_TW/rbot-hangman.po +114 -0
  350. data/po/zh_TW/rbot-keywords.po +3 -3
  351. data/po/zh_TW/rbot-lastfm.po +268 -70
  352. data/po/zh_TW/rbot-markov.po +73 -2
  353. data/po/zh_TW/rbot-quotes.po +21 -21
  354. data/po/zh_TW/rbot-rss.po +6 -2
  355. data/po/zh_TW/rbot-script.po +3 -0
  356. data/po/zh_TW/rbot-seen.po +72 -0
  357. data/po/zh_TW/rbot-spell.po +2 -2
  358. data/po/zh_TW/rbot-translator.po +13 -13
  359. data/po/zh_TW/rbot-twitter.po +3 -3
  360. data/po/zh_TW/rbot-uno.po +131 -114
  361. data/po/zh_TW/rbot-wall.po +7 -8
  362. data/po/zh_TW/rbot-wheelfortune.po +41 -41
  363. data/po/zh_TW/rbot.po +253 -194
  364. data/setup.rb +4 -4
  365. metadata +127 -18
  366. data/README +0 -43
  367. data/data/rbot/plugins/fish.rb +0 -121
  368. data/lib/rbot/dbhash.rb +0 -199
@@ -35,6 +35,7 @@
35
35
  define_structure :OnJoinAction, :host, :action, :channel, :reason
36
36
  define_structure :BadWordAction, :regexp, :action, :channel, :timer, :reason
37
37
  define_structure :WhitelistEntry, :host, :channel
38
+ define_structure :MassHlAction, :num, :perc, :action, :channel, :timer, :reason
38
39
 
39
40
  class BansPlugin < Plugin
40
41
 
@@ -99,6 +100,7 @@ class BansPlugin < Plugin
99
100
  end
100
101
 
101
102
  @registry[:onjoin] = Array.new unless @registry.has_key? :onjoin
103
+ @registry[:masshl] = Array.new unless @registry.has_key? :masshl
102
104
  end
103
105
 
104
106
  def help(plugin, topic="")
@@ -118,29 +120,36 @@ class BansPlugin < Plugin
118
120
  when "bans"
119
121
  case topic
120
122
  when "add"
121
- return "bans add <onjoin|badword|whitelist>: add an automatic action for people that join or say some bad word, or a whitelist entry. further help available"
123
+ return "bans add <onjoin|badword|whitelist|masshl>: add an automatic action for people that join or say some bad word, or a whitelist entry. further help available"
122
124
  when "add onjoin"
123
125
  return "bans add onjoin <hostmask> [action] [#channel] [reason ...]: will add an autoaction for any one who joins with hostmask. default action is silence, default channel is all"
124
126
  when "add badword"
125
127
  return "bans add badword <regexp> [action] [Xs/m/h/d] [#channel|all] [reason ...]: adds a badword regexp, if a user sends a message that matches regexp, the action will be invoked. default action is silence, default channel is all"
126
128
  when "add whitelist"
127
129
  return "bans add whitelist <hostmask> [#channel|all]: add the given hostmask to the whitelist. no autoaction will be triggered by users on the whitelist"
130
+ when "add masshl"
131
+ return "masshl add <max_nicks|percentage> [action] [Xs/m/h/d] [#channel|all] [reason ...]: adds an massive highligh action. You can use both max and % in one trigger, the higher value will be taken. For two triggers in one channel, the one with higher requirements will be taken"
128
132
  when "rm"
129
- return "bans rm <onjoin|badword|whitelist> <hostmask/regexp> [#channel], or bans rm <onjoin|badword|whitelist> index <num>: removes the specified onjoin or badword rule or whitelist entry."
133
+ return "bans rm <onjoin|badword|whitelist> <hostmask/regexp> [#channel], or bans rm <onjoin|badword|whitelist> index <num>: removes the specified onjoin or badword rule or whitelist entry. For masshl, bans rm masshl index [#channel|all]"
130
134
  when "list"
131
- return"bans list <onjoin|badword|whitelist>: lists all onjoin or badwords or whitelist entries"
135
+ return"bans list <onjoin|badword|whitelist|masshl>: lists all onjoin or badwords or whitelist entries. For masshl, you can add [#channel|all]"
136
+ else
137
+ return "commands are: add, add onjoin, add badword, add whitelist, add masshl, rm, list"
132
138
  end
133
139
  end
134
140
  return "bans <command>: allows a user of the bot to do a range of bans and unbans. commands are: [un]ban, kick[ban], [un]silence, add, rm and list"
135
141
  end
136
142
 
137
- def listen(m)
138
- return unless m.respond_to?(:public?) and m.public?
143
+ def message(m)
144
+ return unless m.channel
145
+
146
+ # check the whitelist first
139
147
  @registry[:whitelist].each { |white|
140
148
  next unless ['all', m.target.downcase].include?(white.channel)
141
149
  return if m.source.matches?(white.host)
142
150
  }
143
151
 
152
+ # check the badwords next
144
153
  @registry[:badwords].each { |badword|
145
154
  next unless ['all', m.target.downcase].include?(badword.channel)
146
155
  next unless badword.regexp.match(m.plainmessage)
@@ -149,6 +158,22 @@ class BansPlugin < Plugin
149
158
  do_cmd(badword.action.to_sym, m.source.nick, m.target, badword.timer, badword.reason)
150
159
  return
151
160
  }
161
+
162
+ # and finally, see if the user triggered masshl
163
+ mm = m.plainmessage.irc_downcase(m.server.casemap).split(/[\s\.,:]/)
164
+ nicks_said = (m.channel.users.map { |u| u.downcase} & mm).size
165
+ return unless nicks_said > 0 # not really needed, but saves some cycles
166
+ got_nicks = 0
167
+ masshl_action = nil
168
+ @registry[:masshl].each { |masshl|
169
+ next unless masshl.channel == m.channel.downcase or masshl.channel == "all"
170
+ needed = [masshl.num.to_i, (masshl.perc * m.channel.user_nicks.size / 100).to_i].max
171
+ next if needed > nicks_said or needed < got_nicks
172
+ masshl_action = masshl
173
+ got_nicks = needed
174
+ }
175
+ return unless masshl_action
176
+ do_cmd masshl_action.action.intern, m.sourcenick, m.channel, masshl_action.timer, masshl_action.reason
152
177
  end
153
178
 
154
179
  def join(m)
@@ -200,6 +225,47 @@ class BansPlugin < Plugin
200
225
  do_cmd(:unsilence, nick, channel)
201
226
  end
202
227
 
228
+ def add_masshl(m, params=nil)
229
+ num = params[:num].to_i
230
+ perc = params[:perc] ? /(\d{1,2})\%/.match(params[:perc])[1].to_i : 0
231
+ channel, action = params[:channel].downcase.dup, params[:action]
232
+ timer, reason = params[:timer].dup, params[:reason].to_s
233
+ if perc == 0 and num == 0
234
+ m.reply "both triggers 0, you don't want this."
235
+ return
236
+ end
237
+
238
+ masshl = @registry[:masshl]
239
+ masshl << MassHlAction.new(num, perc, action, channel, timer, reason)
240
+ @registry[:masshl] = masshl
241
+
242
+ m.okay
243
+ end
244
+
245
+ def rm_masshl(m, params=nil)
246
+ masshl = @registry[:masshl]
247
+ masshl_w = params[:channel] ? masshl.select { |mh| mh.channel == params[:channel].downcase } : masshl
248
+ count = masshl_w.length
249
+ idx = params[:idx].to_i
250
+
251
+ if idx > count
252
+ m.reply "No such masshl \##{idx}"
253
+ return
254
+ end
255
+ masshl.delete(masshl_w[idx-1])
256
+ @registry[:masshl] = masshl
257
+ m.okay
258
+ end
259
+
260
+ def list_masshl(m, params=nil)
261
+ masshl = @registry[:masshl]
262
+ masshl = masshl.select { |mh| mh.channel == params[:channel].downcase } if params[:channel]
263
+ m.reply params[:channel] ? "masshl rules: #{masshl.length} for #{params[:channel]}" : "masshl rules: #{masshl.length}"
264
+ masshl.each_with_index { |mh, idx|
265
+ m.reply "\##{idx+1}: #{mh.num} | #{mh.perc}% | #{mh.action} | #{mh.channel} | #{mh.timer} | #{mh.reason}"
266
+ }
267
+ end
268
+
203
269
  def add_onjoin(m, params=nil)
204
270
  begin
205
271
  host, channel = m.server.new_netmask(params[:host]), params[:channel].downcase
@@ -392,7 +458,7 @@ class BansPlugin < Plugin
392
458
  when /^(\d+)m$/
393
459
  timer = $1.to_i * 60
394
460
  when /^(\d+)h$/
395
- timer = $1.to_i * 60 * 60
461
+ timer = $1.to_i * 60 * 60
396
462
  when /^(\d+)d$/
397
463
  timer = $1.to_i * 60 * 60 * 24
398
464
  else
@@ -507,3 +573,31 @@ plugin.map 'bans rm whitelist :host :channel', :action => 'rm_whitelist',
507
573
  plugin.map 'bans list whitelist', :action => 'list_whitelist',
508
574
  :auth_path => 'list::whitelist'
509
575
 
576
+ plugin.map 'bans add masshl :num :perc :action :timer :channel *reason', :action => 'add_masshl',
577
+ :requirements => {:num => /\d{1,2}/, :perc => /\d{1,2}\%/,:action => BansPlugin::ActionRe, :timer => BansPlugin::TimerRe, :channel => BansPlugin::ChannelAllRe},
578
+ :defaults => {:action => 'silence', :timer => "0s", :channel => 'all', :reason => 'masshl'},
579
+ :auth_path => 'edit::masshl'
580
+ plugin.map 'bans add masshl :perc :num :action :timer :channel *reason', :action => 'add_masshl',
581
+ :requirements => {:num => /\d{1,2}/, :perc => /\d{1,2}\%/,:action => BansPlugin::ActionRe, :timer => BansPlugin::TimerRe, :channel => BansPlugin::ChannelAllRe},
582
+ :defaults => {:action => 'silence', :timer => "0s", :channel => 'all', :reason => 'masshl'},
583
+ :auth_path => 'edit::masshl'
584
+ plugin.map 'bans add masshl :perc :action :timer :channel *reason', :action => 'add_masshl',
585
+ :requirements => {:num => /\d{1,2}/, :perc => /\d{1,2}\%/,:action => BansPlugin::ActionRe, :timer => BansPlugin::TimerRe, :channel => BansPlugin::ChannelAllRe},
586
+ :defaults => {:num => 0, :action => 'silence', :timer => "0s", :channel => 'all', :reason => 'masshl'},
587
+ :auth_path => 'edit::masshl'
588
+ plugin.map 'bans add masshl :num :action :timer :channel *reason', :action => 'add_masshl',
589
+ :requirements => {:num => /\d{1,2}/, :perc => /\d{1,2}\%/,:action => BansPlugin::ActionRe, :timer => BansPlugin::TimerRe, :channel => BansPlugin::ChannelAllRe},
590
+ :defaults => {:perc => "0%", :action => 'silence', :timer => "0s", :channel => 'all', :reason => 'masshl'},
591
+ :auth_path => 'edit::masshl'
592
+ plugin.map 'bans rm masshl :idx', :action => 'rm_masshl',
593
+ :requirements => {:channel => nil, :num => BansPlugin::IdxRe},
594
+ :auth_path => 'edit::masshl'
595
+ plugin.map 'bans rm masshl :idx :channel', :action => 'rm_masshl',
596
+ :requirements => {:channel => BansPlugin::ChannelAllRe},
597
+ :defaults => {:channel => nil},
598
+ :auth_path => 'edit::masshl'
599
+ plugin.map 'bans list masshl', :action => 'list_masshl',
600
+ :auth_path => 'list::masshl'
601
+ plugin.map 'bans list masshl :channel', :action => 'list_masshl',
602
+ :defaults => {:channel => nil},
603
+ :auth_path => 'list::masshl'
@@ -67,7 +67,12 @@ class BashPlugin < Plugin
67
67
 
68
68
  include REXML
69
69
  def help(plugin, topic="")
70
- "bash => print a random quote from bash.org, bash quote_id => print that quote id from bash.org, bash latest => print the latest quote from bash.org (currently broken, need to get josh@bash.org to fix the xml)"
70
+ [
71
+ _("bash => print a random quote from bash.org"),
72
+ _("bash quote_id => print that quote id from bash.org"),
73
+ _("bash search <terms> => print the first bash.org quote matching <terms>"),
74
+ _("bash latest => print the latest quote from bash.org")
75
+ ].join(", ")
71
76
  end
72
77
 
73
78
  def bash_filter(s)
@@ -156,7 +161,7 @@ class BashPlugin < Plugin
156
161
  # may want to echo more than one for latest/random
157
162
  quote = quotes.first
158
163
  end
159
- m.reply quote.to_s
164
+ m.reply quote.to_s, :split_at => /\s+\|\s+/
160
165
  end
161
166
 
162
167
  def xml_bash(m, id=nil)
@@ -167,7 +172,7 @@ class BashPlugin < Plugin
167
172
  xml = @bot.httputil.get("http://bash.org/xml/?random&num=1", :cache => false)
168
173
  else
169
174
  xml = @bot.httputil.get("http://bash.org/xml/?" + id + "&num=1")
170
- end
175
+ end
171
176
 
172
177
  unless xml
173
178
  m.reply "bash.org rss parse failed"
@@ -179,7 +184,7 @@ class BashPlugin < Plugin
179
184
  return
180
185
  end
181
186
  doc.elements.each("*/item") {|e|
182
- if(id != 0)
187
+ if(id != 0)
183
188
  reply = e.elements["title"].text.gsub(/QDB: /,"") + " " + e.elements["link"].text.gsub(/QDB: /,"") + "\n"
184
189
  reply = reply + e.elements["description"].text.gsub(/\<br \/\>/, "\n")
185
190
  else
@@ -6,7 +6,7 @@ class CalPlugin < Plugin
6
6
  def help(plugin, topic="")
7
7
  "cal [month year] => show current calendar [optionally specify month and year]"
8
8
  end
9
-
9
+
10
10
  def cal_path
11
11
  @bot.config["cal.path"]
12
12
  end
@@ -16,20 +16,20 @@ class ChuckNorrisPlugin < Plugin
16
16
  else
17
17
  raise "Error: Couldn't find chucknorris.yml[.gz]"
18
18
  end
19
-
19
+
20
20
  debug "+ [chucknorris] Loading #{path}..."
21
-
21
+
22
22
  @@facts = YAML.load(fyml).map{|fact,(score,votes)| votes >= MIN_VOTES ? [score,fact] : nil}.compact
23
23
  debug "+ [chucknorris] #{@@facts.length} Chuck Norris facts loaded..."
24
24
  debug " Random fact: #{@@facts[rand(@@facts.size)].inspect}"
25
-
25
+
26
26
  super
27
27
  end
28
28
 
29
29
  def name
30
30
  "chucknorris"
31
31
  end
32
-
32
+
33
33
  # Just a little helper for the initialize method...
34
34
  def find_facts_file(name)
35
35
  full_path = File.join Config::datadir, "plugins", name
@@ -40,11 +40,11 @@ class ChuckNorrisPlugin < Plugin
40
40
  found_files[0]
41
41
  end
42
42
  end
43
-
43
+
44
44
  # HELP!
45
45
  def help(plugin, topic="chuck")
46
46
  "chuck|norris|chucknorris [min_rating] => show a random Chuck Norris fact (optional minimum rating from 1-10, default=6.0)."
47
- #\"fact [person]\" shows a fact about someone in the channel.
47
+ #\"fact [person]\" shows a fact about someone in the channel.
48
48
  end
49
49
 
50
50
  # The meat.
@@ -18,12 +18,16 @@ class DebugPlugin < Plugin
18
18
  :default => "",
19
19
  :desc => "Directory where profile/string dumps are to be stored")
20
20
 
21
+ def dirname
22
+ @bot.config['debug.logdir']
23
+ end
24
+
21
25
  def initialize
22
26
  super
23
27
  @prev = Hash.new(0)
24
28
  @curr = Hash.new(0)
25
29
  @delta = Hash.new(0)
26
- @file = File.open("#{@bot.botclass}/#{@bot.config['debug.logdir']}/memory_profiler.log",'w')
30
+ @file = File.open(datafile("memory_profiler.log"), 'w')
27
31
  @thread = @bot.timer.add(@bot.config['debug.interval']) {
28
32
  begin
29
33
  GC.start
@@ -39,7 +43,7 @@ class DebugPlugin < Plugin
39
43
  end
40
44
 
41
45
  if @bot.config['debug.dump_strings']
42
- File.open("#{@bot.botclass}/#{@bot.config['debug.logdir']}/memory_profiler_strings.log.#{Time.now.to_i}",'w') do |f|
46
+ File.open(datafile("memory_profiler_strings.log.#{Time.now.to_i}"), 'w') do |f|
43
47
  curr_strings.sort.each do |s|
44
48
  f.puts s
45
49
  end
@@ -107,7 +111,7 @@ class DebugPlugin < Plugin
107
111
  end
108
112
  end
109
113
 
110
- File.open("#{@bot.botclass}/#{@bot.config['debug.logdir']}/memory_profiler_strings.log.#{Time.now.to_i}",'w') do |f|
114
+ File.open(datafile("memory_profiler_strings.log.#{Time.now.to_i}"), 'w') do |f|
111
115
  curr_strings.sort.each do |s|
112
116
  f.puts s
113
117
  end
@@ -79,7 +79,7 @@ class DeepThoughts < Plugin
79
79
  def help(plugin, topic="")
80
80
  "deepthought => think a deep thought."
81
81
  end
82
-
82
+
83
83
  def deepthought(m, params)
84
84
  m.reply THOUGHTS.pick_one
85
85
  end
@@ -62,6 +62,10 @@ class DeliciousPlugin < Plugin
62
62
 
63
63
  def event_url_added(url, options = {})
64
64
  debug("called with #{url}, #{options.inspect}")
65
+ if @bot.config['delicious.user'].empty?
66
+ debug "del.icio.us plugin not configured, skipping"
67
+ return
68
+ end
65
69
  opts = Hash.new
66
70
  opts[:description] = options[:title] || options[:info] || url
67
71
  opts[:extended] = options[:extra] if options[:extra]
@@ -74,10 +78,10 @@ class DeliciousPlugin < Plugin
74
78
  tags.tr(',', ' ').split(/\s+/).each do |t|
75
79
  if t.sub!(/^!/, '')
76
80
  case t
77
- when 'nolog', 'no-log', 'dont-log', 'dontlog', 'skip':
81
+ when 'nolog', 'no-log', 'dont-log', 'dontlog', 'skip'
78
82
  debug "skipping #{url} on user request"
79
83
  return
80
- when 'private', 'unshared', 'not-shared', 'notshared', 'hide':
84
+ when 'private', 'unshared', 'not-shared', 'notshared', 'hide'
81
85
  debug "hiding #{url} on user request"
82
86
  opts[:shared] = 'no'
83
87
  end
@@ -53,7 +53,7 @@ class DicePlugin < Plugin
53
53
  dice = d.split(/d/)
54
54
  repr = []
55
55
  r = 0
56
- unless dice[0] =~ /^[0-9]+/
56
+ unless dice[0] =~ /^\d+/
57
57
  dice[0] = 1
58
58
  end
59
59
  for i in 0...dice[0].to_i
@@ -86,28 +86,28 @@ class DicePlugin < Plugin
86
86
  def privmsg(m)
87
87
  # If either not given parameters or given incorrect parameters, return with
88
88
  # the help message
89
- unless(m.params && m.params =~ /^[0-9]*d[0-9]+(\s*[+-]\s*([0-9]+|[0-9]*d[0-9])+)*$/)
90
- m.nickreply "incorrect usage: " + help(m.plugin)
89
+ unless m.params && m.params =~ /^\d*d\d+(\s*[+-]\s*(\d+|\d*d\d)+)*$/
90
+ m.reply "incorrect usage: " + help(m.plugin)
91
91
  return
92
92
  end
93
93
 
94
94
  # Extract the actual dice request from the message parameters, splitting it
95
95
  # into dice and modifiers
96
- a = m.params.gsub(/\s+/,'').scan(/^[0-9]*d[0-9]+|[+-][0-9]*d[0-9]+|[+-][0-9]+/)
96
+ a = m.params.gsub(/\s+/,'').scan(/^\d*d\d+|[+-]\d*d\d+|[+-]\d+/)
97
97
  # check nr of total dices and sides per dice
98
98
  nr = 0
99
99
  a.each { |dice|
100
100
  dc, ds = dice.split(/d/)
101
101
  # check sides
102
102
  if ds.to_i > @bot.config['dice.max_sides']
103
- m.reply "sorry, don't have any dices with more than %u sides" % @bot.config['dice.max_sides']
103
+ m.reply "sorry, don't have any dices with more than %u sides" % @bot.config['dice.max_sides'], :nick => true
104
104
  return
105
105
  end
106
106
  # We use .max with 1 so that specs such as d6 count as 1 and not as 0
107
107
  nr += [dc.to_i, 1].max
108
108
  }
109
109
  if nr > @bot.config['dice.max_dices']
110
- m.reply "can't handle more than %u dices" % @bot.config['dice.max_dices']
110
+ m.reply "can't handle more than %u dices" % @bot.config['dice.max_dices'], :nick => true
111
111
  return
112
112
  end
113
113
 
@@ -123,7 +123,7 @@ class DicePlugin < Plugin
123
123
  t = t + tmp.get_view
124
124
  end
125
125
  t.chop!
126
- m.nickreply r.to_s + " || " + m.params + ": " + t
126
+ m.reply(r.to_s + " || " + m.params + ": " + t, :nick => true)
127
127
  end
128
128
  end
129
129
  plugin = DicePlugin.new
@@ -53,8 +53,8 @@ class DictPlugin < Plugin
53
53
 
54
54
  def initialize
55
55
  super
56
- @dmurl = "http://www.demauroparavia.it/"
57
- @dmurlrx = %r{http://(?:www\.)?demauroparavia\.it/(\d+)}
56
+ @dmurl = "http://old.demauroparavia.it/"
57
+ @dmurlrx = %r{http://(?:www|old\.)?demauroparavia\.it/(\d+)}
58
58
  @dmwapurl = "http://wap.demauroparavia.it/index.php?lemma=%s"
59
59
  @dmwaplemma = "http://wap.demauroparavia.it/lemma.php?ID=%s"
60
60
  @oxurl = "http://www.askoxford.com/concise_oed/%s"
@@ -112,7 +112,8 @@ class DictPlugin < Plugin
112
112
  text += entries[0...hits].map { |ar|
113
113
  n += 1
114
114
  urls << @dmwaplemma % ar[2]
115
- "#{n}. #{Bold}#{ar[0]}#{Bold} - #{ar[1].gsub(/<\/?em>/,'')}: #{@dmurl}#{ar[2]}"
115
+ key = ar[1].ircify_html
116
+ "#{n}. #{Bold}#{ar[0]}#{Bold} - #{key}: #{@dmurl}#{ar[2]}"
116
117
  }.join(" | ")
117
118
  m.reply text
118
119
 
@@ -15,7 +15,11 @@
15
15
 
16
16
 
17
17
  # requires Ruby/DICT <http://www.caliban.org/ruby/ruby-dict.shtml>
18
- require 'dict'
18
+ begin
19
+ require 'dict'
20
+ rescue LoadError
21
+ raise LoadError, "Ruby/DICT not found, grab it from http://www.caliban.org/ruby/ruby-dict.shtml"
22
+ end
19
23
 
20
24
  class ::String
21
25
  # Returns a new string truncated to length 'to'
@@ -73,11 +77,11 @@ class DictClientPlugin < Plugin
73
77
  Config.register Config::StringValue.new('dictclient.match_format',
74
78
  :default => '<matches>––<database>',
75
79
  :desc => _('Format of match results. <matches> will be replaced with the formatted headwords, <database> with the formatted database name'))
76
-
80
+
77
81
  def initialize
78
82
  super
79
83
  end
80
-
84
+
81
85
  # create a DICT object, which is passed to the block. after the block finishes,
82
86
  # the DICT object is automatically disconnected. the return value of the block
83
87
  # is returned from this method.
@@ -100,15 +104,15 @@ class DictClientPlugin < Plugin
100
104
  end
101
105
  ret
102
106
  end
103
-
107
+
104
108
  def format_headword(w)
105
109
  @bot.config['dictclient.headword_format'].gsub '<headword>', w
106
110
  end
107
-
111
+
108
112
  def format_database(d)
109
113
  @bot.config['dictclient.database_format'].gsub '<database>', d
110
114
  end
111
-
115
+
112
116
  def cmd_define(m, params)
113
117
  phrase = params[:phrase].to_s
114
118
  results = with_dict(m) {|d| d.define(params[:database], params[:phrase])}
@@ -118,7 +122,7 @@ class DictClientPlugin < Plugin
118
122
  # the number of definitions is above dictclient.max_defs_before_collapse
119
123
  if results.any? {|r| r.database != results[0].database} &&
120
124
  results.length > @bot.config['dictclient.max_defs_before_collapse']
121
- _("Many definitions for %{phrase} were found in %{databases}. Use 'define <phrase> from <database> to view a definition.") %
125
+ _("Many definitions for %{phrase} were found in %{databases}. Use 'define <phrase> from <database> to view a definition.") %
122
126
  { :phrase => format_headword(phrase),
123
127
  :databases => results.collect {|r| r.database}.uniq.
124
128
  collect {|d| format_database d}.join(', ') }
@@ -135,13 +139,13 @@ class DictClientPlugin < Plugin
135
139
  }.join ' | '
136
140
  end
137
141
  else
138
- _("No definition for %{phrase} found from %{database}.") %
142
+ _("No definition for %{phrase} found from %{database}.") %
139
143
  { :phrase => format_headword(phrase),
140
144
  :database => format_database(params[:database]) }
141
145
  end
142
146
  )
143
147
  end
144
-
148
+
145
149
  def cmd_match(m, params)
146
150
  phrase = params[:phrase].to_s
147
151
  results = with_dict(m) {|d| d.match(params[:database],
@@ -156,14 +160,14 @@ class DictClientPlugin < Plugin
156
160
  )
157
161
  }.join ' '
158
162
  else
159
- _("Nothing matched %{query} from %{database} using %{strategy}") %
163
+ _("Nothing matched %{query} from %{database} using %{strategy}") %
160
164
  { :query => format_headword(phrase),
161
165
  :database => format_database(params[:database]),
162
166
  :strategy => params[:strategy] }
163
167
  end
164
168
  )
165
169
  end
166
-
170
+
167
171
  def cmd_databases(m, params)
168
172
  with_dict(m) do |d|
169
173
  m.reply _("Databases: %{list}") % {
@@ -171,7 +175,7 @@ class DictClientPlugin < Plugin
171
175
  }
172
176
  end
173
177
  end
174
-
178
+
175
179
  def cmd_strategies(m, params)
176
180
  with_dict(m) do |d|
177
181
  m.reply _("Strategies: %{list}") % {
@@ -179,7 +183,7 @@ class DictClientPlugin < Plugin
179
183
  }
180
184
  end
181
185
  end
182
-
186
+
183
187
  def help(plugin, topic='')
184
188
  case topic
185
189
  when 'define'