feat(weather): wehaer value sky model instead of text cloudness

This commit is contained in:
2024-07-26 18:25:15 +03:00
parent f711b2d77b
commit 48a6cce569
6 changed files with 135 additions and 47 deletions

View File

@@ -10,7 +10,7 @@ class LocationValue(NamedTuple):
@classmethod
def parse(cls, source: str) -> "LocationValue":
location, name = source.split("-")
name, location = source.split("-")
return cls(int(location), name)

View File

@@ -5,6 +5,8 @@ from typing import Dict, Iterable, List, Optional
import dateparser
from bs4 import Tag
from weather.model import Cloudness, Precipitation, Sky, WindDirection
from .core import BaseWidgetParser, RowParser
ONE_DAY_PARSER = BaseWidgetParser(".widget.widget-oneday .widget-items")
@@ -40,12 +42,45 @@ class DateParser(RowParser[datetime.datetime]):
yield time
class CloudnessParser(RowParser[str]):
KEY = "cloudness"
class SkyParser(RowParser[Sky]):
KEY = "sky"
def parse_row(self, tag: Tag) -> Iterable[str]:
CLOUDNESS_MAP: Dict[str, Cloudness] = {
"ясно": Cloudness.CLEAR,
"малооблачно": Cloudness.PARTLY_CLOUDY,
"облачно": Cloudness.CLOUDY,
"пасмурно": Cloudness.MAINLY_CLOUDY,
}
PRECIPITATION_MAP: Dict[str, Precipitation] = {
"без осадков": Precipitation.NO,
"небольшой дождь": Precipitation.SMALL_RAIN,
"дождь": Precipitation.RAIN,
"ливень": Precipitation.SHOWER,
}
def parse_row(self, tag: Tag) -> Iterable[Sky]:
for item in tag.select(".widget-row[data-row=icon-tooltip] > .row-item"):
yield item.attrs["data-tooltip"]
sky_str = item.attrs["data-tooltip"]
values = {item.strip().lower() for item in sky_str.split(",")}
cloudness = Cloudness.CLEAR
precipitation = Precipitation.NO
thunder = "гроза" in values
fog = "дымка" in values
for k, v in self.CLOUDNESS_MAP.items():
if k in values:
cloudness = v
break
for k, v in self.PRECIPITATION_MAP.items():
if k in values:
precipitation = v
break
yield Sky(
cloudness=cloudness,
precipitation=precipitation,
thunder=thunder,
fog=fog,
)
class TemperatureParser(RowParser[int]):
@@ -77,14 +112,27 @@ class WindGustParser(RowParser[int]):
yield int(value.attrs["value"]) if value else 0
class WindDirectionParser(RowParser[str]):
class WindDirectionParser(RowParser[WindDirection]):
KEY = "wind_direction"
def parse_row(self, tag: Tag) -> Iterable[str]:
WIND_DIRECTION_MAP: Dict[str, WindDirection] = {
"штиль": WindDirection.CALM,
"с": WindDirection.N,
"св": WindDirection.NO,
"в": WindDirection.O,
"юв": WindDirection.SO,
"ю": WindDirection.S,
"юз": WindDirection.SW,
"з": WindDirection.W,
"сз": WindDirection.NW,
}
def parse_row(self, tag: Tag) -> Iterable[WindDirection]:
for item in tag.select(
".widget-row[data-row=wind-direction] > .row-item > .direction"
):
yield item.text
wind_direction_str = item.text.lower()
yield self.WIND_DIRECTION_MAP[wind_direction_str]
class WindPrecipitationParser(RowParser[float]):
@@ -117,7 +165,7 @@ class HumidityParser(RowParser[int]):
ROW_PARSERS: List[RowParser] = [
DateParser(),
CloudnessParser(),
SkyParser(),
TemperatureParser(),
WindSpeedParser(),
WindGustParser(),