Source code for bootlace.forms.fields

import enum
import mimetypes
from typing import Any
from typing import Generic
from typing import TypeVar

from werkzeug.http import parse_options_header
from wtforms import fields
from wtforms.validators import Regexp
from wtforms.validators import ValidationError


__all__ = ["EnumField", "MarkdownField", "KnownMIMEType", "SLUG_VALIDATOR"]


SLUG_VALIDATOR = Regexp(r"^[A-Za-z0-9\-]+$", message="Slug must be a URL path component")


E = TypeVar("E", bound=enum.Enum)


def _import_fields() -> None:
    for name in dir(fields):
        if not name.startswith("_") and name[0].isupper():
            globals()[name] = getattr(fields, name)
            __all__.append(name)


def _enum_labelfunc(value: E) -> str:
    return value.name.capitalize().replace("_", "-")


[docs] class EnumField(fields.SelectField, Generic[E]): """Field for selecting an enum value. The choices are generated from the enum values. The label is the enum value. :param label: The label for the field :param validators: Validators for the field :param enum: The enum type """ def __init__(self, label: str | None = None, validators: Any = None, *, enum: type[E], **kwargs: Any) -> None: labelfunc = kwargs.pop("labelfunc", _enum_labelfunc) kwargs.setdefault("choices", [(value.name, labelfunc(value)) for value in enum]) super().__init__(label=label, validators=validators, coerce=self._coerce, **kwargs) self.enum = enum def _coerce(self, value: str | E) -> E: if isinstance(value, self.enum): return value return self.enum[value] # type: ignore def _value(self) -> str: if self.data: return self.data.name else: return ""
def unwrap_paragraphs(txt: str) -> str: return "\n\n".join([paragraph.replace("\n", " ") for paragraph in txt.split("\n\n")])
[docs] class MarkdownField(fields.TextAreaField): """TextArea field designed for Markdown content. The field will unwrap paragraphs and remove newlines from paragraphs.""" def _value(self) -> str: if self.data: return unwrap_paragraphs(self.data) else: return ""
[docs] class KnownMIMEType: """Validator that ensures that a content-type field is a known MIME type""" def __init__(self, message: str | None = None) -> None: if not message: message = "Must be a well known MIME type." self.message = message self.db = mimetypes.MimeTypes()
[docs] def __call__(self, form: Any, field: fields.Field) -> None: """Validates the field :param form: The form contianing the field :param field: The field :raises ValidationError: If the field is not a known MIME type """ mimetype, _options = parse_options_header(field.data) well_known_types, official_types = self.db.types_map_inv if (mimetype not in well_known_types) and (mimetype not in official_types): raise ValidationError(self.message)
_import_fields()