Moved non-gui parts to their own dir.
[zeroinstall.git] / injector / reader.py
blobed7606651d796e0765f193974e86c5c91254ed81
1 from xml.dom import Node, minidom
3 import basedir
4 from namespaces import *
5 from model import *
7 def get_singleton_text(parent, ns, localName):
8 names = parent.getElementsByTagNameNS(ns, localName)
9 if not names:
10 raise Exception('No <%s> element in <%s>' % (localName, parent.localName))
11 if len(names) > 1:
12 raise Exception('Multiple <%s> elements in <%s>' % (localName, parent.localName))
13 text = ''
14 for x in names[0].childNodes:
15 if x.nodeType == Node.TEXT_NODE:
16 text += x.data
17 return text.strip()
19 class Attrs(object):
20 __slots__ = ['version', 'arch', 'path', 'stability']
21 def __init__(self, stability, version = None, arch = None, path = None):
22 self.version = version
23 self.arch = arch
24 self.path = path
25 self.stability = stability
27 def merge(self, item):
28 new = Attrs(self.stability, self.version, self.arch, self.path)
30 if item.hasAttribute('path'):
31 new.path = os.path.join(self.path, item.getAttribute('path'))
32 for x in ('arch', 'stability', 'version'):
33 if item.hasAttribute(x):
34 setattr(new, x, item.getAttribute(x))
35 return new
37 def process_depends(dependency, item):
38 for e in item.getElementsByTagNameNS(XMLNS_IFACE, 'environment'):
39 binding = EnvironmentBinding(e.getAttribute('name'),
40 insert = e.getAttribute('insert'))
41 dependency.bindings.append(binding)
43 def update_from_cache(interface):
44 cached = basedir.load_first_config(config_site, config_prog,
45 'interfaces', escape(interface.uri))
46 if cached:
47 update(interface, cached, trusted = True)
48 interface.uptodate = True
50 def update_from_network(interface):
51 if not interface.uptodate:
52 update_from_cache(interface)
53 assert interface.uptodate
54 update(interface, interface.uri)
55 import writer
56 writer.save_interface(interface)
58 def update(interface, source, trusted = False):
59 assert isinstance(interface, Interface)
61 doc = minidom.parse(source)
63 root = doc.documentElement
64 interface.name = get_singleton_text(root, XMLNS_IFACE, 'name')
65 interface.description = get_singleton_text(root, XMLNS_IFACE, 'description')
66 interface.summary = get_singleton_text(root, XMLNS_IFACE, 'summary')
68 if trusted:
69 stability_policy = root.getAttribute('stability_policy')
70 if stability_policy:
71 interface.set_stability_policy(stability_levels[str(stability_policy)])
73 def process_group(group, group_attrs, base_depends):
74 for item in group.childNodes:
75 depends = base_depends.copy()
76 if item.namespaceURI != XMLNS_IFACE:
77 continue
79 item_attrs = group_attrs.merge(item)
81 for dep_elem in item.getElementsByTagNameNS(XMLNS_IFACE, 'requires'):
82 dep = Dependency(dep_elem.getAttribute('interface'))
83 process_depends(dep, dep_elem)
84 depends[dep.interface] = dep
86 if item.localName == 'group':
87 process_group(item, item_attrs, depends)
88 elif item.localName == 'implementation':
89 impl = interface.get_impl(item_attrs.path)
90 impl.version = map(int, item_attrs.version.split('.'))
91 size = item.getAttribute('size')
92 if size:
93 impl.size = long(size)
94 impl.arch = item_attrs.arch
95 try:
96 stability = stability_levels[str(item_attrs.stability)]
97 except KeyError:
98 raise Exception('Stability "%s" invalid' % item_attrs.stability)
99 if stability >= preferred:
100 raise Exception("Upstream can't set stability to preferred!")
101 impl.upstream_stability = stability
102 if trusted:
103 user_stability = item.getAttribute('user_stability')
104 if user_stability:
105 impl.user_stability = stability_levels[str(user_stability)]
106 impl.dependencies.update(depends)
108 process_group(root, Attrs(testing), {})