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 ) )))
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' )
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)
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 ]
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
def convert(self, value: Iterable[ValueT]) -> CollectionT: if iterable(value): return self._createValue(value) else: raise TypeError('value is not iterable')
def convert(self, value: Iterable[str]) -> Sequence[str]: if iterable(value): return tuple(value) else: raise TypeError('value is not iterable')