Source code for codingame.codingamer

import typing
from typing import Optional  # appears so many times

from .abc import BaseUser
from .exceptions import LoginRequired
from .types.codingamer import Category
from .types.codingamer import CodinGamerFromHandle as CodinGamerFromHandleDict
from .types.codingamer import PartialCodinGamer as PartialCodinGamerDict

if typing.TYPE_CHECKING:
    from .state import ConnectionState

__all__ = ("PartialCodinGamer", "CodinGamer")


[docs]class PartialCodinGamer(BaseUser): """Represents a partial CodinGamer. This class doesn't have all the data of a CodinGamer. Use ``client.get_codingamer(partial_codingamer.public_handle)`` for that. Attributes ----------- public_handle: :class:`str` Public handle of the CodinGamer (hexadecimal str). id: :class:`int` ID of the CodinGamer. Last 7 digits of the :attr:`public_handle` reversed. pseudo: Optional :class:`str` Pseudo of the CodinGamer. country_id: :class:`str` Country ID of the CodinGamer. avatar: Optional :class:`int` Avatar ID of the CodinGamer. You can get the avatar url with :attr:`avatar_url`. cover: Optional :class:`int` Cover ID of the CodinGamer. You can get the cover url with :attr:`cover_url`. """ public_handle: str id: int pseudo: Optional[str] country_id: Optional[str] avatar: Optional[int] cover: Optional[int] avatar_url: Optional[str] cover_url: Optional[str] __slots__ = ("country_id",) def __init__(self, state: "ConnectionState", data: PartialCodinGamerDict): self.public_handle = data["publicHandle"] self.id = data["userId"] self.country_id = data.get("countryId") # account for empty strings and replace them by None self.pseudo = data.get("pseudo") or None self.avatar = data.get("avatar") self.cover = data.get("cover") super().__init__(state) @property def profile_url(self) -> str: """:class:`str`: The URL of the CodinGamer profile.""" return f"https://www.codingame.com/profile/{self.public_handle}"
[docs] def get_followers( self, ) -> typing.Union[ typing.Iterator["CodinGamer"], typing.AsyncIterator["CodinGamer"] ]: """|maybe_coro| Get all the followers of a CodinGamer. You need to be logged in to get the followers or else a :exc:`LoginRequired` will be raised. If you can't log in, you can use :meth:`CodinGamer.get_followers_ids` instead. .. note:: This property is a generator. .. warning:: The :attr:`~CodinGamer.xp` attribute of the following codingamers is ``None``. Raises ------ :exc:`LoginRequired` The Client needs to log in. See :meth:`Client.login`. Yields ------- :class:`CodinGamer` The follower. """ if not self._state.logged_in: raise LoginRequired() if self._state.is_async: async def _get_followers(): followers = await self._state.http.get_codingamer_followers( self.id, self._state.codingamer.id ) for follower in followers: yield CodinGamer(self._state, follower) else: def _get_followers(): followers = self._state.http.get_codingamer_followers( self.id, self._state.codingamer.id ) for follower in followers: yield CodinGamer(self._state, follower) return _get_followers()
[docs] def get_followers_ids( self, ) -> typing.Union[typing.List[int], typing.Awaitable[typing.List[int]]]: """|maybe_coro| Get all the IDs of the followers of a CodinGamer. Returns ------- :class:`list` of :class:`int` The CodinGamer's followers IDs. See :attr:`CodinGamer.id`. """ return self._state.http.get_codingamer_follower_ids(self.id)
[docs] def get_followed( self, ) -> typing.Union[ typing.Iterator["CodinGamer"], typing.AsyncIterator["CodinGamer"] ]: """|maybe_coro| Get all the followed CodinGamers. You need to be logged in to get the followed CodinGamers or else a :exc:`LoginRequired` will be raised. If you can't log in, you can use :meth:`CodinGamer.get_followed_ids` instead. .. note:: This property is a generator. .. warning:: The :attr:`~CodinGamer.xp` attribute of the followed codingamers is ``None``. Raises ------ :exc:`LoginRequired` The Client needs to log in. See :meth:`Client.login`. Yields ------- :class:`CodinGamer` The followed CodinGamer. """ if not self._state.logged_in: raise LoginRequired() if self._state.is_async: async def _get_followed(): followeds = await self._state.http.get_codingamer_following( self.id, self._state.codingamer.id ) for followed in followeds: yield CodinGamer(self._state, followed) else: def _get_followed(): followeds = self._state.http.get_codingamer_following( self.id, self._state.codingamer.id ) for followed in followeds: yield CodinGamer(self._state, followed) return _get_followed()
[docs] def get_followed_ids( self, ) -> typing.Union[typing.List[int], typing.Awaitable[typing.List[int]]]: """|maybe_coro| Get all the IDs of the followed CodinGamers. Returns ------- :class:`list` of :class:`int` The IDs of the followed CodinGamers. See :attr:`CodinGamer.id`. """ return self._state.http.get_codingamer_following_ids(self.id)
[docs] def get_clash_of_code_rank( self, ) -> typing.Union[int, typing.Awaitable[int]]: """|maybe_coro| Get the Clash of Code rank of the CodinGamer. Returns ------- :class:`int` The Clash of Code rank of the CodinGamer. """ if self._state.is_async: async def _get_clash_of_code_rank() -> int: data = await self._state.http.get_codingamer_clash_of_code_rank( self.id ) return data["rank"] else: def _get_clash_of_code_rank() -> int: data = self._state.http.get_codingamer_clash_of_code_rank( self.id ) return data["rank"] return _get_clash_of_code_rank()
[docs]class CodinGamer(PartialCodinGamer): """Represents a CodinGamer. Attributes ----------- public_handle: :class:`str` Public handle of the CodinGamer (hexadecimal str). id: :class:`int` ID of the CodinGamer. Last 7 digits of the :attr:`public_handle` reversed. pseudo: Optional :class:`str` Pseudo of the CodinGamer. rank: :class:`int` Worldwide rank of the CodinGamer. level: :class:`int` Level of the CodinGamer. xp: :class:`int` XP points of the CodinGamer. country_id: :class:`str` Country ID of the CodinGamer. category: Optional :class:`str` Category of the CodinGamer. Can be ``STUDENT`` or ``PROFESSIONAL``. .. note:: You can use :attr:`student` and :attr:`professional` to get a :class:`bool` that describes the CodinGamer's category. student: :class:`bool` Whether the CodinGamer is a student. professional: :class:`bool` Whether the CodinGamer is a professional. tagline: Optional :class:`str` Tagline of the CodinGamer. biography: Optional :class:`str` Biography of the CodinGamer. company: Optional :class:`str` Company of the CodinGamer. school: Optional :class:`str` School of the CodinGamer. avatar: Optional :class:`int` Avatar ID of the CodinGamer. You can get the avatar url with :attr:`avatar_url`. cover: Optional :class:`int` Cover ID of the CodinGamer. You can get the cover url with :attr:`cover_url`. """ public_handle: str id: int pseudo: Optional[str] rank: int level: int xp: Optional[int] country_id: Optional[str] category: Optional[Category] student: bool professional: bool tagline: Optional[str] biography: Optional[str] company: Optional[str] school: Optional[str] avatar: Optional[int] cover: Optional[int] avatar_url: Optional[str] cover_url: Optional[str] __slots__ = ( "rank", "level", "xp", "category", "student", "professional", "tagline", "biography", "company", "school", ) def __init__( self, state: "ConnectionState", data: CodinGamerFromHandleDict ): self.rank = data["rank"] self.level = data["level"] self.xp = data.get("xp") # only None for followers/followed self.category = ( data["category"] if data.get("category", "UNKNOWN") != "UNKNOWN" else None ) self.student = self.category == "STUDENT" self.professional = self.category == "PROFESSIONAL" # account for empty strings and replace them by None self.tagline = data.get("tagline") or None self.biography = data.get("biography") or None self.company = ( data.get("company") or data.get("companyField") or data.get("formValues", {}).get("company") or None ) self.school = ( data.get("school") or data.get("schoolField") or data.get("formValues", {}).get("school") or None ) super().__init__(state, data)