fargo 0.1.0 → 0.1.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.
@@ -1,7 +1,7 @@
1
1
  require 'active_support/configurable'
2
2
  require 'active_support/callbacks'
3
3
 
4
- module Fargo
4
+ module Fargo
5
5
  class ConnectionError < RuntimeError; end
6
6
 
7
7
  module Connection
@@ -10,16 +10,16 @@ module Fargo
10
10
  include ActiveSupport::Configurable
11
11
  include ActiveSupport::Callbacks
12
12
  include Fargo::Publisher
13
-
13
+
14
14
  attr_accessor :socket
15
15
  define_callbacks :listen
16
-
16
+
17
17
  def initialize client
18
18
  @outgoing = Queue.new
19
19
  @client = client
20
20
  config.quit_on_disconnect = true
21
21
  end
22
-
22
+
23
23
  def connect
24
24
  Fargo.logger.info(
25
25
  "#{self}: Opening connection with #{config.address}, #{config.port}"
@@ -35,7 +35,7 @@ module Fargo
35
35
  def receive
36
36
  raise 'Implement me!'
37
37
  end
38
-
38
+
39
39
  def open_socket
40
40
  @socket ||= TCPSocket.open config.address, config.port
41
41
  rescue Errno::ECONNREFUSED
@@ -43,20 +43,21 @@ module Fargo
43
43
  end
44
44
 
45
45
  def connected?
46
- !@socket.nil?
46
+ !@socket.nil? && !@socket.closed?
47
47
  end
48
48
 
49
49
  def listen
50
50
  return unless @threads.nil? || @threads.size == 0
51
-
51
+
52
52
  run_callbacks :listen do
53
53
  @threads = []
54
+ @looping = true
54
55
 
55
56
  # Start a thread to read the socket
56
- @threads << Thread.start { loop { read_data } }
57
+ @threads << Thread.start { read_data while @looping }
57
58
 
58
59
  # Start a thread to send information from the queue
59
- @threads << Thread.start { loop { write_data @outgoing.pop } }
60
+ @threads << Thread.start { write_data @outgoing.pop while @looping }
60
61
 
61
62
  @threads.each { |t| t.abort_on_exception = true }
62
63
  end
@@ -67,8 +68,10 @@ module Fargo
67
68
 
68
69
  write "$Quit #{@client.config.nick}" if config.quit_on_disconnect
69
70
 
71
+ @looping = false
72
+
70
73
  if @threads
71
- @threads.each &:exit
74
+ @threads.each{ |t| t.exit unless t == Thread.current }
72
75
  @threads.clear
73
76
  end
74
77
 
@@ -86,48 +89,38 @@ module Fargo
86
89
  connection_type = self.class.name.split('::').last.downcase
87
90
  @client.publish :"#{connection_type}_disconnected"
88
91
  end
89
-
92
+
90
93
  def write string
91
94
  string << '|' unless string.end_with?('|')
92
95
  @outgoing << string # append this to the queue of things to be written
93
96
  true
94
97
  end
95
-
98
+
96
99
  private
97
100
 
98
101
  def read_data
99
- if @socket.closed?
100
- Fargo.logger.debug 'When reading data, socket was already closed!'
102
+ data = @socket.gets '|'
103
+ raise ConnectionError.new('Received nil data!') if data.nil?
104
+
105
+ Fargo.logger.debug "#{self} Received: #{data.inspect}"
106
+ receive data.chomp('|')
107
+ rescue => e
108
+ unless @socket.closed?
109
+ Fargo.logger.warn "#{self}: Error reading data, going away: #{e}"
101
110
  disconnect
102
- else
103
- begin
104
- data = @socket.gets '|'
105
- raise ConnectionError.new("Received nil data!") if data.nil?
106
- rescue => e
107
- Fargo.logger.warn "#{self}: Error reading data, disconnecting: #{e}"
108
- disconnect
109
- end
110
-
111
- Fargo.logger.debug "#{self} Received: #{data.inspect}"
112
- receive data.chomp('|')
113
111
  end
114
112
  end
115
113
 
116
114
  def write_data data
117
- if @socket.closed?
118
- Fargo.logger.debug "When writing data, socket was already closed!"
115
+ Fargo.logger.debug "#{self} Sending: #{data.inspect}"
116
+ @socket << data
117
+ rescue => e
118
+ unless @socket.closed?
119
+ Fargo.logger.warn "#{self}: Error writing data, going away: #{e}"
119
120
  disconnect
120
- else
121
- begin
122
- Fargo.logger.debug "#{self} Sending: #{data.inspect}"
123
- @socket << data
124
- rescue
125
- @client.publish :write_error
126
- disconnect
127
- end
128
121
  end
129
122
  end
130
-
123
+
131
124
  end
132
125
  end
133
126
  end
@@ -3,24 +3,24 @@ require 'zlib'
3
3
  module Fargo
4
4
  module Connection
5
5
  class Download < Base
6
-
6
+
7
7
  include Fargo::Utils
8
8
  include Fargo::Parser
9
-
9
+
10
10
  set_callback :listen, :before, :pre_listen
11
11
  set_callback :listen, :after do |connection|
12
12
  send_lock if connection.config.first
13
13
  end
14
-
14
+
15
15
  attr_accessor :download
16
16
 
17
17
  def pre_listen
18
18
  Fargo.logger.debug "Initiating connection on: #{config.address}:#{config.port}"
19
-
19
+
20
20
  config.quit_on_disconnect = false
21
21
  @lock, @pk = generate_lock
22
22
  @handshake_step = 0
23
-
23
+
24
24
  @buffer_size = (2 << 12).freeze
25
25
  end
26
26
 
@@ -30,32 +30,38 @@ module Fargo
30
30
 
31
31
  def read_data
32
32
  # only download if we're at the correct time
33
- return super if @handshake_step != 6
33
+ return super if @handshake_step != 6
34
34
 
35
35
  @exit_time = 20 # reset our timeout time
36
-
36
+
37
37
  data = @socket.readpartial @buffer_size
38
-
38
+
39
39
  if @zlib
40
40
  @zs = Zlib::Inflate.new if @zs.nil?
41
41
  data = @zs.inflate data
42
42
  end
43
-
43
+
44
44
  @file << data
45
45
  @recvd += data.length
46
46
 
47
- if @recvd == @length
48
- download_finished!
49
- elsif @recvd > @length
47
+ if @recvd > @length
50
48
  error "#{self} #{@recvd} > #{@length}!!!"
51
49
  download_finished!
52
50
  else
53
- publish :download_progress, :percent => @recvd.to_f / @length,
54
- :file => download_path,
55
- :nick => @other_nick,
56
- :download => @download,
57
- :size => @length,
58
- :compressed => @zlib
51
+ percent = @recvd.to_f / @length
52
+ if percent - @last_published > 0.05
53
+ @file.flush
54
+ publish :download_progress, :percent => percent,
55
+ :file => download_path,
56
+ :nick => @other_nick,
57
+ :download => @download,
58
+ :size => @recvd,
59
+ :compressed => @zlib
60
+
61
+ @last_published = percent
62
+ end
63
+
64
+ download_finished! if @recvd == @length
59
65
  end
60
66
  rescue IOError => e
61
67
  error "#{self}: IOError, disconnecting #{e}"
@@ -67,7 +73,7 @@ module Fargo
67
73
  case message[:type]
68
74
  when :mynick
69
75
  if @handshake_step == 0
70
- @handshake_step = 1
76
+ @handshake_step = 1
71
77
  @other_nick = message[:nick]
72
78
 
73
79
  @client.connected_with! @other_nick
@@ -94,7 +100,7 @@ module Fargo
94
100
  else
95
101
  error 'Premature disconnect when lock received'
96
102
  end
97
-
103
+
98
104
  when :supports
99
105
  if @handshake_step == 2
100
106
  @client_extensions = message[:extensions]
@@ -102,7 +108,7 @@ module Fargo
102
108
  else
103
109
  error 'Premature disconnect when supports received'
104
110
  end
105
-
111
+
106
112
  when :direction
107
113
  if @handshake_step == 3 && message[:direction] == 'upload'
108
114
  @client_num = message[:number]
@@ -110,7 +116,7 @@ module Fargo
110
116
  else
111
117
  error 'Premature disconnect when direction received'
112
118
  end
113
-
119
+
114
120
  when :key
115
121
  if @handshake_step == 4 && generate_key(@lock) == message[:key]
116
122
 
@@ -132,9 +138,9 @@ module Fargo
132
138
 
133
139
  write "$Send" unless @client_extensions.include? 'ADCGet'
134
140
 
135
- publish :download_started, :file => download_path,
136
- :download => @download,
137
- :nick => @other_nick
141
+ publish :download_started, :file => download_path,
142
+ :download => @download,
143
+ :nick => @other_nick
138
144
  else
139
145
  error "Premature disconnect when #{message[:type]} received"
140
146
  end
@@ -142,27 +148,29 @@ module Fargo
142
148
  when :noslots
143
149
  if @download
144
150
  Fargo.logger.debug "#{self}: No Slots for #{self[:download]}"
145
-
151
+
146
152
  download_failed! 'No Slots'
147
153
  end
148
154
 
149
155
  when :error
150
- error "#{self}: Error! #{message[:message]}"
151
-
152
- # This wasn't handled by us, proxy it on up to the client
156
+ Fargo.logger.warn @last_error = "#{self}: Error! #{message[:message]}"
157
+ download_failed! message[:message]
158
+
159
+ # This wasn't handled by us, proxy it on up to the client
153
160
  else
154
161
  @client.publish message[:type], message
155
162
 
156
163
  end
157
164
  end
158
-
165
+
159
166
  def begin_download!
160
- @file = File.new download_path, File::CREAT | File::WRONLY
167
+ @file = File.open download_path, 'wb'
161
168
 
162
169
  @file.seek @download.offset
163
170
  @file.sync = true
164
171
  @socket.sync = true
165
172
  @handshake_step = 5
173
+ @last_published = 0
166
174
 
167
175
  if @download.file_list?
168
176
  if @client_extensions.include? 'XmlBZList'
@@ -177,7 +185,7 @@ module Fargo
177
185
  if @client_extensions.include? 'ADCGet'
178
186
  download_query = @download.file
179
187
  if @download.tth && @client_extensions.include?('TTHF')
180
- download_query = @download.tth.gsub ':', '/'
188
+ download_query = 'TTH/' + @download.tth
181
189
  end
182
190
 
183
191
  zlig = ''
@@ -194,66 +202,67 @@ module Fargo
194
202
  # This is the thread for the timeout of a connection. The @exit_time
195
203
  # variable is reset to 20 after every bit of information is received.
196
204
  @exit_time = 20
197
- @exit_thread = Thread.start {
205
+ @exit_thread = Thread.start {
198
206
  while @exit_time > 0
199
207
  sleep 1
200
208
  @exit_time -= 1
201
209
  Fargo.logger.debug "#{self} time out in #{@exit_time} seconds"
202
210
  end
203
211
 
204
- download_failed! 'Download timeout!'
212
+ download_failed! 'Download timeout!'
205
213
  }
206
-
214
+
207
215
  Fargo.logger.debug "#{self}: Beginning download of #{@download}"
208
216
  end
209
-
217
+
210
218
  def download_failed! msg, opts = {}
211
219
  Fargo.logger.debug "#{self}: #{msg} #{@download}"
212
-
220
+
213
221
  # cache because publishing must be at end of method and we're about to
214
222
  # clear these
215
223
  path, download = download_path, @download
216
224
 
217
225
  reset_download
218
226
 
219
- publish :download_failed, opts.merge(:nick => @other_nick,
220
- :download => download,
221
- :file => path,
227
+ publish :download_failed, opts.merge(:nick => @other_nick,
228
+ :download => download,
229
+ :file => path,
222
230
  :last_error => msg)
223
231
 
224
232
  @exit_thread = nil
225
233
  end
226
-
234
+
227
235
  def download_finished!
228
236
  Fargo.logger.debug "#{self}: Finished download of #{@download}"
229
-
237
+
230
238
  # cache because publishing must be at end of method and we're about to
231
239
  # clear these
232
240
  path, download = download_path, @download
233
-
241
+
234
242
  reset_download
235
-
236
- publish :download_finished, :file => path, :download => download,
243
+
244
+ publish :download_finished, :file => path, :download => download,
237
245
  :nick => @other_nick
246
+ disconnect if download.file_list?
238
247
  end
239
-
248
+
240
249
  def disconnect
241
250
  Fargo.logger.debug "#{self} Disconnecting from: #{@other_nick}"
242
-
251
+
243
252
  super
244
253
 
245
254
  if @download
246
255
  download_failed! @last_error, :recvd => @recvd, :length => @length
247
256
  end
248
-
257
+
249
258
  reset_download
250
259
  end
251
-
260
+
252
261
  private
253
262
  def reset_download
254
263
  @file.close unless @file.nil? || @file.closed?
255
264
  if @file_path && File.exists?(@file_path) && File.size(@file_path) == 0
256
- File.delete(@file_path)
265
+ File.delete(@file_path)
257
266
  end
258
267
 
259
268
  if @socket
@@ -262,18 +271,18 @@ module Fargo
262
271
  end
263
272
 
264
273
  # If this was called from exit thread, don't kill it
265
- if @exit_thread != Thread.current
274
+ if @exit_thread != Thread.current
266
275
  @exit_thread.exit if @exit_thread && @exit_thread.alive?
267
276
  @exit_thread = nil
268
277
  end
269
-
278
+
270
279
  # clear out these variables
271
- @zs = @file_path = @zlib = @download = @length = @recvd = nil
280
+ @zs = @file_path = @zlib = @download = @length = @recvd = nil
272
281
 
273
282
  # Go back to the get step
274
283
  @handshake_step = 5
275
284
  end
276
-
285
+
277
286
  def download_path
278
287
  return nil if @download.try(:file).nil?
279
288
 
@@ -282,10 +291,12 @@ module Fargo
282
291
  filename = File.basename @download.file.gsub("\\", '/')
283
292
  path = File.join(prefix, @other_nick, filename)
284
293
 
285
- i = 0
286
- while File.exists?(path)
287
- i += 1
288
- path = File.join(prefix, @other_nick, "#{i}-#{filename}")
294
+ unless @download.file_list?
295
+ i = 0
296
+ while File.exists?(path)
297
+ i += 1
298
+ path = File.join(prefix, @other_nick, "#{i}-#{filename}")
299
+ end
289
300
  end
290
301
 
291
302
  path
@@ -1,26 +1,42 @@
1
1
  module Fargo
2
2
  module Publisher
3
-
3
+
4
4
  attr_reader :subscribers
5
5
 
6
6
  def subscribe &subscriber
7
- raise RuntimeError.new("Need a subscription block!") if subscriber.nil?
7
+ raise RuntimeError.new('Need a subscription block!') if subscriber.nil?
8
+
8
9
  Fargo.logger.debug "#{self}: subscribing #{subscriber}"
9
10
  (@subscribers ||= []) << subscriber
10
11
  end
11
-
12
+
12
13
  def subscribed_to?
13
14
  @subscribers && @subscribers.size > 0
14
15
  end
15
-
16
+
16
17
  def unsubscribe &subscriber
17
- raise RuntimeError.new("Need a subscription block!") if subscriber.nil?
18
+ raise RuntimeError.new('Need a subscription block!') if subscriber.nil?
19
+
18
20
  Fargo.logger.debug "#{self}: unsubscribing #{subscriber}"
19
21
  (@subscribers ||= []).delete subscriber
20
22
  end
21
23
 
22
24
  def publish message_type, hash = {}
23
- @subscribers.each { |subscriber| subscriber.call message_type, hash } if @subscribers
25
+ @subscribers ||= []
26
+
27
+ to_remove = []
28
+
29
+ @subscribers.each do |subscriber|
30
+ begin
31
+ subscriber.call message_type, hash
32
+ rescue => e
33
+ Fargo.logger.warn "#{self}: error publishing to: #{subscriber}! #{e}"
34
+ to_remove << subscriber
35
+ end
36
+ end
37
+
38
+ @subscribers -= to_remove
24
39
  end
40
+
25
41
  end
26
42
  end
@@ -10,31 +10,48 @@ module Fargo
10
10
  file == 'files.xml.bz2'
11
11
  end
12
12
  end
13
-
13
+
14
14
  attr_reader :current_downloads, :finished_downloads, :queued_downloads,
15
15
  :failed_downloads, :open_download_slots, :trying, :timed_out,
16
16
  :download_slots
17
-
17
+
18
18
  included do
19
19
  set_callback :setup, :after, :initialize_queues
20
20
  end
21
-
21
+
22
22
  def clear_failed_downloads
23
23
  failed_downloads.clear
24
24
  end
25
-
25
+
26
26
  def clear_finished_downloads
27
27
  finished_downloads.clear
28
28
  end
29
29
 
30
- def download nick, file, tth=nil, size=-1, offset=0
30
+ def download nick, file=nil, tth=nil, size=-1, offset=0
31
31
  raise ConnectionException.new 'Not connected yet!' unless hub
32
- raise 'File cannot be nil!' if file.nil?
33
32
 
33
+ if nick.is_a?(Supports::FileList::Listing)
34
+ listing = nick
35
+ nick = listing.nick
36
+ file = listing.name
37
+ tth = listing.tth
38
+ size = listing.size
39
+ elsif nick.is_a?(Download)
40
+ dl = nick
41
+ nick = dl.nick
42
+ file = dl.file
43
+ tth = dl.tth
44
+ size = dl.size || -1
45
+ offset = dl.offset || 0
46
+ end
47
+
48
+ raise 'File must not be nil!' if file.nil?
34
49
  unless nicks.include? nick
35
- raise ConnectionException.new "User #{nick} does not exist!"
50
+ raise ConnectionException.new "User #{nick} does not exist!"
36
51
  end
37
52
 
53
+ tth = tth.gsub /^TTH:/, '' if tth
54
+
38
55
  download = Download.new nick, file, tth, size, offset
39
56
  download.percent = 0
40
57
  download.status = 'idle'
@@ -52,13 +69,13 @@ module Fargo
52
69
  Fargo.logger.warn "#{file} isn't a failed download for: #{nick}!"
53
70
  return
54
71
  end
55
-
72
+
56
73
  @failed_downloads[nick].delete dl
57
74
  download dl.nick, dl.file, dl.tth, dl.size
58
75
  end
59
76
 
60
77
  def remove_download nick, file
61
- # We need to synchronize this access, so append these arguments to a
78
+ # We need to synchronize this access, so append these arguments to a
62
79
  # queue to be processed later
63
80
  @to_remove << [nick, file]
64
81
  true
@@ -93,11 +110,11 @@ module Fargo
93
110
  @downloading_lock.synchronize {
94
111
  # Find the first nick and download list
95
112
  arr = @queued_downloads.to_a.detect{ |nick, downloads|
96
- downloads.size > 0 &&
97
- !@current_downloads.has_key?(nick) &&
98
- !@trying.include?(nick) &&
99
- !@timed_out.include?(nick) &&
100
- has_slot?(nick)
113
+ downloads.size > 0 &&
114
+ !@current_downloads.has_key?(nick) &&
115
+ !@trying.include?(nick) &&
116
+ !@timed_out.include?(nick) &&
117
+ (connection_for(nick) || has_slot?(nick))
101
118
  }
102
119
 
103
120
  return false if arr.nil? || arr.size == 0
@@ -131,7 +148,7 @@ module Fargo
131
148
  return nil
132
149
  end
133
150
 
134
- download = @queued_downloads[user].shift
151
+ download = @queued_downloads[user].shift
135
152
  @current_downloads[user] = download
136
153
  @trying.delete user
137
154
 
@@ -160,12 +177,14 @@ module Fargo
160
177
 
161
178
  download
162
179
  end
163
-
180
+
164
181
  def download_finished! user, failed
165
182
  download = nil
166
- @downloading_lock.synchronize{
183
+ @downloading_lock.synchronize{
167
184
  download = @current_downloads.delete user
168
185
  @open_download_slots += 1
186
+
187
+ # connection_for(user).disconnect if @queued_downloads[user].size == 0
169
188
  }
170
189
 
171
190
  if failed
@@ -176,7 +195,7 @@ module Fargo
176
195
 
177
196
  start_download # Start another download if possible
178
197
  end
179
-
198
+
180
199
  def connection_failed_with! nick
181
200
  @trying.delete nick
182
201
  @timed_out << nick
@@ -224,7 +243,7 @@ module Fargo
224
243
  @download_removal_thread.exit
225
244
  end
226
245
 
227
- # Both of these need access to the synchronization lock, so we use
246
+ # Both of these need access to the synchronization lock, so we use
228
247
  # separate threads to do these processes.
229
248
  def start_download_queue_threads
230
249
  @to_download = Queue.new
@@ -236,8 +255,13 @@ module Fargo
236
255
  download.status = 'timeout'
237
256
  (@failed_downloads[download.nick] ||= []) << download
238
257
  else
239
- (@queued_downloads[download.nick] ||= []) << download
240
- start_download
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
241
265
  end
242
266
  }
243
267
  }
@@ -256,6 +280,6 @@ module Fargo
256
280
  }
257
281
  end
258
282
 
259
- end # Downloads
283
+ end # Downloads
260
284
  end # Supports
261
285
  end # Fargo
@@ -4,13 +4,19 @@ require 'libxml'
4
4
  module Fargo
5
5
  module Supports
6
6
  module FileList
7
- class Listing < Struct.new(:tth, :size, :name); end
7
+ class Listing < Struct.new(:tth, :size, :name, :nick); end
8
8
 
9
9
  # Lazily load the file list for the nick. Subscribe to the client for the
10
10
  # event :file_list to get notified.
11
11
  def file_list nick
12
12
  @file_list ||= {}
13
- return parse_file_list(@file_list[nick]) if @file_list.has_key?(nick)
13
+ @getting_file_list ||= {}
14
+
15
+ if @file_list.has_key?(nick)
16
+ return parse_file_list(@file_list[nick], nick)
17
+ elsif @getting_file_list[nick]
18
+ return true
19
+ end
14
20
 
15
21
  file_gotten = lambda{ |type, map|
16
22
  case type
@@ -19,19 +25,23 @@ module Fargo
19
25
  @file_list[nick] = map[:file]
20
26
  unsubscribe &file_gotten
21
27
  publish :file_list, :nick => nick, :list => @file_list[nick]
28
+ @getting_file_list.delete nick
22
29
  end
23
30
  end
24
31
  }
25
32
 
26
33
  subscribe &file_gotten
27
34
 
35
+ @getting_file_list[nick] = true
28
36
  download nick, 'files.xml.bz2'
29
37
  end
30
38
 
31
39
  # Wait for the results to arrive, timed out after some time
32
40
  def file_list! nick, timeout = 10
33
41
  @file_list ||= {}
34
- return parse_file_list(@file_list[nick]) if @file_list.has_key?(nick)
42
+ if @file_list.has_key?(nick)
43
+ return parse_file_list(@file_list[nick], nick)
44
+ end
35
45
 
36
46
  list = nil
37
47
  list_gotten = lambda{ |type, map|
@@ -45,35 +55,37 @@ module Fargo
45
55
 
46
56
  timeout_response(timeout, list_gotten){ file_list nick }
47
57
 
48
- parse_file_list list
58
+ parse_file_list list, nick
49
59
  end
50
60
 
51
61
  private
52
62
 
53
- def parse_file_list file
63
+ def parse_file_list file, nick
54
64
  if file && File.exists?(file)
65
+ Fargo.logger.debug "Parsing file list for: '#{nick}' at '#{file}'"
55
66
  xml = Bzip2::Reader.open(file).read
56
67
  doc = LibXML::XML::Document.string xml
57
68
 
58
- construct_file_list doc.root
69
+ construct_file_list doc.root, nil, nick
59
70
  else
60
71
  nil
61
72
  end
62
73
  end
63
74
 
64
- def construct_file_list node
75
+ def construct_file_list node, prefix, nick
65
76
  list = {}
66
77
 
67
78
  node.each_element do |element|
68
- element_name = element['Name']
79
+ path = prefix ? prefix + "\\" + element['Name'] : element['Name']
80
+
69
81
  if element.name =~ /directory/i
70
- list[element_name] = construct_file_list element
82
+ list[element['Name']] = construct_file_list element, path, nick
71
83
  else
72
- list[element_name] = Listing.new(
73
- element['TTH'],
74
- element['Size'],
75
- element_name
76
- )
84
+ # Why does this consistently segfault ruby 1.8.7 when I convert
85
+ # element['Size'] to an integer before the struct is created?!
86
+ element = list[element['Name']] = Listing.new(element['TTH'],
87
+ element['Size'], path, nick)
88
+ element.size = element.size.to_i
77
89
  end
78
90
  end
79
91
 
@@ -13,30 +13,33 @@ module Fargo
13
13
 
14
14
  def connection_for nick
15
15
  c = @connection_cache.try :[], nick
16
- return c if c.nil? || c.connected?
16
+ if c.nil? || c.connected?
17
+ Fargo.logger.debug "#{self} has connection with: #{nick}: #{c}"
18
+ return c
19
+ end
17
20
 
18
21
  # If it's present and not connected, remove it from the cache
19
22
  @connection_cache.try :delete, nick
20
23
  nil
21
24
  end
22
-
25
+
23
26
  def connected_with? nick
24
27
  c = @connection_cache.try :[], nick
25
28
  c.connected? unless c.nil?
26
- end
27
-
29
+ end
30
+
28
31
  def disconnect_from nick
29
32
  c = @connection_cache.try :delete, nick
30
33
  c.disconnect unless c.nil?
31
34
  end
32
-
35
+
33
36
  def nicks_connected_with
34
37
  return [] if @connection_cache.nil?
35
38
 
36
39
  nicks = @connection_cache.keys
37
- nicks.reject{ |n| !connected_with? n }
40
+ nicks.reject{ |n| !connected_with? n }
38
41
  end
39
-
42
+
40
43
  def setup_connection_cache
41
44
  @connection_cache = {}
42
45
 
@@ -49,4 +52,4 @@ module Fargo
49
52
 
50
53
  end
51
54
  end
52
- end
55
+ end
data/lib/fargo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fargo
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fargo
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 25
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 1
8
- - 0
9
- version: 0.1.0
9
+ - 1
10
+ version: 0.1.1
10
11
  platform: ruby
11
12
  authors:
12
13
  - Alex Crichton
@@ -14,51 +15,54 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-09-06 00:00:00 -04:00
18
+ date: 2010-09-22 00:00:00 -04:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
- name: activesupport
22
- requirement: &id001 !ruby/object:Gem::Requirement
22
+ version_requirements: &id001 !ruby/object:Gem::Requirement
23
23
  none: false
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
+ hash: 7
27
28
  segments:
28
29
  - 3
29
30
  - 0
30
31
  - 0
31
32
  version: 3.0.0
33
+ requirement: *id001
32
34
  type: :runtime
35
+ name: activesupport
33
36
  prerelease: false
34
- version_requirements: *id001
35
37
  - !ruby/object:Gem::Dependency
36
- name: libxml-ruby
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
+ version_requirements: &id002 !ruby/object:Gem::Requirement
38
39
  none: false
39
40
  requirements:
40
41
  - - ">="
41
42
  - !ruby/object:Gem::Version
43
+ hash: 3
42
44
  segments:
43
45
  - 0
44
46
  version: "0"
47
+ requirement: *id002
45
48
  type: :runtime
49
+ name: libxml-ruby
46
50
  prerelease: false
47
- version_requirements: *id002
48
51
  - !ruby/object:Gem::Dependency
49
- name: bzip2-ruby
50
- requirement: &id003 !ruby/object:Gem::Requirement
52
+ version_requirements: &id003 !ruby/object:Gem::Requirement
51
53
  none: false
52
54
  requirements:
53
55
  - - ">="
54
56
  - !ruby/object:Gem::Version
57
+ hash: 3
55
58
  segments:
56
59
  - 0
57
60
  version: "0"
61
+ requirement: *id003
58
62
  type: :runtime
63
+ name: bzip2-ruby
59
64
  prerelease: false
60
- version_requirements: *id003
61
- description: DC Client
65
+ description: Direct Connect (DC) Client implemented in pure Ruby
62
66
  email: alex@alexcrichton.com
63
67
  executables: []
64
68
 
@@ -103,7 +107,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
103
107
  requirements:
104
108
  - - ">="
105
109
  - !ruby/object:Gem::Version
106
- hash: 1373483426740815041
110
+ hash: 3
107
111
  segments:
108
112
  - 0
109
113
  version: "0"
@@ -112,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
116
  requirements:
113
117
  - - ">="
114
118
  - !ruby/object:Gem::Version
115
- hash: 1373483426740815041
119
+ hash: 3
116
120
  segments:
117
121
  - 0
118
122
  version: "0"