From e4e7ddd527bf55fc4839c0d30eb3af184dcb3742 Mon Sep 17 00:00:00 2001 From: yupix Date: Sat, 24 Dec 2022 17:00:53 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20added=20is=5Fofficial=20att?= =?UTF-8?q?ribute=20a=20Config=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 48 ++++++ mipac/__init__.py | 9 +- mipac/_version.py | 2 +- mipac/actions/admin/__init__.py | 0 mipac/actions/admin/emoji.py | 120 ++++++++++++++ mipac/{manager => actions/admin}/moderator.py | 21 ++- mipac/actions/chart.py | 40 +++++ mipac/actions/favorite.py | 45 ++++++ mipac/actions/follow.py | 150 ++++++++++++++++++ mipac/actions/note.py | 18 +-- mipac/actions/reaction.py | 87 ++++++++++ mipac/actions/user.py | 4 +- mipac/core/__init__.py | 1 - mipac/core/models/__init__.py | 13 -- mipac/core/models/chart.py | 94 ----------- mipac/{manager => }/file.py | 0 mipac/http.py | 6 +- mipac/manager/__init__.py | 5 +- mipac/manager/admin/__init__.py | 3 + mipac/manager/admin/emoji.py | 25 +++ .../admin.py => manager/admin/manager.py} | 16 +- mipac/manager/admin/moderator.py | 39 +++++ mipac/manager/chart.py | 30 +--- mipac/manager/client.py | 10 +- mipac/manager/emoji.py | 69 -------- mipac/manager/favorite.py | 34 ++-- mipac/manager/follow.py | 125 ++------------- mipac/manager/note.py | 22 ++- mipac/manager/reaction.py | 70 ++------ mipac/manager/user.py | 7 + mipac/models/__init__.py | 2 +- mipac/models/chart.py | 126 +++++++++++++++ mipac/models/lite/user.py | 3 +- mipac/models/notification.py | 8 +- mipac/types/chart.py | 20 +-- 35 files changed, 803 insertions(+), 469 deletions(-) create mode 100644 mipac/actions/admin/__init__.py create mode 100644 mipac/actions/admin/emoji.py rename mipac/{manager => actions/admin}/moderator.py (73%) create mode 100644 mipac/actions/chart.py create mode 100644 mipac/actions/favorite.py create mode 100644 mipac/actions/follow.py create mode 100644 mipac/actions/reaction.py delete mode 100644 mipac/core/__init__.py delete mode 100644 mipac/core/models/__init__.py delete mode 100644 mipac/core/models/chart.py rename mipac/{manager => }/file.py (100%) create mode 100644 mipac/manager/admin/emoji.py rename mipac/{actions/admin.py => manager/admin/manager.py} (68%) create mode 100644 mipac/manager/admin/moderator.py delete mode 100644 mipac/manager/emoji.py create mode 100644 mipac/models/chart.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 4059536..e1d31bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,57 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Added +- 💡 added DocString. +- ✨ added `AdminEmojiActions` class. +- ✨ added `AdminManager` class. +- ✨ added `AdminModeratorManager` class. +- ✨ added `ActiveUsersChart` class. +- ✨ added `IDriveChart` class. +- ✨ added `IDriveLocalChart` class. +- ✨ added `IDriveRemoteChart` class. +- ✨ added attribute `is_official` at `Config` class. + - 💡 became `is_ayuskey` attribute is deprecated(I'll remove with v0.4.0) - ✨ added `get_exception_from_id` function. - ✨ Return an exception appropriate for the error encountered. +## Changed + +- 🚚 rename `ActiveUsersChartPayload` class to `IActiveUsersChart` class. +- 🚚 rename `DriveLocalChartPayload` class to `IDriveLocalChart` class. +- 🚚 rename `DriveRemoteChartPayload` class to `IDriveRemoteChart` .class. +- 🚚 rename `DriveChartPayload` class to `IDriveChart` class. +- 💥 **BREAKING CHANGE** + - Moved the reaction attribute of `ClientActions` to `NoteManager`. + - 💡 Change `api.reaction` to `api.note.reaction`. + - Moved methods from `AdminEmojiManager` to `AdminEmojiActions`. + - 💡 Change `api.admin.emoji.add` to `api.admin.emoji.action.add`. + - Moved methods from `AdminModeratorManager` to `AdminModeratorActions`. + - 💡 Change `api.admin.moderator.add` to `api.admin.moderator.action.add`. + - Moved methods from `ChartManager` to `ChartActions`. + - 💡 Change `api.chart.get_active_user` to `api.chat.action.get_active_user`. + - Moved methods from `FollowManager` to `FollowActions`. + - 💡 Change `api.user.follow.add` to `api.user.follow.action.add`. + - Moved methods from `FollowRequestManager` to `FollowRequestActions`. + - 💡 `api.user.follow.action.get_all`. + - Moved some attributes of `NoteActions` to `NoteManager`. + - 💡 Change `api.note.action.reaction.add` to `api.note.reaction.action.add`. + - Moved the reaction attribute of `NoteActions` to `ClientNoteManager`. + - 💡 Change `api.note.action.reaction` to `api.note.reaction.action`. + - 💡 Change `api.note.action.favorite` to `api.note.favorite.action`. + +## Fixed + +- 🐛 can't delete emoji with v12. + +## Removed + +- 🔥 The following attributes have been removed `api.user.action.note` +- 🔥 Delete `RawActiveUsersChart` class. +- 🔥 Delete `RawDriveLocalChart` class. +- 🔥 Delete `RawDriveRemoteChart` class. +- 🔥 Delete `RawDriveChart` class. + + ## [0.3.1] 2022-12-24 ### Added diff --git a/mipac/__init__.py b/mipac/__init__.py index 92d70e3..3e889a7 100644 --- a/mipac/__init__.py +++ b/mipac/__init__.py @@ -10,13 +10,12 @@ del get_versions __path__ = __import__('pkgutil').extend_path(__path__, __name__) +from . import _version from .abstract import * # noqa: F403, F401 +from .actions import * +from .manager import * from .models import * # noqa: F403, F401 from .types import * -from .models import * -from .manager import * -from .actions import * - -from . import _version +from .file import * __version__ = _version.get_versions()['version'] diff --git a/mipac/_version.py b/mipac/_version.py index 539533e..ed8e2ff 100644 --- a/mipac/_version.py +++ b/mipac/_version.py @@ -11,12 +11,12 @@ """Git implementation of _version.py.""" import errno +import functools import os import re import subprocess import sys from typing import Callable, Dict -import functools def get_keywords(): diff --git a/mipac/actions/admin/__init__.py b/mipac/actions/admin/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mipac/actions/admin/emoji.py b/mipac/actions/admin/emoji.py new file mode 100644 index 0000000..9c61edb --- /dev/null +++ b/mipac/actions/admin/emoji.py @@ -0,0 +1,120 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from mipac.abstract.action import AbstractAction +from mipac.errors.base import NotExistRequiredData +from mipac.http import Route +from mipac.util import check_multi_arg + +if TYPE_CHECKING: + from mipac.http import HTTPClient + from mipac.manager.client import ClientActions + + +class AdminEmojiActions(AbstractAction): + def __init__( + self, + emoji_id: None | str = None, + *, + session: HTTPClient, + client: ClientActions + ): + self.__emoji_id = emoji_id + self.__session = session + self.__client = client + + async def add( + self, + file_id: str | None = None, + *, + name: str | None = None, + url: str | None = None, + category: str | None = None, + aliases: list[str] | None = None + ) -> bool: + """絵文字を追加します + + Parameters + ---------- + file_id : str | None, optional + 追加する絵文字のファイルId, by default None + name : str | None, optional + 絵文字名, by default None + url : str | None, optional + 絵文字があるUrl, by default None + category : str | None, optional + 絵文字のカテゴリー, by default None + aliases : list[str] | None, optional + 絵文字のエイリアス, by default None + + Returns + ------- + bool + 成功したかどうか + + Raises + ------ + NotExistRequiredData + 必要なデータが不足している + """ + + if self.__client._config.is_official: + data = {'fileId': file_id} + else: + data = { + 'name': name, + 'url': url, + 'category': category, + 'aliases': aliases, + } + + if not check_multi_arg(file_id, url): + raise NotExistRequiredData('required a file_id or url') + return bool( + await self.__session.request( + Route('POST', '/api/admin/emoji/add'), + json=data, + lower=True, + auth=True, + ) + ) + + async def remove(self, emoji_id: str | None = None) -> bool: + """指定したIdの絵文字を削除します + + Parameters + ---------- + emoji_id : str | None, optional + 削除する絵文字のId, by default None + + Returns + ------- + bool + 成功したかどうか + + Raises + ------ + NotExistRequiredData + Idが不足している + """ + + emoji_id = emoji_id or self.__emoji_id + + if emoji_id is None: + raise NotExistRequiredData('idが不足しています') + + endpoint = ( + '/api/admin/emoji/delete' + if self.__client._config.is_official + else '/api/admin/emoji/remove' + ) + + return bool( + await self.__session.request( + Route('POST', endpoint), + auth=True, + json={'id': emoji_id}, + lower=True, + ) + ) diff --git a/mipac/manager/moderator.py b/mipac/actions/admin/moderator.py similarity index 73% rename from mipac/manager/moderator.py rename to mipac/actions/admin/moderator.py index 38f5cd0..5eeae2a 100644 --- a/mipac/manager/moderator.py +++ b/mipac/actions/admin/moderator.py @@ -1,29 +1,28 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING -from mipac.abstract.manager import AbstractManager -from mipac.http import HTTPClient, Route +from mipac.abstract.action import AbstractAction +from mipac.http import Route if TYPE_CHECKING: - from mipac.client import ClientActions + from mipac.http import HTTPClient + from mipac.manager.client import ClientActions -__all__ = ('AdminModeratorManager',) - -class AdminModeratorManager(AbstractManager): +class AdminModeratorActions(AbstractAction): def __init__( self, - user_id: Optional[str] = None, + user_id: str | None = None, *, session: HTTPClient, client: ClientActions ): - self.__user_id: Optional[str] = user_id self.__session: HTTPClient = session self.__client: ClientActions = client + self.__user_id: str | None = user_id - async def add(self, user_id: Optional[str] = None) -> bool: + async def add(self, user_id: str | None = None) -> bool: """ Add a user as a moderator @@ -48,7 +47,7 @@ class AdminModeratorManager(AbstractManager): ) return bool(res) - async def remove(self, user_id: Optional[str] = None) -> bool: + async def remove(self, user_id: str | None = None) -> bool: """ Unmoderate a user diff --git a/mipac/actions/chart.py b/mipac/actions/chart.py new file mode 100644 index 0000000..27c6278 --- /dev/null +++ b/mipac/actions/chart.py @@ -0,0 +1,40 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from mipac.abstract.action import AbstractAction +from mipac.http import HTTPClient, Route +from mipac.models.chart import ActiveUsersChart, DriveChart + +if TYPE_CHECKING: + from mipac.manager.client import ClientActions + + +class ChartActions(AbstractAction): + def __init__(self, session: HTTPClient, client: ClientActions): + self.__session = session + self.__client = client + + async def get_active_user( + self, span: str = 'day', limit: int = 30, offset: int = 0 + ) -> ActiveUsersChart: + data = {'span': span, 'limit': limit, 'offset': offset} + data = await self.__session.request( + Route('POST', '/api/charts/active-users'), + json=data, + auth=True, + lower=True, + ) + return ActiveUsersChart(data) + + async def get_drive( + self, span: str = 'day', limit: int = 30, offset: int = 0 + ) -> DriveChart: + data = {'span': span, 'limit': limit, 'offset': offset} + data = await self.__session.request( + Route('POST', '/api/charts/drive'), + json=data, + auth=True, + lower=True, + ) + return DriveChart(data) diff --git a/mipac/actions/favorite.py b/mipac/actions/favorite.py new file mode 100644 index 0000000..8380d15 --- /dev/null +++ b/mipac/actions/favorite.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from mipac.abstract.action import AbstractAction +from mipac.http import Route + +if TYPE_CHECKING: + from mipac.http import HTTPClient + from mipac.manager.client import ClientActions + + +class FavoriteActions(AbstractAction): + def __init__( + self, + note_id: str | None = None, + *, + session: HTTPClient, + client: ClientActions + ): + self.__note_id: str | None = note_id + self.__session: HTTPClient = session + self.__client: ClientActions = client + + async def add(self, note_id: str | None = None) -> bool: + note_id = note_id or self.__note_id + data = {'noteId': note_id} + return bool( + await self.__session.request( + Route('POST', '/api/notes/favorites/create'), + json=data, + auth=True, + ) + ) + + async def remove(self, note_id: str | None = None) -> bool: + note_id = note_id or self.__note_id + data = {'noteId': note_id} + return bool( + await self.__session.request( + Route('POST', '/api/notes/favorites/delete'), + json=data, + auth=True, + ) + ) diff --git a/mipac/actions/follow.py b/mipac/actions/follow.py new file mode 100644 index 0000000..3bde824 --- /dev/null +++ b/mipac/actions/follow.py @@ -0,0 +1,150 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from mipac.abstract.action import AbstractAction +from mipac.http import Route +from mipac.models.follow import FollowRequest +from mipac.models.user import UserDetailed +from mipac.types.follow import IFollowRequest + +if TYPE_CHECKING: + from mipac.http import HTTPClient + from mipac.manager.client import ClientActions + + +class FollowActions(AbstractAction): + def __init__( + self, + user_id: str | None = None, + *, + session: HTTPClient, + client: ClientActions + ): + self.__user_id: str | None = user_id + self.__session = session + self.__client = client + + async def add(self, user_id: str | None = None) -> tuple[bool, str | None]: + """ + ユーザーをフォローします + + Returns + ------- + bool + 成功ならTrue, 失敗ならFalse + str + 実行に失敗した際のエラーコード + """ + + user_id = user_id or self.__user_id + + data = {'userId': user_id} + res = await self.__session.request( + Route('POST', '/api/following/create'), + json=data, + auth=True, + lower=True, + ) + if res.get('error'): + code = res['error']['code'] + status = False + else: + code = None + status = True + return status, code + + async def remove(self, user_id: str | None = None) -> bool: + """ + ユーザーのフォローを解除します + + Returns + ------- + bool + 成功ならTrue, 失敗ならFalse + """ + + user_id = user_id or self.__user_id + + data = {'userId': user_id} + res = await self.__session.request( + Route('POST', '/api/following/delete'), json=data, auth=True + ) + return bool(res.status_code == 204 or 200) + + +class FollowRequestActions(AbstractAction): + def __init__( + self, + user_id: str | None = None, + *, + session: HTTPClient, + client: ClientActions + ): + self.__user_id: str | None = user_id + self.__session = session + self.__client = client + + async def get_all(self) -> list[FollowRequest]: + """ + 未承認のフォローリクエストを取得します + """ + + res: list[IFollowRequest] = await self.__session.request( + Route('POST', '/api/following/requests/list'), + auth=True, + lower=True, + ) + return [ + FollowRequest(follow_request=i, client=self.__client) for i in res + ] + + async def get_user(self, user_id: str | None = None) -> UserDetailed: + """ + フォローリクエスト元のユーザーを取得します + Parameters + ---------- + user_id : str | None, default=None + ユーザーID + + Returns + ------- + UserDetailed + フォローリクエスト元のユーザー + """ + + user_id = user_id or self.__user_id + + return await self.__client.user.action.get(user_id) + + async def accept(self, user_id: str | None = None) -> bool: + """ + 与えられたIDのユーザーのフォローリクエストを承認します + """ + + user_id = user_id or self.__user_id + + data = {'userId': user_id} + return bool( + await self.__session.request( + Route('POST', '/api/following/requests/accept'), + json=data, + auth=True, + ) + ) + + async def reject(self, user_id: str | None) -> bool: + """ + 与えられたIDのユーザーのフォローリクエストを拒否します + """ + + user_id = user_id or self.__user_id + + data = {'userId': user_id} + return bool( + await self.__session.request( + Route('POST', '/api/following/requests/reject'), + json=data, + auth=True, + ) + ) diff --git a/mipac/actions/note.py b/mipac/actions/note.py index a7e1d73..eb7afa0 100644 --- a/mipac/actions/note.py +++ b/mipac/actions/note.py @@ -5,9 +5,7 @@ from typing import TYPE_CHECKING, AsyncIterator, Optional from mipac.abstract.action import AbstractAction from mipac.errors.base import ParameterError from mipac.http import HTTPClient, Route -from mipac.manager.favorite import FavoriteManager -from mipac.manager.file import MiFile -from mipac.manager.reaction import ReactionManager +from mipac.file import MiFile from mipac.models.drive import File from mipac.models.note import Note, NoteReaction from mipac.models.poll import Poll @@ -176,10 +174,9 @@ class ClientNoteActions(AbstractAction): self, reaction: str, note_id: Optional[str] = None ) -> list[NoteReaction]: note_id = note_id or self._note_id - return await ReactionManager( - note_id=note_id, client=self._client, session=self._session - ).get_reaction(reaction) - # TODO: self.__clientを使ったインスタンス生成に変えないと循環インポートの原因になりかねない + return await self._client.note.reaction.action.get_reaction( + reaction + ) # TODO: note.reactionのインタンスを新規作成出来るように async def reply( self, @@ -296,12 +293,7 @@ class NoteActions(ClientNoteActions): session: HTTPClient, client: ClientActions ): - self.favorite = FavoriteManager( - note_id=note_id, session=session, client=client - ) - self.reaction = ReactionManager( - note_id=note_id, session=session, client=client - ) + super().__init__(note_id=note_id, session=session, client=client) async def send( diff --git a/mipac/actions/reaction.py b/mipac/actions/reaction.py new file mode 100644 index 0000000..c0b1b31 --- /dev/null +++ b/mipac/actions/reaction.py @@ -0,0 +1,87 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from mipac.abstract.action import AbstractAction +from mipac.http import Route +from mipac.models.emoji import CustomEmoji +from mipac.models.note import NoteReaction +from mipac.types.instance import IInstanceMetaLite +from mipac.types.note import INoteReaction +from mipac.util import remove_dict_empty + +if TYPE_CHECKING: + from mipac.http import HTTPClient + from mipac.manager.client import ClientActions + + +class ReactionActions(AbstractAction): + def __init__( + self, + note_id: str | None = None, + *, + session: HTTPClient, + client: ClientActions + ): + self.__note_id: str | None = note_id + self.__session: HTTPClient = session + self.__client: ClientActions = client + + async def add(self, reaction: str, note_id: str | None = None) -> bool: + """ + 指定したnoteに指定したリアクションを付与します(内部用 + + Parameters + ---------- + reaction : str | None + 付与するリアクション名 + note_id : str | None + 付与対象のノートID + + Returns + ------- + bool + 成功したならTrue,失敗ならFalse + """ + note_id = note_id or self.__note_id + + data = remove_dict_empty({'noteId': note_id, 'reaction': reaction}) + route = Route('POST', '/api/notes/reactions/create') + res: bool = await self.__session.request( + route, json=data, auth=True, lower=True + ) + return bool(res) + + async def remove(self, note_id: str | None = None) -> bool: + note_id = note_id or self.__note_id + + data = remove_dict_empty({'noteId': note_id}) + route = Route('POST', '/api/notes/reactions/delete') + res: bool = await self.__session.request( + route, json=data, auth=True, lower=True + ) + return bool(res) + + async def get_reaction( + self, reaction: str, note_id: str | None = None, *, limit: int = 11 + ) -> list[NoteReaction]: + note_id = note_id or self.__note_id + data = remove_dict_empty( + {'noteId': note_id, 'limit': limit, 'type': reaction} + ) + res: list[INoteReaction] = await self.__session.request( + Route('POST', '/api/notes/reactions'), + json=data, + auth=True, + lower=True, + ) + return [NoteReaction(i, client=self.__client) for i in res] + + async def get_emoji_list(self) -> list[CustomEmoji]: + data: IInstanceMetaLite = await self.__session.request( + Route('GET', '/api/meta'), + json={'detail': False}, + auth=True, + replace_list={'ToSUrl': 'tos_url', 'ToSTextUrl': 'tos_text_url'}, + ) + return [CustomEmoji(i, client=self.__client) for i in data['emojis']] diff --git a/mipac/actions/user.py b/mipac/actions/user.py index b7bd5f8..cb677bf 100644 --- a/mipac/actions/user.py +++ b/mipac/actions/user.py @@ -4,14 +4,13 @@ from typing import TYPE_CHECKING, Literal, Optional from mipac.errors.base import NotExistRequiredData, ParameterError from mipac.http import HTTPClient, Route -from mipac.manager.note import NoteManager from mipac.models.user import UserDetailed from mipac.util import cache, check_multi_arg, remove_dict_empty if TYPE_CHECKING: from mipac.manager.client import ClientActions - from mipac.models.note import Note from mipac.models.lite.user import LiteUser + from mipac.models.note import Note __all__ = ['UserActions'] @@ -26,7 +25,6 @@ class UserActions: self.__session: HTTPClient = session self.__user: Optional[LiteUser] = user self.__client: ClientActions = client - self.note: NoteManager = NoteManager(session=session, client=client) async def get_me(self) -> UserDetailed: """ diff --git a/mipac/core/__init__.py b/mipac/core/__init__.py deleted file mode 100644 index a8e9496..0000000 --- a/mipac/core/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .models import * # noqa: F403, F401 diff --git a/mipac/core/models/__init__.py b/mipac/core/models/__init__.py deleted file mode 100644 index 34a4104..0000000 --- a/mipac/core/models/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -from mipac.core.models.chart import ( - RawActiveUsersChart, - RawDriveChart, - RawDriveLocalChart, - RawDriveRemoteChart, -) - -__all__ = ( - 'RawActiveUsersChart', - 'RawDriveRemoteChart', - 'RawDriveLocalChart', - 'RawDriveChart', -) diff --git a/mipac/core/models/chart.py b/mipac/core/models/chart.py deleted file mode 100644 index 43a73f2..0000000 --- a/mipac/core/models/chart.py +++ /dev/null @@ -1,94 +0,0 @@ -from __future__ import annotations - -from mipac.types.chart import ( - ActiveUsersChartPayload, - DriveChartPayload, - DriveLocalChartPayload, - DriveRemoteChartPayload, -) - -__all__ = ( - 'RawActiveUsersChart', - 'RawDriveRemoteChart', - 'RawDriveLocalChart', - 'RawDriveChart', -) - - -class RawActiveUsersChart: - __slots__ = ( - 'read_write', - 'read', - 'write', - 'registered_within_week', - 'registered_within_month', - 'registered_within_year', - 'registered_outside_week', - 'registered_outside_month', - 'registered_outside_year', - ) - - def __init__(self, data: ActiveUsersChartPayload): - self.read_write: list[int] = data['read_write'] - self.read: list[int] = data['read'] - self.write: list[int] = data['write'] - self.registered_within_week: list[int] = data['registered_within_week'] - self.registered_within_month: list[int] = data[ - 'registered_within_month' - ] - self.registered_within_year: list[int] = data['registered_within_year'] - self.registered_outside_week: list[int] = data[ - 'registered_outside_week' - ] - self.registered_outside_month: list[int] = data[ - 'registered_outside_month' - ] - self.registered_outside_year: list[int] = data[ - 'registered_outside_year' - ] - - -class RawDriveLocalChart: - __slots__ = ( - 'total_count', - 'total_size', - 'inc_count', - 'inc_size', - 'dec_count', - 'dec_size', - ) - - def __init__(self, data: DriveLocalChartPayload): - self.total_count: list[int] = data['total_count'] - self.total_size: list[int] = data['total_size'] - self.inc_count: list[int] = data['inc_count'] - self.inc_size: list[int] = data['inc_size'] - self.dec_count: list[int] = data['dec_count'] - self.dec_size: list[int] = data['dec_size'] - - -class RawDriveRemoteChart: - __slots__ = ( - 'total_count', - 'total_size', - 'inc_count', - 'inc_size', - 'dec_count', - 'dec_size', - ) - - def __init__(self, data: DriveRemoteChartPayload): - self.total_count: list[int] = data['total_count'] - self.total_size: list[int] = data['total_size'] - self.inc_count: list[int] = data['inc_count'] - self.inc_size: list[int] = data['inc_size'] - self.dec_count: list[int] = data['dec_count'] - self.dec_size: list[int] = data['dec_size'] - - -class RawDriveChart: - __slots__ = ('local', 'remote') - - def __init__(self, data: DriveChartPayload): - self.local: RawDriveLocalChart = RawDriveLocalChart(data['local']) - self.remote: RawDriveRemoteChart = RawDriveRemoteChart(data['remote']) diff --git a/mipac/manager/file.py b/mipac/file.py similarity index 100% rename from mipac/manager/file.py rename to mipac/file.py diff --git a/mipac/http.py b/mipac/http.py index c46ff85..3381182 100644 --- a/mipac/http.py +++ b/mipac/http.py @@ -9,11 +9,7 @@ from mipac import __version__ from mipac.errors.base import APIError from mipac.types.endpoints import ENDPOINTS from mipac.types.user import IUserDetailed -from mipac.util import ( - _from_json, - remove_dict_empty, - upper_to_lower, -) +from mipac.util import _from_json, remove_dict_empty, upper_to_lower class _MissingSentinel: diff --git a/mipac/manager/__init__.py b/mipac/manager/__init__.py index 1f6b72d..f55873c 100644 --- a/mipac/manager/__init__.py +++ b/mipac/manager/__init__.py @@ -1,16 +1,13 @@ # noqa: F403, F401 -from .admin import * from .ad import * +from .admin import * from .chart import * from .chat import * from .client import * from .drive import * -from .emoji import * from .favorite import * -from .file import * from .follow import * -from .moderator import * from .my import * from .note import * from .page import * diff --git a/mipac/manager/admin/__init__.py b/mipac/manager/admin/__init__.py index f4a2da0..176d781 100644 --- a/mipac/manager/admin/__init__.py +++ b/mipac/manager/admin/__init__.py @@ -1 +1,4 @@ +from .emoji import * +from .manager import * +from .moderator import * from .user import * diff --git a/mipac/manager/admin/emoji.py b/mipac/manager/admin/emoji.py new file mode 100644 index 0000000..6d3d5e2 --- /dev/null +++ b/mipac/manager/admin/emoji.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from mipac.abstract.manager import AbstractManager +from mipac.actions.admin.emoji import AdminEmojiActions +from mipac.http import HTTPClient + +if TYPE_CHECKING: + from mipac.client import ClientActions + + +class AdminEmojiManager(AbstractManager): + def __init__(self, session: HTTPClient, client: ClientActions): + self.__session: HTTPClient = session + self.__client: ClientActions = client + + @property + def action(self) -> AdminEmojiActions: + return AdminEmojiActions(session=self.__session, client=self.__client) + + def _create_admin_emoji_instance(self, emoji_id: str) -> AdminEmojiActions: + return AdminEmojiActions( + emoji_id=emoji_id, session=self.__session, client=self.__client + ) diff --git a/mipac/actions/admin.py b/mipac/manager/admin/manager.py similarity index 68% rename from mipac/actions/admin.py rename to mipac/manager/admin/manager.py index f17ee21..94529c1 100644 --- a/mipac/actions/admin.py +++ b/mipac/manager/admin/manager.py @@ -1,18 +1,19 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING +from mipac.abstract.manager import AbstractManager from mipac.http import HTTPClient, Route from mipac.manager.ad import AdminAdvertisingManager +from mipac.manager.admin.emoji import AdminEmojiManager +from mipac.manager.admin.moderator import AdminModeratorManager from mipac.manager.admin.user import AdminUserManager -from mipac.manager.emoji import AdminEmojiManager -from mipac.manager.moderator import AdminModeratorManager if TYPE_CHECKING: from mipac.client import ClientActions -class AdminActions: +class AdminManager(AbstractManager): def __init__(self, session: HTTPClient, client: ClientActions): self.__session: HTTPClient = session self.__client: ClientActions = client @@ -21,13 +22,6 @@ class AdminActions: self.ad = AdminAdvertisingManager(session=session, client=client) self.moderator = AdminModeratorManager(session=session, client=client) - def get_emoji_instance( - self, emoji_id: Optional[str] = None - ) -> AdminEmojiManager: - return AdminEmojiManager( - emoji_id, session=self.__session, client=self.__client - ) - async def get_invite(self) -> bool: return bool( await self.__session.request(Route('POST', '/api/admin/invite')) diff --git a/mipac/manager/admin/moderator.py b/mipac/manager/admin/moderator.py new file mode 100644 index 0000000..030268b --- /dev/null +++ b/mipac/manager/admin/moderator.py @@ -0,0 +1,39 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Optional + +from mipac.abstract.manager import AbstractManager +from mipac.actions.admin.moderator import AdminModeratorActions +from mipac.http import HTTPClient + +if TYPE_CHECKING: + from mipac.client import ClientActions + +__all__ = ('AdminModeratorManager',) + + +class AdminModeratorManager(AbstractManager): + def __init__( + self, + user_id: Optional[str] = None, + *, + session: HTTPClient, + client: ClientActions + ): + self.__user_id: Optional[str] = user_id + self.__session: HTTPClient = session + self.__client: ClientActions = client + + @property + def action(self) -> AdminModeratorActions: + """Moderatorに関するアクション + + Returns + ------- + AdminModeratorActions + Moderatorに対するアクションを行うクラス + """ + + return AdminModeratorActions( + session=self.__session, client=self.__client + ) diff --git a/mipac/manager/chart.py b/mipac/manager/chart.py index 28b683e..2971c1e 100644 --- a/mipac/manager/chart.py +++ b/mipac/manager/chart.py @@ -3,11 +3,11 @@ from __future__ import annotations from typing import TYPE_CHECKING from mipac.abstract.manager import AbstractManager -from mipac.core.models.chart import RawActiveUsersChart, RawDriveChart -from mipac.http import HTTPClient, Route +from mipac.actions.chart import ChartActions if TYPE_CHECKING: from mipac.client import ClientActions + from mipac.http import HTTPClient __all__ = ('ChartManager',) @@ -17,26 +17,6 @@ class ChartManager(AbstractManager): self.__session: HTTPClient = session self.__client: ClientActions = client - async def get_active_user( - self, span: str = 'day', limit: int = 30, offset: int = 0 - ) -> RawActiveUsersChart: - data = {'span': span, 'limit': limit, 'offset': offset} - data = await self.__session.request( - Route('POST', '/api/charts/active-users'), - json=data, - auth=True, - lower=True, - ) - return RawActiveUsersChart(data) - - async def get_drive( - self, span: str = 'day', limit: int = 30, offset: int = 0 - ) -> RawDriveChart: - data = {'span': span, 'limit': limit, 'offset': offset} - data = await self.__session.request( - Route('POST', '/api/charts/drive'), - json=data, - auth=True, - lower=True, - ) - return RawDriveChart(data) + @property + def action(self) -> ChartActions: + return ChartActions(session=self.__session, client=self.__client) diff --git a/mipac/manager/client.py b/mipac/manager/client.py index b127f2e..5abf72a 100644 --- a/mipac/manager/client.py +++ b/mipac/manager/client.py @@ -2,20 +2,19 @@ from __future__ import annotations from typing import TYPE_CHECKING -from mipac.actions.admin import AdminActions from mipac.http import HTTPClient +from mipac.manager.admin.manager import AdminManager from mipac.manager.chart import ChartManager from mipac.manager.chat import ChatManager from mipac.manager.drive import DriveManager from mipac.manager.my import MyManager from mipac.manager.note import NoteManager -from mipac.manager.reaction import ReactionManager from mipac.manager.user import UserManager if TYPE_CHECKING: from mipac.config import Config - from mipac.models.user import UserDetailed from mipac.models.lite.user import LiteUser + from mipac.models.user import UserDetailed __all__ = ('ClientActions',) @@ -28,11 +27,8 @@ class ClientActions: self.note: NoteManager = NoteManager(session=session, client=self) self.chat: ChatManager = ChatManager(session=session, client=self) self.user: UserManager = UserManager(session=session, client=self) - self.admin: AdminActions = AdminActions(session=session, client=self) + self.admin: AdminManager = AdminManager(session=session, client=self) self.drive: DriveManager = DriveManager(session=session, client=self) - self.reaction: ReactionManager = ReactionManager( - session=session, client=self - ) self.chart: ChartManager = ChartManager(session=session, client=self) self._config: Config = config diff --git a/mipac/manager/emoji.py b/mipac/manager/emoji.py deleted file mode 100644 index 4f12d1e..0000000 --- a/mipac/manager/emoji.py +++ /dev/null @@ -1,69 +0,0 @@ -from __future__ import annotations - -from typing import TYPE_CHECKING, Optional - -from mipac.abstract.manager import AbstractManager -from mipac.errors.base import NotExistRequiredData -from mipac.http import HTTPClient, Route -from mipac.util import check_multi_arg - -if TYPE_CHECKING: - from mipac.client import ClientActions - - -class AdminEmojiManager(AbstractManager): - def __init__( - self, - emoji_id: Optional[str] = None, - *, - session: HTTPClient, - client: ClientActions - ): - self.emoji_id: Optional[str] = emoji_id - self.__session: HTTPClient = session - self.__client: ClientActions = client - - async def add( - self, - file_id: Optional[str] = None, - *, - name: Optional[str] = None, - url: Optional[str] = None, - category: Optional[str] = None, - aliases: Optional[list[str]] = None - ) -> bool: - if self.__client._config.is_ayuskey: - data = { - 'name': name, - 'url': url, - 'category': category, - 'aliases': aliases, - } - else: - data = {'fileId': file_id} - - if not check_multi_arg(file_id, url): - raise NotExistRequiredData('required a file_id or url') - return bool( - await self.__session.request( - Route('POST', '/api/admin/emoji/add'), - json=data, - lower=True, - auth=True, - ) - ) - - async def remove(self, emoji_id: Optional[str] = None) -> bool: - emoji_id = emoji_id or self.emoji_id - - if emoji_id is None: - raise NotExistRequiredData('idが不足しています') - - return bool( - await self.__session.request( - Route('POST', '/api/admin/emoji/remove'), - json={'id': emoji_id}, - lower=True, - auth=True, - ) - ) diff --git a/mipac/manager/favorite.py b/mipac/manager/favorite.py index 563a91b..7ea879e 100644 --- a/mipac/manager/favorite.py +++ b/mipac/manager/favorite.py @@ -3,7 +3,8 @@ from __future__ import annotations from typing import TYPE_CHECKING, Optional from mipac.abstract.manager import AbstractManager -from mipac.http import HTTPClient, Route +from mipac.actions.favorite import FavoriteActions +from mipac.http import HTTPClient if TYPE_CHECKING: from mipac.client import ClientActions @@ -21,24 +22,17 @@ class FavoriteManager(AbstractManager): self.__session: HTTPClient = session self.__client: ClientActions = client - async def add(self, note_id: Optional[str] = None) -> bool: - note_id = note_id or self.__note_id - data = {'noteId': note_id} - return bool( - await self.__session.request( - Route('POST', '/api/notes/favorites/create'), - json=data, - auth=True, - ) - ) + @property + def action(self) -> FavoriteActions: + """お気に入りに関するアクション - async def remove(self, note_id: Optional[str] = None) -> bool: - note_id = note_id or self.__note_id - data = {'noteId': note_id} - return bool( - await self.__session.request( - Route('POST', '/api/notes/favorites/delete'), - json=data, - auth=True, - ) + Returns + ------- + ReactionActions + お気に入りに対するアクションを行うクラス + """ + return FavoriteActions( + note_id=self.__note_id, + session=self.__session, + client=self.__client, ) diff --git a/mipac/manager/follow.py b/mipac/manager/follow.py index df8e0b1..68d0da6 100644 --- a/mipac/manager/follow.py +++ b/mipac/manager/follow.py @@ -3,9 +3,8 @@ from __future__ import annotations from typing import TYPE_CHECKING, Optional from mipac.abstract.manager import AbstractManager -from mipac.http import HTTPClient, Route -from mipac.models.user import FollowRequest, UserDetailed -from mipac.types.user import IFollowRequest +from mipac.actions.follow import FollowActions +from mipac.http import HTTPClient if TYPE_CHECKING: from mipac.client import ClientActions @@ -24,55 +23,17 @@ class FollowManager(AbstractManager): self.__user_id: Optional[str] = user_id self.__session: HTTPClient = session self.__client: ClientActions = client - - async def add( - self, user_id: Optional[str] = None - ) -> tuple[bool, Optional[str]]: - """ - ユーザーをフォローします - - Returns - ------- - bool - 成功ならTrue, 失敗ならFalse - str - 実行に失敗した際のエラーコード - """ - - user_id = user_id or self.__user_id - - data = {'userId': user_id} - res = await self.__session.request( - Route('POST', '/api/following/create'), - json=data, - auth=True, - lower=True, + self.request: FollowRequestManager = FollowRequestManager( + user_id=user_id, session=session, client=client ) - if res.get('error'): - code = res['error']['code'] - status = False - else: - code = None - status = True - return status, code - - async def remove(self, user_id: Optional[str] = None) -> bool: - """ - ユーザーのフォローを解除します - Returns - ------- - bool - 成功ならTrue, 失敗ならFalse - """ - - user_id = user_id or self.__user_id - - data = {'userId': user_id} - res = await self.__session.request( - Route('POST', '/api/following/delete'), json=data, auth=True + @property + def action(self) -> FollowActions: + return FollowActions( + user_id=self.__user_id, + session=self.__session, + client=self.__client, ) - return bool(res.status_code == 204 or 200) class FollowRequestManager(AbstractManager): @@ -87,64 +48,10 @@ class FollowRequestManager(AbstractManager): self.__session: HTTPClient = session self.__client: ClientActions = client - async def get_all(self) -> list[FollowRequest]: - """ - 未承認のフォローリクエストを取得します - """ - - res: list[IFollowRequest] = await self.__session.request( - Route('POST', '/api/following/requests/list'), - auth=True, - lower=True, - ) - return [FollowRequest(request=i, client=self.__client) for i in res] - - async def get_user(self, user_id: Optional[str] = None) -> UserDetailed: - """ - フォローリクエスト元のユーザーを取得します - Parameters - ---------- - user_id : Optional[str], default=None - ユーザーID - - Returns - ------- - UserDetailed - フォローリクエスト元のユーザー - """ - - user_id = user_id or self.__user_id - - return await self.__client.user.action.get(user_id) - - async def accept(self, user_id: Optional[str] = None) -> bool: - """ - 与えられたIDのユーザーのフォローリクエストを承認します - """ - - user_id = user_id or self.__user_id - - data = {'userId': user_id} - return bool( - await self.__session.request( - Route('POST', '/api/following/requests/accept'), - json=data, - auth=True, - ) - ) - - async def reject(self, user_id: Optional[str]) -> bool: - """ - 与えられたIDのユーザーのフォローリクエストを拒否します - """ - - user_id = user_id or self.__user_id - - data = {'userId': user_id} - return bool( - await self.__session.request( - Route('POST', '/api/following/requests/reject'), - json=data, - auth=True, - ) + @property + def action(self) -> FollowActions: + return FollowActions( + user_id=self.__user_id, + session=self.__session, + client=self.__client, ) diff --git a/mipac/manager/note.py b/mipac/manager/note.py index 77c9410..1094f7b 100644 --- a/mipac/manager/note.py +++ b/mipac/manager/note.py @@ -5,6 +5,8 @@ from typing import TYPE_CHECKING, Optional from mipac.abstract.manager import AbstractManager from mipac.actions.note import ClientNoteActions, NoteActions from mipac.http import HTTPClient, Route +from mipac.manager.favorite import FavoriteManager +from mipac.manager.reaction import ReactionManager if TYPE_CHECKING: from mipac.manager.client import ClientActions @@ -18,9 +20,15 @@ class ClientNoteManager(AbstractManager): session: HTTPClient, client: ClientActions ): + self.__note_id = note_id self.__session: HTTPClient = session self.__client: ClientActions = client - self.__note_id = note_id + self.reaction: ReactionManager = ReactionManager( + note_id=note_id, session=session, client=client + ) + self.favorite = FavoriteManager( + note_id=note_id, session=session, client=client + ) @property def action(self) -> ClientNoteActions: @@ -41,10 +49,18 @@ class NoteManager(AbstractManager): session: HTTPClient, client: ClientActions ): + self.__note_id: str | None = note_id self.__session: HTTPClient = session self.__client: ClientActions = client - self.__note_id = note_id - self.client = ClientNoteManager(session=session, client=client) + self.reaction: ReactionManager = ReactionManager( + note_id=note_id, session=session, client=client + ) + self.favorite = FavoriteManager( + note_id=note_id, session=session, client=client + ) + self._client: ClientNoteManager = ClientNoteManager( + note_id=note_id, session=session, client=client + ) def create_client_note_manager(self, note_id: str) -> ClientNoteManager: return ClientNoteManager( diff --git a/mipac/manager/reaction.py b/mipac/manager/reaction.py index cd4f5fb..7fe2fae 100644 --- a/mipac/manager/reaction.py +++ b/mipac/manager/reaction.py @@ -3,15 +3,11 @@ from __future__ import annotations from typing import TYPE_CHECKING, Optional from mipac.abstract.manager import AbstractManager -from mipac.http import HTTPClient, Route -from mipac.models.emoji import CustomEmoji -from mipac.types.instance import IInstanceMetaLite -from mipac.types.note import INoteReaction -from mipac.util import remove_dict_empty +from mipac.actions.reaction import ReactionActions +from mipac.http import HTTPClient if TYPE_CHECKING: from mipac.client import ClientActions - from mipac.models.note import NoteReaction class ReactionManager(AbstractManager): @@ -26,61 +22,17 @@ class ReactionManager(AbstractManager): self.__session: HTTPClient = session self.__client: ClientActions = client - async def add(self, reaction: str, note_id: Optional[str] = None) -> bool: - """ - 指定したnoteに指定したリアクションを付与します(内部用 - - Parameters - ---------- - reaction : Optional[str] - 付与するリアクション名 - note_id : Optional[str] - 付与対象のノートID + @property + def action(self) -> ReactionActions: + """リアクションに関するアクション Returns ------- - bool - 成功したならTrue,失敗ならFalse + ReactionActions + Reactionに対するアクションを行うクラス """ - note_id = note_id or self.__note_id - - data = remove_dict_empty({'noteId': note_id, 'reaction': reaction}) - route = Route('POST', '/api/notes/reactions/create') - res: bool = await self.__session.request( - route, json=data, auth=True, lower=True - ) - return bool(res) - - async def remove(self, note_id: Optional[str] = None) -> bool: - note_id = note_id or self.__note_id - - data = remove_dict_empty({'noteId': note_id}) - route = Route('POST', '/api/notes/reactions/delete') - res: bool = await self.__session.request( - route, json=data, auth=True, lower=True - ) - return bool(res) - - async def get_reaction( - self, reaction: str, note_id: Optional[str] = None, *, limit: int = 11 - ) -> list[NoteReaction]: - note_id = note_id or self.__note_id - data = remove_dict_empty( - {'noteId': note_id, 'limit': limit, 'type': reaction} - ) - res: list[INoteReaction] = await self.__session.request( - Route('POST', '/api/notes/reactions'), - json=data, - auth=True, - lower=True, - ) - return [NoteReaction(i, client=self.__client) for i in res] - - async def get_emoji_list(self) -> list[CustomEmoji]: - data: IInstanceMetaLite = await self.__session.request( - Route('GET', '/api/meta'), - json={'detail': False}, - auth=True, - replace_list={'ToSUrl': 'tos_url', 'ToSTextUrl': 'tos_text_url'}, + return ReactionActions( + note_id=self.__note_id, + session=self.__session, + client=self.__client, ) - return [CustomEmoji(i, client=self.__client) for i in data['emojis']] diff --git a/mipac/manager/user.py b/mipac/manager/user.py index 09b8071..1fa2035 100644 --- a/mipac/manager/user.py +++ b/mipac/manager/user.py @@ -28,6 +28,13 @@ class UserManager(AbstractManager): @property def action(self) -> UserActions: + """ユーザーに対するアクション + + Returns + ------- + UserActions + ユーザーに対するアクションを行うクラス + """ return UserActions( session=self.__session, client=self.__client, user=self.user ) diff --git a/mipac/models/__init__.py b/mipac/models/__init__.py index 1408ea3..b10f263 100644 --- a/mipac/models/__init__.py +++ b/mipac/models/__init__.py @@ -1,10 +1,10 @@ -from .lite import * from .channel import * from .chat import * from .drive import * from .emoji import * from .follow import * from .instance import * +from .lite import * from .note import * from .notification import * from .poll import * diff --git a/mipac/models/chart.py b/mipac/models/chart.py new file mode 100644 index 0000000..bc0314d --- /dev/null +++ b/mipac/models/chart.py @@ -0,0 +1,126 @@ +from mipac.types.chart import ( + IActiveUsersChart, + IDriveChart, + IDriveLocalChart, + IDriveRemoteChart, +) + + +class ActiveUsersChart: + __slots__ = ('__data',) + + def __init__(self, data: IActiveUsersChart): + self.__data = data + + @property + def read_write(self) -> list[int]: + return self.__data['read_write'] + + @property + def read(self) -> list[int]: + return self.__data['read'] + + @property + def write(self) -> list[int]: + return self.__data['write'] + + @property + def registered_within_week(self) -> list[int]: + return self.__data['registered_within_week'] + + @property + def registered_within_month(self) -> list[int]: + return self.__data['registered_within_month'] + + @property + def registered_within_year(self) -> list[int]: + return self.__data['registered_within_year'] + + @property + def registered_outside_week(self) -> list[int]: + return self.__data['registered_outside_week'] + + @property + def registered_outside_month(self) -> list[int]: + return self.__data['registered_outside_month'] + + @property + def registered_outside_year(self) -> list[int]: + return self.__data['registered_outside_year'] + + +class DriveLocalChart: + __slots__ = ('__data',) + + def __init__(self, data: IDriveLocalChart): + self.__data = data + + @property + def total_count(self) -> list[int]: + return self.__data['total_count'] + + @property + def total_size(self) -> list[int]: + return self.__data['total_size'] + + @property + def inc_count(self) -> list[int]: + return self.__data['inc_count'] + + @property + def inc_size(self) -> list[int]: + return self.__data['inc_size'] + + @property + def dec_count(self) -> list[int]: + return self.__data['dec_count'] + + @property + def dec_size(self) -> list[int]: + return self.__data['dec_size'] + + +class DriveRemoteChart: + __slots__ = ('__data',) + + def __init__(self, data: IDriveRemoteChart): + self.__data: IDriveRemoteChart = data + + @property + def total_count(self) -> list[int]: + return self.__data['total_count'] + + @property + def total_size(self) -> list[int]: + return self.__data['total_size'] + + @property + def inc_count(self) -> list[int]: + return self.__data['inc_count'] + + @property + def inc_size(self) -> list[int]: + return self.__data['inc_size'] + + @property + def dec_count(self) -> list[int]: + return self.__data['dec_count'] + + @property + def dec_size(self) -> list[int]: + return self.__data['dec_size'] + + +class DriveChart: + __slots__ = ('__data',) + + def __init__(self, data: IDriveChart): + self.__data: IDriveChart = data + + @property + def local(self) -> DriveLocalChart: + return DriveLocalChart(self.__data['local']) + + @property + def remote(self) -> DriveRemoteChart: + return DriveRemoteChart(self.__data['remote']) diff --git a/mipac/models/lite/user.py b/mipac/models/lite/user.py index 99076ab..af33410 100644 --- a/mipac/models/lite/user.py +++ b/mipac/models/lite/user.py @@ -1,4 +1,5 @@ from __future__ import annotations + from typing import TYPE_CHECKING, Literal from mipac.models.lite.instance import LiteInstance @@ -7,8 +8,8 @@ from mipac.types.user import ILiteUser from mipac.util import deprecated if TYPE_CHECKING: - from mipac.manager.client import ClientActions from mipac.actions.user import UserActions + from mipac.manager.client import ClientActions class LiteUser: diff --git a/mipac/models/notification.py b/mipac/models/notification.py index 01375ed..e4d8564 100644 --- a/mipac/models/notification.py +++ b/mipac/models/notification.py @@ -3,12 +3,12 @@ from __future__ import annotations from datetime import datetime from typing import TYPE_CHECKING -from mipac.manager.client import ClientActions -from mipac.manager.reaction import ReactionManager from mipac.models.lite.user import LiteUser from mipac.models.note import Note if TYPE_CHECKING: + from mipac.actions.reaction import ReactionActions + from mipac.manager.client import ClientActions from mipac.types.notification import IReactionNf @@ -50,5 +50,5 @@ class NotificationReaction: return self.__reaction['reaction'] @property - def action(self) -> ReactionManager: - return self.__client.reaction + def action(self) -> ReactionActions: + return self.__client.note._client.reaction.action diff --git a/mipac/types/chart.py b/mipac/types/chart.py index b4e512f..5e1061a 100644 --- a/mipac/types/chart.py +++ b/mipac/types/chart.py @@ -1,14 +1,14 @@ from typing import TypedDict __all__ = ( - 'ActiveUsersChartPayload', - 'DriveLocalChartPayload', - 'DriveRemoteChartPayload', - 'DriveChartPayload', + 'IActiveUsersChart', + 'IDriveLocalChart', + 'IDriveRemoteChart', + 'IDriveChart', ) -class ActiveUsersChartPayload(TypedDict): +class IActiveUsersChart(TypedDict): read_write: list[int] read: list[int] write: list[int] @@ -20,7 +20,7 @@ class ActiveUsersChartPayload(TypedDict): registered_outside_year: list[int] -class DriveLocalChartPayload(TypedDict): +class IDriveLocalChart(TypedDict): total_count: list[int] total_size: list[int] inc_count: list[int] @@ -29,7 +29,7 @@ class DriveLocalChartPayload(TypedDict): dec_size: list[int] -class DriveRemoteChartPayload(TypedDict): +class IDriveRemoteChart(TypedDict): total_count: list[int] total_size: list[int] inc_count: list[int] @@ -38,6 +38,6 @@ class DriveRemoteChartPayload(TypedDict): dec_size: list[int] -class DriveChartPayload(TypedDict): - local: DriveLocalChartPayload - remote: DriveRemoteChartPayload +class IDriveChart(TypedDict): + local: IDriveLocalChart + remote: IDriveRemoteChart