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,500 @@
1
+ # ex: set ts=4 et:
2
+
3
+ # Slashdot Headline Generator
4
+ # keep nerds happy on those long network outages
5
+ # by pizza
6
+
7
+ class SlashdotHeadlineGenerator < ModSpox::Plugin
8
+ def initialize(pipeline)
9
+ super
10
+ add_sig(:sig => 'fake/.(?: (\d))?', :method => :random, :desc => 'Slashdot Headline Generator', :params => [:count])
11
+ add_sig(:sig => 'fake/.(?: (' + HeadlineGenerator.new.topics.keys.sort.join("|") + '))?', :method => :topic, :desc => 'Slashdot Headline Generator', :params => [:topic])
12
+ end
13
+
14
+ def random(m, params)
15
+ begin
16
+ params[:count] = params[:count].to_i
17
+ params[:count] = 1 if params[:count] < 1
18
+ params[:count] = 5 if params[:count] > 5
19
+ hg = HeadlineGenerator.new
20
+ say = ""
21
+ params[:count].times { say += hg.headline() + "\n" }
22
+ reply m.replyto, say
23
+ rescue Object => boom
24
+ error m.replyto, "Whoops. #{boom}"
25
+ end
26
+ end
27
+
28
+ def topic(m, params)
29
+ begin
30
+ reply m.replyto, HeadlineGenerator.new.topic(params[:topic])
31
+ rescue Object => boom
32
+ error m.replyto, "Whoops. #{boom}"
33
+ end
34
+ end
35
+ end
36
+
37
+ class HeadlineGenerator
38
+
39
+ def initialize()
40
+ @topics = {
41
+ #"apache" => { lambda{ Apache },
42
+ "apple" => lambda{ Apple() },
43
+ "ask" => lambda{ AskSlashdot() },
44
+ #backslash"" => lambda{ BackSlash() },
45
+ "book" => lambda{ BookReview() },
46
+ "bsd" => lambda{ BSD() },
47
+ "business" => lambda{ Business() },
48
+ "dev" => lambda{ Developers() },
49
+ #"entertainment" => lambda{ Entertainment() }
50
+ #"features" => lambda{ Features() },
51
+ "games" => lambda{ Games() },
52
+ #"geeksinspace" => lambda{ GeeksInSpace() },
53
+ "hardware" => lambda{ Hardware() },
54
+ #"idle" => lambda{ Idle() },
55
+ "interview" => lambda{ Interviews() },
56
+ "it" => lambda{ IT() },
57
+ "linux" => lambda{ Linux() },
58
+ #"media" => lambda{ Media() },
59
+ "news" => lambda{ News() },
60
+ #"polls" => lambda{ Polls() },
61
+ #"politics" => lambda{ Politics() },
62
+ "science" => lambda{ Science() },
63
+ "space" => lambda{ Space() },
64
+ "tech" => lambda{ Technology() },
65
+ "yro" => lambda{ YourRightsOnline() }
66
+ }
67
+ end
68
+
69
+ def topics()
70
+ @topics
71
+ end
72
+
73
+ def headline()
74
+ @topics[any(@topics.keys)].call
75
+ end
76
+
77
+ def topic(what)
78
+ if (@topics.key?(what))
79
+ @topics[what].call
80
+ else
81
+ headline()
82
+ end
83
+ end
84
+
85
+ def Apple()
86
+ foo = rand(3)
87
+ if(foo == 0)
88
+ "New " + AppleProduct() + " Release Features " + GoodBrowserFeature()
89
+ elsif(foo == 1)
90
+ "Apple " + AppleHireFire()
91
+ else
92
+ any([ "Turn", "Transform", "Hack" ]) + " Your " + AppleHardware() + " Into A " + any([ "Fishbowl", "Phaser", "RC Car", "Robot", "Webserver", "Vibrator", "Calculator", "Toaster", "Waterboard", "Coffee Machine", "Doorstop", "Brick" ])
93
+ end
94
+ end
95
+
96
+ def AppleHireFire()
97
+ any([ "Hires", "Re-Hires", "Eying", "Steals" ]) + [ " Former", "" ][rand(2)] + " " + TechCompany() + " " + Profession()
98
+ end
99
+
100
+ def AppleProduct() any([ lambda{ AppleSoftware() }, lambda{ AppleHardware() } ]).call; end
101
+ def AppleSoftware() any([ "OS9", "OS X", "iTunes", "iLife", "SnowLeopard", "Cheetah", "Panther" ]); end
102
+ def AppleHardware() any([ "iMac", "iPod", "iPhone", "MacBook", "Mighty Mouse", "Mac Mini", "Airport" ]); end
103
+
104
+ def AskSlashdot()
105
+ any([ "Encrypting", "Porting", "Taking Over", "Forking", "Selling", "Buying", "Saving", "Archiving" ]) + " " +
106
+ any([ "Abandoned", "Open Source", "Free", "Slow", "Closed Source", "Web-based", "Obsolete" ]) + " " +
107
+ any([ "Hardware", "Software", "Projects", "Drivers", "Operating Systems", "Frameworks", "Programming Languages", "Coffee Machines", "Missile Guidance Software", "Filesystems", "Media" ]) + "?"
108
+ end
109
+
110
+ def BookReview() "Book Review: " + BookReviewAdjective() + " " + ProgrammingLanguageOrFramework() end
111
+
112
+ def BookReviewAdjective()
113
+ if (0 == rand(2))
114
+ TechnoAdjective()
115
+ else
116
+ any([ "Ass-Out", "Balls-to-the-Walls", "Inside-Out", "Upside-down", "Kludge Your Way Through", "Learn Just Enough To Be Dangerous:", "Pig-Latin", "Buzzword-Compliant", "Outdated", "Ineffective" ])
117
+ end
118
+ end
119
+
120
+ def BSD()
121
+ os = NerdOS()
122
+ os + " " + OSVersion(os) + " " + NerdOSSuffix()
123
+ end
124
+
125
+ def Business()
126
+ foo = rand(5)
127
+ if(foo == 0)
128
+ Google()
129
+ elsif(foo == 1)
130
+ Microsoft()
131
+ elsif(foo == 2)
132
+ TechCompany() + " Unveils Potential " + VenerableProduct() + " Killer"
133
+ elsif(foo == 3)
134
+ TechCompany() + " " +
135
+ any([ "Considering", "Possibly" ]) + " " +
136
+ any([ "Purchasing", "Alliance with", "Merging with"]) + " " +
137
+ TechCompany() + "?"
138
+ else
139
+ TechCompany() + " Patents " + Patentable()
140
+ end
141
+ end
142
+
143
+ def Developers() any([ lambda{ MozillaDitchFeature() }, lambda{ IsDead() }, lambda{ BugPatched() }, lambda{ GNU() } ]).call; end
144
+
145
+ def IsDead() "Are " + NerdTopic().sub(/y$/, "ie") + "s " + DeadWords() + "?"; end
146
+ def BugPatched() LongTime()[0..-2] +"-Old Bug Discovered in " + NerdOS() + ", Patched in " + ShortTime() + "s"; end
147
+ def GNU() any([ lambda{ Stallman() } ]).call; end
148
+ def Stallman()
149
+ "Richard Stallman " +
150
+ any([ "Slams", "Decries", "Demonizes" ]) +
151
+ " Use of " +
152
+ any([ "Closed-Source", "Proprietary", "Web-based", "Ascii-Only", "Unicode", "English-Only" ]) + " " +
153
+ any([ "Software", "Hardware", "Firmware", "USB Sticks", "CDs", "Operating Systems" ]) +
154
+ " As " +
155
+ any([ "Capitalistic", "Fundamentally Unfree", "Stupid", "'Worse Than Hitler'" ])
156
+ end
157
+
158
+ def Games()
159
+ Game() + " " +
160
+ any([ "Breaks Everyone's Favorite", "Enhances", "Features New", "Promises Better", "Reconsiders", "Redesigns", "Restricts", "Rethinks", "Will Change How You Think About" ]) + " " +
161
+ any(["AI", "Weapons", "Cheats", "Controls", "Easter Eggs", "Graphics", "Levels", "Team-based Cooperation" ])
162
+ end
163
+
164
+ def Hardware()
165
+ any([ "ATI", "NVidia", "Open Source Graphics Collective" ]) + " " +
166
+ any([ "Secretly", "Purportedly", "Possibly", "Admittedly" ]) + " " +
167
+ any([ "Considers", "Cancels", "Reveals" ]) + " " +
168
+ any([ "Porting", "Adding Pipelines to", "Adding Cores to", "Open Sourcing", "New Features in", "Adding Shaders to", "Adding Raytracing to", "Upgrade to", "Production of" ]) + " " +
169
+ RandomGraphicsCardProduct()
170
+ end
171
+
172
+ def GraphicsPrefix() any([ "Open", "Phys", "GP", "Direct" ]); end
173
+ def GraphicsSuffix() any([ "X", "GL", "Gfx" ]); end
174
+ def RandomGraphicsCardProduct() GraphicsPrefix() + GraphicsSuffix() + [ "", ((rand(7)+2)*100).to_s ][rand(2)]; end
175
+
176
+ def IT()
177
+ foo = rand(2)
178
+ if foo == 0
179
+ TechnoAdjective() + " " +
180
+ any([ "Programming", "Studying", "Training", "Administration" ]) + " " +
181
+ any([ "Rituals", "Secrets", "Habits", "Theories", "Stories", "Experiences", "Close Calls" ])
182
+ else
183
+ "What's Your Favorite " + NerdTopic() + "?"
184
+ end
185
+ end
186
+
187
+ def Game() GameTitle() + " " + GameVersion() end
188
+ def GameTitle() any([ "Quake", "Doom", "The Sims", "Half-Life", "Call of Duty", "Warcraft", "TeamFortress", "Halo", "Guitar Hero", "Grand Theft Auto", "Final Fantasy" ]); end
189
+
190
+ def Interviews() "Ask " + TechOrganization() + " " + Profession() + " " + RandomName() end
191
+
192
+ def Linux() any([ lambda{ LinuxOS() }, lambda{ TorvaldsQuote() } ]).call; end
193
+
194
+ def LinuxOS() "Linux " + LinuxVersion() + " " + NerdOSSuffix() end
195
+ def LinuxVersion() "2.6." + (rand(185)+15).to_s; end
196
+
197
+
198
+ def TorvaldsQuote()
199
+ "Torvalds to " +
200
+ any([ "Users", "Administrators", "Everyone", "the Media", "Long-time Contributors", "Linux Volunteers", "Hard-working Subsystem Maintainers", "Linux Community" ]) + ": " +
201
+ any([ "Piss Off!", "You're All Stupid", "Bite Me", "You Are Idiots", "Shut Up" ])
202
+ end
203
+
204
+ def News() any([ lambda{ WebsiteOutage() }, lambda{ InaneNewsQuestion() } ]).call; end
205
+
206
+ def InaneNewsQuestion()
207
+ any([ "Do We Really Want", "Do We Really Need", "Don't We Have Enough" ]) + " " +
208
+ any([ "ISPs", "Vendors", "Software Companies", "Monopolies", "Advertisers", "DRM", "Watermarks", "Trademarks" ]) + " " +
209
+ any([ "Filtering", "In", "Monitoring", "Embedded in" ]) + " " +
210
+ any([ "Desktops", "Software", "the Workplace", "Entertainment", "Source Code", "Networks", "Schools", "Games" ]) + "?"
211
+ end
212
+
213
+ def Science() any([ lambda{ Physics() }, lambda{ Math() }, lambda{ Science() } ]).call; end
214
+
215
+ def Technology() any([ lambda{ SoftwareVS() }, lambda{ Top10() } ]).call; end
216
+
217
+ def SoftwareVS() SoftwareProduct() + " " + any([ "Takes On", "vs.", "Now Supports", "Drops Support for" ]) + " " + any([ "PDF", "Graphics", "Plaintext", "the Internet", "Email", "Unicode" ]); end
218
+
219
+ def Top10()
220
+ "Top 10 " +
221
+ any([ "Hottest", "Disastrous", "Best", "Worst", "Biggest", "Stupidest" ]) + " " +
222
+ any([ "Applications", "Operating Systems", "Programming Languages", "IDEs", "Debuggers", "PCs", "Products", "Technologies", "Decisions in Software" ])
223
+ end
224
+
225
+ def SoftwareProduct() any([ "MS Word", "Excel", "Visio", "Acrobat", "Photoshop", "Lotus Notes", "OpenOffice", "GNU Cash" ]); end
226
+ def YourRightsOnline() any([ lambda{ Encryption() }, lambda{ FileSharing() }, lambda{ UserDataStolen() }, lambda{ TinfoilHat() } ]).call; end
227
+ def Encryption() "Researchers Break " + TechnoRate() + " " + any(["Encryption", "Transmission", "Internet2" ]) + " Record"; end
228
+
229
+ def UserDataStolen()
230
+ any([ "Bank", "Corporation", "University", "Government", "Military" ]) + " " +
231
+ any([ "Misplaces USB Stick Containing", "Loses Harddrives Containing", "Sells Tape Drive Containing", "Mistakenly Gives Away", "Website Exposes" ]) + " " +
232
+ (rand(500)).to_s + " Million " +
233
+ any([ "Credit Card Numbers", "Social Security Numbers", "User Passwords" ])
234
+ end
235
+
236
+ def TinfoilHat()
237
+ any([
238
+ "Is " + (rand(20)+5).to_s + "-Gauge Tinfoil Really Thick Enough?",
239
+ GovOrg() + " Monitors Your " + PersonalThing(),
240
+ "Encrypting Your " + PersonalThing() + " Won't Thwart " + GovOrg(),
241
+ "Wouldn't " + any([ "You", "Aliens", "Your Mom", "Your Grandmother", "Your Boss" ]) + " Use " + NerdOS() + "?"
242
+ ])
243
+ end
244
+
245
+ def Microsoft()
246
+ any([
247
+ lambda{ Windows() },
248
+ lambda{ WindowsUpdate() },
249
+ lambda{ MicrosoftEvil() },
250
+ lambda{ MicrosoftRandom() }
251
+ ]).call
252
+ end
253
+
254
+ def Windows() WindowsPrefix() + " Windows " + WindowsVersion() end
255
+
256
+ def MicrosoftEvil()
257
+ "Microsoft's " +
258
+ any([ "Patents", "Pricing Policies", "Monopolistic Tactics", "Insecure Software", "High Prices" ]) + " " +
259
+ any([ "Crippling", "Destroying", "Maiming", "Hurting", "Poisoning", "Degrading" ]) + " " +
260
+ any([ "the Internet", "Operating Systems", "the Software Industry", "Society", "Open Source", "Blind Children", "Communities", "the Environment", "Users", "an Entire Generation" ])
261
+ end
262
+
263
+ def WindowsUpdate()
264
+ "Latest Windows " +
265
+ any([ "Patch", "Update", "Service Pack" ]) + " " +
266
+ any([ "Causes More Problems Than It Solves", "Destroys Network", "Contains Virus", "Is a Mess", "Less Than Optimal" ])
267
+ end
268
+
269
+ def MicrosoftRandom() "Microsoft " + EvilVerb() + " " + Victims() end
270
+ def FileSharing()
271
+ any([
272
+ lambda{EvilOrg() + " " + EvilVerb() + " " + Victims() },
273
+ lambda{ RIAA() }
274
+ ]).call
275
+ end
276
+
277
+ def RIAA()
278
+ foo = rand(2)
279
+ if (0 == foo)
280
+ "RIAA's " +
281
+ any([ "Next", "Newest", "Latest" ]) + " " +
282
+ any([ "Dirty", "Dubious", "Abominable", "Horrific", "Ludicruous", "Unconstitutional" ]) + " " +
283
+ any([ "Method", "Tactic", "Trick" ]) + ": " +
284
+ any([ "Pre-Sale", "Thought-based", "Random", "Thought-Crime", "Probabilistic", "Automated", "Pre-Pirating", "EULA-based" ]) + " " +
285
+ any([ "Taxes", "Lawsuits", "Trials", "Executions", "Waterboarding" ])
286
+ else
287
+ any([ "The Pirate Bay", "TPB" ]) + " " +
288
+ any([ "Continue", "Are Still At It", "Haven't Given In", "Haven't Given Up" ]) + " " +
289
+ any([ "Despite Being", "Even Though They Are" ]) + " " +
290
+ any([ "Homeless", "In Jail", "Dead", "in Somalia", "in Parliament", "Now Born-Again Christians", "Surrounded", "Wanted Dead or Alive", "Computerless" ])
291
+ end
292
+ end
293
+
294
+ def Google()
295
+ foo = rand(4)
296
+ if(foo == 0)
297
+ x = MundaneApp()
298
+ "New Google G" + x.sub(" ","") + " Beta Doesn't Just Reinvent the " + x
299
+ elsif(foo == 1)
300
+ "Google's Long-Awaited Web-based " + MundaneApp() + " Enters Beta"
301
+ elsif(foo == 2)
302
+ "Google's Next Recruits: World's Elite " + RandomProfession() + "s"
303
+ else
304
+ "Google Does It Again"
305
+ end
306
+ end
307
+
308
+ def WebsiteOutage() Website() + " Experiences " + ShortTime() + " Outage, Users " + BadNoun() end
309
+
310
+ def MozillaDitchFeature() "Mozilla To Ditch Firefox's " + GoodBrowserFeature() + " Support For Experimental " + StupidFuturisticFirefoxFeature() end
311
+
312
+ def NerdOSSuffix()
313
+ foo = rand(4)
314
+ if(foo == 0)
315
+ "Now Supports " + ArcaneFeature()
316
+ elsif(foo == 1)
317
+ any([ "Voted Best", "Smash Hit", "Cracked" ]) + " At " + NerdCon()
318
+ elsif(foo == 2)
319
+ "Forked"
320
+ else
321
+ "Released"
322
+ end
323
+ end
324
+
325
+ def Space()
326
+ any([
327
+ lambda{ SpaceRevelation() },
328
+ lambda{ SpaceCountry() },
329
+ lambda{ SpaceGeneric() },
330
+ lambda{
331
+ any([ "Probe", "Mission" ]) + " " +
332
+ any([ "Encounters", "Confronts" ]) + " " +
333
+ any([ "Strange", "Debilitating", "Horrifying", "Unexpected", "Damaging" ]) + " " +
334
+ any([ "Turbulence", "Smell", "Sights", "Residue" ]) + " " +
335
+ any([ "on", "Near", "In Vicinity of" ]) + " " +
336
+ any([ "Uranus" ])
337
+ }
338
+ ]).call
339
+ end
340
+
341
+ def SpaceRevelation()
342
+ any([ "CO2", "Water", "Ice", "Fossils", "Methane", "Rocks", "Storms", "Canals", "Artifacts", "Impact Craters", "Strange Patterns" ]) +
343
+ " On " +
344
+ any([ "Moon", "Mars", "Phobos", "Deimos", "Io", "Europa", "Ganymede", "Jupiter", "Saturn", "the Sun" ]) + " " +
345
+ any([ "Could", "May" ]) + " " +
346
+ any([ "Indicate", "Signal", "Foretell", "Affect", "Hint at", "Explain the End of" ]) + " " +
347
+ any([ "Life as We Know It", "Early Life", "the Early Solar System", "Alien Dinosaurs", "Future Space Travel", "Acient Biosphere", "Sunspots", "Mystery Transmissions" ])
348
+ end
349
+
350
+ def SpaceCountry()
351
+ any([ "U.S.", "Canada", "Russia", "China", "Europe" ]) + " " +
352
+ any([ "On Path To", "Takes Aim at", "Looks Towards", "Contemplating" ]) + " " +
353
+ any([ "Moonbase", "Advanced Satellites", "Mars Exploration", "Mars Missions", "Mars Colony" ])
354
+ end
355
+
356
+ def SpaceGeneric()
357
+ [ SpaceAgency(), SpaceVessel(), SpaceVerb(), SpaceBullshit() ].join(" ")
358
+ end
359
+
360
+ def Physics()
361
+ foo = rand(1+1-0)
362
+ if foo == 0
363
+ any([ "Elusive", "Virtual", "Quantum", "Puzzling", "\"Impossible\"" ]) + " " +
364
+ PhysicsBullshit() +
365
+ " Particle " +
366
+ any([ "Discovered", "Never Existed", "Theorized", "Modeled", "Observed", "Detected" ])
367
+ else
368
+ ParticleAccelerator()
369
+ end
370
+ end
371
+
372
+ def ParticleAccelerator()
373
+ foo = rand(3)
374
+ if(foo == 0)
375
+ LastName() + " Particle Accelerator Data Will Take " + LongTime() + " to Process"
376
+ elsif(foo == 1)
377
+ "Particle Accelerator " + any([ "Repairs", "Upgrade", "Construction", "Tune Up", "Systems Test", "Reboot" ]) + " Will " + any([ "Take " + LongTime(), "Cost $" + BigNumber() ])
378
+ else
379
+ LastName() + " Particle Accelerator Bug Means " + LongTime()[0..-2] + " Delay"
380
+ end
381
+ end
382
+
383
+ def Math()
384
+ [
385
+ any([ "New", "Existing", "Surprising", "Optimized", "Powerful", "Exponential" ]),
386
+ any([ "Pattern", "Algorithm", "Power Series", "Financial Model", "Sequence", "Non-Euclidean Geometery" ]),
387
+ any([ "Discovered in", "Found in", "Explains", "Simplifies", "Derived From", "Sheds Light on", "Changes Our Understanding of", "Has Huge Ramifications for" ]),
388
+ any([ "Prime Numbers", "Stock Market", "Financial Markets", "Evolution", "the Cosmos", "Spacetime", "String Theory", "Fluid Dynamics", "Soap Bubbles", "Knots", "Turbulence" ])
389
+ ].join(" ")
390
+ end
391
+
392
+ def NerdOS()
393
+ foo = rand(3)
394
+ if(foo == 0)
395
+ "Linux"
396
+ elsif(foo == 1)
397
+ RandomBSD()
398
+ else
399
+ RandomOS()
400
+ end
401
+ end
402
+
403
+ def BigNumber() (rand(990)+10).to_s + " " + any([ "Million", "Billion", "Trillion" ]); end
404
+
405
+
406
+ def ProgrammingLanguageOrFramework() any([ lambda{ ProgrammingLanguage() }, lambda{ Framework() } ]).call; end
407
+ def ShortTime() (rand(59)+1).to_s + " " + ShortTimeUnit() end
408
+ def LongTime() (rand(6)+5).to_s + " " + LongTimeUnit() end
409
+ def RandomBSD() Prefix() + "BSD"; end
410
+ def RandomOS() Prefix() + "OS"; end
411
+
412
+ def GameVersion() (2+rand(8)).to_s; end
413
+
414
+ def SimpleVersion() rand(10).to_s; end
415
+
416
+ def OSVersion(os)
417
+ if("Linux" == os)
418
+ LinuxVersion()
419
+ else
420
+ Version()
421
+ end
422
+ end
423
+
424
+
425
+ def Version()
426
+ ver = SimpleVersion() + "." + SimpleVersion()
427
+ if rand(2) == 0
428
+ ver = ver + "." + SimpleVersion()
429
+ end
430
+ ver
431
+ end
432
+
433
+ def ArcaneFeature() TechnoAdjective() + " " + TechnoNoun() + " " + TechnoVerb() end
434
+ def NerdCon() Prefix() + "Con"; end
435
+ def StupidSoftwareName() Consonant().to_s.upcase() + Vowel() + Vowel() + Consonant() + Vowel() end
436
+
437
+ def any(l); l[rand(l.length)]; end
438
+
439
+ def WindowsPrefix()
440
+ any([
441
+ "Critical Vulnerability Discovered in",
442
+ "Microsoft Discontinues Support for",
443
+ "Hackers Poke Holes in",
444
+ "Linux Performance Trumps",
445
+ "What Can't You Do In Linux You Can Do In"
446
+ ])
447
+ end
448
+
449
+ def Prefix() any([ "Free", "Net", "Open", "Source", "Nerd", "StarTrek", "React", "Hacker", "Wifi", "Shmoo", "Foo" ]); end
450
+ def NerdTopic() any([ "Text Editor", "Regular Expression", "Database Query", "Functional Programming Language", "Hacking Technique", "Stack-Smasher", "Cmdline", "Keyboard Shortcut", "Spam Solution", "Algorithm", "x86 Opcode", "DRM Workaround", "Filesharing Strategy", "Micro-Optimization", "Design Pattern" ]); end
451
+ def VenerableProduct () any([ "Google", "Oracle", "Relational Database", "Windows", "Wifi", "TCP", "HTTP", "Search Engine", "Desktop", "Server" ]); end
452
+ def TechnoAdjective() any([ "Recursive", "Front-end", "Back-end", "Object-Oriented", "Extreme", "Efficient", "Optimized", "Obfuscated", "Flash-based", "Cached", "Content-based", "Effective", "P=NP", "P!=NP", "Linear", "Functional", "O(log n)", "O(n)", "O(n^2)" ]); end
453
+ def TechnoNoun() any([ "Filesystem", "Kernel", "Module", "Dependency", "Touchscreen", "Pen Input", "USB", "Serial Port", "SCSI", "Storage", "TCP", "CPU", "Network" ]); end
454
+ def TechnoVerb() any([ "Unloading", "Loading", "Injection", "Healing", "Filtering", "Balancing" ]); end
455
+ def WindowsVersion() any([ "3.11", "95", "98", "ME", "XP", "Server 2003", "Vista", "7" ]); end
456
+ def ProgrammingLanguage() any([ "PHP", "Perl", "Python", "Ruby", "Lisp", "Lua" ]); end
457
+ def Framework() any([ "Drupal", "PHPMyAdmin", "Rails", "Django", "Twisted", "Google Gears", "MySQL" ]); end
458
+ def Website() any([ "CNN.com", "Facebook", "Digg", "Youtube", "MSNBC.com", "Yahoo.com", "Google.com", "GMail", "Twitter" ]); end
459
+ def TechCompany() any([ "Oracle", "Microsoft", "Sun", "Hewlett Packard", "Dell", "Yahoo!", "IBM" ]); end
460
+ def BadNoun() any([ "Angry", "Confused", "Oblivious", "Scared" ]); end
461
+ def ShortTimeUnit() any([ "Second", "Minute", "Hour" ]); end
462
+ def LongTimeUnit() any([ "Days", "Weeks", "Months", "Years", "Decades" ]); end
463
+ def EvilOrg() any([ "MPAA", "RIAA", "ISP" ]); end
464
+ def EvilVerb() any([ "Sues", "Hates", "Blocks", "Rootkits", "Monitors", "Cancels" ]); end
465
+ def Victims() any([ "Customers", "Contractors", "Users", "Visitors", "Children", "Computerless Grandmother" ]); end
466
+ def MundaneApp() any([ "Email", "Word Processor", "Text Editor", "Spreadsheet", "BIOS", "Database" ]); end
467
+ def SpaceAgency() any([ "NASA", "European Space Agency", "China" ]); end
468
+ def SpaceVessel() any([ "Shuttle", "Probe", "Satellite", "Rocket", "RamJet" ]); end
469
+ def SpaceVerb() any([ "Launched Toward", "Deploys", "Repairs", "Loses", "Headed For", "Docks With", "Links Up To" ]); end
470
+ def SpaceBullshit() any([ "Important Bolt", "Heatshield", "Experiment", "Sensor", "Orbit", "Mars", "Jupiter", "Saturn", "Uranus" ]); end
471
+ def Vowel() any("aeiou".split(//)); end
472
+ def Consonant() any("bcdfghjklmnpqrtvwxyz".split(//)); end
473
+ def GoodBrowserFeature() any([ "URLs", "Links", "Text", "Image", "Icons", "Mouse Pointer", "Tabs", "Extensions", "Multithreading", "HTTP/1.1", "Mouse Gestures", "Audio Support", "Scrolling" ]); end
474
+ def StupidFuturisticFirefoxFeature() any([ "Awesome Bar", "3D Hologram", "Klingon Language Support", "Invisible Icons", "Upside-Down Pages", "Single Pixel", "Neural Interface", "Joystick" ]); end
475
+ def PhysicsBullshit() any([ "Quasi", "Zig-Zag", "Upside-Down", "Triple-Flavored", "Inside-Out" ]); end
476
+ def Rate() "/" + any([ "sec", "min", "hr" ]); end
477
+ def Amount() any([ "kbit", "Mbit", "GBit", "Tbit", "Pbit", "Ybit" ]); end
478
+ def TechnoRate() (100+rand(900)).to_s + " " + Amount() + Rate() end
479
+ def RandomProfession() any([ "Janitor", "Gardener", "Architect", "Rollerskater", "Superintendent", "Chef", "Bicyclist", "Juggler", "Comedian" ]); end
480
+
481
+ def TechOrganization() StupidSoftwareName() + any(["Soft", "!", "Studios", " Corp"]); end
482
+ def Profession() any([ "CEO", "President", "Founder", "Chairman", "Project Lead", "Guru", "Architect", "Designer", "Creator", "Programmer" ]); end
483
+ def RandomName() FirstName() + " " + LastName() end
484
+ def FirstName() any([ "Arthur", "Bob", "Carl", "David", "Earl", "Fred", "George", "Harold", "Ivan", "Julia", "Kevin", "Larry", "Margaret", "Michael", "Nancy", "Rory", "Ted", "Tracy" ]); end
485
+ def LastName() any([ "Anderson", "Blevins", "Carmack", "Daniels", "Johnson", "Kelvin", "Morris", "Neilson", "Savage", "Smith" ]); end
486
+
487
+ def Patentable() MundaneComputerVerb() + " " + MundaneComputerNoun() end
488
+ def MundaneComputerVerb() any([ "Coloring", "Resizing", "Sorting", "Linking", "Printing", "Retrieving", "Storing" ]); end
489
+ def MundaneComputerNoun() any([ "Harddrives", "Text", "Images", "Messages", "Email" ]); end
490
+
491
+ def GovOrg() any([ "CIA", "NSA", "NRO", "FBI", "Military", "DARPA", "Management" ]); end
492
+ def PersonalThing() any([ "Phone Calls", "Emails", "Handwriting", "HAM Radio Broadcasts", "Dreams", "Nocturnal Emissions" ]); end
493
+ def DeadWords() any([ "Dead", "Obsolete", "Finished", "Worth It", "Valuable", "On the Way Out", "Stupid", "Done For" ]); end
494
+
495
+ end
496
+
497
+ #500.times{ puts HeadlineGenerator.new.topic("yro") }
498
+ #puts HeadlineGenerator.new.topic("yro")
499
+ #puts HeadlineGenerator.new.topics.keys.sort.join("|")
500
+
@@ -0,0 +1,32 @@
1
+ require 'mod_spox/messages/outgoing/Privmsg'
2
+ class Talk < ModSpox::Plugin
3
+
4
+ include Models
5
+
6
+ def initialize(pipeline)
7
+ super
8
+ group = Group.find_or_create(:name => 'talk')
9
+ add_sig(:sig => 'say (\S+) (.+)', :method => :talk, :group => group, :desc => 'Make bot speak given text to target', :req => 'private', :params => [:target, :text])
10
+ add_sig(:sig => 'action (\S+) (.+)', :method => :action, :group => group, :desc => 'Make bot perform action for target', :req => 'private', :params => [:target, :text])
11
+ end
12
+
13
+ def talk(message, params)
14
+ send_p(message, params)
15
+ end
16
+
17
+ def action(message, params)
18
+ send_p(message, params, true)
19
+ end
20
+
21
+ private
22
+
23
+ def send_p(message, params, action=false)
24
+ target = Helpers.find_model(params[:target], false)
25
+ if(target.nil?)
26
+ reply message.replyto, "\2Error:\2 Failed to locate target: #{params[:target]}"
27
+ else
28
+ @pipeline << Messages::Outgoing::Privmsg.new(target, params[:text], action)
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,103 @@
1
+ class Topten < ModSpox::Plugin
2
+
3
+ include Models
4
+
5
+ def initialize(pipeline)
6
+ super
7
+ ChatStat.create_table unless ChatStat.table_exists?
8
+ add_sig(:sig => 'topten', :method => :topten, :req => 'public', :desc => 'Show topten users since midnight')
9
+ add_sig(:sig => 'topten ([0-9]{4}\/[0-9]{2}\/[0-9]{2})', :method => :archive, :desc => 'Show topten from given date', :req => 'public', :params => [:date])
10
+ add_sig(:sig => 'stats ?(\S+)?', :method => :stats, :desc => 'Show stats on nick', :req => 'public', :params => [:nick])
11
+ add_sig(:sig => 'stats lifetime (\S+)?', :method => :life_stats, :desc => 'Show stat totals for given nick', :req => 'public', :params => [:nick])
12
+ @pipeline.hook(self, :log_stats, :Incoming_Privmsg)
13
+ end
14
+
15
+ def topten(m, p)
16
+ stats = ChatStat.filter(:channel_id => m.target.pk, :daykey => construct_daykey).reverse_order(:bytes).limit(10)
17
+ if(stats.count > 0)
18
+ users = []
19
+ stats.each do |stat|
20
+ bytes = (stat.bytes > 1023) ? "#{sprintf('%.2f', (stat.bytes / 1024.0))}kb" : "#{stat.bytes}b"
21
+ users << "#{Nick[stat.nick_id].nick}: #{bytes}"
22
+ end
23
+ reply m.replyto, "\2Topten:\2 #{users.join(', ')}"
24
+ else
25
+ reply m.replyto, "\2Error:\2 No stats found for this channel."
26
+ end
27
+ end
28
+
29
+ def archive(m, p)
30
+ stats = ChatStat.filter(:channel_id => m.target.pk, :daykey => p[:date]).reverse_order(:bytes).limit(10)
31
+ if(stats.count > 0)
32
+ users = []
33
+ stats.each do |stat|
34
+ bytes = (stat.bytes > 1023) ? "#{sprintf('%.2f', (stat.bytes / 1024.0))}kb" : "#{stat.bytes}b"
35
+ users << "#{Nick[stat.nick_id].nick}: #{bytes}"
36
+ end
37
+ reply m.replyto, "\2Topten:\2 #{users.join(', ')}"
38
+ else
39
+ reply m.replyto, "\2Error:\2 No stats found for date given."
40
+ end
41
+ end
42
+
43
+ def stats(m, p)
44
+ nick = p[:nick] ? Nick.locate(p[:nick], false) : m.source
45
+ if(nick.is_a?(Nick))
46
+ stat = ChatStat.filter(:nick_id => nick.pk, :channel_id => m.target.pk, :daykey => construct_daykey).first
47
+ if(stat)
48
+ bytes = (stat.bytes > 1023) ? "#{sprintf('%.2f', (stat.bytes / 1024.0))}kb" : "#{stat.bytes}b"
49
+ reply m.replyto, "#{nick.nick}: #{bytes} logged. #{stat.words} words spoken. #{stat.questions} questions asked."
50
+ else
51
+ reply m.replyto, "\2Error:\2 #{nick.nick} has no stats recorded for today"
52
+ end
53
+ else
54
+ reply m.replyto, "\2Error:\2 Failed to find record of nick: #{p[:nick]}"
55
+ end
56
+ end
57
+
58
+ def life_stats(m, p)
59
+ nick = p[:nick] ? Nick.locate(p[:nick], false) : m.source
60
+ if(nick)
61
+ result = ChatStat.group(:nick_id).select('SUM(bytes) as tbytes'.lit, 'SUM(words) as twords'.lit, 'SUM(questions) as tquestions'.lit).filter(:nick_id => nick.pk).first
62
+ bytes = (result[:tbytes].to_i > 1023) ? "#{sprintf('%.2f', (result[:tbytes].to_i / 1024.0))}kb" : "#{result[:tbytes]}b"
63
+ reply m.replyto, "#{nick.nick} (total): #{bytes} logged, #{result[:twords]} words spoken and #{result[:tquestions]} questions asked"
64
+ else
65
+ reply m.replyto, "\2Error:\2 Failed to find #{p[:nick]}"
66
+ end
67
+ end
68
+
69
+ def log_stats(m)
70
+ return unless m.is_public?
71
+ key = construct_daykey
72
+ stat = ChatStat.find_or_create(:nick_id => m.source.pk, :channel_id => m.target.pk, :daykey => key)
73
+ words = m.message.scan(/([^ ]+ |[^ ]$)/).size
74
+ bytes = m.message.gsub(/[^a-zA-Z0-9`\~\!@#\$%\^&\*\(\)_\+\[\]\}\{;:'"\/\?\.>,<\\|\-=]/, '').length
75
+ questions = m.message.scan(/.+?(!?\?!? |!?\?!?$)/).size
76
+ stat.words += words
77
+ stat.bytes += bytes
78
+ stat.questions += questions
79
+ stat.save
80
+ end
81
+
82
+ private
83
+
84
+ def construct_daykey
85
+ t = Time.now
86
+ return "#{t.year}/#{sprintf('%02d', t.month)}/#{sprintf('%02d', t.day)}"
87
+ end
88
+
89
+ class ChatStat < Sequel::Model
90
+ set_schema do
91
+ primary_key :id
92
+ integer :words, :null => false, :default => 0
93
+ integer :bytes, :null => false, :default => 0
94
+ integer :questions, :null => false, :default => 0
95
+ varchar :daykey, :null => false
96
+ foreign_key :channel_id, :table => :channels
97
+ foreign_key :nick_id, :table => :nicks
98
+ end
99
+ many_to_one :channel, :class => ModSpox::Models::Channel
100
+ many_to_one :nick, :class => ModSpox::Models::Nick
101
+ end
102
+
103
+ end