class TrackerBaseHandler(tornado.web.RequestHandler):
- def get_hexencoded_argument(self, name):
+ def get_hexencoded_argument(self, name, all=False):
try:
- info_hash = self.request.arguments[name][0]
+ arguments = self.request.arguments[name]
except KeyError:
return None
- return decode_hex(info_hash)
+ arguments_new = []
+ for argument in arguments:
+ arguments_new.append(decode_hex(argument))
+
+ arguments = arguments_new
+
+ if all:
+ return arguments
+
+ return arguments[0]
def send_tracker_error(self, error_message):
self.write(bencode({"failure reason" : error_message }))
self.send_tracker_error("Your client forgot to send your torrent's info_hash.")
return
- compact = self.get_argument("compact", "0")
peer = {
"id" : self.get_hexencoded_argument("peer_id"),
"ip" : self.get_argument("ip", None),
tracker.update(hash=info_hash, **peer)
+ no_peer_id = self.get_argument("no_peer_id", False)
numwant = self.get_argument("numwant", tracker.numwant)
self.write(bencode({
"tracker id" : tracker.id,
"interval" : tracker.interval,
"min interval" : tracker.min_interval,
- "peers" : tracker.get_peers(info_hash, limit=numwant, random=True),
+ "peers" : tracker.get_peers(info_hash, limit=numwant,
+ random=True, no_peer_id=no_peer_id),
"complete" : tracker.complete(info_hash),
"incomplete" : tracker.incomplete(info_hash),
}))
self.finish()
+
+
+class TrackerScrapeHandler(TrackerBaseHandler):
+ def get(self):
+ info_hashes = self.get_hexencoded_argument("info_hash", all=True)
+
+ self.write(bencode(tracker.scrape(hashes=info_hashes)))
+ self.finish()
user="tracker",
)
- def _fetch(self, hash, limit=None, random=False, completed=False):
+ def _fetch(self, hash, limit=None, random=False, completed=False, no_peer_id=False):
query = "SELECT * FROM peers WHERE last_update >= %d" % self.since
if hash:
if not peer.ip or not peer.port:
continue
- peers.append({
- "peer id" : str(peer.id),
+ peer_dict = {
"ip" : str(peer.ip),
"port" : int(peer.port),
- })
+ }
+
+ if not no_peer_id:
+ peer_dict["peer id"] = str(peer.id),
+
+ peers.append(peer_dict)
return peers
def event_completed(self, hash, peer_id):
self.db.execute("UPDATE hashes SET completed=completed+1 WHERE hash = '%s'" % hash)
+ def scrape(self, hashes=[]):
+ ret = {}
+ for hash in self.db.query("SELECT hash, completed FROM hashes"):
+ hash, completed = hash.hash, hash.completed
+
+ if hashes and hash not in hashes:
+ continue
+
+ ret[hash] = {
+ "complete" : self.complete(hash),
+ "downloaded" : completed or 0,
+ "incomplete" : self.incomplete(hash),
+ }
+
+ return ret
+
def update(self, hash, id, ip=None, port=None, downloaded=None, uploaded=None, left=None):
args = [ "last_update = '%s'" % self.now ]