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)