class Bencview::Torrent

Attributes

infohash[R]
input[R]

Public Class Methods

new(io) click to toggle source
# File bencview.rb, line 31
def initialize io
  @input = (BEncode::Parser.new io).parse!
  raise 'invalid input' unless @input
  @infohash = sha1
end

Public Instance Methods

any_to_s(obj) click to toggle source
# File bencview.rb, line 37
def any_to_s obj
  obj.kind_of?(Array) ? [obj.size, obj].join("\n ").strip : obj.to_s
end
bti(obj, prefix) click to toggle source

BitTorrent specific

# File bencview.rb, line 58
def bti obj, prefix
  return nil unless obj.kind_of?(Hash)

  rkey = -> key { "#{prefix}#{key}" }

  r = []
  obj.each do |key,val|
    key = key.to_s.strip
    if key == 'piece length'
      # ignore
    elsif key == 'pieces' && obj['piece length']
      pieces = val.bytesize / 20
      r.push "#{rkey.call 'pieces'}: #{num pieces} x #{num obj['piece length']}"
    elsif key =~ /\.utf-8$/
      # ignore
    elsif key =~ /^(files|length)$/
      # ignore, but see below `files_add`
    elsif key == 'profiles' && val.kind_of?(Array)
      val.each {|item| r.concat to_a item, "#{prefix}#{key}/" }
    else
      r.push "#{rkey.call key}: #{val}"
    end
  end

  files = []
  files_add = -> arr do
    bytes = 0
    max = 0
    arr.each do |file|
      bytes += file['length']
      max = file['length'] if max < file['length']
    end
    max = (num max).size + 1

    files.push "#{rkey.call 'files'}: #{arr.size}"
    arr.each do |file|
      files.push "%#{max}s %s" % [num(file['length']), file['path'].join('/')]
    end
    files.push "#{rkey.call '*files size'}: #{num bytes}"
  end

  if obj['files']
    files_add.call obj['files']
  elsif obj['length'] && obj['name']
    files_add.call [{'length' => obj['length'], 'path' => [obj['name']]}]
  end

  r.concat files
end
magnet(name) click to toggle source

BitTorrent specific

# File bencview.rb, line 52
def magnet name
  return nil unless @infohash
  "magnet:?xt=urn:btih:#{@infohash}" + (name ? "&dn=#{ERB::Util.url_encode name}" : "")
end
num(n) click to toggle source
# File bencview.rb, line 41
def num n
  n.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
end
sha1() click to toggle source

BitTorrent specific

# File bencview.rb, line 46
def sha1
  return nil unless @input['info'].kind_of?(Hash)
  Digest::SHA1.hexdigest @input['info'].bencode
end
to_a(obj=nil, prefix='') click to toggle source
# File bencview.rb, line 108
def to_a obj=nil, prefix=''
  obj = @input unless obj

  r = []
  info = nil

  rkey = -> key { "#{prefix}#{key}" }

  if @infohash && prefix == ''
    r.push "*info-hash: #{@infohash}"
    r.push "*uri: #{magnet @input.dig 'info', 'name'}"
  end

  obj.each do |key,val|
    key = key.to_s.strip
    if key == 'info'
      info = bti val, "#{prefix}info/"
    elsif val.kind_of? Hash
      r.concat to_a val, "#{prefix}#{key}/" # recursion
    elsif key =~ /date/
      r.push "#{rkey.call key}: #{DateTime.strptime(val.to_s, '%s').rfc2822}"
    elsif key =~ /-list$/
      r.push "#{rkey.call key}: #{any_to_s val}"
    else
      r.push "#{rkey.call key}: #{val}"
    end
  end

  r.concat info if info       # add the info section to the very end
  r
end
to_json() click to toggle source

walk through object, return a hash suitable for JSON.stringify

# File bencview.rb, line 145
def to_json
  Bencview.hash_walk(@input) do |str|
    begin
      str.to_json
    rescue
      next Base64.strict_encode64 str
    end
    str
  end.to_json
end
to_s(obj=nil, prefix='') click to toggle source
# File bencview.rb, line 140
def to_s obj=nil, prefix=''
  (to_a obj, prefix).join "\n"
end