Created
January 24, 2013 05:32
-
-
Save hannahherbig/4617916 to your computer and use it in GitHub Desktop.
a dead simple torrent tracker in ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'bencode' | |
require 'sinatra' | |
torrents = {} | |
get '/announce' do | |
compact = (params[:compact] || '1') == '1' | |
no_peer_id = params[:no_peer_id] == '1' | |
event = params[:event] || 'empty' | |
numwant = (request[:numwant] || 50).to_i | |
complete = params[:left].to_i == 0 | |
torrents[params[:info_hash]] ||= { peers: {}, snatches: 0 } | |
pcomplete = 0 | |
pincomplete = 0 | |
peerids = torrents[params[:info_hash]][:peers].keys.shuffle | |
peerlist = compact ? '' : [] | |
while numwant > 0 and not peerids.empty? | |
peerid = peerids.shift | |
peer = torrents[params[:info_hash]][:peers][peerid] | |
unless complete and peer[:complete] | |
if compact | |
peerlist << (peer[:ip].split('.').map(&:to_i) + [peer[:port]]).pack('CCCCS>') | |
else | |
peer = { | |
'ip' => peer[:ip], | |
'port' => peer[:port] | |
} | |
peer['peer id'] = peerid unless no_peer_id | |
end | |
numwant -= 1 | |
end | |
if peer[:complete] | |
pcomplete += 1 | |
else | |
pincomplete += 1 | |
end | |
end | |
torrents[params[:info_hash]][:peers][params[:peer_id]] = { | |
ip: params[:ip] || request.ip, | |
port: params[:port].to_i, | |
complete: complete | |
} | |
torrents[params[:info_hash]][:snatches] += 1 if event == 'complete' | |
puts "#{params[:info_hash].unpack('H*').first} #{pcomplete} #{pincomplete}" | |
{ | |
'interval' => 10, | |
'min interval' => 1, | |
'complete' => pcomplete, | |
'incomplete' => pincomplete, | |
'peers' => peerlist | |
}.bencode | |
end | |
get '/scrape' do | |
files = {} | |
(params[:info_hash] ? [params[:info_hash]] : torrents.keys).each do |info_hash| | |
t = torrents[info_hash] | |
files[info_hash] = { | |
complete: t[:peers].values.count { |p| p[:complete] }, | |
downloaded: t[:snatches], | |
incomplete: t[:peers].values.count { |p| not p[:complete] } | |
} | |
end | |
files.each do |i, t| | |
puts "#{i.unpack('H*').first} downloaded=#{t[:downloaded]} complete=#{t[:complete]} incomplete=#{t[:incomplete]}" | |
end | |
{ files: files }.bencode | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment