2 from binascii import b2a_hex
4 from twisted.internet import defer
5 from twisted.web2 import server, http, http_headers
6 from twisted.python import log
8 from apt_dht_conf import config
9 from PeerManager import PeerManager
10 from HTTPServer import TopLevel
11 from MirrorManager import MirrorManager
12 from Hash import HashObject
15 def __init__(self, dht):
16 log.msg('Initializing the main apt_dht application')
18 self.http_server = TopLevel(config.get('DEFAULT', 'cache_dir'), self)
19 self.http_site = server.Site(self.http_server)
20 self.peers = PeerManager()
21 self.mirrors = MirrorManager(config.get('DEFAULT', 'cache_dir'))
26 def check_freshness(self, path, modtime, resp):
27 log.msg('Checking if %s is still fresh' % path)
28 d = self.peers.get([path], "HEAD", modtime)
29 d.addCallback(self.check_freshness_done, path, resp)
32 def check_freshness_done(self, resp, path, orig_resp):
34 log.msg('Still fresh, returning: %s' % path)
37 log.msg('Stale, need to redownload: %s' % path)
38 return self.get_resp(path)
40 def get_resp(self, path):
43 log.msg('Trying to find hash for %s' % path)
44 findDefer = self.mirrors.findHash(path)
46 findDefer.addCallbacks(self.findHash_done, self.findHash_error,
47 callbackArgs=(path, d), errbackArgs=(path, d))
48 findDefer.addErrback(log.err)
51 def findHash_error(self, failure, path, d):
53 self.findHash_done(HashObject(), path, d)
55 def findHash_done(self, hash, path, d):
56 if hash.expected() is None:
57 log.msg('Hash for %s was not found' % path)
58 self.download_file([path], hash, path, d)
60 log.msg('Found hash %s for %s' % (hash.hexexpected(), path))
61 # Lookup hash from DHT
62 key = hash.normexpected(bits = config.getint(config.get('DEFAULT', 'DHT'), 'HASH_LENGTH'))
63 lookupDefer = self.dht.getValue(key)
64 lookupDefer.addCallback(self.lookupHash_done, hash, path, d)
66 def lookupHash_done(self, locations, hash, path, d):
68 log.msg('Peers for %s were not found' % path)
69 self.download_file([path], hash, path, d)
71 log.msg('Found peers for %s: %r' % (path, locations))
72 # Download from the found peers
73 self.download_file(locations, hash, path, d)
75 def download_file(self, locations, hash, path, d):
76 getDefer = self.peers.get(locations)
77 getDefer.addCallback(self.mirrors.save_file, hash, path)
78 getDefer.addErrback(self.mirrors.save_error, path)
79 getDefer.addCallbacks(d.callback, d.errback)