]> git.ipfire.org Git - ipfire.org.git/commitdiff
tracker: Add scrape functionality.
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 1 Apr 2010 22:47:11 +0000 (00:47 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 23 Apr 2010 23:15:13 +0000 (01:15 +0200)
www/webapp/__init__.py
www/webapp/handlers.py
www/webapp/torrent.py

index b40c84fc296554c3425158f39285ab8926a2447c..98e60883fbfd927cdad6f449f69f5e903cf684a7 100644 (file)
@@ -102,6 +102,7 @@ class Application(tornado.web.Application):
                        (r"/[A-Za-z]{2}/?", MainHandler),
                        (r"/[A-Za-z]{2}/index", DownloadTorrentHandler),
                        (r"/a.*", TrackerAnnounceHandler),
+                       (r"/scrape", TrackerScrapeHandler),
                ] + static_handlers)
 
                # ipfire.org
index c93fe9a97b17727b51c5f56137d9f4530940a942..53d47ede8c128c737ab53abc8d31f9977a96c2a3 100644 (file)
@@ -312,13 +312,22 @@ class RSSHandler(BaseHandler):
 
 
 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 }))
@@ -333,7 +342,6 @@ class TrackerAnnounceHandler(TrackerBaseHandler):
                        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),
@@ -372,14 +380,24 @@ class TrackerAnnounceHandler(TrackerBaseHandler):
 
                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()
index 5beeb67bbc18bad7bf31d0de94ef803a7c6ad55e..b005dc74897b16bad9cfcf5429d90c04b214ec43 100644 (file)
@@ -32,7 +32,7 @@ class Tracker(object):
                        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:
@@ -52,11 +52,15 @@ class Tracker(object):
                        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
 
@@ -87,6 +91,22 @@ class Tracker(object):
        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 ]