feat(parser): use ParserError in parsers
This commit is contained in:
@@ -66,7 +66,7 @@ https://api.shmyga.ru/api/schedule/{provider}/{channel_id}/{date}
|
|||||||
| Provider | Site | API sample |
|
| Provider | Site | API sample |
|
||||||
| :- | :- | :- |
|
| :- | :- | :- |
|
||||||
| matchtv | https://matchtv.ru/tvguide | https://api.shmyga.ru/api/schedule/matchtv/igra/today |
|
| matchtv | https://matchtv.ru/tvguide | https://api.shmyga.ru/api/schedule/matchtv/igra/today |
|
||||||
| yandex | https://tv.yandex.ru | https://api.shmyga.ru/api/schedule/yandex/146/today |
|
| yandex | https://tv.yandex.ru | https://api.shmyga.ru/api/schedule/yandex/start-103/today |
|
||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import logging
|
|
||||||
import re
|
import re
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Any, Literal
|
from typing import Any, Literal
|
||||||
@@ -24,8 +23,6 @@ from gallery.sketch.weather.util import fix_dates_sequence, merge_weather_values
|
|||||||
|
|
||||||
from . import PROVIDER
|
from . import PROVIDER
|
||||||
|
|
||||||
logger = logging.getLogger(PROVIDER)
|
|
||||||
|
|
||||||
|
|
||||||
class LocationNameParser(Parser[str, str]):
|
class LocationNameParser(Parser[str, str]):
|
||||||
PATTERN = re.compile('{"ru":{"city":{"name":"(.*?)"')
|
PATTERN = re.compile('{"ru":{"city":{"name":"(.*?)"')
|
||||||
@@ -112,7 +109,7 @@ class SkyParser(TableValueParser[Sky]):
|
|||||||
values.remove(k)
|
values.remove(k)
|
||||||
break
|
break
|
||||||
if values:
|
if values:
|
||||||
logger.warning("unknown sky values: %s:", values)
|
raise ParseError("Unknown sky values", values)
|
||||||
return Sky(
|
return Sky(
|
||||||
cloudness=cloudness,
|
cloudness=cloudness,
|
||||||
precipitation=precipitation,
|
precipitation=precipitation,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from gallery.sketch.weather.model import (
|
|||||||
from gallery.sketch.weather.parse.wind import WIND_DIRECTION_PARSER
|
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 . import PROVIDER
|
||||||
from .openweather import Forecast, ForecastItem
|
from .openweather import Forecast, ForecastItem
|
||||||
from .openweather import Location as OpenWeatherLocation
|
from .openweather import Location as OpenWeatherLocation
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ class OpenWeatherLocationParser(Parser[list[OpenWeatherLocation], list[Location]
|
|||||||
Location(
|
Location(
|
||||||
id=f"{item.lat}:{item.lon}",
|
id=f"{item.lat}:{item.lon}",
|
||||||
name=item.name,
|
name=item.name,
|
||||||
provider="openweather",
|
provider=PROVIDER,
|
||||||
lat=item.lat,
|
lat=item.lat,
|
||||||
lon=item.lon,
|
lon=item.lon,
|
||||||
country=item.country,
|
country=item.country,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import re
|
|||||||
|
|
||||||
from bs4 import Tag
|
from bs4 import Tag
|
||||||
|
|
||||||
|
from gallery.sketch.parse.core import ParseError
|
||||||
from gallery.sketch.parse.date import DATE_PARSER
|
from gallery.sketch.parse.date import DATE_PARSER
|
||||||
from gallery.sketch.parse.html import (
|
from gallery.sketch.parse.html import (
|
||||||
HTMLParser,
|
HTMLParser,
|
||||||
@@ -72,6 +73,8 @@ class CloudnessParser(TableValueParser[Cloudness]):
|
|||||||
def extract(self, data: Tag) -> Cloudness:
|
def extract(self, data: Tag) -> Cloudness:
|
||||||
onmouseover = data.select_one(".cc_0").next_element.attrs["onmouseover"]
|
onmouseover = data.select_one(".cc_0").next_element.attrs["onmouseover"]
|
||||||
cloudness_str = re.compile("<b>(.*?)</b>").search(onmouseover).group(1).strip()
|
cloudness_str = re.compile("<b>(.*?)</b>").search(onmouseover).group(1).strip()
|
||||||
|
if cloudness_str not in self.CLOUDNESS_MAP:
|
||||||
|
raise ParseError("Unknown cloudness value", cloudness_str)
|
||||||
return self.CLOUDNESS_MAP[cloudness_str]
|
return self.CLOUDNESS_MAP[cloudness_str]
|
||||||
|
|
||||||
|
|
||||||
@@ -95,6 +98,8 @@ class PrecipitationParser(TableValueParser[tuple[Precipitation, float]]):
|
|||||||
precipitation_value = float(precipitation_value_matched.group(1)) * 6
|
precipitation_value = float(precipitation_value_matched.group(1)) * 6
|
||||||
if " (" in precipitation_str:
|
if " (" in precipitation_str:
|
||||||
precipitation_str = precipitation_str.split(" (")[0]
|
precipitation_str = precipitation_str.split(" (")[0]
|
||||||
|
if precipitation_str not in self.PRECIPITATION_MAP:
|
||||||
|
raise ParseError("Unknown precipitation value", precipitation_str)
|
||||||
return self.PRECIPITATION_MAP[precipitation_str], precipitation_value
|
return self.PRECIPITATION_MAP[precipitation_str], precipitation_value
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from typing import Any
|
|||||||
|
|
||||||
from bs4 import Tag
|
from bs4 import Tag
|
||||||
|
|
||||||
from gallery.sketch.parse.core import ParsedContext
|
from gallery.sketch.parse.core import ParsedContext, ParseError
|
||||||
from gallery.sketch.parse.json import JSONParser
|
from gallery.sketch.parse.json import JSONParser
|
||||||
from gallery.sketch.schedule.model import Channel, Schedule, ScheduleValue
|
from gallery.sketch.schedule.model import Channel, Schedule, ScheduleValue
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ class ScheduleData:
|
|||||||
class YandexTVScheduleParser(HTMLContextParser[ScheduleData, Schedule]):
|
class YandexTVScheduleParser(HTMLContextParser[ScheduleData, Schedule]):
|
||||||
def extract(self, data: ParsedContext[ScheduleData, Tag]) -> Schedule:
|
def extract(self, data: ParsedContext[ScheduleData, Tag]) -> Schedule:
|
||||||
if data.data.select_one(".CheckboxCaptcha") is not None:
|
if data.data.select_one(".CheckboxCaptcha") is not None:
|
||||||
raise RuntimeError("Captcha")
|
raise ParseError("Captcha")
|
||||||
values = []
|
values = []
|
||||||
channel_name = data.data.select_one(".channel-header__text").text.strip()
|
channel_name = data.data.select_one(".channel-header__text").text.strip()
|
||||||
current_day = datetime.datetime.combine(data.context.date, datetime.datetime.min.time())
|
current_day = datetime.datetime.combine(data.context.date, datetime.datetime.min.time())
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import logging
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from bs4 import Tag
|
from bs4 import Tag
|
||||||
|
|
||||||
|
from gallery.sketch.parse.core import ParseError
|
||||||
from gallery.sketch.parse.date import DATE_PARSER
|
from gallery.sketch.parse.date import DATE_PARSER
|
||||||
from gallery.sketch.parse.html import (
|
from gallery.sketch.parse.html import (
|
||||||
HTMLParser,
|
HTMLParser,
|
||||||
@@ -25,8 +25,6 @@ from gallery.sketch.weather.parse.wind import WIND_DIRECTION_PARSER
|
|||||||
|
|
||||||
from . import PROVIDER
|
from . import PROVIDER
|
||||||
|
|
||||||
logger = logging.getLogger(PROVIDER)
|
|
||||||
|
|
||||||
|
|
||||||
class LocationNameParser(TagParser[str]):
|
class LocationNameParser(TagParser[str]):
|
||||||
selector = "[class^=Suggest_placeholder]"
|
selector = "[class^=Suggest_placeholder]"
|
||||||
@@ -70,28 +68,31 @@ class SkyParser(TableValueParser[Sky]):
|
|||||||
selector = "[style$='-text']"
|
selector = "[style$='-text']"
|
||||||
model_key = "sky"
|
model_key = "sky"
|
||||||
|
|
||||||
|
CLOUDNESS_MAP = {
|
||||||
|
"ясно": Cloudness.CLEAR,
|
||||||
|
"облачно с прояснениями": Cloudness.CLOUDY,
|
||||||
|
"малооблачно": Cloudness.CLOUDY,
|
||||||
|
"пасмурно": Cloudness.MAINLY_CLOUDY,
|
||||||
|
}
|
||||||
|
|
||||||
|
PRECIPITATION_MAP = {
|
||||||
|
"небольшой дождь": Precipitation.SMALL_RAIN,
|
||||||
|
"дождь": Precipitation.RAIN,
|
||||||
|
"ливень": Precipitation.SHOWER,
|
||||||
|
}
|
||||||
|
|
||||||
def extract(self, data: Tag) -> Sky:
|
def extract(self, data: Tag) -> Sky:
|
||||||
sky = data.text.strip()
|
sky = data.text.strip()
|
||||||
cloudness = Cloudness.CLEAR
|
cloudness = Cloudness.CLEAR
|
||||||
precipitation = Precipitation.NO
|
precipitation = Precipitation.NO
|
||||||
thunder = False
|
thunder = False
|
||||||
fog = False
|
fog = False
|
||||||
if sky == "ясно":
|
if sky in self.CLOUDNESS_MAP:
|
||||||
pass
|
cloudness = self.CLOUDNESS_MAP[sky]
|
||||||
elif sky == "облачно с прояснениями":
|
elif sky in self.PRECIPITATION_MAP:
|
||||||
cloudness = Cloudness.PARTLY_CLOUDY
|
precipitation = self.PRECIPITATION_MAP[sky]
|
||||||
elif sky == "малооблачно":
|
|
||||||
cloudness = Cloudness.CLOUDY
|
|
||||||
elif sky == "пасмурно":
|
|
||||||
cloudness = Cloudness.MAINLY_CLOUDY
|
|
||||||
elif sky == "небольшой дождь":
|
|
||||||
precipitation = Precipitation.SMALL_RAIN
|
|
||||||
elif sky == "дождь":
|
|
||||||
precipitation = Precipitation.RAIN
|
|
||||||
elif sky == "ливень":
|
|
||||||
precipitation = Precipitation.SHOWER
|
|
||||||
else:
|
else:
|
||||||
logger.warning("unknown sky value: %s", sky)
|
raise ParseError("Unknown sky value", sky)
|
||||||
return Sky(
|
return Sky(
|
||||||
cloudness=cloudness,
|
cloudness=cloudness,
|
||||||
precipitation=precipitation,
|
precipitation=precipitation,
|
||||||
|
|||||||
Reference in New Issue
Block a user