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,
|
||||
NumberInput,
|
||||
FloatInput,
|
||||
LocationInput,
|
||||
TextAreaInput,
|
||||
DropdownInput,
|
||||
Option,
|
||||
@ -14,6 +13,7 @@ from owrx.form.input.converter import WaterfallColorsConverter, IntConverter
|
||||
from owrx.form.input.receiverid import ReceiverKeysConverter
|
||||
from owrx.form.input.gfx import AvatarInput, TopPhotoInput
|
||||
from owrx.form.input.device import WaterfallLevelsInput, WaterfallAutoLevelsInput
|
||||
from owrx.form.input.location import LocationInput
|
||||
from owrx.waterfall import WaterfallOptions
|
||||
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem
|
||||
from owrx.controllers.settings import SettingsBreadcrumb
|
||||
|
@ -1,6 +1,5 @@
|
||||
from abc import ABC
|
||||
from owrx.modes import Modes
|
||||
from owrx.config import Config
|
||||
from owrx.form.input.validator import Validator
|
||||
from owrx.form.input.converter import Converter, NullConverter, IntConverter, FloatConverter, EnumConverter
|
||||
from enum import Enum
|
||||
@ -158,45 +157,6 @@ class FloatInput(NumberInput):
|
||||
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):
|
||||
def render_input(self, value, errors):
|
||||
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):
|
||||
@abstractmethod
|
||||
def validate(self, key, value):
|
||||
def validate(self, key, value) -> None:
|
||||
pass
|
||||
|
||||
|
||||
class RequiredValidator(Validator):
|
||||
def validate(self, key, value):
|
||||
def validate(self, key, value) -> None:
|
||||
if value is None or value == "":
|
||||
raise ValidationError(key, "Field is required")
|
||||
|
||||
@ -19,7 +19,7 @@ class RangeValidator(Validator):
|
||||
self.minValue = minValue
|
||||
self.maxValue = maxValue
|
||||
|
||||
def validate(self, key, value):
|
||||
def validate(self, key, value) -> None:
|
||||
if value is None or value == "":
|
||||
return # Ignore empty values
|
||||
n = float(value)
|
||||
|
Loading…
Reference in New Issue
Block a user