Class: RubyTorrent::MetaInfo

Inherits:
Object
  • Object
show all
Defined in:
lib/rubytorrent/metainfo.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dict = nil) ⇒ MetaInfo

Returns a new instance of MetaInfo.

Raises:

  • (TypeError)


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/rubytorrent/metainfo.rb', line 133

def initialize(dict=nil)
  raise TypeError, "argument must be a Hash (maybe see MetaInfo.from_location)" unless dict.is_a? Hash
  @s = TypedStruct.new do |s|
    s.field :info => MetaInfoInfo, :announce => URI::HTTP,
            :announce_list => Array, :creation_date => Time,
            :comment => String, :created_by => String, :encoding => String
    s.label :announce_list => "announce-list", :creation_date => "creation date",
            :created_by => "created by"
    s.array :announce_list
    s.coerce :info => lambda { |x| MetaInfoInfo.new(x) },
             :creation_date => lambda { |x| Time.at(x) },
             :announce => lambda { |x| URI.parse(x) },
             :announce_list => lambda { |x| x.map { |y| y.map { |z| URI.parse(z) } } }
  end

  @dict = dict
  unless dict.nil?
    @s.parse dict
    check
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args) ⇒ Object



194
195
196
# File 'lib/rubytorrent/metainfo.rb', line 194

def method_missing(meth, *args)
  @s.send(meth, *args)
end

Class Method Details

.from_bstream(bs) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/rubytorrent/metainfo.rb', line 166

def self.from_bstream(bs)
  dict = nil
  bs.each do |e|
    if dict == nil
      dict = e
    else
      raise MetaInfoFormatError, "too many bencoded elements for metainfo file (just need one)"
    end
  end

  raise MetaInfoFormatError, "bencoded element must be a dictionary, got a #{dict.class}" unless dict.kind_of? ::Hash

  MetaInfo.new(dict)
end

.from_location(fn, http_proxy = ENV["http_proxy"]) ⇒ Object

either a filename or a URL



182
183
184
185
186
187
188
# File 'lib/rubytorrent/metainfo.rb', line 182

def self.from_location(fn, http_proxy=ENV["http_proxy"])
  if http_proxy # lame!
    open(fn, "rb", :proxy => http_proxy) { |f| from_bstream(BStream.new(f)) }
  else
    open(fn, "rb") { |f| from_bstream(BStream.new(f)) }
  end
end

.from_stream(s) ⇒ Object



190
191
192
# File 'lib/rubytorrent/metainfo.rb', line 190

def self.from_stream(s)
  from_bstream(BStream.new(s))
end

Instance Method Details

#checkObject



158
159
160
161
162
163
164
# File 'lib/rubytorrent/metainfo.rb', line 158

def check
  if @s.announce_list
    @s.announce_list.each do |tier|
      tier.each { |track| raise MetaInfoFormatError, "expecting HTTP URL in announce-list, got #{track} instead" unless track.is_a? URI::HTTP }
    end
  end
end

#multiple?Boolean

Returns:

  • (Boolean)


156
# File 'lib/rubytorrent/metainfo.rb', line 156

def multiple?; info.multiple?; end

#single?Boolean

Returns:

  • (Boolean)


155
# File 'lib/rubytorrent/metainfo.rb', line 155

def single?; info.single?; end

#to_bencodingObject



198
199
200
201
# File 'lib/rubytorrent/metainfo.rb', line 198

def to_bencoding
  check
  (@dict || @s).to_bencoding
end

#trackersObject



203
204
205
206
207
208
209
210
211
# File 'lib/rubytorrent/metainfo.rb', line 203

def trackers
  if announce_list && (announce_list.length > 0)
    announce_list.map do |tier|
      tier.extend(ArrayShuffle).shuffle
    end.flatten
  else
    [announce]
  end
end