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
<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://app.fossa.com/projects/git%2Bgithub.com%2Fyupix%2FMiPAC?
ref=badge_shield" alt="FOSSA Status">
@ -62,10 +62,6 @@ MiPACの特徴として、v11,v12,v13のバージョンごとに生じる変更
MiPACのモデルでは多くの場合、キーワード引数に `client`を受け取り、それを用いて`api` プロパティを生成します。しかし、サポート途中の機能なのではそこが省かれ、リリース後にモデルのインスタンス化に必要な引数として `client` が追加されることがあります。また、他にもモデルの更新のために引数が変更される可能性があります。そのため、引数の変更に関することをCHANGELOG等で通知することはありません。
### 開発者向け情報
このプロジェクトでは [black](https://github.com/psf/black)のforkである、[axblack](https://github.com/axiros/axblack)を利用しています。主な違いはダブルクォートがデフォルトではなく、シングルクォートになっている点です
## LICENSE
準備中

@ -16,28 +16,28 @@ TOP_COMMENT = '''\"\"\"
IMPORTS = 'from typing import Literal\n\n'
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)
for path in api['paths']:
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)
for path in api['paths']:
PATHS.append(f'{PREFIX}{path}')
old_endpoints = []
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)
with open('./datas/endpoints.json', mode='w') as f:
with open('./datas/endpoints.json', mode='w', encoding='utf-8') as f:
removed_endpoints = []
for i in old_endpoints:
if i not in list(dict.fromkeys(PATHS)):
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)
old_endpoints.extend(PATHS)

@ -1,14 +1,14 @@
from ._version import get_versions
__title__ = 'mipac'
__author__ = 'yupix'
__license__ = 'MIT'
__copyright__ = 'Copyright 2022-present yupix'
__author_email__ = 'yupi0982@outlook.jp'
__version__ = get_versions()['version']
__title__ = "mipac"
__author__ = "yupix"
__license__ = "MIT"
__copyright__ = "Copyright 2022-present yupix"
__author_email__ = "yupi0982@outlook.jp"
__version__ = get_versions()["version"]
del get_versions
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
__path__ = __import__("pkgutil").extend_path(__path__, __name__)
from . import _version
from .abstract import * # noqa: F403, F401
@ -18,4 +18,4 @@ from .manager import *
from .models import * # noqa: F403, F401
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:
from mipac.manager.client import ClientManager
__all__ = ('AbstractAction',)
__all__ = ("AbstractAction",)
class AbstractAction(ABC):

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

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

@ -22,8 +22,8 @@ class AdminAdvertisingModelActions(AbstractAction):
async def update(
self,
url: str,
place: Literal['square', 'horizontal', 'horizontal-big'],
priority: Literal['high', 'middle', 'low'],
place: Literal["square", "horizontal", "horizontal-big"],
priority: Literal["high", "middle", "low"],
ratio: int,
image_url: str,
id: str | None = None,
@ -33,20 +33,20 @@ class AdminAdvertisingModelActions(AbstractAction):
) -> bool:
ad_id = self._ad_id or id
if ad_id is None:
raise ParameterError('ad_idは必須です')
raise ParameterError("ad_idは必須です")
data = {
'id': ad_id,
'url': url,
'memo': memo or '',
'place': place,
'priority': priority,
'ratio': ratio,
'startsAt': starts_at,
'expiresAt': expires_at,
'imageUrl': image_url,
"id": ad_id,
"url": url,
"memo": memo or "",
"place": place,
"priority": priority,
"ratio": ratio,
"startsAt": starts_at,
"expiresAt": expires_at,
"imageUrl": image_url,
}
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
@ -56,7 +56,7 @@ class AdminAdvertisingModelActions(AbstractAction):
ad_id = self._ad_id or id
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
@ -68,8 +68,8 @@ class AdminAdvertisingActions(AdminAdvertisingModelActions):
async def create(
self,
url: str,
place: Literal['square', 'horizontal', 'horizontal-big'],
priority: Literal['high', 'middle', 'low'],
place: Literal["square", "horizontal", "horizontal-big"],
priority: Literal["high", "middle", "low"],
ratio: int,
image_url: str,
starts_at: int = 0,
@ -80,17 +80,17 @@ class AdminAdvertisingActions(AdminAdvertisingModelActions):
raise NotSupportVersion(NotSupportVersionText)
data = {
'url': url,
'memo': memo or '',
'place': place,
'priority': priority,
'ratio': ratio,
'startsAt': starts_at,
'expiresAt': expires_at,
'imageUrl': image_url,
"url": url,
"memo": memo or "",
"place": place,
"priority": priority,
"ratio": ratio,
"startsAt": starts_at,
"expiresAt": expires_at,
"imageUrl": image_url,
}
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
@ -105,14 +105,14 @@ class AdminAdvertisingActions(AdminAdvertisingModelActions):
raise NotSupportVersion(NotSupportVersionText)
if limit > 100:
raise ParameterError('limitは100以下である必要があります')
raise ParameterError("limitは100以下である必要があります")
if get_all:
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:
raw_ads = await pagination.next()

@ -27,37 +27,40 @@ class AdminActions(AbstractAction):
async def get_meta(self, detail: bool = False) -> AdminMeta:
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)
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:
body = {'full': full, 'analyze': analyze}
body = {"full": full, "analyze": analyze}
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:
if config.use_version < 12:
raise NotSupportVersion('ご利用のインスタンスのバージョンではサポートされていない機能です')
body = {'userId': user_id, 'text': text}
raise NotSupportVersion("ご利用のインスタンスのバージョンではサポートされていない機能です")
body = {"userId": user_id, "text": text}
return bool(
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:
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(
await self.__session.request(
Route('POST', '/api/admin/update-meta'),
Route("POST", "/api/admin/update-meta"),
json=body,
auth=True,
lower=True,
@ -81,7 +84,7 @@ class AdminActions(AbstractAction):
return bool(
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(
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(
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(
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,
) -> AsyncGenerator[ModerationLog, None]:
if config.use_version < 12:
raise NotSupportVersion('ご利用のインスタンスのバージョンではサポートされていない機能です')
raise NotSupportVersion("ご利用のインスタンスのバージョンではサポートされていない機能です")
if limit > 100:
raise ParameterError('limit must be less than 100')
raise ParameterError("limit must be less than 100")
if get_all:
limit = 100
body = {'limit': limit, 'sinceId': since_id, 'untilId': until_id}
body = {"limit": limit, "sinceId": since_id, "untilId": until_id}
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:
@ -169,10 +172,10 @@ class AdminActions(AbstractAction):
for res_moderation_log in res_moderation_logs:
yield ModerationLog(res_moderation_log, client=self.__client)
@cache('server_info')
@cache("server_info")
async def get_server_info(self, **kwargs) -> ServerInfo:
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)
@ -180,21 +183,21 @@ class AdminActions(AbstractAction):
return await self.get_server_info(cache_override=True)
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(
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:
if config.use_version < 12:
raise NotSupportVersion('ご利用のインスタンスのバージョンではサポートされていない機能です')
raise NotSupportVersion("ご利用のインスタンスのバージョンではサポートされていない機能です")
body = {'reportId': report_id, 'forward': forward}
body = {"reportId": report_id, "forward": forward}
return bool(
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(
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]:
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]:
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]
async def get_user_ips(self, user_id: str) -> list[UserIP]:
if config.use_version < 12:
raise NotSupportVersion('ご利用のインスタンスのバージョンではサポートされていない機能です')
raise NotSupportVersion("ご利用のインスタンスのバージョンではサポートされていない機能です")
res: list[IUserIP] = await self.__session.request(
Route('POST', '/api/admin/get-user-ips'),
Route("POST", "/api/admin/get-user-ips"),
auth=True,
json={'userId': user_id},
json={"userId": user_id},
lower=True,
)
return [UserIP(i) for i in res]
async def show_user(self, user_id: str) -> UserDetailed:
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)
@ -247,21 +250,21 @@ class AdminActions(AbstractAction):
limit: int = 10,
offset: int = 0,
sort: str | None = None,
state: str = 'all',
origin: str = 'combined',
state: str = "all",
origin: str = "combined",
username: str | None = None,
hostname: str | None = None,
) -> list[UserDetailed]:
body = {
'limit': limit,
'offset': offset,
'sort': sort,
'state': state,
'origin': origin,
'username': username,
'hostname': hostname,
"limit": limit,
"offset": offset,
"sort": sort,
"state": state,
"origin": origin,
"username": username,
"hostname": hostname,
}
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]

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

@ -28,7 +28,7 @@ class AdminEmojiActions(AbstractAction):
name: str | None = None,
url: str | None = None,
category: str | None = None,
aliases: list[str] | None = None
aliases: list[str] | None = None,
) -> bool:
"""絵文字を追加します
@ -57,20 +57,23 @@ class AdminEmojiActions(AbstractAction):
"""
if self.__client._config.use_version >= 12:
data = {'fileId': file_id}
data = {"fileId": file_id}
else:
data = {
'name': name,
'url': url,
'category': category,
'aliases': aliases,
"name": name,
"url": url,
"category": category,
"aliases": aliases,
}
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(
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,
until_id: str | None = None,
*,
get_all: bool = True
get_all: bool = True,
) -> AsyncGenerator[CustomEmoji, None]:
if limit > 100:
raise ParameterError('limitは100以下である必要があります')
raise ParameterError("limitは100以下である必要があります")
if get_all:
limit = 100
body = {
'query': query,
'limit': limit,
'sinceId': since_id,
'untilId': until_id,
"query": query,
"limit": limit,
"sinceId": since_id,
"untilId": until_id,
}
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:
@ -115,23 +118,23 @@ class AdminEmojiActions(AbstractAction):
since_id: str | None = None,
until_id: str | None = None,
*,
get_all: bool = True
get_all: bool = True,
) -> AsyncGenerator[CustomEmoji, None]:
if limit > 100:
raise ParameterError('limitは100以下である必要があります')
raise ParameterError("limitは100以下である必要があります")
if get_all:
limit = 100
body = {
'query': query,
'host': host,
'limit': limit,
'sinceId': since_id,
'untilId': until_id,
"query": query,
"host": host,
"limit": limit,
"sinceId": since_id,
"untilId": until_id,
}
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:
@ -143,9 +146,9 @@ class AdminEmojiActions(AbstractAction):
break
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(
Route('POST', '/api/admin/emoji/set-license-bulk'),
Route("POST", "/api/admin/emoji/set-license-bulk"),
auth=True,
json=body,
remove_none=False, # remove_noneをFalseにしないとlisenceが消せなくなる
@ -174,16 +177,19 @@ class AdminEmojiActions(AbstractAction):
emoji_id = emoji_id or self.__emoji_id
if emoji_id is None:
raise NotExistRequiredData('idが不足しています')
raise NotExistRequiredData("idが不足しています")
endpoint = (
'/api/admin/emoji/delete'
"/api/admin/emoji/delete"
if self.__client._config.use_version >= 12
else '/api/admin/emoji/remove'
else "/api/admin/emoji/remove"
)
return bool(
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
data = {'userId': user_id}
data = {"userId": user_id}
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)
@ -53,8 +56,11 @@ class AdminModeratorActions(AbstractAction):
成功したか否か
"""
user_id = user_id or self.__user_id
data = {'userId': user_id}
data = {"userId": user_id}
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)

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

@ -32,9 +32,12 @@ class AdminUserActions(AbstractAction):
user_id = user_id or self.__user_id
data = {'userId': user_id}
data = {"userId": user_id}
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)
@ -53,9 +56,12 @@ class AdminUserActions(AbstractAction):
"""
user_id = user_id or self.__user_id
data = {'userId': user_id}
data = {"userId": user_id}
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)
@ -75,9 +81,12 @@ class AdminUserActions(AbstractAction):
"""
user_id = user_id or self.__user_id
data = {'userId': user_id}
data = {"userId": user_id}
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)
@ -97,8 +106,11 @@ class AdminUserActions(AbstractAction):
"""
user_id = user_id or self.__user_id
data = {'userId': user_id}
data = {"userId": user_id}
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)

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

@ -21,14 +21,14 @@ class BlockingActions(AbstractAction):
async def add(self, user_id: str | None = None) -> UserDetailed:
user_id = self.__user_id or user_id
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)
async def remove(self, user_id: str | None = None) -> UserDetailed:
user_id = self.__user_id or user_id
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)
@ -42,10 +42,10 @@ class BlockingActions(AbstractAction):
if get_all:
limit = 100
data = {'limit': limit, 'sinceId': since_id, 'untilId': until_id}
data = {"limit": limit, "sinceId": since_id, "untilId": until_id}
pagination = Pagination[IBlockingUser](
self.__session, Route('POST', '/api/blocking/list'), json=data
self.__session, Route("POST", "/api/blocking/list"), json=data
)
while True:

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

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

@ -48,11 +48,14 @@ class BaseChatAction(AbstractAction):
raise NotSupportVersion(NotSupportVersionText)
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
body = {'messageId': message_id}
body = {"messageId": message_id}
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
@ -77,12 +80,14 @@ class BaseChatAction(AbstractAction):
raise NotSupportVersion(NotSupportVersionText)
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
body = {'messageId': f'{message_id}'}
body = {"messageId": f"{message_id}"}
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)
@ -125,11 +130,11 @@ class ChatAction(BaseChatAction):
raise NotSupportVersion(NotSupportVersionText)
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(
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]
@ -162,12 +167,15 @@ class ChatAction(BaseChatAction):
raise NotSupportVersion(NotSupportVersionText)
user_id = user_id or self.__user_id
data = {
'userId': user_id,
'groupId': group_id,
'text': text,
'fileId': file_id,
"userId": user_id,
"groupId": group_id,
"text": text,
"fileId": file_id,
}
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)

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

@ -52,18 +52,18 @@ class ClientClipActions(AbstractAction):
clip_id = self._clip_id or clip_id
if clip_id is None:
raise ParameterError('clip_id is required')
raise ParameterError("clip_id is required")
if limit > 100:
raise ParameterError('limit must be less than 100')
raise ParameterError("limit must be less than 100")
if get_all:
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](
self._session, Route('POST', '/api/clips/notes'), json=body, auth=True
self._session, Route("POST", "/api/clips/notes"), json=body, auth=True
)
while True:
@ -92,11 +92,11 @@ class ClientClipActions(AbstractAction):
clip_id = self._clip_id or clip_id
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(
Route('POST', '/api/clips/add-note'), json=body, auth=True
Route("POST", "/api/clips/add-note"), json=body, auth=True
)
return result
@ -118,11 +118,11 @@ class ClientClipActions(AbstractAction):
clip_id = self._clip_id or clip_id
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(
Route('POST', '/api/clips/remove-note'), json=body, auth=True
Route("POST", "/api/clips/remove-note"), json=body, auth=True
)
return result
@ -142,11 +142,11 @@ class ClientClipActions(AbstractAction):
clip_id = self._clip_id or clip_id
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(
Route('POST', '/api/clips/delete'), json=body, auth=True
Route("POST", "/api/clips/delete"), json=body, auth=True
)
return result
@ -179,11 +179,11 @@ class ClientClipActions(AbstractAction):
clip_id = self._clip_id or clip_id
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(
Route('POST', '/api/clips/update'), json=body, auth=True
Route("POST", "/api/clips/update"), json=body, auth=True
)
return Clip(result, client=self._client)
@ -201,7 +201,7 @@ class ClipActions(ClientClipActions):
The favorite clips
"""
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]
@ -224,9 +224,9 @@ class ClipActions(ClientClipActions):
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(
Route('POST', '/api/clips/create'), json=body, auth=True
Route("POST", "/api/clips/create"), json=body, auth=True
)
return Clip(clip, client=self._client)
@ -239,7 +239,7 @@ class ClipActions(ClientClipActions):
The clips
"""
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]
@ -256,8 +256,8 @@ class ClipActions(ClientClipActions):
Clip
The clip
"""
body = {'clipId': clip_id}
body = {"clipId": clip_id}
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)

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

@ -21,6 +21,6 @@ class EmojiActions(AbstractAction):
if self.__client._config.use_version < 13:
raise NotSupportVersion(NotSupportVersionText)
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)

@ -18,18 +18,22 @@ class FavoriteActions(AbstractAction):
async def add(self, note_id: str | None = None) -> bool:
note_id = note_id or self.__note_id
data = {'noteId': note_id}
data = {"noteId": note_id}
return bool(
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:
note_id = note_id or self.__note_id
data = {'noteId': note_id}
data = {"noteId": note_id}
return bool(
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]:
return dict(
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
) -> FederationInstance:
# 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(
Route('POST', '/api/ap/show'), auth=True, json=body
Route("POST", "/api/ap/show"), auth=True, json=body
)
return res
@ -47,17 +47,16 @@ class FederationActions(AbstractAction):
limit: int = 10,
get_all: bool = False,
):
if limit > 100:
raise ParameterError('limitは100以下である必要があります')
raise ParameterError("limitは100以下である必要があります")
if get_all:
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](
self.__session, Route('POST', '/api/federation/followers'), json=body
self.__session, Route("POST", "/api/federation/followers"), json=body
)
while True:
@ -76,17 +75,16 @@ class FederationActions(AbstractAction):
limit: int = 10,
get_all: bool = False,
):
if limit > 100:
raise ParameterError('limitは100以下である必要があります')
raise ParameterError("limitは100以下である必要があります")
if get_all:
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](
self.__session, Route('POST', '/api/federation/following'), json=body
self.__session, Route("POST", "/api/federation/following"), json=body
)
while True:
@ -111,31 +109,31 @@ class FederationActions(AbstractAction):
sort: str | None = None,
) -> list[FederationInstance]:
if limit > 100:
raise ParameterError('limitは100以下である必要があります')
raise ParameterError("limitは100以下である必要があります")
body = {
'host': host,
'blocked': blocked,
'notResponding': not_responding,
'suspended': suspended,
'federating': federating,
'subscribing': subscribing,
'publishing': publishing,
'limit': limit,
'offset': offset,
'sort': sort,
"host": host,
"blocked": blocked,
"notResponding": not_responding,
"suspended": suspended,
"federating": federating,
"subscribing": subscribing,
"publishing": publishing,
"limit": limit,
"offset": offset,
"sort": sort,
}
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]
async def show_instance(self, host: str) -> FederationInstance:
res: IFederationInstance = await self.__session.request(
Route('POST', '/api/federation/show-instance'),
Route("POST", "/api/federation/show-instance"),
auth=True,
json={'host': host},
json={"host": host},
lower=True,
)
@ -144,9 +142,9 @@ class FederationActions(AbstractAction):
async def update_remote_user(self, user_id: str) -> bool:
return bool(
self.__session.request(
Route('POST', '/api/federation/update-remote-user'),
Route("POST", "/api/federation/update-remote-user"),
auth=True,
json={'userId': user_id},
json={"userId": user_id},
)
)
@ -159,15 +157,15 @@ class FederationActions(AbstractAction):
get_all: bool = False,
) -> AsyncGenerator[UserDetailed, None]:
if limit > 100:
raise ParameterError('limitは100以下である必要があります')
raise ParameterError("limitは100以下である必要があります")
if get_all:
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](
self.__session, Route('POST', '/api/federation/users'), json=body
self.__session, Route("POST", "/api/federation/users"), json=body
)
while True:
@ -180,8 +178,8 @@ class FederationActions(AbstractAction):
async def get_stats(self, limit: int = 10) -> IFederationInstanceStat:
if limit > 100:
raise ParameterError('limitは100以下である必要があります')
raise ParameterError("limitは100以下である必要があります")
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

@ -32,9 +32,12 @@ class FollowActions(AbstractAction):
user_id = user_id or self.__user_id
data = {'userId': user_id}
data = {"userId": user_id}
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)
@ -50,9 +53,9 @@ class FollowActions(AbstractAction):
user_id = user_id or self.__user_id
data = {'userId': user_id}
data = {"userId": user_id}
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)
@ -68,9 +71,9 @@ class FollowActions(AbstractAction):
user_id = user_id or self.__user_id
data = {'userId': user_id}
data = {"userId": user_id}
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)
@ -92,7 +95,9 @@ class FollowRequestActions(AbstractAction):
"""
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]
@ -113,10 +118,12 @@ class FollowRequestActions(AbstractAction):
user_id = user_id or self.__user_id
data = {'userId': user_id}
data = {"userId": user_id}
return bool(
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
data = {'userId': user_id}
data = {"userId": user_id}
return bool(
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
data = {'userId': user_id}
data = {"userId": user_id}
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)

@ -36,9 +36,9 @@ class MuteActions(AbstractAction):
"""
user_id = user_id or self._user_id
data = {'userId': user_id}
data = {"userId": user_id}
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
@ -58,9 +58,9 @@ class MuteActions(AbstractAction):
"""
user_id = user_id or self._user_id
data = {'userId': user_id}
data = {"userId": user_id}
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
@ -72,15 +72,15 @@ class MuteActions(AbstractAction):
get_all: bool = True,
) -> AsyncGenerator[MuteUser, None]:
if limit > 100:
raise ParameterError('limit は100以下である必要があります')
raise ParameterError("limit は100以下である必要があります")
if get_all:
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](
self._session, Route('POST', '/api/mute/list'), json=body
self._session, Route("POST", "/api/mute/list"), json=body
)
while True:

@ -20,7 +20,9 @@ class MyActions(AbstractAction):
async def fetch_follow_requests(self) -> list[FollowRequest]:
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]
@ -45,6 +47,6 @@ class MyActions(AbstractAction):
if self.__client._config.use_version < 13:
raise NotSupportVersion(NotSupportVersionText)
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

@ -20,12 +20,12 @@ from mipac.utils.util import check_multi_arg
if TYPE_CHECKING:
from mipac.client import ClientManager
__all__ = ['NoteActions']
__all__ = ["NoteActions"]
def create_note_body(
content: str | None = None,
visibility: INoteVisibility = 'public',
visibility: INoteVisibility = "public",
visible_user_ids: list[str] | None = None,
cw: str | None = None,
local_only: bool = False,
@ -40,31 +40,31 @@ def create_note_body(
):
content = content or None
body = {
'visibility': visibility,
'visibleUserIds': visible_user_ids,
'text': content,
'cw': cw,
'localOnly': local_only,
'noExtractMentions': not extract_mentions,
'noExtractHashtags': not extract_hashtags,
'noExtractEmojis': not extract_emojis,
'replyId': reply_id,
'renoteId': renote_id,
'channelId': channel_id,
"visibility": visibility,
"visibleUserIds": visible_user_ids,
"text": content,
"cw": cw,
"localOnly": local_only,
"noExtractMentions": not extract_mentions,
"noExtractHashtags": not extract_hashtags,
"noExtractEmojis": not extract_emojis,
"replyId": reply_id,
"renoteId": renote_id,
"channelId": channel_id,
}
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):
poll_data = remove_dict_empty(
{
'choices': poll.choices,
'multiple': poll.multiple,
'expiresAt': poll.expires_at,
'expiredAfter': poll.expired_after,
"choices": poll.choices,
"multiple": poll.multiple,
"expiresAt": poll.expires_at,
"expiredAfter": poll.expired_after,
}
)
body['poll'] = poll_data
body["poll"] = poll_data
if files:
file_ids = []
for file in files:
@ -75,15 +75,19 @@ def create_note_body(
elif isinstance(file, str):
file_ids.append(file)
else:
raise ParameterError('files must be MiFile or str or File')
body['fileIds'] = file_ids
raise ParameterError("files must be MiFile or str or File")
body["fileIds"] = file_ids
return remove_dict_empty(body)
class ClientNoteActions(AbstractAction):
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._session: HTTPClient = session
@ -106,11 +110,11 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id
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(
Route('POST', '/api/notes/unrenote'), auth=True, json=body
Route("POST", "/api/notes/unrenote"), auth=True, json=body
)
return res
@ -123,7 +127,7 @@ class ClientNoteActions(AbstractAction):
get_all: bool = True,
) -> AsyncGenerator[Note, None]:
if limit > 100:
raise ParameterError('limit は100以下である必要があります')
raise ParameterError("limit は100以下である必要があります")
if get_all:
limit = 100
@ -131,17 +135,17 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id
if note_id is None:
raise ParameterError('note_id is required')
raise ParameterError("note_id is required")
data = {
'noteId': note_id,
'limit': limit,
'sinceId': since_id,
'untilId': untilId,
"noteId": note_id,
"limit": limit,
"sinceId": since_id,
"untilId": untilId,
}
pagination = Pagination[INote](
self._session, Route('POST', '/api/notes/children'), json=data
self._session, Route("POST", "/api/notes/children"), json=data
)
while True:
@ -156,11 +160,11 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id
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(
Route('POST', '/api/notes/state'), auth=True, json=data
Route("POST", "/api/notes/state"), auth=True, json=data
)
return NoteState(res)
@ -186,11 +190,11 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id
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(
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]:
@ -211,11 +215,11 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id
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(
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]
@ -237,10 +241,10 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id
if note_id is None:
raise ParameterError('note_id is required')
raise ParameterError("note_id is required")
data = {'noteId': note_id}
res = await self._session.request(Route('POST', '/api/notes/delete'), json=data, auth=True)
data = {"noteId": note_id}
res = await self._session.request(Route("POST", "/api/notes/delete"), json=data, auth=True)
return bool(res)
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
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)
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]:
note_id = note_id or self._note_id
@ -278,7 +285,7 @@ class ClientNoteActions(AbstractAction):
async def reply(
self,
content: str | None = None,
visibility: INoteVisibility = 'public',
visibility: INoteVisibility = "public",
visible_user_ids: list[str] | None = None,
cw: str | None = None,
local_only: bool = False,
@ -292,7 +299,7 @@ class ClientNoteActions(AbstractAction):
reply_id = reply_id or self._note_id
if reply_id is None:
raise ParameterError('reply_id is required')
raise ParameterError("reply_id is required")
body = create_note_body(
content=content,
@ -308,14 +315,17 @@ class ClientNoteActions(AbstractAction):
files=files,
)
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(
self,
content: str | None = None,
visibility: INoteVisibility = 'public',
visibility: INoteVisibility = "public",
visible_user_ids: list[str] | None = None,
cw: str | None = None,
local_only: bool = False,
@ -358,7 +368,7 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id
if note_id is None:
raise ParameterError('note_id is required')
raise ParameterError("note_id is required")
body = create_note_body(
content=content,
@ -374,14 +384,19 @@ class ClientNoteActions(AbstractAction):
files=files,
)
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(
self, note_id: str | None = None, target_lang: str = 'en-US',
self,
note_id: str | None = None,
target_lang: str = "en-US",
) -> NoteTranslateResult:
"""
Translate a note
@ -401,15 +416,15 @@ class ClientNoteActions(AbstractAction):
note_id = note_id or self._note_id
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(
Route('POST', '/api/notes/translate'), json=data, auth=True
Route("POST", "/api/notes/translate"), json=data, auth=True
)
if isinstance(res, dict):
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(
self,
@ -440,18 +455,18 @@ class ClientNoteActions(AbstractAction):
"""
if limit > 100:
raise ParameterError('limitは100以下である必要があります')
raise ParameterError("limitは100以下である必要があります")
if get_all:
limit = 100
note_id = note_id or self._note_id
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:
res_notes = await pagination.next()
@ -464,14 +479,18 @@ class ClientNoteActions(AbstractAction):
class NoteActions(ClientNoteActions):
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)
async def send(
self,
content: str | None = None,
visibility: INoteVisibility = 'public',
visibility: INoteVisibility = "public",
visible_user_ids: list[str] | None = None,
cw: str | None = None,
local_only: bool = False,
@ -543,11 +562,14 @@ class NoteActions(ClientNoteActions):
reply_id=reply_id,
)
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:
"""
ノートを取得します
@ -563,14 +585,20 @@ class NoteActions(ClientNoteActions):
取得したートID
"""
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)
@cache(group='get_note', override=True)
@cache(group="get_note", override=True)
async def fetch(self, note_id: str) -> Note:
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)
@ -588,26 +616,26 @@ class NoteActions(ClientNoteActions):
get_all: bool = False,
) -> AsyncGenerator[Note, None]:
if limit > 100:
raise ParameterError('limit は100以下である必要があります')
raise ParameterError("limit は100以下である必要があります")
if get_all:
limit = 100
body = remove_dict_empty(
{
'local': local,
'reply': reply,
'renote': renote,
'withFiles': with_files,
'poll': poll,
'limit': limit,
'sinceId': since_id,
'untilId': until_id,
"local": local,
"reply": reply,
"renote": renote,
"withFiles": with_files,
"poll": poll,
"limit": limit,
"sinceId": since_id,
"untilId": until_id,
}
)
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:

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

@ -41,16 +41,16 @@ class ReactionActions(AbstractAction):
"""
note_id = note_id or self.__note_id
data = remove_dict_empty({'noteId': note_id, 'reaction': reaction})
route = Route('POST', '/api/notes/reactions/create')
data = remove_dict_empty({"noteId": note_id, "reaction": reaction})
route = Route("POST", "/api/notes/reactions/create")
res: bool = await self.__session.request(route, json=data, auth=True, lower=True)
return bool(res)
async def remove(self, note_id: str | None = None) -> bool:
note_id = note_id or self.__note_id
data = remove_dict_empty({'noteId': note_id})
route = Route('POST', '/api/notes/reactions/delete')
data = remove_dict_empty({"noteId": note_id})
route = Route("POST", "/api/notes/reactions/delete")
res: bool = await self.__session.request(route, json=data, auth=True, lower=True)
return bool(res)
@ -58,20 +58,23 @@ class ReactionActions(AbstractAction):
self, reaction: str, note_id: str | None = None, *, limit: int = 10
) -> list[NoteReaction]:
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(
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]
async def get_emoji_list(self) -> list[CustomEmoji]:
if config.use_version >= 13:
raise NotSupportVersion('Misskey v13以降では使用できません')
raise NotSupportVersion("Misskey v13以降では使用できません")
data: ILiteMeta = await self.__session.request(
Route('GET', '/api/meta'),
json={'detail': False},
Route("GET", "/api/meta"),
json={"detail": False},
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:
from mipac.manager.client import ClientManager
__all__ = ['UserActions']
__all__ = ["UserActions"]
class UserActions:
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.__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: 自分用のクラスに変更する
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:
return None
host = (
f'{protocol}://{self.__user.host}'
f"{protocol}://{self.__user.host}"
if external and self.__user.host
else self.__session._url
)
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
@cache(group='get_user')
@cache(group="get_user")
async def get(
self,
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(
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)
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:
"""
サーバーにアクセスしユーザーのプロフィールを取得します基本的には get_userをお使いください
@ -123,29 +135,29 @@ class UserActions:
get_all: bool = False,
) -> AsyncGenerator[Note, None]:
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
data = {
'userId': user_id,
'includeReplies': include_replies,
'limit': limit,
'sinceId': since_id,
'untilId': until_id,
'sinceDate': since_date,
'untilDate': until_date,
'includeMyRenotes': include_my_renotes,
'withFiles': with_files,
'fileType': file_type,
'excludeNsfw': exclude_nsfw,
"userId": user_id,
"includeReplies": include_replies,
"limit": limit,
"sinceId": since_id,
"untilId": until_id,
"sinceDate": since_date,
"untilDate": until_date,
"includeMyRenotes": include_my_renotes,
"withFiles": with_files,
"fileType": file_type,
"excludeNsfw": exclude_nsfw,
}
if get_all:
data['limit'] = 100
data["limit"] = 100
limit = 100
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:
@ -173,15 +185,15 @@ class UserActions:
user = user or self.__user
if user is None:
raise NotExistRequiredData('Required parameters: user')
return f'@{user.username}@{user.host}' if user.instance else f'@{user.username}'
raise NotExistRequiredData("Required parameters: user")
return f"@{user.username}@{user.host}" if user.instance else f"@{user.username}"
async def search(
self,
query: str,
limit: int = 100,
offset: int = 0,
origin: Literal['local', 'remote', 'combined'] = 'combined',
origin: Literal["local", "remote", "combined"] = "combined",
detail: bool = True,
*,
get_all: bool = False,
@ -211,17 +223,17 @@ class UserActions:
"""
if limit > 100:
raise ParameterError('limit は100以下である必要があります')
raise ParameterError("limit は100以下である必要があります")
if get_all:
limit = 100
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](
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:
@ -234,7 +246,11 @@ class UserActions:
break
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]:
"""
Search users by username and host.
@ -257,13 +273,13 @@ class UserActions:
"""
if limit > 100:
raise ParameterError('limit は100以下である必要があります')
raise ParameterError("limit は100以下である必要があります")
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(
Route('POST', '/api/users/search-by-username-and-host'),
Route("POST", "/api/users/search-by-username-and-host"),
lower=True,
auth=True,
json=body,
@ -279,18 +295,21 @@ class UserActions:
"""Get achievements of user."""
if config.use_version < 13:
raise NotSupportVersion('ご利用のインスタンスのバージョンではサポートされていない機能です')
raise NotSupportVersion("ご利用のインスタンスのバージョンではサポートされていない機能です")
user_id = user_id or self.__user and self.__user.id
if not user_id:
raise ParameterError('user_id is required')
raise ParameterError("user_id is required")
data = {
'userId': user_id,
"userId": user_id,
}
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]
@ -305,18 +324,18 @@ class UserActions:
user_id = user_id or self.__user and self.__user.id
if not user_id:
raise ParameterError('user_id is required')
raise ParameterError("user_id is required")
if limit > 100:
raise ParameterError('limit must be less than 100')
raise ParameterError("limit must be less than 100")
if get_all:
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](
self.__session, Route('POST', '/api/users/clips'), json=body, auth=True
self.__session, Route("POST", "/api/users/clips"), json=body, auth=True
)
while True:

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

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

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

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

@ -28,29 +28,29 @@ class _MissingSentinel:
return False
def __repr__(self):
return '...'
return "..."
MISSING: Any = _MissingSentinel()
R = TypeVar('R')
R = TypeVar("R")
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)
async def json_or_text(response: aiohttp.ClientResponse):
text = await response.text(encoding='utf-8')
text = await response.text(encoding="utf-8")
try:
if 'application/json' in response.headers['Content-Type']:
if "application/json" in response.headers["Content-Type"]:
return _from_json(text)
except KeyError:
pass
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.method: str = method
@ -58,7 +58,7 @@ class Route:
class HTTPClient:
def __init__(self, url: str, token: str | None = None) -> None:
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._session: aiohttp.ClientSession = MISSING
@ -78,23 +78,23 @@ class HTTPClient:
**kwargs,
) -> R:
headers: dict[str, str] = {
'User-Agent': self.user_agent,
"User-Agent": self.user_agent,
}
if 'json' in kwargs:
headers['Content-Type'] = 'application/json'
kwargs['json'] = kwargs.pop('json')
if "json" in kwargs:
headers["Content-Type"] = "application/json"
kwargs["json"] = kwargs.pop("json")
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):
kwargs[key] = {}
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:
kwargs[i] = remove_dict_empty(kwargs[i])
async with self._session.request(route.method, self._url + route.path, **kwargs) as res:
@ -105,12 +105,12 @@ class HTTPClient:
if isinstance(data, dict):
data = upper_to_lower(data)
_log.debug(
f'''{COLORS.green}
f"""{COLORS.green}
REQUEST:{COLORS.reset}
{kwargs}
{COLORS.green}RESPONSE:{COLORS.reset}
{json.dumps(data, ensure_ascii=False, indent=4) if data else data}
'''
"""
)
if res.status == 204 and data is None:
return True # type: ignore
@ -119,26 +119,27 @@ REQUEST:{COLORS.reset}
if 511 > res.status >= 300:
if isinstance(data, dict):
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:
await self._session.close()
async def login(self) -> IUserDetailed | None:
match_domain = re.search(r'https?:\/\/([^\/]+)', self._url)
match_protocol = re.search(r'^(http|https)', self._url)
match_domain = re.search(r"https?:\/\/([^\/]+)", self._url)
match_protocol = re.search(r"^(http|https)", self._url)
if match_domain is None or match_protocol is None:
raise Exception('Server URL cannot be retrieved or protocol (http / https) is missing')
protocol = True if match_protocol.group(1) == 'https' else False
raise Exception("Server URL cannot be retrieved or protocol (http / https) is missing")
protocol = True if match_protocol.group(1) == "https" else False
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)
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:
meta: IMeta = await self.request(Route('POST', '/api/meta'), auth=True)
use_version = int(meta['version'].split('.')[0])
meta: IMeta = await self.request(Route("POST", "/api/meta"), auth=True)
use_version = int(meta["version"].split(".")[0])
if isinstance(use_version, int) and use_version in (13, 12, 11):
config.use_version = use_version
return data

@ -9,7 +9,7 @@ from mipac.http import HTTPClient, Route
if TYPE_CHECKING:
from mipac.client import ClientManager
__all__ = ('AdminAdvertisingManager', 'AdminAdvertisingModelManager')
__all__ = ("AdminAdvertisingManager", "AdminAdvertisingModelManager")
class AdminAdvertisingModelManager(AbstractManager):
@ -39,20 +39,23 @@ class AdminAdvertisingManager(AbstractManager):
url: str,
memo: str,
place: str,
priority: Literal['high', 'middle', 'low'],
priority: Literal["high", "middle", "low"],
ratio: str,
expires_at: int,
image_url: str,
):
data = {
'url': url,
'memo': memo,
'place': place,
'priority': priority,
'ratio': ratio,
'expires_at': expires_at,
'image_url': image_url,
"url": url,
"memo": memo,
"place": place,
"priority": priority,
"ratio": ratio,
"expires_at": expires_at,
"image_url": image_url,
}
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
) -> 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:
from mipac.client import ClientManager
__all__ = ('AdminModeratorManager',)
__all__ = ("AdminModeratorManager",)
class AdminModeratorManager(AbstractManager):

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

@ -8,12 +8,14 @@ from mipac.http import HTTPClient
if TYPE_CHECKING:
from mipac.manager.client import ClientManager
__all__ = ('ChatManager',)
__all__ = ("ChatManager",)
class ChatManager:
def __init__(
self, session: HTTPClient, client: ClientManager,
self,
session: HTTPClient,
client: ClientManager,
):
self.__session: HTTPClient = session
self.__client: ClientManager = client
@ -26,12 +28,18 @@ class ChatManager:
self, user_id: str | None = None, message_id: str | None = None
) -> 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(
self, user_id: str | None = None, message_id: str | None = None
) -> 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
__all__ = ('ClientManager',)
__all__ = ("ClientManager",)
class ClientManager:
@ -38,10 +38,12 @@ class ClientManager:
self.chart: ChartManager = ChartManager(session=session, client=self)
self.channel: ChannelManager = ChannelManager(session=session, client=self)
self.follow: FollowManager = FollowManager(
session=session, client=self,
session=session,
client=self,
)
self.follow_request: FollowRequestManager = FollowRequestManager(
session=session, client=self,
session=session,
client=self,
)
self.clip: ClipManager = ClipManager(session=session, client=self)
self.emoji: EmojiManager = EmojiManager(session=session, client=self)

@ -12,7 +12,11 @@ if TYPE_CHECKING:
class ClientClipManager(AbstractManager):
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.__session = session
@ -20,7 +24,11 @@ class ClientClipManager(AbstractManager):
@property
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):

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

@ -26,5 +26,7 @@ class FavoriteManager(AbstractManager):
お気に入りに対するアクションを行うクラス
"""
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:
from mipac.client import ClientManager
__all__ = ('FollowManager', 'FollowRequestManager')
__all__ = ("FollowManager", "FollowRequestManager")
class FollowManager(AbstractManager):
@ -23,7 +23,11 @@ class FollowManager(AbstractManager):
@property
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):
@ -35,5 +39,7 @@ class FollowRequestManager(AbstractManager):
@property
def action(self) -> 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
def action(self) -> 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
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
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}
res = await self.__session.request(Route('POST', '/api/i/pages'), json=data, auth=True)
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)
return res

@ -18,4 +18,8 @@ class PollManager(AbstractManager):
@property
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に対するアクションを行うクラス
"""
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
__all__ = ('UserManager',)
__all__ = ("UserManager",)
class UserManager(AbstractManager):

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

@ -26,11 +26,11 @@ class UserIP:
@property
def ip(self) -> str:
return self.__user_ip['ip']
return self.__user_ip["ip"]
@property
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:
return isinstance(__value, UserIP) and self.ip == __value.ip
@ -45,23 +45,23 @@ class IndexStat:
@property
def schemaname(self) -> str:
return self.__index_stat['schemaname']
return self.__index_stat["schemaname"]
@property
def tablename(self) -> str:
return self.__index_stat['tablename']
return self.__index_stat["tablename"]
@property
def indexname(self) -> str:
return self.__index_stat['indexname']
return self.__index_stat["indexname"]
@property
def tablespace(self) -> str | None:
return self.__index_stat['tablespace']
return self.__index_stat["tablespace"]
@property
def indexdef(self) -> str:
return self.__index_stat['indexdef']
return self.__index_stat["indexdef"]
class ModerationLog:
@ -71,27 +71,27 @@ class ModerationLog:
@property
def id(self) -> str:
return self.__moderation_log['id']
return self.__moderation_log["id"]
@property
def created_at(self) -> datetime:
return str_to_datetime(self.__moderation_log['created_at'])
return str_to_datetime(self.__moderation_log["created_at"])
@property
def type(self) -> str:
return self.__moderation_log['type']
return self.__moderation_log["type"]
@property
def info(self) -> dict:
return self.__moderation_log['info']
return self.__moderation_log["info"]
@property
def user_id(self) -> str:
return self.__moderation_log['user_id']
return self.__moderation_log["user_id"]
@property
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:
return isinstance(__value, ModerationLog) and self.id == __value.id
@ -106,11 +106,11 @@ class ServerInfoCpu:
@property
def models(self) -> str:
return self.__server_info_cpu['models']
return self.__server_info_cpu["models"]
@property
def cores(self) -> int:
return self.__server_info_cpu['cores']
return self.__server_info_cpu["cores"]
class ServerInfoMem:
@ -119,7 +119,7 @@ class ServerInfoMem:
@property
def total(self) -> int:
return self.__server_info_mem['total']
return self.__server_info_mem["total"]
class ServerInfoFs:
@ -128,11 +128,11 @@ class ServerInfoFs:
@property
def total(self) -> int:
return self.__server_info_fs['total']
return self.__server_info_fs["total"]
@property
def used(self) -> int:
return self.__server_info_fs['used']
return self.__server_info_fs["used"]
class ServerInfoNet:
@ -141,7 +141,7 @@ class ServerInfoNet:
@property
def interface(self) -> str:
return self.__server_info_net['interface']
return self.__server_info_net["interface"]
class ServerInfo:
@ -150,32 +150,32 @@ class ServerInfo:
@property
def machine(self) -> str:
return self.__server_info['machine']
return self.__server_info["machine"]
@property
def os(self) -> str:
return self.__server_info['os']
return self.__server_info["os"]
@property
def node(self) -> str:
return self.__server_info['node']
return self.__server_info["node"]
@property
def psql(self) -> str:
return self.__server_info['psql']
return self.__server_info["psql"]
@property
def cpu(self) -> ServerInfoCpu:
return ServerInfoCpu(self.__server_info['cpu'])
return ServerInfoCpu(self.__server_info["cpu"])
@property
def mem(self) -> ServerInfoMem:
return ServerInfoMem(self.__server_info['mem'])
return ServerInfoMem(self.__server_info["mem"])
@property
def fs(self) -> ServerInfoFs:
return ServerInfoFs(self.__server_info['fs'])
return ServerInfoFs(self.__server_info["fs"])
@property
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.manager.client import ClientManager
T = TypeVar('T', bound=IAnnouncementCommon)
T = TypeVar("T", bound=IAnnouncementCommon)
class AnnouncementCommon(Generic[T]):
@ -20,31 +20,31 @@ class AnnouncementCommon(Generic[T]):
@property
def id(self) -> str:
return self.__announcement['id']
return self.__announcement["id"]
@property
def created_at(self) -> datetime:
return str_to_datetime(self.__announcement['created_at'])
return str_to_datetime(self.__announcement["created_at"])
@property
def updated_at(self) -> datetime | None:
return (
str_to_datetime(self.__announcement['updated_at'])
if self.__announcement['updated_at']
str_to_datetime(self.__announcement["updated_at"])
if self.__announcement["updated_at"]
else None
)
@property
def text(self) -> str:
return self.__announcement['text']
return self.__announcement["text"]
@property
def title(self) -> str:
return self.__announcement['title']
return self.__announcement["title"]
@property
def image_url(self) -> str | None:
return self.__announcement['image_url']
return self.__announcement["image_url"]
@property
def action(self) -> AdminAnnouncementClientActions:
@ -66,7 +66,7 @@ class Announcement(AnnouncementCommon):
@property
def is_read(self) -> bool:
return self.__announcement['is_read']
return self.__announcement["is_read"]
class AnnouncementSystem(AnnouncementCommon):
@ -76,4 +76,4 @@ class AnnouncementSystem(AnnouncementCommon):
@property
def reads(self) -> int:
return self.__announcement['reads']
return self.__announcement["reads"]

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

@ -15,12 +15,12 @@ class Channel(ChannelLite[IChannel]):
@property
def has_unread_note(self) -> bool:
return self._channel['has_unread_note']
return self._channel["has_unread_note"]
@property
def is_following(self) -> bool | None:
return self._channel.get('is_following')
return self._channel.get("is_following")
@property
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:
__slots__ = ('__data',)
__slots__ = ("__data",)
def __init__(self, data: IActiveUsersChart):
self.__data = data
@property
def read_write(self) -> list[int]:
return self.__data['read_write']
return self.__data["read_write"]
@property
def read(self) -> list[int]:
return self.__data['read']
return self.__data["read"]
@property
def write(self) -> list[int]:
return self.__data['write']
return self.__data["write"]
@property
def registered_within_week(self) -> list[int]:
return self.__data['registered_within_week']
return self.__data["registered_within_week"]
@property
def registered_within_month(self) -> list[int]:
return self.__data['registered_within_month']
return self.__data["registered_within_month"]
@property
def registered_within_year(self) -> list[int]:
return self.__data['registered_within_year']
return self.__data["registered_within_year"]
@property
def registered_outside_week(self) -> list[int]:
return self.__data['registered_outside_week']
return self.__data["registered_outside_week"]
@property
def registered_outside_month(self) -> list[int]:
return self.__data['registered_outside_month']
return self.__data["registered_outside_month"]
@property
def registered_outside_year(self) -> list[int]:
return self.__data['registered_outside_year']
return self.__data["registered_outside_year"]
class DriveLocalChart:
__slots__ = ('__data',)
__slots__ = ("__data",)
def __init__(self, data: IDriveLocalChart):
self.__data = data
@property
def total_count(self) -> list[int]:
return self.__data['total_count']
return self.__data["total_count"]
@property
def total_size(self) -> list[int]:
return self.__data['total_size']
return self.__data["total_size"]
@property
def inc_count(self) -> list[int]:
return self.__data['inc_count']
return self.__data["inc_count"]
@property
def inc_size(self) -> list[int]:
return self.__data['inc_size']
return self.__data["inc_size"]
@property
def dec_count(self) -> list[int]:
return self.__data['dec_count']
return self.__data["dec_count"]
@property
def dec_size(self) -> list[int]:
return self.__data['dec_size']
return self.__data["dec_size"]
class DriveRemoteChart:
__slots__ = ('__data',)
__slots__ = ("__data",)
def __init__(self, data: IDriveRemoteChart):
self.__data: IDriveRemoteChart = data
@property
def total_count(self) -> list[int]:
return self.__data['total_count']
return self.__data["total_count"]
@property
def total_size(self) -> list[int]:
return self.__data['total_size']
return self.__data["total_size"]
@property
def inc_count(self) -> list[int]:
return self.__data['inc_count']
return self.__data["inc_count"]
@property
def inc_size(self) -> list[int]:
return self.__data['inc_size']
return self.__data["inc_size"]
@property
def dec_count(self) -> list[int]:
return self.__data['dec_count']
return self.__data["dec_count"]
@property
def dec_size(self) -> list[int]:
return self.__data['dec_size']
return self.__data["dec_size"]
class DriveChart:
__slots__ = ('__data',)
__slots__ = ("__data",)
def __init__(self, data: IDriveChart):
self.__data: IDriveChart = data
@property
def local(self) -> DriveLocalChart:
return DriveLocalChart(self.__data['local'])
return DriveLocalChart(self.__data["local"])
@property
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.types.chat import IChatGroup, IChatMessage
__all__ = ['ChatGroup', 'ChatMessage']
__all__ = ["ChatGroup", "ChatMessage"]
class ChatGroup:
@ -21,26 +21,26 @@ class ChatGroup:
@property
def id(self) -> str:
"""グループのID"""
return self.__group['id']
return self.__group["id"]
@property
def created_at(self) -> str:
"""グループの作成日時"""
return self.__group['created_at']
return self.__group["created_at"]
@property
def name(self) -> str:
"""グループ名"""
return self.__group['name']
return self.__group["name"]
@property
def owner_id(self) -> str:
"""グループのオーナーのID"""
return self.__group['owner_id']
return self.__group["owner_id"]
@property
def user_ids(self) -> list[str]:
return self.__group['user_ids']
return self.__group["user_ids"]
def __eq__(self, __value: object) -> bool:
return isinstance(__value, ChatGroup) and self.id == __value.id
@ -61,65 +61,65 @@ class ChatMessage:
@property
def id(self) -> str:
"""The message ID."""
return self.__chat['id']
return self.__chat["id"]
@property
def created_at(self) -> str:
"""Returns the date and time the message was created (UTC)"""
return self.__chat['created_at']
return self.__chat["created_at"]
@property
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
def text(self) -> str | None:
"""text of the message"""
return self.__chat['text']
return self.__chat["text"]
@property
def user_id(self) -> str:
return self.__chat['user_id']
return self.__chat["user_id"]
@property
def user(self) -> LiteUser:
return LiteUser(self.__chat['user'], client=self.__client)
return LiteUser(self.__chat["user"], client=self.__client)
@property
def recipient_id(self) -> str | None:
""" The id of the bot self """
return self.__chat['recipient_id']
"""The id of the bot self"""
return self.__chat["recipient_id"]
@property
def recipient(self) -> LiteUser | None:
""" The user of the bot self """
"""The user of the bot self"""
return (
LiteUser(self.__chat['recipient'], client=self.__client)
if self.__chat.get('recipient')
LiteUser(self.__chat["recipient"], client=self.__client)
if self.__chat.get("recipient")
else None
)
@property
def group_id(self) -> str | None:
return self.__chat['group_id']
return self.__chat["group_id"]
@property
def file_id(self) -> str | None:
return self.__chat['file_id']
return self.__chat["file_id"]
@property
def is_read(self) -> bool:
return bool(self.__chat['is_read'])
return bool(self.__chat["is_read"])
@property
def reads(self) -> list[str]:
return self.__chat['reads']
return self.__chat["reads"]
@property
def group(self) -> ChatGroup | None:
return (
ChatGroup(self.__chat['group'], client=self.__client)
if self.__chat.get('group')
ChatGroup(self.__chat["group"], client=self.__client)
if self.__chat.get("group")
else None
)

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

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

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

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

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

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

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

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

@ -16,11 +16,11 @@ class CPU:
@property
def cores(self) -> int:
return self.__cpu['cores']
return self.__cpu["cores"]
@property
def model(self) -> str:
return self.__cpu['model']
return self.__cpu["model"]
class MetaCommon:
@ -30,71 +30,71 @@ class MetaCommon:
@property
def cache_remote_files(self) -> bool:
return self.__meta_common['cache_remote_files']
return self.__meta_common["cache_remote_files"]
@property
def enable_hcaptch(self) -> bool:
return self.__meta_common['enable_hcaptch']
return self.__meta_common["enable_hcaptch"]
@property
def hcaptcha_site_key(self) -> str | None:
return self.__meta_common['hcaptcha_site_key']
return self.__meta_common["hcaptcha_site_key"]
@property
def enable_recaptcha(self) -> bool:
return self.__meta_common['enable_recaptcha']
return self.__meta_common["enable_recaptcha"]
@property
def recaptcha_site_key(self) -> str:
return self.__meta_common['recaptcha_site_key']
return self.__meta_common["recaptcha_site_key"]
@property
def sw_publickey(self) -> str | None:
return self.__meta_common['sw_publickey']
return self.__meta_common["sw_publickey"]
@property
def banner_url(self) -> str | None:
return self.__meta_common['banner_url']
return self.__meta_common["banner_url"]
@property
def error_image_url(self) -> str | None:
return self.__meta_common['error_image_url']
return self.__meta_common["error_image_url"]
@property
def icon_url(self) -> str | None:
return self.__meta_common['icon_url']
return self.__meta_common["icon_url"]
@property
def max_note_text_length(self) -> int:
return self.__meta_common['max_note_text_length']
return self.__meta_common["max_note_text_length"]
@property
def enable_email(self) -> bool:
return self.__meta_common['enable_email']
return self.__meta_common["enable_email"]
@property
def enable_twitter_integration(self) -> bool:
return self.__meta_common['enable_twitter_integration']
return self.__meta_common["enable_twitter_integration"]
@property
def enable_github_integration(self) -> bool:
return self.__meta_common['enable_github_integration']
return self.__meta_common["enable_github_integration"]
@property
def enable_discord_integration(self) -> bool:
return self.__meta_common['enable_discord_integration']
return self.__meta_common["enable_discord_integration"]
@property
def enable_service_worker(self) -> bool:
return self.__meta_common['enable_service_worker']
return self.__meta_common["enable_service_worker"]
@property
def proxy_account_name(self) -> str | None:
return self.__meta_common['proxy_account_name']
return self.__meta_common["proxy_account_name"]
@property
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
def object_storage_s3_force_path_style(self) -> bool:
@ -107,33 +107,33 @@ class MetaCommon:
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
@property
def ads(self) -> list[IAds] | None: # TODO: モデルに
return self.__meta_common.get('ads')
return self.__meta_common.get("ads")
@property
def translator_available(self) -> bool:
return self.__meta_common.get('translator_available', False)
return self.__meta_common.get("translator_available", False)
@property
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
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の共通情報
@property
def emojis(self) -> list[CustomEmoji]:
return (
[CustomEmoji(i, client=self.__client) for i in self.__meta_common['emojis']]
if 'emojis' in self.__meta_common
[CustomEmoji(i, client=self.__client) for i in self.__meta_common["emojis"]]
if "emojis" in self.__meta_common
else []
)
@ -146,128 +146,128 @@ class LiteMeta(MetaCommon):
@property
def description(self) -> str | None:
return self.__lite_meta['description']
return self.__lite_meta["description"]
@property
def disable_registration(self) -> bool:
return self.__lite_meta['disable_registration']
return self.__lite_meta["disable_registration"]
@property
def feedback_url(self) -> str:
return self.__lite_meta['feedback_url']
return self.__lite_meta["feedback_url"]
@property
def maintainer_email(self) -> str | None:
return self.__lite_meta['maintainer_email']
return self.__lite_meta["maintainer_email"]
@property
def maintainer_name(self) -> str | None:
return self.__lite_meta['maintainer_name']
return self.__lite_meta["maintainer_name"]
@property
def name(self) -> str | None:
return self.__lite_meta['name']
return self.__lite_meta["name"]
@property
def repository_url(self) -> str:
return self.__lite_meta['repository_url']
return self.__lite_meta["repository_url"]
@property
def tos_url(self) -> str | None:
return self.__lite_meta['tos_url']
return self.__lite_meta["tos_url"]
@property
def uri(self) -> str:
return self.__lite_meta['uri']
return self.__lite_meta["uri"]
@property
def version(self) -> str:
return self.__lite_meta['version']
return self.__lite_meta["version"]
# v12のMeta
@property
def background_image_url(self) -> str | None:
return self.__lite_meta.get('background_image_url')
return self.__lite_meta.get("background_image_url")
@property
def default_dark_theme(self) -> str | None:
return self.__lite_meta.get('default_dark_theme')
return self.__lite_meta.get("default_dark_theme")
@property
def default_light_theme(self) -> str | None:
return self.__lite_meta.get('default_light_theme')
return self.__lite_meta.get("default_light_theme")
@property
def logo_image_url(self) -> str | None:
return self.__lite_meta.get('logo_image_url')
return self.__lite_meta.get("logo_image_url")
@property
def theme_color(self) -> str | None:
return self.__lite_meta.get('theme_color')
return self.__lite_meta.get("theme_color")
# v11のMeta
@property
def announcements(self) -> list[IMetaAnnouncement] | None: # TODO: 型確認
return self.__lite_meta.get('announcements', None)
return self.__lite_meta.get("announcements", None)
@property
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
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
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
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
def machine(self) -> str | None:
return self.__lite_meta.get('machine')
return self.__lite_meta.get("machine")
@property
def node(self) -> str | None:
return self.__lite_meta.get('node')
return self.__lite_meta.get("node")
@property
def os(self) -> str | None:
return self.__lite_meta.get('os')
return self.__lite_meta.get("os")
@property
def proxy_account(self) -> str | None:
return self.__lite_meta.get('proxy_account')
return self.__lite_meta.get("proxy_account")
@property
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
def psql(self) -> str | None:
return self.__lite_meta.get('psql')
return self.__lite_meta.get("psql")
@property
def redis(self) -> str | None:
return self.__lite_meta.get('redis')
return self.__lite_meta.get("redis")
@property
def secure(self) -> bool:
return self.__lite_meta.get('secure', False)
return self.__lite_meta.get("secure", False)
@property
def summaly_proxy(self) -> str | None:
return self.__lite_meta.get('summaly_proxy')
return self.__lite_meta.get("summaly_proxy")
@property
def tos_text_url(self) -> str | None:
return self.__lite_meta.get('tos_text_url')
return self.__lite_meta.get("tos_text_url")
@property
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
T = TypeVar('T', bound=IPartialNote)
T = TypeVar("T", bound=IPartialNote)
class PartialNote(Generic[T]):
@ -24,19 +24,19 @@ class PartialNote(Generic[T]):
@property
def created_at(self) -> datetime:
return str_to_datetime(self._note['created_at'])
return str_to_datetime(self._note["created_at"])
@property
def cw(self) -> str | None:
return self._note.get('cw')
return self._note.get("cw")
@property
def file_ids(self) -> list[str]:
return self._note['file_ids']
return self._note["file_ids"]
@property
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
def id(self) -> str:
@ -48,7 +48,7 @@ class PartialNote(Generic[T]):
str
ユーザーのID
"""
return self._note['id']
return self._note["id"]
@property
def reaction_acceptance(self) -> IReactionAcceptance | None:
@ -58,7 +58,7 @@ class PartialNote(Generic[T]):
-------
IReactionAcceptance | None
"""
return self._note.get('reaction_acceptance')
return self._note.get("reaction_acceptance")
@property
def reaction_emojis(self) -> dict[str, str] | None:
@ -69,47 +69,49 @@ class PartialNote(Generic[T]):
dict[str, str] | None
リアクション名がキー値はリアクション画像のリンクです
"""
return self._note.get('reaction_emojis')
return self._note.get("reaction_emojis")
@property
def renote_id(self) -> str | None:
return self._note['renote_id']
return self._note["renote_id"]
@property
def renote_count(self) -> int:
return self._note['renote_count']
return self._note["renote_count"]
@property
def reactions(self) -> dict[str, int]:
return self._note['reactions']
return self._note["reactions"]
@property
def replies_count(self) -> int:
return self._note['replies_count']
return self._note["replies_count"]
@property
def reply_id(self) -> str | None:
return self._note['reply_id']
return self._note["reply_id"]
@property
def tags(self) -> list[str]:
return self._note.get('tags', [])
return self._note.get("tags", [])
@property
def content(self) -> str | None:
return self._note.get('text')
return self._note.get("text")
@property
def author(self) -> LiteUser:
return LiteUser(self._note['user'], client=self._client)
return LiteUser(self._note["user"], client=self._client)
@property
def user_id(self) -> str:
return self._note['user_id']
return self._note["user_id"]
@property
def visibility(self,) -> INoteVisibility:
return self._note['visibility']
def visibility(
self,
) -> INoteVisibility:
return self._note["visibility"]
@property
def api(self) -> ClientNoteManager:

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

@ -15,67 +15,67 @@ class Policies:
@property
def gtl_available(self) -> bool:
return self.__policies['gtl_available']
return self.__policies["gtl_available"]
@property
def ltl_available(self) -> bool:
return self.__policies['ltl_available']
return self.__policies["ltl_available"]
@property
def can_public_note(self) -> bool:
return self.__policies['can_public_note']
return self.__policies["can_public_note"]
@property
def can_invite(self) -> bool:
return self.__policies['can_invite']
return self.__policies["can_invite"]
@property
def can_manage_custom_emojis(self) -> bool:
return self.__policies['can_manage_custom_emojis']
return self.__policies["can_manage_custom_emojis"]
@property
def can_hide_ads(self) -> bool:
return self.__policies['can_hide_ads']
return self.__policies["can_hide_ads"]
@property
def drive_capacity_mb(self) -> int:
return self.__policies['drive_capacity_mb']
return self.__policies["drive_capacity_mb"]
@property
def pin_limit(self) -> int:
return self.__policies['pin_limit']
return self.__policies["pin_limit"]
@property
def antenna_limit(self) -> int:
return self.__policies['antenna_limit']
return self.__policies["antenna_limit"]
@property
def word_mute_limit(self) -> int:
return self.__policies['word_mute_limit']
return self.__policies["word_mute_limit"]
@property
def webhook_limit(self) -> int:
return self.__policies['webhook_limit']
return self.__policies["webhook_limit"]
@property
def clip_limit(self) -> int:
return self.__policies['clip_limit']
return self.__policies["clip_limit"]
@property
def note_each_clips_limit(self) -> int:
return self.__policies['note_each_clips_limit']
return self.__policies["note_each_clips_limit"]
@property
def user_list_limit(self) -> int:
return self.__policies['user_list_limit']
return self.__policies["user_list_limit"]
@property
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
def rate_limit_factor(self) -> int:
return self.__policies['rate_limit_factor']
return self.__policies["rate_limit_factor"]
class Features:
@ -84,55 +84,55 @@ class Features:
@property
def registration(self) -> bool:
return self.__features['registration']
return self.__features["registration"]
@property
def elasticsearch(self) -> bool:
return self.__features['elasticsearch']
return self.__features["elasticsearch"]
@property
def hcaptcha(self) -> bool:
return self.__features['hcaptcha']
return self.__features["hcaptcha"]
@property
def recaptcha(self) -> bool:
return self.__features['recaptcha']
return self.__features["recaptcha"]
@property
def object_storage(self) -> bool:
return self.__features['object_storage']
return self.__features["object_storage"]
@property
def twitter(self) -> bool:
return self.__features['twitter']
return self.__features["twitter"]
@property
def github(self) -> bool:
return self.__features['github']
return self.__features["github"]
@property
def discord(self) -> bool:
return self.__features['discord']
return self.__features["discord"]
@property
def service_worker(self) -> bool:
return self.__features['service_worker']
return self.__features["service_worker"]
@property
def miauth(self) -> bool:
return self.__features.get('miauth', False)
return self.__features.get("miauth", False)
@property
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
def global_time_line(self) -> bool:
return self.__features.get('global_time_line', False)
return self.__features.get("global_time_line", False)
@property
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):
@ -144,25 +144,25 @@ class Meta(LiteMeta):
@property
def features(self) -> Features:
return Features(self.__meta['features'])
return Features(self.__meta["features"])
# v12
@property
def pinned_clip_id(self) -> str | None:
return self.__meta.get('pinned_clip_id')
return self.__meta.get("pinned_clip_id")
@property
def pinned_pages(self) -> list[str]:
return self.__meta.get('pinned_pages', [])
return self.__meta.get("pinned_pages", [])
@property
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
def require_setup(self) -> bool:
return self.__meta.get('require_setup', False)
return self.__meta.get("require_setup", False)
class AdminMeta(MetaCommon):
@ -174,127 +174,127 @@ class AdminMeta(MetaCommon):
@property
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
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
def hidden_tags(self) -> list[str]:
return self.__admin_meta.get('hidden_tags', [])
return self.__admin_meta.get("hidden_tags", [])
@property
def blocked_hosts(self) -> list[str]:
return self.__admin_meta.get('blocked_hosts', [])
return self.__admin_meta.get("blocked_hosts", [])
@property
def recaptcha_secret_key(self) -> str | None:
return self.__admin_meta.get('recaptcha_secret_key')
return self.__admin_meta.get("recaptcha_secret_key")
@property
def twitter_consumer_key(self) -> str | None:
return self.__admin_meta.get('twitter_consumer_key')
return self.__admin_meta.get("twitter_consumer_key")
@property
def twitter_consumer_secret(self) -> str | None:
return self.__admin_meta.get('twitter_consumer_secret')
return self.__admin_meta.get("twitter_consumer_secret")
@property
def github_client_id(self) -> str | None:
return self.__admin_meta.get('github_client_id')
return self.__admin_meta.get("github_client_id")
@property
def github_client_secret(self) -> str | None:
return self.__admin_meta.get('github_client_secret')
return self.__admin_meta.get("github_client_secret")
@property
def discord_client_id(self) -> str | None:
return self.__admin_meta.get('discord_client_id')
return self.__admin_meta.get("discord_client_id")
@property
def discord_client_secret(self) -> str | None:
return self.__admin_meta.get('discord_client_secret')
return self.__admin_meta.get("discord_client_secret")
@property
def email(self) -> str | None:
return self.__admin_meta.get('email')
return self.__admin_meta.get("email")
@property
def smtp_secure(self) -> bool:
return self.__admin_meta.get('smtp_secure', False)
return self.__admin_meta.get("smtp_secure", False)
@property
def smtp_host(self) -> str | None:
return self.__admin_meta.get('smtp_host')
return self.__admin_meta.get("smtp_host")
@property
def smtp_port(self) -> int | None:
return self.__admin_meta.get('smtp_port')
return self.__admin_meta.get("smtp_port")
@property
def smtp_user(self) -> str | None:
return self.__admin_meta.get('smtp_user')
return self.__admin_meta.get("smtp_user")
@property
def smtp_pass(self) -> str | None:
return self.__admin_meta.get('smtp_pass')
return self.__admin_meta.get("smtp_pass")
@property
def sw_private_key(self) -> str | None:
return self.__admin_meta.get('sw_private_key')
return self.__admin_meta.get("sw_private_key")
@property
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
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
def object_storage_bucket(self) -> str | None:
return self.__admin_meta.get('object_storage_bucket')
return self.__admin_meta.get("object_storage_bucket")
@property
def object_storage_prefix(self) -> str | None:
return self.__admin_meta.get('object_storage_prefix')
return self.__admin_meta.get("object_storage_prefix")
@property
def object_storage_endpoint(self) -> str | None:
return self.__admin_meta.get('object_storage_endpoint')
return self.__admin_meta.get("object_storage_endpoint")
@property
def object_storage_region(self) -> str | None:
return self.__admin_meta.get('object_storage_region')
return self.__admin_meta.get("object_storage_region")
@property
def object_storage_port(self) -> int | None:
return self.__admin_meta.get('object_storage_port')
return self.__admin_meta.get("object_storage_port")
@property
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
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
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
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
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
def pinned_users(self) -> list[str]:
return self.__admin_meta.get('pinned_users', [])
return self.__admin_meta.get("pinned_users", [])
"""
v12 only
@ -302,36 +302,36 @@ class AdminMeta(MetaCommon):
@property
def hcaptcha_secret_key(self) -> str | None:
return self.__admin_meta.get('hcaptcha_secret_key')
return self.__admin_meta.get("hcaptcha_secret_key")
@property
def sensitive_media_detection(self) -> str | None:
return self.__admin_meta.get('sensitive_media_detection')
return self.__admin_meta.get("sensitive_media_detection")
@property
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
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
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
def proxy_account_id(self) -> str | None:
return self.__admin_meta.get('proxy_account_id')
return self.__admin_meta.get("proxy_account_id")
@property
def summary_proxy(self) -> str | None:
return self.__admin_meta.get('summary_proxy')
return self.__admin_meta.get("summary_proxy")
@property
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
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
def id(self) -> str:
return self.__data['id']
return self.__data["id"]
@property
def created_at(self) -> str:
return self.__data['created_at']
return self.__data["created_at"]
@property
def mutee_id(self) -> str:
return self.__data['mutee_id']
return self.__data["mutee_id"]
@property
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:
return isinstance(__value, IMuteUser) and self.id == __value.id

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

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

@ -10,10 +10,10 @@ if TYPE_CHECKING:
class MiPoll:
def __init__(self, poll: ICreatePoll) -> None:
self.multiple = poll.get('multiple', False)
self.choices = poll.get('choices')
self.expired_after = poll.get('expired_after')
self.expires_at = poll.get('expires_at')
self.multiple = poll.get("multiple", False)
self.choices = poll.get("choices")
self.expired_after = poll.get("expired_after")
self.expires_at = poll.get("expires_at")
class PollChoice:
@ -23,15 +23,15 @@ class PollChoice:
@property
def is_voted(self) -> bool:
return self.__choice['is_voted']
return self.__choice["is_voted"]
@property
def text(self) -> str:
return self.__choice['text']
return self.__choice["text"]
@property
def votes(self) -> int:
return self.__choice['votes']
return self.__choice["votes"]
class Poll:
@ -41,16 +41,16 @@ class Poll:
@property
def multiple(self) -> bool:
return self.__poll['multiple']
return self.__poll["multiple"]
@property
def expires_at(self) -> int:
return self.__poll['expires_at']
return self.__poll["expires_at"]
@property
def expired_after(self) -> int:
return self.__poll['expired_after']
return self.__poll["expired_after"]
@property
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
def reaction(self) -> str:
return self.__reaction['body']['body']['reaction']
return self.__reaction["body"]["body"]["reaction"]
@property
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
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
def id(self) -> str:
return self.__role_user['id']
return self.__role_user["id"]
@property
def user(self) -> LiteUser:
return LiteUser(self.__role_user['user'], client=self.__client)
return LiteUser(self.__role_user["user"], client=self.__client)
@property
def expires_at(self) -> datetime | None:
return (
str_to_datetime(self.__role_user['expires_at'])
if self.__role_user['expires_at']
str_to_datetime(self.__role_user["expires_at"])
if self.__role_user["expires_at"]
else None
)
@ -51,15 +51,15 @@ class RolePolicyValue:
@property
def value(self) -> int:
return self.__policy_value_data.get('value')
return self.__policy_value_data.get("value")
@property
def use_default(self) -> bool:
return self.__policy_value_data.get('use_default')
return self.__policy_value_data.get("use_default")
@property
def priority(self) -> int | None:
return self.__policy_value_data.get('priority')
return self.__policy_value_data.get("priority")
class RolePolicies:
@ -68,67 +68,67 @@ class RolePolicies:
@property
def antenna_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('antenna_limit'))
return RolePolicyValue(self.__role_policies_data.get("antenna_limit"))
@property
def gtl_available(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('gtl_available'))
return RolePolicyValue(self.__role_policies_data.get("gtl_available"))
@property
def ltl_available(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('ltl_available'))
return RolePolicyValue(self.__role_policies_data.get("ltl_available"))
@property
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
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
def can_invite(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('can_invite'))
return RolePolicyValue(self.__role_policies_data.get("can_invite"))
@property
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
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
def pin_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('pin_limit'))
return RolePolicyValue(self.__role_policies_data.get("pin_limit"))
@property
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
def webhook_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('webhook_limit'))
return RolePolicyValue(self.__role_policies_data.get("webhook_limit"))
@property
def clip_limit(self) -> RolePolicyValue:
return RolePolicyValue(self.__role_policies_data.get('clip_limit'))
return RolePolicyValue(self.__role_policies_data.get("clip_limit"))
@property
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
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
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
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:
@ -138,67 +138,67 @@ class Role:
@property
def id(self) -> str:
return self.__role_data.get('id')
return self.__role_data.get("id")
@property
def created_at(self) -> str:
return self.__role_data.get('created_at')
return self.__role_data.get("created_at")
@property
def updated_at(self) -> str:
return self.__role_data.get('updated_at')
return self.__role_data.get("updated_at")
@property
def name(self) -> str:
return self.__role_data.get('name')
return self.__role_data.get("name")
@property
def description(self) -> str:
return self.__role_data.get('description')
return self.__role_data.get("description")
@property
def color(self) -> str | None:
return self.__role_data.get('color')
return self.__role_data.get("color")
@property
def icon_url(self) -> str | None:
return self.__role_data.get('icon_url')
return self.__role_data.get("icon_url")
@property
def target(self) -> str:
return self.__role_data.get('target')
return self.__role_data.get("target")
@property
def cond_formula(self) -> dict:
return self.__role_data.get('cond_formula')
return self.__role_data.get("cond_formula")
@property
def is_public(self) -> bool:
return self.__role_data.get('is_public')
return self.__role_data.get("is_public")
@property
def is_administrator(self) -> bool:
return self.__role_data.get('is_administrator')
return self.__role_data.get("is_administrator")
@property
def is_moderator(self) -> bool:
return self.__role_data.get('is_moderator')
return self.__role_data.get("is_moderator")
@property
def as_badge(self) -> bool:
return self.__role_data.get('as_badge')
return self.__role_data.get("as_badge")
@property
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
def policies(self) -> RolePolicies:
return RolePolicies(self.__role_data.get('policies'))
return RolePolicies(self.__role_data.get("policies"))
@property
def users_count(self) -> int:
return self.__role_data.get('users_count')
return self.__role_data.get("users_count")
@property
def api(self) -> AdminRolesModelManager:

@ -12,7 +12,7 @@ from mipac.utils.format import str_to_datetime
if TYPE_CHECKING:
from mipac.manager.client import ClientManager
__all__ = ('UserDetailed', 'LiteUser', 'Achievement', 'BlockingUser')
__all__ = ("UserDetailed", "LiteUser", "Achievement", "BlockingUser")
class BlockingUser:
@ -22,19 +22,19 @@ class BlockingUser:
@property
def id(self) -> str:
return self.__blocking_user_data['id']
return self.__blocking_user_data["id"]
@property
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
def blockee_id(self) -> str:
return self.__blocking_user_data['blockee_id']
return self.__blocking_user_data["blockee_id"]
@property
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:
return isinstance(__value, BlockingUser) and self.id == __value.id
@ -49,17 +49,17 @@ class Achievement:
@property
def name(self) -> str:
return self.__detail['name']
return self.__detail["name"]
@property
def unlocked_at(self) -> int:
return self.__detail['unlocked_at']
return self.__detail["unlocked_at"]
class UserDetailed(LiteUser):
__slots__ = (
'__detail',
'__client',
"__detail",
"__client",
)
def __init__(self, user: IUserDetailed, *, client: ClientManager):
@ -68,164 +68,166 @@ class UserDetailed(LiteUser):
@property
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
def fields(self) -> list[IUserDetailedField]:
return self.__detail['fields']
return self.__detail["fields"]
@property
def followers_count(self) -> int:
return self.__detail['followers_count']
return self.__detail["followers_count"]
@property
def following_count(self) -> int:
return self.__detail['following_count']
return self.__detail["following_count"]
@property
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
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
def is_admin(self) -> bool:
return self.__detail['is_admin']
return self.__detail["is_admin"]
@property
def is_blocked(self) -> bool | None:
return self.__detail.get('is_blocked')
return self.__detail.get("is_blocked")
@property
def is_blocking(self) -> bool | None:
return self.__detail.get('is_blocking')
return self.__detail.get("is_blocking")
@property
def is_bot(self) -> bool:
return self.__detail['is_bot']
return self.__detail["is_bot"]
@property
def is_cat(self) -> bool:
return self.__detail['is_cat']
return self.__detail["is_cat"]
@property
def is_followed(self) -> bool | None:
return self.__detail.get('is_followed')
return self.__detail.get("is_followed")
@property
def is_following(self) -> bool | None:
return self.__detail.get('is_following')
return self.__detail.get("is_following")
@property
def is_locked(self) -> bool:
return self.__detail['is_locked']
return self.__detail["is_locked"]
@property
def is_moderator(self) -> bool:
return self.__detail['is_moderator']
return self.__detail["is_moderator"]
@property
def is_muted(self) -> bool | None:
return self.__detail.get('is_muted')
return self.__detail.get("is_muted")
@property
def is_silenced(self) -> bool:
return self.__detail['is_silenced']
return self.__detail["is_silenced"]
@property
def is_suspended(self) -> bool:
return self.__detail['is_suspended']
return self.__detail["is_suspended"]
@property
def public_reactions(self) -> bool:
return self.__detail['public_reactions']
return self.__detail["public_reactions"]
@property
def security_keys(self) -> bool:
return self.__detail['security_keys']
return self.__detail["security_keys"]
@property
def two_factor_enabled(self) -> bool:
return self.__detail['two_factor_enabled']
return self.__detail["two_factor_enabled"]
@property
def notes_count(self) -> int:
return self.__detail['notes_count']
return self.__detail["notes_count"]
@property
def pinned_note_ids(self) -> list[str]:
return self.__detail['pinned_note_ids']
return self.__detail["pinned_note_ids"]
@property
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
def banner_blurhash(self) -> str | None:
return self.__detail.get('banner_blurhash')
return self.__detail.get("banner_blurhash")
@property
def banner_color(self) -> str | None:
return self.__detail.get('banner_color')
return self.__detail.get("banner_color")
@property
def banner_url(self) -> str | None:
return self.__detail.get('banner_url')
return self.__detail.get("banner_url")
@property
def birthday(self) -> str | None:
return self.__detail.get('birthday')
return self.__detail.get("birthday")
@property
def created_at(self) -> str | None:
return self.__detail.get('created_at')
return self.__detail.get("created_at")
@property
def description(self) -> str | None:
return self.__detail.get('description')
return self.__detail.get("description")
@property
def ff_visibility(self,) -> Literal['public', 'followers', 'private'] | None:
return self.__detail.get('ff_visibility')
def ff_visibility(
self,
) -> Literal["public", "followers", "private"] | None:
return self.__detail.get("ff_visibility")
@property
def lang(self) -> str | None:
return self.__detail.get('lang')
return self.__detail.get("lang")
@property
def last_fetched_at(self) -> str | None:
return self.__detail.get('last_fetched_at')
return self.__detail.get("last_fetched_at")
@property
def location(self) -> str | None:
return self.__detail.get('location')
return self.__detail.get("location")
@property
def logged_in_days(self) -> int | None:
return self.__detail.get('logged_in_days')
return self.__detail.get("logged_in_days")
@property
def pinned_page(self) -> IPage | None:
return self.__detail.get('pinned_page')
return self.__detail.get("pinned_page")
@property
def pinned_page_id(self) -> str | None:
return self.__detail.get('pinned_page_id')
return self.__detail.get("pinned_page_id")
@property
def updated_at(self) -> str | None:
return self.__detail.get('updated_at')
return self.__detail.get("updated_at")
@property
def uri(self) -> str | None:
return self.__detail.get('uri')
return self.__detail.get("uri")
@property
def url(self) -> str | None:
return self.__detail.get('url')
return self.__detail.get("url")
@property
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
IT_ACHIEVEMENT_NAME = Literal[
'notes1',
'notes10',
'notes100',
'notes500',
'notes1000',
'notes5000',
'notes10000',
'notes20000',
'notes30000',
'notes40000',
'notes50000',
'notes60000',
'notes70000',
'notes80000',
'notes90000',
'notes100000',
'login3',
'login7',
'login15',
'login30',
'login60',
'login100',
'login200',
'login300',
'login400',
'login500',
'login600',
'login700',
'login800',
'login900',
'login1000',
'passedSinceAccountCreated1',
'passedSinceAccountCreated2',
'passedSinceAccountCreated3',
'loggedInOnBirthday',
'loggedInOnNewYearsDay',
'noteClipped1',
'noteFavorited1',
'myNoteFavorited1',
'profileFilled',
'markedAsCat',
'following1',
'following10',
'following50',
'following100',
'following300',
'followers1',
'followers10',
'followers50',
'followers100',
'followers300',
'followers500',
'followers1000',
'collectAchievements30',
'viewAchievements3min',
'iLoveMisskey',
'foundTreasure',
'client30min',
'client60min',
'noteDeletedWithin1min',
'postedAtLateNight',
'postedAt0min0sec',
'selfQuote',
'htl20npm',
'viewInstanceChart',
'outputHelloWorldOnScratchpad',
'open3windows',
'driveFolderCircularReference',
'reactWithoutRead',
'clickedClickHere',
'justPlainLucky',
'setNameToSyuilo',
'cookieClicked',
'brainDiver',
"notes1",
"notes10",
"notes100",
"notes500",
"notes1000",
"notes5000",
"notes10000",
"notes20000",
"notes30000",
"notes40000",
"notes50000",
"notes60000",
"notes70000",
"notes80000",
"notes90000",
"notes100000",
"login3",
"login7",
"login15",
"login30",
"login60",
"login100",
"login200",
"login300",
"login400",
"login500",
"login600",
"login700",
"login800",
"login900",
"login1000",
"passedSinceAccountCreated1",
"passedSinceAccountCreated2",
"passedSinceAccountCreated3",
"loggedInOnBirthday",
"loggedInOnNewYearsDay",
"noteClipped1",
"noteFavorited1",
"myNoteFavorited1",
"profileFilled",
"markedAsCat",
"following1",
"following10",
"following50",
"following100",
"following300",
"followers1",
"followers10",
"followers50",
"followers100",
"followers300",
"followers500",
"followers1000",
"collectAchievements30",
"viewAchievements3min",
"iLoveMisskey",
"foundTreasure",
"client30min",
"client60min",
"noteDeletedWithin1min",
"postedAtLateNight",
"postedAt0min0sec",
"selfQuote",
"htl20npm",
"viewInstanceChart",
"outputHelloWorldOnScratchpad",
"open3windows",
"driveFolderCircularReference",
"reactWithoutRead",
"clickedClickHere",
"justPlainLucky",
"setNameToSyuilo",
"cookieClicked",
"brainDiver",
]

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

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

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

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

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

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

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

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

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

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

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

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

@ -39,7 +39,7 @@ class AuthClient:
MiAuthを使用するか
"""
if permissions is None:
permissions = ['read:account']
permissions = ["read:account"]
self.__client_session = aiohttp.ClientSession()
self.__instance_uri: str = instance_uri
self.__name: str = name
@ -60,45 +60,45 @@ class AuthClient:
認証に使用するURL
"""
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:
field['permissions'] = self.__permissions
field["permissions"] = self.__permissions
query = urlencode(field)
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:
field['permission'] = self.__permissions
field["permission"] = self.__permissions
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:
data = await res.json()
self.__secret = data['secret']
self.__secret = data["secret"]
async with self.__client_session.post(
f'{self.__instance_uri}/api/auth/session/generate',
json={'appSecret': self.__secret},
f"{self.__instance_uri}/api/auth/session/generate",
json={"appSecret": self.__secret},
) as res:
data = await res.json()
self.__session_token = data['token']
return data['url']
self.__session_token = data["token"]
return data["url"]
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:
async with self.__client_session.post(url) as res:
data = await res.json()
if data.get('ok') is True:
if data.get("ok") is True:
return data
await asyncio.sleep(1)
async def wait_oldauth(self) -> None:
while True:
async with self.__client_session.post(
f'{self.__instance_uri}/api/auth/session/userkey',
json={'appSecret': self.__secret, 'token': self.__session_token},
f"{self.__instance_uri}/api/auth/session/userkey",
json={"appSecret": self.__secret, "token": self.__session_token},
) as res:
data = await res.json()
if data.get('error', {}).get('code') != 'PENDING_SESSION':
if data.get("error", {}).get("code") != "PENDING_SESSION":
break
await asyncio.sleep(1)
@ -116,4 +116,4 @@ class AuthClient:
else:
data = await self.wait_oldauth()
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
def cache(group: str = 'default', override: bool = False):
def cache(group: str = "default", override: bool = False):
def decorator(func):
async def wrapper(self, *args, **kwargs):
key = cache_key_builder(func, self, *args, **kwargs)
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
res = await func(self, *args, **kwargs)
set_cache(group, key, res)
@ -43,5 +43,5 @@ def get_cache_key(func):
@lru_cache
def cache_key_builder(func, cls, *args, **kwargs):
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

@ -4,11 +4,11 @@ from typing import Any, Mapping
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)):
if components[i] in replace_list:
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(
@ -23,7 +23,7 @@ def convert_dict_keys_to_camel(
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
----------
@ -103,12 +103,12 @@ def upper_to_lower(
if field is None:
field = {}
for attr in data:
pattern = re.compile('[A-Z]')
pattern = re.compile("[A-Z]")
large = [i.group().lower() for i in pattern.finditer(attr)]
result = [None] * (len(large + pattern.split(attr)))
result[::2] = pattern.split(attr)
result[1::2] = ['_' + i.lower() for i in large]
default_key = ''.join(result)
result[1::2] = ["_" + i.lower() for i in large]
default_key = "".join(result)
if replace_list.get(attr):
default_key = default_key.replace(attr, replace_list.get(attr))
field[default_key] = data[attr]
@ -122,12 +122,12 @@ def upper_to_lower(
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)]
result = [None] * (len(large + pattern.split(text)))
result[::2] = pattern.split(text)
result[1::2] = ['_' + i.lower() for i in large]
return ''.join(result)
result[1::2] = ["_" + i.lower() for i in large]
return "".join(result)
def bool_to_string(boolean: bool) -> str:
@ -143,4 +143,4 @@ def bool_to_string(boolean: bool) -> str:
true or false: str
小文字になったbool文字列
"""
return 'true' if boolean else 'false'
return "true" if boolean else "false"

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

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

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

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

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

Loading…
Cancel
Save