1 # -*- coding: utf-8 -*-
3 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
4 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
10 """ Processing context.
12 >>> ctx = Context(a=1)
13 >>> subctx = Context(ctx, a=2)
15 >>> print subctx.a, subctx.b
19 def __init__(self, _upctx=None, **initial):
20 object.__setattr__(self, '_upctx', _upctx)
21 object.__setattr__(self, '_data', initial or {})
23 def __getattr__(self, name):
24 if name in self._data:
25 return self._data[name]
26 elif self._upctx is not None:
27 return getattr(self._upctx, name)
29 raise AttributeError("'%s' object has no attribute '%s'" % (type(self), name))
31 def __setattr__(self, name, value):
33 self.try_setattr(name, value)
35 self._data[name] = value
37 def try_setattr(self, name, value):
38 if name in self._data:
39 self._data[name] = value
40 elif self._upctx is not None:
41 self._upctx.try_setattr(name, value)
46 class XMLNamespace(object):
47 """A handy structure to repsent names in an XML namespace."""
48 def __init__(self, uri):
51 def __call__(self, tag):
52 return '{%s}%s' % (self.uri, tag)
54 def __contains__(self, tag):
55 return tag.startswith('{' + str(self) + '}')
58 return 'XMLNamespace(%r)' % self.uri
61 return '%s' % self.uri
64 def extend_element(container, element=None, text=None):
65 """ Extends XML element with another one's contents.
67 Differs from etree.Element.extend by taking the text into account.
69 >>> from lxml import etree
70 >>> container = etree.fromstring("<A><B/></A>")
71 >>> element = etree.fromstring("<_>a<b/>c</_>")
72 >>> extend_element(container, element)
73 >>> print etree.tostring(container)
77 add_text = (text or "") + (element.text or "" if element is not None else "")
80 container[-1].tail = (container[-1].tail or "") + add_text
82 container.text = (container.text or "") + add_text
83 if element is not None:
84 container.extend(element)
87 def get_resource(path):
88 return os.path.join(os.path.dirname(__file__), path)