Added preferred as a user-selectable stability level. Always comes first.
[zeroinstall.git] / iface_reader.py
blob7fa6e5bb1b46667a4172bac751890e7c1ba9b6df
1 from xml.dom import Node, minidom
3 from namespaces import XMLNS_IFACE
4 from model import *
6 def get_singleton_text(parent, ns, localName):
7 names = parent.getElementsByTagNameNS(ns, localName)
8 if not names:
9 raise Exception('No <%s> element in <%s>' % (localName, parent.localName))
10 if len(names) > 1:
11 raise Exception('Multiple <%s> elements in <%s>' % (localName, parent.localName))
12 text = ''
13 for x in names[0].childNodes:
14 if x.nodeType == Node.TEXT_NODE:
15 text += x.data
16 return text.strip()
18 class Attrs(object):
19 __slots__ = ['version', 'arch', 'path', 'stability']
20 def __init__(self, stability, version = None, arch = None, path = None):
21 self.version = version
22 self.arch = arch
23 self.path = path
24 self.stability = stability
26 def merge(self, item):
27 new = Attrs(self.stability, self.version, self.arch, self.path)
29 if item.hasAttribute('path'):
30 new.path = os.path.join(self.path, item.getAttribute('path'))
31 for x in ('arch', 'stability', 'version'):
32 if item.hasAttribute(x):
33 setattr(new, x, item.getAttribute(x))
34 return new
36 def process_depends(dependency, item):
37 for e in item.getElementsByTagNameNS(XMLNS_IFACE, 'environment'):
38 binding = EnvironmentBinding(e.getAttribute('name'),
39 insert = e.getAttribute('insert'))
40 dependency.bindings.append(binding)
42 def update(interface):
43 assert isinstance(interface, Interface)
45 doc = minidom.parse(interface.uri)
47 root = doc.documentElement
48 interface.name = get_singleton_text(root, XMLNS_IFACE, 'name')
49 interface.description = get_singleton_text(root, XMLNS_IFACE, 'description')
50 interface.summary = get_singleton_text(root, XMLNS_IFACE, 'summary')
52 def process_group(group, group_attrs, base_depends):
53 for item in group.childNodes:
54 depends = base_depends.copy()
55 if item.namespaceURI != XMLNS_IFACE:
56 continue
58 item_attrs = group_attrs.merge(item)
60 for dep_elem in item.getElementsByTagNameNS(XMLNS_IFACE, 'requires'):
61 dep = Dependency(dep_elem.getAttribute('interface'))
62 process_depends(dep, dep_elem)
63 depends[dep.interface] = dep
65 if item.localName == 'group':
66 process_group(item, item_attrs, depends)
67 elif item.localName == 'implementation':
68 impl = interface.get_impl(item_attrs.path)
69 impl.version = map(int, item_attrs.version.split('.'))
70 size = item.getAttribute('size')
71 if size:
72 impl.size = long(size)
73 impl.arch = item_attrs.arch
74 try:
75 stability = stability_levels[str(item_attrs.stability)]
76 except KeyError:
77 raise Exception('Stability "%s" invalid' % item_attrs.stability)
78 assert stability < preferred
79 impl.upstream_stability = stability
80 impl.dependencies.update(depends)
82 process_group(root, Attrs(testing), {})
83 interface.uptodate = True