feat(api): add multiple days api

This commit is contained in:
2024-07-29 21:42:44 +03:00
parent 22fab7a15a
commit 7f0e19fb5a
16 changed files with 5411 additions and 64 deletions

View File

@@ -1,6 +1,6 @@
import datetime
import re
from typing import Dict, Iterable, List, Optional
from typing import Iterable
import dateparser
from bs4 import Tag
@@ -10,12 +10,13 @@ from weather.model import Cloudness, Precipitation, Sky, WindDirection
from .core import BaseWidgetParser, RowParser
ONE_DAY_PARSER = BaseWidgetParser(".widget.widget-oneday .widget-items")
DAYS_PARSER = BaseWidgetParser(".widget.widget-days .widget-items")
class LocationParser:
PATTERN = re.compile('{"ru":{"city":{"name":"(.*?)"')
def parse_location(self, data: str) -> Optional[str]:
def parse_location(self, data: str) -> str | None:
match = self.PATTERN.search(data)
if match:
return match.group(1)
@@ -29,30 +30,35 @@ class DateParser(RowParser[datetime.datetime]):
KEY = "date"
def parse_row(self, tag: Tag) -> Iterable[datetime.datetime]:
date_str = (
tag.select_one(".widget-row.widget-row-datetime-date > .row-item")
.find(text=True, recursive=False)
.text
datetime_date_tag = tag.select_one(
".widget-row.widget-row-datetime-date > .row-item"
)
date = dateparser.parse(date_str, languages=["ru"])
for item in tag.select(".widget-row.widget-row-datetime-time > .row-item"):
time_str = item.text
time = dateparser.parse(time_str, languages=["ru"])
time = time.replace(year=date.year, month=date.month, day=date.day)
yield time
if datetime_date_tag:
date_str = datetime_date_tag.find(text=True, recursive=False).text
date = dateparser.parse(date_str, languages=["ru"])
for item in tag.select(".widget-row.widget-row-datetime-time > .row-item"):
time_str = item.text
time = dateparser.parse(time_str, languages=["ru"])
time = time.replace(year=date.year, month=date.month, day=date.day)
yield time
else:
for item in tag.select(".widget-row.widget-row-date > .row-item"):
date_str = item.text
date = dateparser.parse(date_str, languages=["ru"])
yield date
class SkyParser(RowParser[Sky]):
KEY = "sky"
CLOUDNESS_MAP: Dict[str, Cloudness] = {
CLOUDNESS_MAP: dict[str, Cloudness] = {
"ясно": Cloudness.CLEAR,
"малооблачно": Cloudness.PARTLY_CLOUDY,
"облачно": Cloudness.CLOUDY,
"пасмурно": Cloudness.MAINLY_CLOUDY,
}
PRECIPITATION_MAP: Dict[str, Precipitation] = {
PRECIPITATION_MAP: dict[str, Precipitation] = {
"без осадков": Precipitation.NO,
"небольшой дождь": Precipitation.SMALL_RAIN,
"дождь": Precipitation.RAIN,
@@ -83,14 +89,16 @@ class SkyParser(RowParser[Sky]):
)
class TemperatureParser(RowParser[int]):
class TemperatureParser(RowParser[list[int]]):
KEY = "temperature"
def parse_row(self, tag: Tag) -> Iterable[int]:
def parse_row(self, tag: Tag) -> Iterable[list[int]]:
for item in tag.select(
".widget-row-chart[data-row=temperature-air] > .chart > .values > .value > temperature-value"
".widget-row-chart[data-row=temperature-air] > .chart > .values > .value"
):
yield int(item.attrs["value"])
yield [
int(value.attrs["value"]) for value in item.select("temperature-value")
]
class WindSpeedParser(RowParser[int]):
@@ -115,7 +123,7 @@ class WindGustParser(RowParser[int]):
class WindDirectionParser(RowParser[WindDirection]):
KEY = "wind_direction"
WIND_DIRECTION_MAP: Dict[str, WindDirection] = {
WIND_DIRECTION_MAP: dict[str, WindDirection] = {
"штиль": WindDirection.CALM,
"с": WindDirection.N,
"св": WindDirection.NO,
@@ -145,14 +153,14 @@ class WindPrecipitationParser(RowParser[float]):
yield float(item.text.replace(",", "."))
class PressureParser(RowParser[int]):
class PressureParser(RowParser[list[int]]):
KEY = "pressure"
def parse_row(self, tag: Tag) -> Iterable[int]:
def parse_row(self, tag: Tag) -> Iterable[list[int]]:
for item in tag.select(
".widget-row-chart[data-row=pressure] > .chart > .values > .value > pressure-value"
".widget-row-chart[data-row=pressure] > .chart > .values > .value"
):
yield int(item.attrs["value"])
yield [int(value.attrs["value"]) for value in item.select("pressure-value")]
class HumidityParser(RowParser[int]):
@@ -163,7 +171,7 @@ class HumidityParser(RowParser[int]):
yield int(item.text)
ROW_PARSERS: List[RowParser] = [
ROW_PARSERS: list[RowParser] = [
DateParser(),
SkyParser(),
TemperatureParser(),
@@ -175,4 +183,4 @@ ROW_PARSERS: List[RowParser] = [
HumidityParser(),
]
ROW_PARSERS_MAP: Dict[str, RowParser] = {parser.KEY: parser for parser in ROW_PARSERS}
ROW_PARSERS_MAP: dict[str, RowParser] = {parser.KEY: parser for parser in ROW_PARSERS}