mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-20 18:06:08 -05:00
[V3] Mod initial rewrite (#1034)
* Readd work due to redoing branch * [modlog] Move to core and start work on separating it from cogs * More work on modlog separation * [Core] Finish logic for modlog, do docstrings, async getters * [Core] Add stuff to dunder all * [Docs] Add mod log docs * [Core] Move away from dunder str for Case class * [Docs] don't need to doc special members in modlog docs * More on mod log to implement commands * More work on Mod * [Mod] compatibility with async getters * [Tests] start tests for mod * [Tests] attempted fix * [Tests] mod tests passing now! * [ModLog] update for i18n * modlog.pot -> messages.pot * [Mod] i18n * fix getting admin/mod roles * Fix doc building * [Mod/Modlog] redo imports * [Tests] fix imports in mod tests * [Mod] fix logger problem * [Mod] cleanup errors * A couple of bug fixes Async getters, some old `config.set` syntax * Filter ignores private channels * Fix softban Was still relying on default channels * Actually ignore private channels * Add check for ignored channels * Fix logic for ignore check * Send confirm messages before making case * Pass in guild when setting modlog * Thanks autocomplete * Maintain all data for case * Properly ignore softbans in events * [Mod] bugfixes * [Mod] more changes * [ModLog] timestamp change * [Mod] split filter and cleanup to their own cogs + regen messages.pot * [Cleanup] change logic * [Cleanup] increase limit for channel.history * [Mod] await getter in modset banmentionspam * [Mod] attempt duplicate modlog message fix * [Mod] get_user -> get_user_info * [Modlog] change reason command so the case author can edit their cases (#806) * [Modlog] make reason command guild only * [Modlog] clarify the reason command's help * [Mod] package path changes + numpy style docstrings for modlog * [Mod] change ban and unban events to need view audit log perms to find/create a case * [Modlog] refactoring * [Filter] add autoban feature * [Mod] update case types + event changes * [Mod/Modlog] fix tests, fix permissions things * [Docs] fix up modlog docs * Regenerate messages.pot
This commit is contained in:
124
redbot/core/utils/mod.py
Normal file
124
redbot/core/utils/mod.py
Normal file
@@ -0,0 +1,124 @@
|
||||
import asyncio
|
||||
from typing import List
|
||||
|
||||
import discord
|
||||
|
||||
from redbot.core import Config
|
||||
from redbot.core.bot import Red
|
||||
|
||||
|
||||
async def mass_purge(messages: List[discord.Message],
|
||||
channel: discord.TextChannel):
|
||||
while messages:
|
||||
if len(messages) > 1:
|
||||
await channel.delete_messages(messages[:100])
|
||||
messages = messages[100:]
|
||||
else:
|
||||
await messages[0].delete()
|
||||
messages = []
|
||||
await asyncio.sleep(1.5)
|
||||
|
||||
|
||||
async def slow_deletion(messages: List[discord.Message]):
|
||||
for message in messages:
|
||||
try:
|
||||
await message.delete()
|
||||
except discord.HTTPException:
|
||||
pass
|
||||
|
||||
|
||||
def get_audit_reason(author: discord.Member, reason: str = None):
|
||||
"""Helper function to construct a reason to be provided
|
||||
as the reason to appear in the audit log."""
|
||||
return \
|
||||
"Action requested by {} (ID {}). Reason: {}".format(author, author.id, reason) if reason else \
|
||||
"Action requested by {} (ID {}).".format(author, author.id)
|
||||
|
||||
|
||||
async def is_allowed_by_hierarchy(
|
||||
bot: Red, settings: Config, server: discord.Guild,
|
||||
mod: discord.Member, user: discord.Member):
|
||||
if not await settings.guild(server).respect_hierarchy():
|
||||
return True
|
||||
is_special = mod == server.owner or await bot.is_owner(mod)
|
||||
return mod.top_role.position > user.top_role.position or is_special
|
||||
|
||||
|
||||
async def is_mod_or_superior(bot: Red, obj: discord.Message or discord.Member or discord.Role):
|
||||
user = None
|
||||
if isinstance(obj, discord.Message):
|
||||
user = obj.author
|
||||
elif isinstance(obj, discord.Member):
|
||||
user = obj
|
||||
elif isinstance(obj, discord.Role):
|
||||
pass
|
||||
else:
|
||||
raise TypeError('Only messages, members or roles may be passed')
|
||||
|
||||
server = obj.guild
|
||||
admin_role_id = await bot.db.guild(server).admin_role()
|
||||
mod_role_id = await bot.db.guild(server).mod_role()
|
||||
|
||||
if isinstance(obj, discord.Role):
|
||||
return obj.id in [admin_role_id, mod_role_id]
|
||||
mod_roles = [r for r in server.roles if r.id == mod_role_id]
|
||||
mod_role = mod_roles[0] if len(mod_roles) > 0 else None
|
||||
admin_roles = [r for r in server.roles if r.id == admin_role_id]
|
||||
admin_role = admin_roles[0] if len(admin_roles) > 0 else None
|
||||
|
||||
if user and user == await bot.is_owner(user):
|
||||
return True
|
||||
elif admin_role and discord.utils.get(user.roles, name=admin_role):
|
||||
return True
|
||||
elif mod_role and discord.utils.get(user.roles, name=mod_role):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def strfdelta(delta):
|
||||
s = []
|
||||
if delta.days:
|
||||
ds = '%i day' % delta.days
|
||||
if delta.days > 1:
|
||||
ds += 's'
|
||||
s.append(ds)
|
||||
hrs, rem = divmod(delta.seconds, 60*60)
|
||||
if hrs:
|
||||
hs = '%i hr' % hrs
|
||||
if hrs > 1:
|
||||
hs += 's'
|
||||
s.append(hs)
|
||||
mins, secs = divmod(rem, 60)
|
||||
if mins:
|
||||
s.append('%i min' % mins)
|
||||
if secs:
|
||||
s.append('%i sec' % secs)
|
||||
return ' '.join(s)
|
||||
|
||||
|
||||
async def is_admin_or_superior(bot: Red, obj: discord.Message or discord.Role or discord.Member):
|
||||
user = None
|
||||
if isinstance(obj, discord.Message):
|
||||
user = obj.author
|
||||
elif isinstance(obj, discord.Member):
|
||||
user = obj
|
||||
elif isinstance(obj, discord.Role):
|
||||
pass
|
||||
else:
|
||||
raise TypeError('Only messages, members or roles may be passed')
|
||||
|
||||
server = obj.guild
|
||||
admin_role_id = await bot.db.guild(server).admin_role()
|
||||
|
||||
if isinstance(obj, discord.Role):
|
||||
return obj.id == admin_role_id
|
||||
admin_roles = [r for r in server.roles if r.id == admin_role_id]
|
||||
admin_role = admin_roles[0] if len(admin_roles) > 0 else None
|
||||
|
||||
if user and await bot.is_owner(user):
|
||||
return True
|
||||
elif admin_roles and discord.utils.get(user.roles, name=admin_role):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
Reference in New Issue
Block a user