rubytorrent 0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,125 @@
1
+ ## rtpeer.rb -- RubyTorrent line-mode BitTorrent peer.
2
+ ## Copyright 2004 William Morgan.
3
+ ##
4
+ ## This file is part of RubyTorrent. RubyTorrent is free software;
5
+ ## you can redistribute it and/or modify it under the terms of version
6
+ ## 2 of the GNU General Public License as published by the Free
7
+ ## Software Foundation.
8
+ ##
9
+ ## RubyTorrent is distributed in the hope that it will be useful, but
10
+ ## WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ ## General Public License (in the file COPYING) for more details.
13
+
14
+ require "rubytorrent"
15
+
16
+ Thread.abort_on_exception = true # make debugging easier
17
+
18
+ def die(x); $stderr << "#{x}\n" && exit(-1); end
19
+ def syntax
20
+ %{
21
+ Syntax: rtpeer <.torrent filename or URL> [<destination file or directory>]
22
+
23
+ rtpeer is a very simple line-based BitTorrent peer. You can use it
24
+ to download .torrents or to seed them, but it's mainly good for debugging.
25
+ }
26
+ end
27
+
28
+ class Numeric
29
+ def k; (self.to_f / 1024.0); end
30
+ def f(format="0.0")
31
+ sprintf("%#{format.to_s}f", self)
32
+ end
33
+ end
34
+
35
+ proxy = ENV["http_proxy"]
36
+ torrent = ARGV.shift or die syntax
37
+ dest = ARGV.shift
38
+
39
+ puts "reading torrent..."
40
+ begin
41
+ mi = RubyTorrent::MetaInfo.from_location(torrent, proxy)
42
+ rescue RubyTorrent::MetaInfoFormatError, RubyTorrent::BEncodingError => e
43
+ die %{Error: can't parse metainfo file "#{torrent}"---maybe not a .torrent?}
44
+ rescue RubyTorrent::TypedStructError => e
45
+ $stderr << <<EOS
46
+ error parsing metainfo file, and it's likely something I should know about.
47
+ please email the torrent file to wmorgan-rubytorrent-bug@masanjin.net,
48
+ along with this backtrace: (this is RubyTorrent version #{RubyTorrent::VERSION})
49
+ EOS
50
+
51
+ raise e
52
+ rescue IOError, SystemCallError => e
53
+ die %{Error: can't read file "#{torrent}": #{e.message}}
54
+ end
55
+
56
+ unless dest.nil?
57
+ if FileTest.directory?(dest) && mi.info.single?
58
+ dest = File.join(dest, mi.info.name)
59
+ elsif FileTest.file?(dest) && mi.info.multiple?
60
+ die %{Error: .torrent contains multiple files, but "#{dest}" is a single file (must be a directory)}
61
+ end
62
+ end
63
+ print "checking file status: " ; $stdout.flush
64
+ package = RubyTorrent::Package.new(mi, dest) do |piece|
65
+ print(piece.complete? && piece.valid? ? "#" : ".")
66
+ $stdout.flush
67
+ end
68
+ puts " done"
69
+
70
+ puts "starting peer..."
71
+ bt = RubyTorrent::BitTorrent.new(mi, package, :http_proxy => proxy) #, :dlratelim => 20*1024, :ulratelim => 10*1024)
72
+
73
+ unless $DEBUG # these are duplicated by debugging information
74
+ bt.on_event(self, :trying_peer) { |s, p| puts "trying peer #{p}" }
75
+ bt.on_event(self, :forgetting_peer) { |s, p| puts "couldn't connect to peer #{p}" }
76
+ bt.on_event(self, :removed_peer) { |s, p| puts "disconnected from peer #{p}" }
77
+ end
78
+ bt.on_event(self, :added_peer) { |s, p| puts "connected to peer #{p}" }
79
+ bt.on_event(self, :received_block) { |s, b, peer| puts "<- got block #{b} from peer #{peer}, now #{package.pieces[b.pindex].percent_done.f}% done and #{package.pieces[b.pindex].percent_claimed.f}% claimed" }
80
+ bt.on_event(self, :sent_block) { |s, b, peer| puts "-> sent block #{b} to peer #{peer}" }
81
+ bt.on_event(self, :requested_block) { |s, b, peer| puts "-- requested block #{b} from #{peer}" }
82
+ bt.on_event(self, :have_piece) { |s, p| puts "***** got complete and valid piece #{p}" }
83
+ bt.on_event(self, :discarded_piece) { |s, p| puts "XXXXX checksum error on piece #{p}, discarded" }
84
+ bt.on_event(self, :tracker_connected) { |s, url| puts "[tracker] connected to tracker #{url}" }
85
+ bt.on_event(self, :tracker_lost) { |s, url| puts "[tracker] couldn't connect to tracker #{url}" }
86
+ bt.on_event(self, :complete) do
87
+ puts <<EOS
88
+ *********************
89
+ * download complete *
90
+ *********************
91
+ EOS
92
+ end
93
+
94
+ puts "listening on #{bt.ip} port #{bt.port}"
95
+
96
+ thread = nil
97
+ ## not sure if this works on windows, but it's just a nicety anyways.
98
+ Signal.trap("INT") do
99
+ Signal.trap("INT", "DEFAULT") # second ^C will really kill us
100
+ thread.kill unless thread.nil?
101
+ bt.shutdown_all
102
+ end unless $DEBUG
103
+
104
+ thread = Thread.new do
105
+ while true
106
+ puts "-" * 78
107
+ ps = bt.peer_info.sort_by { |h| h[:start_time] }.reverse
108
+ puts <<EOS
109
+ downloaded #{bt.dlamt.k.f}k @ #{bt.dlrate.k.f}kb/s, uploaded #{bt.ulamt.k.f}k @ #{bt.ulrate.k.f}kb/s
110
+ completed: #{bt.pieces_completed} / #{bt.num_pieces} pieces = #{bt.bytes_completed.k.f}kb / #{bt.total_bytes.k.f}kb = #{bt.percent_completed.f}%
111
+ tracker: #{bt.tracker || "not connected"}
112
+ connected to #{ps.length} / #{bt.num_possible_peers} possible peers:
113
+ EOS
114
+ ps.each do |p|
115
+ puts <<EOS
116
+ dl #{p[:dlamt].k.f(4.0)}kb @#{p[:dlrate].k.f(3.0)}kb/s, ul #{p[:ulamt].k.f(4.0)}kb @#{p[:ulrate].k.f(3.0)}kb/s, i: #{(p[:interested] ? 'y' : 'n')}/#{(p[:peer_interested] ? 'y' : 'n')} (#{p[:we_desire].f(4.0)}/#{p[:they_desire].f(4.0)}) c: #{(p[:choking] ? 'y' : 'n')}/#{(p[:peer_choking] ? 'y' : 'n')} p: #{p[:pending_send]}/#{p[:pending_recv]}#{(p[:snubbing] ? ', snub' : '')} #{p[:name]}
117
+ EOS
118
+ end
119
+ puts "-" * 78
120
+ sleep 30
121
+ end
122
+ end
123
+
124
+ thread.join
125
+ puts "done"
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubytorrent
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.3"
5
+ platform: ruby
6
+ authors:
7
+ - William Morgan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-01-12 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A Bittorrent library.
17
+ email: wmorgan-rubytorrent@masanjin.net
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - COPYING
24
+ - README
25
+ - doc/api.txt
26
+ - doc/design.txt
27
+ - ReleaseNotes.txt
28
+ files:
29
+ - ./rtpeer.rb
30
+ - ./rtpeer-ncurses.rb
31
+ - ./lib/rubytorrent.rb
32
+ - ./lib/rubytorrent/message.rb
33
+ - ./lib/rubytorrent/peer.rb
34
+ - ./lib/rubytorrent/metainfo.rb
35
+ - ./lib/rubytorrent/controller.rb
36
+ - ./lib/rubytorrent/util.rb
37
+ - ./lib/rubytorrent/package.rb
38
+ - ./lib/rubytorrent/tracker.rb
39
+ - ./lib/rubytorrent/typedstruct.rb
40
+ - ./lib/rubytorrent/bencoding.rb
41
+ - ./lib/rubytorrent/server.rb
42
+ - ./dump-peers.rb
43
+ - ./dump-metainfo.rb
44
+ - ./make-metainfo.rb
45
+ - COPYING
46
+ - README
47
+ - doc/api.txt
48
+ - doc/design.txt
49
+ - ReleaseNotes.txt
50
+ has_rdoc: true
51
+ homepage: http://rubytorrent.rubyforge.org
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --main
55
+ - README
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ requirements: []
71
+
72
+ rubyforge_project: rubytorrent
73
+ rubygems_version: 1.0.1
74
+ signing_key:
75
+ specification_version: 2
76
+ summary: A Bittorrent librar.y
77
+ test_files: []
78
+