feat(api): add ApiSource

This commit is contained in:
2024-08-21 19:42:53 +03:00
parent b3043c3c8c
commit 0638fb8d50
3 changed files with 61 additions and 49 deletions

View File

@@ -2,10 +2,10 @@ import datetime
import logging
from typing import Any, Dict, List
import aiohttp
from aiocache import cached
from bs4 import BeautifulSoup
from gallery.sketch.source import ApiSource
from gallery.sketch.weather.api import WeatherApi
from gallery.sketch.weather.catalog import LocationId
from gallery.sketch.weather.model import WeatherResponse, WeatherValue
@@ -17,33 +17,23 @@ logger = logging.getLogger("gismeteo")
class GismeteoApi(WeatherApi):
BASE_URL = "https://www.gismeteo.ru"
SOURCE = ApiSource(
"https://www.gismeteo.ru",
cookies={
"cf_clearance": (
"zPj8qeaYZWp5BUZsWIRD7kd32s59IDWWaVvD7GGf6b4-1724254262-1.2.1.1-"
"R1PaHoqlm4OEgHfrOg6oAJmVmFJ7053JI_QDjIFlCAmbNY0oyw1J4QtgmEkAkTWF4C99X5hpXmZB2en."
"9Ey3NL0kzaE10UGBHPli5OLxHNKC3wQ34xmxTxg6GcKouXOPRgqo92lVRpQP7ghvDmvvT_"
"S6YXDbRonkamptWhZiAsIhsnIQg2Mt7Lk1fxSEVbaey_RXVQBvaR2ofiFgIavcbQPRFSvJ."
"Ct_FujmymTAZWh1XHTptK32kur81NXyPuARThetOKQm8AklaMa855Oom6Bms1a4F9b0yEHSd2inA4j3FR7uauu8hhwO0Z2goa3."
"ktpXXAQLz6dm.fBEWIHD7wooda15X57tCcDOely4hxhO4LK2lIH6TbOr."
"rZQAiRRhltHiCizP1Ou2SiF_81lb1umoDh739tQD1cnw_USnL."
"JwTHvkB00ZnaHRMi4FCBrsKIE0NxJO6kiv1QANqumzf5.8_pSIGRo2cKeO8xCydduDNFbStdOmLR6FU7ZKqVu"
)
},
)
CACHE_TTL = 10 * 60
USER_AGENT = (
"Mozilla/5.0 (X11; Linux x86_64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/126.0.0.0 Safari/537.36"
)
COOKIE = (
"cf_clearance=U28mYVC0ENu88vorlL_CWmWOoevvXp0vb4xCqfqYC9s-"
"1722273367-1.0.1.1-"
"IDV73azTHY0V.NAnmEvok3zf5HHEkvF098pmya7IiqRRB5nk3FhbLCb0AeWm_kpTFqi1niFk2mYN_ramGTSl0A"
)
async def _request(self, endpoint: str) -> str:
url = f"{self.BASE_URL}/{endpoint}"
logger.info(url)
async with aiohttp.ClientSession(
headers={
"User-Agent": self.USER_AGENT,
"Cookie": self.COOKIE,
},
raise_for_status=True,
) as session:
async with session.request("GET", url) as response:
return await response.text()
def _parse_oneday(self, date: datetime.date, data: str) -> WeatherResponse:
result: List[Dict[str, Any]] = []
soup = BeautifulSoup(data, features="html.parser")
@@ -88,10 +78,10 @@ class GismeteoApi(WeatherApi):
@cached(ttl=CACHE_TTL)
async def get_day(self, location_id: str, date: datetime.date) -> WeatherResponse:
data = await self._request(f"weather-{location_id}/{datehelp.dump(date)}")
data = await self.SOURCE.request(f"weather-{location_id}/{datehelp.dump(date)}")
return self._parse_oneday(date, data)
@cached(ttl=CACHE_TTL)
async def get_days(self, location_id: str, days: int) -> WeatherResponse:
data = await self._request(f"weather-{location_id}/{days}-days")
data = await self.SOURCE.request(f"weather-{location_id}/{days}-days")
return self._parse_manydays(data)

View File

@@ -1,39 +1,21 @@
import datetime
import logging
import aiohttp
from aiocache import cached
from bs4 import BeautifulSoup
from gallery.sketch.schedule.api import ScheduleApi
from gallery.sketch.schedule.catalog import ChannelId
from gallery.sketch.schedule.model import Channel, Schedule, ScheduleValue
from gallery.sketch.source import ApiSource
logger = logging.getLogger("matchtv")
class MatchTvApi(ScheduleApi):
BASE_URL = "https://matchtv.ru"
SOURCE = ApiSource("https://matchtv.ru")
CACHE_TTL = 30 * 60
USER_AGENT = (
"Mozilla/5.0 (X11; Linux x86_64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/126.0.0.0 Safari/537.36"
)
async def _request(self, endpoint: str) -> str:
url = f"{self.BASE_URL}/{endpoint}"
logger.info(url)
async with aiohttp.ClientSession(
headers={
"User-Agent": self.USER_AGENT,
},
raise_for_status=True,
) as session:
async with session.request("GET", url) as response:
return await response.text()
async def get_channels(self) -> list[str]:
return [
ChannelId.MATCH_TV,
@@ -50,7 +32,7 @@ class MatchTvApi(ScheduleApi):
self, channel_id: str, date: datetime.date
) -> Schedule:
endpoint = f"channel/{channel_id}/tvguide?date={date:%d-%m-%Y}"
data = await self._request(endpoint)
data = await self.SOURCE.request(endpoint)
soup = BeautifulSoup(data, features="html.parser")
values = []
channel_name = soup.select_one(".caption__heading").text.split("|")[0].strip()

40
gallery/sketch/source.py Normal file
View File

@@ -0,0 +1,40 @@
import logging
import aiohttp
logger = logging.getLogger("source")
class ApiSource:
DEFAULT_USER_AGENT = (
"Mozilla/5.0 (X11; Linux x86_64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/126.0.0.0 Safari/537.36"
)
DEFAULT_TIMEOUT = 30.0
def __init__(
self,
base_url,
user_agent: str = DEFAULT_USER_AGENT,
timeout: float = DEFAULT_TIMEOUT,
cookies: dict[str, str] | None = None,
):
self._base_url = base_url
self._user_agent = user_agent
self._timeout = timeout
self._cookies = cookies
async def request(self, endpoint: str) -> str:
url = f"{self._base_url}/{endpoint}"
logger.info(url)
headers = {
"User-Agent": self._user_agent,
}
async with aiohttp.ClientSession(
headers=headers,
cookies=self._cookies,
raise_for_status=True,
) as session:
async with session.request("GET", url, timeout=self._timeout) as response:
return await response.text()