Top Level Namespace

Defined Under Namespace

Classes: Transmission, UTorrent

Constant Summary collapse

HOME_DIR =
SETTING_DIR =
"#{HOME_DIR}/.torrentsync"
PEERS_FILE =
File.join(SETTING_DIR, 'peers')
TORRENTS_FILE =
File.join(SETTING_DIR, 'torrents')

Instance Method Summary collapse

Instance Method Details

#find_torrent(name) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/torrentsync.rb', line 125

def find_torrent(name)
  uris = File.open(TORRENTS_FILE).readlines.map(&:chomp).map{|u| URI.parse(u)}
  rv = nil
  uris.each do |uri|
    ts = case uri.scheme
    when 'file'
      Dir.glob(File.join(uri.path, '*.torrent')).map{|t|File.basename(t)}
    when 'http'
      body = open(uri).read
      h = Nokogiri::HTML.parse(body)
      h.css('a').map{|a| a.text}.select{|t| /\.torrent$/ === t}
    else
      raise
    end
    rp = ts.find{|t| !t.index(name).nil?}
    next if rp.nil?
    uri2 = URI.parse(URI.encode("#{uri.to_s}/#{rp}"))
    rv = case uri2.scheme
        when 'file'
          open(uri2.path){|f|f.read}
        when 'http'
          open(uri2){|f|f.read}
        end
    # TODO need to check info_hash too
    break
  end
  rv
end

#get_peersObject



163
164
165
# File 'lib/torrentsync.rb', line 163

def get_peers
  File.open(PEERS_FILE).readlines.map(&:chomp).map(&:split)
end

#get_torrents(peers) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/torrentsync.rb', line 167

def get_torrents(peers)
  torrents = {}
  dead_peers = []
  peers.each do |peer|
    type = peer[0]
    next if type[0, 1] == '#'
    host, port, user, pass = peer[1], peer[2].to_i, peer[3], peer[4]
    tr = begin
      timeout(2) do
        type2class(type).new(host, port, user, pass).list
      end
    rescue TimeoutError, Errno::ECONNREFUSED
      dead_peers << peer
      nil
    end
    next if tr.nil?
    tr['arguments']['torrents'].each do |t|
      h = t['hashString']
      torrents[h] = { :name => t['name'], :peers => [] } unless torrents.key?(h)
      torrents[h][:peers] << [host, port].join(':')
    end
  end
  [torrents, dead_peers]
end

#sync_torrents(peers, torrents) ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/torrentsync.rb', line 192

def sync_torrents(peers, torrents)
  torrents.each do |hash, t|
    name = t[:name]
    hps = t[:peers]
    next if hps.size >= 2
    body = find_torrent(name)
    next if body.nil?
    hps = hps.map{|hp| host, port = hp.split(':'); [host, port.to_i]}
    dests = peers.select do |peer|
      hps.any?{|hp| peer[1] != hp[0] && peer[2] != hp[1]}
    end
    dest = dests.shuffle.first
    puts "mirroring: %s to %s" % [name, dest.join(',')]
    type = dest[0]
    host, port, user, pass = dest[1], dest[2].to_i, dest[3], dest[4]
    dest = type2class(type).new(host, port, user, pass)
    dest.add(body)
  end
end

#type2class(type) ⇒ Object



154
155
156
157
158
159
160
161
# File 'lib/torrentsync.rb', line 154

def type2class(type)
  case type
  when 'transmission'
    Transmission
  when 'utorrent'
    UTorrent
  end
end