Skip to content

Commit

Permalink
fix (docs/types): double-check typing definitions (#207)
Browse files Browse the repository at this point in the history
* fix (docs/types): double-check type definitions

* fix: add missing HitResults and document

* fix: add missing HitResults and document

* chore: reorder score statistics
  • Loading branch information
NiceAesth authored Jan 23, 2024
1 parent f54001e commit 3d930f8
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 70 deletions.
68 changes: 67 additions & 1 deletion aiosu/models/beatmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,20 @@
"BeatmapRankStatus",
"BeatmapUserPlaycount",
"Beatmapset",
"BeatmapsetBundleFilterType",
"BeatmapsetCategory",
"BeatmapsetDiscussion",
"BeatmapsetDiscussionPost",
"BeatmapsetDiscussionPostResponse",
"BeatmapsetDiscussionResponse",
"BeatmapsetDiscussionVoteResponse",
"BeatmapsetDiscussionVoteScoreType",
"BeatmapsetDisscussionType",
"BeatmapsetEvent",
"BeatmapsetEventComment",
"BeatmapsetEventType",
"BeatmapsetGenre",
"BeatmapsetLanguage",
"BeatmapsetRequestStatus",
"BeatmapsetSearchResponse",
"BeatmapsetSortType",
Expand All @@ -73,6 +78,19 @@
"favourites_desc",
]

BeatmapsetCategory = Literal[
"any",
"leaderboard",
"ranked",
"qualified",
"loved",
"favourites",
"pending",
"wip",
"graveyard",
"mine",
]

BeatmapsetBundleFilterType = Literal[
"any",
"currently",
Expand Down Expand Up @@ -128,6 +146,11 @@
"never_ranked",
]

BeatmapsetDiscussionVoteScoreType = Literal[
"1",
"-1",
]

UserBeatmapType = Literal["favourite", "graveyard", "loved", "ranked", "pending"]

BEATMAP_RANK_STATUS_NAMES = {
Expand All @@ -141,6 +164,49 @@
}


@unique
class BeatmapsetGenre(Enum):
UNSPECIFIED = 1
VIDEO_GAME = 2
ANIME = 3
ROCK = 4
POP = 5
OTHER = 6
NOVELTY = 7
HIP_HOP = 9
ELECTRONIC = 10
METAL = 11
CLASSICAL = 12
FOLK = 13
JAZZ = 14

@classmethod
def _missing_(cls, _: object) -> BeatmapsetGenre:
return BeatmapsetGenre.UNSPECIFIED


@unique
class BeatmapsetLanguage(Enum):
UNSPECIFIED = 1
ENGLISH = 2
JAPANESE = 3
CHINESE = 4
INSTRUMENTAL = 5
KOREAN = 6
FRENCH = 7
GERMAN = 8
SWEDISH = 9
SPANISH = 10
ITALIAN = 11
RUSSIAN = 12
POLISH = 13
OTHER = 14

@classmethod
def _missing_(cls, _: object) -> BeatmapsetLanguage:
return BeatmapsetLanguage.UNSPECIFIED


@unique
class BeatmapRankStatus(Enum):
GRAVEYARD = -2
Expand Down Expand Up @@ -560,7 +626,7 @@ class BeatmapsetEventComment(BaseModel):
class BeatmapsetEvent(BaseModel):
id: int
type: BeatmapsetEventType
r"""Information on types: https://github.com/ppy/osu-web/blob/master/resources/assets/lib/interfaces/beatmapset-event-json.ts"""
r"""Information on types: https://github.com/ppy/osu-web/blob/master/resources/js/interfaces/beatmapset-event-json.ts"""
created_at: datetime
user_id: int
beatmapset: Optional[Beatmapset] = None
Expand Down
35 changes: 18 additions & 17 deletions aiosu/models/lazer.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,28 @@ def __str__(self) -> str:


class LazerScoreStatistics(BaseModel):
ok: int = 0
meh: int = 0
"""Relevant information:
https://github.com/ppy/osu/blob/master/osu.Game/Rulesets/Scoring/HitResult.cs
https://github.com/ppy/osu-web/blob/master/resources/js/interfaces/solo-score-json.ts
"""

miss: int = 0
meh: int = 0
ok: int = 0
good: int = 0
great: int = 0
ignore_hit: int = 0
ignore_miss: int = 0
large_bonus: int = 0
large_tick_hit: int = 0
perfect: int = 0
small_tick_miss: int = 0
small_tick_hit: int = 0
large_tick_miss: int = 0
large_tick_hit: int = 0
small_bonus: int = 0
small_tick_hit: int = 0
small_tick_miss: int = 0
good: int = 0
perfect: int = 0
large_bonus: int = 0
ignore_miss: int = 0
ignore_hit: int = 0
combo_break: int = 0
slider_tail_hit: int = 0
legacy_combo_increase: int = 0

@property
Expand Down Expand Up @@ -214,10 +222,3 @@ def mode(self) -> Gamemode:
@cached_property
def mods_str(self) -> str:
return "".join(str(mod) for mod in self.mods)

@model_validator(mode="before")
@classmethod
def _fail_rank(cls, values: dict[str, object]) -> dict[str, object]:
if not values["passed"]:
values["rank"] = "F"
return values
6 changes: 3 additions & 3 deletions aiosu/models/multiplayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
"MultiplayerQueueMode",
"MultiplayerRoom",
"MultiplayerRoomCategory",
"MultiplayerRoomGroupType",
"MultiplayerRoomMode",
"MultiplayerRoomTypeGroup",
"MultiplayerRoomsResponse",
"MultiplayerScore",
"MultiplayerScoreSortType",
Expand Down Expand Up @@ -64,7 +64,7 @@
]
MultiplayerRoomMode = Literal["owned", "participated", "ended"]
MultiplayerRoomCategory = Literal["normal", "spotlight", "featured_artist"]
MultiplayerRoomTypeGroup = Literal["playlists", "realtime"]
MultiplayerRoomGroupType = Literal["playlists", "realtime"]
MultiplayerQueueMode = Literal["host_only", "all_players", "all_players_round_robin"]


Expand Down Expand Up @@ -163,7 +163,7 @@ class MultiplayerRoom(BaseModel):
id: int
name: str
category: MultiplayerRoomCategory
type: MultiplayerRoomTypeGroup
type: MultiplayerRoomGroupType
user_id: int
channel_id: int
active: bool
Expand Down
9 changes: 1 addition & 8 deletions aiosu/models/score.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ class ScoreWeight(BaseModel):


class ScoreStatistics(BaseModel):
count_miss: int
count_50: int
count_100: int
count_300: int
count_miss: int
count_geki: int
count_katu: int

Expand Down Expand Up @@ -210,13 +210,6 @@ def completion(self) -> Optional[float]:

return calculate_score_completion(self.mode, self.statistics, self.beatmap)

@model_validator(mode="before")
@classmethod
def _fail_rank(cls, values: dict[str, object]) -> dict[str, object]:
if not values["passed"]:
values["rank"] = "F"
return values

async def request_beatmap(self, client: v1.Client) -> None:
r"""For v1 Scores: requests the beatmap from the API and sets it.
Expand Down
23 changes: 14 additions & 9 deletions aiosu/v1/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,25 @@ async def get_user(self, user_query: Union[str, int], **kwargs: Any) -> User:
:Keyword Arguments:
* *mode* (``aiosu.models.gamemode.Gamemode``) --
Optional, gamemode to search for, defaults to standard
* *qtype* (``str``) --
* *qtype* (``aiosu.models.user.UserQueryType``) --
Optional, "string" or "id". Type of the user_query
* *event_days* (``aiosu.models.gamemode.Gamemode``) --
* *event_days* (``int``) --
Optional, max number of days since last event, Min: 1, Max: 31, defaults to 1
:raises ValueError: If event_days is not between 1 and 31
:raises APIException: Contains status code and error message
:return: Requested user
:rtype: list[aiosu.models.user.User]
"""
url = f"{self.base_url}/api/get_user"
if not 1 <= (event_days := kwargs.pop("limit", 1)) <= 31:
raise ValueError(
"Invalid event_days specified. Limit must be between 1 and 31",
)
params = {
"k": self.token,
"u": user_query,
"event_days": kwargs.pop("event_days", 1),
"event_days": event_days,
"m": int(Gamemode(kwargs.pop("mode", 0))),
}
add_param(
Expand Down Expand Up @@ -186,7 +191,7 @@ async def __get_type_scores(
Optional, gamemode to search for, defaults to standard
* *limit* (``int``) --
Optional, number of scores to get, defaults to 10
* *qtype* (``str``) --
* *qtype* (``aiosu.models.user.UserQueryType``) --
Optional, "string" or "id". Type of the user_query
:raises ValueError: If request_type is invalid
Expand Down Expand Up @@ -234,7 +239,7 @@ async def get_user_recents(
Optional, gamemode to search for, defaults to standard
* *limit* (``int``) --
Optional, number of scores to get, Min: 1, Max: 50, defaults to 50
* *qtype* (``str``) --
* *qtype* (``aiosu.models.user.UserQueryType``) --
Optional, "string" or "id". Type of the user_query
:raises ValueError: If limit is not between 1 and 50
Expand Down Expand Up @@ -263,7 +268,7 @@ async def get_user_bests(
Optional, gamemode to search for, defaults to standard
* *limit* (``int``) --
Optional, number of scores to get, Min: 1, Max: 100, defaults to 100
* *qtype* (``str``) --
* *qtype* (``aiosu.models.user.UserQueryType``) --
Optional, "string" or "id". Type of the user_query
:raises ValueError: If limit is not between 1 and 100
Expand Down Expand Up @@ -300,7 +305,7 @@ async def get_beatmap(self, **kwargs: Any) -> list[Beatmapset]:
Optional, The MD5 hash of the beatmap
* *user_query* (``Union[str, int]``) --
Optional, username or ID to search by
* *qtype* (``str``) --
* *qtype* (``aiosu.models.user.UserQueryType``) --
Optional, "string" or "id". Type of the user_query
:raises ValueError: If limit is not between 1 and 500
Expand Down Expand Up @@ -356,7 +361,7 @@ async def get_beatmap_scores(self, beatmap_id: int, **kwargs: Any) -> list[Score
Optional, number of scores to get, Min: 1, Max: 100, defaults to 100
* *user_query* (``Union[str, int]``) --
Optional, username or ID to search by
* *qtype* (``str``) --
* *qtype* (``aiosu.models.user.UserQueryType``) --
Optional, "string" or "id". Type of the user_query
:raises ValueError: If limit is not between 1 and 100
Expand Down Expand Up @@ -421,7 +426,7 @@ async def get_replay(self, **kwargs: Any) -> ReplayCompact:
Optional, the ID of the beatmap, specified together with user_query
* *user_query* (``Union[str, int]``) --
Optional, username or ID to search by, specified together with beatmap_id
* *qtype* (``str``) --
* *qtype* (``aiosu.models.user.UserQueryType``) --
Optional, "string" or "id". Type of the user_query
:raises ValueError: If neither score_id nor beatmap_id + user_id specified
Expand Down
Loading

0 comments on commit 3d930f8

Please sign in to comment.