from disco.api.http import APIException from disco.types.permissions import Permissions from rowboat.redis import rdb from rowboat.util.stats import timed from rowboat.util.zalgo import ZALGO_RE from rowboat.plugins import RowboatPlugin as Plugin from rowboat.types import SlottedModel, Field, ListField, DictField, ChannelField, snowflake, lower from rowboat.types.plugin import PluginConfig from rowboat.models.message import Message from rowboat.plugins.modlog import Actions from rowboat.constants import INVITE_LINK_RE, URL_RE CensorReason = Enum( 'INVITE', 'DOMAIN', 'WORD', 'ZALGO', ) class CensorSubConfig(SlottedModel): filter_zalgo = Field(bool, default=True) filter_invites = Field(bool, default=True) invites_guild_whitelist = ListField(snowflake, default=[]) invites_whitelist = ListField(lower, default=[]) invites_blacklist = ListField(lower, default=[]) filter_domains = Field(bool, default=True) domains_whitelist = ListField(lower, default=[]) domains_blacklist = ListField(lower, default=[])
from disco.util.snowflake import to_snowflake from disco.util.functional import cached_property from disco.types.base import ( SlottedModel, Field, ListField, AutoDictField, DictField, snowflake, text, enum, datetime ) from disco.types.user import User from disco.types.voice import VoiceState from disco.types.channel import Channel from disco.types.message import Emoji from disco.types.permissions import PermissionValue, Permissions, Permissible VerificationLevel = Enum( NONE=0, LOW=1, MEDIUM=2, HIGH=3, EXTREME=4, ) ExplicitContentFilterLevel = Enum( NONE=0, WITHOUT_ROLES=1, ALL=2 ) DefaultMessageNotificationsLevel = Enum( ALL_MESSAGES=0, ONLY_MENTIONS=1, )
from holster.enum import Enum from disco.types.base import SlottedModel, Field, snowflake, text, with_equality, with_hash DefaultAvatars = Enum( BLURPLE=0, GREY=1, GREEN=2, ORANGE=3, RED=4, ) class User(SlottedModel, with_equality('id'), with_hash('id')): id = Field(snowflake) username = Field(text) avatar = Field(text) discriminator = Field(text) bot = Field(bool, default=False) verified = Field(bool) email = Field(text) presence = Field(None) def get_avatar_url(self, fmt='webp', size=1024): if not self.avatar: return 'https://cdn.discordapp.com/embed/avatars/{}.png'.format( self.default_avatar.value) return 'https://cdn.discordapp.com/avatars/{}/{}.{}?size={}'.format( self.id, self.avatar, fmt, size)
from disco.bot import CommandLevels from disco.types.base import UNSET, cached_property from disco.util.snowflake import to_unix, to_datetime from disco.util.sanitize import S from rowboat.plugins import RowboatPlugin as Plugin from rowboat.types import SlottedModel, Field, ListField, DictField, ChannelField, snowflake from rowboat.types.plugin import PluginConfig from rowboat.models.message import Message, MessageArchive from rowboat.models.guild import Guild from rowboat.util import ordered_load, MetaException from .pump import ModLogPump # Dynamically updated by the plugin Actions = Enum() URL_REGEX = re.compile(r'(https?://[^\s]+)') def filter_urls(content): return URL_REGEX.sub(r'<\1>', content) class ChannelConfig(SlottedModel): compact = Field(bool, default=True) include = ListField(Actions) exclude = ListField(Actions) rich = ListField(Actions) timestamps = Field(bool, default=False)
class MessageIterator(object): """ An iterator which supports scanning through the messages for a channel. Parameters ---------- client : :class:`disco.client.Client` The disco client instance to use when making requests. channel : `Channel` The channel to iterate within. direction : :attr:`MessageIterator.Direction` The direction in which this iterator will move. bulk : bool If true, this iterator will yield messages in list batches, otherwise each message will be yield individually. before : snowflake The message to begin scanning at. after : snowflake The message to begin scanning at. chunk_size : int The number of messages to request per API call. """ Direction = Enum('UP', 'DOWN') def __init__(self, client, channel, direction=Direction.UP, bulk=False, before=None, after=None, chunk_size=100): self.client = client self.channel = channel self.direction = direction self.bulk = bulk self.before = before self.after = after self.chunk_size = chunk_size self.last = None self._buffer = [] if not any((before, after)) and self.direction == self.Direction.DOWN: raise Exception( 'Must specify either before or after for downward seeking') def fill(self): """ Fills the internal buffer up with :class:`disco.types.message.Message` objects from the API. """ self._buffer = self.client.api.channels_messages_list( self.channel.id, before=self.before, after=self.after, limit=self.chunk_size) if not len(self._buffer): raise StopIteration self.after = None self.before = None if self.direction == self.Direction.UP: self.before = self._buffer[-1].id else: self._buffer.reverse() self.after = self._buffer[-1].id def next(self): return self.__next__() def __iter__(self): return self def __next__(self): if not len(self._buffer): self.fill() if self.bulk: res = self._buffer self._buffer = [] return res else: return self._buffer.pop()
from holster.enum import Enum from disco.types.base import SlottedModel, Field, datetime, enum from disco.types.user import User from disco.types.guild import Guild from disco.types.channel import Channel InviteTargetUserType = Enum(STREAM=1) class Invite(SlottedModel): """ An invite object. Attributes ---------- code : str The invite code. guild : :class:`disco.types.guild.Guild` The guild this invite is for. channel : :class:`disco.types.channel.Channel` The channel this invite is for. target_user : :class:`disco.types.user.User` The user this invite targets. target_user_type : int The type of user target for this invite. approximate_presence_count : int The approximate count of online members. approximate_member_count : int The approximate count of total members. inviter : :class:`disco.types.user.User`
from holster.enum import Enum from holster.emitter import Priority from disco.util.sanitize import ZERO_WIDTH_SPACE from rowboat.plugins import RowboatPlugin as Plugin from rowboat.redis import rdb from rowboat.plugins.modlog import Actions from rowboat.plugins.censor import URL_RE from rowboat.util.leakybucket import LeakyBucket from rowboat.util.stats import timed from rowboat.types.plugin import PluginConfig from rowboat.types import SlottedModel, DictField, Field from rowboat.models.user import Infraction from rowboat.models.message import Message, EMOJI_RE PunishmentType = Enum('NONE', 'MUTE', 'KICK', 'TEMPBAN', 'BAN', 'TEMPMUTE') class CheckConfig(SlottedModel): count = Field(int) interval = Field(int) meta = Field(dict, default=None) class SubConfig(SlottedModel): max_messages = Field(CheckConfig, default=None) max_mentions = Field(CheckConfig, default=None) max_links = Field(CheckConfig, default=None) max_emojis = Field(CheckConfig, default=None) max_newlines = Field(CheckConfig, default=None) max_attachments = Field(CheckConfig, default=None)
from holster.enum import Enum SEND = 1 RECV = 2 OPCode = Enum( DISPATCH=0, HEARTBEAT=1, IDENTIFY=2, STATUS_UPDATE=3, VOICE_STATE_UPDATE=4, VOICE_SERVER_PING=5, RESUME=6, RECONNECT=7, REQUEST_GUILD_MEMBERS=8, INVALID_SESSION=9, HELLO=10, HEARTBEAT_ACK=11, GUILD_SYNC=12, )
@property def mention(self): return '<@{}>'.format(self.id) def to_string(self): return '{}#{}'.format(self.username, self.discriminator) def __str__(self): return '<User {} ({})>'.format(self.id, self.to_string()) def on_create(self): self.client.state.users[self.id] = self GameType = Enum( DEFAULT=0, STREAMING=1, ) Status = Enum('ONLINE', 'IDLE', 'DND', 'INVISIBLE', 'OFFLINE') class Game(Model): type = Field(GameType) name = Field(text) url = Field(text) class Presence(Model): user = Field(User) game = Field(Game) status = Field(Status)
import gevent from collections import namedtuple try: import nacl.secret except ImportError: print('WARNING: nacl is not installed, voice support is disabled') from holster.enum import Enum from disco.util.logging import LoggingClass AudioCodecs = ('opus', ) RTPPayloadTypes = Enum(OPUS=0x78) RTCPPayloadTypes = Enum( SENDER_REPORT=200, RECEIVER_REPORT=201, SOURCE_DESCRIPTION=202, BYE=203, APP=204, RTPFB=205, PSFB=206, ) MAX_UINT32 = 4294967295 MAX_SEQUENCE = 65535 RTP_HEADER_VERSION = 0x80 # Only RTP Version is set here (value of 2 << 6)
import requests from collections import defaultdict from holster.enum import Enum from disco.types.message import MessageEmbed from rowboat.plugins import RowboatPlugin as Plugin from rowboat.redis import rdb from rowboat.models.guild import Guild from rowboat.types.plugin import PluginConfig from rowboat.types import SlottedModel, DictField, Field, ChannelField FormatMode = Enum( 'PLAIN', 'PRETTY' ) class SubRedditConfig(SlottedModel): channel = Field(ChannelField) mode = Field(FormatMode, default=FormatMode.PRETTY) nsfw = Field(bool, default=False) text_length = Field(int, default=256) include_stats = Field(bool, default=False) class RedditConfig(PluginConfig): # TODO: validate they have less than 3 reddits selected subs = DictField(str, SubRedditConfig)
from holster.enum import Enum from disco.api.http import APIException from disco.util.snowflake import to_snowflake from disco.util.functional import cached_property from disco.types.base import Model, Field, snowflake, listof, dictof, datetime, text, binary, enum from disco.types.user import User from disco.types.voice import VoiceState from disco.types.channel import Channel from disco.types.permissions import PermissionValue, Permissions, Permissible VerificationLevel = Enum( NONE=0, LOW=1, MEDIUM=2, HIGH=3, EXTREME=4, ) class Emoji(Model): """ An emoji object Attributes ---------- id : snowflake The ID of this emoji. name : str The name of this emoji.
class Infraction(BaseModel): Types = Enum( 'MUTE', 'KICK', 'TEMPBAN', 'SOFTBAN', 'BAN', 'TEMPMUTE', 'UNBAN', bitmask=False, ) guild_id = BigIntegerField() user_id = BigIntegerField() actor_id = BigIntegerField(null=True) type_ = IntegerField(db_column='type') reason = TextField(null=True) metadata = BinaryJSONField(default={}) expires_at = DateTimeField(null=True) created_at = DateTimeField(default=datetime.utcnow) active = BooleanField(default=True) class Meta: db_table = 'infractions' indexes = ((('guild_id', 'user_id'), False), ) @staticmethod def admin_config(event): return getattr(event.base_config.plugins, 'admin', None) @classmethod def kick(cls, plugin, event, member, reason): User.from_disco_user(member.user) plugin.bot.plugins.get('ModLogPlugin').create_debounce( event, member.user.id, 'kick', actor=unicode(event.author) if event.author.id != member.id else 'Automatic', reason=reason or 'no reason') member.kick() cls.create(guild_id=member.guild_id, user_id=member.user.id, actor_id=event.author.id, type_=cls.Types.KICK, reason=reason) @classmethod def tempban(cls, plugin, event, member, reason, expires_at): User.from_disco_user(member.user) plugin.bot.plugins.get('ModLogPlugin').create_debounce( event, member.user.id, 'ban_reason', actor=unicode(event.author) if event.author.id != member.id else 'Automatic', temp=True, expires=expires_at, reason=reason or 'no reason') member.ban() cls.create(guild_id=member.guild_id, user_id=member.user.id, actor_id=event.author.id, type_=cls.Types.TEMPBAN, reason=reason, expires_at=expires_at) @classmethod def softban(cls, plugin, event, member, reason): User.from_disco_user(member.user) plugin.bot.plugins.get('ModLogPlugin').create_debounce( event, member.user.id, 'ban_reason', actor=unicode(event.author) if event.author.id != member.id else 'Automatic', temp=True, expires=None, reason=reason or 'no reason') member.ban(delete_message_days=7) member.unban() cls.create(guild_id=member.guild_id, user_id=member.user.id, actor_id=event.author.id, type_=cls.Types.SOFTBAN, reason=reason) @classmethod def ban(cls, plugin, event, member, reason, guild): if isinstance(member, (int, long)): user_id = member else: User.from_disco_user(member.user) user_id = member.user.id plugin.bot.plugins.get('ModLogPlugin').create_debounce( event, user_id, 'ban_reason', actor=unicode(event.author) if event.author.id != user_id else 'Automatic', temp=False, expires=None, reason=reason or 'no reason') guild.create_ban(user_id) cls.create(guild_id=guild.id, user_id=user_id, actor_id=event.author.id, type_=cls.Types.BAN, reason=reason) @classmethod def mute(cls, plugin, event, member, reason): admin_config = cls.admin_config(event) plugin.bot.plugins.get('ModLogPlugin').create_debounce( event, member.user.id, 'muted', reason=reason, expires_at=None, actor=unicode(event.author) if event.author.id != member.id else 'Automatic', role=admin_config.mute_role) member.add_role(admin_config.mute_role) cls.create(guild_id=event.guild.id, user_id=member.user.id, actor_id=event.author.id, type_=cls.Types.MUTE, reason=reason, metadata={'role': admin_config.mute_role}) @classmethod def tempmute(cls, plugin, event, member, reason, expires_at): admin_config = cls.admin_config(event) plugin.bot.plugins.get('ModLogPlugin').create_debounce( event, member.user.id, 'muted', reason=reason, expires_at=expires_at, actor=unicode(event.author) if event.author.id != member.id else 'Automatic', role=(admin_config.temp_mute_role or admin_config.mute_role)) role = (admin_config.temp_mute_role or admin_config.mute_role) member.add_role(role) cls.create(guild_id=event.guild.id, user_id=member.user.id, actor_id=event.author.id, type_=cls.Types.TEMPMUTE, reason=reason, expires_at=expires_at, metadata={'role': role})
from holster.enum import Enum VoiceOPCode = Enum( IDENTIFY=0, SELECT_PROTOCOL=1, READY=2, HEARTBEAT=3, SESSION_DESCRIPTION=4, SPEAKING=5, HEARTBEAT_ACK=6, RESUME=7, HELLO=8, RESUMED=9, CLIENT_DISCONNECT=13, )
import functools import unicodedata from holster.enum import Enum from disco.types.base import (SlottedModel, Field, ListField, AutoDictField, snowflake, text, datetime, enum) from disco.util.paginator import Paginator from disco.util.snowflake import to_snowflake from disco.util.functional import cached_property from disco.types.user import User MessageType = Enum(DEFAULT=0, RECIPIENT_ADD=1, RECIPIENT_REMOVE=2, CALL=3, CHANNEL_NAME_CHANGE=4, CHANNEL_ICON_CHANGE=5, PINS_ADD=6) class Emoji(SlottedModel): id = Field(snowflake) name = Field(text) def __eq__(self, other): if isinstance(other, Emoji): return self.id == other.id and self.name == other.name raise NotImplementedError def to_string(self):
from holster.enum import Enum VoiceOPCode = Enum( IDENTIFY=0, SELECT_PROTOCOL=1, READY=2, HEARTBEAT=3, SESSION_DESCRIPTION=4, SPEAKING=5, )
print('WARNING: nacl is not installed, voice support is disabled') from holster.enum import Enum from holster.emitter import Emitter from disco.gateway.encoding.json import JSONEncoder from disco.util.websocket import Websocket from disco.util.logging import LoggingClass from disco.voice.packets import VoiceOPCode from disco.gateway.packets import OPCode VoiceState = Enum( DISCONNECTED=0, AWAITING_ENDPOINT=1, AUTHENTICATING=2, CONNECTING=3, CONNECTED=4, VOICE_CONNECTING=5, VOICE_CONNECTED=6, ) class VoiceException(Exception): def __init__(self, msg, client): self.voice_client = client super(VoiceException, self).__init__(msg) class UDPVoiceClient(LoggingClass): def __init__(self, vc): super(UDPVoiceClient, self).__init__()
class Infraction(BaseModel): Types = Enum( 'MUTE', 'KICK', 'TEMPBAN', 'SOFTBAN', 'BAN', 'TEMPMUTE', 'UNBAN', 'TEMPROLE', 'WARNING', bitmask=False, ) guild_id = BigIntegerField() user_id = BigIntegerField() actor_id = BigIntegerField(null=True) type_ = IntegerField(column_name='type') reason = TextField(null=True) metadata = BinaryJSONField(default={}) expires_at = DateTimeField(null=True) created_at = DateTimeField(default=datetime.utcnow) active = BooleanField(default=True) class Meta: table_name = 'infractions' indexes = ((('guild_id', 'user_id'), False), ) def serialize(self, guild=None, user=None, actor=None, include_metadata=False): base = { 'id': str(self.id), 'guild': (guild and guild.serialize()) or { 'id': str(self.guild_id) }, 'user': (user and user.serialize()) or { 'id': str(self.user_id) }, 'actor': (actor and actor.serialize()) or { 'id': str(self.actor_id) }, 'reason': self.reason, 'expires_at': self.expires_at, 'created_at': self.created_at, 'active': self.active, 'type': { 'id': self.type_, 'name': next(i.name for i in Infraction.Types.attrs if i.index == self.type_) } } if include_metadata: base['metadata'] = self.metadata return base @staticmethod def admin_config(event): return getattr(event.base_config.plugins, 'admin', None) @classmethod def temprole(cls, plugin, event, member, role_id, reason, expires_at): User.from_disco_user(member.user) # TODO: modlog member.add_role(role_id, reason=reason) cls.create(guild_id=event.guild.id, user_id=member.user.id, actor_id=event.author.id, type_=cls.Types.TEMPROLE, reason=reason, expires_at=expires_at, metadata={'role': role_id}) @classmethod def kick(cls, plugin, event, member, reason): from rowboat.plugins.modlog import Actions User.from_disco_user(member.user) # Prevent the GuildMemberRemove log event from triggering plugin.call('ModLogPlugin.create_debounce', event, ['GuildMemberRemove'], user_id=member.user.id) member.kick(reason=reason) # Create a kick modlog event plugin.call('ModLogPlugin.log_action_ext', Actions.MEMBER_KICK, event.guild.id, member=member, actor=event.author if event.author.id != member.id else 'Automatic', reason=reason or 'no reason') cls.create(guild_id=member.guild_id, user_id=member.user.id, actor_id=event.author.id, type_=cls.Types.KICK, reason=reason) @classmethod def tempban(cls, plugin, event, member, reason, expires_at): from rowboat.plugins.modlog import Actions User.from_disco_user(member.user) plugin.call('ModLogPlugin.create_debounce', event, ['GuildMemberRemove', 'GuildBanAdd'], user_id=member.user.id) member.ban(reason=reason) plugin.call( 'ModLogPlugin.log_action_ext', Actions.MEMBER_TEMPBAN, event.guild.id, member=member, actor=event.author if event.author.id != member.id else 'Automatic', reason=reason or 'no reason', expires=expires_at, ) cls.create(guild_id=member.guild_id, user_id=member.user.id, actor_id=event.author.id, type_=cls.Types.TEMPBAN, reason=reason, expires_at=expires_at) @classmethod def softban(cls, plugin, event, member, reason): from rowboat.plugins.modlog import Actions User.from_disco_user(member.user) plugin.call('ModLogPlugin.create_debounce', event, ['GuildMemberRemove', 'GuildBanAdd', 'GuildBanRemove'], user_id=member.user.id) member.ban(delete_message_days=7, reason=reason) member.unban(reason=reason) plugin.call('ModLogPlugin.log_action_ext', Actions.MEMBER_SOFTBAN, event.guild.id, member=member, actor=event.author if event.author.id != member.id else 'Automatic', reason=reason or 'no reason') cls.create(guild_id=member.guild_id, user_id=member.user.id, actor_id=event.author.id, type_=cls.Types.SOFTBAN, reason=reason) @classmethod def ban(cls, plugin, event, member, reason, guild, delete_message_days=0): from rowboat.plugins.modlog import Actions if isinstance(member, int): user_id = member else: User.from_disco_user(member.user) user_id = member.user.id plugin.call( 'ModLogPlugin.create_debounce', event, ['GuildMemberRemove', 'GuildBanAdd'], user_id=user_id, ) guild.create_ban( user_id, delete_message_days if delete_message_days <= 7 else 7, reason=reason) plugin.call( 'ModLogPlugin.log_action_ext', Actions.MEMBER_BAN, guild.id, user=member, user_id=user_id, actor=event.author if event.author.id != user_id else 'Automatic', reason=reason or 'no reason') cls.create(guild_id=guild.id, user_id=user_id, actor_id=event.author.id, type_=cls.Types.BAN, reason=reason) @classmethod def warn(cls, plugin, event, member, reason, guild): from rowboat.plugins.modlog import Actions User.from_disco_user(member.user) user_id = member.user.id cls.create(guild_id=guild.id, user_id=user_id, actor_id=event.author.id, type_=cls.Types.WARNING, reason=reason) plugin.call('ModLogPlugin.log_action_ext', Actions.MEMBER_WARNED, event.guild.id, member=member, actor=event.author if event.author.id != member.id else 'Automatic', reason=reason or 'no reason') @classmethod def mute(cls, plugin, event, member, reason): from rowboat.plugins.modlog import Actions admin_config = cls.admin_config(event) if not admin_config.mute_role: plugin.log.warning('Cannot mute member {}, no mute role'.format( member.id)) return plugin.call( 'ModLogPlugin.create_debounce', event, ['GuildMemberUpdate'], user_id=member.user.id, role_id=admin_config.mute_role, ) member.add_role(admin_config.mute_role, reason=reason) plugin.call('ModLogPlugin.log_action_ext', Actions.MEMBER_MUTED, event.guild.id, member=member, actor=event.author if event.author.id != member.id else 'Automatic', reason=reason or 'no reason') cls.create(guild_id=event.guild.id, user_id=member.user.id, actor_id=event.author.id, type_=cls.Types.MUTE, reason=reason, metadata={'role': admin_config.mute_role}) @classmethod def tempmute(cls, plugin, event, member, reason, expires_at): from rowboat.plugins.modlog import Actions admin_config = cls.admin_config(event) if not admin_config.mute_role: plugin.log.warning( 'Cannot tempmute member {}, no mute role'.format(member.id)) return plugin.call( 'ModLogPlugin.create_debounce', event, ['GuildMemberUpdate'], user_id=member.user.id, role_id=admin_config.mute_role, ) member.add_role(admin_config.mute_role, reason=reason) plugin.call( 'ModLogPlugin.log_action_ext', Actions.MEMBER_TEMP_MUTED, event.guild.id, member=member, actor=event.author if event.author.id != member.id else 'Automatic', reason=reason or 'no reason', expires=expires_at, ) cls.create(guild_id=event.guild.id, user_id=member.user.id, actor_id=event.author.id, type_=cls.Types.TEMPMUTE, reason=reason, expires_at=expires_at, metadata={'role': admin_config.mute_role}) @classmethod def clear_active(cls, event, user_id, types): """ Marks a previously active tempmute as inactive for the given event/user. This should be used in all locations where we either think this is no longer active (e.g. the mute role was removed) _or_ when we don't want to unmute the user any longer, e.g. they've been remuted by another command. """ return cls.update(active=False).where( (cls.guild_id == event.guild.id) & (cls.user_id == user_id) & (cls.type_ << types) & (cls.active == 1)).execute() >= 1
class Guild(ModelBase): WhitelistFlags = Enum('MODLOG_CUSTOM_FORMAT', bitmask=False) guild_id = BigIntegerField(primary_key=True) owner_id = BigIntegerField(null=True) name = TextField(null=True) icon = TextField(null=True) splash = TextField(null=True) region = TextField(null=True) last_ban_sync = DateTimeField(null=True) # Rowboat specific data config = BinaryJSONField(null=True) config_raw = BlobField(null=True) enabled = BooleanField(default=True) whitelist = BinaryJSONField(default=[]) added_at = DateTimeField(default=datetime.utcnow) # SQL = ''' # CREATE OR REPLACE FUNCTION shard (int, bigint) # RETURNS bigint AS $$ # SELECT ($2 >> 22) % $1 # $$ LANGUAGE SQL; # ''' class Meta: table_name = 'guilds' @classmethod def with_id(cls, guild_id): return cls.get(guild_id=guild_id) @classmethod def setup(cls, guild): return cls.create(guild_id=guild.id, owner_id=guild.owner_id, name=guild.name, icon=guild.icon, splash=guild.splash, region=guild.region, config={'web': { guild.owner_id: 'admin' }}, config_raw='') def is_whitelisted(self, flag): return int(flag) in self.whitelist def update_config(self, actor_id, raw): from rowboat.types.guild import GuildConfig parsed = yaml.safe_load(raw) GuildConfig(parsed).validate() GuildConfigChange.create(user_id=actor_id, guild_id=self.guild_id, before_raw=self.config_raw, after_raw=raw) self.update( config=parsed, config_raw=raw).where(Guild.guild_id == self.guild_id).execute() self.emit_update() def emit_update(self): emit('GUILD_UPDATE', id=self.guild_id) def sync(self, guild): updates = {} for key in ['owner_id', 'name', 'icon', 'splash', 'region']: if getattr(guild, key) != getattr(self, key): updates[key] = getattr(guild, key) if updates: Guild.update(**updates).where( Guild.guild_id == self.guild_id).execute() def get_config(self, refresh=False): from rowboat.types.guild import GuildConfig if refresh: self.config = Guild.select(Guild.config).where( Guild.guild_id == self.guild_id).get().config if refresh or not hasattr(self, '_cached_config'): try: self._cached_config = GuildConfig(self.config) except: log.exception('Failed to load config for Guild %s, invalid: ', self.guild_id) return None return self._cached_config def sync_bans(self, guild): # Update last synced time Guild.update(last_ban_sync=datetime.utcnow()).where( Guild.guild_id == self.guild_id).execute() try: bans = guild.get_bans() except: log.exception('sync_bans failed for Guild %s', self.guild_id) return log.info('Syncing %s bans for guild %s', len(bans), guild.id) GuildBan.delete().where((~(GuildBan.user_id << list(bans.keys()))) & (GuildBan.guild_id == guild.id)).execute() for ban in list(bans.values()): GuildBan.ensure(guild, ban.user, ban.reason) def serialize(self): base = { 'id': str(self.guild_id), 'owner_id': str(self.owner_id), 'name': self.name, 'icon': self.icon, 'splash': self.splash, 'region': self.region, 'enabled': self.enabled, 'whitelist': self.whitelist } if hasattr(self, 'role'): base['role'] = self.role return base
from holster.enum import Enum, EnumAttr Permissions = Enum( CREATE_INSTANT_INVITE=1 << 0, KICK_MEMBERS=1 << 1, BAN_MEMBERS=1 << 2, ADMINISTRATOR=1 << 3, MANAGE_CHANNELS=1 << 4, MANAGE_GUILD=1 << 5, READ_MESSAGES=1 << 10, SEND_MESSAGES=1 << 11, SEND_TSS_MESSAGES=1 << 12, MANAGE_MESSAGES=1 << 13, EMBED_LINKS=1 << 14, ATTACH_FILES=1 << 15, READ_MESSAGE_HISTORY=1 << 16, MENTION_EVERYONE=1 << 17, USE_EXTERNAL_EMOJIS=1 << 18, CONNECT=1 << 20, SPEAK=1 << 21, MUTE_MEMBERS=1 << 22, DEAFEN_MEMBERS=1 << 23, MOVE_MEMBERS=1 << 24, USE_VAD=1 << 25, CHANGE_NICKNAME=1 << 26, MANAGE_NICKNAMES=1 << 27, MANAGE_ROLES=1 << 28, MANAGE_WEBHOOKS=1 << 29, MANAGE_EMOJIS=1 << 30, )
func.restype = item[1] setattr(self, name, func) @staticmethod def find_library(): if sys.platform == 'win32': raise Exception('Cannot auto-load opus on Windows, please specify full library path') return ctypes.util.find_library('opus') Application = Enum( AUDIO=2049, VOIP=2048, LOWDELAY=2051 ) Control = Enum( SET_BITRATE=4002, SET_BANDWIDTH=4008, SET_FEC=4012, SET_PLP=4014, ) class OpusEncoder(BaseOpus): EXPORTED = { 'opus_encoder_get_size': ([ctypes.c_int], ctypes.c_int),
from holster.enum import Enum from disco.bot.parser import ArgumentSet, ArgumentError from disco.util.functional import cached_property ARGS_REGEX = '(?: ((?:\n|.)*)$|$)' USER_MENTION_RE = re.compile('<@!?([0-9]+)>') ROLE_MENTION_RE = re.compile('<@&([0-9]+)>') CHANNEL_MENTION_RE = re.compile('<#([0-9]+)>') CommandLevels = Enum( DEFAULT=0, TRUSTED=10, MOD=50, ADMIN=100, OWNER=500, ) class CommandEvent(object): """ An event which is created when a command is triggered. Contains information about the message, command, and parsed arguments (along with shortcuts to message information). Attributes --------- command : :class:`Command` The command this event was created for (aka the triggered command).
import requests import random import gevent import six from holster.enum import Enum from disco.util.logging import LoggingClass from disco.api.ratelimit import RateLimiter # Enum of all HTTP methods used HTTPMethod = Enum( GET='GET', POST='POST', PUT='PUT', PATCH='PATCH', DELETE='DELETE', ) def to_bytes(obj): if isinstance(obj, six.text_type): return obj.encode('utf-8') return obj class Routes(object): """ Simple Python object-enum of all method/url route combinations available to this client. """
import six from holster.enum import Enum from disco.util.snowflake import to_snowflake from disco.util.functional import cached_property, one_or_many, chunks from disco.types.user import User from disco.types.base import SlottedModel, Field, ListField, AutoDictField, snowflake, enum, text from disco.types.permissions import Permissions, Permissible, PermissionValue from disco.voice.client import VoiceClient ChannelType = Enum( GUILD_TEXT=0, DM=1, GUILD_VOICE=2, GROUP_DM=3, ) PermissionOverwriteType = Enum(ROLE='role', MEMBER='member') class ChannelSubType(SlottedModel): channel_id = Field(None) @cached_property def channel(self): return self.client.state.channels.get(self.channel_id) class PermissionOverwrite(ChannelSubType): """