feat: support achievement

pull/48/head
xtaodada 2 years ago
parent d49c1489a8
commit 69809e8776
No known key found for this signature in database
GPG Key ID: 4CBB3F4FA8C85659

@ -9,9 +9,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added ### Added
- none - Achievements
- added `IAchievementNf` class.
- added `NotificationAchievement` class.
- added `Achievement` class.
- added `get_achievements` method at `UserActions` class.
- added `achievements` property at `UserDetailed` class.
## [0.4.0] 2023-01-18 ## [0.4.0] 2023-01-18

@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, AsyncIterator, Literal, Optional
from mipac.errors.base import NotExistRequiredData, ParameterError from mipac.errors.base import NotExistRequiredData, ParameterError
from mipac.http import HTTPClient, Route from mipac.http import HTTPClient, Route
from mipac.models.user import LiteUser, UserDetailed from mipac.models.user import LiteUser, UserDetailed, Achievement
from mipac.util import cache, check_multi_arg, remove_dict_empty from mipac.util import cache, check_multi_arg, remove_dict_empty
if TYPE_CHECKING: if TYPE_CHECKING:
@ -30,7 +30,9 @@ class UserActions:
ログインしているユーザーの情報を取得します ログインしているユーザーの情報を取得します
""" """
res = await self.__session.request(Route('POST', '/api/i'), auth=True) res = await self.__session.request(
Route('POST', '/api/i'), auth=True, lower=True,
)
return UserDetailed(res, client=self.__client) # TODO: 自分用のクラスに変更する return UserDetailed(res, client=self.__client) # TODO: 自分用のクラスに変更する
def get_profile_link( def get_profile_link(
@ -309,3 +311,23 @@ class UserActions:
else LiteUser(user, client=self.__client) else LiteUser(user, client=self.__client)
for user in res for user in res
] ]
async def get_achievements(
self,
user_id: str | None = None
) -> list[Achievement]:
""" Get achievements of user. """
user_id = user_id or self.__user and self.__user.id
if not user_id:
raise ParameterError('user_id is required')
data = {
'userId': user_id,
}
res = await self.__session.request(
Route('POST', '/api/users/achievements'),
json=data, auth=True, lower=True,
)
return [Achievement(i) for i in res]

@ -15,6 +15,7 @@ if TYPE_CHECKING:
INoteNf, INoteNf,
IPollEndNf, IPollEndNf,
IReactionNf, IReactionNf,
IAchievementNf,
) )
@ -141,3 +142,16 @@ class NotificationReaction(Notification):
@property @property
def reaction(self) -> str: def reaction(self) -> str:
return self.__notification['reaction'] return self.__notification['reaction']
class NotificationAchievement(Notification):
def __init__(
self, notification: IAchievementNf, *, client: ClientManager,
) -> None:
super().__init__(notification, client=client)
self.__notification: IAchievementNf = notification
self.__client: ClientManager = client
@property
def achievement(self) -> str:
return self.__notification['achievement']

@ -5,12 +5,13 @@ from typing import TYPE_CHECKING, Literal
from mipac.models.lite.user import LiteUser from mipac.models.lite.user import LiteUser
from mipac.models.note import Note from mipac.models.note import Note
from mipac.types.page import IPage from mipac.types.page import IPage
from mipac.types.user import IFollowRequest, IUserDetailed, IUserDetailedField from mipac.types.user import IFollowRequest, IUserDetailed, \
IUserDetailedField, IAchievement
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
__all__ = ('UserDetailed', 'FollowRequest', 'LiteUser') __all__ = ('UserDetailed', 'FollowRequest', 'LiteUser', 'Achievement')
class FollowRequest: class FollowRequest:
@ -31,6 +32,19 @@ class FollowRequest:
return LiteUser(self.__request['followee'], client=self.__client) return LiteUser(self.__request['followee'], client=self.__client)
class Achievement:
def __init__(self, detail: IAchievement):
self.__detail: IAchievement = detail
@property
def name(self) -> str:
return self.__detail['name']
@property
def unlocked_at(self) -> int:
return self.__detail['unlocked_at']
class UserDetailed(LiteUser): class UserDetailed(LiteUser):
__slots__ = ( __slots__ = (
'__detail', '__detail',
@ -41,6 +55,10 @@ class UserDetailed(LiteUser):
super().__init__(user=user, client=client) super().__init__(user=user, client=client)
self.__detail = user self.__detail = user
@property
def achievements(self) -> list[Achievement]:
return [Achievement(i) for i in self.__detail.get('achievements', [])]
@property @property
def fields(self) -> list[IUserDetailedField]: def fields(self) -> list[IUserDetailedField]:
return self.__detail['fields'] return self.__detail['fields']
@ -178,6 +196,10 @@ class UserDetailed(LiteUser):
def location(self) -> str | None: def location(self) -> str | None:
return self.__detail.get('location') return self.__detail.get('location')
@property
def logged_in_days(self) -> int | None:
return self.__detail.get('logged_in_days')
@property @property
def pinned_page(self) -> IPage | None: def pinned_page(self) -> IPage | None:
return self.__detail.get('pinned_page') return self.__detail.get('pinned_page')

@ -274,6 +274,7 @@ ENDPOINTS = Literal[
'/api/test', '/api/test',
'/api/username/available', '/api/username/available',
'/api/users', '/api/users',
'/api/users/achievements',
'/api/users/clips', '/api/users/clips',
'/api/users/followers', '/api/users/followers',
'/api/users/following', '/api/users/following',

@ -40,3 +40,7 @@ class IReactionNf(INotification):
user: ILiteUser user: ILiteUser
user_id: str user_id: str
note: INote note: INote
class IAchievementNf(INotification):
achievement: str

@ -13,6 +13,7 @@ __all__ = (
'ILiteUser', 'ILiteUser',
'IUserDetailed', 'IUserDetailed',
'IUserDetailedField', 'IUserDetailedField',
'IAchievement',
) )
@ -25,6 +26,11 @@ class ISignin(TypedDict):
success: bool success: bool
class IAchievement(TypedDict):
name: str
unlocked_at: int
class IUserRequired(TypedDict): class IUserRequired(TypedDict):
id: str id: str
username: str username: str
@ -73,6 +79,7 @@ class IUserDetailedRequired(ILiteUser):
class IUserDetailed(IUserDetailedRequired, total=False): class IUserDetailed(IUserDetailedRequired, total=False):
achievements: List[IAchievement]
banner_blurhash: str banner_blurhash: str
banner_color: str banner_color: str
banner_url: str banner_url: str
@ -83,6 +90,7 @@ class IUserDetailed(IUserDetailedRequired, total=False):
lang: str lang: str
last_fetched_at: str last_fetched_at: str
location: str location: str
logged_in_days: int
pinned_page: IPage pinned_page: IPage
pinned_page_id: str pinned_page_id: str
updated_at: str updated_at: str

@ -373,6 +373,11 @@ def upper_to_lower(
field[default_key] = data[attr] field[default_key] = data[attr]
if isinstance(field[default_key], dict) and nest: if isinstance(field[default_key], dict) and nest:
field[default_key] = upper_to_lower(field[default_key]) field[default_key] = upper_to_lower(field[default_key])
elif isinstance(field[default_key], list) and nest:
field[default_key] = [
upper_to_lower(i) if isinstance(i, dict)
else i for i in field[default_key]
]
return field return field

Loading…
Cancel
Save