1
0
Fork 0
This repository has been archived on 2022-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
website_generator/website_generator/fields.py

91 lines
3.0 KiB
Python

from pathlib import Path
from website_generator.utils import PathMatcher
import typesystem
class PathField(typesystem.String):
errors = {
'type': 'Must be a string or instance of pathlib.Path.',
'null': 'May not be null.',
'blank': 'Must not be blank.',
'max_length': 'Must have no more than {max_length} characters.',
'min_length': 'Must have at least {min_length} characters.',
'pattern': 'Must match the pattern /{pattern}/.',
'format': 'Must be a valid {format}.',
'not_found': 'Path does not exist.',
'no_files': 'Path must not point to a file.',
'no_dirs': 'Path must not point to a directory.',
'no_symlinks': 'Path must not point to a symbolic link.',
}
def __init__(self,
*,
must_exist=True,
allow_files=True,
allow_folders=False,
allow_symlinks=True,
**kwargs):
super().__init__(**kwargs)
self.must_exist = must_exist
self.allow_files = must_exist and allow_files
self.allow_folders = must_exist and allow_folders
self.allow_symlinks = must_exist and allow_symlinks
def validate(self, value, *, strict=False):
if isinstance(value, Path):
value = str(value)
value = super().validate(value, strict=strict)
if not value:
return value
value = Path(value)
if not self.allow_symlinks and value.is_symlink():
self.validation_error("no_symlinks")
value = value.expanduser().resolve()
if self.must_exist and not value.exists():
self.validation_error("not_found")
if not self.allow_files and value.is_file():
self.validation_error("no_files")
if not self.allow_folders and value.is_dir():
self.validation_error("no_dirs")
return value
class PathMatcherField(typesystem.Union):
def __init__(self, *, **kwargs):
super().__init__([
typesystem.String(),
typesystem.Array(
items=typesystem.String(),
min_items=1,
),
typesystem.Object(
properties={
'include': typesystem.Union([
typesystem.String(),
typesystem.Array(
items=typesystem.String(),
min_items=1,
),
]),
'exclude': typesystem.Union([
typesystem.String(),
typesystem.Array(
items=typesystem.String(),
min_items=1,
),
]),
},
min_properties=1,
required=['include'],
),
], **kwargs)
def validate(self, *args, **kwargs):
return PathMatcher(super().validate(*args, **kwargs))