Unhexify the returned hashes from the AptPackages lookup.
[quix0rs-apt-p2p.git] / apt_dht / apt_dht.py
1
2 from binascii import a2b_hex
3
4 from twisted.internet import defer
5 from twisted.web2 import server, http, http_headers
6 from twisted.python import log
7
8 from apt_dht_conf import config
9 from PeerManager import PeerManager
10 from HTTPServer import TopLevel
11 from MirrorManager import MirrorManager
12
13 class AptDHT:
14     def __init__(self, dht):
15         log.msg('Initializing the main apt_dht application')
16         self.dht = dht
17         self.http_server = TopLevel(config.get('DEFAULT', 'cache_dir'), self)
18         self.http_site = server.Site(self.http_server)
19         self.peers = PeerManager()
20         self.mirrors = MirrorManager(config.get('DEFAULT', 'cache_dir'))
21     
22     def getSite(self):
23         return self.http_site
24     
25     def check_freshness(self, path, modtime, resp):
26         log.msg('Checking if %s is still fresh' % path)
27         d = self.peers.get([path], "HEAD", modtime)
28         d.addCallback(self.check_freshness_done, path, resp)
29         return d
30     
31     def check_freshness_done(self, resp, path, orig_resp):
32         if resp.code == 304:
33             log.msg('Still fresh, returning: %s' % path)
34             return orig_resp
35         else:
36             log.msg('Stale, need to redownload: %s' % path)
37             return self.get_resp(path)
38     
39     def get_resp(self, path):
40         d = defer.Deferred()
41         
42         log.msg('Trying to find hash for %s' % path)
43         findDefer = self.mirrors.findHash(path)
44         
45         findDefer.addCallback(self.findHash_done, path, d)
46         findDefer.addErrback(self.findHash_error, path, d)
47         return d
48     
49     def findHash_error(self, failure, path, d):
50         log.err(failure)
51         self.findHash_done((None, None), path, d)
52         
53     def findHash_done(self, (hash, size), path, d):
54         if hash is None:
55             log.msg('Hash for %s was not found' % path)
56             self.download_file([path], hash, size, path, d)
57         else:
58             log.msg('Found hash %s for %s' % (hash, path))
59             # Lookup hash from DHT
60             lookupDefer = self.dht.getValue(a2b_hex(hash))
61             lookupDefer.addCallback(self.lookupHash_done, hash, size, path, d)
62             
63     def lookupHash_done(self, locations, hash, size, path, d):
64         if not locations:
65             log.msg('Peers for %s were not found' % path)
66             self.download_file([path], hash, size, path, d)
67         else:
68             log.msg('Found peers for $s: %r' % (path, locations))
69             # Download from the found peers
70             self.download_file(locations, hash, size, path, d)
71             
72     def download_file(self, locations, hash, size, path, d):
73         getDefer = self.peers.get(locations)
74         getDefer.addCallback(self.mirrors.save_file, hash, size, path)
75         getDefer.addErrback(self.mirrors.save_error, path)
76         getDefer.addCallbacks(d.callback, d.errback)