]> git.ipfire.org Git - people/shoehn/ipfire.org.git/blob - www/webapp/handlers_tracker.py
Add job that updates the file database from the main mirror.
[people/shoehn/ipfire.org.git] / www / 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 hashes = self.tracker.hashes
12
13 torrents = []
14 for release in self.releases.list():
15 if not release.torrent_hash:
16 continue
17
18 if release.torrent_hash in hashes:
19 torrents.append(tornado.database.Row({
20 "name" : release.name,
21 "hash" : release.torrent_hash.lower(),
22 "peers" : self.tracker.incomplete(release.torrent_hash),
23 "seeds" : self.tracker.complete(release.torrent_hash),
24 }))
25
26 self.render("tracker-torrents.html", torrents=torrents)
27
28
29 class TrackerDetailHandler(BaseHandler):
30 def get(self, hash):
31 release = None
32 for r in self.releases.list():
33 if not r.torrent_hash:
34 continue
35
36 if r.torrent_hash.lower() == hash.lower():
37 release = r
38 break
39
40 if not release:
41 raise tornado.web.HTTPError(404)
42
43 torrent = tornado.database.Row({
44 "peers" : self.tracker.get_peers(hash),
45 "seeds" : self.tracker.get_seeds(hash),
46 })
47
48 self.render("tracker-torrent-detail.html", release=release, torrent=torrent)
49
50
51 #class TrackerTorrentsHandler(BaseHandler):
52 # @property
53 # def tracker(self):
54 # return self.tracker
55 #
56 # def get(self):
57 # releases = []
58 #
59 # for release in self.releases.get_all():
60 # if not release.torrent_hash:
61 # continue
62 #
63 # release.torrent_hash = release.torrent_hash.lower()
64 #
65 # release.torrent_peers = self.tracker.incomplete(release.torrent_hash)
66 # release.torrent_seeds = self.tracker.complete(release.torrent_hash)
67 #
68 # releases.append(release)
69 #
70 # self.render("tracker-torrents.html", releases=releases)
71
72
73 class TrackerBaseHandler(tornado.web.RequestHandler):
74 @property
75 def tracker(self):
76 return backend.Tracker()
77
78 def get_hexencoded_argument(self, name, all=False):
79 try:
80 arguments = self.request.arguments[name]
81 except KeyError:
82 return None
83
84 arguments_new = []
85 for argument in arguments:
86 arguments_new.append(decode_hex(argument))
87
88 arguments = arguments_new
89
90 if all:
91 return arguments
92
93 return arguments[0]
94
95 def send_tracker_error(self, error_message):
96 self.write(bencode({"failure reason" : error_message }))
97 self.finish()
98
99
100 class TrackerAnnounceHandler(TrackerBaseHandler):
101 def get(self):
102 self.set_header("Content-Type", "text/plain")
103
104 info_hash = self.get_hexencoded_argument("info_hash")
105 if not info_hash:
106 self.send_tracker_error("Your client forgot to send your torrent's info_hash.")
107 return
108
109 peer = {
110 "id" : self.get_hexencoded_argument("peer_id"),
111 "ip" : self.request.remote_ip,
112 "port" : self.get_argument("port", None),
113 "downloaded" : self.get_argument("downloaded", 0),
114 "uploaded" : self.get_argument("uploaded", 0),
115 "left" : self.get_argument("left", 0),
116 }
117
118 event = self.get_argument("event", "")
119 if not event in ("started", "stopped", "completed", ""):
120 self.send_tracker_error("Got unknown event")
121 return
122
123 if peer["port"]:
124 peer["port"] = int(peer["port"])
125
126 if peer["port"] < 0 or peer["port"] > 65535:
127 self.send_tracker_error("Port number is not in valid range")
128 return
129
130 eventhandlers = {
131 "started" : self.tracker.event_started,
132 "stopped" : self.tracker.event_stopped,
133 "completed" : self.tracker.event_completed,
134 }
135
136 if event:
137 eventhandlers[event](info_hash, peer["id"])
138
139 self.tracker.update(hash=info_hash, **peer)
140
141 no_peer_id = self.get_argument("no_peer_id", False)
142 numwant = self.get_argument("numwant", self.tracker.numwant)
143
144 self.write(bencode({
145 "tracker id" : self.tracker.id,
146 "interval" : self.tracker.interval,
147 "min interval" : self.tracker.min_interval,
148 "peers" : self.tracker.get_peers(info_hash, limit=numwant,
149 random=True, no_peer_id=no_peer_id),
150 "complete" : self.tracker.complete(info_hash),
151 "incomplete" : self.tracker.incomplete(info_hash),
152 }))
153 self.finish()
154
155
156 class TrackerScrapeHandler(TrackerBaseHandler):
157 def get(self):
158 info_hashes = self.get_hexencoded_argument("info_hash", all=True)
159
160 self.write(bencode(self.tracker.scrape(hashes=info_hashes)))
161 self.finish()