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,35 @@
1
+ require 'net/http'
2
+ require 'rexml/document'
3
+
4
+ class FML < ModSpox::Plugin
5
+
6
+ def initialize(pipeline)
7
+ super
8
+ add_sig(:sig => 'fml( (love|money|kids|work|health|sex|miscellaneous))?', :method => :random, :desc => 'Fuck my life', :params => [:wspace, :category])
9
+ @site = 'http://api.betacie.com/view/'
10
+ @vars = ['key=readonly', 'language=en']
11
+ end
12
+
13
+ def random(m, params)
14
+ begin
15
+ t = params[:category] ? "#{params[:category].strip}/" : ''
16
+ reply m.replyto, get_text("#{t}random")
17
+ rescue Object => boom
18
+ error m.replyto, 'Failed to fetch.' + boom.to_s
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def get_text(thing)
25
+ data = Net::HTTP.get_response(URI.parse(@site+thing+'?'+@vars.join('&'))).body
26
+ doc = REXML::Document.new(data)
27
+ output = []
28
+ doc.elements.each('root/items/item/text') do |t|
29
+ output << Helpers.convert_entities(t.text)
30
+ end
31
+ raise 'Failed to fetch item from FML' if output.empty?
32
+ return output[rand(output.size)]
33
+ end
34
+
35
+ end
@@ -0,0 +1,129 @@
1
+ class FloodKicker
2
+ def initialize(pipeline)
3
+ super
4
+ flood = Models::Auth.find_or_create(:name => 'flood')
5
+ @watched = []
6
+ @channels = Setting.filter(:name => :floodkicker).first
7
+ @channels = [] if @channels.nil?
8
+ @channels.each do |c|
9
+ @watched << c[:channel]
10
+ end
11
+ @data = {}
12
+ @pipeline.hook(self, :listener, :Incoming_Privmsg)
13
+ add_sig(:sig => 'floodkick enable(\s \S+)?', :method => :add_channel, :group => flood,
14
+ :desc => 'Add channel to flood kicker', :params => [:channel])
15
+ add_sig(:sig => 'floodkick disable(\s \S+)?', :method => :remove_channel, :group => flood,
16
+ :desc => 'Remove channel from flood kicker', :params => [:channel])
17
+ add_sig(:sig => 'floodkick lines(\s \d+)?', :method => :max_lines, :group => flood,
18
+ :desc => 'Maximum number of lines in allowed time', :params => [:lines])
19
+ add_sig(:sig => 'floodkick seconds(\s \d+)?', :method => :max_seconds, :group => flood,
20
+ :desc => 'Maximum number of seconds for allowed lines', :params => [:seconds])
21
+ add_sig(:sig => 'floodkick status(\s \S+)?', :method => :status, :desc => 'Show parameters for given channel',
22
+ :params => [:channel])
23
+ end
24
+ # @channels -> {:channel => chan.pk, :lines => \d+, :seconds => \d+}
25
+
26
+ def add_channel(m, params)
27
+ chan = params[:channel] ? Models::Channel.locate(params[:channel].strip) : m.channel
28
+ unless(watched_channels_ids.include?(chan.pk))
29
+ @channels << {:channel => chan.pk, :lines => 5, :seconds => 1}
30
+ save_channels
31
+ reply m.replyto, "Flood kicker is now enabled for: #{chan.name}"
32
+ else
33
+ reply m.replyto, "\2Error:\2 Flood kicker is already enabled for: #{chan.name}"
34
+ end
35
+ end
36
+
37
+ def remove_channel(m, params)
38
+ chan = params[:channel] ? Models::Channel.locate(params[:channel].strip) : m.channel
39
+ if(watched_channels_ids.include?(chan.pk))
40
+ @channels.delete(get_chan(chan.pk))
41
+ save_channels
42
+ reply m.replyto, "Flood kicker is now disabled for: #{chan.name}"
43
+ else
44
+ reply m.replyto, "Flood kicker is not enabled for: #{chan.name}"
45
+ end
46
+ end
47
+
48
+ def max_lines(m, params)
49
+ lines = params[:lines] ? params[:lines].to_i : nil
50
+ chan = get_chan(m.channel.pk)
51
+ unless(chan.nil?)
52
+ if(lines.nil? || lines == 0)
53
+ reply m.replyto, "Flood kicker lines for this channel currently set at: #{chan[:lines]} lines"
54
+ else
55
+ chan[:lines] = lines
56
+ save_channels
57
+ reply m.replyto, "Flood kicker lines updated to: #{lines} lines"
58
+ end
59
+ else
60
+ reply m.replyto, "\2Error:\2 Flood kicker is not enabled in this channel"
61
+ end
62
+ end
63
+
64
+ def max_seconds(m, params)
65
+ seconds = params[:seconds] ? params[:seconds].to_i : nil
66
+ chan = get_chan(m.channel.pk)
67
+ unless(chan.nil?)
68
+ if(seconds.nil? || seconds == 0)
69
+ reply m.replyto, "Flood kicker seconds for this channel currently set at: #{chan[:seconds]} seconds"
70
+ else
71
+ chan[:seconds] = seconds
72
+ save_channels
73
+ reply m.replyto, "Flood kicker seconds updated to: #{seconds} seconds"
74
+ end
75
+ else
76
+ reply m.replyto, "\2Error:\2 Flood kicker is not enabled in this channel"
77
+ end
78
+ end
79
+
80
+ def listener(m)
81
+ if(@watched.include?(m.channel.pk))
82
+ log_message(m)
83
+ if(kick_nick?(m.nick, m.channel))
84
+ chan = get_chan(m.channel.pk)
85
+ @pipeline << Messages::Outgoing::Kick.new(m.nick, m.channel, "Flooding. (exceeded #{chan[:lines]} lines in #{chan[:seconds]} seconds)")
86
+ end
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ def log_message(m)
93
+ @data[m.channel.pk] = {} unless @data.has_key?(m.channel.pk)
94
+ @data[m.channel.pk][m.nick.pk] = [] unless @data[m.channel.pk].has_key?(m.nick.pk)
95
+ @data[m.channel.pk][m.nick.pk] << {:time => Time.now, :message => m.message}
96
+ @data[m.channel.pk][m.nick.pk].shift until @data[m.channel.pk][m.nick.pk].size <= get_chan(m.channel.pk)[:lines]
97
+ end
98
+
99
+ def kick_nick?(nick, channel)
100
+ chan = get_chan(channel.pk)
101
+ if(@data[channel.pk].has_key?(nick.pk) && @data[channel.pk][nick.pk].size == chan[:lines])
102
+ return @data[channel.pk][nick.pk][@data[channel.pk][nick.pk].size - 1][:time].to_i - @data[channel.pk][nick.pk][0].to_i >= chan[:seconds].to_i
103
+ else
104
+ return false
105
+ end
106
+ end
107
+
108
+ def save_channels
109
+ s = Models::Setting.find_or_create(:name => 'floodkicker')
110
+ s.value = @channels
111
+ s.save
112
+ @watched.clear
113
+ @channels.each{|c| @watched << c.pk}
114
+ end
115
+
116
+ def watched_channels
117
+ @channels.collect{|c| Models::Channel[c[:channel]]}
118
+ end
119
+
120
+ def watched_channels_ids
121
+ @channels.collect{|c| c[:channel]}
122
+ end
123
+
124
+ def get_chan(pk)
125
+ @channels.each do |c|
126
+ return c if c[:channel] == pk
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,76 @@
1
+ class Fortune < ModSpox::Plugin
2
+
3
+ def initialize(pipeline)
4
+ super
5
+ add_sig(:sig => 'fortune( \S+)?', :method => :fortune, :desc => 'Get a fortune', :params => [:type])
6
+ add_sig(:sig => 'fortunes', :method => :show_groups, :desc => 'Show available fortune types')
7
+ add_sig(:sig => 'fortunes count( \S+)?', :method => :count, :desc => 'Count fortunes', :params => [:type])
8
+ @fetching = false
9
+ @db = nil
10
+ @ids = {}
11
+ unless(File.exists?(BotConfig[:userpath] + '/fortunes.db.sql3'))
12
+ @fetching = true
13
+ do_fetch
14
+ else
15
+ @db = Sequel.sqlite(BotConfig[:userpath] + '/fortunes.db.sql3')
16
+ end
17
+ end
18
+
19
+ def count(m, params)
20
+ unless(@fetching)
21
+ output = nil
22
+ if(params[:type])
23
+ params[:type].strip!
24
+ output = "Number of fortunes (type #{params[:type]}): #{@db[:fortunes].filter(:type => params[:type]).count}"
25
+ else
26
+ output = "Number of fortunes: #{@db[:fortunes].count}"
27
+ end
28
+ information m.replyto, output
29
+ else
30
+ error m.replyto, "Waiting for fortunes to complete download"
31
+ end
32
+ end
33
+
34
+ def show_groups(m, params)
35
+ unless(@fetching)
36
+ information m.replyto, "Fortune types available: #{@db['select distinct(type) from fortunes order by type'].map(:type).join(', ')}"
37
+ else
38
+ error m.replyto, "Waiting for fortunes to complete download"
39
+ end
40
+ end
41
+
42
+ def fortune(m, params)
43
+ unless(@fortune)
44
+ f = nil
45
+ if(params[:type])
46
+ t = params[:type].downcase.strip
47
+ unless(@ids[t])
48
+ c = @db[:fortunes].filter(:type => t).map(:id)
49
+ @ids[t] = c unless c.empty?
50
+ end
51
+ f = @db[:fortunes].filter(:id => @ids[t][rand(@ids[t].size)]).first if @ids[t]
52
+ else
53
+ @ids[:all] = @db[:fortunes].count
54
+ f = @db[:fortunes].filter(:id => rand(@ids[:all])).first
55
+ end
56
+ if(f)
57
+ reply m.replyto, f[:fortune]
58
+ else
59
+ error m.replyto, "Failed to locate fortune"
60
+ end
61
+ else
62
+ error m.replyto, "Waiting for fortunes to complete download"
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def do_fetch
69
+ Thread.new do
70
+ `wget --output-document=#{BotConfig[:userpath]}/fortunes.tar.gz http://rubyforge.org/frs/download.php/59569/fortunes.tar.gz`
71
+ `tar -C #{BotConfig[:userpath]} -xzf #{BotConfig[:userpath]}/fortunes.tar.gz`
72
+ @fetching = false
73
+ @db = Sequel.sqlite(BotConfig[:userpath] + '/fortunes.db.sql3')
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,13 @@
1
+ class GoogleIt < ModSpox::Plugin
2
+ def initialize(pipeline)
3
+ super
4
+ add_sig(:sig => 'googleit (.+)', :method => :git, :description => 'Let me google that for you', :params => [:term])
5
+ end
6
+
7
+ def git(m, params)
8
+ link = "http://www.letmegooglethatforyou.com/?q=#{URI.escape(params[:term])}"
9
+ output = ["Oh please, let me google: \2#{params[:term]}\2 for you."]
10
+ output << "\2Result:\2 #{Helpers.tinyurl(link)}"
11
+ reply m.replyto, output
12
+ end
13
+ end
@@ -0,0 +1,59 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+
5
+ class Headers < ModSpox::Plugin
6
+
7
+ def initialize(pipeline)
8
+ super(pipeline)
9
+ admin = Models::Group.find_or_create(:name => 'headers')
10
+ add_sig(:sig => 'headers ((https?:\/\/)?\S+)', :method => :fetch_headers, :desc => 'Fetch HTTP headers', :params => [:url])
11
+ add_sig(:sig => 'headers max (\d+)', :method => :set_max, :group => admin, :desc => 'Set maximum number of headers to return', :params => [:max])
12
+ add_sig(:sig => 'headers max', :method => :show_max, :group => admin, :desc => 'Show maximum number of headers to return ')
13
+ @lock = Mutex.new
14
+ @max = Models::Config.val(:headers_max)
15
+ @max = @max.nil? ? 0 : @max.to_i
16
+ end
17
+
18
+ def set_max(message, params)
19
+ record = Models::Config.set(:headers_max, params[:max].to_i)
20
+ @max = params[:max].to_i
21
+ reply message.replyto, "Max headers returned set to: #{params[:max].to_i}"
22
+ end
23
+
24
+ def show_max(message, params)
25
+ reply message.replyto, "Maximum headers returned: #{@max == 0 ? 'no limit' : @max}"
26
+ end
27
+
28
+ def fetch_headers(message, params)
29
+ params[:url] = "http://#{params[:url]}" unless params[:url].slice(0..3).downcase == 'http'
30
+ uri = URI.parse(params[:url])
31
+ begin
32
+ path = uri.path.nil? || uri.path.empty? ? '/' : uri.path
33
+ path += "?#{uri.query}" unless uri.query.nil?
34
+ reply message.replyto, "Connecting to: #{uri.host} on port: #{uri.port} retrieving: #{path}"
35
+ con = Net::HTTP.new(uri.host, uri.port)
36
+ #con.secure = uri.scheme == 'https'
37
+ con.open_timeout = 5
38
+ con.read_timeout = 5
39
+ response = con.head(path)
40
+ output = ["Response code: #{response.code}"]
41
+ count = 0
42
+ response.each_capitalized{|key,val|
43
+ output << "#{key.slice(0..50)}: #{val.slice(0..200)}"
44
+ count += 1
45
+ break if @max != 0 && count >= @max
46
+ }
47
+ if(count >= @max && @max != 0)
48
+ output << 'Maximum header limit reached.'
49
+ else
50
+ output << 'Header listing complete'
51
+ end
52
+ reply message.replyto, output
53
+ rescue Object => boom
54
+ reply message.replyto, "Error retrieving headers (#{uri.host}): #{boom}"
55
+ Logger.warn("Headers plugin error: #{boom}")
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,302 @@
1
+ require 'mod_spox/messages/internal/TimerAdd'
2
+ require 'mod_spox/messages/outgoing/Privmsg'
3
+
4
+ class Karma < ModSpox::Plugin
5
+
6
+ include Messages::Outgoing
7
+
8
+ def initialize(pipeline)
9
+ super(pipeline)
10
+ Datatype::Karma.create_table unless Datatype::Karma.table_exists?
11
+ Datatype::Alias.create_table unless Datatype::Alias.table_exists?
12
+ alias_group = Models::Group.find_or_create(:name => 'alias')
13
+ add_sig(:sig => 'karma (?!topten|bottomten$)(?!(fight|alias|dealias|aliases|reset) (\S+|\(.+?\)) ?(\S+|\(.+?\))?$)(\S+|\(.+?\))', :method => :score, :desc => 'Returns karma for given thing', :params => [:crap, :crap2, :crap3, :thing])
14
+ add_sig(:sig => 'karma reset (\S+|\(.+?\))', :method => :reset, :group => Models::Group.filter(:name => 'admin').first, :desc => 'Reset a karma score', :params => [:thing])
15
+ add_sig(:sig => 'karma alias (\S+|\(.+?\)) (\S+|\(.+?\))', :method => :aka, :group => alias_group, :desc => 'Alias a karma object to another karma object', :params => [:thing, :thang])
16
+ add_sig(:sig => 'karma dealias (\S+|\(.+?\)) (\S+|\(.+?\))', :method => :dealias, :group => alias_group, :desc => 'Remove a karma alias', :params => [:thing, :otherthing])
17
+ add_sig(:sig => 'karma aliases (\S+|\(.+?\))', :method => :show_aliases, :desc => 'Show all aliases for given thing', :params => [:thing])
18
+ add_sig(:sig => 'karma fight (\S+|\(.+?\)) (\S+|\(.+?\))', :method => :fight, :desc => 'Make two karma objects fight', :params => [:thing, :thang])
19
+ add_sig(:sig => 'antikarma (\S+|\(.+?\))', :method => :antikarma, :desc => 'Show things antikarma', :params => [:thing])
20
+ add_sig(:sig => 'antikarma fight (\S+|\(.+?\)) (\S+|\(.+?\))', :method => :antifight, :desc => 'Make two antikarma objects fight', :params => [:thing, :thang])
21
+ add_sig(:sig => 'karma topten', :method => :topten, :desc => 'Show top ten highest karma objects')
22
+ add_sig(:sig => 'karma bottomten', :method => :bottomten, :desc => 'Show bottom ten lowest karma objects')
23
+ @pipeline.hook(self, :check, :Incoming_Privmsg)
24
+ @thing_maxlen = 32
25
+ @karma_regex = /(\(.{1,#@thing_maxlen}?\)|\S{1,#@thing_maxlen})([+-]{2})(?:\s|$)/
26
+ @eggs = {}
27
+ @eggs[:chameleon] = []
28
+ @eggs[:chameleon] << 'Karma karma karma karma karma chameleon You come and go You come and go Loving would be easy if your colors were like my dream Red, gold and green Red, gold and green'
29
+ @eggs[:chameleon] << 'Didn\'t hear your wicked words every day And you used to be so sweet I heard you say That my love was an addiction When we cling our love is strong When you go youre gone forever You string along You string along'
30
+ @eggs[:chameleon] << 'Every day is like a survival You\'re my lover not my rival Every day is like a survival You\'re my lover not my rival'
31
+ @eggs[:chameleon] << 'I\'m a man without conviction I\'m a man who doesnt know How to sell a contradication You come and go You come and go'
32
+ end
33
+
34
+ def check(message)
35
+ if(message.is_public?)
36
+ @dupes = {}
37
+ message.message.scan(@karma_regex) do |match|
38
+ thing, adj = match
39
+ thing.downcase!
40
+ thing = thing[1..-2] if thing[0..0] == '(' && thing[-1..-1] == ')'
41
+ next if @dupes.has_key?(thing) && @dupes[thing].include?(adj)
42
+ @dupes[thing] = [] unless @dupes[thing]
43
+ @dupes[thing] << adj
44
+ adj = adj == '++' ? +1 : -1
45
+ things = [thing]
46
+ karma = Datatype::Karma.find_or_create(:thing => thing, :channel_id => message.target.pk)
47
+ Datatype::Alias.get_aliases(karma.pk).each do |id|
48
+ things << Datatype::Karma[id].thing.downcase
49
+ end
50
+ if(things.include?(message.source.nick.downcase))
51
+ adj = -1
52
+ end
53
+ karma = Datatype::Karma.find_or_create(:thing => thing, :channel_id => message.target.pk)
54
+ karma.score = karma.score + adj
55
+ karma.save
56
+ end
57
+ end
58
+ end
59
+
60
+ def score(message, params)
61
+ return unless message.is_public?
62
+ thing = params[:thing]
63
+ orig = thing[1..-2] if thing[0..0] == '(' && thing[-1..-1] == ')'
64
+ orig = thing if orig.nil?
65
+ thing = orig.downcase
66
+ karma = Datatype::Karma.filter(:thing => thing, :channel_id => message.target.pk).first
67
+ if(karma)
68
+ @pipeline << Privmsg.new(message.replyto, "Karma for \2#{orig}\2 is #{Datatype::Alias.score_object(karma.pk)}")
69
+ else
70
+ @pipeline << Privmsg.new(message.replyto, "\2Error:\2 #{orig} has no karma")
71
+ end
72
+ if(@eggs.has_key?(params[:thing].downcase.to_sym))
73
+ @pipeline << Messages::Internal::TimerAdd.new(self, rand(5) + 1, nil, true){ egg(params[:thing].downcase, message) }
74
+ end
75
+ end
76
+
77
+ def bottomten(m, params)
78
+ set = Datatype::Karma.filter(:channel_id => m.target.pk).order(:thing.asc).order(:score.asc).limit(10)
79
+ if(set.count > 0)
80
+ output = []
81
+ set.each do |thing|
82
+ output << "#{thing.thing} (#{thing.score.to_s.slice(0) == '-' ? '' : '+'}#{thing.score})"
83
+ end
84
+ reply m.replyto, "\2Karma bottom ten:\2 #{output.join(', ')}"
85
+ else
86
+ error m.replyto, 'No karma objects stored'
87
+ end
88
+ end
89
+
90
+ def topten(m, params)
91
+ set = Datatype::Karma.filter(:channel_id => m.target.pk).order(:thing.asc).order(:score.desc).limit(10)
92
+ if(set.count > 0)
93
+ output = []
94
+ set.each do |thing|
95
+ output << "#{thing.thing} (#{thing.score.to_s.slice(0) == '-' ? '' : '+'}#{thing.score})"
96
+ end
97
+ reply m.replyto, "\2Karma topten:\2 #{output.join(', ')}"
98
+ else
99
+ error m.replyto, 'No karma objects stored'
100
+ end
101
+ end
102
+
103
+ def antikarma(message, params)
104
+ return unless message.is_public?
105
+ thing = params[:thing]
106
+ orig = thing[1..-2] if thing[0..0] == '(' && thing[-1..-1] == ')'
107
+ orig = thing if orig.nil?
108
+ thing = orig.downcase
109
+ karma = Datatype::Karma.filter(:thing => thing, :channel_id => message.target.pk).first
110
+ if(karma)
111
+ @pipeline << Privmsg.new(message.replyto, "Anti-Karma for \2#{orig}\2 is #{0 - Datatype::Alias.score_object(karma.pk).to_i}")
112
+ else
113
+ @pipeline << Privmsg.new(message.replyto, "\2Error:\2 #{orig} has no anti-karma")
114
+ end
115
+ end
116
+
117
+ def reset(message, params)
118
+ sthing = params[:thing].downcase
119
+ sthing = thing[1..-2] if thing[0..0] == '(' && thing[-1..-1] == ')'
120
+ return unless message.is_public?
121
+ karma = Datatype::Karma.filter(:thing => sthing, :channel_id => message.target.pk).first
122
+ if(karma)
123
+ karma.update(:score => 0)
124
+ @pipeline << Privmsg.new(message.replyto, "Karma for \2#{karma.thing}\2 has been reset")
125
+ else
126
+ @pipeline << Privmsg.new(message.replyto, "\2Error:\2 #{sthing} has no karma")
127
+ end
128
+ end
129
+
130
+ def fight(message, params)
131
+ thing = params[:thing]
132
+ thang = params[:thang]
133
+ thing = thing[1..-2] if thing[0..0] == '(' && thing[-1..-1] == ')'
134
+ thang = thang[1..-2] if thang[0..0] == '(' && thang[-1..-1] == ')'
135
+ rthing = Datatype::Karma.find_or_create(:thing => thing.downcase, :channel_id => message.target.pk)
136
+ rthang = Datatype::Karma.find_or_create(:thing => thang.downcase, :channel_id => message.target.pk)
137
+ thing_score = Datatype::Alias.score_object(rthing.pk)
138
+ thang_score = Datatype::Alias.score_object(rthang.pk)
139
+ winner = thing_score > thang_score ? thing : thang
140
+ loser = thing_score > thang_score ? thang : thing
141
+ distance = (thing_score - thang_score).abs
142
+ output = ["\2KARMA FIGHT RESULTS:\2 "]
143
+ if(distance > 0)
144
+ output << "\2#{winner}\2 #{winner[-1] == 's' || winner[-1] == 115 ? 'have' : 'has'} beaten \2#{loser}\2 #{distance > 50 ? 'like a redheaded step child' : ''} (+#{distance} points)"
145
+ else
146
+ output << "\2#{winner}\2 #{winner[-1] == 's' || winner[-1] == 115 ? 'have' : 'has'} tied \2#{loser}\2"
147
+ end
148
+ reply message.replyto, output
149
+ end
150
+
151
+ def antifight(message, params)
152
+ thing = params[:thing]
153
+ thang = params[:thang]
154
+ thing = thing[1..-2] if thing[0..0] == '(' && thing[-1..-1] == ')'
155
+ thang = thang[1..-2] if thang[0..0] == '(' && thang[-1..-1] == ')'
156
+ rthing = Datatype::Karma.find_or_create(:thing => thing.downcase, :channel_id => message.target.pk)
157
+ rthang = Datatype::Karma.find_or_create(:thing => thang.downcase, :channel_id => message.target.pk)
158
+ thing_score = Datatype::Alias.score_object(rthing.pk) * -1
159
+ thang_score = Datatype::Alias.score_object(rthang.pk) * -1
160
+ winner = thing_score > thang_score ? thing : thang
161
+ loser = thing_score > thang_score ? thang : thing
162
+ distance = (thing_score - thang_score).abs
163
+ output = ["\2ANTI-KARMA FIGHT RESULTS:\2 "]
164
+ if(distance > 0)
165
+ output << "\2#{winner}\2 #{winner[-1] == 's' || winner[-1] == 115 ? 'have' : 'has'} beaten \2#{loser}\2 #{distance > 50 ? 'like a redheaded step child' : ''} (+#{distance} points)"
166
+ else
167
+ output << "\2#{winner}\2 #{winner[-1] == 's' || winner[-1] == 115 ? 'have' : 'has'} tied \2#{loser}\2"
168
+ end
169
+ reply message.replyto, output
170
+ end
171
+
172
+ def aka(message, params)
173
+ thing = params[:thing].downcase
174
+ thang = params[:thang].downcase
175
+ thing = thing[1..-2] if thing[0..0] == '(' && thing[-1..-1] == ')'
176
+ thang = thang[1..-2] if thang[0..0] == '(' && thang[-1..-1] == ')'
177
+ thing = Datatype::Karma.find_or_create(:thing => thing, :channel_id => message.target.pk)
178
+ thang = Datatype::Karma.find_or_create(:thing => thang, :channel_id => message.target.pk)
179
+ if(Datatype::Alias.filter('(thing_id = ? AND aka_id = ?) OR (thing_id = ? AND aka_id = ?)', thing.pk, thang.pk, thang.pk, thing.pk).first)
180
+ reply message.replyto, "\2Error:\2 #{thing.thing} is already aliased to #{thang.thing}"
181
+ else
182
+ Datatype::Alias.find_or_create(:thing_id => thing.pk, :aka_id => thang.pk)
183
+ reply message.replyto, "\2Karma Alias:\2 #{thing.thing} is now aliased to #{thang.thing}"
184
+ end
185
+ end
186
+
187
+ def dealias(message, params)
188
+ sthing = params[:thing].downcase
189
+ sotherthing = params[:otherthing].downcase
190
+ sthing = sthing[1..-2] if sthing[0..0] == '(' && sthing[-1..-1] == ')'
191
+ sotherthing = sotherthing[1..-2] if sotherthing[0..0] == '(' && sotherthing[-1..-1] == ')'
192
+ thing = Datatype::Karma.filter(:thing => sthing, :channel_id => message.target.pk).first
193
+ otherthing = Datatype::Karma.filter(:thing => sotherthing, :channel_id => message.target.pk).first
194
+ if(thing && otherthing)
195
+ set = Datatype::Alias.filter('(thing_id = ? AND aka_id = ?) OR (thing_id = ? AND aka_id = ?)', thing.pk, otherthing.pk, otherthing.pk, thing.pk)
196
+ if(set.count < 1)
197
+ reply message.replyto, "\2Error:\2 No alias found between #{thing.thing} and #{otherthing.thing}"
198
+ else
199
+ set.destroy
200
+ reply message.replyto, "#{thing.thing} has been successfully dealiased from #{otherthing.thing}"
201
+ end
202
+ else
203
+ reply message.replyto, "\2Error:\2 No alias found between #{sthing} and #{sotherthing}"
204
+ end
205
+ end
206
+
207
+ def show_aliases(message, params)
208
+ thing = params[:thing].downcase
209
+ thing = thing[1..-2] if thing[0..0] == '(' && thing[-1..-1] == ')'
210
+ thing = Datatype::Karma.filter(:thing => thing, :channel_id => message.target.pk).first
211
+ begin
212
+ if(thing)
213
+ things = []
214
+ Datatype::Alias.get_aliases(thing.pk).each do |id|
215
+ things << Datatype::Karma[id].thing
216
+ end
217
+ if(things.empty?)
218
+ reply message.replyto, "#{thing.thing} is not currently aliased"
219
+ else
220
+ reply message.replyto, "#{thing.thing} is currently aliased to: #{things.sort.join(', ')}"
221
+ end
222
+ else
223
+ reply message.replyto, "\2Error:\2 #{params[:thing]} has never been used and has no aliases"
224
+ end
225
+ rescue Object
226
+ error message.replyto, "No aliases found"
227
+ end
228
+ end
229
+
230
+ def egg(karma, message)
231
+ if(karma.downcase == 'chameleon')
232
+ reply message.replyto, @eggs[:chameleon][rand(@eggs[:chameleon].size - 1)]
233
+ end
234
+ end
235
+
236
+ module Datatype
237
+ class Karma < Sequel::Model
238
+ set_schema do
239
+ primary_key :id
240
+ text :thing, :null => false
241
+ integer :score, :null => false, :default => 0
242
+ foreign_key :channel_id, :table => :channels
243
+ index [:thing, :channel_id], :unique => true
244
+ end
245
+
246
+ many_to_one :channel, :class => ModSpox::Models::Channel
247
+ end
248
+ class Alias < Sequel::Model
249
+ set_schema do
250
+ primary_key :id
251
+ foreign_key :thing_id, :null => false
252
+ foreign_key :aka_id, :null => false
253
+ end
254
+
255
+ def thing
256
+ Karma[thing_id]
257
+ end
258
+
259
+ def aka
260
+ Karma[aka_id]
261
+ end
262
+
263
+ def Alias.score_object(object_id)
264
+ Alias.create_lock unless class_variable_defined?(:@@lock)
265
+ @@objects = []
266
+ score = 0
267
+ @@lock.synchronize do
268
+ score += Alias.sum_objects(object_id)
269
+ end
270
+ return score
271
+ end
272
+
273
+ def Alias.get_aliases(object_id)
274
+ Alias.score_object(object_id)
275
+ objs = @@objects.dup
276
+ objs.delete(object_id)
277
+ return objs
278
+ end
279
+
280
+ private
281
+
282
+ def Alias.sum_objects(object_id)
283
+ return 0 if @@objects.include?(object_id)
284
+ @@objects << object_id
285
+ object = Karma[object_id]
286
+ score = object ? object.score : 0
287
+ Alias.filter(:thing_id => object_id).each do |ali|
288
+ score += Alias.sum_objects(ali.aka.pk)
289
+ end
290
+ Alias.filter(:aka_id => object_id).each do |ali|
291
+ score += Alias.sum_objects(ali.thing.pk)
292
+ end
293
+ return score
294
+ end
295
+
296
+ def Alias.create_lock
297
+ @@lock = Mutex.new
298
+ end
299
+
300
+ end
301
+ end
302
+ end
@@ -0,0 +1,44 @@
1
+ class Locator < ModSpox::Plugin
2
+
3
+ def initialize(pipeline)
4
+ super
5
+ add_sig(:sig => 'locate (\S+)', :method => :locate, :desc => 'Locate the given nick', :params => [:nick])
6
+ end
7
+
8
+ def locate(m, params)
9
+ nick = Models::Nick.filter(:nick => params[:nick]).first
10
+ if(nick)
11
+ if(!nick.address.nil? && !nick.address.empty?)
12
+ con = Net::HTTP.new('www.ip-adress.com', 80)
13
+ res = con.request_get("/ip_tracer/#{nick.address}", nil)
14
+ begin
15
+ info = []
16
+ res.value
17
+ page = res.body
18
+ page = page.split("\n")
19
+ page.size.times do |line|
20
+ unless(page[line].index('IP address country:').nil?)
21
+ info << "\2Country:\2 #{page[line+2].gsub(/<.+?>/, '').strip}"
22
+ end
23
+ unless(page[line].index('IP address state:').nil?)
24
+ info << "\2State:\2 #{page[line+2].gsub(/<.+?>/, '').strip}"
25
+ end
26
+ unless(page[line].index('IP address city:').nil?)
27
+ info << "\2City:\2 #{page[line+2].gsub(/<.+?>/, '').strip}"
28
+ end
29
+ unless(page[line].index('ISP of this IP').nil?)
30
+ info << "\2ISP:\2 #{page[line+2].gsub(/<.+?>/, '').strip}"
31
+ end
32
+ end
33
+ reply m.replyto, "\2Locator:\2 #{params[:nick]} - #{info.join(', ')}"
34
+ rescue Object => boom
35
+ Logger.error("Locator plugin generated an exception: #{boom}")
36
+ end
37
+ else
38
+ error m.replyto, "Current address unavailable for nick: #{params[:nick]}"
39
+ end
40
+ else
41
+ error m.replyto, "Failed to find record of nick: #{params[:nick]}"
42
+ end
43
+ end
44
+ end