Export blitz and bullet ratings.

pull/3/head
Joshua Potter 2023-12-01 07:10:58 -07:00
parent 36d471e395
commit d549e5f5eb
3 changed files with 49 additions and 9 deletions

View File

@ -187,3 +187,9 @@ class Exporter(BaseExporter):
def export_rapid(self) -> Union[int, None]: def export_rapid(self) -> Union[int, None]:
return self.stats_json.get("rapid", {}).get("rating") 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")

View File

@ -4,8 +4,18 @@ from typing_extensions import TypedDict
class Export(TypedDict, total=False): 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 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): class BaseExporter(Repo):
@ -16,13 +26,19 @@ class BaseExporter(Repo):
def export_rapid(self) -> Union[int, None]: def export_rapid(self) -> Union[int, None]:
raise NotImplementedError() raise NotImplementedError()
def export_blitz(self) -> Union[int, None]:
raise NotImplementedError()
def export_bullet(self) -> Union[int, None]:
raise NotImplementedError()
def export(self) -> Export: def export(self) -> Export:
"""Transform coach-specific data into uniform format.""" """Transform coach-specific data into uniform format."""
export: Export = {} export: Export = {}
rapid = self.export_rapid() _insert(export, "rapid", self.export_rapid())
if rapid: _insert(export, "blitz", self.export_blitz())
export["rapid"] = rapid _insert(export, "bullet", self.export_bullet())
self.log( self.log(
[ [

View File

@ -6,7 +6,7 @@ import os.path
from app.repo import AnsiColor, Site from app.repo import AnsiColor, Site
from app.scraper import BaseScraper from app.scraper import BaseScraper
from app.exporter import BaseExporter from app.exporter import BaseExporter
from bs4 import BeautifulSoup from bs4 import BeautifulSoup, SoupStrainer
from typing import List from typing import List
@ -163,6 +163,12 @@ class Scraper(BaseScraper):
return True 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): class Exporter(BaseExporter):
def __init__(self, username: str): def __init__(self, username: str):
super().__init__(site=Site.LICHESS.value, username=username) super().__init__(site=Site.LICHESS.value, username=username)
@ -170,18 +176,30 @@ class Exporter(BaseExporter):
self.stats_soup = None self.stats_soup = None
try: try:
with open(self.path_coach_file(username, "stats.html"), "r") as f: 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: except FileNotFoundError:
pass pass
def export_rapid(self): 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: if self.stats_soup is None:
return None return None
rapid = self.stats_soup.find("a", href=f"/@/{self.username}/perf/rapid") anchor = self.stats_soup.find("a", href=f"/@/{self.username}/perf/{name}")
if rapid is None: if anchor is None:
return None return None
rating = rapid.find("rating") rating = anchor.find("rating")
if rating is None: if rating is None:
return None return None
strong = rating.find("strong") strong = rating.find("strong")