mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-09-04 08:56:19 +00:00
Add support for newest ForumChannel changes
This adds the following: - Forum tag support - Default reaction support - Default slowmode for newly created threads
This commit is contained in:
@ -24,15 +24,16 @@ DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Callable, Dict, Iterable, List, Literal, Optional, Union, TYPE_CHECKING
|
||||
from typing import Callable, Dict, Iterable, List, Literal, Optional, Sequence, Union, TYPE_CHECKING
|
||||
from datetime import datetime
|
||||
import array
|
||||
|
||||
from .mixins import Hashable
|
||||
from .abc import Messageable, _purge_helper
|
||||
from .enums import ChannelType, try_enum
|
||||
from .errors import ClientException
|
||||
from .flags import ChannelFlags
|
||||
from .utils import MISSING, parse_time, _get_as_snowflake
|
||||
from .utils import MISSING, parse_time, _get_as_snowflake, _unique
|
||||
|
||||
__all__ = (
|
||||
'Thread',
|
||||
@ -50,7 +51,7 @@ if TYPE_CHECKING:
|
||||
)
|
||||
from .types.snowflake import SnowflakeList
|
||||
from .guild import Guild
|
||||
from .channel import TextChannel, CategoryChannel, ForumChannel
|
||||
from .channel import TextChannel, CategoryChannel, ForumChannel, ForumTag
|
||||
from .member import Member
|
||||
from .message import Message, PartialMessage
|
||||
from .abc import Snowflake, SnowflakeTime
|
||||
@ -149,6 +150,7 @@ class Thread(Messageable, Hashable):
|
||||
'archive_timestamp',
|
||||
'_created_at',
|
||||
'_flags',
|
||||
'_applied_tags',
|
||||
)
|
||||
|
||||
def __init__(self, *, guild: Guild, state: ConnectionState, data: ThreadPayload) -> None:
|
||||
@ -180,6 +182,8 @@ class Thread(Messageable, Hashable):
|
||||
self.message_count: int = data['message_count']
|
||||
self.member_count: int = data['member_count']
|
||||
self._flags: int = data.get('flags', 0)
|
||||
# SnowflakeList is sorted, but this would not be proper for applied tags, where order actually matters.
|
||||
self._applied_tags: array.array[int] = array.array('Q', map(int, data.get('applied_tags', [])))
|
||||
self._unroll_metadata(data['thread_metadata'])
|
||||
|
||||
self.me: Optional[ThreadMember]
|
||||
@ -255,6 +259,24 @@ class Thread(Messageable, Hashable):
|
||||
"""
|
||||
return list(self._members.values())
|
||||
|
||||
@property
|
||||
def applied_tags(self) -> List[ForumTag]:
|
||||
"""List[:class:`ForumTag`]: A list of tags applied to this thread.
|
||||
|
||||
.. versionadded:: 2.1
|
||||
"""
|
||||
tags = []
|
||||
if self.parent is None or self.parent.type != ChannelType.forum:
|
||||
return tags
|
||||
|
||||
parent = self.parent
|
||||
for tag_id in self._applied_tags:
|
||||
tag = parent.get_tag(tag_id)
|
||||
if tag is not None:
|
||||
tags.append(tag)
|
||||
|
||||
return tags
|
||||
|
||||
@property
|
||||
def starter_message(self) -> Optional[Message]:
|
||||
"""Returns the thread starter message from the cache.
|
||||
@ -542,6 +564,7 @@ class Thread(Messageable, Hashable):
|
||||
pinned: bool = MISSING,
|
||||
slowmode_delay: int = MISSING,
|
||||
auto_archive_duration: ThreadArchiveDuration = MISSING,
|
||||
applied_tags: Sequence[ForumTag] = MISSING,
|
||||
reason: Optional[str] = None,
|
||||
) -> Thread:
|
||||
"""|coro|
|
||||
@ -574,6 +597,10 @@ class Thread(Messageable, Hashable):
|
||||
slowmode_delay: :class:`int`
|
||||
Specifies the slowmode rate limit for user in this thread, in seconds.
|
||||
A value of ``0`` disables slowmode. The maximum value possible is ``21600``.
|
||||
applied_tags: Sequence[:class:`ForumTag`]
|
||||
The new tags to apply to the thread. There can only be up to 5 tags applied to a thread.
|
||||
|
||||
.. versionadded:: 2.1
|
||||
reason: Optional[:class:`str`]
|
||||
The reason for editing this thread. Shows up on the audit log.
|
||||
|
||||
@ -606,11 +633,87 @@ class Thread(Messageable, Hashable):
|
||||
flags = self.flags
|
||||
flags.pinned = pinned
|
||||
payload['flags'] = flags.value
|
||||
if applied_tags is not MISSING:
|
||||
payload['applied_tags'] = [str(tag.id) for tag in applied_tags]
|
||||
|
||||
data = await self._state.http.edit_channel(self.id, **payload, reason=reason)
|
||||
# The data payload will always be a Thread payload
|
||||
return Thread(data=data, state=self._state, guild=self.guild) # type: ignore
|
||||
|
||||
async def add_tags(self, *tags: Snowflake, reason: Optional[str] = None) -> None:
|
||||
r"""|coro|
|
||||
|
||||
Adds the given forum tags to a thread.
|
||||
|
||||
You must have the :attr:`~Permissions.manage_threads` permission to
|
||||
use this or the thread must be owned by you.
|
||||
|
||||
Tags that have :attr:`ForumTag.moderated` set to ``True`` require the
|
||||
:attr:`~Permissions.manage_threads` permissions to be added.
|
||||
|
||||
The maximum number of tags that can be added to a thread is 5.
|
||||
|
||||
The parent channel must be a :class:`ForumChannel`.
|
||||
|
||||
.. versionadded:: 2.1
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
\*tags: :class:`abc.Snowflake`
|
||||
An argument list of :class:`abc.Snowflake` representing a :class:`ForumTag`
|
||||
to add to the thread.
|
||||
reason: Optional[:class:`str`]
|
||||
The reason for adding these tags.
|
||||
|
||||
Raises
|
||||
-------
|
||||
Forbidden
|
||||
You do not have permissions to add these tags.
|
||||
HTTPException
|
||||
Adding tags failed.
|
||||
"""
|
||||
|
||||
applied_tags = [str(tag) for tag in self._applied_tags]
|
||||
applied_tags.extend(str(tag.id) for tag in tags)
|
||||
|
||||
await self._state.http.edit_channel(self.id, applied_tags=_unique(applied_tags), reason=reason)
|
||||
|
||||
async def remove_tags(self, *tags: Snowflake, reason: Optional[str] = None) -> None:
|
||||
r"""|coro|
|
||||
|
||||
Remove the given forum tags to a thread.
|
||||
|
||||
You must have the :attr:`~Permissions.manage_threads` permission to
|
||||
use this or the thread must be owned by you.
|
||||
|
||||
The parent channel must be a :class:`ForumChannel`.
|
||||
|
||||
.. versionadded:: 2.1
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
\*tags: :class:`abc.Snowflake`
|
||||
An argument list of :class:`abc.Snowflake` representing a :class:`ForumTag`
|
||||
to remove to the thread.
|
||||
reason: Optional[:class:`str`]
|
||||
The reason for removing these tags.
|
||||
|
||||
Raises
|
||||
-------
|
||||
Forbidden
|
||||
You do not have permissions to remove these tags.
|
||||
HTTPException
|
||||
Removing tags failed.
|
||||
"""
|
||||
|
||||
# Once again, taking advantage of the fact that dicts are ordered since 3.7
|
||||
applied_tags: Dict[str, Literal[None]] = {str(tag): None for tag in self._applied_tags}
|
||||
|
||||
for tag in tags:
|
||||
applied_tags.pop(str(tag.id), None)
|
||||
|
||||
await self._state.http.edit_channel(self.id, applied_tags=list(applied_tags.keys()), reason=reason)
|
||||
|
||||
async def join(self) -> None:
|
||||
"""|coro|
|
||||
|
||||
|
Reference in New Issue
Block a user