Add GuildChannel.move helper method to help with moving channels
Moving channels is seen as a complicated task, so hopefully this abstracts a lot of it for users. There is no bulk move helper yet since I'm unsure how the API for that should be.
This commit is contained in:
parent
f60e91d700
commit
b850c9cd5d
114
discord/abc.py
114
discord/abc.py
@ -708,6 +708,120 @@ class GuildChannel:
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
async def move(self, **kwargs):
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
A rich interface to help move a channel relative to other channels.
|
||||||
|
|
||||||
|
If exact position movement is required, :meth:`edit` should be used instead.
|
||||||
|
|
||||||
|
You must have the :attr:`~discord.Permissions.manage_channels` permission to
|
||||||
|
do this.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Voice channels will always be sorted below text channels.
|
||||||
|
This is a Discord limitation.
|
||||||
|
|
||||||
|
.. versionadded:: 1.7
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
------------
|
||||||
|
beginning: :class:`bool`
|
||||||
|
Whether to move the channel to the beginning of the
|
||||||
|
channel list (or category if given).
|
||||||
|
This is mutually exclusive with ``end``, ``before``, and ``after``.
|
||||||
|
end: :class:`bool`
|
||||||
|
Whether to move the channel to the end of the
|
||||||
|
channel list (or category if given).
|
||||||
|
This is mutually exclusive with ``beginning``, ``before``, and ``after``.
|
||||||
|
before: :class:`abc.Snowflake`
|
||||||
|
The channel that should be before our current channel.
|
||||||
|
This is mutually exclusive with ``beginning``, ``end``, and ``after``.
|
||||||
|
after: :class:`abc.Snowflake`
|
||||||
|
The channel that should be after our current channel.
|
||||||
|
This is mutually exclusive with ``beginning``, ``end``, and ``before``.
|
||||||
|
offset: :class:`int`
|
||||||
|
The number of channels to offset the move by. For example,
|
||||||
|
an offset of ``2`` with ``beginning=True`` would move
|
||||||
|
it 2 after the beginning. A positive number moves it below
|
||||||
|
while a negative number moves it above. Note that this
|
||||||
|
number is relative and computed after the ``beginning``,
|
||||||
|
``end``, ``before``, and ``after`` parameters.
|
||||||
|
category: Optional[:class:`abc.Snowflake`]
|
||||||
|
The category to move this channel under.
|
||||||
|
If ``None`` is given then it moves it out of the category.
|
||||||
|
sync_permissions: :class:`bool`
|
||||||
|
Whether to sync the permissions with the category (if given).
|
||||||
|
reason: :class:`str`
|
||||||
|
The reason for the move.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
InvalidArgument
|
||||||
|
An invalid position was given or a bad mix of arguments were passed.
|
||||||
|
Forbidden
|
||||||
|
You do not have permissions to move the channel.
|
||||||
|
HTTPException
|
||||||
|
Moving the channel failed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
beginning, end = kwargs.get('beginning'), kwargs.get('end')
|
||||||
|
before, after = kwargs.get('before'), kwargs.get('after')
|
||||||
|
offset = kwargs.get('offset', 0)
|
||||||
|
if sum(bool(a) for a in (beginning, end, before, after)) > 1:
|
||||||
|
raise InvalidArgument('Only one of [before, after, end, beginning] can be used.')
|
||||||
|
|
||||||
|
bucket = self._sorting_bucket
|
||||||
|
parent_id = kwargs.get('category', ...)
|
||||||
|
if parent_id not in (..., None):
|
||||||
|
parent_id = parent_id.id
|
||||||
|
channels = [
|
||||||
|
ch
|
||||||
|
for ch in self.guild.channels
|
||||||
|
if ch._sorting_bucket == bucket
|
||||||
|
and ch.category_id == parent_id
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
channels = [
|
||||||
|
ch
|
||||||
|
for ch in self.guild.channels
|
||||||
|
if ch._sorting_bucket == bucket
|
||||||
|
and ch.category_id == self.category_id
|
||||||
|
]
|
||||||
|
|
||||||
|
channels.sort(key=lambda c: (c.position, c.id))
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Try to remove ourselves from the channel list
|
||||||
|
channels.remove(self)
|
||||||
|
except ValueError:
|
||||||
|
# If we're not there then it's probably due to not being in the category
|
||||||
|
pass
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
if beginning:
|
||||||
|
index = 0
|
||||||
|
elif end:
|
||||||
|
index = len(channels)
|
||||||
|
elif before:
|
||||||
|
index = next((i for i, c in enumerate(channels) if c.id == before.id), 0)
|
||||||
|
elif after:
|
||||||
|
index = next((i + 1 for i, c in enumerate(channels) if c.id == after.id), len(channels))
|
||||||
|
|
||||||
|
channels.insert(max((index + offset), 0), self)
|
||||||
|
payload = []
|
||||||
|
lock_permissions = kwargs.get('sync_permissions', False)
|
||||||
|
reason = kwargs.get('reason')
|
||||||
|
for index, channel in enumerate(channels):
|
||||||
|
d = { 'id': channel.id, 'position': index }
|
||||||
|
if parent_id is not ... and channel.id == self.id:
|
||||||
|
d.update(parent_id=parent_id, lock_permissions=lock_permissions)
|
||||||
|
payload.append(d)
|
||||||
|
|
||||||
|
await self._state.http.bulk_channel_update(self.guild.id, payload, reason=reason)
|
||||||
|
|
||||||
|
|
||||||
async def create_invite(self, *, reason=None, **fields):
|
async def create_invite(self, *, reason=None, **fields):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user