# Functions not dependent on advlabdb from flask import flash, url_for from markupsafe import Markup, escape def flashRandomPassword(email: str, password: str): flash(f"New random password for email {email}: {password}", category="warning") def parse_bool(str): str_lower = str.lower() if str_lower == "false": return False elif str_lower == "true": return True else: raise ValueError(f'Can not parse a bool from "{str}"') def deep_getattr(object, composed_name): names = composed_name.split(".") attr = getattr(object, names[0]) for name in names[1:]: attr = getattr(attr, name) return attr def missing_formatter(view, context, model, name): attr = deep_getattr(model, name) if attr is None: return Markup("MISSING") return attr def str_without_semester_formatter(view, context, model, name): attr = deep_getattr(model, name) if attr is not None: return attr.str_without_semester() return attr def str_formatter(view, context, model, name): attr = deep_getattr(model, name) if attr is not None: return attr.str() return attr def _details_link(url, attr, attr_formatter): return f"{escape(attr_formatter(attr))}" def _default_attr_formatter(attr): return attr def link_formatter(model, name, endpoint, attr_formatter=_default_attr_formatter): attr = deep_getattr(model, name) if attr is None: return "" url = url_for(f"{endpoint}.details_view") if hasattr(attr, "__iter__") and not isinstance(attr, str): # List of attributes links = (_details_link(url, a, attr_formatter) for a in attr) return Markup(", ".join(links)) # Single attribute return Markup(_details_link(url, attr, attr_formatter)) def link_formatter_factory(endpoint, attr_formatter=_default_attr_formatter): def formatter(view, context, model, name): return link_formatter(model, name, endpoint, attr_formatter) return formatter def email_formatter(view, context, model, name): attr = deep_getattr(model, name) if attr is None: return "" return Markup(f"{escape(attr)}")