Export rapid ratings.

pull/3/head
Joshua Potter 2023-11-30 20:35:20 -07:00
parent e050d13aa7
commit 36d471e395
3 changed files with 71 additions and 22 deletions

View File

@ -185,5 +185,5 @@ class Exporter(BaseExporter):
except FileNotFoundError: except FileNotFoundError:
pass pass
def export_fide_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")

View File

@ -4,7 +4,8 @@ from typing_extensions import TypedDict
class Export(TypedDict, total=False): class Export(TypedDict, total=False):
fide_rapid: int # The coach's rapid rating as listed on the site they were sourced from.
rapid: int
class BaseExporter(Repo): class BaseExporter(Repo):
@ -12,16 +13,16 @@ class BaseExporter(Repo):
super().__init__(site) super().__init__(site)
self.username = username self.username = username
def export_fide_rapid(self) -> Union[int, None]: def export_rapid(self) -> Union[int, None]:
raise NotImplementedError() 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 = {}
fide_rapid = self.export_fide_rapid() rapid = self.export_rapid()
if fide_rapid: if rapid:
export["fide_rapid"] = fide_rapid export["rapid"] = rapid
self.log( self.log(
[ [

View File

@ -111,8 +111,27 @@ class Scraper(BaseScraper):
@param username @param username
The coach username corresponding to the downloaded files. The coach username corresponding to the downloaded files.
""" """
filepath = self.path_coach_file(username, f"{username}.html") used_network1 = await self._download_profile_file(
if os.path.isfile(filepath): url=f"https://lichess.org/coach/{username}",
username=username,
filename=self.path_coach_file(username, f"{username}.html"),
)
used_network2 = await self._download_profile_file(
url=f"https://lichess.org/@/{username}",
username=username,
filename=self.path_coach_file(username, "stats.html"),
)
if any([used_network1, used_network2]):
self.log(
[
(AnsiColor.INFO, "[INFO]"),
(None, ": Downloaded data for coach "),
(AnsiColor.DATA, username),
]
)
await asyncio.sleep(SLEEP_SECS)
else:
self.log( self.log(
[ [
(AnsiColor.INFO, "[INFO]"), (AnsiColor.INFO, "[INFO]"),
@ -120,27 +139,56 @@ class Scraper(BaseScraper):
(AnsiColor.DATA, username), (AnsiColor.DATA, username),
] ]
) )
return
response, _unused_status = await self.request( async def _download_profile_file(self, url: str, username: str, filename: str):
url=f"https://lichess.org/coach/{username}" """Writes the contents of url into the specified file.
)
@param url
The URL of the file to download.
@param username
The coach username corresponding to the downloaded file.
@param filename
The output file to write the downloaded content to.
@return:
True if we make a network request. False otherwise.
"""
if os.path.isfile(filename):
return False
response, _unused_status = await self.request(url)
if response is not None: if response is not None:
with open(filepath, "w") as f: with open(filename, "w") as f:
f.write(response) f.write(response)
self.log( return True
[
(AnsiColor.INFO, "[INFO]"),
(None, ": Downloaded data for coach "),
(AnsiColor.DATA, username),
]
)
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)
def export_fide_rapid(self): self.stats_soup = None
return None try:
with open(self.path_coach_file(username, "stats.html"), "r") as f:
self.stats_soup = BeautifulSoup(f.read(), "html.parser")
except FileNotFoundError:
pass
def export_rapid(self):
if self.stats_soup is None:
return None
rapid = self.stats_soup.find("a", href=f"/@/{self.username}/perf/rapid")
if rapid is None:
return None
rating = rapid.find("rating")
if rating is None:
return None
strong = rating.find("strong")
if strong is None:
return None
value = strong.get_text()
if value[-1] == "?":
value = value[:-1]
return value