Rename Server to Guild everywhere.
This commit is contained in:
parent
f33eaa4a61
commit
d1d54a468a
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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__:
|
||||
|
@ -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'
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
"""
|
||||
|
@ -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')
|
||||
|
||||
|
@ -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')
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
-----------
|
||||
|
@ -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
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…
x
Reference in New Issue
Block a user