Validator for crop region defined as X0 Y0 X1 Y1.
| 148 | |
| 149 | |
| 150 | class CropValue(ValidatedValue): |
| 151 | """Validator for crop region defined as X0 Y0 X1 Y1.""" |
| 152 | |
| 153 | _IGNORE_CHARS = (",", "/", "(", ")") |
| 154 | """Characters to ignore.""" |
| 155 | |
| 156 | def __init__(self, value: "str | tuple[int, int, int, int] | CropValue | None" = None): |
| 157 | self._crop: tuple[int, int, int, int] | None = None |
| 158 | if isinstance(value, CropValue): |
| 159 | self._crop = value._crop |
| 160 | elif value is None: |
| 161 | return |
| 162 | else: |
| 163 | crop: tuple[int, ...] = () |
| 164 | if isinstance(value, str): |
| 165 | translation_table = str.maketrans( |
| 166 | {char: " " for char in ScoreWeightsValue._IGNORE_CHARS} |
| 167 | ) |
| 168 | values = value.translate(translation_table).split() |
| 169 | crop = tuple(int(val) for val in values) |
| 170 | elif isinstance(value, tuple): |
| 171 | crop = value |
| 172 | if not len(crop) == 4: |
| 173 | raise ValueError("Crop region must be four numbers of the form X0 Y0 X1 Y1!") |
| 174 | if any(coordinate < 0 for coordinate in crop): |
| 175 | raise ValueError("Crop coordinates must be >= 0") |
| 176 | (x0, y0, x1, y1) = crop |
| 177 | self._crop = (min(x0, x1), min(y0, y1), max(x0, x1), max(y0, y1)) |
| 178 | |
| 179 | @property |
| 180 | def value(self) -> tuple[int, int, int, int] | None: |
| 181 | return self._crop |
| 182 | |
| 183 | def __str__(self) -> str: |
| 184 | if self._crop is None: |
| 185 | return "(none)" |
| 186 | x0, y0, x1, y1 = self._crop |
| 187 | return f"[{x0}, {y0}], [{x1}, {y1}]" |
| 188 | |
| 189 | @staticmethod |
| 190 | def from_config(config_value: str, default: "CropValue") -> "CropValue": |
| 191 | try: |
| 192 | return CropValue(config_value) |
| 193 | except ValueError as ex: |
| 194 | raise OptionParseFailure(f"{ex}") from ex |
| 195 | |
| 196 | |
| 197 | class ScoreWeightsValue(ValidatedValue): |
no outgoing calls
no test coverage detected