diff --git a/mipac/actions/channel.py b/mipac/actions/channel.py index 811be2b..2e1e9c0 100644 --- a/mipac/actions/channel.py +++ b/mipac/actions/channel.py @@ -20,15 +20,11 @@ if TYPE_CHECKING: from mipac.client import ClientManager -class ClientChannelActions(AbstractAction): - def __init__( - self, channel_id: str | None = None, *, session: HTTPClient, client: ClientManager - ): - self._channel_id: str | None = channel_id +class SharedChannelActions(AbstractAction): + def __init__(self, *, session: HTTPClient, client: ClientManager): self._session: HTTPClient = session self._client: ClientManager = client - @credentials_required async def send( self, text: str | None = None, @@ -45,7 +41,7 @@ class ClientChannelActions(AbstractAction): files: list[MiFile | File | str] | None = None, poll: MiPoll | None = None, *, - channel_id: str | None = None, + channel_id: str, ) -> Note: """Send a note @@ -87,7 +83,6 @@ class ClientChannelActions(AbstractAction): Note Created note """ - channel_id = channel_id or self._channel_id return await self._client.note.action.send( text=text, cw=cw, @@ -105,8 +100,7 @@ class ClientChannelActions(AbstractAction): local_only=local_only, ) - @credentials_required - async def follow(self, *, channel_id: str | None = None) -> bool: + async def follow(self, *, channel_id: str) -> bool: """Follow a channel Endpoint: `/api/channels/follow` @@ -121,7 +115,6 @@ class ClientChannelActions(AbstractAction): bool Whether the channel is followed """ - channel_id = channel_id or self._channel_id data = {"channelId": channel_id} res: bool = await self._session.request( @@ -129,8 +122,7 @@ class ClientChannelActions(AbstractAction): ) return res - @credentials_required - async def unfollow(self, *, channel_id: str | None = None) -> bool: + async def unfollow(self, *, channel_id: str) -> bool: """指定したIDのチャンネルのフォローを解除します Endpoint: `/api/channels/unfollow` @@ -145,11 +137,6 @@ class ClientChannelActions(AbstractAction): bool フォロー解除に成功したかどうか """ - channel_id = channel_id or self._channel_id - - if channel_id is None: - raise ValueError("channel_id is required") - data = {"channelId": channel_id} res: bool = await self._session.request( @@ -168,7 +155,7 @@ class ClientChannelActions(AbstractAction): is_sensitive: bool | None = MISSING, allow_renote_to_external: bool | None = MISSING, *, - channel_id: str | None = None, + channel_id: str, ) -> Channel: """チャンネルの情報を更新します @@ -200,11 +187,6 @@ class ClientChannelActions(AbstractAction): Channel 更新後のチャンネル """ - channel_id = channel_id or self._channel_id - - if channel_id is None: - raise ValueError("channel_id is required") - data = remove_dict_missing( { "channelId": channel_id, @@ -231,7 +213,7 @@ class ClientChannelActions(AbstractAction): since_date: int | None = None, until_date: int | None = None, *, - channel_id: str | None = None, + channel_id: str, ) -> list[Note]: """チャンネルのタイムラインを取得します @@ -257,8 +239,6 @@ class ClientChannelActions(AbstractAction): list[Note] 取得したノートのリスト """ - channel_id = channel_id or self._channel_id - if channel_id is None: raise ValueError("channel_id is required") @@ -283,7 +263,7 @@ class ClientChannelActions(AbstractAction): since_date: int | None = None, until_date: int | None = None, *, - channel_id: str | None = None, + channel_id: str, ) -> AsyncGenerator[Note, None]: """チャンネルのタイムラインを全て取得します @@ -309,11 +289,6 @@ class ClientChannelActions(AbstractAction): AsyncGenerator[Note, None] 取得したノートのリスト """ - channel_id = channel_id or self._channel_id - - if channel_id is None: - raise ValueError("channel_id is required") - data = { "channelId": channel_id, "sinceId": since_id, @@ -331,7 +306,7 @@ class ClientChannelActions(AbstractAction): yield Note(raw_note=raw_note, client=self._client) @credentials_required - async def favorite(self, *, channel_id: str | None = None) -> bool: + async def favorite(self, *, channel_id: str) -> bool: """指定したIDのチャンネルをお気に入りにします Endpoint: `/api/channels/favorite` @@ -346,7 +321,6 @@ class ClientChannelActions(AbstractAction): bool お気に入りに追加できたかどうか """ - channel_id = channel_id or self._channel_id data = {"channelId": channel_id} res: bool = await self._session.request( @@ -355,7 +329,7 @@ class ClientChannelActions(AbstractAction): return res @credentials_required - async def unfavorite(self, *, channel_id: str | None = None) -> bool: + async def unfavorite(self, *, channel_id: str) -> bool: """指定したIDのチャンネルをお気に入りから外します Endpoint: `/api/channels/unfavorite` @@ -370,11 +344,6 @@ class ClientChannelActions(AbstractAction): bool お気に入りから外せたかどうか """ - channel_id = channel_id or self._channel_id - - if channel_id is None: - raise ValueError("channel_id is required") - data = {"channelId": channel_id} res: bool = await self._session.request( @@ -383,17 +352,15 @@ class ClientChannelActions(AbstractAction): return res -class ChannelActions(ClientChannelActions): - def __init__( - self, channel_id: str | None = None, *, session: HTTPClient, client: ClientManager - ): - super().__init__(channel_id=channel_id, session=session, client=client) +class ClientChannelActions(SharedChannelActions): + def __init__(self, channel_id: str, *, session: HTTPClient, client: ClientManager): + self._channel_id: str = channel_id + self._session: HTTPClient = session + self._client: ClientManager = client - @credentials_required @override async def send( self, - channel_id: str, text: str | None = None, visibility: INoteVisibility = "public", visible_user_ids: list[str] | None = None, @@ -407,6 +374,8 @@ class ChannelActions(ClientChannelActions): renote_id: str | None = None, files: list[MiFile | File | str] | None = None, poll: MiPoll | None = None, + *, + channel_id: str | None = None, ) -> Note: """Send a note @@ -448,6 +417,7 @@ class ChannelActions(ClientChannelActions): Note Created note """ + channel_id = channel_id or self._channel_id return await super().send( text=text, cw=cw, @@ -465,7 +435,236 @@ class ChannelActions(ClientChannelActions): local_only=local_only, ) - @credentials_required + @override + async def follow(self, *, channel_id: str) -> bool: + """Follow a channel + + Endpoint: `/api/channels/follow` + + Parameters + ---------- + channel_id : str, optional + ID of the channel, by default None + + Returns + ------- + bool + Whether the channel is followed + """ + return await super().follow(channel_id=channel_id) + + @override + async def unfollow(self, *, channel_id: str) -> bool: + """指定したIDのチャンネルのフォローを解除します + + Endpoint: `/api/channels/unfollow` + + Parameters + ---------- + channel_id : str | None + 対象のチャンネルID, default=None + + Returns + ------- + bool + フォロー解除に成功したかどうか + """ + return await super().unfollow(channel_id=channel_id) + + @override + async def update( + self, + name: str | None = MISSING, + description: str | None = MISSING, + banner_id: str | None = MISSING, + is_archived: bool | None = MISSING, + pinned_note_ids: list[str] | None = MISSING, + color: str | None = MISSING, + is_sensitive: bool | None = MISSING, + allow_renote_to_external: bool | None = MISSING, + *, + channel_id: str, + ) -> Channel: + """チャンネルの情報を更新します + + Endpoint: `/api/channels/update` + + Parameters + ---------- + name : str | None + チャンネル名, default=MISSING + description : str | None + チャンネルの説明, default=MISSING + banner_id : str | None + バナー画像のID, default=MISSING + is_archived : bool | None + チャンネルがアーカイブされているかどうか, default=MISSING + pinned_note_ids : list[str] | None + ピン留めするノートのIDリスト, default=MISSING + color : str | None + チャンネルの色, default=MISSING + is_sensitive : bool | None + チャンネルがセンシティブかどうか, default=MISSING + allow_renote_to_external : bool | None + 外部へのリノートを許可するかどうか, default=MISSING + channel_id : str | None + 対象のチャンネルID, default=None + + Returns + ------- + Channel + 更新後のチャンネル + """ + channel_id = channel_id or self._channel_id + + return await super().update( + name=name, + description=description, + banner_id=banner_id, + is_archived=is_archived, + pinned_note_ids=pinned_note_ids, + color=color, + is_sensitive=is_sensitive, + allow_renote_to_external=allow_renote_to_external, + channel_id=channel_id, + ) + + @override + async def timeline( + self, + limit: int = 10, + since_id: str | None = None, + until_id: str | None = None, + since_date: int | None = None, + until_date: int | None = None, + *, + channel_id: str, + ) -> list[Note]: + """チャンネルのタイムラインを取得します + + Endpoint: `/api/channels/timeline` + + Parameters + ---------- + limit : int + 一度に取得する件数, default=10 + since_id : str | None + 指定したIDのノートより後のノートを取得します, default=None + until_id : str | None + 指定したIDのノートより前のノートを取得します, default=None + since_date : int | None + 指定した日付のノートより後のノートを取得します, default=None + until_date : int | None + 指定した日付のノートより前のノートを取得します, default=None + channel_id : str | None + 対象のチャンネルID, default=None + + Returns + ------- + list[Note] + 取得したノートのリスト + """ + channel_id = channel_id or self._channel_id + + return await super().timeline( + limit=limit, + since_id=since_id, + until_id=until_id, + since_date=since_date, + until_date=until_date, + channel_id=channel_id, + ) + + @override + async def get_all_timeline( + self, + since_id: str | None = None, + until_id: str | None = None, + since_date: int | None = None, + until_date: int | None = None, + *, + channel_id: str | None = None, + ) -> AsyncGenerator[Note, None]: + """チャンネルのタイムラインを全て取得します + + Endpoint: `/api/channels/timeline` + + Parameters + ---------- + limit : int + 一度に取得する件数, default=10 + since_id : str | None + 指定したIDのノートより後のノートを取得します, default=None + until_id : str | None + 指定したIDのノートより前のノートを取得します, default=None + since_date : int | None + 指定した日付のノートより後のノートを取得します, default=None + until_date : int | None + 指定した日付のノートより前のノートを取得します, default=None + channel_id : str | None + 対象のチャンネルID, default=None + + Returns + ------- + AsyncGenerator[Note, None] + 取得したノートのリスト + """ + channel_id = channel_id or self._channel_id + + async for i in super().get_all_timeline( + since_id=since_id, + until_id=until_id, + since_date=since_date, + until_date=until_date, + channel_id=channel_id, + ): + yield i + + @override + async def favorite(self, *, channel_id: str) -> bool: + """指定したIDのチャンネルをお気に入りにします + + Endpoint: `/api/channels/favorite` + + Parameters + ---------- + channel_id : str | None + 対象のチャンネルID, default=None + + Returns + ------- + bool + お気に入りに追加できたかどうか + """ + channel_id = channel_id or self._channel_id + + return await super().favorite(channel_id=channel_id) + + @override + async def unfavorite(self, *, channel_id: str) -> bool: + """指定したIDのチャンネルをお気に入りから外します + + Endpoint: `/api/channels/unfavorite` + + Parameters + ---------- + channel_id : str | None + 対象のチャンネルID, default=None + + Returns + ------- + bool + お気に入りから外せたかどうか + """ + channel_id = channel_id or self._channel_id + + return await super().unfavorite(channel_id=channel_id) + + +class ChannelActions(SharedChannelActions): + def __init__(self, *, session: HTTPClient, client: ClientManager): + super().__init__(session=session, client=client) + async def create( self, name: str, @@ -536,56 +735,6 @@ class ChannelActions(ClientChannelActions): Channel(raw_channel=raw_channel, client=self._client) for raw_channel in raw_channels ] - @credentials_required - @override - async def follow(self, channel_id: str) -> bool: - """指定したIDのチャンネルをフォローします - - Endpoint: `/api/channels/follow` - - Parameters - ---------- - channel_id : str - 対象のチャンネルID - - Returns - ------- - bool - フォローに成功したかどうか - """ - return await super().follow(channel_id=channel_id) - - @credentials_required - async def followed( - self, since_id: str | None = None, until_id: str | None = None, limit: int = 5 - ) -> list[Channel]: - """フォロー中のチャンネル一覧を取得します - - Endpoint: `/api/channels/followed` - - Parameters - ---------- - since_id : str | None - 指定したチャンネルIDよりも後のチャンネルを取得します, default=None - until_id : str | None - 指定したチャンネルIDよりも前のチャンネルを取得します, default=None - limit : int, optional - 一度に取得するチャンネルの数, default=5 - - Returns - ------- - list[Channel] - 取得したフォロー中のチャンネルのリスト - """ - data = {"sinceId": since_id, "untilId": until_id, "limit": limit} - - raw_channels: list[IChannel] = await self._session.request( - Route("POST", "/api/channels/followed"), auth=True, json=data - ) - return [ - Channel(raw_channel=raw_channel, client=self._client) for raw_channel in raw_channels - ] - async def get_all_followed( self, since_id: str | None = None, until_id: str | None = None, limit: int = 5 ) -> AsyncGenerator[Channel, None]: @@ -618,7 +767,6 @@ class ChannelActions(ClientChannelActions): for raw_channel in await pagination.next(): yield Channel(raw_channel=raw_channel, client=self._client) - @credentials_required async def owned( self, since_id: str | None = None, until_id: str | None = None, limit: int = 5 ) -> list[Channel]: @@ -701,207 +849,6 @@ class ChannelActions(ClientChannelActions): ) return Channel(raw_channel=raw_channel, client=self._client) - @credentials_required - @override - async def unfollow(self, channel_id: str) -> bool: - """指定したIDのチャンネルのフォローを解除します - - Endpoint: `/api/channels/unfollow` - - Parameters - ---------- - channel_id : str - 対象のチャンネルID - - Returns - ------- - bool - フォロー解除に成功したかどうか - """ - return await super().unfollow(channel_id=channel_id) - - @override - async def timeline( - self, - channel_id: str, - limit: int = 10, - since_id: str | None = None, - until_id: str | None = None, - since_date: int | None = None, - until_date: int | None = None, - ) -> list[Note]: - """チャンネルのタイムラインを取得します - - Endpoint: `/api/channels/timeline` - - Parameters - ---------- - channel_id : str - 対象のチャンネルID - limit : int - 一度に取得する件数, default=10 - since_id : str | None - 指定したIDのノートより後のノートを取得します, default=None - until_id : str | None - 指定したIDのノートより前のノートを取得します, default=None - since_date : int | None - 指定した日付のノートより後のノートを取得します, default=None - until_date : int | None - 指定した日付のノートより前のノートを取得します, default=None - - Returns - ------- - list[Note] - 取得したノートのリスト - """ - - return await super().timeline( - channel_id=channel_id, - limit=limit, - since_id=since_id, - until_id=until_id, - since_date=since_date, - until_date=until_date, - ) - - @override - async def get_all_timeline( - self, - channel_id: str, - since_id: str | None = None, - until_id: str | None = None, - since_date: int | None = None, - until_date: int | None = None, - ) -> AsyncGenerator[Note, None]: - """チャンネルのタイムラインを全て取得します - - Endpoint: `/api/channels/timeline` - - Parameters - ---------- - limit : int - 一度に取得する件数, default=10 - since_id : str | None - 指定したIDのノートより後のノートを取得します, default=None - until_id : str | None - 指定したIDのノートより前のノートを取得します, default=None - since_date : int | None - 指定した日付のノートより後のノートを取得します, default=None - until_date : int | None - 指定した日付のノートより前のノートを取得します, default=None - channel_id : str | None - 対象のチャンネルID, default=None - - Returns - ------- - AsyncGenerator[Note, None] - 取得したノートのリスト - """ - async for i in super().get_all_timeline( - since_id=since_id, - until_id=until_id, - since_date=since_date, - until_date=until_date, - channel_id=channel_id, - ): - yield i - - @credentials_required - @override - async def update( - self, - channel_id: str, - name: str | None = MISSING, - description: str | None = MISSING, - banner_id: str | None = MISSING, - is_archived: bool | None = MISSING, - pinned_note_ids: list[str] | None = MISSING, - color: str | None = MISSING, - is_sensitive: bool | None = MISSING, - allow_renote_to_external: bool | None = MISSING, - ) -> Channel: - """チャンネルの情報を更新します - - Endpoint: `/api/channels/update` - - Parameters - ---------- - channel_id : str - 対象のチャンネルID - name : str | None - チャンネル名, default=MISSING - description : str | None - チャンネルの説明, default=MISSING - banner_id : str | None - バナー画像のID, default=MISSING - is_archived : bool | None - チャンネルがアーカイブされているかどうか, default=MISSING - pinned_note_ids : list[str] | None - ピン留めするノートのIDリスト, default=MISSING - color : str | None - チャンネルの色, default=MISSING - is_sensitive : bool | None - チャンネルがセンシティブかどうか, default=MISSING - allow_renote_to_external : bool | None - 外部へのリノートを許可するかどうか, default=MISSING - - Returns - ------- - Channel - 更新後のチャンネル - """ - - return await super().update( - channel_id=channel_id, - name=name, - description=description, - banner_id=banner_id, - is_archived=is_archived, - pinned_note_ids=pinned_note_ids, - color=color, - is_sensitive=is_sensitive, - allow_renote_to_external=allow_renote_to_external, - ) - - @credentials_required - @override - async def favorite(self, channel_id: str) -> bool: - """指定したIDのチャンネルをお気に入りにします - - Endpoint: `/api/channels/favorite` - - Parameters - ---------- - channel_id : str - 対象のチャンネルID - - Returns - ------- - bool - お気に入りに追加できたかどうか - """ - return await super().favorite(channel_id=channel_id) - - @credentials_required - @override - async def unfavorite(self, channel_id: str) -> bool: - """指定したIDのチャンネルをお気に入りから外します - - Endpoint: `/api/channels/unfavorite` - - Parameters - ---------- - channel_id : str - 対象のチャンネルID - - Returns - ------- - bool - お気に入りから外せたかどうか - """ - return await super().unfavorite(channel_id=channel_id) - - @credentials_required async def my_favorites(self) -> list[Channel]: """自分がお気に入りにしているチャンネルを取得します @@ -919,7 +866,6 @@ class ChannelActions(ClientChannelActions): Channel(raw_channel=raw_channel, client=self._client) for raw_channel in raw_channels ] - @credentials_required async def search( self, query: str, diff --git a/mipac/manager/channel.py b/mipac/manager/channel.py index 0a27840..5db2547 100644 --- a/mipac/manager/channel.py +++ b/mipac/manager/channel.py @@ -25,15 +25,13 @@ class ClientChannelManager(AbstractManager): class ChannelManager(AbstractManager): - def __init__( - self, channel_id: str | None = None, *, session: HTTPClient, client: ClientManager - ): - self.__channel_id: str | None = channel_id + def __init__(self, *, session: HTTPClient, client: ClientManager): self.__session: HTTPClient = session self.__client: ClientManager = client + self.__action: ChannelActions = ChannelActions( + session=self.__session, client=self.__client + ) @property def action(self) -> ChannelActions: - return ChannelActions( - channel_id=self.__channel_id, session=self.__session, client=self.__client - ) + return self.__action