Export blitz and bullet ratings.
parent
36d471e395
commit
d549e5f5eb
|
@ -187,3 +187,9 @@ class Exporter(BaseExporter):
|
|||
|
||||
def export_rapid(self) -> Union[int, None]:
|
||||
return self.stats_json.get("rapid", {}).get("rating")
|
||||
|
||||
def export_blitz(self) -> Union[int, None]:
|
||||
return self.stats_json.get("lightning", {}).get("rating")
|
||||
|
||||
def export_bullet(self) -> Union[int, None]:
|
||||
return self.stats_json.get("bullet", {}).get("rating")
|
||||
|
|
|
@ -4,8 +4,18 @@ from typing_extensions import TypedDict
|
|||
|
||||
|
||||
class Export(TypedDict, total=False):
|
||||
# The coach's rapid rating as listed on the site they were sourced from.
|
||||
# The coach's rapid rating relative to the site they were sourced from.
|
||||
rapid: int
|
||||
# The coach's blitz rating relative to the site they were sourced from.
|
||||
blitz: int
|
||||
# The coach's bullet rating relative to the site they were sourced from.
|
||||
bullet: int
|
||||
|
||||
|
||||
def _insert(export: Export, key: str, value: any):
|
||||
if value is None:
|
||||
return
|
||||
export[key] = value
|
||||
|
||||
|
||||
class BaseExporter(Repo):
|
||||
|
@ -16,13 +26,19 @@ class BaseExporter(Repo):
|
|||
def export_rapid(self) -> Union[int, None]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def export_blitz(self) -> Union[int, None]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def export_bullet(self) -> Union[int, None]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def export(self) -> Export:
|
||||
"""Transform coach-specific data into uniform format."""
|
||||
export: Export = {}
|
||||
|
||||
rapid = self.export_rapid()
|
||||
if rapid:
|
||||
export["rapid"] = rapid
|
||||
_insert(export, "rapid", self.export_rapid())
|
||||
_insert(export, "blitz", self.export_blitz())
|
||||
_insert(export, "bullet", self.export_bullet())
|
||||
|
||||
self.log(
|
||||
[
|
||||
|
|
|
@ -6,7 +6,7 @@ import os.path
|
|||
from app.repo import AnsiColor, Site
|
||||
from app.scraper import BaseScraper
|
||||
from app.exporter import BaseExporter
|
||||
from bs4 import BeautifulSoup
|
||||
from bs4 import BeautifulSoup, SoupStrainer
|
||||
from typing import List
|
||||
|
||||
|
||||
|
@ -163,6 +163,12 @@ class Scraper(BaseScraper):
|
|||
return True
|
||||
|
||||
|
||||
def _stats_filter(elem, attrs):
|
||||
"""Includes only relevant segments of the `stats.html` file."""
|
||||
if "sub-ratings" in attrs.get("class", ""):
|
||||
return True
|
||||
|
||||
|
||||
class Exporter(BaseExporter):
|
||||
def __init__(self, username: str):
|
||||
super().__init__(site=Site.LICHESS.value, username=username)
|
||||
|
@ -170,18 +176,30 @@ class Exporter(BaseExporter):
|
|||
self.stats_soup = None
|
||||
try:
|
||||
with open(self.path_coach_file(username, "stats.html"), "r") as f:
|
||||
self.stats_soup = BeautifulSoup(f.read(), "html.parser")
|
||||
stats_strainer = SoupStrainer(_stats_filter)
|
||||
self.stats_soup = BeautifulSoup(
|
||||
f.read(), "html.parser", parse_only=stats_strainer
|
||||
)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
def export_rapid(self):
|
||||
return self._find_rating("rapid")
|
||||
|
||||
def export_blitz(self):
|
||||
return self._find_rating("blitz")
|
||||
|
||||
def export_bullet(self):
|
||||
return self._find_rating("bullet")
|
||||
|
||||
def _find_rating(self, name):
|
||||
if self.stats_soup is None:
|
||||
return None
|
||||
|
||||
rapid = self.stats_soup.find("a", href=f"/@/{self.username}/perf/rapid")
|
||||
if rapid is None:
|
||||
anchor = self.stats_soup.find("a", href=f"/@/{self.username}/perf/{name}")
|
||||
if anchor is None:
|
||||
return None
|
||||
rating = rapid.find("rating")
|
||||
rating = anchor.find("rating")
|
||||
if rating is None:
|
||||
return None
|
||||
strong = rating.find("strong")
|
||||
|
|
Loading…
Reference in New Issue