1 from xml
.dom
import minidom
2 from zeroinstall
.injector
import namespaces
3 from zeroinstall
.zerostore
import manifest
, Stores
, NotStored
5 from logging
import info
10 id = impl
.getAttribute('id')
12 yield id.split('=', 1)
13 for x
in xmltools
.children(impl
, 'manifest-digest'):
14 for name
, value
in x
.attributes
.itemsNS():
18 def get_version(impl
):
20 v
= impl
.getAttribute('version')
22 impl
= impl
.parentNode
24 def add_digest(impl
, alg_name
):
25 alg
= manifest
.get_algorithm(alg_name
)
27 # Scan through the existing digests
28 # - If we've already got the one we need, return
29 # - Otherwise, find a cached implementation we can use
31 for a
, value
in digests(impl
):
32 digest
= '%s=%s' % (a
, value
)
34 return False # Already signed with this algorithm
37 existing_path
= stores
.lookup(digest
)
39 existing_digest
= digest
43 if existing_path
is None:
44 print "No implementations of %s cached; can't calculate new digest" % get_version(impl
)
47 info("Verifying %s", existing_path
)
48 manifest
.verify(existing_path
, existing_digest
)
50 print "Adding new digest to version %s" % get_version(impl
)
52 new_digest
= alg
.new_digest()
53 for line
in alg
.generate_manifest(existing_path
):
54 new_digest
.update(line
+ '\n')
56 for md
in xmltools
.children(impl
, 'manifest-digest'):
59 md
= xmltools
.create_element(impl
, 'manifest-digest')
60 md
.setAttribute(alg_name
, new_digest
.hexdigest())
64 def add_digests(data
, alg
= None):
65 doc
= minidom
.parseString(data
)
71 for impl
in doc
.documentElement
.getElementsByTagNameNS(namespaces
.XMLNS_IFACE
, 'implementation'):
72 if impl
.getAttribute('id') in "./":
73 continue # Local implementation
75 if add_digest(impl
, alg
):
79 return doc
.toxml('utf-8')