Export blitz and bullet ratings.
parent
36d471e395
commit
d549e5f5eb
|
@ -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")
|
||||||
|
|
|
@ -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(
|
||||||
[
|
[
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in New Issue