fargo 0.1.1 → 0.2.0
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.
- data/ext/fargo/base32.c +61 -0
- data/ext/fargo/base32.h +16 -0
- data/ext/fargo/extconf.rb +8 -0
- data/ext/fargo/fargo_tth.c +34 -0
- data/ext/fargo/sboxes.c +515 -0
- data/ext/fargo/tiger.c +245 -0
- data/ext/fargo/tiger.h +41 -0
- data/ext/fargo/tigertree.c +184 -0
- data/ext/fargo/tigertree.h +48 -0
- data/ext/fargo/tth.c +100 -0
- data/ext/fargo/tth.h +18 -0
- data/lib/fargo/client.rb +47 -118
- data/lib/fargo/protocol/dc.rb +52 -0
- data/lib/fargo/{connection → protocol}/download.rb +56 -88
- data/lib/fargo/protocol/hub.rb +81 -0
- data/lib/fargo/search.rb +21 -16
- data/lib/fargo/search_result.rb +6 -6
- data/lib/fargo/supports/chat.rb +10 -7
- data/lib/fargo/supports/downloads.rb +73 -117
- data/lib/fargo/supports/file_list.rb +21 -10
- data/lib/fargo/supports/nick_list.rb +23 -14
- data/lib/fargo/supports/persistence.rb +28 -23
- data/lib/fargo/supports/searches.rb +30 -9
- data/lib/fargo/supports/timeout.rb +8 -5
- data/lib/fargo/supports/uploads.rb +5 -5
- data/lib/fargo/utils.rb +5 -4
- data/lib/fargo/version.rb +1 -1
- data/lib/fargo.rb +8 -10
- metadata +41 -19
- data/lib/fargo/connection/base.rb +0 -126
- data/lib/fargo/connection/hub.rb +0 -120
- data/lib/fargo/connection/search.rb +0 -19
- data/lib/fargo/connection/upload.rb +0 -85
- data/lib/fargo/publisher.rb +0 -42
- data/lib/fargo/server.rb +0 -52
data/lib/fargo/search_result.rb
CHANGED
@@ -15,17 +15,17 @@ module Fargo
|
|
15
15
|
end
|
16
16
|
|
17
17
|
s << sprintf(" %d/%d\005%s (%s:%d)", @client.open_slots,
|
18
|
-
@client.
|
18
|
+
@client.config.upload_slots,
|
19
19
|
@client.hub.hubname,
|
20
|
-
@client.
|
21
|
-
@client.
|
20
|
+
@client.config.hub_address,
|
21
|
+
@client.config.hub_port)
|
22
22
|
s << "\005#{@target}" if @client.config.passive
|
23
23
|
end
|
24
24
|
|
25
25
|
def active_send nick, ip, port
|
26
|
-
socket =
|
27
|
-
socket.
|
28
|
-
socket.
|
26
|
+
socket = EventMachine.open_datagram_socket '0.0.0.0', 0
|
27
|
+
socket.send_datagram "$SR #{nick} #{to_s}", ip, port
|
28
|
+
socket.close_connection_after_writing
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
data/lib/fargo/supports/chat.rb
CHANGED
@@ -2,9 +2,9 @@ module Fargo
|
|
2
2
|
module Supports
|
3
3
|
module Chat
|
4
4
|
extend ActiveSupport::Concern
|
5
|
-
|
5
|
+
|
6
6
|
included do
|
7
|
-
set_callback :
|
7
|
+
set_callback :initialization, :after, :initialize_chats
|
8
8
|
end
|
9
9
|
|
10
10
|
def messages
|
@@ -12,14 +12,16 @@ module Fargo
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def messages_with nick
|
15
|
-
@chats[nick]
|
15
|
+
@chats[nick]
|
16
16
|
end
|
17
17
|
|
18
|
-
|
18
|
+
protected
|
19
|
+
|
20
|
+
def initialize_chats
|
19
21
|
@public_chats = []
|
20
|
-
@chats
|
22
|
+
@chats = Hash.new{ |h, k| h[k] = [] }
|
21
23
|
|
22
|
-
subscribe do |type, map|
|
24
|
+
channel.subscribe do |type, map|
|
23
25
|
if type == :chat
|
24
26
|
@public_chats << map
|
25
27
|
elsif type == :privmsg
|
@@ -30,6 +32,7 @@ module Fargo
|
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
35
|
+
|
33
36
|
end
|
34
37
|
end
|
35
|
-
end
|
38
|
+
end
|
@@ -11,12 +11,15 @@ module Fargo
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
included do
|
15
|
+
set_callback :initialization, :after, :initialize_download_lists
|
16
|
+
end
|
17
|
+
|
14
18
|
attr_reader :current_downloads, :finished_downloads, :queued_downloads,
|
15
|
-
:failed_downloads, :
|
16
|
-
:download_slots
|
19
|
+
:failed_downloads, :trying, :timed_out
|
17
20
|
|
18
|
-
|
19
|
-
|
21
|
+
def has_download_slot?
|
22
|
+
@current_downloads.size + @trying.size < config.download_slots
|
20
23
|
end
|
21
24
|
|
22
25
|
def clear_failed_downloads
|
@@ -56,34 +59,45 @@ module Fargo
|
|
56
59
|
download.percent = 0
|
57
60
|
download.status = 'idle'
|
58
61
|
|
59
|
-
#
|
60
|
-
|
61
|
-
|
62
|
+
# Using the mutex can be expensive in start_download, defer this
|
63
|
+
if @timed_out.include? download.nick
|
64
|
+
download.status = 'timeout'
|
65
|
+
@failed_downloads[download.nick] << download
|
66
|
+
else
|
67
|
+
unless @queued_downloads[download.nick].include?(download) ||
|
68
|
+
@current_downloads[download.nick] == download
|
69
|
+
@queued_downloads[download.nick] << download
|
70
|
+
|
71
|
+
# This uses the lock and could be expensive, defer this for later
|
72
|
+
EventMachine.defer{ start_download }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
62
76
|
true
|
63
77
|
end
|
64
78
|
|
65
79
|
def retry_download nick, file
|
66
|
-
dl =
|
80
|
+
dl = @failed_downloads[nick].detect{ |h| h.file == file }
|
67
81
|
|
68
|
-
if dl.nil?
|
69
|
-
Fargo.logger.warn "#{file} isn't a failed download for: #{nick}!"
|
70
|
-
return
|
71
|
-
end
|
82
|
+
return if dl.nil?
|
72
83
|
|
73
84
|
@failed_downloads[nick].delete dl
|
74
|
-
download dl
|
85
|
+
download dl
|
75
86
|
end
|
76
87
|
|
77
88
|
def remove_download nick, file
|
78
89
|
# We need to synchronize this access, so append these arguments to a
|
79
90
|
# queue to be processed later
|
80
|
-
|
81
|
-
|
91
|
+
EventMachine.defer do
|
92
|
+
@downloading_lock.synchronize {
|
93
|
+
@queued_downloads[nick].delete_if{ |h| h.file == file }
|
94
|
+
}
|
95
|
+
end
|
82
96
|
end
|
83
97
|
|
84
98
|
def lock_next_download! user, connection
|
85
99
|
@downloading_lock.synchronize {
|
86
|
-
|
100
|
+
get_next_download_with_lock! user, connection
|
87
101
|
}
|
88
102
|
end
|
89
103
|
|
@@ -94,16 +108,17 @@ module Fargo
|
|
94
108
|
@timed_out.delete nick
|
95
109
|
downloads = @failed_downloads[nick].dup
|
96
110
|
@failed_downloads[nick].clear
|
111
|
+
# Reschedule all the failed downloads again
|
97
112
|
downloads.each{ |d| download nick, d.file, d.tth, d.size }
|
98
113
|
|
99
114
|
true
|
100
115
|
end
|
101
116
|
|
102
|
-
|
117
|
+
protected
|
103
118
|
|
104
119
|
# Finds the next queued up download and begins downloading it.
|
105
120
|
def start_download
|
106
|
-
return false
|
121
|
+
return false unless has_download_slot?
|
107
122
|
|
108
123
|
arr = nil
|
109
124
|
|
@@ -114,7 +129,7 @@ module Fargo
|
|
114
129
|
!@current_downloads.has_key?(nick) &&
|
115
130
|
!@trying.include?(nick) &&
|
116
131
|
!@timed_out.include?(nick) &&
|
117
|
-
(connection_for(nick) ||
|
132
|
+
(connection_for(nick) || nick_has_slot?(nick))
|
118
133
|
}
|
119
134
|
|
120
135
|
return false if arr.nil? || arr.size == 0
|
@@ -127,6 +142,7 @@ module Fargo
|
|
127
142
|
if connection
|
128
143
|
Fargo.logger.debug "Requesting previous connection downloads: #{arr[1].first}"
|
129
144
|
download = get_next_download_with_lock! dl_nick, connection
|
145
|
+
|
130
146
|
connection.download = download
|
131
147
|
connection.begin_download!
|
132
148
|
else
|
@@ -135,18 +151,14 @@ module Fargo
|
|
135
151
|
connect_with dl_nick
|
136
152
|
end
|
137
153
|
}
|
138
|
-
|
139
|
-
arr
|
140
154
|
end
|
141
155
|
|
142
156
|
# This method should only be called when synchronized by the mutex
|
143
157
|
def get_next_download_with_lock! user, connection
|
144
|
-
raise 'No open slots!'
|
158
|
+
raise 'No open slots!' unless has_download_slot?
|
145
159
|
raise "Already downloading from #{user}!" if @current_downloads[user]
|
146
160
|
|
147
|
-
|
148
|
-
return nil
|
149
|
-
end
|
161
|
+
return nil if @queued_downloads[user].size == 0
|
150
162
|
|
151
163
|
download = @queued_downloads[user].shift
|
152
164
|
@current_downloads[user] = download
|
@@ -154,26 +166,24 @@ module Fargo
|
|
154
166
|
|
155
167
|
Fargo.logger.debug "#{self}: Locking download: #{download}"
|
156
168
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
169
|
+
subscribed_id = channel.subscribe do |type, map|
|
170
|
+
if map[:nick] == user
|
171
|
+
if type == :download_progress
|
172
|
+
download.percent = map[:percent]
|
173
|
+
elsif type == :download_started
|
174
|
+
download.status = 'downloading'
|
175
|
+
elsif type == :download_finished
|
176
|
+
channel.unsubscribe subscribed_id
|
177
|
+
download.percent = 1
|
178
|
+
download.status = 'finished'
|
179
|
+
download_finished! user, false
|
180
|
+
elsif type == :download_failed || type == :download_disconnected
|
181
|
+
channel.unsubscribe subscribed_id
|
182
|
+
download.status = 'failed'
|
183
|
+
download_finished! user, true
|
184
|
+
end
|
173
185
|
end
|
174
|
-
|
175
|
-
|
176
|
-
connection.subscribe &block
|
186
|
+
end
|
177
187
|
|
178
188
|
download
|
179
189
|
end
|
@@ -182,104 +192,50 @@ module Fargo
|
|
182
192
|
download = nil
|
183
193
|
@downloading_lock.synchronize{
|
184
194
|
download = @current_downloads.delete user
|
185
|
-
@open_download_slots += 1
|
186
|
-
|
187
|
-
# connection_for(user).disconnect if @queued_downloads[user].size == 0
|
188
195
|
}
|
189
196
|
|
190
197
|
if failed
|
191
|
-
|
198
|
+
@failed_downloads[user] << download
|
192
199
|
else
|
193
|
-
|
200
|
+
@finished_downloads[user] << download
|
194
201
|
end
|
195
202
|
|
196
|
-
|
203
|
+
# Start another download if possible
|
204
|
+
EventMachine.defer{ start_download }
|
197
205
|
end
|
198
206
|
|
199
207
|
def connection_failed_with! nick
|
200
|
-
@trying.delete nick
|
201
|
-
@timed_out << nick
|
202
|
-
|
203
208
|
@downloading_lock.synchronize {
|
209
|
+
@trying.delete nick
|
210
|
+
@timed_out << nick
|
211
|
+
|
204
212
|
@queued_downloads[nick].each{ |d| d.status = 'timeout' }
|
205
|
-
@failed_downloads[nick]
|
206
|
-
@failed_downloads[nick] = @failed_downloads[nick] | @queued_downloads[nick]
|
207
|
-
@queued_downloads[nick].clear
|
213
|
+
@failed_downloads[nick] |= @queued_downloads.delete(nick)
|
208
214
|
}
|
209
215
|
|
210
|
-
|
216
|
+
# This one failed, try the next one
|
217
|
+
EventMachine.defer{ start_download }
|
211
218
|
end
|
212
219
|
|
213
|
-
def
|
214
|
-
@download_slots ||= 4
|
215
|
-
|
220
|
+
def initialize_download_lists
|
216
221
|
FileUtils.mkdir_p config.download_dir, :mode => 0755
|
217
222
|
|
218
223
|
@downloading_lock = Mutex.new
|
219
224
|
|
220
|
-
|
221
|
-
@queued_downloads = {}
|
225
|
+
@queued_downloads = Hash.new{ |h, k| h[k] = [] }
|
222
226
|
@current_downloads = {}
|
223
|
-
@failed_downloads = {}
|
224
|
-
@finished_downloads = {}
|
227
|
+
@failed_downloads = Hash.new{ |h, k| h[k] = [] }
|
228
|
+
@finished_downloads = Hash.new{ |h, k| h[k] = [] }
|
225
229
|
@trying = []
|
226
230
|
@timed_out = []
|
227
231
|
|
228
|
-
|
229
|
-
|
230
|
-
subscribe { |type, hash|
|
232
|
+
channel.subscribe do |type, hash|
|
231
233
|
if type == :connection_timeout
|
232
234
|
connection_failed_with! hash[:nick] if @trying.include?(hash[:nick])
|
233
|
-
elsif type == :hub_disconnected
|
234
|
-
exit_download_queue_threads
|
235
|
-
elsif type == :hub_connection_opened
|
236
|
-
start_download_queue_threads
|
237
235
|
end
|
238
|
-
|
239
|
-
end
|
240
|
-
|
241
|
-
def exit_download_queue_threads
|
242
|
-
@download_starter_thread.exit
|
243
|
-
@download_removal_thread.exit
|
244
|
-
end
|
245
|
-
|
246
|
-
# Both of these need access to the synchronization lock, so we use
|
247
|
-
# separate threads to do these processes.
|
248
|
-
def start_download_queue_threads
|
249
|
-
@to_download = Queue.new
|
250
|
-
@download_starter_thread = Thread.start {
|
251
|
-
loop {
|
252
|
-
download = @to_download.pop
|
253
|
-
|
254
|
-
if @timed_out.include? download.nick
|
255
|
-
download.status = 'timeout'
|
256
|
-
(@failed_downloads[download.nick] ||= []) << download
|
257
|
-
else
|
258
|
-
@queued_downloads[download.nick] ||= []
|
259
|
-
|
260
|
-
unless @queued_downloads[download.nick].include?(download) ||
|
261
|
-
@current_downloads[download.nick] == download
|
262
|
-
@queued_downloads[download.nick] << download
|
263
|
-
start_download
|
264
|
-
end
|
265
|
-
end
|
266
|
-
}
|
267
|
-
}
|
268
|
-
|
269
|
-
@to_remove = Queue.new
|
270
|
-
@download_removal_thread = Thread.start {
|
271
|
-
loop {
|
272
|
-
user, file = @to_remove.pop
|
273
|
-
|
274
|
-
@downloading_lock.synchronize {
|
275
|
-
@queued_downloads[user] ||= []
|
276
|
-
download = @queued_downloads[user].detect{ |h| h.file == file }
|
277
|
-
@queued_downloads[user].delete download unless download.nil?
|
278
|
-
}
|
279
|
-
}
|
280
|
-
}
|
236
|
+
end
|
281
237
|
end
|
282
238
|
|
283
|
-
end
|
284
|
-
end
|
285
|
-
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -6,31 +6,35 @@ module Fargo
|
|
6
6
|
module FileList
|
7
7
|
class Listing < Struct.new(:tth, :size, :name, :nick); end
|
8
8
|
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
set_callback :initialization, :after, :initialize_file_lists
|
13
|
+
end
|
14
|
+
|
9
15
|
# Lazily load the file list for the nick. Subscribe to the client for the
|
10
16
|
# event :file_list to get notified.
|
11
17
|
def file_list nick
|
12
|
-
@file_list ||= {}
|
13
|
-
@getting_file_list ||= {}
|
14
|
-
|
15
18
|
if @file_list.has_key?(nick)
|
16
19
|
return parse_file_list(@file_list[nick], nick)
|
17
20
|
elsif @getting_file_list[nick]
|
18
21
|
return true
|
19
22
|
end
|
20
23
|
|
21
|
-
|
24
|
+
subscription_id = channel.subscribe do |type, map|
|
22
25
|
case type
|
23
26
|
when :download_finished, :download_failed, :connection_timeout
|
24
27
|
if map[:nick] == nick
|
25
28
|
@file_list[nick] = map[:file]
|
26
|
-
|
27
|
-
|
29
|
+
|
30
|
+
channel.unsubscribe subscription_id
|
31
|
+
channel << [:file_list,
|
32
|
+
{:nick => nick, :list => @file_list[nick]}]
|
33
|
+
|
28
34
|
@getting_file_list.delete nick
|
29
35
|
end
|
30
36
|
end
|
31
|
-
|
32
|
-
|
33
|
-
subscribe &file_gotten
|
37
|
+
end
|
34
38
|
|
35
39
|
@getting_file_list[nick] = true
|
36
40
|
download nick, 'files.xml.bz2'
|
@@ -38,7 +42,6 @@ module Fargo
|
|
38
42
|
|
39
43
|
# Wait for the results to arrive, timed out after some time
|
40
44
|
def file_list! nick, timeout = 10
|
41
|
-
@file_list ||= {}
|
42
45
|
if @file_list.has_key?(nick)
|
43
46
|
return parse_file_list(@file_list[nick], nick)
|
44
47
|
end
|
@@ -91,6 +94,14 @@ module Fargo
|
|
91
94
|
|
92
95
|
list
|
93
96
|
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
|
100
|
+
def initialize_file_lists
|
101
|
+
@file_list = {}
|
102
|
+
@getting_file_list = {}
|
103
|
+
end
|
104
|
+
|
94
105
|
end
|
95
106
|
end
|
96
107
|
end
|
@@ -2,31 +2,38 @@ module Fargo
|
|
2
2
|
module Supports
|
3
3
|
module NickList
|
4
4
|
extend ActiveSupport::Concern
|
5
|
-
|
5
|
+
|
6
6
|
included do
|
7
|
-
set_callback :
|
7
|
+
set_callback :initialization, :after, :initialize_nick_lists
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
attr_accessor :nicks
|
11
|
-
|
11
|
+
|
12
|
+
def get_info nick
|
13
|
+
hub.send_message 'GetINFO', "#{nick} #{config.nick}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_ip *nicks
|
17
|
+
hub.send_message 'UserIP', nicks.flatten.join('$$')
|
18
|
+
end
|
19
|
+
|
12
20
|
def info nick
|
13
|
-
return nil unless @nick_info
|
14
21
|
if @nick_info.has_key?(nick) || !connected? || !@nicks.include?(nick)
|
15
|
-
return @nick_info[nick]
|
22
|
+
return @nick_info[nick]
|
16
23
|
end
|
17
24
|
|
18
25
|
# If we're connected and we don't already have this user's info, ask the
|
19
26
|
# server. We'll wait for 5 second to respond, otherwise we'll just
|
20
27
|
# return nil and be done with it
|
21
|
-
info_gotten = lambda{ |type, map|
|
22
|
-
|
28
|
+
info_gotten = lambda{ |type, map|
|
29
|
+
type == :myinfo && map[:nick].to_s == nick.to_s
|
23
30
|
}
|
24
31
|
timeout_response(5, info_gotten){ get_info nick }
|
25
32
|
|
26
33
|
@nick_info[nick]
|
27
34
|
end
|
28
|
-
|
29
|
-
def
|
35
|
+
|
36
|
+
def nick_has_slot? nick
|
30
37
|
# This query must be up to date so remove any cached information we have
|
31
38
|
# about the nick so we can get a fresh copy
|
32
39
|
@nick_info.try :delete, nick
|
@@ -41,12 +48,14 @@ module Fargo
|
|
41
48
|
Fargo.logger.debug "#{self} User: #{nick} has #{match[1]} open slots"
|
42
49
|
match[1].to_i > 0
|
43
50
|
end
|
44
|
-
|
45
|
-
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
def initialize_nick_lists
|
46
55
|
@nicks = []
|
47
56
|
@nick_info = Hash.new{ |h, k| h[k] = {} }
|
48
57
|
|
49
|
-
subscribe do |type, map|
|
58
|
+
channel.subscribe do |type, map|
|
50
59
|
case type
|
51
60
|
when :hello
|
52
61
|
@nicks << map[:who] unless @nicks.include? map[:who]
|
@@ -65,7 +74,7 @@ module Fargo
|
|
65
74
|
end
|
66
75
|
end
|
67
76
|
end
|
68
|
-
|
77
|
+
|
69
78
|
end
|
70
79
|
end
|
71
80
|
end
|
@@ -4,50 +4,55 @@ module Fargo
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
set_callback :
|
7
|
+
set_callback :initialization, :after, :initialize_connection_caches
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
@
|
12
|
-
|
10
|
+
def connect_with nick
|
11
|
+
@connection_timeouts[nick] = EventMachine::Timer.new(10) do
|
12
|
+
@connection_timeouts.delete(nick)
|
13
|
+
channel.push [:connection_timeout, {:nick => nick}]
|
14
|
+
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
if config.passive
|
17
|
+
hub.send_message 'RevConnectToMe', "#{self.config.nick} #{nick}"
|
18
|
+
else
|
19
|
+
hub.send_message 'ConnectToMe',
|
20
|
+
"#{nick} #{config.address}:#{config.active_port}"
|
19
21
|
end
|
22
|
+
end
|
20
23
|
|
21
|
-
|
22
|
-
@connection_cache
|
23
|
-
nil
|
24
|
+
def connection_for nick
|
25
|
+
@connection_cache[nick]
|
24
26
|
end
|
25
27
|
|
26
28
|
def connected_with? nick
|
27
|
-
|
28
|
-
c.connected? unless c.nil?
|
29
|
+
@connection_cache.has_key? nick
|
29
30
|
end
|
30
31
|
|
31
32
|
def disconnect_from nick
|
32
|
-
c = @connection_cache.
|
33
|
-
c.
|
33
|
+
c = @connection_cache.delete nick
|
34
|
+
c.try :close_connection_after_writing
|
34
35
|
end
|
35
36
|
|
36
37
|
def nicks_connected_with
|
37
|
-
|
38
|
-
|
39
|
-
nicks = @connection_cache.keys
|
40
|
-
nicks.reject{ |n| !connected_with? n }
|
38
|
+
@connection_cache.keys
|
41
39
|
end
|
42
40
|
|
43
|
-
|
41
|
+
protected
|
42
|
+
|
43
|
+
def initialize_connection_caches
|
44
44
|
@connection_cache = {}
|
45
45
|
|
46
|
-
subscribe
|
46
|
+
channel.subscribe do |type, hash|
|
47
47
|
if type == :hub_disconnected
|
48
48
|
nicks_connected_with.each{ |n| disconnect_from n }
|
49
|
+
elsif type == :download_disconnected
|
50
|
+
@connection_cache.delete hash[:nick]
|
51
|
+
elsif type == :download_opened
|
52
|
+
@connection_timeouts.delete(hash[:nick]).try(:cancel)
|
53
|
+
@connection_cache[hash[:nick]] = hash[:connection]
|
49
54
|
end
|
50
|
-
|
55
|
+
end
|
51
56
|
end
|
52
57
|
|
53
58
|
end
|
@@ -2,9 +2,30 @@ module Fargo
|
|
2
2
|
module Supports
|
3
3
|
module Searches
|
4
4
|
extend ActiveSupport::Concern
|
5
|
-
|
5
|
+
|
6
6
|
included do
|
7
|
-
set_callback :
|
7
|
+
set_callback :initialization, :after, :initialize_search_caches
|
8
|
+
end
|
9
|
+
|
10
|
+
# see parser#@@search for what's passed in
|
11
|
+
#
|
12
|
+
# searches this client's files based on those options and returns an array
|
13
|
+
# of SearchResult(s)
|
14
|
+
def search_files options
|
15
|
+
# TODO: implement me
|
16
|
+
[]
|
17
|
+
end
|
18
|
+
|
19
|
+
def search_hub query
|
20
|
+
raise ConnectionError.new('Not connected Yet!') unless connected?
|
21
|
+
|
22
|
+
if config.passive
|
23
|
+
location = "Hub:#{config.nick}"
|
24
|
+
else
|
25
|
+
location = "#{config.address}:#{config.search_port}"
|
26
|
+
end
|
27
|
+
|
28
|
+
hub.send_message 'Search', "#{location} #{query.to_s}"
|
8
29
|
end
|
9
30
|
|
10
31
|
def search search
|
@@ -17,21 +38,21 @@ module Fargo
|
|
17
38
|
end
|
18
39
|
|
19
40
|
def searches
|
20
|
-
@searches.keys.map { |k| @search_objects[k] }
|
41
|
+
@searches.keys.map { |k| @search_objects[k] }
|
21
42
|
end
|
22
43
|
|
23
44
|
def search_results search
|
24
45
|
search = normalize search
|
25
|
-
@searches[search.to_s]
|
46
|
+
@searches[search.to_s]
|
26
47
|
end
|
27
48
|
|
28
49
|
def remove_search search
|
29
50
|
search = normalize search
|
30
|
-
@searches.delete search.to_s
|
31
|
-
@search_objects.delete search.to_s
|
51
|
+
@searches.delete search.to_s
|
52
|
+
@search_objects.delete search.to_s
|
32
53
|
end
|
33
54
|
|
34
|
-
|
55
|
+
protected
|
35
56
|
|
36
57
|
def normalize search
|
37
58
|
unless search.is_a? Fargo::Search
|
@@ -41,11 +62,11 @@ module Fargo
|
|
41
62
|
search
|
42
63
|
end
|
43
64
|
|
44
|
-
def
|
65
|
+
def initialize_search_caches
|
45
66
|
@searches = {}
|
46
67
|
@search_objects = {}
|
47
68
|
|
48
|
-
subscribe do |type, map|
|
69
|
+
channel.subscribe do |type, map|
|
49
70
|
if type == :search_result
|
50
71
|
@searches.keys.each do |search|
|
51
72
|
if @search_objects[search].matches_result?(map)
|