]> git.ipfire.org Git - ipfire.org.git/blame - webapp/handlers_tracker.py
Move everything to the root of the repository.
[ipfire.org.git] / webapp / handlers_tracker.py
CommitLineData
940227cb
MT
1#!/usr/bin/python
2
3import tornado.web
4
5from backend.tracker import bencode, bdecode, decode_hex
6from handlers_base import *
7
8
9class TrackerIndexHandler(BaseHandler):
10 def get(self):
938d083d 11 releases = self.releases.get_all()
940227cb 12
938d083d
MT
13 limit = 5
14 releases = releases[:limit]
940227cb 15
938d083d 16 self.render("tracker-torrents.html", releases=releases)
940227cb
MT
17
18
19class TrackerDetailHandler(BaseHandler):
938d083d
MT
20 def get(self, torrent_hash):
21 file = self.releases.get_file_for_torrent_hash(torrent_hash)
940227cb 22
938d083d
MT
23 if not file:
24 raise tornado.web.HTTPError(404, "Could not find torrent file for hash: %s" % torrent_hash)
940227cb 25
938d083d
MT
26 peers = self.tracker.get_peers(torrent_hash)
27 seeds = self.tracker.get_seeds(torrent_hash)
940227cb 28
938d083d
MT
29 self.render("tracker-torrent-detail.html", release=file.release,
30 file=file, peers=peers, seeds=seeds)
940227cb
MT
31
32
fadcfd00
MT
33class TrackerDownloadHandler(BaseHandler):
34 def get(self, torrent_hash):
938d083d 35 file = self.releases.get_file_for_torrent_hash(torrent_hash)
fadcfd00
MT
36
37 if not file:
938d083d 38 raise tornado.web.HTTPError(404, "Could not find torrent file for hash: %s" % torrent_hash)
fadcfd00
MT
39
40 # Redirect the user to the download redirector.
938d083d 41 self.redirect("http://downloads.ipfire.org/%s.torrent" % file.filename)
fadcfd00
MT
42
43
940227cb
MT
44#class TrackerTorrentsHandler(BaseHandler):
45# @property
46# def tracker(self):
47# return self.tracker
48#
49# def get(self):
50# releases = []
51#
52# for release in self.releases.get_all():
53# if not release.torrent_hash:
54# continue
55#
56# release.torrent_hash = release.torrent_hash.lower()
57#
58# release.torrent_peers = self.tracker.incomplete(release.torrent_hash)
59# release.torrent_seeds = self.tracker.complete(release.torrent_hash)
60#
61# releases.append(release)
62#
63# self.render("tracker-torrents.html", releases=releases)
64
65
66class TrackerBaseHandler(tornado.web.RequestHandler):
67 @property
68 def tracker(self):
69 return backend.Tracker()
70
71 def get_hexencoded_argument(self, name, all=False):
72 try:
73 arguments = self.request.arguments[name]
74 except KeyError:
75 return None
76
77 arguments_new = []
78 for argument in arguments:
79 arguments_new.append(decode_hex(argument))
80
81 arguments = arguments_new
82
83 if all:
84 return arguments
85
86 return arguments[0]
87
88 def send_tracker_error(self, error_message):
89 self.write(bencode({"failure reason" : error_message }))
90 self.finish()
91
92
93class TrackerAnnounceHandler(TrackerBaseHandler):
94 def get(self):
95 self.set_header("Content-Type", "text/plain")
96
97 info_hash = self.get_hexencoded_argument("info_hash")
98 if not info_hash:
99 self.send_tracker_error("Your client forgot to send your torrent's info_hash.")
100 return
101
f611ae02
MT
102 # Fix for clients behind a proxy that sends "X-Forwarded-For".
103 ip_addr = self.request.remote_ip.split(", ")
104 if ip_addr:
105 ip_addr = ip_addr[-1]
106
940227cb
MT
107 peer = {
108 "id" : self.get_hexencoded_argument("peer_id"),
f611ae02 109 "ip" : ip_addr,
940227cb
MT
110 "port" : self.get_argument("port", None),
111 "downloaded" : self.get_argument("downloaded", 0),
112 "uploaded" : self.get_argument("uploaded", 0),
113 "left" : self.get_argument("left", 0),
114 }
115
116 event = self.get_argument("event", "")
117 if not event in ("started", "stopped", "completed", ""):
118 self.send_tracker_error("Got unknown event")
119 return
120
121 if peer["port"]:
122 peer["port"] = int(peer["port"])
123
124 if peer["port"] < 0 or peer["port"] > 65535:
125 self.send_tracker_error("Port number is not in valid range")
126 return
127
128 eventhandlers = {
129 "started" : self.tracker.event_started,
130 "stopped" : self.tracker.event_stopped,
131 "completed" : self.tracker.event_completed,
132 }
133
134 if event:
135 eventhandlers[event](info_hash, peer["id"])
136
137 self.tracker.update(hash=info_hash, **peer)
138
139 no_peer_id = self.get_argument("no_peer_id", False)
140 numwant = self.get_argument("numwant", self.tracker.numwant)
141
142 self.write(bencode({
143 "tracker id" : self.tracker.id,
144 "interval" : self.tracker.interval,
145 "min interval" : self.tracker.min_interval,
146 "peers" : self.tracker.get_peers(info_hash, limit=numwant,
147 random=True, no_peer_id=no_peer_id),
148 "complete" : self.tracker.complete(info_hash),
149 "incomplete" : self.tracker.incomplete(info_hash),
150 }))
151 self.finish()
152
153
154class TrackerScrapeHandler(TrackerBaseHandler):
155 def get(self):
156 info_hashes = self.get_hexencoded_argument("info_hash", all=True)
157
158 self.write(bencode(self.tracker.scrape(hashes=info_hashes)))
159 self.finish()