rbot 0.9.14 → 0.9.15
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +6 -2
- data/REQUIREMENTS +7 -1
- data/Rakefile +10 -32
- data/bin/rbot +6 -1
- data/bin/svnwatch-postcommit-hook +68 -0
- data/data/rbot/contrib/plugins/stats.rb +3 -3
- data/data/rbot/contrib/plugins/vandale.rb +1 -1
- data/data/rbot/filters/rss.rb +72 -0
- data/data/rbot/languages/finnish.lang +50 -0
- data/data/rbot/plugins/alias.rb +6 -6
- data/data/rbot/plugins/autorejoin.rb +41 -2
- data/data/rbot/plugins/bans.rb +100 -6
- data/data/rbot/plugins/bash.rb +9 -4
- data/data/rbot/plugins/cal.rb +1 -1
- data/data/rbot/plugins/chucknorris.rb +6 -6
- data/data/rbot/plugins/debugger.rb +7 -3
- data/data/rbot/plugins/deepthoughts.rb +1 -1
- data/data/rbot/plugins/delicious.rb +6 -2
- data/data/rbot/plugins/dice.rb +7 -7
- data/data/rbot/plugins/dict.rb +4 -3
- data/data/rbot/plugins/dictclient.rb +17 -13
- data/data/rbot/plugins/digg.rb +3 -3
- data/data/rbot/plugins/eightball.rb +1 -1
- data/data/rbot/plugins/factoids.rb +13 -4
- data/data/rbot/plugins/figlet.rb +4 -4
- data/data/rbot/plugins/forecast.rb +3 -3
- data/data/rbot/plugins/fortune.rb +14 -8
- data/data/rbot/plugins/freshmeat.rb +2 -2
- data/data/rbot/plugins/games/azgame.rb +72 -19
- data/data/rbot/plugins/games/hangman.rb +499 -0
- data/data/rbot/plugins/games/quiz.rb +15 -13
- data/data/rbot/plugins/games/roshambo.rb +1 -1
- data/data/rbot/plugins/games/roulette.rb +4 -4
- data/data/rbot/plugins/games/shiritori.rb +31 -31
- data/data/rbot/plugins/games/uno.rb +28 -6
- data/data/rbot/plugins/games/wheelfortune.rb +1 -3
- data/data/rbot/plugins/geoip.rb +83 -28
- data/data/rbot/plugins/googlefight.rb +64 -0
- data/data/rbot/plugins/greet.rb +45 -0
- data/data/rbot/plugins/grouphug.rb +40 -12
- data/data/rbot/plugins/imdb.rb +4 -4
- data/data/rbot/plugins/insult.rb +2 -2
- data/data/rbot/plugins/karma.rb +6 -5
- data/data/rbot/plugins/keywords.rb +26 -22
- data/data/rbot/plugins/lart.rb +5 -6
- data/data/rbot/plugins/lastfm.rb +488 -125
- data/data/rbot/plugins/lib_spotify.rb +84 -0
- data/data/rbot/plugins/linkbot.rb +1 -1
- data/data/rbot/plugins/markov.rb +567 -78
- data/data/rbot/plugins/math.rb +3 -3
- data/data/rbot/plugins/modes.rb +1 -1
- data/data/rbot/plugins/nickrecover.rb +1 -1
- data/data/rbot/plugins/nickserv.rb +7 -7
- data/data/rbot/plugins/note.rb +55 -0
- data/data/rbot/plugins/nslookup.rb +2 -2
- data/data/rbot/plugins/quakeauth.rb +4 -4
- data/data/rbot/plugins/quotes.rb +53 -19
- data/data/rbot/plugins/reaction.rb +76 -19
- data/data/rbot/plugins/remind.rb +3 -96
- data/data/rbot/plugins/ri.rb +1 -1
- data/data/rbot/plugins/rot13.rb +1 -1
- data/data/rbot/plugins/rss.rb +296 -190
- data/data/rbot/plugins/salut.rb +8 -8
- data/data/rbot/plugins/script.rb +48 -11
- data/data/rbot/plugins/search.rb +124 -28
- data/data/rbot/plugins/seen.rb +162 -31
- data/data/rbot/plugins/shortenurls.rb +1 -1
- data/data/rbot/plugins/slashdot.rb +19 -6
- data/data/rbot/plugins/spotify.rb +78 -0
- data/data/rbot/plugins/theyfightcrime.rb +10 -10
- data/data/rbot/plugins/time.rb +2 -2
- data/data/rbot/plugins/translator.rb +161 -85
- data/data/rbot/plugins/tube.rb +2 -2
- data/data/rbot/plugins/tumblr.rb +143 -0
- data/data/rbot/plugins/twitter.rb +25 -6
- data/data/rbot/plugins/urban.rb +6 -4
- data/data/rbot/plugins/url.rb +49 -10
- data/data/rbot/plugins/weather.rb +6 -6
- data/data/rbot/plugins/wserver.rb +5 -5
- data/data/rbot/plugins/youtube.rb +12 -12
- data/data/rbot/templates/lart/larts-italian +1 -1
- data/launch_here.rb +68 -0
- data/lib/rbot/botuser.rb +1 -1
- data/lib/rbot/compat19.rb +70 -0
- data/lib/rbot/config.rb +8 -6
- data/lib/rbot/core/auth.rb +37 -21
- data/lib/rbot/core/basics.rb +33 -2
- data/lib/rbot/core/config.rb +24 -17
- data/lib/rbot/core/filters_ui.rb +2 -2
- data/lib/rbot/core/irclog.rb +20 -11
- data/lib/rbot/core/remote.rb +9 -9
- data/lib/rbot/core/unicode.rb +4 -0
- data/lib/rbot/core/userdata.rb +16 -1
- data/lib/rbot/core/utils/extends.rb +76 -0
- data/lib/rbot/core/utils/filters.rb +47 -0
- data/lib/rbot/core/utils/httputil.rb +36 -26
- data/lib/rbot/core/utils/parse_time.rb +193 -0
- data/lib/rbot/core/utils/utils.rb +81 -56
- data/lib/rbot/core/utils/wordlist.rb +66 -0
- data/lib/rbot/core/wordlist_ui.rb +27 -0
- data/lib/rbot/irc.rb +59 -19
- data/lib/rbot/ircbot.rb +190 -58
- data/lib/rbot/ircsocket.rb +14 -8
- data/lib/rbot/language.rb +4 -3
- data/lib/rbot/load-gettext.rb +22 -9
- data/lib/rbot/message.rb +89 -18
- data/lib/rbot/messagemapper.rb +71 -19
- data/lib/rbot/plugins.rb +112 -44
- data/lib/rbot/{registry.rb → registry/bdb.rb} +226 -22
- data/lib/rbot/registry/tc.rb +531 -0
- data/lib/rbot/rfc2812.rb +33 -8
- data/lib/rbot/timer.rb +12 -20
- data/po/en_US/rbot-autorejoin.po +3 -0
- data/po/en_US/rbot-azgame.po +51 -43
- data/po/en_US/rbot-bash.po +15 -0
- data/po/en_US/rbot-dictclient.po +20 -20
- data/po/en_US/rbot-factoids.po +9 -9
- data/po/en_US/rbot-geoip.po +0 -0
- data/po/en_US/rbot-googlefight.po +24 -0
- data/po/en_US/rbot-grouphug.po +4 -4
- data/po/en_US/rbot-hangman.po +114 -0
- data/po/en_US/rbot-keywords.po +3 -3
- data/po/en_US/rbot-lastfm.po +268 -70
- data/po/en_US/rbot-markov.po +73 -2
- data/po/en_US/rbot-quotes.po +21 -21
- data/po/en_US/rbot-rss.po +6 -2
- data/po/en_US/rbot-script.po +3 -0
- data/po/en_US/rbot-seen.po +72 -0
- data/po/en_US/rbot-spell.po +2 -2
- data/po/en_US/rbot-translator.po +13 -13
- data/po/en_US/rbot-twitter.po +3 -3
- data/po/en_US/rbot-uno.po +131 -114
- data/po/en_US/rbot-wall.po +12 -13
- data/po/en_US/rbot-wheelfortune.po +41 -41
- data/po/en_US/rbot.po +254 -194
- data/po/fi/rbot-alias.po +82 -0
- data/po/fi/rbot-autoop.po +0 -0
- data/po/fi/rbot-autorejoin.po +20 -0
- data/po/fi/rbot-azgame.po +194 -0
- data/po/fi/rbot-bans.po +0 -0
- data/po/fi/rbot-bash.po +32 -0
- data/po/fi/rbot-botsnack.po +0 -0
- data/po/fi/rbot-cal.po +20 -0
- data/po/fi/rbot-chanserv.po +0 -0
- data/po/fi/rbot-chucknorris.po +0 -0
- data/po/fi/rbot-debugger.po +0 -0
- data/po/fi/rbot-deepthoughts.po +0 -0
- data/po/fi/rbot-delicious.po +0 -0
- data/po/fi/rbot-dice.po +0 -0
- data/po/fi/rbot-dict.po +0 -0
- data/po/fi/rbot-dictclient.po +111 -0
- data/po/fi/rbot-digg.po +0 -0
- data/po/fi/rbot-eightball.po +0 -0
- data/po/fi/rbot-excuse.po +0 -0
- data/po/fi/rbot-factoids.po +107 -0
- data/po/fi/rbot-figlet.po +36 -0
- data/po/fi/rbot-fish.po +0 -0
- data/po/fi/rbot-forecast.po +0 -0
- data/po/fi/rbot-fortune.po +0 -0
- data/po/fi/rbot-freshmeat.po +0 -0
- data/po/fi/rbot-geoip.po +0 -0
- data/po/fi/rbot-googlefight.po +24 -0
- data/po/fi/rbot-grouphug.po +35 -0
- data/po/fi/rbot-hangman.po +121 -0
- data/po/fi/rbot-hl2.po +0 -0
- data/po/fi/rbot-host.po +20 -0
- data/po/fi/rbot-imdb.po +0 -0
- data/po/fi/rbot-insult.po +0 -0
- data/po/fi/rbot-iplookup.po +0 -0
- data/po/fi/rbot-karma.po +0 -0
- data/po/fi/rbot-keywords.po +24 -0
- data/po/fi/rbot-lart.po +0 -0
- data/po/fi/rbot-lastfm.po +377 -0
- data/po/fi/rbot-linkbot.po +0 -0
- data/po/fi/rbot-markov.po +91 -0
- data/po/fi/rbot-math.po +0 -0
- data/po/fi/rbot-modes.po +0 -0
- data/po/fi/rbot-nickrecover.po +36 -0
- data/po/fi/rbot-nickserv.po +104 -0
- data/po/fi/rbot-nslookup.po +0 -0
- data/po/fi/rbot-quakeauth.po +0 -0
- data/po/fi/rbot-quiz.po +0 -0
- data/po/fi/rbot-quotes.po +108 -0
- data/po/fi/rbot-reaction.po +0 -0
- data/po/fi/rbot-remind.po +0 -0
- data/po/fi/rbot-remotectl.po +0 -0
- data/po/fi/rbot-ri.po +0 -0
- data/po/fi/rbot-roshambo.po +0 -0
- data/po/fi/rbot-rot13.po +0 -0
- data/po/fi/rbot-roulette.po +0 -0
- data/po/fi/rbot-rss.po +24 -0
- data/po/fi/rbot-salut.po +0 -0
- data/po/fi/rbot-script.po +20 -0
- data/po/fi/rbot-search.po +0 -0
- data/po/fi/rbot-seen.po +92 -0
- data/po/fi/rbot-shiritori.po +102 -0
- data/po/fi/rbot-shortenurls.po +0 -0
- data/po/fi/rbot-slashdot.po +0 -0
- data/po/fi/rbot-spell.po +54 -0
- data/po/fi/rbot-theyfightcrime.po +0 -0
- data/po/fi/rbot-threat.po +0 -0
- data/po/fi/rbot-time.po +0 -0
- data/po/fi/rbot-topic.po +0 -0
- data/po/fi/rbot-translator.po +77 -0
- data/po/fi/rbot-tube.po +0 -0
- data/po/fi/rbot-twitter.po +24 -0
- data/po/fi/rbot-uno.po +529 -0
- data/po/fi/rbot-urban.po +0 -0
- data/po/fi/rbot-url.po +0 -0
- data/po/fi/rbot-usermodes.po +0 -0
- data/po/fi/rbot-wall.po +32 -0
- data/po/fi/rbot-weather.po +0 -0
- data/po/fi/rbot-wheelfortune.po +205 -0
- data/po/fi/rbot-wow.po +0 -0
- data/po/fi/rbot-wserver.po +0 -0
- data/po/fi/rbot-youtube.po +58 -0
- data/po/fi/rbot.po +1152 -0
- data/po/fr/rbot-autorejoin.po +3 -0
- data/po/fr/rbot-azgame.po +51 -43
- data/po/fr/rbot-bash.po +15 -0
- data/po/fr/rbot-dictclient.po +20 -20
- data/po/fr/rbot-factoids.po +9 -9
- data/po/fr/rbot-geoip.po +0 -0
- data/po/fr/rbot-googlefight.po +24 -0
- data/po/fr/rbot-grouphug.po +4 -4
- data/po/fr/rbot-hangman.po +114 -0
- data/po/fr/rbot-keywords.po +3 -3
- data/po/fr/rbot-lastfm.po +268 -70
- data/po/fr/rbot-markov.po +74 -2
- data/po/fr/rbot-quotes.po +21 -21
- data/po/fr/rbot-rss.po +6 -2
- data/po/fr/rbot-script.po +3 -0
- data/po/fr/rbot-seen.po +72 -0
- data/po/fr/rbot-spell.po +2 -2
- data/po/fr/rbot-translator.po +13 -13
- data/po/fr/rbot-twitter.po +3 -3
- data/po/fr/rbot-uno.po +132 -114
- data/po/fr/rbot-wall.po +8 -9
- data/po/fr/rbot-wheelfortune.po +41 -41
- data/po/fr/rbot.po +268 -197
- data/po/it/rbot-autorejoin.po +3 -0
- data/po/it/rbot-azgame.po +50 -42
- data/po/it/rbot-bash.po +15 -0
- data/po/it/rbot-dictclient.po +20 -20
- data/po/it/rbot-factoids.po +9 -9
- data/po/it/rbot-geoip.po +0 -0
- data/po/it/rbot-googlefight.po +24 -0
- data/po/it/rbot-grouphug.po +4 -4
- data/po/it/rbot-hangman.po +114 -0
- data/po/it/rbot-keywords.po +3 -3
- data/po/it/rbot-lastfm.po +268 -70
- data/po/it/rbot-markov.po +75 -3
- data/po/it/rbot-quotes.po +21 -21
- data/po/it/rbot-rss.po +7 -3
- data/po/it/rbot-script.po +19 -0
- data/po/it/rbot-seen.po +72 -0
- data/po/it/rbot-spell.po +2 -2
- data/po/it/rbot-translator.po +13 -13
- data/po/it/rbot-twitter.po +3 -3
- data/po/it/rbot-uno.po +137 -116
- data/po/it/rbot-wall.po +8 -9
- data/po/it/rbot-wheelfortune.po +41 -41
- data/po/it/rbot.po +265 -208
- data/po/ja/rbot-autorejoin.po +3 -0
- data/po/ja/rbot-azgame.po +51 -43
- data/po/ja/rbot-bash.po +15 -0
- data/po/ja/rbot-dictclient.po +20 -20
- data/po/ja/rbot-factoids.po +9 -9
- data/po/ja/rbot-geoip.po +0 -0
- data/po/ja/rbot-googlefight.po +24 -0
- data/po/ja/rbot-grouphug.po +4 -4
- data/po/ja/rbot-hangman.po +114 -0
- data/po/ja/rbot-keywords.po +3 -3
- data/po/ja/rbot-lastfm.po +268 -70
- data/po/ja/rbot-markov.po +73 -2
- data/po/ja/rbot-quotes.po +21 -21
- data/po/ja/rbot-rss.po +6 -2
- data/po/ja/rbot-script.po +3 -0
- data/po/ja/rbot-seen.po +72 -0
- data/po/ja/rbot-spell.po +2 -2
- data/po/ja/rbot-translator.po +13 -13
- data/po/ja/rbot-twitter.po +3 -3
- data/po/ja/rbot-uno.po +131 -114
- data/po/ja/rbot-wall.po +8 -9
- data/po/ja/rbot-wheelfortune.po +41 -41
- data/po/ja/rbot.po +248 -192
- data/po/rbot-alias.pot +2 -2
- data/po/rbot-autorejoin.pot +21 -0
- data/po/rbot-azgame.pot +51 -43
- data/po/rbot-bash.pot +33 -0
- data/po/rbot-cal.pot +2 -2
- data/po/rbot-dictclient.pot +21 -21
- data/po/rbot-factoids.pot +10 -10
- data/po/rbot-figlet.pot +2 -2
- data/po/rbot-geoip.pot +0 -0
- data/po/rbot-googlefight.pot +25 -0
- data/po/rbot-grouphug.pot +6 -6
- data/po/rbot-hangman.pot +115 -0
- data/po/rbot-host.pot +2 -2
- data/po/rbot-keywords.pot +4 -4
- data/po/rbot-lastfm.pot +270 -72
- data/po/rbot-markov.pot +74 -3
- data/po/rbot-nickrecover.pot +2 -2
- data/po/rbot-nickserv.pot +2 -2
- data/po/rbot-quotes.pot +22 -22
- data/po/rbot-rss.pot +7 -3
- data/po/rbot-script.pot +21 -0
- data/po/rbot-seen.pot +90 -0
- data/po/rbot-shiritori.pot +2 -2
- data/po/rbot-spell.pot +3 -3
- data/po/rbot-translator.pot +14 -14
- data/po/rbot-twitter.pot +4 -4
- data/po/rbot-uno.pot +132 -115
- data/po/rbot-wall.pot +2 -2
- data/po/rbot-wheelfortune.pot +42 -42
- data/po/rbot-youtube.pot +2 -2
- data/po/rbot.pot +249 -193
- data/po/zh_CN/rbot-autorejoin.po +3 -0
- data/po/zh_CN/rbot-azgame.po +50 -42
- data/po/zh_CN/rbot-bash.po +15 -0
- data/po/zh_CN/rbot-dictclient.po +20 -20
- data/po/zh_CN/rbot-factoids.po +9 -9
- data/po/zh_CN/rbot-geoip.po +0 -0
- data/po/zh_CN/rbot-googlefight.po +24 -0
- data/po/zh_CN/rbot-grouphug.po +4 -4
- data/po/zh_CN/rbot-hangman.po +114 -0
- data/po/zh_CN/rbot-keywords.po +3 -3
- data/po/zh_CN/rbot-lastfm.po +268 -70
- data/po/zh_CN/rbot-markov.po +73 -2
- data/po/zh_CN/rbot-quotes.po +21 -21
- data/po/zh_CN/rbot-rss.po +6 -2
- data/po/zh_CN/rbot-script.po +3 -0
- data/po/zh_CN/rbot-seen.po +72 -0
- data/po/zh_CN/rbot-spell.po +2 -2
- data/po/zh_CN/rbot-translator.po +13 -13
- data/po/zh_CN/rbot-twitter.po +3 -3
- data/po/zh_CN/rbot-uno.po +131 -114
- data/po/zh_CN/rbot-wall.po +7 -8
- data/po/zh_CN/rbot-wheelfortune.po +41 -41
- data/po/zh_CN/rbot.po +248 -192
- data/po/zh_TW/rbot-autorejoin.po +3 -0
- data/po/zh_TW/rbot-azgame.po +50 -42
- data/po/zh_TW/rbot-bash.po +15 -0
- data/po/zh_TW/rbot-dictclient.po +20 -20
- data/po/zh_TW/rbot-factoids.po +9 -9
- data/po/zh_TW/rbot-geoip.po +0 -0
- data/po/zh_TW/rbot-googlefight.po +24 -0
- data/po/zh_TW/rbot-grouphug.po +4 -4
- data/po/zh_TW/rbot-hangman.po +114 -0
- data/po/zh_TW/rbot-keywords.po +3 -3
- data/po/zh_TW/rbot-lastfm.po +268 -70
- data/po/zh_TW/rbot-markov.po +73 -2
- data/po/zh_TW/rbot-quotes.po +21 -21
- data/po/zh_TW/rbot-rss.po +6 -2
- data/po/zh_TW/rbot-script.po +3 -0
- data/po/zh_TW/rbot-seen.po +72 -0
- data/po/zh_TW/rbot-spell.po +2 -2
- data/po/zh_TW/rbot-translator.po +13 -13
- data/po/zh_TW/rbot-twitter.po +3 -3
- data/po/zh_TW/rbot-uno.po +131 -114
- data/po/zh_TW/rbot-wall.po +7 -8
- data/po/zh_TW/rbot-wheelfortune.po +41 -41
- data/po/zh_TW/rbot.po +253 -194
- data/setup.rb +4 -4
- metadata +127 -18
- data/README +0 -43
- data/data/rbot/plugins/fish.rb +0 -121
- data/lib/rbot/dbhash.rb +0 -199
@@ -50,6 +50,8 @@ class TwitterPlugin < Plugin
|
|
50
50
|
|
51
51
|
nick = params[:nick] || @registry[m.sourcenick + "_username"]
|
52
52
|
|
53
|
+
friends = params[:friends]
|
54
|
+
|
53
55
|
if not nick
|
54
56
|
m.reply "you should specify the username of the twitter touse, or identify using 'twitter identify [username] [password]'"
|
55
57
|
return false
|
@@ -58,11 +60,18 @@ class TwitterPlugin < Plugin
|
|
58
60
|
user = URI.escape(nick)
|
59
61
|
|
60
62
|
count = @bot.config['twitter.status_count']
|
61
|
-
unless
|
63
|
+
unless friends
|
62
64
|
uri = "http://twitter.com/statuses/user_timeline/#{user}.xml?count=#{count}"
|
63
65
|
else
|
64
66
|
count = @bot.config['twitter.friends_status_count']
|
65
|
-
|
67
|
+
auth = ""
|
68
|
+
if m.private?
|
69
|
+
auth << URI.escape(@registry[m.sourcenick + "_username"])
|
70
|
+
auth << ":"
|
71
|
+
auth << URI.escape(@registry[m.sourcenick + "_password"])
|
72
|
+
auth << "@"
|
73
|
+
end
|
74
|
+
uri = "http://#{auth}twitter.com/statuses/friends_timeline/#{user}.xml"
|
66
75
|
end
|
67
76
|
|
68
77
|
response = @bot.httputil.get(uri, :headers => @header, :cache => false)
|
@@ -83,24 +92,34 @@ class TwitterPlugin < Plugin
|
|
83
92
|
delta = ((time > now) ? time - now : now - time)
|
84
93
|
msg = st.elements['text'].to_s + " (#{Utils.secs_to_string(delta.to_i)} ago via #{st.elements['source'].to_s})"
|
85
94
|
author = ""
|
86
|
-
if
|
95
|
+
if friends
|
87
96
|
author = Utils.decode_html_entities(st.elements['user'].elements['name'].text) + ": " rescue ""
|
88
97
|
end
|
89
98
|
texts << author+Utils.decode_html_entities(msg).ircify_html
|
90
99
|
}
|
91
|
-
if
|
100
|
+
if friends
|
92
101
|
# friends always return the latest 20 updates, so we clip the count
|
93
102
|
texts[count..-1]=nil
|
94
103
|
end
|
95
104
|
rescue
|
96
105
|
error $!
|
97
|
-
|
106
|
+
if friends
|
107
|
+
m.reply "could not parse status for #{nick}'s friends"
|
108
|
+
else
|
109
|
+
m.reply "could not parse status for #{nick}"
|
110
|
+
end
|
98
111
|
return false
|
99
112
|
end
|
100
113
|
m.reply texts.reverse.join("\n")
|
101
114
|
return true
|
102
115
|
else
|
103
|
-
|
116
|
+
if friends
|
117
|
+
rep = "could not get status for #{nick}'s friends"
|
118
|
+
rep << ", try asking in private" unless m.private?
|
119
|
+
else
|
120
|
+
rep = "could not get status for #{nick}"
|
121
|
+
end
|
122
|
+
m.reply rep
|
104
123
|
return false
|
105
124
|
end
|
106
125
|
end
|
data/data/rbot/plugins/urban.rb
CHANGED
@@ -17,11 +17,13 @@ class UrbanPlugin < Plugin
|
|
17
17
|
u = URBAN + URI.escape(word)
|
18
18
|
u += '&page=' + p.to_s if p > 1
|
19
19
|
s = @bot.httputil.get(u)
|
20
|
-
return m.reply
|
20
|
+
return m.reply("Couldn't get the urban dictionary definition for #{word}") if s.nil?
|
21
21
|
|
22
|
-
notfound = s.match %r{<
|
22
|
+
notfound = s.match %r{<i>.*?</i> isn't defined}
|
23
23
|
|
24
|
-
numpages = s[%r{<div id='paginator'>.*?</div>}m]
|
24
|
+
numpages = if s[%r{<div id='paginator'>.*?</div>}m]
|
25
|
+
$&.scan(/\d+/).collect {|x| x.to_i}.max || 1
|
26
|
+
else 1 end
|
25
27
|
|
26
28
|
rv = Array.new
|
27
29
|
s.scan(%r{<td class='index'[^>]*>.*?(\d+)\..*?</td>.*?<td class='word'>(?:<a.*?>)?([^>]+)(?:</a>)?</td>.*?<div class='definition'>(.+?)</div>.*?<div class='example'>(.+?)</div>}m) do |num, wrd, desc, ex|
|
@@ -48,7 +50,7 @@ class UrbanPlugin < Plugin
|
|
48
50
|
resp = @bot.httputil.head('http://www.urbandictionary.com/random.php',
|
49
51
|
:max_redir => -1,
|
50
52
|
:cache => false)
|
51
|
-
return m.reply
|
53
|
+
return m.reply("Couldn't get a random urban dictionary word") if resp.nil?
|
52
54
|
if resp.code == "302" && (loc = resp['location'])
|
53
55
|
words = URI.unescape(loc.match(/define.php\?term=(.*)$/)[1]) rescue nil
|
54
56
|
end
|
data/data/rbot/plugins/url.rb
CHANGED
@@ -28,7 +28,12 @@ class UrlPlugin < Plugin
|
|
28
28
|
:default => ['localhost', '^192\.168\.', '^10\.', '^127\.', '^172\.(1[6-9]|2\d|31)\.'],
|
29
29
|
:on_change => Proc.new { |bot, v| bot.plugins['url'].reset_no_info_hosts },
|
30
30
|
:desc => "A list of regular expressions matching hosts for which no info should be provided")
|
31
|
-
|
31
|
+
Config.register Config::ArrayValue.new('url.only_on_channels',
|
32
|
+
:desc => "Show link info only on these channels",
|
33
|
+
:default => [])
|
34
|
+
Config.register Config::ArrayValue.new('url.ignore',
|
35
|
+
:desc => "Don't show link info for urls from users represented as hostmasks on this list. Useful for ignoring other bots, for example.",
|
36
|
+
:default => [])
|
32
37
|
|
33
38
|
def initialize
|
34
39
|
super
|
@@ -37,6 +42,8 @@ class UrlPlugin < Plugin
|
|
37
42
|
@bot.config.items[:'url.display_link_info'].set_string(@bot.config['url.display_link_info'].to_s)
|
38
43
|
end
|
39
44
|
reset_no_info_hosts
|
45
|
+
self.filter_group = :htmlinfo
|
46
|
+
load_filters
|
40
47
|
end
|
41
48
|
|
42
49
|
def reset_no_info_hosts
|
@@ -69,7 +76,7 @@ class UrlPlugin < Plugin
|
|
69
76
|
checks.flatten!
|
70
77
|
|
71
78
|
unless checks.grep(@no_info_hosts).empty?
|
72
|
-
return "Sorry, info retrieval for #{url.host} (#{checks.first}) is disabled"
|
79
|
+
return ( opts[:always_reply] ? "Sorry, info retrieval for #{url.host} (#{checks.first}) is disabled" : false )
|
73
80
|
end
|
74
81
|
|
75
82
|
logopts = opts.dup
|
@@ -81,6 +88,7 @@ class UrlPlugin < Plugin
|
|
81
88
|
debug "+ getting info for #{url.request_uri}"
|
82
89
|
info = @bot.filter(:htmlinfo, url)
|
83
90
|
debug info
|
91
|
+
logopts[:htmlinfo] = info
|
84
92
|
resp = info[:headers]
|
85
93
|
|
86
94
|
logopts[:title] = title = info[:title]
|
@@ -120,7 +128,23 @@ class UrlPlugin < Plugin
|
|
120
128
|
return extra.join(", ") if title or not @bot.config['url.titles_only']
|
121
129
|
end
|
122
130
|
|
123
|
-
def handle_urls(m,
|
131
|
+
def handle_urls(m, params={})
|
132
|
+
opts = {
|
133
|
+
:display_info => @bot.config['url.display_link_info'],
|
134
|
+
:channels => @bot.config['url.only_on_channels'],
|
135
|
+
:ignore => @bot.config['url.ignore']
|
136
|
+
}.merge params
|
137
|
+
urls = opts[:urls]
|
138
|
+
display_info= opts[:display_info]
|
139
|
+
channels = opts[:channels]
|
140
|
+
ignore = opts[:ignore]
|
141
|
+
|
142
|
+
unless channels.empty?
|
143
|
+
return unless channels.map { |c| c.downcase }.include?(m.channel.downcase)
|
144
|
+
end
|
145
|
+
|
146
|
+
ignore.each { |u| return if m.source.matches?(u) }
|
147
|
+
|
124
148
|
return if urls.empty?
|
125
149
|
debug "found urls #{urls.inspect}"
|
126
150
|
list = m.public? ? @registry[m.target] : nil
|
@@ -128,12 +152,13 @@ class UrlPlugin < Plugin
|
|
128
152
|
urls_displayed = 0
|
129
153
|
urls.each do |urlstr|
|
130
154
|
debug "working on #{urlstr}"
|
131
|
-
next unless urlstr =~ /^https
|
155
|
+
next unless urlstr =~ /^https?:\/\/./
|
132
156
|
title = nil
|
133
157
|
debug "Getting title for #{urlstr}..."
|
134
158
|
reply = nil
|
135
159
|
begin
|
136
160
|
title = get_title_for_url(urlstr,
|
161
|
+
:always_reply => m.address?,
|
137
162
|
:nick => m.source.nick,
|
138
163
|
:channel => m.channel,
|
139
164
|
:ircline => m.message)
|
@@ -145,16 +170,25 @@ class UrlPlugin < Plugin
|
|
145
170
|
# with the last character stripped. this might generate invalid URIs
|
146
171
|
# (e.g. because "some.url" gets chopped to some.url%2, so catch that too
|
147
172
|
if e.message =~ /\(404 - Not Found\)/i or e.kind_of?(URI::InvalidURIError)
|
148
|
-
# chop off last character
|
149
|
-
# look like a
|
150
|
-
|
173
|
+
# chop off last non-word character from the unescaped version of
|
174
|
+
# the URL, and retry if we still have enough string to look like a
|
175
|
+
# minimal URL
|
176
|
+
unescaped = URI.unescape(urlstr)
|
177
|
+
debug "Unescaped: #{unescaped}"
|
178
|
+
if unescaped.sub!(/\W$/,'') and unescaped =~ /^https?:\/\/./
|
179
|
+
urlstr.replace URI.escape(unescaped, OUR_UNSAFE)
|
180
|
+
retry
|
181
|
+
else
|
182
|
+
debug "Not retrying #{unescaped}"
|
183
|
+
end
|
151
184
|
end
|
152
185
|
reply = "Error #{e.message}"
|
153
186
|
end
|
154
187
|
|
155
188
|
if display_info > urls_displayed
|
156
189
|
if reply
|
157
|
-
m.
|
190
|
+
m.reply reply, :overlong => :truncate, :to => :public,
|
191
|
+
:nick => (m.address? ? :auto : false)
|
158
192
|
urls_displayed += 1
|
159
193
|
end
|
160
194
|
end
|
@@ -177,7 +211,12 @@ class UrlPlugin < Plugin
|
|
177
211
|
def info(m, params)
|
178
212
|
escaped = URI.escape(params[:urls].to_s, OUR_UNSAFE)
|
179
213
|
urls = URI.extract(escaped)
|
180
|
-
Thread.new
|
214
|
+
Thread.new do
|
215
|
+
handle_urls(m,
|
216
|
+
:urls => urls,
|
217
|
+
:display_info => params[:urls].length,
|
218
|
+
:channels => [])
|
219
|
+
end
|
181
220
|
end
|
182
221
|
|
183
222
|
def message(m)
|
@@ -186,7 +225,7 @@ class UrlPlugin < Plugin
|
|
186
225
|
escaped = URI.escape(m.message, OUR_UNSAFE)
|
187
226
|
urls = URI.extract(escaped, ['http', 'https'])
|
188
227
|
return if urls.empty?
|
189
|
-
Thread.new { handle_urls(m, urls) }
|
228
|
+
Thread.new { handle_urls(m, :urls => urls) }
|
190
229
|
end
|
191
230
|
|
192
231
|
def reply_urls(opts={})
|
@@ -35,9 +35,9 @@ class CurrentConditions
|
|
35
35
|
end
|
36
36
|
rescue OpenURI::HTTPError => e
|
37
37
|
case e
|
38
|
-
when /304
|
38
|
+
when /304/
|
39
39
|
@iscached = true
|
40
|
-
when /404
|
40
|
+
when /404/
|
41
41
|
raise "Data for #{@station} not found"
|
42
42
|
else
|
43
43
|
raise "Error retrieving data: #{e}"
|
@@ -71,18 +71,18 @@ class WeatherPlugin < Plugin
|
|
71
71
|
Config.register Config::BooleanValue.new('weather.advisory',
|
72
72
|
:default => true,
|
73
73
|
:desc => "Should the bot report special weather advisories when any is present?")
|
74
|
-
|
74
|
+
|
75
75
|
def help(plugin, topic="")
|
76
76
|
case topic
|
77
77
|
when "nws"
|
78
78
|
"weather nws <station> => display the current conditions at the location specified by the NOAA National Weather Service station code <station> ( lookup your station code at http://www.nws.noaa.gov/data/current_obs/ )"
|
79
79
|
when "station", "wu"
|
80
|
-
"weather [<units>] <location> => display the current conditions at the location specified, looking it up on the Weather Underground site; you can use 'station <code>' to look up data by station code ( lookup your station code at http://www.weatherunderground.com/ ); you can optionally set <units> to 'metric' or 'english' if you only want data with the units; use 'both' for units to go back to having both."
|
80
|
+
"weather [<units>] <location> => display the current conditions at the location specified, looking it up on the Weather Underground site; you can use 'station <code>' to look up data by station code ( lookup your station code at http://www.weatherunderground.com/ ); you can optionally set <units> to 'metric' or 'english' if you only want data with the units; use 'both' for units to go back to having both."
|
81
81
|
else
|
82
82
|
"weather information lookup. Looks up weather information for the last location you specified. See topics 'nws' and 'wu' for more information"
|
83
83
|
end
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
def initialize
|
87
87
|
super
|
88
88
|
|
@@ -91,7 +91,7 @@ class WeatherPlugin < Plugin
|
|
91
91
|
@wu_url = "http://mobile.wunderground.com/cgi-bin/findweather/getForecast?brand=mobile%s&query=%s"
|
92
92
|
@wu_station_url = "http://mobile.wunderground.com/auto/mobile%s/global/stations/%s.html"
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
def weather(m, params)
|
96
96
|
if params[:where].empty?
|
97
97
|
if @registry.has_key?(m.sourcenick)
|
@@ -12,20 +12,20 @@ class WserverPlugin < Plugin
|
|
12
12
|
m.reply "cowardly refusing to follow more than 3 redirects"
|
13
13
|
return
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
begin
|
17
17
|
uri = URI.parse(hostname)
|
18
18
|
rescue URI::InvalidURIError => err
|
19
19
|
m.reply "#{hostname} is not a valid URI"
|
20
20
|
return
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
unless(uri)
|
24
24
|
m.reply "incorrect usage: " + help(m.plugin)
|
25
25
|
return
|
26
26
|
end
|
27
|
-
|
28
|
-
|
27
|
+
|
28
|
+
|
29
29
|
resp = @bot.httputil.head(uri)
|
30
30
|
server = resp['Server']
|
31
31
|
if(server && server.length > 0)
|
@@ -34,7 +34,7 @@ class WserverPlugin < Plugin
|
|
34
34
|
m.reply "couldn't tell what #{uri.host} is running"
|
35
35
|
end
|
36
36
|
|
37
|
-
if(resp.code == "302" || resp.code == "301")
|
37
|
+
if(resp.code == "302" || resp.code == "301")
|
38
38
|
newloc = resp['location']
|
39
39
|
newuri = URI.parse(newloc)
|
40
40
|
# detect and ignore incorrect redirects (to relative paths etc)
|
@@ -27,7 +27,7 @@ class YouTubePlugin < Plugin
|
|
27
27
|
def youtube_filter(s)
|
28
28
|
loc = Utils.check_location(s, /youtube\.com/)
|
29
29
|
return nil unless loc
|
30
|
-
if s[:text].include? '<div id="watch-vid-title"
|
30
|
+
if s[:text].include? '<div id="watch-vid-title"'
|
31
31
|
vid = @bot.filter(:"youtube.video", s)
|
32
32
|
return nil unless vid
|
33
33
|
content = _("Category: %{cat}. Rating: %{rating}. Author: %{author}. Duration: %{duration}. %{views} views, faved %{faves} times. %{desc}") % vid
|
@@ -62,11 +62,11 @@ class YouTubePlugin < Plugin
|
|
62
62
|
:title => (e.elements["media:group/media:title"].text rescue nil),
|
63
63
|
:desc => (e.elements["media:group/media:description"].text rescue nil),
|
64
64
|
:cat => (e.elements["media:group/media:category"].text rescue nil),
|
65
|
-
:seconds => (e.elements["media:group/yt:duration
|
66
|
-
:url => (e.elements["media:group/media:player
|
67
|
-
:rating => (("%s/%s" % [e.elements["gd:rating
|
68
|
-
:views => (e.elements["yt:statistics
|
69
|
-
:faves => (e.elements["yt:statistics
|
65
|
+
:seconds => (e.elements["media:group/yt:duration/"].attributes["seconds"].to_i rescue nil),
|
66
|
+
:url => (e.elements["media:group/media:player/"].attributes["url"] rescue nil),
|
67
|
+
:rating => (("%s/%s" % [e.elements["gd:rating"].attributes["average"], e.elements["gd:rating/@max"].value]) rescue nil),
|
68
|
+
:views => (e.elements["yt:statistics"].attributes["viewCount"] rescue nil),
|
69
|
+
:faves => (e.elements["yt:statistics"].attributes["favoriteCount"] rescue nil)
|
70
70
|
}
|
71
71
|
if vid[:desc]
|
72
72
|
vid[:desc].gsub!(/\s+/m, " ")
|
@@ -77,12 +77,12 @@ class YouTubePlugin < Plugin
|
|
77
77
|
vid[:duration] = _("unknown duration")
|
78
78
|
end
|
79
79
|
e.elements.each("media:group/media:content") { |c|
|
80
|
-
if url = (c.
|
81
|
-
type = c.
|
82
|
-
medium = c.
|
83
|
-
expression = c.
|
84
|
-
seconds = c.
|
85
|
-
fmt = case num_fmt = (c.
|
80
|
+
if url = (c.attributes["url"] rescue nil)
|
81
|
+
type = c.attributes["type"] rescue nil
|
82
|
+
medium = c.attributes["medium"] rescue nil
|
83
|
+
expression = c.attributes["expression"] rescue nil
|
84
|
+
seconds = c.attributes["duration"].to_i rescue nil
|
85
|
+
fmt = case num_fmt = (c.attributes["yt:format"] rescue nil)
|
86
86
|
when "1"
|
87
87
|
"h263+amr"
|
88
88
|
when "5"
|
@@ -4,7 +4,7 @@ costringe <who> a programmare in Perl per 3 settimane
|
|
4
4
|
manda l'indirizzo email di <who> a 50 noti spammer
|
5
5
|
restringe il terminale di <who> a 40x24
|
6
6
|
ruba il the di <who>
|
7
|
-
picchia <who> a sangue sulle gengive con una mazza ferrata
|
7
|
+
picchia <who> a sangue sulle gengive con una mazza ferrata arrugginita
|
8
8
|
vende <who> su eBay
|
9
9
|
ficca un peperoncino su per il culo di <who>
|
10
10
|
fa <who> a fettine
|
data/launch_here.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Load rbot from this directory. (No need to install it with setup.rb)
|
4
|
+
#
|
5
|
+
|
6
|
+
SCM_DIR = File.expand_path File.dirname(__FILE__)
|
7
|
+
puts "Running from #{SCM_DIR}"
|
8
|
+
|
9
|
+
$:.unshift File.join(SCM_DIR, 'lib')
|
10
|
+
|
11
|
+
$version = '0.9.15'
|
12
|
+
|
13
|
+
pwd = Dir.pwd
|
14
|
+
begin
|
15
|
+
Dir.chdir SCM_DIR
|
16
|
+
|
17
|
+
if File.exists? '.git'
|
18
|
+
begin
|
19
|
+
git_out = `git log -1 --pretty=raw | git name-rev --stdin`.split("\n")
|
20
|
+
commit, branch_spec = git_out.first.scan(/^commit (\S+)(?: \((\S+)\))?$/).first
|
21
|
+
$version_timestamp = git_out[4].split[-2].to_i
|
22
|
+
subject = git_out[6].strip rescue ""
|
23
|
+
subject[77..-1] = "..." if subject.length > 80
|
24
|
+
rev = "revision #{commit[0,7]}"
|
25
|
+
rev << " [#{subject}]" unless subject.empty?
|
26
|
+
changes = `git diff-index --stat HEAD`.split("\n").last.split(", ").first rescue nil
|
27
|
+
rev << ", #{changes.strip}" if changes
|
28
|
+
if branch_spec
|
29
|
+
tag, branch, offset = branch_spec.scan(/^(?:(tag)s\/)?(\S+?)(?:^0)?(?:~(\d+))?$/).first
|
30
|
+
tag ||= "branch"
|
31
|
+
branch << " #{tag}"
|
32
|
+
branch << "-#{offset}" if offset
|
33
|
+
else
|
34
|
+
branch = "unknown branch"
|
35
|
+
end
|
36
|
+
rescue => e
|
37
|
+
puts e.inspect
|
38
|
+
branch = "unknown branch"
|
39
|
+
rev = "unknown revision"
|
40
|
+
end
|
41
|
+
$version << " (#{branch}, #{rev})"
|
42
|
+
elsif File.directory? File.join(SCM_DIR, '.svn')
|
43
|
+
rev = " (unknown revision)"
|
44
|
+
begin
|
45
|
+
svn_out = `svn info`
|
46
|
+
rev = " (revision #{$1}" if svn_out =~ /Last Changed Rev: (\d+)/
|
47
|
+
svn_st = `svn st #{SCM_DIR}`
|
48
|
+
rev << ", local changes" if svn_st =~ /^[MDA] /
|
49
|
+
rev << ")"
|
50
|
+
rescue => e
|
51
|
+
puts e.inspect
|
52
|
+
end
|
53
|
+
$version += rev
|
54
|
+
end
|
55
|
+
ensure
|
56
|
+
Dir.chdir pwd
|
57
|
+
end
|
58
|
+
|
59
|
+
module Irc
|
60
|
+
class Bot
|
61
|
+
module Config
|
62
|
+
@@datadir = File.join SCM_DIR, 'data/rbot'
|
63
|
+
@@coredir = File.join SCM_DIR, 'lib/rbot/core'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
load File.join(SCM_DIR, 'bin/rbot')
|
data/lib/rbot/botuser.rb
CHANGED
@@ -0,0 +1,70 @@
|
|
1
|
+
#-- vim:sw=2:et
|
2
|
+
#++
|
3
|
+
#
|
4
|
+
# :title: ruby 1.9 compatibility (monkey)patches
|
5
|
+
|
6
|
+
require 'timeout'
|
7
|
+
require "thread"
|
8
|
+
|
9
|
+
class ConditionVariable
|
10
|
+
|
11
|
+
def wait(mutex, timeout=nil)
|
12
|
+
begin
|
13
|
+
# TODO: mutex should not be used
|
14
|
+
@waiters_mutex.synchronize do
|
15
|
+
@waiters.push(Thread.current)
|
16
|
+
end
|
17
|
+
if timeout
|
18
|
+
elapsed = mutex.sleep timeout if timeout > 0.0
|
19
|
+
unless timeout > 0.0 and elapsed < timeout
|
20
|
+
t = @waiters_mutex.synchronize { @waiters.delete Thread.current }
|
21
|
+
signal unless t # if we got notified, pass it along
|
22
|
+
raise TimeoutError, "wait timed out"
|
23
|
+
end
|
24
|
+
else
|
25
|
+
mutex.sleep
|
26
|
+
end
|
27
|
+
end
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
require 'monitor'
|
34
|
+
|
35
|
+
module MonitorMixin
|
36
|
+
|
37
|
+
class ConditionVariable
|
38
|
+
|
39
|
+
def wait(timeout = nil)
|
40
|
+
#if timeout
|
41
|
+
# raise NotImplementedError, "timeout is not implemented yet"
|
42
|
+
#end
|
43
|
+
@monitor.__send__(:mon_check_owner)
|
44
|
+
count = @monitor.__send__(:mon_exit_for_cond)
|
45
|
+
begin
|
46
|
+
@cond.wait(@monitor.instance_variable_get("@mon_mutex"), timeout)
|
47
|
+
return true
|
48
|
+
ensure
|
49
|
+
@monitor.__send__(:mon_enter_for_cond, count)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def signal
|
54
|
+
@monitor.__send__(:mon_check_owner)
|
55
|
+
@cond.signal
|
56
|
+
end
|
57
|
+
|
58
|
+
def broadcast
|
59
|
+
@monitor.__send__(:mon_check_owner)
|
60
|
+
@cond.broadcast
|
61
|
+
end
|
62
|
+
|
63
|
+
end # ConditionVariable
|
64
|
+
|
65
|
+
def self.extend_object(obj)
|
66
|
+
super(obj)
|
67
|
+
obj.__send__(:mon_initialize)
|
68
|
+
end
|
69
|
+
|
70
|
+
end # MonitorMixin
|