1 from xml
.dom
import minidom
2 from zeroinstall
.zerostore
import Store
, manifest
, unpack
3 from zeroinstall
.injector
import namespaces
4 import os
, time
, re
, shutil
, tempfile
, sha
6 def manifest_for_dir(dir, alg
):
7 algorithm
= manifest
.get_algorithm(alg
)
8 digest
= algorithm
.new_digest()
9 for line
in algorithm
.generate_manifest(dir):
10 digest
.update(line
+ '\n')
11 return algorithm
.getID(digest
)
13 def add_archive(data
, url
, local_file
, extract
):
14 if local_file
is None:
15 raise Exception('Use --archive-file option to specify a local copy')
17 doc
= minidom
.parseString(data
)
19 if local_file
.endswith('.deb'):
20 # Debs require 0launch >= 0.20 anyway, so use the new hash to avoid
21 # problems with directory mtimes
26 all_impls
= doc
.documentElement
.getElementsByTagNameNS(namespaces
.XMLNS_IFACE
, 'implementation')
27 tmpdir
= tempfile
.mkdtemp('-0publish')
29 unpack
.unpack_archive(url
, file(local_file
), tmpdir
, extract
)
31 extracted
= os
.path
.join(tmpdir
, extract
)
35 archive_id
= manifest_for_dir(extracted
, alg
)
40 for impl
in all_impls
:
41 this_id
= impl
.getAttribute('id')
42 if this_id
== archive_id
:
44 if this_id
.startswith('/') or this_id
.startswith('.'):
45 local_ifaces
.append(impl
)
47 if len(local_ifaces
) == 0:
48 raise Exception('Nothing with id "%s", and no local implementations' % archive_id
)
49 if len(local_ifaces
) > 1:
50 raise Exception('Nothing with id "%s", and multiple local implementations!' % archive_id
)
51 impl
= local_ifaces
[0]
52 impl
.setAttribute('id', archive_id
)
54 assert impl
.getAttribute('id') == archive_id
56 nl
= doc
.createTextNode('\n ')
59 archive
= doc
.createElementNS(namespaces
.XMLNS_IFACE
, 'archive')
60 impl
.appendChild(archive
)
61 archive
.setAttribute('href', url
)
62 archive
.setAttribute('size', str(os
.stat(local_file
).st_size
))
63 if extract
is not None:
64 archive
.setAttribute('extract', extract
)
66 nl
= doc
.createTextNode('\n ')