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.
Files changed (268) hide show
  1. data/CHANGELOG +174 -0
  2. data/INSTALL +15 -0
  3. data/LICENSE +674 -0
  4. data/README.rdoc +73 -0
  5. data/bin/mod_spox +112 -0
  6. data/data/mod_spox/extras/AOLSpeak.rb +257 -0
  7. data/data/mod_spox/extras/AutoKick.rb +152 -0
  8. data/data/mod_spox/extras/AutoMode.rb +122 -0
  9. data/data/mod_spox/extras/AutoRejoin.rb +37 -0
  10. data/data/mod_spox/extras/Bash.rb +55 -0
  11. data/data/mod_spox/extras/Bouncer.rb +220 -0
  12. data/data/mod_spox/extras/Bullshit.rb +19 -0
  13. data/data/mod_spox/extras/Bytes.rb +11 -0
  14. data/data/mod_spox/extras/Confess.rb +244 -0
  15. data/data/mod_spox/extras/DCC.rb +182 -0
  16. data/data/mod_spox/extras/DevWatch.rb +153 -0
  17. data/data/mod_spox/extras/DownForEveryoneOrJustMe.rb +47 -0
  18. data/data/mod_spox/extras/EightBall.rb +33 -0
  19. data/data/mod_spox/extras/FML.rb +35 -0
  20. data/data/mod_spox/extras/FloodKicker.rb +129 -0
  21. data/data/mod_spox/extras/Fortune.rb +76 -0
  22. data/data/mod_spox/extras/GoogleIt.rb +13 -0
  23. data/data/mod_spox/extras/Headers.rb +59 -0
  24. data/data/mod_spox/extras/Karma.rb +302 -0
  25. data/data/mod_spox/extras/Locator.rb +44 -0
  26. data/data/mod_spox/extras/Logger.rb +182 -0
  27. data/data/mod_spox/extras/LolSpeak.rb +21 -0
  28. data/data/mod_spox/extras/NickServ.rb +84 -0
  29. data/data/mod_spox/extras/PhpCli.rb +308 -0
  30. data/data/mod_spox/extras/PhpFuncLookup.rb +297 -0
  31. data/data/mod_spox/extras/Pinger.rb +11 -0
  32. data/data/mod_spox/extras/Quotes.rb +79 -0
  33. data/data/mod_spox/extras/RegexTracker.rb +158 -0
  34. data/data/mod_spox/extras/Roulette.rb +267 -0
  35. data/data/mod_spox/extras/RubyCli.rb +93 -0
  36. data/data/mod_spox/extras/Search.rb +49 -0
  37. data/data/mod_spox/extras/Seen.rb +150 -0
  38. data/data/mod_spox/extras/Slashdot.rb +35 -0
  39. data/data/mod_spox/extras/SlashdotHeadlineGenerator.rb +500 -0
  40. data/data/mod_spox/extras/Talk.rb +32 -0
  41. data/data/mod_spox/extras/Topten.rb +103 -0
  42. data/data/mod_spox/extras/TracTicket.rb +66 -0
  43. data/data/mod_spox/extras/Translate.rb +132 -0
  44. data/data/mod_spox/extras/Twitter.rb +458 -0
  45. data/data/mod_spox/extras/UrbanDictionary.rb +55 -0
  46. data/data/mod_spox/extras/Weather.rb +55 -0
  47. data/data/mod_spox/plugins/Authenticator.rb +289 -0
  48. data/data/mod_spox/plugins/Banner.rb +585 -0
  49. data/data/mod_spox/plugins/BotNick.rb +18 -0
  50. data/data/mod_spox/plugins/Helper.rb +49 -0
  51. data/data/mod_spox/plugins/Initializer.rb +35 -0
  52. data/data/mod_spox/plugins/Joiner.rb +23 -0
  53. data/data/mod_spox/plugins/Nicker.rb +14 -0
  54. data/data/mod_spox/plugins/Parter.rb +23 -0
  55. data/data/mod_spox/plugins/Permissions.rb +60 -0
  56. data/data/mod_spox/plugins/PluginLoader.rb +180 -0
  57. data/data/mod_spox/plugins/Ponger.rb +70 -0
  58. data/data/mod_spox/plugins/PoolConfig.rb +52 -0
  59. data/data/mod_spox/plugins/Quitter.rb +15 -0
  60. data/data/mod_spox/plugins/Servers.rb +57 -0
  61. data/data/mod_spox/plugins/Status.rb +31 -0
  62. data/data/mod_spox/plugins/Triggers.rb +85 -0
  63. data/lib/mod_spox/BaseConfig.rb +51 -0
  64. data/lib/mod_spox/Bot.rb +604 -0
  65. data/lib/mod_spox/BotConfig.rb +65 -0
  66. data/lib/mod_spox/ConfigurationWizard.rb +180 -0
  67. data/lib/mod_spox/Database.rb +51 -0
  68. data/lib/mod_spox/Exceptions.rb +84 -0
  69. data/lib/mod_spox/Helpers.rb +122 -0
  70. data/lib/mod_spox/Loader.rb +60 -0
  71. data/lib/mod_spox/Logger.rb +37 -0
  72. data/lib/mod_spox/MessageFactory.rb +112 -0
  73. data/lib/mod_spox/Pipeline.rb +207 -0
  74. data/lib/mod_spox/Plugin.rb +97 -0
  75. data/lib/mod_spox/PluginHolder.rb +22 -0
  76. data/lib/mod_spox/PluginManager.rb +257 -0
  77. data/lib/mod_spox/PriorityQueue.rb +69 -0
  78. data/lib/mod_spox/Socket.rb +201 -0
  79. data/lib/mod_spox/Sockets.rb +226 -0
  80. data/lib/mod_spox/Timer.rb +60 -0
  81. data/lib/mod_spox/Version.rb +14 -0
  82. data/lib/mod_spox/handlers/BadNick.rb +19 -0
  83. data/lib/mod_spox/handlers/Bounce.rb +24 -0
  84. data/lib/mod_spox/handlers/Created.rb +27 -0
  85. data/lib/mod_spox/handlers/Handler.rb +39 -0
  86. data/lib/mod_spox/handlers/Invite.rb +28 -0
  87. data/lib/mod_spox/handlers/Join.rb +38 -0
  88. data/lib/mod_spox/handlers/Kick.rb +36 -0
  89. data/lib/mod_spox/handlers/LuserChannels.rb +19 -0
  90. data/lib/mod_spox/handlers/LuserClient.rb +18 -0
  91. data/lib/mod_spox/handlers/LuserMe.rb +16 -0
  92. data/lib/mod_spox/handlers/LuserOp.rb +19 -0
  93. data/lib/mod_spox/handlers/LuserUnknown.rb +19 -0
  94. data/lib/mod_spox/handlers/Mode.rb +62 -0
  95. data/lib/mod_spox/handlers/Motd.rb +38 -0
  96. data/lib/mod_spox/handlers/MyInfo.rb +24 -0
  97. data/lib/mod_spox/handlers/Names.rb +86 -0
  98. data/lib/mod_spox/handlers/Nick.rb +50 -0
  99. data/lib/mod_spox/handlers/NickInUse.rb +19 -0
  100. data/lib/mod_spox/handlers/Notice.rb +35 -0
  101. data/lib/mod_spox/handlers/Part.rb +39 -0
  102. data/lib/mod_spox/handlers/Ping.rb +25 -0
  103. data/lib/mod_spox/handlers/Pong.rb +23 -0
  104. data/lib/mod_spox/handlers/Privmsg.rb +39 -0
  105. data/lib/mod_spox/handlers/Quit.rb +29 -0
  106. data/lib/mod_spox/handlers/Topic.rb +38 -0
  107. data/lib/mod_spox/handlers/Welcome.rb +30 -0
  108. data/lib/mod_spox/handlers/Who.rb +83 -0
  109. data/lib/mod_spox/handlers/Whois.rb +117 -0
  110. data/lib/mod_spox/handlers/YourHost.rb +20 -0
  111. data/lib/mod_spox/messages/Messages.rb +6 -0
  112. data/lib/mod_spox/messages/incoming/BadNick.rb +16 -0
  113. data/lib/mod_spox/messages/incoming/Bounce.rb +18 -0
  114. data/lib/mod_spox/messages/incoming/Created.rb +15 -0
  115. data/lib/mod_spox/messages/incoming/Invite.rb +21 -0
  116. data/lib/mod_spox/messages/incoming/Join.rb +19 -0
  117. data/lib/mod_spox/messages/incoming/Kick.rb +26 -0
  118. data/lib/mod_spox/messages/incoming/LuserChannels.rb +15 -0
  119. data/lib/mod_spox/messages/incoming/LuserClient.rb +24 -0
  120. data/lib/mod_spox/messages/incoming/LuserMe.rb +18 -0
  121. data/lib/mod_spox/messages/incoming/LuserOp.rb +15 -0
  122. data/lib/mod_spox/messages/incoming/LuserUnknown.rb +15 -0
  123. data/lib/mod_spox/messages/incoming/Message.rb +22 -0
  124. data/lib/mod_spox/messages/incoming/Mode.rb +42 -0
  125. data/lib/mod_spox/messages/incoming/Motd.rb +18 -0
  126. data/lib/mod_spox/messages/incoming/MyInfo.rb +24 -0
  127. data/lib/mod_spox/messages/incoming/Names.rb +24 -0
  128. data/lib/mod_spox/messages/incoming/Nick.rb +26 -0
  129. data/lib/mod_spox/messages/incoming/NickInUse.rb +15 -0
  130. data/lib/mod_spox/messages/incoming/Notice.rb +9 -0
  131. data/lib/mod_spox/messages/incoming/Part.rb +21 -0
  132. data/lib/mod_spox/messages/incoming/Ping.rb +18 -0
  133. data/lib/mod_spox/messages/incoming/Pong.rb +9 -0
  134. data/lib/mod_spox/messages/incoming/Privmsg.rb +90 -0
  135. data/lib/mod_spox/messages/incoming/Quit.rb +18 -0
  136. data/lib/mod_spox/messages/incoming/Topic.rb +21 -0
  137. data/lib/mod_spox/messages/incoming/TopicInfo.rb +21 -0
  138. data/lib/mod_spox/messages/incoming/Welcome.rb +27 -0
  139. data/lib/mod_spox/messages/incoming/Who.rb +18 -0
  140. data/lib/mod_spox/messages/incoming/Whois.rb +49 -0
  141. data/lib/mod_spox/messages/incoming/YourHost.rb +18 -0
  142. data/lib/mod_spox/messages/internal/BotInitialized.rb +11 -0
  143. data/lib/mod_spox/messages/internal/ChangeNick.rb +15 -0
  144. data/lib/mod_spox/messages/internal/Connected.rb +20 -0
  145. data/lib/mod_spox/messages/internal/ConnectionFailed.rb +23 -0
  146. data/lib/mod_spox/messages/internal/DCCListener.rb +12 -0
  147. data/lib/mod_spox/messages/internal/DCCRequest.rb +12 -0
  148. data/lib/mod_spox/messages/internal/DCCSocket.rb +19 -0
  149. data/lib/mod_spox/messages/internal/Disconnected.rb +8 -0
  150. data/lib/mod_spox/messages/internal/Disconnecting.rb +8 -0
  151. data/lib/mod_spox/messages/internal/EstablishConnection.rb +22 -0
  152. data/lib/mod_spox/messages/internal/HaltBot.rb +8 -0
  153. data/lib/mod_spox/messages/internal/NickRequest.rb +9 -0
  154. data/lib/mod_spox/messages/internal/NickResponse.rb +15 -0
  155. data/lib/mod_spox/messages/internal/PluginLoadRequest.rb +21 -0
  156. data/lib/mod_spox/messages/internal/PluginLoadResponse.rb +17 -0
  157. data/lib/mod_spox/messages/internal/PluginModuleRequest.rb +14 -0
  158. data/lib/mod_spox/messages/internal/PluginModuleResponse.rb +18 -0
  159. data/lib/mod_spox/messages/internal/PluginReload.rb +18 -0
  160. data/lib/mod_spox/messages/internal/PluginRequest.rb +18 -0
  161. data/lib/mod_spox/messages/internal/PluginResponse.rb +21 -0
  162. data/lib/mod_spox/messages/internal/PluginUnloadRequest.rb +9 -0
  163. data/lib/mod_spox/messages/internal/PluginUnloadResponse.rb +9 -0
  164. data/lib/mod_spox/messages/internal/PluginsReady.rb +10 -0
  165. data/lib/mod_spox/messages/internal/QueueSocket.rb +8 -0
  166. data/lib/mod_spox/messages/internal/Reconnect.rb +8 -0
  167. data/lib/mod_spox/messages/internal/Request.rb +15 -0
  168. data/lib/mod_spox/messages/internal/Response.rb +15 -0
  169. data/lib/mod_spox/messages/internal/Shutdown.rb +8 -0
  170. data/lib/mod_spox/messages/internal/SignaturesUpdate.rb +8 -0
  171. data/lib/mod_spox/messages/internal/StatusRequest.rb +10 -0
  172. data/lib/mod_spox/messages/internal/StatusResponse.rb +18 -0
  173. data/lib/mod_spox/messages/internal/TimerAdd.rb +36 -0
  174. data/lib/mod_spox/messages/internal/TimerClear.rb +16 -0
  175. data/lib/mod_spox/messages/internal/TimerRemove.rb +23 -0
  176. data/lib/mod_spox/messages/internal/TimerResponse.rb +34 -0
  177. data/lib/mod_spox/messages/internal/TriggersUpdate.rb +8 -0
  178. data/lib/mod_spox/messages/internal/UnqueueSocket.rb +8 -0
  179. data/lib/mod_spox/messages/outgoing/Admin.rb +15 -0
  180. data/lib/mod_spox/messages/outgoing/Away.rb +11 -0
  181. data/lib/mod_spox/messages/outgoing/ChannelMode.rb +25 -0
  182. data/lib/mod_spox/messages/outgoing/Connect.rb +24 -0
  183. data/lib/mod_spox/messages/outgoing/Die.rb +9 -0
  184. data/lib/mod_spox/messages/outgoing/Info.rb +15 -0
  185. data/lib/mod_spox/messages/outgoing/Invite.rb +19 -0
  186. data/lib/mod_spox/messages/outgoing/Ison.rb +15 -0
  187. data/lib/mod_spox/messages/outgoing/Join.rb +19 -0
  188. data/lib/mod_spox/messages/outgoing/Kick.rb +23 -0
  189. data/lib/mod_spox/messages/outgoing/Kill.rb +19 -0
  190. data/lib/mod_spox/messages/outgoing/Links.rb +19 -0
  191. data/lib/mod_spox/messages/outgoing/List.rb +19 -0
  192. data/lib/mod_spox/messages/outgoing/Lusers.rb +19 -0
  193. data/lib/mod_spox/messages/outgoing/Motd.rb +16 -0
  194. data/lib/mod_spox/messages/outgoing/Names.rb +20 -0
  195. data/lib/mod_spox/messages/outgoing/Nick.rb +16 -0
  196. data/lib/mod_spox/messages/outgoing/Notice.rb +12 -0
  197. data/lib/mod_spox/messages/outgoing/Oper.rb +19 -0
  198. data/lib/mod_spox/messages/outgoing/Part.rb +19 -0
  199. data/lib/mod_spox/messages/outgoing/Pass.rb +16 -0
  200. data/lib/mod_spox/messages/outgoing/Ping.rb +11 -0
  201. data/lib/mod_spox/messages/outgoing/Pong.rb +17 -0
  202. data/lib/mod_spox/messages/outgoing/Privmsg.rb +43 -0
  203. data/lib/mod_spox/messages/outgoing/Quit.rb +11 -0
  204. data/lib/mod_spox/messages/outgoing/Raw.rb +16 -0
  205. data/lib/mod_spox/messages/outgoing/Rehash.rb +9 -0
  206. data/lib/mod_spox/messages/outgoing/Restart.rb +9 -0
  207. data/lib/mod_spox/messages/outgoing/ServList.rb +19 -0
  208. data/lib/mod_spox/messages/outgoing/Simple.rb +12 -0
  209. data/lib/mod_spox/messages/outgoing/Squery.rb +19 -0
  210. data/lib/mod_spox/messages/outgoing/Squit.rb +19 -0
  211. data/lib/mod_spox/messages/outgoing/Stats.rb +18 -0
  212. data/lib/mod_spox/messages/outgoing/Summon.rb +23 -0
  213. data/lib/mod_spox/messages/outgoing/Time.rb +15 -0
  214. data/lib/mod_spox/messages/outgoing/Topic.rb +19 -0
  215. data/lib/mod_spox/messages/outgoing/Trace.rb +15 -0
  216. data/lib/mod_spox/messages/outgoing/Unaway.rb +9 -0
  217. data/lib/mod_spox/messages/outgoing/User.rb +23 -0
  218. data/lib/mod_spox/messages/outgoing/UserHost.rb +15 -0
  219. data/lib/mod_spox/messages/outgoing/UserMode.rb +19 -0
  220. data/lib/mod_spox/messages/outgoing/Users.rb +15 -0
  221. data/lib/mod_spox/messages/outgoing/Version.rb +16 -0
  222. data/lib/mod_spox/messages/outgoing/Who.rb +23 -0
  223. data/lib/mod_spox/messages/outgoing/WhoWas.rb +23 -0
  224. data/lib/mod_spox/messages/outgoing/Whois.rb +19 -0
  225. data/lib/mod_spox/migrations/001_initialize_models.rb +115 -0
  226. data/lib/mod_spox/migrations/002_persistent_sigs.rb +14 -0
  227. data/lib/mod_spox/migrations/003_auth_restructure.rb +31 -0
  228. data/lib/mod_spox/migrations/004_mode_index_fix.rb +18 -0
  229. data/lib/mod_spox/migrations/005_nick_mode_nopark.rb +18 -0
  230. data/lib/mod_spox/models/Auth.rb +65 -0
  231. data/lib/mod_spox/models/AuthMask.rb +13 -0
  232. data/lib/mod_spox/models/Channel.rb +89 -0
  233. data/lib/mod_spox/models/Config.rb +30 -0
  234. data/lib/mod_spox/models/Group.rb +30 -0
  235. data/lib/mod_spox/models/Models.rb +4 -0
  236. data/lib/mod_spox/models/Nick.rb +195 -0
  237. data/lib/mod_spox/models/NickMode.rb +32 -0
  238. data/lib/mod_spox/models/Server.rb +27 -0
  239. data/lib/mod_spox/models/Setting.rb +52 -0
  240. data/lib/mod_spox/models/Signature.rb +52 -0
  241. data/lib/mod_spox/models/Trigger.rb +9 -0
  242. data/lib/mod_spox/rfc2812.rb +49 -0
  243. data/populate_gemspec.rb +15 -0
  244. data/tests/BotHolder.rb +24 -0
  245. data/tests/handlers/tc_BadNick.rb +21 -0
  246. data/tests/handlers/tc_Created.rb +24 -0
  247. data/tests/handlers/tc_Invite.rb +50 -0
  248. data/tests/handlers/tc_Join.rb +33 -0
  249. data/tests/handlers/tc_Kick.rb +32 -0
  250. data/tests/handlers/tc_Mode.rb +85 -0
  251. data/tests/handlers/tc_Names.rb +35 -0
  252. data/tests/handlers/tc_Nick.rb +55 -0
  253. data/tests/handlers/tc_Part.rb +44 -0
  254. data/tests/handlers/tc_Ping.rb +40 -0
  255. data/tests/handlers/tc_Pong.rb +28 -0
  256. data/tests/handlers/tc_Privmsg.rb +85 -0
  257. data/tests/handlers/tc_Quit.rb +40 -0
  258. data/tests/handlers/tc_Who.rb +50 -0
  259. data/tests/handlers/tc_Whois.rb +61 -0
  260. data/tests/models/tc_Auth.rb +39 -0
  261. data/tests/models/tc_Channel.rb +52 -0
  262. data/tests/models/tc_Config.rb +19 -0
  263. data/tests/models/tc_Nick.rb +144 -0
  264. data/tests/models/tc_NickMode.rb +40 -0
  265. data/tests/models/tc_Setting.rb +21 -0
  266. data/tests/models/tc_Signature.rb +14 -0
  267. data/tests/run_tests.rb +6 -0
  268. metadata +362 -0
@@ -0,0 +1,182 @@
1
+ class ChatLogger < ModSpox::Plugin
2
+
3
+ # This plugin creates a log of conversations the bot sees. It
4
+ # is important to note that the order in which messages are
5
+ # added to the database may not be in order. Due to the
6
+ # async behavior of the pipeline, this plugin may (and most
7
+ # likely will) receive messages out of order. This will be most
8
+ # notable with triggers received and responses from the bot
9
+
10
+ include Models
11
+
12
+ def initialize(pipeline)
13
+ super
14
+ PublicLog.create_table unless PublicLog.table_exists?
15
+ PrivateLog.create_table unless PrivateLog.table_exists?
16
+ @pipeline.hook(self, :log_privmsg, :Incoming_Privmsg)
17
+ @pipeline.hook(self, :log_join, :Incoming_Join)
18
+ @pipeline.hook(self, :log_part, :Incoming_Part)
19
+ @pipeline.hook(self, :log_quit, :Incoming_Quit)
20
+ @pipeline.hook(self, :log_kick, :Incoming_Kick)
21
+ @pipeline.hook(self, :log_mode, :Incoming_Mode)
22
+ @pipeline.hook(self, :log_privmsg, :Incoming_Notice)
23
+ @pipeline.hook(self, :log_outpriv, :Outgoing_Privmsg)
24
+ @pipeline.hook(self, :log_outpriv, :Outgoing_Notice)
25
+ add_sig(:sig => 'seen (\S+)', :method => :seen, :desc => 'Report last sighting of nick', :params => [:nick])
26
+ add_sig(:sig => 'lastspoke (\S+)', :method => :spoke, :desc => 'Report last time nick spoke', :params => [:nick])
27
+ end
28
+
29
+ def log_outpriv(message)
30
+ type = message.is_a?(Messages::Outgoing::Privmsg) ? 'privmsg' : 'notice'
31
+ type = 'action' if message.is_action?
32
+ target = message.target.is_a?(Sequel::Model) ? message.target : Helpers.find_model(message.target)
33
+ if(target.is_a?(Models::Channel))
34
+ PublicLog.new(:message => message.message, :type => type, :sender_id => me.pk,
35
+ :channel_id => target.pk, :received => Time.now).save
36
+ else
37
+ PrivateLog.new(:message => message.message, :type => type, :sender_id => me.pk,
38
+ :receiver_id => target.pk, :received => Time.now).save
39
+ end
40
+ end
41
+
42
+ def log_privmsg(message)
43
+ type = message.is_a?(Messages::Incoming::Privmsg) ? 'privmsg' : 'notice'
44
+ type = 'action' if message.is_action?
45
+ if(message.is_public?)
46
+ PublicLog.new(:message => message.message, :type => type, :sender_id => message.source.pk,
47
+ :channel_id => message.target.pk, :received => message.time).save
48
+ else
49
+ PrivateLog.new(:message => message.message, :type => type, :sender_id => message.source.pk,
50
+ :receiver_id => message.target.pk, :received => message.time).save
51
+ end
52
+ end
53
+
54
+ def log_join(message)
55
+ PublicLog.new(:type => 'join', :sender_id => message.nick.pk, :channel_id => message.channel.pk, :received => message.time).save
56
+ end
57
+
58
+ def log_part(message)
59
+ PublicLog.new(:message => message.reason, :type => 'part', :sender_id => message.nick.pk,
60
+ :channel_id => message.channel.pk, :received => message.time).save
61
+ end
62
+
63
+ def log_quit(message)
64
+ PublicLog.new(:message => message.message, :type => 'quit', :sender_id => message.nick.pk, :received => message.time).save
65
+ end
66
+
67
+ def log_kick(message)
68
+ PublicLog.new(:message => "#{message.kickee.pk}|#{message.reason}", :type => 'kick', :sender_id => message.kicker.pk,
69
+ :channel_id => message.channel.pk, :received => message.time).save
70
+ end
71
+
72
+ # TODO: Fix this
73
+ def log_mode(message)
74
+ # if(message.for_channel?)
75
+ # PublicLog.new(:message => message.mode, :type => 'mode', :sender => message.source.pk,
76
+ # :channel => message.channel.pk, :received => message.time).save
77
+ # else
78
+ # PrivateLog.new(:message => message.mode, :type => 'mode', :sender => message.source.pk,
79
+ # :receiver => message.target.pk, :received => message.time).save
80
+ # end
81
+ end
82
+
83
+ def seen(m, p)
84
+ nick = Helpers.find_model(p[:nick], false)
85
+ if(nick.is_a?(Models::Nick))
86
+ record = PublicLog.filter(:sender_id => nick.pk).order(:received).last
87
+ record_p = PrivateLog.filter(:sender_id => nick.pk).order(:received).last
88
+ record = record_p if !record || (record_p && record && record_p.received > record.received)
89
+ if(record)
90
+ if(record.is_a?(PublicLog))
91
+ case record.values[:type]
92
+ when 'join'
93
+ message = "joining #{record.channel.name}"
94
+ when 'part'
95
+ message = "parting #{record.channel.name} with the message: #{record.message}"
96
+ when 'privmsg'
97
+ message = "in #{record.channel.name} saying: #{record.message}"
98
+ when 'action'
99
+ message = "in #{record.channel.name} saying: * #{p[:nick]} #{record.message}"
100
+ when 'notice'
101
+ message = "in #{record.channel.name} saying: #{record.message}"
102
+ when 'kick'
103
+ if(record.message =~ /^([0-9]+)\|/)
104
+ kickee = Nick[$1.to_i]
105
+ reason = $2
106
+ message = "kicking #{kickee.nick} from #{record.channel.name} (#{record.message})"
107
+ end
108
+ end
109
+ else
110
+ message = "saying to me: #{record.message}"
111
+ end
112
+ reply m.replyto, "I last saw #{p[:nick]} on #{record.received} #{message}"
113
+ else
114
+ reply m.replyto, "\2Error:\2 Failed to find record of #{p[:nick]}"
115
+ end
116
+ else
117
+ reply m.replyto, "\2Error:\2 Failed to find record of #{p[:nick]}"
118
+ end
119
+ end
120
+
121
+ def spoke(m, p)
122
+ nick = Helpers.find_model(p[:nick], false)
123
+ if(nick.is_a?(Models::Nick))
124
+ record = PublicLog.filter(:sender_id => nick.pk).filter("type in ('privmsg', 'action')").order(:received).last
125
+ record_p = PrivateLog.filter(:sender_id => nick.pk).order(:received).last
126
+ record = record_p if !record || (record_p && record && record_p.received > record.received)
127
+ if(record)
128
+ if(record.is_a?(PublicLog))
129
+ reply m.replyto, "I last saw #{p[:nick]} on #{record.received} saying: #{record.values[:type] == 'action' ? "* #{p[:nick]} #{record.message}" : record.message}"
130
+ else
131
+ reply m.replyto, "I last saw #{p[:nick]} on #{record.received} saying to me: #{record.message}"
132
+ end
133
+ else
134
+ reply m.replyto, "\2Error:\2 Failed to find record of #{p[:nick]}"
135
+ end
136
+ else
137
+ reply m.replyto, "\2Error:\2 Failed to find record of #{p[:nick]}"
138
+ end
139
+ end
140
+
141
+ class PrivateLog < Sequel::Model
142
+ set_schema do
143
+ primary_key :id
144
+ text :message, :null => false
145
+ text :type, :null => false, :default => 'privmsg'
146
+ boolean :action, :null => false, :default => false
147
+ timestamp :received, :null => false
148
+ foreign_key :sender_id, :table => :nicks
149
+ foreign_key :receiver_id, :table => :nicks
150
+ end
151
+
152
+ def sender
153
+ Models::Nick[sender_id]
154
+ end
155
+
156
+ def receiver
157
+ Models::Nick[receiver_id]
158
+ end
159
+ end
160
+
161
+ class PublicLog < Sequel::Model
162
+ set_schema do
163
+ primary_key :id
164
+ text :message
165
+ text :type, :null => false, :default => 'privmsg'
166
+ boolean :action, :null => false, :default => false
167
+ timestamp :received, :null => false
168
+ foreign_key :sender_id, :table => :nicks
169
+ foreign_key :channel_id, :table => :channels
170
+ end
171
+
172
+ def sender
173
+ Models::Nick[sender_id]
174
+ end
175
+
176
+ def channel
177
+ Models::Channel[channel_id]
178
+ end
179
+
180
+ end
181
+
182
+ end
@@ -0,0 +1,21 @@
1
+ # IMPORTANT NOTE: This plugin requires installation of the LOLSpeak gem
2
+ class LolSpeak < ModSpox::Plugin
3
+
4
+ include Models
5
+
6
+ def initialize(pipeline)
7
+ super
8
+ begin
9
+ require 'lolspeak'
10
+ rescue Object => boom
11
+ Logger.warn('Error: This plugins requires the lolspeak gem. Please install gem and reload plugin.')
12
+ raise BotException.new("Failed to initialize plugin. Missing lolspeak gem.")
13
+ end
14
+ add_sig(:sig => 'lolspeak (.+)', :method => :translate, :desc => 'Translate text to lolspeak', :params => [:text])
15
+ end
16
+
17
+ def translate(message, params)
18
+ reply message.replyto, "\2lulz:\2 #{params[:text].to_lolspeak}"
19
+ end
20
+
21
+ end
@@ -0,0 +1,84 @@
1
+ require 'mod_spox/messages/outgoing/Privmsg'
2
+ class NickServ < ModSpox::Plugin
3
+
4
+ #TODO: Add support for things like RECOVERY and GHOST
5
+
6
+ def initialize(pipeline)
7
+ super
8
+ admin = Models::Group.find_or_create(:name => 'admin')
9
+ add_sig(:sig => 'nickserv address( \S+)?', :method => :set_address, :group => admin,
10
+ :desc => 'Set/view address to send nickserv info to', :params => [:address])
11
+ add_sig(:sig => 'nickserv combo (\S+) (\S+)', :method => :set_combo, :group => admin,
12
+ :desc => 'Set nick/pass combo', :params => [:nick, :password], :req => 'private')
13
+ add_sig(:sig => 'nickserv show', :method => :output_info, :group => admin,
14
+ :desc => 'Show nickserv info', :req => 'private')
15
+ add_sig(:sig => 'nickserv send', :method => :send_combo, :group => admin,
16
+ :desc => 'Send nickserv info')
17
+ @nickserv = Models::Setting.find_or_create(:name => 'nickserv').value
18
+ unless(@nickserv.is_a?(Hash) && @nickserv.has_key?(:address) && @nickserv.has_key?(:combos))
19
+ @nickserv = {:address => nil, :combos => {}}
20
+ end
21
+ @pipeline.hook(self, :send_nickserv, :Incoming_Welcome)
22
+ end
23
+
24
+ # @nickserv = {:address => 'nickserv@blah', :combos => {'nick' => 'pass'}}
25
+
26
+ def set_address(message, params)
27
+ if(params[:address])
28
+ params[:address].strip!
29
+ @nickserv[:address] = params[:address]
30
+ save_info
31
+ reply message.replyto, "Nickserv address updated to: #{params[:address]}"
32
+ else
33
+ unless(@nickserv[:address].nil?)
34
+ reply message.replyto, "Nickserv address set to: #{@nickserv[:address]}"
35
+ else
36
+ reply message.replyto, "\2Error:\2 Nickserv address has not been set"
37
+ end
38
+ end
39
+ end
40
+
41
+ def set_combo(message, params)
42
+ @nickserv[:combos][params[:nick].to_sym] = params[:password]
43
+ save_info
44
+ reply message.replyto, "Nickserv password saved for nick: \2#{params[:nick]}\2"
45
+ end
46
+
47
+ def output_info(message, params)
48
+ output = ["\2Nickserv information dump:\2"]
49
+ output << "Address used to send identification: #{@nickserv[:address].nil? ? 'unset' : @nickserv[:address]}"
50
+ @nickserv[:combos].each_pair{|k,v| output << "#{k} -> #{v}"}
51
+ reply message.replyto, output
52
+ end
53
+
54
+ def send_combo(message, params)
55
+ output = 'Identification sent to nickserv'
56
+ begin
57
+ identify
58
+ rescue Object => boom
59
+ output = boom.to_s
60
+ ensure
61
+ reply message.replyto, output
62
+ end
63
+ end
64
+
65
+ def send_nickserv(m)
66
+ identify
67
+ end
68
+
69
+ private
70
+
71
+ def save_info
72
+ s = Models::Setting.filter(:name => 'nickserv').first.update(:value => @nickserv)
73
+ end
74
+
75
+ def identify
76
+ raise Exceptions::BotException.new('No address set for nickserv') if @nickserv[:address].nil?
77
+ if(@nickserv[:combos].has_key?(me.nick.to_sym))
78
+ @pipeline << Messages::Outgoing::Privmsg.new(@nickserv[:address], "IDENTIFY #{@nickserv[:combos][me.nick.to_sym]}")
79
+ else
80
+ raise Exceptions::BotException.new("No nickserv password available for: #{me.nick.nick}")
81
+ end
82
+ end
83
+
84
+ end
@@ -0,0 +1,308 @@
1
+ # IMPORTANT NOTE: This plugin will only function if the PHP executable can be located
2
+ class PhpCli < ModSpox::Plugin
3
+
4
+ include Models
5
+ include Messages::Outgoing
6
+
7
+ def initialize(pipeline)
8
+ super(pipeline)
9
+ @path = Config.val(:plugin_directory) + '/phpcli'
10
+ @botini = @path + '/bot.ini'
11
+ unless(File.directory?(@path))
12
+ FileUtils.mkdir_p(@path)
13
+ end
14
+ @exec = Config.val(:phpexec)
15
+ if(@exec.nil?)
16
+ result = Helpers.safe_exec('which php')
17
+ raise NoInterpreter.new if result.empty?
18
+ @exec = 'php'
19
+ end
20
+ unless File.exists?(@botini)
21
+ ini = File.new(@botini, 'w')
22
+ ini.write($ini)
23
+ ini.close
24
+ end
25
+ PhpFunction.create_table unless PhpFunction.table_exists?
26
+ php = Group.find_or_create(:name => 'php')
27
+ phpfunc = Group.find_or_create(:name => 'phpfunc')
28
+ admin = Group.filter(:name => 'admin').first
29
+ add_sig(:sig => 'php (on|off)', :method => :set_channel, :group => admin, :desc => 'Add or remove channel from allowing PHP command', :params => [:action])
30
+ add_sig(:sig => 'php (?!on|off)(.+)', :method => :execute_php, :group => php, :desc => 'Execute PHP code', :params => [:code])
31
+ add_sig(:sig => 'phpq (?!on|off)(.+)', :method => :quiet_php, :group => php, :params => [:code], :desc => 'Execute PHP quietly')
32
+ add_sig(:sig => 'pf add (.+)', :method => :add, :params => [:function], :group => phpfunc, :desc => 'Add a custom PHP function')
33
+ add_sig(:sig => 'pf remove (\d+)', :method => :remove, :params => [:func_id], :group => phpfunc, :desc => 'Remove a custom PHP function')
34
+ add_sig(:sig => 'pf list', :method => :list, :desc => 'List custom PHP functions')
35
+ add_sig(:sig => 'pf edit (.+)', :method => :edit, :params => [:function], :group => phpfunc, :desc => 'Overwrite existing custom PHP function')
36
+ add_sig(:sig => 'pf show (\d+)', :method => :show, :params => [:func_id], :group => phpfunc, :desc => 'Show given PHP function source')
37
+ add_sig(:sig => 'phpexec( (\S+))?', :method => :set_exec, :params => [:exec], :group => admin, :desc => 'Set custom PHP executable')
38
+ @customfuncs = []
39
+ populate_customs
40
+ @channels = Setting.filter(:name => 'phpcli').first
41
+ @channels = @channels.nil? ? [] : @channels.value
42
+ end
43
+
44
+ def set_exec(m, params)
45
+ if(params[:exec])
46
+ path = params[:exec].strip
47
+ unless(path == 'none')
48
+ if(File.executable?(path))
49
+ Config.set(:phpexec, path)
50
+ @exec = path
51
+ information m.replyto, "PHP executable path has been updated: #{@exec}"
52
+ else
53
+ error m.replyto, 'Path given is not a valid executable path'
54
+ end
55
+ else
56
+ Config.filter(:name => 'phpexec').destroy
57
+ @exec = 'php'
58
+ information m.replyto, 'Bot is now using default php executable'
59
+ end
60
+ else
61
+ information m.replyto, "Executable path is: #{@exec}"
62
+ end
63
+ end
64
+
65
+ def set_channel(message, params)
66
+ return unless message.is_public?
67
+ if(params[:action] == 'on')
68
+ unless(@channels.include?(message.target.pk))
69
+ @channels << message.target.pk
70
+ tmp = Setting.find_or_create(:name => 'phpcli')
71
+ tmp.value = @channels
72
+ tmp.save
73
+ end
74
+ reply message.replyto, 'PHP command now active'
75
+ else
76
+ unless(@channels.include?(message.target.pk))
77
+ reply message.replyto, 'PHP command is not currently active in this channel'
78
+ else
79
+ @channels.delete(message.target.pk)
80
+ tmp = Setting.find_or_create(:name => 'phpcli')
81
+ tmp.value = @channels
82
+ tmp.save
83
+ reply message.replyto, 'PHP command is now disabled'
84
+ end
85
+ end
86
+ end
87
+
88
+ def quiet_php(message, params)
89
+ execute_php(message, params, true)
90
+ end
91
+
92
+ def execute_php(message, params, shh=false)
93
+ return unless @channels.include?(message.target.pk)
94
+ filepath = @path + "/#{rand(99999)}.bot.php"
95
+ file = File.open(filepath, 'w')
96
+ file.write("<? $_SERVER = $_ENV = $GLOBALS = array(); #{@customfuncs.join(' ')} #{params[:code]} ?>")
97
+ file.close
98
+ begin
99
+ output = Helpers.safe_exec("#{@exec} -c #{@path}/bot.ini -d max_execution_time=10 #{filepath} 2>&1 | head -n 4")
100
+ if(output =~ /^sh: line [0-9]+:(.*)$/)
101
+ output = $1
102
+ end
103
+ if(output =~ /^(Fatal error|Warning|Parse error): (.+?) in .*? on line [0-9]+[\n|\r]*(.*)$/)
104
+ warning = $2
105
+ type = $1
106
+ output = $3
107
+ end
108
+ if(output.length > 300)
109
+ reply message.replyto, "#{message.source.nick}: Your result has been truncated. Don't print so much."
110
+ output = output.slice(0, 300)
111
+ end
112
+ if(!warning.nil?)
113
+ reply message.replyto, "PHP #{type}: "+warning
114
+ end
115
+ if(warning.nil? || type !~ /(Fatal|Parse)/)
116
+ reply message.replyto, "#{shh ? '' : 'Result: '}"+output
117
+ end
118
+ File.delete(filepath)
119
+ rescue Timeout::Error => boom
120
+ reply message.replyto, "\2Error:\2 Timeout reached: #{boom}"
121
+ rescue Object => boom
122
+ reply message.replyto, "\2Error:\2 Script execution terminated. (#{boom})"
123
+ File.delete(filepath)
124
+ end
125
+ end
126
+
127
+ def add(m, params)
128
+ if(params[:function].scan(/function\s+([^\(]+)\(/).size > 1)
129
+ error m.replyto, 'Only one function can be added at a time'
130
+ return
131
+ end
132
+ if(params[:function] =~ /^function\s+([^\(]+)\(/)
133
+ name = $1.downcase
134
+ f = PhpFunction.filter(:name => name).first
135
+ unless(f)
136
+ begin
137
+ parse(params[:function])
138
+ save(params[:function], name, m.source)
139
+ information m.replyto, "New function \2#{name}\2 added to custom PHP functions"
140
+ populate_customs
141
+ rescue Object => boom
142
+ error m.replyto, "Failed to add function #{name}. Error: #{boom}"
143
+ end
144
+ else
145
+ error m.replyto, "Function with name: #{name} already exists"
146
+ end
147
+ else
148
+ error m.replyto, "Function is not in proper format"
149
+ end
150
+ end
151
+
152
+ def remove(m, params)
153
+ f = PhpFunction[params[:func_id].to_i]
154
+ if(f)
155
+ name = f.name
156
+ f.destroy
157
+ information m.replyto, "Function \2#{name}\2 has been removed"
158
+ populate_customs
159
+ else
160
+ error m.replyto, "Failed to locate function with ID: #{params[:func_id]}"
161
+ end
162
+ end
163
+
164
+ def list(m, params)
165
+ output = ["\2Custom PHP functions:\2"]
166
+ PhpFunction.all.each do |f|
167
+ output << "\2ID:\2 #{f.pk} \2Name:\2 #{f.name} \2Author:\2 #{f.nick.nick} \2Added:\2 #{f.added.strftime("%Y/%m/%d-%H:%M:%S")}"
168
+ end
169
+ reply m.replyto, output
170
+ end
171
+
172
+ def edit(m, params)
173
+ if(params[:function] =~ /^function\s+([^\(]+)\(/)
174
+ name = $1.downcase
175
+ begin
176
+ parse(params[:function])
177
+ save(params[:function], name, m.source)
178
+ information m.replyto, "New function \2#{name}\2 added to custom PHP functions"
179
+ populate_customs
180
+ rescue Object => boom
181
+ error m.replyto, "Failed to add function #{name}. Error: #{boom}"
182
+ end
183
+ else
184
+ error m.replyto, "Function is not in proper format"
185
+ end
186
+ end
187
+
188
+ def show(m, params)
189
+ f = PhpFunction[params[:func_id].to_i]
190
+ if(f)
191
+ reply m.replyto, ["Source for function \2#{f.name}\2:", f.php_function]
192
+ else
193
+ error m.replyto, "Failed to find custom PHP function with ID: #{params[:func_id]}"
194
+ end
195
+ end
196
+
197
+ def parse(func)
198
+ filepath = @path + "/#{rand(99999)}.bot.php"
199
+ file = File.open(filepath, 'w')
200
+ file.write("<? #{func} ?>")
201
+ file.close
202
+ output = Helpers.safe_exec("php -l #{filepath} 2>&1 | head -n 4").strip.gsub(/\s{2,}/, ' ').gsub(/[\r\n]+/, ' ')
203
+ File.delete(filepath)
204
+ if(output =~ /(Parse error.+) in/)
205
+ raise "#{$1}"
206
+ end
207
+ end
208
+
209
+ def save(func, name, nick)
210
+ f = PhpFunction.filter(:name => name).first
211
+ f = PhpFunction.new unless f
212
+ f.name = name
213
+ f.php_function = func
214
+ f.added = ::Time.now
215
+ f.nick = nick
216
+ f.save
217
+ end
218
+
219
+ def populate_customs
220
+ @customfuncs = []
221
+ PhpFunction.all.each{|f| @customfuncs << f.php_function }
222
+ end
223
+
224
+ class NoInterpreter < Exceptions::BotException
225
+ end
226
+
227
+ class PhpFunction < Sequel::Model
228
+ set_schema do
229
+ text :php_function, :null => false
230
+ varchar :name, :null => false, :unique => true
231
+ timestamp :added, :null => false
232
+ foreign_key :nick_id, :null => false
233
+ primary_key :id
234
+ end
235
+
236
+ Sequel::Model.plugin :serialization, :marshal, :php_function
237
+ # serialize(:php_function, :format => :marshal)
238
+
239
+ def nick
240
+ Models::Nick[nick_id]
241
+ end
242
+
243
+ def nick=(n)
244
+ values[:nick_id] = n.pk
245
+ end
246
+ end
247
+
248
+ end
249
+
250
+ $ini = <<EOF
251
+ [PHP]
252
+ engine = On
253
+ zend.ze1_compatibility_mode = Off
254
+ short_open_tag = On
255
+ asp_tags = Off
256
+ precision = 12
257
+ y2k_compliance = On
258
+ output_buffering = Off
259
+ zlib.output_compression = Off
260
+ implicit_flush = Off
261
+ unserialize_callback_func=
262
+ serialize_precision = 100
263
+ allow_call_time_pass_reference = On
264
+ safe_mode = On
265
+ safe_mode_gid = On
266
+ safe_mode_include_dir = /tmp/mod_spox/php
267
+ safe_mode_exec_dir = /tmp/mod_spox/php
268
+ safe_mode_allowed_env_vars = PHP_
269
+ safe_mode_protected_env_vars = LD_LIBRARY_PATH
270
+ open_basedir = /tmp/mod_spox
271
+ disable_functions = fscanf fputs chown chmod copy delete fflush file flock ftell glob link fseek lstat move_uploaded_file rename realpath set_file_buffer touch fprintf chgrp fgetss readfile dio_close dio_fnctl dio_open dio_read dio_seek dio_stat dio_tcsetattr dio_truncate dio_write chdir chroot dir closedir getcwd opendir readdir rewinddir scandir posix_kill posix_access posix_ctermid posix_get_last_error posix_getcwd posix_getegid posix_geteuid posix_getgid posix_getgrgid posix_getgrnam posix_getgroups posix_getlogin posix_getpgid posix_getpgrp posix_getpid posix_getppid posix_getpwnam posix_getpwuid posix_getwuid posix_getrlimit posix_getsid posix_getuid posix_isatty posix_mkfifo posix_mknod posix_setegid posix_setgid posix_setpgid posix_setsid posix_setuid posix_strerror posix_times posix_ttyname posix_uname expect_expectl expect_popen sleep time_sleep_until usleep pfsockopen fsockopen openlog debugger_on proc_open pclose popen fsockopen fread set_time_limit ini_set ini_alter ini_restore exec system passthru proc_close proc_nice proc_open proc_terminiate shell_exec sleep usleep pcntl_fork pcntl_exec pcntl_alarm pcntl_getpriority pcntl_setpriority pcntl_waitpid pcntl_wexitstatus pcntl_wifexited pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig pcntl_wtermsig readline_add_history readline_callback_handler_install readline_callback_handler_remove readline_callback_read_char readline_clear_history readline_completion_function readline_info readline_list_history readline_on_new_line readline_read_history readline_redisplay readline_write_history readline dl set_include_path set_magic_quotes_runtime file_put_contents fwrite fputs copy fputcsv tmpfile symlink tempnam mysql_connect unlink putenv ftp_connect socket_create socket_create socket_close socket_accept socket_bind socket_close socket_connect socket_create_listen socket_create_pair socket_get_option socket_listen socket_read socket_recv socket_select socket_send socket_sendto shmop_close shmop_open shmop_delete shmop_read shmop_size shmop_write msg_get_queue msg_receive msg_remove_queue msg_send msg_set_queue msg_stat_queue msg_acquire sem_aquire sem_release sem_get sem_remove mail time_nanosleep usleep include include_once require require_once ftp_alloc ftp_cdup ftp_chdir ftp_chmod ftp_close ftp_connect ftp_delete ftp_exec ftp_fget ftp_fput ftp_get ftp_get_option ftp_login ftp_mdtm ftp_mkdir ftp_nb_continue ftp_nb_fget ftp_nb_fput ftp_nb_get ftp_nb_put
272
+ disable_classes = dir
273
+ expose_php = On
274
+ max_execution_time = 10
275
+ max_input_time = 20
276
+ memory_limit = 4M
277
+ error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT
278
+ display_errors = On
279
+ display_startup_errors = Off
280
+ log_errors = Off
281
+ log_errors_max_len = 1024
282
+ ignore_repeated_errors = Off
283
+ ignore_repeated_source = Off
284
+ report_memleaks = On
285
+ track_errors = Off
286
+ variables_order = "EGPCS"
287
+ register_globals = Off
288
+ register_long_arrays = On
289
+ register_argc_argv = On
290
+ post_max_size = 8M
291
+ magic_quotes_gpc = On
292
+ magic_quotes_runtime = Off
293
+ magic_quotes_sybase = Off
294
+ auto_prepend_file =
295
+ auto_append_file =
296
+ default_mimetype = "text/html"
297
+ include_path = ".:/usr/share/php"
298
+ doc_root = /tmp/mod_spox/php
299
+ user_dir = /tmp/mod_spox/php
300
+ enable_dl = On
301
+ file_uploads = Off
302
+ allow_url_fopen = Off
303
+ default_socket_timeout = 10
304
+ define_syslog_variables = Off
305
+ sendmail_path = /dev/null
306
+ [Sockets]
307
+ sockets.use_system_read = On
308
+ EOF