This commit is contained in:
2024-07-24 20:31:43 +03:00
commit 234a2b7b0e
20 changed files with 4363 additions and 0 deletions

51
gismeteo/api.py Normal file
View File

@@ -0,0 +1,51 @@
import datetime
from typing import Any, Dict, List, NamedTuple
import aiohttp
from bs4 import BeautifulSoup
from .location import LOCATION_BUNDLE
from .parser import ROW_PARSERS, OneDayParser
class WeatherValue(NamedTuple):
date: datetime.datetime
cloudness: str
temperature: int
wind_speed: int
wind_gust: int
wind_direction: str
precipitation: float
pressure: int
humidity: int
class GismeteoApi:
BASE_URL = "https://www.gismeteo.ru"
async def _request(self, endpoint: str) -> str:
url = f"{self.BASE_URL}/{endpoint}"
async with aiohttp.ClientSession(raise_for_status=True) as session:
async with session.request("GET", url) as response:
return await response.text()
def _parse_oneday(self, data: str) -> List[WeatherValue]:
result: List[Dict[str, Any]] = []
soup = BeautifulSoup(data, features="html.parser")
widget = OneDayParser().parse_widget(soup)
for parser in ROW_PARSERS:
for index, value in enumerate(parser.parse_row(widget)):
while len(result) < index + 1:
result.append({})
result[index][parser.KEY] = value
return [WeatherValue(**item) for item in result]
async def today(self, location_id: str) -> List[WeatherValue]:
location = LOCATION_BUNDLE.parse(location_id)
data = await self._request(f"weather-{location}/today")
return self._parse_oneday(data)
async def tomorrow(self, location_id: str) -> List[WeatherValue]:
location = LOCATION_BUNDLE.parse(location_id)
data = await self._request(f"weather-{location}/tomorrow")
return self._parse_oneday(data)