async def _notify_user(config, action, guild, user, targets, reason, extra=None, auto=False): if action == 'massban': return if config and not config.dm_user: return # Should always be True, because we don't send DMs to massbanned users. assert len(targets) == 1, f'too many targets for {action}' mod_action = _mod_actions[action] action_applied = f'You have been {mod_action.repr}' if extra: action_applied += f' for {parse_delta(extra.delta)}' embed = (discord.Embed(color=mod_action.color, timestamp=datetime.utcnow()) .set_author(name=f'{action_applied}!', icon_url=emoji_url(mod_action.emoji)) .add_field(name='In', value=str(guild), inline=False) .add_field(name='By', value=str(user), inline=False)) if reason: embed.add_field(name='Reason', value=reason, inline=False) for target in targets: with contextlib.suppress(discord.HTTPException): await target.send(embed=embed)
def _create_embed(self, number, action, mod, targets, reason, extra, time=None): time = time or datetime.utcnow() action = _mod_actions[action] bot_avatar = self.bot.user.avatar_url if not extra: duration_string = '' elif isinstance(extra, (float, int)): duration_string = f' for {duration_units(extra)}' else: duration_string = f' for {parse_delta(extra.delta)}' action_field = f'{action.repr.title()}{duration_string} by {mod}' reason = reason or f'No reason. Please provide one.' embed = (discord.Embed(color=action.color, timestamp=time) .set_author(name=f'Case #{number}', icon_url=emoji_url(action.emoji)) .add_field(name=f'User{"s" * (len(targets) != 1)}', value=', '.join(map(str, targets))) .add_field(name='Action', value=action_field, inline=False) .add_field(name='Reason', value=reason, inline=False) .set_footer(text=f'ID: {mod.id}', icon_url=bot_avatar)) if len(targets) == 1: avatar_url = getattr(targets[0], 'avatar_url', None) else: avatar_url = MASSBAN_THUMBNAIL if avatar_url: embed.set_thumbnail(url=avatar_url) return embed
async def _update_display(self): board = self._board if self._status is Status.PLAYING: instructions = self._instructions() icon = emoji_url(board.TILES[PIECES[board.turn]]) else: instructions = '' icon = discord.Embed.Empty if self._status is Status.END: user = self._players[not self._board.turn] else: user = self.current() header = _MESSAGES[self._status].format(user=user) self._display.description = f'{instructions}{board}' self._display.set_author(name=header, icon_url=icon)
mod_id = db.Column(db.BigInt, nullable=True) class ModLogConfig(db.Table, table_name='modlog_config'): guild_id = db.Column(db.BigInt, primary_key=True) channel_id = db.Column(db.BigInt, default=0) enabled = db.Column(db.Boolean, default=True) log_auto = db.Column(db.Boolean, default=True) dm_user = db.Column(db.Boolean, default=True) poll_audit_log = db.Column(db.Boolean, default=True) events = db.Column(db.Integer, default=_default_flags.value) MASSBAN_THUMBNAIL = emoji_url('\N{NO ENTRY}') fields = 'channel_id enabled, log_auto dm_user poll_audit_log events' ModlogConfig = collections.namedtuple('ModlogConfig', fields) del fields def _is_mod_action(ctx): return ctx.command.qualified_name in _mod_actions @cache.cache(max_size=512) async def _get_message(channel, message_id): fake = discord.Object(message_id + 1) msg = await channel.history(limit=1, before=fake).next()
def __str__(self): return str(self.server) class _DummyEntry(namedtuple('_DummyEntry', 'id')): """This class makes sure that the object for ignore is mentionable.""" __slots__ = () @property def mention(self): return f'<Not Found: {self.id}>' _value_embed_mappings = { True: (0x00FF00, 'enabled', emoji_url('\N{WHITE HEAVY CHECK MARK}')), False: (0xFF0000, 'disabled', emoji_url('\N{NO ENTRY SIGN}')), None: (0x7289DA, 'reset', emoji_url('\U0001f504')), -1: (0xFF0000, 'deleted', emoji_url('\N{PUT LITTER IN ITS PLACE SYMBOL}')), } _plonk_embed_mappings = { True: (0xF44336, 'plonk'), False: (0x4CAF50, 'unplonk'), } PLONK_ICON = emoji_url('\N{HAMMER}') class Permissions: """Used for enabling or disabling commands for a channel, member, role or even the whole server.""" def __init__(self, bot): self.bot = bot
f'Slow down, mate! This command is on cooldown.\n**{hours} hours, {minutes} minutes and {seconds} seconds remaining.**' ) # Error Webhook _ignored_exceptions = ( commands.NoPrivateMessage, commands.DisabledCommand, commands.CheckFailure, commands.CommandNotFound, commands.UserInputError, discord.Forbidden, ) ERROR_ICON_URL = emoji_url('\N{NO ENTRY SIGN}') async def _send_error_webhook(ctx, error): if not isinstance(error, commands.CommandNotFound): ctx.bot.command_counter['failed'] += 1 webhook = ctx.bot.webhook if not webhook: return error = getattr(error, 'original', error) if isinstance(error, _ignored_exceptions) or getattr( error, '__ignore__', False): return
import json import discord from discord.ext import commands from utils.misc import emoji_url, truncate from utils.paginator import FieldPaginator from utils.time import FutureTime, human_timedelta MAX_REMINDERS = 10 ALARM_CLOCK_URL = emoji_url('\N{ALARM CLOCK}') CLOCK_URL = emoji_url('\N{MANTELPIECE CLOCK}') CANCELED_URL = emoji_url('\N{BELL WITH CANCELLATION STROKE}') # Idea from Danno, Skidded? Not this time. class Reminder: def __init__(self, bot): self.bot = bot @staticmethod def _create_reminder_embed(ctx, when, message): # Discord attempts to be smart with breaking up long lines. If a line # is extremely long, it will attempt to insert a line break before the next word. # This will lead to overstretched embeds to the right. # # To not give myself a headache, I will not attempt to do that manually. return (discord.Embed( colour=0x00FF00, description=message, timestamp=when).set_author(
from .errors import NotEnoughMoney from utils import db from utils.colors import random_color from utils.context_managers import temporary_item from utils.paginator import InteractiveSession, trigger from utils.misc import emoji_url class SavedSudokuGames(db.Table, table_name='saved_sudoku_games'): user_id = db.Column(db.BigInt, primary_key=True) board = db.Column(db.Text) clues = db.Column(db.Text) SUDOKU_ICON = emoji_url('\N{INPUT SYMBOL FOR NUMBERS}') # Some default constants BLOCK_SIZE = 3 BOARD_SIZE = 81 EMPTY = 0 # Sudoku board generator by Gareth Rees # This works best when m = 3. # For some reason it goes significantly slower when m >= 4 # And it doesn't work when m = 2 def _make_board(m=3): """Returns a randomly filled m**2 x m**2 Sudoku board.""" n = m * m nn = n * n
import asyncpg import discord from discord.ext import commands from utils import db, disambiguate from utils.colors import random_color from utils.misc import emoji_url, truncate class Blacklist(db.Table): snowflake = db.Column(db.BigInt, primary_key=True) blacklisted_when = db.Column(db.Timestamp) reason = db.Column(db.Text, nullable=True) _blocked_icon = emoji_url('\N{NO ENTRY}') _unblocked_icon = emoji_url('\N{WHITE HEAVY CHECK MARK}') class Blacklisted(commands.CheckFailure): def __init__(self, message, reason, *args): self.message = message self.reason = reason super().__init__(message, *args) def to_embed(self): embed = (discord.Embed(description=self.reason, color=random_color()).set_author( name=self.message, icon_url=_blocked_icon)) if self.reason: