Merge remote-tracking branch 'refs/remotes/origin/v3' into v3

This commit is contained in:
Brandon Silva 2022-01-16 18:28:58 -05:00
commit 42c0bc5a08
5 changed files with 183 additions and 107 deletions

View file

@ -69,7 +69,14 @@ class ActivityLogger(commands.Cog):
self.bot = bot self.bot = bot
self.config = Config.get_conf(self, identifier=9584736583, force_registration=True) self.config = Config.get_conf(self, identifier=9584736583, force_registration=True)
default_global = { default_global = {
"attrs": {"attachments": False, "default": False, "direct": False, "everything": False, "rotation": "m"} "attrs": {
"attachments": False,
"default": False,
"direct": False,
"everything": False,
"rotation": "m",
"check_audit": True,
}
} }
self.default_guild = {"all_s": False, "voice": False, "events": False, "prefixes": []} self.default_guild = {"all_s": False, "voice": False, "events": False, "prefixes": []}
self.default_channel = {"enabled": False} self.default_channel = {"enabled": False}
@ -598,6 +605,10 @@ class ActivityLogger(commands.Cog):
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)
] ]
if not message_chunks:
await ctx.send(error("No logs found for the specified location and time period!"))
return
for msgs in message_chunks: for msgs in message_chunks:
temp_file = os.path.join(log_path, datetime.utcnow().strftime("%Y%m%d%X").replace(":", "") + ".txt") 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:
@ -1003,6 +1014,25 @@ class ActivityLogger(commands.Cog):
""" """
pass pass
@logset.command(name="check-audit")
async def set_audit_check(self, ctx, on_off: bool = None):
"""
Set whether to access audit logs to get who does what audit action
Turning this off means audit actions are saved but who did those actions are not saved.
This should be turned off for bots in large amount of servers since you will hit global ratelimits very quickly.
"""
if on_off is not None:
async with self.config.attrs() as attrs:
attrs["check_audit"] = on_off
self.cache["check_audit"] = on_off
status = self.cache["check_audit"]
if status:
await ctx.send("Checking audit logs is enabled.")
else:
await ctx.send("Checking audit logs is disabled.")
@logset.command(name="everything", aliases=["global"]) @logset.command(name="everything", aliases=["global"])
async def set_everything(self, ctx, on_off: bool = None): async def set_everything(self, ctx, on_off: bool = None):
""" """
@ -1471,22 +1501,25 @@ class ActivityLogger(commands.Cog):
async def on_message_delete(self, message): async def on_message_delete(self, message):
if await self.bot.cog_disabled_in_guild(self, message.guild): if await self.bot.cog_disabled_in_guild(self, message.guild):
return return
if not self.should_log(message.channel):
return
entry_s = None entry_s = None
timestamp = message.created_at.strftime(TIMESTAMP_FORMAT) timestamp = message.created_at.strftime(TIMESTAMP_FORMAT)
try: if self.cache["check_audit"]:
async for entry in message.guild.audit_logs(limit=2): try:
# target is user who had message deleted async for entry in message.guild.audit_logs(limit=2):
if entry.action is discord.AuditLogAction.message_delete: # target is user who had message deleted
if ( if entry.action is discord.AuditLogAction.message_delete:
entry.target.id == message.author.id if (
and entry.extra.channel.id == message.channel.id entry.target.id == message.author.id
and entry.created_at.timestamp() > time.time() - 3000 and entry.extra.channel.id == message.channel.id
and entry.extra.count >= 1 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 entry_s = DELETE_AUDIT_TEMPLATE.format(entry.user, message, message.author, timestamp)
except: break
pass except:
pass
if not entry_s: if not entry_s:
entry_s = DELETE_TEMPLATE.format(message, timestamp) entry_s = DELETE_TEMPLATE.format(message, timestamp)
@ -1511,14 +1544,18 @@ class ActivityLogger(commands.Cog):
async def on_guild_update(self, before, after): async def on_guild_update(self, before, after):
if await self.bot.cog_disabled_in_guild(self, after): if await self.bot.cog_disabled_in_guild(self, after):
return return
if not self.should_log(before):
return
entries = [] entries = []
user = None user = None
try: if self.cache["check_audit"]:
async for entry in after.audit_logs(limit=1): try:
if entry.action is discord.AuditLogAction.guild_update: async for entry in after.audit_logs(limit=1):
user = entry.user if entry.action is discord.AuditLogAction.guild_update:
except: user = entry.user
pass except:
pass
if before.owner != after.owner: if before.owner != after.owner:
if user: if user:
@ -1570,14 +1607,18 @@ class ActivityLogger(commands.Cog):
async def on_guild_role_create(self, role): async def on_guild_role_create(self, role):
if await self.bot.cog_disabled_in_guild(self, role.guild): if await self.bot.cog_disabled_in_guild(self, role.guild):
return return
if not self.should_log(role.guild):
return
user = None user = None
try: if self.cache["check_audit"]:
async for entry in role.guild.audit_logs(limit=2): try:
if entry.action is discord.AuditLogAction.role_create: async for entry in role.guild.audit_logs(limit=2):
if entry.target.id == role.id: if entry.action is discord.AuditLogAction.role_create:
user = entry.user if entry.target.id == role.id:
except: user = entry.user
pass except:
pass
if user: if user:
entry = "Role created by @{1.name}#{1.discriminator}(id:{1.id}): '{0}' (id {0.id})".format(role, user) entry = "Role created by @{1.name}#{1.discriminator}(id:{1.id}): '{0}' (id {0.id})".format(role, user)
@ -1590,14 +1631,18 @@ class ActivityLogger(commands.Cog):
async def on_guild_role_delete(self, role): async def on_guild_role_delete(self, role):
if await self.bot.cog_disabled_in_guild(self, role.guild): if await self.bot.cog_disabled_in_guild(self, role.guild):
return return
if not self.should_log(role.guild):
return
user = None user = None
try: if self.cache["check_audit"]:
async for entry in role.guild.audit_logs(limit=2): try:
if entry.action is discord.AuditLogAction.role_delete: async for entry in role.guild.audit_logs(limit=2):
if entry.target.id == role.id: if entry.action is discord.AuditLogAction.role_delete:
user = entry.user if entry.target.id == role.id:
except: user = entry.user
pass except:
pass
if user: if user:
entry = "Role deleted by @{1.name}#{1.discriminator}(id:{1.id}): '{0}' (id {0.id})".format(role, user) entry = "Role deleted by @{1.name}#{1.discriminator}(id:{1.id}): '{0}' (id {0.id})".format(role, user)
@ -1610,15 +1655,19 @@ class ActivityLogger(commands.Cog):
async def on_guild_role_update(self, before, after): async def on_guild_role_update(self, before, after):
if await self.bot.cog_disabled_in_guild(self, after.guild): if await self.bot.cog_disabled_in_guild(self, after.guild):
return return
if not self.should_log(before.guild):
return
entries = [] entries = []
user = None user = None
try: if self.cache["check_audit"]:
async for entry in after.guild.audit_logs(limit=2): try:
if entry.action is discord.AuditLogAction.role_update: async for entry in after.guild.audit_logs(limit=2):
if entry.target.id == after.id: if entry.action is discord.AuditLogAction.role_update:
user = entry.user if entry.target.id == after.id:
except: user = entry.user
pass except:
pass
if before.name != after.name: if before.name != after.name:
if user: if user:
@ -1708,14 +1757,19 @@ class ActivityLogger(commands.Cog):
async def on_member_remove(self, member): async def on_member_remove(self, member):
if await self.bot.cog_disabled_in_guild(self, member.guild): if await self.bot.cog_disabled_in_guild(self, member.guild):
return return
if not self.should_log(member.guild):
await self.config.member(member).clear()
return
user = None user = None
try: if self.cache["check_audit"]:
async for entry in member.guild.audit_logs(limit=2): try:
if entry.action is discord.AuditLogAction.kick: async for entry in member.guild.audit_logs(limit=2):
if entry.target.id == member.id: if entry.action is discord.AuditLogAction.kick:
user = entry.user if entry.target.id == member.id:
except: user = entry.user
pass except:
pass
if user: 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)
@ -1733,14 +1787,18 @@ class ActivityLogger(commands.Cog):
async def on_member_ban(self, guild, member): async def on_member_ban(self, guild, member):
if await self.bot.cog_disabled_in_guild(self, guild): if await self.bot.cog_disabled_in_guild(self, guild):
return return
if not self.should_log(guild):
return
user = None user = None
try: if self.cache["check_audit"]:
async for entry in guild.audit_logs(limit=2): try:
if entry.action is discord.AuditLogAction.ban: async for entry in guild.audit_logs(limit=2):
if entry.target.id == member.id: if entry.action is discord.AuditLogAction.ban:
user = entry.user if entry.target.id == member.id:
except: user = entry.user
pass except:
pass
if user: 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)
@ -1753,14 +1811,18 @@ class ActivityLogger(commands.Cog):
async def on_member_unban(self, guild, member): async def on_member_unban(self, guild, member):
if await self.bot.cog_disabled_in_guild(self, guild): if await self.bot.cog_disabled_in_guild(self, guild):
return return
if not self.should_log(guild):
return
user = None user = None
try: if self.cache["check_audit"]:
async for entry in guild.audit_logs(limit=2): try:
if entry.action is discord.AuditLogAction.unban: async for entry in guild.audit_logs(limit=2):
if entry.target.id == member.id: if entry.action is discord.AuditLogAction.unban:
user = entry.user if entry.target.id == member.id:
except: user = entry.user
pass except:
pass
if user: 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)
@ -1773,18 +1835,22 @@ class ActivityLogger(commands.Cog):
async def on_member_update(self, before, after): async def on_member_update(self, before, after):
if await self.bot.cog_disabled_in_guild(self, after.guild): if await self.bot.cog_disabled_in_guild(self, after.guild):
return return
if not self.should_log(before.guild):
return
entries = [] entries = []
user = None user = None
try: if self.cache["check_audit"]:
async for entry in after.guild.audit_logs(limit=2): try:
if ( async for entry in after.guild.audit_logs(limit=2):
entry.action is discord.AuditLogAction.member_update if (
or entry.action is discord.AuditLogAction.member_role_update 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 if entry.target.id == after.id:
except: user = entry.user
pass except:
pass
if before.nick != after.nick: if before.nick != after.nick:
if user: if user:
@ -1850,14 +1916,18 @@ class ActivityLogger(commands.Cog):
async def on_guild_channel_create(self, channel): async def on_guild_channel_create(self, channel):
if await self.bot.cog_disabled_in_guild(self, channel.guild): if await self.bot.cog_disabled_in_guild(self, channel.guild):
return return
if not self.should_log(channel.guild):
return
user = None user = None
try: if self.cache["check_audit"]:
async for entry in channel.guild.audit_logs(limit=2): try:
if entry.action is discord.AuditLogAction.channel_create: async for entry in channel.guild.audit_logs(limit=2):
if entry.target.id == after.id: if entry.action is discord.AuditLogAction.channel_create:
user = entry.user if entry.target.id == after.id:
except: user = entry.user
pass except:
pass
if user: if user:
entry = 'Channel created by @{1.name}#{1.discriminator}(id:{1.id}): "{0.name}" (id {0.id})'.format( entry = 'Channel created by @{1.name}#{1.discriminator}(id:{1.id}): "{0.name}" (id {0.id})'.format(
@ -1872,14 +1942,18 @@ class ActivityLogger(commands.Cog):
async def on_guild_channel_delete(self, channel): async def on_guild_channel_delete(self, channel):
if await self.bot.cog_disabled_in_guild(self, channel.guild): if await self.bot.cog_disabled_in_guild(self, channel.guild):
return return
if not self.should_log(channel.guild):
return
user = None user = None
try: if self.cache["check_audit"]:
async for entry in channel.guild.audit_logs(limit=2): try:
if entry.action is discord.AuditLogAction.channel_delete: async for entry in channel.guild.audit_logs(limit=2):
if entry.target.id == after.id: if entry.action is discord.AuditLogAction.channel_delete:
user = entry.user if entry.target.id == after.id:
except: user = entry.user
pass except:
pass
if user: if user:
entry = 'Channel deleted by @{1.name}#{1.discriminator}(id:{1.id}): "{0.name}" (id {0.id})'.format( entry = 'Channel deleted by @{1.name}#{1.discriminator}(id:{1.id}): "{0.name}" (id {0.id})'.format(
@ -1894,14 +1968,18 @@ class ActivityLogger(commands.Cog):
async def on_guild_channel_update(self, before, after): async def on_guild_channel_update(self, before, after):
if await self.bot.cog_disabled_in_guild(self, after.guild): if await self.bot.cog_disabled_in_guild(self, after.guild):
return return
if not self.should_log(before.guild):
return
user = None user = None
try: if self.cache["check_audit"]:
async for entry in after.guild.audit_logs(limit=2): try:
if entry.action is discord.AuditLogAction.channel_update: async for entry in after.guild.audit_logs(limit=2):
if entry.target.id == after.id: if entry.action is discord.AuditLogAction.channel_update:
user = entry.user if entry.target.id == after.id:
except: user = entry.user
pass except:
pass
entries = [] entries = []

View file

@ -2,7 +2,7 @@ import aiohttp, discord
from redbot.core import Config, commands from redbot.core import Config, commands
from wand.image import Image from wand.image import Image
from io import BytesIO from io import BytesIO
from typing import Optional, Tuple from typing import Optional, Tuple, Literal
import asyncio, functools, urllib import asyncio, functools, urllib
MAX_SIZE = 8 * 1024 * 1024 MAX_SIZE = 8 * 1024 * 1024

View file

@ -43,13 +43,13 @@ class Pony(commands.Cog):
@commands.command() @commands.command()
@commands.guild_only() @commands.guild_only()
async def pony(self, ctx, *text): async def pony(self, ctx, *, text: str = ""):
"""Retrieves the latest result from Derpibooru""" """Retrieves the latest result from Derpibooru"""
await self.fetch_image(ctx, randomize=False, tags=text) await self.fetch_image(ctx, randomize=False, tags=text)
@commands.command() @commands.command()
@commands.guild_only() @commands.guild_only()
async def ponyr(self, ctx, *text): async def ponyr(self, ctx, *, text: str = ""):
"""Retrieves a random result from Derpibooru""" """Retrieves a random result from Derpibooru"""
await self.fetch_image(ctx, randomize=True, tags=text) await self.fetch_image(ctx, randomize=True, tags=text)
@ -60,7 +60,7 @@ class Pony(commands.Cog):
""" """
Gives a random picture of our mascot! Gives a random picture of our mascot!
""" """
await self.fetch_image(ctx, randomize=True, mascot=True, tags=["safe,", "coe"]) await self.fetch_image(ctx, randomize=True, mascot=True, tags="safe, coe OR oc:aurelia coe")
@commands.group() @commands.group()
@commands.guild_only() @commands.guild_only()
@ -254,7 +254,7 @@ class Pony(commands.Cog):
except json.decoder.JSONDecodeError: except json.decoder.JSONDecodeError:
await ctx.send("Invalid or malformed json files.") 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: str = "", mascot=False):
guild = ctx.guild guild = ctx.guild
# check cooldown # check cooldown
@ -267,6 +267,7 @@ class Pony(commands.Cog):
cooldown = await self.config.guild(guild).cooldown() cooldown = await self.config.guild(guild).cooldown()
self.cooldowns[guild.id][ctx.author.id] = time.time() + cooldown self.cooldowns[guild.id][ctx.author.id] = time.time() + cooldown
tags = [t for t in tags.split(",") if t != ""]
filters = await self.config.guild(guild).filters() filters = await self.config.guild(guild).filters()
verbose = await self.config.guild(guild).verbose() verbose = await self.config.guild(guild).verbose()
display_artist = await self.config.guild(guild).display_artist() display_artist = await self.config.guild(guild).display_artist()
@ -288,15 +289,12 @@ class Pony(commands.Cog):
# Assign tags to URL # Assign tags to URL
if tags: if tags:
tagSearch += "{} ".format(" ".join(tags)).strip().strip(",") # parentheses resolves user's search before filters so that OR operator doesnt break search
if filters and not mascot: tagSearch += "({})".format(", ".join(tags)).strip().strip(",")
if not mascot:
if filters != [] and tags: if filters != [] and tags:
tagSearch += ", " tagSearch += ", "
tagSearch += ", ".join(filters) tagSearch += ", ".join(filters)
elif not mascot:
if tags:
tagSearch += ", "
tagSearch += ", ".join(filters)
search += parse.quote_plus(tagSearch) search += parse.quote_plus(tagSearch)
if search[-1] == "=": if search[-1] == "=":

View file

@ -11,7 +11,7 @@
"hidden": false, "hidden": false,
"requirements": ["python-dateutil"], "requirements": ["python-dateutil"],
"tags": [ "tags": [
"subscription", "subscription"
], ],
"end_user_data_statement": "This cog will store when a user's role will be removed in a guild" "end_user_data_statement": "This cog will store when a user's role will be removed in a guild"
} }

View file

@ -28,7 +28,7 @@ TIME_RE = re.compile(TIME_RE_STRING, re.I)
class Subscriber(commands.Cog): class Subscriber(commands.Cog):
""" """
Automates subscriptions to roles to make donators and over roles easier to manage. Automates subscriptions to roles to make donators and other roles easier to manage.
""" """
def __init__(self, bot): def __init__(self, bot):