Export rapid ratings.
parent
e050d13aa7
commit
36d471e395
|
@ -185,5 +185,5 @@ class Exporter(BaseExporter):
|
|||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
def export_fide_rapid(self) -> Union[int, None]:
|
||||
def export_rapid(self) -> Union[int, None]:
|
||||
return self.stats_json.get("rapid", {}).get("rating")
|
||||
|
|
|
@ -4,7 +4,8 @@ from typing_extensions import TypedDict
|
|||
|
||||
|
||||
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):
|
||||
|
@ -12,16 +13,16 @@ class BaseExporter(Repo):
|
|||
super().__init__(site)
|
||||
self.username = username
|
||||
|
||||
def export_fide_rapid(self) -> Union[int, None]:
|
||||
def export_rapid(self) -> Union[int, None]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def export(self) -> Export:
|
||||
"""Transform coach-specific data into uniform format."""
|
||||
export: Export = {}
|
||||
|
||||
fide_rapid = self.export_fide_rapid()
|
||||
if fide_rapid:
|
||||
export["fide_rapid"] = fide_rapid
|
||||
rapid = self.export_rapid()
|
||||
if rapid:
|
||||
export["rapid"] = rapid
|
||||
|
||||
self.log(
|
||||
[
|
||||
|
|
|
@ -111,24 +111,18 @@ class Scraper(BaseScraper):
|
|||
@param username
|
||||
The coach username corresponding to the downloaded files.
|
||||
"""
|
||||
filepath = self.path_coach_file(username, f"{username}.html")
|
||||
if os.path.isfile(filepath):
|
||||
self.log(
|
||||
[
|
||||
(AnsiColor.INFO, "[INFO]"),
|
||||
(None, ": Skipping download for coach "),
|
||||
(AnsiColor.DATA, username),
|
||||
]
|
||||
used_network1 = await self._download_profile_file(
|
||||
url=f"https://lichess.org/coach/{username}",
|
||||
username=username,
|
||||
filename=self.path_coach_file(username, f"{username}.html"),
|
||||
)
|
||||
return
|
||||
|
||||
response, _unused_status = await self.request(
|
||||
url=f"https://lichess.org/coach/{username}"
|
||||
used_network2 = await self._download_profile_file(
|
||||
url=f"https://lichess.org/@/{username}",
|
||||
username=username,
|
||||
filename=self.path_coach_file(username, "stats.html"),
|
||||
)
|
||||
if response is not None:
|
||||
with open(filepath, "w") as f:
|
||||
f.write(response)
|
||||
|
||||
if any([used_network1, used_network2]):
|
||||
self.log(
|
||||
[
|
||||
(AnsiColor.INFO, "[INFO]"),
|
||||
|
@ -136,11 +130,65 @@ class Scraper(BaseScraper):
|
|||
(AnsiColor.DATA, username),
|
||||
]
|
||||
)
|
||||
await asyncio.sleep(SLEEP_SECS)
|
||||
else:
|
||||
self.log(
|
||||
[
|
||||
(AnsiColor.INFO, "[INFO]"),
|
||||
(None, ": Skipping download for coach "),
|
||||
(AnsiColor.DATA, username),
|
||||
]
|
||||
)
|
||||
|
||||
async def _download_profile_file(self, url: str, username: str, filename: str):
|
||||
"""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:
|
||||
with open(filename, "w") as f:
|
||||
f.write(response)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class Exporter(BaseExporter):
|
||||
def __init__(self, username: str):
|
||||
super().__init__(site=Site.LICHESS.value, username=username)
|
||||
|
||||
def export_fide_rapid(self):
|
||||
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")
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue