spox-mod_spox 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +174 -0
- data/INSTALL +15 -0
- data/LICENSE +674 -0
- data/README.rdoc +73 -0
- data/bin/mod_spox +112 -0
- data/data/mod_spox/extras/AOLSpeak.rb +257 -0
- data/data/mod_spox/extras/AutoKick.rb +152 -0
- data/data/mod_spox/extras/AutoMode.rb +122 -0
- data/data/mod_spox/extras/AutoRejoin.rb +37 -0
- data/data/mod_spox/extras/Bash.rb +55 -0
- data/data/mod_spox/extras/Bouncer.rb +220 -0
- data/data/mod_spox/extras/Bullshit.rb +19 -0
- data/data/mod_spox/extras/Bytes.rb +11 -0
- data/data/mod_spox/extras/Confess.rb +244 -0
- data/data/mod_spox/extras/DCC.rb +182 -0
- data/data/mod_spox/extras/DevWatch.rb +153 -0
- data/data/mod_spox/extras/DownForEveryoneOrJustMe.rb +47 -0
- data/data/mod_spox/extras/EightBall.rb +33 -0
- data/data/mod_spox/extras/FML.rb +35 -0
- data/data/mod_spox/extras/FloodKicker.rb +129 -0
- data/data/mod_spox/extras/Fortune.rb +76 -0
- data/data/mod_spox/extras/GoogleIt.rb +13 -0
- data/data/mod_spox/extras/Headers.rb +59 -0
- data/data/mod_spox/extras/Karma.rb +302 -0
- data/data/mod_spox/extras/Locator.rb +44 -0
- data/data/mod_spox/extras/Logger.rb +182 -0
- data/data/mod_spox/extras/LolSpeak.rb +21 -0
- data/data/mod_spox/extras/NickServ.rb +84 -0
- data/data/mod_spox/extras/PhpCli.rb +308 -0
- data/data/mod_spox/extras/PhpFuncLookup.rb +297 -0
- data/data/mod_spox/extras/Pinger.rb +11 -0
- data/data/mod_spox/extras/Quotes.rb +79 -0
- data/data/mod_spox/extras/RegexTracker.rb +158 -0
- data/data/mod_spox/extras/Roulette.rb +267 -0
- data/data/mod_spox/extras/RubyCli.rb +93 -0
- data/data/mod_spox/extras/Search.rb +49 -0
- data/data/mod_spox/extras/Seen.rb +150 -0
- data/data/mod_spox/extras/Slashdot.rb +35 -0
- data/data/mod_spox/extras/SlashdotHeadlineGenerator.rb +500 -0
- data/data/mod_spox/extras/Talk.rb +32 -0
- data/data/mod_spox/extras/Topten.rb +103 -0
- data/data/mod_spox/extras/TracTicket.rb +66 -0
- data/data/mod_spox/extras/Translate.rb +132 -0
- data/data/mod_spox/extras/Twitter.rb +458 -0
- data/data/mod_spox/extras/UrbanDictionary.rb +55 -0
- data/data/mod_spox/extras/Weather.rb +55 -0
- data/data/mod_spox/plugins/Authenticator.rb +289 -0
- data/data/mod_spox/plugins/Banner.rb +585 -0
- data/data/mod_spox/plugins/BotNick.rb +18 -0
- data/data/mod_spox/plugins/Helper.rb +49 -0
- data/data/mod_spox/plugins/Initializer.rb +35 -0
- data/data/mod_spox/plugins/Joiner.rb +23 -0
- data/data/mod_spox/plugins/Nicker.rb +14 -0
- data/data/mod_spox/plugins/Parter.rb +23 -0
- data/data/mod_spox/plugins/Permissions.rb +60 -0
- data/data/mod_spox/plugins/PluginLoader.rb +180 -0
- data/data/mod_spox/plugins/Ponger.rb +70 -0
- data/data/mod_spox/plugins/PoolConfig.rb +52 -0
- data/data/mod_spox/plugins/Quitter.rb +15 -0
- data/data/mod_spox/plugins/Servers.rb +57 -0
- data/data/mod_spox/plugins/Status.rb +31 -0
- data/data/mod_spox/plugins/Triggers.rb +85 -0
- data/lib/mod_spox/BaseConfig.rb +51 -0
- data/lib/mod_spox/Bot.rb +604 -0
- data/lib/mod_spox/BotConfig.rb +65 -0
- data/lib/mod_spox/ConfigurationWizard.rb +180 -0
- data/lib/mod_spox/Database.rb +51 -0
- data/lib/mod_spox/Exceptions.rb +84 -0
- data/lib/mod_spox/Helpers.rb +122 -0
- data/lib/mod_spox/Loader.rb +60 -0
- data/lib/mod_spox/Logger.rb +37 -0
- data/lib/mod_spox/MessageFactory.rb +112 -0
- data/lib/mod_spox/Pipeline.rb +207 -0
- data/lib/mod_spox/Plugin.rb +97 -0
- data/lib/mod_spox/PluginHolder.rb +22 -0
- data/lib/mod_spox/PluginManager.rb +257 -0
- data/lib/mod_spox/PriorityQueue.rb +69 -0
- data/lib/mod_spox/Socket.rb +201 -0
- data/lib/mod_spox/Sockets.rb +226 -0
- data/lib/mod_spox/Timer.rb +60 -0
- data/lib/mod_spox/Version.rb +14 -0
- data/lib/mod_spox/handlers/BadNick.rb +19 -0
- data/lib/mod_spox/handlers/Bounce.rb +24 -0
- data/lib/mod_spox/handlers/Created.rb +27 -0
- data/lib/mod_spox/handlers/Handler.rb +39 -0
- data/lib/mod_spox/handlers/Invite.rb +28 -0
- data/lib/mod_spox/handlers/Join.rb +38 -0
- data/lib/mod_spox/handlers/Kick.rb +36 -0
- data/lib/mod_spox/handlers/LuserChannels.rb +19 -0
- data/lib/mod_spox/handlers/LuserClient.rb +18 -0
- data/lib/mod_spox/handlers/LuserMe.rb +16 -0
- data/lib/mod_spox/handlers/LuserOp.rb +19 -0
- data/lib/mod_spox/handlers/LuserUnknown.rb +19 -0
- data/lib/mod_spox/handlers/Mode.rb +62 -0
- data/lib/mod_spox/handlers/Motd.rb +38 -0
- data/lib/mod_spox/handlers/MyInfo.rb +24 -0
- data/lib/mod_spox/handlers/Names.rb +86 -0
- data/lib/mod_spox/handlers/Nick.rb +50 -0
- data/lib/mod_spox/handlers/NickInUse.rb +19 -0
- data/lib/mod_spox/handlers/Notice.rb +35 -0
- data/lib/mod_spox/handlers/Part.rb +39 -0
- data/lib/mod_spox/handlers/Ping.rb +25 -0
- data/lib/mod_spox/handlers/Pong.rb +23 -0
- data/lib/mod_spox/handlers/Privmsg.rb +39 -0
- data/lib/mod_spox/handlers/Quit.rb +29 -0
- data/lib/mod_spox/handlers/Topic.rb +38 -0
- data/lib/mod_spox/handlers/Welcome.rb +30 -0
- data/lib/mod_spox/handlers/Who.rb +83 -0
- data/lib/mod_spox/handlers/Whois.rb +117 -0
- data/lib/mod_spox/handlers/YourHost.rb +20 -0
- data/lib/mod_spox/messages/Messages.rb +6 -0
- data/lib/mod_spox/messages/incoming/BadNick.rb +16 -0
- data/lib/mod_spox/messages/incoming/Bounce.rb +18 -0
- data/lib/mod_spox/messages/incoming/Created.rb +15 -0
- data/lib/mod_spox/messages/incoming/Invite.rb +21 -0
- data/lib/mod_spox/messages/incoming/Join.rb +19 -0
- data/lib/mod_spox/messages/incoming/Kick.rb +26 -0
- data/lib/mod_spox/messages/incoming/LuserChannels.rb +15 -0
- data/lib/mod_spox/messages/incoming/LuserClient.rb +24 -0
- data/lib/mod_spox/messages/incoming/LuserMe.rb +18 -0
- data/lib/mod_spox/messages/incoming/LuserOp.rb +15 -0
- data/lib/mod_spox/messages/incoming/LuserUnknown.rb +15 -0
- data/lib/mod_spox/messages/incoming/Message.rb +22 -0
- data/lib/mod_spox/messages/incoming/Mode.rb +42 -0
- data/lib/mod_spox/messages/incoming/Motd.rb +18 -0
- data/lib/mod_spox/messages/incoming/MyInfo.rb +24 -0
- data/lib/mod_spox/messages/incoming/Names.rb +24 -0
- data/lib/mod_spox/messages/incoming/Nick.rb +26 -0
- data/lib/mod_spox/messages/incoming/NickInUse.rb +15 -0
- data/lib/mod_spox/messages/incoming/Notice.rb +9 -0
- data/lib/mod_spox/messages/incoming/Part.rb +21 -0
- data/lib/mod_spox/messages/incoming/Ping.rb +18 -0
- data/lib/mod_spox/messages/incoming/Pong.rb +9 -0
- data/lib/mod_spox/messages/incoming/Privmsg.rb +90 -0
- data/lib/mod_spox/messages/incoming/Quit.rb +18 -0
- data/lib/mod_spox/messages/incoming/Topic.rb +21 -0
- data/lib/mod_spox/messages/incoming/TopicInfo.rb +21 -0
- data/lib/mod_spox/messages/incoming/Welcome.rb +27 -0
- data/lib/mod_spox/messages/incoming/Who.rb +18 -0
- data/lib/mod_spox/messages/incoming/Whois.rb +49 -0
- data/lib/mod_spox/messages/incoming/YourHost.rb +18 -0
- data/lib/mod_spox/messages/internal/BotInitialized.rb +11 -0
- data/lib/mod_spox/messages/internal/ChangeNick.rb +15 -0
- data/lib/mod_spox/messages/internal/Connected.rb +20 -0
- data/lib/mod_spox/messages/internal/ConnectionFailed.rb +23 -0
- data/lib/mod_spox/messages/internal/DCCListener.rb +12 -0
- data/lib/mod_spox/messages/internal/DCCRequest.rb +12 -0
- data/lib/mod_spox/messages/internal/DCCSocket.rb +19 -0
- data/lib/mod_spox/messages/internal/Disconnected.rb +8 -0
- data/lib/mod_spox/messages/internal/Disconnecting.rb +8 -0
- data/lib/mod_spox/messages/internal/EstablishConnection.rb +22 -0
- data/lib/mod_spox/messages/internal/HaltBot.rb +8 -0
- data/lib/mod_spox/messages/internal/NickRequest.rb +9 -0
- data/lib/mod_spox/messages/internal/NickResponse.rb +15 -0
- data/lib/mod_spox/messages/internal/PluginLoadRequest.rb +21 -0
- data/lib/mod_spox/messages/internal/PluginLoadResponse.rb +17 -0
- data/lib/mod_spox/messages/internal/PluginModuleRequest.rb +14 -0
- data/lib/mod_spox/messages/internal/PluginModuleResponse.rb +18 -0
- data/lib/mod_spox/messages/internal/PluginReload.rb +18 -0
- data/lib/mod_spox/messages/internal/PluginRequest.rb +18 -0
- data/lib/mod_spox/messages/internal/PluginResponse.rb +21 -0
- data/lib/mod_spox/messages/internal/PluginUnloadRequest.rb +9 -0
- data/lib/mod_spox/messages/internal/PluginUnloadResponse.rb +9 -0
- data/lib/mod_spox/messages/internal/PluginsReady.rb +10 -0
- data/lib/mod_spox/messages/internal/QueueSocket.rb +8 -0
- data/lib/mod_spox/messages/internal/Reconnect.rb +8 -0
- data/lib/mod_spox/messages/internal/Request.rb +15 -0
- data/lib/mod_spox/messages/internal/Response.rb +15 -0
- data/lib/mod_spox/messages/internal/Shutdown.rb +8 -0
- data/lib/mod_spox/messages/internal/SignaturesUpdate.rb +8 -0
- data/lib/mod_spox/messages/internal/StatusRequest.rb +10 -0
- data/lib/mod_spox/messages/internal/StatusResponse.rb +18 -0
- data/lib/mod_spox/messages/internal/TimerAdd.rb +36 -0
- data/lib/mod_spox/messages/internal/TimerClear.rb +16 -0
- data/lib/mod_spox/messages/internal/TimerRemove.rb +23 -0
- data/lib/mod_spox/messages/internal/TimerResponse.rb +34 -0
- data/lib/mod_spox/messages/internal/TriggersUpdate.rb +8 -0
- data/lib/mod_spox/messages/internal/UnqueueSocket.rb +8 -0
- data/lib/mod_spox/messages/outgoing/Admin.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Away.rb +11 -0
- data/lib/mod_spox/messages/outgoing/ChannelMode.rb +25 -0
- data/lib/mod_spox/messages/outgoing/Connect.rb +24 -0
- data/lib/mod_spox/messages/outgoing/Die.rb +9 -0
- data/lib/mod_spox/messages/outgoing/Info.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Invite.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Ison.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Join.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Kick.rb +23 -0
- data/lib/mod_spox/messages/outgoing/Kill.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Links.rb +19 -0
- data/lib/mod_spox/messages/outgoing/List.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Lusers.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Motd.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Names.rb +20 -0
- data/lib/mod_spox/messages/outgoing/Nick.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Notice.rb +12 -0
- data/lib/mod_spox/messages/outgoing/Oper.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Part.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Pass.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Ping.rb +11 -0
- data/lib/mod_spox/messages/outgoing/Pong.rb +17 -0
- data/lib/mod_spox/messages/outgoing/Privmsg.rb +43 -0
- data/lib/mod_spox/messages/outgoing/Quit.rb +11 -0
- data/lib/mod_spox/messages/outgoing/Raw.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Rehash.rb +9 -0
- data/lib/mod_spox/messages/outgoing/Restart.rb +9 -0
- data/lib/mod_spox/messages/outgoing/ServList.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Simple.rb +12 -0
- data/lib/mod_spox/messages/outgoing/Squery.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Squit.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Stats.rb +18 -0
- data/lib/mod_spox/messages/outgoing/Summon.rb +23 -0
- data/lib/mod_spox/messages/outgoing/Time.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Topic.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Trace.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Unaway.rb +9 -0
- data/lib/mod_spox/messages/outgoing/User.rb +23 -0
- data/lib/mod_spox/messages/outgoing/UserHost.rb +15 -0
- data/lib/mod_spox/messages/outgoing/UserMode.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Users.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Version.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Who.rb +23 -0
- data/lib/mod_spox/messages/outgoing/WhoWas.rb +23 -0
- data/lib/mod_spox/messages/outgoing/Whois.rb +19 -0
- data/lib/mod_spox/migrations/001_initialize_models.rb +115 -0
- data/lib/mod_spox/migrations/002_persistent_sigs.rb +14 -0
- data/lib/mod_spox/migrations/003_auth_restructure.rb +31 -0
- data/lib/mod_spox/migrations/004_mode_index_fix.rb +18 -0
- data/lib/mod_spox/migrations/005_nick_mode_nopark.rb +18 -0
- data/lib/mod_spox/models/Auth.rb +65 -0
- data/lib/mod_spox/models/AuthMask.rb +13 -0
- data/lib/mod_spox/models/Channel.rb +89 -0
- data/lib/mod_spox/models/Config.rb +30 -0
- data/lib/mod_spox/models/Group.rb +30 -0
- data/lib/mod_spox/models/Models.rb +4 -0
- data/lib/mod_spox/models/Nick.rb +195 -0
- data/lib/mod_spox/models/NickMode.rb +32 -0
- data/lib/mod_spox/models/Server.rb +27 -0
- data/lib/mod_spox/models/Setting.rb +52 -0
- data/lib/mod_spox/models/Signature.rb +52 -0
- data/lib/mod_spox/models/Trigger.rb +9 -0
- data/lib/mod_spox/rfc2812.rb +49 -0
- data/populate_gemspec.rb +15 -0
- data/tests/BotHolder.rb +24 -0
- data/tests/handlers/tc_BadNick.rb +21 -0
- data/tests/handlers/tc_Created.rb +24 -0
- data/tests/handlers/tc_Invite.rb +50 -0
- data/tests/handlers/tc_Join.rb +33 -0
- data/tests/handlers/tc_Kick.rb +32 -0
- data/tests/handlers/tc_Mode.rb +85 -0
- data/tests/handlers/tc_Names.rb +35 -0
- data/tests/handlers/tc_Nick.rb +55 -0
- data/tests/handlers/tc_Part.rb +44 -0
- data/tests/handlers/tc_Ping.rb +40 -0
- data/tests/handlers/tc_Pong.rb +28 -0
- data/tests/handlers/tc_Privmsg.rb +85 -0
- data/tests/handlers/tc_Quit.rb +40 -0
- data/tests/handlers/tc_Who.rb +50 -0
- data/tests/handlers/tc_Whois.rb +61 -0
- data/tests/models/tc_Auth.rb +39 -0
- data/tests/models/tc_Channel.rb +52 -0
- data/tests/models/tc_Config.rb +19 -0
- data/tests/models/tc_Nick.rb +144 -0
- data/tests/models/tc_NickMode.rb +40 -0
- data/tests/models/tc_Setting.rb +21 -0
- data/tests/models/tc_Signature.rb +14 -0
- data/tests/run_tests.rb +6 -0
- metadata +362 -0
@@ -0,0 +1,267 @@
|
|
1
|
+
require 'mod_spox/messages/internal/PluginRequest'
|
2
|
+
|
3
|
+
class Roulette < ModSpox::Plugin
|
4
|
+
|
5
|
+
include Models
|
6
|
+
|
7
|
+
def initialize(pipeline)
|
8
|
+
super(pipeline)
|
9
|
+
add_sig(:sig => 'roulette', :method => :roulette, :req => 'public')
|
10
|
+
add_sig(:sig => 'suicide', :method => :suicide, :req => 'public')
|
11
|
+
add_sig(:sig => 'shoot (\S+)', :method => :shoot, :req => 'public', :params => [:nick])
|
12
|
+
add_sig(:sig => 'roulette topten', :method => :topten, :req => 'public')
|
13
|
+
add_sig(:sig => 'roulette stats ?(\S+)?', :method => :stats, :req => 'public', :params => [:nick])
|
14
|
+
add_sig(:sig => 'roulette chambers', :method => :chambers, :req => 'public')
|
15
|
+
Game.create_table unless Game.table_exists?
|
16
|
+
Info.create_table unless Info.table_exists?
|
17
|
+
@banner = nil
|
18
|
+
@pipeline.hook(self, :get_banner, :Internal_PluginResponse)
|
19
|
+
end
|
20
|
+
|
21
|
+
# message:: ModSpox::Messages::Incoming::Privmsg
|
22
|
+
# Display chamber statistics
|
23
|
+
def chambers(m, p)
|
24
|
+
total = Game.all.size
|
25
|
+
result = Game.group(:chamber).select(:chamber, 'COUNT(chamber) as total'.lit).reverse_order(:total)
|
26
|
+
if(result)
|
27
|
+
output = []
|
28
|
+
result.each do |res|
|
29
|
+
percent = sprintf('%.2d', ((res[:total].to_f / total.to_f) * 100.0))
|
30
|
+
output << "chamber #{res.chamber}: #{percent}% (#{res[:total]})"
|
31
|
+
end
|
32
|
+
reply m.replyto, "\2Chamber stats:\2 #{output.join(', ')}"
|
33
|
+
else
|
34
|
+
reply m.replyto, "\2Error:\2 No games found"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# message:: ModSpox::Messages::Internal::PluginResponse
|
39
|
+
# Get the banner plugin
|
40
|
+
def get_banner(message)
|
41
|
+
@banner = message.plugin if message.found?
|
42
|
+
end
|
43
|
+
|
44
|
+
# message:: ModSpox::Messages::Incoming::Privmsg
|
45
|
+
# params:: empty
|
46
|
+
# Play roulette
|
47
|
+
def roulette(message, params)
|
48
|
+
return unless message.is_public?
|
49
|
+
do_shot(message.source, message.target)
|
50
|
+
end
|
51
|
+
|
52
|
+
# message:: ModSpox::Messages::Incoming::Privmsg
|
53
|
+
# params:: empty
|
54
|
+
# Kill self
|
55
|
+
def suicide(message, params)
|
56
|
+
return unless message.is_public?
|
57
|
+
do_suicide(message.source, message.target)
|
58
|
+
end
|
59
|
+
|
60
|
+
# message:: ModSpox::Messages::Incoming::Privmsg
|
61
|
+
# params:: nick
|
62
|
+
# Shoot other person playing current game
|
63
|
+
def shoot(message, params)
|
64
|
+
return unless message.is_public?
|
65
|
+
cur_game = game(message.target)
|
66
|
+
nick = Helpers.find_model(params[:nick], false)
|
67
|
+
if(cur_game.shots == 1 && nick && Info.filter(:game_id => cur_game.pk, :nick_id => nick.pk))
|
68
|
+
do_shot(nick, message.target)
|
69
|
+
else
|
70
|
+
do_suicide(message.source, message.target)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# message:: ModSpox::Messages::Incoming::Privmsg
|
75
|
+
# params:: empty
|
76
|
+
# List topten players
|
77
|
+
def topten(message, params)
|
78
|
+
return unless message.is_public?
|
79
|
+
ds = Database.db[:infos].left_outer_join(:games, :id => :game_id)
|
80
|
+
res = ds.select(:nick_id, 'COUNT(win) as wins'.lit).where(:channel_id => message.target.pk, :win => true).group(:nick_id).reverse_order(:wins).limit(10)
|
81
|
+
ids = res.map(:nick_id)
|
82
|
+
top = []
|
83
|
+
ids.each do |id|
|
84
|
+
nick = Nick[id]
|
85
|
+
top << "#{nick.nick} (#{win_loss_ratio(nick, message.target)}% survival with #{games_won(nick, message.target)} wins)"
|
86
|
+
end
|
87
|
+
if(top.empty?)
|
88
|
+
reply(message.replyto, "\2Error:\2 No one has survived")
|
89
|
+
else
|
90
|
+
reply(message.replyto, "Roulette topten: #{top.join(', ')}")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# message:: ModSpox::Messages::Incoming::Privmsg
|
95
|
+
# params:: empty | nick
|
96
|
+
# List statistics on self or given nick
|
97
|
+
def stats(message, params)
|
98
|
+
return unless message.is_public?
|
99
|
+
if(params[:nick])
|
100
|
+
nick = Helpers.find_model(params[:nick], false)
|
101
|
+
unless(nick)
|
102
|
+
reply(message.replyto, "\2Error:\2 Failed to find record of #{params[:nick]}")
|
103
|
+
return
|
104
|
+
end
|
105
|
+
else
|
106
|
+
nick = message.source
|
107
|
+
end
|
108
|
+
reply(message.replyto, "\2Roulette stats #{nick.nick}:\2 #{win_loss_ratio(nick, message.target)}% survival rate. Has won #{games_won(nick, message.target)} games and lost #{games_lost(nick, message.target)} games, taking a total of #{total_shots(nick, message.target)} shots.")
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
# nick:: ModSpox::Models::Nick
|
114
|
+
# channel:: ModSpox::Models::Channel
|
115
|
+
# Report win/loss ratio for nick
|
116
|
+
def win_loss_ratio(nick, channel)
|
117
|
+
if(games_lost(nick, channel) > 0)
|
118
|
+
val = (games_won(nick, channel).to_f / games_total(nick, channel).to_f) * 100
|
119
|
+
elsif(games_lost(nick, channel) == 0 && games_won(nick, channel) == 0)
|
120
|
+
val = 0
|
121
|
+
else
|
122
|
+
val = 100
|
123
|
+
end
|
124
|
+
return sprintf("%.2f", val)
|
125
|
+
end
|
126
|
+
|
127
|
+
# nick:: ModSpox::Models::Nick
|
128
|
+
# channel:: ModSpox::Models::Channel
|
129
|
+
# Return number of games nick has won
|
130
|
+
def games_won(nick, channel)
|
131
|
+
Info.left_outer_join(:games, :id => :game_id).filter('nick_id = ?', nick.pk).filter('channel_id = ?', channel.pk).filter('win = ?', true).count
|
132
|
+
end
|
133
|
+
|
134
|
+
# nick:: ModSpox::Models::Nick
|
135
|
+
# channel:: ModSpox::Models::Channel
|
136
|
+
# Return number of games nick has lost
|
137
|
+
def games_lost(nick, channel)
|
138
|
+
games_total(nick, channel) - games_won(nick, channel)
|
139
|
+
end
|
140
|
+
|
141
|
+
# nick:: ModSpox::Models::Nick
|
142
|
+
# channel:: ModSpox::Models::Channel
|
143
|
+
# Return number of games nick has played
|
144
|
+
def games_total(nick, channel)
|
145
|
+
Info.left_outer_join(:games, :id => :game_id).filter('nick_id = ?', nick.pk).filter('channel_id = ?', channel.pk).exclude(:game_id => game(channel).pk).count
|
146
|
+
end
|
147
|
+
|
148
|
+
# nick:: ModSpox::Models::Nick
|
149
|
+
# channel:: ModSpox::Models::Channel
|
150
|
+
# Return number of shots nick has taken
|
151
|
+
def total_shots(nick, channel)
|
152
|
+
v = Info.left_outer_join(:games, :id => :game_id).filter('nick_id = ?', nick.pk).filter('channel_id = ?', channel.pk).exclude(:game_id => game(channel).pk).sum(:infos__shots)
|
153
|
+
v = 0 unless v
|
154
|
+
return v
|
155
|
+
end
|
156
|
+
|
157
|
+
# nick:: ModSpox::Models::Nick
|
158
|
+
# channel:: ModSpox::Models::Channel
|
159
|
+
# Fire shot
|
160
|
+
def do_shot(nick, channel)
|
161
|
+
begin
|
162
|
+
shot(nick, channel)
|
163
|
+
reply(channel, "#{nick.nick}: *click*")
|
164
|
+
rescue Bullet => bang
|
165
|
+
game_over(nick, bang.game)
|
166
|
+
kill_nick(nick, channel)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# nick:: ModSpox::Models::Nick
|
171
|
+
# channel:: ModSpox::Models::Channel
|
172
|
+
# Commit suicide
|
173
|
+
def do_suicide(nick, channel)
|
174
|
+
begin
|
175
|
+
6.times do
|
176
|
+
shot(nick, channel)
|
177
|
+
end
|
178
|
+
rescue Bullet => bang
|
179
|
+
game_over(nick, bang.game)
|
180
|
+
kill_nick(nick, channel)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def kill_nick(nick, channel)
|
185
|
+
unless(@banner.nil?)
|
186
|
+
begin
|
187
|
+
@banner.plugin.ban(nick, channel, 30, '*BANG*', true, false)
|
188
|
+
rescue Banner::NotOperator => boom
|
189
|
+
reply(channel, "#{nick.nick}: *BANG*")
|
190
|
+
rescue Object => boom
|
191
|
+
reply(channel, "#{nick.nick}: *BANG*")
|
192
|
+
Logger.warn("Error: Roulette ban generated an unexpected error: #{boom}")
|
193
|
+
end
|
194
|
+
else
|
195
|
+
reply(channel, "#{nick.nick}: *BANG*")
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# channel:: ModSpox::Models::Channel
|
200
|
+
# Return current game
|
201
|
+
def game(channel)
|
202
|
+
@pipeline << Messages::Internal::PluginRequest.new(self, 'Banner') if @banner.nil?
|
203
|
+
game = Game.filter('shots > ?', 0).filter('channel_id = ?', channel.pk).first
|
204
|
+
unless(game)
|
205
|
+
chamber = rand(6) + 1
|
206
|
+
game = Game.new(:chamber => chamber, :shots => chamber, :channel_id => channel.pk)
|
207
|
+
game.save
|
208
|
+
end
|
209
|
+
return game
|
210
|
+
end
|
211
|
+
|
212
|
+
# nick:: ModSpox::Models::Nick
|
213
|
+
# channel:: ModSpox::Models::Channel
|
214
|
+
# Process shot
|
215
|
+
def shot(nick, channel)
|
216
|
+
cur_game = game(channel)
|
217
|
+
info = Info.find_or_create(:game_id => cur_game.pk, :nick_id => nick.pk)
|
218
|
+
info.update(:shots => info.shots + 1)
|
219
|
+
cur_game.update(:shots => cur_game.shots - 1)
|
220
|
+
raise Bullet.new(cur_game) if cur_game.shots < 1
|
221
|
+
end
|
222
|
+
|
223
|
+
# nick:: ModSpox::Models::Nick
|
224
|
+
# game:: Game
|
225
|
+
# Return number of games nick has won
|
226
|
+
def game_over(nick, game)
|
227
|
+
Info.filter(:game_id => game.pk).each do |info|
|
228
|
+
info.update(:win => true) unless info.nick_id == nick.pk
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
class Game < Sequel::Model
|
233
|
+
set_schema do
|
234
|
+
primary_key :id
|
235
|
+
timestamp :stamp, :null => false
|
236
|
+
integer :shots, :null => false, :default => 6
|
237
|
+
integer :chamber, :null => false, :default => 1
|
238
|
+
foreign_key :channel_id, :null => false, :table => :channels
|
239
|
+
end
|
240
|
+
|
241
|
+
many_to_one :channel, :class => ModSpox::Models::Channel
|
242
|
+
|
243
|
+
def before_create
|
244
|
+
self.stamp = Time.now
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
class Info < Sequel::Model
|
249
|
+
set_schema do
|
250
|
+
primary_key :id
|
251
|
+
integer :shots, :null => false, :default => 0
|
252
|
+
boolean :win, :null => false, :default => false
|
253
|
+
foreign_key :nick_id, :null => false, :table => :nicks
|
254
|
+
foreign_key :game_id, :null => false, :table => :games
|
255
|
+
end
|
256
|
+
|
257
|
+
many_to_one :nick, :class => ModSpox::Models::Nick
|
258
|
+
many_to_one :game, :class => Game
|
259
|
+
end
|
260
|
+
|
261
|
+
class Bullet < Exception
|
262
|
+
attr_reader :game
|
263
|
+
def initialize(game)
|
264
|
+
@game = game
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
|
2
|
+
require 'timeout'
|
3
|
+
class RubyCli < ModSpox::Plugin
|
4
|
+
|
5
|
+
include Models
|
6
|
+
include Messages::Outgoing
|
7
|
+
|
8
|
+
def initialize(pipeline)
|
9
|
+
super(pipeline)
|
10
|
+
ruby = Group.find_or_create(:name => 'ruby')
|
11
|
+
admin = Group.filter(:name => 'admin').first
|
12
|
+
add_sig(:sig => 'ruby (on|off)', :method => :set_channel, :group => admin, :desc => 'Add or remove channel from allowing ruby command', :params => [:action])
|
13
|
+
add_sig(:sig => 'ruby (?!on|off)(.+)', :method => :execute_ruby, :group => ruby, :desc => 'Execute ruby code', :params => [:code])
|
14
|
+
add_sig(:sig => 'rubyq (?!on|off)(.+)', :method => :quiet_ruby, :group => ruby, :params => [:code], :desc => 'Execute ruby quietly')
|
15
|
+
@channels = Setting.filter(:name => 'rubycli').first
|
16
|
+
@channels = @channels.nil? ? [] : @channels.value
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_channel(message, params)
|
20
|
+
return unless message.is_public?
|
21
|
+
if(params[:action] == 'on')
|
22
|
+
unless(@channels.include?(message.target.pk))
|
23
|
+
@channels << message.target.pk
|
24
|
+
tmp = Setting.find_or_create(:name => 'rubycli')
|
25
|
+
tmp.value = @channels
|
26
|
+
tmp.save
|
27
|
+
end
|
28
|
+
information message.replyto, 'Ruby command now active'
|
29
|
+
else
|
30
|
+
unless(@channels.include?(message.target.pk))
|
31
|
+
warning message.replyto, 'Ruby command is not currently active in this channel'
|
32
|
+
else
|
33
|
+
@channels.delete(message.target.pk)
|
34
|
+
tmp = Setting.find_or_create(:name => 'rubycli')
|
35
|
+
tmp.value = @channels
|
36
|
+
tmp.save
|
37
|
+
information message.replyto, 'Ruby command is now disabled'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def quiet_ruby(message, params)
|
43
|
+
execute_ruby(message, params, true)
|
44
|
+
end
|
45
|
+
|
46
|
+
# we fork into a separate process for more control
|
47
|
+
# over untrusted code
|
48
|
+
def execute_ruby(message, params, shh=false)
|
49
|
+
return unless @channels.include?(message.target.pk)
|
50
|
+
rd, wr = IO.pipe
|
51
|
+
cid = Kernel.fork do
|
52
|
+
rd.close
|
53
|
+
result = nil
|
54
|
+
begin
|
55
|
+
result = lambda{$SAFE=4; eval(params[:code])}.call
|
56
|
+
rescue Object => boom
|
57
|
+
result = boom
|
58
|
+
ensure
|
59
|
+
wr.write [Marshal.dump(result)].pack('m')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
if(cid)
|
63
|
+
Database.reset_connections
|
64
|
+
begin
|
65
|
+
result = nil
|
66
|
+
Timeout::timeout(5) do
|
67
|
+
wr.close
|
68
|
+
result = rd.read
|
69
|
+
rd.close
|
70
|
+
end
|
71
|
+
result = result.size > 0 ? Marshal.load(result.unpack('m')[0]) : ''
|
72
|
+
if(result.is_a?(Exception))
|
73
|
+
error message.replyto, "Exception generated: #{result.to_s.index(' for ').nil? ? result.to_s : result.to_s.slice(0..result.to_s.index(' for '))}"
|
74
|
+
else
|
75
|
+
result = result.to_s
|
76
|
+
reply message.replyto, "#{message.source.nick}: Your result has been truncated. Don't print so much." if result.size > 300
|
77
|
+
reply message.replyto, "#{shh ? '' : 'Result: '}#{result.slice(0..300)}"
|
78
|
+
end
|
79
|
+
rescue Timeout::Error
|
80
|
+
error message.replyto, 'Execution timeout reached.'
|
81
|
+
Logger.warn("Child process #{cid} to be killed")
|
82
|
+
Process.kill('KILL', cid)
|
83
|
+
Logger.warn("Child process #{cid} has been killed")
|
84
|
+
rescue Object => boom
|
85
|
+
error message.replyto, "Unknown error encountered: #{boom}"
|
86
|
+
ensure
|
87
|
+
Process.wait(cid, Process::WNOHANG)
|
88
|
+
Logger.info("RubyCli process has exited.")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'cgi'
|
4
|
+
class Search < ModSpox::Plugin
|
5
|
+
|
6
|
+
include Messages::Outgoing
|
7
|
+
|
8
|
+
def initialize(pipeline)
|
9
|
+
super(pipeline)
|
10
|
+
add_sig(:sig => 'search count (.+)', :method => 'search_count', :params => [:terms], :desc => 'Show number of results for given search')
|
11
|
+
add_sig(:sig => 'search (?!count)(\d+)? ?(.+)', :method => 'search', :desc => 'Search the internet', :params => [:number, :terms])
|
12
|
+
end
|
13
|
+
|
14
|
+
def search(message, params)
|
15
|
+
limit = params[:number] ? params[:number].to_i : 1
|
16
|
+
limit = limit > 5 || limit < 1 ? 1 : limit
|
17
|
+
begin
|
18
|
+
resp = Net::HTTP.new('www.scroogle.org', 80).request_get("/cgi-bin/nbbw.cgi?Gw=#{CGI::escape(params[:terms])}")
|
19
|
+
resp.value
|
20
|
+
page = resp.body
|
21
|
+
results = []
|
22
|
+
page.scan(/<A Href="(.+?)">(.+?)<\/a>/) do |url,title|
|
23
|
+
title.gsub!(/<.*?>/, '')
|
24
|
+
title = CGI::unescapeHTML(title)
|
25
|
+
results.push [title, url]
|
26
|
+
end
|
27
|
+
output = []
|
28
|
+
results.slice(0, limit).each do |title, url|
|
29
|
+
output << "#{Helpers.convert_entities(title)} -> #{Helpers.tinyurl(url)} [#{url.scan(/^http:\/\/.+?\//)[0]}]"
|
30
|
+
end
|
31
|
+
output = output.empty? ? "No results for: \2#{params[:terms]}\2" : ["Search results for \2#{params[:terms]}:\2"] + output
|
32
|
+
reply message.replyto, output
|
33
|
+
rescue Object => boom
|
34
|
+
reply message.replyto, "Failed to find any results for: #{params[:terms]} Reason: #{boom}"
|
35
|
+
Logger.warn("Error: #{boom}\n#{boom.backtrace.join("\n")}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def search_count(m, params)
|
40
|
+
buf = open("http://www.google.com/search?hl=en&q=#{CGI::escape(params[:terms])}", 'UserAgent' => 'mod_spox IRC bot').read
|
41
|
+
output = ''
|
42
|
+
if(buf =~ /of\s+about.+?([\d,]+)/)
|
43
|
+
output = "There are about \2#{$1}\2 results for the term \2#{params[:terms]}\2"
|
44
|
+
else
|
45
|
+
output = "There are no results found for the term \2#{params[:terms]}\2"
|
46
|
+
end
|
47
|
+
reply m.replyto, output
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
class Seen < ModSpox::Plugin
|
2
|
+
def initialize(pipe)
|
3
|
+
super
|
4
|
+
SeenLog.create_table unless SeenLog.table_exists?
|
5
|
+
@pipeline.hook(self, :log_privmsg, :Incoming_Privmsg)
|
6
|
+
@pipeline.hook(self, :log_join, :Incoming_Join)
|
7
|
+
@pipeline.hook(self, :log_part, :Incoming_Part)
|
8
|
+
@pipeline.hook(self, :log_quit, :Incoming_Quit)
|
9
|
+
@pipeline.hook(self, :log_kick, :Incoming_Kick)
|
10
|
+
@pipeline.hook(self, :log_privmsg, :Incoming_Notice)
|
11
|
+
@pipeline.hook(self, :log_outpriv, :Outgoing_Privmsg)
|
12
|
+
@pipeline.hook(self, :log_outpriv, :Outgoing_Notice)
|
13
|
+
add_sig(:sig => 'seen (\S+)', :method => :seen, :desc => 'Report last sighting of nick', :params => [:nick])
|
14
|
+
end
|
15
|
+
|
16
|
+
def seen(m, params)
|
17
|
+
nick = Models::Nick.filter(:nick => params[:nick]).first
|
18
|
+
log = SeenLog.filter(:nick_id => nick.pk).first if nick
|
19
|
+
if(nick && log)
|
20
|
+
message = "I last saw #{params[:nick]} on #{log.received} "
|
21
|
+
case log.type
|
22
|
+
when 'join'
|
23
|
+
message << "joining #{log.channel.name}"
|
24
|
+
when 'part'
|
25
|
+
message << "parting #{log.channel.name} "
|
26
|
+
message << "reason: #{log.message}" unless log.message.nil? || log.message.empty?
|
27
|
+
when 'privmsg'
|
28
|
+
message << "in #{log.channel.name} " unless log.channel.nil?
|
29
|
+
message << "saying #{log.message}" unless log.action
|
30
|
+
message << "doing: #{log.message}" if log.action
|
31
|
+
when 'notice'
|
32
|
+
message << "in #{log.channel.name} " unless log.channel.nil?
|
33
|
+
message << "sending notice: #{log.message}"
|
34
|
+
when 'kicking'
|
35
|
+
mes = log.message.dup
|
36
|
+
k = mes.slice!(0..mes.index('|')-1)
|
37
|
+
mes.slice!(0)
|
38
|
+
k = Models::Nick[k.to_i]
|
39
|
+
message << "kicking #{k.nick} from #{log.channel.name} (Reason: #{mes})"
|
40
|
+
when 'kicked'
|
41
|
+
mes = log.message.dup
|
42
|
+
k = mes.slice!(0..mes.index('|')-1)
|
43
|
+
mes.slice!(0)
|
44
|
+
k = Models::Nick[k.to_i]
|
45
|
+
message << "kicked from #{log.channel.name} by #{k.nick} (Reason: #{mes})"
|
46
|
+
end
|
47
|
+
information m.replyto, message
|
48
|
+
else
|
49
|
+
error m.replyto, "Failed to find record of given nick: #{params[:nick]}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def log_outpriv(message)
|
54
|
+
type = message.instance_of?(Messages::Outgoing::Privmsg) ? 'privmsg' : 'notice'
|
55
|
+
target = message.target.is_a?(Sequel::Model) ? message.target : Helpers.find_model(message.target)
|
56
|
+
target = nil unless target.is_a?(Models::Channel)
|
57
|
+
log = get_log(me.pk)
|
58
|
+
log.action = message.is_action?
|
59
|
+
log.message = message.message
|
60
|
+
log.type = type
|
61
|
+
log.channel = target unless target.nil?
|
62
|
+
log.received = Time.now
|
63
|
+
log.save
|
64
|
+
end
|
65
|
+
|
66
|
+
def log_privmsg(message)
|
67
|
+
return unless message.source.is_a?(Models::Nick)
|
68
|
+
type = message.instance_of?(Messages::Incoming::Privmsg) ? 'privmsg' : 'notice'
|
69
|
+
target = message.target.is_a?(Sequel::Model) ? message.target : Helpers.find_model(message.target)
|
70
|
+
target = nil unless target.is_a?(Models::Channel)
|
71
|
+
log = get_log(message.source.pk)
|
72
|
+
log.action = message.is_action?
|
73
|
+
log.message = message.message
|
74
|
+
log.type = type
|
75
|
+
log.channel = target unless target.nil?
|
76
|
+
log.received = message.time
|
77
|
+
log.save
|
78
|
+
end
|
79
|
+
|
80
|
+
def log_join(message)
|
81
|
+
log = get_log(message.nick.pk)
|
82
|
+
log.action = false
|
83
|
+
log.message = nil
|
84
|
+
log.type = 'join'
|
85
|
+
log.channel = message.channel
|
86
|
+
log.received = message.time
|
87
|
+
log.save
|
88
|
+
end
|
89
|
+
|
90
|
+
def log_part(message)
|
91
|
+
log = get_log(message.nick.pk)
|
92
|
+
log.action = false
|
93
|
+
log.type = 'part'
|
94
|
+
log.message = message.reason
|
95
|
+
log.channel = message.channel
|
96
|
+
log.received = message.time
|
97
|
+
log.save
|
98
|
+
end
|
99
|
+
|
100
|
+
def log_quit(message)
|
101
|
+
log = get_log(message.nick.pk)
|
102
|
+
log.action = false
|
103
|
+
log.type = 'quit'
|
104
|
+
log.message = message.message
|
105
|
+
log.channel = nil
|
106
|
+
log.received = message.time
|
107
|
+
log.save
|
108
|
+
end
|
109
|
+
|
110
|
+
def log_kick(message)
|
111
|
+
# log kicker
|
112
|
+
log = get_log(message.kicker.pk)
|
113
|
+
log.action = false
|
114
|
+
log.type = 'kicking'
|
115
|
+
log.channel = message.channel
|
116
|
+
log.received = message.time
|
117
|
+
log.message = "#{message.kickee.pk}|#{message.reason}"
|
118
|
+
log.save
|
119
|
+
# log kickee
|
120
|
+
log = get_log(message.kickee.pk)
|
121
|
+
log.action = false
|
122
|
+
log.type = 'kicked'
|
123
|
+
log.channel = message.channel
|
124
|
+
log.received = message.time
|
125
|
+
log.message = "#{message.kicker.pk}|#{message.reason}"
|
126
|
+
log.save
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def get_log(pk)
|
132
|
+
log = SeenLog.filter(:nick_id => pk).first
|
133
|
+
log = SeenLog.new(:nick_id => pk) unless log
|
134
|
+
return log
|
135
|
+
end
|
136
|
+
|
137
|
+
class SeenLog < Sequel::Model
|
138
|
+
set_schema do
|
139
|
+
foreign_key :nick_id, :table => :nicks, :null => false
|
140
|
+
foreign_key :channel_id, :table => :channels
|
141
|
+
varchar :type, :default => 'privmsg'
|
142
|
+
timestamp :received, :null => false
|
143
|
+
boolean :action, :null => false, :default => true
|
144
|
+
text :message
|
145
|
+
primary_key :nick_id
|
146
|
+
end
|
147
|
+
many_to_one :nick, :class => ModSpox::Models::Nick
|
148
|
+
many_to_one :channel, :class => ModSpox::Models::Channel
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
class Slashdot < ModSpox::Plugin
|
5
|
+
|
6
|
+
def initialize(pipeline)
|
7
|
+
begin
|
8
|
+
require 'htmlentities'
|
9
|
+
rescue Object => boom
|
10
|
+
Logger.warn('Error: This plugin requires the HTMLEntities gem. Please install and reload plugin.')
|
11
|
+
raise Exceptions::BotException.new("Missing required HTMLEntities library")
|
12
|
+
end
|
13
|
+
super
|
14
|
+
add_sig(:sig => '(slashdot|\/\.) ?(\d+)?', :method => 'show_slashdot', :desc => 'Slashdot headlines', :params => [:trig, :num])
|
15
|
+
@coder = HTMLEntities.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def show_slashdot(message, params)
|
19
|
+
src = open('http://rss.slashdot.org/Slashdot/slashdot')
|
20
|
+
doc = REXML::Document.new(src.read)
|
21
|
+
num = params[:num].nil? || params[:num].to_i < 1 ? 1 : params[:num].to_i
|
22
|
+
num = 5 if num > 5
|
23
|
+
output = []
|
24
|
+
doc.elements.each('rdf:RDF/item') do |item|
|
25
|
+
num -= 1
|
26
|
+
title = CGI::unescapeHTML(item.elements['title'].text)
|
27
|
+
title = title.gsub(/<.+?>/, ' ').gsub(/[\r\n]/, '').gsub(/\s+/, ' ')
|
28
|
+
title = @coder.decode(title)
|
29
|
+
output << "\2/.\2 #{title.strip} \2->\2 #{Helpers.tinyurl(item.elements['link'].text)}"
|
30
|
+
break if num < 1
|
31
|
+
end
|
32
|
+
reply message.replyto, output
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|