]> git.ipfire.org Git - ipfire.org.git/blob - webapp/handlers_tracker.py
Move everything to the root of the repository.
[ipfire.org.git] / webapp / handlers_tracker.py
1 #!/usr/bin/python
2
3 import tornado.web
4
5 from backend.tracker import bencode, bdecode, decode_hex
6 from handlers_base import *
7
8
9 class TrackerIndexHandler(BaseHandler):
10 def get(self):
11 releases = self.releases.get_all()
12
13 limit = 5
14 releases = releases[:limit]
15
16 self.render("tracker-torrents.html", releases=releases)
17
18
19 class TrackerDetailHandler(BaseHandler):
20 def get(self, torrent_hash):
21 file = self.releases.get_file_for_torrent_hash(torrent_hash)
22
23 if not file:
24 raise tornado.web.HTTPError(404, "Could not find torrent file for hash: %s" % torrent_hash)
25
26 peers = self.tracker.get_peers(torrent_hash)
27 seeds = self.tracker.get_seeds(torrent_hash)
28
29 self.render("tracker-torrent-detail.html", release=file.release,
30 file=file, peers=peers, seeds=seeds)
31
32
33 class TrackerDownloadHandler(BaseHandler):
34 def get(self, torrent_hash):
35 file = self.releases.get_file_for_torrent_hash(torrent_hash)
36
37 if not file:
38 raise tornado.web.HTTPError(404, "Could not find torrent file for hash: %s" % torrent_hash)
39
40 # Redirect the user to the download redirector.
41 self.redirect("http://downloads.ipfire.org/%s.torrent" % file.filename)
42
43
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
66 class 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
93 class 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
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
107 peer = {
108 "id" : self.get_hexencoded_argument("peer_id"),
109 "ip" : ip_addr,
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
154 class 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()