Esempio n. 1
0
 def __getitem__(self: ContainerT, index: XMLContent) -> ContainerT:
     if iterable(index):
         newContents = cast(Iterable[XMLContent], index)
     else:
         newContents = (index,)
     return self._replaceContents(tuple(chain(
         self._contents, *(
             self._adaptContentElement(element)
             for element in newContents
             )
         )))
Esempio n. 2
0
 def _adaptContentElement(self, element: XMLContent
                          ) -> Iterator[XMLPresentable]:
     if option.sameTag(element):
         yield cast(XML, element)
     elif isinstance(element, (str, int, Enum)):
         yield option(value = element)[ element ]
     elif iterable(element):
         for child in cast(Iterable[XMLContent], element):
             yield from self._adaptContentElement(child)
     elif isinstance(element, type) and issubclass(element, Enum):
         for value in element.__members__.values():
             yield option(value = value)[ value ]
     elif hasattr(element, 'present'):
         yield cast(XMLPresentable, element)
     else:
         raise TypeError(
             f'Cannot adapt "{type(element).__name__}" to selection option'
             )
Esempio n. 3
0
def checkPrivilegeForOwned(
        user: User,
        priv: str,
        owned: Union[Owned, Iterable[Owned]],
        text: Union[None, str, Tuple[str, str]] = None) -> None:
    '''Checks whether a user is allowed to perform an action on an owned
    database record.
    @param owned Record or sequence of records to test for ownership.
    @param text String to display if the user is not allowed to perform
        the action, or a tuple of which the first element is the string to
        display if the user is not allowed to perform the action on this
        particular record and the second element is the string to display
        if the user is not allowed to perform the action on any record
        of this type.
    '''
    assert not priv.endswith('o'), priv
    if user.hasPrivilege(priv):
        # User is allowed to take action also for non-owned records.
        return
    ownedPriv = priv + 'o'
    hasOwnedPriv = ownedPriv in privileges and user.hasPrivilege(ownedPriv)
    if hasOwnedPriv:
        # User is allowed to perform action, but only for owned records.
        userName = user.name
        if iterable(owned):
            if all(rec.owner == userName
                   for rec in cast(Iterable[Owned], owned)):
                return
        else:
            if cast(Owned, owned).owner == userName:
                return
    # Construct error message.
    if isinstance(text, tuple):
        text = text[0 if hasOwnedPriv else 1]
    if text is None:
        raise AccessDenied()
    else:
        raise AccessDenied(text)
Esempio n. 4
0
    def present(self, **kwargs: Any) -> XMLContent:
        form: _FormPresenter = kwargs['form']
        formArgs: Optional[PageArgs] = kwargs['formArgs']
        attributes = self._attributes

        multiple = attributes.get('multiple', False)

        name = cast(Optional[str], attributes.get('name'))
        focus = form.addControl(name, not attributes.get('disabled', False))

        if name is not None:
            if multiple:
                form.addClearCode(
                    f'var options = inputs.{name}.options;',
                    'for (var i = 0; i < options.length; i++) {',
                    '\toptions[i].selected = false;',
                    '}'
                    )
            else:
                default = _argDefault(formArgs, name)
                if default not in (None, dynamic, mandatory):
                    if iterable(default):
                        # Multiple drop-down lists are combined to populate
                        # a single argument.
                        value: Optional[str] = ''
                    else:
                        value = option.adaptAttributeValue(cast(str, default))
                    form.addClearCode(
                        f'inputs.{name}.value = "{value}";'
                        )

        if 'selected' in attributes:
            attributes = dict(attributes)
            selected = attributes.pop('selected')
        elif name is None:
            selected = None
        else:
            selected = _argValue(formArgs, name)

        selectedSet = set()
        if selected is not None:
            if multiple:
                if not iterable(selected):
                    raise TypeError(
                        f'singular ({type(selected).__name__}) '
                        f'"selected" attribute for multi-select'
                        )
            else:
                selected = (selected, )
            for item in cast(Iterable[XMLAttributeValue], selected):
                itemStr = option.adaptAttributeValue(item)
                if itemStr is not None:
                    selectedSet.add(itemStr)

        optionsPresentation = []
        for content in self._presentContents(**kwargs):
            if option.sameTag(content):
                node = cast(XMLNode, content)
                if node.attrs.get('value') in selectedSet:
                    node = node(selected = True)
                optionsPresentation.append(node)
            else:
                raise ValueError(f'Expected <option>, got {content}')

        return xhtml.select(autofocus=focus, **attributes)[
            optionsPresentation
            ]
Esempio n. 5
0
 def joinStyles(styles: Iterable[str]) -> Optional[str]:
     '''Returns a single string containing all the given CSS styles separated
     by spaces, or None if there were no styles given.
     '''
     assert iterable(styles), type(styles)
     return ' '.join(styles) or None
Esempio n. 6
0
 def convert(self, value: Iterable[ValueT]) -> CollectionT:
     if iterable(value):
         return self._createValue(value)
     else:
         raise TypeError('value is not iterable')
Esempio n. 7
0
 def convert(self, value: Iterable[str]) -> Sequence[str]:
     if iterable(value):
         return tuple(value)
     else:
         raise TypeError('value is not iterable')