refactor(weather): rework wind parser

This commit is contained in:
2026-09-22 20:58:18 +03:00
parent c0503458e4
commit 3612658323
7 changed files with 57 additions and 62 deletions
+2 -2
View File
@@ -19,7 +19,7 @@ from gallery.sketch.weather.model import (
WeatherValue, WeatherValue,
WindDirection, WindDirection,
) )
from gallery.sketch.weather.parser import parse_wind_direction from gallery.sketch.weather.parse.wind import WIND_DIRECTION_PARSER
from gallery.sketch.weather.util import fix_dates_sequence, merge_weather_values from gallery.sketch.weather.util import fix_dates_sequence, merge_weather_values
from . import PROVIDER from . import PROVIDER
@@ -152,7 +152,7 @@ class WindDirectionParser(TableValueParser[WindDirection | None]):
model_key = "wind.direction" model_key = "wind.direction"
def extract(self, data: Tag) -> WindDirection | None: def extract(self, data: Tag) -> WindDirection | None:
return parse_wind_direction(data.text.strip()) return WIND_DIRECTION_PARSER.parse(data.text.strip())
class PrecipitationParser(TableValueParser[float]): class PrecipitationParser(TableValueParser[float]):
+2 -2
View File
@@ -7,7 +7,7 @@ from gallery.sketch.weather.model import (
Precipitation, Precipitation,
WeatherValue, WeatherValue,
) )
from gallery.sketch.weather.parser import parse_wind_direction from gallery.sketch.weather.parse.wind import WIND_DIRECTION_PARSER
from gallery.sketch.weather.util import convert_hPa_to_mmHg from gallery.sketch.weather.util import convert_hPa_to_mmHg
from .openweather import Forecast, ForecastItem from .openweather import Forecast, ForecastItem
@@ -47,7 +47,7 @@ class ForecastItemParser(Parser[ForecastItem, list[WeatherValue]]):
"wind": { "wind": {
"speed": round(data.wind.speed), "speed": round(data.wind.speed),
"gust": round(data.wind.gust), "gust": round(data.wind.gust),
"direction": parse_wind_direction(data.wind.deg), "direction": WIND_DIRECTION_PARSER.parse(data.wind.deg),
}, },
"temperature": [round(data.main.temp)], # [round(data.main.temp_max), round(data.main.temp_min)] "temperature": [round(data.main.temp)], # [round(data.main.temp_max), round(data.main.temp_min)]
"precipitation": round(data.rain.interval_3h, 1) if data.rain else 0, "precipitation": round(data.rain.interval_3h, 1) if data.rain else 0,
+2 -2
View File
@@ -19,7 +19,7 @@ from gallery.sketch.weather.model import (
WeatherValue, WeatherValue,
WindDirection, WindDirection,
) )
from gallery.sketch.weather.parser import parse_wind_direction from gallery.sketch.weather.parse.wind import WIND_DIRECTION_PARSER
from gallery.sketch.weather.util import fix_dates_sequence from gallery.sketch.weather.util import fix_dates_sequence
from . import PROVIDER from . import PROVIDER
@@ -135,7 +135,7 @@ class WindDirectionParser(TableValueParser[WindDirection | None]):
model_key = "wind.direction" model_key = "wind.direction"
def extract(self, data: Tag) -> WindDirection | None: def extract(self, data: Tag) -> WindDirection | None:
return parse_wind_direction(data.text.strip()) return WIND_DIRECTION_PARSER.parse(data.text.strip())
class HumidityParser(TableValueParser[int]): class HumidityParser(TableValueParser[int]):
+2 -2
View File
@@ -21,7 +21,7 @@ from gallery.sketch.weather.model import (
WeatherValue, WeatherValue,
WindDirection, WindDirection,
) )
from gallery.sketch.weather.parser import parse_wind_direction from gallery.sketch.weather.parse.wind import WIND_DIRECTION_PARSER
from . import PROVIDER from . import PROVIDER
@@ -113,7 +113,7 @@ class WindDirectionParser(TableValueParser[WindDirection | None]):
model_key = "wind.direction" model_key = "wind.direction"
def extract(self, data: Tag) -> WindDirection | None: def extract(self, data: Tag) -> WindDirection | None:
return parse_wind_direction(data.text.strip()) return WIND_DIRECTION_PARSER.parse(data.text.strip())
class HumidityParser(TableValueParser[int]): class HumidityParser(TableValueParser[int]):
+49
View File
@@ -0,0 +1,49 @@
from gallery.sketch.parse.core import Parser
from ..model import WindDirection
class WindDirectionParser(Parser[str | int | float, WindDirection | None]):
WIND_DIRECTION_MAP: dict[str, WindDirection | None] = {
"с": WindDirection.N,
"св": WindDirection.NE,
"в": WindDirection.E,
"юв": WindDirection.SE,
"ю": WindDirection.S,
"юз": WindDirection.SW,
"з": WindDirection.W,
"сз": WindDirection.NW,
}
# pylint:disable=too-many-return-statements
def _parse_number(self, value: int | float) -> WindDirection | None:
if value > 337.5 or value <= 22.25:
return WindDirection.N
elif value <= 67.5:
return WindDirection.NE
elif value <= 112.5:
return WindDirection.E
elif value <= 157.5:
return WindDirection.SE
elif value <= 202.5:
return WindDirection.S
elif value <= 247.5:
return WindDirection.SW
elif value <= 292.5:
return WindDirection.W
elif value <= 337.5:
return WindDirection.NW
else:
return None
def _parse_str(self, value: str) -> WindDirection | None:
return self.WIND_DIRECTION_MAP.get(value.replace("-", "").lower())
def parse(self, data: str | int | float) -> WindDirection | None:
if isinstance(data, str):
return self._parse_str(data)
else:
return self._parse_number(data)
WIND_DIRECTION_PARSER = WindDirectionParser()
-54
View File
@@ -1,54 +0,0 @@
from typing import Self
from gallery.sketch.weather.model import WindDirection
class ParseError(Exception):
@classmethod
def invalid_date(cls, date_str: str) -> Self:
return cls("Invalid date string", date_str)
WIND_DIRECTION_MAP: dict[str, WindDirection | None] = {
"с": WindDirection.N,
"св": WindDirection.NE,
"в": WindDirection.E,
"юв": WindDirection.SE,
"ю": WindDirection.S,
"юз": WindDirection.SW,
"з": WindDirection.W,
"сз": WindDirection.NW,
}
# pylint:disable=too-many-return-statements
def _parse_wind_direction_number(value: int | float) -> WindDirection | None:
if value > 337.5 or value <= 22.25:
return WindDirection.N
elif value <= 67.5:
return WindDirection.NE
elif value <= 112.5:
return WindDirection.E
elif value <= 157.5:
return WindDirection.SE
elif value <= 202.5:
return WindDirection.S
elif value <= 247.5:
return WindDirection.SW
elif value <= 292.5:
return WindDirection.W
elif value <= 337.5:
return WindDirection.NW
else:
return None
def _parse_wind_direction_str(value: str) -> WindDirection | None:
return WIND_DIRECTION_MAP.get(value.replace("-", "").lower())
def parse_wind_direction(value: str | int | float) -> WindDirection | None:
if isinstance(value, str):
return _parse_wind_direction_str(value)
else:
return _parse_wind_direction_number(value)