From f5891ffb900db1c7662b4bc47399b64c8263580e Mon Sep 17 00:00:00 2001 From: brandons209 Date: Mon, 27 Jan 2020 15:04:50 -0500 Subject: [PATCH] add black code formatter gitaction, update all cogs to follow format --- .github/workflows/black-checker.yml | 13 + activitylog/__init__.py | 1 + activitylog/activitylog.py | 417 +++++++++++++++------------- activitylog/time_utils.py | 1 - admincustom/admin.py | 58 +--- admincustom/announcer.py | 4 +- events/__init__.py | 1 + events/events.py | 90 +++++- pony/__init__.py | 1 + pony/pony.py | 70 +++-- punish/__init__.py | 1 + punish/memoizer.py | 3 +- punish/punish.py | 395 ++++++++++++++------------ punish/utils.py | 62 ++--- roleplay/roleplay.py | 42 +-- 15 files changed, 632 insertions(+), 527 deletions(-) create mode 100644 .github/workflows/black-checker.yml diff --git a/.github/workflows/black-checker.yml b/.github/workflows/black-checker.yml new file mode 100644 index 0000000..9d006dd --- /dev/null +++ b/.github/workflows/black-checker.yml @@ -0,0 +1,13 @@ +name: black-checker + +on: [pull_request, push] + +jobs: + black: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Black Code Formatter + uses: lgeiger/black-action@v1.0.1 + with: + args: "--line-length 120 --target-version py38 --check ." diff --git a/activitylog/__init__.py b/activitylog/__init__.py index 6ae613d..77f8152 100644 --- a/activitylog/__init__.py +++ b/activitylog/__init__.py @@ -1,5 +1,6 @@ from .activitylog import ActivityLogger + async def setup(bot): n = ActivityLogger(bot) await n.initialize() diff --git a/activitylog/activitylog.py b/activitylog/activitylog.py index b14a6b2..32fe48d 100644 --- a/activitylog/activitylog.py +++ b/activitylog/activitylog.py @@ -12,13 +12,9 @@ import os import asyncio import glob -__version__ = '3.0.0' +__version__ = "3.0.0" -TIMESTAMP_FORMAT = '%Y-%m-%d %X' # YYYY-MM-DD HH:MM:SS -#PATH_LIST = ['data', 'activitylogger'] -#JSON = os.path.join(*PATH_LIST, "settings.json") -#NAMES_JSON = os.path.join(*PATH_LIST, "past_names.json") -EDIT_TIMEDELTA = timedelta(seconds=3) +TIMESTAMP_FORMAT = "%Y-%m-%d %X" # YYYY-MM-DD HH:MM:SS # 0 is Message object AUTHOR_TEMPLATE = "@{0.author.name}#{0.author.discriminator}(id:{0.author.id})" @@ -42,6 +38,7 @@ DELETE_AUDIT_TEMPLATE = "@{0.name}#{0.discriminator}(id:{0.id}) deleted message MAX_LINES = 50000 + def get_all_names(guild_files, user): names = [str(user)] for log in guild_files: @@ -68,19 +65,21 @@ def get_all_names(guild_files, user): names.append(username) return set(names) -def format_list(*items, join='and', delim=', '): + +def format_list(*items, join="and", delim=", "): if len(items) > 1: - return (' %s ' % join).join((delim.join(items[:-1]), items[-1])) + return (" %s " % join).join((delim.join(items[:-1]), items[-1])) elif items: return items[0] else: - return '' + return "" class LogHandle: """basic wrapper for logfile handles, used to keep track of stale handles""" - def __init__(self, path, time=None, mode='a', buf=1): - self.handle = open(path, mode, buf, errors='backslashreplace') + + def __init__(self, path, time=None, mode="a", buf=1): + self.handle = open(path, mode, buf, errors="backslashreplace") self.lock = asyncio.Lock() if time: @@ -111,34 +110,13 @@ class ActivityLogger(commands.Cog): self.bot = bot self.config = Config.get_conf(self, identifier=9584736583, force_registration=True) default_global = { - "attrs": { - "attachments" : False, - "default" : False, - "direct" : False, - "everything" : False, - "rotation" : "m" - } - } - self.default_guild = { - "all_s": False, - "voice": False, - "events": False, - "prefixes": [] - } - self.default_channel = { - "enabled": False - } - default_user = { - "past_names": [] + "attrs": {"attachments": False, "default": False, "direct": False, "everything": False, "rotation": "m"} } + self.default_guild = {"all_s": False, "voice": False, "events": False, "prefixes": []} + self.default_channel = {"enabled": False} + default_user = {"past_names": []} default_member = { - "stats": { - "total_msg": 0, - "bot_cmd": 0, - "avg_len": 0.0, - "vc_time_sec": 0.0, - "last_vc_time": None - } + "stats": {"total_msg": 0, "bot_cmd": 0, "avg_len": 0.0, "vc_time_sec": 0.0, "last_vc_time": None} } self.config.register_global(**default_global) self.config.register_guild(**self.default_guild) @@ -203,9 +181,7 @@ class ActivityLogger(commands.Cog): since_joined = "?" user_joined = "Unknown" user_created = user.created_at.strftime("%b %d, %Y %H:%M UTC") - member_number = (sorted(guild.members, - key=lambda m: m.joined_at or ctx.message.created_at) - .index(user) + 1) + member_number = sorted(guild.members, key=lambda m: m.joined_at or ctx.message.created_at).index(user) + 1 created_on = "{}\n({} days ago)".format(user_created, since_created) joined_on = "{}\n({} days ago)".format(user_joined, since_joined) @@ -243,8 +219,7 @@ class ActivityLogger(commands.Cog): names = pagify(names, page_length=1000) for name in names: data.add_field(name="Also known as:", value=name, inline=False) - data.set_footer(text="Member #{} | User ID:{}" - "".format(member_number, user.id)) + data.set_footer(text="Member #{} | User ID:{}" "".format(member_number, user.id)) name = str(user) name = " ~ ".join((name, user.nick)) if user.nick else name @@ -274,7 +249,7 @@ class ActivityLogger(commands.Cog): stats = await self.config.member(user).stats() async with self.config.user(user).past_names() as past_names: if not past_names: - guild_files = sorted(glob.glob(os.path.join(PATH, 'usernames', "*.log"))) + guild_files = sorted(glob.glob(os.path.join(PATH, "usernames", "*.log"))) names = get_all_names(guild_files, user) else: names = past_names @@ -306,7 +281,9 @@ class ActivityLogger(commands.Cog): msg += "Average message length: `{:.2f}` words\n".format(avg_len / (num_messages - num_bot_commands)) except ZeroDivisionError: msg += "Average message length: `{:.2f}` words\n".format(0) - msg += "Time spent in voice chat: `{:.0f}` {}.\n".format(minutes if minutes <= 120 else hours, "minutes" if minutes <= 120 else "hours") + msg += "Time spent in voice chat: `{:.0f}` {}.\n".format( + minutes if minutes <= 120 else hours, "minutes" if minutes <= 120 else "hours" + ) msg += f"Bans: `{bans}`, Kicks: `{kicks}`, Mutes: `{mutes}`" if len(names) > 1: return msg, format_list(*names) @@ -351,12 +328,12 @@ class ActivityLogger(commands.Cog): messages = [message for message in messages if str(user.id) in message] message_chunks = [ - messages[i * MAX_LINES:(i + 1) * MAX_LINES] for i in range((len(messages) + MAX_LINES - 1) // MAX_LINES) + messages[i * MAX_LINES : (i + 1) * MAX_LINES] for i in range((len(messages) + MAX_LINES - 1) // MAX_LINES) ] for msgs in message_chunks: temp_file = os.path.join(log_path, datetime.utcnow().strftime("%Y%m%d%X").replace(":", "") + ".txt") - with open(temp_file, encoding='utf-8', mode="w") as f: + with open(temp_file, encoding="utf-8", mode="w") as f: f.writelines(msgs) await ctx.channel.send(file=discord.File(temp_file)) @@ -436,12 +413,12 @@ class ActivityLogger(commands.Cog): """ try: dates = date.split(";") - dates = [dates[0].strip(), dates[1].strip()] # only use 2 dates + dates = [dates[0].strip(), dates[1].strip()] # only use 2 dates start, end = [parse_time(date).replace(tzinfo=None) for date in dates] # order doesnt matter, so check which date is older than the other # end time should be the newest date since logs are processed in reverse - if start < end: # start is before end date - start, end = end, start # swap order + if start < end: # start is before end date + start, end = end, start # swap order except: await ctx.send("Invalid dates! Try again.") return @@ -530,12 +507,12 @@ class ActivityLogger(commands.Cog): """ try: dates = date.split(";") - dates = [dates[0].strip(), dates[1].strip()] # only use 2 dates + dates = [dates[0].strip(), dates[1].strip()] # only use 2 dates start, end = [parse_time(date).replace(tzinfo=None) for date in dates] # order doesnt matter, so check which date is older than the other # end time should be the newest date since logs are processed in reverse - if start < end: # start is before end date - start, end = end, start # swap order + if start < end: # start is before end date + start, end = end, start # swap order except: await ctx.send("Invalid dates! Try again.") return @@ -624,12 +601,12 @@ class ActivityLogger(commands.Cog): """ try: dates = date.split(";") - dates = [dates[0].strip(), dates[1].strip()] # only use 2 dates + dates = [dates[0].strip(), dates[1].strip()] # only use 2 dates start, end = [parse_time(date).replace(tzinfo=None) for date in dates] # order doesnt matter, so check which date is older than the other # end time should be the newest date since logs are processed in reverse - if start < end: # start is before end date - start, end = end, start # swap order + if start < end: # start is before end date + start, end = end, start # swap order except: await ctx.send("Invalid dates! Try again.") return @@ -719,12 +696,12 @@ class ActivityLogger(commands.Cog): """ try: dates = date.split(";") - dates = [dates[0].strip(), dates[1].strip()] # only use 2 dates + dates = [dates[0].strip(), dates[1].strip()] # only use 2 dates start, end = [parse_time(date).replace(tzinfo=None) for date in dates] # order doesnt matter, so check which date is older than the other # end time should be the newest date since logs are processed in reverse - if start < end: # start is before end date - start, end = end, start # swap order + if start < end: # start is before end date + start, end = end, start # swap order except: await ctx.send("Invalid dates! Try again.") return @@ -746,7 +723,7 @@ class ActivityLogger(commands.Cog): """ pass - @logset.command(name='everything', aliases=['global']) + @logset.command(name="everything", aliases=["global"]) async def set_everything(self, ctx, on_off: bool = None): """ Global override for all logging @@ -762,7 +739,7 @@ class ActivityLogger(commands.Cog): else: await ctx.send("Global logging override is disabled.") - @logset.command(name='default') + @logset.command(name="default") async def set_default(self, ctx, on_off: bool = None): """ Sets whether logging is on or off where unset @@ -780,7 +757,7 @@ class ActivityLogger(commands.Cog): else: await ctx.send("Logging is disabled by default.") - @logset.command(name='dm') + @logset.command(name="dm") async def set_direct(self, ctx, on_off: bool = None): """ Log direct messages? @@ -797,7 +774,7 @@ class ActivityLogger(commands.Cog): else: await ctx.send("Logging of direct messages is disabled.") - @logset.command(name='attachments') + @logset.command(name="attachments") async def set_attachments(self, ctx, on_off: bool = None): """ Download message attachments? @@ -813,7 +790,7 @@ class ActivityLogger(commands.Cog): else: await ctx.send("Downloading of attachments is disabled.") - @logset.command(name='channel') + @logset.command(name="channel") @commands.guild_only() async def set_channel(self, ctx, on_off: bool, channel: discord.TextChannel = None): """ @@ -830,11 +807,11 @@ class ActivityLogger(commands.Cog): await self.config.channel(channel).enabled.set(on_off) if on_off: - await ctx.send('Logging enabled for %s' % channel.mention) + await ctx.send("Logging enabled for %s" % channel.mention) else: - await ctx.send('Logging disabled for %s' % channel.mention) + await ctx.send("Logging disabled for %s" % channel.mention) - @logset.command(name='server') + @logset.command(name="server") @commands.guild_only() async def set_guild(self, ctx, on_off: bool): """ @@ -846,11 +823,11 @@ class ActivityLogger(commands.Cog): await self.config.guild(guild).all_s.set(on_off) if on_off: - await ctx.send('Logging enabled for %s' % guild) + await ctx.send("Logging enabled for %s" % guild) else: - await ctx.send('Logging disabled for %s' % guild) + await ctx.send("Logging disabled for %s" % guild) - @logset.command(name='voice') + @logset.command(name="voice") @commands.guild_only() async def set_voice(self, ctx, on_off: bool): """ @@ -862,11 +839,11 @@ class ActivityLogger(commands.Cog): await self.config.guild(guild).voice.set(on_off) if on_off: - await ctx.send('Voice event logging enabled for %s' % guild) + await ctx.send("Voice event logging enabled for %s" % guild) else: - await ctx.send('Voice event logging disabled for %s' % guild) + await ctx.send("Voice event logging disabled for %s" % guild) - @logset.command(name='events') + @logset.command(name="events") @commands.guild_only() async def set_events(self, ctx, on_off: bool): """ @@ -878,9 +855,9 @@ class ActivityLogger(commands.Cog): await self.config.guild(guild).events.set(on_off) if on_off: - await ctx.send('Logging enabled for guild events in %s' % guild) + await ctx.send("Logging enabled for guild events in %s" % guild) else: - await ctx.send('Logging disabled for guild events in %s' % guild) + await ctx.send("Logging disabled for guild events in %s" % guild) @logset.command(name="prefixes") @commands.guild_only() @@ -895,16 +872,16 @@ class ActivityLogger(commands.Cog): await self.config.guild(ctx.guild).prefixes.set([ctx.clean_prefix]) self.cache[ctx.guild.id]["prefixes"] = [ctx.clean_prefix] return - await ctx.send("Current Prefixes: " + format_list(*curr, delim=', ')) + await ctx.send("Current Prefixes: " + format_list(*curr, delim=", ")) return - prefixes = [p for p in prefixes if p != ' '] + prefixes = [p for p in prefixes if p != " "] await self.config.guild(ctx.guild).prefixes.set(prefixes) self.cache[ctx.guild.id]["prefixes"] = prefixes prefixes = [f"`{p}`" for p in prefixes] - await ctx.send("Prefixes set to: " + format_list(*prefixes, delim=', ')) + await ctx.send("Prefixes set to: " + format_list(*prefixes, delim=", ")) - @logset.command(name='rotation') + @logset.command(name="rotation") async def set_rotation(self, ctx, freq: str = None): """ Show, disable, or set the log rotation period @@ -921,12 +898,12 @@ class ActivityLogger(commands.Cog): - y: one log file per year (starts 00:00Z Jan 1) """ if freq: - freq = freq.lower().strip('"\'` ') + freq = freq.lower().strip("\"'` ") - if freq in ('d', 'w', 'm', 'y', 'none', 'disable'): - adj = 'now' + if freq in ("d", "w", "m", "y", "none", "disable"): + adj = "now" - if freq in ('none', 'disable'): + if freq in ("none", "disable"): freq = None async with self.config.attrs() as attrs: @@ -937,53 +914,48 @@ class ActivityLogger(commands.Cog): await self.bot.send_cmd_help(ctx) return else: - adj = 'currently' + adj = "currently" freq = self.cache["rotation"] if not freq: await ctx.send("Log rotation is %s disabled." % adj) else: - desc = { - 'd' : 'daily', - 'w' : 'weekly', - 'm' : 'monthly', - 'y' : 'yearly' - }[freq] + desc = {"d": "daily", "w": "weekly", "m": "monthly", "y": "yearly"}[freq] - await ctx.send('Log rotation period is %s %s.' % (adj, desc)) + await ctx.send("Log rotation period is %s %s." % (adj, desc)) @staticmethod def format_rotation_string(timestamp, rotation_code, filename=None): kwargs = dict(hour=0, minute=0, second=0, microsecond=0) if not rotation_code: - return filename or '' + return filename or "" - if rotation_code == 'y': + if rotation_code == "y": kwargs.update(day=1, month=1) start = timestamp.replace(**kwargs) - elif rotation_code == 'm': + elif rotation_code == "m": kwargs.update(day=1) start = timestamp.replace(**kwargs) - elif rotation_code == 'w': + elif rotation_code == "w": start = timestamp - timedelta(days=timestamp.weekday()) - spec = start.strftime('%Y%m%d') + spec = start.strftime("%Y%m%d") - if rotation_code == 'w': - spec += '--P7D' + if rotation_code == "w": + spec += "--P7D" else: - spec += '--P1%c' % rotation_code.upper() + spec += "--P1%c" % rotation_code.upper() if filename: - return '%s_%s' % (spec, filename) + return "%s_%s" % (spec, filename) else: return spec @staticmethod def get_voice_flags(voice_state): flags = [] - for f in ('deaf', 'mute', 'self_deaf', 'self_mute', 'self_stream', 'self_video'): + for f in ("deaf", "mute", "self_deaf", "self_mute", "self_stream", "self_video"): if getattr(voice_state, f, None): flags.append(f) @@ -992,11 +964,13 @@ class ActivityLogger(commands.Cog): @staticmethod def format_overwrite(target, channel, before, after, user=None): if user: - target_str = 'Channel overwrites by @{1.name}#{1.discriminator}(id:{1.id}): {0.name} ({0.id}): '.format(channel, user) + target_str = "Channel overwrites by @{1.name}#{1.discriminator}(id:{1.id}): {0.name} ({0.id}): ".format( + channel, user + ) else: - target_str = 'Channel overwrites: {0.name} ({0.id}): '.format(channel) - target_str += 'role' if isinstance(target, discord.Role) else 'member' - target_str += ' {0.name} ({0.id})'.format(target) + target_str = "Channel overwrites: {0.name} ({0.id}): ".format(channel) + target_str += "role" if isinstance(target, discord.Role) else "member" + target_str += " {0.name} ({0.id})".format(target) if before: bpair = [x.value for x in before.pair()] @@ -1005,14 +979,14 @@ class ActivityLogger(commands.Cog): apair = [x.value for x in after.pair()] if before and after: - fmt = ' updated to values %i, %i (was %i, %i)' + fmt = " updated to values %i, %i (was %i, %i)" return target_str + fmt % tuple(apair + bpair) elif after: - return target_str + ' added with values %i, %i' % tuple(apair) + return target_str + " added with values %i, %i" % tuple(apair) elif before: - return target_str + ' removed (was %i, %i)' % tuple(bpair) + return target_str + " removed (was %i, %i)" % tuple(bpair) - def gethandle(self, path, mode='a'): + def gethandle(self, path, mode="a"): """Manages logfile handles, culling stale ones and creating folders""" if path in self.handles: if os.path.exists(path): @@ -1047,34 +1021,34 @@ class ActivityLogger(commands.Cog): return handle def should_log(self, location): - if self.cache.get('everything', False): + if self.cache.get("everything", False): return True - default = self.cache.get('default', False) + default = self.cache.get("default", False) if type(location) is discord.Guild: loc = self.cache[location.id] - return loc.get('all_s', False) or loc.get('events', default) + return loc.get("all_s", False) or loc.get("events", default) elif type(location) is discord.TextChannel: loc = self.cache[location.guild.id] - opts = [loc.get('all_s', False), self.cache[location.id].get("enabled", default)] + opts = [loc.get("all_s", False), self.cache[location.id].get("enabled", default)] return any(opts) elif type(location) is discord.VoiceChannel: loc = self.cache[location.guild.id] - opts = [loc.get('all_s', False), loc.get('voice', False)] + opts = [loc.get("all_s", False), loc.get("voice", False)] return any(opts) elif isinstance(location, discord.abc.PrivateChannel): - return self.cache.get('direct', default) + return self.cache.get("direct", default) else: # can't log other types return False def should_download(self, msg): - return self.should_log(msg.channel) and self.cache.get('attachments', False) + return self.should_log(msg.channel) and self.cache.get("attachments", False) def process_attachment(self, message, a): aid = a.id @@ -1086,23 +1060,23 @@ class ActivityLogger(commands.Cog): if type(channel) is discord.TextChannel: guildid = channel.guild.id elif isinstance(channel, discord.abc.PrivateChannel): - guildid = 'direct' + guildid = "direct" - path = os.path.join(path, str(guildid), str(channel.id) + '_attachments') - filename = str(aid) + '_' + aname + path = os.path.join(path, str(guildid), str(channel.id) + "_attachments") + filename = str(aid) + "_" + aname if len(filename) > 255: target_len = 255 - len(aid) - 4 part_a = target_len // 2 part_b = target_len - part_a - filename = aid + '_' + aname[:part_a] + '...' + aname[-part_b:] + filename = aid + "_" + aname[:part_a] + "..." + aname[-part_b:] truncated = True else: truncated = False return aid, url, path, filename, truncated - async def log(self, location, text, timestamp=None, force=False, subfolder=None, mode='a'): + async def log(self, location, text, timestamp=None, force=False, subfolder=None, mode="a"): if not timestamp: timestamp = datetime.utcnow() @@ -1111,24 +1085,24 @@ class ActivityLogger(commands.Cog): path = [] entry = [timestamp.strftime(TIMESTAMP_FORMAT)] - rotation = self.cache['rotation'] + rotation = self.cache["rotation"] if type(location) is discord.Guild: - path += [str(location.id), 'guild.log'] + path += [str(location.id), "guild.log"] elif type(location) is discord.TextChannel or type(location) is discord.VoiceChannel: guildid = str(location.guild.id) - entry.append('#' + location.name) - path += [guildid, str(location.id) + '.log'] + entry.append("#" + location.name) + path += [guildid, str(location.id) + ".log"] elif isinstance(location, discord.abc.PrivateChannel): - path += ['direct', str(location.id) + '.log'] + path += ["direct", str(location.id) + ".log"] elif type(location) is discord.User or type(location) is discord.Member: - path += ['usernames', 'usernames.log'] + path += ["usernames", "usernames.log"] else: return if subfolder: path.insert(-1, str(subfolder)) - text = text.replace('\n', '\\n') + text = text.replace("\n", "\\n") entry.append(text) if rotation: @@ -1136,7 +1110,7 @@ class ActivityLogger(commands.Cog): fname = os.path.join(PATH, *path) handle = self.gethandle(fname, mode=mode) - await handle.write(' '.join(entry) + '\n') + await handle.write(" ".join(entry) + "\n") async def message_handler(self, message, *args, force_attachments=None, **kwargs): dl_attachment = self.should_download(message) @@ -1149,15 +1123,17 @@ class ActivityLogger(commands.Cog): for a in message.attachments: attachments += [self.process_attachment(message, a)] - entry = DOWNLOAD_TEMPLATE.format(message, [a[3] + ' (filename truncated)' if a[4] else a[3] for a in attachments]) + entry = DOWNLOAD_TEMPLATE.format( + message, [a[3] + " (filename truncated)" if a[4] else a[3] for a in attachments] + ) elif message.attachments: - urls = ','.join(a.url for a in message.attachments) + urls = ",".join(a.url for a in message.attachments) entry = ATTACHMENT_TEMPLATE.format(message, urls) else: entry = MESSAGE_TEMPLATE.format(message) - if message.author.id != self.bot.user.id: # don't calculate bot stats + if message.author.id != self.bot.user.id: # don't calculate bot stats async with self.config.member(message.author).stats() as stats: stats["total_msg"] += 1 if len(message.content) > 0 and message.content[0] in self.cache[message.guild.id]["prefixes"]: @@ -1199,10 +1175,12 @@ class ActivityLogger(commands.Cog): async for entry in message.guild.audit_logs(limit=1): # target is user who had message deleted if entry.action is discord.AuditLogAction.message_delete: - if entry.target.id == message.author.id and \ - entry.extra.channel.id == message.channel.id and \ - entry.created_at.timestamp() > time.time() - 3000 and \ - entry.extra.count >= 1: + if ( + entry.target.id == message.author.id + and entry.extra.channel.id == message.channel.id + and entry.created_at.timestamp() > time.time() - 3000 + and entry.extra.count >= 1 + ): entry_s = DELETE_AUDIT_TEMPLATE.format(entry.user, message, message.author, timestamp) break except: @@ -1215,12 +1193,12 @@ class ActivityLogger(commands.Cog): @commands.Cog.listener() async def on_guild_join(self, guild): - entry = 'this bot joined the guild' + entry = "this bot joined the guild" await self.log(guild, entry) @commands.Cog.listener() async def on_guild_remove(self, guild): - entry = 'this bot left the guild' + entry = "this bot left the guild" await self.log(guild, entry) @commands.Cog.listener() @@ -1230,39 +1208,49 @@ class ActivityLogger(commands.Cog): try: async for entry in after.audit_logs(limit=1): if entry.action is discord.AuditLogAction.guild_update: - user = entry.user + user = entry.user except: pass if before.owner != after.owner: if user: - entries.append('guild owner changed by @{2.name}#{2.discriminator}(id:{2.id}), from {0.owner} (id {0.owner.id}) to {1.owner} (id {1.owner.id})') + entries.append( + "guild owner changed by @{2.name}#{2.discriminator}(id:{2.id}), from {0.owner} (id {0.owner.id}) to {1.owner} (id {1.owner.id})" + ) else: - entries.append('guild owner changed from {0.owner} (id {0.owner.id}) to {1.owner} (id {1.owner.id})') + entries.append("guild owner changed from {0.owner} (id {0.owner.id}) to {1.owner} (id {1.owner.id})") if before.region != after.region: if user: - entries.append('guild region changed by @{2.name}#{2.discriminator}(id:{2.id}), from {0.region} to {1.region}') + entries.append( + "guild region changed by @{2.name}#{2.discriminator}(id:{2.id}), from {0.region} to {1.region}" + ) else: - entries.append('guild region changed from {0.region} to {1.region}') + entries.append("guild region changed from {0.region} to {1.region}") if before.name != after.name: if user: - entries.append('guild name changed by @{2.name}#{2.discriminator}(id:{2.id}), from "{0.name}" to "{1.name}"') + entries.append( + 'guild name changed by @{2.name}#{2.discriminator}(id:{2.id}), from "{0.name}" to "{1.name}"' + ) else: entries.append('guild name changed from "{0.name}" to "{1.name}"') if before.icon_url != after.icon_url: if user: - entries.append('guild icon changed by @{2.name}#{2.discriminator}(id:{2.id}), from {0.icon_url} to {1.icon_url}') + entries.append( + "guild icon changed by @{2.name}#{2.discriminator}(id:{2.id}), from {0.icon_url} to {1.icon_url}" + ) else: - entries.append('guild icon changed from {0.icon_url} to {1.icon_url}') + entries.append("guild icon changed from {0.icon_url} to {1.icon_url}") if before.splash != after.splash: if user: - entries.append('guild splash changed by @{2.name}#{2.discriminator}(id:{2.id}), from {0.splash} to {1.splash}') + entries.append( + "guild splash changed by @{2.name}#{2.discriminator}(id:{2.id}), from {0.splash} to {1.splash}" + ) else: - entries.append('guild splash changed from {0.splash} to {1.splash}') + entries.append("guild splash changed from {0.splash} to {1.splash}") for e in entries: if user: @@ -1326,45 +1314,61 @@ class ActivityLogger(commands.Cog): if before.color != after.color: if user: - entries.append('Role color by @{2.name}#{2.discriminator}(id:{2.id}): "{0}" (id {0.id}) changed from {0.color} to {1.color}') + entries.append( + 'Role color by @{2.name}#{2.discriminator}(id:{2.id}): "{0}" (id {0.id}) changed from {0.color} to {1.color}' + ) else: entries.append('Role color: "{0}" (id {0.id}) changed from {0.color} to {1.color}') if before.mentionable != after.mentionable: if after.mentionable: if user: - entries.append('Role mentionable by @{2.name}#{2.discriminator}(id:{2.id}): "{1.name}" (id {1.id}) is now mentionable') + entries.append( + 'Role mentionable by @{2.name}#{2.discriminator}(id:{2.id}): "{1.name}" (id {1.id}) is now mentionable' + ) else: entries.append('Role mentionable: "{1.name}" (id {1.id}) is now mentionable') else: if user: - entries.append('Role mentionable by @{2.name}#{2.discriminator}(id:{2.id}): "{1.name}" (id {1.id}) is no longer mentionable') + entries.append( + 'Role mentionable by @{2.name}#{2.discriminator}(id:{2.id}): "{1.name}" (id {1.id}) is no longer mentionable' + ) else: entries.append('Role mentionable: "{1.name}" (id {1.id}) is no longer mentionable') if before.hoist != after.hoist: if after.hoist: if user: - entries.append('Role hoist by @{2.name}#{2.discriminator}(id:{2.id}): "{1.name}" (id {1.id}) is now shown seperately') + entries.append( + 'Role hoist by @{2.name}#{2.discriminator}(id:{2.id}): "{1.name}" (id {1.id}) is now shown seperately' + ) else: entries.append('Role hoist: "{1.name}" (id {1.id}) is now shown seperately') else: if user: - entries.append('Role hoist by @{2.name}#{2.discriminator}(id:{2.id}): "{1.name}" (id {1.id}) is no longer shown seperately') + entries.append( + 'Role hoist by @{2.name}#{2.discriminator}(id:{2.id}): "{1.name}" (id {1.id}) is no longer shown seperately' + ) else: entries.append('Role hoist: "{1.name}" (id {1.id}) is no longer shown seperately') if before.permissions != after.permissions: if user: - entries.append('Role permissions by @{2.name}#{2.discriminator}(id:{2.id}): "{1.name}" (id {1.id}) changed from {0.permissions.value} ' - 'to {1.permissions.value}') + entries.append( + 'Role permissions by @{2.name}#{2.discriminator}(id:{2.id}): "{1.name}" (id {1.id}) changed from {0.permissions.value} ' + "to {1.permissions.value}" + ) else: - entries.append('Role permissions: "{1.name}" (id {1.id}) changed from {0.permissions.value} ' - 'to {1.permissions.value}') + entries.append( + 'Role permissions: "{1.name}" (id {1.id}) changed from {0.permissions.value} ' + "to {1.permissions.value}" + ) if before.position != after.position: if user: - entries.append('Role position by @{2.name}#{2.discriminator}(id:{2.id}): "{0}" changed from {0.position} to {1.position}') + entries.append( + 'Role position by @{2.name}#{2.discriminator}(id:{2.id}): "{0}" changed from {0.position} to {1.position}' + ) else: entries.append('Role position: "{0}" changed from {0.position} to {1.position}') @@ -1376,7 +1380,7 @@ class ActivityLogger(commands.Cog): @commands.Cog.listener() async def on_member_join(self, member): - entry = 'Member join: @{0} (id {0.id})'.format(member) + entry = "Member join: @{0} (id {0.id})".format(member) async with self.config.user(member).past_names() as past_names: if str(member) not in past_names: @@ -1396,9 +1400,9 @@ class ActivityLogger(commands.Cog): pass if user: - entry = 'Member kicked by @{1.name}#{1.discriminator}(id:{1.id}): @{0} (id {0.id})'.format(member, user) + entry = "Member kicked by @{1.name}#{1.discriminator}(id:{1.id}): @{0} (id {0.id})".format(member, user) else: - entry = 'Member leave: @{0} (id {0.id})'.format(member) + entry = "Member leave: @{0} (id {0.id})".format(member) await self.config.member(member).clear() await self.log(member.guild, entry) @@ -1415,9 +1419,9 @@ class ActivityLogger(commands.Cog): pass if user: - entry = 'Member banned by @{1.name}#{1.discriminator}(id:{1.id}): @{0} (id {0.id})'.format(member, user) + entry = "Member banned by @{1.name}#{1.discriminator}(id:{1.id}): @{0} (id {0.id})".format(member, user) else: - entry = 'Member ban: @{0} (id {0.id})'.format(member) + entry = "Member ban: @{0} (id {0.id})".format(member) await self.log(member.guild, entry) @@ -1433,9 +1437,9 @@ class ActivityLogger(commands.Cog): pass if user: - entry = 'Member unbanned by @{1.name}#{1.discriminator}(id:{1.id}): @{0} (id {0.id})'.format(member, user) + entry = "Member unbanned by @{1.name}#{1.discriminator}(id:{1.id}): @{0} (id {0.id})".format(member, user) else: - entry = 'Member unban: @{0} (id {0.id})'.format(member) + entry = "Member unban: @{0} (id {0.id})".format(member) await self.log(guild, entry) @@ -1445,8 +1449,10 @@ class ActivityLogger(commands.Cog): user = None try: async for entry in after.guild.audit_logs(limit=1): - if entry.action is discord.AuditLogAction.member_update \ - or entry.action is discord.AuditLogAction.member_role_update: + if ( + entry.action is discord.AuditLogAction.member_update + or entry.action is discord.AuditLogAction.member_role_update + ): if entry.target.id == after.id: user = entry.user except: @@ -1454,7 +1460,9 @@ class ActivityLogger(commands.Cog): if before.nick != after.nick: if user: - entries.append('Member nickname changed by @{2.name}#{2.discriminator}(id:{2.id}): "@{0}" (id {0.id}) nickname change from "{0.nick}" to "{1.nick}"') + entries.append( + 'Member nickname changed by @{2.name}#{2.discriminator}(id:{2.id}): "@{0}" (id {0.id}) nickname change from "{0.nick}" to "{1.nick}"' + ) else: entries.append('Member nickname: "@{0}" (id {0.id}) changed nickname from "{0.nick}" to "{1.nick}"') @@ -1466,18 +1474,27 @@ class ActivityLogger(commands.Cog): for r in added: if user: - entries.append('Member role added by @{1.name}#{1.discriminator}(id:{1.id}): "{0}" (id {0.id}) role ' - 'was added to "@{{0}}" (id {{0.id}})'.format(r, user)) + entries.append( + 'Member role added by @{1.name}#{1.discriminator}(id:{1.id}): "{0}" (id {0.id}) role ' + 'was added to "@{{0}}" (id {{0.id}})'.format(r, user) + ) else: - entries.append('Member role add: "{0}" (id {0.id}) role ' - 'was added to "@{{0}}" (id {{0.id}})'.format(r)) + entries.append( + 'Member role add: "{0}" (id {0.id}) role ' 'was added to "@{{0}}" (id {{0.id}})'.format(r) + ) for r in removed: if user: - entries.append('Member role removed by @{1.name}#{1.discriminator}(id:{1.id}): "{0}" (id {0.id}) role was removed from "@{{0}}" (id {{0.id}})'.format(r, user)) + entries.append( + 'Member role removed by @{1.name}#{1.discriminator}(id:{1.id}): "{0}" (id {0.id}) role was removed from "@{{0}}" (id {{0.id}})'.format( + r, user + ) + ) else: - entries.append('Member role remove: "{0}" (id {0.id}) role ' - 'was removed from "@{{0}}" (id {{0.id}})'.format(r)) + entries.append( + 'Member role remove: "{0}" (id {0.id}) role ' + 'was removed from "@{{0}}" (id {{0.id}})'.format(r) + ) for e in entries: await self.log(before.guild, e.format(before, after, user)) @@ -1513,7 +1530,9 @@ class ActivityLogger(commands.Cog): pass if user: - entry = 'Channel created by @{1.name}#{1.discriminator}(id:{1.id}): "{0.name}" (id {0.id})'.format(channel, user) + entry = 'Channel created by @{1.name}#{1.discriminator}(id:{1.id}): "{0.name}" (id {0.id})'.format( + channel, user + ) else: entry = 'Channel created: "{0.name}" (id {0.id})'.format(channel) @@ -1531,7 +1550,9 @@ class ActivityLogger(commands.Cog): pass if user: - entry = 'Channel deleted by @{1.name}#{1.discriminator}(id:{1.id}): "{0.name}" (id {0.id})'.format(channel, user) + entry = 'Channel deleted by @{1.name}#{1.discriminator}(id:{1.id}): "{0.name}" (id {0.id})'.format( + channel, user + ) else: entry = 'Channel deleted: "{0.name}" (id {0.id})'.format(channel) @@ -1552,19 +1573,25 @@ class ActivityLogger(commands.Cog): if before.name != after.name: if user: - entries.append('Channel rename by @{2.name}#{2.discriminator}(id:{2.id}): "{0.name}" (id {0.id}) renamed to "{1.name}"') + entries.append( + 'Channel rename by @{2.name}#{2.discriminator}(id:{2.id}): "{0.name}" (id {0.id}) renamed to "{1.name}"' + ) else: entries.append('Channel rename: "{0.name}" (id {0.id}) renamed to "{1.name}"') if before.topic != after.topic: if user: - entries.append('Channel topic by @{2.name}#{2.discriminator}(id:{2.id}): "{0.name}" (id {0.id}) topic was set to "{1.topic}"') + entries.append( + 'Channel topic by @{2.name}#{2.discriminator}(id:{2.id}): "{0.name}" (id {0.id}) topic was set to "{1.topic}"' + ) else: entries.append('Channel topic: "{0.name}" (id {0.id}) topic was set to "{1.topic}"') if before.position != after.position: if user: - entries.append('Channel position by @{2.name}#{2.discriminator}(id:{2.id}): "{0.name}" (id {0.id}) moved from {0.position} to {1.position}') + entries.append( + 'Channel position by @{2.name}#{2.discriminator}(id:{2.id}): "{0.name}" (id {0.id}) moved from {0.position} to {1.position}' + ) else: entries.append('Channel position: "{0.name}" (id {0.id}) moved from {0.position} to {1.position}') @@ -1603,11 +1630,11 @@ class ActivityLogger(commands.Cog): msg = "Voice channel leave: {0} (id {0.id})" async with self.config.member(member).stats() as stats: - stats["vc_time_sec"] += (time.time() - stats["last_vc_time"]) + stats["vc_time_sec"] += time.time() - stats["last_vc_time"] stats["last_vc_time"] = None if after.channel: - msg += ' moving to {1.channel}' + msg += " moving to {1.channel}" await self.log(before.channel, msg.format(member, after)) @@ -1618,35 +1645,35 @@ class ActivityLogger(commands.Cog): stats["last_vc_time"] = time.time() if before.channel: - msg += ', moved from {1.channel}' + msg += ", moved from {1.channel}" flags = self.get_voice_flags(after) if flags: - msg += ', flags: %s' % ','.join(flags) + msg += ", flags: %s" % ",".join(flags) await self.log(after.channel, msg.format(member, before)) if before.deaf != after.deaf: - verb = 'deafen' if after.deaf else 'undeafen' - await self.log(before.channel, 'guild {0}: {1} (id {1.id})'.format(verb, member)) + verb = "deafen" if after.deaf else "undeafen" + await self.log(before.channel, "guild {0}: {1} (id {1.id})".format(verb, member)) if before.mute != after.mute: - verb = 'mute' if after.mute else 'unmute' - await self.log(before.channel, 'guild {0}: {1} (id {1.id})'.format(verb, member)) + verb = "mute" if after.mute else "unmute" + await self.log(before.channel, "guild {0}: {1} (id {1.id})".format(verb, member)) if before.self_deaf != after.self_deaf: - verb = 'deafen' if after.self_deaf else 'undeafen' - await self.log(before.channel, 'guild self-{0}: {1} (id {1.id})'.format(verb, member)) + verb = "deafen" if after.self_deaf else "undeafen" + await self.log(before.channel, "guild self-{0}: {1} (id {1.id})".format(verb, member)) if before.self_mute != after.self_mute: - verb = 'mute' if after.self_mute else 'unmute' - await self.log(before.channel, 'guild self-{0}: {1} (id {1.id})'.format(verb, member)) + verb = "mute" if after.self_mute else "unmute" + await self.log(before.channel, "guild self-{0}: {1} (id {1.id})".format(verb, member)) if before.self_stream != after.self_stream: - verb = 'stop-stream' if not after.self_stream else 'start-stream' - await self.log(before.channel, 'guild self-{0}: {1} (id {1.id})'.format(verb, member)) + verb = "stop-stream" if not after.self_stream else "start-stream" + await self.log(before.channel, "guild self-{0}: {1} (id {1.id})".format(verb, member)) if before.self_video != after.self_video: - verb = 'start-video' if after.self_video else 'stop-video' - await self.log(before.channel, 'guild self-{0}: {1} (id {1.id})'.format(verb, member)) + verb = "start-video" if after.self_video else "stop-video" + await self.log(before.channel, "guild self-{0}: {1} (id {1.id})".format(verb, member)) diff --git a/activitylog/time_utils.py b/activitylog/time_utils.py index 7622fed..0711fc0 100644 --- a/activitylog/time_utils.py +++ b/activitylog/time_utils.py @@ -43,7 +43,6 @@ def parse_time(datetimestring: str): return ret - def parse_time_naive(datetimestring: str): return parser.parse(datetimestring) diff --git a/admincustom/admin.py b/admincustom/admin.py index 33d1d7e..e6c7652 100644 --- a/admincustom/admin.py +++ b/admincustom/admin.py @@ -59,9 +59,7 @@ class Admin(commands.Cog): self.conf.register_global(serverlocked=False) self.conf.register_guild( - announce_ignore=False, - announce_channel=None, # Integer ID - selfroles=[], # List of integer ID's + announce_ignore=False, announce_channel=None, selfroles=[], # Integer ID # List of integer ID's ) self.__current_announcer = None @@ -114,16 +112,12 @@ class Admin(commands.Cog): await member.add_roles(role) except discord.Forbidden: if not self.pass_hierarchy_check(ctx, role): - await self.complain( - ctx, T_(HIERARCHY_ISSUE), role=role, member=member, verb=_("add") - ) + await self.complain(ctx, T_(HIERARCHY_ISSUE), role=role, member=member, verb=_("add")) else: await self.complain(ctx, T_(GENERIC_FORBIDDEN)) else: await ctx.send( - _("I successfully added {role.name} to {member.display_name}").format( - role=role, member=member - ) + _("I successfully added {role.name} to {member.display_name}").format(role=role, member=member) ) async def _removerole(self, ctx: commands.Context, member: discord.Member, role: discord.Role): @@ -134,24 +128,18 @@ class Admin(commands.Cog): await member.remove_roles(role) except discord.Forbidden: if not self.pass_hierarchy_check(ctx, role): - await self.complain( - ctx, T_(HIERARCHY_ISSUE), role=role, member=member, verb=_("remove") - ) + await self.complain(ctx, T_(HIERARCHY_ISSUE), role=role, member=member, verb=_("remove")) else: await self.complain(ctx, T_(GENERIC_FORBIDDEN)) else: await ctx.send( - _("I successfully removed {role.name} from {member.display_name}").format( - role=role, member=member - ) + _("I successfully removed {role.name} from {member.display_name}").format(role=role, member=member) ) @commands.command() @commands.guild_only() @checks.admin_or_permissions(manage_roles=True) - async def addrole( - self, ctx: commands.Context, rolename: discord.Role, *, user: MemberDefaultAuthor = None - ): + async def addrole(self, ctx: commands.Context, rolename: discord.Role, *, user: MemberDefaultAuthor = None): """Add a role to a user. If user is left blank it defaults to the author of the command. @@ -162,16 +150,12 @@ class Admin(commands.Cog): # noinspection PyTypeChecker await self._addrole(ctx, user, rolename) else: - await self.complain( - ctx, T_(USER_HIERARCHY_ISSUE), member=user, role=rolename, verb=_("add") - ) + await self.complain(ctx, T_(USER_HIERARCHY_ISSUE), member=user, role=rolename, verb=_("add")) @commands.command() @commands.guild_only() @checks.admin_or_permissions(manage_roles=True) - async def removerole( - self, ctx: commands.Context, rolename: discord.Role, *, user: MemberDefaultAuthor = None - ): + async def removerole(self, ctx: commands.Context, rolename: discord.Role, *, user: MemberDefaultAuthor = None): """Remove a role from a user. If user is left blank it defaults to the author of the command. @@ -182,9 +166,7 @@ class Admin(commands.Cog): # noinspection PyTypeChecker await self._removerole(ctx, user, rolename) else: - await self.complain( - ctx, T_(USER_HIERARCHY_ISSUE), member=user, role=rolename, verb=_("remove") - ) + await self.complain(ctx, T_(USER_HIERARCHY_ISSUE), member=user, role=rolename, verb=_("remove")) @commands.group() @commands.guild_only() @@ -194,9 +176,7 @@ class Admin(commands.Cog): pass @editrole.command(name="colour", aliases=["color"]) - async def editrole_colour( - self, ctx: commands.Context, role: discord.Role, value: discord.Colour - ): + async def editrole_colour(self, ctx: commands.Context, role: discord.Role, value: discord.Colour): """Edit a role's colour. Use double quotes if the role contains spaces. @@ -234,9 +214,7 @@ class Admin(commands.Cog): """ author = ctx.message.author old_name = role.name - reason = "{}({}) changed the name of role '{}' to '{}'".format( - author.name, author.id, old_name, name - ) + reason = "{}({}) changed the name of role '{}' to '{}'".format(author.name, author.id, old_name, name) if not self.pass_user_hierarchy_check(ctx, role): await self.complain(ctx, T_(ROLE_USER_HIERARCHY_ISSUE), role=role) @@ -285,9 +263,7 @@ class Admin(commands.Cog): channel = ctx.channel await self.conf.guild(ctx.guild).announce_channel.set(channel.id) - await ctx.send( - _("The announcement channel has been set to {channel.mention}").format(channel=channel) - ) + await ctx.send(_("The announcement channel has been set to {channel.mention}").format(channel=channel)) @announce.command(name="ignore") @commands.guild_only() @@ -298,15 +274,9 @@ class Admin(commands.Cog): await self.conf.guild(ctx.guild).announce_ignore.set(not ignored) if ignored: # Keeping original logic.... - await ctx.send( - _("The server {guild.name} will receive announcements.").format(guild=ctx.guild) - ) + await ctx.send(_("The server {guild.name} will receive announcements.").format(guild=ctx.guild)) else: - await ctx.send( - _("The server {guild.name} will not receive announcements.").format( - guild=ctx.guild - ) - ) + await ctx.send(_("The server {guild.name} will not receive announcements.").format(guild=ctx.guild)) async def _valid_selfroles(self, guild: discord.Guild) -> Tuple[discord.Role]: """ diff --git a/admincustom/announcer.py b/admincustom/announcer.py index 154eacb..2b79bb1 100644 --- a/admincustom/announcer.py +++ b/admincustom/announcer.py @@ -66,9 +66,7 @@ class Announcer: try: await channel.send(self.message) except discord.Forbidden: - await bot_owner.send( - _("I could not announce to server: {server.id}").format(server=g) - ) + await bot_owner.send(_("I could not announce to server: {server.id}").format(server=g)) await asyncio.sleep(0.5) self.active = False diff --git a/events/__init__.py b/events/__init__.py index 0cb8d6e..d7da4ad 100644 --- a/events/__init__.py +++ b/events/__init__.py @@ -1,5 +1,6 @@ from .events import Events + def setup(bot): n = Events(bot) bot.add_cog(n) diff --git a/events/events.py b/events/events.py index cf694eb..fcfbf6a 100644 --- a/events/events.py +++ b/events/events.py @@ -11,11 +11,30 @@ import pytz from tzlocal import get_localzone -basic_colors = [discord.Colour.blue(), discord.Colour.teal(), discord.Colour.dark_teal(), discord.Colour.green(), discord.Colour.dark_green(), discord.Colour.dark_blue(), discord.Colour.purple(), discord.Colour.dark_purple(), discord.Colour.magenta(), discord.Colour.gold(), discord.Colour.orange(), discord.Colour.red(), discord.Colour.dark_red(), discord.Colour.blurple(), discord.Colour.greyple()] +basic_colors = [ + discord.Colour.blue(), + discord.Colour.teal(), + discord.Colour.dark_teal(), + discord.Colour.green(), + discord.Colour.dark_green(), + discord.Colour.dark_blue(), + discord.Colour.purple(), + discord.Colour.dark_purple(), + discord.Colour.magenta(), + discord.Colour.gold(), + discord.Colour.orange(), + discord.Colour.red(), + discord.Colour.dark_red(), + discord.Colour.blurple(), + discord.Colour.greyple(), +] + + class Events(commands.Cog): """ Set events that track time since set events """ + def __init__(self, bot): super().__init__() self.config = Config.get_conf(self, identifier=6748392754) @@ -55,18 +74,33 @@ class Events(commands.Cog): elapsed_time = datetime.datetime.utcnow() - start_time embed = discord.Embed(title=event_name, colour=random.choice(basic_colors)) - embed.add_field(name="Event time", value=start_time.replace(tzinfo=pytz.utc).astimezone(self.timezone).strftime("%b %d, %Y, %H:%M")) + embed.add_field( + name="Event time", + value=start_time.replace(tzinfo=pytz.utc).astimezone(self.timezone).strftime("%b %d, %Y, %H:%M"), + ) day_msg = "{} day{},".format(elapsed_time.days, "s" if elapsed_time.days > 1 else "") - hour_msg = " {} hour{}".format(int(elapsed_time.seconds / 60 / 60), "s" if int(elapsed_time.seconds / 60 / 60) > 1 else "") + hour_msg = " {} hour{}".format( + int(elapsed_time.seconds / 60 / 60), "s" if int(elapsed_time.seconds / 60 / 60) > 1 else "" + ) if elapsed_time.days > 0 or int(elapsed_time.seconds / 60 / 60) > 0: - minute_msg = ", and {} minute{}".format(int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), "s" if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 else "") + minute_msg = ", and {} minute{}".format( + int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), + "s" if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 else "", + ) else: - minute_msg = "{} minute{}".format(int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), "s" if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 else "") - msg = "{}{}{}".format(day_msg if elapsed_time.days > 0 else "", hour_msg if int(elapsed_time.seconds / 60 / 60) > 0 else "", minute_msg) + minute_msg = "{} minute{}".format( + int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), + "s" if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 else "", + ) + msg = "{}{}{}".format( + day_msg if elapsed_time.days > 0 else "", + hour_msg if int(elapsed_time.seconds / 60 / 60) > 0 else "", + minute_msg, + ) embed.add_field(name="Elapsed time", value=msg) message = await channel.send(embed=embed) async with self.config.guild(guild).events() as events: - new_event = {"start_time" : int(start_time.replace(tzinfo=pytz.utc).timestamp()), "name" : event_name} + new_event = {"start_time": int(start_time.replace(tzinfo=pytz.utc).timestamp()), "name": event_name} events[message.id] = new_event await ctx.send("Event added!") @@ -98,13 +132,20 @@ class Events(commands.Cog): msg += "```" await ctx.send(msg) await ctx.send("Please choose which event you want to delete. (type number in chat)") + def m_check(m): try: - return m.author.id == ctx.author.id and m.channel.id == ctx.channel.id and int(m.content) <= counter and int(m.content) >= 0 + return ( + m.author.id == ctx.author.id + and m.channel.id == ctx.channel.id + and int(m.content) <= counter + and int(m.content) >= 0 + ) except: return False + try: - response = await self.bot.wait_for('message', timeout=30, check=m_check) + response = await self.bot.wait_for("message", timeout=30, check=m_check) except: await ctx.send("Timed out, event deletion cancelled.") return @@ -179,14 +220,35 @@ class Events(commands.Cog): elapsed_time = datetime.datetime.utcnow() - start_time embed = message.embeds[0] embed.clear_fields() - embed.add_field(name="Event time", value=start_time.replace(tzinfo=pytz.utc).astimezone(self.timezone).strftime("%b %d, %Y, %H:%M")) + embed.add_field( + name="Event time", + value=start_time.replace(tzinfo=pytz.utc) + .astimezone(self.timezone) + .strftime("%b %d, %Y, %H:%M"), + ) day_msg = "{} day{},".format(elapsed_time.days, "s" if elapsed_time.days > 1 else "") - hour_msg = " {} hour{}".format(int(elapsed_time.seconds / 60 / 60), "s" if int(elapsed_time.seconds / 60 / 60) > 1 else "") + hour_msg = " {} hour{}".format( + int(elapsed_time.seconds / 60 / 60), "s" if int(elapsed_time.seconds / 60 / 60) > 1 else "" + ) if elapsed_time.days > 0 or int(elapsed_time.seconds / 60 / 60) > 0: - minute_msg = ", and {} minute{}".format(int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), "s" if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 else "") + minute_msg = ", and {} minute{}".format( + int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), + "s" + if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 + else "", + ) else: - minute_msg = "{} minute{}".format(int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), "s" if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 else "") - msg = "{}{}{}".format(day_msg if elapsed_time.days > 0 else "", hour_msg if int(elapsed_time.seconds / 60 / 60) > 0 else "", minute_msg) + minute_msg = "{} minute{}".format( + int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), + "s" + if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 + else "", + ) + msg = "{}{}{}".format( + day_msg if elapsed_time.days > 0 else "", + hour_msg if int(elapsed_time.seconds / 60 / 60) > 0 else "", + minute_msg, + ) embed.add_field(name="Elapsed time", value=msg) await message.edit(embed=embed) await asyncio.sleep(30) diff --git a/pony/__init__.py b/pony/__init__.py index 0939c7d..fb4f105 100644 --- a/pony/__init__.py +++ b/pony/__init__.py @@ -1,4 +1,5 @@ from .pony import Pony + def setup(bot): bot.add_cog(Pony()) diff --git a/pony/pony.py b/pony/pony.py index 4596a37..a158088 100644 --- a/pony/pony.py +++ b/pony/pony.py @@ -7,18 +7,14 @@ import os import traceback import json + class Pony(commands.Cog): def __init__(self): super().__init__() self.config = Config.get_conf(self, identifier=7384662719) - default_global = { - "maxfilters":50 - } - self.default_guild = { - "filters": ["-meme", "safe", "-spoiler:*", "-vulgar"], - "verbose": False - } + default_global = {"maxfilters": 50} + self.default_guild = {"filters": ["-meme", "safe", "-spoiler:*", "-vulgar"], "verbose": False} self.config.register_guild(**self.default_guild) self.config.register_global(**default_global) @@ -40,7 +36,7 @@ class Pony(commands.Cog): """ Gives a random picture of our mascot! """ - await fetch_image(self, ctx, randomize=True, mascot=True, tags=['safe,', 'coe']) + await fetch_image(self, ctx, randomize=True, mascot=True, tags=["safe,", "coe"]) @commands.group() @commands.guild_only() @@ -53,7 +49,7 @@ class Pony(commands.Cog): pass @ponyfilter.command(name="add") - async def _add_ponyfilter(self, ctx, filter_tag : str): + async def _add_ponyfilter(self, ctx, filter_tag: str): """Adds a tag to the server's pony filter list Example: !ponyfilter add safe""" @@ -72,7 +68,7 @@ class Pony(commands.Cog): await ctx.send("This server has exceeded the maximum filters ({}/{}).".format(len(filters), max_filters)) @ponyfilter.command(name="del") - async def _del_ponyfilter(self, ctx, filter_tag : str=""): + async def _del_ponyfilter(self, ctx, filter_tag: str = ""): """Deletes a tag from the server's pony filter list Without arguments, reverts to the default pony filter list @@ -100,10 +96,10 @@ class Pony(commands.Cog): guild = ctx.guild filters = await self.config.guild(guild).filters() if filters: - filter_list = '\n'.join(sorted(filters)) + filter_list = "\n".join(sorted(filters)) target_guild = "{}'s".format(guild.name) else: - filter_list = '\n'.join(sorted(filters["default"])) + filter_list = "\n".join(sorted(filters["default"])) target_guild = "Default" await ctx.send("{} pony filter list contains:```\n{}```".format(target_guild, filter_list)) @@ -114,7 +110,7 @@ class Pony(commands.Cog): pass @ponyset.command(name="verbose") - async def _verbose_ponyset(self, ctx, toggle : str="toggle"): + async def _verbose_ponyset(self, ctx, toggle: str = "toggle"): """Toggles verbose mode""" guild = ctx.guild verbose = await self.config.guild(guild).verbose() @@ -140,7 +136,7 @@ class Pony(commands.Cog): @ponyset.command(name="maxfilters") @checks.is_owner() - async def _maxfilters_ponyset(self, ctx, new_max_filters : int): + async def _maxfilters_ponyset(self, ctx, new_max_filters: int): """Sets the global tag limit for the filter list. Leave blank to get current max filters. @@ -178,7 +174,7 @@ class Pony(commands.Cog): if guild is None: continue - await self.config.guild(guild).verbose.set(json_guild_verbose['verbose']) + await self.config.guild(guild).verbose.set(json_guild_verbose["verbose"]) msg += "**{}**\n".format(guild) if len(msg) + 100 > 2000: await ctx.send(msg) @@ -194,7 +190,7 @@ class Pony(commands.Cog): for json_guild_id, json_guild_filters in import_filters.items(): if json_guild_id != "default": - guild = bot.get_guild(int(json_guild_id)) # returns None if guild is not found + guild = bot.get_guild(int(json_guild_id)) # returns None if guild is not found if guild is None: continue @@ -204,7 +200,7 @@ class Pony(commands.Cog): await ctx.send(msg) msg = "" else: - continue + continue if msg != "": await ctx.send(msg) @@ -213,25 +209,25 @@ class Pony(commands.Cog): except json.decoder.JSONDecodeError: await ctx.send("Invalid or malformed json files.") - async def fetch_image(self, ctx, randomize : bool=False, tags : list=[], mascot=False): + async def fetch_image(self, ctx, randomize: bool = False, tags: list = [], mascot=False): guild = ctx.guild filters = await self.config.guild(guild).filters() verbose = await self.config.guild(guild).verbose() - #Initialize variables - artist = "unknown artist" - artists = "" - artistList = [] - embedLink = "" - embedTitle = "" - imageId = "" - message = "" - output = None - rating = "" + # Initialize variables + artist = "unknown artist" + artists = "" + artistList = [] + embedLink = "" + embedTitle = "" + imageId = "" + message = "" + output = None + rating = "" ratingColor = "FFFFFF" - ratingWord = "unknown" - search = "https://derpibooru.org/search.json?q=" - tagSearch = "" + ratingWord = "unknown" + search = "https://derpibooru.org/search.json?q=" + tagSearch = "" # Assign tags to URL if tags: @@ -250,12 +246,12 @@ class Pony(commands.Cog): # Randomize results and apply Derpibooru's "Everything" filter if randomize: if not tags and filters: - if filters == []: - search = "https://derpibooru.org/images/random.json?filter_id=56027" - else: - search += "&random_image=y&filter_id=56027" + if filters == []: + search = "https://derpibooru.org/images/random.json?filter_id=56027" + else: + search += "&random_image=y&filter_id=56027" else: - search += "&random_image=y&filter_id=56027" + search += "&random_image=y&filter_id=56027" # Inform users about image retrieving message = await ctx.send("Fetching pony image...") @@ -263,7 +259,7 @@ class Pony(commands.Cog): # Fetch the image or display an error try: async with aiohttp.ClientSession(loop=ctx.bot.loop) as session: - async with session.get(search, headers={'User-Agent': "Booru-Cogs (https://git.io/booru)"}) as r: + async with session.get(search, headers={"User-Agent": "Booru-Cogs (https://git.io/booru)"}) as r: website = await r.json() if randomize: if "id" in website: diff --git a/punish/__init__.py b/punish/__init__.py index 483dfc9..31de3d2 100644 --- a/punish/__init__.py +++ b/punish/__init__.py @@ -1,5 +1,6 @@ from .punish import Punish + async def setup(bot): punish = Punish(bot) await punish.initialize() diff --git a/punish/memoizer.py b/punish/memoizer.py index ecac949..811f953 100644 --- a/punish/memoizer.py +++ b/punish/memoizer.py @@ -2,7 +2,8 @@ class Memoizer: """ General purpose cache for function results. Appends positional args, overlays kwargs. Both must be hashable. """ - __slots__ = ['_cache', '_func', '_args', '_kwargs'] + + __slots__ = ["_cache", "_func", "_args", "_kwargs"] def __init__(self, func, *args, **kwargs): self._cache = {} diff --git a/punish/punish.py b/punish/punish.py index 7cc5038..953c759 100644 --- a/punish/punish.py +++ b/punish/punish.py @@ -16,21 +16,22 @@ import logging import time import textwrap -log = logging.getLogger('red.punish') +log = logging.getLogger("red.punish") -__version__ = '3.0.0' +__version__ = "3.0.0" PURGE_MESSAGES = 1 # for cpunish -DEFAULT_ROLE_NAME = 'Punished' +DEFAULT_ROLE_NAME = "Punished" DEFAULT_TEXT_OVERWRITE = discord.PermissionOverwrite(send_messages=False, send_tts_messages=False, add_reactions=False) DEFAULT_VOICE_OVERWRITE = discord.PermissionOverwrite(speak=False, connect=False) DEFAULT_TIMEOUT_OVERWRITE = discord.PermissionOverwrite(send_messages=True, read_messages=True) QUEUE_TIME_CUTOFF = 30 -DEFAULT_TIMEOUT = '5m' -DEFAULT_CASE_MIN_LENGTH = '5m' # only create modlog cases when length is longer than this +DEFAULT_TIMEOUT = "5m" +DEFAULT_CASE_MIN_LENGTH = "5m" # only create modlog cases when length is longer than this + class Punish(commands.Cog): """ @@ -38,6 +39,7 @@ class Punish(commands.Cog): do other things that can be denied using discord permissions. Includes auto-setup and more. """ + def __init__(self, bot): super().__init__() @@ -53,7 +55,7 @@ class Punish(commands.Cog): "VOICE_OVERWRITE": overwrite_to_dict(DEFAULT_VOICE_OVERWRITE), "ROLE_ID": None, "NITRO_ID": None, - "CHANNEL_ID": None + "CHANNEL_ID": None, } self.config.register_guild(**default_guild) @@ -100,7 +102,7 @@ class Punish(commands.Cog): elif user: await self._punish_cmd_common(ctx, user, duration, reason) - @punish.command(name='cstart') + @punish.command(name="cstart") @commands.guild_only() @checks.mod() async def punish_cstart(self, ctx, user: discord.Member, duration: str = None, *, reason: str = None): @@ -121,7 +123,7 @@ class Punish(commands.Cog): except discord.errors.Forbidden: await ctx.send("Punishment set, but I need permissions to manage messages to clean up.") - @punish.command(name='list') + @punish.command(name="list") @commands.guild_only() @checks.mod() async def punish_list(self, ctx): @@ -135,7 +137,7 @@ class Punish(commands.Cog): guild = ctx.guild guild_id = guild.id now = time.time() - headers = ['Member', 'Remaining', 'Moderator', 'Reason'] + headers = ["Member", "Remaining", "Moderator", "Reason"] punished = await self.config.guild(guild).PUNISHED() embeds = [] @@ -143,13 +145,13 @@ class Punish(commands.Cog): for i, data in enumerate(punished.items()): member_id, data = data member_name = getmname(member_id, guild) - moderator = getmname(data['by'], guild) - reason = data['reason'] - until = data['until'] + moderator = getmname(data["by"], guild) + reason = data["reason"] + until = data["until"] sort = until or float("inf") - remaining = generate_timespec(until - now, short=True) if until else 'forever' + remaining = generate_timespec(until - now, short=True) if until else "forever" - row = [member_name, remaining, moderator, reason or 'No reason set.'] + row = [member_name, remaining, moderator, reason or "No reason set."] embed = discord.Embed(title="Punish List", colour=discord.Colour.from_rgb(255, 0, 0)) for header, row_val in zip(headers, row): @@ -164,7 +166,7 @@ class Punish(commands.Cog): await menu(ctx, embeds, DEFAULT_CONTROLS) - @punish.command(name='clean') + @punish.command(name="clean") @commands.guild_only() @checks.mod() async def punish_clean(self, ctx, clean_pending: bool = False): @@ -189,14 +191,14 @@ class Punish(commands.Cog): if not mid.isdigit() or guild.get_member(mid): continue - elif clean_pending or ((mdata['until'] or 0) < now): - del(data[mid]) + elif clean_pending or ((mdata["until"] or 0) < now): + del data[mid] count += 1 await self.config.guild(guild).PUNISHED.set(data) - await ctx.send('Cleaned %i absent members from the list.' % count) + await ctx.send("Cleaned %i absent members from the list." % count) - @punish.command(name='clean-bans') + @punish.command(name="clean-bans") @commands.guild_only() @checks.mod() async def punish_clean_bans(self, ctx): @@ -220,13 +222,13 @@ class Punish(commands.Cog): continue elif mid in ban_ids: - del(data[mid]) + del data[mid] count += 1 await self.config.guild(guild).PUNISHED.set(data) - await ctx.send('Cleaned %i banned users from the list.' % count) + await ctx.send("Cleaned %i banned users from the list." % count) - @punish.command(name='warn') + @punish.command(name="warn") @commands.guild_only() @checks.mod_or_permissions(manage_messages=True) async def punish_warn(self, ctx, user: discord.Member, *, reason: str = None): @@ -234,16 +236,15 @@ class Punish(commands.Cog): Warns a user with boilerplate about the rules """ - msg = ['Hey %s, ' % user.mention] - msg.append("you're doing something that might get you muted if you keep " - "doing it.") + msg = ["Hey %s, " % user.mention] + msg.append("you're doing something that might get you muted if you keep " "doing it.") if reason: msg.append(" Specifically, %s." % reason) msg.append("Be sure to review the guild rules.") - await ctx.send(' '.join(msg)) + await ctx.send(" ".join(msg)) - @punish.command(name='end', aliases=['remove']) + @punish.command(name="end", aliases=["remove"]) @commands.guild_only() @checks.mod() async def punish_end(self, ctx, user: discord.Member, *, reason: str = None): @@ -260,60 +261,64 @@ class Punish(commands.Cog): now = time.time() punished = await self.config.guild(guild).PUNISHED() data = punished.get(str(user.id), {}) - removed_roles_parsed = resolve_role_list(guild, data.get('removed_roles', [])) + removed_roles_parsed = resolve_role_list(guild, data.get("removed_roles", [])) if role and role in user.roles: - msg = 'Punishment manually ended early by %s.' % ctx.author + msg = "Punishment manually ended early by %s." % ctx.author - original_start = data.get('start') - original_end = data.get('until') + original_start = data.get("start") + original_end = data.get("until") remaining = original_end and (original_end - now) if remaining: - msg += ' %s was left' % generate_timespec(round(remaining)) + msg += " %s was left" % generate_timespec(round(remaining)) if original_start: - msg += ' of the original %s.' % generate_timespec(round(original_end - original_start)) + msg += " of the original %s." % generate_timespec(round(original_end - original_start)) else: - msg += '.' + msg += "." if reason: - msg += '\n\nReason for ending early: ' + reason + msg += "\n\nReason for ending early: " + reason - if data.get('reason'): - msg += '\n\nOriginal reason was: ' + data['reason'] + if data.get("reason"): + msg += "\n\nOriginal reason was: " + data["reason"] - updated_reason = str(msg) # copy string + updated_reason = str(msg) # copy string if removed_roles_parsed: names_list = format_list(*(r.name for r in removed_roles_parsed)) msg += "\nRestored role(s): {}".format(names_list) if not await self._unpunish(user, reason=updated_reason, update=True, moderator=moderator): - msg += '\n\n(failed to send punishment end notification DM)' + msg += "\n\n(failed to send punishment end notification DM)" await ctx.send(msg) elif data: # This shouldn't happen, but just in case now = time.time() - until = data.get('until') - remaining = until and generate_timespec(round(until - now)) or 'forever' + until = data.get("until") + remaining = until and generate_timespec(round(until - now)) or "forever" - data_fmt = '\n'.join([ - "**Reason:** %s" % (data.get('reason') or 'no reason set'), - "**Time remaining:** %s" % remaining, - "**Moderator**: %s" % (user.guild.get_member(data.get('by')) or 'Missing ID#%s' % data.get('by')) - ]) - del(punished[str(user.id)]) + data_fmt = "\n".join( + [ + "**Reason:** %s" % (data.get("reason") or "no reason set"), + "**Time remaining:** %s" % remaining, + "**Moderator**: %s" % (user.guild.get_member(data.get("by")) or "Missing ID#%s" % data.get("by")), + ] + ) + del punished[str(user.id)] await self.config.guild(guild).PUNISHED.set(punished) - await ctx.send("That user doesn't have the %s role, but they still have a data entry. I removed it, " - "but in case it's needed, this is what was there:\n\n%s" % (role.name, data_fmt)) + await ctx.send( + "That user doesn't have the %s role, but they still have a data entry. I removed it, " + "but in case it's needed, this is what was there:\n\n%s" % (role.name, data_fmt) + ) elif role: await ctx.send("That user doesn't have the %s role." % role.name) else: await ctx.send("The punish role couldn't be found in this guild.") - @punish.command(name='reason') + @punish.command(name="reason") @commands.guild_only() @checks.mod() async def punish_reason(self, ctx, user: discord.Member, *, reason: str = None): @@ -325,19 +330,21 @@ class Punish(commands.Cog): data = punished.get(str(user.id), None) if not data: - await ctx.send("That user doesn't have an active punishment entry. To update modlog " - "cases manually, use the `%sreason` command." % ctx.prefix) + await ctx.send( + "That user doesn't have an active punishment entry. To update modlog " + "cases manually, use the `%sreason` command." % ctx.prefix + ) return - punished[str(user.id)]['reason'] = reason + punished[str(user.id)]["reason"] = reason await self.config.guild(guild).PUNISHED.set(punished) if reason: - msg = 'Reason updated.' + msg = "Reason updated." else: - msg = 'Reason cleared.' + msg = "Reason cleared." - caseno = data.get('caseno') + caseno = data.get("caseno") try: case = await modlog.get_case(caseno, guild, self.bot) except: @@ -348,12 +355,12 @@ class Punish(commands.Cog): moderator = ctx.author try: - edits = {'reason': reason} + edits = {"reason": reason} - if moderator.id != data.get('by'): - edits['amended_by'] = moderator + if moderator.id != data.get("by"): + edits["amended_by"] = moderator - edits['modified_at'] = ctx.message.created_at.timestamp() + edits["modified_at"] = ctx.message.created_at.timestamp() await case.edit(edits) except: @@ -504,23 +511,23 @@ class Punish(commands.Cog): try: # Combine sets to get the baseline (roles they'd have normally) - member_roles |= set(role_memo.filter(member_data['removed_roles'], skip_nulls=True)) + member_roles |= set(role_memo.filter(member_data["removed_roles"], skip_nulls=True)) except KeyError: pass # update new removed roles with intersection of guild removal list and baseline new_removed = guild_remove_roles & member_roles - punished[str(member.id)]['removed_roles'] = [r.id for r in new_removed] + punished[str(member.id)]["removed_roles"] = [r.id for r in new_removed] member_roles -= guild_remove_roles # can't restore, so skip (remove from set) - for role in (member_roles - original_roles): + for role in member_roles - original_roles: if role >= highest_role: member_roles.discard(role) # can't remove, so skip (re-add to set) - for role in (original_roles - member_roles): + for role in original_roles - member_roles: if role >= highest_role: member_roles.add(role) @@ -541,7 +548,7 @@ class Punish(commands.Cog): await ctx.send(msg) - @punishset.command(name='setup') + @punishset.command(name="setup") async def punishset_setup(self, ctx): """ (Re)configures the punish role and channel overrides @@ -568,28 +575,29 @@ class Punish(commands.Cog): perms = discord.Permissions.none() role = await guild.create_role(name=default_name, permissions=perms, reason="punish cog.") else: - msgobj = await ctx.send('%s role exists... ' % role.name) + msgobj = await ctx.send("%s role exists... " % role.name) if role.position != (guild.me.top_role.position - 1): if role < guild.me.top_role: - await msgobj.edit(content=msgobj.content + 'moving role to higher position... ') + await msgobj.edit(content=msgobj.content + "moving role to higher position... ") await role.edit(position=guild.me.top_role.position - 1) else: - await msgobj.edit(content=msgobj.content + 'role is too high to manage.' - ' Please move it to below my highest role.') + await msgobj.edit( + content=msgobj.content + "role is too high to manage." " Please move it to below my highest role." + ) return - await msgobj.edit(content=msgobj.content + '(re)configuring channels... ') + await msgobj.edit(content=msgobj.content + "(re)configuring channels... ") for channel in guild.channels: await self.setup_channel(channel, role) - await msgobj.edit(content=msgobj.content + 'done.') + await msgobj.edit(content=msgobj.content + "done.") if role and role.id != role_id: await self.config.guild(guild).ROLE_ID.set(role.id) - @punishset.command(name='channel') + @punishset.command(name="channel") async def punishset_channel(self, ctx, channel: discord.TextChannel = None): """ Sets or shows the punishment "timeout" channel. @@ -613,13 +621,16 @@ class Punish(commands.Cog): await ctx.send("The timeout channel is currently %s." % current.mention) else: if current == channel: - await ctx.send("The timeout channel is already %s. If you need to repair its permissions, use `%spunishset setup`." % (current.mention, ctx.prefix)) + await ctx.send( + "The timeout channel is already %s. If you need to repair its permissions, use `%spunishset setup`." + % (current.mention, ctx.prefix) + ) return await self.config.guild(guild).CHANNEL_ID.set(channel.id) role = await self.get_role(guild, create=True) - update_msg = '{} to the %s role' % role + update_msg = "{} to the %s role" % role grants = [] denies = [] perms = permissions_for_roles(channel, role) @@ -631,7 +642,7 @@ class Punish(commands.Cog): if getattr(perms, perm) != value: setattr(overwrite, perm, value) - name = perm.replace('_', ' ').title().replace("Tts", "TTS") + name = perm.replace("_", " ").title().replace("Tts", "TTS") if value: grants.append(name) @@ -640,8 +651,8 @@ class Punish(commands.Cog): # Any changes made? Apply them. if grants or denies: - grants = grants and ('grant ' + format_list(*grants)) - denies = denies and ('deny ' + format_list(*denies)) + grants = grants and ("grant " + format_list(*grants)) + denies = denies and ("deny " + format_list(*denies)) to_join = [x for x in (grants, denies) if x] update_msg = update_msg.format(format_list(*to_join)) @@ -655,14 +666,14 @@ class Punish(commands.Cog): await self.setup_channel(current, role) if channel.permissions_for(guild.me).manage_roles: - await ctx.send(info('Updating permissions in %s to %s...' % (channel.mention, update_msg))) + await ctx.send(info("Updating permissions in %s to %s..." % (channel.mention, update_msg))) await channel.set_permissions(role, overwrite=overwrite) else: await ctx.send(error("I don't have permissions to %s." % update_msg)) await ctx.send("Timeout channel set to %s." % channel.mention) - @punishset.command(name='clear-channel') + @punishset.command(name="clear-channel") async def punishset_clear_channel(self, ctx): """ Clears the timeout channel and resets its permissions @@ -678,7 +689,7 @@ class Punish(commands.Cog): if current.permissions_for(guild.me).manage_roles: role = await self.get_role(guild, quiet=True) await self.setup_channel(current, role) - msg = ' and its permissions reset' + msg = " and its permissions reset" else: msg = ", but I don't have permissions to reset its permissions." @@ -686,7 +697,7 @@ class Punish(commands.Cog): else: await ctx.send("No timeout channel has been set yet.") - @punishset.command(name='case-min') + @punishset.command(name="case-min") async def punishset_case_min(self, ctx, *, timespec: str = None): """ Set/disable or display the minimum punishment case duration @@ -699,11 +710,11 @@ class Punish(commands.Cog): if not timespec: if current: - await ctx.send('Punishments longer than %s will create cases.' % generate_timespec(current)) + await ctx.send("Punishments longer than %s will create cases." % generate_timespec(current)) else: await ctx.send("Punishment case creation is disabled.") else: - if timespec.strip('\'"').lower() == 'disable': + if timespec.strip("'\"").lower() == "disable": value = None else: try: @@ -714,9 +725,9 @@ class Punish(commands.Cog): await self.config.guild(guild).CASE_MIN_LENGTH.set(value) - await ctx.send('Punishments longer than %s will create cases.' % generate_timespec(value)) + await ctx.send("Punishments longer than %s will create cases." % generate_timespec(value)) - @punishset.command(name='overrides') + @punishset.command(name="overrides") async def punishset_overrides(self, ctx, *, channel_id: int = None): """ Copy or display the punish role overrides @@ -751,52 +762,58 @@ class Punish(commands.Cog): confirm_msg = "Are you sure you want to copy overrides from this channel?" if channel.type is discord.ChannelType.text: - key = 'text' + key = "text" elif channel.type is discord.ChannelType.voice: - key = 'voice' + key = "voice" else: await ctx.send(error("Unknown channel type!")) return if confirm_msg: - await ctx.send(warning(confirm_msg + '(reply `yes` within 30s to confirm)')) + await ctx.send(warning(confirm_msg + "(reply `yes` within 30s to confirm)")) + def check(m): return m.author == ctx.author and m.channel == ctx.channel + try: - reply = await self.bot.wait_for('message', check=check, timeout=30.0) - if reply.content.strip(' `"\'').lower() != 'yes': - await ctx.send('Commmand cancelled.') + reply = await self.bot.wait_for("message", check=check, timeout=30.0) + if reply.content.strip(" `\"'").lower() != "yes": + await ctx.send("Commmand cancelled.") return except asyncio.TimeoutError: - await ctx.send('Timed out waiting for a response.') + await ctx.send("Timed out waiting for a response.") return - if key == 'text': + if key == "text": await self.config.guild(guild).TEXT_OVERWRITE.set(overwrite_to_dict(overwrite)) else: await self.config.guild(guild).VOICE_OVERWRITE.set(overwrite_to_dict(overwrite)) - await ctx.send("{} channel overrides set to:\n".format(key.title()) + - format_permissions(overwrite) + - "\n\nRun `%spunishset setup` to apply them to all channels." % ctx.prefix) + await ctx.send( + "{} channel overrides set to:\n".format(key.title()) + + format_permissions(overwrite) + + "\n\nRun `%spunishset setup` to apply them to all channels." % ctx.prefix + ) else: msg = [] - for key in ('text', 'voice'): - if key == 'text': + for key in ("text", "voice"): + if key == "text": data = await self.config.guild(guild).TEXT_OVERWRITE() else: data = await self.config.guild(guild).VOICE_OVERWRITE() - title = '%s permission overrides:' % key.title() + title = "%s permission overrides:" % key.title() - if data == overwrite_to_dict(DEFAULT_TEXT_OVERWRITE) or data == overwrite_to_dict(DEFAULT_VOICE_OVERWRITE): - title = title[:-1] + ' (defaults):' + if data == overwrite_to_dict(DEFAULT_TEXT_OVERWRITE) or data == overwrite_to_dict( + DEFAULT_VOICE_OVERWRITE + ): + title = title[:-1] + " (defaults):" - msg.append(bold(title) + '\n' + format_permissions(overwrite_from_dict(data))) + msg.append(bold(title) + "\n" + format_permissions(overwrite_from_dict(data))) - await ctx.send('\n\n'.join(msg)) + await ctx.send("\n\n".join(msg)) - @punishset.command(name='reset-overrides') - async def punishset_reset_overrides(self, ctx, channel_type: str = 'both'): + @punishset.command(name="reset-overrides") + async def punishset_reset_overrides(self, ctx, channel_type: str = "both"): """ Resets the punish role overrides for text, voice or both (default) @@ -804,21 +821,21 @@ class Punish(commands.Cog): for newly created channels. """ - channel_type = channel_type.strip('`"\' ').lower() + channel_type = channel_type.strip("`\"' ").lower() msg = [] - for key in ('text', 'voice'): - if channel_type not in ['both', key]: + for key in ("text", "voice"): + if channel_type not in ["both", key]: continue - title = '%s permission overrides reset to:' % key.title() + title = "%s permission overrides reset to:" % key.title() - if key == 'text': + if key == "text": await self.config.guild(guild).TEXT_OVERWRITE.set(overwrite_to_dict(DEFAULT_TEXT_OVERWRITE)) - msg.append(bold(title) + '\n' + format_permissions(overwrite_to_dict(DEFAULT_TEXT_OVERWRITE))) + msg.append(bold(title) + "\n" + format_permissions(overwrite_to_dict(DEFAULT_TEXT_OVERWRITE))) else: await self.config.guild(guild).VOICE_OVERWRITE.set(overwrite_to_dict(DEFAULT_VOICE_OVERWRITE)) - msg.append(bold(title) + '\n' + format_permissions(overwrite_to_dict(DEFAULT_VOICE_OVERWRITE))) + msg.append(bold(title) + "\n" + format_permissions(overwrite_to_dict(DEFAULT_VOICE_OVERWRITE))) if not msg: await ctx.send("Invalid channel type. Use `text`, `voice`, or `both` (the default, if not specified)") @@ -826,7 +843,7 @@ class Punish(commands.Cog): msg.append("Run `%spunishset setup` to apply them to all channels." % ctx.prefix) - await ctx.send('\n\n'.join(msg)) + await ctx.send("\n\n".join(msg)) async def get_role(self, guild, quiet=False, create=False): role_id = await self.config.guild(guild).ROLE_ID() @@ -848,19 +865,19 @@ class Punish(commands.Cog): if not quiet: msgobj = await ctx.send(msg) - log.debug('Creating punish role in %s' % guild.name) + log.debug("Creating punish role in %s" % guild.name) perms = discord.Permissions.none() role = await guild.create_role(name=DEFAULT_ROLE_NAME, permissions=perms, reason="punish cog.") await role.edit(position=guild.me.top_role.position - 1) if not quiet: - await msgobj.edit(content=msgobj.content + '\nconfiguring channels... ') + await msgobj.edit(content=msgobj.content + "\nconfiguring channels... ") for channel in guild.channels: await self.setup_channel(channel, role) if not quiet: - await msgobj.edit(content=msgobj.content + '\ndone.') + await msgobj.edit(content=msgobj.content + "\ndone.") if role and role.id != role_id: await self.config.guild(guild).ROLE_ID.set(role.id) @@ -906,23 +923,23 @@ class Punish(commands.Cog): for member_id, data in punished.items(): - until = data['until'] + until = data["until"] member = guild.get_member(member_id) if until and (until - time.time()) < 0: if member: - reason = 'Punishment removal overdue, maybe the bot was offline. ' + reason = "Punishment removal overdue, maybe the bot was offline. " - if data['reason']: - reason += data['reason'] + if data["reason"]: + reason += data["reason"] await self._unpunish(member, reason=reason) else: # member disappeared - del(punished[str(member_id)]) + del punished[str(member_id)] elif member: # re-check roles user_roles = set(member.roles) - removed_roles = set(role_memo.filter(data.get('removed_roles', ()), skip_nulls=True)) + removed_roles = set(role_memo.filter(data.get("removed_roles", ()), skip_nulls=True)) removed_roles = user_roles & {r for r in removed_roles if r < me.top_role} user_roles -= removed_roles @@ -954,7 +971,7 @@ class Punish(commands.Cog): except Exception: pass - log.debug('queue manager dying') + log.debug("queue manager dying") while not self.queue.empty(): self.queue.get_nowait() @@ -985,7 +1002,7 @@ class Punish(commands.Cog): return removed is not None - async def put_queue_event(self, run_at : float, *args): + async def put_queue_event(self, run_at: float, *args): diff = run_at - time.time() if args in self.enqueued: @@ -1038,7 +1055,7 @@ class Punish(commands.Cog): remove_role_set = set(resolve_role_list(guild, remove_role_set)) punished = await self.config.guild(guild).PUNISHED() current = punished.get(str(member.id), {}) - reason = reason or current.get('reason') # don't clear if not given + reason = reason or current.get("reason") # don't clear if not given hierarchy_allowed = ctx.author.top_role > member.top_role case_min_length = await self.config.guild(guild).CASE_MIN_LENGTH() nitro_role = await self.config.guild(guild).NITRO_ID() @@ -1051,7 +1068,7 @@ class Punish(commands.Cog): await ctx.send("You can't punish the bot.") return - if duration and duration.lower() in ['forever', 'inf', 'infinite']: + if duration and duration.lower() in ["forever", "inf", "infinite"]: duration = None else: if not duration: @@ -1071,7 +1088,7 @@ class Punish(commands.Cog): if role is None: return elif role >= guild.me.top_role: - await ctx.send('The %s role is too high for me to manage.' % role) + await ctx.send("The %s role is too high for me to manage." % role) return # Call time() after getting the role due to potential creation delay @@ -1085,22 +1102,26 @@ class Punish(commands.Cog): try: if current: - case_number = current.get('caseno') + case_number = current.get("caseno") try: case = await modlog.get_case(case_number, guild, self.bot) - except: # shouldn't happen - await ctx.send(warning("Error, modlog case not found, but user is punished with case.\nTry unpunishing and punishing again.")) + except: # shouldn't happen + await ctx.send( + warning( + "Error, modlog case not found, but user is punished with case.\nTry unpunishing and punishing again." + ) + ) return moderator = ctx.author try: - edits = {'reason': reason} + edits = {"reason": reason} - if moderator.id != current.get('by'): - edits['amended_by'] = moderator + if moderator.id != current.get("by"): + edits["amended_by"] = moderator - edits['modified_at'] = ctx.message.created_at.timestamp() + edits["modified_at"] = ctx.message.created_at.timestamp() await case.edit(edits) except Exception as e: @@ -1110,7 +1131,16 @@ class Punish(commands.Cog): updating_case = True else: - case = await modlog.create_case(self.bot, guild, now_date, "Timed Mute", member, moderator=ctx.author, reason=reason, until=mod_until) + case = await modlog.create_case( + self.bot, + guild, + now_date, + "Timed Mute", + member, + moderator=ctx.author, + reason=reason, + until=mod_until, + ) case_number = case.case_number except Exception as e: @@ -1118,18 +1148,18 @@ class Punish(commands.Cog): else: case_number = None - subject = 'the %s role' % role.name + subject = "the %s role" % role.name if str(member.id) in punished: if role in member.roles: - msg = '{0} already had the {1.name} role; resetting their timer.' + msg = "{0} already had the {1.name} role; resetting their timer." else: - msg = '{0} is missing the {1.name} role for some reason. I added it and reset their timer.' + msg = "{0} is missing the {1.name} role for some reason. I added it and reset their timer." elif role in member.roles: - msg = '{0} already had the {1.name} role, but had no timer; setting it now.' + msg = "{0} already had the {1.name} role, but had no timer; setting it now." else: - msg = 'Applied the {1.name} role to {0}.' - subject = 'it' + msg = "Applied the {1.name} role to {0}." + subject = "it" msg = msg.format(member, role) @@ -1137,24 +1167,24 @@ class Punish(commands.Cog): timespec = generate_timespec(duration) if using_default: - timespec += ' (the default)' + timespec += " (the default)" - msg += ' I will remove %s in %s.' % (subject, timespec) + msg += " I will remove %s in %s." % (subject, timespec) if case_error: if isinstance(case_error, CaseMessageNotFound): - case_error = 'the case message could not be found' + case_error = "the case message could not be found" elif isinstance(case_error, NoModLogAccess): - case_error = 'I do not have access to the modlog channel' + case_error = "I do not have access to the modlog channel" else: case_error = None if case_error: - verb = 'updating' if updating_case else 'creating' - msg += '\n\n' + warning('There was an error %s the modlog case: %s.' % (verb, case_error)) + verb = "updating" if updating_case else "creating" + msg += "\n\n" + warning("There was an error %s the modlog case: %s." % (verb, case_error)) elif case_number: - verb = 'updated' if updating_case else 'created' - msg += ' I also %s case #%i in the modlog.' % (verb, case_number) + verb = "updated" if updating_case else "created" + msg += " I also %s case #%i in the modlog." % (verb, case_number) voice_overwrite = await self.config.guild(guild).VOICE_OVERWRITE() @@ -1175,12 +1205,12 @@ class Punish(commands.Cog): # build lists of roles that *should* be removed and ones that *can* be removed_roles = user_roles & remove_role_set too_high_to_remove = {r for r in removed_roles if r >= guild.me.top_role} - user_roles -= (removed_roles - too_high_to_remove) + user_roles -= removed_roles - too_high_to_remove user_roles.add(role) # add punish role to the set await member.edit(roles=user_roles, reason=f"punish {member}") else: - removed_roles = set(resolve_role_list(guild, current.get('removed_roles', []))) + removed_roles = set(resolve_role_list(guild, current.get("removed_roles", []))) too_high_to_remove = {r for r in removed_roles if r >= guild.me.top_role} if removed_roles: @@ -1190,8 +1220,10 @@ class Punish(commands.Cog): if too_high_to_remove: fmt_list = format_list(*(r.name for r in removed_roles)) - msg += "\n" + warning("These roles were too high to remove (fix hierarchy, then run " - "`{}punishset sync-roles`): {}".format(ctx.prefix, fmt_list)) + msg += "\n" + warning( + "These roles were too high to remove (fix hierarchy, then run " + "`{}punishset sync-roles`): {}".format(ctx.prefix, fmt_list) + ) if member.voice: muted = member.voice.mute else: @@ -1199,13 +1231,13 @@ class Punish(commands.Cog): async with self.config.guild(guild).PUNISHED() as punished: punished[str(member.id)] = { - 'start' : current.get('start') or now, # don't override start time if updating - 'until' : until, - 'by' : current.get('by') or ctx.author.id, # don't override original moderator - 'reason' : reason, - 'unmute' : overwrite_denies_speak and not muted, - 'caseno' : case_number, - 'removed_roles' : [r.id for r in removed_roles] + "start": current.get("start") or now, # don't override start time if updating + "until": until, + "by": current.get("by") or ctx.author.id, # don't override original moderator + "reason": reason, + "unmute": overwrite_denies_speak and not muted, + "caseno": case_number, + "removed_roles": [r.id for r in removed_roles], } if member.voice and overwrite_denies_speak: @@ -1256,8 +1288,8 @@ class Punish(commands.Cog): if role: data = await self.config.guild(guild).PUNISHED() member_data = data.get(str(member.id), {}) - caseno = member_data.get('caseno') - removed_roles = set(resolve_role_list(guild, member_data.get('removed_roles', []))) + caseno = member_data.get("caseno") + removed_roles = set(resolve_role_list(guild, member_data.get("removed_roles", []))) # Has to be done first to prevent triggering listeners await self._unpunish_data(member) @@ -1280,20 +1312,20 @@ class Punish(commands.Cog): await member.edit(roles=user_roles, reason="punish end") if update and caseno: - until = member_data.get('until') or False + until = member_data.get("until") or False # fallback gracefully - moderator = moderator or guild.get_member(member_data.get('by')) or guild.me + moderator = moderator or guild.get_member(member_data.get("by")) or guild.me if until: until = datetime.utcfromtimestamp(until).timestamp() - edits = {'reason': reason} + edits = {"reason": reason} - if moderator.id != data.get('by'): - edits['amended_by'] = moderator + if moderator.id != data.get("by"): + edits["amended_by"] = moderator - edits['modified_at'] = time.time() - edits['until'] = until + edits["modified_at"] = time.time() + edits["until"] = until try: case = await modlog.get_case(caseno, guild, self.bot) @@ -1301,7 +1333,7 @@ class Punish(commands.Cog): except Exception: pass - if member_data.get('unmute', False): + if member_data.get("unmute", False): if member.voice: if member.voice.channel: await member.edit(mute=False) @@ -1313,7 +1345,7 @@ class Punish(commands.Cog): if quiet: return True - msg = 'Your punishment in %s has ended.' % member.guild.name + msg = "Your punishment in %s has ended." % member.guild.name if reason: msg += "\nReason: %s" % reason @@ -1323,8 +1355,9 @@ class Punish(commands.Cog): if too_high_to_restore: fmt_list = format_list(*(r.name for r in too_high_to_restore)) - msg += "\n" + warning("These roles were too high for me to restore: {}. " - "Ask a mod for help.".format(fmt_list)) + msg += "\n" + warning( + "These roles were too high for me to restore: {}. " "Ask a mod for help.".format(fmt_list) + ) try: await member.send(msg) @@ -1338,7 +1371,7 @@ class Punish(commands.Cog): async with self.config.guild(guild).PUNISHED() as punished: if str(member.id) in punished: - del(punished[str(member.id)]) + del punished[str(member.id)] # Listeners @commands.Cog.listener() @@ -1365,14 +1398,14 @@ class Punish(commands.Cog): new_roles = {role.id: role for role in after.roles} if role in before.roles and role.id not in new_roles: - msg = 'Punishment manually ended early by a moderator/admin.' + msg = "Punishment manually ended early by a moderator/admin." - if member_data['reason']: - msg += '\nReason was: ' + member_data['reason'] + if member_data["reason"]: + msg += "\nReason was: " + member_data["reason"] await self._unpunish(after, reason=msg, update=True) else: - to_remove = {new_roles.get(role_id) for role_id in member_data.get('removed_roles', [])} + to_remove = {new_roles.get(role_id) for role_id in member_data.get("removed_roles", [])} to_remove = [r for r in to_remove if r and r < after.guild.me.top_role] if to_remove: @@ -1393,7 +1426,7 @@ class Punish(commands.Cog): member = self.bot.get_guild(guild.id).get_member(member.id) role = await self.get_role(member.guild, quiet=True) - until = data['until'] + until = data["until"] duration = until - time.time() if role and duration > 0: @@ -1433,7 +1466,7 @@ class Punish(commands.Cog): msg = "Punishment ended early due to ban." - if member_data.get('reason'): - msg += '\n\nOriginal reason was: ' + member_data['reason'] + if member_data.get("reason"): + msg += "\n\nOriginal reason was: " + member_data["reason"] await self._unpunish(member, reason=msg, apply_roles=False, update=True, quiet=True) diff --git a/punish/utils.py b/punish/utils.py index 2bd5296..0a77ab1 100644 --- a/punish/utils.py +++ b/punish/utils.py @@ -2,13 +2,14 @@ import re import discord UNIT_TABLE = ( - (('weeks', 'wks', 'w'), 60 * 60 * 24 * 7), - (('days', 'dys', 'd'), 60 * 60 * 24), - (('hours', 'hrs', 'h'), 60 * 60), - (('minutes', 'mins', 'm'), 60), - (('seconds', 'secs', 's'), 1), + (("weeks", "wks", "w"), 60 * 60 * 24 * 7), + (("days", "dys", "d"), 60 * 60 * 24), + (("hours", "hrs", "h"), 60 * 60), + (("minutes", "mins", "m"), 60), + (("seconds", "secs", "s"), 1), ) + class BadTimeExpr(Exception): pass @@ -23,24 +24,23 @@ def _find_unit(unit): def parse_time(time): time = time.lower() if not time.isdigit(): - time = re.split(r'\s*([\d.]+\s*[^\d\s,;]*)(?:[,;\s]|and)*', time) + time = re.split(r"\s*([\d.]+\s*[^\d\s,;]*)(?:[,;\s]|and)*", time) time = sum(map(_timespec_sec, filter(None, time))) return int(time) def _timespec_sec(expr): - atoms = re.split(r'([\d.]+)\s*([^\d\s]*)', expr) + atoms = re.split(r"([\d.]+)\s*([^\d\s]*)", expr) atoms = list(filter(None, atoms)) if len(atoms) > 2: # This shouldn't ever happen raise BadTimeExpr("invalid expression: '%s'" % expr) elif len(atoms) == 2: names, length = _find_unit(atoms[1]) - if atoms[0].count('.') > 1 or \ - not atoms[0].replace('.', '').isdigit(): + if atoms[0].count(".") > 1 or not atoms[0].replace(".", "").isdigit(): raise BadTimeExpr("Not a number: '%s'" % atoms[0]) else: - names, length = _find_unit('seconds') + names, length = _find_unit("seconds") try: return float(atoms[0]) * length @@ -59,48 +59,46 @@ def generate_timespec(sec: int, short=False, micro=False) -> str: if n: if micro: - s = '%d%s' % (n, names[2]) + s = "%d%s" % (n, names[2]) elif short: - s = '%d%s' % (n, names[1]) + s = "%d%s" % (n, names[1]) else: - s = '%d %s' % (n, names[0]) + s = "%d %s" % (n, names[0]) - if n <= 1 and not (micro and names[2] == 's'): - s = s.rstrip('s') + if n <= 1 and not (micro and names[2] == "s"): + s = s.rstrip("s") timespec.append(s) if len(timespec) > 1: if micro: - spec = ''.join(timespec) + spec = "".join(timespec) segments = timespec[:-1], timespec[-1:] - spec = ' and '.join(', '.join(x) for x in segments) + spec = " and ".join(", ".join(x) for x in segments) elif timespec: spec = timespec[0] else: - return '0' + return "0" if neg: - spec += ' ago' + spec += " ago" return spec -def format_list(*items, join='and', delim=', '): +def format_list(*items, join="and", delim=", "): if len(items) > 1: - return (' %s ' % join).join((delim.join(items[:-1]), items[-1])) + return (" %s " % join).join((delim.join(items[:-1]), items[-1])) elif items: return items[0] else: - return '' + return "" + def overwrite_to_dict(overwrite): allow, deny = overwrite.pair() - return { - 'allow' : allow.value, - 'deny' : deny.value - } + return {"allow": allow.value, "deny": deny.value} def format_permissions(permissions, include_null=False): @@ -116,10 +114,10 @@ def format_permissions(permissions, include_null=False): else: continue - entries.append(symbol + ' ' + perm.replace('_', ' ').title().replace("Tts", "TTS")) + entries.append(symbol + " " + perm.replace("_", " ").title().replace("Tts", "TTS")) if entries: - return '\n'.join(entries) + return "\n".join(entries) else: return "No permission entries." @@ -130,7 +128,7 @@ def getmname(mid, guild): if member: return str(member) else: - return '(absent user #%s)' % mid + return "(absent user #%s)" % mid def role_from_string(guild, rolename, roles=None): @@ -186,7 +184,7 @@ def permissions_for_roles(channel, *roles): if overwrite.id == default.id: base.handle_overwrite(allow=overwrite.allow, deny=overwrite.deny) - if overwrite.type == 'role' and overwrite.id in role_ids: + if overwrite.type == "role" and overwrite.id in role_ids: denies |= overwrite.deny allows |= overwrite.allow @@ -218,6 +216,6 @@ def permissions_for_roles(channel, *roles): def overwrite_from_dict(data): - allow = discord.Permissions(data.get('allow', 0)) - deny = discord.Permissions(data.get('deny', 0)) + allow = discord.Permissions(data.get("allow", 0)) + deny = discord.Permissions(data.get("deny", 0)) return discord.PermissionOverwrite.from_pair(allow, deny) diff --git a/roleplay/roleplay.py b/roleplay/roleplay.py index 1046057..98f42fa 100644 --- a/roleplay/roleplay.py +++ b/roleplay/roleplay.py @@ -14,6 +14,7 @@ import asyncio import os import json + class RolePlay(commands.Cog): def __init__(self): super().__init__() @@ -31,7 +32,8 @@ class RolePlay(commands.Cog): "lotsa spaghetti", "a brick", "a slice of cheese", - "my foot"], + "my foot", + ], "high_iq_msgs": [ "wow!", "that's pretty big.", @@ -40,7 +42,8 @@ class RolePlay(commands.Cog): "someone here is actually smart.", "thats a dab.", "<:aureliawink:549481308519399425>", - "you must of watched Rick and Morty."], + "you must of watched Rick and Morty.", + ], "low_iq_msgs": [ ":rofl:", "oof.", @@ -49,7 +52,8 @@ class RolePlay(commands.Cog): "awww you're special aren't you.", ":crying_cat_face:", "god I'm sorry (not).", - "I didn't know people could have IQ that low."] + "I didn't know people could have IQ that low.", + ], } self.config.register_guild(**self.default_guild) @@ -104,12 +108,11 @@ class RolePlay(commands.Cog): elif user.id == botid: user = ctx.message.author botname = ctx.bot.user.name - await ctx.send("`-" + botname + " slaps " + user.display_name + - " multiple times with " + - (choice(slap_items) + "-`")) + await ctx.send( + "`-" + botname + " slaps " + user.display_name + " multiple times with " + (choice(slap_items) + "-`") + ) else: - await ctx.send("`-slaps " + user.display_name + " with " + - (choice(slap_items) + "-`")) + await ctx.send("`-slaps " + user.display_name + " with " + (choice(slap_items) + "-`")) @slap.command(name="add") @checks.admin() @@ -126,7 +129,7 @@ class RolePlay(commands.Cog): @slap.command(name="remove") @checks.admin() - async def _remove_slap(self, ctx, slap_item: str=""): + async def _remove_slap(self, ctx, slap_item: str = ""): """Removes item to use for slaps!""" guild = ctx.guild slap_items = await self.config.guild(guild).slap_items() @@ -146,7 +149,7 @@ class RolePlay(commands.Cog): msg = "" for item in slap_items: msg += "+ {}\n".format(item) - pages = pagify(msg) # pages is an iterator of pages + pages = pagify(msg) # pages is an iterator of pages for page in pages: await ctx.send(box(page, lang="diff")) @@ -173,9 +176,8 @@ class RolePlay(commands.Cog): except json.decoder.JSONDecodeError: await ctx.send("Invalid or malformed json file.") - @commands.group(invoke_without_command=True) - async def iq(self, ctx, *users : discord.Member): + async def iq(self, ctx, *users: discord.Member): """ Gets IQ of a user. Use multiple users to compare IQs """ @@ -199,7 +201,9 @@ class RolePlay(commands.Cog): iqs = sorted(iqs.items(), key=lambda x: x[1]) for user, iq in iqs: - msg += "{}'s iq is {}, {}\n".format(user.display_name, iq, choice(high_iq_msgs) if int(iq) > 130 else choice(low_iq_messages)) + msg += "{}'s iq is {}, {}\n".format( + user.display_name, iq, choice(high_iq_msgs) if int(iq) > 130 else choice(low_iq_messages) + ) await ctx.send(msg) @@ -215,11 +219,11 @@ class RolePlay(commands.Cog): for high_phrase in high_iq_msgs: msg1 += "+ {}\n".format(high_phrase) - high_pages = pagify(msg1) # pages is an iterator of pages + high_pages = pagify(msg1) # pages is an iterator of pages for low_phrase in low_iq_msgs: msg2 += "+ {}\n".format(low_phrase) - low_pages = pagify(msg2) # pages is an iterator of pages + low_pages = pagify(msg2) # pages is an iterator of pages for high_page in high_pages: await ctx.send(box(high_page, lang="diff")) @@ -255,7 +259,7 @@ class RolePlay(commands.Cog): @iq.command(name="removehigh") @checks.admin() - async def _removehigh_iq(self, ctx, high_phrase: str=""): + async def _removehigh_iq(self, ctx, high_phrase: str = ""): """Removes phrases for high IQ's!""" guild = ctx.guild high_iq_msgs = await self.config.guild(guild).high_iq_msgs() @@ -274,7 +278,7 @@ class RolePlay(commands.Cog): @iq.command(name="removelow") @checks.admin() - async def _removelow_iq(self, ctx, low_phrase: str=""): + async def _removelow_iq(self, ctx, low_phrase: str = ""): """Removes phrases for low IQ's!""" guild = ctx.guild low_iq_msgs = await self.config.guild(guild).low_iq_msgs() @@ -306,7 +310,7 @@ class RolePlay(commands.Cog): largest_factor = 1 else: largest_factor = [x for x in range(1, horses) if horses % x == 0][-1] - #largest_factor = [x for x in largest_factor if x <= 15][-1] + # largest_factor = [x for x in largest_factor if x <= 15][-1] if largest_factor == 1: largest_factor = horses rows = 1 @@ -367,7 +371,7 @@ class RolePlay(commands.Cog): if user.id == ctx.bot.user.id: await ctx.send(":newspaper2: :newspaper2: :newspaper2: " + italics(ctx.message.author.display_name)) else: - await ctx.send(":newspaper2: " + italics(user.display_name) ) + await ctx.send(":newspaper2: " + italics(user.display_name)) @commands.command() async def flip(self, ctx, *, user: discord.Member = None):