Refactor/use lsp (#122)

* refactor: reaction周りを再実装 progress #120

* chore: fix type

* refactor: ad周りを再実装 progress #120

* refactor: annoucement周りを再実装 progress #120

* refactor: file周りを再実装 progress #120

* refactor: folder周りを再実装 progress #120

* refactor: mute周りを再実装 progress #120

* refactor: antenna周りを再実装 progress #120

* refactor: clip周りを再実装 progress #120

* refactor: favorite周りを再実装 progress #120

* refactor: invite周りを再実装 progress #120

* refactor: poll周りを再実装 progress #120

* chore: format

* docs: update CHANGELOG.md
pull/125/head
yupix 7 months ago committed by GitHub
parent b8792c565e
commit b81ed06c0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -2,6 +2,43 @@
## [Unreleased]
### Breaking changes 💔
#### 以下のクラスを削除しました
この変更はMisskeyのSchemaに似せた形で再実装するにあたり、MisskeyのSchemaよりも細かくモデルを作成していたため、そういったものを削除した形となります。
- `UserDetailed` -> `UserDetailedNotMe | MeDetailed`
- `MeDetailedModerator` -> `MeDetailed`
- `UserDetailedModerator` -> `UserDetailedNotMe | MeDetailed`
- `UserDetailedNotLogined` -> `UserDetailedNotMe | MeDetailed`
- `AdminAnnouncementClientActions` -> `ClientAdminAnnouncementActions`
- `AnnouncementSystem` -> `AnnoucementDetailed`
#### クラス名の変更
- `AdminAdvertisingModelActions` -> `ClientAdminAdActions`
- `AdminAdvertisingActions` -> `AdminAdActions`
- `AdminAdvertisingModelManager` -> `ClientAdminAdManager`
- `AdminAdvertisingManager` -> `AdminAdManager`
#### 引数に関する変更
`*Actions` 系にて `*_id` のような引数はすべてキーワード引数に変更されました。これはリスコフの置換法則に則るうえで必要な作業であり、今後のコード変更に対する耐性を上げるためでもあります。ご迷惑をお掛けしますがご理解のほどよろしくお願いいたします。
#### 戻り値の変更
- `Announcement.action -> ClientAdminAnnouncementActions` -> `Announcement.action -> ClientAdminAnnouncementManager`
- `AnnouncementDetailed.action -> ClientAdminAnnouncementActions` -> `AnnouncementDetailed.action -> ClientAdminAnnouncementManager`
#### `get_all` 引数を廃止
今まで多くの配列を返すメソッドをジェネレータとして作成していましたが、少ししかデータは要らないのに `async for` を書くのは大変ということで `get_all` 引数を廃止します。
これにより今まで `get_all` 引数があった ジェネレータは全て通常の list等を返すメソッドに変更されます。
今まで通りのジェネレータとしての機能が必要な場合は `get_all_*` というメソッドが新しく増えているためそちらをご利用ください。
## [0.5.99] 2023-12-03
このリリースは最新の Misskey 向けに最適化された `develop` ブランチの物となります。インスタンスで `v11``v12` を利用している場合は更新しないことをおすすめします。

@ -12,17 +12,12 @@ if TYPE_CHECKING:
from mipac.client import ClientManager
class AdminAdvertisingModelActions(AbstractAction):
def __init__(self, ad_id: str | None = None, *, session: HTTPClient, client: ClientManager):
self._ad_id: str | None = ad_id
class SharedAdminAdActions(AbstractAction):
def __init__(self, *, session: HTTPClient, client: ClientManager):
self._session: HTTPClient = session
self._client: ClientManager = client
async def delete(self, *, id: str | None = None) -> bool:
ad_id = self._ad_id or id
if ad_id is None:
raise ValueError("ad id is required")
async def delete(self, *, ad_id: str) -> bool:
res: bool = await self._session.request(
Route("POST", "/api/admin/ad/delete"), json={"id": ad_id}, auth=True, lower=True
)
@ -40,11 +35,8 @@ class AdminAdvertisingModelActions(AbstractAction):
starts_at: int,
day_of_week: int,
*,
ad_id: str | None = None,
ad_id: str,
) -> bool:
ad_id = self._ad_id or ad_id
if ad_id is None:
raise ValueError("ad id is required")
data = {
"id": ad_id,
"memo": memo or "",
@ -63,7 +55,49 @@ class AdminAdvertisingModelActions(AbstractAction):
return res
class AdminAdvertisingActions(AdminAdvertisingModelActions):
class ClientAdminAdActions(SharedAdminAdActions):
def __init__(self, ad_id: str, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
self._ad_id: str = ad_id
@override
async def delete(self, *, ad_id: str | None = None) -> bool:
ad_id = ad_id or self._ad_id
return await super().delete(ad_id=ad_id)
@override
async def update(
self,
memo: str,
url: str,
image_url: str,
place: Literal["square", "horizontal", "horizontal-big"],
priority: Literal["high", "middle", "low"],
ratio: int,
expires_at: int,
starts_at: int,
day_of_week: int,
*,
ad_id: str | None = None,
) -> bool:
ad_id = ad_id or self._ad_id
return await super().update(
memo=memo,
url=url,
image_url=image_url,
place=place,
priority=priority,
ratio=ratio,
expires_at=expires_at,
starts_at=starts_at,
day_of_week=day_of_week,
ad_id=ad_id,
)
class AdminAdActions(SharedAdminAdActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
@ -95,10 +129,6 @@ class AdminAdvertisingActions(AdminAdvertisingModelActions):
)
return Ad(ad_data=raw_ad, client=self._client)
@override
async def delete(self, id: str) -> bool:
return await super().delete(id=id)
async def get_list(
self,
limit: int = 10,
@ -142,30 +172,3 @@ class AdminAdvertisingActions(AdminAdvertisingModelActions):
for raw_ad in raw_ads:
yield Ad(ad_data=raw_ad, client=self._client)
@override
async def update(
self,
ad_id: str,
memo: str,
url: str,
image_url: str,
place: Literal["square", "horizontal", "horizontal-big"],
priority: Literal["high", "middle", "low"],
ratio: int,
expires_at: int,
starts_at: int,
day_of_week: int,
) -> bool:
return await super().update(
ad_id=ad_id,
memo=memo,
url=url,
image_url=image_url,
place=place,
priority=priority,
ratio=ratio,
expires_at=expires_at,
starts_at=starts_at,
day_of_week=day_of_week,
)

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, AsyncGenerator
from typing import TYPE_CHECKING, AsyncGenerator, override
from mipac.abstract.action import AbstractAction
from mipac.http import HTTPClient, Route
@ -12,21 +12,18 @@ if TYPE_CHECKING:
from mipac.manager.client import ClientManager
class AdminAnnouncementClientActions(AbstractAction):
class SharedAdminAnnouncementActions(AbstractAction):
def __init__(
self,
announce_id: str | None = None,
*,
session: HTTPClient,
client: ClientManager,
):
self.__announce_id = announce_id
self.__session: HTTPClient = session
self.__client: ClientManager = client
) -> None:
self._session: HTTPClient = session
self._client: ClientManager = client
async def delete(self, announce_id: str | None = None) -> bool:
announce_id = announce_id or self.__announce_id
res: bool = await self.__session.request(
async def delete(self, *, announce_id: str) -> bool:
res: bool = await self._session.request(
Route("POST", "/api/admin/announcements/delete"),
json={"id": announce_id},
auth=True,
@ -39,16 +36,15 @@ class AdminAnnouncementClientActions(AbstractAction):
text: str,
image_url: str | None = None,
*,
announce_id: str | None = None,
announce_id: str,
):
announce_id = announce_id or self.__announce_id
body = {
"id": announce_id,
"title": title,
"text": text,
"imageUrl": image_url,
}
res: bool = await self.__session.request(
res: bool = await self._session.request(
Route("POST", "/api/admin/announcements/update"),
json=body,
auth=True,
@ -57,26 +53,56 @@ class AdminAnnouncementClientActions(AbstractAction):
return res
class AdminAnnouncementActions(AdminAnnouncementClientActions):
class ClientAdminAnnouncementActions(SharedAdminAnnouncementActions):
def __init__(
self,
announce_id: str,
*,
session: HTTPClient,
client: ClientManager,
) -> None:
super().__init__(session=session, client=client)
self.__announce_id: str = announce_id
@override
async def delete(self, *, announce_id: str | None = None) -> bool:
announce_id = announce_id or self.__announce_id
return await super().delete(announce_id=announce_id)
@override
async def update(
self,
title: str,
text: str,
image_url: str | None = None,
*,
announce_id: str | None = None,
):
announce_id = announce_id or self.__announce_id
return await super().update(
title=title, text=text, image_url=image_url, announce_id=announce_id
)
class AdminAnnouncementActions(SharedAdminAnnouncementActions):
def __init__(
self,
*,
session: HTTPClient,
client: ClientManager,
):
super().__init__(announce_id=announce_id, session=session, client=client)
super().__init__(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}
created_announcement: IAnnouncement = await self.__session.request(
created_announcement: IAnnouncement = await self._session.request(
Route("POST", "/api/admin/announcements/create"),
json=body,
auth=True,
lower=True,
remove_none=False,
)
return Announcement(created_announcement, client=self.__client)
return Announcement(created_announcement, client=self._client)
async def gets(
self,
@ -97,13 +123,13 @@ class AdminAnnouncementActions(AdminAnnouncementClientActions):
}
pagination = Pagination[IAnnouncementDetailed](
self.__session, Route("POST", "/api/admin/announcements/list"), json=body
self._session, Route("POST", "/api/admin/announcements/list"), json=body
)
while True:
res_annonuncement_systems = await pagination.next()
for res_announcement_system in res_annonuncement_systems:
yield AnnouncementDetailed(res_announcement_system, client=self.__client)
yield AnnouncementDetailed(res_announcement_system, client=self._client)
if get_all is False or pagination.is_final:
break

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, AsyncGenerator
from typing import TYPE_CHECKING, AsyncGenerator, override
from mipac.abstract.action import AbstractAction
from mipac.http import HTTPClient, Route
@ -16,15 +16,12 @@ if TYPE_CHECKING:
from mipac.client import ClientManager
class ClientAntennaActions(AbstractAction):
def __init__(
self, *, antenna_id: str | None = None, session: HTTPClient, client: ClientManager
):
self._antenna_id: str | None = antenna_id
class SharedAntennaActions(AbstractAction):
def __init__(self, *, session: HTTPClient, client: ClientManager):
self._session: HTTPClient = session
self._client: ClientManager = client
async def delete(self, antenna_id: str | None = None) -> bool:
async def delete(self, *, antenna_id: str) -> bool:
"""
Delete antenna from identifier
@ -42,9 +39,6 @@ class ClientAntennaActions(AbstractAction):
bool
success or failure
"""
antenna_id = antenna_id or self._antenna_id
if antenna_id is None:
raise ValueError("antenna id is required")
body = {"antennaId": antenna_id}
res: bool = await self._session.request(
@ -52,7 +46,7 @@ class ClientAntennaActions(AbstractAction):
)
return res
async def show(self, antenna_id: str | None = None) -> Antenna:
async def show(self, *, antenna_id: str) -> Antenna:
"""Show antenna from identifier
Parameters
@ -70,10 +64,6 @@ class ClientAntennaActions(AbstractAction):
ParameterError
antenna id is required
"""
antenna_id = antenna_id or self._antenna_id
if antenna_id is None:
raise ValueError("antenna id is required")
body = {"antennaId": antenna_id}
res_antenna: IAntenna = await self._session.request(
Route("POST", "/api/antennas/show"), auth=True, json=body
@ -82,19 +72,16 @@ class ClientAntennaActions(AbstractAction):
async def get_notes(
self,
antenna_id: str | None = None,
limit: int = 10,
since_id: str | None = None,
until_id: str | None = None,
since_date: str | None = None,
until_date: str | None = None,
get_all: bool = False,
*,
antenna_id: str,
) -> AsyncGenerator[Note, None]:
antenna_id = antenna_id or self._antenna_id
if antenna_id is None:
raise ValueError("antenna id is required")
if limit > 100:
if limit > 100: # TODO: 廃止する
raise ValueError("limit must be less than 100")
if get_all:
@ -135,7 +122,8 @@ class ClientAntennaActions(AbstractAction):
with_file: bool,
notify: bool,
user_list_id: str | None = None,
antenna_id: str | None = None,
*,
antenna_id: str,
) -> Antenna:
"""Update an antenna.
@ -167,11 +155,6 @@ class ClientAntennaActions(AbstractAction):
Antenna
The created antenna.
"""
antenna_id = antenna_id or self._antenna_id
if antenna_id is None:
raise ValueError("antenna id is required")
if (
all(
[
@ -204,7 +187,147 @@ class ClientAntennaActions(AbstractAction):
return Antenna(res_antenna, client=self._client)
class AntennaActions(ClientAntennaActions):
class ClientAntennaActions(SharedAntennaActions):
def __init__(self, *, antenna_id: str, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
self._antenna_id: str = antenna_id
@override
async def delete(self, *, antenna_id: str | None = None) -> bool:
"""
Delete antenna from identifier
Parameters
----------
antenna_id : str | None, optional
target identifier
Raises
------
ParameterError
antenna id is required
Returns
-------
bool
success or failure
"""
antenna_id = antenna_id or self._antenna_id
return await super().delete(antenna_id=antenna_id)
@override
async def show(self, *, antenna_id: str | None = None) -> Antenna:
"""Show antenna from identifier
Parameters
----------
antenna_id : str | None, optional
target identifier, by default None
Returns
-------
Antenna
antenna object
Raises
------
ParameterError
antenna id is required
"""
antenna_id = antenna_id or self._antenna_id
return await super().show(antenna_id=antenna_id)
@override
async def get_notes(
self,
limit: int = 10,
since_id: str | None = None,
until_id: str | None = None,
since_date: str | None = None,
until_date: str | None = None,
get_all: bool = False,
*,
antenna_id: str | None = None,
) -> AsyncGenerator[Note, None]:
antenna_id = antenna_id or self._antenna_id
async for note in super().get_notes(
limit=limit,
since_id=since_id,
until_id=until_id,
since_date=since_date,
until_date=until_date,
get_all=get_all,
antenna_id=antenna_id,
):
yield note
@override
async def update(
self,
name: str,
src: IAntennaReceiveSource,
keywords: list[list[str]],
exclude_keywords: list[list[str]],
users: list[str],
case_sensitive: bool,
with_replies: bool,
with_file: bool,
notify: bool,
user_list_id: str | None = None,
*,
antenna_id: str | None = None,
) -> Antenna:
"""Update an antenna.
Parameters
----------
name : str
Name of the antenna.
src : IAntennaReceiveSource
Receive source of the antenna.
keywords : list[list[str]]
Receive keywords.
exclude_keywords : list[list[str]]
Excluded keywords.
users : list[str]
List of target user ID. Required when selecting 'users' as the receive source.
case_sensitive : bool
Whether to differentiate between uppercase and lowercase letters.
with_replies : bool
Whether to include replies.
with_file : bool
Whether to limit to notes with attached files.
notify : bool
Whether to notify for new notes.
user_list_id : str | None, default None
List of user IDs when selecting 'users' as the receive source for the antenna.
Returns
-------
Antenna
The created antenna.
"""
antenna_id = antenna_id or self._antenna_id
return await super().update(
name=name,
src=src,
keywords=keywords,
exclude_keywords=exclude_keywords,
users=users,
case_sensitive=case_sensitive,
with_replies=with_replies,
with_file=with_file,
notify=notify,
user_list_id=user_list_id,
antenna_id=antenna_id,
)
class AntennaActions(SharedAntennaActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, AsyncGenerator
from typing import TYPE_CHECKING, AsyncGenerator, override
from mipac.abstract.action import AbstractAction
from mipac.http import HTTPClient, Route
@ -14,9 +14,8 @@ if TYPE_CHECKING:
from mipac.manager.client import ClientManager
class ClientClipActions(AbstractAction):
def __init__(self, *, clip_id: str | None = None, session: HTTPClient, client: ClientManager):
self._clip_id = clip_id
class SharedClipActions(AbstractAction):
def __init__(self, *, session: HTTPClient, client: ClientManager):
self._session = session
self._client = client
@ -26,8 +25,9 @@ class ClientClipActions(AbstractAction):
since_id: str | None = None,
until_id: str | None = None,
get_all: bool = False,
*,
clip_id: str | None = None,
) -> AsyncGenerator[Note, None]:
) -> AsyncGenerator[Note, None]: # TODO: 作り直し
"""Get notes from a clip
Parameters
----------
@ -47,12 +47,6 @@ class ClientClipActions(AbstractAction):
AsyncGenerator[Note, None]
The notes
"""
clip_id = self._clip_id or clip_id
if clip_id is None:
raise ValueError("clip_id is required")
if limit > 100:
raise ValueError("limit must be less than 100")
@ -73,7 +67,7 @@ class ClientClipActions(AbstractAction):
if get_all is False or pagination.is_final:
break
async def add_note(self, note_id: str, clip_id: str | None = None) -> bool:
async def add_note(self, note_id: str, *, clip_id: str) -> bool:
"""Add a note to a clip
Parameters
@ -88,18 +82,13 @@ class ClientClipActions(AbstractAction):
bool
True if the note was added to the clip, False otherwise
"""
clip_id = self._clip_id or clip_id
if clip_id is None:
raise ValueError("clip_id is required")
body = {"clipId": clip_id, "noteId": note_id}
result: bool = await self._session.request(
Route("POST", "/api/clips/add-note"), json=body, auth=True
)
return result
async def remove_note(self, note_id: str, clip_id: str | None) -> bool:
async def remove_note(self, note_id: str, *, clip_id: str) -> bool:
"""Remove a note from a clip
Parameters
@ -114,18 +103,13 @@ class ClientClipActions(AbstractAction):
bool
True if the note was removed from the clip, False otherwise
"""
clip_id = self._clip_id or clip_id
if clip_id is None:
raise ValueError("clip_id is required")
body = {"clipId": clip_id, "noteId": note_id}
result: bool = await self._session.request(
Route("POST", "/api/clips/remove-note"), json=body, auth=True
)
return result
async def delete(self, clip_id: str | None = None) -> bool:
async def delete(self, *, clip_id: str) -> bool:
"""Delete a clip
Parameters
@ -138,11 +122,6 @@ class ClientClipActions(AbstractAction):
bool
True if the clip was deleted, False otherwise
"""
clip_id = self._clip_id or clip_id
if clip_id is None:
raise ValueError("clip_id is required")
body = {"clipId": clip_id}
result: bool = await self._session.request(
Route("POST", "/api/clips/delete"), json=body, auth=True
@ -154,7 +133,8 @@ class ClientClipActions(AbstractAction):
name: str,
is_public: bool | None = None,
description: str | None = None,
clip_id: str | None = None,
*,
clip_id: str,
) -> Clip:
"""Update a clip
@ -175,11 +155,6 @@ class ClientClipActions(AbstractAction):
True if the clip was updated, False otherwise
"""
clip_id = self._clip_id or clip_id
if clip_id is None:
raise ValueError("clip_id is required")
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
@ -187,9 +162,138 @@ class ClientClipActions(AbstractAction):
return Clip(result, client=self._client)
class ClipActions(ClientClipActions):
def __init__(self, *, clip_id: str | None = None, session: HTTPClient, client: ClientManager):
super().__init__(clip_id=clip_id, session=session, client=client)
class ClientClipActions(SharedClipActions): # TODO: 使うようにする
def __init__(self, clip_id: str, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
self._clip_id = clip_id
@override
async def get_notes(
self,
limit: int = 10,
since_id: str | None = None,
until_id: str | None = None,
get_all: bool = False,
*,
clip_id: str | None = None,
) -> AsyncGenerator[Note, None]:
"""Get notes from a clip
Parameters
----------
clip_id : str | None, optional, by default None
The clip id
limit : int, optional, by default 10
The number of notes to get
since_id : str | None, optional, by default None
The note id to get notes after
until_id : str | None, optional, by default None
The note id to get notes before
get_all : bool, optional, by default False
Whether to get all notes
Yields
------
AsyncGenerator[Note, None]
The notes
"""
clip_id = clip_id or self._clip_id
async for note in super().get_notes(
limit=limit, since_id=since_id, until_id=until_id, get_all=get_all, clip_id=clip_id
):
yield note
async def add_note(self, note_id: str, clip_id: str | None = None) -> bool:
"""Add a note to a clip
Parameters
----------
clip_id : str | None, optional, by default None
The clip id
note_id : str
The note id
Returns
-------
bool
True if the note was added to the clip, False otherwise
"""
clip_id = clip_id or self._clip_id
return await super().add_note(note_id=note_id, clip_id=clip_id)
async def remove_note(self, note_id: str, clip_id: str | None) -> bool:
"""Remove a note from a clip
Parameters
----------
clip_id : str | None, optional, by default None
The clip id
note_id : str
The note id
Returns
-------
bool
True if the note was removed from the clip, False otherwise
"""
clip_id = clip_id or self._clip_id
return await super().remove_note(note_id=note_id, clip_id=clip_id)
async def delete(self, clip_id: str | None = None) -> bool:
"""Delete a clip
Parameters
----------
clip_id : str | None, optional, by default None
The clip id
Returns
-------
bool
True if the clip was deleted, False otherwise
"""
clip_id = clip_id or self._clip_id
return await super().delete(clip_id=clip_id)
async def update(
self,
name: str,
is_public: bool | None = None,
description: str | None = None,
clip_id: str | None = None,
) -> Clip:
"""Update a clip
Parameters
----------
clip_id : str | None, optional, by default None
The clip id
name : str
The clip name
is_public : bool, optional
Whether the clip is public, by default None
description : str, optional
The clip description, by default None
Returns
-------
bool
True if the clip was updated, False otherwise
"""
clip_id = clip_id or self._clip_id
return await super().update(
name=name, is_public=is_public, description=description, clip_id=clip_id
)
class ClipActions(SharedClipActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
async def get_my_favorites(self):
"""Get my favorite clips

@ -18,9 +18,8 @@ if TYPE_CHECKING:
from mipac.manager.client import ClientManager
class ClientFileActions(AbstractAction):
def __init__(self, file_ids: str | None = None, *, session: HTTPClient, client: ClientManager):
self.__file_ids: str | None = file_ids
class SharedFileActions(AbstractAction):
def __init__(self, *, session: HTTPClient, client: ClientManager):
self._session: HTTPClient = session
self._client: ClientManager = client
@ -30,7 +29,7 @@ class ClientFileActions(AbstractAction):
until_id: str | None = None,
limit: int = 10,
*,
file_id: str | None = None,
file_id: str,
) -> list[Note]:
"""Get the attached notes of a file
@ -52,12 +51,6 @@ class ClientFileActions(AbstractAction):
list[Note]
The attached notes of the file
"""
file_id = file_id or self.__file_ids
if file_id is None:
raise ValueError("file_id is required")
body = {
"sinceId": since_id,
"untilId": until_id,
@ -76,13 +69,8 @@ class ClientFileActions(AbstractAction):
until_id: str | None = None,
limit: int = 10,
*,
file_id: str | None = None,
file_id: str,
) -> AsyncGenerator[Note, None]:
file_id = file_id or self.__file_ids
if file_id is None:
raise ValueError("file_id is required")
body = {
"sinceId": since_id,
"untilId": until_id,
@ -101,7 +89,7 @@ class ClientFileActions(AbstractAction):
for raw_note in await pagination.next():
yield Note(raw_note, client=self._client)
async def delete(self, *, file_id: str | None = None) -> bool:
async def delete(self, *, file_id: str) -> bool:
"""指定したファイルIDのファイルを削除します
Endpoint: `/api/drive/files/delete`
@ -116,9 +104,6 @@ class ClientFileActions(AbstractAction):
bool
削除に成功したかどうか
"""
file_id = file_id or self.__file_ids
data = {"fileId": file_id}
res: bool = await self._session.request(
@ -133,7 +118,7 @@ class ClientFileActions(AbstractAction):
is_sensitive: bool = MISSING,
comment: str | None = MISSING,
*,
file_id: str | None = None,
file_id: str,
) -> File:
"""指定したIDのファイル情報を更新します
@ -157,8 +142,6 @@ class ClientFileActions(AbstractAction):
File
更新後のファイル
"""
file_id = file_id or self.__file_ids
data = remove_dict_missing(
{
"fileId": file_id,
@ -175,7 +158,128 @@ class ClientFileActions(AbstractAction):
return File(res, client=self._client)
class FileActions(ClientFileActions):
class ClientFileActions(SharedFileActions):
def __init__(self, file_ids: str, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
self.__file_ids: str = file_ids
@override
async def get_attached_notes(
self,
since_id: str | None = None,
until_id: str | None = None,
limit: int = 10,
*,
file_id: str | None = None,
) -> list[Note]:
"""Get the attached notes of a file
Endpoint: `/api/drive/files/attached-notes`
Parameters
----------
since_id: str | None
The id of the note to start from, defaults to None
until_id: str | None
The id of the note to end at, defaults to None
limit: int
The amount of notes to get, defaults to 10
file_id: str | None
The id of the file to get notes from, defaults to None
Returns
-------
list[Note]
The attached notes of the file
"""
file_id = file_id or self.__file_ids
return await super().get_attached_notes(
since_id=since_id, until_id=until_id, limit=limit, file_id=file_id
)
@override
async def get_all_attached_notes(
self,
since_id: str | None = None,
until_id: str | None = None,
limit: int = 10,
*,
file_id: str | None = None,
) -> AsyncGenerator[Note, None]:
file_id = file_id or self.__file_ids
async for note in super().get_all_attached_notes(
since_id=since_id, until_id=until_id, limit=limit, file_id=file_id
):
yield note
@override
async def delete(self, *, file_id: str | None = None) -> bool:
"""指定したファイルIDのファイルを削除します
Endpoint: `/api/drive/files/delete`
Parameters
----------
file_id: str | None
対象のファイルID, default=None
Returns
-------
bool
削除に成功したかどうか
"""
file_id = file_id or self.__file_ids
return await super().delete(file_id=file_id)
@override
async def update(
self,
folder_id: str | None = MISSING,
name: str | None = MISSING,
is_sensitive: bool = MISSING,
comment: str | None = MISSING,
*,
file_id: str | None = None,
) -> File:
"""指定したIDのファイル情報を更新します
Endpoint: `/api/drive/files/update`
Parameters
----------
folder_id: str | None
ファイルを置くフォルダID, default=MISSING
name: str | None
ファイル名, default=MISSING
is_sensitive: bool
ファイルがセンシティブかどうか, default=MISSING
comment: str | None
ファイルのコメント, default=MISSING
file_id: str | None
対象のファイルID, default=None
Returns
-------
File
更新後のファイル
"""
file_id = file_id or self.__file_ids
return await super().update(
folder_id=folder_id,
name=name,
is_sensitive=is_sensitive,
comment=comment,
file_id=file_id,
)
class FileActions(SharedFileActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
@ -254,66 +358,6 @@ class FileActions(ClientFileActions):
for raw_file in await pagination.next():
yield File(raw_file, client=self._client)
@override
async def get_attached_notes(
self,
file_id: str,
since_id: str | None = None,
until_id: str | None = None,
limit: int = 10,
) -> list[Note]:
"""指定したファイルを含む全てのノートを取得します
Parameters
----------
file_id: str
ートを取得するファイルID
since_id: str | None
指定するとそのートIDよりも後のートを返します, default=None
until_id: str | None
指定するとそのートIDよりも前のートを返します, default=None
limit: int
一度に取得するノート数, default=10
Returns
-------
list[Note]
取得したノート
"""
return await super().get_attached_notes(
since_id=since_id, until_id=until_id, limit=limit, file_id=file_id
)
@override
async def get_all_attached_notes(
self,
file_id: str,
since_id: str | None = None,
until_id: str | None = None,
limit: int = 10,
) -> AsyncGenerator[Note, None]:
"""指定したファイルを含む全てのノートを取得します
Parameters
----------
file_id: str
ートを取得するファイルID
since_id: str | None
指定するとそのートIDよりも後のートを返します, default=None
until_id: str | None
指定するとそのートIDよりも前のートを返します, default=None
limit: int
一度に取得するノート数, default=10
Returns
-------
AsyncGenerator[Note, None]
取得したノート
"""
async for i in super().get_all_attached_notes(since_id, until_id, limit, file_id=file_id):
yield i
@credentials_required
async def check_existence(self, md5: str) -> bool:
"""指定したmd5のファイルが既に存在するか確認します
@ -398,24 +442,6 @@ class FileActions(ClientFileActions):
)
return File(res, client=self._client)
async def delete(self, file_id: str) -> bool:
"""指定したファイルIDのファイルを削除します
Endpoint: `/api/drive/files/delete`
Parameters
----------
file_id: str
対象のファイルID
Returns
-------
bool
削除に成功したかどうか
"""
return await super().delete(file_id=file_id)
async def find_by_hash(self, md5: str) -> list[File]:
"""指定したハッシュのファイルを検索します
@ -489,45 +515,6 @@ class FileActions(ClientFileActions):
)
return File(res, client=self._client)
async def update(
self,
file_id: str,
folder_id: str | None = MISSING,
name: str | None = MISSING,
is_sensitive: bool = MISSING,
comment: str | None = MISSING,
) -> File:
"""指定したIDのファイル情報を更新します
Endpoint: `/api/drive/files/update`
Parameters
----------
file_id: str
対象のファイルID
folder_id: str | None
ファイルを置くフォルダID, default=MISSING
name: str | None
ファイル名, default=MISSING
is_sensitive: bool
ファイルがセンシティブかどうか, default=MISSING
comment: str | None
ファイルのコメント, default=MISSING
Returns
-------
File
更新後のファイル
"""
return await super().update(
file_id=file_id,
folder_id=folder_id,
name=name,
is_sensitive=is_sensitive,
comment=comment,
)
async def upload_from_url(
self,
url: str,

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, override
from mipac.abstract.action import AbstractAction
from mipac.http import HTTPClient, Route
@ -154,11 +154,8 @@ class ClientFileActionsInFolder(AbstractAction):
)
class ClientFolderActions(AbstractAction):
def __init__(
self, folder_id: str | None = None, *, session: HTTPClient, client: ClientManager
):
self.__folder_id: str | None = folder_id
class SharedFolderActions(AbstractAction):
def __init__(self, *, session: HTTPClient, client: ClientManager):
self._session: HTTPClient = session
self._client: ClientManager = client
@ -168,7 +165,7 @@ class ClientFolderActions(AbstractAction):
since_id: str | None = None,
until_id: str | None = None,
*,
folder_id: str | None = None,
folder_id: str,
) -> list[Folder]:
"""Get folders
@ -194,7 +191,7 @@ class ClientFolderActions(AbstractAction):
"limit": limit,
"sinceId": since_id,
"untilId": until_id,
"folderId": folder_id or self.__folder_id,
"folderId": folder_id,
}
raw_folders: list[IFolder] = await self._session.request(
Route("POST", "/api/drive/folders"),
@ -204,7 +201,7 @@ class ClientFolderActions(AbstractAction):
return [Folder(raw_folder=raw_folder, client=self._client) for raw_folder in raw_folders]
async def create(self, name: str | None = None, *, parent_id: str | None = None) -> Folder:
async def create(self, name: str | None = None, parent_id: str | None = None) -> Folder:
"""Create a new folder
Endpoint: `/api/drive/folders/create`
@ -221,8 +218,6 @@ class ClientFolderActions(AbstractAction):
Folder
The created folder
"""
parent_id = parent_id or self.__folder_id
data = {"name": name, "parentId": parent_id}
raw_created_folder: IFolder = await self._session.request(
Route("POST", "/api/drive/folders/create"), auth=True, json=data
@ -230,7 +225,7 @@ class ClientFolderActions(AbstractAction):
return Folder(raw_folder=raw_created_folder, client=self._client)
async def delete(self, folder_id: str | None = None) -> bool:
async def delete(self, *, folder_id: str) -> bool:
"""Delete a folder
Endpoint: `/api/drive/folders/delete`
@ -245,8 +240,6 @@ class ClientFolderActions(AbstractAction):
bool
Whether the folder was deleted or not
"""
folder_id = folder_id or self.__folder_id
res: bool = await self._session.request(
Route("POST", "/api/drive/folders/delete"), auth=True, json={"folderId": folder_id}
)
@ -258,7 +251,7 @@ class ClientFolderActions(AbstractAction):
name: str | None = MISSING,
parent_id: str | None = MISSING,
*,
folder_id: str | None = None,
folder_id: str,
) -> Folder:
"""Update a folder
@ -278,9 +271,7 @@ class ClientFolderActions(AbstractAction):
Folder
The updated folder
"""
data = remove_dict_missing(
{"folderId": folder_id or self.__folder_id, "name": name, "parentId": parent_id}
)
data = remove_dict_missing({"folderId": folder_id, "name": name, "parentId": parent_id})
raw_updated_folder: IFolder = await self._session.request(
Route("POST", "/api/drive/folders/update"), auth=True, json=data
)
@ -288,15 +279,19 @@ class ClientFolderActions(AbstractAction):
return Folder(raw_folder=raw_updated_folder, client=self._client)
class FolderActions(ClientFolderActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
class ClientFolderActions(SharedFolderActions):
def __init__(self, folder_id: str, *, session: HTTPClient, client: ClientManager):
self.__folder_id: str = folder_id
self._session: HTTPClient = session
self._client: ClientManager = client
@override
async def gets(
self,
limit: int = 10,
since_id: str | None = None,
until_id: str | None = None,
*,
folder_id: str | None = None,
) -> list[Folder]:
"""Get folders
@ -305,24 +300,30 @@ class FolderActions(ClientFolderActions):
Parameters
----------
folder_id: str | None
The ID of the folder to get, defaults to None
limit: int
The limit of folders to get, defaults to 10
since_id: str | None
The ID of the folder to get since, defaults to None
until_id: str | None
The ID of the folder to get until, defaults to None
folder_id: str | None
The ID of the folder to get, defaults to None
Returns
-------
list[Folder]
The found folders
"""
folder_id = folder_id or self.__folder_id
return await super().gets(
limit=limit, since_id=since_id, until_id=until_id, folder_id=folder_id
limit=limit,
since_id=since_id,
until_id=until_id,
folder_id=folder_id,
)
@override
async def create(self, name: str | None = None, parent_id: str | None = None) -> Folder:
"""Create a new folder
@ -340,25 +341,64 @@ class FolderActions(ClientFolderActions):
Folder
The created folder
"""
parent_id = parent_id or self.__folder_id
return await super().create(name=name, parent_id=parent_id)
async def delete(self, folder_id: str) -> bool:
@override
async def delete(self, folder_id: str | None = None) -> bool:
"""Delete a folder
Endpoint: `/api/drive/folders/delete`
Parameters
----------
folder_id : str
The ID of the folder
folder_id : str, optional
The ID of the folder, by default None
Returns
-------
bool
Whether the folder was deleted or not
"""
res: bool = await super().delete(folder_id=folder_id)
return res
folder_id = folder_id or self.__folder_id
return await super().delete(folder_id=folder_id)
@override
async def update(
self,
name: str | None = MISSING,
parent_id: str | None = MISSING,
*,
folder_id: str | None = None,
) -> Folder:
"""Update a folder
Endpoint: `/api/drive/folders/update`
Parameters
----------
name : str, optional
The name of the folder, by default MISSING
parent_id : str, optional
The parent ID of the folder, by default MISSING
folder_id : str, optional
The ID of the folder, by default None
Returns
-------
Folder
The updated folder
"""
folder_id = folder_id or self.__folder_id
return await super().update(name=name, parent_id=parent_id, folder_id=folder_id)
class FolderActions(SharedFolderActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
async def find(self, name: str, parent_id: str | None = None) -> list[Folder]:
"""Find folders
@ -409,26 +449,3 @@ class FolderActions(ClientFolderActions):
)
return Folder(raw_folder=raw_folder, client=self._client)
async def update(
self, folder_id: str | None = None, name: str | None = None, parent_id: str | None = None
) -> Folder:
"""Update a folder
Endpoint: `/api/drive/folders/update`
Parameters
----------
folder_id : str
The ID of the folder
name : str, optional
The name of the folder, by default None
parent_id : str, optional
The parent ID of the folder, by default None
Returns
-------
Folder
The updated folder
"""
return await super().update(name=name, parent_id=parent_id, folder_id=folder_id)

@ -10,18 +10,12 @@ if TYPE_CHECKING:
from mipac.manager.client import ClientManager
class ClientFavoriteActions(AbstractAction):
def __init__(self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager):
self.__note_id: str | None = note_id
class SharedFavoriteActions(AbstractAction):
def __init__(self, *, session: HTTPClient, client: ClientManager):
self._session: HTTPClient = session
self._client: ClientManager = client
async def create(self, *, note_id: str | None = None) -> bool:
note_id = note_id or self.__note_id
if note_id is None:
raise ValueError("note_id is required")
async def create(self, *, note_id: str) -> bool:
data = {"noteId": note_id}
return bool(
await self._session.request(
@ -32,15 +26,10 @@ class ClientFavoriteActions(AbstractAction):
)
@deprecated
async def add(self, *, note_id: str | None = None) -> bool:
async def add(self, *, note_id: str) -> bool:
return await self.create(note_id=note_id)
async def delete(self, *, note_id: str | None = None) -> bool:
note_id = note_id or self.__note_id
if note_id is None:
raise ValueError("note_id is required")
async def delete(self, *, note_id: str) -> bool:
data = {"noteId": note_id}
return bool(
await self._session.request(
@ -51,26 +40,42 @@ class ClientFavoriteActions(AbstractAction):
)
@deprecated
async def remove(self, *, note_id: str | None = None) -> bool:
async def remove(self, *, note_id: str) -> bool:
return await self.delete(note_id=note_id)
class FavoriteActions(ClientFavoriteActions):
def __init__(self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager):
super().__init__(note_id, session=session, client=client)
class ClientFavoriteActions(SharedFavoriteActions):
def __init__(self, note_id: str, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
self.__note_id: str = note_id
@override
async def create(self, note_id: str) -> bool:
async def create(self, *, note_id: str | None = None) -> bool:
note_id = note_id or self.__note_id
return await super().create(note_id=note_id)
@deprecated
@override
async def add(self, note_id: str) -> bool:
return await super().add(note_id=note_id)
async def add(self, *, note_id: str | None = None) -> bool:
note_id = note_id or self.__note_id
return await super().create(note_id=note_id)
@override
async def delete(self, note_id: str) -> bool:
async def delete(self, *, note_id: str | None = None) -> bool:
note_id = note_id or self.__note_id
return await super().delete(note_id=note_id)
@deprecated
@override
async def remove(self, note_id: str) -> bool:
return await super().remove(note_id=note_id)
async def remove(self, *, note_id: str | None = None) -> bool:
note_id = note_id or self.__note_id
return await super().delete(note_id=note_id)
class FavoriteActions(SharedFavoriteActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, AsyncGenerator
from typing import TYPE_CHECKING, AsyncGenerator, override
from mipac.abstract.action import AbstractAction
from mipac.http import HTTPClient, Route
@ -13,13 +13,12 @@ if TYPE_CHECKING:
from mipac.manager.client import ClientManager
class ClientInviteActions(AbstractAction):
def __init__(self, invite_id: str | None, *, session: HTTPClient, client: ClientManager):
self._invite_id: str | None = invite_id
class SharedInviteActions(AbstractAction):
def __init__(self, *, session: HTTPClient, client: ClientManager):
self._session: HTTPClient = session
self._client: ClientManager = client
async def delete(self, *, invite_id: str | None = None) -> bool:
async def delete(self, *, invite_id: str) -> bool:
"""Delete an invite code.
Parameters
@ -33,8 +32,6 @@ class ClientInviteActions(AbstractAction):
Whether the invite code was deleted.
"""
invite_id = invite_id or self._invite_id
res: bool = await self._session.request(
Route("POST", "/api/invite/delete"), json={"inviteId": invite_id}, auth=True
)
@ -42,11 +39,34 @@ class ClientInviteActions(AbstractAction):
return res
class InviteActions(ClientInviteActions):
def __init__(
self, invite_id: str | None = None, *, session: HTTPClient, client: ClientManager
):
super().__init__(invite_id=invite_id, session=session, client=client)
class ClientInviteActions(SharedInviteActions):
def __init__(self, invite_id: str, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
self._invite_id: str = invite_id
@override
async def delete(self, *, invite_id: str | None = None) -> bool:
"""Delete an invite code.
Parameters
----------
invite_id : str | None, optional
The invite code to delete, by default None
Returns
-------
bool
Whether the invite code was deleted.
"""
invite_id = invite_id or self._invite_id
return await super().delete(invite_id=invite_id)
class InviteActions(SharedInviteActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
async def create(self) -> InviteCode:
"""Create a new invite code.
@ -63,24 +83,6 @@ class InviteActions(ClientInviteActions):
)
return InviteCode(raw_code, client=self._client)
async def delete(self, invite_id: str) -> bool:
"""Delete an invite code.
Endpoint: `/api/invite/delete`
Parameters
----------
invite_id : str
The invite code to delete
Returns
-------
bool
Whether the invite code was deleted.
"""
return await super().delete(invite_id=invite_id)
@credentials_required
async def get_list(
self, limit: int = 30, since_id: str | None = None, until_id: str | None = None

@ -13,18 +13,17 @@ if TYPE_CHECKING:
from mipac.manager.client import ClientManager
class ClientPollActions(AbstractAction):
def __init__(self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager):
self._note_id: str | None = note_id
class SharedPollActions(AbstractAction):
def __init__(self, *, session: HTTPClient, client: ClientManager):
self._session: HTTPClient = session
self._client: ClientManager = client
async def vote(self, choice: int, *, note_id: str | None = None) -> bool:
note_id = note_id or self._note_id
if note_id is None:
raise ValueError("note_id is required")
async def vote(
self,
choice: int,
*,
note_id: str,
) -> bool:
data = {"noteId": note_id, "choice": choice}
res: bool = await self._session.request(
Route("POST", "/api/notes/polls/vote"), auth=True, json=data
@ -32,9 +31,21 @@ class ClientPollActions(AbstractAction):
return res
class PollActions(ClientPollActions):
def __init__(self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager):
super().__init__(note_id=note_id, session=session, client=client)
class ClientPollActions(SharedPollActions):
def __init__(self, note_id: str, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
self._note_id: str = note_id
@override
async def vote(self, choice: int, *, note_id: str | None = None) -> bool:
note_id = note_id or self._note_id
return await super().vote(choice=choice, note_id=note_id)
class PollActions(SharedPollActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
@credentials_required
async def recommendation(self, limit: int = 100, offset: int = 0):
@ -68,7 +79,3 @@ class PollActions(ClientPollActions):
yield Note(note, client=self._client)
if pagination.is_final:
break
@override
async def vote(self, note_id: str, choice: int) -> bool:
return await super().vote(note_id=note_id, choice=choice)

@ -15,13 +15,12 @@ if TYPE_CHECKING:
from mipac.manager.client import ClientManager
class ClientReactionActions(AbstractAction):
def __init__(self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager):
self.__note_id: str | None = note_id
self.__session: HTTPClient = session
self.__client: ClientManager = client
class SharedReactionActions(AbstractAction):
def __init__(self, *, session: HTTPClient, client: ClientManager) -> None:
self._session: HTTPClient = session
self._client: ClientManager = client
async def add(self, reaction: str, *, note_id: str | None = None) -> bool:
async def add(self, reaction: str, *, note_id: str) -> bool:
"""Add reaction to note
Endpoint: `/api/notes/reactions/create`
@ -38,15 +37,12 @@ class ClientReactionActions(AbstractAction):
bool
success or not
"""
note_id = note_id or self.__note_id
data = remove_dict_empty({"noteId": note_id, "reaction": reaction})
route = Route("POST", "/api/notes/reactions/create")
res: bool = await self.__session.request(route, json=data, auth=True, lower=True)
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:
async def remove(self, *, note_id: str) -> bool:
"""Remove reaction from note
Endpoint: `/api/notes/reactions/delete`
@ -61,11 +57,9 @@ class ClientReactionActions(AbstractAction):
bool
success or not
"""
note_id = note_id or self.__note_id
data = remove_dict_empty({"noteId": note_id})
route = Route("POST", "/api/notes/reactions/delete")
res: bool = await self.__session.request(route, json=data, auth=True, lower=True)
res: bool = await self._session.request(route, json=data, auth=True, lower=True)
return bool(res)
@cache(group="get_note_reaction")
@ -76,13 +70,8 @@ class ClientReactionActions(AbstractAction):
since_id: str | None = None,
until_id: str | None = None,
*,
note_id: str | None = None,
note_id: str,
) -> list[NoteReaction]:
note_id = note_id or self.__note_id
if note_id is None:
raise ValueError("note_id is required.")
data = remove_dict_empty(
{
"noteId": note_id,
@ -92,13 +81,13 @@ class ClientReactionActions(AbstractAction):
"untilId": until_id,
}
)
res: list[INoteReaction] = await self.__session.request(
res: list[INoteReaction] = await self._session.request(
Route("POST", "/api/notes/reactions"),
json=data,
auth=True,
lower=True,
)
return [NoteReaction(i, client=self.__client) for i in res]
return [NoteReaction(i, client=self._client) for i in res]
@cache(group="get_note_reaction", override=True)
async def fetch_reactions(
@ -108,58 +97,105 @@ class ClientReactionActions(AbstractAction):
since_id: str | None = None,
until_id: str | None = None,
*,
note_id: str | None = None,
note_id: str,
) -> list[NoteReaction]:
return await self.get_reactions(
type=type, note_id=note_id, limit=limit, since_id=since_id, until_id=until_id
)
class ReactionActions(ClientReactionActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
class ClientReactionActions(SharedReactionActions):
def __init__(self, note_id: str, *, session: HTTPClient, client: ClientManager) -> None:
super().__init__(session=session, client=client)
self.__note_id: str = note_id
@override
async def add(self, note_id: str, reaction: str):
async def add(self, reaction: str, *, note_id: str | None = None) -> bool:
"""Add reaction to note
Endpoint: `/api/notes/reactions/create`
Parameters
----------
reaction : str
reaction
note_id : str, optional
note id, by default None
Returns
-------
bool
success or not
"""
note_id = note_id or self.__note_id
return await super().add(reaction=reaction, note_id=note_id)
@override
async def remove(self, note_id: str):
async def remove(self, *, note_id: str | None = None) -> bool:
"""Remove reaction from note
Endpoint: `/api/notes/reactions/delete`
Parameters
----------
note_id : str, optional
note id, by default None
Returns
-------
bool
success or not
"""
note_id = note_id or self.__note_id
return await super().remove(note_id=note_id)
@override
async def get_reactions(
self,
note_id: str,
type: str | None = None,
limit: int = 10,
since_id: str | None = None,
until_id: str | None = None,
):
*,
note_id: str | None = None,
) -> list[NoteReaction]:
note_id = note_id or self.__note_id
return await super().get_reactions(
type=type, limit=limit, since_id=since_id, until_id=until_id, note_id=note_id
type=type, note_id=note_id, limit=limit, since_id=since_id, until_id=until_id
)
@override
async def fetch_reactions(
self,
note_id: str,
type: str | None = None,
limit: int = 10,
since_id: str | None = None,
until_id: str | None = None,
):
*,
note_id: str | None = None,
) -> list[NoteReaction]:
note_id = note_id or self.__note_id
return await super().fetch_reactions(
type=type, limit=limit, since_id=since_id, until_id=until_id, note_id=note_id
type=type, note_id=note_id, limit=limit, since_id=since_id, until_id=until_id
)
class ReactionActions(SharedReactionActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
async def get_emoji_list(
self,
) -> list[CustomEmoji]: # TODO: metaからemojisは削除されてるので別の方法に切り替える
data: IPartialMeta = await self.__session.request(
data: IPartialMeta = await self._session.request(
Route("GET", "/api/meta"),
json={"detail": False},
auth=True,
replace_list={"ToSUrl": "tos_url", "ToSTextUrl": "tos_text_url"},
)
return [CustomEmoji(i, client=self.__client) for i in data.get("emojis", [])]
return [CustomEmoji(i, client=self._client) for i in data.get("emojis", [])]

@ -12,13 +12,12 @@ if TYPE_CHECKING:
from mipac.client import ClientManager
class ClientMuteActions(AbstractAction):
def __init__(self, user_id: str | None = None, *, session: HTTPClient, client: ClientManager):
self.__user_id: str | None = user_id
class SharedMuteActions(AbstractAction):
def __init__(self, *, session: HTTPClient, client: ClientManager):
self._session: HTTPClient = session
self._client: ClientManager = client
async def create(self, expires_at: int | None = None, *, user_id: str | None = None) -> bool:
async def create(self, expires_at: int | None = None, *, user_id: str) -> bool:
"""指定したユーザーをミュートします
Parameters
@ -33,17 +32,13 @@ class ClientMuteActions(AbstractAction):
bool
ミュートに成功したかどうか
"""
if user_id or self.__user_id:
raise ValueError("Parameter 'user_id' is required.")
body = {"userId": user_id, "expiresAt": expires_at}
res: bool = await self._session.request(route=Route("POST", "/api/mute/create"), json=body)
return res
async def delete(self, *, user_id: str | None = None) -> bool:
async def delete(self, *, user_id: str) -> bool:
"""指定したユーザーのミュートを解除します
Parameters
@ -56,10 +51,6 @@ class ClientMuteActions(AbstractAction):
bool
ミュート解除に成功したかどうか
"""
if user_id or self.__user_id:
raise ValueError("Parameter 'user_id' is required.")
res: bool = await self._session.request(
route=Route("POST", "/api/mute/delete"), json={"userId": user_id}
)
@ -67,7 +58,51 @@ class ClientMuteActions(AbstractAction):
return res
class MuteActions(ClientMuteActions):
class ClientMuteActions(SharedMuteActions):
def __init__(self, user_id: str, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
self.__user_id: str = user_id
@override
async def create(self, expires_at: int | None = None, *, user_id: str | None = None) -> bool:
"""指定したユーザーをミュートします
Parameters
----------
user_id : str
対象のユーザーID
expires_at : int | None
ミュートする期間()無期限でミュートする場合はNoneを指定します
Returns
-------
bool
ミュートに成功したかどうか
"""
user_id = user_id or self.__user_id
return await super().create(expires_at=expires_at, user_id=user_id or self.__user_id)
@override
async def delete(self, *, user_id: str | None = None) -> bool:
"""指定したユーザーのミュートを解除します
Parameters
----------
user_id : str
対象のユーザーID
Returns
-------
bool
ミュート解除に成功したかどうか
"""
user_id = user_id or self.__user_id
return await super().delete(user_id=user_id or self.__user_id)
class MuteActions(SharedMuteActions):
def __init__(self, *, session: HTTPClient, client: ClientManager):
super().__init__(session=session, client=client)
@ -118,41 +153,3 @@ class MuteActions(ClientMuteActions):
while pagination.is_final is False:
for raw_muted_user in await pagination.next():
yield MutedUser(raw_mute_user=raw_muted_user, client=self._client)
@override
async def create(
self,
user_id: str,
expires_at: int | None = None,
) -> bool:
"""指定したユーザーをミュートします
Parameters
----------
user_id : str
対象のユーザーID
expires_at : int | None
ミュートする期間()無期限でミュートする場合はNoneを指定します
Returns
-------
bool
ミュートに成功したかどうか
"""
return await super().create(user_id=user_id, expires_at=expires_at)
@override
async def delete(self, user_id: str) -> bool:
"""指定したユーザーのミュートを解除します
Parameters
----------
user_id : str
対象のユーザーID
Returns
-------
bool
ミュート解除に成功したかどうか
"""
return await super().delete(user_id=user_id)

@ -3,36 +3,36 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Literal
from mipac.abstract.manager import AbstractManager
from mipac.actions.admins.ad import AdminAdvertisingActions, AdminAdvertisingModelActions
from mipac.actions.admins.ad import AdminAdActions, ClientAdminAdActions
from mipac.http import HTTPClient, Route
if TYPE_CHECKING:
from mipac.client import ClientManager
__all__ = ("AdminAdvertisingManager", "AdminAdvertisingModelManager")
__all__ = ("AdminAdManager", "ClientAdminAdManager")
class AdminAdvertisingModelManager(AbstractManager):
def __init__(self, ad_id: str | None = None, *, session: HTTPClient, client: ClientManager):
self.__ad_id: str | None = ad_id
class ClientAdminAdManager(AbstractManager):
def __init__(self, ad_id: str, *, session: HTTPClient, client: ClientManager):
self.__ad_id: str = ad_id
self.__session: HTTPClient = session
self.__client: ClientManager = client
@property
def action(self) -> AdminAdvertisingModelActions:
return AdminAdvertisingModelActions(
def action(self) -> ClientAdminAdActions:
return ClientAdminAdActions(
ad_id=self.__ad_id, session=self.__session, client=self.__client
)
class AdminAdvertisingManager(AbstractManager):
class AdminAdManager(AbstractManager):
def __init__(self, *, session: HTTPClient, client: ClientManager):
self.__session: HTTPClient = session
self.__client: ClientManager = client
@property
def action(self) -> AdminAdvertisingActions:
return AdminAdvertisingActions(session=self.__session, client=self.__client)
def action(self) -> AdminAdActions:
return AdminAdActions(session=self.__session, client=self.__client)
async def create(
self,

@ -5,8 +5,11 @@ from typing import TYPE_CHECKING
from mipac.abstract.manager import AbstractManager
from mipac.actions.admins.admin import AdminActions
from mipac.http import HTTPClient
from mipac.manager.admins.ad import AdminAdvertisingManager, AdminAdvertisingModelManager
from mipac.manager.admins.announcement import AdminAnnouncementManager
from mipac.manager.admins.ad import AdminAdManager, ClientAdminAdManager
from mipac.manager.admins.announcement import (
AdminAnnouncementManager,
ClientAdminAnnouncementManager,
)
from mipac.manager.admins.drive import AdminDriveManager
from mipac.manager.admins.emoji import AdminEmojiManager
from mipac.manager.admins.invite import AdminInviteManager
@ -24,7 +27,7 @@ class AdminManager(AbstractManager):
self.__client: ClientManager = client
self.emoji: AdminEmojiManager = AdminEmojiManager(session=session, client=client)
self.user: AdminUserManager = AdminUserManager(session=session, client=client)
self.ad: AdminAdvertisingManager = AdminAdvertisingManager(session=session, client=client)
self.ad: AdminAdManager = AdminAdManager(session=session, client=client)
self.moderator: AdminModeratorManager = AdminModeratorManager(
session=session, client=client
)
@ -44,7 +47,14 @@ class AdminManager(AbstractManager):
role_id=role_id, session=self.__session, client=self.__client
)
def create_ad_model_manager(self, ad_id: str | None = None) -> AdminAdvertisingModelManager:
return AdminAdvertisingModelManager(
ad_id=ad_id, session=self.__session, client=self.__client
def _create_client_ad_manager(self, ad_id: str) -> ClientAdminAdManager:
return ClientAdminAdManager(ad_id=ad_id, session=self.__session, client=self.__client)
def _create_client_announcement_manager(
self, announce_id: str
) -> ClientAdminAnnouncementManager:
return ClientAdminAnnouncementManager(
announce_id=announce_id,
session=self.__session,
client=self.__client,
)

@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
from mipac.abstract.manager import AbstractManager
from mipac.actions.admins.announcement import (
AdminAnnouncementActions,
AdminAnnouncementClientActions,
ClientAdminAnnouncementActions,
)
from mipac.http import HTTPClient
@ -13,20 +13,27 @@ if TYPE_CHECKING:
from mipac.manager.client import ClientManager
class ClientAdminAnnouncementManager(AbstractManager):
def __init__(self, announce_id: str, *, session: HTTPClient, client: ClientManager):
self.__announce_id: str = announce_id
self.__session: HTTPClient = session
self.__client: ClientManager = client
@property
def action(self) -> ClientAdminAnnouncementActions:
return ClientAdminAnnouncementActions(
announce_id=self.__announce_id, session=self.__session, client=self.__client
)
class AdminAnnouncementManager(AbstractManager):
def __init__(self, *, session: HTTPClient, client: ClientManager):
self.__session: HTTPClient = session
self.__client: ClientManager = client
self.__action: AdminAnnouncementActions = AdminAnnouncementActions(
session=self.__session, client=self.__client
)
@property
def action(self) -> AdminAnnouncementActions:
return AdminAnnouncementActions(session=self.__session, client=self.__client)
def _create_client_announcement_instance(
self, announce_id: str
) -> AdminAnnouncementClientActions:
return AdminAnnouncementClientActions(
announce_id=announce_id,
session=self.__session,
client=self.__client,
)
return self.__action

@ -8,7 +8,7 @@ from mipac.manager.admins.admin import AdminManager
from mipac.manager.antenna import AntennaManager
from mipac.manager.channel import ChannelManager, ClientChannelManager
from mipac.manager.chart import ChartManager
from mipac.manager.clip import ClipManager
from mipac.manager.clip import ClientClipManager, ClipManager
from mipac.manager.drive.drive import DriveManager
from mipac.manager.emoji import EmojiManager
from mipac.manager.follow import FollowManager, FollowRequestManager
@ -83,5 +83,8 @@ class ClientManager:
def _create_client_user_manager(self, user: PartialUser) -> ClientUserManager:
return ClientUserManager(user=user, session=self.__session, client=self)
def _get_client_clip_instance(self, *, clip_id: str) -> ClientClipManager:
return ClientClipManager(clip_id=clip_id, session=self.__session, client=self)
async def get_me(self) -> MeDetailed:
return await self.user.action.get_me()

@ -3,7 +3,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from mipac.abstract.manager import AbstractManager
from mipac.actions.clip import ClipActions
from mipac.actions.clip import ClientClipActions, ClipActions
from mipac.http import HTTPClient
if TYPE_CHECKING:
@ -13,7 +13,7 @@ if TYPE_CHECKING:
class ClientClipManager(AbstractManager):
def __init__(
self,
clip_id: str | None = None,
clip_id: str,
*,
session: HTTPClient,
client: ClientManager,
@ -23,8 +23,8 @@ class ClientClipManager(AbstractManager):
self.__client = client
@property
def action(self) -> ClipActions:
return ClipActions(
def action(self) -> ClientClipActions:
return ClientClipActions(
clip_id=self.__clip_id,
session=self.__session,
client=self.__client,
@ -39,6 +39,3 @@ class ClipManager(AbstractManager):
@property
def action(self) -> ClipActions:
return ClipActions(session=self.__session, client=self.__client)
def _get_client_clip_instance(self, *, clip_id: str | None = None) -> ClientClipManager:
return ClientClipManager(clip_id=clip_id, session=self.__session, client=self.__client)

@ -43,8 +43,8 @@ class NoteManager(AbstractManager):
self.__session: HTTPClient = session
self.__client: ClientManager = client
self.reaction: ReactionManager = ReactionManager(session=session, client=client)
self.favorite = FavoriteManager(note_id=note_id, session=session, client=client)
self.poll: PollManager = PollManager(note_id=note_id, session=session, client=client)
self.favorite = FavoriteManager(session=session, client=client)
self.poll: PollManager = PollManager(session=session, client=client)
self.__action: NoteActions = NoteActions(
note_id=self.__note_id,
session=self.__session,

@ -11,30 +11,25 @@ if TYPE_CHECKING:
class ClientPollManager(AbstractManager):
def __init__(self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager):
self.__note_id: str | None = note_id
def __init__(self, note_id: str, *, session: HTTPClient, client: ClientManager):
self.__note_id: str = note_id
self.__session: HTTPClient = session
self.__client: ClientManager = client
self.__action: ClientPollActions = ClientPollActions(
note_id=self.__note_id, session=self.__session, client=self.__client
)
@property
def action(self) -> ClientPollActions:
return ClientPollActions(
note_id=self.__note_id,
session=self.__session,
client=self.__client,
)
return self.__action
class PollManager(AbstractManager):
def __init__(self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager):
self.__note_id: str | None = note_id
def __init__(self, *, session: HTTPClient, client: ClientManager):
self.__session: HTTPClient = session
self.__client: ClientManager = client
self.__action: PollActions = PollActions(session=self.__session, client=self.__client)
@property
def action(self) -> PollActions:
return PollActions(
note_id=self.__note_id,
session=self.__session,
client=self.__client,
)
return self.__action

@ -11,11 +11,12 @@ if TYPE_CHECKING:
class ClientReactionManager(AbstractManager):
def __init__(self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager):
def __init__(self, note_id: str, *, session: HTTPClient, client: ClientManager):
self.__note_id: str | None = note_id
self.__session: HTTPClient = session
self.__client: ClientManager = client
self.__action = ClientReactionActions(
note_id=self.__note_id,
session=self.__session,
client=self.__client,
)

@ -7,7 +7,7 @@ from mipac.types.announcement import IAnnouncement, IAnnouncementDetailed
from mipac.utils.format import str_to_datetime
if TYPE_CHECKING:
from mipac.actions.admins.announcement import AdminAnnouncementClientActions
from mipac.manager.admins.announcement import ClientAdminAnnouncementManager
from mipac.manager.client import ClientManager
@ -75,10 +75,8 @@ class Announcement:
return not self.__eq__(__value)
@property
def action(self) -> AdminAnnouncementClientActions:
return self.__client.admin.announcement._create_client_announcement_instance(
announce_id=self.id
)
def action(self) -> ClientAdminAnnouncementManager:
return self.__client.admin._create_client_announcement_manager(announce_id=self.id)
class AnnouncementDetailed:
@ -154,7 +152,5 @@ class AnnouncementDetailed:
return not self.__eq__(__value)
@property
def action(self) -> AdminAnnouncementClientActions:
return self.__client.admin.announcement._create_client_announcement_instance(
announce_id=self.id
)
def action(self) -> ClientAdminAnnouncementManager:
return self.__client.admin._create_client_announcement_manager(announce_id=self.id)

@ -67,4 +67,4 @@ class Clip:
@property
def api(self) -> ClientClipManager:
return self.__client.clip._get_client_clip_instance(clip_id=self.id)
return self.__client._get_client_clip_instance(clip_id=self.id)

@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Any, TypeVar
from mipac.types.ads import IAdPlaces, IPartialAd
if TYPE_CHECKING:
from mipac.manager.admins.ad import AdminAdvertisingModelManager
from mipac.manager.admins.ad import ClientAdminAdManager
from mipac.manager.client import ClientManager
@ -53,8 +53,8 @@ class PartialAd[T: IPartialAd]:
return self._raw_ad.get(key)
@property
def api(self) -> AdminAdvertisingModelManager:
return self._client.admin.create_ad_model_manager(ad_id=self.id)
def api(self) -> ClientAdminAdManager:
return self._client.admin._create_client_ad_manager(ad_id=self.id)
def __eq__(self, __value: object) -> bool:
return isinstance(__value, PartialAd) and self.id == __value.id

@ -40,8 +40,8 @@ class MutedUser:
def mutee(self) -> UserDetailedNotMe:
return UserDetailedNotMe(self.__raw_mute_user["mutee"], client=self.__client)
def __eq__(self, __value: MutedUser) -> bool:
def __eq__(self, __value: object) -> bool:
return isinstance(__value, MutedUser) and self.id == __value.id
def __ne__(self, __value: MutedUser) -> bool:
def __ne__(self, __value: object) -> bool:
return not self.__eq__(__value)

Loading…
Cancel
Save