mirror of
https://github.com/Ryujinx/ryuko-ng.git
synced 2024-12-22 19:25:38 +00:00
Change robocop_ng to have state directory differ from working directory
This commit is contained in:
parent
8463b9b2fb
commit
48f9cc5cde
|
@ -9,4 +9,4 @@ COPY . .
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
CMD [ "python", "-m", "robocop_ng" ]
|
CMD [ "python", "-m", "robocop_ng", "/state" ]
|
||||||
|
|
|
@ -7,7 +7,14 @@ import aiohttp
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from robocop_ng import config
|
if len(sys.argv[1:]) != 1:
|
||||||
|
sys.stderr.write("usage: <state_dir>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
state_dir = os.path.abspath(sys.argv[1])
|
||||||
|
sys.path.append(state_dir)
|
||||||
|
|
||||||
|
import config
|
||||||
|
|
||||||
# TODO: check __name__ for __main__ nerd
|
# TODO: check __name__ for __main__ nerd
|
||||||
|
|
||||||
|
@ -50,6 +57,11 @@ wanted_jsons = [
|
||||||
"data/persistent_roles.json",
|
"data/persistent_roles.json",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
for wanted_json_idx in range(len(wanted_jsons)):
|
||||||
|
wanted_jsons[wanted_json_idx] = os.path.join(
|
||||||
|
state_dir, wanted_jsons[wanted_json_idx]
|
||||||
|
)
|
||||||
|
|
||||||
intents = discord.Intents.all()
|
intents = discord.Intents.all()
|
||||||
intents.typing = False
|
intents.typing = False
|
||||||
|
|
||||||
|
@ -61,6 +73,7 @@ bot.help_command = commands.DefaultHelpCommand(dm_help=True)
|
||||||
bot.log = log
|
bot.log = log
|
||||||
bot.config = config
|
bot.config = config
|
||||||
bot.script_name = script_name
|
bot.script_name = script_name
|
||||||
|
bot.state_dir = state_dir
|
||||||
bot.wanted_jsons = wanted_jsons
|
bot.wanted_jsons = wanted_jsons
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_bot_manager
|
from robocop_ng.helpers.checks import check_if_bot_manager
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,7 +93,7 @@ class Admin(Cog):
|
||||||
|
|
||||||
async def cog_load_actions(self, cog_name):
|
async def cog_load_actions(self, cog_name):
|
||||||
if cog_name == "verification":
|
if cog_name == "verification":
|
||||||
verif_channel = self.bot.get_channel(config.welcome_channel)
|
verif_channel = self.bot.get_channel(self.bot.config.welcome_channel)
|
||||||
await self.bot.do_resetalgo(verif_channel, "cog load")
|
await self.bot.do_resetalgo(verif_channel, "cog load")
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
@ -109,7 +108,7 @@ class Admin(Cog):
|
||||||
cogs_to_reload = re.findall(r"cogs/([a-z_]*).py[ ]*\|", git_output)
|
cogs_to_reload = re.findall(r"cogs/([a-z_]*).py[ ]*\|", git_output)
|
||||||
for cog in cogs_to_reload:
|
for cog in cogs_to_reload:
|
||||||
cog_name = "robocop_ng.cogs." + cog
|
cog_name = "robocop_ng.cogs." + cog
|
||||||
if cog_name not in config.initial_cogs:
|
if cog_name not in self.bot.config.initial_cogs:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -4,8 +4,6 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
|
|
||||||
|
|
||||||
class Basic(Cog):
|
class Basic(Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
@ -39,7 +37,9 @@ class Basic(Cog):
|
||||||
async def robocop(self, ctx):
|
async def robocop(self, ctx):
|
||||||
"""Shows a quick embed with bot info."""
|
"""Shows a quick embed with bot info."""
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
title="Robocop-NG", url=config.source_url, description=config.embed_desc
|
title="Robocop-NG",
|
||||||
|
url=self.bot.config.source_url,
|
||||||
|
description=self.bot.config.embed_desc,
|
||||||
)
|
)
|
||||||
|
|
||||||
embed.set_thumbnail(url=str(self.bot.user.display_avatar))
|
embed.set_thumbnail(url=str(self.bot.user.display_avatar))
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
|
|
||||||
|
|
||||||
class BasicReswitched(Cog):
|
class BasicReswitched(Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
@ -12,7 +10,7 @@ class BasicReswitched(Cog):
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def communitycount(self, ctx):
|
async def communitycount(self, ctx):
|
||||||
"""Prints the community member count of the server."""
|
"""Prints the community member count of the server."""
|
||||||
community = ctx.guild.get_role(config.named_roles["community"])
|
community = ctx.guild.get_role(self.bot.config.named_roles["community"])
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"{ctx.guild.name} has {len(community.members)} community members!"
|
f"{ctx.guild.name} has {len(community.members)} community members!"
|
||||||
)
|
)
|
||||||
|
@ -21,7 +19,7 @@ class BasicReswitched(Cog):
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def hackercount(self, ctx):
|
async def hackercount(self, ctx):
|
||||||
"""Prints the hacker member count of the server."""
|
"""Prints the hacker member count of the server."""
|
||||||
h4x0r = ctx.guild.get_role(config.named_roles["hacker"])
|
h4x0r = ctx.guild.get_role(self.bot.config.named_roles["hacker"])
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"{ctx.guild.name} has {len(h4x0r.members)} people with hacker role!"
|
f"{ctx.guild.name} has {len(h4x0r.members)} people with hacker role!"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,29 +1,30 @@
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_collaborator
|
from robocop_ng.helpers.checks import check_if_collaborator
|
||||||
|
|
||||||
|
|
||||||
class Invites(Cog):
|
class Invites(Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.invites_json_path = os.path.join(self.bot.state_dir, "data/invites.json")
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.check(check_if_collaborator)
|
@commands.check(check_if_collaborator)
|
||||||
async def invite(self, ctx):
|
async def invite(self, ctx):
|
||||||
welcome_channel = self.bot.get_channel(config.welcome_channel)
|
welcome_channel = self.bot.get_channel(self.bot.config.welcome_channel)
|
||||||
author = ctx.message.author
|
author = ctx.message.author
|
||||||
reason = f"Created by {str(author)} ({author.id})"
|
reason = f"Created by {str(author)} ({author.id})"
|
||||||
invite = await welcome_channel.create_invite(
|
invite = await welcome_channel.create_invite(
|
||||||
max_age=0, max_uses=1, temporary=True, unique=True, reason=reason
|
max_age=0, max_uses=1, temporary=True, unique=True, reason=reason
|
||||||
)
|
)
|
||||||
|
|
||||||
with open("data/invites.json", "r") as f:
|
with open(self.invites_json_path, "r") as f:
|
||||||
invites = json.load(f)
|
invites = json.load(f)
|
||||||
|
|
||||||
invites[invite.id] = {
|
invites[invite.id] = {
|
||||||
|
@ -33,7 +34,7 @@ class Invites(Cog):
|
||||||
"code": invite.code,
|
"code": invite.code,
|
||||||
}
|
}
|
||||||
|
|
||||||
with open("data/invites.json", "w") as f:
|
with open(self.invites_json_path, "w") as f:
|
||||||
f.write(json.dumps(invites))
|
f.write(json.dumps(invites))
|
||||||
|
|
||||||
await ctx.message.add_reaction("🆗")
|
await ctx.message.add_reaction("🆗")
|
||||||
|
|
|
@ -2,8 +2,6 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
|
|
||||||
|
|
||||||
class Links(Cog):
|
class Links(Cog):
|
||||||
"""
|
"""
|
||||||
|
@ -38,13 +36,13 @@ class Links(Cog):
|
||||||
@commands.command(hidden=True, aliases=["guides", "link"])
|
@commands.command(hidden=True, aliases=["guides", "link"])
|
||||||
async def guide(self, ctx):
|
async def guide(self, ctx):
|
||||||
"""Link to the guides"""
|
"""Link to the guides"""
|
||||||
await ctx.send(config.links_guide_text)
|
await ctx.send(self.bot.config.links_guide_text)
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def source(self, ctx):
|
async def source(self, ctx):
|
||||||
"""Gives link to source code."""
|
"""Gives link to source code."""
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"You can find my source at {config.source_url}. "
|
f"You can find my source at {self.bot.config.source_url}. "
|
||||||
"Serious PRs and issues welcome!"
|
"Serious PRs and issues welcome!"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -55,7 +53,7 @@ class Links(Cog):
|
||||||
targetuser = ctx.author
|
targetuser = ctx.author
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"{targetuser.mention}: A link to the rules "
|
f"{targetuser.mention}: A link to the rules "
|
||||||
f"can be found here: {config.rules_url}"
|
f"can be found here: {self.bot.config.rules_url}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
|
|
|
@ -5,8 +5,6 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
|
|
||||||
|
|
||||||
class Lists(Cog):
|
class Lists(Cog):
|
||||||
"""
|
"""
|
||||||
|
@ -19,7 +17,7 @@ class Lists(Cog):
|
||||||
# Helpers
|
# Helpers
|
||||||
|
|
||||||
def check_if_target_is_staff(self, target):
|
def check_if_target_is_staff(self, target):
|
||||||
return any(r.id in config.staff_role_ids for r in target.roles)
|
return any(r.id in self.bot.config.staff_role_ids for r in target.roles)
|
||||||
|
|
||||||
def is_edit(self, emoji):
|
def is_edit(self, emoji):
|
||||||
return str(emoji)[0] == "✏" or str(emoji)[0] == "📝"
|
return str(emoji)[0] == "✏" or str(emoji)[0] == "📝"
|
||||||
|
@ -84,7 +82,7 @@ class Lists(Cog):
|
||||||
fields = embeds[0].fields
|
fields = embeds[0].fields
|
||||||
for field in fields:
|
for field in fields:
|
||||||
if field.name == "Message ID":
|
if field.name == "Message ID":
|
||||||
files_channel = self.bot.get_channel(config.list_files_channel)
|
files_channel = self.bot.get_channel(self.bot.config.list_files_channel)
|
||||||
file_message = await files_channel.fetch_message(int(field.value))
|
file_message = await files_channel.fetch_message(int(field.value))
|
||||||
await file_message.delete()
|
await file_message.delete()
|
||||||
|
|
||||||
|
@ -133,7 +131,7 @@ class Lists(Cog):
|
||||||
await ctx.send(f"Number must be greater than 0.")
|
await ctx.send(f"Number must be greater than 0.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if channel.id not in config.list_channels:
|
if channel.id not in self.bot.config.list_channels:
|
||||||
await ctx.send(f"{channel.mention} is not a list channel.")
|
await ctx.send(f"{channel.mention} is not a list channel.")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -160,7 +158,7 @@ class Lists(Cog):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
|
|
||||||
# We only care about reactions in Rules, and Support FAQ
|
# We only care about reactions in Rules, and Support FAQ
|
||||||
if payload.channel_id not in config.list_channels:
|
if payload.channel_id not in self.bot.config.list_channels:
|
||||||
return
|
return
|
||||||
|
|
||||||
channel = self.bot.get_channel(payload.channel_id)
|
channel = self.bot.get_channel(payload.channel_id)
|
||||||
|
@ -201,8 +199,8 @@ class Lists(Cog):
|
||||||
await r.remove(user)
|
await r.remove(user)
|
||||||
|
|
||||||
# When editing we want to provide the user a copy of the raw text.
|
# When editing we want to provide the user a copy of the raw text.
|
||||||
if self.is_edit(reaction.emoji) and config.list_files_channel != 0:
|
if self.is_edit(reaction.emoji) and self.bot.config.list_files_channel != 0:
|
||||||
files_channel = self.bot.get_channel(config.list_files_channel)
|
files_channel = self.bot.get_channel(self.bot.config.list_files_channel)
|
||||||
file = discord.File(
|
file = discord.File(
|
||||||
io.BytesIO(message.content.encode("utf-8")),
|
io.BytesIO(message.content.encode("utf-8")),
|
||||||
filename=f"{message.id}.txt",
|
filename=f"{message.id}.txt",
|
||||||
|
@ -221,7 +219,7 @@ class Lists(Cog):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
|
|
||||||
# We only care about reactions in Rules, and Support FAQ
|
# We only care about reactions in Rules, and Support FAQ
|
||||||
if payload.channel_id not in config.list_channels:
|
if payload.channel_id not in self.bot.config.list_channels:
|
||||||
return
|
return
|
||||||
|
|
||||||
channel = self.bot.get_channel(payload.channel_id)
|
channel = self.bot.get_channel(payload.channel_id)
|
||||||
|
@ -232,7 +230,7 @@ class Lists(Cog):
|
||||||
return
|
return
|
||||||
|
|
||||||
# We want to remove the embed we added.
|
# We want to remove the embed we added.
|
||||||
if self.is_edit(payload.emoji) and config.list_files_channel != 0:
|
if self.is_edit(payload.emoji) and self.bot.config.list_files_channel != 0:
|
||||||
await self.clean_up_raw_text_file_message(message)
|
await self.clean_up_raw_text_file_message(message)
|
||||||
|
|
||||||
@Cog.listener()
|
@Cog.listener()
|
||||||
|
@ -240,7 +238,7 @@ class Lists(Cog):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
|
|
||||||
# We only care about messages in Rules, and Support FAQ
|
# We only care about messages in Rules, and Support FAQ
|
||||||
if message.channel.id not in config.list_channels:
|
if message.channel.id not in self.bot.config.list_channels:
|
||||||
return
|
return
|
||||||
|
|
||||||
# We don"t care about messages from bots.
|
# We don"t care about messages from bots.
|
||||||
|
@ -252,7 +250,7 @@ class Lists(Cog):
|
||||||
await message.delete()
|
await message.delete()
|
||||||
return
|
return
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.log_channel)
|
log_channel = self.bot.get_channel(self.bot.config.log_channel)
|
||||||
channel = message.channel
|
channel = message.channel
|
||||||
content = message.content
|
content = message.content
|
||||||
user = message.author
|
user = message.author
|
||||||
|
@ -300,7 +298,7 @@ class Lists(Cog):
|
||||||
targeted_message = targeted_reaction.message
|
targeted_message = targeted_reaction.message
|
||||||
|
|
||||||
if self.is_edit(targeted_reaction):
|
if self.is_edit(targeted_reaction):
|
||||||
if config.list_files_channel != 0:
|
if self.bot.config.list_files_channel != 0:
|
||||||
await self.clean_up_raw_text_file_message(targeted_message)
|
await self.clean_up_raw_text_file_message(targeted_message)
|
||||||
await targeted_message.edit(content=content)
|
await targeted_message.edit(content=content)
|
||||||
await targeted_reaction.remove(user)
|
await targeted_reaction.remove(user)
|
||||||
|
|
|
@ -2,7 +2,6 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff
|
from robocop_ng.helpers.checks import check_if_staff
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +23,7 @@ class Lockdown(Cog):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def unlock_for_staff(self, channel: discord.TextChannel, issuer):
|
async def unlock_for_staff(self, channel: discord.TextChannel, issuer):
|
||||||
for role in config.staff_role_ids:
|
for role in self.bot.config.staff_role_ids:
|
||||||
await self.set_sendmessage(channel, role, True, issuer)
|
await self.set_sendmessage(channel, role, True, issuer)
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
@ -36,15 +35,15 @@ class Lockdown(Cog):
|
||||||
Defaults to current channel."""
|
Defaults to current channel."""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = ctx.channel
|
channel = ctx.channel
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
|
|
||||||
roles = None
|
roles = None
|
||||||
for key, lockdown_conf in config.lockdown_configs.items():
|
for key, lockdown_conf in self.bot.config.lockdown_configs.items():
|
||||||
if channel.id in lockdown_conf["channels"]:
|
if channel.id in lockdown_conf["channels"]:
|
||||||
roles = lockdown_conf["roles"]
|
roles = lockdown_conf["roles"]
|
||||||
|
|
||||||
if roles is None:
|
if roles is None:
|
||||||
roles = config.lockdown_configs["default"]["roles"]
|
roles = self.bot.config.lockdown_configs["default"]["roles"]
|
||||||
|
|
||||||
for role in roles:
|
for role in roles:
|
||||||
await self.set_sendmessage(channel, role, False, ctx.author)
|
await self.set_sendmessage(channel, role, False, ctx.author)
|
||||||
|
@ -76,15 +75,15 @@ class Lockdown(Cog):
|
||||||
"""Unlocks speaking in current channel, staff only."""
|
"""Unlocks speaking in current channel, staff only."""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = ctx.channel
|
channel = ctx.channel
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
|
|
||||||
roles = None
|
roles = None
|
||||||
for key, lockdown_conf in config.lockdown_configs.items():
|
for key, lockdown_conf in self.bot.config.lockdown_configs.items():
|
||||||
if channel.id in lockdown_conf["channels"]:
|
if channel.id in lockdown_conf["channels"]:
|
||||||
roles = lockdown_conf["roles"]
|
roles = lockdown_conf["roles"]
|
||||||
|
|
||||||
if roles is None:
|
if roles is None:
|
||||||
roles = config.lockdown_configs["default"]["roles"]
|
roles = self.bot.config.lockdown_configs["default"]["roles"]
|
||||||
|
|
||||||
await self.unlock_for_staff(channel, ctx.author)
|
await self.unlock_for_staff(channel, ctx.author)
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@ import aiohttp
|
||||||
from discord import Colour, Embed
|
from discord import Colour, Embed
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
format="%(asctime)s (%(levelname)s) %(message)s (Line %(lineno)d)",
|
format="%(asctime)s (%(levelname)s) %(message)s (Line %(lineno)d)",
|
||||||
level=logging.INFO,
|
level=logging.INFO,
|
||||||
|
@ -16,7 +14,7 @@ logging.basicConfig(
|
||||||
class LogFileReader(Cog):
|
class LogFileReader(Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.bot_log_allowed_channels = config.bot_log_allowed_channels
|
self.bot_log_allowed_channels = self.bot.config.bot_log_allowed_channels
|
||||||
self.ryujinx_blue = Colour(0x4A90E2)
|
self.ryujinx_blue = Colour(0x4A90E2)
|
||||||
self.uploaded_log_info = []
|
self.uploaded_log_info = []
|
||||||
|
|
||||||
|
@ -620,14 +618,16 @@ class LogFileReader(Cog):
|
||||||
|
|
||||||
is_channel_allowed = False
|
is_channel_allowed = False
|
||||||
|
|
||||||
for allowed_channel_id in config.bot_log_allowed_channels.values():
|
for (
|
||||||
|
allowed_channel_id
|
||||||
|
) in self.bot.config.bot_log_allowed_channels.values():
|
||||||
if message.channel.id == allowed_channel_id:
|
if message.channel.id == allowed_channel_id:
|
||||||
is_channel_allowed = True
|
is_channel_allowed = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if is_channel_allowed:
|
if is_channel_allowed:
|
||||||
if re.match(pr_version, self.embed["emu_info"]["ryu_version"]):
|
if re.match(pr_version, self.embed["emu_info"]["ryu_version"]):
|
||||||
pr_version_warning = f"**⚠️ PR build logs should be posted in <#{config.bot_log_allowed_channels['pr-testing']}> if reporting bugs or tests**"
|
pr_version_warning = f"**⚠️ PR build logs should be posted in <#{self.bot.config.bot_log_allowed_channels['pr-testing']}> if reporting bugs or tests**"
|
||||||
self.embed["game_info"]["notes"].append(pr_version_warning)
|
self.embed["game_info"]["notes"].append(pr_version_warning)
|
||||||
|
|
||||||
if re.match(
|
if re.match(
|
||||||
|
@ -776,13 +776,13 @@ class LogFileReader(Cog):
|
||||||
description="\n".join(
|
description="\n".join(
|
||||||
(
|
(
|
||||||
f"Please upload Ryujinx log files to the correct location:\n",
|
f"Please upload Ryujinx log files to the correct location:\n",
|
||||||
f'<#{config.bot_log_allowed_channels["windows-support"]}>: Windows help and troubleshooting',
|
f'<#{self.bot.config.bot_log_allowed_channels["windows-support"]}>: Windows help and troubleshooting',
|
||||||
f'<#{config.bot_log_allowed_channels["linux-support"]}>: Linux help and troubleshooting',
|
f'<#{self.bot.config.bot_log_allowed_channels["linux-support"]}>: Linux help and troubleshooting',
|
||||||
f'<#{config.bot_log_allowed_channels["macos-support"]}>: macOS help and troubleshooting',
|
f'<#{self.bot.config.bot_log_allowed_channels["macos-support"]}>: macOS help and troubleshooting',
|
||||||
f'<#{config.bot_log_allowed_channels["patreon-support"]}>: Help and troubleshooting for Patreon subscribers',
|
f'<#{self.bot.config.bot_log_allowed_channels["patreon-support"]}>: Help and troubleshooting for Patreon subscribers',
|
||||||
f'<#{config.bot_log_allowed_channels["development"]}>: Ryujinx development discussion',
|
f'<#{self.bot.config.bot_log_allowed_channels["development"]}>: Ryujinx development discussion',
|
||||||
f'<#{config.bot_log_allowed_channels["pr-testing"]}>: Discussion of in-progress pull request builds',
|
f'<#{self.bot.config.bot_log_allowed_channels["pr-testing"]}>: Discussion of in-progress pull request builds',
|
||||||
f'<#{config.bot_log_allowed_channels["linux-master-race"]}>: Linux support and discussion',
|
f'<#{self.bot.config.bot_log_allowed_channels["linux-master-race"]}>: Linux support and discussion',
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
colour=self.ryujinx_blue,
|
colour=self.ryujinx_blue,
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff
|
from robocop_ng.helpers.checks import check_if_staff
|
||||||
from robocop_ng.helpers.restrictions import get_user_restrictions
|
from robocop_ng.helpers.restrictions import get_user_restrictions
|
||||||
|
from robocop_ng.helpers.userlogs import get_userlog
|
||||||
|
|
||||||
|
|
||||||
class Logs(Cog):
|
class Logs(Cog):
|
||||||
|
@ -16,6 +17,7 @@ class Logs(Cog):
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
self.invites_json_path = os.path.join(self.bot.state_dir, "data/invites.json")
|
||||||
self.invite_re = re.compile(
|
self.invite_re = re.compile(
|
||||||
r"((discord\.gg|discordapp\.com/" r"+invite)/+[a-zA-Z0-9-]+)", re.IGNORECASE
|
r"((discord\.gg|discordapp\.com/" r"+invite)/+[a-zA-Z0-9-]+)", re.IGNORECASE
|
||||||
)
|
)
|
||||||
|
@ -23,7 +25,7 @@ class Logs(Cog):
|
||||||
self.clean_re = re.compile(r"[^a-zA-Z0-9_ ]+", re.UNICODE)
|
self.clean_re = re.compile(r"[^a-zA-Z0-9_ ]+", re.UNICODE)
|
||||||
# All lower case, no spaces, nothing non-alphanumeric
|
# All lower case, no spaces, nothing non-alphanumeric
|
||||||
susp_hellgex = "|".join(
|
susp_hellgex = "|".join(
|
||||||
[r"\W*".join(list(word)) for word in config.suspect_words]
|
[r"\W*".join(list(word)) for word in self.bot.config.suspect_words]
|
||||||
)
|
)
|
||||||
self.susp_hellgex = re.compile(susp_hellgex, re.IGNORECASE)
|
self.susp_hellgex = re.compile(susp_hellgex, re.IGNORECASE)
|
||||||
|
|
||||||
|
@ -31,15 +33,15 @@ class Logs(Cog):
|
||||||
async def on_member_join(self, member):
|
async def on_member_join(self, member):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
|
|
||||||
if member.guild.id not in config.guild_whitelist:
|
if member.guild.id not in self.bot.config.guild_whitelist:
|
||||||
return
|
return
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.log_channel)
|
log_channel = self.bot.get_channel(self.bot.config.log_channel)
|
||||||
# We use this a lot, might as well get it once
|
# We use this a lot, might as well get it once
|
||||||
escaped_name = self.bot.escape_message(member)
|
escaped_name = self.bot.escape_message(member)
|
||||||
|
|
||||||
# Attempt to correlate the user joining with an invite
|
# Attempt to correlate the user joining with an invite
|
||||||
with open("data/invites.json", "r") as f:
|
with open(self.invites_json_path, "r") as f:
|
||||||
invites = json.load(f)
|
invites = json.load(f)
|
||||||
|
|
||||||
real_invites = await member.guild.invites()
|
real_invites = await member.guild.invites()
|
||||||
|
@ -74,7 +76,7 @@ class Logs(Cog):
|
||||||
del invites[id]
|
del invites[id]
|
||||||
|
|
||||||
# Save invites data.
|
# Save invites data.
|
||||||
with open("data/invites.json", "w") as f:
|
with open(self.invites_json_path, "w") as f:
|
||||||
f.write(json.dumps(invites))
|
f.write(json.dumps(invites))
|
||||||
|
|
||||||
# Prepare the invite correlation message
|
# Prepare the invite correlation message
|
||||||
|
@ -88,7 +90,7 @@ class Logs(Cog):
|
||||||
|
|
||||||
# Check if user account is older than 15 minutes
|
# Check if user account is older than 15 minutes
|
||||||
age = member.joined_at - member.created_at
|
age = member.joined_at - member.created_at
|
||||||
if age < config.min_age:
|
if age < self.bot.config.min_age:
|
||||||
try:
|
try:
|
||||||
await member.send(
|
await member.send(
|
||||||
f"Your account is too new to "
|
f"Your account is too new to "
|
||||||
|
@ -126,13 +128,12 @@ class Logs(Cog):
|
||||||
|
|
||||||
# Handles user restrictions
|
# Handles user restrictions
|
||||||
# Basically, gives back muted role to users that leave with it.
|
# Basically, gives back muted role to users that leave with it.
|
||||||
rsts = get_user_restrictions(member.id)
|
rsts = get_user_restrictions(self.bot, member.id)
|
||||||
roles = [discord.utils.get(member.guild.roles, id=rst) for rst in rsts]
|
roles = [discord.utils.get(member.guild.roles, id=rst) for rst in rsts]
|
||||||
await member.add_roles(*roles)
|
await member.add_roles(*roles)
|
||||||
|
|
||||||
# Real hell zone.
|
# Real hell zone.
|
||||||
with open("data/userlog.json", "r") as f:
|
warns = get_userlog()
|
||||||
warns = json.load(f)
|
|
||||||
try:
|
try:
|
||||||
if len(warns[str(member.id)]["warns"]) == 0:
|
if len(warns[str(member.id)]["warns"]) == 0:
|
||||||
await log_channel.send(msg)
|
await log_channel.send(msg)
|
||||||
|
@ -170,16 +171,17 @@ class Logs(Cog):
|
||||||
msg += f"\n- Has invite: https://{invite[0]}"
|
msg += f"\n- Has invite: https://{invite[0]}"
|
||||||
alert = True
|
alert = True
|
||||||
|
|
||||||
for susp_word in config.suspect_words:
|
for susp_word in self.bot.config.suspect_words:
|
||||||
if susp_word in cleancont and not any(
|
if susp_word in cleancont and not any(
|
||||||
ok_word in cleancont for ok_word in config.suspect_ignored_words
|
ok_word in cleancont
|
||||||
|
for ok_word in self.bot.config.suspect_ignored_words
|
||||||
):
|
):
|
||||||
msg += f"\n- Contains suspicious word: `{susp_word}`"
|
msg += f"\n- Contains suspicious word: `{susp_word}`"
|
||||||
alert = True
|
alert = True
|
||||||
|
|
||||||
if alert:
|
if alert:
|
||||||
msg += f"\n\nJump: <{message.jump_url}>"
|
msg += f"\n\nJump: <{message.jump_url}>"
|
||||||
spy_channel = self.bot.get_channel(config.spylog_channel)
|
spy_channel = self.bot.get_channel(self.bot.config.spylog_channel)
|
||||||
|
|
||||||
# Bad Code :tm:, blame retr0id
|
# Bad Code :tm:, blame retr0id
|
||||||
message_clean = message.content.replace("*", "").replace("_", "")
|
message_clean = message.content.replace("*", "").replace("_", "")
|
||||||
|
@ -205,13 +207,13 @@ class Logs(Cog):
|
||||||
f"R11 violating name by {message.author.mention} " f"({message.author.id})."
|
f"R11 violating name by {message.author.mention} " f"({message.author.id})."
|
||||||
)
|
)
|
||||||
|
|
||||||
spy_channel = self.bot.get_channel(config.spylog_channel)
|
spy_channel = self.bot.get_channel(self.bot.config.spylog_channel)
|
||||||
await spy_channel.send(msg)
|
await spy_channel.send(msg)
|
||||||
|
|
||||||
@Cog.listener()
|
@Cog.listener()
|
||||||
async def on_message(self, message):
|
async def on_message(self, message):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
if message.channel.id not in config.spy_channels:
|
if message.channel.id not in self.bot.config.spy_channels:
|
||||||
return
|
return
|
||||||
|
|
||||||
await self.do_spy(message)
|
await self.do_spy(message)
|
||||||
|
@ -219,7 +221,7 @@ class Logs(Cog):
|
||||||
@Cog.listener()
|
@Cog.listener()
|
||||||
async def on_message_edit(self, before, after):
|
async def on_message_edit(self, before, after):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
if after.channel.id not in config.spy_channels or after.author.bot:
|
if after.channel.id not in self.bot.config.spy_channels or after.author.bot:
|
||||||
return
|
return
|
||||||
|
|
||||||
# If content is the same, just skip over it
|
# If content is the same, just skip over it
|
||||||
|
@ -233,7 +235,7 @@ class Logs(Cog):
|
||||||
before_content = before.clean_content.replace("`", "`\u200d")
|
before_content = before.clean_content.replace("`", "`\u200d")
|
||||||
after_content = after.clean_content.replace("`", "`\u200d")
|
after_content = after.clean_content.replace("`", "`\u200d")
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.log_channel)
|
log_channel = self.bot.get_channel(self.bot.config.log_channel)
|
||||||
|
|
||||||
msg = (
|
msg = (
|
||||||
"📝 **Message edit**: \n"
|
"📝 **Message edit**: \n"
|
||||||
|
@ -252,10 +254,10 @@ class Logs(Cog):
|
||||||
@Cog.listener()
|
@Cog.listener()
|
||||||
async def on_message_delete(self, message):
|
async def on_message_delete(self, message):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
if message.channel.id not in config.spy_channels or message.author.bot:
|
if message.channel.id not in self.bot.config.spy_channels or message.author.bot:
|
||||||
return
|
return
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.log_channel)
|
log_channel = self.bot.get_channel(self.bot.config.log_channel)
|
||||||
msg = (
|
msg = (
|
||||||
"🗑️ **Message delete**: \n"
|
"🗑️ **Message delete**: \n"
|
||||||
f"from {self.bot.escape_message(message.author.name)} "
|
f"from {self.bot.escape_message(message.author.name)} "
|
||||||
|
@ -274,10 +276,10 @@ class Logs(Cog):
|
||||||
async def on_member_remove(self, member):
|
async def on_member_remove(self, member):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
|
|
||||||
if member.guild.id not in config.guild_whitelist:
|
if member.guild.id not in self.bot.config.guild_whitelist:
|
||||||
return
|
return
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.log_channel)
|
log_channel = self.bot.get_channel(self.bot.config.log_channel)
|
||||||
msg = (
|
msg = (
|
||||||
f"⬅️ **Leave**: {member.mention} | "
|
f"⬅️ **Leave**: {member.mention} | "
|
||||||
f"{self.bot.escape_message(member)}\n"
|
f"{self.bot.escape_message(member)}\n"
|
||||||
|
@ -289,10 +291,10 @@ class Logs(Cog):
|
||||||
async def on_member_ban(self, guild, member):
|
async def on_member_ban(self, guild, member):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
|
|
||||||
if guild.id not in config.guild_whitelist:
|
if guild.id not in self.bot.config.guild_whitelist:
|
||||||
return
|
return
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
msg = (
|
msg = (
|
||||||
f"⛔ **Ban**: {member.mention} | "
|
f"⛔ **Ban**: {member.mention} | "
|
||||||
f"{self.bot.escape_message(member)}\n"
|
f"{self.bot.escape_message(member)}\n"
|
||||||
|
@ -304,10 +306,10 @@ class Logs(Cog):
|
||||||
async def on_member_unban(self, guild, user):
|
async def on_member_unban(self, guild, user):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
|
|
||||||
if guild.id not in config.guild_whitelist:
|
if guild.id not in self.bot.config.guild_whitelist:
|
||||||
return
|
return
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
msg = (
|
msg = (
|
||||||
f"⚠️ **Unban**: {user.mention} | "
|
f"⚠️ **Unban**: {user.mention} | "
|
||||||
f"{self.bot.escape_message(user)}\n"
|
f"{self.bot.escape_message(user)}\n"
|
||||||
|
@ -328,11 +330,11 @@ class Logs(Cog):
|
||||||
async def on_member_update(self, member_before, member_after):
|
async def on_member_update(self, member_before, member_after):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
|
|
||||||
if member_after.guild.id not in config.guild_whitelist:
|
if member_after.guild.id not in self.bot.config.guild_whitelist:
|
||||||
return
|
return
|
||||||
|
|
||||||
msg = ""
|
msg = ""
|
||||||
log_channel = self.bot.get_channel(config.log_channel)
|
log_channel = self.bot.get_channel(self.bot.config.log_channel)
|
||||||
if member_before.roles != member_after.roles:
|
if member_before.roles != member_after.roles:
|
||||||
# role removal
|
# role removal
|
||||||
role_removal = []
|
role_removal = []
|
||||||
|
|
|
@ -18,12 +18,15 @@ from robocop_ng.helpers.macros import (
|
||||||
|
|
||||||
|
|
||||||
class Macro(Cog):
|
class Macro(Cog):
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
@commands.cooldown(3, 30, BucketType.member)
|
@commands.cooldown(3, 30, BucketType.member)
|
||||||
@commands.command(aliases=["m"])
|
@commands.command(aliases=["m"])
|
||||||
async def macro(self, ctx: Context, target: Optional[discord.Member], key: str):
|
async def macro(self, ctx: Context, target: Optional[discord.Member], key: str):
|
||||||
await ctx.message.delete()
|
await ctx.message.delete()
|
||||||
if len(key) > 0:
|
if len(key) > 0:
|
||||||
text = get_macro(key)
|
text = get_macro(self.bot, key)
|
||||||
if text is not None:
|
if text is not None:
|
||||||
if target is not None:
|
if target is not None:
|
||||||
await ctx.send(f"{target.mention}:\n{text}")
|
await ctx.send(f"{target.mention}:\n{text}")
|
||||||
|
@ -42,7 +45,7 @@ class Macro(Cog):
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command(name="macroadd", aliases=["ma", "addmacro", "add_macro"])
|
@commands.command(name="macroadd", aliases=["ma", "addmacro", "add_macro"])
|
||||||
async def add_macro(self, ctx: Context, key: str, *, text: str):
|
async def add_macro(self, ctx: Context, key: str, *, text: str):
|
||||||
if add_macro(key, text):
|
if add_macro(self.bot, key, text):
|
||||||
await ctx.send(f"Macro '{key}' added!")
|
await ctx.send(f"Macro '{key}' added!")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"Error: Macro '{key}' already exists.")
|
await ctx.send(f"Error: Macro '{key}' already exists.")
|
||||||
|
@ -53,7 +56,7 @@ class Macro(Cog):
|
||||||
if len(new_keys) == 0:
|
if len(new_keys) == 0:
|
||||||
await ctx.send("Error: You need to add at least one alias.")
|
await ctx.send("Error: You need to add at least one alias.")
|
||||||
else:
|
else:
|
||||||
if add_aliases(existing_key, list(new_keys)):
|
if add_aliases(self.bot, existing_key, list(new_keys)):
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"Added {len(new_keys)} aliases to macro '{existing_key}'!"
|
f"Added {len(new_keys)} aliases to macro '{existing_key}'!"
|
||||||
)
|
)
|
||||||
|
@ -63,7 +66,7 @@ class Macro(Cog):
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command(name="macroedit", aliases=["me", "editmacro", "edit_macro"])
|
@commands.command(name="macroedit", aliases=["me", "editmacro", "edit_macro"])
|
||||||
async def edit_macro(self, ctx: Context, key: str, *, text: str):
|
async def edit_macro(self, ctx: Context, key: str, *, text: str):
|
||||||
if edit_macro(key, text):
|
if edit_macro(self.bot, key, text):
|
||||||
await ctx.send(f"Macro '{key}' edited!")
|
await ctx.send(f"Macro '{key}' edited!")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"Error: Macro '{key}' not found.")
|
await ctx.send(f"Error: Macro '{key}' not found.")
|
||||||
|
@ -86,7 +89,7 @@ class Macro(Cog):
|
||||||
if len(remove_keys) == 0:
|
if len(remove_keys) == 0:
|
||||||
await ctx.send("Error: You need to remove at least one alias.")
|
await ctx.send("Error: You need to remove at least one alias.")
|
||||||
else:
|
else:
|
||||||
if remove_aliases(existing_key, list(remove_keys)):
|
if remove_aliases(self.bot, existing_key, list(remove_keys)):
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"Removed {len(remove_keys)} aliases from macro '{existing_key}'!"
|
f"Removed {len(remove_keys)} aliases from macro '{existing_key}'!"
|
||||||
)
|
)
|
||||||
|
@ -109,7 +112,7 @@ class Macro(Cog):
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def remove_macro(self, ctx: Context, key: str):
|
async def remove_macro(self, ctx: Context, key: str):
|
||||||
if remove_macro(key):
|
if remove_macro(self.bot, key):
|
||||||
await ctx.send(f"Macro '{key}' removed!")
|
await ctx.send(f"Macro '{key}' removed!")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"Error: Macro '{key}' not found.")
|
await ctx.send(f"Error: Macro '{key}' not found.")
|
||||||
|
@ -117,7 +120,7 @@ class Macro(Cog):
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command(name="aliasclear", aliases=["clearalias", "clear_alias"])
|
@commands.command(name="aliasclear", aliases=["clearalias", "clear_alias"])
|
||||||
async def clear_alias_macro(self, ctx: Context, existing_key: str):
|
async def clear_alias_macro(self, ctx: Context, existing_key: str):
|
||||||
if clear_aliases(existing_key):
|
if clear_aliases(self.bot, existing_key):
|
||||||
await ctx.send(f"Removed all aliases of macro '{existing_key}'!")
|
await ctx.send(f"Removed all aliases of macro '{existing_key}'!")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"Error: No aliases found for macro '{existing_key}'.")
|
await ctx.send(f"Error: No aliases found for macro '{existing_key}'.")
|
||||||
|
@ -125,7 +128,7 @@ class Macro(Cog):
|
||||||
@commands.cooldown(3, 30, BucketType.channel)
|
@commands.cooldown(3, 30, BucketType.channel)
|
||||||
@commands.command(name="macros", aliases=["ml", "listmacros", "list_macros"])
|
@commands.command(name="macros", aliases=["ml", "listmacros", "list_macros"])
|
||||||
async def list_macros(self, ctx: Context):
|
async def list_macros(self, ctx: Context):
|
||||||
macros = get_macros_dict()
|
macros = get_macros_dict(self.bot)
|
||||||
if len(macros["macros"]) > 0:
|
if len(macros["macros"]) > 0:
|
||||||
macros = [f"- {key}\n" for key in sorted(macros["macros"].keys())]
|
macros = [f"- {key}\n" for key in sorted(macros["macros"].keys())]
|
||||||
message = "📝 **Macros**:\n"
|
message = "📝 **Macros**:\n"
|
||||||
|
@ -138,7 +141,7 @@ class Macro(Cog):
|
||||||
@commands.cooldown(3, 30, BucketType.channel)
|
@commands.cooldown(3, 30, BucketType.channel)
|
||||||
@commands.command(name="aliases", aliases=["listaliases", "list_aliases"])
|
@commands.command(name="aliases", aliases=["listaliases", "list_aliases"])
|
||||||
async def list_aliases(self, ctx: Context, existing_key: str):
|
async def list_aliases(self, ctx: Context, existing_key: str):
|
||||||
macros = get_macros_dict()
|
macros = get_macros_dict(self.bot)
|
||||||
existing_key = existing_key.lower()
|
existing_key = existing_key.lower()
|
||||||
if existing_key in macros["aliases"].keys():
|
if existing_key in macros["aliases"].keys():
|
||||||
message = f"📝 **Aliases for '{existing_key}'**:\n"
|
message = f"📝 **Aliases for '{existing_key}'**:\n"
|
||||||
|
|
|
@ -5,7 +5,6 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff, check_if_bot_manager
|
from robocop_ng.helpers.checks import check_if_staff, check_if_bot_manager
|
||||||
from robocop_ng.helpers.restrictions import add_restriction, remove_restriction
|
from robocop_ng.helpers.restrictions import add_restriction, remove_restriction
|
||||||
from robocop_ng.helpers.userlogs import userlog
|
from robocop_ng.helpers.userlogs import userlog
|
||||||
|
@ -16,7 +15,7 @@ class Mod(Cog):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
def check_if_target_is_staff(self, target):
|
def check_if_target_is_staff(self, target):
|
||||||
return any(r.id in config.staff_role_ids for r in target.roles)
|
return any(r.id in self.bot.config.staff_role_ids for r in target.roles)
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.check(check_if_bot_manager)
|
@commands.check(check_if_bot_manager)
|
||||||
|
@ -27,7 +26,7 @@ class Mod(Cog):
|
||||||
await ctx.guild.edit(icon=img_bytes, reason=str(ctx.author))
|
await ctx.guild.edit(icon=img_bytes, reason=str(ctx.author))
|
||||||
await ctx.send(f"Done!")
|
await ctx.send(f"Done!")
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
log_msg = (
|
log_msg = (
|
||||||
f"✏️ **Guild Icon Update**: {ctx.author} changed the guild icon."
|
f"✏️ **Guild Icon Update**: {ctx.author} changed the guild icon."
|
||||||
f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
||||||
|
@ -62,7 +61,7 @@ class Mod(Cog):
|
||||||
"I can't mute this user as they're a member of staff."
|
"I can't mute this user as they're a member of staff."
|
||||||
)
|
)
|
||||||
|
|
||||||
userlog(target.id, ctx.author, reason, "mutes", target.name)
|
userlog(self.bot, target.id, ctx.author, reason, "mutes", target.name)
|
||||||
|
|
||||||
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
||||||
ctx, str(target)
|
ctx, str(target)
|
||||||
|
@ -79,7 +78,7 @@ class Mod(Cog):
|
||||||
# or has DMs disabled
|
# or has DMs disabled
|
||||||
pass
|
pass
|
||||||
|
|
||||||
mute_role = ctx.guild.get_role(config.mute_role)
|
mute_role = ctx.guild.get_role(self.bot.config.mute_role)
|
||||||
|
|
||||||
await target.add_roles(mute_role, reason=str(ctx.author))
|
await target.add_roles(mute_role, reason=str(ctx.author))
|
||||||
|
|
||||||
|
@ -99,10 +98,10 @@ class Mod(Cog):
|
||||||
|
|
||||||
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
await log_channel.send(chan_message)
|
await log_channel.send(chan_message)
|
||||||
await ctx.send(f"{target.mention} can no longer speak.")
|
await ctx.send(f"{target.mention} can no longer speak.")
|
||||||
add_restriction(target.id, config.mute_role)
|
add_restriction(self.bot, target.id, self.bot.config.mute_role)
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
|
@ -113,7 +112,7 @@ class Mod(Cog):
|
||||||
ctx, str(target)
|
ctx, str(target)
|
||||||
)
|
)
|
||||||
|
|
||||||
mute_role = ctx.guild.get_role(config.mute_role)
|
mute_role = ctx.guild.get_role(self.bot.config.mute_role)
|
||||||
await target.remove_roles(mute_role, reason=str(ctx.author))
|
await target.remove_roles(mute_role, reason=str(ctx.author))
|
||||||
|
|
||||||
chan_message = (
|
chan_message = (
|
||||||
|
@ -124,10 +123,10 @@ class Mod(Cog):
|
||||||
|
|
||||||
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
await log_channel.send(chan_message)
|
await log_channel.send(chan_message)
|
||||||
await ctx.send(f"{target.mention} can now speak again.")
|
await ctx.send(f"{target.mention} can now speak again.")
|
||||||
remove_restriction(target.id, config.mute_role)
|
remove_restriction(self.bot, target.id, self.bot.config.mute_role)
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.bot_has_permissions(kick_members=True)
|
@commands.bot_has_permissions(kick_members=True)
|
||||||
|
@ -156,7 +155,7 @@ class Mod(Cog):
|
||||||
"I can't kick this user as they're a member of staff."
|
"I can't kick this user as they're a member of staff."
|
||||||
)
|
)
|
||||||
|
|
||||||
userlog(target.id, ctx.author, reason, "kicks", target.name)
|
userlog(self.bot, target.id, ctx.author, reason, "kicks", target.name)
|
||||||
|
|
||||||
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
||||||
ctx, str(target)
|
ctx, str(target)
|
||||||
|
@ -195,7 +194,7 @@ class Mod(Cog):
|
||||||
|
|
||||||
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
await log_channel.send(chan_message)
|
await log_channel.send(chan_message)
|
||||||
await ctx.send(f"👢 {safe_name}, 👍.")
|
await ctx.send(f"👢 {safe_name}, 👍.")
|
||||||
|
|
||||||
|
@ -228,7 +227,7 @@ class Mod(Cog):
|
||||||
elif self.check_if_target_is_staff(target):
|
elif self.check_if_target_is_staff(target):
|
||||||
return await ctx.send("I can't ban this user as they're a member of staff.")
|
return await ctx.send("I can't ban this user as they're a member of staff.")
|
||||||
|
|
||||||
userlog(target.id, ctx.author, reason, "bans", target.name)
|
userlog(self.bot, target.id, ctx.author, reason, "bans", target.name)
|
||||||
|
|
||||||
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
||||||
ctx, str(target)
|
ctx, str(target)
|
||||||
|
@ -265,7 +264,7 @@ class Mod(Cog):
|
||||||
|
|
||||||
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
await log_channel.send(chan_message)
|
await log_channel.send(chan_message)
|
||||||
await ctx.send(f"{safe_name} is now b&. 👍")
|
await ctx.send(f"{safe_name} is now b&. 👍")
|
||||||
|
|
||||||
|
@ -305,7 +304,7 @@ class Mod(Cog):
|
||||||
"Message delete day count needs to be between 0 and 7 days."
|
"Message delete day count needs to be between 0 and 7 days."
|
||||||
)
|
)
|
||||||
|
|
||||||
userlog(target.id, ctx.author, reason, "bans", target.name)
|
userlog(self.bot, target.id, ctx.author, reason, "bans", target.name)
|
||||||
|
|
||||||
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
||||||
ctx, str(target)
|
ctx, str(target)
|
||||||
|
@ -343,7 +342,7 @@ class Mod(Cog):
|
||||||
|
|
||||||
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
await log_channel.send(chan_message)
|
await log_channel.send(chan_message)
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"{safe_name} is now b&, with {day_count} days of messages deleted. 👍"
|
f"{safe_name} is now b&, with {day_count} days of messages deleted. 👍"
|
||||||
|
@ -367,7 +366,7 @@ class Mod(Cog):
|
||||||
elif target_member and self.check_if_target_is_staff(target_member):
|
elif target_member and self.check_if_target_is_staff(target_member):
|
||||||
return await ctx.send("I can't ban this user as they're a member of staff.")
|
return await ctx.send("I can't ban this user as they're a member of staff.")
|
||||||
|
|
||||||
userlog(target, ctx.author, reason, "bans", target_user.name)
|
userlog(self.bot, target, ctx.author, reason, "bans", target_user.name)
|
||||||
|
|
||||||
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
||||||
ctx, str(target)
|
ctx, str(target)
|
||||||
|
@ -392,7 +391,7 @@ class Mod(Cog):
|
||||||
|
|
||||||
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
await log_channel.send(chan_message)
|
await log_channel.send(chan_message)
|
||||||
await ctx.send(f"{safe_name} is now b&. 👍")
|
await ctx.send(f"{safe_name} is now b&. 👍")
|
||||||
|
|
||||||
|
@ -421,7 +420,7 @@ class Mod(Cog):
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
userlog(target, ctx.author, f"massban", "bans", target_user.name)
|
userlog(self.bot, target, ctx.author, f"massban", "bans", target_user.name)
|
||||||
|
|
||||||
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
||||||
ctx, str(target)
|
ctx, str(target)
|
||||||
|
@ -441,7 +440,7 @@ class Mod(Cog):
|
||||||
|
|
||||||
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
await log_channel.send(chan_message)
|
await log_channel.send(chan_message)
|
||||||
await ctx.send(f"All {len(targets_int)} users are now b&. 👍")
|
await ctx.send(f"All {len(targets_int)} users are now b&. 👍")
|
||||||
|
|
||||||
|
@ -474,7 +473,7 @@ class Mod(Cog):
|
||||||
|
|
||||||
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
await log_channel.send(chan_message)
|
await log_channel.send(chan_message)
|
||||||
await ctx.send(f"{safe_name} is now unb&.")
|
await ctx.send(f"{safe_name} is now unb&.")
|
||||||
|
|
||||||
|
@ -494,7 +493,7 @@ class Mod(Cog):
|
||||||
elif self.check_if_target_is_staff(target):
|
elif self.check_if_target_is_staff(target):
|
||||||
return await ctx.send("I can't ban this user as they're a member of staff.")
|
return await ctx.send("I can't ban this user as they're a member of staff.")
|
||||||
|
|
||||||
userlog(target.id, ctx.author, reason, "bans", target.name)
|
userlog(self.bot, target.id, ctx.author, reason, "bans", target.name)
|
||||||
|
|
||||||
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
||||||
ctx, str(target)
|
ctx, str(target)
|
||||||
|
@ -519,7 +518,7 @@ class Mod(Cog):
|
||||||
|
|
||||||
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
chan_message += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
await log_channel.send(chan_message)
|
await log_channel.send(chan_message)
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
@ -529,9 +528,10 @@ class Mod(Cog):
|
||||||
self, ctx, target: Optional[discord.Member], role: str = "community"
|
self, ctx, target: Optional[discord.Member], role: str = "community"
|
||||||
):
|
):
|
||||||
"""Add a role to a user (default: community), staff only."""
|
"""Add a role to a user (default: community), staff only."""
|
||||||
if role not in config.named_roles:
|
if role not in self.bot.config.named_roles:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"No such role! Available roles: " + ",".join(config.named_roles)
|
"No such role! Available roles: "
|
||||||
|
+ ",".join(self.bot.config.named_roles)
|
||||||
)
|
)
|
||||||
|
|
||||||
if target is None and ctx.message.reference is None:
|
if target is None and ctx.message.reference is None:
|
||||||
|
@ -544,8 +544,8 @@ class Mod(Cog):
|
||||||
ctx.message.reference.message_id
|
ctx.message.reference.message_id
|
||||||
).author
|
).author
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
target_role = ctx.guild.get_role(config.named_roles[role])
|
target_role = ctx.guild.get_role(self.bot.config.named_roles[role])
|
||||||
|
|
||||||
if target_role in target.roles:
|
if target_role in target.roles:
|
||||||
return await ctx.send("Target already has this role.")
|
return await ctx.send("Target already has this role.")
|
||||||
|
@ -567,9 +567,10 @@ class Mod(Cog):
|
||||||
self, ctx, target: Optional[discord.Member], role: str = "community"
|
self, ctx, target: Optional[discord.Member], role: str = "community"
|
||||||
):
|
):
|
||||||
"""Remove a role from a user (default: community), staff only."""
|
"""Remove a role from a user (default: community), staff only."""
|
||||||
if role not in config.named_roles:
|
if role not in self.bot.config.named_roles:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"No such role! Available roles: " + ",".join(config.named_roles)
|
"No such role! Available roles: "
|
||||||
|
+ ",".join(self.bot.config.named_roles)
|
||||||
)
|
)
|
||||||
|
|
||||||
if target is None and ctx.message.reference is None:
|
if target is None and ctx.message.reference is None:
|
||||||
|
@ -582,8 +583,8 @@ class Mod(Cog):
|
||||||
ctx.message.reference.message_id
|
ctx.message.reference.message_id
|
||||||
).author
|
).author
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
target_role = ctx.guild.get_role(config.named_roles[role])
|
target_role = ctx.guild.get_role(self.bot.config.named_roles[role])
|
||||||
|
|
||||||
if target_role not in target.roles:
|
if target_role not in target.roles:
|
||||||
return await ctx.send("Target doesn't have this role.")
|
return await ctx.send("Target doesn't have this role.")
|
||||||
|
@ -603,7 +604,7 @@ class Mod(Cog):
|
||||||
@commands.command(aliases=["clear"])
|
@commands.command(aliases=["clear"])
|
||||||
async def purge(self, ctx, limit: int, channel: discord.TextChannel = None):
|
async def purge(self, ctx, limit: int, channel: discord.TextChannel = None):
|
||||||
"""Clears a given number of messages, staff only."""
|
"""Clears a given number of messages, staff only."""
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = ctx.channel
|
channel = ctx.channel
|
||||||
await channel.purge(limit=limit)
|
await channel.purge(limit=limit)
|
||||||
|
@ -639,8 +640,10 @@ class Mod(Cog):
|
||||||
"I can't warn this user as they're a member of staff."
|
"I can't warn this user as they're a member of staff."
|
||||||
)
|
)
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
warn_count = userlog(target.id, ctx.author, reason, "warns", target.name)
|
warn_count = userlog(
|
||||||
|
self.bot, target.id, ctx.author, reason, "warns", target.name
|
||||||
|
)
|
||||||
|
|
||||||
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
||||||
ctx, str(target)
|
ctx, str(target)
|
||||||
|
@ -655,7 +658,7 @@ class Mod(Cog):
|
||||||
if reason:
|
if reason:
|
||||||
msg += " The given reason is: " + reason
|
msg += " The given reason is: " + reason
|
||||||
msg += (
|
msg += (
|
||||||
f"\n\nPlease read the rules in {config.rules_url}. "
|
f"\n\nPlease read the rules in {self.bot.config.rules_url}. "
|
||||||
f"This is warn #{warn_count}."
|
f"This is warn #{warn_count}."
|
||||||
)
|
)
|
||||||
if warn_count == 2:
|
if warn_count == 2:
|
||||||
|
@ -718,7 +721,7 @@ class Mod(Cog):
|
||||||
"I can't warn this user as they're a member of staff."
|
"I can't warn this user as they're a member of staff."
|
||||||
)
|
)
|
||||||
|
|
||||||
warn_count = userlog(target, ctx.author, reason, "warns", target_user)
|
warn_count = userlog(self.bot, target, ctx.author, reason, "warns", target_user)
|
||||||
|
|
||||||
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
||||||
ctx, str(target)
|
ctx, str(target)
|
||||||
|
@ -731,7 +734,14 @@ class Mod(Cog):
|
||||||
)
|
)
|
||||||
|
|
||||||
if warn_count == 4:
|
if warn_count == 4:
|
||||||
userlog(target, ctx.author, "exceeded warn limit", "bans", target_user.name)
|
userlog(
|
||||||
|
self.bot,
|
||||||
|
target,
|
||||||
|
ctx.author,
|
||||||
|
"exceeded warn limit",
|
||||||
|
"bans",
|
||||||
|
target_user.name,
|
||||||
|
)
|
||||||
chan_msg += "**This resulted in an auto-hackban.**\n"
|
chan_msg += "**This resulted in an auto-hackban.**\n"
|
||||||
await ctx.guild.ban(
|
await ctx.guild.ban(
|
||||||
target_user,
|
target_user,
|
||||||
|
@ -750,7 +760,7 @@ class Mod(Cog):
|
||||||
|
|
||||||
chan_msg += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
chan_msg += f"\n🔗 __Jump__: <{ctx.message.jump_url}>"
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
await log_channel.send(chan_msg)
|
await log_channel.send(chan_msg)
|
||||||
await ctx.send(f"{safe_name} warned. " f"User has {warn_count} warning(s).")
|
await ctx.send(f"{safe_name} warned. " f"User has {warn_count} warning(s).")
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class ModNote(Cog):
|
||||||
@commands.command(aliases=["addnote"])
|
@commands.command(aliases=["addnote"])
|
||||||
async def note(self, ctx, target: discord.Member, *, note: str = ""):
|
async def note(self, ctx, target: discord.Member, *, note: str = ""):
|
||||||
"""Adds a note to a user, staff only."""
|
"""Adds a note to a user, staff only."""
|
||||||
userlog(target.id, ctx.author, note, "notes", target.name)
|
userlog(self.bot, target.id, ctx.author, note, "notes", target.name)
|
||||||
await ctx.send(f"{ctx.author.mention}: noted!")
|
await ctx.send(f"{ctx.author.mention}: noted!")
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
@ -23,7 +23,7 @@ class ModNote(Cog):
|
||||||
@commands.command(aliases=["addnoteid"])
|
@commands.command(aliases=["addnoteid"])
|
||||||
async def noteid(self, ctx, target: int, *, note: str = ""):
|
async def noteid(self, ctx, target: int, *, note: str = ""):
|
||||||
"""Adds a note to a user by userid, staff only."""
|
"""Adds a note to a user by userid, staff only."""
|
||||||
userlog(target, ctx.author, note, "notes")
|
userlog(self.bot, target, ctx.author, note, "notes")
|
||||||
await ctx.send(f"{ctx.author.mention}: noted!")
|
await ctx.send(f"{ctx.author.mention}: noted!")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff
|
from robocop_ng.helpers.checks import check_if_staff
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +23,7 @@ class ModReact(Cog):
|
||||||
limit: int = 50,
|
limit: int = 50,
|
||||||
):
|
):
|
||||||
"""Clears reacts from a given user in the given channel, staff only."""
|
"""Clears reacts from a given user in the given channel, staff only."""
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = ctx.channel
|
channel = ctx.channel
|
||||||
count = 0
|
count = 0
|
||||||
|
@ -49,7 +48,7 @@ class ModReact(Cog):
|
||||||
self, ctx, *, limit: int = 50, channel: discord.TextChannel = None
|
self, ctx, *, limit: int = 50, channel: discord.TextChannel = None
|
||||||
):
|
):
|
||||||
"""Clears all reacts in a given channel, staff only. Use with care."""
|
"""Clears all reacts in a given channel, staff only. Use with care."""
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = ctx.channel
|
channel = ctx.channel
|
||||||
count = 0
|
count = 0
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff
|
from robocop_ng.helpers.checks import check_if_staff
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,10 +12,10 @@ class ModReswitched(Cog):
|
||||||
@commands.command(aliases=["pingmods", "summonmods"])
|
@commands.command(aliases=["pingmods", "summonmods"])
|
||||||
async def pingmod(self, ctx):
|
async def pingmod(self, ctx):
|
||||||
"""Pings mods, only use when there's an emergency."""
|
"""Pings mods, only use when there's an emergency."""
|
||||||
can_ping = any(r.id in config.pingmods_allow for r in ctx.author.roles)
|
can_ping = any(r.id in self.bot.config.pingmods_allow for r in ctx.author.roles)
|
||||||
if can_ping:
|
if can_ping:
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"<@&{config.pingmods_role}>: {ctx.author.mention} needs assistance."
|
f"<@&{self.bot.config.pingmods_role}>: {ctx.author.mention} needs assistance."
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
|
@ -28,7 +27,7 @@ class ModReswitched(Cog):
|
||||||
@commands.command(aliases=["togglemod"])
|
@commands.command(aliases=["togglemod"])
|
||||||
async def modtoggle(self, ctx):
|
async def modtoggle(self, ctx):
|
||||||
"""Toggles your mod role, staff only."""
|
"""Toggles your mod role, staff only."""
|
||||||
target_role = ctx.guild.get_role(config.modtoggle_role)
|
target_role = ctx.guild.get_role(self.bot.config.modtoggle_role)
|
||||||
|
|
||||||
if target_role in ctx.author.roles:
|
if target_role in ctx.author.roles:
|
||||||
await ctx.author.remove_roles(
|
await ctx.author.remove_roles(
|
||||||
|
|
|
@ -5,7 +5,6 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff
|
from robocop_ng.helpers.checks import check_if_staff
|
||||||
from robocop_ng.helpers.restrictions import add_restriction
|
from robocop_ng.helpers.restrictions import add_restriction
|
||||||
from robocop_ng.helpers.robocronp import add_job
|
from robocop_ng.helpers.robocronp import add_job
|
||||||
|
@ -17,7 +16,7 @@ class ModTimed(Cog):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
def check_if_target_is_staff(self, target):
|
def check_if_target_is_staff(self, target):
|
||||||
return any(r.id in config.staff_role_ids for r in target.roles)
|
return any(r.id in self.bot.config.staff_role_ids for r in target.roles)
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.bot_has_permissions(ban_members=True)
|
@commands.bot_has_permissions(ban_members=True)
|
||||||
|
@ -49,6 +48,7 @@ class ModTimed(Cog):
|
||||||
)
|
)
|
||||||
|
|
||||||
userlog(
|
userlog(
|
||||||
|
self.bot,
|
||||||
target.id,
|
target.id,
|
||||||
ctx.author,
|
ctx.author,
|
||||||
f"{reason} (Timed, until " f"{duration_text})",
|
f"{reason} (Timed, until " f"{duration_text})",
|
||||||
|
@ -89,9 +89,9 @@ class ModTimed(Cog):
|
||||||
" as the reason is automatically sent to the user."
|
" as the reason is automatically sent to the user."
|
||||||
)
|
)
|
||||||
|
|
||||||
add_job("unban", target.id, {"guild": ctx.guild.id}, expiry_timestamp)
|
add_job(self.bot, "unban", target.id, {"guild": ctx.guild.id}, expiry_timestamp)
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.log_channel)
|
log_channel = self.bot.get_channel(self.bot.config.log_channel)
|
||||||
await log_channel.send(chan_message)
|
await log_channel.send(chan_message)
|
||||||
await ctx.send(f"{safe_name} is now b&. " f"It will expire {duration_text}. 👍")
|
await ctx.send(f"{safe_name} is now b&. " f"It will expire {duration_text}. 👍")
|
||||||
|
|
||||||
|
@ -126,6 +126,7 @@ class ModTimed(Cog):
|
||||||
)
|
)
|
||||||
|
|
||||||
userlog(
|
userlog(
|
||||||
|
self.bot,
|
||||||
target.id,
|
target.id,
|
||||||
ctx.author,
|
ctx.author,
|
||||||
f"{reason} (Timed, until " f"{duration_text})",
|
f"{reason} (Timed, until " f"{duration_text})",
|
||||||
|
@ -149,7 +150,7 @@ class ModTimed(Cog):
|
||||||
# or has DMs disabled
|
# or has DMs disabled
|
||||||
pass
|
pass
|
||||||
|
|
||||||
mute_role = ctx.guild.get_role(config.mute_role)
|
mute_role = ctx.guild.get_role(self.bot.config.mute_role)
|
||||||
|
|
||||||
await target.add_roles(mute_role, reason=str(ctx.author))
|
await target.add_roles(mute_role, reason=str(ctx.author))
|
||||||
|
|
||||||
|
@ -167,14 +168,16 @@ class ModTimed(Cog):
|
||||||
" as the reason is automatically sent to the user."
|
" as the reason is automatically sent to the user."
|
||||||
)
|
)
|
||||||
|
|
||||||
add_job("unmute", target.id, {"guild": ctx.guild.id}, expiry_timestamp)
|
add_job(
|
||||||
|
self.bot, "unmute", target.id, {"guild": ctx.guild.id}, expiry_timestamp
|
||||||
|
)
|
||||||
|
|
||||||
log_channel = self.bot.get_channel(config.log_channel)
|
log_channel = self.bot.get_channel(self.bot.config.log_channel)
|
||||||
await log_channel.send(chan_message)
|
await log_channel.send(chan_message)
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"{target.mention} can no longer speak. " f"It will expire {duration_text}."
|
f"{target.mention} can no longer speak. " f"It will expire {duration_text}."
|
||||||
)
|
)
|
||||||
add_restriction(target.id, config.mute_role)
|
add_restriction(self.bot, target.id, self.bot.config.mute_role)
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
async def setup(bot):
|
||||||
|
|
|
@ -4,7 +4,6 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff
|
from robocop_ng.helpers.checks import check_if_staff
|
||||||
from robocop_ng.helpers.userlogs import get_userlog, set_userlog, userlog_event_types
|
from robocop_ng.helpers.userlogs import get_userlog, set_userlog, userlog_event_types
|
||||||
|
|
||||||
|
@ -22,7 +21,7 @@ class ModUserlog(Cog):
|
||||||
wanted_events = [event]
|
wanted_events = [event]
|
||||||
embed = discord.Embed(color=discord.Color.dark_red())
|
embed = discord.Embed(color=discord.Color.dark_red())
|
||||||
embed.set_author(name=f"Userlog for {name}")
|
embed.set_author(name=f"Userlog for {name}")
|
||||||
userlog = get_userlog()
|
userlog = get_userlog(self.bot)
|
||||||
|
|
||||||
if uid not in userlog:
|
if uid not in userlog:
|
||||||
embed.description = f"There are none!{own_note} (no entry)"
|
embed.description = f"There are none!{own_note} (no entry)"
|
||||||
|
@ -55,18 +54,18 @@ class ModUserlog(Cog):
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
def clear_event_from_id(self, uid: str, event_type):
|
def clear_event_from_id(self, uid: str, event_type):
|
||||||
userlog = get_userlog()
|
userlog = get_userlog(self.bot)
|
||||||
if uid not in userlog:
|
if uid not in userlog:
|
||||||
return f"<@{uid}> has no {event_type}!"
|
return f"<@{uid}> has no {event_type}!"
|
||||||
event_count = len(userlog[uid][event_type])
|
event_count = len(userlog[uid][event_type])
|
||||||
if not event_count:
|
if not event_count:
|
||||||
return f"<@{uid}> has no {event_type}!"
|
return f"<@{uid}> has no {event_type}!"
|
||||||
userlog[uid][event_type] = []
|
userlog[uid][event_type] = []
|
||||||
set_userlog(json.dumps(userlog))
|
set_userlog(self.bot, json.dumps(userlog))
|
||||||
return f"<@{uid}> no longer has any {event_type}!"
|
return f"<@{uid}> no longer has any {event_type}!"
|
||||||
|
|
||||||
def delete_event_from_id(self, uid: str, idx: int, event_type):
|
def delete_event_from_id(self, uid: str, idx: int, event_type):
|
||||||
userlog = get_userlog()
|
userlog = get_userlog(self.bot)
|
||||||
if uid not in userlog:
|
if uid not in userlog:
|
||||||
return f"<@{uid}> has no {event_type}!"
|
return f"<@{uid}> has no {event_type}!"
|
||||||
event_count = len(userlog[uid][event_type])
|
event_count = len(userlog[uid][event_type])
|
||||||
|
@ -85,7 +84,7 @@ class ModUserlog(Cog):
|
||||||
f"Reason: {event['reason']}",
|
f"Reason: {event['reason']}",
|
||||||
)
|
)
|
||||||
del userlog[uid][event_type][idx - 1]
|
del userlog[uid][event_type][idx - 1]
|
||||||
set_userlog(json.dumps(userlog))
|
set_userlog(self.bot, json.dumps(userlog))
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
@ -137,7 +136,7 @@ class ModUserlog(Cog):
|
||||||
@commands.command(aliases=["clearwarns"])
|
@commands.command(aliases=["clearwarns"])
|
||||||
async def clearevent(self, ctx, target: discord.Member, event="warns"):
|
async def clearevent(self, ctx, target: discord.Member, event="warns"):
|
||||||
"""Clears all events of given type for a user, staff only."""
|
"""Clears all events of given type for a user, staff only."""
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
msg = self.clear_event_from_id(str(target.id), event)
|
msg = self.clear_event_from_id(str(target.id), event)
|
||||||
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
safe_name = await commands.clean_content(escape_markdown=True).convert(
|
||||||
ctx, str(target)
|
ctx, str(target)
|
||||||
|
@ -156,7 +155,7 @@ class ModUserlog(Cog):
|
||||||
@commands.command(aliases=["clearwarnsid"])
|
@commands.command(aliases=["clearwarnsid"])
|
||||||
async def cleareventid(self, ctx, target: int, event="warns"):
|
async def cleareventid(self, ctx, target: int, event="warns"):
|
||||||
"""Clears all events of given type for a userid, staff only."""
|
"""Clears all events of given type for a userid, staff only."""
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
msg = self.clear_event_from_id(str(target), event)
|
msg = self.clear_event_from_id(str(target), event)
|
||||||
await ctx.send(msg)
|
await ctx.send(msg)
|
||||||
msg = (
|
msg = (
|
||||||
|
@ -171,7 +170,7 @@ class ModUserlog(Cog):
|
||||||
@commands.command(aliases=["delwarn"])
|
@commands.command(aliases=["delwarn"])
|
||||||
async def delevent(self, ctx, target: discord.Member, idx: int, event="warns"):
|
async def delevent(self, ctx, target: discord.Member, idx: int, event="warns"):
|
||||||
"""Removes a specific event from a user, staff only."""
|
"""Removes a specific event from a user, staff only."""
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
del_event = self.delete_event_from_id(str(target.id), idx, event)
|
del_event = self.delete_event_from_id(str(target.id), idx, event)
|
||||||
event_name = userlog_event_types[event].lower()
|
event_name = userlog_event_types[event].lower()
|
||||||
# This is hell.
|
# This is hell.
|
||||||
|
@ -195,7 +194,7 @@ class ModUserlog(Cog):
|
||||||
@commands.command(aliases=["delwarnid"])
|
@commands.command(aliases=["delwarnid"])
|
||||||
async def deleventid(self, ctx, target: int, idx: int, event="warns"):
|
async def deleventid(self, ctx, target: int, idx: int, event="warns"):
|
||||||
"""Removes a specific event from a userid, staff only."""
|
"""Removes a specific event from a userid, staff only."""
|
||||||
log_channel = self.bot.get_channel(config.modlog_channel)
|
log_channel = self.bot.get_channel(self.bot.config.modlog_channel)
|
||||||
del_event = self.delete_event_from_id(str(target), idx, event)
|
del_event = self.delete_event_from_id(str(target), idx, event)
|
||||||
event_name = userlog_event_types[event].lower()
|
event_name = userlog_event_types[event].lower()
|
||||||
# This is hell.
|
# This is hell.
|
||||||
|
|
|
@ -15,7 +15,7 @@ class ModWatch(Cog):
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def watch(self, ctx, target: discord.Member, *, note: str = ""):
|
async def watch(self, ctx, target: discord.Member, *, note: str = ""):
|
||||||
"""Puts a user under watch, staff only."""
|
"""Puts a user under watch, staff only."""
|
||||||
setwatch(target.id, ctx.author, True, target.name)
|
setwatch(self.bot, target.id, ctx.author, True, target.name)
|
||||||
await ctx.send(f"{ctx.author.mention}: user is now on watch.")
|
await ctx.send(f"{ctx.author.mention}: user is now on watch.")
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
@ -23,7 +23,7 @@ class ModWatch(Cog):
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def watchid(self, ctx, target: int, *, note: str = ""):
|
async def watchid(self, ctx, target: int, *, note: str = ""):
|
||||||
"""Puts a user under watch by userid, staff only."""
|
"""Puts a user under watch by userid, staff only."""
|
||||||
setwatch(target, ctx.author, True, target.name)
|
setwatch(self.bot, target, ctx.author, True, target.name)
|
||||||
await ctx.send(f"{target.mention}: user is now on watch.")
|
await ctx.send(f"{target.mention}: user is now on watch.")
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
@ -31,7 +31,7 @@ class ModWatch(Cog):
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def unwatch(self, ctx, target: discord.Member, *, note: str = ""):
|
async def unwatch(self, ctx, target: discord.Member, *, note: str = ""):
|
||||||
"""Removes a user from watch, staff only."""
|
"""Removes a user from watch, staff only."""
|
||||||
setwatch(target.id, ctx.author, False, target.name)
|
setwatch(self.bot, target.id, ctx.author, False, target.name)
|
||||||
await ctx.send(f"{ctx.author.mention}: user is now not on watch.")
|
await ctx.send(f"{ctx.author.mention}: user is now not on watch.")
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
@ -39,7 +39,7 @@ class ModWatch(Cog):
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def unwatchid(self, ctx, target: int, *, note: str = ""):
|
async def unwatchid(self, ctx, target: int, *, note: str = ""):
|
||||||
"""Removes a user from watch by userid, staff only."""
|
"""Removes a user from watch by userid, staff only."""
|
||||||
setwatch(target, ctx.author, False, target.name)
|
setwatch(self.bot, target, ctx.author, False, target.name)
|
||||||
await ctx.send(f"{target.mention}: user is now not on watch.")
|
await ctx.send(f"{target.mention}: user is now not on watch.")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ from discord.enums import MessageType
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_collaborator
|
from robocop_ng.helpers.checks import check_if_collaborator
|
||||||
from robocop_ng.helpers.checks import check_if_pin_channel
|
from robocop_ng.helpers.checks import check_if_pin_channel
|
||||||
|
|
||||||
|
@ -60,13 +59,13 @@ class Pin(Cog):
|
||||||
return (data["id"], data["files"]["pinboard.md"]["content"])
|
return (data["id"], data["files"]["pinboard.md"]["content"])
|
||||||
|
|
||||||
async def add_pin_to_pinboard(self, channel, data):
|
async def add_pin_to_pinboard(self, channel, data):
|
||||||
if config.github_oauth_token == "":
|
if self.bot.config.github_oauth_token == "":
|
||||||
# Don't add to gist pinboard if we don't have an oauth token
|
# Don't add to gist pinboard if we don't have an oauth token
|
||||||
return
|
return
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
gh = gidgethub.aiohttp.GitHubAPI(
|
gh = gidgethub.aiohttp.GitHubAPI(
|
||||||
session, "RoboCop-NG", oauth_token=config.github_oauth_token
|
session, "RoboCop-NG", oauth_token=self.bot.config.github_oauth_token
|
||||||
)
|
)
|
||||||
(id, content) = await self.get_pinboard(gh, channel)
|
(id, content) = await self.get_pinboard(gh, channel)
|
||||||
content += "- " + data + "\n"
|
content += "- " + data + "\n"
|
||||||
|
@ -103,7 +102,7 @@ class Pin(Cog):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check that reaction pinning is allowd in this channel
|
# Check that reaction pinning is allowd in this channel
|
||||||
if payload.channel_id not in config.allowed_pin_channels:
|
if payload.channel_id not in self.bot.config.allowed_pin_channels:
|
||||||
return
|
return
|
||||||
|
|
||||||
target_guild = self.bot.get_guild(payload.guild_id)
|
target_guild = self.bot.get_guild(payload.guild_id)
|
||||||
|
@ -112,7 +111,7 @@ class Pin(Cog):
|
||||||
|
|
||||||
# Check that the user is allowed to reaction-pin
|
# Check that the user is allowed to reaction-pin
|
||||||
target_user = target_guild.get_member(payload.user_id)
|
target_user = target_guild.get_member(payload.user_id)
|
||||||
for role in config.staff_role_ids + config.allowed_pin_roles:
|
for role in self.bot.config.staff_role_ids + self.bot.config.allowed_pin_roles:
|
||||||
if role in [role.id for role in target_user.roles]:
|
if role in [role.id for role in target_user.roles]:
|
||||||
target_chan = self.bot.get_channel(payload.channel_id)
|
target_chan = self.bot.get_channel(payload.channel_id)
|
||||||
target_msg = await target_chan.get_message(payload.message_id)
|
target_msg = await target_chan.get_message(payload.message_id)
|
||||||
|
|
|
@ -17,7 +17,7 @@ class Remind(Cog):
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def remindlist(self, ctx):
|
async def remindlist(self, ctx):
|
||||||
"""Lists your reminders."""
|
"""Lists your reminders."""
|
||||||
ctab = get_crontab()
|
ctab = get_crontab(self.bot)
|
||||||
uid = str(ctx.author.id)
|
uid = str(ctx.author.id)
|
||||||
embed = discord.Embed(title=f"Active robocronp jobs")
|
embed = discord.Embed(title=f"Active robocronp jobs")
|
||||||
for jobtimestamp in ctab["remind"]:
|
for jobtimestamp in ctab["remind"]:
|
||||||
|
@ -61,6 +61,7 @@ class Remind(Cog):
|
||||||
added_on = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S (UTC)")
|
added_on = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S (UTC)")
|
||||||
|
|
||||||
add_job(
|
add_job(
|
||||||
|
self.bot,
|
||||||
"remind",
|
"remind",
|
||||||
ctx.author.id,
|
ctx.author.id,
|
||||||
{"text": safe_text, "added": added_on},
|
{"text": safe_text, "added": added_on},
|
||||||
|
|
|
@ -5,7 +5,6 @@ import discord
|
||||||
from discord.ext import commands, tasks
|
from discord.ext import commands, tasks
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff
|
from robocop_ng.helpers.checks import check_if_staff
|
||||||
from robocop_ng.helpers.restrictions import remove_restriction
|
from robocop_ng.helpers.restrictions import remove_restriction
|
||||||
from robocop_ng.helpers.robocronp import get_crontab, delete_job
|
from robocop_ng.helpers.robocronp import get_crontab, delete_job
|
||||||
|
@ -26,7 +25,7 @@ class Robocronp(Cog):
|
||||||
async def send_data(self):
|
async def send_data(self):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
data_files = [discord.File(fpath) for fpath in self.bot.wanted_jsons]
|
data_files = [discord.File(fpath) for fpath in self.bot.wanted_jsons]
|
||||||
log_channel = await self.bot.get_channel_safe(config.botlog_channel)
|
log_channel = await self.bot.get_channel_safe(self.bot.config.botlog_channel)
|
||||||
await log_channel.send("Hourly data backups:", files=data_files)
|
await log_channel.send("Hourly data backups:", files=data_files)
|
||||||
|
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
|
@ -34,7 +33,7 @@ class Robocronp(Cog):
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def listjobs(self, ctx):
|
async def listjobs(self, ctx):
|
||||||
"""Lists timed robocronp jobs, staff only."""
|
"""Lists timed robocronp jobs, staff only."""
|
||||||
ctab = get_crontab()
|
ctab = get_crontab(self.bot)
|
||||||
embed = discord.Embed(title=f"Active robocronp jobs")
|
embed = discord.Embed(title=f"Active robocronp jobs")
|
||||||
for jobtype in ctab:
|
for jobtype in ctab:
|
||||||
for jobtimestamp in ctab[jobtype]:
|
for jobtimestamp in ctab[jobtype]:
|
||||||
|
@ -59,31 +58,31 @@ class Robocronp(Cog):
|
||||||
- job name (userid, like 420332322307571713)
|
- job name (userid, like 420332322307571713)
|
||||||
|
|
||||||
You can get all 3 from listjobs command."""
|
You can get all 3 from listjobs command."""
|
||||||
delete_job(timestamp, job_type, job_name)
|
delete_job(self.bot, timestamp, job_type, job_name)
|
||||||
await ctx.send(f"{ctx.author.mention}: Deleted!")
|
await ctx.send(f"{ctx.author.mention}: Deleted!")
|
||||||
|
|
||||||
async def do_jobs(self, ctab, jobtype, timestamp):
|
async def do_jobs(self, ctab, jobtype, timestamp):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
log_channel = await self.bot.get_channel_safe(config.botlog_channel)
|
log_channel = await self.bot.get_channel_safe(self.bot.config.botlog_channel)
|
||||||
for job_name in ctab[jobtype][timestamp]:
|
for job_name in ctab[jobtype][timestamp]:
|
||||||
try:
|
try:
|
||||||
job_details = ctab[jobtype][timestamp][job_name]
|
job_details = ctab[jobtype][timestamp][job_name]
|
||||||
if jobtype == "unban":
|
if jobtype == "unban":
|
||||||
target_user = await self.bot.fetch_user(job_name)
|
target_user = await self.bot.fetch_user(job_name)
|
||||||
target_guild = self.bot.get_guild(job_details["guild"])
|
target_guild = self.bot.get_guild(job_details["guild"])
|
||||||
delete_job(timestamp, jobtype, job_name)
|
delete_job(self.bot, timestamp, jobtype, job_name)
|
||||||
await target_guild.unban(
|
await target_guild.unban(
|
||||||
target_user, reason="Robocronp: Timed ban expired."
|
target_user, reason="Robocronp: Timed ban expired."
|
||||||
)
|
)
|
||||||
elif jobtype == "unmute":
|
elif jobtype == "unmute":
|
||||||
remove_restriction(job_name, config.mute_role)
|
remove_restriction(self.bot, job_name, self.bot.config.mute_role)
|
||||||
target_guild = self.bot.get_guild(job_details["guild"])
|
target_guild = self.bot.get_guild(job_details["guild"])
|
||||||
target_member = target_guild.get_member(int(job_name))
|
target_member = target_guild.get_member(int(job_name))
|
||||||
target_role = target_guild.get_role(config.mute_role)
|
target_role = target_guild.get_role(self.bot.config.mute_role)
|
||||||
await target_member.remove_roles(
|
await target_member.remove_roles(
|
||||||
target_role, reason="Robocronp: Timed mute expired."
|
target_role, reason="Robocronp: Timed mute expired."
|
||||||
)
|
)
|
||||||
delete_job(timestamp, jobtype, job_name)
|
delete_job(self.bot, timestamp, jobtype, job_name)
|
||||||
elif jobtype == "remind":
|
elif jobtype == "remind":
|
||||||
text = job_details["text"]
|
text = job_details["text"]
|
||||||
added_on = job_details["added"]
|
added_on = job_details["added"]
|
||||||
|
@ -92,10 +91,10 @@ class Robocronp(Cog):
|
||||||
await target.send(
|
await target.send(
|
||||||
f"You asked to be reminded about `{text}` on {added_on}."
|
f"You asked to be reminded about `{text}` on {added_on}."
|
||||||
)
|
)
|
||||||
delete_job(timestamp, jobtype, job_name)
|
delete_job(self.bot, timestamp, jobtype, job_name)
|
||||||
except:
|
except:
|
||||||
# Don't kill cronjobs if something goes wrong.
|
# Don't kill cronjobs if something goes wrong.
|
||||||
delete_job(timestamp, jobtype, job_name)
|
delete_job(self.bot, timestamp, jobtype, job_name)
|
||||||
await log_channel.send(
|
await log_channel.send(
|
||||||
"Crondo has errored, job deleted: ```"
|
"Crondo has errored, job deleted: ```"
|
||||||
f"{traceback.format_exc()}```"
|
f"{traceback.format_exc()}```"
|
||||||
|
@ -103,7 +102,7 @@ class Robocronp(Cog):
|
||||||
|
|
||||||
async def clean_channel(self, channel_id):
|
async def clean_channel(self, channel_id):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
log_channel = await self.bot.get_channel_safe(config.botlog_channel)
|
log_channel = await self.bot.get_channel_safe(self.bot.config.botlog_channel)
|
||||||
channel = await self.bot.get_channel_safe(channel_id)
|
channel = await self.bot.get_channel_safe(channel_id)
|
||||||
try:
|
try:
|
||||||
done_cleaning = False
|
done_cleaning = False
|
||||||
|
@ -125,9 +124,9 @@ class Robocronp(Cog):
|
||||||
@tasks.loop(minutes=1)
|
@tasks.loop(minutes=1)
|
||||||
async def minutely(self):
|
async def minutely(self):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
log_channel = await self.bot.get_channel_safe(config.botlog_channel)
|
log_channel = await self.bot.get_channel_safe(self.bot.config.botlog_channel)
|
||||||
try:
|
try:
|
||||||
ctab = get_crontab()
|
ctab = get_crontab(self.bot)
|
||||||
timestamp = time.time()
|
timestamp = time.time()
|
||||||
for jobtype in ctab:
|
for jobtype in ctab:
|
||||||
for jobtimestamp in ctab[jobtype]:
|
for jobtimestamp in ctab[jobtype]:
|
||||||
|
@ -135,7 +134,7 @@ class Robocronp(Cog):
|
||||||
await self.do_jobs(ctab, jobtype, jobtimestamp)
|
await self.do_jobs(ctab, jobtype, jobtimestamp)
|
||||||
|
|
||||||
# Handle clean channels
|
# Handle clean channels
|
||||||
for clean_channel in config.minutely_clean_channels:
|
for clean_channel in self.bot.config.minutely_clean_channels:
|
||||||
await self.clean_channel(clean_channel)
|
await self.clean_channel(clean_channel)
|
||||||
except:
|
except:
|
||||||
# Don't kill cronjobs if something goes wrong.
|
# Don't kill cronjobs if something goes wrong.
|
||||||
|
@ -146,11 +145,11 @@ class Robocronp(Cog):
|
||||||
@tasks.loop(hours=1)
|
@tasks.loop(hours=1)
|
||||||
async def hourly(self):
|
async def hourly(self):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
log_channel = await self.bot.get_channel_safe(config.botlog_channel)
|
log_channel = await self.bot.get_channel_safe(self.bot.config.botlog_channel)
|
||||||
try:
|
try:
|
||||||
await self.send_data()
|
await self.send_data()
|
||||||
# Handle clean channels
|
# Handle clean channels
|
||||||
for clean_channel in config.hourly_clean_channels:
|
for clean_channel in self.bot.config.hourly_clean_channels:
|
||||||
await self.clean_channel(clean_channel)
|
await self.clean_channel(clean_channel)
|
||||||
except:
|
except:
|
||||||
# Don't kill cronjobs if something goes wrong.
|
# Don't kill cronjobs if something goes wrong.
|
||||||
|
@ -161,11 +160,13 @@ class Robocronp(Cog):
|
||||||
@tasks.loop(hours=24)
|
@tasks.loop(hours=24)
|
||||||
async def daily(self):
|
async def daily(self):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
log_channel = await self.bot.get_channel_safe(config.botlog_channel)
|
log_channel = await self.bot.get_channel_safe(self.bot.config.botlog_channel)
|
||||||
try:
|
try:
|
||||||
# Reset verification and algorithm
|
# Reset verification and algorithm
|
||||||
if "cogs.verification" in config.initial_cogs:
|
if "cogs.verification" in self.bot.config.initial_cogs:
|
||||||
verif_channel = await self.bot.get_channel_safe(config.welcome_channel)
|
verif_channel = await self.bot.get_channel_safe(
|
||||||
|
self.bot.config.welcome_channel
|
||||||
|
)
|
||||||
await self.bot.do_resetalgo(verif_channel, "daily robocronp")
|
await self.bot.do_resetalgo(verif_channel, "daily robocronp")
|
||||||
except:
|
except:
|
||||||
# Don't kill cronjobs if something goes wrong.
|
# Don't kill cronjobs if something goes wrong.
|
||||||
|
|
|
@ -22,11 +22,11 @@ class RolePersistence(Cog):
|
||||||
save_roles.append(role.id)
|
save_roles.append(role.id)
|
||||||
|
|
||||||
if len(save_roles) > 0:
|
if len(save_roles) > 0:
|
||||||
add_user_roles(payload.user.id, save_roles)
|
add_user_roles(self.bot, payload.user.id, save_roles)
|
||||||
|
|
||||||
@Cog.listener()
|
@Cog.listener()
|
||||||
async def on_member_join(self, member: Member):
|
async def on_member_join(self, member: Member):
|
||||||
user_roles = get_user_roles(member.id)
|
user_roles = get_user_roles(self.bot, member.id)
|
||||||
if len(user_roles) > 0:
|
if len(user_roles) > 0:
|
||||||
user_roles = [
|
user_roles = [
|
||||||
member.guild.get_role(int(role))
|
member.guild.get_role(int(role))
|
||||||
|
|
|
@ -6,7 +6,6 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff
|
from robocop_ng.helpers.checks import check_if_staff
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,10 +13,12 @@ class RyujinxReactionRoles(Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.channel_id = (
|
self.channel_id = (
|
||||||
config.reaction_roles_channel_id
|
self.bot.config.reaction_roles_channel_id
|
||||||
) # The channel to send the reaction role message. (self-roles channel)
|
) # The channel to send the reaction role message. (self-roles channel)
|
||||||
|
|
||||||
self.file = "data/reactionroles.json" # the file to store the required reaction role data. (message id of the RR message.)
|
self.file = os.path.join(
|
||||||
|
self.bot.state_dir, "data/reactionroles.json"
|
||||||
|
) # the file to store the required reaction role data. (message id of the RR message.)
|
||||||
|
|
||||||
self.msg_id = None
|
self.msg_id = None
|
||||||
self.m = None # the msg object
|
self.m = None # the msg object
|
||||||
|
@ -33,7 +34,7 @@ class RyujinxReactionRoles(Cog):
|
||||||
if emoji_name[0] == "<":
|
if emoji_name[0] == "<":
|
||||||
emoji_name = emoji_name[1:-1]
|
emoji_name = emoji_name[1:-1]
|
||||||
|
|
||||||
if target_role_id in config.staff_role_ids:
|
if target_role_id in self.bot.config.staff_role_ids:
|
||||||
return await ctx.send("Error: Dangerous role found!")
|
return await ctx.send("Error: Dangerous role found!")
|
||||||
|
|
||||||
target_role = ctx.guild.get_role(target_role_id)
|
target_role = ctx.guild.get_role(target_role_id)
|
||||||
|
@ -155,7 +156,6 @@ class RyujinxReactionRoles(Cog):
|
||||||
|
|
||||||
def load_reaction_config(self):
|
def load_reaction_config(self):
|
||||||
if not os.path.exists(self.file):
|
if not os.path.exists(self.file):
|
||||||
self.bot.log.error("HERE?!")
|
|
||||||
with open(self.file, "w") as f:
|
with open(self.file, "w") as f:
|
||||||
json.dump({}, f)
|
json.dump({}, f)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff
|
from robocop_ng.helpers.checks import check_if_staff
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,10 +17,10 @@ class RyujinxVerification(Cog):
|
||||||
async def on_member_join(self, member):
|
async def on_member_join(self, member):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
|
|
||||||
if member.guild.id not in config.guild_whitelist:
|
if member.guild.id not in self.bot.config.guild_whitelist:
|
||||||
return
|
return
|
||||||
|
|
||||||
join_channel = self.bot.get_channel(config.welcome_channel)
|
join_channel = self.bot.get_channel(self.bot.config.welcome_channel)
|
||||||
|
|
||||||
if join_channel is not None:
|
if join_channel is not None:
|
||||||
await join_channel.send(
|
await join_channel.send(
|
||||||
|
@ -32,14 +31,14 @@ class RyujinxVerification(Cog):
|
||||||
|
|
||||||
async def process_message(self, message):
|
async def process_message(self, message):
|
||||||
"""Process the verification process"""
|
"""Process the verification process"""
|
||||||
if message.channel.id == config.welcome_channel:
|
if message.channel.id == self.bot.config.welcome_channel:
|
||||||
# Assign common stuff into variables to make stuff less of a mess
|
# Assign common stuff into variables to make stuff less of a mess
|
||||||
mcl = message.content.lower()
|
mcl = message.content.lower()
|
||||||
|
|
||||||
# Get the role we will give in case of success
|
# Get the role we will give in case of success
|
||||||
success_role = message.guild.get_role(config.participant_role)
|
success_role = message.guild.get_role(self.bot.config.participant_role)
|
||||||
|
|
||||||
if config.verification_string == mcl:
|
if self.bot.config.verification_string == mcl:
|
||||||
await message.author.add_roles(success_role)
|
await message.author.add_roles(success_role)
|
||||||
await message.delete()
|
await message.delete()
|
||||||
|
|
||||||
|
@ -69,22 +68,22 @@ class RyujinxVerification(Cog):
|
||||||
async def on_member_join(self, member):
|
async def on_member_join(self, member):
|
||||||
await self.bot.wait_until_ready()
|
await self.bot.wait_until_ready()
|
||||||
|
|
||||||
if member.guild.id not in config.guild_whitelist:
|
if member.guild.id not in self.bot.config.guild_whitelist:
|
||||||
return
|
return
|
||||||
|
|
||||||
join_channel = self.bot.get_channel(config.welcome_channel)
|
join_channel = self.bot.get_channel(self.bot.config.welcome_channel)
|
||||||
|
|
||||||
if join_channel is not None:
|
if join_channel is not None:
|
||||||
await join_channel.send(config.join_message.format(member))
|
await join_channel.send(self.bot.config.join_message.format(member))
|
||||||
|
|
||||||
@commands.check(check_if_staff)
|
@commands.check(check_if_staff)
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def reset(self, ctx, limit: int = 100, force: bool = False):
|
async def reset(self, ctx, limit: int = 100, force: bool = False):
|
||||||
"""Wipes messages and pastes the welcome message again. Staff only."""
|
"""Wipes messages and pastes the welcome message again. Staff only."""
|
||||||
if ctx.message.channel.id != config.welcome_channel and not force:
|
if ctx.message.channel.id != self.bot.config.welcome_channel and not force:
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"This command is limited to"
|
f"This command is limited to"
|
||||||
f" <#{config.welcome_channel}>, unless forced."
|
f" <#{self.bot.config.welcome_channel}>, unless forced."
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
await self.do_reset(ctx.channel, ctx.author.mention, limit)
|
await self.do_reset(ctx.channel, ctx.author.mention, limit)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff_or_ot
|
from robocop_ng.helpers.checks import check_if_staff_or_ot
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,8 +15,8 @@ class SAR(Cog):
|
||||||
"""Lists self assignable roles."""
|
"""Lists self assignable roles."""
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"Self assignable roles in this guild: "
|
"Self assignable roles in this guild: "
|
||||||
+ ",".join(config.self_assignable_roles)
|
+ ",".join(self.bot.config.self_assignable_roles)
|
||||||
+ f"\n\nRun `{config.prefixes[0]}iam role_name_goes_here` to get or remove one."
|
+ f"\n\nRun `{self.bot.config.prefixes[0]}iam role_name_goes_here` to get or remove one."
|
||||||
)
|
)
|
||||||
|
|
||||||
@commands.cooldown(1, 30, type=commands.BucketType.user)
|
@commands.cooldown(1, 30, type=commands.BucketType.user)
|
||||||
|
@ -26,12 +25,12 @@ class SAR(Cog):
|
||||||
@commands.check(check_if_staff_or_ot)
|
@commands.check(check_if_staff_or_ot)
|
||||||
async def iam(self, ctx, role: str):
|
async def iam(self, ctx, role: str):
|
||||||
"""Gets you a self assignable role."""
|
"""Gets you a self assignable role."""
|
||||||
if role not in config.self_assignable_roles:
|
if role not in self.bot.config.self_assignable_roles:
|
||||||
return await ctx.send(
|
return await ctx.send(
|
||||||
"There's no self assignable role with that name. Run .sar to see what you can self assign."
|
"There's no self assignable role with that name. Run .sar to see what you can self assign."
|
||||||
)
|
)
|
||||||
|
|
||||||
target_role = ctx.guild.get_role(config.self_assignable_roles[role])
|
target_role = ctx.guild.get_role(self.bot.config.self_assignable_roles[role])
|
||||||
|
|
||||||
if target_role in ctx.author.roles:
|
if target_role in ctx.author.roles:
|
||||||
await ctx.author.remove_roles(target_role, reason=str(ctx.author))
|
await ctx.author.remove_roles(target_role, reason=str(ctx.author))
|
||||||
|
|
|
@ -8,14 +8,13 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
from robocop_ng.helpers.checks import check_if_staff
|
from robocop_ng.helpers.checks import check_if_staff
|
||||||
|
|
||||||
|
|
||||||
class Verification(Cog):
|
class Verification(Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.hash_choice = random.choice(config.welcome_hashes)
|
self.hash_choice = random.choice(self.bot.config.welcome_hashes)
|
||||||
|
|
||||||
# Export reset channel functions
|
# Export reset channel functions
|
||||||
self.bot.do_reset = self.do_reset
|
self.bot.do_reset = self.do_reset
|
||||||
|
@ -24,10 +23,10 @@ class Verification(Cog):
|
||||||
async def do_reset(self, channel, author, limit: int = 100):
|
async def do_reset(self, channel, author, limit: int = 100):
|
||||||
await channel.purge(limit=limit)
|
await channel.purge(limit=limit)
|
||||||
|
|
||||||
await channel.send(config.welcome_header)
|
await channel.send(self.bot.config.welcome_header)
|
||||||
rules = [
|
rules = [
|
||||||
"**{}**. {}".format(i, cleandoc(r))
|
"**{}**. {}".format(i, cleandoc(r))
|
||||||
for i, r in enumerate(config.welcome_rules, 1)
|
for i, r in enumerate(self.bot.config.welcome_rules, 1)
|
||||||
]
|
]
|
||||||
rule_choice = random.randint(2, len(rules))
|
rule_choice = random.randint(2, len(rules))
|
||||||
hash_choice_str = self.hash_choice.upper()
|
hash_choice_str = self.hash_choice.upper()
|
||||||
|
@ -35,12 +34,14 @@ class Verification(Cog):
|
||||||
hash_choice_str += "-512"
|
hash_choice_str += "-512"
|
||||||
elif hash_choice_str == "BLAKE2S":
|
elif hash_choice_str == "BLAKE2S":
|
||||||
hash_choice_str += "-256"
|
hash_choice_str += "-256"
|
||||||
rules[rule_choice - 1] += "\n" + config.hidden_term_line.format(hash_choice_str)
|
rules[rule_choice - 1] += "\n" + self.bot.config.hidden_term_line.format(
|
||||||
|
hash_choice_str
|
||||||
|
)
|
||||||
msg = (
|
msg = (
|
||||||
f"🗑 **Reset**: {author} cleared {limit} messages " f" in {channel.mention}"
|
f"🗑 **Reset**: {author} cleared {limit} messages " f" in {channel.mention}"
|
||||||
)
|
)
|
||||||
msg += f"\n💬 __Current challenge location__: under rule {rule_choice}"
|
msg += f"\n💬 __Current challenge location__: under rule {rule_choice}"
|
||||||
log_channel = self.bot.get_channel(config.log_channel)
|
log_channel = self.bot.get_channel(self.bot.config.log_channel)
|
||||||
await log_channel.send(msg)
|
await log_channel.send(msg)
|
||||||
|
|
||||||
# find rule that puts us over 2,000 characters, if any
|
# find rule that puts us over 2,000 characters, if any
|
||||||
|
@ -62,19 +63,19 @@ class Verification(Cog):
|
||||||
await channel.send(item)
|
await channel.send(item)
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
for x in config.welcome_footer:
|
for x in self.bot.config.welcome_footer:
|
||||||
await channel.send(cleandoc(x))
|
await channel.send(cleandoc(x))
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
async def do_resetalgo(self, channel, author, limit: int = 100):
|
async def do_resetalgo(self, channel, author, limit: int = 100):
|
||||||
# randomize hash_choice on reset
|
# randomize hash_choice on reset
|
||||||
self.hash_choice = random.choice(tuple(config.welcome_hashes))
|
self.hash_choice = random.choice(tuple(self.bot.config.welcome_hashes))
|
||||||
|
|
||||||
msg = (
|
msg = (
|
||||||
f"📘 **Reset Algorithm**: {author} reset " f"algorithm in {channel.mention}"
|
f"📘 **Reset Algorithm**: {author} reset " f"algorithm in {channel.mention}"
|
||||||
)
|
)
|
||||||
msg += f"\n💬 __Current algorithm__: {self.hash_choice.upper()}"
|
msg += f"\n💬 __Current algorithm__: {self.hash_choice.upper()}"
|
||||||
log_channel = self.bot.get_channel(config.log_channel)
|
log_channel = self.bot.get_channel(self.bot.config.log_channel)
|
||||||
await log_channel.send(msg)
|
await log_channel.send(msg)
|
||||||
|
|
||||||
await self.do_reset(channel, author)
|
await self.do_reset(channel, author)
|
||||||
|
@ -83,10 +84,10 @@ class Verification(Cog):
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def reset(self, ctx, limit: int = 100, force: bool = False):
|
async def reset(self, ctx, limit: int = 100, force: bool = False):
|
||||||
"""Wipes messages and pastes the welcome message again. Staff only."""
|
"""Wipes messages and pastes the welcome message again. Staff only."""
|
||||||
if ctx.message.channel.id != config.welcome_channel and not force:
|
if ctx.message.channel.id != self.bot.config.welcome_channel and not force:
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"This command is limited to"
|
f"This command is limited to"
|
||||||
f" <#{config.welcome_channel}>, unless forced."
|
f" <#{self.bot.config.welcome_channel}>, unless forced."
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
await self.do_reset(ctx.channel, ctx.author.mention, limit)
|
await self.do_reset(ctx.channel, ctx.author.mention, limit)
|
||||||
|
@ -95,10 +96,10 @@ class Verification(Cog):
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def resetalgo(self, ctx, limit: int = 100, force: bool = False):
|
async def resetalgo(self, ctx, limit: int = 100, force: bool = False):
|
||||||
"""Resets the verification algorithm and does what reset does. Staff only."""
|
"""Resets the verification algorithm and does what reset does. Staff only."""
|
||||||
if ctx.message.channel.id != config.welcome_channel and not force:
|
if ctx.message.channel.id != self.bot.config.welcome_channel and not force:
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"This command is limited to"
|
f"This command is limited to"
|
||||||
f" <#{config.welcome_channel}>, unless forced."
|
f" <#{self.bot.config.welcome_channel}>, unless forced."
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ class Verification(Cog):
|
||||||
Not really a rewrite but more of a port
|
Not really a rewrite but more of a port
|
||||||
|
|
||||||
Git blame tells me that I should blame/credit Robin Lambertz"""
|
Git blame tells me that I should blame/credit Robin Lambertz"""
|
||||||
if message.channel.id == config.welcome_channel:
|
if message.channel.id == self.bot.config.welcome_channel:
|
||||||
# Assign common stuff into variables to make stuff less of a mess
|
# Assign common stuff into variables to make stuff less of a mess
|
||||||
member = message.author
|
member = message.author
|
||||||
full_name = str(member)
|
full_name = str(member)
|
||||||
|
@ -136,7 +137,7 @@ class Verification(Cog):
|
||||||
return await chan.send(snark)
|
return await chan.send(snark)
|
||||||
|
|
||||||
# Get the role we will give in case of success
|
# Get the role we will give in case of success
|
||||||
success_role = guild.get_role(config.named_roles["participant"])
|
success_role = guild.get_role(self.bot.config.named_roles["participant"])
|
||||||
|
|
||||||
# Get a list of stuff we'll allow and will consider close
|
# Get a list of stuff we'll allow and will consider close
|
||||||
allowed_names = [f"@{full_name}", full_name, str(member.id)]
|
allowed_names = [f"@{full_name}", full_name, str(member.id)]
|
||||||
|
@ -169,11 +170,13 @@ class Verification(Cog):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Detect if the user uses the wrong hash algorithm
|
# Detect if the user uses the wrong hash algorithm
|
||||||
wrong_hash_algos = list(set(config.welcome_hashes) - {self.hash_choice})
|
wrong_hash_algos = list(
|
||||||
|
set(self.bot.config.welcome_hashes) - {self.hash_choice}
|
||||||
|
)
|
||||||
for algo in wrong_hash_algos:
|
for algo in wrong_hash_algos:
|
||||||
for name in itertools.chain(allowed_names, close_names):
|
for name in itertools.chain(allowed_names, close_names):
|
||||||
if hashlib.new(algo, name.encode("utf-8")).hexdigest() in mcl:
|
if hashlib.new(algo, name.encode("utf-8")).hexdigest() in mcl:
|
||||||
log_channel = self.bot.get_channel(config.log_channel)
|
log_channel = self.bot.get_channel(self.bot.config.log_channel)
|
||||||
await log_channel.send(
|
await log_channel.send(
|
||||||
f"User {message.author.mention} tried verification with algo {algo} instead of {self.hash_choice}."
|
f"User {message.author.mention} tried verification with algo {algo} instead of {self.hash_choice}."
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,8 +6,6 @@ import secrets
|
||||||
|
|
||||||
from discord.ext.commands import Cog
|
from discord.ext.commands import Cog
|
||||||
|
|
||||||
from robocop_ng import config
|
|
||||||
|
|
||||||
|
|
||||||
class YubicoOTP(Cog):
|
class YubicoOTP(Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
@ -58,7 +56,7 @@ class YubicoOTP(Cog):
|
||||||
return int("".join(hexconv), 16)
|
return int("".join(hexconv), 16)
|
||||||
|
|
||||||
def calc_signature(self, text):
|
def calc_signature(self, text):
|
||||||
key = base64.b64decode(config.yubico_otp_secret)
|
key = base64.b64decode(self.bot.config.yubico_otp_secret)
|
||||||
signature_bytes = hmac.digest(key, text.encode(), "SHA1")
|
signature_bytes = hmac.digest(key, text.encode(), "SHA1")
|
||||||
return base64.b64encode(signature_bytes).decode()
|
return base64.b64encode(signature_bytes).decode()
|
||||||
|
|
||||||
|
@ -74,10 +72,10 @@ class YubicoOTP(Cog):
|
||||||
|
|
||||||
async def validate_yubico_otp(self, otp):
|
async def validate_yubico_otp(self, otp):
|
||||||
nonce = secrets.token_hex(15) # Random number in the valid range
|
nonce = secrets.token_hex(15) # Random number in the valid range
|
||||||
params = f"id={config.yubico_otp_client_id}&nonce={nonce}&otp={otp}"
|
params = f"id={self.bot.config.yubico_otp_client_id}&nonce={nonce}&otp={otp}"
|
||||||
|
|
||||||
# If secret is supplied, sign our request
|
# If secret is supplied, sign our request
|
||||||
if config.yubico_otp_secret:
|
if self.bot.config.yubico_otp_secret:
|
||||||
params += "&h=" + self.calc_signature(params)
|
params += "&h=" + self.calc_signature(params)
|
||||||
|
|
||||||
for api_server in self.api_servers:
|
for api_server in self.api_servers:
|
||||||
|
@ -101,7 +99,7 @@ class YubicoOTP(Cog):
|
||||||
assert datafields["nonce"] == nonce
|
assert datafields["nonce"] == nonce
|
||||||
|
|
||||||
# Verify signature if secret is present
|
# Verify signature if secret is present
|
||||||
if config.yubico_otp_secret:
|
if self.bot.config.yubico_otp_secret:
|
||||||
assert self.validate_response_signature(datafields)
|
assert self.validate_response_signature(datafields)
|
||||||
|
|
||||||
# If we got a success, then return True
|
# If we got a success, then return True
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from robocop_ng import config
|
import config
|
||||||
|
|
||||||
|
|
||||||
def check_if_staff(ctx):
|
def check_if_staff(ctx):
|
||||||
|
|
|
@ -2,12 +2,14 @@ import json
|
||||||
import os
|
import os
|
||||||
from typing import Optional, Union
|
from typing import Optional, Union
|
||||||
|
|
||||||
MACROS_FILE = "data/macros.json"
|
|
||||||
|
def get_crontab_path(bot):
|
||||||
|
return os.path.join(bot.state_dir, "data/macros.json")
|
||||||
|
|
||||||
|
|
||||||
def get_macros_dict() -> dict[str, dict[str, Union[list[str], str]]]:
|
def get_macros_dict(bot) -> dict[str, dict[str, Union[list[str], str]]]:
|
||||||
if os.path.isfile(MACROS_FILE):
|
if os.path.isfile(get_crontab_path(bot)):
|
||||||
with open(MACROS_FILE, "r") as f:
|
with open(get_crontab_path(bot), "r") as f:
|
||||||
macros = json.load(f)
|
macros = json.load(f)
|
||||||
|
|
||||||
# Migration code
|
# Migration code
|
||||||
|
@ -37,10 +39,10 @@ def get_macros_dict() -> dict[str, dict[str, Union[list[str], str]]]:
|
||||||
|
|
||||||
|
|
||||||
def is_macro_key_available(
|
def is_macro_key_available(
|
||||||
key: str, macros: dict[str, dict[str, Union[list[str], str]]] = None
|
bot, key: str, macros: dict[str, dict[str, Union[list[str], str]]] = None
|
||||||
) -> bool:
|
) -> bool:
|
||||||
if macros is None:
|
if macros is None:
|
||||||
macros = get_macros_dict()
|
macros = get_macros_dict(bot)
|
||||||
if key in macros["macros"].keys():
|
if key in macros["macros"].keys():
|
||||||
return False
|
return False
|
||||||
for aliases in macros["aliases"].values():
|
for aliases in macros["aliases"].values():
|
||||||
|
@ -49,13 +51,13 @@ def is_macro_key_available(
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def set_macros(contents: dict[str, dict[str, Union[list[str], str]]]):
|
def set_macros(bot, contents: dict[str, dict[str, Union[list[str], str]]]):
|
||||||
with open(MACROS_FILE, "w") as f:
|
with open(get_crontab_path(bot), "w") as f:
|
||||||
json.dump(contents, f)
|
json.dump(contents, f)
|
||||||
|
|
||||||
|
|
||||||
def get_macro(key: str) -> Optional[str]:
|
def get_macro(bot, key: str) -> Optional[str]:
|
||||||
macros = get_macros_dict()
|
macros = get_macros_dict(bot)
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
if key in macros["macros"].keys():
|
if key in macros["macros"].keys():
|
||||||
return macros["macros"][key]
|
return macros["macros"][key]
|
||||||
|
@ -65,43 +67,43 @@ def get_macro(key: str) -> Optional[str]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def add_macro(key: str, message: str) -> bool:
|
def add_macro(bot, key: str, message: str) -> bool:
|
||||||
macros = get_macros_dict()
|
macros = get_macros_dict(bot)
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
if is_macro_key_available(key, macros):
|
if is_macro_key_available(bot, key, macros):
|
||||||
macros["macros"][key] = message
|
macros["macros"][key] = message
|
||||||
set_macros(macros)
|
set_macros(bot, macros)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def add_aliases(key: str, aliases: list[str]) -> bool:
|
def add_aliases(bot, key: str, aliases: list[str]) -> bool:
|
||||||
macros = get_macros_dict()
|
macros = get_macros_dict(bot)
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
success = False
|
success = False
|
||||||
if key in macros["macros"].keys():
|
if key in macros["macros"].keys():
|
||||||
for alias in aliases:
|
for alias in aliases:
|
||||||
alias = alias.lower()
|
alias = alias.lower()
|
||||||
if is_macro_key_available(alias, macros):
|
if is_macro_key_available(bot, alias, macros):
|
||||||
macros["aliases"][key].append(alias)
|
macros["aliases"][key].append(alias)
|
||||||
success = True
|
success = True
|
||||||
if success:
|
if success:
|
||||||
set_macros(macros)
|
set_macros(bot, macros)
|
||||||
return success
|
return success
|
||||||
|
|
||||||
|
|
||||||
def edit_macro(key: str, message: str) -> bool:
|
def edit_macro(bot, key: str, message: str) -> bool:
|
||||||
macros = get_macros_dict()
|
macros = get_macros_dict(bot)
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
if key in macros["macros"].keys():
|
if key in macros["macros"].keys():
|
||||||
macros["macros"][key] = message
|
macros["macros"][key] = message
|
||||||
set_macros(macros)
|
set_macros(bot, macros)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def remove_aliases(key: str, aliases: list[str]) -> bool:
|
def remove_aliases(bot, key: str, aliases: list[str]) -> bool:
|
||||||
macros = get_macros_dict()
|
macros = get_macros_dict(bot)
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
success = False
|
success = False
|
||||||
if key not in macros["aliases"].keys():
|
if key not in macros["aliases"].keys():
|
||||||
|
@ -114,25 +116,25 @@ def remove_aliases(key: str, aliases: list[str]) -> bool:
|
||||||
del macros["aliases"][key]
|
del macros["aliases"][key]
|
||||||
success = True
|
success = True
|
||||||
if success:
|
if success:
|
||||||
set_macros(macros)
|
set_macros(bot, macros)
|
||||||
return success
|
return success
|
||||||
|
|
||||||
|
|
||||||
def remove_macro(key: str) -> bool:
|
def remove_macro(bot, key: str) -> bool:
|
||||||
macros = get_macros_dict()
|
macros = get_macros_dict(bot)
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
if key in macros["macros"].keys():
|
if key in macros["macros"].keys():
|
||||||
del macros["macros"][key]
|
del macros["macros"][key]
|
||||||
set_macros(macros)
|
set_macros(bot, macros)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def clear_aliases(key: str) -> bool:
|
def clear_aliases(bot, key: str) -> bool:
|
||||||
macros = get_macros_dict()
|
macros = get_macros_dict(bot)
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
if key in macros["macros"].keys() and key in macros["aliases"].keys():
|
if key in macros["macros"].keys() and key in macros["aliases"].keys():
|
||||||
del macros["aliases"][key]
|
del macros["aliases"][key]
|
||||||
set_macros(macros)
|
set_macros(bot, macros)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -1,42 +1,47 @@
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
def get_restrictions():
|
def get_restrictions_path(bot):
|
||||||
with open("data/restrictions.json", "r") as f:
|
return os.path.join(bot.state_dir, "data/restrictions.json")
|
||||||
|
|
||||||
|
|
||||||
|
def get_restrictions(bot):
|
||||||
|
with open(get_restrictions_path(bot), "r") as f:
|
||||||
return json.load(f)
|
return json.load(f)
|
||||||
|
|
||||||
|
|
||||||
def set_restrictions(contents):
|
def set_restrictions(bot, contents):
|
||||||
with open("data/restrictions.json", "w") as f:
|
with open(get_restrictions_path(bot), "w") as f:
|
||||||
f.write(contents)
|
f.write(contents)
|
||||||
|
|
||||||
|
|
||||||
def get_user_restrictions(uid):
|
def get_user_restrictions(bot, uid):
|
||||||
uid = str(uid)
|
uid = str(uid)
|
||||||
with open("data/restrictions.json", "r") as f:
|
with open(get_restrictions_path(bot), "r") as f:
|
||||||
rsts = json.load(f)
|
rsts = json.load(f)
|
||||||
if uid in rsts:
|
if uid in rsts:
|
||||||
return rsts[uid]
|
return rsts[uid]
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def add_restriction(uid, rst):
|
def add_restriction(bot, uid, rst):
|
||||||
# mostly from kurisu source, credits go to ihaveamac
|
# mostly from kurisu source, credits go to ihaveamac
|
||||||
uid = str(uid)
|
uid = str(uid)
|
||||||
rsts = get_restrictions()
|
rsts = get_restrictions(bot)
|
||||||
if uid not in rsts:
|
if uid not in rsts:
|
||||||
rsts[uid] = []
|
rsts[uid] = []
|
||||||
if rst not in rsts[uid]:
|
if rst not in rsts[uid]:
|
||||||
rsts[uid].append(rst)
|
rsts[uid].append(rst)
|
||||||
set_restrictions(json.dumps(rsts))
|
set_restrictions(bot, json.dumps(rsts))
|
||||||
|
|
||||||
|
|
||||||
def remove_restriction(uid, rst):
|
def remove_restriction(bot, uid, rst):
|
||||||
# mostly from kurisu source, credits go to ihaveamac
|
# mostly from kurisu source, credits go to ihaveamac
|
||||||
uid = str(uid)
|
uid = str(uid)
|
||||||
rsts = get_restrictions()
|
rsts = get_restrictions(bot)
|
||||||
if uid not in rsts:
|
if uid not in rsts:
|
||||||
rsts[uid] = []
|
rsts[uid] = []
|
||||||
if rst in rsts[uid]:
|
if rst in rsts[uid]:
|
||||||
rsts[uid].remove(rst)
|
rsts[uid].remove(rst)
|
||||||
set_restrictions(json.dumps(rsts))
|
set_restrictions(bot, json.dumps(rsts))
|
||||||
|
|
|
@ -1,21 +1,26 @@
|
||||||
import json
|
import json
|
||||||
import math
|
import math
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
def get_crontab():
|
def get_crontab_path(bot):
|
||||||
with open("data/robocronptab.json", "r") as f:
|
return os.path.join(bot.state_dir, "data/robocronptab.json")
|
||||||
|
|
||||||
|
|
||||||
|
def get_crontab(bot):
|
||||||
|
with open(get_crontab_path(bot), "r") as f:
|
||||||
return json.load(f)
|
return json.load(f)
|
||||||
|
|
||||||
|
|
||||||
def set_crontab(contents):
|
def set_crontab(bot, contents):
|
||||||
with open("data/robocronptab.json", "w") as f:
|
with open(get_crontab_path(bot), "w") as f:
|
||||||
f.write(contents)
|
f.write(contents)
|
||||||
|
|
||||||
|
|
||||||
def add_job(job_type, job_name, job_details, timestamp):
|
def add_job(bot, job_type, job_name, job_details, timestamp):
|
||||||
timestamp = str(math.floor(timestamp))
|
timestamp = str(math.floor(timestamp))
|
||||||
job_name = str(job_name)
|
job_name = str(job_name)
|
||||||
ctab = get_crontab()
|
ctab = get_crontab(bot)
|
||||||
|
|
||||||
if job_type not in ctab:
|
if job_type not in ctab:
|
||||||
ctab[job_type] = {}
|
ctab[job_type] = {}
|
||||||
|
@ -24,14 +29,14 @@ def add_job(job_type, job_name, job_details, timestamp):
|
||||||
ctab[job_type][timestamp] = {}
|
ctab[job_type][timestamp] = {}
|
||||||
|
|
||||||
ctab[job_type][timestamp][job_name] = job_details
|
ctab[job_type][timestamp][job_name] = job_details
|
||||||
set_crontab(json.dumps(ctab))
|
set_crontab(bot, json.dumps(ctab))
|
||||||
|
|
||||||
|
|
||||||
def delete_job(timestamp, job_type, job_name):
|
def delete_job(bot, timestamp, job_type, job_name):
|
||||||
timestamp = str(timestamp)
|
timestamp = str(timestamp)
|
||||||
job_name = str(job_name)
|
job_name = str(job_name)
|
||||||
ctab = get_crontab()
|
ctab = get_crontab(bot)
|
||||||
|
|
||||||
del ctab[job_type][timestamp][job_name]
|
del ctab[job_type][timestamp][job_name]
|
||||||
|
|
||||||
set_crontab(json.dumps(ctab))
|
set_crontab(bot, json.dumps(ctab))
|
||||||
|
|
|
@ -1,33 +1,36 @@
|
||||||
import json
|
import json
|
||||||
import os.path
|
import os.path
|
||||||
|
import os
|
||||||
PERSISTENT_ROLES_FILE = "data/persistent_roles.json"
|
|
||||||
|
|
||||||
|
|
||||||
def get_persistent_roles() -> dict[str, list[str]]:
|
def get_persistent_roles_path(bot):
|
||||||
if os.path.isfile(PERSISTENT_ROLES_FILE):
|
return os.path.join(bot.state_dir, "data/persistent_roles.json")
|
||||||
with open(PERSISTENT_ROLES_FILE, "r") as f:
|
|
||||||
|
|
||||||
|
def get_persistent_roles(bot) -> dict[str, list[str]]:
|
||||||
|
if os.path.isfile(get_persistent_roles_path(bot)):
|
||||||
|
with open(get_persistent_roles_path(bot), "r") as f:
|
||||||
return json.load(f)
|
return json.load(f)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def set_persistent_roles(contents: dict[str, list[str]]):
|
def set_persistent_roles(bot, contents: dict[str, list[str]]):
|
||||||
with open(PERSISTENT_ROLES_FILE, "w") as f:
|
with open(get_persistent_roles_path(bot), "w") as f:
|
||||||
json.dump(contents, f)
|
json.dump(contents, f)
|
||||||
|
|
||||||
|
|
||||||
def add_user_roles(uid: int, roles: list[int]):
|
def add_user_roles(bot, uid: int, roles: list[int]):
|
||||||
uid = str(uid)
|
uid = str(uid)
|
||||||
roles = [str(x) for x in roles]
|
roles = [str(x) for x in roles]
|
||||||
|
|
||||||
persistent_roles = get_persistent_roles()
|
persistent_roles = get_persistent_roles(bot)
|
||||||
persistent_roles[uid] = roles
|
persistent_roles[uid] = roles
|
||||||
set_persistent_roles(persistent_roles)
|
set_persistent_roles(bot, persistent_roles)
|
||||||
|
|
||||||
|
|
||||||
def get_user_roles(uid: int) -> list[str]:
|
def get_user_roles(bot, uid: int) -> list[str]:
|
||||||
uid = str(uid)
|
uid = str(uid)
|
||||||
with open(PERSISTENT_ROLES_FILE, "r") as f:
|
with open(get_persistent_roles_path(bot), "r") as f:
|
||||||
roles = json.load(f)
|
roles = json.load(f)
|
||||||
if uid in roles:
|
if uid in roles:
|
||||||
return roles[uid]
|
return roles[uid]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import time
|
import time
|
||||||
|
|
||||||
userlog_event_types = {
|
userlog_event_types = {
|
||||||
|
@ -10,18 +11,22 @@ userlog_event_types = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_userlog():
|
def get_userlog_path(bot):
|
||||||
with open("data/userlog.json", "r") as f:
|
return os.path.join(bot.state_dir, "data/userlog.json")
|
||||||
|
|
||||||
|
|
||||||
|
def get_userlog(bot):
|
||||||
|
with open(get_userlog_path(bot), "r") as f:
|
||||||
return json.load(f)
|
return json.load(f)
|
||||||
|
|
||||||
|
|
||||||
def set_userlog(contents):
|
def set_userlog(bot, contents):
|
||||||
with open("data/userlog.json", "w") as f:
|
with open(get_userlog_path(bot), "w") as f:
|
||||||
f.write(contents)
|
f.write(contents)
|
||||||
|
|
||||||
|
|
||||||
def fill_userlog(userid, uname):
|
def fill_userlog(bot, userid, uname):
|
||||||
userlogs = get_userlog()
|
userlogs = get_userlog(bot)
|
||||||
uid = str(userid)
|
uid = str(userid)
|
||||||
if uid not in userlogs:
|
if uid not in userlogs:
|
||||||
userlogs[uid] = {
|
userlogs[uid] = {
|
||||||
|
@ -39,8 +44,8 @@ def fill_userlog(userid, uname):
|
||||||
return userlogs, uid
|
return userlogs, uid
|
||||||
|
|
||||||
|
|
||||||
def userlog(uid, issuer, reason, event_type, uname: str = ""):
|
def userlog(bot, uid, issuer, reason, event_type, uname: str = ""):
|
||||||
userlogs, uid = fill_userlog(uid, uname)
|
userlogs, uid = fill_userlog(bot, uid, uname)
|
||||||
|
|
||||||
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||||||
log_data = {
|
log_data = {
|
||||||
|
@ -52,13 +57,13 @@ def userlog(uid, issuer, reason, event_type, uname: str = ""):
|
||||||
if event_type not in userlogs[uid]:
|
if event_type not in userlogs[uid]:
|
||||||
userlogs[uid][event_type] = []
|
userlogs[uid][event_type] = []
|
||||||
userlogs[uid][event_type].append(log_data)
|
userlogs[uid][event_type].append(log_data)
|
||||||
set_userlog(json.dumps(userlogs))
|
set_userlog(bot, json.dumps(userlogs))
|
||||||
return len(userlogs[uid][event_type])
|
return len(userlogs[uid][event_type])
|
||||||
|
|
||||||
|
|
||||||
def setwatch(uid, issuer, watch_state, uname: str = ""):
|
def setwatch(bot, uid, issuer, watch_state, uname: str = ""):
|
||||||
userlogs, uid = fill_userlog(uid, uname)
|
userlogs, uid = fill_userlog(bot, uid, uname)
|
||||||
|
|
||||||
userlogs[uid]["watch"] = watch_state
|
userlogs[uid]["watch"] = watch_state
|
||||||
set_userlog(json.dumps(userlogs))
|
set_userlog(bot, json.dumps(userlogs))
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in a new issue