Mostly functioning, quirks with command execution
This commit is contained in:
parent
9143b8f4b4
commit
7e53127e19
37 changed files with 1111 additions and 918 deletions
|
@ -4,6 +4,7 @@ from functools import partial
|
|||
from typing import Any
|
||||
|
||||
import jurigged
|
||||
from statipy.db import init_db
|
||||
from interactions import Intents
|
||||
from jarvis_core.db import connect
|
||||
from jarvis_core.log import get_logger
|
||||
|
@ -65,12 +66,14 @@ async def run() -> None:
|
|||
logger.addHandler(file_handler)
|
||||
|
||||
# Configure client
|
||||
intents = Intents.DEFAULT | Intents.MESSAGES | Intents.GUILD_MEMBERS | Intents.GUILD_MESSAGE_CONTENT
|
||||
intents = Intents.DEFAULT | Intents.MESSAGES | Intents.GUILD_MEMBERS | Intents.GUILD_MESSAGES
|
||||
redis_config = jconfig.redis.copy()
|
||||
redis_host = redis_config.pop("host")
|
||||
|
||||
redis = await aioredis.from_url(redis_host, decode_responses=True, **redis_config)
|
||||
|
||||
await init_db(**jconfig.mongo["connect"])
|
||||
|
||||
jarvis = Jarvis(
|
||||
intents=intents,
|
||||
sync_interactions=jconfig.sync,
|
||||
|
@ -99,8 +102,9 @@ async def run() -> None:
|
|||
for extension in get_extensions(cogs_path):
|
||||
jarvis.load_extension(extension)
|
||||
logger.debug("Loaded %s", extension)
|
||||
logger.debug("Loading nafftrack")
|
||||
jarvis.load_extension("nafftrack.extension")
|
||||
|
||||
logger.debug("Loading statipy")
|
||||
jarvis.load_extension("statipy.ext")
|
||||
|
||||
jarvis.max_messages = jconfig.max_messages
|
||||
logger.debug("Running JARVIS")
|
||||
|
|
|
@ -6,6 +6,7 @@ from interactions import Client
|
|||
from interactions.ext.prefixed_commands.context import PrefixedContext
|
||||
from interactions.models.internal.context import BaseContext, InteractionContext
|
||||
from jarvis_core.util.ansi import Fore, Format, fmt
|
||||
from statipy import StatipyClient
|
||||
|
||||
from jarvis.client.errors import ErrorMixin
|
||||
from jarvis.client.events import EventMixin
|
||||
|
@ -19,7 +20,7 @@ VAL_FMT = fmt(Fore.WHITE)
|
|||
CMD_FMT = fmt(Fore.GREEN, Format.BOLD)
|
||||
|
||||
|
||||
class Jarvis(Client, ErrorMixin, EventMixin, TaskMixin):
|
||||
class Jarvis(StatipyClient, ErrorMixin, EventMixin, TaskMixin):
|
||||
def __init__(self, redis: "aioredis.Redis", *args, **kwargs): # noqa: ANN002 ANN003
|
||||
super().__init__(*args, **kwargs)
|
||||
self.redis = redis
|
||||
|
|
|
@ -18,7 +18,7 @@ DEFAULT_SITE = "https://paste.zevs.me"
|
|||
ERROR_MSG = """
|
||||
Command Information:
|
||||
Guild: {guild_name}
|
||||
Name: {invoked_name}
|
||||
Name: {invoke_target}
|
||||
Args:
|
||||
{arg_str}
|
||||
|
||||
|
@ -74,7 +74,7 @@ class ErrorMixin:
|
|||
full_message = ERROR_MSG.format(
|
||||
guild_name=ctx.guild.name,
|
||||
error_time=error_time,
|
||||
invoked_name=name,
|
||||
invoke_target=name,
|
||||
arg_str=arg_str,
|
||||
callback_args=callback_args,
|
||||
callback_kwargs=callback_kwargs,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import asyncio
|
||||
|
||||
from aiohttp import ClientSession
|
||||
from beanie.operators import Set
|
||||
from interactions import listen
|
||||
from interactions.ext.prefixed_commands.context import PrefixedContext
|
||||
from interactions.models.discord.channel import DMChannel
|
||||
|
@ -11,12 +12,12 @@ from interactions.models.internal.context import BaseContext, InteractionContext
|
|||
from jarvis_core.db import q
|
||||
from jarvis_core.db.models import Reminder, Setting
|
||||
from jarvis_core.util.ansi import RESET, Fore, Format, fmt
|
||||
from statipy.db import StaticStat
|
||||
|
||||
from jarvis import const
|
||||
from jarvis.client.events.components import ComponentEventMixin
|
||||
from jarvis.client.events.member import MemberEventMixin
|
||||
from jarvis.client.events.message import MessageEventMixin
|
||||
from jarvis.tracking import jarvis_info
|
||||
from jarvis.utils import build_embed
|
||||
|
||||
KEY_FMT = fmt(Fore.GRAY)
|
||||
|
@ -27,9 +28,11 @@ CMD_FMT = fmt(Fore.GREEN, Format.BOLD)
|
|||
class EventMixin(MemberEventMixin, MessageEventMixin, ComponentEventMixin):
|
||||
async def _chunk_all(self) -> None:
|
||||
"""Chunk all guilds."""
|
||||
for guild in self.guilds:
|
||||
self.logger.debug(f"Chunking guild {guild.name} <{guild.id}>")
|
||||
await guild.chunk_guild()
|
||||
self.logger.warn("Deprecated function, nothing will happen")
|
||||
# for guild in self.guilds:
|
||||
# if not guild.chunked.is_set():
|
||||
# self.logger.debug(f"Chunking guild {guild.name} <{guild.id}>")
|
||||
# await guild.chunk_guild()
|
||||
|
||||
async def _sync_domains(self) -> None:
|
||||
self.logger.debug("Loading phishing domains")
|
||||
|
@ -42,7 +45,20 @@ class EventMixin(MemberEventMixin, MessageEventMixin, ComponentEventMixin):
|
|||
@listen()
|
||||
async def on_startup(self) -> None:
|
||||
"""NAFF on_startup override. Prometheus info generated here."""
|
||||
jarvis_info.info({"version": const.__version__})
|
||||
await StaticStat.find_one(StaticStat.name == "jarvis_version", StaticStat.client_id == self.user.id).upsert(
|
||||
Set(
|
||||
{
|
||||
StaticStat.client_name: self.client_name,
|
||||
StaticStat.value: const.__version__,
|
||||
}
|
||||
),
|
||||
on_insert=StaticStat(
|
||||
name="jarvis_version",
|
||||
client_id=self.user.id,
|
||||
client_name=self.client_name,
|
||||
value=const.__version__,
|
||||
),
|
||||
)
|
||||
try:
|
||||
if not self.synced:
|
||||
await self._sync_domains()
|
||||
|
|
|
@ -3,13 +3,14 @@ import re
|
|||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
from aiohttp import ClientSession
|
||||
from beanie.operators import Inc, Set
|
||||
from interactions import listen
|
||||
from interactions.api.events.discord import MessageCreate, MessageDelete, MessageUpdate
|
||||
from interactions.client.utils.misc_utils import find_all
|
||||
from interactions.models.discord.channel import DMChannel, GuildText
|
||||
from interactions.models.discord.components import ActionRow, Button
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.enums import ButtonStyles, Permissions
|
||||
from interactions.models.discord.enums import ButtonStyle, Permissions
|
||||
from interactions.models.discord.message import Message
|
||||
from interactions.models.discord.user import Member
|
||||
from jarvis_core.db import q
|
||||
|
@ -24,11 +25,12 @@ from jarvis_core.db.models import (
|
|||
Warning,
|
||||
)
|
||||
from jarvis_core.filters import invites, url
|
||||
from statipy.db import Stat
|
||||
|
||||
from jarvis.branding import get_command_color
|
||||
from jarvis.embeds.admin import warning_embed
|
||||
from jarvis.tracking import malicious_tracker, warnings_tracker
|
||||
from jarvis.utils import build_embed
|
||||
from jarvis.tracking import WarningMetadata
|
||||
|
||||
|
||||
class MessageEventMixin:
|
||||
|
@ -99,8 +101,16 @@ class MessageEventMixin:
|
|||
reason="Sent an invite link",
|
||||
user=message.author.id,
|
||||
).commit()
|
||||
tracker = warnings_tracker.labels(guild_id=message.guild.id, guild_name=message.guild.name)
|
||||
tracker.inc()
|
||||
md = WarningMetadata(
|
||||
client_id=self.user.id,
|
||||
client_name=self.client_name,
|
||||
name="warning",
|
||||
type="invite",
|
||||
guild_id=message.guild.id,
|
||||
guild_name=message.guild.name,
|
||||
value=1,
|
||||
)
|
||||
await Stat(meta=md).insert()
|
||||
embed = warning_embed(message.author, "Sent an invite link", self.user)
|
||||
try:
|
||||
await message.channel.send(embeds=embed)
|
||||
|
@ -123,8 +133,16 @@ class MessageEventMixin:
|
|||
reason="Sent a message with a filtered word",
|
||||
user=message.author.id,
|
||||
).commit()
|
||||
tracker = warnings_tracker.labels(guild_id=message.guild.id, guild_name=message.guild.name)
|
||||
tracker.inc()
|
||||
md = WarningMetadata(
|
||||
client_id=self.user.id,
|
||||
client_name=self.client_name,
|
||||
name="warning",
|
||||
type="filter",
|
||||
guild_id=message.guild.id,
|
||||
guild_name=message.guild.name,
|
||||
value=1,
|
||||
)
|
||||
await Stat(meta=md).insert()
|
||||
embed = warning_embed(message.author, "Sent a message with a filtered word", self.user)
|
||||
try:
|
||||
await message.reply(embeds=embed)
|
||||
|
@ -169,8 +187,16 @@ class MessageEventMixin:
|
|||
reason="Mass Mention",
|
||||
user=message.author.id,
|
||||
).commit()
|
||||
tracker = warnings_tracker.labels(guild_id=message.guild.id, guild_name=message.guild.name)
|
||||
tracker.inc()
|
||||
md = WarningMetadata(
|
||||
client_id=self.user.id,
|
||||
client_name=self.client_name,
|
||||
name="warning",
|
||||
type="massmention",
|
||||
guild_id=message.guild.id,
|
||||
guild_name=message.guild.name,
|
||||
value=1,
|
||||
)
|
||||
await Stat(meta=md).insert()
|
||||
embed = warning_embed(message.author, "Mass Mention", self.user)
|
||||
try:
|
||||
await message.channel.send(embeds=embed)
|
||||
|
@ -233,8 +259,16 @@ class MessageEventMixin:
|
|||
reason="Pinged a blocked role/user with a blocked role",
|
||||
user=message.author.id,
|
||||
).commit()
|
||||
tracker = warnings_tracker.labels(guild_id=message.guild.id, guild_name=message.guild.name)
|
||||
tracker.inc()
|
||||
md = WarningMetadata(
|
||||
client_id=self.user.id,
|
||||
client_name=self.client_name,
|
||||
name="warning",
|
||||
type="roleping",
|
||||
guild_id=message.guild.id,
|
||||
guild_name=message.guild.name,
|
||||
value=1,
|
||||
)
|
||||
await Stat(meta=md).insert()
|
||||
embed = warning_embed(message.author, "Pinged a blocked role/user with a blocked role", self.user)
|
||||
try:
|
||||
await message.channel.send(embeds=embed)
|
||||
|
@ -261,8 +295,16 @@ class MessageEventMixin:
|
|||
reason="Phishing URL",
|
||||
user=message.author.id,
|
||||
).commit()
|
||||
tracker = warnings_tracker.labels(guild_id=message.guild.id, guild_name=message.guild.name)
|
||||
tracker.inc()
|
||||
md = WarningMetadata(
|
||||
client_id=self.user.id,
|
||||
client_name=self.client_name,
|
||||
name="warning",
|
||||
type="phishing",
|
||||
guild_id=message.guild.id,
|
||||
guild_name=message.guild.name,
|
||||
value=1,
|
||||
)
|
||||
await Stat(meta=md).insert()
|
||||
embed = warning_embed(message.author, "Phishing URL", self.user)
|
||||
try:
|
||||
await message.channel.send(embeds=embed)
|
||||
|
@ -272,8 +314,6 @@ class MessageEventMixin:
|
|||
await message.delete()
|
||||
except Exception:
|
||||
self.logger.warn("Failed to delete malicious message")
|
||||
tracker = malicious_tracker.labels(guild_id=message.guild.id, guild_name=message.guild.name)
|
||||
tracker.inc()
|
||||
|
||||
if not pl or not pl.confirmed:
|
||||
if not pl:
|
||||
|
@ -286,8 +326,8 @@ class MessageEventMixin:
|
|||
fields=[EmbedField(name="URL", value=m)],
|
||||
)
|
||||
|
||||
valid_button = Button(style=ButtonStyles.GREEN, emoji="✔️", custom_id=f"pl|valid|{pl.id}")
|
||||
invalid_button = Button(style=ButtonStyles.RED, emoji="✖️", custom_id=f"pl|invalid|{pl.id}")
|
||||
valid_button = Button(style=ButtonStyle.GREEN, emoji="✔️", custom_id=f"pl|valid|{pl.id}")
|
||||
invalid_button = Button(style=ButtonStyle.RED, emoji="✖️", custom_id=f"pl|invalid|{pl.id}")
|
||||
|
||||
channel = await self.fetch_channel(1026918337554423868)
|
||||
|
||||
|
@ -331,8 +371,16 @@ class MessageEventMixin:
|
|||
reason="Unsafe URL",
|
||||
user=message.author.id,
|
||||
).commit()
|
||||
tracker = warnings_tracker.labels(guild_id=message.guild.id, guild_name=message.guild.name)
|
||||
tracker.inc()
|
||||
md = WarningMetadata(
|
||||
client_id=self.user.id,
|
||||
client_name=self.client_name,
|
||||
name="warning",
|
||||
type="malicious",
|
||||
guild_id=message.guild.id,
|
||||
guild_name=message.guild.name,
|
||||
value=1,
|
||||
)
|
||||
await Stat(meta=md).insert()
|
||||
reasons = ", ".join(f"{m['source']}: {m['type']}" for m in data["matches"])
|
||||
embed = warning_embed(message.author, reasons, self.user)
|
||||
try:
|
||||
|
@ -343,8 +391,6 @@ class MessageEventMixin:
|
|||
await message.delete()
|
||||
except Exception:
|
||||
self.logger.warn("Failed to delete malicious message")
|
||||
tracker = malicious_tracker.labels(guild_id=message.guild.id, guild_name=message.guild.name)
|
||||
tracker.inc()
|
||||
|
||||
if not pl or not pl.confirmed:
|
||||
if not pl:
|
||||
|
@ -357,8 +403,8 @@ class MessageEventMixin:
|
|||
fields=[EmbedField(name="URL", value=m)],
|
||||
)
|
||||
|
||||
valid_button = Button(style=ButtonStyles.GREEN, emoji="✔️", custom_id=f"pl|valid|{pl.id}")
|
||||
invalid_button = Button(style=ButtonStyles.RED, emoji="✖️", custom_id=f"pl|invalid|{pl.id}")
|
||||
valid_button = Button(style=ButtonStyle.GREEN, emoji="✔️", custom_id=f"pl|valid|{pl.id}")
|
||||
invalid_button = Button(style=ButtonStyle.RED, emoji="✖️", custom_id=f"pl|invalid|{pl.id}")
|
||||
|
||||
channel = await self.fetch_channel(1026918337554423868)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ from interactions import Client, Extension, InteractionContext, Permissions
|
|||
from interactions.client.utils.misc_utils import find
|
||||
from interactions.models.discord.channel import GuildText
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -81,11 +81,11 @@ class AutoReactCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Autoreact channel to add emote to",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.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=OptionType.BOOLEAN, required=False)
|
||||
@slash_option(name="emote", description="Emote to add", opt_type=OptionType.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
|
||||
|
@ -138,13 +138,13 @@ class AutoReactCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Autoreact channel to remove emote from",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.CHANNEL,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="emote",
|
||||
description="Emote to remove (use all to delete)",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
@ -179,7 +179,7 @@ class AutoReactCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to remove autoreact from",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.CHANNEL,
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
@ -197,7 +197,7 @@ class AutoReactCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Autoreact channel to list",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.CHANNEL,
|
||||
required=True,
|
||||
)
|
||||
async def _autoreact_list(self, ctx: InteractionContext, channel: GuildText) -> None:
|
||||
|
|
|
@ -8,7 +8,7 @@ from interactions.ext.paginators import Paginator
|
|||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.user import User
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
SlashCommandChoice,
|
||||
slash_command,
|
||||
|
@ -84,12 +84,12 @@ class BanCog(ModcaseCog):
|
|||
await ctx.send(embeds=embed)
|
||||
|
||||
@slash_command(name="ban", description="Ban a user")
|
||||
@slash_option(name="user", description="User to ban", opt_type=OptionTypes.USER, required=True)
|
||||
@slash_option(name="reason", description="Ban reason", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="user", description="User to ban", opt_type=OptionType.USER, required=True)
|
||||
@slash_option(name="reason", description="Ban reason", opt_type=OptionType.STRING, required=True)
|
||||
@slash_option(
|
||||
name="btype",
|
||||
description="Ban type",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
choices=[
|
||||
SlashCommandChoice(name="Permanent", value="perm"),
|
||||
|
@ -100,13 +100,13 @@ class BanCog(ModcaseCog):
|
|||
@slash_option(
|
||||
name="duration",
|
||||
description="Temp ban duration in hours",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=False,
|
||||
)
|
||||
@slash_option(
|
||||
name="delete_history",
|
||||
description="Delete message history, format: 1w 3d 7h 5m 20s",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
|
@ -197,8 +197,8 @@ class BanCog(ModcaseCog):
|
|||
await ctx.guild.unban(user, reason="Ban was softban")
|
||||
|
||||
@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)
|
||||
@slash_option(name="user", description="User to unban", opt_type=OptionType.STRING, required=True)
|
||||
@slash_option(name="reason", description="Unban reason", opt_type=OptionType.STRING, required=True)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
async def _unban(
|
||||
self,
|
||||
|
@ -288,7 +288,7 @@ class BanCog(ModcaseCog):
|
|||
@slash_option(
|
||||
name="btype",
|
||||
description="Ban type",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=False,
|
||||
choices=[
|
||||
SlashCommandChoice(name="All", value=0),
|
||||
|
@ -300,7 +300,7 @@ class BanCog(ModcaseCog):
|
|||
@slash_option(
|
||||
name="active",
|
||||
description="Active bans",
|
||||
opt_type=OptionTypes.BOOLEAN,
|
||||
opt_type=OptionType.BOOLEAN,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
|
|
|
@ -13,7 +13,7 @@ from interactions import (
|
|||
)
|
||||
from interactions.models.discord.modal import InputText, Modal, TextStyles
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -88,7 +88,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=OptionType.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)
|
||||
|
@ -98,7 +98,7 @@ class FilterCog(Extension):
|
|||
name="name",
|
||||
description="Filter to edit",
|
||||
autocomplete=True,
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_MESSAGES))
|
||||
|
@ -110,7 +110,7 @@ class FilterCog(Extension):
|
|||
name="name",
|
||||
description="Filter to view",
|
||||
autocomplete=True,
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
async def _filter_view(self, ctx: InteractionContext, name: str) -> None:
|
||||
|
@ -128,7 +128,7 @@ class FilterCog(Extension):
|
|||
name="name",
|
||||
description="Filter to delete",
|
||||
autocomplete=True,
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_MESSAGES))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
from interactions import InteractionContext, Permissions
|
||||
from interactions.models.discord.user import User
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
slash_command,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -18,8 +18,8 @@ class KickCog(ModcaseCog):
|
|||
"""JARVIS KickCog."""
|
||||
|
||||
@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="user", description="User to kick", opt_type=OptionType.USER, required=True)
|
||||
@slash_option(name="reason", description="Kick reason", opt_type=OptionType.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:
|
||||
|
|
|
@ -7,7 +7,7 @@ from interactions.client.utils.misc_utils import get
|
|||
from interactions.models.discord.channel import GuildText, GuildVoice
|
||||
from interactions.models.discord.enums import Permissions
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
slash_command,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -89,7 +89,7 @@ class LockCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to unlock",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.CHANNEL,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_CHANNELS))
|
||||
|
|
|
@ -8,7 +8,7 @@ from interactions.models.discord.enums import Permissions
|
|||
from interactions.models.discord.guild import Guild
|
||||
from interactions.models.discord.user import Member
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -108,11 +108,11 @@ 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=OptionType.STRING, required=True)
|
||||
@slash_option(
|
||||
name="duration",
|
||||
description="Duration in minutes",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_CHANNELS))
|
||||
|
|
|
@ -6,7 +6,7 @@ from interactions.ext.paginators import Paginator
|
|||
from interactions.models.discord.embed import Embed, EmbedField
|
||||
from interactions.models.discord.user import Member
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -184,13 +184,13 @@ class CaseCog(Extension):
|
|||
@slash_option(
|
||||
name="user",
|
||||
description="User to filter cases to",
|
||||
opt_type=OptionTypes.USER,
|
||||
opt_type=OptionType.USER,
|
||||
required=False,
|
||||
)
|
||||
@slash_option(
|
||||
name="closed",
|
||||
description="Include closed cases",
|
||||
opt_type=OptionTypes.BOOLEAN,
|
||||
opt_type=OptionType.BOOLEAN,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
|
@ -214,7 +214,7 @@ class CaseCog(Extension):
|
|||
show = case.group(name="show", description="Show information about a specific case")
|
||||
|
||||
@show.subcommand(sub_cmd_name="summary", sub_cmd_description="Summarize a specific case")
|
||||
@slash_option(name="cid", description="Case ID", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="cid", description="Case ID", opt_type=OptionType.STRING, required=True)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
async def _case_show_summary(self, ctx: InteractionContext, cid: str) -> None:
|
||||
case = await Modlog.find_one(q(guild=ctx.guild.id, nanoid=cid))
|
||||
|
@ -226,7 +226,7 @@ class CaseCog(Extension):
|
|||
await ctx.send(embeds=embed)
|
||||
|
||||
@show.subcommand(sub_cmd_name="actions", sub_cmd_description="Get case actions")
|
||||
@slash_option(name="cid", description="Case ID", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="cid", description="Case ID", opt_type=OptionType.STRING, required=True)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
async def _case_show_actions(self, ctx: InteractionContext, cid: str) -> None:
|
||||
case = await Modlog.find_one(q(guild=ctx.guild.id, nanoid=cid))
|
||||
|
@ -239,7 +239,7 @@ class CaseCog(Extension):
|
|||
await paginator.send(ctx)
|
||||
|
||||
@case.subcommand(sub_cmd_name="close", sub_cmd_description="Show a specific case")
|
||||
@slash_option(name="cid", description="Case ID", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="cid", description="Case ID", opt_type=OptionType.STRING, required=True)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
async def _case_close(self, ctx: InteractionContext, cid: str) -> None:
|
||||
case = await Modlog.find_one(q(guild=ctx.guild.id, nanoid=cid))
|
||||
|
@ -254,7 +254,7 @@ class CaseCog(Extension):
|
|||
await ctx.send(embeds=embed)
|
||||
|
||||
@case.subcommand(sub_cmd_name="repoen", sub_cmd_description="Reopen a specific case")
|
||||
@slash_option(name="cid", description="Case ID", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="cid", description="Case ID", opt_type=OptionType.STRING, required=True)
|
||||
@check(admin_or_permissions(Permissions.BAN_MEMBERS))
|
||||
async def _case_reopen(self, ctx: InteractionContext, cid: str) -> None:
|
||||
case = await Modlog.find_one(q(guild=ctx.guild.id, nanoid=cid))
|
||||
|
@ -269,8 +269,8 @@ class CaseCog(Extension):
|
|||
await ctx.send(embeds=embed)
|
||||
|
||||
@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="cid", description="Case ID", opt_type=OptionType.STRING, required=True)
|
||||
@slash_option(name="note", description="Note to add", opt_type=OptionType.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))
|
||||
|
@ -295,8 +295,8 @@ class CaseCog(Extension):
|
|||
await ctx.send(embeds=embed)
|
||||
|
||||
@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="user", description="Target user", opt_type=OptionType.USER, required=True)
|
||||
@slash_option(name="note", description="Note to add", opt_type=OptionType.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))
|
||||
|
|
|
@ -9,8 +9,8 @@ from interactions.client.errors import Forbidden
|
|||
from interactions.models.discord.modal import InputText, Modal, TextStyles
|
||||
from interactions.models.discord.user import Member
|
||||
from interactions.models.internal.application_commands import (
|
||||
CommandTypes,
|
||||
OptionTypes,
|
||||
CommandType,
|
||||
OptionType,
|
||||
SlashCommandChoice,
|
||||
context_menu,
|
||||
slash_command,
|
||||
|
@ -41,7 +41,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)
|
||||
@context_menu(name="Mute User", context_type=CommandType.USER)
|
||||
@check(admin_or_permissions(Permissions.MUTE_MEMBERS, Permissions.BAN_MEMBERS, Permissions.KICK_MEMBERS))
|
||||
async def _timeout_cm(self, ctx: InteractionContext) -> None:
|
||||
modal = Modal(
|
||||
|
@ -103,23 +103,23 @@ class MuteCog(ModcaseCog):
|
|||
await response.send("Unable to mute this user", ephemeral=True)
|
||||
|
||||
@slash_command(name="mute", description="Mute a user")
|
||||
@slash_option(name="user", description="User to mute", opt_type=OptionTypes.USER, required=True)
|
||||
@slash_option(name="user", description="User to mute", opt_type=OptionType.USER, required=True)
|
||||
@slash_option(
|
||||
name="reason",
|
||||
description="Reason for mute",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="time",
|
||||
description="Duration of mute, default 1",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=False,
|
||||
)
|
||||
@slash_option(
|
||||
name="scale",
|
||||
description="Time scale, default Hour(s)",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=False,
|
||||
choices=[
|
||||
SlashCommandChoice(name="Minute(s)", value=1),
|
||||
|
@ -159,8 +159,8 @@ 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)
|
||||
@slash_option(name="user", description="User to unmute", opt_type=OptionType.USER, required=True)
|
||||
@slash_option(name="reason", description="Reason for unmute", opt_type=OptionType.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 (
|
||||
|
|
|
@ -4,7 +4,7 @@ import logging
|
|||
from interactions import Client, Extension, InteractionContext, Permissions
|
||||
from interactions.models.discord.channel import GuildText
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
slash_command,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -26,7 +26,7 @@ class PurgeCog(Extension):
|
|||
@slash_option(
|
||||
name="amount",
|
||||
description="Amount of messages to purge, default 10",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_MESSAGES))
|
||||
|
@ -51,13 +51,13 @@ class PurgeCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to autopurge",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.CHANNEL,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="delay",
|
||||
description="Seconds to keep message before purge, default 30",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_MESSAGES))
|
||||
|
@ -90,7 +90,7 @@ class PurgeCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to remove from autopurge",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.CHANNEL,
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_MESSAGES))
|
||||
|
@ -110,13 +110,13 @@ class PurgeCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to update",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.CHANNEL,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="delay",
|
||||
description="New time to save",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_MESSAGES))
|
||||
|
|
|
@ -8,7 +8,7 @@ from interactions.models.discord.embed import EmbedField
|
|||
from interactions.models.discord.role import Role
|
||||
from interactions.models.discord.user import Member
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -33,7 +33,7 @@ class RolepingCog(Extension):
|
|||
sub_cmd_name="add",
|
||||
sub_cmd_description="Add a role to roleping",
|
||||
)
|
||||
@slash_option(name="role", description="Role to add", opt_type=OptionTypes.ROLE, required=True)
|
||||
@slash_option(name="role", description="Role to add", opt_type=OptionType.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _roleping_add(self, ctx: InteractionContext, role: Role) -> None:
|
||||
roleping = await Roleping.find_one(q(guild=ctx.guild.id, role=role.id))
|
||||
|
@ -55,7 +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=OptionType.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))
|
||||
|
@ -133,8 +133,8 @@ class RolepingCog(Extension):
|
|||
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=OptionType.USER, required=True)
|
||||
@slash_option(name="role", description="Rolepinged role", opt_type=OptionType.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
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))
|
||||
|
@ -170,8 +170,8 @@ 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=OptionType.ROLE, required=True)
|
||||
@slash_option(name="role", description="Rolepinged role", opt_type=OptionType.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _roleping_bypass_role(self, ctx: InteractionContext, bypass: Role, role: Role) -> None:
|
||||
if bypass.id == ctx.guild.id:
|
||||
|
@ -203,8 +203,8 @@ 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=OptionType.USER, required=True)
|
||||
@slash_option(name="role", description="Rolepinged role", opt_type=OptionType.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
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))
|
||||
|
@ -224,8 +224,8 @@ 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=OptionType.ROLE, required=True)
|
||||
@slash_option(name="role", description="Rolepinged role", opt_type=OptionType.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
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))
|
||||
|
|
|
@ -5,12 +5,12 @@ from typing import Any
|
|||
|
||||
from interactions import AutocompleteContext, Client, Extension, InteractionContext
|
||||
from interactions.models.discord.channel import GuildText
|
||||
from interactions.models.discord.components import ActionRow, Button, ButtonStyles
|
||||
from interactions.models.discord.components import ActionRow, Button, ButtonStyle
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.enums import Permissions
|
||||
from interactions.models.discord.role import Role
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -55,7 +55,7 @@ class SettingsCog(Extension):
|
|||
sub_cmd_name="modlog",
|
||||
sub_cmd_description="Set Moglod channel",
|
||||
)
|
||||
@slash_option(name="channel", description="ModLog Channel", opt_type=OptionTypes.CHANNEL, required=True)
|
||||
@slash_option(name="channel", description="ModLog Channel", opt_type=OptionType.CHANNEL, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _set_modlog(self, ctx: InteractionContext, channel: GuildText) -> None:
|
||||
if not isinstance(channel, GuildText):
|
||||
|
@ -71,7 +71,7 @@ class SettingsCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Activitylog Channel",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.CHANNEL,
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
@ -86,7 +86,7 @@ class SettingsCog(Extension):
|
|||
@slash_option(
|
||||
name="amount",
|
||||
description="Amount of mentions (0 to disable)",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
@ -96,7 +96,7 @@ class SettingsCog(Extension):
|
|||
await ctx.send(f"Settings applied. New massmention limit is {amount}")
|
||||
|
||||
@set_.subcommand(sub_cmd_name="verified", sub_cmd_description="Set verified role")
|
||||
@slash_option(name="role", description="Verified role", opt_type=OptionTypes.ROLE, required=True)
|
||||
@slash_option(name="role", description="Verified role", opt_type=OptionType.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _set_verified(self, ctx: InteractionContext, role: Role) -> None:
|
||||
if role.id == ctx.guild.id:
|
||||
|
@ -113,7 +113,7 @@ class SettingsCog(Extension):
|
|||
await ctx.send(f"Settings applied. New verified role is `{role.name}`")
|
||||
|
||||
@set_.subcommand(sub_cmd_name="unverified", sub_cmd_description="Set unverified role")
|
||||
@slash_option(name="role", description="Unverified role", opt_type=OptionTypes.ROLE, required=True)
|
||||
@slash_option(name="role", description="Unverified role", opt_type=OptionType.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _set_unverified(self, ctx: InteractionContext, role: Role) -> None:
|
||||
if role.id == ctx.guild.id:
|
||||
|
@ -130,7 +130,7 @@ class SettingsCog(Extension):
|
|||
await ctx.send(f"Settings applied. New unverified role is `{role.name}`")
|
||||
|
||||
@set_.subcommand(sub_cmd_name="noinvite", sub_cmd_description="Set if invite deletion should happen")
|
||||
@slash_option(name="active", description="Active?", opt_type=OptionTypes.BOOLEAN, required=True)
|
||||
@slash_option(name="active", description="Active?", opt_type=OptionType.BOOLEAN, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _set_invitedel(self, ctx: InteractionContext, active: bool) -> None:
|
||||
await ctx.defer()
|
||||
|
@ -138,7 +138,7 @@ class SettingsCog(Extension):
|
|||
await ctx.send(f"Settings applied. Automatic invite active: {active}")
|
||||
|
||||
@set_.subcommand(sub_cmd_name="notify", sub_cmd_description="Notify users of admin action?")
|
||||
@slash_option(name="active", description="Notify?", opt_type=OptionTypes.BOOLEAN, required=True)
|
||||
@slash_option(name="active", description="Notify?", opt_type=OptionType.BOOLEAN, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _set_notify(self, ctx: InteractionContext, active: bool) -> None:
|
||||
await ctx.defer()
|
||||
|
@ -146,7 +146,7 @@ class SettingsCog(Extension):
|
|||
await ctx.send(f"Settings applied. Notifications active: {active}")
|
||||
|
||||
@set_.subcommand(sub_cmd_name="log_ignore", sub_cmd_description="Ignore a channel for ActivityLog")
|
||||
@slash_option(name="channel", description="Channel to ignore", opt_type=OptionTypes.CHANNEL, required=True)
|
||||
@slash_option(name="channel", description="Channel to ignore", opt_type=OptionType.CHANNEL, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _add_log_ignore(self, ctx: InteractionContext, channel: GuildText) -> None:
|
||||
if not isinstance(channel, GuildText):
|
||||
|
@ -224,7 +224,7 @@ class SettingsCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to stop ignoring",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
|
@ -293,8 +293,8 @@ class SettingsCog(Extension):
|
|||
async def _clear(self, ctx: InteractionContext) -> None:
|
||||
components = [
|
||||
ActionRow(
|
||||
Button(style=ButtonStyles.RED, emoji="✖️", custom_id=f"{ctx.guild.id}|set_clear|no"),
|
||||
Button(style=ButtonStyles.GREEN, emoji="✔️", custom_id=f"{ctx.guild.id}|set_clear|yes"),
|
||||
Button(style=ButtonStyle.RED, emoji="✖️", custom_id=f"{ctx.guild.id}|set_clear|no"),
|
||||
Button(style=ButtonStyle.GREEN, emoji="✔️", custom_id=f"{ctx.guild.id}|set_clear|yes"),
|
||||
)
|
||||
]
|
||||
message = await ctx.send("***Are you sure?***", components=components)
|
||||
|
|
|
@ -7,11 +7,11 @@ from dateparser_data.settings import default_parsers
|
|||
from interactions import Client, Extension, InteractionContext, Permissions
|
||||
from interactions.models.discord.components import Button
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.enums import ButtonStyles
|
||||
from interactions.models.discord.enums import ButtonStyle
|
||||
from interactions.models.discord.role import Role
|
||||
from interactions.models.discord.user import Member
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
slash_command,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -30,18 +30,18 @@ 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=OptionType.USER, required=True)
|
||||
@slash_option(name="role", description="Role to grant", opt_type=OptionType.ROLE, required=True)
|
||||
@slash_option(
|
||||
name="duration",
|
||||
description="Duration of temp role (i.e. 2 hours)",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="reason",
|
||||
description="Reason for temporary role",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_ROLES))
|
||||
|
@ -109,5 +109,5 @@ class TemproleCog(Extension):
|
|||
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}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
|
|
@ -4,7 +4,7 @@ import logging
|
|||
from random import randint
|
||||
|
||||
from interactions import Client, Extension, InteractionContext
|
||||
from interactions.models.discord.components import Button, ButtonStyles, spread_to_rows
|
||||
from interactions.models.discord.components import Button, ButtonStyle, spread_to_rows
|
||||
from interactions.models.internal.application_commands import slash_command
|
||||
from interactions.models.internal.command import cooldown
|
||||
from interactions.models.internal.cooldowns import Buckets
|
||||
|
@ -19,7 +19,7 @@ def create_layout() -> list:
|
|||
for i in range(3):
|
||||
label = "YES" if i == yes else "NO"
|
||||
id = f"no_{i}" if not i == yes else "yes"
|
||||
color = ButtonStyles.GREEN if i == yes else ButtonStyles.RED
|
||||
color = ButtonStyle.GREEN if i == yes else ButtonStyle.RED
|
||||
buttons.append(
|
||||
Button(
|
||||
style=color,
|
||||
|
|
|
@ -7,7 +7,7 @@ from interactions.ext.paginators import Paginator
|
|||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.user import Member
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
slash_command,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -25,17 +25,17 @@ class WarningCog(ModcaseCog):
|
|||
"""JARVIS WarningCog."""
|
||||
|
||||
@slash_command(name="warn", description="Warn a user")
|
||||
@slash_option(name="user", description="User to warn", opt_type=OptionTypes.USER, required=True)
|
||||
@slash_option(name="user", description="User to warn", opt_type=OptionType.USER, required=True)
|
||||
@slash_option(
|
||||
name="reason",
|
||||
description="Reason for warning",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="duration",
|
||||
description="Duration of warning in hours, default 24",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
@ -67,11 +67,11 @@ class WarningCog(ModcaseCog):
|
|||
await ctx.send(embeds=embed)
|
||||
|
||||
@slash_command(name="warnings", description="Get count of user warnings")
|
||||
@slash_option(name="user", description="User to view", opt_type=OptionTypes.USER, required=True)
|
||||
@slash_option(name="user", description="User to view", opt_type=OptionType.USER, required=True)
|
||||
@slash_option(
|
||||
name="active",
|
||||
description="View active only",
|
||||
opt_type=OptionTypes.BOOLEAN,
|
||||
opt_type=OptionType.BOOLEAN,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
|
|
@ -11,7 +11,7 @@ from interactions.ext.prefixed_commands.command import prefixed_command
|
|||
from interactions.ext.prefixed_commands.context import PrefixedContext
|
||||
from interactions.models.discord.components import Button
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.enums import ButtonStyles
|
||||
from interactions.models.discord.enums import ButtonStyle
|
||||
from interactions.models.discord.file import File
|
||||
from rich.console import Console
|
||||
|
||||
|
@ -86,7 +86,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=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@prefixed_command(name="update")
|
||||
|
@ -118,7 +118,7 @@ class BotutilCog(Extension):
|
|||
|
||||
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=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
if len(content) < 3000:
|
||||
await ctx.reply(content, embeds=embed, components=components)
|
||||
else:
|
||||
|
@ -131,7 +131,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=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.reply(embeds=embed, components=components)
|
||||
|
||||
|
||||
|
|
|
@ -11,10 +11,10 @@ from interactions import AutocompleteContext, Client, Extension, InteractionCont
|
|||
from interactions.models.discord.channel import GuildChannel
|
||||
from interactions.models.discord.components import ActionRow, Button
|
||||
from interactions.models.discord.embed import Embed, EmbedField
|
||||
from interactions.models.discord.enums import ButtonStyles
|
||||
from interactions.models.discord.enums import ButtonStyle
|
||||
from interactions.models.discord.modal import InputText, Modal, TextStyles
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -45,7 +45,7 @@ class RemindmeCog(Extension):
|
|||
@slash_option(
|
||||
name="private",
|
||||
description="Send as DM?",
|
||||
opt_type=OptionTypes.BOOLEAN,
|
||||
opt_type=OptionType.BOOLEAN,
|
||||
required=False,
|
||||
)
|
||||
async def _remindme(
|
||||
|
@ -159,10 +159,10 @@ class RemindmeCog(Extension):
|
|||
icon_url=ctx.author.display_avatar.url,
|
||||
)
|
||||
embed.set_thumbnail(url=ctx.author.display_avatar.url)
|
||||
delete_button = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
delete_button = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = [delete_button]
|
||||
if not r.guild == ctx.author.id:
|
||||
copy_button = Button(style=ButtonStyles.GREEN, emoji="📋", custom_id=f"copy|rme|{r.id}")
|
||||
copy_button = Button(style=ButtonStyle.GREEN, emoji="📋", custom_id=f"copy|rme|{r.id}")
|
||||
components.append(copy_button)
|
||||
private = private if private is not None else False
|
||||
components = [ActionRow(*components)]
|
||||
|
@ -211,14 +211,14 @@ class RemindmeCog(Extension):
|
|||
return
|
||||
|
||||
embed = await self.get_reminders_embed(ctx, reminders)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@reminders.subcommand(sub_cmd_name="delete", sub_cmd_description="Delete a reminder")
|
||||
@slash_option(
|
||||
name="content",
|
||||
description="Content of the reminder",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
|
@ -244,7 +244,7 @@ class RemindmeCog(Extension):
|
|||
)
|
||||
embed.set_thumbnail(url=ctx.author.display_avatar.url)
|
||||
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
try:
|
||||
await reminder.delete()
|
||||
except Exception:
|
||||
|
@ -258,7 +258,7 @@ class RemindmeCog(Extension):
|
|||
@slash_option(
|
||||
name="content",
|
||||
description="Content of the reminder",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
|
@ -283,7 +283,7 @@ class RemindmeCog(Extension):
|
|||
)
|
||||
|
||||
embed.set_thumbnail(url=ctx.author.display_avatar.url)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, ephemeral=reminder.private, components=components)
|
||||
if reminder.remind_at <= datetime.now(tz=timezone.utc) and not reminder.active:
|
||||
try:
|
||||
|
|
|
@ -10,7 +10,7 @@ from asyncpraw.models.reddit.submission import Subreddit as Sub
|
|||
from asyncprawcore.exceptions import Forbidden, NotFound, Redirect
|
||||
from interactions import Client, Extension, InteractionContext, Permissions
|
||||
from interactions.client.utils.misc_utils import get
|
||||
from interactions.models.discord.channel import ChannelTypes, GuildText
|
||||
from interactions.models.discord.channel import ChannelType, GuildText
|
||||
from interactions.models.discord.components import (
|
||||
ActionRow,
|
||||
StringSelectMenu,
|
||||
|
@ -18,7 +18,7 @@ from interactions.models.discord.components import (
|
|||
)
|
||||
from interactions.models.discord.embed import Embed, EmbedField
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
SlashCommandChoice,
|
||||
slash_option,
|
||||
|
@ -143,14 +143,14 @@ class RedditCog(Extension):
|
|||
@slash_option(
|
||||
name="name",
|
||||
description="Redditor name",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to post to",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
channel_types=[ChannelTypes.GUILD_TEXT],
|
||||
opt_type=OptionType.CHANNEL,
|
||||
channel_types=[ChannelType.GUILD_TEXT],
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
@ -255,14 +255,14 @@ class RedditCog(Extension):
|
|||
@slash_option(
|
||||
name="name",
|
||||
description="Subreddit display name",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to post to",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
channel_types=[ChannelTypes.GUILD_TEXT],
|
||||
opt_type=OptionType.CHANNEL,
|
||||
channel_types=[ChannelType.GUILD_TEXT],
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
@ -371,7 +371,7 @@ class RedditCog(Extension):
|
|||
await message.edit(components=components)
|
||||
|
||||
@reddit.subcommand(sub_cmd_name="hot", sub_cmd_description="Get the hot post of a subreddit")
|
||||
@slash_option(name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="name", description="Subreddit name", opt_type=OptionType.STRING, required=True)
|
||||
async def _subreddit_hot(self, ctx: InteractionContext, name: str) -> None:
|
||||
if not sub_name.match(name):
|
||||
await ctx.send("Invalid Subreddit name", ephemeral=True)
|
||||
|
@ -404,11 +404,11 @@ class RedditCog(Extension):
|
|||
await ctx.send(embeds=embeds)
|
||||
|
||||
@reddit.subcommand(sub_cmd_name="top", sub_cmd_description="Get the top post of a subreddit")
|
||||
@slash_option(name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="name", description="Subreddit name", opt_type=OptionType.STRING, required=True)
|
||||
@slash_option(
|
||||
name="time",
|
||||
description="Top time",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=False,
|
||||
choices=[
|
||||
SlashCommandChoice(name="All", value="all"),
|
||||
|
@ -451,7 +451,7 @@ class RedditCog(Extension):
|
|||
await ctx.send(embeds=embeds)
|
||||
|
||||
@reddit.subcommand(sub_cmd_name="random", sub_cmd_description="Get a random post of a subreddit")
|
||||
@slash_option(name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="name", description="Subreddit name", opt_type=OptionType.STRING, required=True)
|
||||
async def _subreddit_random(self, ctx: InteractionContext, name: str) -> None:
|
||||
if not sub_name.match(name):
|
||||
await ctx.send("Invalid Subreddit name", ephemeral=True)
|
||||
|
@ -484,7 +484,7 @@ class RedditCog(Extension):
|
|||
await ctx.send(embeds=embeds)
|
||||
|
||||
@reddit.subcommand(sub_cmd_name="rising", sub_cmd_description="Get a rising post of a subreddit")
|
||||
@slash_option(name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="name", description="Subreddit name", opt_type=OptionType.STRING, required=True)
|
||||
async def _subreddit_rising(self, ctx: InteractionContext, name: str) -> None:
|
||||
if not sub_name.match(name):
|
||||
await ctx.send("Invalid Subreddit name", ephemeral=True)
|
||||
|
@ -517,7 +517,7 @@ class RedditCog(Extension):
|
|||
await ctx.send(embeds=embeds)
|
||||
|
||||
@reddit.subcommand(sub_cmd_name="post", sub_cmd_description="Get a specific submission")
|
||||
@slash_option(name="sid", description="Submission ID", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="sid", description="Submission ID", opt_type=OptionType.STRING, required=True)
|
||||
async def _reddit_post(self, ctx: InteractionContext, sid: str) -> None:
|
||||
await ctx.defer()
|
||||
try:
|
||||
|
@ -541,7 +541,7 @@ class RedditCog(Extension):
|
|||
await ctx.send(embeds=embeds)
|
||||
|
||||
@reddit.subcommand(sub_cmd_name="dm_nsfw", sub_cmd_description="DM NSFW posts if channel isn't NSFW")
|
||||
@slash_option(name="dm", description="Send DM?", opt_type=OptionTypes.BOOLEAN, required=True)
|
||||
@slash_option(name="dm", description="Send DM?", opt_type=OptionType.BOOLEAN, required=True)
|
||||
async def _reddit_dm(self, ctx: InteractionContext, dm: bool) -> None:
|
||||
setting = await UserSetting.find_one(q(user=ctx.author.id, type="reddit", setting="dm_nsfw"))
|
||||
if not setting:
|
||||
|
|
|
@ -12,7 +12,7 @@ from interactions.models.discord.components import (
|
|||
StringSelectOption,
|
||||
)
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -45,17 +45,17 @@ class TwitterCog(Extension):
|
|||
sub_cmd_name="follow",
|
||||
sub_cmd_description="Follow a Twitter acount",
|
||||
)
|
||||
@slash_option(name="handle", description="Twitter account", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="handle", description="Twitter account", opt_type=OptionType.STRING, required=True)
|
||||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to post tweets to",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.CHANNEL,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="retweets",
|
||||
description="Mirror re-tweets?",
|
||||
opt_type=OptionTypes.BOOLEAN,
|
||||
opt_type=OptionType.BOOLEAN,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
@ -171,7 +171,7 @@ class TwitterCog(Extension):
|
|||
@slash_option(
|
||||
name="retweets",
|
||||
description="Mirror re-tweets?",
|
||||
opt_type=OptionTypes.BOOLEAN,
|
||||
opt_type=OptionType.BOOLEAN,
|
||||
required=False,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
|
|
@ -9,19 +9,19 @@ from io import BytesIO
|
|||
|
||||
import numpy as np
|
||||
from dateparser import parse
|
||||
from interactions import Client, Extension, InteractionContext
|
||||
from interactions import Client, Extension, SlashContext
|
||||
from interactions import __version__ as ipyv
|
||||
from interactions.models.discord.channel import GuildCategory, GuildText, GuildVoice
|
||||
from interactions.models.discord.components import Button
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.enums import ButtonStyles
|
||||
from interactions.models.discord.enums import ButtonStyle
|
||||
from interactions.models.discord.file import File
|
||||
from interactions.models.discord.guild import Guild
|
||||
from interactions.models.discord.role import Role
|
||||
from interactions.models.discord.user import User
|
||||
from interactions.models.internal.application_commands import (
|
||||
CommandTypes,
|
||||
OptionTypes,
|
||||
CommandType,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
SlashCommandChoice,
|
||||
context_menu,
|
||||
|
@ -55,7 +55,7 @@ class UtilCog(Extension):
|
|||
bot = SlashCommand(name="bot", description="Bot commands")
|
||||
|
||||
@bot.subcommand(sub_cmd_name="sex", sub_cmd_description="Have sex with JARVIS")
|
||||
async def _sex(self, ctx: InteractionContext) -> None:
|
||||
async def _sex(self, ctx: SlashContext) -> None:
|
||||
if ctx.author.id == 264072583987593217:
|
||||
await ctx.send("Oh fuck no, go fuck yourself")
|
||||
elif ctx.author.id == 840031256201003008:
|
||||
|
@ -71,13 +71,15 @@ class UtilCog(Extension):
|
|||
|
||||
@bot.subcommand(sub_cmd_name="status", sub_cmd_description="Retrieve JARVIS status")
|
||||
@cooldown(bucket=Buckets.CHANNEL, rate=1, interval=30)
|
||||
async def _status(self, ctx: InteractionContext) -> None:
|
||||
async def _status(self, ctx: SlashContext) -> None:
|
||||
self.bot.logger.debug("Entered bot status")
|
||||
title = "JARVIS Status"
|
||||
desc = (
|
||||
f"All systems online"
|
||||
f"\nConnected to **{len(self.bot.guilds)}** guilds"
|
||||
f"\nListening for **{len(self.bot.application_commands)}** commands"
|
||||
)
|
||||
self.bot.logger.debug("Description made")
|
||||
color = "#3498db"
|
||||
fields = []
|
||||
uptime = int(self.bot.start_time.timestamp())
|
||||
|
@ -92,13 +94,14 @@ class UtilCog(Extension):
|
|||
fields.append(
|
||||
EmbedField(name="interactions", value=f"[{ipyv}](https://interactionspy.readthedocs.io)", inline=True)
|
||||
)
|
||||
self.bot.logger.debug("Getting repo information")
|
||||
repo_url = f"https://git.zevaryx.com/stark-industries/jarvis/jarvis-bot/-/tree/{get_repo_hash()}"
|
||||
fields.append(EmbedField(name="Git Hash", value=f"[{get_repo_hash()[:7]}]({repo_url})", inline=True))
|
||||
fields.append(EmbedField(name="Online Since", value=f"<t:{uptime}:F>", inline=False))
|
||||
num_domains = len(self.bot.phishing_domains)
|
||||
fields.append(EmbedField(name="Phishing Protection", value=f"Detecting {num_domains} phishing domains"))
|
||||
embed = build_embed(title=title, description=desc, fields=fields, color=color)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@bot.subcommand(
|
||||
|
@ -106,18 +109,18 @@ class UtilCog(Extension):
|
|||
sub_cmd_description="Get the current logo",
|
||||
)
|
||||
@cooldown(bucket=Buckets.CHANNEL, rate=1, interval=30)
|
||||
async def _logo(self, ctx: InteractionContext) -> None:
|
||||
async def _logo(self, ctx: SlashContext) -> None:
|
||||
with BytesIO() as image_bytes:
|
||||
JARVIS_LOGO.save(image_bytes, "PNG")
|
||||
image_bytes.seek(0)
|
||||
logo = File(image_bytes, file_name="logo.png")
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(file=logo, components=components)
|
||||
|
||||
rc = SlashCommand(name="rc", description="Robot Camo emoji commands")
|
||||
|
||||
@rc.subcommand(sub_cmd_name="hk", sub_cmd_description="Robot Camo HK416")
|
||||
async def _rchk(self, ctx: InteractionContext) -> None:
|
||||
async def _rchk(self, ctx: SlashContext) -> None:
|
||||
await ctx.send(content=hk, ephemeral=True)
|
||||
|
||||
@rc.subcommand(
|
||||
|
@ -127,10 +130,10 @@ class UtilCog(Extension):
|
|||
@slash_option(
|
||||
name="text",
|
||||
description="Text to camo-ify",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
async def _rcauto(self, ctx: InteractionContext, text: str) -> None:
|
||||
async def _rcauto(self, ctx: SlashContext, text: str) -> None:
|
||||
to_send = ""
|
||||
if len(text) == 1 and not re.match(r"^[A-Z0-9-()$@!?^'#. ]$", text.upper()):
|
||||
await ctx.send("Please use ASCII characters.", ephemeral=True)
|
||||
|
@ -148,7 +151,7 @@ class UtilCog(Extension):
|
|||
else:
|
||||
await ctx.send(to_send, ephemeral=True)
|
||||
|
||||
async def _avatar(self, ctx: InteractionContext, user: User = None) -> None:
|
||||
async def _avatar(self, ctx: SlashContext, user: User = None) -> None:
|
||||
if not user:
|
||||
user = ctx.author
|
||||
|
||||
|
@ -157,7 +160,7 @@ class UtilCog(Extension):
|
|||
embed = build_embed(title="Avatar", description="", fields=[], color="#00FFEE")
|
||||
embed.set_image(url=avatar)
|
||||
embed.set_author(name=f"{user.username}#{user.discriminator}", icon_url=avatar)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@slash_command(
|
||||
|
@ -167,10 +170,10 @@ class UtilCog(Extension):
|
|||
@slash_option(
|
||||
name="role",
|
||||
description="Role to get info of",
|
||||
opt_type=OptionTypes.ROLE,
|
||||
opt_type=OptionType.ROLE,
|
||||
required=True,
|
||||
)
|
||||
async def _roleinfo(self, ctx: InteractionContext, role: Role) -> None:
|
||||
async def _roleinfo(self, ctx: SlashContext, role: Role) -> None:
|
||||
fields = [
|
||||
EmbedField(name="ID", value=str(role.id), inline=True),
|
||||
EmbedField(name="Name", value=role.mention, inline=True),
|
||||
|
@ -205,25 +208,25 @@ class UtilCog(Extension):
|
|||
im.save(image_bytes, "PNG")
|
||||
image_bytes.seek(0)
|
||||
color_show = File(image_bytes, file_name="color_show.png")
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, file=color_show, components=components)
|
||||
|
||||
@slash_command(name="avatar", description="Get a user avatar")
|
||||
@slash_option(
|
||||
name="user",
|
||||
description="User to view avatar of",
|
||||
opt_type=OptionTypes.USER,
|
||||
opt_type=OptionType.USER,
|
||||
required=False,
|
||||
)
|
||||
@cooldown(bucket=Buckets.USER, rate=1, interval=5)
|
||||
async def _avatar_slash(self, ctx: InteractionContext, user: User = None) -> None:
|
||||
async def _avatar_slash(self, ctx: SlashContext, user: User = None) -> None:
|
||||
await self._avatar(ctx, user)
|
||||
|
||||
@context_menu(name="Avatar", context_type=CommandTypes.USER)
|
||||
async def _avatar_menu(self, ctx: InteractionContext) -> None:
|
||||
@context_menu(name="Avatar", context_type=CommandType.USER)
|
||||
async def _avatar_menu(self, ctx: SlashContext) -> None:
|
||||
await self._avatar(ctx, ctx.target)
|
||||
|
||||
async def _userinfo(self, ctx: InteractionContext, user: User = None) -> None:
|
||||
async def _userinfo(self, ctx: SlashContext, user: User = None) -> None:
|
||||
await ctx.defer()
|
||||
if not user:
|
||||
user = ctx.author
|
||||
|
@ -271,12 +274,12 @@ class UtilCog(Extension):
|
|||
)
|
||||
embed.set_thumbnail(url=user.display_avatar.url)
|
||||
embed.set_footer(text=f"ID: {user.id}")
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@slash_command(name="lmgtfy", description="Let me Google that for you")
|
||||
@slash_option(name="search", description="What to search", opt_type=OptionTypes.STRING, required=True)
|
||||
async def _lmgtfy(self, ctx: InteractionContext, search: str) -> None:
|
||||
@slash_option(name="search", description="What to search", opt_type=OptionType.STRING, required=True)
|
||||
async def _lmgtfy(self, ctx: SlashContext, search: str) -> None:
|
||||
url = "https://letmegooglethat.com/?q=" + urllib.parse.quote_plus(search)
|
||||
await ctx.send(url)
|
||||
|
||||
|
@ -287,18 +290,18 @@ class UtilCog(Extension):
|
|||
@slash_option(
|
||||
name="user",
|
||||
description="User to get info of",
|
||||
opt_type=OptionTypes.USER,
|
||||
opt_type=OptionType.USER,
|
||||
required=False,
|
||||
)
|
||||
async def _userinfo_slsh(self, ctx: InteractionContext, user: User = None) -> None:
|
||||
async def _userinfo_slsh(self, ctx: SlashContext, user: User = None) -> None:
|
||||
await self._userinfo(ctx, user)
|
||||
|
||||
@context_menu(name="User Info", context_type=CommandTypes.USER)
|
||||
async def _userinfo_menu(self, ctx: InteractionContext) -> None:
|
||||
@context_menu(name="User Info", context_type=CommandType.USER)
|
||||
async def _userinfo_menu(self, ctx: SlashContext) -> None:
|
||||
await self._userinfo(ctx, ctx.target)
|
||||
|
||||
@slash_command(name="serverinfo", description="Get server info")
|
||||
async def _server_info(self, ctx: InteractionContext) -> None:
|
||||
async def _server_info(self, ctx: SlashContext) -> None:
|
||||
guild: Guild = ctx.guild
|
||||
|
||||
owner = await guild.fetch_owner()
|
||||
|
@ -332,7 +335,7 @@ class UtilCog(Extension):
|
|||
embed.set_author(name=guild.name, icon_url=guild.icon.url)
|
||||
embed.set_thumbnail(url=guild.icon.url)
|
||||
embed.set_footer(text=f"ID: {guild.id} | Server Created")
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@slash_command(
|
||||
|
@ -344,13 +347,13 @@ class UtilCog(Extension):
|
|||
@slash_option(
|
||||
name="length",
|
||||
description="Password length (default 32)",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=False,
|
||||
)
|
||||
@slash_option(
|
||||
name="chars",
|
||||
description="Characters to include (default last option)",
|
||||
opt_type=OptionTypes.INTEGER,
|
||||
opt_type=OptionType.INTEGER,
|
||||
required=False,
|
||||
choices=[
|
||||
SlashCommandChoice(name="A-Za-z", value=0),
|
||||
|
@ -360,7 +363,7 @@ class UtilCog(Extension):
|
|||
],
|
||||
)
|
||||
@cooldown(bucket=Buckets.USER, rate=1, interval=15)
|
||||
async def _pw_gen(self, ctx: InteractionContext, length: int = 32, chars: int = 3) -> None:
|
||||
async def _pw_gen(self, ctx: SlashContext, length: int = 32, chars: int = 3) -> None:
|
||||
if length > 256:
|
||||
await ctx.send("Please limit password to 256 characters", ephemeral=True)
|
||||
return
|
||||
|
@ -381,8 +384,8 @@ class UtilCog(Extension):
|
|||
)
|
||||
|
||||
@slash_command(name="pigpen", description="Encode a string into pigpen")
|
||||
@slash_option(name="text", description="Text to encode", opt_type=OptionTypes.STRING, required=True)
|
||||
async def _pigpen(self, ctx: InteractionContext, text: str) -> None:
|
||||
@slash_option(name="text", description="Text to encode", opt_type=OptionType.STRING, required=True)
|
||||
async def _pigpen(self, ctx: SlashContext, text: str) -> None:
|
||||
outp = "`"
|
||||
for c in text:
|
||||
c = c.lower()
|
||||
|
@ -397,9 +400,9 @@ class UtilCog(Extension):
|
|||
await ctx.send(outp[:2000])
|
||||
|
||||
@slash_command(name="timestamp", description="Convert a datetime or timestamp into it's counterpart")
|
||||
@slash_option(name="string", description="String to convert", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="private", description="Respond quietly?", opt_type=OptionTypes.BOOLEAN, required=False)
|
||||
async def _timestamp(self, ctx: InteractionContext, string: str, private: bool = False) -> None:
|
||||
@slash_option(name="string", description="String to convert", opt_type=OptionType.STRING, required=True)
|
||||
@slash_option(name="private", description="Respond quietly?", opt_type=OptionType.BOOLEAN, required=False)
|
||||
async def _timestamp(self, ctx: SlashContext, string: str, private: bool = False) -> None:
|
||||
timestamp = parse(string)
|
||||
if not timestamp:
|
||||
await ctx.send("Valid time not found, try again", ephemeral=True)
|
||||
|
@ -420,11 +423,11 @@ class UtilCog(Extension):
|
|||
EmbedField(name="ISO8601", value=timestamp.isoformat()),
|
||||
]
|
||||
embed = build_embed(title="Converted Time", description=f"`{string}`", fields=fields)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, ephemeral=private, components=components)
|
||||
|
||||
@bot.subcommand(sub_cmd_name="support", sub_cmd_description="Got issues?")
|
||||
async def _support(self, ctx: InteractionContext) -> None:
|
||||
async def _support(self, ctx: SlashContext) -> None:
|
||||
await ctx.send(
|
||||
f"""
|
||||
Run into issues with {self.bot.user.mention}? Please report them here!
|
||||
|
@ -436,7 +439,7 @@ We'll help as best we can with whatever issues you encounter.
|
|||
)
|
||||
|
||||
@bot.subcommand(sub_cmd_name="privacy_terms", sub_cmd_description="View Privacy and Terms of Use")
|
||||
async def _privacy_terms(self, ctx: InteractionContext) -> None:
|
||||
async def _privacy_terms(self, ctx: SlashContext) -> None:
|
||||
await ctx.send(
|
||||
"""
|
||||
View the privacy statement here: https://s.zevs.me/jarvis-privacy
|
||||
|
|
|
@ -6,9 +6,9 @@ from calculator import calculate
|
|||
from interactions import AutocompleteContext, Client, Extension, InteractionContext
|
||||
from interactions.models.discord.components import Button
|
||||
from interactions.models.discord.embed import Embed, EmbedField
|
||||
from interactions.models.discord.enums import ButtonStyles
|
||||
from interactions.models.discord.enums import ButtonStyle
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
SlashCommandChoice,
|
||||
slash_option,
|
||||
|
@ -76,13 +76,13 @@ class CalcCog(Extension):
|
|||
calc = SlashCommand(name="calc", description="Calculate some things")
|
||||
|
||||
@calc.subcommand(sub_cmd_name="math", sub_cmd_description="Do a basic math calculation")
|
||||
@slash_option(name="expression", description="Expression to calculate", required=True, opt_type=OptionTypes.STRING)
|
||||
@slash_option(name="expression", description="Expression to calculate", required=True, opt_type=OptionType.STRING)
|
||||
async def _calc_math(self, ctx: InteractionContext, expression: str) -> None:
|
||||
if expression == "The answer to life, the universe, and everything":
|
||||
fields = (EmbedField(name="Expression", value=f"`{expression}`"), EmbedField(name="Result", value=str(42)))
|
||||
embed = build_embed(title="Calculator", description=None, fields=fields)
|
||||
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
return
|
||||
try:
|
||||
|
@ -97,18 +97,18 @@ class CalcCog(Extension):
|
|||
fields = (EmbedField(name="Expression", value=f"`{expression}`"), EmbedField(name="Result", value=str(value)))
|
||||
embed = build_embed(title="Calculator", description=None, fields=fields)
|
||||
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
convert = calc.group(name="convert", description="Conversion helpers")
|
||||
|
||||
@convert.subcommand(sub_cmd_name="temperature", sub_cmd_description="Convert between temperatures")
|
||||
@slash_option(name="value", description="Value to convert", required=True, opt_type=OptionTypes.NUMBER)
|
||||
@slash_option(name="value", description="Value to convert", required=True, opt_type=OptionType.NUMBER)
|
||||
@slash_option(
|
||||
name="from_unit", description="From unit", required=True, opt_type=OptionTypes.INTEGER, choices=TEMP_CHOICES
|
||||
name="from_unit", description="From unit", required=True, opt_type=OptionType.INTEGER, choices=TEMP_CHOICES
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="To unit", required=True, opt_type=OptionTypes.INTEGER, choices=TEMP_CHOICES
|
||||
name="to_unit", description="To unit", required=True, opt_type=OptionType.INTEGER, choices=TEMP_CHOICES
|
||||
)
|
||||
async def _calc_convert_temperature(
|
||||
self, ctx: InteractionContext, value: int, from_unit: int, to_unit: int
|
||||
|
@ -139,23 +139,23 @@ class CalcCog(Extension):
|
|||
description=f"°{TEMP_LOOKUP.get(from_unit)} -> °{TEMP_LOOKUP.get(to_unit)}",
|
||||
fields=fields,
|
||||
)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="currency", sub_cmd_description="Convert currency based on current rates")
|
||||
@slash_option(name="value", description="Value of starting currency", required=True, opt_type=OptionTypes.NUMBER)
|
||||
@slash_option(name="value", description="Value of starting currency", required=True, opt_type=OptionType.NUMBER)
|
||||
@slash_option(
|
||||
name="from_currency",
|
||||
description="Currency to convert from",
|
||||
required=True,
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_currency",
|
||||
description="Currency to convert to",
|
||||
required=True,
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
autocomplete=True,
|
||||
)
|
||||
async def _calc_convert_currency(
|
||||
|
@ -174,180 +174,180 @@ class CalcCog(Extension):
|
|||
)
|
||||
|
||||
embed = build_embed(title="Conversion", description=f"{from_currency} -> {to_currency}", fields=fields)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
async def _convert(self, ctx: InteractionContext, from_: str, to: str, value: int) -> Embed:
|
||||
*_, which = ctx.invoked_name.split(" ")
|
||||
*_, which = ctx.invoke_target.split(" ")
|
||||
which = getattr(units, which.capitalize(), None)
|
||||
ratio = which.get_rate(from_, to)
|
||||
converted = value / ratio
|
||||
fields = (EmbedField(name=from_, value=f"{value:0.2f}"), EmbedField(name=to, value=f"{converted:0.2f}"))
|
||||
embed = build_embed(title="Conversion", description=f"{from_} -> {to}", fields=fields)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="angle", sub_cmd_description="Convert angles")
|
||||
@slash_option(name="value", description="Angle to convert", opt_type=OptionTypes.NUMBER, required=True)
|
||||
@slash_option(name="value", description="Angle to convert", opt_type=OptionType.NUMBER, required=True)
|
||||
@slash_option(
|
||||
name="from_unit",
|
||||
description="Units to convert from",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionTypes.STRING, required=True, autocomplete=True
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionType.STRING, required=True, autocomplete=True
|
||||
)
|
||||
async def _calc_convert_angle(self, ctx: InteractionContext, value: int, from_unit: str, to_unit: str) -> None:
|
||||
await self._convert(ctx, from_unit, to_unit, value)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="area", sub_cmd_description="Convert areas")
|
||||
@slash_option(name="value", description="Area to convert", opt_type=OptionTypes.NUMBER, required=True)
|
||||
@slash_option(name="value", description="Area to convert", opt_type=OptionType.NUMBER, required=True)
|
||||
@slash_option(
|
||||
name="from_unit",
|
||||
description="Units to convert from",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionTypes.STRING, required=True, autocomplete=True
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionType.STRING, required=True, autocomplete=True
|
||||
)
|
||||
async def _calc_convert_area(self, ctx: InteractionContext, value: int, from_unit: str, to_unit: str) -> None:
|
||||
await self._convert(ctx, from_unit, to_unit, value)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="data", sub_cmd_description="Convert data sizes")
|
||||
@slash_option(name="value", description="Data size to convert", opt_type=OptionTypes.NUMBER, required=True)
|
||||
@slash_option(name="value", description="Data size to convert", opt_type=OptionType.NUMBER, required=True)
|
||||
@slash_option(
|
||||
name="from_unit",
|
||||
description="Units to convert from",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionTypes.STRING, required=True, autocomplete=True
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionType.STRING, required=True, autocomplete=True
|
||||
)
|
||||
async def _calc_convert_data(self, ctx: InteractionContext, value: int, from_unit: str, to_unit: str) -> None:
|
||||
await self._convert(ctx, from_unit, to_unit, value)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="energy", sub_cmd_description="Convert energy")
|
||||
@slash_option(name="value", description="Energy to convert", opt_type=OptionTypes.NUMBER, required=True)
|
||||
@slash_option(name="value", description="Energy to convert", opt_type=OptionType.NUMBER, required=True)
|
||||
@slash_option(
|
||||
name="from_unit",
|
||||
description="Units to convert from",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionTypes.STRING, required=True, autocomplete=True
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionType.STRING, required=True, autocomplete=True
|
||||
)
|
||||
async def _calc_convert_energy(self, ctx: InteractionContext, value: int, from_unit: str, to_unit: str) -> None:
|
||||
await self._convert(ctx, from_unit, to_unit, value)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="length", sub_cmd_description="Convert lengths")
|
||||
@slash_option(name="value", description="Length to convert", opt_type=OptionTypes.NUMBER, required=True)
|
||||
@slash_option(name="value", description="Length to convert", opt_type=OptionType.NUMBER, required=True)
|
||||
@slash_option(
|
||||
name="from_unit",
|
||||
description="Units to convert from",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionTypes.STRING, required=True, autocomplete=True
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionType.STRING, required=True, autocomplete=True
|
||||
)
|
||||
async def _calc_convert_length(self, ctx: InteractionContext, value: int, from_unit: str, to_unit: str) -> None:
|
||||
await self._convert(ctx, from_unit, to_unit, value)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="power", sub_cmd_description="Convert powers")
|
||||
@slash_option(name="value", description="Power to convert", opt_type=OptionTypes.NUMBER, required=True)
|
||||
@slash_option(name="value", description="Power to convert", opt_type=OptionType.NUMBER, required=True)
|
||||
@slash_option(
|
||||
name="from_unit",
|
||||
description="Units to convert from",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionTypes.STRING, required=True, autocomplete=True
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionType.STRING, required=True, autocomplete=True
|
||||
)
|
||||
async def _calc_convert_power(self, ctx: InteractionContext, value: int, from_unit: str, to_unit: str) -> None:
|
||||
await self._convert(ctx, from_unit, to_unit, value)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="pressure", sub_cmd_description="Convert pressures")
|
||||
@slash_option(name="value", description="Pressure to convert", opt_type=OptionTypes.NUMBER, required=True)
|
||||
@slash_option(name="value", description="Pressure to convert", opt_type=OptionType.NUMBER, required=True)
|
||||
@slash_option(
|
||||
name="from_unit",
|
||||
description="Units to convert from",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionTypes.STRING, required=True, autocomplete=True
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionType.STRING, required=True, autocomplete=True
|
||||
)
|
||||
async def _calc_convert_pressure(self, ctx: InteractionContext, value: int, from_unit: str, to_unit: str) -> None:
|
||||
await self._convert(ctx, from_unit, to_unit, value)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="speed", sub_cmd_description="Convert speeds")
|
||||
@slash_option(name="value", description="Speed to convert", opt_type=OptionTypes.NUMBER, required=True)
|
||||
@slash_option(name="value", description="Speed to convert", opt_type=OptionType.NUMBER, required=True)
|
||||
@slash_option(
|
||||
name="from_unit",
|
||||
description="Units to convert from",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionTypes.STRING, required=True, autocomplete=True
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionType.STRING, required=True, autocomplete=True
|
||||
)
|
||||
async def _calc_convert_speed(self, ctx: InteractionContext, value: int, from_unit: str, to_unit: str) -> None:
|
||||
await self._convert(ctx, from_unit, to_unit, value)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="time", sub_cmd_description="Convert times")
|
||||
@slash_option(name="value", description="Time to convert", opt_type=OptionTypes.NUMBER, required=True)
|
||||
@slash_option(name="value", description="Time to convert", opt_type=OptionType.NUMBER, required=True)
|
||||
@slash_option(
|
||||
name="from_unit",
|
||||
description="Units to convert from",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionTypes.STRING, required=True, autocomplete=True
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionType.STRING, required=True, autocomplete=True
|
||||
)
|
||||
async def _calc_convert_time(self, ctx: InteractionContext, value: int, from_unit: str, to_unit: str) -> None:
|
||||
await self._convert(ctx, from_unit, to_unit, value)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="volume", sub_cmd_description="Convert volumes")
|
||||
@slash_option(name="value", description="Volume to convert", opt_type=OptionTypes.NUMBER, required=True)
|
||||
@slash_option(name="value", description="Volume to convert", opt_type=OptionType.NUMBER, required=True)
|
||||
@slash_option(
|
||||
name="from_unit",
|
||||
description="Units to convert from",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionTypes.STRING, required=True, autocomplete=True
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionType.STRING, required=True, autocomplete=True
|
||||
)
|
||||
async def _calc_convert_volume(self, ctx: InteractionContext, value: int, from_unit: str, to_unit: str) -> None:
|
||||
await self._convert(ctx, from_unit, to_unit, value)
|
||||
|
||||
@convert.subcommand(sub_cmd_name="weight", sub_cmd_description="Convert weights")
|
||||
@slash_option(name="value", description="Weight to convert", opt_type=OptionTypes.NUMBER, required=True)
|
||||
@slash_option(name="value", description="Weight to convert", opt_type=OptionType.NUMBER, required=True)
|
||||
@slash_option(
|
||||
name="from_unit",
|
||||
description="Units to convert from",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionTypes.STRING, required=True, autocomplete=True
|
||||
name="to_unit", description="Units to convert to", opt_type=OptionType.STRING, required=True, autocomplete=True
|
||||
)
|
||||
async def _calc_convert_weight(self, ctx: InteractionContext, value: int, from_unit: str, to_unit: str) -> None:
|
||||
await self._convert(ctx, from_unit, to_unit, value)
|
||||
|
@ -370,12 +370,10 @@ class CalcCog(Extension):
|
|||
@_calc_convert_time.autocomplete("from_unit")
|
||||
@_calc_convert_volume.autocomplete("from_unit")
|
||||
@_calc_convert_weight.autocomplete("from_unit")
|
||||
async def _autocomplete_from_unit(
|
||||
self, ctx: AutocompleteContext, from_unit: str, to_unit: str = None, value: int = 0
|
||||
) -> None:
|
||||
*_, which = ctx.invoked_name.split(" ")
|
||||
async def _autocomplete_from_unit(self, ctx: AutocompleteContext) -> None:
|
||||
*_, which = ctx.invoke_target.split(" ")
|
||||
which = getattr(units, which.capitalize(), None)
|
||||
await ctx.send(choices=self._unit_autocomplete(which, from_unit))
|
||||
await ctx.send(choices=self._unit_autocomplete(which, ctx.input_text))
|
||||
|
||||
@_calc_convert_angle.autocomplete("to_unit")
|
||||
@_calc_convert_area.autocomplete("to_unit")
|
||||
|
@ -388,12 +386,10 @@ class CalcCog(Extension):
|
|||
@_calc_convert_time.autocomplete("to_unit")
|
||||
@_calc_convert_volume.autocomplete("to_unit")
|
||||
@_calc_convert_weight.autocomplete("to_unit")
|
||||
async def _autocomplete_to_unit(
|
||||
self, ctx: AutocompleteContext, from_unit: str, to_unit: str = None, value: int = 0
|
||||
) -> None:
|
||||
*_, which = ctx.invoked_name.split(" ")
|
||||
async def _autocomplete_to_unit(self, ctx: AutocompleteContext) -> None:
|
||||
*_, which = ctx.invoke_target.split(" ")
|
||||
which = getattr(units, which.capitalize(), None)
|
||||
await ctx.send(choices=self._unit_autocomplete(which, to_unit))
|
||||
await ctx.send(choices=self._unit_autocomplete(which, ctx.input_text))
|
||||
|
||||
def _currency_autocomplete(self, currency: str) -> list[dict[str, str]]:
|
||||
results = process.extract(currency, CURRENCIES, limit=25)
|
||||
|
@ -402,16 +398,12 @@ class CalcCog(Extension):
|
|||
return [{"name": r[0], "value": r[0]} for r in results]
|
||||
|
||||
@_calc_convert_currency.autocomplete("from_currency")
|
||||
async def _autocomplete_from_currency(
|
||||
self, ctx: AutocompleteContext, from_currency: str = None, to_currency: str = None, value: int = 0
|
||||
) -> None:
|
||||
await ctx.send(choices=self._currency_autocomplete(from_currency))
|
||||
async def _autocomplete_from_currency(self, ctx: AutocompleteContext) -> None:
|
||||
await ctx.send(choices=self._currency_autocomplete(ctx.input_text))
|
||||
|
||||
@_calc_convert_currency.autocomplete("to_currency")
|
||||
async def _autocomplete_to_currency(
|
||||
self, ctx: AutocompleteContext, from_currency: str = None, to_currency: str = None, value: int = 0
|
||||
) -> None:
|
||||
await ctx.send(choices=self._currency_autocomplete(to_currency))
|
||||
async def _autocomplete_to_currency(self, ctx: AutocompleteContext) -> None:
|
||||
await ctx.send(choices=self._currency_autocomplete(ctx.input_text))
|
||||
|
||||
|
||||
def setup(bot: Client) -> None:
|
||||
|
|
|
@ -15,11 +15,11 @@ from bson import ObjectId
|
|||
from interactions import Client, Extension, InteractionContext
|
||||
from interactions.models.discord.components import Button
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.enums import ButtonStyles
|
||||
from interactions.models.discord.enums import ButtonStyle
|
||||
from interactions.models.discord.file import File
|
||||
from interactions.models.discord.message import Attachment
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
SlashCommandChoice,
|
||||
slash_option,
|
||||
|
@ -64,17 +64,17 @@ class DevCog(Extension):
|
|||
@slash_option(
|
||||
name="method",
|
||||
description="Hash method",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
choices=[SlashCommandChoice(name=x, value=x) for x in supported_hashes],
|
||||
)
|
||||
@slash_option(
|
||||
name="data",
|
||||
description="Data to hash",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=False,
|
||||
)
|
||||
@slash_option(name="attach", description="File to hash", opt_type=OptionTypes.ATTACHMENT, required=False)
|
||||
@slash_option(name="attach", description="File to hash", opt_type=OptionType.ATTACHMENT, required=False)
|
||||
@cooldown(bucket=Buckets.USER, rate=1, interval=2)
|
||||
async def _hash(self, ctx: InteractionContext, method: str, data: str = None, attach: Attachment = None) -> None:
|
||||
if not data and not attach:
|
||||
|
@ -117,21 +117,21 @@ class DevCog(Extension):
|
|||
]
|
||||
|
||||
embed = build_embed(title=title, description=description, fields=fields)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@dev.subcommand(sub_cmd_name="uuid", sub_cmd_description="Generate a UUID")
|
||||
@slash_option(
|
||||
name="version",
|
||||
description="UUID version",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
choices=[SlashCommandChoice(name=x, value=x) for x in ["3", "4", "5"]],
|
||||
)
|
||||
@slash_option(
|
||||
name="data",
|
||||
description="Data for UUID version 3,5",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=False,
|
||||
)
|
||||
async def _uuid(self, ctx: InteractionContext, version: str, data: str = None) -> None:
|
||||
|
@ -173,7 +173,7 @@ class DevCog(Extension):
|
|||
sub_cmd_name="uuid2ulid",
|
||||
sub_cmd_description="Convert a UUID to a ULID",
|
||||
)
|
||||
@slash_option(name="uuid", description="UUID to convert", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="uuid", description="UUID to convert", opt_type=OptionType.STRING, required=True)
|
||||
@cooldown(bucket=Buckets.USER, rate=1, interval=2)
|
||||
async def _uuid2ulid(self, ctx: InteractionContext, uuid: str) -> None:
|
||||
if UUID_VERIFY.match(uuid):
|
||||
|
@ -186,7 +186,7 @@ class DevCog(Extension):
|
|||
sub_cmd_name="ulid2uuid",
|
||||
sub_cmd_description="Convert a ULID to a UUID",
|
||||
)
|
||||
@slash_option(name="ulid", description="ULID to convert", opt_type=OptionTypes.STRING, required=True)
|
||||
@slash_option(name="ulid", description="ULID to convert", opt_type=OptionType.STRING, required=True)
|
||||
@cooldown(bucket=Buckets.USER, rate=1, interval=2)
|
||||
async def _ulid2uuid(self, ctx: InteractionContext, ulid: str) -> None:
|
||||
if ULID_VERIFY.match(ulid):
|
||||
|
@ -201,14 +201,14 @@ class DevCog(Extension):
|
|||
@slash_option(
|
||||
name="method",
|
||||
description="Encode method",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
choices=[SlashCommandChoice(name=x, value=x) for x in base64_methods],
|
||||
)
|
||||
@slash_option(
|
||||
name="data",
|
||||
description="Data to encode",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
async def _encode(self, ctx: InteractionContext, method: str, data: str) -> None:
|
||||
|
@ -230,21 +230,21 @@ class DevCog(Extension):
|
|||
EmbedField(name=mstr, value=f"`{encoded}`", inline=False),
|
||||
]
|
||||
embed = build_embed(title="Encoded Data", description="", fields=fields)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@dev.subcommand(sub_cmd_name="decode", sub_cmd_description="Decode some data")
|
||||
@slash_option(
|
||||
name="method",
|
||||
description="Decode method",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
choices=[SlashCommandChoice(name=x, value=x) for x in base64_methods],
|
||||
)
|
||||
@slash_option(
|
||||
name="data",
|
||||
description="Data to decode",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
async def _decode(self, ctx: InteractionContext, method: str, data: str) -> None:
|
||||
|
@ -266,7 +266,7 @@ class DevCog(Extension):
|
|||
EmbedField(name=mstr, value=f"`{decoded}`", inline=False),
|
||||
]
|
||||
embed = build_embed(title="Decoded Data", description="", fields=fields)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@dev.subcommand(sub_cmd_name="cloc", sub_cmd_description="Get JARVIS lines of code")
|
||||
|
|
|
@ -9,11 +9,11 @@ import numpy as np
|
|||
from interactions import Client, Extension, InteractionContext
|
||||
from interactions.models.discord.components import Button
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.enums import ButtonStyles
|
||||
from interactions.models.discord.enums import ButtonStyle
|
||||
from interactions.models.discord.file import File
|
||||
from interactions.models.discord.message import Attachment
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -46,19 +46,19 @@ class ImageCog(Extension):
|
|||
@slash_option(
|
||||
name="target",
|
||||
description="Target size, i.e. 200KB",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="attachment",
|
||||
description="Image to resize",
|
||||
opt_type=OptionTypes.ATTACHMENT,
|
||||
opt_type=OptionType.ATTACHMENT,
|
||||
required=False,
|
||||
)
|
||||
@slash_option(
|
||||
name="url",
|
||||
description="URL to download and resize",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=False,
|
||||
)
|
||||
async def _resize(
|
||||
|
@ -149,7 +149,7 @@ class ImageCog(Extension):
|
|||
]
|
||||
embed = build_embed(title=filename, description="", fields=fields)
|
||||
embed.set_image(url="attachment://resized.png")
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, file=File(file=bufio, file_name="resized.png"), components=components)
|
||||
|
||||
|
||||
|
|
|
@ -11,11 +11,11 @@ from interactions.models.discord.components import (
|
|||
StringSelectMenu,
|
||||
StringSelectOption,
|
||||
)
|
||||
from interactions.models.discord.enums import ButtonStyles
|
||||
from interactions.models.discord.enums import ButtonStyle
|
||||
from interactions.models.discord.message import Message
|
||||
from interactions.models.internal.application_commands import (
|
||||
CommandTypes,
|
||||
OptionTypes,
|
||||
CommandType,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
context_menu,
|
||||
slash_option,
|
||||
|
@ -75,7 +75,7 @@ class PinboardCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Pinboard channel",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.CHANNEL,
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
@ -111,7 +111,7 @@ class PinboardCog(Extension):
|
|||
@slash_option(
|
||||
name="channel",
|
||||
description="Pinboard channel",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
opt_type=OptionType.CHANNEL,
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
|
@ -233,7 +233,7 @@ class PinboardCog(Extension):
|
|||
embed.set_footer(text=ctx.guild.name + " | " + channel.name)
|
||||
if image_url:
|
||||
embed.set_image(url=image_url)
|
||||
star_components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
star_components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
star = await starboard.send(embeds=embed, components=star_components)
|
||||
|
||||
await Star(
|
||||
|
@ -254,7 +254,7 @@ class PinboardCog(Extension):
|
|||
components=components,
|
||||
)
|
||||
|
||||
@context_menu(name="Pin Message", context_type=CommandTypes.MESSAGE)
|
||||
@context_menu(name="Pin Message", context_type=CommandType.MESSAGE)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _star_message(self, ctx: InteractionContext) -> None:
|
||||
await self._star_add(ctx, message=str(ctx.target_id))
|
||||
|
|
|
@ -19,10 +19,10 @@ from interactions.models.discord.components import (
|
|||
StringSelectOption,
|
||||
)
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.enums import ButtonStyles
|
||||
from interactions.models.discord.enums import ButtonStyle
|
||||
from interactions.models.discord.role import Role
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -53,13 +53,18 @@ class RolegiverCog(Extension):
|
|||
if not guild:
|
||||
await rolegiver.delete()
|
||||
continue
|
||||
role = await guild.fetch_role(rolegiver.role)
|
||||
if not role:
|
||||
await rolegiver.delete()
|
||||
continue
|
||||
if guild.id not in self.cache:
|
||||
self.cache[guild.id] = {}
|
||||
self.cache[guild.id][role.name] = role.id
|
||||
roles = []
|
||||
for role in rolegiver.roles:
|
||||
role = await guild.fetch_role(role)
|
||||
if role:
|
||||
roles.append(role.id)
|
||||
else:
|
||||
continue
|
||||
if guild.id not in self.cache:
|
||||
self.cache[guild.id] = {}
|
||||
self.cache[guild.id][role.name] = role.id
|
||||
rolegiver.roles = roles
|
||||
await rolegiver.commit()
|
||||
|
||||
rolegiver = SlashCommand(name="rolegiver", description="Allow users to choose their own roles")
|
||||
|
||||
|
@ -67,7 +72,7 @@ class RolegiverCog(Extension):
|
|||
sub_cmd_name="add",
|
||||
sub_cmd_description="Add a role to rolegiver",
|
||||
)
|
||||
@slash_option(name="role", description="Role to add", opt_type=OptionTypes.ROLE, required=True)
|
||||
@slash_option(name="role", description="Role to add", opt_type=OptionType.ROLE, required=True)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _rolegiver_add(self, ctx: InteractionContext, role: Role) -> None:
|
||||
if role.id == ctx.guild.id:
|
||||
|
@ -120,7 +125,7 @@ class RolegiverCog(Extension):
|
|||
embed.set_thumbnail(url=ctx.guild.icon.url)
|
||||
|
||||
embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
if ctx.guild.id not in self.cache:
|
||||
|
@ -131,7 +136,7 @@ class RolegiverCog(Extension):
|
|||
@slash_option(
|
||||
name="role",
|
||||
description="Name of role to add",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
|
@ -212,7 +217,7 @@ class RolegiverCog(Extension):
|
|||
embed.set_thumbnail(url=ctx.guild.icon.url)
|
||||
|
||||
embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@rolegiver.subcommand(sub_cmd_name="get", sub_cmd_description="Get a role")
|
||||
|
|
|
@ -7,10 +7,10 @@ from typing import Dict, List
|
|||
from interactions import AutocompleteContext, Client, Extension, InteractionContext
|
||||
from interactions.models.discord.components import Button
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.enums import ButtonStyles, Permissions
|
||||
from interactions.models.discord.enums import ButtonStyle, Permissions
|
||||
from interactions.models.discord.modal import InputText, Modal, TextStyles
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -39,7 +39,7 @@ class TagCog(Extension):
|
|||
name="name",
|
||||
description="Tag to get",
|
||||
autocomplete=True,
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
async def _get(self, ctx: InteractionContext, name: str) -> None:
|
||||
|
@ -125,7 +125,7 @@ class TagCog(Extension):
|
|||
icon_url=ctx.author.display_avatar.url,
|
||||
)
|
||||
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
|
||||
await response.send(embeds=embed, components=components)
|
||||
if ctx.guild.id not in self.cache:
|
||||
|
@ -136,7 +136,7 @@ class TagCog(Extension):
|
|||
@slash_option(
|
||||
name="name",
|
||||
description="Tag name",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
autocomplete=True,
|
||||
required=True,
|
||||
)
|
||||
|
@ -225,7 +225,7 @@ class TagCog(Extension):
|
|||
name=ctx.author.username + "#" + ctx.author.discriminator,
|
||||
icon_url=ctx.author.display_avatar.url,
|
||||
)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await response.send(embeds=embed, components=components)
|
||||
if tag.name not in self.cache[ctx.guild.id]:
|
||||
self.cache[ctx.guild.id].remove(old_name)
|
||||
|
@ -235,7 +235,7 @@ class TagCog(Extension):
|
|||
@slash_option(
|
||||
name="name",
|
||||
description="Tag name",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
|
@ -259,7 +259,7 @@ class TagCog(Extension):
|
|||
@slash_option(
|
||||
name="name",
|
||||
description="Tag name",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
autocomplete=True,
|
||||
)
|
||||
|
@ -302,7 +302,7 @@ class TagCog(Extension):
|
|||
name=f"{username}#{discrim}" if username else "Unknown User",
|
||||
icon_url=url,
|
||||
)
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@tag.subcommand(sub_cmd_name="list", sub_cmd_description="List tag names")
|
||||
|
@ -310,7 +310,7 @@ class TagCog(Extension):
|
|||
tags = await Tag.find(q(guild=ctx.guild.id)).to_list(None)
|
||||
names = "\n".join(f"`{t.name}`" for t in tags)
|
||||
embed = build_embed(title="All Tags", description=names, fields=[])
|
||||
components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
components = Button(style=ButtonStyle.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
|
||||
await ctx.send(embeds=embed, components=components)
|
||||
|
||||
@_get.autocomplete("name")
|
||||
|
|
|
@ -5,11 +5,11 @@ import re
|
|||
import aiohttp
|
||||
from interactions import Client, Extension, InteractionContext
|
||||
from interactions.ext.paginators import Paginator
|
||||
from interactions.models.discord.components import ActionRow, Button, ButtonStyles
|
||||
from interactions.models.discord.components import ActionRow, Button, ButtonStyle
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.user import Member, User
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -46,14 +46,14 @@ 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"))]
|
||||
components = [ActionRow(Button(style=ButtonStyle.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=OptionType.STRING, required=True)
|
||||
@cooldown(bucket=Buckets.USER, rate=1, interval=2)
|
||||
async def _pw(self, ctx: InteractionContext, guess: str) -> None:
|
||||
if len(guess) > 800:
|
||||
|
|
|
@ -9,7 +9,7 @@ from interactions import Client, Extension, InteractionContext
|
|||
from interactions.client.utils import find
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
slash_option,
|
||||
)
|
||||
|
@ -204,7 +204,7 @@ class DbrandCog(Extension):
|
|||
@slash_option(
|
||||
name="search",
|
||||
description="Country search query (2 character code, country name, flag emoji)",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=True,
|
||||
)
|
||||
@cooldown(bucket=Buckets.USER, rate=1, interval=2)
|
||||
|
|
|
@ -10,7 +10,7 @@ from interactions.models.discord.embed import Embed, EmbedField
|
|||
from interactions.models.discord.modal import InputText, Modal, TextStyles
|
||||
from interactions.models.discord.user import Member
|
||||
from interactions.models.internal.application_commands import (
|
||||
OptionTypes,
|
||||
OptionType,
|
||||
SlashCommand,
|
||||
SlashCommandChoice,
|
||||
slash_command,
|
||||
|
@ -40,7 +40,7 @@ class GitlabCog(Extension):
|
|||
sub_cmd_name="issue",
|
||||
sub_cmd_description="Get an issue from GitLab",
|
||||
)
|
||||
@slash_option(name="id", description="Issue ID", opt_type=OptionTypes.INTEGER, required=True)
|
||||
@slash_option(name="id", description="Issue ID", opt_type=OptionType.INTEGER, required=True)
|
||||
async def _issue(self, ctx: InteractionContext, id: int) -> None:
|
||||
try:
|
||||
issue = self.project.issues.get(int(id))
|
||||
|
@ -102,7 +102,7 @@ class GitlabCog(Extension):
|
|||
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=OptionType.INTEGER, required=True)
|
||||
async def _milestone(self, ctx: InteractionContext, id: int) -> None:
|
||||
try:
|
||||
milestone = self.project.milestones.get(int(id))
|
||||
|
@ -150,7 +150,7 @@ class GitlabCog(Extension):
|
|||
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=OptionType.INTEGER, required=True)
|
||||
async def _mergerequest(self, ctx: InteractionContext, id: int) -> None:
|
||||
try:
|
||||
mr = self.project.mergerequests.get(int(id))
|
||||
|
@ -251,7 +251,7 @@ class GitlabCog(Extension):
|
|||
@slash_option(
|
||||
name="state",
|
||||
description="State of issues to get",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=False,
|
||||
choices=[
|
||||
SlashCommandChoice(name="Open", value="opened"),
|
||||
|
@ -305,7 +305,7 @@ class GitlabCog(Extension):
|
|||
@slash_option(
|
||||
name="state",
|
||||
description="State of merge requests to get",
|
||||
opt_type=OptionTypes.STRING,
|
||||
opt_type=OptionType.STRING,
|
||||
required=False,
|
||||
choices=[
|
||||
SlashCommandChoice(name="Open", value="opened"),
|
||||
|
@ -391,7 +391,7 @@ class GitlabCog(Extension):
|
|||
@slash_option(
|
||||
name="user",
|
||||
description="Credit someone else for this issue",
|
||||
opt_type=OptionTypes.USER,
|
||||
opt_type=OptionType.USER,
|
||||
required=False,
|
||||
)
|
||||
async def _open_issue(self, ctx: InteractionContext, user: Member = None) -> None:
|
||||
|
|
|
@ -1,14 +1,5 @@
|
|||
"""JARVIS Prometheus extra tracking."""
|
||||
from prometheus_client import Counter, Info
|
||||
from statipy.db import GuildMetadata
|
||||
|
||||
malicious_tracker = Counter(
|
||||
"jarvis_malicious_blocked",
|
||||
"Amount of malicious messages blocked",
|
||||
labelnames=["guild_id", "guild_name"],
|
||||
)
|
||||
|
||||
warnings_tracker = Counter(
|
||||
"jarvis_warnings", "Amount of warnings given out", labelnames=["guild_id", "guild_name"]
|
||||
)
|
||||
|
||||
jarvis_info = Info("jarvis", "Jarvis version")
|
||||
class WarningMetadata(GuildMetadata):
|
||||
type: str
|
||||
|
|
|
@ -3,13 +3,14 @@ import logging
|
|||
from datetime import timedelta
|
||||
|
||||
from interactions import Client, Extension, InteractionContext
|
||||
from interactions.models.discord.components import ActionRow, Button, ButtonStyles
|
||||
from interactions.models.discord.components import ActionRow, Button, ButtonStyle
|
||||
from interactions.models.discord.embed import EmbedField
|
||||
from interactions.models.discord.user import Member
|
||||
from jarvis_core.db import q
|
||||
from jarvis_core.db.models import Action, Ban, Kick, Modlog, Mute, Setting, Warning
|
||||
from statipy.db import Stat
|
||||
|
||||
from jarvis.tracking import warnings_tracker
|
||||
from jarvis.tracking import WarningMetadata
|
||||
from jarvis.utils import build_embed
|
||||
|
||||
MODLOG_LOOKUP = {"Ban": Ban, "Kick": Kick, "Mute": Mute, "Warning": Warning}
|
||||
|
@ -41,8 +42,16 @@ class ModcaseCog(Extension):
|
|||
|
||||
if name in MODLOG_LOOKUP and ctx.invoke_target not in IGNORE_COMMANDS[name]:
|
||||
if name == "Warning":
|
||||
tracker = warnings_tracker.labels(guild_id=ctx.guild.id, guild_name=ctx.guild.name)
|
||||
tracker.inc()
|
||||
md = WarningMetadata(
|
||||
client_id=self.user.id,
|
||||
client_name=self.client_name,
|
||||
name="warning",
|
||||
type="manual",
|
||||
guild_id=message.guild.id,
|
||||
guild_name=message.guild.name,
|
||||
value=1,
|
||||
)
|
||||
await Stat(meta=md).insert()
|
||||
user = kwargs.pop("user", None)
|
||||
if not user and not ctx.target_id:
|
||||
self.logger.warning("Admin action %s missing user, exiting", name)
|
||||
|
@ -141,8 +150,8 @@ class ModcaseCog(Extension):
|
|||
embed.set_author(name=user.username + "#" + user.discriminator, icon_url=avatar_url)
|
||||
components = [
|
||||
ActionRow(
|
||||
Button(style=ButtonStyles.RED, emoji="✖️", custom_id="modcase|no"),
|
||||
Button(style=ButtonStyles.GREEN, emoji="✔️", custom_id="modcase|yes"),
|
||||
Button(style=ButtonStyle.RED, emoji="✖️", custom_id="modcase|no"),
|
||||
Button(style=ButtonStyle.GREEN, emoji="✔️", custom_id="modcase|yes"),
|
||||
)
|
||||
]
|
||||
message = await channel.send(embeds=embed, components=components)
|
||||
|
|
1249
poetry.lock
generated
1249
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -27,9 +27,10 @@ nest-asyncio = "^1.5.5"
|
|||
thefuzz = {extras = ["speedup"], git = "https://github.com/zevaryx/thefuzz.git", rev = "master"} # Forked
|
||||
beautifulsoup4 = "^4.11.1"
|
||||
calculator = {git = "https://git.zevaryx.com/zevaryx/calculator.git"} # Mine
|
||||
nafftrack = {git = "https://github.com/zevaryx/nafftrack.git"} # Contributed
|
||||
redis = "^4.4.0"
|
||||
interactions = {git = "https://github.com/interactions-py/interactions.py", rev = "5.x"}
|
||||
statipy = {git = "https://github.com/zevaryx/statipy", rev = "main"}
|
||||
beanie = "^1.17.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
black = {version = "^22.3.0", allow-prereleases = true}
|
||||
|
|
Loading…
Add table
Reference in a new issue