mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-07-05 17:41:53 +00:00
Stateful Message and remove Invite.xkcd since it is removed.
This commit is contained in:
parent
1070cf0735
commit
f33eaa4a61
123
discord/abc.py
123
discord/abc.py
@ -32,6 +32,7 @@ import asyncio
|
|||||||
from .message import Message
|
from .message import Message
|
||||||
from .iterators import LogsFromIterator
|
from .iterators import LogsFromIterator
|
||||||
from .context_managers import Typing
|
from .context_managers import Typing
|
||||||
|
from .errors import ClientException, NoMoreMessages
|
||||||
|
|
||||||
class Snowflake(metaclass=abc.ABCMeta):
|
class Snowflake(metaclass=abc.ABCMeta):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
@ -287,6 +288,40 @@ class MessageChannel(metaclass=abc.ABCMeta):
|
|||||||
data = yield from self._state.http.get_message(self.id, id)
|
data = yield from self._state.http.get_message(self.id, id)
|
||||||
return Message(channel=self, state=self._state, data=data)
|
return Message(channel=self, state=self._state, data=data)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def delete_messages(self, messages):
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Deletes a list of messages. This is similar to :meth:`Message.delete`
|
||||||
|
except it bulk deletes multiple messages.
|
||||||
|
|
||||||
|
Usable only by bot accounts.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
messages : iterable of :class:`Message`
|
||||||
|
An iterable of messages denoting which ones to bulk delete.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
ClientException
|
||||||
|
The number of messages to delete is less than 2 or more than 100.
|
||||||
|
Forbidden
|
||||||
|
You do not have proper permissions to delete the messages or
|
||||||
|
you're not using a bot account.
|
||||||
|
HTTPException
|
||||||
|
Deleting the messages failed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
messages = list(messages)
|
||||||
|
if len(messages) > 100 or len(messages) < 2:
|
||||||
|
raise ClientException('Can only delete messages in the range of [2, 100]')
|
||||||
|
|
||||||
|
message_ids = [m.id for m in messages]
|
||||||
|
channel_id, guild_id = self._get_destination()
|
||||||
|
|
||||||
|
yield from self._state.http.delete_messages(channel_id, message_ids, guild_id)
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def pins(self):
|
def pins(self):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
@ -367,3 +402,91 @@ class MessageChannel(metaclass=abc.ABCMeta):
|
|||||||
counter += 1
|
counter += 1
|
||||||
"""
|
"""
|
||||||
return LogsFromIterator(self, limit=limit, before=before, after=after, around=around, reverse=reverse)
|
return LogsFromIterator(self, limit=limit, before=before, after=after, around=around, reverse=reverse)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def purge(self, *, limit=100, check=None, before=None, after=None, around=None):
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Purges a list of messages that meet the criteria given by the predicate
|
||||||
|
``check``. If a ``check`` is not provided then all messages are deleted
|
||||||
|
without discrimination.
|
||||||
|
|
||||||
|
You must have :attr:`Permissions.manage_messages` permission to
|
||||||
|
delete messages even if they are your own. The
|
||||||
|
:attr:`Permissions.read_message_history` permission is also needed to
|
||||||
|
retrieve message history.
|
||||||
|
|
||||||
|
Usable only by bot accounts.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
limit: int
|
||||||
|
The number of messages to search through. This is not the number
|
||||||
|
of messages that will be deleted, though it can be.
|
||||||
|
check: predicate
|
||||||
|
The function used to check if a message should be deleted.
|
||||||
|
It must take a :class:`Message` as its sole parameter.
|
||||||
|
before
|
||||||
|
Same as ``before`` in :meth:`history`.
|
||||||
|
after
|
||||||
|
Same as ``after`` in :meth:`history`.
|
||||||
|
around
|
||||||
|
Same as ``around`` in :meth:`history`.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
Forbidden
|
||||||
|
You do not have proper permissions to do the actions required or
|
||||||
|
you're not using a bot account.
|
||||||
|
HTTPException
|
||||||
|
Purging the messages failed.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
---------
|
||||||
|
|
||||||
|
Deleting bot's messages ::
|
||||||
|
|
||||||
|
def is_me(m):
|
||||||
|
return m.author == client.user
|
||||||
|
|
||||||
|
deleted = await channel.purge(limit=100, check=is_me)
|
||||||
|
await channel.send_message('Deleted {} message(s)'.format(len(deleted)))
|
||||||
|
|
||||||
|
Returns
|
||||||
|
--------
|
||||||
|
list
|
||||||
|
The list of messages that were deleted.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if check is None:
|
||||||
|
check = lambda m: True
|
||||||
|
|
||||||
|
iterator = self.history(limit=limit, before=before, after=after, around=around)
|
||||||
|
ret = []
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
msg = yield from iterator.get()
|
||||||
|
except NoMoreMessages:
|
||||||
|
# no more messages to poll
|
||||||
|
if count >= 2:
|
||||||
|
# more than 2 messages -> bulk delete
|
||||||
|
to_delete = ret[-count:]
|
||||||
|
yield from self.delete_messages(to_delete)
|
||||||
|
elif count == 1:
|
||||||
|
# delete a single message
|
||||||
|
yield from ret[-1].delete()
|
||||||
|
|
||||||
|
return ret
|
||||||
|
else:
|
||||||
|
if count == 100:
|
||||||
|
# we've reached a full 'queue'
|
||||||
|
to_delete = ret[-100:]
|
||||||
|
yield from self.delete_messages(to_delete)
|
||||||
|
count = 0
|
||||||
|
yield from asyncio.sleep(1)
|
||||||
|
|
||||||
|
if check(msg):
|
||||||
|
count += 1
|
||||||
|
ret.append(msg)
|
||||||
|
@ -50,34 +50,32 @@ class Invite(Hashable):
|
|||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
-----------
|
-----------
|
||||||
max_age : int
|
max_age: int
|
||||||
How long the before the invite expires in seconds. A value of 0 indicates that it doesn't expire.
|
How long the before the invite expires in seconds. A value of 0 indicates that it doesn't expire.
|
||||||
code : str
|
code: str
|
||||||
The URL fragment used for the invite. :attr:`xkcd` is also a possible fragment.
|
The URL fragment used for the invite. :attr:`xkcd` is also a possible fragment.
|
||||||
server : :class:`Server`
|
server: :class:`Server`
|
||||||
The server the invite is for.
|
The server the invite is for.
|
||||||
revoked : bool
|
revoked: bool
|
||||||
Indicates if the invite has been revoked.
|
Indicates if the invite has been revoked.
|
||||||
created_at : `datetime.datetime`
|
created_at: `datetime.datetime`
|
||||||
A datetime object denoting the time the invite was created.
|
A datetime object denoting the time the invite was created.
|
||||||
temporary : bool
|
temporary: bool
|
||||||
Indicates that the invite grants temporary membership.
|
Indicates that the invite grants temporary membership.
|
||||||
If True, members who joined via this invite will be kicked upon disconnect.
|
If True, members who joined via this invite will be kicked upon disconnect.
|
||||||
uses : int
|
uses: int
|
||||||
How many times the invite has been used.
|
How many times the invite has been used.
|
||||||
max_uses : int
|
max_uses: int
|
||||||
How many times the invite can be used.
|
How many times the invite can be used.
|
||||||
xkcd : str
|
inviter: :class:`User`
|
||||||
The URL fragment used for the invite if it is human readable.
|
|
||||||
inviter : :class:`User`
|
|
||||||
The user who created the invite.
|
The user who created the invite.
|
||||||
channel : :class:`Channel`
|
channel: :class:`Channel`
|
||||||
The channel the invite is for.
|
The channel the invite is for.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
__slots__ = ( 'max_age', 'code', 'server', 'revoked', 'created_at', 'uses',
|
__slots__ = ( 'max_age', 'code', 'server', 'revoked', 'created_at', 'uses',
|
||||||
'temporary', 'max_uses', 'xkcd', 'inviter', 'channel', '_state' )
|
'temporary', 'max_uses', 'inviter', 'channel', '_state' )
|
||||||
|
|
||||||
def __init__(self, *, state, data):
|
def __init__(self, *, state, data):
|
||||||
self._state = state
|
self._state = state
|
||||||
@ -89,7 +87,6 @@ class Invite(Hashable):
|
|||||||
self.temporary = data.get('temporary')
|
self.temporary = data.get('temporary')
|
||||||
self.uses = data.get('uses')
|
self.uses = data.get('uses')
|
||||||
self.max_uses = data.get('max_uses')
|
self.max_uses = data.get('max_uses')
|
||||||
self.xkcd = data.get('xkcdpass')
|
|
||||||
|
|
||||||
inviter_data = data.get('inviter')
|
inviter_data = data.get('inviter')
|
||||||
self.inviter = None if inviter_data is None else User(state=state, data=data)
|
self.inviter = None if inviter_data is None else User(state=state, data=data)
|
||||||
@ -101,7 +98,7 @@ class Invite(Hashable):
|
|||||||
@property
|
@property
|
||||||
def id(self):
|
def id(self):
|
||||||
"""Returns the proper code portion of the invite."""
|
"""Returns the proper code portion of the invite."""
|
||||||
return self.xkcd if self.xkcd else self.code
|
return self.code
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def url(self):
|
def url(self):
|
||||||
|
@ -24,12 +24,14 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|||||||
DEALINGS IN THE SOFTWARE.
|
DEALINGS IN THE SOFTWARE.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import re
|
||||||
|
|
||||||
from .user import User
|
from .user import User
|
||||||
from .reaction import Reaction
|
from .reaction import Reaction
|
||||||
from . import utils, abc
|
from . import utils, abc
|
||||||
from .object import Object
|
from .object import Object
|
||||||
from .calls import CallMessage
|
from .calls import CallMessage
|
||||||
import re
|
|
||||||
from .enums import MessageType, try_enum
|
from .enums import MessageType, try_enum
|
||||||
|
|
||||||
class Message:
|
class Message:
|
||||||
@ -343,3 +345,86 @@ class Message:
|
|||||||
return 'You missed a call from {0.author.name}'.format(self)
|
return 'You missed a call from {0.author.name}'.format(self)
|
||||||
else:
|
else:
|
||||||
return '{0.author.name} started a call \N{EM DASH} Join the call.'.format(self)
|
return '{0.author.name} started a call \N{EM DASH} Join the call.'.format(self)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def delete(self):
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Deletes the message.
|
||||||
|
|
||||||
|
Your own messages could be deleted without any proper permissions. However to
|
||||||
|
delete other people's messages, you need the :attr:`Permissions.manage_messages`
|
||||||
|
permission.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
Forbidden
|
||||||
|
You do not have proper permissions to delete the message.
|
||||||
|
HTTPException
|
||||||
|
Deleting the message failed.
|
||||||
|
"""
|
||||||
|
yield from self._state.http.delete_message(self.channel.id, self.id, getattr(self.server, 'id', None))
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def edit(self, *, content: str):
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Edits the message.
|
||||||
|
|
||||||
|
The content must be able to be transformed into a string via ``str(content)``.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
content: str
|
||||||
|
The new content to replace the message with.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
HTTPException
|
||||||
|
Editing the message failed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
guild_id = getattr(self.server, 'id', None)
|
||||||
|
data = yield from self._state.http.edit_message(self.id, self.channel.id, str(content), guild_id=guild_id)
|
||||||
|
self._update(channel=self.channel, data=data)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def pin(self):
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Pins the message. You must have :attr:`Permissions.manage_messages`
|
||||||
|
permissions to do this in a non-private channel context.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
Forbidden
|
||||||
|
You do not have permissions to pin the message.
|
||||||
|
NotFound
|
||||||
|
The message or channel was not found or deleted.
|
||||||
|
HTTPException
|
||||||
|
Pinning the message failed, probably due to the channel
|
||||||
|
having more than 50 pinned messages.
|
||||||
|
"""
|
||||||
|
|
||||||
|
yield from self._state.http.pin_message(self.channel.id, self.id)
|
||||||
|
self.pinned = True
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def unpin(self):
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Unpins the message. You must have :attr:`Permissions.manage_messages`
|
||||||
|
permissions to do this in a non-private channel context.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
Forbidden
|
||||||
|
You do not have permissions to unpin the message.
|
||||||
|
NotFound
|
||||||
|
The message or channel was not found or deleted.
|
||||||
|
HTTPException
|
||||||
|
Unpinning the message failed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
yield from self._state.http.unpin_message(self.channel.id, self.id)
|
||||||
|
self.pinned = False
|
||||||
|
Loading…
x
Reference in New Issue
Block a user