mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-04-19 15:36:02 +00:00
Add enumerators instead of strings.
Changes channel type, status and server region into 3.4 enums.
This commit is contained in:
parent
680575bf58
commit
79bdf2a721
@ -26,44 +26,37 @@ DEALINGS IN THE SOFTWARE.
|
||||
from copy import deepcopy
|
||||
from . import utils
|
||||
from .permissions import Permissions
|
||||
from .enums import ChannelType
|
||||
from collections import namedtuple
|
||||
|
||||
Overwrites = namedtuple('Overwrites', 'id allow deny type')
|
||||
|
||||
class Channel(object):
|
||||
class Channel:
|
||||
"""Represents a Discord server channel.
|
||||
|
||||
Instance attributes:
|
||||
|
||||
.. attribute:: name
|
||||
|
||||
Attributes
|
||||
-----------
|
||||
name : str
|
||||
The channel name.
|
||||
.. attribute:: server
|
||||
|
||||
The :class:`Server` the channel belongs to.
|
||||
.. attribute:: id
|
||||
|
||||
server : :class:`Server`
|
||||
The server the channel belongs to.
|
||||
id : str
|
||||
The channel ID.
|
||||
.. attribute:: topic
|
||||
|
||||
topic : Optional[str]
|
||||
The channel's topic. None if it doesn't exist.
|
||||
.. attribute:: is_private
|
||||
|
||||
is_private : bool
|
||||
``True`` if the channel is a private channel (i.e. PM). ``False`` in this case.
|
||||
.. attribute:: position
|
||||
|
||||
position : int
|
||||
The position in the channel list.
|
||||
.. attribute:: type
|
||||
|
||||
The channel type. Usually ``'voice'`` or ``'text'``.
|
||||
.. attribute:: changed_roles
|
||||
|
||||
type : :class:`ChannelType`
|
||||
The channel type. There is a chance that the type will be ``str`` if
|
||||
the channel type is not within the ones recognised by the enumerator.
|
||||
changed_roles
|
||||
A list of :class:`Roles` that have been overridden from their default
|
||||
values in the :attr:`Server.roles` attribute.
|
||||
.. attribute:: voice_members
|
||||
|
||||
voice_members
|
||||
A list of :class:`Members` that are currently inside this voice channel.
|
||||
If :attr:`type` is not ``'voice'`` then this is always an empty array.
|
||||
If :attr:`type` is not :attr:`ChannelType.voice` then this is always an empty array.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@ -78,6 +71,11 @@ class Channel(object):
|
||||
self.is_private = False
|
||||
self.position = kwargs.get('position')
|
||||
self.type = kwargs.get('type')
|
||||
try:
|
||||
self.type = ChannelType(self.type)
|
||||
except:
|
||||
pass
|
||||
|
||||
self.changed_roles = []
|
||||
self._permission_overwrites = []
|
||||
for overridden in kwargs.get('permission_overwrites', []):
|
||||
@ -98,11 +96,11 @@ class Channel(object):
|
||||
self.changed_roles.append(override)
|
||||
|
||||
def is_default_channel(self):
|
||||
"""Checks if this is the default channel for the :class:`Server` it belongs to."""
|
||||
"""bool : Indicates if this is the default channel for the :class:`Server` it belongs to."""
|
||||
return self.server.id == self.id
|
||||
|
||||
def mention(self):
|
||||
"""Returns a string that allows you to mention the channel."""
|
||||
"""str : The string that allows you to mention the channel."""
|
||||
return '<#{0.id}>'.format(self)
|
||||
|
||||
def permissions_for(self, member):
|
||||
@ -116,8 +114,15 @@ class Channel(object):
|
||||
- Member overrides
|
||||
- Whether the channel is the default channel.
|
||||
|
||||
:param member: The :class:`Member` to resolve permissions for.
|
||||
:return: The resolved :class:`Permissions` for the :class:`Member`.
|
||||
Parameters
|
||||
----------
|
||||
member : :class:`Member`
|
||||
The member to resolve permissions for.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`Permissions`
|
||||
The resolved permissions for the member.
|
||||
"""
|
||||
|
||||
# The current cases can be explained as:
|
||||
@ -173,19 +178,16 @@ class Channel(object):
|
||||
|
||||
return base
|
||||
|
||||
class PrivateChannel(object):
|
||||
class PrivateChannel:
|
||||
"""Represents a Discord private channel.
|
||||
|
||||
Instance attributes:
|
||||
|
||||
.. attribute:: user
|
||||
|
||||
The :class:`User` in the private channel.
|
||||
.. attribute:: id
|
||||
|
||||
Attributes
|
||||
----------
|
||||
user : :class:`User`
|
||||
The user you are participating with in the private channel.
|
||||
id : str
|
||||
The private channel ID.
|
||||
.. attribute:: is_private
|
||||
|
||||
is_private : bool
|
||||
``True`` if the channel is a private channel (i.e. PM). ``True`` in this case.
|
||||
"""
|
||||
|
||||
@ -207,8 +209,15 @@ class PrivateChannel(object):
|
||||
- can_manage_messages: You cannot delete others messages in a PM.
|
||||
- can_mention_everyone: There is no one to mention in a PM.
|
||||
|
||||
:param user: The :class:`User` to check permissions for.
|
||||
:return: A :class:`Permission` with the resolved permission value.
|
||||
Parameters
|
||||
-----------
|
||||
user : :class:`User`
|
||||
The user to check permissions for.
|
||||
|
||||
Returns
|
||||
--------
|
||||
:class:`Permission`
|
||||
The resolved permissions for the user.
|
||||
"""
|
||||
|
||||
base = Permissions.TEXT
|
||||
|
@ -34,6 +34,7 @@ from .object import Object
|
||||
from .errors import *
|
||||
from .state import ConnectionState
|
||||
from . import utils
|
||||
from .enums import ChannelType, ServerRegion
|
||||
|
||||
import asyncio
|
||||
import aiohttp
|
||||
@ -1085,7 +1086,7 @@ class Client:
|
||||
log.debug(request_success_log.format(response=r, json=payload, data=data))
|
||||
|
||||
@asyncio.coroutine
|
||||
def create_channel(self, server, name, type='text'):
|
||||
def create_channel(self, server, name, type=None):
|
||||
"""|coro|
|
||||
|
||||
Creates a :class:`Channel` in the specified :class:`Server`.
|
||||
@ -1098,8 +1099,8 @@ class Client:
|
||||
The server to create the channel in.
|
||||
name : str
|
||||
The channel's name.
|
||||
type : str
|
||||
The type of channel to create. 'text' or 'voice'.
|
||||
type : :class:`ChannelType`
|
||||
The type of channel to create. Defaults to :attr:`ChannelType.text`.
|
||||
|
||||
Raises
|
||||
-------
|
||||
@ -1117,9 +1118,12 @@ class Client:
|
||||
different than the one that will be added in cache.
|
||||
"""
|
||||
|
||||
if type is None:
|
||||
type = ChannelType.text
|
||||
|
||||
payload = {
|
||||
'name': name,
|
||||
'type': type
|
||||
'type': str(type)
|
||||
}
|
||||
|
||||
url = '{0}/{1.id}/channels'.format(endpoints.SERVERS, server)
|
||||
@ -1160,4 +1164,3 @@ class Client:
|
||||
response = yield from self.session.delete(url, headers=self.headers)
|
||||
log.debug(request_logging_format.format(method='DELETE', response=response))
|
||||
yield from utils._verify_successful_response(response)
|
||||
|
||||
|
54
discord/enums.py
Normal file
54
discord/enums.py
Normal file
@ -0,0 +1,54 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Rapptz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
"""
|
||||
|
||||
from enum import Enum
|
||||
|
||||
class ChannelType(Enum):
|
||||
text = 'text'
|
||||
voice = 'voice'
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
class ServerRegion(Enum):
|
||||
us_west = 'us-west'
|
||||
us_east = 'us-east'
|
||||
singapore = 'singapore'
|
||||
london = 'london'
|
||||
sydney = 'sydney'
|
||||
amsterdam = 'amsterdam'
|
||||
frankfurt = 'frankfurt'
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
class Status(Enum):
|
||||
online = 'online'
|
||||
offline = 'offline'
|
||||
idle = 'idle'
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
@ -26,6 +26,7 @@ DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from .user import User
|
||||
from .utils import parse_time
|
||||
from .enums import Status
|
||||
|
||||
class Member(User):
|
||||
"""Represents a Discord member to a :class:`Server`.
|
||||
@ -33,44 +34,34 @@ class Member(User):
|
||||
This is a subclass of :class:`User` that extends more functionality
|
||||
that server members have such as roles and permissions.
|
||||
|
||||
Instance attributes:
|
||||
|
||||
.. attribute:: deaf
|
||||
|
||||
A boolean that specifies if the member is currently deafened by the server.
|
||||
.. attribute:: mute
|
||||
|
||||
A boolean that specifies if the member is currently muted by the server.
|
||||
.. attribute:: self_mute
|
||||
|
||||
A boolean that specifies if the member is currently muted by their own accord.
|
||||
.. attribute:: self_deaf
|
||||
|
||||
A boolean that specifies if the member is currently deafened by their own accord.
|
||||
.. attribute:: is_afk
|
||||
|
||||
A boolean that specifies if the member is currently in the AFK channel in the server.
|
||||
.. attribute:: voice_channel
|
||||
|
||||
A voice :class:`Channel` that the member is currently connected to. None if the member
|
||||
Attributes
|
||||
----------
|
||||
deaf : bool
|
||||
Indicates if the member is currently deafened by the server.
|
||||
mute : bool
|
||||
Indicates if the member is currently muted by the server.
|
||||
self_mute : bool
|
||||
Indicates if the member is currently muted by their own accord.
|
||||
self_deaf : bool
|
||||
Indicates if the member is currently deafened by their own accord.
|
||||
is_afk : bool
|
||||
Indicates if the member is currently in the AFK channel in the server.
|
||||
voice_channel : :class:`Channel`
|
||||
The voice channel that the member is currently connected to. None if the member
|
||||
is not currently in a voice channel.
|
||||
.. attribute:: roles
|
||||
|
||||
roles
|
||||
A list of :class:`Role` that the member belongs to. Note that the first element of this
|
||||
list is always the default '@everyone' role.
|
||||
.. attribute:: joined_at
|
||||
|
||||
joined_at : `datetime.datetime`
|
||||
A datetime object that specifies the date and time in UTC that the member joined the server for
|
||||
the first time.
|
||||
.. attribute:: status
|
||||
|
||||
A string that denotes the user's status. Can be 'online', 'offline' or 'idle'.
|
||||
.. attribute:: game_id
|
||||
|
||||
status : :class:`Status`
|
||||
The member's status. There is a chance that the status will be a ``str``
|
||||
if it is a value that is not recognised by the enumerator.
|
||||
game_id : int
|
||||
The game ID that the user is currently playing. Could be None if no game is being played.
|
||||
.. attribute:: server
|
||||
|
||||
The :class:`Server` that the member belongs to.
|
||||
server : :class:`Server`
|
||||
The server that the member belongs to.
|
||||
"""
|
||||
|
||||
def __init__(self, deaf, joined_at, user, roles, mute, **kwargs):
|
||||
@ -79,7 +70,7 @@ class Member(User):
|
||||
self.mute = mute
|
||||
self.joined_at = parse_time(joined_at)
|
||||
self.roles = roles
|
||||
self.status = 'offline'
|
||||
self.status = Status.offline
|
||||
self.game_id = kwargs.get('game_id', None)
|
||||
self.server = kwargs.get('server', None)
|
||||
self.update_voice_state(mute=mute, deaf=deaf)
|
||||
|
@ -28,45 +28,36 @@ from . import utils
|
||||
from .role import Role
|
||||
from .member import Member
|
||||
from .channel import Channel
|
||||
from .enums import ServerRegion, Status
|
||||
|
||||
class Server(object):
|
||||
class Server:
|
||||
"""Represents a Discord server.
|
||||
|
||||
Instance attributes:
|
||||
|
||||
.. attribute:: name
|
||||
|
||||
Attributes
|
||||
----------
|
||||
name : str
|
||||
The server name.
|
||||
.. attribute:: roles
|
||||
|
||||
roles
|
||||
A list of :class:`Role` that the server has available.
|
||||
.. attribute:: region
|
||||
|
||||
The region the server belongs on.
|
||||
.. attribute:: afk_timeout
|
||||
|
||||
region : :class:`ServerRegion`
|
||||
The region the server belongs on. There is a chance that the region
|
||||
will be a ``str`` if the value is not recognised by the enumerator.
|
||||
afk_timeout : int
|
||||
The timeout to get sent to the AFK channel.
|
||||
.. attribute:: afk_channel
|
||||
|
||||
The :class:`Channel` that denotes the AFK channel. None if it doesn't exist.
|
||||
.. attribute:: members
|
||||
|
||||
afk_channel : :class:`Channel`
|
||||
The channel that denotes the AFK channel. None if it doesn't exist.
|
||||
members
|
||||
A list of :class:`Member` that are currently on the server.
|
||||
.. attribute:: channels
|
||||
|
||||
channels
|
||||
A list of :class:`Channel` that are currently on the server.
|
||||
.. attribute:: icon
|
||||
|
||||
icon : str
|
||||
The server's icon.
|
||||
.. attribute:: id
|
||||
|
||||
id : str
|
||||
The server's ID.
|
||||
.. attribute:: owner
|
||||
|
||||
The :class:`Member` who owns the server.
|
||||
.. attribute:: unavailable
|
||||
|
||||
A boolean indicating if the server is unavailable. If this is ``True`` then the
|
||||
owner : :class:`Member`
|
||||
The member who owns the server.
|
||||
unavailable : bool
|
||||
Indicates if the server is unavailable. If this is ``True`` then the
|
||||
reliability of other attributes outside of :meth:`Server.id` is slim and they might
|
||||
all be None. It is best to not do anything with the server if it is unavailable.
|
||||
|
||||
@ -88,6 +79,11 @@ class Server(object):
|
||||
def _from_data(self, guild):
|
||||
self.name = guild.get('name')
|
||||
self.region = guild.get('region')
|
||||
try:
|
||||
self.region = ServerRegion(self.region)
|
||||
except:
|
||||
pass
|
||||
|
||||
self.afk_timeout = guild.get('afk_timeout')
|
||||
self.icon = guild.get('icon')
|
||||
self.unavailable = guild.get('unavailable', False)
|
||||
@ -119,6 +115,10 @@ class Server(object):
|
||||
member = utils.find(lambda m: m.id == user_id, self.members)
|
||||
if member is not None:
|
||||
member.status = presence['status']
|
||||
try:
|
||||
member.status = Status(member.status)
|
||||
except:
|
||||
pass
|
||||
member.game_id = presence['game_id']
|
||||
|
||||
self.channels = [Channel(server=self, **c) for c in guild['channels']]
|
||||
@ -137,7 +137,7 @@ class Server(object):
|
||||
return utils.find(lambda c: c.is_default_channel(), self.channels)
|
||||
|
||||
def icon_url(self):
|
||||
"""Returns the URL version of the server's icon. Returns None if it has no icon."""
|
||||
"""Returns the URL version of the server's icon. Returns an empty string if it has no icon."""
|
||||
if self.icon is None:
|
||||
return ''
|
||||
return 'https://cdn.discordapp.com/icons/{0.id}/{0.icon}.jpg'.format(self)
|
||||
|
@ -31,6 +31,7 @@ from .channel import Channel, PrivateChannel
|
||||
from .member import Member
|
||||
from .role import Role
|
||||
from . import utils
|
||||
from .enums import Status
|
||||
|
||||
from collections import deque
|
||||
import copy
|
||||
@ -113,6 +114,10 @@ class ConnectionState:
|
||||
if member is not None:
|
||||
old_member = copy.copy(member)
|
||||
member.status = data.get('status')
|
||||
try:
|
||||
member.status = Status(member.status)
|
||||
except:
|
||||
pass
|
||||
member.game_id = data.get('game_id')
|
||||
member.name = user.get('username', member.name)
|
||||
member.avatar = user.get('avatar', member.avatar)
|
||||
|
61
docs/api.rst
61
docs/api.rst
@ -297,6 +297,67 @@ Utility Functions
|
||||
.. autofunction:: discord.utils.find
|
||||
|
||||
|
||||
Enumerators
|
||||
------------
|
||||
|
||||
The API provides some enumerators for certain types of strings to avoid the API
|
||||
from being stringly typed in case the strings change in the future.
|
||||
|
||||
All enumerators are subclasses of `enum`_.
|
||||
|
||||
.. _enum: https://docs.python.org/3/library/enum.html
|
||||
|
||||
.. class:: ChannelType
|
||||
|
||||
Specifies the type of :class:`Channel`.
|
||||
|
||||
.. attribute:: text
|
||||
|
||||
A text channel.
|
||||
.. attribute:: voice
|
||||
|
||||
A voice channel.
|
||||
|
||||
.. class:: ServerRegion
|
||||
|
||||
Specifies the region a :class:`Server`'s voice server belongs to.
|
||||
|
||||
.. attribute:: us_west
|
||||
|
||||
The US West region.
|
||||
.. attribute:: us_east
|
||||
|
||||
The US East region.
|
||||
.. attribute:: singapore
|
||||
|
||||
The Singapore region.
|
||||
.. attribute:: london
|
||||
|
||||
The London region.
|
||||
.. attribute:: sydney
|
||||
|
||||
The Sydney region.
|
||||
.. attribute:: amsterdam
|
||||
|
||||
The Amsterdam region.
|
||||
.. attribute:: frankfurt
|
||||
|
||||
The Frankfurt region.
|
||||
|
||||
.. class:: Status
|
||||
|
||||
Specifies a :class:`Member` 's status.
|
||||
|
||||
.. attribute:: online
|
||||
|
||||
The member is online.
|
||||
.. attribute:: offline
|
||||
|
||||
The member is offline.
|
||||
.. attribute:: idle
|
||||
|
||||
The member is idle.
|
||||
|
||||
Data Classes
|
||||
--------------
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user