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.
- data/CHANGELOG +36 -0
- data/INSTALL +2 -2
- data/README +0 -1
- data/bin/mod_spox +51 -12
- data/data/mod_spox/extras/AOLSpeak.rb +5 -18
- data/data/mod_spox/extras/AutoKick.rb +44 -23
- data/data/mod_spox/extras/AutoMode.rb +2 -5
- data/data/mod_spox/extras/AutoRejoin.rb +21 -0
- data/data/mod_spox/extras/Bouncer.rb +10 -10
- data/data/mod_spox/extras/Bytes.rb +12 -0
- data/data/mod_spox/extras/Confess.rb +131 -52
- data/data/mod_spox/extras/DCC.rb +189 -0
- data/data/mod_spox/extras/DevWatch.rb +32 -33
- data/data/mod_spox/extras/FloodKicker.rb +129 -0
- data/data/mod_spox/extras/GoogleIt.rb +13 -0
- data/data/mod_spox/extras/Headers.rb +31 -4
- data/data/mod_spox/extras/Karma.rb +103 -49
- data/data/mod_spox/extras/Logger.rb +45 -30
- data/data/mod_spox/extras/LolSpeak.rb +1 -1
- data/data/mod_spox/extras/NickServ.rb +83 -0
- data/data/mod_spox/extras/PhpCli.rb +12 -15
- data/data/mod_spox/extras/PhpFuncLookup.rb +57 -25
- data/data/mod_spox/extras/Quotes.rb +5 -4
- data/data/mod_spox/extras/RegexTracker.rb +160 -0
- data/data/mod_spox/extras/Roulette.rb +22 -23
- data/data/mod_spox/extras/Search.rb +3 -2
- data/data/mod_spox/extras/Slashdot.rb +35 -0
- data/data/mod_spox/extras/Topten.rb +5 -5
- data/data/mod_spox/extras/TracTicket.rb +68 -0
- data/data/mod_spox/extras/Translate.rb +69 -30
- data/data/mod_spox/extras/Twitter.rb +372 -0
- data/data/mod_spox/extras/UrbanDictionary.rb +21 -12
- data/data/mod_spox/extras/Weather.rb +1 -1
- data/data/mod_spox/plugins/Authenticator.rb +63 -30
- data/data/mod_spox/plugins/Banner.rb +164 -151
- data/data/mod_spox/plugins/Helper.rb +18 -7
- data/data/mod_spox/plugins/PluginLoader.rb +46 -22
- data/data/mod_spox/plugins/PoolConfig.rb +52 -0
- data/data/mod_spox/plugins/Quitter.rb +1 -1
- data/data/mod_spox/plugins/Status.rb +28 -0
- data/lib/mod_spox/Action.rb +20 -3
- data/lib/mod_spox/BaseConfig.rb +1 -0
- data/lib/mod_spox/Bot.rb +98 -75
- data/lib/mod_spox/BotConfig.rb +14 -6
- data/lib/mod_spox/ConfigurationWizard.rb +94 -105
- data/lib/mod_spox/Database.rb +33 -13
- data/lib/mod_spox/Helpers.rb +67 -38
- data/lib/mod_spox/Loader.rb +25 -5
- data/lib/mod_spox/Logger.rb +20 -62
- data/lib/mod_spox/MessageFactory.rb +34 -25
- data/lib/mod_spox/Monitors.rb +5 -0
- data/lib/mod_spox/Pipeline.rb +40 -51
- data/lib/mod_spox/Plugin.rb +40 -9
- data/lib/mod_spox/PluginManager.rb +46 -38
- data/lib/mod_spox/Pool.rb +129 -143
- data/lib/mod_spox/Socket.rb +41 -50
- data/lib/mod_spox/Sockets.rb +211 -0
- data/lib/mod_spox/Timer.rb +86 -69
- data/lib/mod_spox/handlers/BadNick.rb +1 -1
- data/lib/mod_spox/handlers/Created.rb +1 -1
- data/lib/mod_spox/handlers/Handler.rb +9 -0
- data/lib/mod_spox/handlers/Invite.rb +1 -1
- data/lib/mod_spox/handlers/Join.rb +2 -2
- data/lib/mod_spox/handlers/Kick.rb +1 -1
- data/lib/mod_spox/handlers/LuserChannels.rb +1 -1
- data/lib/mod_spox/handlers/LuserOp.rb +1 -1
- data/lib/mod_spox/handlers/LuserUnknown.rb +1 -1
- data/lib/mod_spox/handlers/Mode.rb +2 -2
- data/lib/mod_spox/handlers/MyInfo.rb +1 -1
- data/lib/mod_spox/handlers/Names.rb +1 -1
- data/lib/mod_spox/handlers/Nick.rb +20 -3
- data/lib/mod_spox/handlers/NickInUse.rb +3 -3
- data/lib/mod_spox/handlers/Notice.rb +5 -15
- data/lib/mod_spox/handlers/Part.rb +1 -1
- data/lib/mod_spox/handlers/Ping.rb +1 -1
- data/lib/mod_spox/handlers/Pong.rb +1 -1
- data/lib/mod_spox/handlers/Privmsg.rb +2 -2
- data/lib/mod_spox/handlers/Quit.rb +1 -1
- data/lib/mod_spox/handlers/Topic.rb +2 -1
- data/lib/mod_spox/handlers/Welcome.rb +3 -3
- data/lib/mod_spox/handlers/Who.rb +9 -7
- data/lib/mod_spox/handlers/Whois.rb +29 -16
- data/lib/mod_spox/handlers/YourHost.rb +1 -1
- data/lib/mod_spox/messages/incoming/Privmsg.rb +38 -19
- data/lib/mod_spox/messages/internal/DCCListener.rb +12 -0
- data/lib/mod_spox/messages/internal/DCCRequest.rb +12 -0
- data/lib/mod_spox/messages/internal/DCCSocket.rb +19 -0
- data/lib/mod_spox/messages/internal/StatusRequest.rb +2 -1
- data/lib/mod_spox/messages/outgoing/Privmsg.rb +21 -5
- data/lib/mod_spox/migrations/001_initialize_models.rb +115 -0
- data/lib/mod_spox/models/Auth.rb +24 -16
- data/lib/mod_spox/models/AuthGroup.rb +4 -3
- data/lib/mod_spox/models/Channel.rb +20 -12
- data/lib/mod_spox/models/ChannelMode.rb +2 -2
- data/lib/mod_spox/models/Config.rb +11 -3
- data/lib/mod_spox/models/Group.rb +6 -1
- data/lib/mod_spox/models/Nick.rb +93 -33
- data/lib/mod_spox/models/NickChannel.rb +8 -6
- data/lib/mod_spox/models/NickGroup.rb +16 -0
- data/lib/mod_spox/models/NickMode.rb +3 -3
- data/lib/mod_spox/models/Server.rb +6 -2
- data/lib/mod_spox/models/Setting.rb +12 -6
- data/lib/mod_spox/models/Signature.rb +7 -13
- data/lib/mod_spox/models/Trigger.rb +1 -1
- metadata +125 -100
@@ -13,11 +13,19 @@ class Confess < ModSpox::Plugin
|
|
13
13
|
begin
|
14
14
|
require 'htmlentities'
|
15
15
|
rescue Object => boom
|
16
|
-
Logger.
|
16
|
+
Logger.warn('Error: This plugin requires the HTMLEntities gem. Please install and reload plugin.')
|
17
17
|
raise Exceptions::BotException.new("Missing required HTMLEntities library")
|
18
18
|
end
|
19
|
-
|
20
|
-
|
19
|
+
begin
|
20
|
+
Confession.db = Sequel.sqlite(BotConfig[:userpath] + '/confessions.db')
|
21
|
+
rescue Object => boom
|
22
|
+
Logger.warn("Error: Unable to initialize this plugin: #{boom}")
|
23
|
+
raise Exceptions::BotException.new("Failed to create database: #{boom}")
|
24
|
+
end
|
25
|
+
Confession.build_confession && Confession.create_table unless Confession.table_exists?
|
26
|
+
Signature.find_or_create(:signature => 'confess', :plugin => name, :method => 'confess',
|
27
|
+
:description => 'Print a confession')
|
28
|
+
Signature.find_or_create(:signature => 'confess (?!score|count|fetcher|\+\+|\-\-)(.+)?', :plugin => name, :method => 'confess',
|
21
29
|
:description => 'Print a confession').params = [:term]
|
22
30
|
Signature.find_or_create(:signature => 'confess(\+\+|\-\-) ?(\d+)?', :plugin => name, :method => 'score',
|
23
31
|
:description => 'Score a confession').params = [:score, :id]
|
@@ -30,62 +38,100 @@ class Confess < ModSpox::Plugin
|
|
30
38
|
Config[:confess] = 'nofetch' if Config[:confess].nil?
|
31
39
|
@last_confession = {}
|
32
40
|
@fetch = false
|
33
|
-
@mutex = Mutex.new
|
34
41
|
@coder = HTMLEntities.new
|
42
|
+
@timer = {:action => nil, :id => nil}
|
43
|
+
@lock = Mutex.new
|
35
44
|
start_fetcher if Config[:confess] == 'fetch'
|
36
45
|
end
|
37
46
|
|
47
|
+
def destroy
|
48
|
+
Confession.db.disconnect
|
49
|
+
end
|
50
|
+
|
38
51
|
def confess(message, params)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
52
|
+
begin
|
53
|
+
c = nil
|
54
|
+
pk = nil
|
55
|
+
@lock.synchronize do
|
56
|
+
if(params[:term])
|
57
|
+
return if params[:term] == 'count'
|
58
|
+
if(params[:term] =~ /^\d+$/)
|
59
|
+
c = Confession[params[:term].to_i]
|
60
|
+
else
|
61
|
+
cs = Confession.search(params[:term])
|
62
|
+
Logger.info("Size of confession results: #{cs.size}")
|
63
|
+
rand_idx = rand(cs.size - 1)
|
64
|
+
rand_id = cs[rand_idx].to_i
|
65
|
+
Logger.info("Random index to be used: #{rand_idx}")
|
66
|
+
Logger.info("Random ID to be used for confession: #{rand_id}")
|
67
|
+
c = Confession[rand_id]
|
68
|
+
end
|
69
|
+
else
|
70
|
+
c = Confession[rand(Confession.count) - 1]
|
71
|
+
end
|
72
|
+
unless c.nil?
|
73
|
+
pk = c.pk
|
74
|
+
c = c.confession
|
75
|
+
end
|
76
|
+
end
|
77
|
+
if(c)
|
78
|
+
reply message.replyto, "\2[#{pk}]\2: #{c}"
|
79
|
+
@last_confession[message.target.pk] = pk
|
44
80
|
else
|
45
|
-
|
46
|
-
reg = true
|
81
|
+
reply message.replyto, "\2Error:\2 Failed to find confession"
|
47
82
|
end
|
48
|
-
|
49
|
-
|
50
|
-
c = Confession[ids[rand(ids.size - 1)].to_i]
|
51
|
-
end
|
52
|
-
if(c)
|
53
|
-
reply message.replyto, "\2[#{c.pk}]\2: #{reg ? c.confession.gsub(/(#{params[:term]})/, "\2\\1\2") : c.confession}"
|
54
|
-
@last_confession[message.target.pk] = c.pk
|
55
|
-
else
|
56
|
-
reply message.replyto, "\2Error:\2 Failed to find confession"
|
83
|
+
rescue Object => boom
|
84
|
+
reply message.replyto, "Failed to locate a match. Error encountered: #{boom}"
|
57
85
|
end
|
58
86
|
end
|
59
87
|
|
60
88
|
def show_score(message, params)
|
61
|
-
|
62
|
-
|
63
|
-
|
89
|
+
pk = nil
|
90
|
+
score = nil
|
91
|
+
c = nil
|
92
|
+
@lock.synchronize do
|
93
|
+
c = Confession[params[:id].to_i]
|
94
|
+
if(c)
|
95
|
+
pk = c.pk
|
96
|
+
score = c.score.to_i
|
97
|
+
end
|
98
|
+
end
|
99
|
+
if(pk)
|
100
|
+
reply message.replyto, "\2[#{pk}]:\2 #{score}% of raters gave this confession a positive score"
|
64
101
|
else
|
65
102
|
reply message.replyto, "\2Error:\2 Failed to find confession with ID: #{params[:id]}"
|
66
103
|
end
|
67
104
|
end
|
68
105
|
|
69
106
|
def score(message, params)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
107
|
+
c = nil
|
108
|
+
@lock.synchronize do
|
109
|
+
if(params[:id])
|
110
|
+
c = Confession[params[:id].to_i]
|
111
|
+
else
|
112
|
+
c = Confession[@last_confession[message.target.pk]] if @last_confession.has_key?(message.target.pk)
|
113
|
+
end
|
74
114
|
end
|
75
115
|
if(c)
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
116
|
+
@lock.synchronize do
|
117
|
+
if(params[:score] == '++')
|
118
|
+
c.update_with_params(:positive => c.positive.to_i + 1)
|
119
|
+
else
|
120
|
+
c.update_with_params(:negative => c.negative.to_i + 1)
|
121
|
+
end
|
122
|
+
c.update_with_params(:score => ((c.positive.to_f) / (c.positive.to_f + c.negative.to_f)) * 100.0)
|
80
123
|
end
|
81
|
-
c.update_with_params(:score => ((c.positive.to_f) / (c.positive.to_f + c.negative.to_f)) * 100.0)
|
82
124
|
else
|
83
125
|
reply message.replyto, "\2Error:\2 Failed to find confession to score"
|
84
126
|
end
|
85
127
|
end
|
86
128
|
|
87
129
|
def count(message, params)
|
88
|
-
|
130
|
+
c = 0
|
131
|
+
@lock.synchronize do
|
132
|
+
c = Confession.count
|
133
|
+
end
|
134
|
+
reply message.replyto, "Current number of stored confessions: #{c}"
|
89
135
|
end
|
90
136
|
|
91
137
|
def fetcher(message, params)
|
@@ -100,6 +146,7 @@ class Confess < ModSpox::Plugin
|
|
100
146
|
else
|
101
147
|
if(Config[:confess] == 'fetch')
|
102
148
|
Config[:confess] = 'nofetch'
|
149
|
+
stop_fetcher
|
103
150
|
reply message.replyto, 'Confession fetcher has been stopped'
|
104
151
|
else
|
105
152
|
reply message.replyto, 'Confession fetcher is not currently running'
|
@@ -109,58 +156,90 @@ class Confess < ModSpox::Plugin
|
|
109
156
|
|
110
157
|
def grab_page
|
111
158
|
begin
|
112
|
-
connection = Net::HTTP.new('
|
113
|
-
response = connection.request_get(
|
159
|
+
connection = Net::HTTP.new('www.grouphug.us', 80)
|
160
|
+
response = connection.request_get("/frontpage?page=#{rand(17349)+1}", nil)
|
114
161
|
response.value
|
115
162
|
page = response.body.gsub(/[\r\n]/, ' ')
|
116
|
-
Logger.
|
163
|
+
Logger.info("Processing matches")
|
117
164
|
page.scan(/<div class="content">\s*<p>\s*(.+?)\s*<\/p>\s*<\/div>/).each{|match|
|
118
|
-
Logger.
|
165
|
+
Logger.info("Match found: #{match[0]}")
|
119
166
|
conf = CGI::unescapeHTML(match[0])
|
120
167
|
conf = conf.gsub(/<.+?>/, ' ').gsub(/[\r\n]/, '').gsub(/\s+/, ' ')
|
121
168
|
conf = @coder.decode(conf)
|
122
|
-
Logger.
|
169
|
+
Logger.info("Match turned into: #{conf}")
|
123
170
|
if conf.length < 300
|
124
171
|
begin
|
125
|
-
|
172
|
+
@lock.synchronize do
|
173
|
+
c = Confession.new(:hash => Digest::MD5.hexdigest(conf)).save
|
174
|
+
c.confession = conf
|
175
|
+
end
|
126
176
|
rescue Object => boom
|
127
|
-
Logger.
|
177
|
+
Logger.warn('Warning: Fetched confession already found in database')
|
128
178
|
end
|
129
179
|
end
|
130
180
|
}
|
131
181
|
rescue Object => boom
|
132
|
-
Logger.
|
133
|
-
|
134
|
-
|
135
|
-
@pipeline << Messages::Internal::TimerAdd.new(self, rand(500), nil, true){ grab_page }
|
136
|
-
else
|
137
|
-
stop_fetcher
|
182
|
+
Logger.warn("Error fetching data: #{boom}")
|
183
|
+
ensure
|
184
|
+
@timer[:action].reset_period(rand(1000)+1) unless @timer[:action].nil?
|
138
185
|
end
|
139
186
|
end
|
140
187
|
|
141
188
|
private
|
142
189
|
|
143
190
|
def start_fetcher
|
144
|
-
@
|
145
|
-
grab_page
|
191
|
+
if(@timer[:action].nil?)
|
192
|
+
m = Messages::Internal::TimerAdd.new(self, rand(1000)+1){ grab_page }
|
193
|
+
@timer[:id] = m.id
|
194
|
+
@pipeline << m
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def get_timer(m)
|
199
|
+
if(m.id == @timer[:id])
|
200
|
+
if(m.action_added?)
|
201
|
+
@timer[:action] = m.action
|
202
|
+
else
|
203
|
+
@timer = {:action => nil, :id => nil}
|
204
|
+
end
|
146
205
|
end
|
147
206
|
end
|
148
207
|
|
149
208
|
def stop_fetcher
|
150
|
-
@
|
151
|
-
@
|
209
|
+
unless(@timer[:action].nil?)
|
210
|
+
@pipeline << Messages::Internal::TimerRemove(@timer[:action])
|
152
211
|
end
|
153
212
|
end
|
154
213
|
|
155
|
-
class Confession < Sequel::Model
|
214
|
+
class Confession < Sequel::Model
|
215
|
+
def Confession.build_confession
|
216
|
+
db << 'CREATE VIRTUAL TABLE `confessions_confession` USING FTS3(`confession` TEXT NOT NULL)'
|
217
|
+
end
|
218
|
+
|
156
219
|
set_schema do
|
157
|
-
text :confession, :null => false
|
158
220
|
text :hash, :null => false, :unique => true
|
159
221
|
integer :positive, :null => false, :default => 0
|
160
222
|
integer :negative, :null => false, :default => 0
|
161
223
|
float :score, :null => false, :default => 0
|
162
224
|
primary_key :id
|
163
225
|
end
|
226
|
+
|
227
|
+
def confession=(c)
|
228
|
+
if(confession)
|
229
|
+
db[:confessions_confession].filter('docid = ?', pk).update(:confession => c)
|
230
|
+
else
|
231
|
+
db[:confessions_confession] << {:docid => pk, :confession => c}
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def confession
|
236
|
+
c = db[:confessions_confession].select(:confession).where('docid = ?', pk).first
|
237
|
+
return c.nil? ? nil : c[:confession]
|
238
|
+
end
|
239
|
+
|
240
|
+
def Confession.search(terms)
|
241
|
+
results = db['select docid from confessions_confession where confession match ?', terms].map(:docid)
|
242
|
+
end
|
164
243
|
end
|
165
244
|
|
166
245
|
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
['ipaddr', 'socket', 'timeout'].each{|f| require f}
|
2
|
+
|
3
|
+
class DCC < ModSpox::Plugin
|
4
|
+
|
5
|
+
include Models
|
6
|
+
|
7
|
+
def initialize(pipeline)
|
8
|
+
super
|
9
|
+
group = Group.find_or_create(:name => 'dcc')
|
10
|
+
admin = Group.find_or_create(:name => 'admin')
|
11
|
+
Signature.find_or_create(:signature => 'file list(\s(.+))?', :plugin => name, :method => 'file_list',
|
12
|
+
:description => 'List available DCC files', :group_id => group.pk).params = [:pattern]
|
13
|
+
Signature.find_or_create(:signature => 'file get (.+)', :plugin => name, :method => 'file_get',
|
14
|
+
:description => 'Download file', :group_id => group.pk).params = [:filename]
|
15
|
+
Signature.find_or_create(:signature => 'file ports (\d+)-(\d+)', :plugin => name, :method => 'set_ports',
|
16
|
+
:description => 'Set allowed DCC ports', :group_id => admin.pk).params = [:start, :end]
|
17
|
+
Signature.find_or_create(:signature => 'file adddir (.+)', :plugin => name, :method => 'add_dir',
|
18
|
+
:description => 'Add directory to file list', :group_id => admin.pk).params = [:dir]
|
19
|
+
Signature.find_or_create(:signature => 'file rmdir (\d+)', :plugin => name, :method => 'rm_dir',
|
20
|
+
:description => 'Remove directory from file list', :group_id => admin.pk).params = [:dir]
|
21
|
+
Signature.find_or_create(:signature => 'file show dir', :plugin => name, :method => 'show_dirs',
|
22
|
+
:description => 'Show directories available to file list', :group_id => admin.pk)
|
23
|
+
Signature.find_or_create(:signature => 'file show ports', :plugin => name, :method => 'show_ports',
|
24
|
+
:description => 'Show allowed ports', :group_id => admin.pk)
|
25
|
+
Signature.find_or_create(:signature => 'file max wait(\s(\d+))?', :plugin => name, :method => 'max_wait',
|
26
|
+
:description => 'Show/set timeout for accepting files', :group_id => admin.pk).params = [:wait]
|
27
|
+
Signature.find_or_create(:signature => 'dcc chat', :plugin => name, :method => 'dcc_chat',
|
28
|
+
:description => 'Start a DCC chat with the bot (useful if behind firewall', :group_id => group.pk)
|
29
|
+
@servers = {}
|
30
|
+
@ports = Setting[:dcc_ports]
|
31
|
+
@ports = {:start => 49152, :end => 65535} if @ports.nil?
|
32
|
+
@dirs = Setting.find_or_create(:name => 'dcc_dirs').value
|
33
|
+
@dirs = [] unless @dirs.is_a?(Array)
|
34
|
+
@max_wait = Setting[:dcc_max_wait]
|
35
|
+
@max_wait = @max_wait.nil? ? 60 : @max_wait.to_i
|
36
|
+
end
|
37
|
+
|
38
|
+
def file_list(message, params)
|
39
|
+
matches = []
|
40
|
+
pattern = params[:pattern] ? Regexp.new(params[:pattern].strip!) : nil
|
41
|
+
@dirs.each do |path|
|
42
|
+
dir = Dir.new(path)
|
43
|
+
dir.each do |file|
|
44
|
+
next if File.directory?("#{dir.path}/#{file}") || (file[0] == 46 || file[0] == '.') || !File.readable?("#{dir.path}/#{file}")
|
45
|
+
unless(pattern.nil?)
|
46
|
+
if(pattern.match(file))
|
47
|
+
matches << dir.path + '/' + file + " - #{Helpers.format_size(File.size(dir.path + '/' + file))}"
|
48
|
+
end
|
49
|
+
else
|
50
|
+
matches << dir.path + '/' + file + " - #{Helpers.format_size(File.size(dir.path + '/' + file))}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
output = ["\2Files in available list:\2 (matching: #{params[:pattern] ? params[:pattern] : ''})"]
|
55
|
+
output = output + matches
|
56
|
+
reply message.replyto, output
|
57
|
+
end
|
58
|
+
|
59
|
+
def file_get(message, params)
|
60
|
+
@try = 0
|
61
|
+
socket = nil
|
62
|
+
port = 0
|
63
|
+
unless(@dirs.include?(File.dirname(params[:filename])))
|
64
|
+
reply message.replyto, "\2Error:\2 #{params[:filename]} is not within the allowed directories"
|
65
|
+
else
|
66
|
+
while(socket.nil? && @try < 3) do
|
67
|
+
begin
|
68
|
+
port = rand(@ports[:end] - @ports[:start]) + @ports[:start]
|
69
|
+
socket = Object::Socket.new(Object::Socket::AF_INET, Object::Socket::SOCK_STREAM, 0)
|
70
|
+
addr = Object::Socket.pack_sockaddr_in(port, me.address)
|
71
|
+
socket.bind(addr)
|
72
|
+
initialize_getter(socket, params[:filename])
|
73
|
+
rescue Object => boom
|
74
|
+
Logger.warn("Failed to initialize DCC TCPServer. Reason: #{boom}")
|
75
|
+
@try += 1
|
76
|
+
socket = nil
|
77
|
+
port = nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
if(socket.nil?)
|
81
|
+
reply message.replyto, "\2Error:\2 Failed to initialize file getter process."
|
82
|
+
else
|
83
|
+
ip = IPAddr.new(me.address).to_i
|
84
|
+
@pipeline << Messages::Outgoing::Privmsg.new(message.source, "SEND #{File.basename(params[:filename])} #{ip} #{port} #{File.size(params[:filename])}", false, true, 'DCC')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def max_wait(message, params)
|
90
|
+
wait = params[:wait].nil? ? nil : params[:wait].strip
|
91
|
+
unless(wait.nil?)
|
92
|
+
@max_wait = wait.to_i
|
93
|
+
record = Setting.find_or_create(:name => 'dcc_max_wait')
|
94
|
+
record.value = wait
|
95
|
+
record.save
|
96
|
+
reply message.replyto, "Timeout for file download changed to: #{@max_wait} seconds"
|
97
|
+
else
|
98
|
+
reply message.replyto, "Timeout for file download is: #{@max_wait} seconds"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def set_ports(message, params)
|
103
|
+
if(params[:start].to_i > 1024 && params[:end].to_i < 65536)
|
104
|
+
@ports = {:start => params[:start].to_i, :end => params[:end].to_i}
|
105
|
+
record = Setting.find_or_create(:name => 'dcc_ports')
|
106
|
+
record.value = @ports
|
107
|
+
record.save
|
108
|
+
reply message.replyto, "File ports have been updated to: #{@ports[:start]} - #{@ports[:end]}"
|
109
|
+
else
|
110
|
+
reply message.replyto, "\2Error:\2 Ports given are out of acceptable range (1025 - 65535)"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def add_dir(message, params)
|
115
|
+
if(File.readable?(params[:dir]))
|
116
|
+
if(@dirs.include?(dir))
|
117
|
+
reply message.replyto, "\2Error:\2 Given directory is already in available list. (#{params[:dir]})"
|
118
|
+
else
|
119
|
+
@dirs << dir
|
120
|
+
record = Setting.find_or_create(:name => 'dcc_dirs')
|
121
|
+
record.value = @dirs
|
122
|
+
record.save
|
123
|
+
reply message.replyto, "New directory added to DCC directory list: #{params[:dir]}"
|
124
|
+
end
|
125
|
+
else
|
126
|
+
reply message.replyto, "\2Error:\2 Given directory is not readable. (#{params[:dir]})"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def rm_dir(message, params)
|
131
|
+
if(@dirs.include?(params[:dir]))
|
132
|
+
@dirs.delete(params[:dir])
|
133
|
+
record = Setting.find_or_create(:name => 'dcc_dirs')
|
134
|
+
record.value = @dirs
|
135
|
+
record.save
|
136
|
+
reply message.replyto, "DCC directory successfully updated"
|
137
|
+
else
|
138
|
+
reply message.replyto, "\2Error:\2 Failed to find directory: #{params[:dir]} in available directory list"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def show_dirs(message, params)
|
143
|
+
output = []
|
144
|
+
output << "\2Directories available for DCC file list:\2"
|
145
|
+
output += @dirs
|
146
|
+
reply message.replyto, output
|
147
|
+
end
|
148
|
+
|
149
|
+
def show_ports(message, params)
|
150
|
+
reply message.replyto, "\2Allowed Ports:\2 #{@ports[:start]} - #{@ports[:end]}"
|
151
|
+
end
|
152
|
+
|
153
|
+
def dcc_chat(message, params)
|
154
|
+
@pipeline << Messages::Internal::DCCListener.new(message.source)
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
def initialize_getter(socket, filename)
|
160
|
+
@servers[socket.object_id] = Thread.new do
|
161
|
+
client = nil
|
162
|
+
addrinfo = nil
|
163
|
+
cport = nil
|
164
|
+
cip = nil
|
165
|
+
begin
|
166
|
+
Timeout::timeout(@max_wait) do
|
167
|
+
socket.listen(5)
|
168
|
+
client, addrinfo = socket.accept
|
169
|
+
cport, cip = Object::Socket.unpack_sockaddr_in(addrinfo)
|
170
|
+
end
|
171
|
+
Logger.info("Sending file: #{filename} to IP: #{cip}:#{cport}")
|
172
|
+
file = File.new(filename)
|
173
|
+
until((line = file.gets).nil?) do
|
174
|
+
client << line
|
175
|
+
end
|
176
|
+
Logger.info("Sending of file: #{filename} to IP: #{addrinfo} is now complete")
|
177
|
+
rescue Timeout::Error => boom
|
178
|
+
Logger.warn("Error sending file: #{filename}. Timeout exceeded (#{@max_wait} seconds)")
|
179
|
+
rescue Object => boom
|
180
|
+
Logger.warn("Error sending file: #{filename}. Unknown reason: #{boom}")
|
181
|
+
ensure
|
182
|
+
socket.close
|
183
|
+
client.close
|
184
|
+
@servers.delete(socket.object_id)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
@@ -19,12 +19,10 @@ class DevWatch < ModSpox::Plugin
|
|
19
19
|
if(Setting[:devwatch].nil?)
|
20
20
|
Setting.find_or_create(:name => 'devwatch').value = {:channels => [], :interval => 300}
|
21
21
|
end
|
22
|
-
@pipeline.hook(self, :timer_response, :Internal_TimerResponse)
|
23
22
|
@original = nil
|
24
23
|
@new = nil
|
25
|
-
@timer = nil
|
26
|
-
|
27
|
-
run
|
24
|
+
@timer = {:action => nil, :id => nil}
|
25
|
+
start_auto
|
28
26
|
end
|
29
27
|
|
30
28
|
def enable_watch(message, params)
|
@@ -39,7 +37,7 @@ class DevWatch < ModSpox::Plugin
|
|
39
37
|
reply(message.replyto, "#{channel.name} has been removed from the development watch list")
|
40
38
|
end
|
41
39
|
Setting.filter(:name => 'devwatch').first.value = vals
|
42
|
-
|
40
|
+
update_auto
|
43
41
|
else
|
44
42
|
reply(message.replyto, "\2Error:\2 I have no record of #{params[:channel]}.")
|
45
43
|
end
|
@@ -61,7 +59,7 @@ class DevWatch < ModSpox::Plugin
|
|
61
59
|
vals[:url] = params[:url]
|
62
60
|
reply(message.replyto, "OK")
|
63
61
|
Setting.filter(:name => 'devwatch').first.value = vals
|
64
|
-
|
62
|
+
update_auto
|
65
63
|
else
|
66
64
|
if(Setting[:devwatch].has_key?(:url))
|
67
65
|
reply(message.replyto, "\2Devwatch URL:\2 #{Setting[:devwatch][:url]}")
|
@@ -76,38 +74,17 @@ class DevWatch < ModSpox::Plugin
|
|
76
74
|
vals = Setting[:devwatch]
|
77
75
|
vals[:interval] = params[:time].to_i
|
78
76
|
Setting.filter(:name => 'devwatch').first.value = vals
|
79
|
-
@timer
|
77
|
+
if(@timer[:action].nil?)
|
78
|
+
update_auto
|
79
|
+
else
|
80
|
+
@timer[:action].reset_period(params[:time].to_i)
|
81
|
+
end
|
80
82
|
reply(message.replyto, "Devwatch announcement interval reset to: #{Helpers.format_seconds(params[:time].to_i)}")
|
81
83
|
else
|
82
84
|
reply(message.replyto, "Devwatch announcement interval set to: #{Helpers.format_seconds(Setting[:devwatch][:interval].to_i)}")
|
83
85
|
end
|
84
86
|
end
|
85
87
|
|
86
|
-
def run
|
87
|
-
@lock.synchronize do
|
88
|
-
check_updates
|
89
|
-
if(Setting[:devwatch].has_key?(:url) && Setting[:devwatch][:channels].size > 0)
|
90
|
-
if(@timer.nil?)
|
91
|
-
@pipeline << ModSpox::Messages::Internal::TimerAdd.new(self, Setting[:devwatch][:interval].to_i){check_updates}
|
92
|
-
sleep(0.01) while @timer.nil?
|
93
|
-
end
|
94
|
-
else
|
95
|
-
if(@timer)
|
96
|
-
@pipeline << ModSpox::Messages::Internal::TimerRemove.new(@timer)
|
97
|
-
sleep(0.01) until @timer.nil?
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def timer_response(message)
|
104
|
-
if(message.origin == self && message.action_added?)
|
105
|
-
@timer = message.action
|
106
|
-
elsif(message.action == @timer && message.action_removed?)
|
107
|
-
@timer = nil
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
88
|
def check_updates
|
112
89
|
if(Setting[:devwatch].has_key?(:url) && Setting[:devwatch][:channels].size > 0)
|
113
90
|
src = open(Setting[:devwatch][:url])
|
@@ -117,7 +94,7 @@ class DevWatch < ModSpox::Plugin
|
|
117
94
|
@original = item.elements['title'].text
|
118
95
|
break
|
119
96
|
end
|
120
|
-
Logger.
|
97
|
+
Logger.info("Initialized development watch RSS feed: #{@original}")
|
121
98
|
else
|
122
99
|
@new = doc
|
123
100
|
print_new
|
@@ -150,5 +127,27 @@ class DevWatch < ModSpox::Plugin
|
|
150
127
|
end
|
151
128
|
end
|
152
129
|
end
|
130
|
+
|
131
|
+
def get_timer(m)
|
132
|
+
if(m.id == @timer[:id])
|
133
|
+
@timer[:action] = m.action_added? ? m.action : nil
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def update_auto
|
138
|
+
unless(@timer[:action].nil?)
|
139
|
+
@pipeline << Messages::Internal::TimerRemove.new(@timer[:action])
|
140
|
+
end
|
141
|
+
sleep(0.01)
|
142
|
+
start_auto
|
143
|
+
end
|
144
|
+
|
145
|
+
def start_auto
|
146
|
+
if(@timer[:action].nil? && Setting[:devwatch].has_key?(:url) && Setting[:devwatch][:channels].size > 0)
|
147
|
+
m = Messages::Internal::TimerAdd.new(self, Setting[:devwatch][:interval].to_i){ check_updates }
|
148
|
+
@timer[:id] = m.id
|
149
|
+
@pipeline << m
|
150
|
+
end
|
151
|
+
end
|
153
152
|
|
154
153
|
end
|