Class: RubyTorrent::Package
- Inherits:
-
Object
- Object
- RubyTorrent::Package
- Includes:
- EventSource
- Defined in:
- lib/rubytorrent/package.rb
Overview
finally, the Package. one Package per Controller so we don’t do any thread safety stuff in here.
Instance Attribute Summary collapse
-
#pieces ⇒ Object
readonly
Returns the value of attribute pieces.
-
#size ⇒ Object
readonly
Returns the value of attribute size.
Instance Method Summary collapse
- #bytes_completed ⇒ Object
- #complete? ⇒ Boolean
-
#initialize(metainfo, out = nil, validity_assumption = nil) ⇒ Package
constructor
A new instance of Package.
- #num_pieces ⇒ Object
- #percent_completed ⇒ Object
- #pieces_completed ⇒ Object
- #reopen_ro ⇒ Object
- #ro? ⇒ Boolean
- #to_s ⇒ Object
Methods included from EventSource
append_features, #on_event, #relay_event, #send_event, #unregister_events
Constructor Details
#initialize(metainfo, out = nil, validity_assumption = nil) ⇒ Package
Returns a new instance of Package.
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 |
# File 'lib/rubytorrent/package.rb', line 487 def initialize(, out=nil, validity_assumption=nil) info = .info created = false out ||= info.name case out when File raise ArgumentError, "'out' cannot be a File for a multi-file .torrent" if info.multiple? fstream = out when Dir raise ArgumentError, "'out' cannot be a Dir for a single-file .torrent" if info.single? fstream = out when String if info.single? rt_debug "output file is #{out}" begin fstream = File.open(out, "rb+") rescue Errno::ENOENT created = true fstream = File.open(out, "wb+") end else rt_debug "output directory is #{out}" unless File.exists? out Dir.mkdir(out) created = true end fstream = Dir.open(out) end else raise ArgumentError, "'out' should be a File, Dir or String object, is #{out.class}" end @ro = false @size = info.total_length if info.single? @files = [[fstream, Mutex.new, info.length]] else @files = info.files.map do |finfo| path = File.join(finfo.path[0, finfo.path.length - 1].inject(fstream.path) do |path, el| dir = File.join(path, el) unless File.exist? dir rt_debug "making directory #{dir}" Dir.mkdir dir end dir end, finfo.path[finfo.path.length - 1]) rt_debug "opening #{path}..." [open_file(path), Mutex.new, finfo.length] end end i = 0 @pieces = info.pieces.unpack("a20" * (info.pieces.length / 20)).map do |hash| start = (info.piece_length * i) len = [info.piece_length, @size - start].min p = Piece.new(i, hash, start, len, @files, (created ? false : validity_assumption)) p.on_event(self, :complete) { send_event(:complete) if complete? } yield p if block_given? (i += 1) && p end reopen_ro if complete? end |
Instance Attribute Details
#pieces ⇒ Object (readonly)
Returns the value of attribute pieces.
484 485 486 |
# File 'lib/rubytorrent/package.rb', line 484 def pieces @pieces end |
#size ⇒ Object (readonly)
Returns the value of attribute size.
484 485 486 |
# File 'lib/rubytorrent/package.rb', line 484 def size @size end |
Instance Method Details
#bytes_completed ⇒ Object
566 567 568 |
# File 'lib/rubytorrent/package.rb', line 566 def bytes_completed @pieces.inject(0) { |s, p| s + (p.complete? ? p.length : 0) } end |
#complete? ⇒ Boolean
564 |
# File 'lib/rubytorrent/package.rb', line 564 def complete?; @pieces.detect { |p| !p.complete? || !p.valid? } == nil; end |
#num_pieces ⇒ Object
578 |
# File 'lib/rubytorrent/package.rb', line 578 def num_pieces; @pieces.length; end |
#percent_completed ⇒ Object
574 575 576 |
# File 'lib/rubytorrent/package.rb', line 574 def percent_completed 100.0 * pieces_completed.to_f / @pieces.length.to_f end |
#pieces_completed ⇒ Object
570 571 572 |
# File 'lib/rubytorrent/package.rb', line 570 def pieces_completed @pieces.inject(0) { |s, p| s + (p.complete? ? 1 : 0) } end |
#reopen_ro ⇒ Object
553 554 555 556 557 558 559 560 561 562 |
# File 'lib/rubytorrent/package.rb', line 553 def reopen_ro raise "called on incomplete package" unless complete? return if @ro rt_debug "reopening all files with mode r" @files = @files.map do |fp, mutex, size| [fp.reopen(fp.path, "rb"), mutex, size] end @ro = true end |
#ro? ⇒ Boolean
552 |
# File 'lib/rubytorrent/package.rb', line 552 def ro?; @ro; end |
#to_s ⇒ Object
580 581 582 |
# File 'lib/rubytorrent/package.rb', line 580 def to_s "<#{self.class} size #@size>" end |