add a validator that prevents invalid locations
This commit is contained in:
parent
0f2aca62f3
commit
818b9d87b8
@ -5,7 +5,6 @@ from owrx.form.input import (
|
|||||||
TextInput,
|
TextInput,
|
||||||
NumberInput,
|
NumberInput,
|
||||||
FloatInput,
|
FloatInput,
|
||||||
LocationInput,
|
|
||||||
TextAreaInput,
|
TextAreaInput,
|
||||||
DropdownInput,
|
DropdownInput,
|
||||||
Option,
|
Option,
|
||||||
@ -14,6 +13,7 @@ from owrx.form.input.converter import WaterfallColorsConverter, IntConverter
|
|||||||
from owrx.form.input.receiverid import ReceiverKeysConverter
|
from owrx.form.input.receiverid import ReceiverKeysConverter
|
||||||
from owrx.form.input.gfx import AvatarInput, TopPhotoInput
|
from owrx.form.input.gfx import AvatarInput, TopPhotoInput
|
||||||
from owrx.form.input.device import WaterfallLevelsInput, WaterfallAutoLevelsInput
|
from owrx.form.input.device import WaterfallLevelsInput, WaterfallAutoLevelsInput
|
||||||
|
from owrx.form.input.location import LocationInput
|
||||||
from owrx.waterfall import WaterfallOptions
|
from owrx.waterfall import WaterfallOptions
|
||||||
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem
|
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem
|
||||||
from owrx.controllers.settings import SettingsBreadcrumb
|
from owrx.controllers.settings import SettingsBreadcrumb
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from abc import ABC
|
from abc import ABC
|
||||||
from owrx.modes import Modes
|
from owrx.modes import Modes
|
||||||
from owrx.config import Config
|
|
||||||
from owrx.form.input.validator import Validator
|
from owrx.form.input.validator import Validator
|
||||||
from owrx.form.input.converter import Converter, NullConverter, IntConverter, FloatConverter, EnumConverter
|
from owrx.form.input.converter import Converter, NullConverter, IntConverter, FloatConverter, EnumConverter
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
@ -158,45 +157,6 @@ class FloatInput(NumberInput):
|
|||||||
return FloatConverter()
|
return FloatConverter()
|
||||||
|
|
||||||
|
|
||||||
class LocationInput(Input):
|
|
||||||
def render_input_group(self, value, errors):
|
|
||||||
return """
|
|
||||||
<div class="row {rowclass}">
|
|
||||||
{inputs}
|
|
||||||
</div>
|
|
||||||
{errors}
|
|
||||||
<div class="row">
|
|
||||||
<div class="col map-input" data-key="{key}" for="{id}"></div>
|
|
||||||
</div>
|
|
||||||
""".format(
|
|
||||||
id=self.id,
|
|
||||||
rowclass="is-invalid" if errors else "",
|
|
||||||
inputs=self.render_input(value, errors),
|
|
||||||
errors=self.render_errors(errors),
|
|
||||||
key=Config.get()["google_maps_api_key"],
|
|
||||||
)
|
|
||||||
|
|
||||||
def render_input(self, value, errors):
|
|
||||||
return "".join(self.render_sub_input(value, id, errors) for id in ["lat", "lon"])
|
|
||||||
|
|
||||||
def render_sub_input(self, value, id, errors):
|
|
||||||
return """
|
|
||||||
<div class="col">
|
|
||||||
<input type="number" class="{classes}" id="{id}" name="{id}" placeholder="{label}" value="{value}"
|
|
||||||
step="any" {disabled}>
|
|
||||||
</div>
|
|
||||||
""".format(
|
|
||||||
id="{0}-{1}".format(self.id, id),
|
|
||||||
label=self.label,
|
|
||||||
classes=self.input_classes(errors),
|
|
||||||
value=value[id],
|
|
||||||
disabled="disabled" if self.disabled else "",
|
|
||||||
)
|
|
||||||
|
|
||||||
def parse(self, data):
|
|
||||||
return {self.id: {k: float(data["{0}-{1}".format(self.id, k)][0]) for k in ["lat", "lon"]}}
|
|
||||||
|
|
||||||
|
|
||||||
class TextAreaInput(Input):
|
class TextAreaInput(Input):
|
||||||
def render_input(self, value, errors):
|
def render_input(self, value, errors):
|
||||||
return """
|
return """
|
||||||
|
64
owrx/form/input/location.py
Normal file
64
owrx/form/input/location.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
from owrx.form.input import Input
|
||||||
|
from owrx.form.input.validator import Validator
|
||||||
|
from owrx.form.error import ValidationError
|
||||||
|
from owrx.config import Config
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class LocationValidator(Validator):
|
||||||
|
def validate(self, key, value):
|
||||||
|
if "lat" in value and not -90 < value["lat"] < 90:
|
||||||
|
raise ValidationError(key, "Latitude out of range (-90 to 90)")
|
||||||
|
if "lon" in value and not -180 < value["lon"] < 180:
|
||||||
|
raise ValidationError(key, "Longitude out of range (-180 to 180)")
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class LocationInput(Input):
|
||||||
|
def __init__(self, id, label, validator: Validator = None):
|
||||||
|
if validator is None:
|
||||||
|
validator = LocationValidator()
|
||||||
|
super().__init__(id, label, validator=validator)
|
||||||
|
|
||||||
|
def render_input_group(self, value, errors):
|
||||||
|
return """
|
||||||
|
<div class="row {rowclass}">
|
||||||
|
{inputs}
|
||||||
|
</div>
|
||||||
|
{errors}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col map-input" data-key="{key}" for="{id}"></div>
|
||||||
|
</div>
|
||||||
|
""".format(
|
||||||
|
id=self.id,
|
||||||
|
rowclass="is-invalid" if errors else "",
|
||||||
|
inputs=self.render_input(value, errors),
|
||||||
|
errors=self.render_errors(errors),
|
||||||
|
key=Config.get()["google_maps_api_key"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def render_input(self, value, errors):
|
||||||
|
return "".join(self.render_sub_input(value, id, errors) for id in ["lat", "lon"])
|
||||||
|
|
||||||
|
def render_sub_input(self, value, id, errors):
|
||||||
|
return """
|
||||||
|
<div class="col">
|
||||||
|
<input type="number" class="{classes}" id="{id}" name="{id}" placeholder="{label}" value="{value}"
|
||||||
|
step="any" {disabled}>
|
||||||
|
</div>
|
||||||
|
""".format(
|
||||||
|
id="{0}-{1}".format(self.id, id),
|
||||||
|
label=self.label,
|
||||||
|
classes=self.input_classes(errors),
|
||||||
|
value=value[id],
|
||||||
|
disabled="disabled" if self.disabled else "",
|
||||||
|
)
|
||||||
|
|
||||||
|
def parse(self, data):
|
||||||
|
value = {k: float(data["{0}-{1}".format(self.id, k)][0]) for k in ["lat", "lon"]}
|
||||||
|
if self.validator is not None:
|
||||||
|
self.validator.validate(self.id, value)
|
||||||
|
return {self.id: value}
|
@ -4,12 +4,12 @@ from owrx.form.error import ValidationError
|
|||||||
|
|
||||||
class Validator(ABC):
|
class Validator(ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def validate(self, key, value):
|
def validate(self, key, value) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class RequiredValidator(Validator):
|
class RequiredValidator(Validator):
|
||||||
def validate(self, key, value):
|
def validate(self, key, value) -> None:
|
||||||
if value is None or value == "":
|
if value is None or value == "":
|
||||||
raise ValidationError(key, "Field is required")
|
raise ValidationError(key, "Field is required")
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ class RangeValidator(Validator):
|
|||||||
self.minValue = minValue
|
self.minValue = minValue
|
||||||
self.maxValue = maxValue
|
self.maxValue = maxValue
|
||||||
|
|
||||||
def validate(self, key, value):
|
def validate(self, key, value) -> None:
|
||||||
if value is None or value == "":
|
if value is None or value == "":
|
||||||
return # Ignore empty values
|
return # Ignore empty values
|
||||||
n = float(value)
|
n = float(value)
|
||||||
|
Loading…
Reference in New Issue
Block a user