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.
- data/COPYING +340 -0
- data/README +21 -0
- data/ReleaseNotes.txt +25 -0
- data/doc/api.txt +289 -0
- data/doc/design.txt +59 -0
- data/dump-metainfo.rb +55 -0
- data/dump-peers.rb +45 -0
- data/lib/rubytorrent.rb +94 -0
- data/lib/rubytorrent/bencoding.rb +174 -0
- data/lib/rubytorrent/controller.rb +610 -0
- data/lib/rubytorrent/message.rb +128 -0
- data/lib/rubytorrent/metainfo.rb +214 -0
- data/lib/rubytorrent/package.rb +595 -0
- data/lib/rubytorrent/peer.rb +536 -0
- data/lib/rubytorrent/server.rb +166 -0
- data/lib/rubytorrent/tracker.rb +225 -0
- data/lib/rubytorrent/typedstruct.rb +132 -0
- data/lib/rubytorrent/util.rb +186 -0
- data/make-metainfo.rb +211 -0
- data/rtpeer-ncurses.rb +340 -0
- data/rtpeer.rb +125 -0
- metadata +78 -0
data/rtpeer.rb
ADDED
@@ -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
|
+
|