Reorganize commands for future opt-in structure
This commit is contained in:
parent
0a096e4831
commit
fe3ef1ad35
24 changed files with 143 additions and 278 deletions
11
jarvis/cogs/core/__init__.py
Normal file
11
jarvis/cogs/core/__init__.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
"""JARVIS Core Cogs."""
|
||||
from naff import Client
|
||||
|
||||
from jarvis.cogs.core import admin, botutil, socials
|
||||
|
||||
|
||||
def setup(bot: Client) -> None:
|
||||
"""Add core cogs to JARVIS"""
|
||||
admin.setup(bot)
|
||||
botutil.setup(bot)
|
||||
socials.setup(bot)
|
|
@ -3,7 +3,8 @@ import logging
|
|||
|
||||
from naff import Client
|
||||
|
||||
from jarvis.cogs.admin import (
|
||||
from jarvis.cogs.core.admin import (
|
||||
autoreact,
|
||||
ban,
|
||||
filters,
|
||||
kick,
|
||||
|
@ -13,6 +14,9 @@ from jarvis.cogs.admin import (
|
|||
mute,
|
||||
purge,
|
||||
roleping,
|
||||
settings,
|
||||
temprole,
|
||||
verify,
|
||||
warning,
|
||||
)
|
||||
|
||||
|
@ -21,8 +25,12 @@ def setup(bot: Client) -> None:
|
|||
"""Add admin cogs to JARVIS"""
|
||||
logger = logging.getLogger(__name__)
|
||||
msg = "Loaded jarvis.cogs.admin.{}"
|
||||
autoreact.AutoReactCog(bot)
|
||||
logger.debug(msg.format("autoreact"))
|
||||
ban.BanCog(bot)
|
||||
logger.debug(msg.format("ban"))
|
||||
filters.FilterCog(bot)
|
||||
logger.debug(msg.format("filters"))
|
||||
kick.KickCog(bot)
|
||||
logger.debug(msg.format("kick"))
|
||||
lock.LockCog(bot)
|
||||
|
@ -37,7 +45,11 @@ def setup(bot: Client) -> None:
|
|||
logger.debug(msg.format("purge"))
|
||||
roleping.RolepingCog(bot)
|
||||
logger.debug(msg.format("roleping"))
|
||||
settings.SettingsCog(bot)
|
||||
logger.debug(msg.format("settings"))
|
||||
temprole.TemproleCog(bot)
|
||||
logger.debug(msg.format("temprole"))
|
||||
verify.VerifyCog(bot)
|
||||
logger.debug(msg.format("verify"))
|
||||
warning.WarningCog(bot)
|
||||
logger.debug(msg.format("warning"))
|
||||
filters.FilterCog(bot)
|
||||
logger.debug(msg.format("filters"))
|
|
@ -84,12 +84,8 @@ class AutoReactCog(Extension):
|
|||
opt_type=OptionTypes.CHANNEL,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="thread", description="Create a thread?", opt_type=OptionTypes.BOOLEAN, required=False
|
||||
)
|
||||
@slash_option(
|
||||
name="emote", description="Emote to add", opt_type=OptionTypes.STRING, required=False
|
||||
)
|
||||
@slash_option(name="thread", description="Create a thread?", opt_type=OptionTypes.BOOLEAN, required=False)
|
||||
@slash_option(name="emote", description="Emote to add", opt_type=OptionTypes.STRING, required=False)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _autoreact_add(
|
||||
self, ctx: InteractionContext, channel: GuildText, thread: bool = True, emote: str = None
|
||||
|
@ -152,9 +148,7 @@ class AutoReactCog(Extension):
|
|||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _autoreact_remove(
|
||||
self, ctx: InteractionContext, channel: GuildText, emote: str
|
||||
) -> None:
|
||||
async def _autoreact_remove(self, ctx: InteractionContext, channel: GuildText, emote: str) -> None:
|
||||
autoreact = await Autoreact.find_one(q(guild=ctx.guild.id, channel=channel.id))
|
||||
if not autoreact:
|
||||
await ctx.send(
|
||||
|
@ -216,9 +210,7 @@ class AutoReactCog(Extension):
|
|||
return
|
||||
message = ""
|
||||
if len(exists.reactions) > 0:
|
||||
message = f"Current active autoreacts on {channel.mention}:\n" + "\n".join(
|
||||
exists.reactions
|
||||
)
|
||||
message = f"Current active autoreacts on {channel.mention}:\n" + "\n".join(exists.reactions)
|
||||
else:
|
||||
message = f"No reactions set on {channel.mention}"
|
||||
await ctx.send(message)
|
|
@ -163,6 +163,12 @@ class BanCog(ModcaseCog):
|
|||
if mtype == "temp":
|
||||
user_message += f"\nDuration: {duration} hours"
|
||||
|
||||
if btype != "temp":
|
||||
duration = None
|
||||
active = True
|
||||
if btype == "soft":
|
||||
active = False
|
||||
|
||||
user_embed = ban_embed(
|
||||
user=user,
|
||||
admin=ctx.author,
|
||||
|
@ -186,12 +192,6 @@ class BanCog(ModcaseCog):
|
|||
if mtype == "soft":
|
||||
await ctx.guild.unban(user, reason="Ban was softban")
|
||||
|
||||
if btype != "temp":
|
||||
duration = None
|
||||
active = True
|
||||
if btype == "soft":
|
||||
active = False
|
||||
|
||||
@slash_command(name="unban", description="Unban a user")
|
||||
@slash_option(name="user", description="User to unban", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="reason", description="Unban reason", opt_type=OptionTypes.STRING, required=True)
|
|
@ -82,9 +82,7 @@ class FilterCog(Extension):
|
|||
filter_ = SlashCommand(name="filter", description="Manage keyword filters")
|
||||
|
||||
@filter_.subcommand(sub_cmd_name="create", sub_cmd_description="Create a new filter")
|
||||
@slash_option(
|
||||
name="name", description="Name of new filter", required=True, opt_type=OptionTypes.STRING
|
||||
)
|
||||
@slash_option(name="name", description="Name of new filter", required=True, opt_type=OptionTypes.STRING)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_MESSAGES))
|
||||
async def _filter_create(self, ctx: InteractionContext, name: str) -> None:
|
||||
return await self._edit_filter(ctx, name)
|
|
@ -19,9 +19,7 @@ class KickCog(ModcaseCog):
|
|||
|
||||
@slash_command(name="kick", description="Kick a user")
|
||||
@slash_option(name="user", description="User to kick", opt_type=OptionTypes.USER, required=True)
|
||||
@slash_option(
|
||||
name="reason", description="Kick reason", opt_type=OptionTypes.STRING, required=True
|
||||
)
|
||||
@slash_option(name="reason", description="Kick reason", opt_type=OptionTypes.STRING, required=True)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
async def _kick(self, ctx: InteractionContext, user: User, reason: str) -> None:
|
||||
if not user or user == ctx.author:
|
|
@ -19,9 +19,7 @@ from naff.models.naff.command import check
|
|||
from jarvis.utils.permissions import admin_or_permissions
|
||||
|
||||
|
||||
async def lock(
|
||||
bot: Client, target: GuildChannel, admin: Member, reason: str, duration: int
|
||||
) -> None:
|
||||
async def lock(bot: Client, target: GuildChannel, admin: Member, reason: str, duration: int) -> None:
|
||||
"""
|
||||
Lock an existing channel
|
||||
|
||||
|
@ -110,9 +108,7 @@ class LockdownCog(Extension):
|
|||
sub_cmd_name="start",
|
||||
sub_cmd_description="Lockdown the server",
|
||||
)
|
||||
@slash_option(
|
||||
name="reason", description="Lockdown reason", opt_type=OptionTypes.STRING, required=True
|
||||
)
|
||||
@slash_option(name="reason", description="Lockdown reason", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(
|
||||
name="duration",
|
||||
description="Duration in minutes",
|
|
@ -114,9 +114,7 @@ class CaseCog(Extension):
|
|||
note_output = f"```ansi\n{note_output}\n{note_output_extra}\n```"
|
||||
|
||||
fields = (
|
||||
EmbedField(
|
||||
name="Actions", value=action_output if mod_case.actions else "No Actions Found"
|
||||
),
|
||||
EmbedField(name="Actions", value=action_output if mod_case.actions else "No Actions Found"),
|
||||
EmbedField(name="Notes", value=note_output if mod_case.notes else "No Notes Found"),
|
||||
)
|
||||
|
||||
|
@ -196,9 +194,7 @@ class CaseCog(Extension):
|
|||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
async def _cases_list(
|
||||
self, ctx: InteractionContext, user: Optional[Member] = None, closed: bool = False
|
||||
) -> None:
|
||||
async def _cases_list(self, ctx: InteractionContext, user: Optional[Member] = None, closed: bool = False) -> None:
|
||||
query = q(guild=ctx.guild.id)
|
||||
if not closed:
|
||||
query.update(q(open=True))
|
||||
|
@ -274,9 +270,7 @@ class CaseCog(Extension):
|
|||
|
||||
@case.subcommand(sub_cmd_name="note", sub_cmd_description="Add a note to a specific case")
|
||||
@slash_option(name="cid", description="Case ID", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(
|
||||
name="note", description="Note to add", opt_type=OptionTypes.STRING, required=True
|
||||
)
|
||||
@slash_option(name="note", description="Note to add", opt_type=OptionTypes.STRING, required=True)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
async def _case_note(self, ctx: InteractionContext, cid: str, note: str) -> None:
|
||||
case = await Modlog.find_one(q(guild=ctx.guild.id, nanoid=cid))
|
||||
|
@ -302,9 +296,7 @@ class CaseCog(Extension):
|
|||
|
||||
@case.subcommand(sub_cmd_name="new", sub_cmd_description="Open a new case")
|
||||
@slash_option(name="user", description="Target user", opt_type=OptionTypes.USER, required=True)
|
||||
@slash_option(
|
||||
name="note", description="Note to add", opt_type=OptionTypes.STRING, required=True
|
||||
)
|
||||
@slash_option(name="note", description="Note to add", opt_type=OptionTypes.STRING, required=True)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
async def _case_new(self, ctx: InteractionContext, user: Member, note: str) -> None:
|
||||
case = await Modlog.find_one(q(guild=ctx.guild.id, user=user.id, open=True))
|
||||
|
@ -322,9 +314,7 @@ class CaseCog(Extension):
|
|||
|
||||
note = Note(admin=ctx.author.id, content=note)
|
||||
|
||||
case = Modlog(
|
||||
user=user.id, guild=ctx.guild.id, admin=ctx.author.id, notes=[note], actions=[]
|
||||
)
|
||||
case = Modlog(user=user.id, guild=ctx.guild.id, admin=ctx.author.id, notes=[note], actions=[])
|
||||
await case.commit()
|
||||
await case.reload()
|
||||
|
|
@ -27,9 +27,7 @@ from jarvis.utils.permissions import admin_or_permissions
|
|||
class MuteCog(ModcaseCog):
|
||||
"""JARVIS MuteCog."""
|
||||
|
||||
async def _apply_timeout(
|
||||
self, ctx: InteractionContext, user: Member, reason: str, until: datetime
|
||||
) -> None:
|
||||
async def _apply_timeout(self, ctx: InteractionContext, user: Member, reason: str, until: datetime) -> None:
|
||||
await user.timeout(communication_disabled_until=until, reason=reason)
|
||||
duration = int((until - datetime.now(tz=timezone.utc)).seconds / 60)
|
||||
await Mute(
|
||||
|
@ -44,11 +42,7 @@ class MuteCog(ModcaseCog):
|
|||
return mute_embed(user=user, admin=ctx.author, reason=reason, guild=ctx.guild)
|
||||
|
||||
@context_menu(name="Mute User", context_type=CommandTypes.USER)
|
||||
@check(
|
||||
admin_or_permissions(
|
||||
Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS
|
||||
)
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS))
|
||||
async def _timeout_cm(self, ctx: InteractionContext) -> None:
|
||||
modal = Modal(
|
||||
title=f"Muting {ctx.target.mention}",
|
||||
|
@ -82,9 +76,7 @@ class MuteCog(ModcaseCog):
|
|||
"RETURN_AS_TIMEZONE_AWARE": True,
|
||||
}
|
||||
rt_settings = base_settings.copy()
|
||||
rt_settings["PARSERS"] = [
|
||||
x for x in default_parsers if x not in ["absolute-time", "timestamp"]
|
||||
]
|
||||
rt_settings["PARSERS"] = [x for x in default_parsers if x not in ["absolute-time", "timestamp"]]
|
||||
|
||||
rt_until = parse(until, settings=rt_settings)
|
||||
|
||||
|
@ -99,14 +91,10 @@ class MuteCog(ModcaseCog):
|
|||
until = at_until
|
||||
else:
|
||||
self.logger.debug(f"Failed to parse delay: {until}")
|
||||
await response.send(
|
||||
f"`{until}` is not a parsable date, please try again", ephemeral=True
|
||||
)
|
||||
await response.send(f"`{until}` is not a parsable date, please try again", ephemeral=True)
|
||||
return
|
||||
if until < datetime.now(tz=timezone.utc):
|
||||
await response.send(
|
||||
f"`{old_until}` is in the past, which isn't allowed", ephemeral=True
|
||||
)
|
||||
await response.send(f"`{old_until}` is in the past, which isn't allowed", ephemeral=True)
|
||||
return
|
||||
try:
|
||||
embed = await self._apply_timeout(ctx, ctx.target, reason, until)
|
||||
|
@ -140,11 +128,7 @@ class MuteCog(ModcaseCog):
|
|||
SlashCommandChoice(name="Week(s)", value=10080),
|
||||
],
|
||||
)
|
||||
@check(
|
||||
admin_or_permissions(
|
||||
Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS
|
||||
)
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS))
|
||||
async def _timeout(
|
||||
self, ctx: InteractionContext, user: Member, reason: str, time: int = 1, scale: int = 60
|
||||
) -> None:
|
||||
|
@ -175,22 +159,13 @@ class MuteCog(ModcaseCog):
|
|||
await ctx.send("Unable to mute this user", ephemeral=True)
|
||||
|
||||
@slash_command(name="unmute", description="Unmute a user")
|
||||
@slash_option(
|
||||
name="user", description="User to unmute", opt_type=OptionTypes.USER, required=True
|
||||
)
|
||||
@slash_option(
|
||||
name="reason", description="Reason for unmute", opt_type=OptionTypes.STRING, required=True
|
||||
)
|
||||
@check(
|
||||
admin_or_permissions(
|
||||
Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS
|
||||
)
|
||||
)
|
||||
@slash_option(name="user", description="User to unmute", opt_type=OptionTypes.USER, required=True)
|
||||
@slash_option(name="reason", description="Reason for unmute", opt_type=OptionTypes.STRING, required=True)
|
||||
@check(admin_or_permissions(Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS))
|
||||
async def _unmute(self, ctx: InteractionContext, user: Member, reason: str) -> None:
|
||||
if (
|
||||
not user.communication_disabled_until
|
||||
or user.communication_disabled_until.timestamp()
|
||||
< datetime.now(tz=timezone.utc).timestamp() # noqa: W503
|
||||
or user.communication_disabled_until.timestamp() < datetime.now(tz=timezone.utc).timestamp() # noqa: W503
|
||||
):
|
||||
await ctx.send("User is not muted", ephemeral=True)
|
||||
return
|
|
@ -47,9 +47,7 @@ class PurgeCog(Extension):
|
|||
count=amount,
|
||||
).commit()
|
||||
|
||||
@slash_command(
|
||||
name="autopurge", sub_cmd_name="add", sub_cmd_description="Automatically purge messages"
|
||||
)
|
||||
@slash_command(name="autopurge", sub_cmd_name="add", sub_cmd_description="Automatically purge messages")
|
||||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to autopurge",
|
||||
|
@ -63,9 +61,7 @@ class PurgeCog(Extension):
|
|||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_MESSAGES))
|
||||
async def _autopurge_add(
|
||||
self, ctx: InteractionContext, channel: GuildText, delay: int = 30
|
||||
) -> None:
|
||||
async def _autopurge_add(self, ctx: InteractionContext, channel: GuildText, delay: int = 30) -> None:
|
||||
if not isinstance(channel, GuildText):
|
||||
await ctx.send("Channel must be a GuildText channel", ephemeral=True)
|
||||
return
|
||||
|
@ -90,9 +86,7 @@ class PurgeCog(Extension):
|
|||
|
||||
await ctx.send(f"Autopurge set up on {channel.mention}, delay is {delay} seconds")
|
||||
|
||||
@slash_command(
|
||||
name="autopurge", sub_cmd_name="remove", sub_cmd_description="Remove an autopurge"
|
||||
)
|
||||
@slash_command(name="autopurge", sub_cmd_name="remove", sub_cmd_description="Remove an autopurge")
|
||||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to remove from autopurge",
|
||||
|
@ -126,9 +120,7 @@ class PurgeCog(Extension):
|
|||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_MESSAGES))
|
||||
async def _autopurge_update(
|
||||
self, ctx: InteractionContext, channel: GuildText, delay: int
|
||||
) -> None:
|
||||
async def _autopurge_update(self, ctx: InteractionContext, channel: GuildText, delay: int) -> None:
|
||||
autopurge = await Autopurge.find_one(q(guild=ctx.guild.id, channel=channel.id))
|
||||
if not autopurge:
|
||||
await ctx.send("Autopurge does not exist.", ephemeral=True)
|
|
@ -27,9 +27,7 @@ class RolepingCog(Extension):
|
|||
self.bot = bot
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
roleping = SlashCommand(
|
||||
name="roleping", description="Set up warnings for pinging specific roles"
|
||||
)
|
||||
roleping = SlashCommand(name="roleping", description="Set up warnings for pinging specific roles")
|
||||
|
||||
@roleping.subcommand(
|
||||
sub_cmd_name="add",
|
||||
|
@ -57,9 +55,7 @@ class RolepingCog(Extension):
|
|||
await ctx.send(f"Role `{role.name}` added to roleping.")
|
||||
|
||||
@roleping.subcommand(sub_cmd_name="remove", sub_cmd_description="Remove a role")
|
||||
@slash_option(
|
||||
name="role", description="Role to remove", opt_type=OptionTypes.ROLE, required=True
|
||||
)
|
||||
@slash_option(name="role", description="Role to remove", opt_type=OptionTypes.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _roleping_remove(self, ctx: InteractionContext, role: Role) -> None:
|
||||
roleping = await Roleping.find_one(q(guild=ctx.guild.id, role=role.id))
|
||||
|
@ -87,11 +83,10 @@ class RolepingCog(Extension):
|
|||
if not role:
|
||||
await roleping.delete()
|
||||
continue
|
||||
broles = find_all(lambda x: x.id in roleping.bypass["roles"], ctx.guild.roles)
|
||||
broles = find_all(lambda x: x.id in roleping.bypass["roles"], ctx.guild.roles) # noqa: B023
|
||||
bypass_roles = [r.mention or "||`[redacted]`||" for r in broles]
|
||||
bypass_users = [
|
||||
(await ctx.guild.fetch_member(u)).mention or "||`[redacted]`||"
|
||||
for u in roleping.bypass["users"]
|
||||
(await ctx.guild.fetch_member(u)).mention or "||`[redacted]`||" for u in roleping.bypass["users"]
|
||||
]
|
||||
bypass_roles = bypass_roles or ["None"]
|
||||
bypass_users = bypass_users or ["None"]
|
||||
|
@ -132,24 +127,16 @@ class RolepingCog(Extension):
|
|||
|
||||
await paginator.send(ctx)
|
||||
|
||||
bypass = roleping.group(
|
||||
name="bypass", description="Allow specific users/roles to ping rolepings"
|
||||
)
|
||||
bypass = roleping.group(name="bypass", description="Allow specific users/roles to ping rolepings")
|
||||
|
||||
@bypass.subcommand(
|
||||
sub_cmd_name="user",
|
||||
sub_cmd_description="Add a user as a bypass to a roleping",
|
||||
)
|
||||
@slash_option(
|
||||
name="bypass", description="User to add", opt_type=OptionTypes.USER, required=True
|
||||
)
|
||||
@slash_option(
|
||||
name="role", description="Rolepinged role", opt_type=OptionTypes.ROLE, required=True
|
||||
)
|
||||
@slash_option(name="bypass", description="User to add", opt_type=OptionTypes.USER, required=True)
|
||||
@slash_option(name="role", description="Rolepinged role", opt_type=OptionTypes.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _roleping_bypass_user(
|
||||
self, ctx: InteractionContext, bypass: Member, role: Role
|
||||
) -> None:
|
||||
async def _roleping_bypass_user(self, ctx: InteractionContext, bypass: Member, role: Role) -> None:
|
||||
roleping = await Roleping.find_one(q(guild=ctx.guild.id, role=role.id))
|
||||
if not roleping:
|
||||
await ctx.send(f"Roleping not configured for {role.mention}", ephemeral=True)
|
||||
|
@ -183,16 +170,10 @@ class RolepingCog(Extension):
|
|||
sub_cmd_name="role",
|
||||
sub_cmd_description="Add a role as a bypass to roleping",
|
||||
)
|
||||
@slash_option(
|
||||
name="bypass", description="Role to add", opt_type=OptionTypes.ROLE, required=True
|
||||
)
|
||||
@slash_option(
|
||||
name="role", description="Rolepinged role", opt_type=OptionTypes.ROLE, required=True
|
||||
)
|
||||
@slash_option(name="bypass", description="Role to add", opt_type=OptionTypes.ROLE, required=True)
|
||||
@slash_option(name="role", description="Rolepinged role", opt_type=OptionTypes.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _roleping_bypass_role(
|
||||
self, ctx: InteractionContext, bypass: Role, role: Role
|
||||
) -> None:
|
||||
async def _roleping_bypass_role(self, ctx: InteractionContext, bypass: Role, role: Role) -> None:
|
||||
if bypass.id == ctx.guild.id:
|
||||
await ctx.send("Cannot add `@everyone` as a bypass", ephemeral=True)
|
||||
return
|
||||
|
@ -207,8 +188,7 @@ class RolepingCog(Extension):
|
|||
|
||||
if len(roleping.bypass["roles"]) == 10:
|
||||
await ctx.send(
|
||||
"Already have 10 roles in bypass. "
|
||||
"Please consider consolidating roles for roleping bypass",
|
||||
"Already have 10 roles in bypass. " "Please consider consolidating roles for roleping bypass",
|
||||
ephemeral=True,
|
||||
)
|
||||
return
|
||||
|
@ -223,16 +203,10 @@ class RolepingCog(Extension):
|
|||
sub_cmd_name="user",
|
||||
sub_cmd_description="Remove a bypass from a roleping (restoring it)",
|
||||
)
|
||||
@slash_option(
|
||||
name="bypass", description="User to remove", opt_type=OptionTypes.USER, required=True
|
||||
)
|
||||
@slash_option(
|
||||
name="role", description="Rolepinged role", opt_type=OptionTypes.ROLE, required=True
|
||||
)
|
||||
@slash_option(name="bypass", description="User to remove", opt_type=OptionTypes.USER, required=True)
|
||||
@slash_option(name="role", description="Rolepinged role", opt_type=OptionTypes.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _roleping_restore_user(
|
||||
self, ctx: InteractionContext, bypass: Member, role: Role
|
||||
) -> None:
|
||||
async def _roleping_restore_user(self, ctx: InteractionContext, bypass: Member, role: Role) -> None:
|
||||
roleping: Roleping = await Roleping.find_one(q(guild=ctx.guild.id, role=role.id))
|
||||
if not roleping:
|
||||
await ctx.send(f"Roleping not configured for {role.mention}", ephemeral=True)
|
||||
|
@ -250,16 +224,10 @@ class RolepingCog(Extension):
|
|||
sub_cmd_name="role",
|
||||
sub_cmd_description="Remove a bypass from a roleping (restoring it)",
|
||||
)
|
||||
@slash_option(
|
||||
name="bypass", description="Role to remove", opt_type=OptionTypes.ROLE, required=True
|
||||
)
|
||||
@slash_option(
|
||||
name="role", description="Rolepinged role", opt_type=OptionTypes.ROLE, required=True
|
||||
)
|
||||
@slash_option(name="bypass", description="Role to remove", opt_type=OptionTypes.ROLE, required=True)
|
||||
@slash_option(name="role", description="Rolepinged role", opt_type=OptionTypes.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _roleping_restore_role(
|
||||
self, ctx: InteractionContext, bypass: Role, role: Role
|
||||
) -> None:
|
||||
async def _roleping_restore_role(self, ctx: InteractionContext, bypass: Role, role: Role) -> None:
|
||||
roleping: Roleping = await Roleping.find_one(q(guild=ctx.guild.id, role=role.id))
|
||||
if not roleping:
|
||||
await ctx.send(f"Roleping not configured for {role.mention}", ephemeral=True)
|
|
@ -30,12 +30,8 @@ class TemproleCog(Extension):
|
|||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
@slash_command(name="temprole", description="Give a user a temporary role")
|
||||
@slash_option(
|
||||
name="user", description="User to grant role", opt_type=OptionTypes.USER, required=True
|
||||
)
|
||||
@slash_option(
|
||||
name="role", description="Role to grant", opt_type=OptionTypes.ROLE, required=True
|
||||
)
|
||||
@slash_option(name="user", description="User to grant role", opt_type=OptionTypes.USER, required=True)
|
||||
@slash_option(name="role", description="Role to grant", opt_type=OptionTypes.ROLE, required=True)
|
||||
@slash_option(
|
||||
name="duration",
|
||||
description="Duration of temp role (i.e. 2 hours)",
|
||||
|
@ -74,9 +70,7 @@ class TemproleCog(Extension):
|
|||
"RETURN_AS_TIMEZONE_AWARE": True,
|
||||
}
|
||||
rt_settings = base_settings.copy()
|
||||
rt_settings["PARSERS"] = [
|
||||
x for x in default_parsers if x not in ["absolute-time", "timestamp"]
|
||||
]
|
||||
rt_settings["PARSERS"] = [x for x in default_parsers if x not in ["absolute-time", "timestamp"]]
|
||||
|
||||
rt_duration = parse(duration, settings=rt_settings)
|
||||
|
||||
|
@ -94,9 +88,7 @@ class TemproleCog(Extension):
|
|||
return
|
||||
|
||||
if duration < datetime.now(tz=timezone.utc):
|
||||
await ctx.send(
|
||||
f"`{duration}` is in the past. Past durations aren't allowed", ephemeral=True
|
||||
)
|
||||
await ctx.send(f"`{duration}` is in the past. Past durations aren't allowed", ephemeral=True)
|
||||
return
|
||||
|
||||
await user.add_role(role, reason=reason)
|
||||
|
@ -116,15 +108,6 @@ class TemproleCog(Extension):
|
|||
description=f"Role temporarily granted to {user.mention}",
|
||||
fields=fields,
|
||||
)
|
||||
embed.set_author(
|
||||
name=f"{user.username}#{user.discriminator}", icon_url=user.display_avatar.url
|
||||
)
|
||||
components = Button(
|
||||
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||
)
|
||||
embed.set_author(name=f"{user.username}#{user.discriminator}", icon_url=user.display_avatar.url)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
|
||||
def setup(bot: Client) -> None:
|
||||
"""Add TemproleCog to JARVIS"""
|
||||
TemproleCog(bot)
|
|
@ -85,9 +85,7 @@ class VerifyCog(Extension):
|
|||
role = await ctx.guild.fetch_role(setting.value)
|
||||
await ctx.author.remove_role(role, reason="Verification passed")
|
||||
except AttributeError:
|
||||
self.logger.warning(
|
||||
"Unverified role deleted before verification finished"
|
||||
)
|
||||
self.logger.warning("Unverified role deleted before verification finished")
|
||||
|
||||
await response.context.edit_origin(
|
||||
content=f"Welcome, {ctx.author.mention}. Please enjoy your stay.",
|
||||
|
@ -97,10 +95,7 @@ class VerifyCog(Extension):
|
|||
self.logger.debug(f"User {ctx.author.id} verified successfully")
|
||||
else:
|
||||
await response.context.edit_origin(
|
||||
content=(
|
||||
f"{ctx.author.mention}, incorrect. "
|
||||
"Please press the button that says `YES`"
|
||||
)
|
||||
content=(f"{ctx.author.mention}, incorrect. " "Please press the button that says `YES`")
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
await message.delete(delay=2)
|
|
@ -39,9 +39,7 @@ class WarningCog(ModcaseCog):
|
|||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _warn(
|
||||
self, ctx: InteractionContext, user: Member, reason: str, duration: int = 24
|
||||
) -> None:
|
||||
async def _warn(self, ctx: InteractionContext, user: Member, reason: str, duration: int = 24) -> None:
|
||||
if len(reason) > 100:
|
||||
await ctx.send("Reason must be < 100 characters", ephemeral=True)
|
||||
return
|
||||
|
@ -122,9 +120,7 @@ class WarningCog(ModcaseCog):
|
|||
for i in range(0, len(fields), 5):
|
||||
embed = build_embed(
|
||||
title="Warnings",
|
||||
description=(
|
||||
f"{len(warnings)} total | {len(active_warns)} currently active"
|
||||
),
|
||||
description=(f"{len(warnings)} total | {len(active_warns)} currently active"),
|
||||
fields=fields[i : i + 5],
|
||||
)
|
||||
embed.set_author(
|
||||
|
@ -153,9 +149,7 @@ class WarningCog(ModcaseCog):
|
|||
description=(f"{len(warnings)} total | {len(active_warns)} currently active"),
|
||||
fields=fields[i : i + 5],
|
||||
)
|
||||
embed.set_author(
|
||||
name=user.username + "#" + user.discriminator, icon_url=user.display_avatar.url
|
||||
)
|
||||
embed.set_author(name=user.username + "#" + user.discriminator, icon_url=user.display_avatar.url)
|
||||
embed.set_thumbnail(url=ctx.guild.icon.url)
|
||||
pages.append(embed)
|
||||
|
|
@ -84,9 +84,7 @@ class BotutilCog(Extension):
|
|||
)
|
||||
embed = build_embed(title="System Info", description="", fields=fields)
|
||||
embed.set_image(url=self.bot.user.avatar.url)
|
||||
components = Button(
|
||||
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||
)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@prefixed_command(name="update")
|
||||
|
@ -113,16 +111,12 @@ class BotutilCog(Extension):
|
|||
if changed:
|
||||
fields.append(EmbedField(name="Changed Modules", value=f"```\n{changed}\n```"))
|
||||
|
||||
embed = build_embed(
|
||||
"Update Status", description="Updates have been applied", fields=fields
|
||||
)
|
||||
embed = build_embed("Update Status", description="Updates have been applied", fields=fields)
|
||||
embed.set_thumbnail(url="https://dev.zevaryx.com/git.png")
|
||||
|
||||
self.logger.info("Updates applied")
|
||||
content = f"```ansi\n{capture.get()}\n```"
|
||||
components = Button(
|
||||
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||
)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
if len(content) < 3000:
|
||||
await ctx.reply(content, embeds=embed, components=components)
|
||||
else:
|
||||
|
@ -135,9 +129,7 @@ class BotutilCog(Extension):
|
|||
else:
|
||||
embed = build_embed(title="Update Status", description="No changes applied", fields=[])
|
||||
embed.set_thumbnail(url="https://dev.zevaryx.com/git.png")
|
||||
components = Button(
|
||||
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
|
||||
)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.reply(embeds=embed, components=components)
|
||||
|
||||
|
11
jarvis/cogs/core/socials/__init__.py
Normal file
11
jarvis/cogs/core/socials/__init__.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
"""JARVIS Social Cogs."""
|
||||
|
||||
from naff import Client
|
||||
|
||||
from jarvis.cogs.core.socials import reddit, twitter
|
||||
|
||||
|
||||
def setup(bot: Client) -> None:
|
||||
"""Add social cogs to JARVIS"""
|
||||
reddit.RedditCog(bot)
|
||||
twitter.TwitterCog(bot)
|
11
jarvis/cogs/unique/__init__.py
Normal file
11
jarvis/cogs/unique/__init__.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
"""JARVIS guild-specific cogs"""
|
||||
from naff import Client
|
||||
|
||||
from jarvis.cogs.unique import ctc2, dbrand, gl
|
||||
|
||||
|
||||
def setup(bot: Client) -> None:
|
||||
"""Add guild-specific cogs to JARVIS"""
|
||||
ctc2.setup(bot)
|
||||
dbrand.setup(bot)
|
||||
gl.setup(bot)
|
|
@ -46,39 +46,25 @@ class CTCCog(Extension):
|
|||
@ctc2.subcommand(sub_cmd_name="about")
|
||||
@cooldown(bucket=Buckets.USER, rate=1, interval=30)
|
||||
async def _about(self, ctx: InteractionContext) -> None:
|
||||
components = [
|
||||
ActionRow(
|
||||
Button(style=ButtonStyles.URL, url="https://completethecode.com", label="More Info")
|
||||
)
|
||||
]
|
||||
await ctx.send(
|
||||
"See https://completethecode.com for more information", components=components
|
||||
)
|
||||
components = [ActionRow(Button(style=ButtonStyles.URL, url="https://completethecode.com", label="More Info"))]
|
||||
await ctx.send("See https://completethecode.com for more information", components=components)
|
||||
|
||||
@ctc2.subcommand(
|
||||
sub_cmd_name="pw",
|
||||
sub_cmd_description="Guess a password for https://completethecodetwo.cards",
|
||||
)
|
||||
@slash_option(
|
||||
name="guess", description="Guess a password", opt_type=OptionTypes.STRING, required=True
|
||||
)
|
||||
@slash_option(name="guess", description="Guess a password", opt_type=OptionTypes.STRING, required=True)
|
||||
@cooldown(bucket=Buckets.USER, rate=1, interval=2)
|
||||
async def _pw(self, ctx: InteractionContext, guess: str) -> None:
|
||||
if len(guess) > 800:
|
||||
await ctx.send(
|
||||
(
|
||||
"Listen here, dipshit. Don't be like <@256110768724901889>. "
|
||||
"Make your guesses < 800 characters."
|
||||
),
|
||||
("Listen here, dipshit. Don't be like <@256110768724901889>. " "Make your guesses < 800 characters."),
|
||||
ephemeral=True,
|
||||
)
|
||||
return
|
||||
elif not valid.fullmatch(guess):
|
||||
await ctx.send(
|
||||
(
|
||||
"Listen here, dipshit. Don't be like <@256110768724901889>. "
|
||||
"Make your guesses *readable*."
|
||||
),
|
||||
("Listen here, dipshit. Don't be like <@256110768724901889>. " "Make your guesses *readable*."),
|
||||
ephemeral=True,
|
||||
)
|
||||
return
|
|
@ -63,9 +63,7 @@ async def parse_db_status() -> dict:
|
|||
else:
|
||||
cell = cell.get_text().strip()
|
||||
row_data.append(cell)
|
||||
data[data_key].append(
|
||||
{headers[idx]: value for idx, value in enumerate(row_data)}
|
||||
)
|
||||
data[data_key].append({headers[idx]: value for idx, value in enumerate(row_data)})
|
||||
return data
|
||||
|
||||
|
||||
|
@ -99,9 +97,7 @@ class DbrandCog(Extension):
|
|||
self.cache["status"] = status
|
||||
status = status.get("operations")
|
||||
emojies = [x["Status"] for x in status]
|
||||
fields = [
|
||||
EmbedField(name=f'{x["Status"]} {x["Service"]}', value=x["Detail"]) for x in status
|
||||
]
|
||||
fields = [EmbedField(name=f'{x["Status"]} {x["Service"]}', value=x["Detail"]) for x in status]
|
||||
color = "#FBBD1E"
|
||||
if all("green" in x for x in emojies):
|
||||
color = "#38F657"
|
||||
|
@ -192,17 +188,13 @@ class DbrandCog(Extension):
|
|||
f"[Be (not) extorted]({self.base_url + 'not-extortion'})",
|
||||
"[Robot Camo Wallpapers](https://db.io/wallpapers)",
|
||||
]
|
||||
embed = build_embed(
|
||||
title="Useful Links", description="\n\n".join(urls), fields=[], color="#FFBB00"
|
||||
)
|
||||
embed = build_embed(title="Useful Links", description="\n\n".join(urls), fields=[], color="#FFBB00")
|
||||
embed.set_footer(
|
||||
text="dbrand.com",
|
||||
icon_url="https://dev.zevaryx.com/db_logo.png",
|
||||
)
|
||||
embed.set_thumbnail(url="https://dev.zevaryx.com/db_logo.png")
|
||||
embed.set_author(
|
||||
name="dbrand", url=self.base_url, icon_url="https://dev.zevaryx.com/db_logo.png"
|
||||
)
|
||||
embed.set_author(name="dbrand", url=self.base_url, icon_url="https://dev.zevaryx.com/db_logo.png")
|
||||
await ctx.send(embeds=embed)
|
||||
|
||||
@db.subcommand(
|
||||
|
@ -264,15 +256,11 @@ class DbrandCog(Extension):
|
|||
for service in data["shipping_services_available"]:
|
||||
service_data = self.cache.get(f"{dest}-{service}")
|
||||
if not service_data or service_data["cache_expiry"] < datetime.now(tz=timezone.utc):
|
||||
service_data = await self._session.get(
|
||||
self.api_url + dest + "/" + service["url"]
|
||||
)
|
||||
service_data = await self._session.get(self.api_url + dest + "/" + service["url"])
|
||||
if service_data.status > 400:
|
||||
continue
|
||||
service_data = await service_data.json()
|
||||
service_data["cache_expiry"] = datetime.now(tz=timezone.utc) + timedelta(
|
||||
hours=24
|
||||
)
|
||||
service_data["cache_expiry"] = datetime.now(tz=timezone.utc) + timedelta(hours=24)
|
||||
self.cache[f"{dest}-{service}"] = service_data
|
||||
title = f'{service_data["carrier"]} {service_data["tier-title"]} | {service_data["costs-min"]}'
|
||||
message = service_data["time-title"]
|
||||
|
@ -296,7 +284,9 @@ class DbrandCog(Extension):
|
|||
description = ""
|
||||
color = "#FFBB00"
|
||||
if shipping_info:
|
||||
description = f'{shipping_info["Status"]}\u200b \u200b {shipping_info["Est. Delivery Time"].split(":")[0]}'
|
||||
description = (
|
||||
f'{shipping_info["Status"]}\u200b \u200b {shipping_info["Est. Delivery Time"].split(":")[0]}'
|
||||
)
|
||||
created = self.cache.get("status").get("cache_expiry") - timedelta(hours=2)
|
||||
ts = int(created.timestamp())
|
||||
description += f" \u200b | \u200b Last updated: <t:{ts}:R>\n\u200b"
|
||||
|
@ -326,8 +316,7 @@ class DbrandCog(Extension):
|
|||
embed = build_embed(
|
||||
title="Check Shipping Times",
|
||||
description=(
|
||||
"Country not found.\nYou can [view all shipping "
|
||||
"destinations here](https://dbrand.com/shipping)"
|
||||
"Country not found.\nYou can [view all shipping " "destinations here](https://dbrand.com/shipping)"
|
||||
),
|
||||
fields=[],
|
||||
url="https://dbrand.com/shipping",
|
|
@ -53,9 +53,7 @@ class GitlabCog(Extension):
|
|||
else:
|
||||
assignee = "None"
|
||||
|
||||
created_at = datetime.strptime(issue.created_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime(
|
||||
"%Y-%m-%d %H:%M:%S UTC"
|
||||
)
|
||||
created_at = datetime.strptime(issue.created_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||
|
||||
labels = issue.labels
|
||||
if labels:
|
||||
|
@ -73,9 +71,7 @@ class GitlabCog(Extension):
|
|||
color = self.project.labels.get(issue.labels[0]).color
|
||||
fields.append(EmbedField(name="Created At", value=created_at))
|
||||
if issue.state == "closed":
|
||||
closed_at = datetime.strptime(issue.closed_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime(
|
||||
"%Y-%m-%d %H:%M:%S UTC"
|
||||
)
|
||||
closed_at = datetime.strptime(issue.closed_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||
fields.append(EmbedField(name="Closed At", value=closed_at))
|
||||
if issue.milestone:
|
||||
fields.append(
|
||||
|
@ -99,18 +95,14 @@ class GitlabCog(Extension):
|
|||
icon_url=issue.author["avatar_url"],
|
||||
url=issue.author["web_url"],
|
||||
)
|
||||
embed.set_thumbnail(
|
||||
url="https://about.gitlab.com/images/press/logo/png/gitlab-icon-rgb.png"
|
||||
)
|
||||
embed.set_thumbnail(url="https://about.gitlab.com/images/press/logo/png/gitlab-icon-rgb.png")
|
||||
await ctx.send(embeds=embed)
|
||||
|
||||
@gl.subcommand(
|
||||
sub_cmd_name="milestone",
|
||||
sub_cmd_description="Get a milestone from GitLab",
|
||||
)
|
||||
@slash_option(
|
||||
name="id", description="Milestone ID", opt_type=OptionTypes.INTEGER, required=True
|
||||
)
|
||||
@slash_option(name="id", description="Milestone ID", opt_type=OptionTypes.INTEGER, required=True)
|
||||
async def _milestone(self, ctx: InteractionContext, id: int) -> None:
|
||||
try:
|
||||
milestone = self.project.milestones.get(int(id))
|
||||
|
@ -118,9 +110,7 @@ class GitlabCog(Extension):
|
|||
await ctx.send("Milestone does not exist.", ephemeral=True)
|
||||
return
|
||||
|
||||
created_at = datetime.strptime(milestone.created_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime(
|
||||
"%Y-%m-%d %H:%M:%S UTC"
|
||||
)
|
||||
created_at = datetime.strptime(milestone.created_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||
|
||||
fields = [
|
||||
EmbedField(
|
||||
|
@ -153,18 +143,14 @@ class GitlabCog(Extension):
|
|||
url="https://git.zevaryx.com/jarvis",
|
||||
icon_url="https://git.zevaryx.com/uploads/-/system/user/avatar/11/avatar.png",
|
||||
)
|
||||
embed.set_thumbnail(
|
||||
url="https://about.gitlab.com/images/press/logo/png/gitlab-icon-rgb.png"
|
||||
)
|
||||
embed.set_thumbnail(url="https://about.gitlab.com/images/press/logo/png/gitlab-icon-rgb.png")
|
||||
await ctx.send(embeds=embed)
|
||||
|
||||
@gl.subcommand(
|
||||
sub_cmd_name="mr",
|
||||
sub_cmd_description="Get a merge request from GitLab",
|
||||
)
|
||||
@slash_option(
|
||||
name="id", description="Merge Request ID", opt_type=OptionTypes.INTEGER, required=True
|
||||
)
|
||||
@slash_option(name="id", description="Merge Request ID", opt_type=OptionTypes.INTEGER, required=True)
|
||||
async def _mergerequest(self, ctx: InteractionContext, id: int) -> None:
|
||||
try:
|
||||
mr = self.project.mergerequests.get(int(id))
|
||||
|
@ -177,9 +163,7 @@ class GitlabCog(Extension):
|
|||
else:
|
||||
assignee = "None"
|
||||
|
||||
created_at = datetime.strptime(mr.created_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime(
|
||||
"%Y-%m-%d %H:%M:%S UTC"
|
||||
)
|
||||
created_at = datetime.strptime(mr.created_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||
|
||||
labels = mr.labels
|
||||
if labels:
|
||||
|
@ -199,14 +183,10 @@ class GitlabCog(Extension):
|
|||
color = "#00FFEE"
|
||||
fields.append(EmbedField(name="Created At", value=created_at, inline=True))
|
||||
if mr.state == "merged":
|
||||
merged_at = datetime.strptime(mr.merged_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime(
|
||||
"%Y-%m-%d %H:%M:%S UTC"
|
||||
)
|
||||
merged_at = datetime.strptime(mr.merged_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||
fields.append(EmbedField(name="Merged At", value=merged_at, inline=True))
|
||||
elif mr.state == "closed":
|
||||
closed_at = datetime.strptime(mr.closed_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime(
|
||||
"%Y-%m-%d %H:%M:%S UTC"
|
||||
)
|
||||
closed_at = datetime.strptime(mr.closed_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||
fields.append(EmbedField(name="Closed At", value=closed_at, inline=True))
|
||||
if mr.milestone:
|
||||
fields.append(
|
||||
|
@ -230,9 +210,7 @@ class GitlabCog(Extension):
|
|||
icon_url=mr.author["avatar_url"],
|
||||
url=mr.author["web_url"],
|
||||
)
|
||||
embed.set_thumbnail(
|
||||
url="https://about.gitlab.com/images/press/logo/png/gitlab-icon-rgb.png"
|
||||
)
|
||||
embed.set_thumbnail(url="https://about.gitlab.com/images/press/logo/png/gitlab-icon-rgb.png")
|
||||
await ctx.send(embeds=embed)
|
||||
|
||||
def build_embed_page(self, api_list: list, t_state: str, name: str) -> Embed:
|
||||
|
@ -263,9 +241,7 @@ class GitlabCog(Extension):
|
|||
url="https://git.zevaryx.com/jarvis",
|
||||
icon_url="https://git.zevaryx.com/uploads/-/system/user/avatar/11/avatar.png",
|
||||
)
|
||||
embed.set_thumbnail(
|
||||
url="https://about.gitlab.com/images/press/logo/png/gitlab-icon-rgb.png"
|
||||
)
|
||||
embed.set_thumbnail(url="https://about.gitlab.com/images/press/logo/png/gitlab-icon-rgb.png")
|
||||
return embed
|
||||
|
||||
@gl.subcommand(
|
||||
|
@ -370,9 +346,7 @@ class GitlabCog(Extension):
|
|||
pages = []
|
||||
t_state = t_state[0].upper() + t_state[1:]
|
||||
for i in range(0, len(merges), 5):
|
||||
pages.append(
|
||||
self.build_embed_page(merges[i : i + 5], t_state=t_state, name="merge request")
|
||||
)
|
||||
pages.append(self.build_embed_page(merges[i : i + 5], t_state=t_state, name="merge request"))
|
||||
|
||||
paginator = Paginator.create_from_embeds(self.bot, *pages, timeout=300)
|
||||
|
||||
|
@ -407,9 +381,7 @@ class GitlabCog(Extension):
|
|||
|
||||
pages = []
|
||||
for i in range(0, len(milestones), 5):
|
||||
pages.append(
|
||||
self.build_embed_page(milestones[i : i + 5], t_state=None, name="milestone")
|
||||
)
|
||||
pages.append(self.build_embed_page(milestones[i : i + 5], t_state=None, name="milestone"))
|
||||
|
||||
paginator = Paginator.create_from_embeds(self.bot, *pages, timeout=300)
|
||||
|
Loading…
Add table
Reference in a new issue