feat: axblackを辞めてblackに

feat/add-sphinx-doc
yupix 1 year ago
parent 5ad3412a08
commit f7b930fbdd
No known key found for this signature in database
GPG Key ID: 2FF705F5C56D9C06

@ -1,7 +1,7 @@
# MiPAC # MiPAC
<a href="https://discord.gg/CcT997U"><img src="https://img.shields.io/discord/530299114387406860?style=flat-square&color=5865f2&logo=discord&logoColor=ffffff&label=discord" alt="Discord server invite" /></a> <a href="https://discord.gg/CcT997U"><img src="https://img.shields.io/discord/530299114387406860?style=flat-square&color=5865f2&logo=discord&logoColor=ffffff&label=discord" alt="Discord server invite" /></a>
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-axblack-8bd124.svg"></a> <a href="https://github.com/psf/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg" /></a>
<a href="https://www.codacy.com/gh/yupix/MiPAC/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=yupix/MiPAC&amp;utm_campaign=Badge_Grade"><img src="https://app.codacy.com/project/badge/Grade/c9bf85f195f94ab58bc72ad018a2be9f"/></a> <a href="https://www.codacy.com/gh/yupix/MiPAC/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=yupix/MiPAC&amp;utm_campaign=Badge_Grade"><img src="https://app.codacy.com/project/badge/Grade/c9bf85f195f94ab58bc72ad018a2be9f"/></a>
<a href="https://app.fossa.com/projects/git%2Bgithub.com%2Fyupix%2FMiPAC? <a href="https://app.fossa.com/projects/git%2Bgithub.com%2Fyupix%2FMiPAC?
ref=badge_shield" alt="FOSSA Status"> ref=badge_shield" alt="FOSSA Status">
@ -62,10 +62,6 @@ MiPACの特徴として、v11,v12,v13のバージョンごとに生じる変更
MiPACのモデルでは多くの場合、キーワード引数に `client`を受け取り、それを用いて`api` プロパティを生成します。しかし、サポート途中の機能なのではそこが省かれ、リリース後にモデルのインスタンス化に必要な引数として `client` が追加されることがあります。また、他にもモデルの更新のために引数が変更される可能性があります。そのため、引数の変更に関することをCHANGELOG等で通知することはありません。 MiPACのモデルでは多くの場合、キーワード引数に `client`を受け取り、それを用いて`api` プロパティを生成します。しかし、サポート途中の機能なのではそこが省かれ、リリース後にモデルのインスタンス化に必要な引数として `client` が追加されることがあります。また、他にもモデルの更新のために引数が変更される可能性があります。そのため、引数の変更に関することをCHANGELOG等で通知することはありません。
### 開発者向け情報
このプロジェクトでは [black](https://github.com/psf/black)のforkである、[axblack](https://github.com/axiros/axblack)を利用しています。主な違いはダブルクォートがデフォルトではなく、シングルクォートになっている点です
## LICENSE ## LICENSE
準備中 準備中

@ -16,28 +16,28 @@ TOP_COMMENT = '''\"\"\"
IMPORTS = 'from typing import Literal\n\n' IMPORTS = 'from typing import Literal\n\n'
TEMPLATES = 'ENDPOINTS = ' TEMPLATES = 'ENDPOINTS = '
with open('./datas/v13_api.json', mode='r') as f: with open('./datas/v13_api.json', mode='r', encoding='utf-8') as f:
api: OpenAPI = json.load(f) api: OpenAPI = json.load(f)
for path in api['paths']: for path in api['paths']:
PATHS.append(f'{PREFIX}{path}') PATHS.append(f'{PREFIX}{path}')
with open('./datas/ayuskey_api.json', mode='r') as f: with open('./datas/ayuskey_api.json', mode='r', encoding='utf-8') as f:
api: OpenAPI = json.load(f) api: OpenAPI = json.load(f)
for path in api['paths']: for path in api['paths']:
PATHS.append(f'{PREFIX}{path}') PATHS.append(f'{PREFIX}{path}')
old_endpoints = [] old_endpoints = []
if os.path.exists('./datas/endpoints.json'): if os.path.exists('./datas/endpoints.json'):
with open('./datas/endpoints.json', mode='r') as f: with open('./datas/endpoints.json', mode='r', encoding='utf-8') as f:
old_endpoints = json.load(f) old_endpoints = json.load(f)
with open('./datas/endpoints.json', mode='w') as f: with open('./datas/endpoints.json', mode='w', encoding='utf-8') as f:
removed_endpoints = [] removed_endpoints = []
for i in old_endpoints: for i in old_endpoints:
if i not in list(dict.fromkeys(PATHS)): if i not in list(dict.fromkeys(PATHS)):
removed_endpoints.append(i) removed_endpoints.append(i)
with open('./datas/removed-endpoints.json', mode='w') as removed_endpoints_f: with open('./datas/removed-endpoints.json', mode='w', encoding='utf-8') as removed_endpoints_f:
json.dump(removed_endpoints, removed_endpoints_f, ensure_ascii=False, indent=4) json.dump(removed_endpoints, removed_endpoints_f, ensure_ascii=False, indent=4)
old_endpoints.extend(PATHS) old_endpoints.extend(PATHS)

@ -1,14 +1,14 @@
from ._version import get_versions from ._version import get_versions
__title__ = 'mipac' __title__ = "mipac"
__author__ = 'yupix' __author__ = "yupix"
__license__ = 'MIT' __license__ = "MIT"
__copyright__ = 'Copyright 2022-present yupix' __copyright__ = "Copyright 2022-present yupix"
__author_email__ = 'yupi0982@outlook.jp' __author_email__ = "yupi0982@outlook.jp"
__version__ = get_versions()['version'] __version__ = get_versions()["version"]
del get_versions del get_versions
__path__ = __import__('pkgutil').extend_path(__path__, __name__) __path__ = __import__("pkgutil").extend_path(__path__, __name__)
from . import _version from . import _version
from .abstract import * # noqa: F403, F401 from .abstract import * # noqa: F403, F401
@ -18,4 +18,4 @@ from .manager import *
from .models import * # noqa: F403, F401 from .models import * # noqa: F403, F401
from .types import * from .types import *
__version__ = _version.get_versions()['version'] __version__ = _version.get_versions()["version"]

@ -8,7 +8,7 @@ from mipac.http import HTTPClient
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
__all__ = ('AbstractAction',) __all__ = ("AbstractAction",)
class AbstractAction(ABC): class AbstractAction(ABC):

@ -8,7 +8,7 @@ from mipac.http import HTTPClient
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
__all__ = ('AbstractManager',) __all__ = ("AbstractManager",)
class AbstractManager(ABC): class AbstractManager(ABC):

@ -1,6 +1,6 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
__all__ = ('AbstractModel',) __all__ = ("AbstractModel",)
class AbstractModel(ABC): class AbstractModel(ABC):

@ -22,8 +22,8 @@ class AdminAdvertisingModelActions(AbstractAction):
async def update( async def update(
self, self,
url: str, url: str,
place: Literal['square', 'horizontal', 'horizontal-big'], place: Literal["square", "horizontal", "horizontal-big"],
priority: Literal['high', 'middle', 'low'], priority: Literal["high", "middle", "low"],
ratio: int, ratio: int,
image_url: str, image_url: str,
id: str | None = None, id: str | None = None,
@ -33,20 +33,20 @@ class AdminAdvertisingModelActions(AbstractAction):
) -> bool: ) -> bool:
ad_id = self._ad_id or id ad_id = self._ad_id or id
if ad_id is None: if ad_id is None:
raise ParameterError('ad_idは必須です') raise ParameterError("ad_idは必須です")
data = { data = {
'id': ad_id, "id": ad_id,
'url': url, "url": url,
'memo': memo or '', "memo": memo or "",
'place': place, "place": place,
'priority': priority, "priority": priority,
'ratio': ratio, "ratio": ratio,
'startsAt': starts_at, "startsAt": starts_at,
'expiresAt': expires_at, "expiresAt": expires_at,
'imageUrl': image_url, "imageUrl": image_url,
} }
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/admin/ad/update'), json=data, auth=True, lower=True Route("POST", "/api/admin/ad/update"), json=data, auth=True, lower=True
) )
return res return res
@ -56,7 +56,7 @@ class AdminAdvertisingModelActions(AbstractAction):
ad_id = self._ad_id or id ad_id = self._ad_id or id
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/admin/ad/delete'), json={'id': ad_id}, auth=True, lower=True Route("POST", "/api/admin/ad/delete"), json={"id": ad_id}, auth=True, lower=True
) )
return res return res
@ -68,8 +68,8 @@ class AdminAdvertisingActions(AdminAdvertisingModelActions):
async def create( async def create(
self, self,
url: str, url: str,
place: Literal['square', 'horizontal', 'horizontal-big'], place: Literal["square", "horizontal", "horizontal-big"],
priority: Literal['high', 'middle', 'low'], priority: Literal["high", "middle", "low"],
ratio: int, ratio: int,
image_url: str, image_url: str,
starts_at: int = 0, starts_at: int = 0,
@ -80,17 +80,17 @@ class AdminAdvertisingActions(AdminAdvertisingModelActions):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
data = { data = {
'url': url, "url": url,
'memo': memo or '', "memo": memo or "",
'place': place, "place": place,
'priority': priority, "priority": priority,
'ratio': ratio, "ratio": ratio,
'startsAt': starts_at, "startsAt": starts_at,
'expiresAt': expires_at, "expiresAt": expires_at,
'imageUrl': image_url, "imageUrl": image_url,
} }
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/admin/ad/create'), json=data, auth=True, lower=True Route("POST", "/api/admin/ad/create"), json=data, auth=True, lower=True
) )
return res return res
@ -105,14 +105,14 @@ class AdminAdvertisingActions(AdminAdvertisingModelActions):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
data = {'limit': limit, 'sinceId': since_id, 'untilId': until_id} data = {"limit": limit, "sinceId": since_id, "untilId": until_id}
pagination = Pagination[IAd](self._session, Route('POST', '/api/admin/ad/list'), json=data) pagination = Pagination[IAd](self._session, Route("POST", "/api/admin/ad/list"), json=data)
while True: while True:
raw_ads = await pagination.next() raw_ads = await pagination.next()

@ -27,37 +27,40 @@ class AdminActions(AbstractAction):
async def get_meta(self, detail: bool = False) -> AdminMeta: async def get_meta(self, detail: bool = False) -> AdminMeta:
res: IAdminMeta = await self.__session.request( res: IAdminMeta = await self.__session.request(
Route('POST', '/api/admin/meta'), json={'detail': detail}, auth=True, lower=True, Route("POST", "/api/admin/meta"),
json={"detail": detail},
auth=True,
lower=True,
) )
return AdminMeta(res, client=self.__client) return AdminMeta(res, client=self.__client)
async def get_invite(self) -> bool: async def get_invite(self) -> bool:
return bool(await self.__session.request(Route('POST', '/api/admin/invite'))) return bool(await self.__session.request(Route("POST", "/api/admin/invite")))
async def vacuum(self, full: bool = False, analyze: bool = False) -> bool: async def vacuum(self, full: bool = False, analyze: bool = False) -> bool:
body = {'full': full, 'analyze': analyze} body = {"full": full, "analyze": analyze}
return bool( return bool(
await self.__session.request(Route('POST', '/api/admin/vacuum'), auth=True, json=body) await self.__session.request(Route("POST", "/api/admin/vacuum"), auth=True, json=body)
) )
async def update_user_note(self, user_id: str, text: str) -> bool: async def update_user_note(self, user_id: str, text: str) -> bool:
if config.use_version < 12: if config.use_version < 12:
raise NotSupportVersion('ご利用のインスタンスのバージョンではサポートされていない機能です') raise NotSupportVersion("ご利用のインスタンスのバージョンではサポートされていない機能です")
body = {'userId': user_id, 'text': text} body = {"userId": user_id, "text": text}
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/admin/update-user-note'), auth=True, json=body Route("POST", "/api/admin/update-user-note"), auth=True, json=body
) )
) )
async def update_meta(self, meta: IUpdateMetaBody) -> bool: async def update_meta(self, meta: IUpdateMetaBody) -> bool:
body = convert_dict_keys_to_camel( body = convert_dict_keys_to_camel(
meta, replace_list={'tos_text_url': 'ToSTextUrl', 'tos_url': 'ToSUrl'} meta, replace_list={"tos_text_url": "ToSTextUrl", "tos_url": "ToSUrl"}
) )
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/admin/update-meta'), Route("POST", "/api/admin/update-meta"),
json=body, json=body,
auth=True, auth=True,
lower=True, lower=True,
@ -81,7 +84,7 @@ class AdminActions(AbstractAction):
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/admin/unsuspend-user'), json={'userId': user_id}, auth=True Route("POST", "/api/admin/unsuspend-user"), json={"userId": user_id}, auth=True
) )
) )
@ -101,7 +104,7 @@ class AdminActions(AbstractAction):
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/admin/unsilence-user'), json={'userId': user_id}, auth=True Route("POST", "/api/admin/unsilence-user"), json={"userId": user_id}, auth=True
) )
) )
@ -120,7 +123,7 @@ class AdminActions(AbstractAction):
""" """
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/admin/suspend-user'), json={'userId': user_id}, auth=True Route("POST", "/api/admin/suspend-user"), json={"userId": user_id}, auth=True
) )
) )
@ -139,7 +142,7 @@ class AdminActions(AbstractAction):
""" """
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/admin/silence-user'), json={'userId': user_id}, auth=True Route("POST", "/api/admin/silence-user"), json={"userId": user_id}, auth=True
) )
) )
@ -151,17 +154,17 @@ class AdminActions(AbstractAction):
get_all: bool = False, get_all: bool = False,
) -> AsyncGenerator[ModerationLog, None]: ) -> AsyncGenerator[ModerationLog, None]:
if config.use_version < 12: if config.use_version < 12:
raise NotSupportVersion('ご利用のインスタンスのバージョンではサポートされていない機能です') raise NotSupportVersion("ご利用のインスタンスのバージョンではサポートされていない機能です")
if limit > 100: if limit > 100:
raise ParameterError('limit must be less than 100') raise ParameterError("limit must be less than 100")
if get_all: if get_all:
limit = 100 limit = 100
body = {'limit': limit, 'sinceId': since_id, 'untilId': until_id} body = {"limit": limit, "sinceId": since_id, "untilId": until_id}
pagination = Pagination[IModerationLog]( pagination = Pagination[IModerationLog](
self.__session, Route('POST', '/api/admin/show-moderation-logs'), json=body self.__session, Route("POST", "/api/admin/show-moderation-logs"), json=body
) )
while True: while True:
@ -169,10 +172,10 @@ class AdminActions(AbstractAction):
for res_moderation_log in res_moderation_logs: for res_moderation_log in res_moderation_logs:
yield ModerationLog(res_moderation_log, client=self.__client) yield ModerationLog(res_moderation_log, client=self.__client)
@cache('server_info') @cache("server_info")
async def get_server_info(self, **kwargs) -> ServerInfo: async def get_server_info(self, **kwargs) -> ServerInfo:
server_info_payload: IServerInfo = await self.__session.request( server_info_payload: IServerInfo = await self.__session.request(
Route('POST', '/api/admin/server-info'), auth=True, lower=True Route("POST", "/api/admin/server-info"), auth=True, lower=True
) )
return ServerInfo(server_info_payload) return ServerInfo(server_info_payload)
@ -180,21 +183,21 @@ class AdminActions(AbstractAction):
return await self.get_server_info(cache_override=True) return await self.get_server_info(cache_override=True)
async def send_email(self, to: str, subject: str, text: str) -> bool: async def send_email(self, to: str, subject: str, text: str) -> bool:
body = {'to': to, 'subject': subject, 'text': text} body = {"to": to, "subject": subject, "text": text}
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/admin/send-email'), auth=True, json=body Route("POST", "/api/admin/send-email"), auth=True, json=body
) )
) )
async def resolve_abuse_user_report(self, report_id: str, forward: bool = False) -> bool: async def resolve_abuse_user_report(self, report_id: str, forward: bool = False) -> bool:
if config.use_version < 12: if config.use_version < 12:
raise NotSupportVersion('ご利用のインスタンスのバージョンではサポートされていない機能です') raise NotSupportVersion("ご利用のインスタンスのバージョンではサポートされていない機能です")
body = {'reportId': report_id, 'forward': forward} body = {"reportId": report_id, "forward": forward}
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/admin/resolve-abuse-user-report'), auth=True, json=body Route("POST", "/api/admin/resolve-abuse-user-report"), auth=True, json=body
) )
) )
@ -212,33 +215,33 @@ class AdminActions(AbstractAction):
新しいパスワード 新しいパスワード
""" """
return await self.__session.request( return await self.__session.request(
Route('POST', '/api/admin/reset-password'), auth=True, json={'userId': user_id} Route("POST", "/api/admin/reset-password"), auth=True, json={"userId": user_id}
) )
async def get_table_stats(self) -> dict[str, ITableStats]: async def get_table_stats(self) -> dict[str, ITableStats]:
return await self.__session.request(Route('POST', '/api/admin/get-table-stats'), auth=True) return await self.__session.request(Route("POST", "/api/admin/get-table-stats"), auth=True)
async def get_index_stats(self) -> list[IndexStat]: async def get_index_stats(self) -> list[IndexStat]:
res: list[IIndexStat] = await self.__session.request( res: list[IIndexStat] = await self.__session.request(
Route('POST', '/api/admin/get-index-stats'), auth=True Route("POST", "/api/admin/get-index-stats"), auth=True
) )
return [IndexStat(i) for i in res] return [IndexStat(i) for i in res]
async def get_user_ips(self, user_id: str) -> list[UserIP]: async def get_user_ips(self, user_id: str) -> list[UserIP]:
if config.use_version < 12: if config.use_version < 12:
raise NotSupportVersion('ご利用のインスタンスのバージョンではサポートされていない機能です') raise NotSupportVersion("ご利用のインスタンスのバージョンではサポートされていない機能です")
res: list[IUserIP] = await self.__session.request( res: list[IUserIP] = await self.__session.request(
Route('POST', '/api/admin/get-user-ips'), Route("POST", "/api/admin/get-user-ips"),
auth=True, auth=True,
json={'userId': user_id}, json={"userId": user_id},
lower=True, lower=True,
) )
return [UserIP(i) for i in res] return [UserIP(i) for i in res]
async def show_user(self, user_id: str) -> UserDetailed: async def show_user(self, user_id: str) -> UserDetailed:
res: IUserDetailed = await self.__session.request( res: IUserDetailed = await self.__session.request(
Route('POST', '/api/admin/show-user'), auth=True, json={'userId': user_id} Route("POST", "/api/admin/show-user"), auth=True, json={"userId": user_id}
) )
return UserDetailed(res, client=self.__client) return UserDetailed(res, client=self.__client)
@ -247,21 +250,21 @@ class AdminActions(AbstractAction):
limit: int = 10, limit: int = 10,
offset: int = 0, offset: int = 0,
sort: str | None = None, sort: str | None = None,
state: str = 'all', state: str = "all",
origin: str = 'combined', origin: str = "combined",
username: str | None = None, username: str | None = None,
hostname: str | None = None, hostname: str | None = None,
) -> list[UserDetailed]: ) -> list[UserDetailed]:
body = { body = {
'limit': limit, "limit": limit,
'offset': offset, "offset": offset,
'sort': sort, "sort": sort,
'state': state, "state": state,
'origin': origin, "origin": origin,
'username': username, "username": username,
'hostname': hostname, "hostname": hostname,
} }
res: list[IUserDetailed] = await self.__session.request( res: list[IUserDetailed] = await self.__session.request(
Route('POST', '/api/admin/show-users'), auth=True, json=body Route("POST", "/api/admin/show-users"), auth=True, json=body
) )
return [UserDetailed(i, client=self.__client) for i in res] return [UserDetailed(i, client=self.__client) for i in res]

@ -15,7 +15,11 @@ if TYPE_CHECKING:
class AdminAnnouncementClientActions(AbstractAction): class AdminAnnouncementClientActions(AbstractAction):
def __init__( def __init__(
self, announce_id: str | None = None, *, session: HTTPClient, client: ClientManager, self,
announce_id: str | None = None,
*,
session: HTTPClient,
client: ClientManager,
): ):
self.__announce_id = announce_id self.__announce_id = announce_id
self.__session: HTTPClient = session self.__session: HTTPClient = session
@ -24,7 +28,9 @@ class AdminAnnouncementClientActions(AbstractAction):
async def delete(self, announce_id: str | None = None) -> bool: async def delete(self, announce_id: str | None = None) -> bool:
announce_id = announce_id or self.__announce_id announce_id = announce_id or self.__announce_id
res: bool = await self.__session.request( res: bool = await self.__session.request(
Route('POST', '/api/admin/announcements/delete'), json={'id': announce_id}, auth=True, Route("POST", "/api/admin/announcements/delete"),
json={"id": announce_id},
auth=True,
) )
return res return res
@ -38,13 +44,13 @@ class AdminAnnouncementClientActions(AbstractAction):
): ):
announce_id = announce_id or self.__announce_id announce_id = announce_id or self.__announce_id
body = { body = {
'id': announce_id, "id": announce_id,
'title': title, "title": title,
'text': text, "text": text,
'imageUrl': image_url, "imageUrl": image_url,
} }
res: bool = await self.__session.request( res: bool = await self.__session.request(
Route('POST', '/api/admin/announcements/update'), Route("POST", "/api/admin/announcements/update"),
json=body, json=body,
auth=True, auth=True,
remove_none=False, remove_none=False,
@ -54,14 +60,18 @@ class AdminAnnouncementClientActions(AbstractAction):
class AdminAnnouncementActions(AdminAnnouncementClientActions): class AdminAnnouncementActions(AdminAnnouncementClientActions):
def __init__( def __init__(
self, announce_id: str | None = None, *, session: HTTPClient, client: ClientManager, self,
announce_id: str | None = None,
*,
session: HTTPClient,
client: ClientManager,
): ):
super().__init__(announce_id=announce_id, session=session, client=client) super().__init__(announce_id=announce_id, session=session, client=client)
async def create(self, title: str, text: str, image_url: str | None = None) -> Announcement: async def create(self, title: str, text: str, image_url: str | None = None) -> Announcement:
body = {'title': title, 'text': text, 'imageUrl': image_url} body = {"title": title, "text": text, "imageUrl": image_url}
created_announcement: IAnnouncement = await self.__session.request( created_announcement: IAnnouncement = await self.__session.request(
Route('POST', '/api/admin/announcements/create'), Route("POST", "/api/admin/announcements/create"),
json=body, json=body,
auth=True, auth=True,
lower=True, lower=True,
@ -77,18 +87,18 @@ class AdminAnnouncementActions(AdminAnnouncementClientActions):
get_all: bool = False, get_all: bool = False,
) -> AsyncGenerator[AnnouncementSystem, None]: ) -> AsyncGenerator[AnnouncementSystem, None]:
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = { body = {
'limit': limit, "limit": limit,
'sinceId': since_id, "sinceId": since_id,
'untilId': until_id, "untilId": until_id,
} }
pagination = Pagination[IAnnouncementSystem]( pagination = Pagination[IAnnouncementSystem](
self.__session, Route('POST', '/api/admin/announcements/list'), json=body self.__session, Route("POST", "/api/admin/announcements/list"), json=body
) )
while True: while True:

@ -28,7 +28,7 @@ class AdminEmojiActions(AbstractAction):
name: str | None = None, name: str | None = None,
url: str | None = None, url: str | None = None,
category: str | None = None, category: str | None = None,
aliases: list[str] | None = None aliases: list[str] | None = None,
) -> bool: ) -> bool:
"""絵文字を追加します """絵文字を追加します
@ -57,20 +57,23 @@ class AdminEmojiActions(AbstractAction):
""" """
if self.__client._config.use_version >= 12: if self.__client._config.use_version >= 12:
data = {'fileId': file_id} data = {"fileId": file_id}
else: else:
data = { data = {
'name': name, "name": name,
'url': url, "url": url,
'category': category, "category": category,
'aliases': aliases, "aliases": aliases,
} }
if not check_multi_arg(file_id, url): if not check_multi_arg(file_id, url):
raise NotExistRequiredData('required a file_id or url') raise NotExistRequiredData("required a file_id or url")
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/admin/emoji/add'), json=data, lower=True, auth=True, Route("POST", "/api/admin/emoji/add"),
json=data,
lower=True,
auth=True,
) )
) )
@ -81,22 +84,22 @@ class AdminEmojiActions(AbstractAction):
since_id: str | None = None, since_id: str | None = None,
until_id: str | None = None, until_id: str | None = None,
*, *,
get_all: bool = True get_all: bool = True,
) -> AsyncGenerator[CustomEmoji, None]: ) -> AsyncGenerator[CustomEmoji, None]:
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = { body = {
'query': query, "query": query,
'limit': limit, "limit": limit,
'sinceId': since_id, "sinceId": since_id,
'untilId': until_id, "untilId": until_id,
} }
pagination = Pagination[ICustomEmoji]( pagination = Pagination[ICustomEmoji](
self.__session, Route('POST', '/api/admin/emoji/list'), json=body self.__session, Route("POST", "/api/admin/emoji/list"), json=body
) )
while True: while True:
@ -115,23 +118,23 @@ class AdminEmojiActions(AbstractAction):
since_id: str | None = None, since_id: str | None = None,
until_id: str | None = None, until_id: str | None = None,
*, *,
get_all: bool = True get_all: bool = True,
) -> AsyncGenerator[CustomEmoji, None]: ) -> AsyncGenerator[CustomEmoji, None]:
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = { body = {
'query': query, "query": query,
'host': host, "host": host,
'limit': limit, "limit": limit,
'sinceId': since_id, "sinceId": since_id,
'untilId': until_id, "untilId": until_id,
} }
pagination = Pagination[ICustomEmoji]( pagination = Pagination[ICustomEmoji](
self.__session, Route('POST', '/api/admin/emoji/list-remote'), json=body self.__session, Route("POST", "/api/admin/emoji/list-remote"), json=body
) )
while True: while True:
@ -143,9 +146,9 @@ class AdminEmojiActions(AbstractAction):
break break
async def set_license_bulk(self, ids: list[str], license: str | None = None) -> bool: async def set_license_bulk(self, ids: list[str], license: str | None = None) -> bool:
body = {'ids': ids, 'license': license} body = {"ids": ids, "license": license}
res: bool = await self.__session.request( res: bool = await self.__session.request(
Route('POST', '/api/admin/emoji/set-license-bulk'), Route("POST", "/api/admin/emoji/set-license-bulk"),
auth=True, auth=True,
json=body, json=body,
remove_none=False, # remove_noneをFalseにしないとlisenceが消せなくなる remove_none=False, # remove_noneをFalseにしないとlisenceが消せなくなる
@ -174,16 +177,19 @@ class AdminEmojiActions(AbstractAction):
emoji_id = emoji_id or self.__emoji_id emoji_id = emoji_id or self.__emoji_id
if emoji_id is None: if emoji_id is None:
raise NotExistRequiredData('idが不足しています') raise NotExistRequiredData("idが不足しています")
endpoint = ( endpoint = (
'/api/admin/emoji/delete' "/api/admin/emoji/delete"
if self.__client._config.use_version >= 12 if self.__client._config.use_version >= 12
else '/api/admin/emoji/remove' else "/api/admin/emoji/remove"
) )
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', endpoint), auth=True, json={'id': emoji_id}, lower=True, Route("POST", endpoint),
auth=True,
json={"id": emoji_id},
lower=True,
) )
) )

@ -32,9 +32,12 @@ class AdminModeratorActions(AbstractAction):
""" """
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
res = await self.__session.request( res = await self.__session.request(
Route('POST', '/api/admin/moderators/add'), json=data, auth=True, lower=True, Route("POST", "/api/admin/moderators/add"),
json=data,
auth=True,
lower=True,
) )
return bool(res) return bool(res)
@ -53,8 +56,11 @@ class AdminModeratorActions(AbstractAction):
成功したか否か 成功したか否か
""" """
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
res = await self.__session.request( res = await self.__session.request(
Route('POST', '/api/admin/moderators/remove'), json=data, auth=True, lower=True, Route("POST", "/api/admin/moderators/remove"),
json=data,
auth=True,
lower=True,
) )
return bool(res) return bool(res)

@ -28,7 +28,7 @@ class AdminRoleModelActions(AbstractAction):
role_id: str | None = None, role_id: str | None = None,
color: str | None = None, color: str | None = None,
iconUrl: str | None = None, iconUrl: str | None = None,
target: Literal['manual', 'conditional'] = 'manual', target: Literal["manual", "conditional"] = "manual",
cond_formula: dict[Any, Any] | None = None, cond_formula: dict[Any, Any] | None = None,
is_public: bool = False, is_public: bool = False,
is_moderator: bool = False, is_moderator: bool = False,
@ -40,24 +40,24 @@ class AdminRoleModelActions(AbstractAction):
if self._client._config.use_version >= 13: if self._client._config.use_version >= 13:
role_id = self._role_id or role_id role_id = self._role_id or role_id
if role_id is None: if role_id is None:
raise ParameterError('role_idは必須です') raise ParameterError("role_idは必須です")
body = { body = {
'roleId': role_id, "roleId": role_id,
'name': name, "name": name,
'description': description, "description": description,
'color': color, "color": color,
'iconUrl': iconUrl, "iconUrl": iconUrl,
'target': target, "target": target,
'condFormula': cond_formula or {}, "condFormula": cond_formula or {},
'isPublic': is_public, "isPublic": is_public,
'isModerator': is_moderator, "isModerator": is_moderator,
'isAdministrator': is_administrator, "isAdministrator": is_administrator,
'asBadge': as_badge, "asBadge": as_badge,
'canEditMembersByModerator': can_edit_members_by_moderator, "canEditMembersByModerator": can_edit_members_by_moderator,
'policies': policies or {}, "policies": policies or {},
} }
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/admin/roles/update'), Route("POST", "/api/admin/roles/update"),
json=body, json=body,
auth=True, auth=True,
lower=True, lower=True,
@ -70,11 +70,11 @@ class AdminRoleModelActions(AbstractAction):
if self._client._config.use_version >= 13: if self._client._config.use_version >= 13:
role_id = self._role_id or role_id role_id = self._role_id or role_id
if role_id is None: if role_id is None:
raise ParameterError('role_idは必須です') raise ParameterError("role_idは必須です")
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/admin/roles/delete'), Route("POST", "/api/admin/roles/delete"),
auth=True, auth=True,
json={'roleId': role_id}, json={"roleId": role_id},
lower=True, lower=True,
) )
return res return res
@ -101,10 +101,10 @@ class AdminRoleModelActions(AbstractAction):
""" """
if self._client._config.use_version >= 13: if self._client._config.use_version >= 13:
if role_id is None: if role_id is None:
raise ParameterError('role_idは必須です') raise ParameterError("role_idは必須です")
body = {'roleId': role_id, 'userId': user_id, 'expiresAt': expires_at} body = {"roleId": role_id, "userId": user_id, "expiresAt": expires_at}
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/admin/roles/assign'), auth=True, json=body Route("POST", "/api/admin/roles/assign"), auth=True, json=body
) )
return res return res
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
@ -129,10 +129,10 @@ class AdminRoleModelActions(AbstractAction):
if self._client._config.use_version >= 13: if self._client._config.use_version >= 13:
role_id = self._role_id or role_id role_id = self._role_id or role_id
if role_id is None: if role_id is None:
raise ParameterError('role_idは必須です') raise ParameterError("role_idは必須です")
body = {'roleId': role_id, 'userId': user_id} body = {"roleId": role_id, "userId": user_id}
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/admin/roles/unassign'), auth=True, json=body Route("POST", "/api/admin/roles/unassign"), auth=True, json=body
) )
return res return res
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
@ -141,10 +141,10 @@ class AdminRoleModelActions(AbstractAction):
if self._client._config.use_version >= 13: if self._client._config.use_version >= 13:
role_id = self._role_id or role_id role_id = self._role_id or role_id
if role_id is None: if role_id is None:
raise ParameterError('role_idは必須です') raise ParameterError("role_idは必須です")
res: IRole = await self._session.request( res: IRole = await self._session.request(
Route('POST', '/api/admin/roles/show'), Route("POST", "/api/admin/roles/show"),
json={'roleId': role_id}, json={"roleId": role_id},
auth=True, auth=True,
lower=True, lower=True,
) )
@ -165,18 +165,18 @@ class AdminRoleModelActions(AbstractAction):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
if role_id is None: if role_id is None:
raise ParameterError('role_idは必須です') raise ParameterError("role_idは必須です")
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = {'limit': limit, 'sinceId': since_id, 'untilId': until_id, 'roleId': role_id} body = {"limit": limit, "sinceId": since_id, "untilId": until_id, "roleId": role_id}
pagination = Pagination[IRoleUser]( pagination = Pagination[IRoleUser](
self._session, Route('POST', '/api/admin/roles/users'), json=body self._session, Route("POST", "/api/admin/roles/users"), json=body
) )
while True: while True:
@ -198,7 +198,7 @@ class AdminRoleActions(AdminRoleModelActions):
description: str, description: str,
color: str | None = None, color: str | None = None,
iconUrl: str | None = None, iconUrl: str | None = None,
target: Literal['manual', 'conditional'] = 'manual', target: Literal["manual", "conditional"] = "manual",
cond_formula: dict[Any, Any] | None = None, cond_formula: dict[Any, Any] | None = None,
is_public: bool = False, is_public: bool = False,
is_moderator: bool = False, is_moderator: bool = False,
@ -210,22 +210,22 @@ class AdminRoleActions(AdminRoleModelActions):
) -> Role: ) -> Role:
if self._client._config.use_version >= 13: if self._client._config.use_version >= 13:
body = { body = {
'name': name, "name": name,
'description': description, "description": description,
'color': color, "color": color,
'iconUrl': iconUrl, "iconUrl": iconUrl,
'target': target, "target": target,
'condFormula': cond_formula or {}, "condFormula": cond_formula or {},
'isPublic': is_public, "isPublic": is_public,
'isModerator': is_moderator, "isModerator": is_moderator,
'isAdministrator': is_administrator, "isAdministrator": is_administrator,
'asBadge': as_badge, "asBadge": as_badge,
'canEditMembersByModerator': can_edit_members_by_moderator, "canEditMembersByModerator": can_edit_members_by_moderator,
'policies': policies or {}, "policies": policies or {},
'isExplorable': is_explorable, "isExplorable": is_explorable,
} }
res: IRole = await self._session.request( res: IRole = await self._session.request(
Route('POST', '/api/admin/roles/create'), Route("POST", "/api/admin/roles/create"),
auth=True, auth=True,
json=body, json=body,
lower=True, lower=True,
@ -237,7 +237,7 @@ class AdminRoleActions(AdminRoleModelActions):
async def get_list(self) -> list[Role]: async def get_list(self) -> list[Role]:
if self._client._config.use_version >= 13: if self._client._config.use_version >= 13:
res: list[IRole] = await self._session.request( res: list[IRole] = await self._session.request(
Route('POST', '/api/admin/roles/list'), auth=True, lower=True Route("POST", "/api/admin/roles/list"), auth=True, lower=True
) )
return [Role(i, client=self._client) for i in res] return [Role(i, client=self._client) for i in res]
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
@ -245,27 +245,27 @@ class AdminRoleActions(AdminRoleModelActions):
async def update_default_policies(self, policies: IPolicies): async def update_default_policies(self, policies: IPolicies):
if self._client._config.use_version >= 13: if self._client._config.use_version >= 13:
body = { body = {
'policies': { "policies": {
'gtlAvailable': policies.get('gtl_available'), "gtlAvailable": policies.get("gtl_available"),
'ltlAvailable': policies.get('ltl_available'), "ltlAvailable": policies.get("ltl_available"),
'canPublicNote': policies.get('can_public_note'), "canPublicNote": policies.get("can_public_note"),
'canInvite': policies.get('can_invite'), "canInvite": policies.get("can_invite"),
'canManageCustomEmojis': policies.get('can_manage_custom_emojis'), "canManageCustomEmojis": policies.get("can_manage_custom_emojis"),
'canHideAds': policies.get('can_hide_ads'), "canHideAds": policies.get("can_hide_ads"),
'driveCapacityMb': policies.get('drive_capacity_mb'), "driveCapacityMb": policies.get("drive_capacity_mb"),
'pinLimit': policies.get('pin_limit'), "pinLimit": policies.get("pin_limit"),
'antennaLimit': policies.get('antenna_limit'), "antennaLimit": policies.get("antenna_limit"),
'wordMuteLimit': policies.get('word_mute_limit'), "wordMuteLimit": policies.get("word_mute_limit"),
'webhookLimit': policies.get('webhook_limit'), "webhookLimit": policies.get("webhook_limit"),
'clipLimit': policies.get('clip_limit'), "clipLimit": policies.get("clip_limit"),
'noteEachClipsLimit': policies.get('note_each_clips_limit'), "noteEachClipsLimit": policies.get("note_each_clips_limit"),
'userListLimit': policies.get('user_list_limit'), "userListLimit": policies.get("user_list_limit"),
'userEachUserListsLimit': policies.get('user_each_user_lists_limit'), "userEachUserListsLimit": policies.get("user_each_user_lists_limit"),
'rateLimitFactor': policies.get('rate_limit_factor'), "rateLimitFactor": policies.get("rate_limit_factor"),
} }
} }
res = await self._session.request( res = await self._session.request(
Route('POST', '/api/admin/roles/update-default-policies'), Route("POST", "/api/admin/roles/update-default-policies"),
auth=True, auth=True,
lower=True, lower=True,
json=body, json=body,

@ -32,9 +32,12 @@ class AdminUserActions(AbstractAction):
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
res = await self.__session.request( res = await self.__session.request(
Route('POST', '/api/admin/accounts/delete'), json=data, auth=True, lower=True, Route("POST", "/api/admin/accounts/delete"),
json=data,
auth=True,
lower=True,
) )
return bool(res) return bool(res)
@ -53,9 +56,12 @@ class AdminUserActions(AbstractAction):
""" """
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
res = await self.__session.request( res = await self.__session.request(
Route('GET', '/api/admin/show-user'), json=data, auth=True, lower=True, Route("GET", "/api/admin/show-user"),
json=data,
auth=True,
lower=True,
) )
return UserDetailed(res, client=self.__client) return UserDetailed(res, client=self.__client)
@ -75,9 +81,12 @@ class AdminUserActions(AbstractAction):
""" """
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
res = await self.__session.request( res = await self.__session.request(
Route('POST', '/api/admin/suspend-user'), json=data, auth=True, lower=True, Route("POST", "/api/admin/suspend-user"),
json=data,
auth=True,
lower=True,
) )
return bool(res) return bool(res)
@ -97,8 +106,11 @@ class AdminUserActions(AbstractAction):
""" """
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
res: bool = await self.__session.request( res: bool = await self.__session.request(
Route('POST', '/api/admin/unsuspend-user'), json=data, auth=True, lower=True, Route("POST", "/api/admin/unsuspend-user"),
json=data,
auth=True,
lower=True,
) )
return bool(res) return bool(res)

@ -44,11 +44,11 @@ class ClientAntennaActions(AbstractAction):
""" """
antenna_id = antenna_id or self._antenna_id antenna_id = antenna_id or self._antenna_id
if antenna_id is None: if antenna_id is None:
raise ParameterError('antenna id is required') raise ParameterError("antenna id is required")
body = {'antennaId': antenna_id} body = {"antennaId": antenna_id}
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/antennas/delete'), auth=True, json=body Route("POST", "/api/antennas/delete"), auth=True, json=body
) )
return res return res
@ -72,11 +72,11 @@ class ClientAntennaActions(AbstractAction):
""" """
antenna_id = antenna_id or self._antenna_id antenna_id = antenna_id or self._antenna_id
if antenna_id is None: if antenna_id is None:
raise ParameterError('antenna id is required') raise ParameterError("antenna id is required")
body = {'antennaId': antenna_id} body = {"antennaId": antenna_id}
res_antenna: IAntenna = await self._session.request( res_antenna: IAntenna = await self._session.request(
Route('POST', '/api/antennas/show'), auth=True, json=body Route("POST", "/api/antennas/show"), auth=True, json=body
) )
return Antenna(res_antenna, client=self._client) return Antenna(res_antenna, client=self._client)
@ -92,27 +92,27 @@ class ClientAntennaActions(AbstractAction):
) -> AsyncGenerator[Note, None]: ) -> AsyncGenerator[Note, None]:
antenna_id = antenna_id or self._antenna_id antenna_id = antenna_id or self._antenna_id
if antenna_id is None: if antenna_id is None:
raise ParameterError('antenna id is required') raise ParameterError("antenna id is required")
if limit > 100: if limit > 100:
raise ParameterError('limit must be less than 100') raise ParameterError("limit must be less than 100")
if get_all: if get_all:
limit = 100 limit = 100
body = remove_dict_empty( body = remove_dict_empty(
{ {
'antennaId': antenna_id, "antennaId": antenna_id,
'limit': limit, "limit": limit,
'sinceId': since_id, "sinceId": since_id,
'untilId': until_id, "untilId": until_id,
'sinceDate': since_date, "sinceDate": since_date,
'untilDate': until_date, "untilDate": until_date,
} }
) )
pagination = Pagination[INote]( pagination = Pagination[INote](
self._session, Route('POST', '/api/antennas/notes'), json=body self._session, Route("POST", "/api/antennas/notes"), json=body
) )
while True: while True:
@ -170,26 +170,35 @@ class ClientAntennaActions(AbstractAction):
antenna_id = antenna_id or self._antenna_id antenna_id = antenna_id or self._antenna_id
if antenna_id is None: if antenna_id is None:
raise ParameterError('antenna id is required') raise ParameterError("antenna id is required")
if all([name, src, keywords,]) is False: if (
raise ParameterError('Required parameters are missing') all(
[
name,
src,
keywords,
]
)
is False
):
raise ParameterError("Required parameters are missing")
body = { body = {
'antennaId': antenna_id, "antennaId": antenna_id,
'name': name, "name": name,
'src': src, "src": src,
'userListId': user_list_id, "userListId": user_list_id,
'keywords': keywords, "keywords": keywords,
'excludeKeywords': exclude_keywords, "excludeKeywords": exclude_keywords,
'users': users, "users": users,
'caseSensitive': case_sensitive, "caseSensitive": case_sensitive,
'withReplies': with_replies, "withReplies": with_replies,
'withFile': with_file, "withFile": with_file,
'notify': notify, "notify": notify,
} }
res_antenna: IAntenna = await self._session.request( res_antenna: IAntenna = await self._session.request(
Route('POST', '/api/antennas/update'), auth=True, json=body, remove_none=False Route("POST", "/api/antennas/update"), auth=True, json=body, remove_none=False
) )
return Antenna(res_antenna, client=self._client) return Antenna(res_antenna, client=self._client)
@ -244,34 +253,43 @@ class AntennaActions(ClientAntennaActions):
""" """
if users is None: if users is None:
users = [''] users = [""]
if exclude_keywords is None: if exclude_keywords is None:
exclude_keywords = [[]] exclude_keywords = [[]]
if all([name, src, keywords,]) is False: if (
raise ParameterError('Required parameters are missing') all(
[
name,
src,
keywords,
]
)
is False
):
raise ParameterError("Required parameters are missing")
body = { body = {
'name': name, "name": name,
'src': src, "src": src,
'userListId': user_list_id, "userListId": user_list_id,
'keywords': keywords, "keywords": keywords,
'excludeKeywords': exclude_keywords, "excludeKeywords": exclude_keywords,
'users': users, "users": users,
'caseSensitive': case_sensitive, "caseSensitive": case_sensitive,
'withReplies': with_replies, "withReplies": with_replies,
'withFile': with_file, "withFile": with_file,
'notify': notify, "notify": notify,
} }
res_antenna: IAntenna = await self._session.request( res_antenna: IAntenna = await self._session.request(
Route('POST', '/api/antennas/create'), auth=True, json=body, remove_none=False Route("POST", "/api/antennas/create"), auth=True, json=body, remove_none=False
) )
return Antenna(res_antenna, client=self._client) return Antenna(res_antenna, client=self._client)
async def get_list(self) -> list[Antenna]: async def get_list(self) -> list[Antenna]:
res_antennas: list[IAntenna] = await self._session.request( res_antennas: list[IAntenna] = await self._session.request(
Route('POST', '/api/antennas/list'), auth=True Route("POST", "/api/antennas/list"), auth=True
) )
return [Antenna(res_antenna, client=self._client) for res_antenna in res_antennas] return [Antenna(res_antenna, client=self._client) for res_antenna in res_antennas]

@ -21,14 +21,14 @@ class BlockingActions(AbstractAction):
async def add(self, user_id: str | None = None) -> UserDetailed: async def add(self, user_id: str | None = None) -> UserDetailed:
user_id = self.__user_id or user_id user_id = self.__user_id or user_id
res: IUserDetailed = await self.__session.request( res: IUserDetailed = await self.__session.request(
Route('POST', '/api/blocking/create'), auth=True, json={'userId': user_id}, lower=True Route("POST", "/api/blocking/create"), auth=True, json={"userId": user_id}, lower=True
) )
return UserDetailed(res, client=self.__client) return UserDetailed(res, client=self.__client)
async def remove(self, user_id: str | None = None) -> UserDetailed: async def remove(self, user_id: str | None = None) -> UserDetailed:
user_id = self.__user_id or user_id user_id = self.__user_id or user_id
res: IUserDetailed = await self.__session.request( res: IUserDetailed = await self.__session.request(
Route('POST', '/api/blocking/delete'), auth=True, json={'userId': user_id}, lower=True Route("POST", "/api/blocking/delete"), auth=True, json={"userId": user_id}, lower=True
) )
return UserDetailed(res, client=self.__client) return UserDetailed(res, client=self.__client)
@ -42,10 +42,10 @@ class BlockingActions(AbstractAction):
if get_all: if get_all:
limit = 100 limit = 100
data = {'limit': limit, 'sinceId': since_id, 'untilId': until_id} data = {"limit": limit, "sinceId": since_id, "untilId": until_id}
pagination = Pagination[IBlockingUser]( pagination = Pagination[IBlockingUser](
self.__session, Route('POST', '/api/blocking/list'), json=data self.__session, Route("POST", "/api/blocking/list"), json=data
) )
while True: while True:

@ -45,7 +45,7 @@ class ClientChannelActions(AbstractAction):
raise Exception() raise Exception()
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/channels/favorite'), auth=True, json={'channelId': channel_id} Route("POST", "/api/channels/favorite"), auth=True, json={"channelId": channel_id}
) )
return res return res
@ -72,7 +72,7 @@ class ClientChannelActions(AbstractAction):
raise Exception() raise Exception()
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/channels/unfavorite'), auth=True, json={'channelId': channel_id} Route("POST", "/api/channels/unfavorite"), auth=True, json={"channelId": channel_id}
) )
return res return res
@ -96,10 +96,10 @@ class ClientChannelActions(AbstractAction):
channel_id = self._channel_id or channel_id channel_id = self._channel_id or channel_id
if channel_id is None: if channel_id is None:
raise ParameterError('required channel_id') raise ParameterError("required channel_id")
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/channels/follow'), auth=True, json={'channelId': channel_id} Route("POST", "/api/channels/follow"), auth=True, json={"channelId": channel_id}
) )
return res return res
@ -123,10 +123,10 @@ class ClientChannelActions(AbstractAction):
channel_id = self._channel_id or channel_id channel_id = self._channel_id or channel_id
if channel_id is None: if channel_id is None:
raise ParameterError('required channel_id') raise ParameterError("required channel_id")
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/channels/unfollow'), auth=True, json={'channelId': channel_id} Route("POST", "/api/channels/unfollow"), auth=True, json={"channelId": channel_id}
) )
return res return res
@ -173,19 +173,19 @@ class ClientChannelActions(AbstractAction):
channel_id = self._channel_id or channel_id channel_id = self._channel_id or channel_id
if channel_id is None: if channel_id is None:
raise ParameterError('required channel_id') raise ParameterError("required channel_id")
body = { body = {
'channelId': channel_id, "channelId": channel_id,
'name': name, "name": name,
'description': description, "description": description,
'bannerId': banner_id, "bannerId": banner_id,
'isArchived': is_archived, "isArchived": is_archived,
'pinnedNoteIds': pinned_note_ids, "pinnedNoteIds": pinned_note_ids,
'color': color, "color": color,
} }
res: IChannel = await self._session.request( res: IChannel = await self._session.request(
Route('POST', '/api/channels/update'), auth=True, json=body Route("POST", "/api/channels/update"), auth=True, json=body
) )
return Channel(res, client=self._client) return Channel(res, client=self._client)
@ -209,7 +209,7 @@ class ClientChannelActions(AbstractAction):
channel_id = self._channel_id or channel_id channel_id = self._channel_id or channel_id
if channel_id is None: if channel_id is None:
raise ParameterError('required channel_id') raise ParameterError("required channel_id")
res = await self.update(channel_id=channel_id, is_archived=True) res = await self.update(channel_id=channel_id, is_archived=True)
@ -234,7 +234,7 @@ class ClientChannelActions(AbstractAction):
channel_id = self._channel_id or channel_id channel_id = self._channel_id or channel_id
if channel_id is None: if channel_id is None:
raise ParameterError('required channel_id') raise ParameterError("required channel_id")
res = await self.update(channel_id=channel_id, is_archived=False) res = await self.update(channel_id=channel_id, is_archived=False)
@ -252,7 +252,7 @@ class ChannelActions(ClientChannelActions):
name: str, name: str,
description: str | None = None, description: str | None = None,
banner_id: str | None = None, banner_id: str | None = None,
color: str = '#000', color: str = "#000",
) -> ChannelLite: ) -> ChannelLite:
""" """
Create a channel. Create a channel.
@ -276,9 +276,9 @@ class ChannelActions(ClientChannelActions):
if self._client._config.use_version < 13: if self._client._config.use_version < 13:
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
body = {'name': name, 'description': description, 'bannerId': banner_id, 'color': color} body = {"name": name, "description": description, "bannerId": banner_id, "color": color}
res: IChannel = await self._session.request( res: IChannel = await self._session.request(
Route('POST', '/api/channels/create'), auth=True, json=body Route("POST", "/api/channels/create"), auth=True, json=body
) )
return ChannelLite(res, client=self._client) return ChannelLite(res, client=self._client)
@ -297,7 +297,7 @@ class ChannelActions(ClientChannelActions):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
res: list[IChannel] = await self._session.request( res: list[IChannel] = await self._session.request(
Route('POST', '/api/channels/featured'), auth=True Route("POST", "/api/channels/featured"), auth=True
) )
return [Channel(i, client=self._client) for i in res] return [Channel(i, client=self._client) for i in res]
@ -332,15 +332,15 @@ class ChannelActions(ClientChannelActions):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
if limit > 100: if limit > 100:
raise ParameterError('limit must be less than 100') raise ParameterError("limit must be less than 100")
if get_all: if get_all:
limit = 100 limit = 100
body = {'sinceId': since_id, 'untilId': until_id, 'limit': limit} body = {"sinceId": since_id, "untilId": until_id, "limit": limit}
pagination = Pagination[IChannel]( pagination = Pagination[IChannel](
self._session, Route('POST', '/api/channels/followed'), auth=True, json=body self._session, Route("POST", "/api/channels/followed"), auth=True, json=body
) )
while True: while True:
@ -375,10 +375,10 @@ class ChannelActions(ClientChannelActions):
if self._client._config.use_version < 13: if self._client._config.use_version < 13:
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
body = {'sinceId': since_id, 'untilId': until_id} body = {"sinceId": since_id, "untilId": until_id}
pagination = Pagination[IChannel]( pagination = Pagination[IChannel](
self._session, Route('POST', '/api/channels/owned'), auth=True, json=body self._session, Route("POST", "/api/channels/owned"), auth=True, json=body
) )
while True: while True:
@ -407,7 +407,7 @@ class ChannelActions(ClientChannelActions):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
res: IChannel = await self._session.request( res: IChannel = await self._session.request(
Route('POST', '/api/channels/show'), auth=True, json={'channelId': channel_id} Route("POST", "/api/channels/show"), auth=True, json={"channelId": channel_id}
) )
return Channel(res, client=self._client) return Channel(res, client=self._client)
@ -424,14 +424,14 @@ class ChannelActions(ClientChannelActions):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
res: list[IChannel] = await self._session.request( res: list[IChannel] = await self._session.request(
Route('POST', '/api/channels/my-favorites'), auth=True Route("POST", "/api/channels/my-favorites"), auth=True
) )
return [Channel(i, client=self._client) for i in res] return [Channel(i, client=self._client) for i in res]
async def search( async def search(
self, self,
query: str, query: str,
type: Literal['nameAndDescription', 'nameOnly'] = 'nameAndDescription', type: Literal["nameAndDescription", "nameOnly"] = "nameAndDescription",
since_id: str | None = None, since_id: str | None = None,
until_id: str | None = None, until_id: str | None = None,
limit: int = 5, limit: int = 5,
@ -465,21 +465,21 @@ class ChannelActions(ClientChannelActions):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
if limit > 100: if limit > 100:
raise ParameterError('limit must be less than 100') raise ParameterError("limit must be less than 100")
if get_all: if get_all:
limit = 100 limit = 100
body = { body = {
'query': query, "query": query,
'type': type, "type": type,
'sinceId': since_id, "sinceId": since_id,
'untilId': until_id, "untilId": until_id,
'limit': limit, "limit": limit,
} }
pagination = Pagination[IChannel]( pagination = Pagination[IChannel](
self._session, Route('POST', '/api/channels/search'), auth=True, json=body self._session, Route("POST", "/api/channels/search"), auth=True, json=body
) )
while True: while True:

@ -16,17 +16,23 @@ class ChartActions(AbstractAction):
self.__client = client self.__client = client
async def get_active_user( async def get_active_user(
self, span: str = 'day', limit: int = 30, offset: int = 0 self, span: str = "day", limit: int = 30, offset: int = 0
) -> ActiveUsersChart: ) -> ActiveUsersChart:
data = {'span': span, 'limit': limit, 'offset': offset} data = {"span": span, "limit": limit, "offset": offset}
data = await self.__session.request( data = await self.__session.request(
Route('POST', '/api/charts/active-users'), json=data, auth=True, lower=True, Route("POST", "/api/charts/active-users"),
json=data,
auth=True,
lower=True,
) )
return ActiveUsersChart(data) return ActiveUsersChart(data)
async def get_drive(self, span: str = 'day', limit: int = 30, offset: int = 0) -> DriveChart: async def get_drive(self, span: str = "day", limit: int = 30, offset: int = 0) -> DriveChart:
data = {'span': span, 'limit': limit, 'offset': offset} data = {"span": span, "limit": limit, "offset": offset}
data = await self.__session.request( data = await self.__session.request(
Route('POST', '/api/charts/drive'), json=data, auth=True, lower=True, Route("POST", "/api/charts/drive"),
json=data,
auth=True,
lower=True,
) )
return DriveChart(data) return DriveChart(data)

@ -48,11 +48,14 @@ class BaseChatAction(AbstractAction):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
if check_multi_arg(message_id, self.__message_id) is False: if check_multi_arg(message_id, self.__message_id) is False:
raise ParameterError('message_idがありません') raise ParameterError("message_idがありません")
message_id = message_id or self.__message_id message_id = message_id or self.__message_id
body = {'messageId': message_id} body = {"messageId": message_id}
res: bool = await self.__session.request( res: bool = await self.__session.request(
Route('POST', '/api/messaging/messages/read'), json=body, auth=True, lower=True, Route("POST", "/api/messaging/messages/read"),
json=body,
auth=True,
lower=True,
) )
return res return res
@ -77,12 +80,14 @@ class BaseChatAction(AbstractAction):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
if check_multi_arg(message_id, self.__message_id) is False: if check_multi_arg(message_id, self.__message_id) is False:
raise ParameterError('message_idがありません') raise ParameterError("message_idがありません")
message_id = message_id or self.__message_id message_id = message_id or self.__message_id
body = {'messageId': f'{message_id}'} body = {"messageId": f"{message_id}"}
res: bool = await self.__session.request( res: bool = await self.__session.request(
Route('POST', '/api/messaging/messages/delete'), json=body, auth=True, Route("POST", "/api/messaging/messages/delete"),
json=body,
auth=True,
) )
return bool(res) return bool(res)
@ -125,11 +130,11 @@ class ChatAction(BaseChatAction):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
if limit > 100: if limit > 100:
raise ParameterError('limit must be greater than 100') raise ParameterError("limit must be greater than 100")
args = {'limit': limit, 'group': group} args = {"limit": limit, "group": group}
data: list[IChatMessage] = await self.__session.request( data: list[IChatMessage] = await self.__session.request(
Route('POST', '/api/messaging/history'), json=args, auth=True Route("POST", "/api/messaging/history"), json=args, auth=True
) )
return [ChatMessage(d, client=self.__client) for d in data] return [ChatMessage(d, client=self.__client) for d in data]
@ -162,12 +167,15 @@ class ChatAction(BaseChatAction):
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = { data = {
'userId': user_id, "userId": user_id,
'groupId': group_id, "groupId": group_id,
'text': text, "text": text,
'fileId': file_id, "fileId": file_id,
} }
res = await self.__session.request( res = await self.__session.request(
Route('POST', '/api/messaging/messages/create'), json=data, auth=True, lower=True, Route("POST", "/api/messaging/messages/create"),
json=data,
auth=True,
lower=True,
) )
return ChatMessage(res, client=self.__client) return ChatMessage(res, client=self.__client)

@ -31,10 +31,10 @@ class ClientActions(AbstractAction):
async def get_meta(self, detail: bool = False): async def get_meta(self, detail: bool = False):
params = { params = {
'route': Route('POST', '/api/meta'), "route": Route("POST", "/api/meta"),
'json': {'detail': detail}, "json": {"detail": detail},
'auth': True, "auth": True,
'lower': True, "lower": True,
} }
if detail is True: if detail is True:
meta: IMeta = await self.__session.request(**params) meta: IMeta = await self.__session.request(**params)
@ -49,22 +49,22 @@ class ClientActions(AbstractAction):
since_id: str | None = None, since_id: str | None = None,
until_id: str | None = None, until_id: str | None = None,
*, *,
get_all: bool = False get_all: bool = False,
) -> AsyncGenerator[Announcement, None]: ) -> AsyncGenerator[Announcement, None]:
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = { body = {
'limit': limit, "limit": limit,
'withUnreads': with_unreads, "withUnreads": with_unreads,
'sinceId': since_id, "sinceId": since_id,
'untilId': until_id, "untilId": until_id,
} }
pagination = Pagination[IAnnouncement]( pagination = Pagination[IAnnouncement](
self.__session, Route('POST', '/api/announcements'), json=body self.__session, Route("POST", "/api/announcements"), json=body
) )
while True: while True:

@ -52,18 +52,18 @@ class ClientClipActions(AbstractAction):
clip_id = self._clip_id or clip_id clip_id = self._clip_id or clip_id
if clip_id is None: if clip_id is None:
raise ParameterError('clip_id is required') raise ParameterError("clip_id is required")
if limit > 100: if limit > 100:
raise ParameterError('limit must be less than 100') raise ParameterError("limit must be less than 100")
if get_all: if get_all:
limit = 100 limit = 100
body = {'clipId': clip_id, 'limit': limit, 'sinceId': since_id, 'untilId': until_id} body = {"clipId": clip_id, "limit": limit, "sinceId": since_id, "untilId": until_id}
pagination = Pagination[INote]( pagination = Pagination[INote](
self._session, Route('POST', '/api/clips/notes'), json=body, auth=True self._session, Route("POST", "/api/clips/notes"), json=body, auth=True
) )
while True: while True:
@ -92,11 +92,11 @@ class ClientClipActions(AbstractAction):
clip_id = self._clip_id or clip_id clip_id = self._clip_id or clip_id
if clip_id is None: if clip_id is None:
raise ParameterError('clip_id is required') raise ParameterError("clip_id is required")
body = {'clipId': clip_id, 'noteId': note_id} body = {"clipId": clip_id, "noteId": note_id}
result: bool = await self._session.request( result: bool = await self._session.request(
Route('POST', '/api/clips/add-note'), json=body, auth=True Route("POST", "/api/clips/add-note"), json=body, auth=True
) )
return result return result
@ -118,11 +118,11 @@ class ClientClipActions(AbstractAction):
clip_id = self._clip_id or clip_id clip_id = self._clip_id or clip_id
if clip_id is None: if clip_id is None:
raise ParameterError('clip_id is required') raise ParameterError("clip_id is required")
body = {'clipId': clip_id, 'noteId': note_id} body = {"clipId": clip_id, "noteId": note_id}
result: bool = await self._session.request( result: bool = await self._session.request(
Route('POST', '/api/clips/remove-note'), json=body, auth=True Route("POST", "/api/clips/remove-note"), json=body, auth=True
) )
return result return result
@ -142,11 +142,11 @@ class ClientClipActions(AbstractAction):
clip_id = self._clip_id or clip_id clip_id = self._clip_id or clip_id
if clip_id is None: if clip_id is None:
raise ParameterError('clip_id is required') raise ParameterError("clip_id is required")
body = {'clipId': clip_id} body = {"clipId": clip_id}
result: bool = await self._session.request( result: bool = await self._session.request(
Route('POST', '/api/clips/delete'), json=body, auth=True Route("POST", "/api/clips/delete"), json=body, auth=True
) )
return result return result
@ -179,11 +179,11 @@ class ClientClipActions(AbstractAction):
clip_id = self._clip_id or clip_id clip_id = self._clip_id or clip_id
if clip_id is None: if clip_id is None:
raise ParameterError('clip_id is required') raise ParameterError("clip_id is required")
body = {'clipId': clip_id, 'name': name, 'isPublic': is_public, 'description': description} body = {"clipId": clip_id, "name": name, "isPublic": is_public, "description": description}
result: IClip = await self._session.request( result: IClip = await self._session.request(
Route('POST', '/api/clips/update'), json=body, auth=True Route("POST", "/api/clips/update"), json=body, auth=True
) )
return Clip(result, client=self._client) return Clip(result, client=self._client)
@ -201,7 +201,7 @@ class ClipActions(ClientClipActions):
The favorite clips The favorite clips
""" """
clips: list[INote] = await self._session.request( clips: list[INote] = await self._session.request(
Route('POST', '/api/clips/my-favorites'), auth=True Route("POST", "/api/clips/my-favorites"), auth=True
) )
return [Note(raw_clip, client=self._client) for raw_clip in clips] return [Note(raw_clip, client=self._client) for raw_clip in clips]
@ -224,9 +224,9 @@ class ClipActions(ClientClipActions):
Clip Clip
The created clip The created clip
""" """
body = {'name': name, 'isPublic': is_public, 'description': description} body = {"name": name, "isPublic": is_public, "description": description}
clip: IClip = await self._session.request( clip: IClip = await self._session.request(
Route('POST', '/api/clips/create'), json=body, auth=True Route("POST", "/api/clips/create"), json=body, auth=True
) )
return Clip(clip, client=self._client) return Clip(clip, client=self._client)
@ -239,7 +239,7 @@ class ClipActions(ClientClipActions):
The clips The clips
""" """
clips: list[IClip] = await self._session.request( clips: list[IClip] = await self._session.request(
Route('POST', '/api/clips/list'), auth=True Route("POST", "/api/clips/list"), auth=True
) )
return [Clip(raw_clip, client=self._client) for raw_clip in clips] return [Clip(raw_clip, client=self._client) for raw_clip in clips]
@ -256,8 +256,8 @@ class ClipActions(ClientClipActions):
Clip Clip
The clip The clip
""" """
body = {'clipId': clip_id} body = {"clipId": clip_id}
clip: IClip = await self._session.request( clip: IClip = await self._session.request(
Route('POST', '/api/clips/show'), json=body, auth=True Route("POST", "/api/clips/show"), json=body, auth=True
) )
return Clip(clip, client=self._client) return Clip(clip, client=self._client)

@ -17,7 +17,7 @@ from mipac.utils.util import deprecated
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
__all__ = ('DriveActions', 'FileActions', 'FolderActions') __all__ = ("DriveActions", "FileActions", "FolderActions")
class ClientFileActions(AbstractAction): class ClientFileActions(AbstractAction):
@ -28,7 +28,7 @@ class ClientFileActions(AbstractAction):
url: str | None = None, url: str | None = None,
*, *,
session: HTTPClient, session: HTTPClient,
client: ClientManager client: ClientManager,
) -> None: ) -> None:
self._session: HTTPClient = session self._session: HTTPClient = session
self._client: ClientManager = client self._client: ClientManager = client
@ -53,11 +53,13 @@ class ClientFileActions(AbstractAction):
file_id = file_id or self._file_id file_id = file_id or self._file_id
if file_id is None: if file_id is None:
raise ParameterError('file_id is required') raise ParameterError("file_id is required")
return bool( return bool(
await self._session.request( await self._session.request(
Route('POST', '/api/drive/files/delete'), json={'fileId': file_id}, auth=True, Route("POST", "/api/drive/files/delete"),
json={"fileId": file_id},
auth=True,
) )
) )
@ -70,7 +72,7 @@ class ClientFileActions(AbstractAction):
file_id = file_id or self._file_id file_id = file_id or self._file_id
url = url or self._url url = url or self._url
if any([file_id, url]) is False: if any([file_id, url]) is False:
raise ParameterError('file_id is required') raise ParameterError("file_id is required")
if url is None: if url is None:
result = await self._client.drive.file.action.show_file(file_id=file_id) result = await self._client.drive.file.action.show_file(file_id=file_id)
@ -79,12 +81,12 @@ class ClientFileActions(AbstractAction):
async with self._session.session.get(url) as resp: async with self._session.session.get(url) as resp:
if resp.status == 200: if resp.status == 200:
content = await resp.read() content = await resp.read()
with open(fp, 'wb') as f: with open(fp, "wb") as f:
return f.write(content) return f.write(content)
elif resp.status == 400: elif resp.status == 400:
raise FileNotFoundError('File not found') raise FileNotFoundError("File not found")
else: else:
raise HTTPException(resp, 'Failed to get file') raise HTTPException(resp, "Failed to get file")
@deprecated @deprecated
async def remove_file(self, file_id: str | None = None) -> bool: async def remove_file(self, file_id: str | None = None) -> bool:
@ -105,7 +107,9 @@ class ClientFileActions(AbstractAction):
file_id = file_id or self._file_id file_id = file_id or self._file_id
return bool( return bool(
await self._session.request( await self._session.request(
Route('POST', '/api/drive/files/delete'), json={'fileId': file_id}, auth=True, Route("POST", "/api/drive/files/delete"),
json={"fileId": file_id},
auth=True,
) )
) )
@ -118,7 +122,7 @@ class FileActions(ClientFileActions):
url: str | None = None, url: str | None = None,
*, *,
session: HTTPClient, session: HTTPClient,
client: ClientManager client: ClientManager,
) -> None: ) -> None:
super().__init__( super().__init__(
file_id=file_id, folder_id=folder_id, url=url, session=session, client=client file_id=file_id, folder_id=folder_id, url=url, session=session, client=client
@ -141,9 +145,12 @@ class FileActions(ClientFileActions):
ファイルの情報 ファイルの情報
""" """
data = remove_dict_empty({'fileId': file_id, 'url': url}) data = remove_dict_empty({"fileId": file_id, "url": url})
res: IDriveFile = await self._session.request( res: IDriveFile = await self._session.request(
Route('POST', '/api/admin/drive/show-file'), json=data, auth=True, lower=True, Route("POST", "/api/admin/drive/show-file"),
json=data,
auth=True,
lower=True,
) )
return File(res, client=self._client) return File(res, client=self._client)
@ -173,7 +180,7 @@ class FileActions(ClientFileActions):
取得したいファイルの拡張子 取得したいファイルの拡張子
""" """
if limit > 100: if limit > 100:
raise ParameterError('limit must be less than 100') raise ParameterError("limit must be less than 100")
if get_all: if get_all:
limit = 100 limit = 100
@ -181,15 +188,15 @@ class FileActions(ClientFileActions):
folder_id = self._folder_id or folder_id folder_id = self._folder_id or folder_id
body = { body = {
'limit': limit, "limit": limit,
'sinceId': since_id, "sinceId": since_id,
'untilId': until_id, "untilId": until_id,
'folderId': folder_id, "folderId": folder_id,
'Type': file_type, "Type": file_type,
} }
pagination = Pagination[IDriveFile]( pagination = Pagination[IDriveFile](
self._session, Route('POST', '/api/drive/files'), json=body self._session, Route("POST", "/api/drive/files"), json=body
) )
while True: while True:
@ -233,19 +240,22 @@ class FileActions(ClientFileActions):
File File
アップロードしたファイルの情報 アップロードしたファイルの情報
""" """
file_byte = open(file, 'rb') if file else None file_byte = open(file, "rb") if file else None
folder_id = self._folder_id or folder_id folder_id = self._folder_id or folder_id
data = { data = {
'file': file_byte, "file": file_byte,
'name': file_name, "name": file_name,
'folderId': folder_id, "folderId": folder_id,
'comment': comment, "comment": comment,
'isSensitive': bool_to_string(is_sensitive), "isSensitive": bool_to_string(is_sensitive),
'force': bool_to_string(force), "force": bool_to_string(force),
} }
res: IDriveFile = await self._session.request( res: IDriveFile = await self._session.request(
Route('POST', '/api/drive/files/create'), data=data, auth=True, lower=True, Route("POST", "/api/drive/files/create"),
data=data,
auth=True,
lower=True,
) )
return File(res, client=self._client) return File(res, client=self._client)
@ -276,9 +286,12 @@ class ClientFolderActions(AbstractAction):
""" """
parent_id = parent_id or self._folder_id parent_id = parent_id or self._folder_id
data = {'name': name, 'parent_id': parent_id} data = {"name": name, "parent_id": parent_id}
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/drive/folders/create'), json=data, lower=True, auth=True, Route("POST", "/api/drive/folders/create"),
json=data,
lower=True,
auth=True,
) )
return bool(res) return bool(res)
@ -295,9 +308,12 @@ class ClientFolderActions(AbstractAction):
削除に成功したか否か 削除に成功したか否か
""" """
folder_id = folder_id or self._folder_id folder_id = folder_id or self._folder_id
data = {'folderId': folder_id} data = {"folderId": folder_id}
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/drive/folders/delete'), json=data, lower=True, auth=True, Route("POST", "/api/drive/folders/delete"),
json=data,
lower=True,
auth=True,
) )
return bool(res) return bool(res)
@ -327,7 +343,7 @@ class ClientFolderActions(AbstractAction):
取得したいファイルの拡張子 取得したいファイルの拡張子
""" """
if limit > 100: if limit > 100:
raise ParameterError('limit must be less than 100') raise ParameterError("limit must be less than 100")
if get_all: if get_all:
limit = 100 limit = 100
@ -335,15 +351,15 @@ class ClientFolderActions(AbstractAction):
folder_id = self._folder_id or folder_id folder_id = self._folder_id or folder_id
body = { body = {
'limit': limit, "limit": limit,
'sinceId': since_id, "sinceId": since_id,
'untilId': until_id, "untilId": until_id,
'folderId': folder_id, "folderId": folder_id,
'Type': file_type, "Type": file_type,
} }
pagination = Pagination[IDriveFile]( pagination = Pagination[IDriveFile](
self._session, Route('POST', '/api/drive/files'), json=body self._session, Route("POST", "/api/drive/files"), json=body
) )
while True: while True:
@ -394,19 +410,19 @@ class DriveActions(AbstractAction):
""" """
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = { body = {
'limit': limit, "limit": limit,
'sinceId': since_id, "sinceId": since_id,
'untilId': until_id, "untilId": until_id,
'folderId': folder_id, "folderId": folder_id,
} }
pagination = Pagination[FolderPayload]( pagination = Pagination[FolderPayload](
self._session, Route('POST', '/api/drive/folders'), json=body self._session, Route("POST", "/api/drive/folders"), json=body
) )
while True: while True:

@ -21,6 +21,6 @@ class EmojiActions(AbstractAction):
if self.__client._config.use_version < 13: if self.__client._config.use_version < 13:
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
emoji: ICustomEmoji = await self.__session.request( emoji: ICustomEmoji = await self.__session.request(
Route('POST', '/api/emoji'), auth=True, lower=True, json={'name': name} Route("POST", "/api/emoji"), auth=True, lower=True, json={"name": name}
) )
return CustomEmoji(emoji=emoji, client=self.__client) return CustomEmoji(emoji=emoji, client=self.__client)

@ -18,18 +18,22 @@ class FavoriteActions(AbstractAction):
async def add(self, note_id: str | None = None) -> bool: async def add(self, note_id: str | None = None) -> bool:
note_id = note_id or self.__note_id note_id = note_id or self.__note_id
data = {'noteId': note_id} data = {"noteId": note_id}
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/notes/favorites/create'), json=data, auth=True, Route("POST", "/api/notes/favorites/create"),
json=data,
auth=True,
) )
) )
async def remove(self, note_id: str | None = None) -> bool: async def remove(self, note_id: str | None = None) -> bool:
note_id = note_id or self.__note_id note_id = note_id or self.__note_id
data = {'noteId': note_id} data = {"noteId": note_id}
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/notes/favorites/delete'), json=data, auth=True, Route("POST", "/api/notes/favorites/delete"),
json=data,
auth=True,
) )
) )

@ -24,7 +24,7 @@ class FederationActions(AbstractAction):
async def get_ap(self, uri: str) -> dict[Any, Any]: async def get_ap(self, uri: str) -> dict[Any, Any]:
return dict( return dict(
await self.__session.request( await self.__session.request(
Route('POST', '/api/ap/get'), auth=True, json={'uri': uri}, lower=True Route("POST", "/api/ap/get"), auth=True, json={"uri": uri}, lower=True
) )
) )
@ -32,10 +32,10 @@ class FederationActions(AbstractAction):
self, host: str, since_id: str | None = None, until_id: str | None = None, limit: int = 10 self, host: str, since_id: str | None = None, until_id: str | None = None, limit: int = 10
) -> FederationInstance: ) -> FederationInstance:
# TODO: これ本当にuntilId必要なのか確認する # TODO: これ本当にuntilId必要なのか確認する
body = {'host': host, 'sinceId': since_id, 'untilId': until_id, 'limit': limit} body = {"host": host, "sinceId": since_id, "untilId": until_id, "limit": limit}
res: FederationInstance = await self.__session.request( res: FederationInstance = await self.__session.request(
Route('POST', '/api/ap/show'), auth=True, json=body Route("POST", "/api/ap/show"), auth=True, json=body
) )
return res return res
@ -47,17 +47,16 @@ class FederationActions(AbstractAction):
limit: int = 10, limit: int = 10,
get_all: bool = False, get_all: bool = False,
): ):
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = {'host': host, 'sinceId': since_id, 'untilId': until_id, 'limit': limit} body = {"host": host, "sinceId": since_id, "untilId": until_id, "limit": limit}
pagination = Pagination[IFederationFollower]( pagination = Pagination[IFederationFollower](
self.__session, Route('POST', '/api/federation/followers'), json=body self.__session, Route("POST", "/api/federation/followers"), json=body
) )
while True: while True:
@ -76,17 +75,16 @@ class FederationActions(AbstractAction):
limit: int = 10, limit: int = 10,
get_all: bool = False, get_all: bool = False,
): ):
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = {'host': host, 'sinceId': since_id, 'untilId': until_id, 'limit': limit} body = {"host": host, "sinceId": since_id, "untilId": until_id, "limit": limit}
pagination = Pagination[IFederationFollowing]( pagination = Pagination[IFederationFollowing](
self.__session, Route('POST', '/api/federation/following'), json=body self.__session, Route("POST", "/api/federation/following"), json=body
) )
while True: while True:
@ -111,31 +109,31 @@ class FederationActions(AbstractAction):
sort: str | None = None, sort: str | None = None,
) -> list[FederationInstance]: ) -> list[FederationInstance]:
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
body = { body = {
'host': host, "host": host,
'blocked': blocked, "blocked": blocked,
'notResponding': not_responding, "notResponding": not_responding,
'suspended': suspended, "suspended": suspended,
'federating': federating, "federating": federating,
'subscribing': subscribing, "subscribing": subscribing,
'publishing': publishing, "publishing": publishing,
'limit': limit, "limit": limit,
'offset': offset, "offset": offset,
'sort': sort, "sort": sort,
} }
res: list[IFederationInstance] = await self.__session.request( res: list[IFederationInstance] = await self.__session.request(
Route('POST', '/api/federation/instances'), auth=True, lower=True, json=body Route("POST", "/api/federation/instances"), auth=True, lower=True, json=body
) )
return [FederationInstance(i, client=self.__client) for i in res] return [FederationInstance(i, client=self.__client) for i in res]
async def show_instance(self, host: str) -> FederationInstance: async def show_instance(self, host: str) -> FederationInstance:
res: IFederationInstance = await self.__session.request( res: IFederationInstance = await self.__session.request(
Route('POST', '/api/federation/show-instance'), Route("POST", "/api/federation/show-instance"),
auth=True, auth=True,
json={'host': host}, json={"host": host},
lower=True, lower=True,
) )
@ -144,9 +142,9 @@ class FederationActions(AbstractAction):
async def update_remote_user(self, user_id: str) -> bool: async def update_remote_user(self, user_id: str) -> bool:
return bool( return bool(
self.__session.request( self.__session.request(
Route('POST', '/api/federation/update-remote-user'), Route("POST", "/api/federation/update-remote-user"),
auth=True, auth=True,
json={'userId': user_id}, json={"userId": user_id},
) )
) )
@ -159,15 +157,15 @@ class FederationActions(AbstractAction):
get_all: bool = False, get_all: bool = False,
) -> AsyncGenerator[UserDetailed, None]: ) -> AsyncGenerator[UserDetailed, None]:
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = {'host': host, 'sinceId': since_id, 'untilId': until_id, 'limit': limit} body = {"host": host, "sinceId": since_id, "untilId": until_id, "limit": limit}
pagination = Pagination[IUserDetailed]( pagination = Pagination[IUserDetailed](
self.__session, Route('POST', '/api/federation/users'), json=body self.__session, Route("POST", "/api/federation/users"), json=body
) )
while True: while True:
@ -180,8 +178,8 @@ class FederationActions(AbstractAction):
async def get_stats(self, limit: int = 10) -> IFederationInstanceStat: async def get_stats(self, limit: int = 10) -> IFederationInstanceStat:
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
res: IFederationInstanceStat = await self.__session.request( res: IFederationInstanceStat = await self.__session.request(
Route('POST', '/api/federation/stats'), auth=True, body={'limit': limit}, lower=True Route("POST", "/api/federation/stats"), auth=True, body={"limit": limit}, lower=True
) )
return res return res

@ -32,9 +32,12 @@ class FollowActions(AbstractAction):
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
res: ILiteUser = await self.__session.request( res: ILiteUser = await self.__session.request(
Route('POST', '/api/following/create'), json=data, auth=True, lower=True, Route("POST", "/api/following/create"),
json=data,
auth=True,
lower=True,
) )
return LiteUser(res, client=self.__client) return LiteUser(res, client=self.__client)
@ -50,9 +53,9 @@ class FollowActions(AbstractAction):
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
res = await self.__session.request( res = await self.__session.request(
Route('POST', '/api/following/delete'), json=data, auth=True Route("POST", "/api/following/delete"), json=data, auth=True
) )
return LiteUser(res, client=self.__client) return LiteUser(res, client=self.__client)
@ -68,9 +71,9 @@ class FollowActions(AbstractAction):
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
res: ILiteUser = await self.__session.request( res: ILiteUser = await self.__session.request(
Route('POST', '/api/following/invalidate'), json=data, auth=True Route("POST", "/api/following/invalidate"), json=data, auth=True
) )
return LiteUser(res, client=self.__client) return LiteUser(res, client=self.__client)
@ -92,7 +95,9 @@ class FollowRequestActions(AbstractAction):
""" """
res: list[IFollowRequest] = await self.__session.request( res: list[IFollowRequest] = await self.__session.request(
Route('POST', '/api/following/requests/list'), auth=True, lower=True, Route("POST", "/api/following/requests/list"),
auth=True,
lower=True,
) )
return [FollowRequest(follow_request=i, client=self.__client) for i in res] return [FollowRequest(follow_request=i, client=self.__client) for i in res]
@ -113,10 +118,12 @@ class FollowRequestActions(AbstractAction):
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/following/requests/accept'), json=data, auth=True, Route("POST", "/api/following/requests/accept"),
json=data,
auth=True,
) )
) )
@ -137,10 +144,12 @@ class FollowRequestActions(AbstractAction):
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
return bool( return bool(
await self.__session.request( await self.__session.request(
Route('POST', '/api/following/requests/reject'), json=data, auth=True, Route("POST", "/api/following/requests/reject"),
json=data,
auth=True,
) )
) )
@ -161,8 +170,11 @@ class FollowRequestActions(AbstractAction):
user_id = user_id or self.__user_id user_id = user_id or self.__user_id
data = {'userId': user_id} data = {"userId": user_id}
res: ILiteUser = await self.__session.request( res: ILiteUser = await self.__session.request(
Route('POST', '/api/following/requests/cancel'), json=data, auth=True, lower=True, Route("POST", "/api/following/requests/cancel"),
json=data,
auth=True,
lower=True,
) )
return LiteUser(res, client=self.__client) return LiteUser(res, client=self.__client)

@ -36,9 +36,9 @@ class MuteActions(AbstractAction):
""" """
user_id = user_id or self._user_id user_id = user_id or self._user_id
data = {'userId': user_id} data = {"userId": user_id}
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/mute/create'), auth=True, json=data Route("POST", "/api/mute/create"), auth=True, json=data
) )
return res return res
@ -58,9 +58,9 @@ class MuteActions(AbstractAction):
""" """
user_id = user_id or self._user_id user_id = user_id or self._user_id
data = {'userId': user_id} data = {"userId": user_id}
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/mute/delete'), auth=True, json=data Route("POST", "/api/mute/delete"), auth=True, json=data
) )
return res return res
@ -72,15 +72,15 @@ class MuteActions(AbstractAction):
get_all: bool = True, get_all: bool = True,
) -> AsyncGenerator[MuteUser, None]: ) -> AsyncGenerator[MuteUser, None]:
if limit > 100: if limit > 100:
raise ParameterError('limit は100以下である必要があります') raise ParameterError("limit は100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = remove_dict_empty({'limit': limit, 'sinceId': since_id, 'untilId': until_id}) body = remove_dict_empty({"limit": limit, "sinceId": since_id, "untilId": until_id})
pagination = Pagination[IMuteUser]( pagination = Pagination[IMuteUser](
self._session, Route('POST', '/api/mute/list'), json=body self._session, Route("POST", "/api/mute/list"), json=body
) )
while True: while True:

@ -20,7 +20,9 @@ class MyActions(AbstractAction):
async def fetch_follow_requests(self) -> list[FollowRequest]: async def fetch_follow_requests(self) -> list[FollowRequest]:
res: list[IFollowRequest] = await self.__session.request( res: list[IFollowRequest] = await self.__session.request(
Route('POST', '/api/following/requests/list'), auth=True, lower=True, Route("POST", "/api/following/requests/list"),
auth=True,
lower=True,
) )
return [FollowRequest(i, client=self.__client) for i in res] return [FollowRequest(i, client=self.__client) for i in res]
@ -45,6 +47,6 @@ class MyActions(AbstractAction):
if self.__client._config.use_version < 13: if self.__client._config.use_version < 13:
raise NotSupportVersion(NotSupportVersionText) raise NotSupportVersion(NotSupportVersionText)
res: bool = await self.__session.request( res: bool = await self.__session.request(
Route('POST', '/api/i/claim-achievement'), auth=True, json={'name': name}, lower=True Route("POST", "/api/i/claim-achievement"), auth=True, json={"name": name}, lower=True
) )
return res return res

@ -20,12 +20,12 @@ from mipac.utils.util import check_multi_arg
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.client import ClientManager from mipac.client import ClientManager
__all__ = ['NoteActions'] __all__ = ["NoteActions"]
def create_note_body( def create_note_body(
content: str | None = None, content: str | None = None,
visibility: INoteVisibility = 'public', visibility: INoteVisibility = "public",
visible_user_ids: list[str] | None = None, visible_user_ids: list[str] | None = None,
cw: str | None = None, cw: str | None = None,
local_only: bool = False, local_only: bool = False,
@ -40,31 +40,31 @@ def create_note_body(
): ):
content = content or None content = content or None
body = { body = {
'visibility': visibility, "visibility": visibility,
'visibleUserIds': visible_user_ids, "visibleUserIds": visible_user_ids,
'text': content, "text": content,
'cw': cw, "cw": cw,
'localOnly': local_only, "localOnly": local_only,
'noExtractMentions': not extract_mentions, "noExtractMentions": not extract_mentions,
'noExtractHashtags': not extract_hashtags, "noExtractHashtags": not extract_hashtags,
'noExtractEmojis': not extract_emojis, "noExtractEmojis": not extract_emojis,
'replyId': reply_id, "replyId": reply_id,
'renoteId': renote_id, "renoteId": renote_id,
'channelId': channel_id, "channelId": channel_id,
} }
if not check_multi_arg(content, files, renote_id, poll): if not check_multi_arg(content, files, renote_id, poll):
raise ParameterError('ートの送信にはcontent, file_ids, renote_id またはpollのいずれか1つが無くてはいけません') raise ParameterError("ートの送信にはcontent, file_ids, renote_id またはpollのいずれか1つが無くてはいけません")
if poll and type(Poll): if poll and type(Poll):
poll_data = remove_dict_empty( poll_data = remove_dict_empty(
{ {
'choices': poll.choices, "choices": poll.choices,
'multiple': poll.multiple, "multiple": poll.multiple,
'expiresAt': poll.expires_at, "expiresAt": poll.expires_at,
'expiredAfter': poll.expired_after, "expiredAfter": poll.expired_after,
} }
) )
body['poll'] = poll_data body["poll"] = poll_data
if files: if files:
file_ids = [] file_ids = []
for file in files: for file in files:
@ -75,15 +75,19 @@ def create_note_body(
elif isinstance(file, str): elif isinstance(file, str):
file_ids.append(file) file_ids.append(file)
else: else:
raise ParameterError('files must be MiFile or str or File') raise ParameterError("files must be MiFile or str or File")
body['fileIds'] = file_ids body["fileIds"] = file_ids
return remove_dict_empty(body) return remove_dict_empty(body)
class ClientNoteActions(AbstractAction): class ClientNoteActions(AbstractAction):
def __init__( def __init__(
self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager, self,
note_id: str | None = None,
*,
session: HTTPClient,
client: ClientManager,
): ):
self._note_id: str | None = note_id self._note_id: str | None = note_id
self._session: HTTPClient = session self._session: HTTPClient = session
@ -106,11 +110,11 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id note_id = note_id or self._note_id
if note_id is None: if note_id is None:
raise ParameterError('note_id is required') raise ParameterError("note_id is required")
body = {'noteId': note_id} body = {"noteId": note_id}
res: bool = await self._session.request( res: bool = await self._session.request(
Route('POST', '/api/notes/unrenote'), auth=True, json=body Route("POST", "/api/notes/unrenote"), auth=True, json=body
) )
return res return res
@ -123,7 +127,7 @@ class ClientNoteActions(AbstractAction):
get_all: bool = True, get_all: bool = True,
) -> AsyncGenerator[Note, None]: ) -> AsyncGenerator[Note, None]:
if limit > 100: if limit > 100:
raise ParameterError('limit は100以下である必要があります') raise ParameterError("limit は100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
@ -131,17 +135,17 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id note_id = note_id or self._note_id
if note_id is None: if note_id is None:
raise ParameterError('note_id is required') raise ParameterError("note_id is required")
data = { data = {
'noteId': note_id, "noteId": note_id,
'limit': limit, "limit": limit,
'sinceId': since_id, "sinceId": since_id,
'untilId': untilId, "untilId": untilId,
} }
pagination = Pagination[INote]( pagination = Pagination[INote](
self._session, Route('POST', '/api/notes/children'), json=data self._session, Route("POST", "/api/notes/children"), json=data
) )
while True: while True:
@ -156,11 +160,11 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id note_id = note_id or self._note_id
if note_id is None: if note_id is None:
raise ParameterError('note_id is required') raise ParameterError("note_id is required")
data = {'noteId': note_id} data = {"noteId": note_id}
res: INoteState = await self._session.request( res: INoteState = await self._session.request(
Route('POST', '/api/notes/state'), auth=True, json=data Route("POST", "/api/notes/state"), auth=True, json=data
) )
return NoteState(res) return NoteState(res)
@ -186,11 +190,11 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id note_id = note_id or self._note_id
if note_id is None: if note_id is None:
raise ParameterError('note_id is required') raise ParameterError("note_id is required")
data = {'noteId': note_id, 'clipId': clip_id} data = {"noteId": note_id, "clipId": clip_id}
return bool( return bool(
await self._session.request(Route('POST', '/api/clips/add-note'), json=data, auth=True) await self._session.request(Route("POST", "/api/clips/add-note"), json=data, auth=True)
) )
async def get_clips(self, note_id: str | None = None) -> list[Clip]: async def get_clips(self, note_id: str | None = None) -> list[Clip]:
@ -211,11 +215,11 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id note_id = note_id or self._note_id
if note_id is None: if note_id is None:
raise ParameterError('note_id is required') raise ParameterError("note_id is required")
data = {'noteId': note_id} data = {"noteId": note_id}
res: list[IClip] = await self._session.request( res: list[IClip] = await self._session.request(
Route('POST', '/api/notes/clips'), json=data, auth=True Route("POST", "/api/notes/clips"), json=data, auth=True
) )
return [Clip(clip, client=self._client) for clip in res] return [Clip(clip, client=self._client) for clip in res]
@ -237,10 +241,10 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id note_id = note_id or self._note_id
if note_id is None: if note_id is None:
raise ParameterError('note_id is required') raise ParameterError("note_id is required")
data = {'noteId': note_id} data = {"noteId": note_id}
res = await self._session.request(Route('POST', '/api/notes/delete'), json=data, auth=True) res = await self._session.request(Route("POST", "/api/notes/delete"), json=data, auth=True)
return bool(res) return bool(res)
async def create_renote(self, note_id: str | None = None) -> Note: async def create_renote(self, note_id: str | None = None) -> Note:
@ -261,13 +265,16 @@ class ClientNoteActions(AbstractAction):
note_id = self._note_id or note_id note_id = self._note_id or note_id
if note_id is None: if note_id is None:
raise ParameterError('note_id is required') raise ParameterError("note_id is required")
body = create_note_body(renote_id=note_id) body = create_note_body(renote_id=note_id)
res: ICreatedNote = await self._session.request( res: ICreatedNote = await self._session.request(
Route('POST', '/api/notes/create'), json=body, auth=True, lower=True, Route("POST", "/api/notes/create"),
json=body,
auth=True,
lower=True,
) )
return Note(res['created_note'], client=self._client) return Note(res["created_note"], client=self._client)
async def get_reaction(self, reaction: str, note_id: str | None = None) -> list[NoteReaction]: async def get_reaction(self, reaction: str, note_id: str | None = None) -> list[NoteReaction]:
note_id = note_id or self._note_id note_id = note_id or self._note_id
@ -278,7 +285,7 @@ class ClientNoteActions(AbstractAction):
async def reply( async def reply(
self, self,
content: str | None = None, content: str | None = None,
visibility: INoteVisibility = 'public', visibility: INoteVisibility = "public",
visible_user_ids: list[str] | None = None, visible_user_ids: list[str] | None = None,
cw: str | None = None, cw: str | None = None,
local_only: bool = False, local_only: bool = False,
@ -292,7 +299,7 @@ class ClientNoteActions(AbstractAction):
reply_id = reply_id or self._note_id reply_id = reply_id or self._note_id
if reply_id is None: if reply_id is None:
raise ParameterError('reply_id is required') raise ParameterError("reply_id is required")
body = create_note_body( body = create_note_body(
content=content, content=content,
@ -308,14 +315,17 @@ class ClientNoteActions(AbstractAction):
files=files, files=files,
) )
res: ICreatedNote = await self._session.request( res: ICreatedNote = await self._session.request(
Route('POST', '/api/notes/create'), json=body, lower=True, auth=True, Route("POST", "/api/notes/create"),
json=body,
lower=True,
auth=True,
) )
return Note(res['created_note'], client=self._client) return Note(res["created_note"], client=self._client)
async def create_quote( async def create_quote(
self, self,
content: str | None = None, content: str | None = None,
visibility: INoteVisibility = 'public', visibility: INoteVisibility = "public",
visible_user_ids: list[str] | None = None, visible_user_ids: list[str] | None = None,
cw: str | None = None, cw: str | None = None,
local_only: bool = False, local_only: bool = False,
@ -358,7 +368,7 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id note_id = note_id or self._note_id
if note_id is None: if note_id is None:
raise ParameterError('note_id is required') raise ParameterError("note_id is required")
body = create_note_body( body = create_note_body(
content=content, content=content,
@ -374,14 +384,19 @@ class ClientNoteActions(AbstractAction):
files=files, files=files,
) )
res: ICreatedNote = await self._session.request( res: ICreatedNote = await self._session.request(
Route('POST', '/api/notes/create'), json=body, auth=True, lower=True, Route("POST", "/api/notes/create"),
json=body,
auth=True,
lower=True,
) )
return Note(res['created_note'], client=self._client) return Note(res["created_note"], client=self._client)
@cache(group='translate_note') @cache(group="translate_note")
async def translate( async def translate(
self, note_id: str | None = None, target_lang: str = 'en-US', self,
note_id: str | None = None,
target_lang: str = "en-US",
) -> NoteTranslateResult: ) -> NoteTranslateResult:
""" """
Translate a note Translate a note
@ -401,15 +416,15 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id note_id = note_id or self._note_id
if note_id is None: if note_id is None:
raise ParameterError('note_id is required') raise ParameterError("note_id is required")
data = {'noteId': note_id, 'targetLang': target_lang} data = {"noteId": note_id, "targetLang": target_lang}
res: INoteTranslateResult = await self._session.request( res: INoteTranslateResult = await self._session.request(
Route('POST', '/api/notes/translate'), json=data, auth=True Route("POST", "/api/notes/translate"), json=data, auth=True
) )
if isinstance(res, dict): if isinstance(res, dict):
return NoteTranslateResult(res) return NoteTranslateResult(res)
APIError(f'Translate Error: {res}', res if isinstance(res, int) else 204).raise_error() APIError(f"Translate Error: {res}", res if isinstance(res, int) else 204).raise_error()
async def get_replies( async def get_replies(
self, self,
@ -440,18 +455,18 @@ class ClientNoteActions(AbstractAction):
""" """
if limit > 100: if limit > 100:
raise ParameterError('limitは100以下である必要があります') raise ParameterError("limitは100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
note_id = note_id or self._note_id note_id = note_id or self._note_id
if note_id is None: if note_id is None:
raise ParameterError('note_id is required') raise ParameterError("note_id is required")
body = {'noteId': note_id, 'sinceId': since_id, 'untilId': until_id, 'limit': limit} body = {"noteId": note_id, "sinceId": since_id, "untilId": until_id, "limit": limit}
pagination = Pagination[INote](self._session, Route('POST', '/api/notes'), json=body) pagination = Pagination[INote](self._session, Route("POST", "/api/notes"), json=body)
while True: while True:
res_notes = await pagination.next() res_notes = await pagination.next()
@ -464,14 +479,18 @@ class ClientNoteActions(AbstractAction):
class NoteActions(ClientNoteActions): class NoteActions(ClientNoteActions):
def __init__( def __init__(
self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager, self,
note_id: str | None = None,
*,
session: HTTPClient,
client: ClientManager,
): ):
super().__init__(note_id=note_id, session=session, client=client) super().__init__(note_id=note_id, session=session, client=client)
async def send( async def send(
self, self,
content: str | None = None, content: str | None = None,
visibility: INoteVisibility = 'public', visibility: INoteVisibility = "public",
visible_user_ids: list[str] | None = None, visible_user_ids: list[str] | None = None,
cw: str | None = None, cw: str | None = None,
local_only: bool = False, local_only: bool = False,
@ -543,11 +562,14 @@ class NoteActions(ClientNoteActions):
reply_id=reply_id, reply_id=reply_id,
) )
res: ICreatedNote = await self._session.request( res: ICreatedNote = await self._session.request(
Route('POST', '/api/notes/create'), json=body, auth=True, lower=True, Route("POST", "/api/notes/create"),
json=body,
auth=True,
lower=True,
) )
return Note(res['created_note'], client=self._client) return Note(res["created_note"], client=self._client)
@cache(group='get_note') @cache(group="get_note")
async def get(self, note_id: str) -> Note: async def get(self, note_id: str) -> Note:
""" """
ノートを取得します ノートを取得します
@ -563,14 +585,20 @@ class NoteActions(ClientNoteActions):
取得したートID 取得したートID
""" """
res = await self._session.request( res = await self._session.request(
Route('POST', '/api/notes/show'), json={'noteId': note_id}, auth=True, lower=True, Route("POST", "/api/notes/show"),
json={"noteId": note_id},
auth=True,
lower=True,
) )
return Note(res, client=self._client) return Note(res, client=self._client)
@cache(group='get_note', override=True) @cache(group="get_note", override=True)
async def fetch(self, note_id: str) -> Note: async def fetch(self, note_id: str) -> Note:
res = await self._session.request( res = await self._session.request(
Route('POST', '/api/notes/show'), json={'noteId': note_id}, auth=True, lower=True, Route("POST", "/api/notes/show"),
json={"noteId": note_id},
auth=True,
lower=True,
) )
return Note(res, client=self._client) return Note(res, client=self._client)
@ -588,26 +616,26 @@ class NoteActions(ClientNoteActions):
get_all: bool = False, get_all: bool = False,
) -> AsyncGenerator[Note, None]: ) -> AsyncGenerator[Note, None]:
if limit > 100: if limit > 100:
raise ParameterError('limit は100以下である必要があります') raise ParameterError("limit は100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = remove_dict_empty( body = remove_dict_empty(
{ {
'local': local, "local": local,
'reply': reply, "reply": reply,
'renote': renote, "renote": renote,
'withFiles': with_files, "withFiles": with_files,
'poll': poll, "poll": poll,
'limit': limit, "limit": limit,
'sinceId': since_id, "sinceId": since_id,
'untilId': until_id, "untilId": until_id,
} }
) )
pagination = Pagination[INote]( pagination = Pagination[INote](
self._session, Route('POST', '/api/notes'), json=body, limit=limit self._session, Route("POST", "/api/notes"), json=body, limit=limit
) )
while True: while True:

@ -23,29 +23,28 @@ class PollActions(AbstractAction):
note_id = note_id or self.__note_id note_id = note_id or self.__note_id
if note_id is None: if note_id is None:
raise ParameterError('note_id is required') raise ParameterError("note_id is required")
data = {'noteId': note_id, 'choice': choice} data = {"noteId": note_id, "choice": choice}
res: bool = await self.__session.request( res: bool = await self.__session.request(
Route('POST', '/api/notes/polls/vote'), auth=True, json=data Route("POST", "/api/notes/polls/vote"), auth=True, json=data
) )
return res return res
async def recommendation(self, limit: int = 100, offset: int = 0, get_all: bool = True): async def recommendation(self, limit: int = 100, offset: int = 0, get_all: bool = True):
if limit > 100: if limit > 100:
raise ParameterError('limit must be less than 100') raise ParameterError("limit must be less than 100")
if get_all: if get_all:
limit = 100 limit = 100
data = {'limit': limit, 'offset': offset} data = {"limit": limit, "offset": offset}
pagination = Pagination[INote]( pagination = Pagination[INote](
self.__session, self.__session,
Route('POST', '/api/notes/polls/recommendation'), Route("POST", "/api/notes/polls/recommendation"),
json=data, json=data,
pagination_type='count', pagination_type="count",
) )
while True: while True:

@ -41,16 +41,16 @@ class ReactionActions(AbstractAction):
""" """
note_id = note_id or self.__note_id note_id = note_id or self.__note_id
data = remove_dict_empty({'noteId': note_id, 'reaction': reaction}) data = remove_dict_empty({"noteId": note_id, "reaction": reaction})
route = Route('POST', '/api/notes/reactions/create') route = Route("POST", "/api/notes/reactions/create")
res: bool = await self.__session.request(route, json=data, auth=True, lower=True) res: bool = await self.__session.request(route, json=data, auth=True, lower=True)
return bool(res) return bool(res)
async def remove(self, note_id: str | None = None) -> bool: async def remove(self, note_id: str | None = None) -> bool:
note_id = note_id or self.__note_id note_id = note_id or self.__note_id
data = remove_dict_empty({'noteId': note_id}) data = remove_dict_empty({"noteId": note_id})
route = Route('POST', '/api/notes/reactions/delete') route = Route("POST", "/api/notes/reactions/delete")
res: bool = await self.__session.request(route, json=data, auth=True, lower=True) res: bool = await self.__session.request(route, json=data, auth=True, lower=True)
return bool(res) return bool(res)
@ -58,20 +58,23 @@ class ReactionActions(AbstractAction):
self, reaction: str, note_id: str | None = None, *, limit: int = 10 self, reaction: str, note_id: str | None = None, *, limit: int = 10
) -> list[NoteReaction]: ) -> list[NoteReaction]:
note_id = note_id or self.__note_id note_id = note_id or self.__note_id
data = remove_dict_empty({'noteId': note_id, 'limit': limit, 'type': reaction}) data = remove_dict_empty({"noteId": note_id, "limit": limit, "type": reaction})
res: list[INoteReaction] = await self.__session.request( res: list[INoteReaction] = await self.__session.request(
Route('POST', '/api/notes/reactions'), json=data, auth=True, lower=True, Route("POST", "/api/notes/reactions"),
json=data,
auth=True,
lower=True,
) )
return [NoteReaction(i, client=self.__client) for i in res] return [NoteReaction(i, client=self.__client) for i in res]
async def get_emoji_list(self) -> list[CustomEmoji]: async def get_emoji_list(self) -> list[CustomEmoji]:
if config.use_version >= 13: if config.use_version >= 13:
raise NotSupportVersion('Misskey v13以降では使用できません') raise NotSupportVersion("Misskey v13以降では使用できません")
data: ILiteMeta = await self.__session.request( data: ILiteMeta = await self.__session.request(
Route('GET', '/api/meta'), Route("GET", "/api/meta"),
json={'detail': False}, json={"detail": False},
auth=True, auth=True,
replace_list={'ToSUrl': 'tos_url', 'ToSTextUrl': 'tos_text_url'}, replace_list={"ToSUrl": "tos_url", "ToSTextUrl": "tos_text_url"},
) )
return [CustomEmoji(i, client=self.__client) for i in data.get('emojis', [])] return [CustomEmoji(i, client=self.__client) for i in data.get("emojis", [])]

@ -18,12 +18,15 @@ from mipac.utils.util import check_multi_arg
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
__all__ = ['UserActions'] __all__ = ["UserActions"]
class UserActions: class UserActions:
def __init__( def __init__(
self, session: HTTPClient, client: ClientManager, user: Optional[LiteUser] = None, self,
session: HTTPClient,
client: ClientManager,
user: Optional[LiteUser] = None,
): ):
self.__session: HTTPClient = session self.__session: HTTPClient = session
self.__user: Optional[LiteUser] = user self.__user: Optional[LiteUser] = user
@ -34,25 +37,31 @@ class UserActions:
ログインしているユーザーの情報を取得します ログインしているユーザーの情報を取得します
""" """
res = await self.__session.request(Route('POST', '/api/i'), auth=True, lower=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(
self, external: bool = True, protocol: Literal['http', 'https'] = 'https', self,
external: bool = True,
protocol: Literal["http", "https"] = "https",
): ):
if not self.__user: if not self.__user:
return None return None
host = ( host = (
f'{protocol}://{self.__user.host}' f"{protocol}://{self.__user.host}"
if external and self.__user.host if external and self.__user.host
else self.__session._url else self.__session._url
) )
path = ( path = (
f'/@{self.__user.username}' if external else f'/{self.__user.api.action.get_mention()}' f"/@{self.__user.username}" if external else f"/{self.__user.api.action.get_mention()}"
) )
return host + path return host + path
@cache(group='get_user') @cache(group="get_user")
async def get( async def get(
self, self,
user_id: str | None = None, user_id: str | None = None,
@ -79,14 +88,17 @@ class UserActions:
ユーザー情報 ユーザー情報
""" """
field = remove_dict_empty({'userId': user_id, 'username': username, 'host': host}) field = remove_dict_empty({"userId": user_id, "username": username, "host": host})
data = await self.__session.request( data = await self.__session.request(
Route('POST', '/api/users/show'), json=field, auth=True, lower=True Route("POST", "/api/users/show"), json=field, auth=True, lower=True
) )
return UserDetailed(data, client=self.__client) return UserDetailed(data, client=self.__client)
async def fetch( async def fetch(
self, user_id: str | None = None, username: str | None = None, host: str | None = None, self,
user_id: str | None = None,
username: str | None = None,
host: str | None = None,
) -> UserDetailed: ) -> UserDetailed:
""" """
サーバーにアクセスしユーザーのプロフィールを取得します基本的には get_userをお使いください サーバーにアクセスしユーザーのプロフィールを取得します基本的には get_userをお使いください
@ -123,29 +135,29 @@ class UserActions:
get_all: bool = False, get_all: bool = False,
) -> AsyncGenerator[Note, None]: ) -> AsyncGenerator[Note, None]:
if check_multi_arg(user_id, self.__user) is False: if check_multi_arg(user_id, self.__user) is False:
raise ParameterError('user_idがありません', user_id, self.__user) raise ParameterError("user_idがありません", user_id, self.__user)
user_id = user_id or self.__user and self.__user.id user_id = user_id or self.__user and self.__user.id
data = { data = {
'userId': user_id, "userId": user_id,
'includeReplies': include_replies, "includeReplies": include_replies,
'limit': limit, "limit": limit,
'sinceId': since_id, "sinceId": since_id,
'untilId': until_id, "untilId": until_id,
'sinceDate': since_date, "sinceDate": since_date,
'untilDate': until_date, "untilDate": until_date,
'includeMyRenotes': include_my_renotes, "includeMyRenotes": include_my_renotes,
'withFiles': with_files, "withFiles": with_files,
'fileType': file_type, "fileType": file_type,
'excludeNsfw': exclude_nsfw, "excludeNsfw": exclude_nsfw,
} }
if get_all: if get_all:
data['limit'] = 100 data["limit"] = 100
limit = 100 limit = 100
pagination = Pagination[INote]( pagination = Pagination[INote](
self.__session, Route('POST', '/api/users/notes'), json=data, limit=limit self.__session, Route("POST", "/api/users/notes"), json=data, limit=limit
) )
while True: while True:
@ -173,15 +185,15 @@ class UserActions:
user = user or self.__user user = user or self.__user
if user is None: if user is None:
raise NotExistRequiredData('Required parameters: user') raise NotExistRequiredData("Required parameters: user")
return f'@{user.username}@{user.host}' if user.instance else f'@{user.username}' return f"@{user.username}@{user.host}" if user.instance else f"@{user.username}"
async def search( async def search(
self, self,
query: str, query: str,
limit: int = 100, limit: int = 100,
offset: int = 0, offset: int = 0,
origin: Literal['local', 'remote', 'combined'] = 'combined', origin: Literal["local", "remote", "combined"] = "combined",
detail: bool = True, detail: bool = True,
*, *,
get_all: bool = False, get_all: bool = False,
@ -211,17 +223,17 @@ class UserActions:
""" """
if limit > 100: if limit > 100:
raise ParameterError('limit は100以下である必要があります') raise ParameterError("limit は100以下である必要があります")
if get_all: if get_all:
limit = 100 limit = 100
body = remove_dict_empty( body = remove_dict_empty(
{'query': query, 'limit': limit, 'offset': offset, 'origin': origin, 'detail': detail} {"query": query, "limit": limit, "offset": offset, "origin": origin, "detail": detail}
) )
pagination = Pagination[UserDetailed | LiteUser]( pagination = Pagination[UserDetailed | LiteUser](
self.__session, Route('POST', '/api/users/search'), json=body, pagination_type='count' self.__session, Route("POST", "/api/users/search"), json=body, pagination_type="count"
) )
while True: while True:
@ -234,7 +246,11 @@ class UserActions:
break break
async def search_by_username_and_host( async def search_by_username_and_host(
self, username: str, host: str, limit: int = 100, detail: bool = True, self,
username: str,
host: str,
limit: int = 100,
detail: bool = True,
) -> list[UserDetailed | LiteUser]: ) -> list[UserDetailed | LiteUser]:
""" """
Search users by username and host. Search users by username and host.
@ -257,13 +273,13 @@ class UserActions:
""" """
if limit > 100: if limit > 100:
raise ParameterError('limit は100以下である必要があります') raise ParameterError("limit は100以下である必要があります")
body = remove_dict_empty( body = remove_dict_empty(
{'username': username, 'host': host, 'limit': limit, 'detail': detail} {"username": username, "host": host, "limit": limit, "detail": detail}
) )
res = await self.__session.request( res = await self.__session.request(
Route('POST', '/api/users/search-by-username-and-host'), Route("POST", "/api/users/search-by-username-and-host"),
lower=True, lower=True,
auth=True, auth=True,
json=body, json=body,
@ -279,18 +295,21 @@ class UserActions:
"""Get achievements of user.""" """Get achievements of user."""
if config.use_version < 13: if config.use_version < 13:
raise NotSupportVersion('ご利用のインスタンスのバージョンではサポートされていない機能です') raise NotSupportVersion("ご利用のインスタンスのバージョンではサポートされていない機能です")
user_id = user_id or self.__user and self.__user.id user_id = user_id or self.__user and self.__user.id
if not user_id: if not user_id:
raise ParameterError('user_id is required') raise ParameterError("user_id is required")
data = { data = {
'userId': user_id, "userId": user_id,
} }
res = await self.__session.request( res = await self.__session.request(
Route('POST', '/api/users/achievements'), json=data, auth=True, lower=True, Route("POST", "/api/users/achievements"),
json=data,
auth=True,
lower=True,
) )
return [Achievement(i) for i in res] return [Achievement(i) for i in res]
@ -305,18 +324,18 @@ class UserActions:
user_id = user_id or self.__user and self.__user.id user_id = user_id or self.__user and self.__user.id
if not user_id: if not user_id:
raise ParameterError('user_id is required') raise ParameterError("user_id is required")
if limit > 100: if limit > 100:
raise ParameterError('limit must be less than 100') raise ParameterError("limit must be less than 100")
if get_all: if get_all:
limit = 100 limit = 100
body = {'userId': user_id, 'limit': limit, 'sinceId': since_id, 'untilId': until_id} body = {"userId": user_id, "limit": limit, "sinceId": since_id, "untilId": until_id}
pagination = Pagination[IClip]( pagination = Pagination[IClip](
self.__session, Route('POST', '/api/users/clips'), json=body, auth=True self.__session, Route("POST", "/api/users/clips"), json=body, auth=True
) )
while True: while True:

@ -12,7 +12,7 @@ class Client:
url: str, url: str,
token: str | None = None, token: str | None = None,
*, *,
log_level: LOGING_LEVEL_TYPE | None = 'INFO', log_level: LOGING_LEVEL_TYPE | None = "INFO",
use_version: IMisskeyVersions = 12, use_version: IMisskeyVersions = 12,
use_version_autodetect: bool = True use_version_autodetect: bool = True
) -> None: ) -> None:

@ -14,7 +14,7 @@ class CacheConfig:
self.ttl: int = options.ttl self.ttl: int = options.ttl
IMisskeyDistribution = Literal['ayuskey', 'm544', 'areionskey', 'official'] IMisskeyDistribution = Literal["ayuskey", "m544", "areionskey", "official"]
IMisskeyVersions = Literal[13, 12, 11] IMisskeyVersions = Literal[13, 12, 11]
@ -30,22 +30,22 @@ class IFeatures(TypedDict, total=False):
class Limits: class Limits:
def __init__(self, limits: ILimits | None = None) -> None: def __init__(self, limits: ILimits | None = None) -> None:
limits = limits or {} limits = limits or {}
self.channel_name: int = limits.get('channel_name', 128) self.channel_name: int = limits.get("channel_name", 128)
self.channel_description: int = limits.get('channel_description', 2048) self.channel_description: int = limits.get("channel_description", 2048)
def from_dict(self, limits: ILimits): def from_dict(self, limits: ILimits):
self.channel_name = limits.get('channel_name') or self.channel_description self.channel_name = limits.get("channel_name") or self.channel_description
self.channel_description = limits.get('channel_description') or self.channel_description self.channel_description = limits.get("channel_description") or self.channel_description
return self return self
class Features: class Features:
def __init__(self, features: IFeatures | None = None) -> None: def __init__(self, features: IFeatures | None = None) -> None:
features = features or {} features = features or {}
self.chat = features.get('chat', False) self.chat = features.get("chat", False)
def from_dict(self, features: IFeatures): def from_dict(self, features: IFeatures):
self.chat = features.get('chat') or self.chat self.chat = features.get("chat") or self.chat
return self return self
@ -53,9 +53,9 @@ class Config:
def __init__( def __init__(
self, self,
*, *,
host: str = '', host: str = "",
is_ssl: bool = True, is_ssl: bool = True,
distro: IMisskeyDistribution = 'official', distro: IMisskeyDistribution = "official",
is_ayuskey: bool = False, is_ayuskey: bool = False,
use_version: IMisskeyVersions = 12, use_version: IMisskeyVersions = 12,
cache: CacheConfigData | None = None, cache: CacheConfigData | None = None,

@ -12,19 +12,19 @@ class APIError(Exception):
self.id: str | None = None self.id: str | None = None
self.message: str | None = None self.message: str | None = None
if isinstance(data, dict): if isinstance(data, dict):
error = data.get('error', {}) error = data.get("error", {})
if isinstance(error, dict): if isinstance(error, dict):
self.code: str | None = error.get('code', '') self.code: str | None = error.get("code", "")
self.id: str | None = error.get('id') self.id: str | None = error.get("id")
self.message: str | None = error.get('message', '') self.message: str | None = error.get("message", "")
super().__init__(f'{self.message}\nRaw error: {self.raw} ' if self.message else self.raw) super().__init__(f"{self.message}\nRaw error: {self.raw} " if self.message else self.raw)
def raise_error(self): def raise_error(self):
if not self.code: if not self.code:
raise self raise self
if value := getattr( if value := getattr(
import_module('mipac.errors.errors'), import_module("mipac.errors.errors"),
''.join([i.capitalize() for i in self.code.split('_')]) + 'Error', "".join([i.capitalize() for i in self.code.split("_")]) + "Error",
None, None,
): ):
raise value(self.raw, self.status) raise value(self.raw, self.status)
@ -44,4 +44,4 @@ class NotSupportVersion(Exception):
"""サポートされていないバージョンのインスタンス""" """サポートされていないバージョンのインスタンス"""
NotSupportVersionText = 'ご利用のインスタンスのバージョンではサポートされていない機能です' NotSupportVersionText = "ご利用のインスタンスのバージョンではサポートされていない機能です"

@ -2,388 +2,388 @@ from .base import APIError
class AccessDeniedError(APIError): class AccessDeniedError(APIError):
""" アクセス権限がありません。 """ """アクセス権限がありません。"""
class AlreadyAddedError(APIError): class AlreadyAddedError(APIError):
""" """ """ """
class AlreadyBlockingError(APIError): class AlreadyBlockingError(APIError):
""" すでにブロックしています。 """ """すでにブロックしています。"""
class AlreadyClippedError(APIError): class AlreadyClippedError(APIError):
""" """ """ """
class AlreadyExpiredError(APIError): class AlreadyExpiredError(APIError):
""" """ """ """
class AlreadyFavoritedError(APIError): class AlreadyFavoritedError(APIError):
""" 既にお気に入り登録されています。 """ """既にお気に入り登録されています。"""
class AlreadyFollowingError(APIError): class AlreadyFollowingError(APIError):
""" すでにフォローしています。 """ """すでにフォローしています。"""
class AlreadyInvitedError(APIError): class AlreadyInvitedError(APIError):
""" """ """ """
class AlreadyLikedError(APIError): class AlreadyLikedError(APIError):
""" すでにいいねをつけています。 """ """すでにいいねをつけています。"""
class AlreadyMutingError(APIError): class AlreadyMutingError(APIError):
""" すでにそのユーザーをミュートしています。 """ """すでにそのユーザーをミュートしています。"""
class AlreadyPinnedError(APIError): class AlreadyPinnedError(APIError):
""" 指定されたノートは既にピン留めされています。 """ """指定されたノートは既にピン留めされています。"""
class AlreadyPromotedError(APIError): class AlreadyPromotedError(APIError):
""" """ """ """
class AlreadyReactedError(APIError): class AlreadyReactedError(APIError):
""" 既にリアクションしています。 """ """既にリアクションしています。"""
class AlreadyVotedError(APIError): class AlreadyVotedError(APIError):
""" """ """ """
class AvatarNotAnImageError(APIError): class AvatarNotAnImageError(APIError):
""" アバター画像に、画像ではないファイルが指定されました。 """ """アバター画像に、画像ではないファイルが指定されました。"""
class BannerNotAnImageError(APIError): class BannerNotAnImageError(APIError):
""" バナー画像に、画像ではないファイルが指定されました。 """ """バナー画像に、画像ではないファイルが指定されました。"""
class BlockedError(APIError): class BlockedError(APIError):
""" ユーザーにブロックされています。 """ """ユーザーにブロックされています。"""
class BlockeeIsYourselfError(APIError): class BlockeeIsYourselfError(APIError):
""" 自分のブロックを解除しようとしました。 """ """自分のブロックを解除しようとしました。"""
class BlockingError(APIError): class BlockingError(APIError):
""" ユーザーをブロックしています。 """ """ユーザーをブロックしています。"""
class CannotCreateAlreadyExpiredPollError(APIError): class CannotCreateAlreadyExpiredPollError(APIError):
""" アンケートの期限の指定が誤っています。 """ """アンケートの期限の指定が誤っています。"""
class CannotRenoteToAPureRenoteError(APIError): class CannotRenoteToAPureRenoteError(APIError):
""" 単純なRenoteを再度Renoteすることはできません。 """ """単純なRenoteを再度Renoteすることはできません。"""
class CannotReplyToAPureRenoteError(APIError): class CannotReplyToAPureRenoteError(APIError):
""" 単純なRenoteに返信することはできません。 """ """単純なRenoteに返信することはできません。"""
class CannotReportTheAdminError(APIError): class CannotReportTheAdminError(APIError):
""" 管理者を通報しようとしました。 """ """管理者を通報しようとしました。"""
class CannotReportYourselfError(APIError): class CannotReportYourselfError(APIError):
""" 自身を通報しようとしました。 """ """自身を通報しようとしました。"""
class ContentRequiredError(APIError): class ContentRequiredError(APIError):
""" """ """ """
class CredentialRequiredError(APIError): class CredentialRequiredError(APIError):
""" クレデンシャル必須のエンドポイントにクレデンシャル無しでリクエストされました。 """ """クレデンシャル必須のエンドポイントにクレデンシャル無しでリクエストされました。"""
class FailedToResolveRemoteUserError(APIError): class FailedToResolveRemoteUserError(APIError):
""" リモートユーザーの検索に失敗しました。 """ """リモートユーザーの検索に失敗しました。"""
class FolloweeIsYourselfError(APIError): class FolloweeIsYourselfError(APIError):
""" 自分のフォローを解除しようとしました。 """ """自分のフォローを解除しようとしました。"""
class FollowerIsYourselfError(APIError): class FollowerIsYourselfError(APIError):
""" 自分をフォロワー解除しようとしました。 """ """自分をフォロワー解除しようとしました。"""
class FollowRequestNotFoundError(APIError): class FollowRequestNotFoundError(APIError):
""" フォローリクエストがありません。 """ """フォローリクエストがありません。"""
class ForbiddenError(APIError): class ForbiddenError(APIError):
""" """ """ """
class GroupAccessDeniedError(APIError): class GroupAccessDeniedError(APIError):
""" """ """ """
class GtlDisabledError(APIError): class GtlDisabledError(APIError):
""" グローバルタイムラインが無効になっています。 """ """グローバルタイムラインが無効になっています。"""
class HasChildFilesOrFoldersError(APIError): class HasChildFilesOrFoldersError(APIError):
""" フォルダーが空ではありません。 """ """フォルダーが空ではありません。"""
class InappropriateError(APIError): class InappropriateError(APIError):
""" 不適切なコンテンツを含んでいる可能性があると判定されました。 """ """不適切なコンテンツを含んでいる可能性があると判定されました。"""
class InternalErrorError(APIError): class InternalErrorError(APIError):
""" サーバー内部で問題が発生しました。引き続き問題が発生する場合は管理者にお問い合わせください。 """ """サーバー内部で問題が発生しました。引き続き問題が発生する場合は管理者にお問い合わせください。"""
class InvalidChoiceError(APIError): class InvalidChoiceError(APIError):
""" """ """ """
class InvalidFileNameError(APIError): class InvalidFileNameError(APIError):
""" ファイル名が不正です。 """ """ファイル名が不正です。"""
class InvalidParamError(APIError): class InvalidParamError(APIError):
""" リクエストパラメータに誤りがあります。 """ """リクエストパラメータに誤りがあります。"""
class InvalidRegexpError(APIError): class InvalidRegexpError(APIError):
""" 正規表現が不正です。 """ """正規表現が不正です。"""
class InvalidUrlError(APIError): class InvalidUrlError(APIError):
""" """ """ """
class IsOwnerError(APIError): class IsOwnerError(APIError):
""" """ """ """
class LtlDisabledError(APIError): class LtlDisabledError(APIError):
""" ローカルタイムラインが無効になっています。 """ """ローカルタイムラインが無効になっています。"""
class MoSuchFileError(APIError): class MoSuchFileError(APIError):
""" """ """ """
class MuteeIsYourselfError(APIError): class MuteeIsYourselfError(APIError):
""" 自分に対してミュートを解除しようとしました。 """ """自分に対してミュートを解除しようとしました。"""
class NameAlreadyExistsError(APIError): class NameAlreadyExistsError(APIError):
""" 同じURLにページがすでに存在します。 """ """同じURLにページがすでに存在します。"""
class NotBlockingError(APIError): class NotBlockingError(APIError):
""" ブロックしていないユーザーです。 """ """ブロックしていないユーザーです。"""
class NotFavoritedError(APIError): class NotFavoritedError(APIError):
""" お気に入り登録されていません。 """ """お気に入り登録されていません。"""
class NotFollowingError(APIError): class NotFollowingError(APIError):
""" ユーザーにフォローされていません。 """ """ユーザーにフォローされていません。"""
class NotLikedError(APIError): class NotLikedError(APIError):
""" いいねをつけていないページです。 """ """いいねをつけていないページです。"""
class NotMutingError(APIError): class NotMutingError(APIError):
""" 対象となるユーザーをそもそもミュートしていません。 """ """対象となるユーザーをそもそもミュートしていません。"""
class NotReactedError(APIError): class NotReactedError(APIError):
""" リアクションしていません。 """ """リアクションしていません。"""
class NoFollowRequestError(APIError): class NoFollowRequestError(APIError):
""" ユーザーからのフォローリクエストがありません。 """ """ユーザーからのフォローリクエストがありません。"""
class NoFreeSpaceError(APIError): class NoFreeSpaceError(APIError):
""" ドライブに空き容量がありません。 """ """ドライブに空き容量がありません。"""
class NoPollError(APIError): class NoPollError(APIError):
""" """ """ """
class NoSuchAdError(APIError): class NoSuchAdError(APIError):
""" """ """ """
class NoSuchAnnouncementError(APIError): class NoSuchAnnouncementError(APIError):
""" お知らせが存在しません。 """ """お知らせが存在しません。"""
class NoSuchAntennaError(APIError): class NoSuchAntennaError(APIError):
""" """ """ """
class NoSuchAppError(APIError): class NoSuchAppError(APIError):
""" アプリが存在しません。 """ """アプリが存在しません。"""
class NoSuchAvatarError(APIError): class NoSuchAvatarError(APIError):
""" アバター画像のファイルが存在しません。 """ """アバター画像のファイルが存在しません。"""
class NoSuchBannerError(APIError): class NoSuchBannerError(APIError):
""" バナー画像のファイルが存在しません。 """ """バナー画像のファイルが存在しません。"""
class NoSuchChannelError(APIError): class NoSuchChannelError(APIError):
""" 指定されたチャンネルが存在しないか、アクセスが許可されていません。 """ """指定されたチャンネルが存在しないか、アクセスが許可されていません。"""
class NoSuchClipError(APIError): class NoSuchClipError(APIError):
""" """ """ """
class NoSuchEmojiError(APIError): class NoSuchEmojiError(APIError):
""" """ """ """
class NoSuchFileError(APIError): class NoSuchFileError(APIError):
""" ファイルが存在しません。 """ """ファイルが存在しません。"""
class NoSuchFolderError(APIError): class NoSuchFolderError(APIError):
""" フォルダーが存在しません。 """ """フォルダーが存在しません。"""
class NoSuchGroupError(APIError): class NoSuchGroupError(APIError):
""" """ """ """
class NoSuchGroupMemberError(APIError): class NoSuchGroupMemberError(APIError):
""" """ """ """
class NoSuchHashtagError(APIError): class NoSuchHashtagError(APIError):
""" ハッシュタグが存在しません。 """ """ハッシュタグが存在しません。"""
class NoSuchInvitationError(APIError): class NoSuchInvitationError(APIError):
""" """ """ """
class NoSuchListError(APIError): class NoSuchListError(APIError):
""" """ """ """
class NoSuchMessageError(APIError): class NoSuchMessageError(APIError):
""" """ """ """
class NoSuchNoteError(APIError): class NoSuchNoteError(APIError):
""" 指定されたノートが存在しないか、アクセスが許可されていません。 """ """指定されたノートが存在しないか、アクセスが許可されていません。"""
class NoSuchNotificationError(APIError): class NoSuchNotificationError(APIError):
""" 通知が存在しません。 """ """通知が存在しません。"""
class NoSuchObjectError(APIError): class NoSuchObjectError(APIError):
""" """ """ """
class NoSuchPageError(APIError): class NoSuchPageError(APIError):
""" ページが存在しません。 """ """ページが存在しません。"""
class NoSuchParentFolderError(APIError): class NoSuchParentFolderError(APIError):
""" 親フォルダーが存在しません。 """ """親フォルダーが存在しません。"""
class NoSuchPostError(APIError): class NoSuchPostError(APIError):
""" """ """ """
class NoSuchRenoteTargetError(APIError): class NoSuchRenoteTargetError(APIError):
""" Renoteに指定されたートが存在しないか、アクセスが許可されていません。 """ """Renoteに指定されたートが存在しないか、アクセスが許可されていません。"""
class NoSuchReplyTargetError(APIError): class NoSuchReplyTargetError(APIError):
""" 返信先に指定されたノートが存在しないか、アクセスが許可されていません。 """ """返信先に指定されたノートが存在しないか、アクセスが許可されていません。"""
class NoSuchSessionError(APIError): class NoSuchSessionError(APIError):
""" セッションが存在しません。 """ """セッションが存在しません。"""
class NoSuchUserError(APIError): class NoSuchUserError(APIError):
""" ユーザーが存在しません。 """ """ユーザーが存在しません。"""
class NoSuchUserGroupError(APIError): class NoSuchUserGroupError(APIError):
""" """ """ """
class NoSuchUserListError(APIError): class NoSuchUserListError(APIError):
""" """ """ """
class NoSuchWebhookError(APIError): class NoSuchWebhookError(APIError):
""" Webhookが存在しません。 """ """Webhookが存在しません。"""
class PendingSessionError(APIError): class PendingSessionError(APIError):
""" """ """ """
class PermissionDeniedError(APIError): class PermissionDeniedError(APIError):
""" 与えられたクレデンシャルには必要なパーミッションがありません。 """ """与えられたクレデンシャルには必要なパーミッションがありません。"""
class PinLimitExceededError(APIError): class PinLimitExceededError(APIError):
""" これ以上ピン留めできません。 """ """これ以上ピン留めできません。"""
class RateLimitExceededError(APIError): class RateLimitExceededError(APIError):
""" レートリミットによる制限のため一時的に利用できません。 """ """レートリミットによる制限のため一時的に利用できません。"""
class ReactionsNotPublicError(APIError): class ReactionsNotPublicError(APIError):
""" リアクションが公開されていません。 """ """リアクションが公開されていません。"""
class RecipientIsYourselfError(APIError): class RecipientIsYourselfError(APIError):
""" """ """ """
class StlDisabledError(APIError): class StlDisabledError(APIError):
""" ソーシャルタイムラインが無効になっています。 """ """ソーシャルタイムラインが無効になっています。"""
class YourAccountSuspendedError(APIError): class YourAccountSuspendedError(APIError):
""" アカウントが凍結されているため利用できません。 """ """アカウントが凍結されているため利用できません。"""
class YourPageError(APIError): class YourPageError(APIError):
""" 自身のページにいいねをつけようとしました。 """ """自身のページにいいねをつけようとしました。"""
class YourPostError(APIError): class YourPostError(APIError):
""" """ """ """
class YouAreOwnerError(APIError): class YouAreOwnerError(APIError):
""" """ """ """
class YouHaveBeenBlockedError(APIError): class YouHaveBeenBlockedError(APIError):
""" ブロックされているユーザーのノートにリアクションは行えません。 """ """ブロックされているユーザーのノートにリアクションは行えません。"""

@ -1,12 +1,12 @@
class MiFile: class MiFile:
__slots__ = ( __slots__ = (
'path', "path",
'file_id', "file_id",
'name', "name",
'folder_id', "folder_id",
'comment', "comment",
'is_sensitive', "is_sensitive",
'force', "force",
) )
def __init__( def __init__(

@ -28,29 +28,29 @@ class _MissingSentinel:
return False return False
def __repr__(self): def __repr__(self):
return '...' return "..."
MISSING: Any = _MissingSentinel() MISSING: Any = _MissingSentinel()
R = TypeVar('R') R = TypeVar("R")
class MisskeyClientWebSocketResponse(aiohttp.ClientWebSocketResponse): class MisskeyClientWebSocketResponse(aiohttp.ClientWebSocketResponse):
async def close(self, *, code: int = 4000, message: bytes = b'') -> bool: async def close(self, *, code: int = 4000, message: bytes = b"") -> bool:
return await super().close(code=code, message=message) return await super().close(code=code, message=message)
async def json_or_text(response: aiohttp.ClientResponse): async def json_or_text(response: aiohttp.ClientResponse):
text = await response.text(encoding='utf-8') text = await response.text(encoding="utf-8")
try: try:
if 'application/json' in response.headers['Content-Type']: if "application/json" in response.headers["Content-Type"]:
return _from_json(text) return _from_json(text)
except KeyError: except KeyError:
pass pass
class Route: class Route:
def __init__(self, method: Literal['GET', 'POST'], path: ENDPOINTS): def __init__(self, method: Literal["GET", "POST"], path: ENDPOINTS):
self.path: str = path self.path: str = path
self.method: str = method self.method: str = method
@ -58,7 +58,7 @@ class Route:
class HTTPClient: class HTTPClient:
def __init__(self, url: str, token: str | None = None) -> None: def __init__(self, url: str, token: str | None = None) -> None:
user_agent = ( user_agent = (
'Misskey Bot (https://github.com/yupix/MiPA {0})' + 'Python/{1[0]}.{1[1]} aiohttp/{2}' "Misskey Bot (https://github.com/yupix/MiPA {0})" + "Python/{1[0]}.{1[1]} aiohttp/{2}"
) )
self.user_agent = user_agent.format(__version__, sys.version_info, aiohttp.__version__) self.user_agent = user_agent.format(__version__, sys.version_info, aiohttp.__version__)
self._session: aiohttp.ClientSession = MISSING self._session: aiohttp.ClientSession = MISSING
@ -78,23 +78,23 @@ class HTTPClient:
**kwargs, **kwargs,
) -> R: ) -> R:
headers: dict[str, str] = { headers: dict[str, str] = {
'User-Agent': self.user_agent, "User-Agent": self.user_agent,
} }
if 'json' in kwargs: if "json" in kwargs:
headers['Content-Type'] = 'application/json' headers["Content-Type"] = "application/json"
kwargs['json'] = kwargs.pop('json') kwargs["json"] = kwargs.pop("json")
if auth: if auth:
key = 'json' if 'json' in kwargs or 'data' not in kwargs else 'data' key = "json" if "json" in kwargs or "data" not in kwargs else "data"
if not kwargs.get(key): if not kwargs.get(key):
kwargs[key] = {} kwargs[key] = {}
if self._token: if self._token:
kwargs[key]['i'] = self._token kwargs[key]["i"] = self._token
replace_list = kwargs.pop('replace_list', {}) replace_list = kwargs.pop("replace_list", {})
for i in ('json', 'data'): for i in ("json", "data"):
if kwargs.get(i) and remove_none: if kwargs.get(i) and remove_none:
kwargs[i] = remove_dict_empty(kwargs[i]) kwargs[i] = remove_dict_empty(kwargs[i])
async with self._session.request(route.method, self._url + route.path, **kwargs) as res: async with self._session.request(route.method, self._url + route.path, **kwargs) as res:
@ -105,12 +105,12 @@ class HTTPClient:
if isinstance(data, dict): if isinstance(data, dict):
data = upper_to_lower(data) data = upper_to_lower(data)
_log.debug( _log.debug(
f'''{COLORS.green} f"""{COLORS.green}
REQUEST:{COLORS.reset} REQUEST:{COLORS.reset}
{kwargs} {kwargs}
{COLORS.green}RESPONSE:{COLORS.reset} {COLORS.green}RESPONSE:{COLORS.reset}
{json.dumps(data, ensure_ascii=False, indent=4) if data else data} {json.dumps(data, ensure_ascii=False, indent=4) if data else data}
''' """
) )
if res.status == 204 and data is None: if res.status == 204 and data is None:
return True # type: ignore return True # type: ignore
@ -119,26 +119,27 @@ REQUEST:{COLORS.reset}
if 511 > res.status >= 300: if 511 > res.status >= 300:
if isinstance(data, dict): if isinstance(data, dict):
APIError(data, res.status).raise_error() APIError(data, res.status).raise_error()
APIError('HTTP ERROR', res.status).raise_error() APIError("HTTP ERROR", res.status).raise_error()
async def close_session(self) -> None: async def close_session(self) -> None:
await self._session.close() await self._session.close()
async def login(self) -> IUserDetailed | None: async def login(self) -> IUserDetailed | None:
match_domain = re.search(r'https?:\/\/([^\/]+)', self._url) match_domain = re.search(r"https?:\/\/([^\/]+)", self._url)
match_protocol = re.search(r'^(http|https)', self._url) match_protocol = re.search(r"^(http|https)", self._url)
if match_domain is None or match_protocol is None: if match_domain is None or match_protocol is None:
raise Exception('Server URL cannot be retrieved or protocol (http / https) is missing') raise Exception("Server URL cannot be retrieved or protocol (http / https) is missing")
protocol = True if match_protocol.group(1) == 'https' else False protocol = True if match_protocol.group(1) == "https" else False
config.from_dict( config.from_dict(
host=match_domain.group(1), is_ssl=protocol, host=match_domain.group(1),
is_ssl=protocol,
) )
self._session = aiohttp.ClientSession(ws_response_class=MisskeyClientWebSocketResponse) self._session = aiohttp.ClientSession(ws_response_class=MisskeyClientWebSocketResponse)
if self._token: if self._token:
data: IUserDetailed = await self.request(Route('POST', '/api/i'), auth=True) data: IUserDetailed = await self.request(Route("POST", "/api/i"), auth=True)
if config.use_version_autodetect: if config.use_version_autodetect:
meta: IMeta = await self.request(Route('POST', '/api/meta'), auth=True) meta: IMeta = await self.request(Route("POST", "/api/meta"), auth=True)
use_version = int(meta['version'].split('.')[0]) use_version = int(meta["version"].split(".")[0])
if isinstance(use_version, int) and use_version in (13, 12, 11): if isinstance(use_version, int) and use_version in (13, 12, 11):
config.use_version = use_version config.use_version = use_version
return data return data

@ -9,7 +9,7 @@ from mipac.http import HTTPClient, Route
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.client import ClientManager from mipac.client import ClientManager
__all__ = ('AdminAdvertisingManager', 'AdminAdvertisingModelManager') __all__ = ("AdminAdvertisingManager", "AdminAdvertisingModelManager")
class AdminAdvertisingModelManager(AbstractManager): class AdminAdvertisingModelManager(AbstractManager):
@ -39,20 +39,23 @@ class AdminAdvertisingManager(AbstractManager):
url: str, url: str,
memo: str, memo: str,
place: str, place: str,
priority: Literal['high', 'middle', 'low'], priority: Literal["high", "middle", "low"],
ratio: str, ratio: str,
expires_at: int, expires_at: int,
image_url: str, image_url: str,
): ):
data = { data = {
'url': url, "url": url,
'memo': memo, "memo": memo,
'place': place, "place": place,
'priority': priority, "priority": priority,
'ratio': ratio, "ratio": ratio,
'expires_at': expires_at, "expires_at": expires_at,
'image_url': image_url, "image_url": image_url,
} }
return await self.__session.request( return await self.__session.request(
Route('POST', '/api/admin/ad/create'), json=data, auth=True, lower=True, Route("POST", "/api/admin/ad/create"),
json=data,
auth=True,
lower=True,
) )

@ -26,5 +26,7 @@ class AdminAnnouncementManager(AbstractManager):
self, announce_id: str self, announce_id: str
) -> AdminAnnouncementClientActions: ) -> AdminAnnouncementClientActions:
return AdminAnnouncementClientActions( return AdminAnnouncementClientActions(
announce_id=announce_id, session=self.__session, client=self.__client, announce_id=announce_id,
session=self.__session,
client=self.__client,
) )

@ -9,7 +9,7 @@ from mipac.http import HTTPClient
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.client import ClientManager from mipac.client import ClientManager
__all__ = ('AdminModeratorManager',) __all__ = ("AdminModeratorManager",)
class AdminModeratorManager(AbstractManager): class AdminModeratorManager(AbstractManager):

@ -9,7 +9,7 @@ if TYPE_CHECKING:
from mipac.client import ClientManager from mipac.client import ClientManager
from mipac.http import HTTPClient from mipac.http import HTTPClient
__all__ = ('ChartManager',) __all__ = ("ChartManager",)
class ChartManager(AbstractManager): class ChartManager(AbstractManager):

@ -8,12 +8,14 @@ from mipac.http import HTTPClient
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
__all__ = ('ChatManager',) __all__ = ("ChatManager",)
class ChatManager: class ChatManager:
def __init__( def __init__(
self, session: HTTPClient, client: ClientManager, self,
session: HTTPClient,
client: ClientManager,
): ):
self.__session: HTTPClient = session self.__session: HTTPClient = session
self.__client: ClientManager = client self.__client: ClientManager = client
@ -26,12 +28,18 @@ class ChatManager:
self, user_id: str | None = None, message_id: str | None = None self, user_id: str | None = None, message_id: str | None = None
) -> BaseChatAction: ) -> BaseChatAction:
return BaseChatAction( return BaseChatAction(
session=self.__session, client=self.__client, user_id=user_id, message_id=message_id, session=self.__session,
client=self.__client,
user_id=user_id,
message_id=message_id,
) )
def custom_action( def custom_action(
self, user_id: str | None = None, message_id: str | None = None self, user_id: str | None = None, message_id: str | None = None
) -> ChatAction: ) -> ChatAction:
return ChatAction( return ChatAction(
session=self.__session, client=self.__client, user_id=user_id, message_id=message_id, session=self.__session,
client=self.__client,
user_id=user_id,
message_id=message_id,
) )

@ -23,7 +23,7 @@ if TYPE_CHECKING:
from mipac.models.user import UserDetailed from mipac.models.user import UserDetailed
__all__ = ('ClientManager',) __all__ = ("ClientManager",)
class ClientManager: class ClientManager:
@ -38,10 +38,12 @@ class ClientManager:
self.chart: ChartManager = ChartManager(session=session, client=self) self.chart: ChartManager = ChartManager(session=session, client=self)
self.channel: ChannelManager = ChannelManager(session=session, client=self) self.channel: ChannelManager = ChannelManager(session=session, client=self)
self.follow: FollowManager = FollowManager( self.follow: FollowManager = FollowManager(
session=session, client=self, session=session,
client=self,
) )
self.follow_request: FollowRequestManager = FollowRequestManager( self.follow_request: FollowRequestManager = FollowRequestManager(
session=session, client=self, session=session,
client=self,
) )
self.clip: ClipManager = ClipManager(session=session, client=self) self.clip: ClipManager = ClipManager(session=session, client=self)
self.emoji: EmojiManager = EmojiManager(session=session, client=self) self.emoji: EmojiManager = EmojiManager(session=session, client=self)

@ -12,7 +12,11 @@ if TYPE_CHECKING:
class ClientClipManager(AbstractManager): class ClientClipManager(AbstractManager):
def __init__( def __init__(
self, clip_id: str | None = None, *, session: HTTPClient, client: ClientManager, self,
clip_id: str | None = None,
*,
session: HTTPClient,
client: ClientManager,
): ):
self.__clip_id = clip_id self.__clip_id = clip_id
self.__session = session self.__session = session
@ -20,7 +24,11 @@ class ClientClipManager(AbstractManager):
@property @property
def action(self) -> ClipActions: def action(self) -> ClipActions:
return ClipActions(clip_id=self.__clip_id, session=self.__session, client=self.__client,) return ClipActions(
clip_id=self.__clip_id,
session=self.__session,
client=self.__client,
)
class ClipManager(AbstractManager): class ClipManager(AbstractManager):

@ -15,7 +15,7 @@ from mipac.http import HTTPClient
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.client import ClientManager from mipac.client import ClientManager
__all__ = ['FolderManager', 'FileManager', 'DriveManager'] __all__ = ["FolderManager", "FileManager", "DriveManager"]
class ClientFileManager(AbstractManager): class ClientFileManager(AbstractManager):
@ -26,7 +26,7 @@ class ClientFileManager(AbstractManager):
url: str | None = None, url: str | None = None,
*, *,
session: HTTPClient, session: HTTPClient,
client: ClientManager client: ClientManager,
): ):
self.__session: HTTPClient = session self.__session: HTTPClient = session
self.__client: ClientManager = client self.__client: ClientManager = client
@ -53,7 +53,7 @@ class FileManager(AbstractManager):
url: str | None = None, url: str | None = None,
*, *,
session: HTTPClient, session: HTTPClient,
client: ClientManager client: ClientManager,
): ):
self.__session: HTTPClient = session self.__session: HTTPClient = session
self.__client: ClientManager = client self.__client: ClientManager = client
@ -100,7 +100,9 @@ class ClientFolderManager(AbstractManager):
フォルダーに対するアクション フォルダーに対するアクション
""" """
return ClientFolderActions( return ClientFolderActions(
folder_id=self.__folder_id, session=self.__session, client=self.__client, folder_id=self.__folder_id,
session=self.__session,
client=self.__client,
) )
@ -124,7 +126,9 @@ class FolderManager(AbstractManager):
フォルダーに対するアクション フォルダーに対するアクション
""" """
return FolderActions( return FolderActions(
folder_id=self.__folder_id, session=self.__session, client=self.__client, folder_id=self.__folder_id,
session=self.__session,
client=self.__client,
) )
def _get_file_instance(self, file_id: str) -> FileManager: def _get_file_instance(self, file_id: str) -> FileManager:

@ -26,5 +26,7 @@ class FavoriteManager(AbstractManager):
お気に入りに対するアクションを行うクラス お気に入りに対するアクションを行うクラス
""" """
return FavoriteActions( return FavoriteActions(
note_id=self.__note_id, session=self.__session, client=self.__client, note_id=self.__note_id,
session=self.__session,
client=self.__client,
) )

@ -9,7 +9,7 @@ from mipac.http import HTTPClient
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.client import ClientManager from mipac.client import ClientManager
__all__ = ('FollowManager', 'FollowRequestManager') __all__ = ("FollowManager", "FollowRequestManager")
class FollowManager(AbstractManager): class FollowManager(AbstractManager):
@ -23,7 +23,11 @@ class FollowManager(AbstractManager):
@property @property
def action(self) -> FollowActions: def action(self) -> FollowActions:
return FollowActions(user_id=self.__user_id, session=self.__session, client=self.__client,) return FollowActions(
user_id=self.__user_id,
session=self.__session,
client=self.__client,
)
class FollowRequestManager(AbstractManager): class FollowRequestManager(AbstractManager):
@ -35,5 +39,7 @@ class FollowRequestManager(AbstractManager):
@property @property
def action(self) -> FollowRequestActions: def action(self) -> FollowRequestActions:
return FollowRequestActions( return FollowRequestActions(
user_id=self.__user_id, session=self.__session, client=self.__client, user_id=self.__user_id,
session=self.__session,
client=self.__client,
) )

@ -27,7 +27,9 @@ class ClientNoteManager(AbstractManager):
@property @property
def action(self) -> ClientNoteActions: def action(self) -> ClientNoteActions:
return ClientNoteActions( return ClientNoteActions(
note_id=self.__note_id, session=self.__session, client=self.__client, note_id=self.__note_id,
session=self.__session,
client=self.__client,
) )
@ -52,4 +54,8 @@ class NoteManager(AbstractManager):
@property @property
def action(self) -> NoteActions: def action(self) -> NoteActions:
return NoteActions(note_id=self.__note_id, session=self.__session, client=self.__client,) return NoteActions(
note_id=self.__note_id,
session=self.__session,
client=self.__client,
)

@ -15,8 +15,11 @@ class PagesManager(AbstractManager):
self.__client: ClientManager = client self.__client: ClientManager = client
async def get_pages( async def get_pages(
self, limit: int = 100, since_id: int | None = None, until_id: int | None = None, self,
limit: int = 100,
since_id: int | None = None,
until_id: int | None = None,
): ):
data = {'limit': limit, 'since_id': since_id, 'until_id': until_id} data = {"limit": limit, "since_id": since_id, "until_id": until_id}
res = await self.__session.request(Route('POST', '/api/i/pages'), json=data, auth=True) res = await self.__session.request(Route("POST", "/api/i/pages"), json=data, auth=True)
return res return res

@ -18,4 +18,8 @@ class PollManager(AbstractManager):
@property @property
def action(self) -> PollActions: def action(self) -> PollActions:
return PollActions(note_id=self.__note_id, session=self.__session, client=self.__client,) return PollActions(
note_id=self.__note_id,
session=self.__session,
client=self.__client,
)

@ -26,5 +26,7 @@ class ReactionManager(AbstractManager):
Reactionに対するアクションを行うクラス Reactionに対するアクションを行うクラス
""" """
return ReactionActions( return ReactionActions(
note_id=self.__note_id, session=self.__session, client=self.__client, note_id=self.__note_id,
session=self.__session,
client=self.__client,
) )

@ -14,7 +14,7 @@ if TYPE_CHECKING:
from mipac.models.lite.user import LiteUser from mipac.models.lite.user import LiteUser
__all__ = ('UserManager',) __all__ = ("UserManager",)
class UserManager(AbstractManager): class UserManager(AbstractManager):

@ -18,43 +18,43 @@ class Ad:
@property @property
def id(self) -> str: def id(self) -> str:
return self.__ad_data['id'] return self.__ad_data["id"]
@property @property
def created_at(self) -> datetime: def created_at(self) -> datetime:
return str_to_datetime(self.__ad_data['created_at']) return str_to_datetime(self.__ad_data["created_at"])
@property @property
def starts_at(self) -> datetime: def starts_at(self) -> datetime:
return str_to_datetime(self.__ad_data['id']) return str_to_datetime(self.__ad_data["id"])
@property @property
def expires_at(self) -> datetime: def expires_at(self) -> datetime:
return str_to_datetime(self.__ad_data['id']) return str_to_datetime(self.__ad_data["id"])
@property @property
def url(self) -> str: def url(self) -> str:
return self.__ad_data['url'] return self.__ad_data["url"]
@property @property
def place(self) -> Literal['square' 'horizontal' 'horizontal-big']: def place(self) -> Literal["square" "horizontal" "horizontal-big"]:
return self.__ad_data['place'] return self.__ad_data["place"]
@property @property
def priority(self) -> Literal['high' 'middle' 'low']: def priority(self) -> Literal["high" "middle" "low"]:
return self.__ad_data['priority'] return self.__ad_data["priority"]
@property @property
def ratio(self) -> int: def ratio(self) -> int:
return self.__ad_data['ratio'] return self.__ad_data["ratio"]
@property @property
def image_url(self) -> str: def image_url(self) -> str:
return self.__ad_data['image_url'] return self.__ad_data["image_url"]
@property @property
def memo(self) -> str | None: def memo(self) -> str | None:
return self.__ad_data['memo'] return self.__ad_data["memo"]
@property @property
def api(self) -> AdminAdvertisingModelManager: def api(self) -> AdminAdvertisingModelManager:

@ -26,11 +26,11 @@ class UserIP:
@property @property
def ip(self) -> str: def ip(self) -> str:
return self.__user_ip['ip'] return self.__user_ip["ip"]
@property @property
def created_at(self) -> datetime: def created_at(self) -> datetime:
return str_to_datetime(self.__user_ip['created_at']) return str_to_datetime(self.__user_ip["created_at"])
def __eq__(self, __value: object) -> bool: def __eq__(self, __value: object) -> bool:
return isinstance(__value, UserIP) and self.ip == __value.ip return isinstance(__value, UserIP) and self.ip == __value.ip
@ -45,23 +45,23 @@ class IndexStat:
@property @property
def schemaname(self) -> str: def schemaname(self) -> str:
return self.__index_stat['schemaname'] return self.__index_stat["schemaname"]
@property @property
def tablename(self) -> str: def tablename(self) -> str:
return self.__index_stat['tablename'] return self.__index_stat["tablename"]
@property @property
def indexname(self) -> str: def indexname(self) -> str:
return self.__index_stat['indexname'] return self.__index_stat["indexname"]
@property @property
def tablespace(self) -> str | None: def tablespace(self) -> str | None:
return self.__index_stat['tablespace'] return self.__index_stat["tablespace"]
@property @property
def indexdef(self) -> str: def indexdef(self) -> str:
return self.__index_stat['indexdef'] return self.__index_stat["indexdef"]
class ModerationLog: class ModerationLog:
@ -71,27 +71,27 @@ class ModerationLog:
@property @property
def id(self) -> str: def id(self) -> str:
return self.__moderation_log['id'] return self.__moderation_log["id"]
@property @property
def created_at(self) -> datetime: def created_at(self) -> datetime:
return str_to_datetime(self.__moderation_log['created_at']) return str_to_datetime(self.__moderation_log["created_at"])
@property @property
def type(self) -> str: def type(self) -> str:
return self.__moderation_log['type'] return self.__moderation_log["type"]
@property @property
def info(self) -> dict: def info(self) -> dict:
return self.__moderation_log['info'] return self.__moderation_log["info"]
@property @property
def user_id(self) -> str: def user_id(self) -> str:
return self.__moderation_log['user_id'] return self.__moderation_log["user_id"]
@property @property
def user(self) -> UserDetailed: def user(self) -> UserDetailed:
return UserDetailed(self.__moderation_log['user'], client=self.__client) return UserDetailed(self.__moderation_log["user"], client=self.__client)
def __eq__(self, __value: object) -> bool: def __eq__(self, __value: object) -> bool:
return isinstance(__value, ModerationLog) and self.id == __value.id return isinstance(__value, ModerationLog) and self.id == __value.id
@ -106,11 +106,11 @@ class ServerInfoCpu:
@property @property
def models(self) -> str: def models(self) -> str:
return self.__server_info_cpu['models'] return self.__server_info_cpu["models"]
@property @property
def cores(self) -> int: def cores(self) -> int:
return self.__server_info_cpu['cores'] return self.__server_info_cpu["cores"]
class ServerInfoMem: class ServerInfoMem:
@ -119,7 +119,7 @@ class ServerInfoMem:
@property @property
def total(self) -> int: def total(self) -> int:
return self.__server_info_mem['total'] return self.__server_info_mem["total"]
class ServerInfoFs: class ServerInfoFs:
@ -128,11 +128,11 @@ class ServerInfoFs:
@property @property
def total(self) -> int: def total(self) -> int:
return self.__server_info_fs['total'] return self.__server_info_fs["total"]
@property @property
def used(self) -> int: def used(self) -> int:
return self.__server_info_fs['used'] return self.__server_info_fs["used"]
class ServerInfoNet: class ServerInfoNet:
@ -141,7 +141,7 @@ class ServerInfoNet:
@property @property
def interface(self) -> str: def interface(self) -> str:
return self.__server_info_net['interface'] return self.__server_info_net["interface"]
class ServerInfo: class ServerInfo:
@ -150,32 +150,32 @@ class ServerInfo:
@property @property
def machine(self) -> str: def machine(self) -> str:
return self.__server_info['machine'] return self.__server_info["machine"]
@property @property
def os(self) -> str: def os(self) -> str:
return self.__server_info['os'] return self.__server_info["os"]
@property @property
def node(self) -> str: def node(self) -> str:
return self.__server_info['node'] return self.__server_info["node"]
@property @property
def psql(self) -> str: def psql(self) -> str:
return self.__server_info['psql'] return self.__server_info["psql"]
@property @property
def cpu(self) -> ServerInfoCpu: def cpu(self) -> ServerInfoCpu:
return ServerInfoCpu(self.__server_info['cpu']) return ServerInfoCpu(self.__server_info["cpu"])
@property @property
def mem(self) -> ServerInfoMem: def mem(self) -> ServerInfoMem:
return ServerInfoMem(self.__server_info['mem']) return ServerInfoMem(self.__server_info["mem"])
@property @property
def fs(self) -> ServerInfoFs: def fs(self) -> ServerInfoFs:
return ServerInfoFs(self.__server_info['fs']) return ServerInfoFs(self.__server_info["fs"])
@property @property
def net(self) -> ServerInfoNet: def net(self) -> ServerInfoNet:
return ServerInfoNet(self.__server_info['net']) return ServerInfoNet(self.__server_info["net"])

@ -10,7 +10,7 @@ if TYPE_CHECKING:
from mipac.actions.admins.announcement import AdminAnnouncementClientActions from mipac.actions.admins.announcement import AdminAnnouncementClientActions
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
T = TypeVar('T', bound=IAnnouncementCommon) T = TypeVar("T", bound=IAnnouncementCommon)
class AnnouncementCommon(Generic[T]): class AnnouncementCommon(Generic[T]):
@ -20,31 +20,31 @@ class AnnouncementCommon(Generic[T]):
@property @property
def id(self) -> str: def id(self) -> str:
return self.__announcement['id'] return self.__announcement["id"]
@property @property
def created_at(self) -> datetime: def created_at(self) -> datetime:
return str_to_datetime(self.__announcement['created_at']) return str_to_datetime(self.__announcement["created_at"])
@property @property
def updated_at(self) -> datetime | None: def updated_at(self) -> datetime | None:
return ( return (
str_to_datetime(self.__announcement['updated_at']) str_to_datetime(self.__announcement["updated_at"])
if self.__announcement['updated_at'] if self.__announcement["updated_at"]
else None else None
) )
@property @property
def text(self) -> str: def text(self) -> str:
return self.__announcement['text'] return self.__announcement["text"]
@property @property
def title(self) -> str: def title(self) -> str:
return self.__announcement['title'] return self.__announcement["title"]
@property @property
def image_url(self) -> str | None: def image_url(self) -> str | None:
return self.__announcement['image_url'] return self.__announcement["image_url"]
@property @property
def action(self) -> AdminAnnouncementClientActions: def action(self) -> AdminAnnouncementClientActions:
@ -66,7 +66,7 @@ class Announcement(AnnouncementCommon):
@property @property
def is_read(self) -> bool: def is_read(self) -> bool:
return self.__announcement['is_read'] return self.__announcement["is_read"]
class AnnouncementSystem(AnnouncementCommon): class AnnouncementSystem(AnnouncementCommon):
@ -76,4 +76,4 @@ class AnnouncementSystem(AnnouncementCommon):
@property @property
def reads(self) -> int: def reads(self) -> int:
return self.__announcement['reads'] return self.__announcement["reads"]

@ -18,59 +18,59 @@ class Antenna:
@property @property
def case_sensitive(self) -> bool: def case_sensitive(self) -> bool:
return self.__antenna['case_sensitive'] return self.__antenna["case_sensitive"]
@property @property
def created_at(self) -> datetime: def created_at(self) -> datetime:
return str_to_datetime(self.__antenna['created_at']) return str_to_datetime(self.__antenna["created_at"])
@property @property
def exclude_keywords(self) -> list[str]: def exclude_keywords(self) -> list[str]:
return self.__antenna['exclude_keywords'] return self.__antenna["exclude_keywords"]
@property @property
def has_unread_note(self) -> bool: def has_unread_note(self) -> bool:
return self.__antenna['has_unread_note'] return self.__antenna["has_unread_note"]
@property @property
def id(self) -> str: def id(self) -> str:
return self.__antenna['id'] return self.__antenna["id"]
@property @property
def is_actor(self) -> bool: def is_actor(self) -> bool:
return self.__antenna['is_actor'] return self.__antenna["is_actor"]
@property @property
def keywords(self) -> list[str]: def keywords(self) -> list[str]:
return self.__antenna['keywords'] return self.__antenna["keywords"]
@property @property
def name(self) -> str: def name(self) -> str:
return self.__antenna['name'] return self.__antenna["name"]
@property @property
def notify(self) -> bool: def notify(self) -> bool:
return self.__antenna['notify'] return self.__antenna["notify"]
@property @property
def src(self) -> IAntennaReceiveSource: def src(self) -> IAntennaReceiveSource:
return self.__antenna['src'] return self.__antenna["src"]
@property @property
def user_list_id(self) -> str | None: def user_list_id(self) -> str | None:
return self.__antenna['user_list_id'] return self.__antenna["user_list_id"]
@property @property
def users(self) -> list[str]: def users(self) -> list[str]:
return self.__antenna['users'] return self.__antenna["users"]
@property @property
def with_file(self) -> bool: def with_file(self) -> bool:
return self.__antenna['with_file'] return self.__antenna["with_file"]
@property @property
def with_replies(self) -> bool: def with_replies(self) -> bool:
return self.__antenna['with_replies'] return self.__antenna["with_replies"]
@property @property
def api(self) -> ClientAntennaManager: def api(self) -> ClientAntennaManager:

@ -15,12 +15,12 @@ class Channel(ChannelLite[IChannel]):
@property @property
def has_unread_note(self) -> bool: def has_unread_note(self) -> bool:
return self._channel['has_unread_note'] return self._channel["has_unread_note"]
@property @property
def is_following(self) -> bool | None: def is_following(self) -> bool | None:
return self._channel.get('is_following') return self._channel.get("is_following")
@property @property
def is_favorited(self) -> bool | None: def is_favorited(self) -> bool | None:
return self._channel.get('is_favorited') return self._channel.get("is_favorited")

@ -2,120 +2,120 @@ from mipac.types.chart import IActiveUsersChart, IDriveChart, IDriveLocalChart,
class ActiveUsersChart: class ActiveUsersChart:
__slots__ = ('__data',) __slots__ = ("__data",)
def __init__(self, data: IActiveUsersChart): def __init__(self, data: IActiveUsersChart):
self.__data = data self.__data = data
@property @property
def read_write(self) -> list[int]: def read_write(self) -> list[int]:
return self.__data['read_write'] return self.__data["read_write"]
@property @property
def read(self) -> list[int]: def read(self) -> list[int]:
return self.__data['read'] return self.__data["read"]
@property @property
def write(self) -> list[int]: def write(self) -> list[int]:
return self.__data['write'] return self.__data["write"]
@property @property
def registered_within_week(self) -> list[int]: def registered_within_week(self) -> list[int]:
return self.__data['registered_within_week'] return self.__data["registered_within_week"]
@property @property
def registered_within_month(self) -> list[int]: def registered_within_month(self) -> list[int]:
return self.__data['registered_within_month'] return self.__data["registered_within_month"]
@property @property
def registered_within_year(self) -> list[int]: def registered_within_year(self) -> list[int]:
return self.__data['registered_within_year'] return self.__data["registered_within_year"]
@property @property
def registered_outside_week(self) -> list[int]: def registered_outside_week(self) -> list[int]:
return self.__data['registered_outside_week'] return self.__data["registered_outside_week"]
@property @property
def registered_outside_month(self) -> list[int]: def registered_outside_month(self) -> list[int]:
return self.__data['registered_outside_month'] return self.__data["registered_outside_month"]
@property @property
def registered_outside_year(self) -> list[int]: def registered_outside_year(self) -> list[int]:
return self.__data['registered_outside_year'] return self.__data["registered_outside_year"]
class DriveLocalChart: class DriveLocalChart:
__slots__ = ('__data',) __slots__ = ("__data",)
def __init__(self, data: IDriveLocalChart): def __init__(self, data: IDriveLocalChart):
self.__data = data self.__data = data
@property @property
def total_count(self) -> list[int]: def total_count(self) -> list[int]:
return self.__data['total_count'] return self.__data["total_count"]
@property @property
def total_size(self) -> list[int]: def total_size(self) -> list[int]:
return self.__data['total_size'] return self.__data["total_size"]
@property @property
def inc_count(self) -> list[int]: def inc_count(self) -> list[int]:
return self.__data['inc_count'] return self.__data["inc_count"]
@property @property
def inc_size(self) -> list[int]: def inc_size(self) -> list[int]:
return self.__data['inc_size'] return self.__data["inc_size"]
@property @property
def dec_count(self) -> list[int]: def dec_count(self) -> list[int]:
return self.__data['dec_count'] return self.__data["dec_count"]
@property @property
def dec_size(self) -> list[int]: def dec_size(self) -> list[int]:
return self.__data['dec_size'] return self.__data["dec_size"]
class DriveRemoteChart: class DriveRemoteChart:
__slots__ = ('__data',) __slots__ = ("__data",)
def __init__(self, data: IDriveRemoteChart): def __init__(self, data: IDriveRemoteChart):
self.__data: IDriveRemoteChart = data self.__data: IDriveRemoteChart = data
@property @property
def total_count(self) -> list[int]: def total_count(self) -> list[int]:
return self.__data['total_count'] return self.__data["total_count"]
@property @property
def total_size(self) -> list[int]: def total_size(self) -> list[int]:
return self.__data['total_size'] return self.__data["total_size"]
@property @property
def inc_count(self) -> list[int]: def inc_count(self) -> list[int]:
return self.__data['inc_count'] return self.__data["inc_count"]
@property @property
def inc_size(self) -> list[int]: def inc_size(self) -> list[int]:
return self.__data['inc_size'] return self.__data["inc_size"]
@property @property
def dec_count(self) -> list[int]: def dec_count(self) -> list[int]:
return self.__data['dec_count'] return self.__data["dec_count"]
@property @property
def dec_size(self) -> list[int]: def dec_size(self) -> list[int]:
return self.__data['dec_size'] return self.__data["dec_size"]
class DriveChart: class DriveChart:
__slots__ = ('__data',) __slots__ = ("__data",)
def __init__(self, data: IDriveChart): def __init__(self, data: IDriveChart):
self.__data: IDriveChart = data self.__data: IDriveChart = data
@property @property
def local(self) -> DriveLocalChart: def local(self) -> DriveLocalChart:
return DriveLocalChart(self.__data['local']) return DriveLocalChart(self.__data["local"])
@property @property
def remote(self) -> DriveRemoteChart: def remote(self) -> DriveRemoteChart:
return DriveRemoteChart(self.__data['remote']) return DriveRemoteChart(self.__data["remote"])

@ -10,7 +10,7 @@ if TYPE_CHECKING:
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
from mipac.types.chat import IChatGroup, IChatMessage from mipac.types.chat import IChatGroup, IChatMessage
__all__ = ['ChatGroup', 'ChatMessage'] __all__ = ["ChatGroup", "ChatMessage"]
class ChatGroup: class ChatGroup:
@ -21,26 +21,26 @@ class ChatGroup:
@property @property
def id(self) -> str: def id(self) -> str:
"""グループのID""" """グループのID"""
return self.__group['id'] return self.__group["id"]
@property @property
def created_at(self) -> str: def created_at(self) -> str:
"""グループの作成日時""" """グループの作成日時"""
return self.__group['created_at'] return self.__group["created_at"]
@property @property
def name(self) -> str: def name(self) -> str:
"""グループ名""" """グループ名"""
return self.__group['name'] return self.__group["name"]
@property @property
def owner_id(self) -> str: def owner_id(self) -> str:
"""グループのオーナーのID""" """グループのオーナーのID"""
return self.__group['owner_id'] return self.__group["owner_id"]
@property @property
def user_ids(self) -> list[str]: def user_ids(self) -> list[str]:
return self.__group['user_ids'] return self.__group["user_ids"]
def __eq__(self, __value: object) -> bool: def __eq__(self, __value: object) -> bool:
return isinstance(__value, ChatGroup) and self.id == __value.id return isinstance(__value, ChatGroup) and self.id == __value.id
@ -61,65 +61,65 @@ class ChatMessage:
@property @property
def id(self) -> str: def id(self) -> str:
"""The message ID.""" """The message ID."""
return self.__chat['id'] return self.__chat["id"]
@property @property
def created_at(self) -> str: def created_at(self) -> str:
"""Returns the date and time the message was created (UTC)""" """Returns the date and time the message was created (UTC)"""
return self.__chat['created_at'] return self.__chat["created_at"]
@property @property
def file(self) -> File | None: def file(self) -> File | None:
return File(self.__chat['file'], client=self.__client) if self.__chat['file'] else None return File(self.__chat["file"], client=self.__client) if self.__chat["file"] else None
@property @property
def text(self) -> str | None: def text(self) -> str | None:
"""text of the message""" """text of the message"""
return self.__chat['text'] return self.__chat["text"]
@property @property
def user_id(self) -> str: def user_id(self) -> str:
return self.__chat['user_id'] return self.__chat["user_id"]
@property @property
def user(self) -> LiteUser: def user(self) -> LiteUser:
return LiteUser(self.__chat['user'], client=self.__client) return LiteUser(self.__chat["user"], client=self.__client)
@property @property
def recipient_id(self) -> str | None: def recipient_id(self) -> str | None:
""" The id of the bot self """ """The id of the bot self"""
return self.__chat['recipient_id'] return self.__chat["recipient_id"]
@property @property
def recipient(self) -> LiteUser | None: def recipient(self) -> LiteUser | None:
""" The user of the bot self """ """The user of the bot self"""
return ( return (
LiteUser(self.__chat['recipient'], client=self.__client) LiteUser(self.__chat["recipient"], client=self.__client)
if self.__chat.get('recipient') if self.__chat.get("recipient")
else None else None
) )
@property @property
def group_id(self) -> str | None: def group_id(self) -> str | None:
return self.__chat['group_id'] return self.__chat["group_id"]
@property @property
def file_id(self) -> str | None: def file_id(self) -> str | None:
return self.__chat['file_id'] return self.__chat["file_id"]
@property @property
def is_read(self) -> bool: def is_read(self) -> bool:
return bool(self.__chat['is_read']) return bool(self.__chat["is_read"])
@property @property
def reads(self) -> list[str]: def reads(self) -> list[str]:
return self.__chat['reads'] return self.__chat["reads"]
@property @property
def group(self) -> ChatGroup | None: def group(self) -> ChatGroup | None:
return ( return (
ChatGroup(self.__chat['group'], client=self.__client) ChatGroup(self.__chat["group"], client=self.__client)
if self.__chat.get('group') if self.__chat.get("group")
else None else None
) )

@ -18,52 +18,52 @@ class Clip:
@property @property
def id(self) -> str: def id(self) -> str:
"""The clip id""" """The clip id"""
return self.__clip['id'] return self.__clip["id"]
@property @property
def created_at(self) -> str: def created_at(self) -> str:
"""The time the clip was created""" """The time the clip was created"""
return self.__clip['created_at'] return self.__clip["created_at"]
@property @property
def last_clipped_at(self) -> str: def last_clipped_at(self) -> str:
"""The last time the clip was clipped""" """The last time the clip was clipped"""
return self.__clip['last_clipped_at'] return self.__clip["last_clipped_at"]
@property @property
def user_id(self) -> str: def user_id(self) -> str:
"""The user id who created the clip""" """The user id who created the clip"""
return self.__clip['user_id'] return self.__clip["user_id"]
@property @property
def user(self) -> LiteUser: def user(self) -> LiteUser:
"""The user who created the clip""" """The user who created the clip"""
return LiteUser(self.__clip['user'], client=self.__client) return LiteUser(self.__clip["user"], client=self.__client)
@property @property
def name(self) -> str: def name(self) -> str:
"""The clip name""" """The clip name"""
return self.__clip['name'] return self.__clip["name"]
@property @property
def description(self) -> str | None: def description(self) -> str | None:
"""The clip description""" """The clip description"""
return self.__clip['description'] return self.__clip["description"]
@property @property
def is_public(self) -> bool: def is_public(self) -> bool:
"""Whether the clip is public""" """Whether the clip is public"""
return self.__clip['is_public'] return self.__clip["is_public"]
@property @property
def is_favorited(self) -> bool: def is_favorited(self) -> bool:
"""Whether the clip is favorited""" """Whether the clip is favorited"""
return self.__clip['is_favorited'] return self.__clip["is_favorited"]
@property @property
def favorited_count(self) -> int: def favorited_count(self) -> int:
"""The number of times the clip has been favorited""" """The number of times the clip has been favorited"""
return self.__clip['favorited_count'] return self.__clip["favorited_count"]
@property @property
def api(self) -> ClientClipManager: def api(self) -> ClientClipManager:

@ -7,7 +7,7 @@ if TYPE_CHECKING:
from mipac.manager.drive import ClientFileManager, ClientFolderManager from mipac.manager.drive import ClientFileManager, ClientFolderManager
from mipac.types import FolderPayload, IDriveFile, IFileProperties from mipac.types import FolderPayload, IDriveFile, IFileProperties
__all__ = ['FileProperties', 'File', 'Folder'] __all__ = ["FileProperties", "File", "Folder"]
class FileProperties: class FileProperties:
@ -16,15 +16,15 @@ class FileProperties:
@property @property
def width(self) -> int | None: def width(self) -> int | None:
return self.__properties['width'] return self.__properties["width"]
@property @property
def height(self) -> int: def height(self) -> int:
return self.__properties['height'] return self.__properties["height"]
@property @property
def avg_color(self) -> str | None: def avg_color(self) -> str | None:
return self.__properties['avg_color'] return self.__properties["avg_color"]
class Folder: class Folder:
@ -35,35 +35,35 @@ class Folder:
@property @property
def id(self) -> str: def id(self) -> str:
"""フォルダのID""" """フォルダのID"""
return self.__folder['id'] return self.__folder["id"]
@property @property
def created_at(self) -> str: # TODO: 型 def created_at(self) -> str: # TODO: 型
"""フォルダの作成日時""" """フォルダの作成日時"""
return self.__folder['created_at'] return self.__folder["created_at"]
@property @property
def name(self) -> str: def name(self) -> str:
"""フォルダ名""" """フォルダ名"""
return self.__folder['name'] return self.__folder["name"]
@property @property
def folders_count(self) -> int: def folders_count(self) -> int:
"""フォルダ内のフォルダ数""" """フォルダ内のフォルダ数"""
return self.__folder['folders_count'] return self.__folder["folders_count"]
@property @property
def files_count(self) -> int: def files_count(self) -> int:
"""フォルダ内のファイル数""" """フォルダ内のファイル数"""
return self.__folder['files_count'] return self.__folder["files_count"]
@property @property
def parent_id(self) -> str: def parent_id(self) -> str:
return self.__folder['parent_id'] return self.__folder["parent_id"]
@property @property
def parent(self) -> dict[str, Any]: def parent(self) -> dict[str, Any]:
return self.__folder['parent'] return self.__folder["parent"]
@property @property
def api(self) -> ClientFolderManager: def api(self) -> ClientFolderManager:
@ -83,47 +83,47 @@ class File:
@property @property
def id(self) -> str: def id(self) -> str:
return self.__file['id'] return self.__file["id"]
@property @property
def created_at(self): def created_at(self):
return self.__file['created_at'] return self.__file["created_at"]
@property @property
def is_sensitive(self) -> bool: def is_sensitive(self) -> bool:
return self.__file['is_sensitive'] return self.__file["is_sensitive"]
@property @property
def name(self) -> str: def name(self) -> str:
return self.__file['name'] return self.__file["name"]
@property @property
def thumbnail_url(self) -> str: def thumbnail_url(self) -> str:
return self.__file['thumbnail_url'] return self.__file["thumbnail_url"]
@property @property
def url(self) -> str: def url(self) -> str:
return self.__file['url'] return self.__file["url"]
@property @property
def type(self) -> str: def type(self) -> str:
return self.__file['type'] return self.__file["type"]
@property @property
def size(self) -> int: def size(self) -> int:
return self.__file['size'] return self.__file["size"]
@property @property
def md5(self) -> str: def md5(self) -> str:
return self.__file['md5'] return self.__file["md5"]
@property @property
def blurhash(self) -> str: def blurhash(self) -> str:
return self.__file['blurhash'] return self.__file["blurhash"]
@property @property
def properties(self) -> FileProperties: def properties(self) -> FileProperties:
return FileProperties(self.__file['properties']) return FileProperties(self.__file["properties"])
@property @property
def api(self) -> ClientFileManager: def api(self) -> ClientFileManager:

@ -8,7 +8,7 @@ from mipac.types.emoji import ICustomEmoji
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.client import ClientManager from mipac.client import ClientManager
__all__ = ('CustomEmoji',) __all__ = ("CustomEmoji",)
class CustomEmoji(PartialCustomEmoji): class CustomEmoji(PartialCustomEmoji):
@ -18,23 +18,23 @@ class CustomEmoji(PartialCustomEmoji):
@property @property
def id(self) -> str: def id(self) -> str:
return self.__emoji['id'] return self.__emoji["id"]
@property @property
def aliases(self) -> list[str]: def aliases(self) -> list[str]:
return self.__emoji['aliases'] return self.__emoji["aliases"]
@property @property
def category(self) -> str: def category(self) -> str:
return self.__emoji['category'] return self.__emoji["category"]
@property @property
def license(self) -> str | None: def license(self) -> str | None:
return self.__emoji['license'] return self.__emoji["license"]
@property @property
def host(self) -> str | None: def host(self) -> str | None:
return self.__emoji['host'] return self.__emoji["host"]
def __eq__(self, __value: object) -> bool: def __eq__(self, __value: object) -> bool:
return isinstance(__value, CustomEmoji) and self.id == __value.id return isinstance(__value, CustomEmoji) and self.id == __value.id

@ -17,15 +17,15 @@ class FollowRequest:
@property @property
def id(self) -> str: def id(self) -> str:
return self.__follow_request['id'] return self.__follow_request["id"]
@property @property
def follower(self) -> LiteUser: def follower(self) -> LiteUser:
return LiteUser(self.__follow_request['follower'], client=self.__client) return LiteUser(self.__follow_request["follower"], client=self.__client)
@property @property
def followee(self) -> LiteUser: def followee(self) -> LiteUser:
return LiteUser(self.__follow_request['followee'], client=self.__client) return LiteUser(self.__follow_request["followee"], client=self.__client)
@property @property
def api(self) -> FollowRequestManager: def api(self) -> FollowRequestManager:

@ -15,99 +15,99 @@ class FederationInstance:
@property @property
def id(self) -> str: def id(self) -> str:
return self.__instance['id'] return self.__instance["id"]
@property @property
def host(self) -> str: def host(self) -> str:
return self.__instance['host'] return self.__instance["host"]
@property @property
def users_count(self) -> int: def users_count(self) -> int:
return self.__instance['users_count'] return self.__instance["users_count"]
@property @property
def notes_count(self) -> int: def notes_count(self) -> int:
return self.__instance['notes_count'] return self.__instance["notes_count"]
@property @property
def following_count(self) -> int: def following_count(self) -> int:
return self.__instance['following_count'] return self.__instance["following_count"]
@property @property
def followers_count(self) -> int: def followers_count(self) -> int:
return self.__instance['followers_count'] return self.__instance["followers_count"]
@property @property
def is_not_responding(self) -> bool: def is_not_responding(self) -> bool:
return self.__instance['is_not_responding'] return self.__instance["is_not_responding"]
@property @property
def is_suspended(self) -> bool: def is_suspended(self) -> bool:
return self.__instance['is_suspended'] return self.__instance["is_suspended"]
@property @property
def is_blocked(self) -> bool: def is_blocked(self) -> bool:
return self.__instance['is_blocked'] return self.__instance["is_blocked"]
@property @property
def software_name(self) -> str: def software_name(self) -> str:
return self.__instance['software_name'] return self.__instance["software_name"]
@property @property
def software_version(self) -> str: def software_version(self) -> str:
return self.__instance['software_version'] return self.__instance["software_version"]
@property @property
def open_registrations(self) -> bool: def open_registrations(self) -> bool:
return self.__instance['open_registrations'] return self.__instance["open_registrations"]
@property @property
def name(self) -> str: def name(self) -> str:
return self.__instance['name'] return self.__instance["name"]
@property @property
def description(self) -> str: def description(self) -> str:
return self.__instance['description'] return self.__instance["description"]
@property @property
def maintainer_name(self) -> str: def maintainer_name(self) -> str:
return self.__instance['maintainer_name'] return self.__instance["maintainer_name"]
@property @property
def maintainer_email(self) -> str: def maintainer_email(self) -> str:
return self.__instance['maintainer_email'] return self.__instance["maintainer_email"]
@property @property
def icon_url(self) -> str: def icon_url(self) -> str:
return self.__instance['icon_url'] return self.__instance["icon_url"]
@property @property
def favicon_url(self) -> str: def favicon_url(self) -> str:
return self.__instance['favicon_url'] return self.__instance["favicon_url"]
@property @property
def theme_color(self) -> str: def theme_color(self) -> str:
return self.__instance['theme_color'] return self.__instance["theme_color"]
@property @property
def info_updated_at(self) -> str: def info_updated_at(self) -> str:
return self.__instance['info_updated_at'] return self.__instance["info_updated_at"]
@property @property
def caught_at(self) -> str | None: def caught_at(self) -> str | None:
return self.__instance.get('caught_at') return self.__instance.get("caught_at")
@property @property
def first_retrieved_at(self) -> str | None: def first_retrieved_at(self) -> str | None:
return self.__instance.get('first_retrieved_at') return self.__instance.get("first_retrieved_at")
@property @property
def latest_request_sent_at(self) -> str | None: def latest_request_sent_at(self) -> str | None:
return self.__instance.get('latest_request_sent_at') return self.__instance.get("latest_request_sent_at")
@property @property
def last_communicated_at(self) -> str | None: def last_communicated_at(self) -> str | None:
return self.__instance.get('last_communicated_at') return self.__instance.get("last_communicated_at")
def __eq__(self, __value: object) -> bool: def __eq__(self, __value: object) -> bool:
return isinstance(__value, FederationInstance) and self.id == __value.id return isinstance(__value, FederationInstance) and self.id == __value.id

@ -11,7 +11,7 @@ if TYPE_CHECKING:
from mipac.manager.channel import ChannelManager from mipac.manager.channel import ChannelManager
T = TypeVar('T', bound=IChannelLite) T = TypeVar("T", bound=IChannelLite)
class ChannelLite(Generic[T]): class ChannelLite(Generic[T]):
@ -21,44 +21,44 @@ class ChannelLite(Generic[T]):
@property @property
def id(self) -> str: def id(self) -> str:
return self._channel['id'] return self._channel["id"]
@property @property
def created_at(self) -> datetime: def created_at(self) -> datetime:
return str_to_datetime(self._channel['created_at']) return str_to_datetime(self._channel["created_at"])
@property @property
def last_noted_at(self) -> datetime | None: def last_noted_at(self) -> datetime | None:
last_noted_at = self._channel.get('last_noted_at') last_noted_at = self._channel.get("last_noted_at")
return str_to_datetime(last_noted_at) if last_noted_at else None return str_to_datetime(last_noted_at) if last_noted_at else None
@property @property
def name(self) -> str: def name(self) -> str:
return self._channel['name'] return self._channel["name"]
@property @property
def description(self) -> str | None: def description(self) -> str | None:
return self._channel['description'] return self._channel["description"]
@property @property
def user_id(self) -> str: def user_id(self) -> str:
return self._channel['user_id'] return self._channel["user_id"]
@property @property
def banner_url(self) -> str | None: def banner_url(self) -> str | None:
return self._channel['banner_url'] return self._channel["banner_url"]
@property @property
def users_count(self) -> int: def users_count(self) -> int:
return self._channel['users_count'] return self._channel["users_count"]
@property @property
def notes_count(self) -> int: def notes_count(self) -> int:
return self._channel['notes_count'] return self._channel["notes_count"]
@property @property
def pinned_note_ids(self) -> list: def pinned_note_ids(self) -> list:
return self._channel.get('pinned_note_ids', []) return self._channel.get("pinned_note_ids", [])
@property @property
def api(self) -> ChannelManager: def api(self) -> ChannelManager:

@ -16,12 +16,12 @@ class PartialCustomEmoji:
@property @property
def name(self) -> str: def name(self) -> str:
return self.__emoji['name'] return self.__emoji["name"]
@property @property
def url(self) -> str | None: def url(self) -> str | None:
if config.use_version == 13: if config.use_version == 13:
protocol = 'https' if config.is_ssl else 'http' protocol = "https" if config.is_ssl else "http"
url = f'{protocol}://{config.host}/emoji/{self.name}.webp' url = f"{protocol}://{config.host}/emoji/{self.name}.webp"
return url return url
return self.__emoji.get('url') return self.__emoji.get("url")

@ -9,19 +9,19 @@ class LiteInstance:
@property @property
def name(self) -> str: def name(self) -> str:
return self.__instance['name'] return self.__instance["name"]
def software_name(self) -> str: def software_name(self) -> str:
return self.__instance['software_name'] return self.__instance["software_name"]
def software_version(self) -> str: def software_version(self) -> str:
return self.__instance['software_version'] return self.__instance["software_version"]
def icon_url(self) -> str: def icon_url(self) -> str:
return self.__instance['icon_url'] return self.__instance["icon_url"]
def favicon_url(self) -> str: def favicon_url(self) -> str:
return self.__instance['favicon_url'] return self.__instance["favicon_url"]
def theme_color(self) -> str: def theme_color(self) -> str:
return self.__instance['theme_color'] return self.__instance["theme_color"]

@ -16,11 +16,11 @@ class CPU:
@property @property
def cores(self) -> int: def cores(self) -> int:
return self.__cpu['cores'] return self.__cpu["cores"]
@property @property
def model(self) -> str: def model(self) -> str:
return self.__cpu['model'] return self.__cpu["model"]
class MetaCommon: class MetaCommon:
@ -30,71 +30,71 @@ class MetaCommon:
@property @property
def cache_remote_files(self) -> bool: def cache_remote_files(self) -> bool:
return self.__meta_common['cache_remote_files'] return self.__meta_common["cache_remote_files"]
@property @property
def enable_hcaptch(self) -> bool: def enable_hcaptch(self) -> bool:
return self.__meta_common['enable_hcaptch'] return self.__meta_common["enable_hcaptch"]
@property @property
def hcaptcha_site_key(self) -> str | None: def hcaptcha_site_key(self) -> str | None:
return self.__meta_common['hcaptcha_site_key'] return self.__meta_common["hcaptcha_site_key"]
@property @property
def enable_recaptcha(self) -> bool: def enable_recaptcha(self) -> bool:
return self.__meta_common['enable_recaptcha'] return self.__meta_common["enable_recaptcha"]
@property @property
def recaptcha_site_key(self) -> str: def recaptcha_site_key(self) -> str:
return self.__meta_common['recaptcha_site_key'] return self.__meta_common["recaptcha_site_key"]
@property @property
def sw_publickey(self) -> str | None: def sw_publickey(self) -> str | None:
return self.__meta_common['sw_publickey'] return self.__meta_common["sw_publickey"]
@property @property
def banner_url(self) -> str | None: def banner_url(self) -> str | None:
return self.__meta_common['banner_url'] return self.__meta_common["banner_url"]
@property @property
def error_image_url(self) -> str | None: def error_image_url(self) -> str | None:
return self.__meta_common['error_image_url'] return self.__meta_common["error_image_url"]
@property @property
def icon_url(self) -> str | None: def icon_url(self) -> str | None:
return self.__meta_common['icon_url'] return self.__meta_common["icon_url"]
@property @property
def max_note_text_length(self) -> int: def max_note_text_length(self) -> int:
return self.__meta_common['max_note_text_length'] return self.__meta_common["max_note_text_length"]
@property @property
def enable_email(self) -> bool: def enable_email(self) -> bool:
return self.__meta_common['enable_email'] return self.__meta_common["enable_email"]
@property @property
def enable_twitter_integration(self) -> bool: def enable_twitter_integration(self) -> bool:
return self.__meta_common['enable_twitter_integration'] return self.__meta_common["enable_twitter_integration"]
@property @property
def enable_github_integration(self) -> bool: def enable_github_integration(self) -> bool:
return self.__meta_common['enable_github_integration'] return self.__meta_common["enable_github_integration"]
@property @property
def enable_discord_integration(self) -> bool: def enable_discord_integration(self) -> bool:
return self.__meta_common['enable_discord_integration'] return self.__meta_common["enable_discord_integration"]
@property @property
def enable_service_worker(self) -> bool: def enable_service_worker(self) -> bool:
return self.__meta_common['enable_service_worker'] return self.__meta_common["enable_service_worker"]
@property @property
def proxy_account_name(self) -> str | None: def proxy_account_name(self) -> str | None:
return self.__meta_common['proxy_account_name'] return self.__meta_common["proxy_account_name"]
@property @property
def use_star_for_reaction_fallback(self) -> bool: def use_star_for_reaction_fallback(self) -> bool:
return self.__meta_common.get('use_star_for_reaction_fallback', False) return self.__meta_common.get("use_star_for_reaction_fallback", False)
@property @property
def object_storage_s3_force_path_style(self) -> bool: def object_storage_s3_force_path_style(self) -> bool:
@ -107,33 +107,33 @@ class MetaCommon:
bool bool
有効かどうか 有効かどうか
""" """
return self.__meta_common.get('object_storage_s3_force_path_style', False) return self.__meta_common.get("object_storage_s3_force_path_style", False)
# v12 only # v12 only
@property @property
def ads(self) -> list[IAds] | None: # TODO: モデルに def ads(self) -> list[IAds] | None: # TODO: モデルに
return self.__meta_common.get('ads') return self.__meta_common.get("ads")
@property @property
def translator_available(self) -> bool: def translator_available(self) -> bool:
return self.__meta_common.get('translator_available', False) return self.__meta_common.get("translator_available", False)
@property @property
def email_required_for_signup(self) -> bool: def email_required_for_signup(self) -> bool:
return self.__meta_common.get('email_required_for_signup', False) return self.__meta_common.get("email_required_for_signup", False)
@property @property
def mascot_image_url(self) -> str | None: def mascot_image_url(self) -> str | None:
return self.__meta_common.get('mascot_image_url') return self.__meta_common.get("mascot_image_url")
# v12とv11の共通情報 # v12とv11の共通情報
@property @property
def emojis(self) -> list[CustomEmoji]: def emojis(self) -> list[CustomEmoji]:
return ( return (
[CustomEmoji(i, client=self.__client) for i in self.__meta_common['emojis']] [CustomEmoji(i, client=self.__client) for i in self.__meta_common["emojis"]]
if 'emojis' in self.__meta_common if "emojis" in self.__meta_common
else [] else []
) )
@ -146,128 +146,128 @@ class LiteMeta(MetaCommon):
@property @property
def description(self) -> str | None: def description(self) -> str | None:
return self.__lite_meta['description'] return self.__lite_meta["description"]
@property @property
def disable_registration(self) -> bool: def disable_registration(self) -> bool:
return self.__lite_meta['disable_registration'] return self.__lite_meta["disable_registration"]
@property @property
def feedback_url(self) -> str: def feedback_url(self) -> str:
return self.__lite_meta['feedback_url'] return self.__lite_meta["feedback_url"]
@property @property
def maintainer_email(self) -> str | None: def maintainer_email(self) -> str | None:
return self.__lite_meta['maintainer_email'] return self.__lite_meta["maintainer_email"]
@property @property
def maintainer_name(self) -> str | None: def maintainer_name(self) -> str | None:
return self.__lite_meta['maintainer_name'] return self.__lite_meta["maintainer_name"]
@property @property
def name(self) -> str | None: def name(self) -> str | None:
return self.__lite_meta['name'] return self.__lite_meta["name"]
@property @property
def repository_url(self) -> str: def repository_url(self) -> str:
return self.__lite_meta['repository_url'] return self.__lite_meta["repository_url"]
@property @property
def tos_url(self) -> str | None: def tos_url(self) -> str | None:
return self.__lite_meta['tos_url'] return self.__lite_meta["tos_url"]
@property @property
def uri(self) -> str: def uri(self) -> str:
return self.__lite_meta['uri'] return self.__lite_meta["uri"]
@property @property
def version(self) -> str: def version(self) -> str:
return self.__lite_meta['version'] return self.__lite_meta["version"]
# v12のMeta # v12のMeta
@property @property
def background_image_url(self) -> str | None: def background_image_url(self) -> str | None:
return self.__lite_meta.get('background_image_url') return self.__lite_meta.get("background_image_url")
@property @property
def default_dark_theme(self) -> str | None: def default_dark_theme(self) -> str | None:
return self.__lite_meta.get('default_dark_theme') return self.__lite_meta.get("default_dark_theme")
@property @property
def default_light_theme(self) -> str | None: def default_light_theme(self) -> str | None:
return self.__lite_meta.get('default_light_theme') return self.__lite_meta.get("default_light_theme")
@property @property
def logo_image_url(self) -> str | None: def logo_image_url(self) -> str | None:
return self.__lite_meta.get('logo_image_url') return self.__lite_meta.get("logo_image_url")
@property @property
def theme_color(self) -> str | None: def theme_color(self) -> str | None:
return self.__lite_meta.get('theme_color') return self.__lite_meta.get("theme_color")
# v11のMeta # v11のMeta
@property @property
def announcements(self) -> list[IMetaAnnouncement] | None: # TODO: 型確認 def announcements(self) -> list[IMetaAnnouncement] | None: # TODO: 型確認
return self.__lite_meta.get('announcements', None) return self.__lite_meta.get("announcements", None)
@property @property
def cpu(self) -> CPU | None: def cpu(self) -> CPU | None:
return CPU(self.__lite_meta['cpu']) if 'cpu' in self.__lite_meta else None return CPU(self.__lite_meta["cpu"]) if "cpu" in self.__lite_meta else None
@property @property
def disable_local_timeline(self) -> bool: def disable_local_timeline(self) -> bool:
return self.__lite_meta.get('disable_local_timeline', False) return self.__lite_meta.get("disable_local_timeline", False)
@property @property
def disable_global_timeline(self) -> bool: def disable_global_timeline(self) -> bool:
return self.__lite_meta.get('disable_global_timeline', False) return self.__lite_meta.get("disable_global_timeline", False)
@property @property
def enable_emoji_reaction(self) -> bool: def enable_emoji_reaction(self) -> bool:
return self.__lite_meta.get('enable_emoji_reaction', False) return self.__lite_meta.get("enable_emoji_reaction", False)
@property @property
def machine(self) -> str | None: def machine(self) -> str | None:
return self.__lite_meta.get('machine') return self.__lite_meta.get("machine")
@property @property
def node(self) -> str | None: def node(self) -> str | None:
return self.__lite_meta.get('node') return self.__lite_meta.get("node")
@property @property
def os(self) -> str | None: def os(self) -> str | None:
return self.__lite_meta.get('os') return self.__lite_meta.get("os")
@property @property
def proxy_account(self) -> str | None: def proxy_account(self) -> str | None:
return self.__lite_meta.get('proxy_account') return self.__lite_meta.get("proxy_account")
@property @property
def proxy_remote_files(self) -> bool: def proxy_remote_files(self) -> bool:
return self.__lite_meta.get('proxy_remote_files', False) return self.__lite_meta.get("proxy_remote_files", False)
@property @property
def psql(self) -> str | None: def psql(self) -> str | None:
return self.__lite_meta.get('psql') return self.__lite_meta.get("psql")
@property @property
def redis(self) -> str | None: def redis(self) -> str | None:
return self.__lite_meta.get('redis') return self.__lite_meta.get("redis")
@property @property
def secure(self) -> bool: def secure(self) -> bool:
return self.__lite_meta.get('secure', False) return self.__lite_meta.get("secure", False)
@property @property
def summaly_proxy(self) -> str | None: def summaly_proxy(self) -> str | None:
return self.__lite_meta.get('summaly_proxy') return self.__lite_meta.get("summaly_proxy")
@property @property
def tos_text_url(self) -> str | None: def tos_text_url(self) -> str | None:
return self.__lite_meta.get('tos_text_url') return self.__lite_meta.get("tos_text_url")
@property @property
def turnstile_secret_key(self) -> str | None: def turnstile_secret_key(self) -> str | None:
return self.__lite_meta.get('turnstile_secret_key') return self.__lite_meta.get("turnstile_secret_key")

@ -14,7 +14,7 @@ if TYPE_CHECKING:
from mipac.manager.note import ClientNoteManager from mipac.manager.note import ClientNoteManager
T = TypeVar('T', bound=IPartialNote) T = TypeVar("T", bound=IPartialNote)
class PartialNote(Generic[T]): class PartialNote(Generic[T]):
@ -24,19 +24,19 @@ class PartialNote(Generic[T]):
@property @property
def created_at(self) -> datetime: def created_at(self) -> datetime:
return str_to_datetime(self._note['created_at']) return str_to_datetime(self._note["created_at"])
@property @property
def cw(self) -> str | None: def cw(self) -> str | None:
return self._note.get('cw') return self._note.get("cw")
@property @property
def file_ids(self) -> list[str]: def file_ids(self) -> list[str]:
return self._note['file_ids'] return self._note["file_ids"]
@property @property
def files(self) -> list[File]: def files(self) -> list[File]:
return [File(file, client=self._client) for file in self._note['files']] return [File(file, client=self._client) for file in self._note["files"]]
@property @property
def id(self) -> str: def id(self) -> str:
@ -48,7 +48,7 @@ class PartialNote(Generic[T]):
str str
ユーザーのID ユーザーのID
""" """
return self._note['id'] return self._note["id"]
@property @property
def reaction_acceptance(self) -> IReactionAcceptance | None: def reaction_acceptance(self) -> IReactionAcceptance | None:
@ -58,7 +58,7 @@ class PartialNote(Generic[T]):
------- -------
IReactionAcceptance | None IReactionAcceptance | None
""" """
return self._note.get('reaction_acceptance') return self._note.get("reaction_acceptance")
@property @property
def reaction_emojis(self) -> dict[str, str] | None: def reaction_emojis(self) -> dict[str, str] | None:
@ -69,47 +69,49 @@ class PartialNote(Generic[T]):
dict[str, str] | None dict[str, str] | None
リアクション名がキー値はリアクション画像のリンクです リアクション名がキー値はリアクション画像のリンクです
""" """
return self._note.get('reaction_emojis') return self._note.get("reaction_emojis")
@property @property
def renote_id(self) -> str | None: def renote_id(self) -> str | None:
return self._note['renote_id'] return self._note["renote_id"]
@property @property
def renote_count(self) -> int: def renote_count(self) -> int:
return self._note['renote_count'] return self._note["renote_count"]
@property @property
def reactions(self) -> dict[str, int]: def reactions(self) -> dict[str, int]:
return self._note['reactions'] return self._note["reactions"]
@property @property
def replies_count(self) -> int: def replies_count(self) -> int:
return self._note['replies_count'] return self._note["replies_count"]
@property @property
def reply_id(self) -> str | None: def reply_id(self) -> str | None:
return self._note['reply_id'] return self._note["reply_id"]
@property @property
def tags(self) -> list[str]: def tags(self) -> list[str]:
return self._note.get('tags', []) return self._note.get("tags", [])
@property @property
def content(self) -> str | None: def content(self) -> str | None:
return self._note.get('text') return self._note.get("text")
@property @property
def author(self) -> LiteUser: def author(self) -> LiteUser:
return LiteUser(self._note['user'], client=self._client) return LiteUser(self._note["user"], client=self._client)
@property @property
def user_id(self) -> str: def user_id(self) -> str:
return self._note['user_id'] return self._note["user_id"]
@property @property
def visibility(self,) -> INoteVisibility: def visibility(
return self._note['visibility'] self,
) -> INoteVisibility:
return self._note["visibility"]
@property @property
def api(self) -> ClientNoteManager: def api(self) -> ClientNoteManager:

@ -12,7 +12,7 @@ if TYPE_CHECKING:
class LiteUser: class LiteUser:
__slots__ = ('__user', '__client') __slots__ = ("__user", "__client")
def __init__(self, user: ILiteUser, *, client: ClientManager) -> None: def __init__(self, user: ILiteUser, *, client: ClientManager) -> None:
self.__user: ILiteUser = user self.__user: ILiteUser = user
@ -20,31 +20,33 @@ class LiteUser:
@property @property
def id(self) -> str: def id(self) -> str:
return self.__user['id'] return self.__user["id"]
@property @property
def username(self) -> str: def username(self) -> str:
return self.__user['username'] return self.__user["username"]
@property @property
def host(self) -> str | None: def host(self) -> str | None:
return self.__user['host'] if 'host' in self.__user else None return self.__user["host"] if "host" in self.__user else None
@property @property
def nickname(self) -> str: def nickname(self) -> str:
return self.__user['name'] return self.__user["name"]
@property @property
def online_status(self,) -> Literal['online', 'active', 'offline', 'unknown']: def online_status(
return self.__user['online_status'] self,
) -> Literal["online", "active", "offline", "unknown"]:
return self.__user["online_status"]
@property @property
def avatar_url(self) -> str: def avatar_url(self) -> str:
return self.__user['avatar_url'] return self.__user["avatar_url"]
@property @property
def avatar_blurhash(self) -> str: def avatar_blurhash(self) -> str:
return self.__user['avatar_blurhash'] return self.__user["avatar_blurhash"]
@property @property
def avatar_color(self) -> str | None: def avatar_color(self) -> str | None:
@ -59,7 +61,7 @@ class LiteUser:
average color of the avatar average color of the avatar
""" """
return self.__user.get('avatar_color') return self.__user.get("avatar_color")
@property @property
def emojis(self) -> list[ICustomEmojiLite]: # TODO: ちゃんとモデルにする def emojis(self) -> list[ICustomEmojiLite]: # TODO: ちゃんとモデルにする
@ -73,11 +75,11 @@ class LiteUser:
List of emoji included in nicknames, etc List of emoji included in nicknames, etc
""" """
return self.__user.get('emojis', []) return self.__user.get("emojis", [])
@property @property
def instance(self) -> LiteInstance | None: def instance(self) -> LiteInstance | None:
return LiteInstance(self.__user['instance']) if 'instance' in self.__user else None return LiteInstance(self.__user["instance"]) if "instance" in self.__user else None
@property @property
def api(self) -> UserManager: def api(self) -> UserManager:

@ -15,67 +15,67 @@ class Policies:
@property @property
def gtl_available(self) -> bool: def gtl_available(self) -> bool:
return self.__policies['gtl_available'] return self.__policies["gtl_available"]
@property @property
def ltl_available(self) -> bool: def ltl_available(self) -> bool:
return self.__policies['ltl_available'] return self.__policies["ltl_available"]
@property @property
def can_public_note(self) -> bool: def can_public_note(self) -> bool:
return self.__policies['can_public_note'] return self.__policies["can_public_note"]
@property @property
def can_invite(self) -> bool: def can_invite(self) -> bool:
return self.__policies['can_invite'] return self.__policies["can_invite"]
@property @property
def can_manage_custom_emojis(self) -> bool: def can_manage_custom_emojis(self) -> bool:
return self.__policies['can_manage_custom_emojis'] return self.__policies["can_manage_custom_emojis"]
@property @property
def can_hide_ads(self) -> bool: def can_hide_ads(self) -> bool:
return self.__policies['can_hide_ads'] return self.__policies["can_hide_ads"]
@property @property
def drive_capacity_mb(self) -> int: def drive_capacity_mb(self) -> int:
return self.__policies['drive_capacity_mb'] return self.__policies["drive_capacity_mb"]
@property @property
def pin_limit(self) -> int: def pin_limit(self) -> int:
return self.__policies['pin_limit'] return self.__policies["pin_limit"]
@property @property
def antenna_limit(self) -> int: def antenna_limit(self) -> int:
return self.__policies['antenna_limit'] return self.__policies["antenna_limit"]
@property @property
def word_mute_limit(self) -> int: def word_mute_limit(self) -> int:
return self.__policies['word_mute_limit'] return self.__policies["word_mute_limit"]
@property @property
def webhook_limit(self) -> int: def webhook_limit(self) -> int:
return self.__policies['webhook_limit'] return self.__policies["webhook_limit"]
@property @property
def clip_limit(self) -> int: def clip_limit(self) -> int:
return self.__policies['clip_limit'] return self.__policies["clip_limit"]
@property @property
def note_each_clips_limit(self) -> int: def note_each_clips_limit(self) -> int:
return self.__policies['note_each_clips_limit'] return self.__policies["note_each_clips_limit"]
@property @property
def user_list_limit(self) -> int: def user_list_limit(self) -> int:
return self.__policies['user_list_limit'] return self.__policies["user_list_limit"]
@property @property
def user_each_user_lists_limit(self) -> int: def user_each_user_lists_limit(self) -> int:
return self.__policies['user_each_user_lists_limit'] return self.__policies["user_each_user_lists_limit"]
@property @property
def rate_limit_factor(self) -> int: def rate_limit_factor(self) -> int:
return self.__policies['rate_limit_factor'] return self.__policies["rate_limit_factor"]
class Features: class Features:
@ -84,55 +84,55 @@ class Features:
@property @property
def registration(self) -> bool: def registration(self) -> bool:
return self.__features['registration'] return self.__features["registration"]
@property @property
def elasticsearch(self) -> bool: def elasticsearch(self) -> bool:
return self.__features['elasticsearch'] return self.__features["elasticsearch"]
@property @property
def hcaptcha(self) -> bool: def hcaptcha(self) -> bool:
return self.__features['hcaptcha'] return self.__features["hcaptcha"]
@property @property
def recaptcha(self) -> bool: def recaptcha(self) -> bool:
return self.__features['recaptcha'] return self.__features["recaptcha"]
@property @property
def object_storage(self) -> bool: def object_storage(self) -> bool:
return self.__features['object_storage'] return self.__features["object_storage"]
@property @property
def twitter(self) -> bool: def twitter(self) -> bool:
return self.__features['twitter'] return self.__features["twitter"]
@property @property
def github(self) -> bool: def github(self) -> bool:
return self.__features['github'] return self.__features["github"]
@property @property
def discord(self) -> bool: def discord(self) -> bool:
return self.__features['discord'] return self.__features["discord"]
@property @property
def service_worker(self) -> bool: def service_worker(self) -> bool:
return self.__features['service_worker'] return self.__features["service_worker"]
@property @property
def miauth(self) -> bool: def miauth(self) -> bool:
return self.__features.get('miauth', False) return self.__features.get("miauth", False)
@property @property
def email_required_for_signup(self) -> bool: def email_required_for_signup(self) -> bool:
return self.__features.get('email_required_for_signup', False) return self.__features.get("email_required_for_signup", False)
@property @property
def global_time_line(self) -> bool: def global_time_line(self) -> bool:
return self.__features.get('global_time_line', False) return self.__features.get("global_time_line", False)
@property @property
def local_time_line(self) -> bool: def local_time_line(self) -> bool:
return self.__features.get('local_time_line', False) return self.__features.get("local_time_line", False)
class Meta(LiteMeta): class Meta(LiteMeta):
@ -144,25 +144,25 @@ class Meta(LiteMeta):
@property @property
def features(self) -> Features: def features(self) -> Features:
return Features(self.__meta['features']) return Features(self.__meta["features"])
# v12 # v12
@property @property
def pinned_clip_id(self) -> str | None: def pinned_clip_id(self) -> str | None:
return self.__meta.get('pinned_clip_id') return self.__meta.get("pinned_clip_id")
@property @property
def pinned_pages(self) -> list[str]: def pinned_pages(self) -> list[str]:
return self.__meta.get('pinned_pages', []) return self.__meta.get("pinned_pages", [])
@property @property
def policies(self) -> Policies | None: def policies(self) -> Policies | None:
return Policies(self.__meta['policies']) if 'policies' in self.__meta else None return Policies(self.__meta["policies"]) if "policies" in self.__meta else None
@property @property
def require_setup(self) -> bool: def require_setup(self) -> bool:
return self.__meta.get('require_setup', False) return self.__meta.get("require_setup", False)
class AdminMeta(MetaCommon): class AdminMeta(MetaCommon):
@ -174,127 +174,127 @@ class AdminMeta(MetaCommon):
@property @property
def drive_capacity_per_local_user_mb(self) -> int | None: def drive_capacity_per_local_user_mb(self) -> int | None:
return self.__admin_meta.get('drive_capacity_per_local_user_mb') return self.__admin_meta.get("drive_capacity_per_local_user_mb")
@property @property
def drive_capacity_per_remote_user_mb(self) -> int | None: def drive_capacity_per_remote_user_mb(self) -> int | None:
return self.__admin_meta.get('drive_capacity_per_remote_user_mb') return self.__admin_meta.get("drive_capacity_per_remote_user_mb")
@property @property
def hidden_tags(self) -> list[str]: def hidden_tags(self) -> list[str]:
return self.__admin_meta.get('hidden_tags', []) return self.__admin_meta.get("hidden_tags", [])
@property @property
def blocked_hosts(self) -> list[str]: def blocked_hosts(self) -> list[str]:
return self.__admin_meta.get('blocked_hosts', []) return self.__admin_meta.get("blocked_hosts", [])
@property @property
def recaptcha_secret_key(self) -> str | None: def recaptcha_secret_key(self) -> str | None:
return self.__admin_meta.get('recaptcha_secret_key') return self.__admin_meta.get("recaptcha_secret_key")
@property @property
def twitter_consumer_key(self) -> str | None: def twitter_consumer_key(self) -> str | None:
return self.__admin_meta.get('twitter_consumer_key') return self.__admin_meta.get("twitter_consumer_key")
@property @property
def twitter_consumer_secret(self) -> str | None: def twitter_consumer_secret(self) -> str | None:
return self.__admin_meta.get('twitter_consumer_secret') return self.__admin_meta.get("twitter_consumer_secret")
@property @property
def github_client_id(self) -> str | None: def github_client_id(self) -> str | None:
return self.__admin_meta.get('github_client_id') return self.__admin_meta.get("github_client_id")
@property @property
def github_client_secret(self) -> str | None: def github_client_secret(self) -> str | None:
return self.__admin_meta.get('github_client_secret') return self.__admin_meta.get("github_client_secret")
@property @property
def discord_client_id(self) -> str | None: def discord_client_id(self) -> str | None:
return self.__admin_meta.get('discord_client_id') return self.__admin_meta.get("discord_client_id")
@property @property
def discord_client_secret(self) -> str | None: def discord_client_secret(self) -> str | None:
return self.__admin_meta.get('discord_client_secret') return self.__admin_meta.get("discord_client_secret")
@property @property
def email(self) -> str | None: def email(self) -> str | None:
return self.__admin_meta.get('email') return self.__admin_meta.get("email")
@property @property
def smtp_secure(self) -> bool: def smtp_secure(self) -> bool:
return self.__admin_meta.get('smtp_secure', False) return self.__admin_meta.get("smtp_secure", False)
@property @property
def smtp_host(self) -> str | None: def smtp_host(self) -> str | None:
return self.__admin_meta.get('smtp_host') return self.__admin_meta.get("smtp_host")
@property @property
def smtp_port(self) -> int | None: def smtp_port(self) -> int | None:
return self.__admin_meta.get('smtp_port') return self.__admin_meta.get("smtp_port")
@property @property
def smtp_user(self) -> str | None: def smtp_user(self) -> str | None:
return self.__admin_meta.get('smtp_user') return self.__admin_meta.get("smtp_user")
@property @property
def smtp_pass(self) -> str | None: def smtp_pass(self) -> str | None:
return self.__admin_meta.get('smtp_pass') return self.__admin_meta.get("smtp_pass")
@property @property
def sw_private_key(self) -> str | None: def sw_private_key(self) -> str | None:
return self.__admin_meta.get('sw_private_key') return self.__admin_meta.get("sw_private_key")
@property @property
def use_object_storage(self) -> bool: def use_object_storage(self) -> bool:
return self.__admin_meta.get('use_object_storage', False) return self.__admin_meta.get("use_object_storage", False)
@property @property
def object_storage_base_url(self) -> str | None: def object_storage_base_url(self) -> str | None:
return self.__admin_meta.get('object_storage_base_url') return self.__admin_meta.get("object_storage_base_url")
@property @property
def object_storage_bucket(self) -> str | None: def object_storage_bucket(self) -> str | None:
return self.__admin_meta.get('object_storage_bucket') return self.__admin_meta.get("object_storage_bucket")
@property @property
def object_storage_prefix(self) -> str | None: def object_storage_prefix(self) -> str | None:
return self.__admin_meta.get('object_storage_prefix') return self.__admin_meta.get("object_storage_prefix")
@property @property
def object_storage_endpoint(self) -> str | None: def object_storage_endpoint(self) -> str | None:
return self.__admin_meta.get('object_storage_endpoint') return self.__admin_meta.get("object_storage_endpoint")
@property @property
def object_storage_region(self) -> str | None: def object_storage_region(self) -> str | None:
return self.__admin_meta.get('object_storage_region') return self.__admin_meta.get("object_storage_region")
@property @property
def object_storage_port(self) -> int | None: def object_storage_port(self) -> int | None:
return self.__admin_meta.get('object_storage_port') return self.__admin_meta.get("object_storage_port")
@property @property
def object_storage_access_key(self) -> str | None: def object_storage_access_key(self) -> str | None:
return self.__admin_meta.get('object_storage_access_key') return self.__admin_meta.get("object_storage_access_key")
@property @property
def object_storage_secret_key(self) -> str | None: def object_storage_secret_key(self) -> str | None:
return self.__admin_meta.get('object_storage_secret_key') return self.__admin_meta.get("object_storage_secret_key")
@property @property
def object_storage_use_ssl(self) -> bool: def object_storage_use_ssl(self) -> bool:
return self.__admin_meta.get('object_storage_use_ssl', False) return self.__admin_meta.get("object_storage_use_ssl", False)
@property @property
def object_storage_use_proxy(self) -> bool: def object_storage_use_proxy(self) -> bool:
return self.__admin_meta.get('object_storage_use_proxy', False) return self.__admin_meta.get("object_storage_use_proxy", False)
@property @property
def object_storage_set_public_read(self) -> bool: def object_storage_set_public_read(self) -> bool:
return self.__admin_meta.get('object_storage_set_public_read', False) return self.__admin_meta.get("object_storage_set_public_read", False)
@property @property
def pinned_users(self) -> list[str]: def pinned_users(self) -> list[str]:
return self.__admin_meta.get('pinned_users', []) return self.__admin_meta.get("pinned_users", [])
""" """
v12 only v12 only
@ -302,36 +302,36 @@ class AdminMeta(MetaCommon):
@property @property
def hcaptcha_secret_key(self) -> str | None: def hcaptcha_secret_key(self) -> str | None:
return self.__admin_meta.get('hcaptcha_secret_key') return self.__admin_meta.get("hcaptcha_secret_key")
@property @property
def sensitive_media_detection(self) -> str | None: def sensitive_media_detection(self) -> str | None:
return self.__admin_meta.get('sensitive_media_detection') return self.__admin_meta.get("sensitive_media_detection")
@property @property
def sensitive_media_detection_sensitivity(self) -> str | None: def sensitive_media_detection_sensitivity(self) -> str | None:
return self.__admin_meta.get('sensitive_media_detection_sensitivity') return self.__admin_meta.get("sensitive_media_detection_sensitivity")
@property @property
def set_sensitive_flag_automatically(self) -> bool: def set_sensitive_flag_automatically(self) -> bool:
return self.__admin_meta.get('set_sensitive_flag_automatically', False) return self.__admin_meta.get("set_sensitive_flag_automatically", False)
@property @property
def enable_sensitive_media_detection_for_videos(self) -> bool: def enable_sensitive_media_detection_for_videos(self) -> bool:
return self.__admin_meta.get('enable_sensitive_media_detection_for_videos', False) return self.__admin_meta.get("enable_sensitive_media_detection_for_videos", False)
@property @property
def proxy_account_id(self) -> str | None: def proxy_account_id(self) -> str | None:
return self.__admin_meta.get('proxy_account_id') return self.__admin_meta.get("proxy_account_id")
@property @property
def summary_proxy(self) -> str | None: def summary_proxy(self) -> str | None:
return self.__admin_meta.get('summary_proxy') return self.__admin_meta.get("summary_proxy")
@property @property
def enable_ip_logging(self) -> bool: def enable_ip_logging(self) -> bool:
return self.__admin_meta.get('enable_ip_logging', False) return self.__admin_meta.get("enable_ip_logging", False)
@property @property
def enable_active_email_validation(self) -> bool: def enable_active_email_validation(self) -> bool:
return self.__admin_meta.get('enable_active_email_validation', False) return self.__admin_meta.get("enable_active_email_validation", False)

@ -16,19 +16,19 @@ class MuteUser:
@property @property
def id(self) -> str: def id(self) -> str:
return self.__data['id'] return self.__data["id"]
@property @property
def created_at(self) -> str: def created_at(self) -> str:
return self.__data['created_at'] return self.__data["created_at"]
@property @property
def mutee_id(self) -> str: def mutee_id(self) -> str:
return self.__data['mutee_id'] return self.__data["mutee_id"]
@property @property
def mutee(self) -> UserDetailed: def mutee(self) -> UserDetailed:
return UserDetailed(self.__data['mutee'], client=self.__client) return UserDetailed(self.__data["mutee"], client=self.__client)
def __eq__(self, __value: object) -> bool: def __eq__(self, __value: object) -> bool:
return isinstance(__value, IMuteUser) and self.id == __value.id return isinstance(__value, IMuteUser) and self.id == __value.id

@ -23,13 +23,13 @@ if TYPE_CHECKING:
from mipac.types.emoji import ICustomEmojiLite from mipac.types.emoji import ICustomEmojiLite
__all__ = ( __all__ = (
'NoteState', "NoteState",
'Note', "Note",
'Follow', "Follow",
'Header', "Header",
'NoteReaction', "NoteReaction",
'NoteDeleted', "NoteDeleted",
'NoteTranslateResult', "NoteTranslateResult",
) )
@ -39,15 +39,15 @@ class NoteState:
@property @property
def is_favorite(self) -> bool: def is_favorite(self) -> bool:
return self.__data['is_favorited'] return self.__data["is_favorited"]
@property @property
def is_watching(self) -> bool: def is_watching(self) -> bool:
return self.__data['is_watching'] return self.__data["is_watching"]
@property @property
def is_muted_thread(self) -> bool: def is_muted_thread(self) -> bool:
return self.__data.get('is_muted_thread', False) return self.__data.get("is_muted_thread", False)
class NoteDeleted: class NoteDeleted:
@ -56,11 +56,11 @@ class NoteDeleted:
@property @property
def note_id(self) -> str: def note_id(self) -> str:
return self.__data['body']['id'] return self.__data["body"]["id"]
@property @property
def deleted_at(self) -> datetime: def deleted_at(self) -> datetime:
return str_to_datetime(self.__data['body']['body']['deleted_at']) return str_to_datetime(self.__data["body"]["body"]["deleted_at"])
def __eq__(self, __value: object) -> bool: def __eq__(self, __value: object) -> bool:
return isinstance(__value, NoteDeleted) and self.note_id == __value.note_id return isinstance(__value, NoteDeleted) and self.note_id == __value.note_id
@ -71,12 +71,14 @@ class NoteDeleted:
class Follow: # TODO: 消す class Follow: # TODO: 消す
def __init__(self, data): def __init__(self, data):
self.id: str | None = data.get('id') self.id: str | None = data.get("id")
self.created_at: Optional[datetime] = datetime.strptime( self.created_at: Optional[datetime] = (
data['created_at'], '%Y-%m-%dT%H:%M:%S.%fZ' datetime.strptime(data["created_at"], "%Y-%m-%dT%H:%M:%S.%fZ")
) if data.get('created_at') else None if data.get("created_at")
self.type: str | None = data.get('type') else None
self.user: Optional[UserDetailed] = data.get('user') )
self.type: str | None = data.get("type")
self.user: Optional[UserDetailed] = data.get("user")
async def follow(self) -> tuple[bool, str | None]: async def follow(self) -> tuple[bool, str | None]:
""" """
@ -90,7 +92,7 @@ class Follow: # TODO: 消す
""" """
if self.id: if self.id:
raise NotExistRequiredData('user_idがありません') raise NotExistRequiredData("user_idがありません")
return await self._state.user.follow.add(user_id=self.id) return await self._state.user.follow.add(user_id=self.id)
async def unfollow(self, user_id: str | None = None) -> bool: async def unfollow(self, user_id: str | None = None) -> bool:
@ -115,12 +117,12 @@ class Follow: # TODO: 消す
class Header: class Header:
def __init__(self, data): def __init__(self, data):
self.id = data.get('id') self.id = data.get("id")
self.type = data.get('type') self.type = data.get("type")
class NoteReaction: class NoteReaction:
__slots__ = ('__reaction', '__client') __slots__ = ("__reaction", "__client")
def __init__(self, reaction: INoteReaction, *, client: ClientManager): def __init__(self, reaction: INoteReaction, *, client: ClientManager):
self.__reaction: INoteReaction = reaction self.__reaction: INoteReaction = reaction
@ -128,23 +130,23 @@ class NoteReaction:
@property @property
def id(self) -> str | None: def id(self) -> str | None:
return self.__reaction['id'] return self.__reaction["id"]
@property @property
def created_at(self) -> datetime | None: def created_at(self) -> datetime | None:
return ( return (
datetime.strptime(self.__reaction['created_at'], '%Y-%m-%dT%H:%M:%S.%fZ') datetime.strptime(self.__reaction["created_at"], "%Y-%m-%dT%H:%M:%S.%fZ")
if 'created_at' in self.__reaction if "created_at" in self.__reaction
else None else None
) )
@property @property
def type(self) -> str | None: def type(self) -> str | None:
return self.__reaction['type'] return self.__reaction["type"]
@property @property
def user(self) -> LiteUser: def user(self) -> LiteUser:
return LiteUser(self.__reaction['user'], client=self.__client) return LiteUser(self.__reaction["user"], client=self.__client)
def __eq__(self, __value: object) -> bool: def __eq__(self, __value: object) -> bool:
return isinstance(__value, NoteReaction) and self.id == __value.id return isinstance(__value, NoteReaction) and self.id == __value.id
@ -179,49 +181,49 @@ class Note(PartialNote[INote]):
List of emojis contained in note text List of emojis contained in note text
""" """
return self._note.get('emojis', []) return self._note.get("emojis", [])
@property @property
def renote(self) -> Self | None: def renote(self) -> Self | None:
return ( return (
Note(note=self._note['renote'], client=self._client) Note(note=self._note["renote"], client=self._client)
if 'renote' in self._note if "renote" in self._note
else None else None
) )
@property @property
def reply(self) -> Self | None: def reply(self) -> Self | None:
return ( return (
Note(note=self._note['reply'], client=self._client) if 'reply' in self._note else None Note(note=self._note["reply"], client=self._client) if "reply" in self._note else None
) )
@property @property
def visible_user_ids(self) -> list[str]: def visible_user_ids(self) -> list[str]:
return self._note['visible_user_ids'] if 'visible_user_ids' in self._note else [] return self._note["visible_user_ids"] if "visible_user_ids" in self._note else []
@property @property
def local_only(self) -> bool: def local_only(self) -> bool:
return self._note['local_only'] if 'local_only' in self._note else False return self._note["local_only"] if "local_only" in self._note else False
@property @property
def my_reaction(self) -> str | None: def my_reaction(self) -> str | None:
return self._note['my_reaction'] if 'my_reaction' in self._note else None return self._note["my_reaction"] if "my_reaction" in self._note else None
@property @property
def uri(self) -> str | None: def uri(self) -> str | None:
return self._note['uri'] if 'uri' in self._note else None return self._note["uri"] if "uri" in self._note else None
@property @property
def url(self) -> str | None: def url(self) -> str | None:
return self._note['url'] if 'url' in self._note else None return self._note["url"] if "url" in self._note else None
@property @property
def is_hidden(self) -> bool: def is_hidden(self) -> bool:
return self._note['is_hidden'] if 'is_hidden' in self._note else False return self._note["is_hidden"] if "is_hidden" in self._note else False
@property @property
def poll(self) -> Poll | None: def poll(self) -> Poll | None:
return Poll(self._note['poll'], client=self._client) if 'poll' in self._note else None return Poll(self._note["poll"], client=self._client) if "poll" in self._note else None
class NoteTranslateResult: class NoteTranslateResult:
@ -239,8 +241,8 @@ class NoteTranslateResult:
@property @property
def source_language(self) -> str: def source_language(self) -> str:
return self.__translate_result['sourceLang'] return self.__translate_result["sourceLang"]
@property @property
def text(self) -> str: def text(self) -> str:
return self.__translate_result['text'] return self.__translate_result["text"]

@ -20,25 +20,30 @@ if TYPE_CHECKING:
class Notification: class Notification:
def __init__(self, notification: INotification, *, client: ClientManager,) -> None: def __init__(
self,
notification: INotification,
*,
client: ClientManager,
) -> None:
self.__notification: INotification = notification self.__notification: INotification = notification
self.__client: ClientManager = client self.__client: ClientManager = client
@property @property
def id(self) -> str: def id(self) -> str:
return self.__notification['id'] return self.__notification["id"]
@property @property
def type(self) -> str: def type(self) -> str:
return self.__notification['type'] return self.__notification["type"]
@property @property
def created_at(self) -> datetime: def created_at(self) -> datetime:
return datetime.strptime(self.__notification['created_at'], '%Y-%m-%dT%H:%M:%S.%fZ') return datetime.strptime(self.__notification["created_at"], "%Y-%m-%dT%H:%M:%S.%fZ")
@property @property
def is_read(self) -> bool: def is_read(self) -> bool:
return self.__notification['is_read'] return self.__notification["is_read"]
def __eq__(self, __value: object) -> bool: def __eq__(self, __value: object) -> bool:
return isinstance(__value, Notification) and self.id == __value.id return isinstance(__value, Notification) and self.id == __value.id
@ -48,18 +53,26 @@ class Notification:
class NotificationFollow(Notification): class NotificationFollow(Notification):
def __init__(self, notification: IUserNf, *, client: ClientManager,) -> None: def __init__(
self,
notification: IUserNf,
*,
client: ClientManager,
) -> None:
super().__init__(notification, client=client) super().__init__(notification, client=client)
self.__notification: IUserNf = notification self.__notification: IUserNf = notification
self.__client: ClientManager = client self.__client: ClientManager = client
@property @property
def user(self) -> LiteUser: def user(self) -> LiteUser:
return LiteUser(self.__notification['user'], client=self.__client,) return LiteUser(
self.__notification["user"],
client=self.__client,
)
@property @property
def user_id(self) -> str: def user_id(self) -> str:
return self.__notification['user_id'] return self.__notification["user_id"]
@property @property
def api(self) -> FollowManager: def api(self) -> FollowManager:
@ -67,18 +80,26 @@ class NotificationFollow(Notification):
class NotificationFollowRequest(Notification): class NotificationFollowRequest(Notification):
def __init__(self, notification: IUserNf, *, client: ClientManager,) -> None: def __init__(
self,
notification: IUserNf,
*,
client: ClientManager,
) -> None:
super().__init__(notification, client=client) super().__init__(notification, client=client)
self.__notification: IUserNf = notification self.__notification: IUserNf = notification
self.__client: ClientManager = client self.__client: ClientManager = client
@property @property
def user(self) -> LiteUser: def user(self) -> LiteUser:
return LiteUser(self.__notification['user'], client=self.__client,) return LiteUser(
self.__notification["user"],
client=self.__client,
)
@property @property
def user_id(self) -> str: def user_id(self) -> str:
return self.__notification['user_id'] return self.__notification["user_id"]
@property @property
def api(self) -> FollowRequestManager: def api(self) -> FollowRequestManager:
@ -86,33 +107,52 @@ class NotificationFollowRequest(Notification):
class NotificationNote(Notification): class NotificationNote(Notification):
def __init__(self, notification: INoteNf, *, client: ClientManager,) -> None: def __init__(
self,
notification: INoteNf,
*,
client: ClientManager,
) -> None:
super().__init__(notification, client=client) super().__init__(notification, client=client)
self.__notification: INoteNf = notification self.__notification: INoteNf = notification
self.__client: ClientManager = client self.__client: ClientManager = client
@property @property
def user(self) -> LiteUser: def user(self) -> LiteUser:
return LiteUser(self.__notification['user'], client=self.__client,) return LiteUser(
self.__notification["user"],
client=self.__client,
)
@property @property
def user_id(self) -> str: def user_id(self) -> str:
return self.__notification['user_id'] return self.__notification["user_id"]
@property @property
def note(self) -> Note: def note(self) -> Note:
return Note(self.__notification['note'], client=self.__client,) return Note(
self.__notification["note"],
client=self.__client,
)
class NotificationPollEnd(Notification): class NotificationPollEnd(Notification):
def __init__(self, notification: IPollEndNf, *, client: ClientManager,) -> None: def __init__(
self,
notification: IPollEndNf,
*,
client: ClientManager,
) -> None:
super().__init__(notification, client=client) super().__init__(notification, client=client)
self.__notification: IPollEndNf = notification self.__notification: IPollEndNf = notification
self.__client: ClientManager = client self.__client: ClientManager = client
@property @property
def note(self) -> Note: def note(self) -> Note:
return Note(self.__notification['note'], client=self.__client,) return Note(
self.__notification["note"],
client=self.__client,
)
class NotificationReaction(Notification): class NotificationReaction(Notification):
@ -123,23 +163,28 @@ class NotificationReaction(Notification):
@property @property
def user(self) -> LiteUser: def user(self) -> LiteUser:
return LiteUser(self.__notification['user'], client=self.__client) return LiteUser(self.__notification["user"], client=self.__client)
@property @property
def note(self) -> Note: def note(self) -> Note:
return Note(self.__notification['note'], client=self.__client) return Note(self.__notification["note"], client=self.__client)
@property @property
def reaction(self) -> str: def reaction(self) -> str:
return self.__notification['reaction'] return self.__notification["reaction"]
class NotificationAchievement(Notification): class NotificationAchievement(Notification):
def __init__(self, notification: IAchievementNf, *, client: ClientManager,) -> None: def __init__(
self,
notification: IAchievementNf,
*,
client: ClientManager,
) -> None:
super().__init__(notification, client=client) super().__init__(notification, client=client)
self.__notification: IAchievementNf = notification self.__notification: IAchievementNf = notification
self.__client: ClientManager = client self.__client: ClientManager = client
@property @property
def achievement(self) -> str: def achievement(self) -> str:
return self.__notification['achievement'] return self.__notification["achievement"]

@ -10,10 +10,10 @@ if TYPE_CHECKING:
class MiPoll: class MiPoll:
def __init__(self, poll: ICreatePoll) -> None: def __init__(self, poll: ICreatePoll) -> None:
self.multiple = poll.get('multiple', False) self.multiple = poll.get("multiple", False)
self.choices = poll.get('choices') self.choices = poll.get("choices")
self.expired_after = poll.get('expired_after') self.expired_after = poll.get("expired_after")
self.expires_at = poll.get('expires_at') self.expires_at = poll.get("expires_at")
class PollChoice: class PollChoice:
@ -23,15 +23,15 @@ class PollChoice:
@property @property
def is_voted(self) -> bool: def is_voted(self) -> bool:
return self.__choice['is_voted'] return self.__choice["is_voted"]
@property @property
def text(self) -> str: def text(self) -> str:
return self.__choice['text'] return self.__choice["text"]
@property @property
def votes(self) -> int: def votes(self) -> int:
return self.__choice['votes'] return self.__choice["votes"]
class Poll: class Poll:
@ -41,16 +41,16 @@ class Poll:
@property @property
def multiple(self) -> bool: def multiple(self) -> bool:
return self.__poll['multiple'] return self.__poll["multiple"]
@property @property
def expires_at(self) -> int: def expires_at(self) -> int:
return self.__poll['expires_at'] return self.__poll["expires_at"]
@property @property
def expired_after(self) -> int: def expired_after(self) -> int:
return self.__poll['expired_after'] return self.__poll["expired_after"]
@property @property
def choices(self) -> list[PollChoice]: def choices(self) -> list[PollChoice]:
return [PollChoice(i, client=self.__client) for i in self.__poll['choices']] return [PollChoice(i, client=self.__client) for i in self.__poll["choices"]]

@ -18,12 +18,12 @@ class PartialReaction:
@property @property
def reaction(self) -> str: def reaction(self) -> str:
return self.__reaction['body']['body']['reaction'] return self.__reaction["body"]["body"]["reaction"]
@property @property
def emoji(self) -> PartialCustomEmoji: def emoji(self) -> PartialCustomEmoji:
return PartialCustomEmoji(self.__reaction['body']['body']['emoji'], client=self.__client) return PartialCustomEmoji(self.__reaction["body"]["body"]["emoji"], client=self.__client)
@property @property
def user_id(self) -> str: def user_id(self) -> str:
return self.__reaction['body']['body']['user_id'] return self.__reaction["body"]["body"]["user_id"]

@ -20,17 +20,17 @@ class RoleUser:
@property @property
def id(self) -> str: def id(self) -> str:
return self.__role_user['id'] return self.__role_user["id"]
@property @property
def user(self) -> LiteUser: def user(self) -> LiteUser:
return LiteUser(self.__role_user['user'], client=self.__client) return LiteUser(self.__role_user["user"], client=self.__client)
@property @property
def expires_at(self) -> datetime | None: def expires_at(self) -> datetime | None:
return ( return (
str_to_datetime(self.__role_user['expires_at']) str_to_datetime(self.__role_user["expires_at"])
if self.__role_user['expires_at'] if self.__role_user["expires_at"]
else None else None
) )
@ -51,15 +51,15 @@ class RolePolicyValue:
@property @property
def value(self) -> int: def value(self) -> int:
return self.__policy_value_data.get('value') return self.__policy_value_data.get("value")
@property @property
def use_default(self) -> bool: def use_default(self) -> bool:
return self.__policy_value_data.get('use_default') return self.__policy_value_data.get("use_default")
@property @property
def priority(self) -> int | None: def priority(self) -> int | None:
return self.__policy_value_data.get('priority') return self.__policy_value_data.get("priority")
class RolePolicies: class RolePolicies:
@ -68,67 +68,67 @@ class RolePolicies:
@property @property
def antenna_limit(self) -> RolePolicyValue: def antenna_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('antenna_limit')) return RolePolicyValue(self.__role_policies_data.get("antenna_limit"))
@property @property
def gtl_available(self) -> RolePolicyValue: def gtl_available(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('gtl_available')) return RolePolicyValue(self.__role_policies_data.get("gtl_available"))
@property @property
def ltl_available(self) -> RolePolicyValue: def ltl_available(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('ltl_available')) return RolePolicyValue(self.__role_policies_data.get("ltl_available"))
@property @property
def can_public_note(self) -> RolePolicyValue: def can_public_note(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('can_public_note')) return RolePolicyValue(self.__role_policies_data.get("can_public_note"))
@property @property
def drive_capacity_mb(self) -> RolePolicyValue: def drive_capacity_mb(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('drive_capacity_mb')) return RolePolicyValue(self.__role_policies_data.get("drive_capacity_mb"))
@property @property
def can_invite(self) -> RolePolicyValue: def can_invite(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('can_invite')) return RolePolicyValue(self.__role_policies_data.get("can_invite"))
@property @property
def can_manage_custom_emojis(self) -> RolePolicyValue: def can_manage_custom_emojis(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('can_manage_custom_emojis')) return RolePolicyValue(self.__role_policies_data.get("can_manage_custom_emojis"))
@property @property
def can_hide_ads(self) -> RolePolicyValue: def can_hide_ads(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('can_hide_ads')) return RolePolicyValue(self.__role_policies_data.get("can_hide_ads"))
@property @property
def pin_limit(self) -> RolePolicyValue: def pin_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('pin_limit')) return RolePolicyValue(self.__role_policies_data.get("pin_limit"))
@property @property
def word_mute_limit(self) -> RolePolicyValue: def word_mute_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('word_mute_limit')) return RolePolicyValue(self.__role_policies_data.get("word_mute_limit"))
@property @property
def webhook_limit(self) -> RolePolicyValue: def webhook_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('webhook_limit')) return RolePolicyValue(self.__role_policies_data.get("webhook_limit"))
@property @property
def clip_limit(self) -> RolePolicyValue: def clip_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('clip_limit')) return RolePolicyValue(self.__role_policies_data.get("clip_limit"))
@property @property
def note_each_clips_limit(self) -> RolePolicyValue: def note_each_clips_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('note_each_clips_limit')) return RolePolicyValue(self.__role_policies_data.get("note_each_clips_limit"))
@property @property
def user_list_limit(self) -> RolePolicyValue: def user_list_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('user_list_limit')) return RolePolicyValue(self.__role_policies_data.get("user_list_limit"))
@property @property
def user_each_user_lists_limit(self) -> RolePolicyValue: def user_each_user_lists_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('user_each_user_lists_limit')) return RolePolicyValue(self.__role_policies_data.get("user_each_user_lists_limit"))
@property @property
def rate_limit_factor(self) -> RolePolicyValue: def rate_limit_factor(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('rate_limit_factor')) return RolePolicyValue(self.__role_policies_data.get("rate_limit_factor"))
class Role: class Role:
@ -138,67 +138,67 @@ class Role:
@property @property
def id(self) -> str: def id(self) -> str:
return self.__role_data.get('id') return self.__role_data.get("id")
@property @property
def created_at(self) -> str: def created_at(self) -> str:
return self.__role_data.get('created_at') return self.__role_data.get("created_at")
@property @property
def updated_at(self) -> str: def updated_at(self) -> str:
return self.__role_data.get('updated_at') return self.__role_data.get("updated_at")
@property @property
def name(self) -> str: def name(self) -> str:
return self.__role_data.get('name') return self.__role_data.get("name")
@property @property
def description(self) -> str: def description(self) -> str:
return self.__role_data.get('description') return self.__role_data.get("description")
@property @property
def color(self) -> str | None: def color(self) -> str | None:
return self.__role_data.get('color') return self.__role_data.get("color")
@property @property
def icon_url(self) -> str | None: def icon_url(self) -> str | None:
return self.__role_data.get('icon_url') return self.__role_data.get("icon_url")
@property @property
def target(self) -> str: def target(self) -> str:
return self.__role_data.get('target') return self.__role_data.get("target")
@property @property
def cond_formula(self) -> dict: def cond_formula(self) -> dict:
return self.__role_data.get('cond_formula') return self.__role_data.get("cond_formula")
@property @property
def is_public(self) -> bool: def is_public(self) -> bool:
return self.__role_data.get('is_public') return self.__role_data.get("is_public")
@property @property
def is_administrator(self) -> bool: def is_administrator(self) -> bool:
return self.__role_data.get('is_administrator') return self.__role_data.get("is_administrator")
@property @property
def is_moderator(self) -> bool: def is_moderator(self) -> bool:
return self.__role_data.get('is_moderator') return self.__role_data.get("is_moderator")
@property @property
def as_badge(self) -> bool: def as_badge(self) -> bool:
return self.__role_data.get('as_badge') return self.__role_data.get("as_badge")
@property @property
def can_edit_members_by_moderator(self) -> bool: def can_edit_members_by_moderator(self) -> bool:
return self.__role_data.get('can_edit_members_by_moderator') return self.__role_data.get("can_edit_members_by_moderator")
@property @property
def policies(self) -> RolePolicies: def policies(self) -> RolePolicies:
return RolePolicies(self.__role_data.get('policies')) return RolePolicies(self.__role_data.get("policies"))
@property @property
def users_count(self) -> int: def users_count(self) -> int:
return self.__role_data.get('users_count') return self.__role_data.get("users_count")
@property @property
def api(self) -> AdminRolesModelManager: def api(self) -> AdminRolesModelManager:

@ -12,7 +12,7 @@ from mipac.utils.format import str_to_datetime
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
__all__ = ('UserDetailed', 'LiteUser', 'Achievement', 'BlockingUser') __all__ = ("UserDetailed", "LiteUser", "Achievement", "BlockingUser")
class BlockingUser: class BlockingUser:
@ -22,19 +22,19 @@ class BlockingUser:
@property @property
def id(self) -> str: def id(self) -> str:
return self.__blocking_user_data['id'] return self.__blocking_user_data["id"]
@property @property
def created_at(self) -> datetime: def created_at(self) -> datetime:
return str_to_datetime(self.__blocking_user_data['created_at']) return str_to_datetime(self.__blocking_user_data["created_at"])
@property @property
def blockee_id(self) -> str: def blockee_id(self) -> str:
return self.__blocking_user_data['blockee_id'] return self.__blocking_user_data["blockee_id"]
@property @property
def blockee(self) -> UserDetailed: def blockee(self) -> UserDetailed:
return UserDetailed(self.__blocking_user_data['blockee'], client=self.__client) return UserDetailed(self.__blocking_user_data["blockee"], client=self.__client)
def __eq__(self, __value: object) -> bool: def __eq__(self, __value: object) -> bool:
return isinstance(__value, BlockingUser) and self.id == __value.id return isinstance(__value, BlockingUser) and self.id == __value.id
@ -49,17 +49,17 @@ class Achievement:
@property @property
def name(self) -> str: def name(self) -> str:
return self.__detail['name'] return self.__detail["name"]
@property @property
def unlocked_at(self) -> int: def unlocked_at(self) -> int:
return self.__detail['unlocked_at'] return self.__detail["unlocked_at"]
class UserDetailed(LiteUser): class UserDetailed(LiteUser):
__slots__ = ( __slots__ = (
'__detail', "__detail",
'__client', "__client",
) )
def __init__(self, user: IUserDetailed, *, client: ClientManager): def __init__(self, user: IUserDetailed, *, client: ClientManager):
@ -68,164 +68,166 @@ class UserDetailed(LiteUser):
@property @property
def achievements(self) -> list[Achievement]: def achievements(self) -> list[Achievement]:
return [Achievement(i) for i in self.__detail.get('achievements', [])] 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"]
@property @property
def followers_count(self) -> int: def followers_count(self) -> int:
return self.__detail['followers_count'] return self.__detail["followers_count"]
@property @property
def following_count(self) -> int: def following_count(self) -> int:
return self.__detail['following_count'] return self.__detail["following_count"]
@property @property
def has_pending_follow_request_from_you(self) -> bool | None: def has_pending_follow_request_from_you(self) -> bool | None:
return self.__detail.get('has_pending_follow_request_from_you') return self.__detail.get("has_pending_follow_request_from_you")
@property @property
def has_pending_follow_request_to_you(self) -> bool | None: def has_pending_follow_request_to_you(self) -> bool | None:
return self.__detail.get('has_pending_follow_request_to_you') return self.__detail.get("has_pending_follow_request_to_you")
@property @property
def is_admin(self) -> bool: def is_admin(self) -> bool:
return self.__detail['is_admin'] return self.__detail["is_admin"]
@property @property
def is_blocked(self) -> bool | None: def is_blocked(self) -> bool | None:
return self.__detail.get('is_blocked') return self.__detail.get("is_blocked")
@property @property
def is_blocking(self) -> bool | None: def is_blocking(self) -> bool | None:
return self.__detail.get('is_blocking') return self.__detail.get("is_blocking")
@property @property
def is_bot(self) -> bool: def is_bot(self) -> bool:
return self.__detail['is_bot'] return self.__detail["is_bot"]
@property @property
def is_cat(self) -> bool: def is_cat(self) -> bool:
return self.__detail['is_cat'] return self.__detail["is_cat"]
@property @property
def is_followed(self) -> bool | None: def is_followed(self) -> bool | None:
return self.__detail.get('is_followed') return self.__detail.get("is_followed")
@property @property
def is_following(self) -> bool | None: def is_following(self) -> bool | None:
return self.__detail.get('is_following') return self.__detail.get("is_following")
@property @property
def is_locked(self) -> bool: def is_locked(self) -> bool:
return self.__detail['is_locked'] return self.__detail["is_locked"]
@property @property
def is_moderator(self) -> bool: def is_moderator(self) -> bool:
return self.__detail['is_moderator'] return self.__detail["is_moderator"]
@property @property
def is_muted(self) -> bool | None: def is_muted(self) -> bool | None:
return self.__detail.get('is_muted') return self.__detail.get("is_muted")
@property @property
def is_silenced(self) -> bool: def is_silenced(self) -> bool:
return self.__detail['is_silenced'] return self.__detail["is_silenced"]
@property @property
def is_suspended(self) -> bool: def is_suspended(self) -> bool:
return self.__detail['is_suspended'] return self.__detail["is_suspended"]
@property @property
def public_reactions(self) -> bool: def public_reactions(self) -> bool:
return self.__detail['public_reactions'] return self.__detail["public_reactions"]
@property @property
def security_keys(self) -> bool: def security_keys(self) -> bool:
return self.__detail['security_keys'] return self.__detail["security_keys"]
@property @property
def two_factor_enabled(self) -> bool: def two_factor_enabled(self) -> bool:
return self.__detail['two_factor_enabled'] return self.__detail["two_factor_enabled"]
@property @property
def notes_count(self) -> int: def notes_count(self) -> int:
return self.__detail['notes_count'] return self.__detail["notes_count"]
@property @property
def pinned_note_ids(self) -> list[str]: def pinned_note_ids(self) -> list[str]:
return self.__detail['pinned_note_ids'] return self.__detail["pinned_note_ids"]
@property @property
def pinned_notes(self) -> list[Note]: def pinned_notes(self) -> list[Note]:
return [Note(i, client=self.__client) for i in self.__detail['pinned_notes']] return [Note(i, client=self.__client) for i in self.__detail["pinned_notes"]]
@property @property
def banner_blurhash(self) -> str | None: def banner_blurhash(self) -> str | None:
return self.__detail.get('banner_blurhash') return self.__detail.get("banner_blurhash")
@property @property
def banner_color(self) -> str | None: def banner_color(self) -> str | None:
return self.__detail.get('banner_color') return self.__detail.get("banner_color")
@property @property
def banner_url(self) -> str | None: def banner_url(self) -> str | None:
return self.__detail.get('banner_url') return self.__detail.get("banner_url")
@property @property
def birthday(self) -> str | None: def birthday(self) -> str | None:
return self.__detail.get('birthday') return self.__detail.get("birthday")
@property @property
def created_at(self) -> str | None: def created_at(self) -> str | None:
return self.__detail.get('created_at') return self.__detail.get("created_at")
@property @property
def description(self) -> str | None: def description(self) -> str | None:
return self.__detail.get('description') return self.__detail.get("description")
@property @property
def ff_visibility(self,) -> Literal['public', 'followers', 'private'] | None: def ff_visibility(
return self.__detail.get('ff_visibility') self,
) -> Literal["public", "followers", "private"] | None:
return self.__detail.get("ff_visibility")
@property @property
def lang(self) -> str | None: def lang(self) -> str | None:
return self.__detail.get('lang') return self.__detail.get("lang")
@property @property
def last_fetched_at(self) -> str | None: def last_fetched_at(self) -> str | None:
return self.__detail.get('last_fetched_at') return self.__detail.get("last_fetched_at")
@property @property
def location(self) -> str | None: def location(self) -> str | None:
return self.__detail.get('location') return self.__detail.get("location")
@property @property
def logged_in_days(self) -> int | None: def logged_in_days(self) -> int | None:
return self.__detail.get('logged_in_days') 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")
@property @property
def pinned_page_id(self) -> str | None: def pinned_page_id(self) -> str | None:
return self.__detail.get('pinned_page_id') return self.__detail.get("pinned_page_id")
@property @property
def updated_at(self) -> str | None: def updated_at(self) -> str | None:
return self.__detail.get('updated_at') return self.__detail.get("updated_at")
@property @property
def uri(self) -> str | None: def uri(self) -> str | None:
return self.__detail.get('uri') return self.__detail.get("uri")
@property @property
def url(self) -> str | None: def url(self) -> str | None:
return self.__detail.get('url') return self.__detail.get("url")
@property @property
def use_password_less_login(self) -> bool | None: def use_password_less_login(self) -> bool | None:
return self.__detail.get('use_password_less_login') return self.__detail.get("use_password_less_login")

@ -1,78 +1,78 @@
from typing import Literal from typing import Literal
IT_ACHIEVEMENT_NAME = Literal[ IT_ACHIEVEMENT_NAME = Literal[
'notes1', "notes1",
'notes10', "notes10",
'notes100', "notes100",
'notes500', "notes500",
'notes1000', "notes1000",
'notes5000', "notes5000",
'notes10000', "notes10000",
'notes20000', "notes20000",
'notes30000', "notes30000",
'notes40000', "notes40000",
'notes50000', "notes50000",
'notes60000', "notes60000",
'notes70000', "notes70000",
'notes80000', "notes80000",
'notes90000', "notes90000",
'notes100000', "notes100000",
'login3', "login3",
'login7', "login7",
'login15', "login15",
'login30', "login30",
'login60', "login60",
'login100', "login100",
'login200', "login200",
'login300', "login300",
'login400', "login400",
'login500', "login500",
'login600', "login600",
'login700', "login700",
'login800', "login800",
'login900', "login900",
'login1000', "login1000",
'passedSinceAccountCreated1', "passedSinceAccountCreated1",
'passedSinceAccountCreated2', "passedSinceAccountCreated2",
'passedSinceAccountCreated3', "passedSinceAccountCreated3",
'loggedInOnBirthday', "loggedInOnBirthday",
'loggedInOnNewYearsDay', "loggedInOnNewYearsDay",
'noteClipped1', "noteClipped1",
'noteFavorited1', "noteFavorited1",
'myNoteFavorited1', "myNoteFavorited1",
'profileFilled', "profileFilled",
'markedAsCat', "markedAsCat",
'following1', "following1",
'following10', "following10",
'following50', "following50",
'following100', "following100",
'following300', "following300",
'followers1', "followers1",
'followers10', "followers10",
'followers50', "followers50",
'followers100', "followers100",
'followers300', "followers300",
'followers500', "followers500",
'followers1000', "followers1000",
'collectAchievements30', "collectAchievements30",
'viewAchievements3min', "viewAchievements3min",
'iLoveMisskey', "iLoveMisskey",
'foundTreasure', "foundTreasure",
'client30min', "client30min",
'client60min', "client60min",
'noteDeletedWithin1min', "noteDeletedWithin1min",
'postedAtLateNight', "postedAtLateNight",
'postedAt0min0sec', "postedAt0min0sec",
'selfQuote', "selfQuote",
'htl20npm', "htl20npm",
'viewInstanceChart', "viewInstanceChart",
'outputHelloWorldOnScratchpad', "outputHelloWorldOnScratchpad",
'open3windows', "open3windows",
'driveFolderCircularReference', "driveFolderCircularReference",
'reactWithoutRead', "reactWithoutRead",
'clickedClickHere', "clickedClickHere",
'justPlainLucky', "justPlainLucky",
'setNameToSyuilo', "setNameToSyuilo",
'cookieClicked', "cookieClicked",
'brainDiver', "brainDiver",
] ]

@ -15,8 +15,8 @@ class IAd(TypedDict):
starts_at: int starts_at: int
expires_at: int expires_at: int
url: str url: str
place: Literal['square' 'horizontal' 'horizontal-big'] place: Literal["square" "horizontal" "horizontal-big"]
priority: Literal['high' 'middle' 'low'] priority: Literal["high" "middle" "low"]
ratio: int ratio: int
image_url: str image_url: str
memo: str | None memo: str | None

@ -1,6 +1,6 @@
from typing import Literal, TypedDict from typing import Literal, TypedDict
IAntennaReceiveSource = Literal['home', 'all', 'users', 'list'] IAntennaReceiveSource = Literal["home", "all", "users", "list"]
class IAntenna(TypedDict): class IAntenna(TypedDict):

@ -1,10 +1,10 @@
from typing import TypedDict from typing import TypedDict
__all__ = ( __all__ = (
'IActiveUsersChart', "IActiveUsersChart",
'IDriveLocalChart', "IDriveLocalChart",
'IDriveRemoteChart', "IDriveRemoteChart",
'IDriveChart', "IDriveChart",
) )

@ -6,7 +6,7 @@ if TYPE_CHECKING:
from mipac.types import IDriveFile from mipac.types import IDriveFile
from mipac.types.user import ILiteUser from mipac.types.user import ILiteUser
__all__ = ('IChatGroup', 'IChatMessage') __all__ = ("IChatGroup", "IChatMessage")
class IChatGroup(TypedDict): class IChatGroup(TypedDict):

@ -2,7 +2,7 @@ from __future__ import annotations
from typing import Any, TypedDict from typing import Any, TypedDict
__all__ = ('IFileProperties', 'FolderPayload', 'IDriveFile') __all__ = ("IFileProperties", "FolderPayload", "IDriveFile")
class IFileProperties(TypedDict): class IFileProperties(TypedDict):

@ -1,6 +1,6 @@
from typing import Optional, TypedDict from typing import Optional, TypedDict
__all__ = ('EmojiPayload', 'ICustomEmojiLite', 'ICustomEmoji') __all__ = ("EmojiPayload", "ICustomEmojiLite", "ICustomEmoji")
class ICustomEmojiLiteRequired(TypedDict): class ICustomEmojiLiteRequired(TypedDict):

@ -6,9 +6,9 @@ from mipac.types.poll import IPoll
from mipac.types.reaction import IReactionAcceptance from mipac.types.reaction import IReactionAcceptance
from mipac.types.user import ILiteUser from mipac.types.user import ILiteUser
T = TypeVar('T') T = TypeVar("T")
INoteVisibility = Literal['public', 'home', 'followers', 'specified'] INoteVisibility = Literal["public", "home", "followers", "specified"]
class INoteState(TypedDict): class INoteState(TypedDict):
@ -18,7 +18,7 @@ class INoteState(TypedDict):
class INoteUpdated(TypedDict, Generic[T]): class INoteUpdated(TypedDict, Generic[T]):
type: Literal['noteUpdated'] type: Literal["noteUpdated"]
body: T body: T
@ -28,7 +28,7 @@ class INoteUpdatedDeleteBody(TypedDict):
class INoteUpdatedDelete(TypedDict): class INoteUpdatedDelete(TypedDict):
id: str id: str
type: Literal['deleted'] type: Literal["deleted"]
body: INoteUpdatedDeleteBody body: INoteUpdatedDeleteBody
@ -40,7 +40,7 @@ class INoteUpdatedReactionBody(TypedDict):
class INoteUpdatedReaction(TypedDict): class INoteUpdatedReaction(TypedDict):
id: str id: str
type: Literal['reacted', 'unreacted'] type: Literal["reacted", "unreacted"]
body: INoteUpdatedReactionBody body: INoteUpdatedReactionBody
@ -82,8 +82,8 @@ class INote(IPartialNote, total=False):
note object note object
""" """
renote: 'INote' renote: "INote"
reply: 'INote' reply: "INote"
visible_user_ids: list[str] visible_user_ids: list[str]
local_only: bool local_only: bool
my_reaction: str my_reaction: str

@ -9,13 +9,13 @@ if TYPE_CHECKING:
from mipac.types.drive import IFileProperties from mipac.types.drive import IFileProperties
__all__ = ( __all__ = (
'PageContentPayload', "PageContentPayload",
'VariablePayload', "VariablePayload",
'PageFilePayload', "PageFilePayload",
'EyeCatchingImagePayload', "EyeCatchingImagePayload",
'AttachedFilePayload', "AttachedFilePayload",
'PagePayload', "PagePayload",
'IPage', "IPage",
) )
@ -66,7 +66,7 @@ class PageContentPayload(TypedDict):
default: str | None default: str | None
value: Optional[list[Any]] value: Optional[list[Any]]
children: Optional['PageContentPayload'] children: Optional["PageContentPayload"]
class VariablePayload(TypedDict): class VariablePayload(TypedDict):

@ -1,6 +1,6 @@
from typing import TypedDict from typing import TypedDict
__all__ = ('IPoll', 'IPollChoice', 'ICreatePoll', 'IBasePoll') __all__ = ("IPoll", "IPollChoice", "ICreatePoll", "IBasePoll")
class IPollChoice(TypedDict): class IPollChoice(TypedDict):

@ -5,9 +5,9 @@ from typing import TYPE_CHECKING, Literal, TypedDict
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.types.user import ILiteUser from mipac.types.user import ILiteUser
__all__ = ('NoteReactionPayload',) __all__ = ("NoteReactionPayload",)
IReactionAcceptance = Literal['likeOnly', 'likeOnlyForRemote'] IReactionAcceptance = Literal["likeOnly", "likeOnlyForRemote"]
class NoteReactionPayload(TypedDict): class NoteReactionPayload(TypedDict):

@ -8,13 +8,13 @@ if TYPE_CHECKING:
from mipac.types.note import INote from mipac.types.note import INote
from mipac.types.page import IPage from mipac.types.page import IPage
__all__ = ( __all__ = (
'IFollowRequest', "IFollowRequest",
'IUserRequired', "IUserRequired",
'ILiteUser', "ILiteUser",
'IUserDetailed', "IUserDetailed",
'IUserDetailedField', "IUserDetailedField",
'IAchievement', "IAchievement",
'IBlockingUser', "IBlockingUser",
) )
@ -43,7 +43,7 @@ class IUserRequired(TypedDict):
id: str id: str
username: str username: str
name: str name: str
online_status: Literal['online', 'active', 'offline', 'unknown'] online_status: Literal["online", "active", "offline", "unknown"]
avatar_url: str avatar_url: str
avatar_blurhash: str avatar_blurhash: str
@ -94,7 +94,7 @@ class IUserDetailed(IUserDetailedRequired, total=False):
birthday: str birthday: str
created_at: str created_at: str
description: str description: str
ff_visibility: Literal['public', 'followers', 'private'] ff_visibility: Literal["public", "followers", "private"]
lang: str lang: str
last_fetched_at: str last_fetched_at: str
location: str location: str

@ -24,20 +24,20 @@ else:
HAS_ORJSON = True HAS_ORJSON = True
__all__ = ( __all__ = (
'deprecated', "deprecated",
'MiTime', "MiTime",
'get_cache_key', "get_cache_key",
'key_builder', "key_builder",
'check_multi_arg', "check_multi_arg",
'remove_list_empty', "remove_list_empty",
'remove_dict_empty', "remove_dict_empty",
'upper_to_lower', "upper_to_lower",
'str_lower', "str_lower",
'bool_to_string', "bool_to_string",
'_from_json', "_from_json",
'str_to_datetime', "str_to_datetime",
'convert_dict_keys_to_camel', "convert_dict_keys_to_camel",
'snake_to_camel', "snake_to_camel",
) )
@ -60,13 +60,13 @@ def deprecated(func):
@functools.wraps(func) @functools.wraps(func)
def new_func(*args, **kwargs): def new_func(*args, **kwargs):
warnings.simplefilter('always', DeprecationWarning) # turn off filter warnings.simplefilter("always", DeprecationWarning) # turn off filter
warnings.warn( warnings.warn(
'Call to deprecated function {}.'.format(func.__name__), "Call to deprecated function {}.".format(func.__name__),
category=DeprecationWarning, category=DeprecationWarning,
stacklevel=2, stacklevel=2,
) )
warnings.simplefilter('default', DeprecationWarning) # reset filter warnings.simplefilter("default", DeprecationWarning) # reset filter
return func(*args, **kwargs) return func(*args, **kwargs)
return new_func return new_func
@ -74,11 +74,11 @@ def deprecated(func):
@new_deprecated @new_deprecated
def snake_to_camel(snake_str: str, replace_list: dict[str, str]) -> str: def snake_to_camel(snake_str: str, replace_list: dict[str, str]) -> str:
components: list[str] = snake_str.split('_') components: list[str] = snake_str.split("_")
for i in range(len(components)): for i in range(len(components)):
if components[i] in replace_list: if components[i] in replace_list:
components[i] = replace_list[components[i]] components[i] = replace_list[components[i]]
return components[0] + ''.join(x.title() for x in components[1:]) return components[0] + "".join(x.title() for x in components[1:])
@new_deprecated @new_deprecated
@ -95,7 +95,7 @@ def convert_dict_keys_to_camel(
@new_deprecated @new_deprecated
def str_to_datetime(data: str, format: str = '%Y-%m-%dT%H:%M:%S.%fZ') -> datetime: def str_to_datetime(data: str, format: str = "%Y-%m-%dT%H:%M:%S.%fZ") -> datetime:
""" """
Parameters Parameters
---------- ----------
@ -152,7 +152,7 @@ class AuthClient:
MiAuthを使用するか MiAuthを使用するか
""" """
if permissions is None: if permissions is None:
permissions = ['read:account'] permissions = ["read:account"]
self.__client_session = aiohttp.ClientSession() self.__client_session = aiohttp.ClientSession()
self.__instance_uri: str = instance_uri self.__instance_uri: str = instance_uri
self.__name: str = name self.__name: str = name
@ -173,45 +173,45 @@ class AuthClient:
認証に使用するURL 認証に使用するURL
""" """
field = remove_dict_empty( field = remove_dict_empty(
{'name': self.__name, 'description': self.__description, 'icon': self.__icon} {"name": self.__name, "description": self.__description, "icon": self.__icon}
) )
if self.__use_miauth: if self.__use_miauth:
field['permissions'] = self.__permissions field["permissions"] = self.__permissions
query = urlencode(field) query = urlencode(field)
self.__session_token = uuid.uuid4() self.__session_token = uuid.uuid4()
return f'{self.__instance_uri}/miauth/{self.__session_token}?{query}' return f"{self.__instance_uri}/miauth/{self.__session_token}?{query}"
else: else:
field['permission'] = self.__permissions field["permission"] = self.__permissions
async with self.__client_session.post( async with self.__client_session.post(
f'{self.__instance_uri}/api/app/create', json=field f"{self.__instance_uri}/api/app/create", json=field
) as res: ) as res:
data = await res.json() data = await res.json()
self.__secret = data['secret'] self.__secret = data["secret"]
async with self.__client_session.post( async with self.__client_session.post(
f'{self.__instance_uri}/api/auth/session/generate', f"{self.__instance_uri}/api/auth/session/generate",
json={'appSecret': self.__secret}, json={"appSecret": self.__secret},
) as res: ) as res:
data = await res.json() data = await res.json()
self.__session_token = data['token'] self.__session_token = data["token"]
return data['url'] return data["url"]
async def wait_miauth(self) -> str: async def wait_miauth(self) -> str:
url = f'{self.__instance_uri}/api/miauth/{self.__session_token}/check' url = f"{self.__instance_uri}/api/miauth/{self.__session_token}/check"
while True: while True:
async with self.__client_session.post(url) as res: async with self.__client_session.post(url) as res:
data = await res.json() data = await res.json()
if data.get('ok') is True: if data.get("ok") is True:
return data return data
await asyncio.sleep(1) await asyncio.sleep(1)
async def wait_oldauth(self) -> None: async def wait_oldauth(self) -> None:
while True: while True:
async with self.__client_session.post( async with self.__client_session.post(
f'{self.__instance_uri}/api/auth/session/userkey', f"{self.__instance_uri}/api/auth/session/userkey",
json={'appSecret': self.__secret, 'token': self.__session_token}, json={"appSecret": self.__secret, "token": self.__session_token},
) as res: ) as res:
data = await res.json() data = await res.json()
if data.get('error', {}).get('code') != 'PENDING_SESSION': if data.get("error", {}).get("code") != "PENDING_SESSION":
break break
await asyncio.sleep(1) await asyncio.sleep(1)
@ -229,7 +229,7 @@ class AuthClient:
else: else:
data = await self.wait_oldauth() data = await self.wait_oldauth()
await self.__client_session.close() await self.__client_session.close()
return data['token'] if self.__use_miauth else data['accessToken'] return data["token"] if self.__use_miauth else data["accessToken"]
@new_deprecated @new_deprecated
@ -245,13 +245,13 @@ def set_cache(group: str, key: str, value: Any):
@new_deprecated @new_deprecated
def cache(group: str = 'default', override: bool = False): def cache(group: str = "default", override: bool = False):
def decorator(func): def decorator(func):
async def wrapper(self, *args, **kwargs): async def wrapper(self, *args, **kwargs):
ordered_kwargs = sorted(kwargs.items()) ordered_kwargs = sorted(kwargs.items())
key = '.{0}' + str(args) + str(ordered_kwargs) key = ".{0}" + str(args) + str(ordered_kwargs)
hit_item = DEFAULT_CACHE_VALUE.get(key) hit_item = DEFAULT_CACHE_VALUE.get(key)
if hit_item and override is False and kwargs.get('cache_override') is None: if hit_item and override is False and kwargs.get("cache_override") is None:
return hit_item return hit_item
res = await func(self, *args, **kwargs) res = await func(self, *args, **kwargs)
set_cache(group, key, res) set_cache(group, key, res)
@ -266,7 +266,7 @@ def cache(group: str = 'default', override: bool = False):
def get_cache_key(func): def get_cache_key(func):
async def decorator(self, *args, **kwargs): async def decorator(self, *args, **kwargs):
ordered_kwargs = sorted(kwargs.items()) ordered_kwargs = sorted(kwargs.items())
key = (func.__module__ or '') + '.{0}' + f'{self}' + str(args) + str(ordered_kwargs) key = (func.__module__ or "") + ".{0}" + f"{self}" + str(args) + str(ordered_kwargs)
return await func(self, *args, **kwargs, cache_key=key) return await func(self, *args, **kwargs, cache_key=key)
return decorator return decorator
@ -276,7 +276,7 @@ def get_cache_key(func):
def key_builder(func, cls, *args, **kwargs): def key_builder(func, cls, *args, **kwargs):
ordered_kwargs = sorted(kwargs.items()) ordered_kwargs = sorted(kwargs.items())
key = ( key = (
(func.__module__ or '') + f'.{func.__name__}' + f'{cls}' + str(args) + str(ordered_kwargs) (func.__module__ or "") + f".{func.__name__}" + f"{cls}" + str(args) + str(ordered_kwargs)
) )
return key return key
@ -365,12 +365,12 @@ def upper_to_lower(
if field is None: if field is None:
field = {} field = {}
for attr in data: for attr in data:
pattern = re.compile('[A-Z]') pattern = re.compile("[A-Z]")
large = [i.group().lower() for i in pattern.finditer(attr)] large = [i.group().lower() for i in pattern.finditer(attr)]
result = [None] * (len(large + pattern.split(attr))) result = [None] * (len(large + pattern.split(attr)))
result[::2] = pattern.split(attr) result[::2] = pattern.split(attr)
result[1::2] = ['_' + i.lower() for i in large] result[1::2] = ["_" + i.lower() for i in large]
default_key = ''.join(result) default_key = "".join(result)
if replace_list.get(attr): if replace_list.get(attr):
default_key = default_key.replace(attr, replace_list.get(attr)) default_key = default_key.replace(attr, replace_list.get(attr))
field[default_key] = data[attr] field[default_key] = data[attr]
@ -385,12 +385,12 @@ def upper_to_lower(
@new_deprecated @new_deprecated
def str_lower(text: str): def str_lower(text: str):
pattern = re.compile('[A-Z]') pattern = re.compile("[A-Z]")
large = [i.group().lower() for i in pattern.finditer(text)] large = [i.group().lower() for i in pattern.finditer(text)]
result = [None] * (len(large + pattern.split(text))) result = [None] * (len(large + pattern.split(text)))
result[::2] = pattern.split(text) result[::2] = pattern.split(text)
result[1::2] = ['_' + i.lower() for i in large] result[1::2] = ["_" + i.lower() for i in large]
return ''.join(result) return "".join(result)
@new_deprecated @new_deprecated
@ -407,4 +407,4 @@ def bool_to_string(boolean: bool) -> str:
true or false: str true or false: str
小文字になったbool文字列 小文字になったbool文字列
""" """
return 'true' if boolean else 'false' return "true" if boolean else "false"

@ -39,7 +39,7 @@ class AuthClient:
MiAuthを使用するか MiAuthを使用するか
""" """
if permissions is None: if permissions is None:
permissions = ['read:account'] permissions = ["read:account"]
self.__client_session = aiohttp.ClientSession() self.__client_session = aiohttp.ClientSession()
self.__instance_uri: str = instance_uri self.__instance_uri: str = instance_uri
self.__name: str = name self.__name: str = name
@ -60,45 +60,45 @@ class AuthClient:
認証に使用するURL 認証に使用するURL
""" """
field = remove_dict_empty( field = remove_dict_empty(
{'name': self.__name, 'description': self.__description, 'icon': self.__icon} {"name": self.__name, "description": self.__description, "icon": self.__icon}
) )
if self.__use_miauth: if self.__use_miauth:
field['permissions'] = self.__permissions field["permissions"] = self.__permissions
query = urlencode(field) query = urlencode(field)
self.__session_token = uuid.uuid4() self.__session_token = uuid.uuid4()
return f'{self.__instance_uri}/miauth/{self.__session_token}?{query}' return f"{self.__instance_uri}/miauth/{self.__session_token}?{query}"
else: else:
field['permission'] = self.__permissions field["permission"] = self.__permissions
async with self.__client_session.post( async with self.__client_session.post(
f'{self.__instance_uri}/api/app/create', json=field f"{self.__instance_uri}/api/app/create", json=field
) as res: ) as res:
data = await res.json() data = await res.json()
self.__secret = data['secret'] self.__secret = data["secret"]
async with self.__client_session.post( async with self.__client_session.post(
f'{self.__instance_uri}/api/auth/session/generate', f"{self.__instance_uri}/api/auth/session/generate",
json={'appSecret': self.__secret}, json={"appSecret": self.__secret},
) as res: ) as res:
data = await res.json() data = await res.json()
self.__session_token = data['token'] self.__session_token = data["token"]
return data['url'] return data["url"]
async def wait_miauth(self) -> str: async def wait_miauth(self) -> str:
url = f'{self.__instance_uri}/api/miauth/{self.__session_token}/check' url = f"{self.__instance_uri}/api/miauth/{self.__session_token}/check"
while True: while True:
async with self.__client_session.post(url) as res: async with self.__client_session.post(url) as res:
data = await res.json() data = await res.json()
if data.get('ok') is True: if data.get("ok") is True:
return data return data
await asyncio.sleep(1) await asyncio.sleep(1)
async def wait_oldauth(self) -> None: async def wait_oldauth(self) -> None:
while True: while True:
async with self.__client_session.post( async with self.__client_session.post(
f'{self.__instance_uri}/api/auth/session/userkey', f"{self.__instance_uri}/api/auth/session/userkey",
json={'appSecret': self.__secret, 'token': self.__session_token}, json={"appSecret": self.__secret, "token": self.__session_token},
) as res: ) as res:
data = await res.json() data = await res.json()
if data.get('error', {}).get('code') != 'PENDING_SESSION': if data.get("error", {}).get("code") != "PENDING_SESSION":
break break
await asyncio.sleep(1) await asyncio.sleep(1)
@ -116,4 +116,4 @@ class AuthClient:
else: else:
data = await self.wait_oldauth() data = await self.wait_oldauth()
await self.__client_session.close() await self.__client_session.close()
return data['token'] if self.__use_miauth else data['accessToken'] return data["token"] if self.__use_miauth else data["accessToken"]

@ -16,12 +16,12 @@ def set_cache(group: str, key: str, value: Any):
DEFAULT_CACHE_VALUE[key] = value DEFAULT_CACHE_VALUE[key] = value
def cache(group: str = 'default', override: bool = False): def cache(group: str = "default", override: bool = False):
def decorator(func): def decorator(func):
async def wrapper(self, *args, **kwargs): async def wrapper(self, *args, **kwargs):
key = cache_key_builder(func, self, *args, **kwargs) key = cache_key_builder(func, self, *args, **kwargs)
hit_item = DEFAULT_CACHE_VALUE.get(key) hit_item = DEFAULT_CACHE_VALUE.get(key)
if hit_item and override is False and kwargs.get('cache_override') is None: if hit_item and override is False and kwargs.get("cache_override") is None:
return hit_item return hit_item
res = await func(self, *args, **kwargs) res = await func(self, *args, **kwargs)
set_cache(group, key, res) set_cache(group, key, res)
@ -43,5 +43,5 @@ def get_cache_key(func):
@lru_cache @lru_cache
def cache_key_builder(func, cls, *args, **kwargs): def cache_key_builder(func, cls, *args, **kwargs):
ordered_kwargs = sorted(kwargs.items()) ordered_kwargs = sorted(kwargs.items())
key = (func.__module__ or '') + '.{0}' + f'{cls}' + str(args) + str(ordered_kwargs) key = (func.__module__ or "") + ".{0}" + f"{cls}" + str(args) + str(ordered_kwargs)
return key return key

@ -4,11 +4,11 @@ from typing import Any, Mapping
def snake_to_camel(snake_str: str, replace_list: dict[str, str]) -> str: def snake_to_camel(snake_str: str, replace_list: dict[str, str]) -> str:
components: list[str] = snake_str.split('_') components: list[str] = snake_str.split("_")
for i in range(len(components)): for i in range(len(components)):
if components[i] in replace_list: if components[i] in replace_list:
components[i] = replace_list[components[i]] components[i] = replace_list[components[i]]
return components[0] + ''.join(x.title() for x in components[1:]) return components[0] + "".join(x.title() for x in components[1:])
def convert_dict_keys_to_camel( def convert_dict_keys_to_camel(
@ -23,7 +23,7 @@ def convert_dict_keys_to_camel(
return new_dict return new_dict
def str_to_datetime(data: str, format: str = '%Y-%m-%dT%H:%M:%S.%fZ') -> datetime: def str_to_datetime(data: str, format: str = "%Y-%m-%dT%H:%M:%S.%fZ") -> datetime:
""" """
Parameters Parameters
---------- ----------
@ -103,12 +103,12 @@ def upper_to_lower(
if field is None: if field is None:
field = {} field = {}
for attr in data: for attr in data:
pattern = re.compile('[A-Z]') pattern = re.compile("[A-Z]")
large = [i.group().lower() for i in pattern.finditer(attr)] large = [i.group().lower() for i in pattern.finditer(attr)]
result = [None] * (len(large + pattern.split(attr))) result = [None] * (len(large + pattern.split(attr)))
result[::2] = pattern.split(attr) result[::2] = pattern.split(attr)
result[1::2] = ['_' + i.lower() for i in large] result[1::2] = ["_" + i.lower() for i in large]
default_key = ''.join(result) default_key = "".join(result)
if replace_list.get(attr): if replace_list.get(attr):
default_key = default_key.replace(attr, replace_list.get(attr)) default_key = default_key.replace(attr, replace_list.get(attr))
field[default_key] = data[attr] field[default_key] = data[attr]
@ -122,12 +122,12 @@ def upper_to_lower(
def str_lower(text: str): def str_lower(text: str):
pattern = re.compile('[A-Z]') pattern = re.compile("[A-Z]")
large = [i.group().lower() for i in pattern.finditer(text)] large = [i.group().lower() for i in pattern.finditer(text)]
result = [None] * (len(large + pattern.split(text))) result = [None] * (len(large + pattern.split(text)))
result[::2] = pattern.split(text) result[::2] = pattern.split(text)
result[1::2] = ['_' + i.lower() for i in large] result[1::2] = ["_" + i.lower() for i in large]
return ''.join(result) return "".join(result)
def bool_to_string(boolean: bool) -> str: def bool_to_string(boolean: bool) -> str:
@ -143,4 +143,4 @@ def bool_to_string(boolean: bool) -> str:
true or false: str true or false: str
小文字になったbool文字列 小文字になったbool文字列
""" """
return 'true' if boolean else 'false' return "true" if boolean else "false"

@ -1,14 +1,14 @@
import logging import logging
from typing import Literal from typing import Literal
LOGING_LEVEL_TYPE = Literal['NOTSET', 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'] LOGING_LEVEL_TYPE = Literal["NOTSET", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
LOGING_LEVELS = { LOGING_LEVELS = {
'NOTSET': 0, "NOTSET": 0,
'DEBUG': 10, "DEBUG": 10,
'INFO': 20, "INFO": 20,
'WARNING': 30, "WARNING": 30,
'ERROR': 40, "ERROR": 40,
'CRITICAL': 50, "CRITICAL": 50,
} }
@ -16,19 +16,19 @@ def setup_logging(
*, *,
handler: logging.Handler | None = None, handler: logging.Handler | None = None,
formatter: logging.Formatter | None = None, formatter: logging.Formatter | None = None,
level: LOGING_LEVEL_TYPE = 'INFO', level: LOGING_LEVEL_TYPE = "INFO",
) -> None: ) -> None:
if level not in LOGING_LEVELS: if level not in LOGING_LEVELS:
raise Exception(f'Not found logging level {level}') raise Exception(f"Not found logging level {level}")
_level = LOGING_LEVELS[level] _level = LOGING_LEVELS[level]
if handler is None: if handler is None:
handler = logging.StreamHandler() handler = logging.StreamHandler()
if formatter is None: if formatter is None:
dt_fmt = '%Y-%m-%d %H:%M:%S' dt_fmt = "%Y-%m-%d %H:%M:%S"
formatter = logging.Formatter( formatter = logging.Formatter(
'[{asctime}] [{levelname:<8}] {name}: {message}', dt_fmt, style='{' "[{asctime}] [{levelname:<8}] {name}: {message}", dt_fmt, style="{"
) )
logger = logging.getLogger() logger = logging.getLogger()
handler.setFormatter(formatter) handler.setFormatter(formatter)

@ -2,7 +2,7 @@ from typing import Any, Generic, Literal, TypeVar
from mipac.http import HTTPClient, Route from mipac.http import HTTPClient, Route
T = TypeVar('T') T = TypeVar("T")
class Pagination(Generic[T]): class Pagination(Generic[T]):
@ -14,7 +14,7 @@ class Pagination(Generic[T]):
auth: bool = True, auth: bool = True,
remove_none: bool = True, remove_none: bool = True,
lower: bool = True, lower: bool = True,
pagination_type: Literal['until', 'count'] = 'until', pagination_type: Literal["until", "count"] = "until",
can_use_limit: bool = True, can_use_limit: bool = True,
limit: int = 100, limit: int = 100,
max_limit: int = 100, max_limit: int = 100,
@ -25,18 +25,18 @@ class Pagination(Generic[T]):
self.auth: bool = auth self.auth: bool = auth
self.remove_none: bool = remove_none self.remove_none: bool = remove_none
self.lower: bool = lower self.lower: bool = lower
self.pagination_type: Literal['until', 'count'] = pagination_type self.pagination_type: Literal["until", "count"] = pagination_type
self.can_use_limit: bool = can_use_limit self.can_use_limit: bool = can_use_limit
self.limit: int = limit self.limit: int = limit
self.max_limit: int = max_limit self.max_limit: int = max_limit
self.count = 0 self.count = 0
self.next_id: str = '' self.next_id: str = ""
self.previous_id: str = '' self.previous_id: str = ""
self.latest_res_count: int = 0 self.latest_res_count: int = 0
async def next(self) -> list[T]: async def next(self) -> list[T]:
if self.pagination_type == 'count': if self.pagination_type == "count":
self.json['offset'] = self.json.get('limit', self.limit) * self.count self.json["offset"] = self.json.get("limit", self.limit) * self.count
self.count += 1 self.count += 1
res: list[T] = await self.http_client.request( res: list[T] = await self.http_client.request(
self.route, self.route,
@ -45,22 +45,22 @@ class Pagination(Generic[T]):
lower=self.lower, lower=self.lower,
json=self.json, json=self.json,
) )
if self.pagination_type == 'until': if self.pagination_type == "until":
self.previous_id = self.json.get('untilId', '') # 前のIDを保存しておく self.previous_id = self.json.get("untilId", "") # 前のIDを保存しておく
if len(res) > 0: if len(res) > 0:
self.next_id = res[-1]['id'] # type: ignore self.next_id = res[-1]["id"] # type: ignore
self.json['untilId'] = self.next_id self.json["untilId"] = self.next_id
self.latest_res_count = len(res) self.latest_res_count = len(res)
return res return res
@property @property
def is_final(self) -> bool: def is_final(self) -> bool:
if ( if (
self.pagination_type == 'count' self.pagination_type == "count"
and self.latest_res_count == 0 and self.latest_res_count == 0
or self.latest_res_count < self.max_limit or self.latest_res_count < self.max_limit
): ):
return True return True
if self.pagination_type == 'until' and self.latest_res_count == 0: if self.pagination_type == "until" and self.latest_res_count == 0:
return True return True
return False return False

@ -26,13 +26,13 @@ def deprecated(func):
@functools.wraps(func) @functools.wraps(func)
def new_func(*args, **kwargs): def new_func(*args, **kwargs):
warnings.simplefilter('always', DeprecationWarning) # turn off filter warnings.simplefilter("always", DeprecationWarning) # turn off filter
warnings.warn( warnings.warn(
'Call to deprecated function {}.'.format(func.__name__), "Call to deprecated function {}.".format(func.__name__),
category=DeprecationWarning, category=DeprecationWarning,
stacklevel=2, stacklevel=2,
) )
warnings.simplefilter('default', DeprecationWarning) # reset filter warnings.simplefilter("default", DeprecationWarning) # reset filter
return func(*args, **kwargs) return func(*args, **kwargs)
return new_func return new_func
@ -63,8 +63,8 @@ class MiTime:
class Colors: class Colors:
def __init__(self) -> None: def __init__(self) -> None:
self.green = '\x1b[92;1m' self.green = "\x1b[92;1m"
self.reset = '\x1b[0m' self.reset = "\x1b[0m"
COLORS = Colors() COLORS = Colors()

@ -1,6 +1,11 @@
[tool.black] [tool.black]
line-length = 99 line-length = 99
exclude = 'mipac/_version.py' extend-exclude = '''
(
_version.py
|endpoints.py
)
'''
[tool.isort] [tool.isort]

@ -13,7 +13,7 @@ with open('requirements.txt', 'r') as f:
requirements = f.read().splitlines() requirements = f.read().splitlines()
extras_require = { extras_require = {
'dev': ['axblack', 'isort', 'mypy', 'flake8', 'pre-commit', 'ruff'], 'dev': ['black', 'isort', 'mypy', 'flake8', 'pre-commit', 'ruff'],
'ci': ['flake8', 'mypy', 'ruff'], 'ci': ['flake8', 'mypy', 'ruff'],
'speed': ['orjson'], 'speed': ['orjson'],
'doc': ['sphinx', 'furo', 'sphinxcontrib_trio'], 'doc': ['sphinx', 'furo', 'sphinxcontrib_trio'],

Loading…
Cancel
Save