mod_spox 0.1.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. data/CHANGELOG +36 -0
  2. data/INSTALL +2 -2
  3. data/README +0 -1
  4. data/bin/mod_spox +51 -12
  5. data/data/mod_spox/extras/AOLSpeak.rb +5 -18
  6. data/data/mod_spox/extras/AutoKick.rb +44 -23
  7. data/data/mod_spox/extras/AutoMode.rb +2 -5
  8. data/data/mod_spox/extras/AutoRejoin.rb +21 -0
  9. data/data/mod_spox/extras/Bouncer.rb +10 -10
  10. data/data/mod_spox/extras/Bytes.rb +12 -0
  11. data/data/mod_spox/extras/Confess.rb +131 -52
  12. data/data/mod_spox/extras/DCC.rb +189 -0
  13. data/data/mod_spox/extras/DevWatch.rb +32 -33
  14. data/data/mod_spox/extras/FloodKicker.rb +129 -0
  15. data/data/mod_spox/extras/GoogleIt.rb +13 -0
  16. data/data/mod_spox/extras/Headers.rb +31 -4
  17. data/data/mod_spox/extras/Karma.rb +103 -49
  18. data/data/mod_spox/extras/Logger.rb +45 -30
  19. data/data/mod_spox/extras/LolSpeak.rb +1 -1
  20. data/data/mod_spox/extras/NickServ.rb +83 -0
  21. data/data/mod_spox/extras/PhpCli.rb +12 -15
  22. data/data/mod_spox/extras/PhpFuncLookup.rb +57 -25
  23. data/data/mod_spox/extras/Quotes.rb +5 -4
  24. data/data/mod_spox/extras/RegexTracker.rb +160 -0
  25. data/data/mod_spox/extras/Roulette.rb +22 -23
  26. data/data/mod_spox/extras/Search.rb +3 -2
  27. data/data/mod_spox/extras/Slashdot.rb +35 -0
  28. data/data/mod_spox/extras/Topten.rb +5 -5
  29. data/data/mod_spox/extras/TracTicket.rb +68 -0
  30. data/data/mod_spox/extras/Translate.rb +69 -30
  31. data/data/mod_spox/extras/Twitter.rb +372 -0
  32. data/data/mod_spox/extras/UrbanDictionary.rb +21 -12
  33. data/data/mod_spox/extras/Weather.rb +1 -1
  34. data/data/mod_spox/plugins/Authenticator.rb +63 -30
  35. data/data/mod_spox/plugins/Banner.rb +164 -151
  36. data/data/mod_spox/plugins/Helper.rb +18 -7
  37. data/data/mod_spox/plugins/PluginLoader.rb +46 -22
  38. data/data/mod_spox/plugins/PoolConfig.rb +52 -0
  39. data/data/mod_spox/plugins/Quitter.rb +1 -1
  40. data/data/mod_spox/plugins/Status.rb +28 -0
  41. data/lib/mod_spox/Action.rb +20 -3
  42. data/lib/mod_spox/BaseConfig.rb +1 -0
  43. data/lib/mod_spox/Bot.rb +98 -75
  44. data/lib/mod_spox/BotConfig.rb +14 -6
  45. data/lib/mod_spox/ConfigurationWizard.rb +94 -105
  46. data/lib/mod_spox/Database.rb +33 -13
  47. data/lib/mod_spox/Helpers.rb +67 -38
  48. data/lib/mod_spox/Loader.rb +25 -5
  49. data/lib/mod_spox/Logger.rb +20 -62
  50. data/lib/mod_spox/MessageFactory.rb +34 -25
  51. data/lib/mod_spox/Monitors.rb +5 -0
  52. data/lib/mod_spox/Pipeline.rb +40 -51
  53. data/lib/mod_spox/Plugin.rb +40 -9
  54. data/lib/mod_spox/PluginManager.rb +46 -38
  55. data/lib/mod_spox/Pool.rb +129 -143
  56. data/lib/mod_spox/Socket.rb +41 -50
  57. data/lib/mod_spox/Sockets.rb +211 -0
  58. data/lib/mod_spox/Timer.rb +86 -69
  59. data/lib/mod_spox/handlers/BadNick.rb +1 -1
  60. data/lib/mod_spox/handlers/Created.rb +1 -1
  61. data/lib/mod_spox/handlers/Handler.rb +9 -0
  62. data/lib/mod_spox/handlers/Invite.rb +1 -1
  63. data/lib/mod_spox/handlers/Join.rb +2 -2
  64. data/lib/mod_spox/handlers/Kick.rb +1 -1
  65. data/lib/mod_spox/handlers/LuserChannels.rb +1 -1
  66. data/lib/mod_spox/handlers/LuserOp.rb +1 -1
  67. data/lib/mod_spox/handlers/LuserUnknown.rb +1 -1
  68. data/lib/mod_spox/handlers/Mode.rb +2 -2
  69. data/lib/mod_spox/handlers/MyInfo.rb +1 -1
  70. data/lib/mod_spox/handlers/Names.rb +1 -1
  71. data/lib/mod_spox/handlers/Nick.rb +20 -3
  72. data/lib/mod_spox/handlers/NickInUse.rb +3 -3
  73. data/lib/mod_spox/handlers/Notice.rb +5 -15
  74. data/lib/mod_spox/handlers/Part.rb +1 -1
  75. data/lib/mod_spox/handlers/Ping.rb +1 -1
  76. data/lib/mod_spox/handlers/Pong.rb +1 -1
  77. data/lib/mod_spox/handlers/Privmsg.rb +2 -2
  78. data/lib/mod_spox/handlers/Quit.rb +1 -1
  79. data/lib/mod_spox/handlers/Topic.rb +2 -1
  80. data/lib/mod_spox/handlers/Welcome.rb +3 -3
  81. data/lib/mod_spox/handlers/Who.rb +9 -7
  82. data/lib/mod_spox/handlers/Whois.rb +29 -16
  83. data/lib/mod_spox/handlers/YourHost.rb +1 -1
  84. data/lib/mod_spox/messages/incoming/Privmsg.rb +38 -19
  85. data/lib/mod_spox/messages/internal/DCCListener.rb +12 -0
  86. data/lib/mod_spox/messages/internal/DCCRequest.rb +12 -0
  87. data/lib/mod_spox/messages/internal/DCCSocket.rb +19 -0
  88. data/lib/mod_spox/messages/internal/StatusRequest.rb +2 -1
  89. data/lib/mod_spox/messages/outgoing/Privmsg.rb +21 -5
  90. data/lib/mod_spox/migrations/001_initialize_models.rb +115 -0
  91. data/lib/mod_spox/models/Auth.rb +24 -16
  92. data/lib/mod_spox/models/AuthGroup.rb +4 -3
  93. data/lib/mod_spox/models/Channel.rb +20 -12
  94. data/lib/mod_spox/models/ChannelMode.rb +2 -2
  95. data/lib/mod_spox/models/Config.rb +11 -3
  96. data/lib/mod_spox/models/Group.rb +6 -1
  97. data/lib/mod_spox/models/Nick.rb +93 -33
  98. data/lib/mod_spox/models/NickChannel.rb +8 -6
  99. data/lib/mod_spox/models/NickGroup.rb +16 -0
  100. data/lib/mod_spox/models/NickMode.rb +3 -3
  101. data/lib/mod_spox/models/Server.rb +6 -2
  102. data/lib/mod_spox/models/Setting.rb +12 -6
  103. data/lib/mod_spox/models/Signature.rb +7 -13
  104. data/lib/mod_spox/models/Trigger.rb +1 -1
  105. metadata +125 -100
@@ -16,7 +16,7 @@ class PluginLoader < ModSpox::Plugin
16
16
  @pipeline.hook(self, :get_module, :Internal_PluginModuleResponse)
17
17
  @plugins_mod = nil
18
18
  end
19
-
19
+
20
20
  # message:: ModSpox::Messages::Incoming::Privmsg
21
21
  # params:: matching signature params
22
22
  # Output currently available plugins for loading
@@ -27,7 +27,7 @@ class PluginLoader < ModSpox::Plugin
27
27
  end
28
28
  reply message.replyto, output
29
29
  end
30
-
30
+
31
31
  # message:: ModSpox::Messages::Incoming::Privmsg
32
32
  # params:: matching signature params
33
33
  # Output currently loaded plugins
@@ -39,32 +39,32 @@ class PluginLoader < ModSpox::Plugin
39
39
  # Load the given plugin
40
40
  def load_plugin(message, params)
41
41
  plugins = find_plugins
42
- if(plugins.has_key?(params[:plugin]))
43
- name = plugin_discovery(BotConfig[:pluginextraspath]).keys.include?(params[:plugin]) ? nil : "#{params[:plugin]}.rb"
44
- @pipeline << Messages::Internal::PluginLoadRequest.new(self, plugins[params[:plugin]], name)
42
+ if(plugins.has_key?(params[:plugin].to_sym))
43
+ name = plugin_discovery(BotConfig[:pluginextraspath]).keys.include?(params[:plugin].to_sym) ? nil : "#{params[:plugin]}.rb"
44
+ @pipeline << Messages::Internal::PluginLoadRequest.new(self, plugins[params[:plugin].to_sym], name)
45
45
  @pipeline << Messages::Outgoing::Privmsg.new(message.replyto, "Okay")
46
46
  else
47
47
  @pipeline << Messages::Outgoing::Privmsg.new(message.replyto, "Failed to find plugin: #{params[:plugin]}")
48
48
  end
49
49
  end
50
-
50
+
51
51
  # message:: ModSpox::Messages::Incoming::Privmsg
52
52
  # params:: matching signature params
53
53
  # Unload the given plugin
54
54
  def unload_plugin(message, params)
55
- path = loaded_path(params[:plugin])
55
+ path = loaded_path(params[:plugin].to_sym)
56
56
  unless(path.nil?)
57
- name = plugin_discovery(BotConfig[:pluginextraspath]).keys.include?(params[:plugin]) ? nil : ".#{params[:plugin]}.rb"
57
+ name = plugin_discovery(BotConfig[:pluginextraspath]).keys.include?(params[:plugin].to_sym) ? nil : ".#{params[:plugin]}.rb"
58
58
  @pipeline << Messages::Internal::PluginUnloadRequest.new(self, path, name)
59
59
  @pipeline << Messages::Outgoing::Privmsg.new(message.replyto, "Okay")
60
60
  else
61
61
  @pipeline << Messages::Outgoing::Privmsg.new(message.replyto, "Failed to find loaded plugin named: #{params[:plugin]}")
62
62
  end
63
63
  end
64
-
64
+
65
65
  # message:: ModSpox::Messages::Incoming::Privmsg
66
66
  # params:: matching signature params
67
- # Reloads plugins
67
+ # Reloads plugins
68
68
  def reload_plugin(message, params)
69
69
  if(params[:plugin])
70
70
  users = plugin_discovery(BotConfig[:userpluginpath])
@@ -84,15 +84,34 @@ class PluginLoader < ModSpox::Plugin
84
84
  @pipeline << Messages::Outgoing::Privmsg.new(message.replyto, 'Full plugin reload requested')
85
85
  end
86
86
  end
87
-
87
+
88
88
  # message:: ModSpox::Messages::Internal::PluginModuleResponse
89
89
  # Receives the plugins module
90
90
  def get_module(message)
91
91
  @plugins_mod = message.module
92
92
  end
93
93
 
94
+ # Upgrades extra plugins to latest version
95
+ def extras_upgrade
96
+ Logger.info("Starting plugin upgrade to current version: #{$BOTVERSION}")
97
+ extras = plugin_discovery(BotConfig[:pluginextraspath])
98
+ pl = plugin_list
99
+ extras.keys.each{|d| extras.delete(d) unless pl.include?(d)}
100
+ extras.keys.each do |plugin|
101
+ path = loaded_path(plugin)
102
+ @pipeline << Messages::Internal::PluginUnloadRequest.new(self, path, plugin)
103
+ end
104
+ Logger.info('Waiting for plugins to complete unloading...')
105
+ sleep(3)
106
+ Logger.info('Loading active plugins back into the bot')
107
+ extras.each do |name, path|
108
+ @pipeline << Messages::Internal::PluginLoadRequest.new(self, path)
109
+ end
110
+ Logger.info("Plugin upgrade is now complete. Upgraded to version: #{$BOTVERSION}")
111
+ end
112
+
94
113
  private
95
-
114
+
96
115
  # Returns the list of currently loaded plugins
97
116
  def plugin_list
98
117
  plug = []
@@ -107,7 +126,7 @@ class PluginLoader < ModSpox::Plugin
107
126
  @plugins_mod = nil
108
127
  return plug
109
128
  end
110
-
129
+
111
130
  # Finds available plugins for loading
112
131
  def find_plugins
113
132
  users = plugin_discovery(BotConfig[:userpluginpath])
@@ -118,7 +137,7 @@ class PluginLoader < ModSpox::Plugin
118
137
  end
119
138
  return plugins
120
139
  end
121
-
140
+
122
141
  # path:: path to directory
123
142
  # Discovers any plugins within the files in the given path
124
143
  def plugin_discovery(path)
@@ -130,24 +149,29 @@ class PluginLoader < ModSpox::Plugin
130
149
  sandbox.module_eval(IO.readlines("#{path}/#{file}").join("\n"))
131
150
  sandbox.constants.each do |const|
132
151
  klass = sandbox.const_get(const)
133
- plugins[const] = "#{path}/#{file}" if klass < Plugin
152
+ plugins[const.to_sym] = "#{path}/#{file}" if klass < Plugin
134
153
  end
135
154
  rescue Object => boom
136
- Logger.log("Failed to parse file: #{path}/#{file}. Reason: #{boom}")
155
+ Logger.warn("Failed to parse file: #{path}/#{file}. Reason: #{boom}\n#{boom.backtrace.join("\n")}")
156
+ next
137
157
  end
138
158
  end
139
159
  return plugins
140
160
  end
141
-
161
+
142
162
  # name:: plugin name
143
163
  # Returns the file path the given plugin originated from
144
164
  def loaded_path(name)
145
165
  Dir.new(BotConfig[:userpluginpath]).each do |file|
146
- next unless file =~ /\.rb$/
147
- sandbox = Module.new
148
- sandbox.module_eval(IO.readlines("#{BotConfig[:userpluginpath]}/#{file}").join("\n"))
149
- sandbox.constants.each do |const|
150
- return "#{BotConfig[:userpluginpath]}/#{file}" if const == name
166
+ begin
167
+ next unless file =~ /\.rb$/
168
+ sandbox = Module.new
169
+ sandbox.module_eval(IO.readlines("#{BotConfig[:userpluginpath]}/#{file}").join("\n"))
170
+ sandbox.constants.each do |const|
171
+ return "#{BotConfig[:userpluginpath]}/#{file}" if const == name
172
+ end
173
+ rescue Object => boom
174
+ Logger.warn("Failed to load file: #{file}. Reason: #{boom}")
151
175
  end
152
176
  end
153
177
  return nil
@@ -0,0 +1,52 @@
1
+ class PoolConfig < ModSpox::Plugin
2
+
3
+ def initialize(args)
4
+ super
5
+ group = Group.find_or_create(:name => 'admin')
6
+ add_sig(:sig => 'pool max workers(\s(\d+))?', :method => :max_workers, :group => group,
7
+ :desc => 'Show/set max number of worker threads', :params => [:max])
8
+ add_sig(:sig => 'pool worker timeout(\s(\d+))?', :method => :max_timeout, :group => group,
9
+ :desc => 'Show/set max worker timeout', :params => [:max])
10
+ add_sig(:sig => 'pool workers total', :method => :workers_total, :group => group,
11
+ :desc => 'Show current number of workers in pool')
12
+ end
13
+
14
+ def max_workers(message, params)
15
+ if(params[:max].nil?)
16
+ reply message.replyto, "Maximum number of worker threads allowed in pool: #{Pool.workers_max}"
17
+ else
18
+ params[:max] = params[:max].strip.to_i
19
+ if(params[:max] > 0)
20
+ config = Config.find_or_create(:name => 'pool_workers_min')
21
+ config.value = params[:max]
22
+ config.save
23
+ Pool.workers_max = params[:max]
24
+ reply message.replyto, "\2Thread Pool Update:\2 Number of worker threads updated to: #{params[:max]}"
25
+ else
26
+ reply message.replyto, "\2Error:\2 You must have at least one worker thread"
27
+ end
28
+ end
29
+ end
30
+
31
+ def max_timeout(message, params)
32
+ if(params[:max].nil?)
33
+ reply message.replyto, "Maximum number of seconds threads allowed per task: #{Pool.worker_timeout == 0 ? 'no limit' : Pool.worker_timeout}"
34
+ else
35
+ params[:max] = params[:max].strip.to_i
36
+ if(params[:max] >= 0)
37
+ config = Config.find_or_create(:name => 'pool_timeout')
38
+ config.value = params[:max]
39
+ config.save
40
+ Pool.worker_timeout = params[:max]
41
+ reply message.replyto, "\2Thread Pool Update:\2 Worker processing timeout updated to: #{params[:max]} seconds"
42
+ else
43
+ reply message.replyto, "\2Error:\2 Threads are not able to finish executing before they start"
44
+ end
45
+ end
46
+ end
47
+
48
+ def workers_total(message, params)
49
+ reply message.replyto, "Current number of worker threads in pool: #{Pool.workers}"
50
+ end
51
+
52
+ end
@@ -2,7 +2,7 @@ class Quitter < ModSpox::Plugin
2
2
 
3
3
  def initialize(pipeline)
4
4
  super(pipeline)
5
- Models::Signature.find_or_create(:signature => 'quit\s(.*)', :plugin => name, :method => 'quit',
5
+ Models::Signature.find_or_create(:signature => 'quit(\s.+)?', :plugin => name, :method => 'quit',
6
6
  :group_id => Models::Group.filter(:name => 'admin').first.pk).params = [:channel, :message]
7
7
  end
8
8
 
@@ -0,0 +1,28 @@
1
+ class Status < ModSpox::Plugin
2
+
3
+ def initialize(pipeline)
4
+ super
5
+ add_sig(:sig => 'status', :method => :status, :desc => 'Show current status')
6
+ add_sig(:sig => 'version', :method => :version, :desc => 'Show version information')
7
+ @pipeline.hook(self, :get_status, :Internal_StatusResponse)
8
+ @resp = []
9
+ end
10
+
11
+ def status(m, pa)
12
+ @resp << m.replyto
13
+ @pipeline << Messages::Internal::StatusRequest.new(self)
14
+ end
15
+
16
+ def version(message, params)
17
+ reply message.replyto, "mod_spox IRC bot - Version: \2#{$BOTVERSION}\2 (#{$BOTCODENAME}) [http://modspox.rubyforge.org]"
18
+ end
19
+
20
+ def get_status(m)
21
+ @resp.uniq!
22
+ @resp.each do |c|
23
+ reply c, "\2Status:\2 \2Uptime:\2 #{m.status[:uptime]} \2Plugins:\2 #{m.status[:plugins]} loaded \2Lines sent:\2 #{m.status[:sent]} \2Lines Received:\2 #{m.status[:received]}"
24
+ @resp.delete(c)
25
+ end
26
+ end
27
+
28
+ end
@@ -19,12 +19,30 @@ module ModSpox
19
19
  @timer = timer
20
20
  @completed = false
21
21
  @wait_remaining = @period
22
+ @owner = nil
23
+ end
24
+
25
+ def owner=(o)
26
+ unless(o.is_a?(Symbol))
27
+ if(o.is_a?(ModSpox::Plugin))
28
+ o = o.name.to_sym
29
+ else
30
+ raise Exceptions::BotException.new('Unsupported type given for owner')
31
+ end
32
+ end
33
+ @owner = o
34
+ end
35
+
36
+ def owner
37
+ @owner
22
38
  end
23
39
 
24
40
  # amount:: number of seconds passed
25
41
  # Decrement wait time by given number of seconds
26
42
  def tick(amount)
27
- @wait_remaining = @wait_remaining - amount
43
+ @wait_remaining = @wait_remaining - amount if @wait_remaining > 0
44
+ @wait_remaining = 0 if @wait_remaining < 0
45
+ @completed = true if @once && @wait_remaining <= 0
28
46
  end
29
47
 
30
48
  # Returns true if action is due to run
@@ -66,9 +84,8 @@ module ModSpox
66
84
  @func.call
67
85
  end
68
86
  rescue Object => boom
69
- Logger.log("Action generated an exception during run: #{boom}\n#{boom.backtrace.join("\n")}", 10)
87
+ Logger.warn("Action generated an exception during run: #{boom}\n#{boom.backtrace.join("\n")}")
70
88
  end
71
- @completed = true if @once
72
89
  end
73
90
  end
74
91
 
@@ -23,6 +23,7 @@ module ModSpox
23
23
  def []=(key, value)
24
24
  key = key.to_sym unless key.is_a?(Symbol)
25
25
  @config[key] = value
26
+ write_configuration
26
27
  end
27
28
 
28
29
  # Parses the configuration file into a usable Hash