Browse Source

Merge 7605cc859d into b5d26190a6

pull/177/merge
Nate the great 5 years ago
committed by GitHub
parent
commit
15642d8e5d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      .biblio.yaml
  2. 2
      .gitignore
  3. 0
      bot_tutorial/README.md
  4. 0
      bot_tutorial/SUMMARY.md
  5. 0
      bot_tutorial/advanced.md
  6. 0
      bot_tutorial/building_block_commands.md
  7. 0
      bot_tutorial/building_block_listeners.md
  8. 0
      bot_tutorial/building_block_plugins.md
  9. 0
      bot_tutorial/first_steps.md
  10. 0
      bot_tutorial/installation.md
  11. 0
      bot_tutorial/message_embeds.md
  12. 463
      disco/types/channel.py
  13. 670
      disco/types/guild.py
  14. 20
      docs/Makefile
  15. 10
      docs/book.json
  16. 20
      docs/build.sh
  17. 60
      docs/conf.py
  18. 17
      docs/index.rst
  19. 35
      docs/make.bat
  20. 5
      docs/types/channel.rst
  21. 5
      docs/types/guild.rst
  22. 9
      docs/types/index.rst
  23. 5
      setup.py

8
.biblio.yaml

@ -1,8 +0,0 @@
name: Disco
rules:
disco/*.py:
parser: numpy
outputs:
- {type: markdown, path: docs/api/, title: 'Disco Documentation'}

2
.gitignore

@ -9,7 +9,7 @@ storage.json
.cache/ .cache/
.benchmarks/ .benchmarks/
__pycache__ __pycache__
.venv .venv/
# Documentation stuff # Documentation stuff
docs/api/ docs/api/

0
docs/README.md → bot_tutorial/README.md

0
docs/SUMMARY.md → bot_tutorial/SUMMARY.md

0
docs/bot_tutorial/advanced.md → bot_tutorial/advanced.md

0
docs/bot_tutorial/building_block_commands.md → bot_tutorial/building_block_commands.md

0
docs/bot_tutorial/building_block_listeners.md → bot_tutorial/building_block_listeners.md

0
docs/bot_tutorial/building_block_plugins.md → bot_tutorial/building_block_plugins.md

0
docs/bot_tutorial/first_steps.md → bot_tutorial/first_steps.md

0
docs/installation.md → bot_tutorial/installation.md

0
docs/bot_tutorial/message_embeds.md → bot_tutorial/message_embeds.md

463
disco/types/channel.py

@ -44,12 +44,14 @@ class PermissionOverwrite(ChannelSubType):
---------- ----------
id : snowflake id : snowflake
The overwrite ID. The overwrite ID.
type : :const:`disco.types.channel.PermissionsOverwriteType` type : :const:`~disco.types.channel.PermissionsOverwriteType`
The overwrite type. The overwrite type.
allow : :class:`disco.types.permissions.PermissionValue` allow : :class:`~disco.types.permissions.PermissionValue`
All allowed permissions. All allowed permissions.
deny : :class:`disco.types.permissions.PermissionValue` deny : :class:`~disco.types.permissions.PermissionValue`
All denied permissions. All denied permissions.
compiled : :class:`~disco.types.permissions.PermissionValue`
All permissions, both allowed and denied
""" """
id = Field(snowflake) id = Field(snowflake)
type = Field(enum(PermissionOverwriteType)) type = Field(enum(PermissionOverwriteType))
@ -60,6 +62,27 @@ class PermissionOverwrite(ChannelSubType):
@classmethod @classmethod
def create_for_channel(cls, channel, entity, allow=0, deny=0): def create_for_channel(cls, channel, entity, allow=0, deny=0):
""""
Creates a permission overwrite
Generates a permission overwrite for a channel given the entity and the permission bitsets provided.
Parameters
---------
channel : :class:`~disco.types.channel.Channel`
Channel to apply permission overwrite too
entity : :class:`~disco.types.guild.Role` or :class:`~disco.types.guild.GuildMember`
The role or member to provide or deny permissions too
allow : :class:`~disco.types.permissions.Permissions`, optional
Permissions to allow the role or user for the channel
deny : :class:`~disco.types.permissions.Permissions` optional
Permissions to deny the role or user for the channel
Returns
-------
:class:`~disco.types.channel.PermissionOverwrite`
An instance of the overwrite that was created
"""
from disco.types.guild import Role from disco.types.guild import Role
ptype = PermissionOverwriteType.ROLE if isinstance(entity, Role) else PermissionOverwriteType.MEMBER ptype = PermissionOverwriteType.ROLE if isinstance(entity, Role) else PermissionOverwriteType.MEMBER
@ -80,6 +103,22 @@ class PermissionOverwrite(ChannelSubType):
return value return value
def save(self, **kwargs): def save(self, **kwargs):
"""
Send discord the permission overwrite
This method is used if you created a permission overwrite without uploading it.
For most use cases, use the create_for_channel classmethod instead.
Parameters
----------
kwargs
Extra arguments to provide channels_permissions_modify
Returns
-------
:class:`~disco.types.channel.PermissionOverwrite`
Returns itself, no changes made
"""
self.client.api.channels_permissions_modify(self.channel_id, self.client.api.channels_permissions_modify(self.channel_id,
self.id, self.id,
self.allow.value or 0, self.allow.value or 0,
@ -89,6 +128,16 @@ class PermissionOverwrite(ChannelSubType):
return self return self
def delete(self, **kwargs): def delete(self, **kwargs):
"""
Delete permission overwrite
Removes the permission overwrite instance from it's channel. You can reverse the change with the save method.
Parameters
----------
kwargs
Extra arguments to provide channels_permissions_delete
"""
self.client.api.channels_permissions_delete(self.channel_id, self.id, **kwargs) self.client.api.channels_permissions_delete(self.channel_id, self.id, **kwargs)
@ -100,8 +149,8 @@ class Channel(SlottedModel, Permissible):
---------- ----------
id : snowflake id : snowflake
The channel ID. The channel ID.
guild_id : Optional[snowflake] guild_id : snowflake, optional
The guild id this channel is part of. The guild id the channel is part of.
name : str name : str
The channel's name. The channel's name.
topic : str topic : str
@ -112,12 +161,16 @@ class Channel(SlottedModel, Permissible):
The channel's bitrate. The channel's bitrate.
user_limit : int user_limit : int
The channel's user limit. The channel's user limit.
recipients : list(:class:`disco.types.user.User`) recipients : list of :class:`~disco.types.user.User`
Members of this channel (if this is a DM channel). Members of the channel (if the is a DM channel).
type : :const:`ChannelType` type : :const:`~disco.types.channel.ChannelType`
The type of this channel. The type of the channel.
overwrites : dict(snowflake, :class:`disco.types.channel.PermissionOverwrite`) overwrites : dict of snowflake to :class:`~disco.types.channel.PermissionOverwrite`
Channel permissions overwrites. Channel permissions overwrites.
mention : str
The channel's mention
guild : :class:`~disco.types.guild.Guild`, optional
Guild the channel belongs to (or None if not applicable).
""" """
id = Field(snowflake) id = Field(snowflake)
guild_id = Field(snowflake) guild_id = Field(snowflake)
@ -152,9 +205,18 @@ class Channel(SlottedModel, Permissible):
""" """
Get the permissions a user has in the channel. Get the permissions a user has in the channel.
This method will first apply the user's permissions based on their roles and / or if they're the owner.
It will then overwrite those permissions with the channel's permission overwrites.
If the channel is a DM, the user is considered an administrator.
Parameters
----------
user : :class:`~disco.types.user.User` or :class:`~disco.types.guild.GuildMember`
A user-like instance of the ID of a user to get the permissions for
Returns Returns
------- -------
:class:`disco.types.permissions.PermissionValue` :class:`~disco.types.permissions.PermissionValue`
Computed permission value for the user. Computed permission value for the user.
""" """
if not self.guild_id: if not self.guild_id:
@ -189,7 +251,7 @@ class Channel(SlottedModel, Permissible):
@property @property
def is_guild(self): def is_guild(self):
""" """
Whether this channel belongs to a guild. Whether the channel belongs to a guild.
""" """
return self.type in ( return self.type in (
ChannelType.GUILD_TEXT, ChannelType.GUILD_TEXT,
@ -201,7 +263,7 @@ class Channel(SlottedModel, Permissible):
@property @property
def is_news(self): def is_news(self):
""" """
Whether this channel contains news for the guild (used for verified guilds Whether the channel contains news for the guild (used for verified guilds
to produce activity feed news). to produce activity feed news).
""" """
return self.type == ChannelType.GUILD_NEWS return self.type == ChannelType.GUILD_NEWS
@ -209,51 +271,55 @@ class Channel(SlottedModel, Permissible):
@property @property
def is_dm(self): def is_dm(self):
""" """
Whether this channel is a DM (does not belong to a guild). Whether the channel is a DM (does not belong to a guild).
""" """
return self.type in (ChannelType.DM, ChannelType.GROUP_DM) return self.type in (ChannelType.DM, ChannelType.GROUP_DM)
@property @property
def is_nsfw(self): def is_nsfw(self):
""" """
Whether this channel is an NSFW channel. Whether the channel is an NSFW channel.
""" """
return bool(self.type == ChannelType.GUILD_TEXT and (self.nsfw or NSFW_RE.match(self.name))) return bool(self.type == ChannelType.GUILD_TEXT and (self.nsfw or NSFW_RE.match(self.name)))
@property @property
def is_voice(self): def is_voice(self):
""" """
Whether this channel supports voice. Whether the channel supports voice.
""" """
return self.type in (ChannelType.GUILD_VOICE, ChannelType.GROUP_DM) return self.type in (ChannelType.GUILD_VOICE, ChannelType.GROUP_DM)
@property @property
def messages(self): def messages(self):
""" """
A default `MessageIterator` for the channel, can be used to quickly and A default :class:`~disco.types.channel.MessageIterator` for the channel, can be used to quickly and
easily iterate over the channels entire message history. For more control, easily iterate over the channels entire message history. For more control,
use `Channel.messages_iter`. use :func:`~disco.types.channel.Channel.messages_iter`.
""" """
return self.messages_iter() return self.messages_iter()
@cached_property @cached_property
def guild(self): def guild(self):
"""
Guild this channel belongs to (or None if not applicable).
"""
return self.client.state.guilds.get(self.guild_id) return self.client.state.guilds.get(self.guild_id)
@cached_property @cached_property
def parent(self): def parent(self):
""" """
Parent this channel belongs to (or None if not applicable). Parent the channel belongs to (or None if not applicable).
""" """
return self.guild.channels.get(self.parent_id) return self.guild.channels.get(self.parent_id)
def messages_iter(self, **kwargs): def messages_iter(self, **kwargs):
""" """
Creates a new `MessageIterator` for the channel with the given keyword Creates message iterator
Creates a new :class:`~disco.types.channel.MessageIterator` for the channel with the given keyword
arguments. arguments.
Parameters
----------
kwargs
Extra arguments to be passed into :class:`~disco.types.channel.MessageIterator`
""" """
return MessageIterator(self.client, self, **kwargs) return MessageIterator(self.client, self, **kwargs)
@ -262,30 +328,49 @@ class Channel(SlottedModel, Permissible):
Attempts to fetch and return a `Message` from the message object Attempts to fetch and return a `Message` from the message object
or id. or id.
Arguments
---------
message : :class:`~disco.types.message.Message` or snowflake
Returns Returns
------- -------
`Message` :class:`~disco.types.message.Message`
The fetched message. The fetched message.
""" """
return self.client.api.channels_messages_get(self.id, to_snowflake(message)) return self.client.api.channels_messages_get(self.id, to_snowflake(message))
def get_invites(self): def get_invites(self):
""" """
Finds invites for the channel
Invites are not global for a server like they used to be, and now must be created for specific channels.
This method finds all the invites that use the channel as the landing page.
Returns Returns
------- -------
list(`Invite`) list of :class:`~disco.types.invite.Invite`
Returns a list of all invites for this channel. Returns a list of all invites for the channel.
""" """
return self.client.api.channels_invites_list(self.id) return self.client.api.channels_invites_list(self.id)
def create_invite(self, *args, **kwargs): def create_invite(self, *args, **kwargs):
""" """
Create an invite for the channel
Attempts to create a new invite with the given arguments. For more Attempts to create a new invite with the given arguments. For more
information see `Invite.create_for_channel`. information see :func:`~disco.types.invite.Invite.create_for_channel`.
Parameters
----------
args
Arguments to be passed into :func:`~disco.types.invite.Invite.create_for_channel`
kwargs
Keyword arguments to be passed into :func:`~disco.types.invite.Invite.create_for_channel`
Returns Returns
------- -------
`Invite` :class:`~disco.types.invite.Invite`
The generated invite for the channel
""" """
from disco.types.invite import Invite from disco.types.invite import Invite
@ -293,10 +378,14 @@ class Channel(SlottedModel, Permissible):
def get_pins(self): def get_pins(self):
""" """
Get pinned messages
Messages that have been pinned to the channel if there are any
Returns Returns
------- -------
list(`Message`) list of :class:`~disco.types.message.Message`
Returns a list of all pinned messages for this channel. Returns a list of all pinned messages for the channel.
""" """
return self.client.api.channels_pins_list(self.id) return self.client.api.channels_pins_list(self.id)
@ -304,9 +393,10 @@ class Channel(SlottedModel, Permissible):
""" """
Pins the given message to the channel. Pins the given message to the channel.
Parameters Parameters
---------- ----------
message : `Message`|snowflake message : :class:`~disco.types.message.Message` or snowflake
The message or message ID to pin. The message or message ID to pin.
""" """
self.client.api.channels_pins_create(self.id, to_snowflake(message)) self.client.api.channels_pins_create(self.id, to_snowflake(message))
@ -317,25 +407,36 @@ class Channel(SlottedModel, Permissible):
Parameters Parameters
---------- ----------
message : `Message`|snowflake message : :class:`~disco.types.message.Message` or snowflake
The message or message ID to pin. The message or message ID to pin.
""" """
self.client.api.channels_pins_delete(self.id, to_snowflake(message)) self.client.api.channels_pins_delete(self.id, to_snowflake(message))
def get_webhooks(self): def get_webhooks(self):
""" """
Fetchs all webhooks operating on the channel
Returns Returns
------- -------
list(`Webhook`) list of :class:`~disco.types.webhook.Webhook`
Returns a list of all webhooks for this channel. Returns a list of all webhooks for the channel.
""" """
return self.client.api.channels_webhooks_list(self.id) return self.client.api.channels_webhooks_list(self.id)
def create_webhook(self, *args, **kwargs): def create_webhook(self, *args, **kwargs):
""" """
Creates a webhook for this channel. See `APIClient.channels_webhooks_create` Creates a webhook
Creates a webhook for the channel. See :func:`~disco.api.client.APIClient.channels_webhooks_create`
for more information. for more information.
Parameters
----------
args
Arguments to be passed into :func:`~disco.api.client.APIClient.channels_webhooks_create`
kwargs
Keyword arguments to be passed into :func:`~disco.api.client.APIClient.channels_webhooks_create`
Returns Returns
------- -------
`Webhook` `Webhook`
@ -345,37 +446,58 @@ class Channel(SlottedModel, Permissible):
def send_message(self, *args, **kwargs): def send_message(self, *args, **kwargs):
""" """
Send a message to this channel. See `APIClient.channels_messages_create` Send a message
Send a message to the channel. See :func:`~disco.api.client.APIClient.channels_messages_create`
for more information. for more information.
Parameters
----------
args
Arguments to be passed into :func:`~disco.api.client.APIClient.channels_messages_create`
kwargs
Keyword arguments to be passed into :func:`~disco.api.client.APIClient.channels_messages_create`
Returns Returns
------- -------
`disco.types.message.Message` :class:`~disco.types.message.Message`
The created message. The sent message.
""" """
return self.client.api.channels_messages_create(self.id, *args, **kwargs) return self.client.api.channels_messages_create(self.id, *args, **kwargs)
def send_typing(self): def send_typing(self):
""" """
Sends a typing event to this channel. See `APIClient.channels_typing` Signal typing status
for more information.
Sends a typing event to the channel. this will make it seem as though the bot is sending a message.
This status is removed if a message is not sent before another typing event is sent, or a message is sent.
See :func:`~disco.api.client.APIClient.channels_typing` for more information.
""" """
self.client.api.channels_typing(self.id) self.client.api.channels_typing(self.id)
def create_overwrite(self, *args, **kwargs): def create_overwrite(self, *args, **kwargs):
""" """
Creates a `PermissionOverwrite` for this channel. See Create permission overwrite
`PermissionOverwrite.create_for_channel` for more information.
Creates a `PermissionOverwrite` for the channel.
See `PermissionOverwrite.create_for_channel` for more information.
Parameters
----------
args
Arguments to be passed into :func:`~disco.types.channel.PermissionOverwrite.create_for_channel`
kwargs
Keyword arguments to be passed into :func:`~disco.types.channel.PermissionOverwrite.create_for_channel`
""" """
return PermissionOverwrite.create_for_channel(self, *args, **kwargs) return PermissionOverwrite.create_for_channel(self, *args, **kwargs)
def delete_message(self, message): def delete_message(self, message):
""" """
Deletes a single message from this channel. Deletes a single message from the channel.
Parameters Parameters
---------- ----------
message : snowflake|`Message` message : snowflake or :class:`~disco.types.message.Message`
The message to delete. The message to delete.
""" """
self.client.api.channels_messages_delete(self.id, to_snowflake(message)) self.client.api.channels_messages_delete(self.id, to_snowflake(message))
@ -383,14 +505,16 @@ class Channel(SlottedModel, Permissible):
@one_or_many @one_or_many
def delete_messages(self, messages): def delete_messages(self, messages):
""" """
Deletes many messages
Deletes a set of messages using the correct API route based on the number Deletes a set of messages using the correct API route based on the number
of messages passed. of messages passed.
Parameters Parameters
---------- ----------
messages : list(snowflake|`Message`) messages : list of snowflake or list of :class:`~disco.types.message.Message`
List of messages (or message ids) to delete. All messages must originate List of messages (or message ids) to delete. All messages must originate
from this channel. from the channel.
""" """
message_ids = list(map(to_snowflake, messages)) message_ids = list(map(to_snowflake, messages))
@ -405,13 +529,27 @@ class Channel(SlottedModel, Permissible):
self.delete_message(msg) self.delete_message(msg)
def delete(self, **kwargs): def delete(self, **kwargs):
"""
Delete guild channel
Parameters
----------
kwargs
Keyword arguments to be passed into :func:`~disco.api.client.APIClient.channels_delete`
Raises
------
AssertionError
Raised is the channel is a DM, or if the bot doesn't have MANAGE_CHANNELS permissions for this guild.
"""
assert (self.is_dm or self.guild.can(self.client.state.me, Permissions.MANAGE_CHANNELS)), 'Invalid Permissions' assert (self.is_dm or self.guild.can(self.client.state.me, Permissions.MANAGE_CHANNELS)), 'Invalid Permissions'
self.client.api.channels_delete(self.id, **kwargs) self.client.api.channels_delete(self.id, **kwargs)
def close(self): def close(self):
""" """
Closes a DM channel. This is intended as a safer version of `delete`, Delete guild channel
enforcing that the channel is actually a DM.
Copy of :func:`~disco.types.channel.Channel.delete`, but doesn't check if the bot has correct permissions
""" """
assert self.is_dm, 'Cannot close non-DM channel' assert self.is_dm, 'Cannot close non-DM channel'
self.delete() self.delete()
@ -419,24 +557,79 @@ class Channel(SlottedModel, Permissible):
def set_topic(self, topic, reason=None): def set_topic(self, topic, reason=None):
""" """
Sets the channels topic. Sets the channels topic.
Parameters
----------
topic : str
The channel's topic or description
reason : str, optional
The reason for setting the topic
Returns
-------
:class:`~disco.types.channel.Channel`
Updated version of the channel
""" """
return self.client.api.channels_modify(self.id, topic=topic, reason=reason) return self.client.api.channels_modify(self.id, topic=topic, reason=reason)
def set_name(self, name, reason=None): def set_name(self, name, reason=None):
""" """
Sets the channels name. Sets the channels name.
Parameters
----------
name : str
The new channel name
reason : str
Reason for channel name update
Returns
-------
:class:`~disco.types.channel.Channel`
Updated version of the channel
""" """
return self.client.api.channels_modify(self.id, name=name, reason=reason) return self.client.api.channels_modify(self.id, name=name, reason=reason)
def set_position(self, position, reason=None): def set_position(self, position, reason=None):
""" """
Sets the channels position. Sets the channels position.
Change the order which channels are listed.
Parameters
----------
position : int
The new channel position (Check the guild to see how many channels it has)
reason : str
Reason for channel position update
Returns
-------
:class:`~disco.types.channel.Channel`
Updated version of the channel
""" """
return self.client.api.channels_modify(self.id, position=position, reason=reason) return self.client.api.channels_modify(self.id, position=position, reason=reason)
def set_nsfw(self, value, reason=None): def set_nsfw(self, value, reason=None):
""" """
Sets whether the channel is NSFW. Sets whether the channel is NSFW.
Parameters
----------
value : bool
Whether the channel should be NSFW or not
reason : str
Reason for channel nsfw update
Returns
-------
:class:`~disco.types.channel.Channel`
Updated version of the channel
Raises
------
AssertionError
Raised if the channel type isn't a guild text channel
""" """
assert (self.type == ChannelType.GUILD_TEXT) assert (self.type == ChannelType.GUILD_TEXT)
return self.client.api.channels_modify(self.id, nsfw=value, reason=reason) return self.client.api.channels_modify(self.id, nsfw=value, reason=reason)
@ -444,6 +637,23 @@ class Channel(SlottedModel, Permissible):
def set_bitrate(self, bitrate, reason=None): def set_bitrate(self, bitrate, reason=None):
""" """
Sets the channels bitrate. Sets the channels bitrate.
Parameters
----------
bitrate : int
The voice channel's new bitrate
reason : str
Reason for channel bitrate update
Returns
-------
:class:`~disco.types.channel.Channel`
Updated version of the channel
Raises
------
AssertionError
Raised if the channel isn't a voice channel
""" """
assert (self.is_voice) assert (self.is_voice)
return self.client.api.channels_modify(self.id, bitrate=bitrate, reason=reason) return self.client.api.channels_modify(self.id, bitrate=bitrate, reason=reason)
@ -451,6 +661,25 @@ class Channel(SlottedModel, Permissible):
def set_user_limit(self, user_limit, reason=None): def set_user_limit(self, user_limit, reason=None):
""" """
Sets the channels user limit. Sets the channels user limit.
Voice channels can be capped at how many people can be in it, this method sets that limit.
Parameters
----------
user_limit : int
The max amount of people in a voice channel
reason : str
Reason for channel user limit update
Returns
-------
:class:`~disco.types.channel.Channel`
Updated version of the channel
Raises
------
AssertionError
Raised if channel isn't a voice channel
""" """
assert (self.is_voice) assert (self.is_voice)
return self.client.api.channels_modify(self.id, user_limit=user_limit, reason=reason) return self.client.api.channels_modify(self.id, user_limit=user_limit, reason=reason)
@ -458,6 +687,25 @@ class Channel(SlottedModel, Permissible):
def set_parent(self, parent, reason=None): def set_parent(self, parent, reason=None):
""" """
Sets the channels parent. Sets the channels parent.
Channels can be organized under categories, this method moves the channel under a category
Parameters
----------
parent : :class:`~disco.types.channel.Channel` or snowflake
The category to move the channel under
reason : str
Reason for channel parent update
Returns
-------
:class:`~disco.types.channel.Channel`
Updated version of the channel
Raises
------
AssertionError
Raised if the channel doesn't belong to a guild
""" """
assert (self.is_guild) assert (self.is_guild)
return self.client.api.channels_modify( return self.client.api.channels_modify(
@ -467,7 +715,26 @@ class Channel(SlottedModel, Permissible):
def set_slowmode(self, interval, reason=None): def set_slowmode(self, interval, reason=None):
""" """
Sets the channels slowmode (rate_limit_per_user). Sets the channels slowmode
Slowmode is used to restrict how many messages a user can send at once
Parameters
----------
interval : int
The amount of seconds users have to wait after sending a message (between 0-21600 inclusive)
reason : str
Reason for channel slowmode update
Returns
-------
:class:`~disco.types.channel.Channel`
Updated version of the channel
Raises
------
AssertionError
Raised if the channel is not a guild text channel
""" """
assert (self.type == ChannelType.GUILD_TEXT) assert (self.type == ChannelType.GUILD_TEXT)
return self.client.api.channels_modify( return self.client.api.channels_modify(
@ -477,8 +744,27 @@ class Channel(SlottedModel, Permissible):
def create_text_channel(self, *args, **kwargs): def create_text_channel(self, *args, **kwargs):
""" """
Creates a sub-text-channel in this category. See `Guild.create_text_channel` Create text channel under this category
for arguments and more information.
Creates a text channel under this channel to keep channels organized.
This can only be used if the channel is a category.
Parameters
----------
args
Arguments to be passed into :func:`~disco.types.guild.Guild.create_text_channel`
kwargs
Keyword arguments to be passed into :func:`~disco.types.Guild.create_text_channel`
Returns
-------
:class:`~disco.types.channel.Channel`
Created text channel
Raises
------
ValueError
Raised if the channel is not a category channel
""" """
if self.type != ChannelType.GUILD_CATEGORY: if self.type != ChannelType.GUILD_CATEGORY:
raise ValueError('Cannot create a sub-channel on a non-category channel') raise ValueError('Cannot create a sub-channel on a non-category channel')
@ -491,8 +777,27 @@ class Channel(SlottedModel, Permissible):
def create_voice_channel(self, *args, **kwargs): def create_voice_channel(self, *args, **kwargs):
""" """
Creates a sub-voice-channel in this category. See `Guild.create_voice_channel` Create voice channel under this category
for arguments and more information.
Creates a voice channel under this channel to keep channels organized.
This can only be used if the channel is a category.
Parameters
----------
args
Arguments to be passed into :func:`~disco.types.guild.Guild.create_voice_channel`
kwargs
Keyword arguments to be passed into :func:`~disco.types.Guild.create_voice_channel`
Returns
-------
:class:`~disco.types.channel.Channel`
Created text channel
Raises
------
ValueError
Raised if the channel is not a category channel
""" """
if self.type != ChannelType.GUILD_CATEGORY: if self.type != ChannelType.GUILD_CATEGORY:
raise ValueError('Cannot create a sub-channel on a non-category channel') raise ValueError('Cannot create a sub-channel on a non-category channel')
@ -506,18 +811,24 @@ class Channel(SlottedModel, Permissible):
class MessageIterator(object): class MessageIterator(object):
""" """
An iterator which supports scanning through the messages for a channel. Message iterator
Parameters The discord API allows you to fetch 100 messages at once.
After that 100 you need to create a new request based on the last messages's snowflake.
This class makes interacting with the api much easier, and provides a constant stream of messages.
This is used internally for :func:`~disco.types.channel.Channel.messages_iter`,
and the :attr:`~disco.types.channel.Channel.messages` attribute.
Attributes
---------- ----------
client : :class:`disco.client.Client` client : :class:`~disco.client.Client`
The disco client instance to use when making requests. The disco client instance to use when making requests.
channel : `Channel` channel : :class:`~disco.types.channel.Channel`
The channel to iterate within. The channel to iterate within.
direction : :attr:`MessageIterator.Direction` direction : :attr:`~disco.types.channel.MessageIterator.Direction`
The direction in which this iterator will move. The direction in which the iterator will move.
bulk : bool bulk : bool
If true, this iterator will yield messages in list batches, otherwise each If true, the iterator will yield messages in list batches, otherwise each
message will be yield individually. message will be yield individually.
before : snowflake before : snowflake
The message to begin scanning at. The message to begin scanning at.
@ -527,6 +838,16 @@ class MessageIterator(object):
The number of messages to request per API call. The number of messages to request per API call.
""" """
class Direction(object): class Direction(object):
"""
What direction to go when traversing a channel
Attributes
----------
UP : int
Search through messages earliest to oldest
DOWN : int
Search through messages oldest to earliest
"""
UP = 1 UP = 1
DOWN = 2 DOWN = 2
@ -547,9 +868,14 @@ class MessageIterator(object):
def fill(self): def fill(self):
""" """
Fills the internal buffer up with :class:`disco.types.message.Message` objects from the API. Fetch messages
Fills the internal buffer up with :class:`~disco.types.message.Message` objects from the API.
Returns a boolean indicating whether items were added to the buffer. Returns
-------
bool
If True, the buffer was filled with more messages
""" """
self._buffer = self.client.api.channels_messages_list( self._buffer = self.client.api.channels_messages_list(
self.channel.id, self.channel.id,
@ -573,6 +899,19 @@ class MessageIterator(object):
return True return True
def next(self): def next(self):
"""
Get the next message
Returns
-------
:class:`~disco.types.message.Message`
The next message in the channel
Raises
------
StopIteration
Raised when there are no more messages left
"""
return self.__next__() return self.__next__()
def __iter__(self): def __iter__(self):

670
disco/types/guild.py

File diff suppressed because it is too large

20
docs/Makefile

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

10
docs/book.json

@ -1,10 +0,0 @@
{
"title": "Disco",
"plugins": ["prism", "-highlight", "hints", "anchorjs"],
"pluginsConfig": {
"anchorjs": {
"placement": "left",
"visible": "always"
}
}
}

20
docs/build.sh

@ -1,20 +0,0 @@
#!/bin/bash
echo "Building Autogenerated API Docs"
pushd ..
python -m biblio.cli ../disco/.biblio.yaml
popd
echo "Running Gitbook Build"
gitbook build
if [ ! -z "${GH_TOKEN:-}" ]; then
echo "Deploying to Github Pages"
pushd _book/
git init
git config user.name "AutoDoc"
git config user.email "<>"
git add .
git commit -m "Generated Documentation"
git push --force --quiet "https://${GH_TOKEN}@github.com/b1naryth1ef/disco" master:gh-pages
popd
fi

60
docs/conf.py

@ -0,0 +1,60 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
# -- Project information -----------------------------------------------------
project = 'disco'
copyright = '2020, Andrei Zbikowski'
author = 'Andrei Zbikowski'
# The full version, including alpha/beta/rc tags
release = '0.0.12'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.napoleon',
'sphinx.ext.autodoc'
]
napoleon_use_ivar = True
napoleon_use_rtype = False
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'groundwork'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

17
docs/index.rst

@ -0,0 +1,17 @@
Welcome to disco's documentation!
=================================
.. toctree::
:maxdepth: 1
:caption: Contents:
types/index
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

35
docs/make.bat

@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

5
docs/types/channel.rst

@ -0,0 +1,5 @@
Disco Channel API
=================
.. automodule:: disco.types.channel
:members:

5
docs/types/guild.rst

@ -0,0 +1,5 @@
Disco Guild API
=================
.. automodule:: disco.types.guild
:members:

9
docs/types/index.rst

@ -0,0 +1,9 @@
Disco Type API
==============
.. toctree::
:maxdepth: 1
:caption: Disco Type APIs
channel
guild

5
setup.py

@ -20,7 +20,10 @@ extras_require = {
'wsaccel==0.6.2', 'wsaccel==0.6.2',
], ],
'sharding': ['gipc==0.6.0'], 'sharding': ['gipc==0.6.0'],
'docs': ['biblio==0.0.4'], 'docs': [
'sphinx==2.4.4',
'groundwork-sphinx-theme==1.1.1'
],
} }
setup( setup(

Loading…
Cancel
Save