Export rapid ratings.
parent
e050d13aa7
commit
36d471e395
|
@ -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")
|
||||||
|
|
|
@ -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(
|
||||||
[
|
[
|
||||||
|
|
|
@ -111,24 +111,18 @@ 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}",
|
||||||
self.log(
|
username=username,
|
||||||
[
|
filename=self.path_coach_file(username, f"{username}.html"),
|
||||||
(AnsiColor.INFO, "[INFO]"),
|
|
||||||
(None, ": Skipping download for coach "),
|
|
||||||
(AnsiColor.DATA, username),
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
return
|
used_network2 = await self._download_profile_file(
|
||||||
|
url=f"https://lichess.org/@/{username}",
|
||||||
response, _unused_status = await self.request(
|
username=username,
|
||||||
url=f"https://lichess.org/coach/{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(
|
self.log(
|
||||||
[
|
[
|
||||||
(AnsiColor.INFO, "[INFO]"),
|
(AnsiColor.INFO, "[INFO]"),
|
||||||
|
@ -136,11 +130,65 @@ class Scraper(BaseScraper):
|
||||||
(AnsiColor.DATA, username),
|
(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):
|
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
|
||||||
|
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
|
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