class Torrent
Sample usage
t = Torrent.new
(“your.tracker.com”) t.add_file(“path/to/file.foo”) t.write_torrent(“~/Downloads/mytorrent.torrent”)
Attributes
defaultdir[RW]
filehashes[RW]
files[RW]
info[RW]
infohash[R]
piecelength[RW]
privacy[RW]
size[RW]
torrent_file[R]
tracker[RW]
tracker_list[RW]
webseed[RW]
Public Class Methods
new(tracker)
click to toggle source
optionally initialize filename
# File lib/mktorrent.rb, line 16 def initialize(tracker) @tracker = tracker @piecelength = 512 * 1024 # 512 KB @files = [] @filehashes = [] @size = 0 @tracker_list = [ [@tracker] ] @defaultdir = "torrent" @privacy = 0 @webseed = "" @dirbase = "" build_the_torrent end
Public Instance Methods
add_directory(path)
click to toggle source
# File lib/mktorrent.rb, line 131 def add_directory(path) path = Pathname.new(path) @dirbase = File.dirname(path) unless path.relative? add_directory_to_torrent(path) end
add_directory_to_torrent(path)
click to toggle source
# File lib/mktorrent.rb, line 137 def add_directory_to_torrent(path) # Using Dir.entries instead of glob so that non-escaped paths can be used Dir.entries(path).each do |entry| # Ignore unix current and parent directories next if entry == '.' or entry == '..' filename = File.join(path, entry).gsub(@dirbase, '') # Add a relative path if File.directory?(filename) add_directory_to_torrent(filename) else add_file(filename) end end end
add_file(filepath)
click to toggle source
# File lib/mktorrent.rb, line 110 def add_file(filepath) path_for_torrent = path_for_torrent_from_file(filepath) if((@files.select { |f| f[:path] == path_for_torrent } ).count > 0) raise IOError, "Can't add duplicate file #{File.basename(filepath)}" end # Remove a leading slash if ( ! @dirbase.empty?) && filepath[0] == '/' filepath = filepath.slice(1, filepath.length) end if File.exist?(filepath) @files << { path: path_for_torrent, length: File::open(filepath, "rb").size } elsif @dirbase && File.exist?(File.join(@dirbase, filepath)) @files << { path: path_for_torrent, length: File::open(File.join(@dirbase, filepath), "rb").size } else raise IOError, "Couldn't access #{filepath}" end end
add_tracker(tracker)
click to toggle source
# File lib/mktorrent.rb, line 157 def add_tracker(tracker) @tracker_list << [tracker] end
all_files()
click to toggle source
# File lib/mktorrent.rb, line 30 def all_files if @files.any? @files.collect { |file| file[:path] } end end
build()
click to toggle source
# File lib/mktorrent.rb, line 73 def build @info = { :announce => @tracker, :'announce-list' => @tracker_list, :'creation date' => DateTime.now.strftime("%s"), :info => { :name => @defaultdir, :'piece length' => @piecelength, :files => @files, :private => @privacy, } } @info[:info][:pieces] = "" @info.merge!({ :'url-list' => @webseed }) unless @webseed.empty? if @files.count > 0 read_pieces(all_files, @piecelength) do |piece| @info[:info][:pieces] += Digest::SHA1.digest(piece) end end end
Also aliased as: build_the_torrent
count()
click to toggle source
# File lib/mktorrent.rb, line 36 def count @files.count end
path_for_reading_pieces(f)
click to toggle source
# File lib/mktorrent.rb, line 40 def path_for_reading_pieces(f) if @dirbase.empty? # it's a single file torrent f = File.join(File.join(f)) end f = File.join(@dirbase, f) unless @dirbase.empty? f end
read_pieces(files, length) { |buffer| ... }
click to toggle source
# File lib/mktorrent.rb, line 48 def read_pieces(files, length) buffer = "" files.each do |file| f = path_for_reading_pieces(file) next if File.directory?(f) File.open(f) do |fh| begin read = fh.read(length - buffer.length) # Make sure file not empty unless read.nil? if (buffer.length + read.length) == length yield(buffer + read) buffer = "" else buffer += read end end end until fh.eof? end end yield buffer end
set_private()
click to toggle source
# File lib/mktorrent.rb, line 161 def set_private @privacy = 1 end
set_public()
click to toggle source
# File lib/mktorrent.rb, line 165 def set_public @privacy = 0 end
set_webseed(url)
click to toggle source
# File lib/mktorrent.rb, line 152 def set_webseed(url) validate_url!(url) @webseed = url end
to_s()
click to toggle source
Return the .torrent file as a string
# File lib/mktorrent.rb, line 104 def to_s return "You must add at least one file." if(@files.count < 1) build_the_torrent unless (@info[:info][:files].count == @files.count) @info.bencode end
write_torrent(filename)
click to toggle source
# File lib/mktorrent.rb, line 94 def write_torrent(filename) build_the_torrent @torrent_file = File.absolute_path(filename) open(@torrent_file, 'wb') do |file| file.write self.to_s end set_infohash end
Private Instance Methods
path_for_torrent_from_file(filepath)
click to toggle source
# File lib/mktorrent.rb, line 179 def path_for_torrent_from_file(filepath) unless @dirbase.empty? filepath = filepath.sub(@dirbase, '') end # Remove leading blank item path_for_torrent = filepath.split('/') - [""] path_for_torrent end
set_infohash()
click to toggle source
# File lib/mktorrent.rb, line 190 def set_infohash @infohash = Digest::SHA1.hexdigest @info[:info].bencode end
validate_url!(url)
click to toggle source
# File lib/mktorrent.rb, line 172 def validate_url!(url) u = URI.parse(url) if u.scheme.nil? || u.host.nil? raise ArgumentError.new("#{url} is not a valid URL") end end