mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-05-14 17:59:48 +00:00
parent
8727472b85
commit
2abdbc70c2
@ -740,7 +740,7 @@ class Messageable(metaclass=abc.ABCMeta):
|
|||||||
return [state.create_message(channel=channel, data=m) for m in data]
|
return [state.create_message(channel=channel, data=m) for m in data]
|
||||||
|
|
||||||
def history(self, *, limit=100, before=None, after=None, around=None, reverse=None):
|
def history(self, *, limit=100, before=None, after=None, around=None, reverse=None):
|
||||||
"""Return an async iterator that enables receiving the destination's message history.
|
"""Return an :class:`AsyncIterator` that enables receiving the destination's message history.
|
||||||
|
|
||||||
You must have Read Message History permissions to use this.
|
You must have Read Message History permissions to use this.
|
||||||
|
|
||||||
|
@ -35,7 +35,108 @@ from .object import Object
|
|||||||
|
|
||||||
PY35 = sys.version_info >= (3, 5)
|
PY35 = sys.version_info >= (3, 5)
|
||||||
|
|
||||||
class ReactionIterator:
|
@asyncio.coroutine
|
||||||
|
def _probably_coroutine(f, e):
|
||||||
|
if asyncio.iscoroutinefunction(f):
|
||||||
|
return (yield from f(e))
|
||||||
|
else:
|
||||||
|
return f(e)
|
||||||
|
|
||||||
|
class _AsyncIterator:
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
|
def get(self, **attrs):
|
||||||
|
def predicate(elem):
|
||||||
|
for attr, val in attrs.items():
|
||||||
|
nested = attr.split('__')
|
||||||
|
obj = elem
|
||||||
|
for attribute in nested:
|
||||||
|
obj = getattr(obj, attribute)
|
||||||
|
|
||||||
|
if obj != val:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
return self.find(predicate)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def find(self, predicate):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
elem = yield from self.get()
|
||||||
|
except NoMoreItems:
|
||||||
|
return None
|
||||||
|
|
||||||
|
ret = yield from _probably_coroutine(predicate, elem)
|
||||||
|
if ret:
|
||||||
|
return elem
|
||||||
|
|
||||||
|
def map(self, func):
|
||||||
|
return _MappedAsyncIterator(self, func)
|
||||||
|
|
||||||
|
def filter(self, predicate):
|
||||||
|
return _FilteredAsyncIterator(self, predicate)
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def flatten(self):
|
||||||
|
ret = []
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
item = yield from self.get()
|
||||||
|
except NoMoreItems:
|
||||||
|
return ret
|
||||||
|
else:
|
||||||
|
ret.append(item)
|
||||||
|
|
||||||
|
if PY35:
|
||||||
|
@asyncio.coroutine
|
||||||
|
def __aiter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def __anext__(self):
|
||||||
|
try:
|
||||||
|
msg = yield from self.get()
|
||||||
|
except NoMoreItems:
|
||||||
|
raise StopAsyncIteration()
|
||||||
|
else:
|
||||||
|
return msg
|
||||||
|
|
||||||
|
def _identity(x):
|
||||||
|
return x
|
||||||
|
|
||||||
|
class _MappedAsyncIterator(_AsyncIterator):
|
||||||
|
def __init__(self, iterator, func):
|
||||||
|
self.iterator = iterator
|
||||||
|
self.func = func
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def get(self):
|
||||||
|
# this raises NoMoreItems and will propagate appropriately
|
||||||
|
item = yield from self.iterator.get()
|
||||||
|
return (yield from _probably_coroutine(self.func, item))
|
||||||
|
|
||||||
|
class _FilteredAsyncIterator(_AsyncIterator):
|
||||||
|
def __init__(self, iterator, predicate):
|
||||||
|
self.iterator = iterator
|
||||||
|
|
||||||
|
if predicate is None:
|
||||||
|
predicate = _identity
|
||||||
|
|
||||||
|
self.predicate = predicate
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def get(self):
|
||||||
|
getter = self.iterator.get
|
||||||
|
pred = self.predicate
|
||||||
|
while True:
|
||||||
|
# propagate NoMoreItems similar to _MappedAsyncIterator
|
||||||
|
item = yield from getter()
|
||||||
|
ret = yield from _probably_coroutine(pred, item)
|
||||||
|
if ret:
|
||||||
|
return item
|
||||||
|
|
||||||
|
class ReactionIterator(_AsyncIterator):
|
||||||
def __init__(self, message, emoji, limit=100, after=None):
|
def __init__(self, message, emoji, limit=100, after=None):
|
||||||
self.message = message
|
self.message = message
|
||||||
self.limit = limit
|
self.limit = limit
|
||||||
@ -85,32 +186,7 @@ class ReactionIterator:
|
|||||||
else:
|
else:
|
||||||
yield from self.users.put(User(state=self.state, data=element))
|
yield from self.users.put(User(state=self.state, data=element))
|
||||||
|
|
||||||
@asyncio.coroutine
|
class HistoryIterator(_AsyncIterator):
|
||||||
def flatten(self):
|
|
||||||
ret = []
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
user = yield from self.get()
|
|
||||||
except NoMoreItems:
|
|
||||||
return ret
|
|
||||||
else:
|
|
||||||
ret.append(user)
|
|
||||||
|
|
||||||
if PY35:
|
|
||||||
@asyncio.coroutine
|
|
||||||
def __aiter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
|
||||||
def __anext__(self):
|
|
||||||
try:
|
|
||||||
msg = yield from self.get()
|
|
||||||
except NoMoreItems:
|
|
||||||
raise StopAsyncIteration()
|
|
||||||
else:
|
|
||||||
return msg
|
|
||||||
|
|
||||||
class HistoryIterator:
|
|
||||||
"""Iterator for receiving a channel's message history.
|
"""Iterator for receiving a channel's message history.
|
||||||
|
|
||||||
The messages endpoint has two behaviours we care about here:
|
The messages endpoint has two behaviours we care about here:
|
||||||
@ -281,18 +357,3 @@ class HistoryIterator:
|
|||||||
self.around = None
|
self.around = None
|
||||||
return data
|
return data
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if PY35:
|
|
||||||
@asyncio.coroutine
|
|
||||||
def __aiter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
|
||||||
def __anext__(self):
|
|
||||||
try:
|
|
||||||
msg = yield from self.get()
|
|
||||||
return msg
|
|
||||||
except NoMoreItems:
|
|
||||||
# if we're still empty at this point...
|
|
||||||
# we didn't get any new messages so stop looping
|
|
||||||
raise StopAsyncIteration()
|
|
||||||
|
@ -89,7 +89,7 @@ class Reaction:
|
|||||||
def users(self, limit=None, after=None):
|
def users(self, limit=None, after=None):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
Returns an asynchronous iterator representing the
|
Returns an :class:`AsyncIterator` representing the
|
||||||
users that have reacted to the message.
|
users that have reacted to the message.
|
||||||
|
|
||||||
The ``after`` parameter must represent a member
|
The ``after`` parameter must represent a member
|
||||||
|
84
docs/api.rst
84
docs/api.rst
@ -40,14 +40,6 @@ Client
|
|||||||
.. autoclass:: AutoShardedClient
|
.. autoclass:: AutoShardedClient
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
|
||||||
Voice
|
|
||||||
-----
|
|
||||||
|
|
||||||
.. autoclass:: VoiceClient
|
|
||||||
:members:
|
|
||||||
|
|
||||||
|
|
||||||
Opus Library
|
Opus Library
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -683,6 +675,82 @@ All enumerations are subclasses of `enum`_.
|
|||||||
|
|
||||||
You have sent a friend request to this user.
|
You have sent a friend request to this user.
|
||||||
|
|
||||||
|
Async Iterator
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Some API functions return an "async iterator". An async iterator is something that is
|
||||||
|
capable of being used in an `async for <https://docs.python.org/3/reference/compound_stmts.html#the-async-for-statement>`_
|
||||||
|
statement.
|
||||||
|
|
||||||
|
These async iterators can be used as follows in 3.5 or higher: ::
|
||||||
|
|
||||||
|
async for elem in channel.history():
|
||||||
|
# do stuff with elem here
|
||||||
|
|
||||||
|
If you are using 3.4 however, you will have to use the more verbose way: ::
|
||||||
|
|
||||||
|
iterator = channel.history() # or whatever returns an async iterator
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
item = yield from iterator.get()
|
||||||
|
except discord.NoMoreItems:
|
||||||
|
break
|
||||||
|
|
||||||
|
# do stuff with item here
|
||||||
|
|
||||||
|
Certain utilities make working with async iterators easier, detailed below.
|
||||||
|
|
||||||
|
.. class:: AsyncIterator
|
||||||
|
|
||||||
|
Represents the "AsyncIterator" concept. Note that no such class exists,
|
||||||
|
it is purely abstract.
|
||||||
|
|
||||||
|
.. method:: get(**attrs)
|
||||||
|
|
||||||
|
|coro|
|
||||||
|
|
||||||
|
Similar to :func:`utils.get` except run over the async iterator.
|
||||||
|
|
||||||
|
.. method:: find(predicate)
|
||||||
|
|
||||||
|
|coro|
|
||||||
|
|
||||||
|
Similar to :func:`utils.find` except run over the async iterator.
|
||||||
|
|
||||||
|
Unlike :func:`utils.find`\, the predicate provided can be a
|
||||||
|
coroutine.
|
||||||
|
|
||||||
|
:param predicate: The predicate to use. Can be a coroutine.
|
||||||
|
:return: The first element that returns ``True`` for the predicate or ``None``.
|
||||||
|
|
||||||
|
.. method:: flatten()
|
||||||
|
|
||||||
|
|coro|
|
||||||
|
|
||||||
|
Flattens the async iterator into a ``list`` with all the elements.
|
||||||
|
|
||||||
|
:return: A list of every element in the async iterator.
|
||||||
|
:rtype: list
|
||||||
|
|
||||||
|
.. method:: map(func)
|
||||||
|
|
||||||
|
This is similar to the built-in ``map`` function. Another
|
||||||
|
:class:`AsyncIterator` is returned that executes the function on
|
||||||
|
every element it is iterating over. This function can either be a
|
||||||
|
regular function or a coroutine.
|
||||||
|
|
||||||
|
:param func: The function to call on every element. Could be a coroutine.
|
||||||
|
:return: An async iterator.
|
||||||
|
|
||||||
|
.. method:: filter(predicate)
|
||||||
|
|
||||||
|
This is similar to the built-in ``filter`` function. Another
|
||||||
|
:class:`AsyncIterator` is returned that filters over the original
|
||||||
|
async iterator. This predicate can be a regular function or a coroutine.
|
||||||
|
|
||||||
|
:param predicate: The predicate to call on every element. Could be a coroutine.
|
||||||
|
:return: An async iterator.
|
||||||
|
|
||||||
.. _discord_api_data:
|
.. _discord_api_data:
|
||||||
|
|
||||||
Data Classes
|
Data Classes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user