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,297 @@
1
+ require 'cgi'
2
+ require 'open-uri'
3
+
4
+ # Inspired from an old plugin for the original mod_spox
5
+ # Original development: spox & Ryan "pizza_milkshake" Flynn
6
+ # Ported: 2008
7
+
8
+ class PhpFuncLookup < ModSpox::Plugin
9
+
10
+ include Models
11
+
12
+ def initialize(pipeline)
13
+ super(pipeline)
14
+ setup_setting
15
+ @path = Setting.val(:phpfunc)[:directory]
16
+ @trigger = Setting.val(:phpfunc)[:trigger]
17
+ @manual = "#{@path}/html"
18
+ @classlist = []
19
+ fetch_manual unless File.exists?("#{@path}/manual.tar.gz")
20
+ @ops = {
21
+ "-" => [ "arithmetic", "Subtraction or Negation", "3 - 2 == 1" ],
22
+ "+" => [ "arithmetic", "Addition", "3 + 2 == 5" ],
23
+ "*" => [ "arithmetic", "Multiplication", "3 * 2 == 6" ],
24
+ "/" => [ "arithmetic", "Division", "3 / 2 == 1.5" ],
25
+ "%" => [ "arithmetic", "Modulus", "3 % 2 == 1" ],
26
+ "=" => [ "assignment", "Assignment", "$foo = 1; -> $foo == 1" ],
27
+ "&" => [
28
+ [ "bitwise", "references" ],
29
+ [ "Bitwise And", "Reference" ],
30
+ [ "0x3 & 0x1 -> 1", "$foo=1; $bar=&$foo; $bar++; -> $foo == 2" ]
31
+ ],
32
+ "|" => [ "bitwise", "Bitwise Or", "" ],
33
+ "^" => [ "bitwise", "Bitwise Xor", "" ],
34
+ "~" => [ "bitwise", "Bitwise Not", "" ],
35
+ "<<" => [ "bitwise", "Bitwise Shift left", "" ],
36
+ ">>" => [ "bitwise", "Bitwise Shift right", "" ],
37
+ "==" => [ "comparison", "Equal", "" ],
38
+ "===" => [ "comparison", "Identical", "" ],
39
+ "!=" => [ "comparison", "Not Equal", "" ],
40
+ "<>" => [ "comparison", "Not Equal", "" ],
41
+ "!==" => [ "comparison", "Not Identical", "" ],
42
+ "<" => [ "comparison", "Less Than", "" ],
43
+ ">" => [ "comparison", "Greater Than", "" ],
44
+ "<=" => [ "comparison", "Less Than Or Equal To", "" ],
45
+ ">=" => [ "comparison", "Greater Than Or Equal To", "" ],
46
+ "@" => [ "errorcontrol","Error Control", "" ],
47
+ "`" => [ "execution", "Execution", "" ],
48
+ "++" => [ "increment", "Pre- or Post-Increment", "" ],
49
+ "--" => [ "increment", "Pre- or Post-Decrement", "" ],
50
+ "and" => [ "logical", "And", "" ],
51
+ "or" => [ "logical", "Or", "" ],
52
+ "xor" => [ "logical", "Xor", "" ],
53
+ "!" => [ "logical", "Not", "" ],
54
+ "&&" => [ "logical", "And", "" ],
55
+ "||" => [ "logical", "Or", "" ],
56
+ "." => [ "string", "Concatenation", "" ],
57
+ ".=" => [ "string", "Concatenation Assignment", "" ],
58
+ "instanceof" => [ "type", "Instance Of", "" ],
59
+ "new" => [ "", "New Object", "" ],
60
+ "+=" => [ "assignment", "Addition Assignment", "" ],
61
+ "-=" => [ "assignment", "Subtraction Assignment", "" ],
62
+ "/=" => [ "assignment", "Division Assignment", "" ],
63
+ "*=" => [ "assignment", "Multiplication Assignment", "" ],
64
+ "%=" => [ "assignment", "Modulus Assignment", "" ],
65
+ "->" => [ "?", "Object member accessor thingy","" ],
66
+ }
67
+ admin = Group.filter(:name => 'admin').first
68
+ add_sig(:sig => 'pfunc (\S+)', :method => :phpfunc, :desc => 'Lookup PHP function', :params => [:name])
69
+ add_sig(:sig => 'fetch php manual', :method => :fetch, :group => admin, :desc => 'Download and extract PHP manual')
70
+ add_sig(:sig => 'pfunc trigger (\S+)', :method => :set_trigger, :group => admin, :desc => 'Set the trigger for auto-lookups', :params => [:trigger])
71
+ add_sig(:sig => 'pfunc show trigger', :method => :show_trigger, :desc => 'Show current trigger')
72
+ add_sig(:sig => 'pfunc (add|remove) (\S+)', :method => :set_channels, :group => admin, :desc => 'Add or remove channels from auto-lookups', :params => [:action, :channel])
73
+ add_sig(:sig => 'pfunc show channels', :method => :list_channels, :desc => 'Show channels with auto lookup enabled')
74
+ @pipeline.hook(self, :listen, :Incoming_Privmsg)
75
+ populate_classes
76
+ end
77
+
78
+ def phpfunc(m, params)
79
+ name = params[:name].downcase
80
+ Logger.info "phpfunc name=#{name}"
81
+ if name =~ /^\S+$/ && name =~ /\*/
82
+ parse_wildcard(m, name)
83
+ elsif name =~ /^\$/
84
+ parse_predefined(m, name)
85
+ elsif name =~ /^\S+$/ && filename = find_control_file(name)
86
+ parse_control(m, name, filename)
87
+ elsif name =~ /^\S+$/ && filename = find_function_file(name)
88
+ parse_function(m, name, filename)
89
+ elsif @ops.has_key?(name)
90
+ parse_operator(m, name)
91
+ end
92
+ end
93
+
94
+ def fetch(m, params)
95
+ reply m.replyto, "Fetching PHP manual (This could take a few minutes)"
96
+ fetch_manual(m)
97
+ end
98
+
99
+ def listen(m)
100
+ if(m.target.is_a?(Channel) && Setting.val(:phpfunc)[:channels].include?(m.target.pk))
101
+ if m.message =~ /^#{Regexp.escape(@trigger)}(\S+)$/
102
+ phpfunc(m, {:name => $1})
103
+ end
104
+ end
105
+ end
106
+
107
+ def set_trigger(message, params)
108
+ vals = Setting.val(:phpfunc)
109
+ vals[:trigger] = params[:trigger]
110
+ Setting.filter(:name => 'phpfunc').first.value = vals
111
+ @trigger = params[:trigger]
112
+ reply message.replyto, "PHP function lookup trigger set to: #{params[:trigger]}"
113
+ end
114
+
115
+ def set_channels(message, params)
116
+ channel = Channel.filter(:name => params[:channel]).first
117
+ if(channel)
118
+ vals = Setting.val(:phpfunc)
119
+ if(params[:action] == 'add')
120
+ vals[:channels] << channel.pk unless Setting.val(:phpfunc)[:channels].include?(channel.pk)
121
+ reply message.replyto, "Channel \2#{params[:channel]}\2 added to PHP auto lookup"
122
+ else
123
+ vals[:channels].delete(channel.pk) if Setting.val(:phpfunc)[:channels].include?(channel.pk)
124
+ reply message.replyto, "Channel \2#{params[:channel]}\2 has been removed from PHP auto lookup"
125
+ end
126
+ Setting.filter(:name => 'phpfunc').first.value = vals
127
+ else
128
+ reply message.replyto, "Error: No record of channel #{params[:channel]}"
129
+ end
130
+ end
131
+
132
+ def list_channels(message, params)
133
+ if(Setting.val(:phpfunc)[:channels].size > 0)
134
+ chans = []
135
+ Setting.val(:phpfunc)[:channels].each do |id|
136
+ chans << Channel[id].name
137
+ end
138
+ reply message.replyto, "PHP auto lookup enabled channels: #{chans.join(', ')}"
139
+ else
140
+ reply message.replyto, 'No channels currently enabled for PHP auto lookup'
141
+ end
142
+ end
143
+
144
+ def show_trigger(message, p)
145
+ reply message.replyto, "PHP auto lookup trigger: \2#{Setting.val(:phpfunc)[:trigger]}\2"
146
+ end
147
+
148
+ private
149
+
150
+ def find_function_file(name)
151
+ Dir.new(@manual).each do |filename|
152
+ return filename if filename.downcase == "function.#{name.gsub(/(_|->)/, '-').downcase}.html"
153
+ end
154
+ return nil
155
+ end
156
+
157
+ def find_control_file(name)
158
+ Dir.new(@manual).each do |filename|
159
+ return filename if filename.downcase == "control-structures.#{name}.html"
160
+ end
161
+ return nil
162
+ end
163
+
164
+ def fetch_manual(message=nil, params=nil)
165
+ Thread.new do
166
+ Logger.info 'Fetching PHP manual from http://us.php.net'
167
+ open("#{@path}/manual.tar.gz", 'w').write(open('http://us.php.net/distributions/manual/php_manual_en.tar.gz').read)
168
+ Dir.chdir(@path)
169
+ Helpers.safe_exec("tar -xzf #{@path}/manual.tar.gz", 60)
170
+ Logger.info "PHP manual fetching complete."
171
+ reply message.replyto, "PHP manual fetch is now complete" unless message.nil?
172
+ end
173
+ end
174
+
175
+ def setup_setting
176
+ s = Setting.filter(:name => 'phpfunc').first
177
+ unless(s)
178
+ s = Setting.find_or_create(:name => 'phpfunc')
179
+ s.value = {:directory => Config.val(:plugin_directory) + '/php', :trigger => '@', :channels => []}
180
+ end
181
+ unless(File.directory?(Setting.val(:phpfunc)[:directory]))
182
+ FileUtils.mkdir_p(Setting.val(:phpfunc)[:directory])
183
+ end
184
+ end
185
+
186
+ def parse_predefined(m, name)
187
+ name.upcase!
188
+ page = File.open("#{@manual}/language.variables.predefined.html").readlines.join(' ').gsub(/[\n\r]/, '')
189
+ if page =~ /<dt>\s*<span class="term"><a href="reserved\.variables\.html.+? class="link">#{name.gsub(/\$/, '\$')}<\/a><\/span>\s*<dd>\s*<span class="simpara">(.+?)<\/span>/
190
+ desc = $1
191
+ desc.gsub!(/[\r\n]/, ' ')
192
+ desc.gsub!(/<.+?>/, ' ')
193
+ desc = CGI::unescapeHTML(desc.gsub(/\s+/, ' '))
194
+ output = ["\2PHP Superglobal\2"]
195
+ output << "\2#{name}:\2 #{desc}"
196
+ else
197
+ output = "No superglobal found matching: #{name}"
198
+ end
199
+ reply m.replyto, output
200
+ end
201
+
202
+ def parse_wildcard(m, name)
203
+ matches = []
204
+ pattern = name.gsub(/\*/, '.*?').gsub(/_/, '-')
205
+ Dir.open(@manual).each do |file|
206
+ if(file =~ /^(function\.#{pattern})\.html/)
207
+ match = $1
208
+ if(match =~ /^function\.(.+?)\-/)
209
+ if(@classlist.include?($1.downcase))
210
+ match.gsub!(/[-]/, '_')
211
+ match.sub!(/_/, '->')
212
+ else
213
+ match.gsub!(/[-]/, '_')
214
+ end
215
+ end
216
+ match.gsub!(/^function\./, '')
217
+ matches << match unless match.empty?
218
+ end
219
+ end
220
+ matches.sort!
221
+ output = matches.size > 20 ? ["Lots of matching functions. Truncating list to 20 results."] : []
222
+ if(matches.empty?)
223
+ output = "\2Error:\2 No matches found"
224
+ else
225
+ output << "Matches against term: \2#{name}:\2"
226
+ output << matches.values_at(0..19).join(', ')
227
+ end
228
+ reply m.replyto, output
229
+ end
230
+
231
+ def parse_function(m, name, filename)
232
+ page = File.open("#{@manual}/#{filename}", 'r').readlines.join('')
233
+ page.gsub!(/[\r\n]/, '')
234
+ versions = page =~ /<p class="verinfo">(.+?)<\/p>/i ? $1 : '(UNKNOWN)'
235
+ proto = page =~ /<div class="methodsynopsis dc-description">(.+?)<\/div>/i ? $1 : name
236
+ desc = page =~ /<p class="(para rdfs-comment|simpara)">(.+?)<\/p>/i ? $2.strip : '(UNKNOWN)'
237
+ versions = CGI::unescapeHTML(versions)
238
+ proto = CGI::unescapeHTML(proto.gsub(/<.+?>/, ' ').gsub(/[\s]+/, ' '))
239
+ desc = CGI::unescapeHTML(desc.gsub(/<.+?>/, ' ').gsub(/[\s]+/, ' '))
240
+ output = [versions]
241
+ output << "\2#{proto}\2"
242
+ output << Helpers.convert_entities(desc)
243
+ output << "http://www.php.net/manual/en/#{filename.gsub(/\.html$/, '.php')}"
244
+ reply m.replyto, output
245
+ end
246
+
247
+ def parse_operator(m, name)
248
+ Logger.info "parse_operator name=#{name}"
249
+ name.downcase!
250
+ type, title, ejemplo = @ops[name]
251
+ if(title.is_a?(Array))
252
+ output = ["\2#{name}\2 is the \2#{title.join("\2 or \2")}\2 operator"]
253
+ if(ejemplo.is_a?(Array))
254
+ (0..(ejemplo.size - 1)).each do |i|
255
+ output << "\2Example (#{type[i]}):\2 #{ejemplo[i]}"
256
+ end
257
+ elsif(!ejemplo.nil?)
258
+ output << "\2Example (#{type}):\2 #{ejemplo}"
259
+ end
260
+ type.each do |t|
261
+ output << "http://php.net/manual/en/language.operators.#{t}.php"
262
+ end
263
+ else
264
+ output = ["\2#{name}\2 is the \2#{title}\2 operator"]
265
+ output << "\2Example usage:\2 #{ejemplo}" unless ejemplo.nil? || ejemplo.empty?
266
+ output << "http://php.net/manual/en/language.operators.#{type}.php"
267
+ end
268
+ reply m.replyto, output
269
+ end
270
+
271
+ def parse_control(m, name, filename)
272
+ page = File.open("#{@manual}/#{filename}", 'r').readlines.join('')
273
+ page.gsub!(/[\r\n]/, '')
274
+ con = page =~ /<h2 class="title"><i>([^<]+)</ ? $1 : '(UNKNOWN)'
275
+ par = page =~ /^.+?<p class="para">(.+?)<div/ ? $1.strip : '(UNKNOWN)'
276
+ Logger.info("Match: #{par}")
277
+ par = par.gsub(/<.+?>/, ' ').gsub(/\s{2,}/, ' ')
278
+ par.gsub!(/\.[^\.]+:$/, '.')
279
+ #par.slice!(0..199) if par.size > 200
280
+ output = ["\2Control structure: #{con}\2"]
281
+ output << par
282
+ output << "http://www.php.net/manual/en/#{filename.gsub(/\.html$/, '.php')}"
283
+ reply m.replyto, output
284
+ end
285
+
286
+ def populate_classes
287
+ if(@classlist.empty?)
288
+ Dir.open(@manual).each do |file|
289
+ if(file =~ /^class\.(.+?)\.html/)
290
+ @classlist << $1
291
+ end
292
+ end
293
+ @classlist.uniq!
294
+ end
295
+ end
296
+
297
+ end
@@ -0,0 +1,11 @@
1
+ class Pinger < ModSpox::Plugin
2
+
3
+ def initialize(pipeline)
4
+ super(pipeline)
5
+ add_sig(:sig => 'ping', :method => :ping)
6
+ end
7
+
8
+ def ping(message, params)
9
+ reply message.replyto, "#{message.source.nick}: pong"
10
+ end
11
+ end
@@ -0,0 +1,79 @@
1
+ class Quotes < ModSpox::Plugin
2
+
3
+ include Models
4
+
5
+ def initialize(pipeline)
6
+ super
7
+ Quote.create_table unless Quote.table_exists?
8
+ group = Group.find_or_create(:name => 'quote')
9
+ add_sig(:sig => 'quote ?(.+)?', :method => :quote, :desc => 'Display random quote, random quote containing search term, or quote with given ID', :params => [:term])
10
+ add_sig(:sig => 'addquote (.+)', :method => :addquote, :desc => 'Add a new quote', :params => [:quote])
11
+ add_sig(:sig => 'searchquote (.+)', :method => :searchquote, :desc => 'Return IDs of quotes matching term', :params => [:term])
12
+ add_sig(:sig => 'delquote (\d+)', :method => :delquote, :group => group, :desc => 'Delete quote with given ID', :params => [:id])
13
+ end
14
+
15
+ def quote(message, params)
16
+ quote = nil
17
+ reg = false
18
+ if(params[:term])
19
+ if(params[:term] =~ /^\d+$/)
20
+ quote = Quote[params[:term].to_i]
21
+ else
22
+ ids = Quote.filter(:quote => Regexp.new(params[:term], Regexp::IGNORECASE)).map(:id)
23
+ quote = Quote[ids[rand(ids.size)].to_i]
24
+ reg = true
25
+ end
26
+ else
27
+ ids = Quote.select(:id).map(:id)
28
+ quote = Quote[ids[rand(ids.size)].to_i]
29
+ end
30
+ if(quote)
31
+ reply message.replyto, "\2[\2#{quote.pk}\2|\2#{quote.added.year}/#{sprintf('%02d', quote.added.month)}/#{sprintf('%02d', quote.added.day)}\2]:\2 #{reg ? quote.quote.gsub(/(#{params[:term]})/i, "\2\\1\2") : quote.quote}"
32
+ else
33
+ reply message.replyto, "\2Error:\2 Failed to find quote"
34
+ end
35
+ end
36
+
37
+ def addquote(message, params)
38
+ quote = Quote.new(:nick_id => message.source.pk, :channel_id => message.target.pk)
39
+ quote.quote = params[:quote]
40
+ quote.added = Time.now
41
+ quote.save
42
+ reply message.replyto, "\2Quote added:\2 ##{quote.pk}"
43
+ end
44
+
45
+ def searchquote(message, params)
46
+ result = Quote.filter(:quote => Regexp.new(params[:term], Regexp::IGNORECASE))
47
+ if(result.count > 0)
48
+ ids = result.map(:id)
49
+ ids.sort!
50
+ ids = ids.slice(0, 20)
51
+ reply message.replyto, "Quotes matching term (#{params[:term]}): #{ids.join(', ')}"
52
+ else
53
+ reply message.replyto, "\2Error:\2 No quotes match search term: #{params[:term]}"
54
+ end
55
+ end
56
+
57
+ def delquote(message, params)
58
+ result = Quote.filter(:id => params[:id].to_i)
59
+ if(result.count < 1)
60
+ reply message.replyto, "\2Error:\2 Failed to find quote with ID: #{params[:id]}"
61
+ else
62
+ result.destroy
63
+ reply message.replyto, "\2Quote deleted:\2 ##{params[:id]}"
64
+ end
65
+ end
66
+
67
+ class Quote < Sequel::Model
68
+ set_schema do
69
+ primary_key :id
70
+ text :quote, :null => false
71
+ timestamp :added, :null => false
72
+ foreign_key :nick_id, :table => :nicks
73
+ foreign_key :channel_id, :table => :channels
74
+ end
75
+ many_to_one :nick, :class => ModSpox::Models::Nick
76
+ many_to_one :channel, :class => ModSpox::Models::Channel
77
+ end
78
+
79
+ end
@@ -0,0 +1,158 @@
1
+ class RegexTracker < ModSpox::Plugin
2
+
3
+ include Models
4
+ def initialize(pipeline)
5
+ super
6
+ track = Group.find_or_create(:name => 'track')
7
+ add_sig(:sig => 'track info (\d+)', :method => :score, :desc => 'Show info on regex tracking',
8
+ :params => [:id])
9
+ add_sig(:sig => 'track list(\s\S+)?', :method => :list, :desc => 'List currently tracked regex', :params => [:channel])
10
+ add_sig(:sig => 'track add (.+)', :method => :add, :desc => 'Add new regex for tracking',
11
+ :params => [:regex], :group => track)
12
+ add_sig(:sig => 'track remove (\d+)', :method => :remove, :desc => 'Remove regex from tracking',
13
+ :params => [:id], :group => track)
14
+ add_sig(:sig => 'track modify (\d+) (.+)', :method => :modify, :desc => 'Modify regex',
15
+ :params => [:id, :regex], :group => track)
16
+ @pipeline.hook(self, :check, :Incoming_Privmsg)
17
+ TrackInfo.create_table unless TrackInfo.table_exists?
18
+ @cache = {}
19
+ build_cache
20
+ end
21
+
22
+ def check(message)
23
+ return unless @cache.has_key?(message.target.pk.to_i)
24
+ time = Time.now
25
+ @cache[message.target.pk.to_i].each do |t|
26
+ if(message.message =~ /#{t[:regex]}/)
27
+ ti = TrackInfo[t[:id]]
28
+ if(ti.last_score.year != time.year || ti.last_score.yday != time.yday)
29
+ ti.score_today = 0
30
+ end
31
+ ti.last_score = Time.now
32
+ ti.score_today += 1
33
+ ti.score_total += 1
34
+ ti.save
35
+ end
36
+ end
37
+ end
38
+
39
+ def list(message, params)
40
+ output = ''
41
+ begin
42
+ raise 'No channel given for list' if message.is_private? && !params[:channel]
43
+ channel = params[:channel] ? Helpers.find_model(params[:channel].strip, false) : message.target
44
+ if(TrackInfo.filter(:channel_id => channel.pk).count > 0)
45
+ output = []
46
+ output << "\2Currently tracked regexs in #{channel.name}"
47
+ TrackInfo.filter(:channel_id => channel.pk).each do |t|
48
+ output << "\2ID:\2 #{t.pk} --- \2REGEX:\2 #{t.regex}"
49
+ end
50
+ else
51
+ output = 'Error: Nothing is currently being tracked'
52
+ end
53
+ rescue Object => boom
54
+ output = "Error: #{boom}"
55
+ ensure
56
+ reply message.replyto, output
57
+ end
58
+ end
59
+
60
+ def add(message, params)
61
+ output = ''
62
+ begin
63
+ r = Regexp.new(params[:regex])
64
+ t = TrackInfo.new
65
+ t.regex = params[:regex]
66
+ t.channel = message.target
67
+ t.last_score = Time.now
68
+ t.save
69
+ build_cache
70
+ output = "New regex has been added for tracking (ID: #{t.pk})"
71
+ rescue Object => boom
72
+ output = "Failed to save regex: #{boom}"
73
+ ensure
74
+ reply message.replyto, output
75
+ end
76
+ end
77
+
78
+ def remove(message, params)
79
+ id = params[:id].to_i
80
+ tis = TrackInfo.filter(:id => id)
81
+ if(tis.count > 0)
82
+ tis.destroy
83
+ build_cache
84
+ reply message.replyto, "Regex has been removed (ID: #{id})"
85
+ else
86
+ reply message.replyto, "Failed to find regex being tracked with ID: #{id}"
87
+ end
88
+ end
89
+
90
+ def modify(message, params)
91
+ id = params[:id].to_i
92
+ tis = TrackInfo.filter(:id => id)
93
+ output = ''
94
+ begin
95
+ r = Regexp.new(params[:regex])
96
+ if(tis.count > 0)
97
+ t = tis.first
98
+ t.regex = params[:regex]
99
+ t.save
100
+ build_cache
101
+ output = "Regex has been update (ID: #{t.pk})"
102
+ else
103
+ output = "Failed to locate tracking regex (ID: #{id})"
104
+ end
105
+ rescue Object => boom
106
+ output = "Failed to save regex. #{boom}"
107
+ ensure
108
+ reply message.replyto, output
109
+ end
110
+ end
111
+
112
+ def score(message, params)
113
+ id = params[:id].to_i
114
+ t = TrackInfo.filter(:id => id).first
115
+ if(t)
116
+ reply message.replyto, "\2(#{id})\2: Regex: #{t.regex}, Today: #{t.score_today}, Total: #{t.score_total}, Last occurance: #{t.last_score}"
117
+ else
118
+ reply message.replyto, "Failed to find tracking regex with ID: #{id}"
119
+ end
120
+ end
121
+
122
+ def build_cache
123
+ @cache = {}
124
+ TrackInfo.all.each do |t|
125
+ @cache[t.channel_id.to_i] = [] unless @cache.has_key?(t.channel_id.to_i)
126
+ @cache[t.channel_id.to_i] << {:id => t.pk, :regex => t.regex}
127
+ end
128
+ end
129
+
130
+ class TrackInfo < Sequel::Model
131
+ set_schema do
132
+ primary_key :id, :null => false
133
+ varchar :regex, :null => false
134
+ integer :score_total, :null => false, :default => 0
135
+ integer :score_today, :null => false, :default => 0
136
+ timestamp :last_score, :null => false
137
+ foreign_key :channel_id, :table => :channels, :null => false
138
+ index [:regex, :channel_id], :unique => true
139
+ end
140
+
141
+ many_to_one :channel, :class => ModSpox::Models::Channel
142
+
143
+ def channel=(chan)
144
+ raise Exceptions::InvalidType.new('Channel model was expected') unless chan.is_a?(Models::Channel)
145
+ values[:channel_id] = chan.pk
146
+ end
147
+
148
+ def regex=(r)
149
+ r = [Marshal.dump(r)].pack('m')
150
+ super(r)
151
+ end
152
+
153
+ def regex
154
+ values[:regex] ? Marshal.load(values[:regex].unpack('m')[0]) : nil
155
+ end
156
+ end
157
+
158
+ end