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 local_file
= os
.path
.abspath(os
.path
.basename(url
))
16 if not os
.path
.exists(local_file
):
17 raise Exception("Use --archive-file option to specify a local copy of the archive "
18 "(default file '%s' does not exist)" % local_file
)
20 doc
= minidom
.parseString(data
)
22 if local_file
.endswith('.deb'):
23 # Debs require 0launch >= 0.20 anyway, so use the new hash to avoid
24 # problems with directory mtimes
29 all_impls
= doc
.documentElement
.getElementsByTagNameNS(namespaces
.XMLNS_IFACE
, 'implementation')
30 tmpdir
= tempfile
.mkdtemp('-0publish')
32 unpack
.unpack_archive(url
, file(local_file
), tmpdir
, extract
)
34 extracted
= os
.path
.join(tmpdir
, extract
)
38 archive_id
= manifest_for_dir(extracted
, alg
)
43 for impl
in all_impls
:
44 this_id
= impl
.getAttribute('id')
45 if this_id
== archive_id
:
47 if this_id
.startswith('/') or this_id
.startswith('.'):
48 local_ifaces
.append(impl
)
50 if len(local_ifaces
) == 0:
51 raise Exception('Nothing with id "%s", and no local implementations' % archive_id
)
52 if len(local_ifaces
) > 1:
53 raise Exception('Nothing with id "%s", and multiple local implementations!' % archive_id
)
54 impl
= local_ifaces
[0]
55 impl
.setAttribute('id', archive_id
)
57 assert impl
.getAttribute('id') == archive_id
59 nl
= doc
.createTextNode('\n ')
62 archive
= doc
.createElementNS(namespaces
.XMLNS_IFACE
, 'archive')
63 impl
.appendChild(archive
)
64 archive
.setAttribute('href', url
)
65 archive
.setAttribute('size', str(os
.stat(local_file
).st_size
))
66 if extract
is not None:
67 archive
.setAttribute('extract', extract
)
69 nl
= doc
.createTextNode('\n ')