Browse Source

Rename Server to Guild everywhere.

pull/447/head
Rapptz 9 years ago
parent
commit
d1d54a468a
  1. 4
      discord/__init__.py
  2. 2
      discord/abc.py
  3. 8
      discord/calls.py
  4. 66
      discord/channel.py
  5. 444
      discord/client.py
  6. 12
      discord/emoji.py
  7. 2
      discord/enums.py
  8. 6
      discord/ext/commands/bot.py
  9. 50
      discord/ext/commands/converter.py
  10. 6
      discord/ext/commands/cooldowns.py
  11. 10
      discord/ext/commands/core.py
  12. 12
      discord/gateway.py
  13. 90
      discord/guild.py
  14. 12
      discord/http.py
  15. 10
      discord/invite.py
  16. 40
      discord/member.py
  17. 32
      discord/message.py
  18. 24
      discord/permissions.py
  19. 20
      discord/role.py
  20. 276
      discord/state.py
  21. 2
      discord/user.py
  22. 20
      discord/utils.py
  23. 12
      discord/voice_client.py
  24. 102
      docs/api.rst

4
discord/__init__.py

@ -22,7 +22,7 @@ from .user import User
from .game import Game
from .emoji import Emoji
from .channel import *
from .server import Server
from .guild import Guild
from .member import Member, VoiceState
from .message import Message
from .errors import *
@ -35,7 +35,7 @@ from .object import Object
from .reaction import Reaction
from . import utils, opus, compat, abc
from .voice_client import VoiceClient
from .enums import ChannelType, ServerRegion, Status, MessageType, VerificationLevel
from .enums import ChannelType, GuildRegion, Status, MessageType, VerificationLevel
from collections import namedtuple
from .embeds import Embed

2
discord/abc.py

@ -107,7 +107,7 @@ class GuildChannel(metaclass=abc.ABCMeta):
return NotImplemented
mro = C.__mro__
for attr in ('name', 'server', 'overwrites_for', 'permissions_for', 'mention'):
for attr in ('name', 'guild', 'overwrites_for', 'permissions_for', 'mention'):
for base in mro:
if attr in base.__dict__:
break

8
discord/calls.py

@ -26,7 +26,7 @@ DEALINGS IN THE SOFTWARE.
from . import utils
import datetime
from .enums import ServerRegion, try_enum
from .enums import GuildRegion, try_enum
from .member import VoiceState
class CallMessage:
@ -90,8 +90,8 @@ class GroupCall:
Denotes if this group call is unavailable.
ringing: List[:class:`User`]
A list of users that are currently being rung to join the call.
region: :class:`ServerRegion`
The server region the group call is being hosted on.
region: :class:`GuildRegion`
The guild region the group call is being hosted on.
"""
def __init__(self, **kwargs):
@ -105,7 +105,7 @@ class GroupCall:
self._update(**kwargs)
def _update(self, **kwargs):
self.region = try_enum(ServerRegion, kwargs.get('region'))
self.region = try_enum(GuildRegion, kwargs.get('region'))
lookup = {u.id: u for u in self.call.channel.recipients}
me = self.call.channel.me
lookup[me.id] = me

66
discord/channel.py

@ -51,8 +51,8 @@ class CommonGuildChannel(Hashable):
raise InvalidArgument('Channel position cannot be less than 0.')
http = self._state.http
url = '{0}/{1.server.id}/channels'.format(http.GUILDS, self)
channels = [c for c in self.server.channels if isinstance(c, type(self))]
url = '{0}/{1.guild.id}/channels'.format(http.GUILDS, self)
channels = [c for c in self.guild.channels if isinstance(c, type(self))]
if position >= len(channels):
raise InvalidArgument('Channel position cannot be greater than {}'.format(len(channels) - 1))
@ -75,7 +75,7 @@ class CommonGuildChannel(Hashable):
def _fill_overwrites(self, data):
self._overwrites = []
everyone_index = 0
everyone_id = self.server.id
everyone_id = self.guild.id
for index, overridden in enumerate(data.get('permission_overwrites', [])):
overridden_id = int(overridden.pop('id'))
@ -100,10 +100,10 @@ class CommonGuildChannel(Hashable):
@property
def changed_roles(self):
"""Returns a list of :class:`Roles` that have been overridden from
their default values in the :attr:`Server.roles` attribute."""
their default values in the :attr:`Guild.roles` attribute."""
ret = []
for overwrite in filter(lambda o: o.type == 'role', self._overwrites):
role = utils.get(self.server.roles, id=overwrite.id)
role = utils.get(self.guild.roles, id=overwrite.id)
if role is None:
continue
@ -114,8 +114,8 @@ class CommonGuildChannel(Hashable):
@property
def is_default(self):
"""bool : Indicates if this is the default channel for the :class:`Server` it belongs to."""
return self.server.id == self.id
"""bool : Indicates if this is the default channel for the :class:`Guild` it belongs to."""
return self.guild.id == self.id
@property
def mention(self):
@ -190,8 +190,8 @@ class CommonGuildChannel(Hashable):
This function takes into consideration the following cases:
- Server owner
- Server roles
- Guild owner
- Guild roles
- Channel overrides
- Member overrides
- Whether the channel is the default channel.
@ -208,7 +208,7 @@ class CommonGuildChannel(Hashable):
"""
# The current cases can be explained as:
# Server owner get all permissions -- no questions asked. Otherwise...
# Guild owner get all permissions -- no questions asked. Otherwise...
# The @everyone role gets the first application.
# After that, the applied roles that the user has in the channel
# (or otherwise) are then OR'd together.
@ -223,17 +223,17 @@ class CommonGuildChannel(Hashable):
# The operation first takes into consideration the denied
# and then the allowed.
if member.id == self.server.owner.id:
if member.id == self.guild.owner.id:
return Permissions.all()
default = self.server.default_role
default = self.guild.default_role
base = Permissions(default.permissions.value)
# Apply server roles that the member has.
# Apply guild roles that the member has.
for role in member.roles:
base.value |= role.permissions.value
# Server-wide Administrator -> True for everything
# Guild-wide Administrator -> True for everything
# Bypass all channel-specific overrides
if base.administrator:
return Permissions.all()
@ -300,7 +300,7 @@ class CommonGuildChannel(Hashable):
yield from self._state.http.delete_channel(self.id)
class TextChannel(abc.MessageChannel, CommonGuildChannel):
"""Represents a Discord server text channel.
"""Represents a Discord guild text channel.
Supported Operations:
@ -320,8 +320,8 @@ class TextChannel(abc.MessageChannel, CommonGuildChannel):
-----------
name: str
The channel name.
server: :class:`Server`
The server the channel belongs to.
guild: :class:`Guild`
The guild the channel belongs to.
id: int
The channel ID.
topic: Optional[str]
@ -331,23 +331,23 @@ class TextChannel(abc.MessageChannel, CommonGuildChannel):
top channel is position 0.
"""
__slots__ = ( 'name', 'id', 'server', 'topic', '_state',
__slots__ = ( 'name', 'id', 'guild', 'topic', '_state',
'position', '_overwrites' )
def __init__(self, *, state, server, data):
def __init__(self, *, state, guild, data):
self._state = state
self.id = int(data['id'])
self._update(server, data)
self._update(guild, data)
def _update(self, server, data):
self.server = server
def _update(self, guild, data):
self.guild = guild
self.name = data['name']
self.topic = data.get('topic')
self.position = data['position']
self._fill_overwrites(data)
def _get_destination(self):
return self.id, self.server.id
return self.id, self.guild.id
@asyncio.coroutine
def edit(self, **options):
@ -385,10 +385,10 @@ class TextChannel(abc.MessageChannel, CommonGuildChannel):
if options:
data = yield from self._state.http.edit_channel(self.id, **options)
self._update(self.server, data)
self._update(self.guild, data)
class VoiceChannel(CommonGuildChannel):
"""Represents a Discord server voice channel.
"""Represents a Discord guild voice channel.
Supported Operations:
@ -408,8 +408,8 @@ class VoiceChannel(CommonGuildChannel):
-----------
name: str
The channel name.
server: :class:`Server`
The server the channel belongs to.
guild: :class:`Guild`
The guild the channel belongs to.
id: int
The channel ID.
position: int
@ -423,17 +423,17 @@ class VoiceChannel(CommonGuildChannel):
The channel's limit for number of members that can be in a voice channel.
"""
__slots__ = ( 'voice_members', 'name', 'id', 'server', 'bitrate',
__slots__ = ( 'voice_members', 'name', 'id', 'guild', 'bitrate',
'user_limit', '_state', 'position', '_overwrites' )
def __init__(self, *, state, server, data):
def __init__(self, *, state, guild, data):
self._state = state
self.id = int(data['id'])
self._update(server, data)
self._update(guild, data)
self.voice_members = []
def _update(self, server, data):
self.server = server
def _update(self, guild, data):
self.guild = guild
self.name = data['name']
self.position = data['position']
self.bitrate = data.get('bitrate')
@ -475,7 +475,7 @@ class VoiceChannel(CommonGuildChannel):
if options:
data = yield from self._state.http.edit_channel(self.id, **options)
self._update(self.server, data)
self._update(self.guild, data)
class DMChannel(abc.MessageChannel, Hashable):
"""Represents a Discord direct message channel.

444
discord/client.py

File diff suppressed because it is too large

12
discord/emoji.py

@ -62,16 +62,16 @@ class Emoji(Hashable):
If colons are required to use this emoji in the client (:PJSalt: vs PJSalt).
managed: bool
If this emoji is managed by a Twitch integration.
server: :class:`Server`
The server the emoji belongs to.
guild: :class:`Guild`
The guild the emoji belongs to.
roles: List[:class:`Role`]
A list of :class:`Role` that is allowed to use this emoji. If roles is empty,
the emoji is unrestricted.
"""
__slots__ = ('require_colons', 'managed', 'id', 'name', 'roles', 'server', '_state')
__slots__ = ('require_colons', 'managed', 'id', 'name', 'roles', 'guild', '_state')
def __init__(self, *, server, state, data):
self.server = server
def __init__(self, *, guild, state, data):
self.guild = guild
self._state = state
self._from_data(data)
@ -83,7 +83,7 @@ class Emoji(Hashable):
self.roles = emoji.get('roles', [])
if self.roles:
roles = set(self.roles)
self.roles = [role for role in self.server.roles if role.id in roles]
self.roles = [role for role in self.guild.roles if role.id in roles]
def _iterator(self):
for attr in self.__slots__:

2
discord/enums.py

@ -44,7 +44,7 @@ class MessageType(Enum):
channel_icon_change = 5
pins_add = 6
class ServerRegion(Enum):
class GuildRegion(Enum):
us_west = 'us-west'
us_east = 'us-east'
us_south = 'us-south'

6
discord/ext/commands/bot.py

@ -55,9 +55,9 @@ def _get_variable(name):
def when_mentioned(bot, msg):
"""A callable that implements a command prefix equivalent
to being mentioned, e.g. ``@bot ``."""
server = msg.server
if server is not None:
return '{0.me.mention} '.format(server)
guild = msg.guild
if guild is not None:
return '{0.me.mention} '.format(guild)
return '{0.user.mention} '.format(bot)
def when_mentioned_or(*prefixes):

50
discord/ext/commands/converter.py

@ -35,10 +35,10 @@ __all__ = [ 'Converter', 'MemberConverter', 'UserConverter',
'ChannelConverter', 'InviteConverter', 'RoleConverter',
'GameConverter', 'ColourConverter' ]
def _get_from_servers(bot, getter, argument):
def _get_from_guilds(bot, getter, argument):
result = None
for server in bot.servers:
result = getattr(server, getter)(argument)
for guild in bot.guilds:
result = getattr(guild, getter)(argument)
if result:
return result
return result
@ -81,20 +81,20 @@ class MemberConverter(IDConverter):
message = self.ctx.message
bot = self.ctx.bot
match = self._get_id_match() or re.match(r'<@!?([0-9]+)>$', self.argument)
server = message.server
guild = message.guild
result = None
if match is None:
# not a mention...
if server:
result = server.get_member_named(self.argument)
if guild:
result = guild.get_member_named(self.argument)
else:
result = _get_from_servers(bot, 'get_member_named', self.argument)
result = _get_from_guilds(bot, 'get_member_named', self.argument)
else:
user_id = int(match.group(1))
if server:
result = server.get_member(user_id)
if guild:
result = guild.get_member(user_id)
else:
result = _get_from_servers(bot, 'get_member', user_id)
result = _get_from_guilds(bot, 'get_member', user_id)
if result is None:
raise BadArgument('Member "{}" not found'.format(self.argument))
@ -110,19 +110,19 @@ class ChannelConverter(IDConverter):
match = self._get_id_match() or re.match(r'<#([0-9]+)>$', self.argument)
result = None
server = message.server
guild = message.guild
if match is None:
# not a mention
if server:
result = discord.utils.get(server.channels, name=self.argument)
if guild:
result = discord.utils.get(guild.channels, name=self.argument)
else:
result = discord.utils.get(bot.get_all_channels(), name=self.argument)
else:
channel_id = int(match.group(1))
if server:
result = server.get_channel(channel_id)
if guild:
result = guild.get_channel(channel_id)
else:
result = _get_from_servers(bot, 'get_channel', channel_id)
result = _get_from_guilds(bot, 'get_channel', channel_id)
if result is None:
raise BadArgument('Channel "{}" not found.'.format(self.argument))
@ -146,13 +146,13 @@ class ColourConverter(Converter):
class RoleConverter(IDConverter):
def convert(self):
server = self.ctx.message.server
if not server:
guild = self.ctx.message.guild
if not guild:
raise NoPrivateMessage()
match = self._get_id_match() or re.match(r'<@&([0-9]+)>$', self.argument)
params = dict(id=int(match.group(1))) if match else dict(name=self.argument)
result = discord.utils.get(server.roles, **params)
result = discord.utils.get(guild.roles, **params)
if result is None:
raise BadArgument('Role "{}" not found.'.format(self.argument))
return result
@ -178,11 +178,11 @@ class EmojiConverter(IDConverter):
match = self._get_id_match() or re.match(r'<:[a-zA-Z0-9]+:([0-9]+)>$', self.argument)
result = None
server = message.server
guild = message.guild
if match is None:
# Try to get the emoji by name. Try local server first.
if server:
result = discord.utils.get(server.emojis, name=self.argument)
# Try to get the emoji by name. Try local guild first.
if guild:
result = discord.utils.get(guild.emojis, name=self.argument)
if result is None:
result = discord.utils.get(bot.get_all_emojis(), name=self.argument)
@ -190,8 +190,8 @@ class EmojiConverter(IDConverter):
emoji_id = int(match.group(1))
# Try to look up emoji by id.
if server:
result = discord.utils.get(server.emojis, id=emoji_id)
if guild:
result = discord.utils.get(guild.emojis, id=emoji_id)
if result is None:
result = discord.utils.get(bot.get_all_emojis(), id=emoji_id)

6
discord/ext/commands/cooldowns.py

@ -31,7 +31,7 @@ __all__ = ['BucketType', 'Cooldown', 'CooldownMapping']
class BucketType(enum.Enum):
default = 0
user = 1
server = 2
guild = 2
channel = 3
class Cooldown:
@ -97,8 +97,8 @@ class CooldownMapping:
bucket_type = self._cooldown.type
if bucket_type is BucketType.user:
return msg.author.id
elif bucket_type is BucketType.server:
return getattr(msg.server, 'id', msg.author.id)
elif bucket_type is BucketType.guild:
return getattr(msg.guild, 'id', msg.author.id)
elif bucket_type is BucketType.channel:
return msg.channel.id

10
discord/ext/commands/core.py

@ -847,7 +847,7 @@ def bot_has_role(name):
ch = ctx.message.channel
if ch.is_private:
return False
me = ch.server.me
me = ch.guild.me
role = discord.utils.get(me.roles, name=name)
return role is not None
return check(predicate)
@ -860,7 +860,7 @@ def bot_has_any_role(*names):
ch = ctx.message.channel
if ch.is_private:
return False
me = ch.server.me
me = ch.guild.me
getter = functools.partial(discord.utils.get, me.roles)
return any(getter(name=name) is not None for name in names)
return check(predicate)
@ -871,7 +871,7 @@ def bot_has_permissions(**perms):
"""
def predicate(ctx):
ch = ctx.message.channel
me = ch.server.me if not ch.is_private else ctx.bot.user
me = ch.guild.me if not ch.is_private else ctx.bot.user
permissions = ch.permissions_for(me)
return all(getattr(permissions, perm, None) == value for perm, value in perms.items())
return check(predicate)
@ -882,13 +882,13 @@ def cooldown(rate, per, type=BucketType.default):
A cooldown allows a command to only be used a specific amount
of times in a specific time frame. These cooldowns can be based
either on a per-server, per-channel, per-user, or global basis.
either on a per-guild, per-channel, per-user, or global basis.
Denoted by the third argument of ``type`` which must be of enum
type ``BucketType`` which could be either:
- ``BucketType.default`` for a global basis.
- ``BucketType.user`` for a per-user basis.
- ``BucketType.server`` for a per-server basis.
- ``BucketType.guild`` for a per-guild basis.
- ``BucketType.channel`` for a per-channel basis.
If a cooldown is triggered, then :exc:`CommandOnCooldown` is triggered in

12
discord/gateway.py

@ -115,15 +115,15 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol):
PRESENCE
Send only. Updates your presence.
VOICE_STATE
Send only. Starts a new connection to a voice server.
Send only. Starts a new connection to a voice guild.
VOICE_PING
Send only. Checks ping time to a voice server, do not use.
Send only. Checks ping time to a voice guild, do not use.
RESUME
Send only. Resumes an existing connection.
RECONNECT
Receive only. Tells the client to reconnect to a new gateway.
REQUEST_MEMBERS
Send only. Asks for the full member list of a server.
Send only. Asks for the full member list of a guild.
INVALIDATE_SESSION
Receive only. Tells the client to invalidate the session and IDENTIFY
again.
@ -436,8 +436,8 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol):
if status_enum is Status.invisible:
status_enum = Status.offline
for server in self._connection.servers:
me = server.me
for guild in self._connection.guilds:
me = guild.me
if me is None:
continue
@ -524,7 +524,7 @@ class DiscordVoiceWebSocket(websockets.client.WebSocketClientProtocol):
identify = {
'op': cls.IDENTIFY,
'd': {
'server_id': client.guild_id,
'guild_id': client.guild_id,
'user_id': client.user.id,
'session_id': client.session_id,
'token': client.token

90
discord/server.py → discord/guild.py

@ -30,88 +30,90 @@ from .member import Member, VoiceState
from .emoji import Emoji
from .game import Game
from .channel import *
from .enums import ServerRegion, Status, ChannelType, try_enum, VerificationLevel
from .enums import GuildRegion, Status, ChannelType, try_enum, VerificationLevel
from .mixins import Hashable
import copy
class Server(Hashable):
"""Represents a Discord server.
class Guild(Hashable):
"""Represents a Discord guild.
This is referred to as a "server" in the official Discord UI.
Supported Operations:
+-----------+--------------------------------------+
| Operation | Description |
+===========+======================================+
| x == y | Checks if two servers are equal. |
| x == y | Checks if two guilds are equal. |
+-----------+--------------------------------------+
| x != y | Checks if two servers are not equal. |
| x != y | Checks if two guilds are not equal. |
+-----------+--------------------------------------+
| hash(x) | Returns the server's hash. |
| hash(x) | Returns the guild's hash. |
+-----------+--------------------------------------+
| str(x) | Returns the server's name. |
| str(x) | Returns the guild's name. |
+-----------+--------------------------------------+
Attributes
----------
name: str
The server name.
The guild name.
me: :class:`Member`
Similar to :attr:`Client.user` except an instance of :class:`Member`.
This is essentially used to get the member version of yourself.
roles
A list of :class:`Role` that the server has available.
A list of :class:`Role` that the guild has available.
emojis
A list of :class:`Emoji` that the server owns.
region: :class:`ServerRegion`
The region the server belongs on. There is a chance that the region
A list of :class:`Emoji` that the guild owns.
region: :class:`GuildRegion`
The region the guild 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.
afk_channel: :class:`Channel`
The channel that denotes the AFK channel. None if it doesn't exist.
members
An iterable of :class:`Member` that are currently on the server.
An iterable of :class:`Member` that are currently on the guild.
channels
An iterable of :class:`Channel` that are currently on the server.
An iterable of :class:`Channel` that are currently on the guild.
icon: str
The server's icon.
The guild's icon.
id: int
The server's ID.
The guild's ID.
owner_id: int
The server owner's ID. Use :attr:`Server.owner` instead.
The guild owner's ID. Use :attr:`Guild.owner` instead.
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.
Indicates if the guild is unavailable. If this is ``True`` then the
reliability of other attributes outside of :meth:`Guild.id` is slim and they might
all be None. It is best to not do anything with the guild if it is unavailable.
Check the :func:`on_server_unavailable` and :func:`on_server_available` events.
Check the :func:`on_guild_unavailable` and :func:`on_guild_available` events.
large: bool
Indicates if the server is a 'large' server. A large server is defined as having
Indicates if the guild is a 'large' guild. A large guild is defined as having
more than ``large_threshold`` count members, which for this library is set to
the maximum of 250.
voice_client: Optional[:class:`VoiceClient`]
The VoiceClient associated with this server. A shortcut for the
The VoiceClient associated with this guild. A shortcut for the
:meth:`Client.voice_client_in` call.
mfa_level: int
Indicates the server's two factor authorisation level. If this value is 0 then
the server does not require 2FA for their administrative members. If the value is
Indicates the guild's two factor authorisation level. If this value is 0 then
the guild does not require 2FA for their administrative members. If the value is
1 then they do.
verification_level: :class:`VerificationLevel`
The server's verification level.
The guild's verification level.
features: List[str]
A list of features that the server has. They are currently as follows:
A list of features that the guild has. They are currently as follows:
- ``VIP_REGIONS``: Server has VIP voice regions
- ``VANITY_URL``: Server has a vanity invite URL (e.g. discord.gg/discord-api)
- ``INVITE_SPLASH``: Server's invite page has a special splash.
- ``VIP_REGIONS``: Guild has VIP voice regions
- ``VANITY_URL``: Guild has a vanity invite URL (e.g. discord.gg/discord-api)
- ``INVITE_SPLASH``: Guild's invite page has a special splash.
splash: str
The server's invite splash.
The guild's invite splash.
"""
__slots__ = ('afk_timeout', 'afk_channel', '_members', '_channels', 'icon',
'name', 'id', 'unavailable', 'name', 'region',
'name', 'id', 'unavailable', 'name', 'region', '_state',
'_default_role', '_default_channel', 'roles', '_member_count',
'large', 'owner_id', 'mfa_level', 'emojis', 'features',
'verification_level', 'splash', '_voice_states' )
@ -218,19 +220,19 @@ class Server(Hashable):
def _from_data(self, guild):
# according to Stan, this is always available even if the guild is unavailable
# I don't have this guarantee when someone updates the server.
# I don't have this guarantee when someone updates the guild.
member_count = guild.get('member_count', None)
if member_count:
self._member_count = member_count
self.name = guild.get('name')
self.region = try_enum(ServerRegion, guild.get('region'))
self.region = try_enum(GuildRegion, guild.get('region'))
self.verification_level = try_enum(VerificationLevel, guild.get('verification_level'))
self.afk_timeout = guild.get('afk_timeout')
self.icon = guild.get('icon')
self.unavailable = guild.get('unavailable', False)
self.id = int(guild['id'])
self.roles = [Role(server=self, data=r, state=self._state) for r in guild.get('roles', [])]
self.roles = [Role(guild=self, data=r, state=self._state) for r in guild.get('roles', [])]
self.mfa_level = guild.get('mfa_level')
self.emojis = [Emoji(server=self, data=r, state=self._state) for r in guild.get('emojis', [])]
self.features = guild.get('features', [])
@ -244,7 +246,7 @@ class Server(Hashable):
roles.append(role)
mdata['roles'] = roles
member = Member(data=mdata, server=self, state=self._state)
member = Member(data=mdata, guild=self, state=self._state)
self._add_member(member)
self._sync(guild)
@ -274,9 +276,9 @@ class Server(Hashable):
channels = data['channels']
for c in channels:
if c['type'] == ChannelType.text.value:
channel = TextChannel(server=self, data=c, state=self._state)
channel = TextChannel(guild=self, data=c, state=self._state)
else:
channel = VoiceChannel(server=self, data=c, state=self._state)
channel = VoiceChannel(guild=self, data=c, state=self._state)
self._add_channel(channel)
@ -287,17 +289,17 @@ class Server(Hashable):
@utils.cached_slot_property('_default_channel')
def default_channel(self):
"""Gets the default :class:`Channel` for the server."""
"""Gets the default :class:`Channel` for the guild."""
return utils.find(lambda c: c.is_default, self.channels)
@property
def owner(self):
""":class:`Member`: The member that owns the server."""
""":class:`Member`: The member that owns the guild."""
return self.get_member(self.owner_id)
@property
def icon_url(self):
"""Returns the URL version of the server's icon. Returns an empty string if it has no icon."""
"""Returns the URL version of the guild's icon. Returns an empty string if it has no icon."""
if self.icon is None:
return ''
return 'https://discordapp.com/api/guilds/{0.id}/icons/{0.icon}.jpg'.format(self)
@ -316,12 +318,12 @@ class Server(Hashable):
@property
def created_at(self):
"""Returns the server's creation time in UTC."""
"""Returns the guild's creation time in UTC."""
return utils.snowflake_time(self.id)
@property
def role_hierarchy(self):
"""Returns the server's roles in the order of the hierarchy.
"""Returns the guild's roles in the order of the hierarchy.
The first element of this list will be the highest role in the
hierarchy.
@ -351,7 +353,7 @@ class Server(Hashable):
Returns
--------
:class:`Member`
The member in this server with the associated name. If not found
The member in this guild with the associated name. If not found
then ``None`` is returned.
"""

12
discord/http.py

@ -341,7 +341,7 @@ class HTTPClient:
url = '{0.GUILDS}/{1}/bans/{2}'.format(self, guild_id, user_id)
return self.delete(url, bucket=_func_())
def server_voice_state(self, user_id, guild_id, *, mute=None, deafen=None):
def guild_voice_state(self, user_id, guild_id, *, mute=None, deafen=None):
url = '{0.GUILDS}/{1}/members/{2}'.format(self, guild_id, user_id)
payload = {}
if mute is not None:
@ -411,17 +411,17 @@ class HTTPClient:
url = '{0.CHANNELS}/{1}'.format(self, channel_id)
return self.delete(url, bucket=_func_())
# Server management
# Guild management
def leave_server(self, guild_id):
def leave_guild(self, guild_id):
url = '{0.USERS}/@me/guilds/{1}'.format(self, guild_id)
return self.delete(url, bucket=_func_())
def delete_server(self, guild_id):
def delete_guild(self, guild_id):
url = '{0.GUILDS}/{1}'.format(self, guild_id)
return self.delete(url, bucket=_func_())
def create_server(self, name, region, icon):
def create_guild(self, name, region, icon):
payload = {
'name': name,
'icon': icon,
@ -430,7 +430,7 @@ class HTTPClient:
return self.post(self.GUILDS, json=payload, bucket=_func_())
def edit_server(self, guild_id, **fields):
def edit_guild(self, guild_id, **fields):
valid_keys = ('name', 'region', 'icon', 'afk_timeout', 'owner_id',
'afk_channel_id', 'splash', 'verification_level')

10
discord/invite.py

@ -29,7 +29,7 @@ from .utils import parse_time
from .mixins import Hashable
class Invite(Hashable):
"""Represents a Discord :class:`Server` or :class:`Channel` invite.
"""Represents a Discord :class:`Guild` or :class:`Channel` invite.
Depending on the way this object was created, some of the attributes can
have a value of ``None``.
@ -54,8 +54,8 @@ class Invite(Hashable):
How long the before the invite expires in seconds. A value of 0 indicates that it doesn't expire.
code: str
The URL fragment used for the invite. :attr:`xkcd` is also a possible fragment.
server: :class:`Server`
The server the invite is for.
guild: :class:`Guild`
The guild the invite is for.
revoked: bool
Indicates if the invite has been revoked.
created_at: `datetime.datetime`
@ -74,14 +74,14 @@ class Invite(Hashable):
"""
__slots__ = ( 'max_age', 'code', 'server', 'revoked', 'created_at', 'uses',
__slots__ = ( 'max_age', 'code', 'guild', 'revoked', 'created_at', 'uses',
'temporary', 'max_uses', 'inviter', 'channel', '_state' )
def __init__(self, *, state, data):
self._state = state
self.max_age = data.get('max_age')
self.code = data.get('code')
self.server = data.get('server')
self.guild = data.get('guild')
self.revoked = data.get('revoked')
self.created_at = parse_time(data.get('created_at'))
self.temporary = data.get('temporary')

40
discord/member.py

@ -37,15 +37,15 @@ class VoiceState:
Attributes
------------
deaf: bool
Indicates if the user is currently deafened by the server.
Indicates if the user is currently deafened by the guild.
mute: bool
Indicates if the user is currently muted by the server.
Indicates if the user is currently muted by the guild.
self_mute: bool
Indicates if the user is currently muted by their own accord.
self_deaf: bool
Indicates if the user is currently deafened by their own accord.
is_afk: bool
Indicates if the user is currently in the AFK channel in the server.
Indicates if the user is currently in the AFK channel in the guild.
channel: Optional[Union[:class:`Channel`, :class:`PrivateChannel`]]
The voice channel that the user is currently connected to. None if the user
is not currently in a voice channel.
@ -99,7 +99,7 @@ def flatten_user(cls):
@flatten_user
class Member:
"""Represents a Discord member to a :class:`Server`.
"""Represents a Discord member to a :class:`Guild`.
This implements a lot of the functionality of :class:`User`.
@ -123,22 +123,22 @@ class Member:
A list of :class:`Role` that the member belongs to. Note that the first element of this
list is always the default '@everyone' role.
joined_at : `datetime.datetime`
A datetime object that specifies the date and time in UTC that the member joined the server for
A datetime object that specifies the date and time in UTC that the member joined the guild for
the first time.
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 : :class:`Game`
The game that the user is currently playing. Could be None if no game is being played.
server : :class:`Server`
The server that the member belongs to.
guild : :class:`Guild`
The guild that the member belongs to.
nick : Optional[str]
The server specific nickname of the user.
The guild specific nickname of the user.
"""
__slots__ = ('roles', 'joined_at', 'status', 'game', 'server', 'nick', '_user', '_state')
__slots__ = ('roles', 'joined_at', 'status', 'game', 'guild', 'nick', '_user', '_state')
def __init__(self, *, data, server, state):
def __init__(self, *, data, guild, state):
self._state = state
self._user = state.try_insert_user(data['user'])
self.joined_at = utils.parse_time(data.get('joined_at'))
@ -146,14 +146,14 @@ class Member:
self.status = Status.offline
game = data.get('game', {})
self.game = Game(**game) if game else None
self.server = server
self.guild = guild
self.nick = data.get('nick', None)
def __str__(self):
return self._user.__str__()
def __eq__(self, other):
return isinstance(other, Member) and other._user.id == self._user.id and self.server.id == other.server.id
return isinstance(other, Member) and other._user.id == self._user.id and self.guild.id == other.guild.id
def __ne__(self, other):
return not self.__eq__(other)
@ -173,8 +173,8 @@ class Member:
self.nick = data['nick']
# update the roles
self.roles = [self.server.default_role]
for role in self.server.roles:
self.roles = [self.guild.default_role]
for role in self.guild.roles:
if role.id in data['roles']:
self.roles.append(role)
@ -254,20 +254,20 @@ class Member:
return None
@property
def server_permissions(self):
"""Returns the member's server permissions.
def guild_permissions(self):
"""Returns the member's guild permissions.
This only takes into consideration the server permissions
This only takes into consideration the guild permissions
and not most of the implied permissions or any of the
channel permission overwrites. For 100% accurate permission
calculation, please use either :meth:`permissions_in` or
:meth:`Channel.permissions_for`.
This does take into consideration server ownership and the
This does take into consideration guild ownership and the
administrator implication.
"""
if self.server.owner == self:
if self.guild.owner == self:
return Permissions.all()
base = Permissions.none()
@ -282,4 +282,4 @@ class Member:
@property
def voice(self):
"""Optional[:class:`VoiceState`]: Returns the member's current voice state."""
return self.server._voice_state_for(self._user.id)
return self.guild._voice_state_for(self._user.id)

32
discord/message.py

@ -54,7 +54,7 @@ class Message:
content: str
The actual contents of the message.
nonce
The value used by the discord server and the client to verify that the message is successfully sent.
The value used by the discord guild and the client to verify that the message is successfully sent.
This is typically non-important.
embeds: list
A list of embedded objects. The elements are objects that meet oEmbed's specification_.
@ -66,8 +66,8 @@ class Message:
In :issue:`very rare cases <21>` this could be a :class:`Object` instead.
For the sake of convenience, this :class:`Object` instance has an attribute ``is_private`` set to ``True``.
server: Optional[:class:`Server`]
The server that the message belongs to. If not applicable (i.e. a PM) then it's None instead.
guild: Optional[:class:`Guild`]
The guild that the message belongs to. If not applicable (i.e. a PM) then it's None instead.
call: Optional[:class:`CallMessage`]
The call that the message refers to. This is only applicable to messages of type
:attr:`MessageType.call`.
@ -112,7 +112,7 @@ class Message:
__slots__ = ( 'edited_timestamp', 'tts', 'content', 'channel', 'webhook_id',
'mention_everyone', 'embeds', 'id', 'mentions', 'author',
'_cs_channel_mentions', 'server', '_cs_raw_mentions', 'attachments',
'_cs_channel_mentions', 'guild', '_cs_raw_mentions', 'attachments',
'_cs_clean_content', '_cs_raw_channel_mentions', 'nonce', 'pinned',
'role_mentions', '_cs_raw_role_mentions', 'type', 'call',
'_cs_system_content', '_state', 'reactions' )
@ -160,21 +160,21 @@ class Message:
def _handle_mentions(self, mentions):
self.mentions = []
if self.server is None:
if self.guild is None:
self.mentions = [self._state.try_insert_user(m) for m in mentions]
return
for mention in mentions:
id_search = int(mention['id'])
member = self.server.get_member(id_search)
member = self.guild.get_member(id_search)
if member is not None:
self.mentions.append(member)
def _handle_mention_roles(self, role_mentions):
self.role_mentions = []
if self.server is not None:
if self.guild is not None:
for role_id in role_mentions:
role = utils.get(self.server.roles, id=role_id)
role = utils.get(self.guild.roles, id=role_id)
if role is not None:
self.role_mentions.append(role)
@ -224,9 +224,9 @@ class Message:
@utils.cached_slot_property('_cs_channel_mentions')
def channel_mentions(self):
if self.server is None:
if self.guild is None:
return []
it = filter(None, map(lambda m: self.server.get_channel(m), self.raw_channel_mentions))
it = filter(None, map(lambda m: self.guild.get_channel(m), self.raw_channel_mentions))
return utils._unique(it)
@utils.cached_slot_property('_cs_clean_content')
@ -259,7 +259,7 @@ class Message:
transformations.update(mention_transforms)
transformations.update(second_mention_transforms)
if self.server is not None:
if self.guild is not None:
role_transforms = {
re.escape('<@&{0.id}>'.format(role)): '@' + role.name
for role in self.role_mentions
@ -284,7 +284,7 @@ class Message:
return pattern.sub(repl2, result)
def _handle_upgrades(self, channel_id):
self.server = None
self.guild = None
if isinstance(self.channel, Object):
return
@ -295,8 +295,8 @@ class Message:
return
if isinstance(self.channel, abc.GuildChannel):
self.server = self.channel.server
found = self.server.get_member(self.author.id)
self.guild = self.channel.guild
found = self.guild.get_member(self.author.id)
if found is not None:
self.author = found
@ -363,7 +363,7 @@ class Message:
HTTPException
Deleting the message failed.
"""
yield from self._state.http.delete_message(self.channel.id, self.id, getattr(self.server, 'id', None))
yield from self._state.http.delete_message(self.channel.id, self.id, getattr(self.guild, 'id', None))
@asyncio.coroutine
def edit(self, *, content: str):
@ -384,7 +384,7 @@ class Message:
Editing the message failed.
"""
guild_id = getattr(self.server, 'id', None)
guild_id = getattr(self.guild, '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)

24
discord/permissions.py

@ -132,10 +132,10 @@ class Permissions:
@classmethod
def all_channel(cls):
"""A :class:`Permissions` with all channel-specific permissions set to
True and the server-specific ones set to False. The server-specific
True and the guild-specific ones set to False. The guild-specific
permissions are currently:
- manager_server
- manager_guild
- kick_members
- ban_members
- administrator
@ -220,7 +220,7 @@ class Permissions:
@property
def kick_members(self):
"""Returns True if the user can kick users from the server."""
"""Returns True if the user can kick users from the guild."""
return self._bit(1)
@kick_members.setter
@ -229,7 +229,7 @@ class Permissions:
@property
def ban_members(self):
"""Returns True if a user can ban users from the server."""
"""Returns True if a user can ban users from the guild."""
return self._bit(2)
@ban_members.setter
@ -250,7 +250,7 @@ class Permissions:
@property
def manage_channels(self):
"""Returns True if a user can edit, delete, or create channels in the server.
"""Returns True if a user can edit, delete, or create channels in the guild.
This also corresponds to the "manage channel" channel-specific override."""
return self._bit(4)
@ -260,12 +260,12 @@ class Permissions:
self._set(4, value)
@property
def manage_server(self):
"""Returns True if a user can edit server properties."""
def manage_guild(self):
"""Returns True if a user can edit guild properties."""
return self._bit(5)
@manage_server.setter
def manage_server(self, value):
@manage_guild.setter
def manage_guild(self, value):
self._set(5, value)
@property
@ -353,7 +353,7 @@ class Permissions:
@property
def external_emojis(self):
"""Returns True if a user can use emojis from other servers."""
"""Returns True if a user can use emojis from other guilds."""
return self._bit(18)
@external_emojis.setter
@ -418,7 +418,7 @@ class Permissions:
@property
def change_nickname(self):
"""Returns True if a user can change their nickname in the server."""
"""Returns True if a user can change their nickname in the guild."""
return self._bit(26)
@change_nickname.setter
@ -427,7 +427,7 @@ class Permissions:
@property
def manage_nicknames(self):
"""Returns True if a user can change other user's nickname in the server."""
"""Returns True if a user can change other user's nickname in the guild."""
return self._bit(27)
@manage_nicknames.setter

20
discord/role.py

@ -30,7 +30,7 @@ from .mixins import Hashable
from .utils import snowflake_time
class Role(Hashable):
"""Represents a Discord role in a :class:`Server`.
"""Represents a Discord role in a :class:`Guild`.
Supported Operations:
@ -62,8 +62,8 @@ class Role(Hashable):
The name of the role.
permissions: :class:`Permissions`
Represents the role's permissions.
server: :class:`Server`
The server the role belongs to.
guild: :class:`Guild`
The guild the role belongs to.
colour: :class:`Colour`
Represents the role colour. An alias exists under ``color``.
hoist: bool
@ -72,17 +72,17 @@ class Role(Hashable):
The position of the role. This number is usually positive. The bottom
role has a position of 0.
managed: bool
Indicates if the role is managed by the server through some form of
Indicates if the role is managed by the guild through some form of
integrations such as Twitch.
mentionable: bool
Indicates if the role can be mentioned by users.
"""
__slots__ = ('id', 'name', 'permissions', 'color', 'colour', 'position',
'managed', 'mentionable', 'hoist', 'server', '_state' )
'managed', 'mentionable', 'hoist', 'guild', '_state' )
def __init__(self, *, server, state, data):
self.server = server
def __init__(self, *, guild, state, data):
self.guild = guild
self._state = state
self.id = int(data['id'])
self._update(data)
@ -94,8 +94,8 @@ class Role(Hashable):
if not isinstance(other, Role) or not isinstance(self, Role):
return NotImplemented
if self.server != other.server:
raise RuntimeError('cannot compare roles from two different servers.')
if self.guild != other.guild:
raise RuntimeError('cannot compare roles from two different guilds.')
if self.position < other.position:
return True
@ -133,7 +133,7 @@ class Role(Hashable):
@property
def is_everyone(self):
"""Checks if the role is the @everyone role."""
return self.server.id == self.id
return self.guild.id == self.id
@property
def created_at(self):

276
discord/state.py

@ -24,7 +24,7 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from .server import Server
from .guild import Guild
from .user import User
from .game import Game
from .emoji import Emoji
@ -49,7 +49,7 @@ class ListenerType(enum.Enum):
Listener = namedtuple('Listener', ('type', 'future', 'predicate'))
StateContext = namedtuple('StateContext', 'try_insert_user http')
log = logging.getLogger(__name__)
ReadyState = namedtuple('ReadyState', ('launch', 'servers'))
ReadyState = namedtuple('ReadyState', ('launch', 'guilds'))
class ConnectionState:
def __init__(self, *, dispatch, chunker, syncer, http, loop, **options):
@ -69,7 +69,7 @@ class ConnectionState:
self.session_id = None
self._calls = {}
self._users = {}
self._servers = {}
self._guilds = {}
self._voice_clients = {}
self._private_channels = {}
# extra dict to look up private channels by user id
@ -129,17 +129,17 @@ class ConnectionState:
return user
@property
def servers(self):
return self._servers.values()
def guilds(self):
return self._guilds.values()
def _get_server(self, server_id):
return self._servers.get(server_id)
def _get_guild(self, guild_id):
return self._guilds.get(guild_id)
def _add_server(self, server):
self._servers[server.id] = server
def _add_guild(self, guild):
self._guilds[guild.id] = guild
def _remove_server(self, server):
self._servers.pop(server.id, None)
def _remove_guild(self, guild):
self._guilds.pop(guild.id, None)
@property
def private_channels(self):
@ -164,16 +164,16 @@ class ConnectionState:
def _get_message(self, msg_id):
return utils.find(lambda m: m.id == msg_id, self.messages)
def _add_server_from_data(self, guild):
server = Server(data=guild, state=self.ctx)
Server.me = property(lambda s: s.get_member(self.user.id))
Server.voice_client = property(lambda s: self._get_voice_client(s.id))
self._add_server(server)
return server
def _add_guild_from_data(self, guild):
guild = Guild(data=guild, state=self.ctx)
Guild.me = property(lambda s: s.get_member(self.user.id))
Guild.voice_client = property(lambda s: self._get_voice_client(s.id))
self._add_guild(guild)
return guild
def chunks_needed(self, server):
for chunk in range(math.ceil(server._member_count / 1000)):
yield self.receive_chunk(server.id)
def chunks_needed(self, guild):
for chunk in range(math.ceil(guild._member_count / 1000)):
yield self.receive_chunk(guild.id)
@asyncio.coroutine
def _delay_ready(self):
@ -184,15 +184,15 @@ class ConnectionState:
launch.set()
yield from asyncio.sleep(2, loop=self.loop)
servers = self._ready_state.servers
guilds = self._ready_state.guilds
# get all the chunks
chunks = []
for server in servers:
chunks.extend(self.chunks_needed(server))
for guild in guilds:
chunks.extend(self.chunks_needed(guild))
# we only want to request ~75 guilds per chunk request.
splits = [servers[i:i + 75] for i in range(0, len(servers), 75)]
splits = [guilds[i:i + 75] for i in range(0, len(guilds), 75)]
for split in splits:
yield from self.chunker(split)
@ -211,22 +211,22 @@ class ConnectionState:
# call GUILD_SYNC after we're done chunking
if not self.is_bot:
log.info('Requesting GUILD_SYNC for %s guilds' % len(self.servers))
yield from self.syncer([s.id for s in self.servers])
log.info('Requesting GUILD_SYNC for %s guilds' % len(self.guilds))
yield from self.syncer([s.id for s in self.guilds])
# dispatch the event
self.dispatch('ready')
def parse_ready(self, data):
self._ready_state = ReadyState(launch=asyncio.Event(), servers=[])
self._ready_state = ReadyState(launch=asyncio.Event(), guilds=[])
self.user = self.try_insert_user(data['user'])
guilds = data.get('guilds')
servers = self._ready_state.servers
for guild in guilds:
server = self._add_server_from_data(guild)
if not self.is_bot or server.large:
servers.append(server)
guilds = self._ready_state.guilds
for guild_data in guilds:
guild = self._add_server_from_data(guild_data)
if not self.is_bot or guild.large:
guilds.append(guild)
for pm in data.get('private_channels'):
factory, _ = _channel_factory(pm['type'])
@ -324,22 +324,22 @@ class ConnectionState:
self.dispatch('reaction_remove', reaction, member)
def parse_presence_update(self, data):
server = self._get_server(utils._get_as_snowflake(data, 'guild_id'))
if server is None:
guild = self._get_guild(utils._get_as_snowflake(data, 'guild_id'))
if guild is None:
return
status = data.get('status')
user = data['user']
member_id = user['id']
member = server.get_member(member_id)
member = guild.get_member(member_id)
if member is None:
if 'username' not in user:
# sometimes we receive 'incomplete' member data post-removal.
# skip these useless cases.
return
member = self._make_member(server, data)
server._add_member(member)
member = self._make_member(guild, data)
guild._add_member(member)
old_member = copy.copy(member)
member._presence_update(data=data, user=user)
@ -349,12 +349,12 @@ class ConnectionState:
self.user = User(state=self.ctx, data=data)
def parse_channel_delete(self, data):
server = self._get_server(utils._get_as_snowflake(data, 'guild_id'))
guild = self._get_guild(utils._get_as_snowflake(data, 'guild_id'))
channel_id = int(data['id'])
if server is not None:
channel = server.get_channel(channel_id)
if guild is not None:
channel = guild.get_channel(channel_id)
if channel is not None:
server._remove_channel(channel)
guild._remove_channel(channel)
self.dispatch('channel_delete', channel)
else:
# the reason we're doing this is so it's also removed from the
@ -372,12 +372,12 @@ class ConnectionState:
self.dispatch('channel_update', old_channel, channel)
return
server = self._get_server(utils._get_as_snowflake(data, 'guild_id'))
if server is not None:
channel = server.get_channel(channel_id)
guild = self._get_guild(utils._get_as_snowflake(data, 'guild_id'))
if guild is not None:
channel = guild.get_channel(channel_id)
if channel is not None:
old_channel = copy.copy(channel)
channel._update(server, data)
channel._update(guild, data)
self.dispatch('channel_update', old_channel, channel)
def parse_channel_create(self, data):
@ -387,10 +387,10 @@ class ConnectionState:
channel = factory(me=self.user, data=data, state=self.ctx)
self._add_private_channel(channel)
else:
server = self._get_server(utils._get_as_snowflake(data, 'guild_id'))
if server is not None:
channel = factory(server=server, state=self.ctx, data=data)
server._add_channel(channel)
guild = self._get_guild(utils._get_as_snowflake(data, 'guild_id'))
if guild is not None:
channel = factory(guild=guild, state=self.ctx, data=data)
guild._add_channel(channel)
self.dispatch('channel_create', channel)
@ -410,34 +410,34 @@ class ConnectionState:
else:
self.dispatch('group_remove', channel, user)
def _make_member(self, server, data):
roles = [server.default_role]
def _make_member(self, guild, data):
roles = [guild.default_role]
for roleid in data.get('roles', []):
role = utils.get(server.roles, id=roleid)
role = utils.get(guild.roles, id=roleid)
if role is not None:
roles.append(role)
data['roles'] = sorted(roles, key=lambda r: r.id)
return Member(server=server, data=data, state=self.ctx)
return Member(guild=guild, data=data, state=self.ctx)
def parse_guild_member_add(self, data):
server = self._get_server(int(data['guild_id']))
member = self._make_member(server, data)
server._add_member(member)
server._member_count += 1
guild = self._get_guild(int(data['guild_id']))
member = self._make_member(guild, data)
guild._add_member(member)
guild._member_count += 1
self.dispatch('member_join', member)
def parse_guild_member_remove(self, data):
server = self._get_server(int(data['guild_id']))
if server is not None:
guild = self._get_guild(int(data['guild_id']))
if guild is not None:
user_id = data['user']['id']
member = server.get_member(user_id)
member = guild.get_member(user_id)
if member is not None:
server._remove_member(member)
server._member_count -= 1
guild._remove_member(member)
guild._member_count -= 1
# remove them from the voice channel member list
vc = server._voice_state_for(user_id)
vc = guild._voice_state_for(user_id)
if vc:
voice_channel = vc.channel
if voice_channel is not None:
@ -449,38 +449,38 @@ class ConnectionState:
self.dispatch('member_remove', member)
def parse_guild_member_update(self, data):
server = self._get_server(int(data['guild_id']))
guild = self._get_guild(int(data['guild_id']))
user = data['user']
user_id = user['id']
member = server.get_member(user_id)
member = guild.get_member(user_id)
if member is not None:
old_member = copy.copy(member)
member._update(data, user)
self.dispatch('member_update', old_member, member)
def parse_guild_emojis_update(self, data):
server = self._get_server(int(data['guild_id']))
before_emojis = server.emojis
server.emojis = [Emoji(server=server, data=e, state=self.ctx) for e in data.get('emojis', [])]
self.dispatch('server_emojis_update', before_emojis, server.emojis)
guild = self._get_guild(int(data['guild_id']))
before_emojis = guild.emojis
guild.emojis = [Emoji(guild=guild, data=e, state=self.ctx) for e in data.get('emojis', [])]
self.dispatch('guild_emojis_update', before_emojis, guild.emojis)
def _get_create_server(self, data):
def _get_create_guild(self, data):
if data.get('unavailable') == False:
# GUILD_CREATE with unavailable in the response
# usually means that the server has become available
# usually means that the guild has become available
# and is therefore in the cache
server = self._get_server(data.get('id'))
if server is not None:
server.unavailable = False
server._from_data(data)
return server
guild = self._get_guild(data.get('id'))
if guild is not None:
guild.unavailable = False
guild._from_data(data)
return guild
return self._add_server_from_data(data)
return self._add_guild_from_data(data)
@asyncio.coroutine
def _chunk_and_dispatch(self, server, unavailable):
yield from self.chunker(server)
chunks = list(self.chunks_needed(server))
def _chunk_and_dispatch(self, guild, unavailable):
yield from self.chunker(guild)
chunks = list(self.chunks_needed(guild))
if chunks:
try:
yield from asyncio.wait(chunks, timeout=len(chunks), loop=self.loop)
@ -488,30 +488,30 @@ class ConnectionState:
log.info('Somehow timed out waiting for chunks.')
if unavailable == False:
self.dispatch('server_available', server)
self.dispatch('guild_available', guild)
else:
self.dispatch('server_join', server)
self.dispatch('guild_join', guild)
def parse_guild_create(self, data):
unavailable = data.get('unavailable')
if unavailable == True:
# joined a server with unavailable == True so..
# joined a guild with unavailable == True so..
return
server = self._get_create_server(data)
guild = self._get_create_guild(data)
# check if it requires chunking
if server.large:
if guild.large:
if unavailable == False:
# check if we're waiting for 'useful' READY
# and if we are, we don't want to dispatch any
# event such as server_join or server_available
# event such as guild_join or guild_available
# because we're still in the 'READY' phase. Or
# so we say.
try:
state = self._ready_state
state.launch.clear()
state.servers.append(server)
state.guilds.append(guild)
except AttributeError:
# the _ready_state attribute is only there during
# processing of useful READY.
@ -521,43 +521,43 @@ class ConnectionState:
# since we're not waiting for 'useful' READY we'll just
# do the chunk request here
compat.create_task(self._chunk_and_dispatch(server, unavailable), loop=self.loop)
compat.create_task(self._chunk_and_dispatch(guild, unavailable), loop=self.loop)
return
# Dispatch available if newly available
if unavailable == False:
self.dispatch('server_available', server)
self.dispatch('guild_available', guild)
else:
self.dispatch('server_join', server)
self.dispatch('guild_join', guild)
def parse_guild_sync(self, data):
server = self._get_server(int(data['id']))
server._sync(data)
guild = self._get_guild(int(data['id']))
guild._sync(data)
def parse_guild_update(self, data):
server = self._get_server(int(data['id']))
if server is not None:
old_server = copy.copy(server)
server._from_data(data)
self.dispatch('server_update', old_server, server)
guild = self._get_guild(int(data['id']))
if guild is not None:
old_guild = copy.copy(guild)
guild._from_data(data)
self.dispatch('guild_update', old_guild, guild)
def parse_guild_delete(self, data):
server = self._get_server(int(data['id']))
if server is None:
guild = self._get_guild(int(data['id']))
if guild is None:
return
if data.get('unavailable', False) and server is not None:
if data.get('unavailable', False) and guild is not None:
# GUILD_DELETE with unavailable being True means that the
# server that was available is now currently unavailable
server.unavailable = True
self.dispatch('server_unavailable', server)
# guild that was available is now currently unavailable
guild.unavailable = True
self.dispatch('guild_unavailable', guild)
return
# do a cleanup of the messages cache
self.messages = deque((msg for msg in self.messages if msg.server != server), maxlen=self.max_messages)
self.messages = deque((msg for msg in self.messages if msg.guild != guild), maxlen=self.max_messages)
self._remove_server(server)
self.dispatch('server_remove', server)
self._remove_guild(guild)
self.dispatch('guild_remove', guild)
def parse_guild_ban_add(self, data):
# we make the assumption that GUILD_BAN_ADD is done
@ -565,72 +565,72 @@ class ConnectionState:
# hence we don't remove it from cache or do anything
# strange with it, the main purpose of this event
# is mainly to dispatch to another event worth listening to for logging
server = self._get_server(int(data['guild_id']))
if server is not None:
guild = self._get_guild(int(data['guild_id']))
if guild is not None:
user_id = data.get('user', {}).get('id')
member = utils.get(server.members, id=user_id)
member = utils.get(guild.members, id=user_id)
if member is not None:
self.dispatch('member_ban', member)
def parse_guild_ban_remove(self, data):
server = self._get_server(int(data['guild_id']))
if server is not None:
guild = self._get_guild(int(data['guild_id']))
if guild is not None:
if 'user' in data:
user = self.try_insert_user(data['user'])
self.dispatch('member_unban', server, user)
self.dispatch('member_unban', guild, user)
def parse_guild_role_create(self, data):
server = self._get_server(int(data['guild_id']))
guild = self._get_guild(int(data['guild_id']))
role_data = data['role']
role = Role(server=server, data=role_data, state=self.ctx)
server._add_role(role)
self.dispatch('server_role_create', role)
role = Role(guild=guild, data=role_data, state=self.ctx)
guild._add_role(role)
self.dispatch('guild_role_create', role)
def parse_guild_role_delete(self, data):
server = self._get_server(int(data['guild_id']))
if server is not None:
guild = self._get_guild(int(data['guild_id']))
if guild is not None:
role_id = data.get('role_id')
role = utils.find(lambda r: r.id == role_id, server.roles)
role = utils.find(lambda r: r.id == role_id, guild.roles)
try:
server._remove_role(role)
guild._remove_role(role)
except ValueError:
return
else:
self.dispatch('server_role_delete', role)
self.dispatch('guild_role_delete', role)
def parse_guild_role_update(self, data):
server = self._get_server(int(data['guild_id']))
if server is not None:
guild = self._get_guild(int(data['guild_id']))
if guild is not None:
role_data = data['role']
role_id = role_data['id']
role = utils.find(lambda r: r.id == role_id, server.roles)
role = utils.find(lambda r: r.id == role_id, guild.roles)
if role is not None:
old_role = copy.copy(role)
role._update(role_data)
self.dispatch('server_role_update', old_role, role)
self.dispatch('guild_role_update', old_role, role)
def parse_guild_members_chunk(self, data):
server = self._get_server(int(data['guild_id']))
guild = self._get_guild(int(data['guild_id']))
members = data.get('members', [])
for member in members:
m = self._make_member(server, member)
existing = server.get_member(m.id)
m = self._make_member(guild, member)
existing = guild.get_member(m.id)
if existing is None or existing.joined_at is None:
server._add_member(m)
guild._add_member(m)
log.info('processed a chunk for {} members.'.format(len(members)))
self.process_listeners(ListenerType.chunk, server, len(members))
self.process_listeners(ListenerType.chunk, guild, len(members))
def parse_voice_state_update(self, data):
server = self._get_server(utils._get_as_snowflake(data, 'guild_id'))
guild = self._get_guild(utils._get_as_snowflake(data, 'guild_id'))
channel_id = utils._get_as_snowflake(data, 'channel_id')
if server is not None:
if guild is not None:
if int(data['user_id']) == self.user.id:
voice = self._get_voice_client(server.id)
voice = self._get_voice_client(guild.id)
if voice is not None:
voice.channel = server.get_channel(channel_id)
voice.channel = guild.get_channel(channel_id)
member, before, after = server._update_voice_state(data, channel_id)
member, before, after = guild._update_voice_state(data, channel_id)
if after is not None:
self.dispatch('voice_state_update', member, before, after)
else:
@ -647,7 +647,7 @@ class ConnectionState:
if isinstance(channel, DMChannel):
member = channel.recipient
elif isinstance(channel, TextChannel):
member = channel.server.get_member(user_id)
member = channel.guild.get_member(user_id)
elif isinstance(channel, GroupChannel):
member = utils.find(lambda x: x.id == user_id, channel.recipients)
@ -708,8 +708,8 @@ class ConnectionState:
if id is None:
return None
for server in self.servers:
channel = server.get_channel(id)
for guild in self.guilds:
channel = guild.get_channel(id)
if channel is not None:
return channel

2
discord/user.py

@ -136,7 +136,7 @@ class User:
"""Returns the user's display name.
For regular users this is just their username, but
if they have a server specific nickname then that
if they have a guild specific nickname then that
is returned instead.
"""
return getattr(self, 'nick', None) or self.name

20
discord/utils.py

@ -91,9 +91,9 @@ def deprecated(instead=None):
return decorated
return actual_decorator
def oauth_url(client_id, permissions=None, server=None, redirect_uri=None):
def oauth_url(client_id, permissions=None, guild=None, redirect_uri=None):
"""A helper function that returns the OAuth2 URL for inviting the bot
into servers.
into guilds.
Parameters
-----------
@ -102,16 +102,16 @@ def oauth_url(client_id, permissions=None, server=None, redirect_uri=None):
permissions : :class:`Permissions`
The permissions you're requesting. If not given then you won't be requesting any
permissions.
server : :class:`Server`
The server to pre-select in the authorization screen, if available.
guild : :class:`Guild`
The guild to pre-select in the authorization screen, if available.
redirect_uri : str
An optional valid redirect URI.
"""
url = 'https://discordapp.com/oauth2/authorize?client_id={}&scope=bot'.format(client_id)
if permissions is not None:
url = url + '&permissions=' + str(permissions.value)
if server is not None:
url = url + "&guild_id=" + server.id
if guild is not None:
url = url + "&guild_id=" + guild.id
if redirect_uri is not None:
from urllib.parse import urlencode
url = url + "&response_type=code&" + urlencode({'redirect_uri': redirect_uri})
@ -144,7 +144,7 @@ def find(predicate, seq):
"""A helper to return the first element found in the sequence
that meets the predicate. For example: ::
member = find(lambda m: m.name == 'Mighty', channel.server.members)
member = find(lambda m: m.name == 'Mighty', channel.guild.members)
would find the first :class:`Member` whose name is 'Mighty' and return it.
If an entry is not found, then ``None`` is returned.
@ -190,19 +190,19 @@ def get(iterable, **attrs):
.. code-block:: python
member = discord.utils.get(message.server.members, name='Foo')
member = discord.utils.get(message.guild.members, name='Foo')
Multiple attribute matching:
.. code-block:: python
channel = discord.utils.get(server.channels, name='Foo', type=ChannelType.voice)
channel = discord.utils.get(guild.channels, name='Foo', type=ChannelType.voice)
Nested attribute matching:
.. code-block:: python
channel = discord.utils.get(client.get_all_channels(), server__name='Cool', name='general')
channel = discord.utils.get(client.get_all_channels(), guild__name='Cool', name='general')
Parameters
-----------

12
discord/voice_client.py

@ -26,7 +26,7 @@ DEALINGS IN THE SOFTWARE.
"""Some documentation to refer to:
- Our main web socket (mWS) sends opcode 4 with a server ID and channel ID.
- Our main web socket (mWS) sends opcode 4 with a guild ID and channel ID.
- The mWS receives VOICE_STATE_UPDATE and VOICE_SERVER_UPDATE.
- We pull the session_id from VOICE_STATE_UPDATE.
- We pull the token, endpoint and guild_id from VOICE_SERVER_UPDATE.
@ -202,9 +202,9 @@ class VoiceClient:
The endpoint we are connecting to.
channel : :class:`Channel`
The voice channel connected to.
server : :class:`Server`
The server the voice channel is connected to.
Shorthand for ``channel.server``.
guild : :class:`Guild`
The guild the voice channel is connected to.
Shorthand for ``channel.guild``.
loop
The event loop that the voice client is running on.
"""
@ -229,8 +229,8 @@ class VoiceClient:
warn_nacl = not has_nacl
@property
def server(self):
return self.channel.server
def guild(self):
return self.channel.guild
def checked_add(self, attr, value, limit):
val = getattr(self, attr)

102
docs/api.rst

@ -102,7 +102,7 @@ to handle it, which defaults to print a traceback and ignore the exception.
.. function:: on_ready()
Called when the client is done preparing the data received from Discord. Usually after login is successful
and the :attr:`Client.servers` and co. are filled up.
and the :attr:`Client.guilds` and co. are filled up.
.. warning::
@ -139,7 +139,7 @@ to handle it, which defaults to print a traceback and ignore the exception.
.. function:: on_message(message)
Called when a message is created and sent to a server.
Called when a message is created and sent to a guild.
:param message: A :class:`Message` of the current message.
@ -184,7 +184,7 @@ to handle it, which defaults to print a traceback and ignore the exception.
Called when a message is deleted. If the message is not found in the
:attr:`Client.messages` cache, then these events will not be called. This
happens if the message is too old or the client is participating in high
traffic servers. To fix this, increase the ``max_messages`` option of
traffic guilds. To fix this, increase the ``max_messages`` option of
:class:`Client`.
:param message: A :class:`Message` of the deleted message.
@ -194,14 +194,14 @@ to handle it, which defaults to print a traceback and ignore the exception.
Called when a message receives an update event. If the message is not found
in the :attr:`Client.messages` cache, then these events will not be called.
This happens if the message is too old or the client is participating in high
traffic servers. To fix this, increase the ``max_messages`` option of :class:`Client`.
traffic guilds. To fix this, increase the ``max_messages`` option of :class:`Client`.
The following non-exhaustive cases trigger this event:
- A message has been pinned or unpinned.
- The message content has been changed.
- The message has received an embed.
- For performance reasons, the embed server does not do this in a "consistent" manner.
- For performance reasons, the embed guild does not do this in a "consistent" manner.
- A call message has received an update to its participants or ending time.
:param before: A :class:`Message` of the previous version of the message.
@ -245,9 +245,9 @@ to handle it, which defaults to print a traceback and ignore the exception.
.. function:: on_channel_delete(channel)
on_channel_create(channel)
Called whenever a channel is removed or added from a server.
Called whenever a channel is removed or added from a guild.
Note that you can get the server from :attr:`Channel.server`.
Note that you can get the guild from :attr:`Channel.guild`.
:func:`on_channel_create` could also pass in a :class:`PrivateChannel` depending
on the value of :attr:`Channel.is_private`.
@ -263,7 +263,7 @@ to handle it, which defaults to print a traceback and ignore the exception.
.. function:: on_member_join(member)
on_member_remove(member)
Called when a :class:`Member` leaves or joins a :class:`Server`.
Called when a :class:`Member` leaves or joins a :class:`Guild`.
:param member: The :class:`Member` that joined or left.
@ -282,71 +282,71 @@ to handle it, which defaults to print a traceback and ignore the exception.
:param before: The :class:`Member` that updated their profile with the old info.
:param after: The :class:`Member` that updated their profile with the updated info.
.. function:: on_server_join(server)
.. function:: on_guild_join(guild)
Called when a :class:`Server` is either created by the :class:`Client` or when the
:class:`Client` joins a server.
Called when a :class:`Guild` is either created by the :class:`Client` or when the
:class:`Client` joins a guild.
:param server: The class:`Server` that was joined.
:param guild: The class:`Guild` that was joined.
.. function:: on_server_remove(server)
.. function:: on_guild_remove(guild)
Called when a :class:`Server` is removed from the :class:`Client`.
Called when a :class:`Guild` is removed from the :class:`Client`.
This happens through, but not limited to, these circumstances:
- The client got banned.
- The client got kicked.
- The client left the server.
- The client or the server owner deleted the server.
- The client left the guild.
- The client or the guild owner deleted the guild.
In order for this event to be invoked then the :class:`Client` must have
been part of the server to begin with. (i.e. it is part of :attr:`Client.servers`)
been part of the guild to begin with. (i.e. it is part of :attr:`Client.guilds`)
:param server: The :class:`Server` that got removed.
:param guild: The :class:`Guild` that got removed.
.. function:: on_server_update(before, after)
.. function:: on_guild_update(before, after)
Called when a :class:`Server` updates, for example:
Called when a :class:`Guild` updates, for example:
- Changed name
- Changed AFK channel
- Changed AFK timeout
- etc
:param before: The :class:`Server` prior to being updated.
:param after: The :class:`Server` after being updated.
:param before: The :class:`Guild` prior to being updated.
:param after: The :class:`Guild` after being updated.
.. function:: on_server_role_create(role)
on_server_role_delete(role)
.. function:: on_guild_role_create(role)
on_guild_role_delete(role)
Called when a :class:`Server` creates or deletes a new :class:`Role`.
Called when a :class:`Guild` creates or deletes a new :class:`Role`.
To get the server it belongs to, use :attr:`Role.server`.
To get the guild it belongs to, use :attr:`Role.guild`.
:param role: The :class:`Role` that was created or deleted.
.. function:: on_server_role_update(before, after)
.. function:: on_guild_role_update(before, after)
Called when a :class:`Role` is changed server-wide.
Called when a :class:`Role` is changed guild-wide.
:param before: The :class:`Role` that updated with the old info.
:param after: The :class:`Role` that updated with the updated info.
.. function:: on_server_emojis_update(before, after)
.. function:: on_guild_emojis_update(before, after)
Called when a :class:`Server` adds or removes :class:`Emoji`.
Called when a :class:`Guild` adds or removes :class:`Emoji`.
:param before: A list of :class:`Emoji` before the update.
:param after: A list of :class:`Emoji` after the update.
.. function:: on_server_available(server)
on_server_unavailable(server)
.. function:: on_guild_available(guild)
on_guild_unavailable(guild)
Called when a server becomes available or unavailable. The server must have
existed in the :attr:`Client.servers` cache.
Called when a guild becomes available or unavailable. The guild must have
existed in the :attr:`Client.guilds` cache.
:param server: The :class:`Server` that has changed availability.
:param guild: The :class:`Guild` that has changed availability.
.. function:: on_voice_state_update(before, after)
@ -357,24 +357,24 @@ to handle it, which defaults to print a traceback and ignore the exception.
- A member joins a voice room.
- A member leaves a voice room.
- A member is muted or deafened by their own accord.
- A member is muted or deafened by a server administrator.
- A member is muted or deafened by a guild administrator.
:param before: The :class:`Member` whose voice state changed prior to the changes.
:param after: The :class:`Member` whose voice state changed after the changes.
.. function:: on_member_ban(member)
Called when a :class:`Member` gets banned from a :class:`Server`.
Called when a :class:`Member` gets banned from a :class:`Guild`.
You can access the server that the member got banned from via :attr:`Member.server`.
You can access the guild that the member got banned from via :attr:`Member.guild`.
:param member: The member that got banned.
.. function:: on_member_unban(server, user)
.. function:: on_member_unban(guild, user)
Called when a :class:`User` gets unbanned from a :class:`Server`.
Called when a :class:`User` gets unbanned from a :class:`Guild`.
:param server: The server the user got unbanned from.
:param guild: The guild the user got unbanned from.
:param user: The user that got unbanned.
.. function:: on_typing(channel, user, when)
@ -499,9 +499,9 @@ All enumerations are subclasses of `enum`_.
The system message denoting that a pinned message has been added to a channel.
.. class:: ServerRegion
.. class:: GuildRegion
Specifies the region a :class:`Server`'s voice server belongs to.
Specifies the region a :class:`Guild`'s voice server belongs to.
.. attribute:: us_west
@ -539,18 +539,18 @@ All enumerations are subclasses of `enum`_.
The Brazil region.
.. attribute:: vip_us_east
The US East region for VIP servers.
The US East region for VIP guilds.
.. attribute:: vip_us_west
The US West region for VIP servers.
The US West region for VIP guilds.
.. attribute:: vip_amsterdam
The Amsterdam region for VIP servers.
The Amsterdam region for VIP guilds.
.. class:: VerificationLevel
Specifies a :class:`Server`\'s verification level, which is the criteria in
which a member must meet before being able to send messages to the server.
Specifies a :class:`Guild`\'s verification level, which is the criteria in
which a member must meet before being able to send messages to the guild.
.. attribute:: none
@ -565,7 +565,7 @@ All enumerations are subclasses of `enum`_.
.. attribute:: high
Member must have a verified email, be registered on Discord for more
than five minutes, and be a member of the server itself for more than
than five minutes, and be a member of the guild itself for more than
ten minutes.
.. attribute:: table_flip
@ -670,10 +670,10 @@ GroupCall
.. autoclass:: GroupCall
:members:
Server
Guild
~~~~~~
.. autoclass:: Server
.. autoclass:: Guild
:members:
Member

Loading…
Cancel
Save