diff --git a/jarvis/__init__.py b/jarvis/__init__.py index d382b1d..3768bb0 100644 --- a/jarvis/__init__.py +++ b/jarvis/__init__.py @@ -9,12 +9,13 @@ from discord.ext import commands from discord.ext.tasks import loop from discord.utils import find, get from discord_slash import SlashCommand +from psutil import Process + from jarvis import logo, utils from jarvis.config import get_config from jarvis.utils import build_embed from jarvis.utils.db import DBManager from jarvis.utils.field import Field -from psutil import Process if asyncio.get_event_loop().is_closed(): asyncio.set_event_loop(asyncio.new_event_loop()) @@ -28,10 +29,15 @@ invites = re.compile( ) -jarvis = commands.Bot(command_prefix=utils.get_prefix, intents=intents) +jarvis = commands.Bot( + command_prefix=utils.get_prefix, intents=intents, help_command=None +) slash = SlashCommand(jarvis, sync_commands=True, sync_on_cog_reload=True) jarvis_self = Process() -__version__ = "0.9.9" +__version__ = "1.0.0" + + +db = DBManager(get_config().mongo).mongo @jarvis.event @@ -84,8 +90,10 @@ async def on_member_join(user: Member): @jarvis.event async def on_message(message: Message): - if not isinstance(message.channel, DMChannel): - db = DBManager(get_config().mongo).mongo + if ( + not isinstance(message.channel, DMChannel) + and not message.author.id == jarvis.client.id + ): autoreact = db.jarvis.autoreact.find_one( {"guild": message.guild.id, "channel": message.channel.id} ) @@ -97,9 +105,10 @@ async def on_message(message: Message): ) if ( massmention["value"] > 0 - and len(message.mentions) > massmention["value"] + and len(message.mentions) + - (1 if message.author in message.mentions else 0) + > massmention["value"] ): - await message.delete() db.jarvis.warns.insert_one( { "user": message.author.id, @@ -137,7 +146,13 @@ async def on_message(message: Message): for mention in message.mentions: for role in mention.roles: roles.append(role.id) - if roleping and any(x.id in roleping["value"] for x in roles): + if ( + roleping + and any(x in roleping["value"] for x in roles) + and not any( + x.id in roleping["value"] for x in message.author.roles + ) + ): db.jarvis.warns.insert_one( { "user": message.author.id, diff --git a/jarvis/cogs/admin.py b/jarvis/cogs/admin.py index 3d42863..d2f9b9b 100644 --- a/jarvis/cogs/admin.py +++ b/jarvis/cogs/admin.py @@ -31,7 +31,6 @@ class AdminCog(commands.Cog): @cog_ext.cog_slash( name="ban", description="Ban a user", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="user", @@ -71,7 +70,7 @@ class AdminCog(commands.Cog): user: User = None, reason: str = None, type: str = "perm", - length: int = 4, + duration: int = 4, ): if not user or user == ctx.author: await ctx.send("You cannot ban yourself.", hidden=True) @@ -79,11 +78,14 @@ class AdminCog(commands.Cog): if user == self.bot.user: await ctx.send("I'm afraid I can't let you do that", hidden=True) return - if type == "temp" and length < 0: + if type == "temp" and duration < 0: await ctx.send( "You cannot set a temp ban to < 0 hours.", hidden=True ) return + if len(reason) > 100: + await ctx.send("Reason must be < 100 characters", hidden=True) + return if not reason: reason = ( "Mr. Stark is displeased with your presence. Please leave." @@ -101,11 +103,15 @@ class AdminCog(commands.Cog): time = datetime.now() expiry = None if mtype == "temp": - user_message += f"\nDuration: {length} hours" - expiry = time + timedelta(hours=length) + user_message += f"\nDuration: {duration} hours" + expiry = time + timedelta(hours=duration) + try: + await ctx.guild.ban(user, reason=reason) + except Exception as e: + await ctx.send(f"Failed to ban user:\n```\n{e}\n```", hidden=True) + return await user.send(user_message) - await ctx.guild.ban(user, reason=reason) if mtype == "soft": await ctx.guild.unban(user, reason="Ban was softban") await ctx.send( @@ -113,7 +119,7 @@ class AdminCog(commands.Cog): + f" Reason:\n{reason}" ) if type != "temp": - length = None + duration = None active = True if type == "soft": active = False @@ -128,7 +134,7 @@ class AdminCog(commands.Cog): "time": datetime.now(), "guild": ctx.guild.id, "type": type, - "length": length, + "duration": duration, "expiry": expiry, "active": active, } @@ -158,7 +164,6 @@ class AdminCog(commands.Cog): @cog_ext.cog_slash( name="unban", description="Unban a user", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="user", @@ -181,7 +186,9 @@ class AdminCog(commands.Cog): user: str, reason: str, ): - await ctx.defer() + if len(reason) > 100: + await ctx.send("Reason must be < 100 characters", hidden=True) + return orig_user = user discrim = None @@ -246,7 +253,7 @@ class AdminCog(commands.Cog): database_ban_info = self.db.jarvis.bans.find_one(search) if not discord_ban_info and not database_ban_info: - await ctx.send(f"Unable to find user {orig_user}") + await ctx.send(f"Unable to find user {orig_user}", hidden=True) elif discord_ban_info: await self.discord_apply_unban(ctx, discord_ban_info.user, reason) @@ -283,7 +290,6 @@ class AdminCog(commands.Cog): base="bans", name="list", description="List bans", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="type", @@ -314,7 +320,6 @@ class AdminCog(commands.Cog): self, ctx: SlashContext, type: int = 0, active: int = 1 ): active = bool(active) - await ctx.defer() types = [0, "perm", "temp", "soft"] search = {"guild": ctx.guild.id} if active: @@ -358,7 +363,6 @@ class AdminCog(commands.Cog): @cog_ext.cog_slash( name="kick", description="Kick a user", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="user", @@ -382,6 +386,9 @@ class AdminCog(commands.Cog): if user == self.bot.user: await ctx.send("I'm afraid I can't let you do that", hidden=True) return + if len(reason) > 100: + await ctx.send("Reason must be < 100 characters", hidden=True) + return if not reason: reason = ( "Mr. Stark is displeased with your presence. Please leave." @@ -411,7 +418,6 @@ class AdminCog(commands.Cog): @cog_ext.cog_slash( name="purge", description="Purge messages from channel", - guild_ids=[578757004059738142, 862402786116763668], options=[ create_option( name="amount", @@ -445,7 +451,6 @@ class AdminCog(commands.Cog): @cog_ext.cog_slash( name="mute", description="Mute a user", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="user", @@ -460,8 +465,8 @@ class AdminCog(commands.Cog): required=True, ), create_option( - name="length", - description="Mute length", + name="duration", + description="Mute duration", option_type=4, required=False, ), @@ -469,15 +474,17 @@ class AdminCog(commands.Cog): ) @admin_or_permissions(mute_members=True) async def _mute( - self, ctx: SlashContext, user: Member, reason: str, length: int = 30 + self, ctx: SlashContext, user: Member, reason: str, duration: int = 30 ): - await ctx.defer() if user == ctx.author: await ctx.send("You cannot mute yourself.", hidden=True) return if user == self.bot.user: await ctx.send("I'm afraid I can't let you do that", hidden=True) return + if len(reason) > 100: + await ctx.send("Reason must be < 100 characters", hidden=True) + return mute_setting = self.db.jarvis.settings.find_one( {"guild": ctx.guild.id, "setting": "mute"} ) @@ -488,13 +495,15 @@ class AdminCog(commands.Cog): ) return role = get(ctx.guild.roles, id=mute_setting["value"]) + if role in user.roles: + await ctx.send("User already muted", hidden=True) await user.add_roles(role, reason=reason) time = datetime.now() expiry = None - if length < 0: - length = -1 - if length >= 0: - expiry = time + timedelta(minutes=length) + if duration < 0: + duration = -1 + if duration >= 0: + expiry = time + timedelta(minutes=duration) self.db.jarvis.mutes.insert_one( { "user": user.id, @@ -502,9 +511,9 @@ class AdminCog(commands.Cog): "admin": ctx.author.id, "time": time, "guild": ctx.guild.id, - "length": length, + "duration": duration, "expiry": expiry, - "active": True if length >= 0 else False, + "active": True if duration >= 0 else False, } ) self.db.jarvis.mutes.update_many( @@ -520,7 +529,6 @@ class AdminCog(commands.Cog): @cog_ext.cog_slash( name="unmute", description="Unmute a user", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="user", @@ -532,7 +540,6 @@ class AdminCog(commands.Cog): ) @admin_or_permissions(mute_members=True) async def _unmute(self, ctx: SlashContext, user: Member): - await ctx.defer() mute_setting = self.db.jarvis.settings.find_one( {"guild": ctx.guild.id, "setting": "mute"} ) @@ -591,7 +598,6 @@ class AdminCog(commands.Cog): @cog_ext.cog_slash( name="lock", description="Locks a channel", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="reason", @@ -621,7 +627,10 @@ class AdminCog(commands.Cog): duration: int = 10, channel: Union[TextChannel, VoiceChannel] = None, ): - await ctx.defer() + await ctx.defer(hidden=True) + if len(reason) > 100: + await ctx.send("Reason must be < 100 characters", hidden=True) + return if not channel: channel = ctx.channel for role in ctx.guild.roles: @@ -645,7 +654,6 @@ class AdminCog(commands.Cog): @cog_ext.cog_slash( name="unlock", description="Unlocks a channel", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="channel", @@ -661,7 +669,6 @@ class AdminCog(commands.Cog): ctx: SlashContext, channel: Union[TextChannel, VoiceChannel] = None, ): - await ctx.defer() if not channel: channel = ctx.channel lock = self.db.jarvis.locks.find_one( @@ -688,7 +695,6 @@ class AdminCog(commands.Cog): base="lockdown", name="start", description="Locks a server", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="reason", @@ -742,14 +748,12 @@ class AdminCog(commands.Cog): base="lockdown", name="end", description="Unlocks a server", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], ) @commands.has_permissions(administrator=True) async def _lockdown_end( self, ctx: SlashContext, ): - await ctx.defer() channels = ctx.guild.channels roles = ctx.guild.roles updates = [] @@ -759,6 +763,7 @@ class AdminCog(commands.Cog): if not locks: await ctx.send("No lockdown detected.", hidden=True) return + await ctx.defer() for channel in channels: for role in roles: try: @@ -782,7 +787,6 @@ class AdminCog(commands.Cog): @cog_ext.cog_slash( name="warn", description="Warn a user", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="user", @@ -808,6 +812,9 @@ class AdminCog(commands.Cog): async def _warn( self, ctx: SlashContext, user: User, reason: str, duration: int = 24 ): + if len(reason) > 100: + await ctx.send("Reason must be < 100 characters", hidden=True) + return await ctx.defer() self.db.jarvis.warns.insert_one( { @@ -844,7 +851,6 @@ class AdminCog(commands.Cog): @cog_ext.cog_slash( name="warnings", description="Get count of user warnings", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="user", @@ -865,9 +871,20 @@ class AdminCog(commands.Cog): } ) ) - active = len(list(filter(lambda x: x["active"], warnings))) + active = ( + [ + y["reason"] + for y in list(filter(lambda x: x["active"], warnings)) + ] + if warnings + else ["None"] + ) + total = len(warnings) - fields = [Field("Active", active), Field("Total", total)] + fields = [ + Field(f"{len(active)} Active", "\n".join(active)), + Field("Total", total), + ] embed = build_embed( title="Warnings", description=f"{user.mention} active and total warnings", @@ -885,7 +902,6 @@ class AdminCog(commands.Cog): base="roleping", name="block", description="Add a role to the roleping blocklist", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="role", @@ -920,7 +936,6 @@ class AdminCog(commands.Cog): base="roleping", name="allow", description="Remove a role from the roleping blocklist", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="role", @@ -956,7 +971,6 @@ class AdminCog(commands.Cog): base="roleping", name="list", description="List all blocklisted roles", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], ) async def _roleping_list(self, ctx: SlashContext): roles = self.db.jarvis.settings.find_one( @@ -982,7 +996,6 @@ class AdminCog(commands.Cog): base="autopurge", name="add", description="Automatically purge messages after x seconds", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="channel", @@ -1002,6 +1015,9 @@ class AdminCog(commands.Cog): async def _autopurge_add( self, ctx: SlashContext, channel: TextChannel, delay: int = 30 ): + if not isinstance(channel, TextChannel): + await ctx.send("Channel must be a TextChannel", hidden=True) + return autopurge = self.db.jarvis.autopurge.find( {"guild": ctx.guild.id, "channel": channel.id} ) @@ -1025,7 +1041,6 @@ class AdminCog(commands.Cog): base="autopurge", name="remove", description="Remove an autopurge", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="channel", @@ -1050,7 +1065,6 @@ class AdminCog(commands.Cog): base="autopurge", name="update", description="Update autopurge on a channel", - guild_ids=[418094694325813248, 578757004059738142, 862402786116763668], options=[ create_option( name="channel", @@ -1070,7 +1084,7 @@ class AdminCog(commands.Cog): async def _autopurge_update( self, ctx: SlashContext, channel: TextChannel, delay: int ): - autopurge = self.db.jarvis.autopurge.find( + autopurge = self.db.jarvis.autopurge.find_one( {"guild": ctx.guild.id, "channel": channel.id} ) if not autopurge: diff --git a/jarvis/cogs/autoreact.py b/jarvis/cogs/autoreact.py index a2d49db..4708cdd 100644 --- a/jarvis/cogs/autoreact.py +++ b/jarvis/cogs/autoreact.py @@ -24,7 +24,6 @@ class AutoReactCog(commands.Cog): base="autoreact", name="create", description="Add an autoreact to a channel", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="channel", @@ -62,7 +61,6 @@ class AutoReactCog(commands.Cog): base="autoreact", name="delete", description="Delete an autoreact from a channel", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="channel", @@ -87,7 +85,6 @@ class AutoReactCog(commands.Cog): base="autoreact", name="add", description="Add an autoreact emote to an existing autoreact", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="channel", @@ -154,7 +151,6 @@ class AutoReactCog(commands.Cog): base="autoreact", name="remove", description="Remove an autoreact emote from an existing autoreact", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="channel", @@ -199,7 +195,6 @@ class AutoReactCog(commands.Cog): base="autoreact", name="list", description="List all autoreacts on a channel", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="channel", diff --git a/jarvis/cogs/ctc2.py b/jarvis/cogs/ctc2.py index 5c5729f..2a07c0a 100644 --- a/jarvis/cogs/ctc2.py +++ b/jarvis/cogs/ctc2.py @@ -6,6 +6,8 @@ import jarvis from jarvis.config import get_config from jarvis.utils.db import DBManager +guild_ids = [578757004059738142, 520021794380447745, 862402786116763668] + class CTCCog(commands.Cog): def __init__(self, bot): @@ -19,7 +21,7 @@ class CTCCog(commands.Cog): base="ctc2", name="about", description="CTC2 related commands", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, ) async def _about(self, ctx): await ctx.send("See https://completethecode.com for more information") @@ -28,7 +30,7 @@ class CTCCog(commands.Cog): base="ctc2", name="pw", description="Guess a password for https://completethecodetwo.cards", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, ) async def _pw(self, ctx, guess: str): guessed = self.db.ctc2.guesses.find_one({"guess": guess}) diff --git a/jarvis/cogs/dbrand.py b/jarvis/cogs/dbrand.py index c001deb..2d9823f 100644 --- a/jarvis/cogs/dbrand.py +++ b/jarvis/cogs/dbrand.py @@ -1,15 +1,18 @@ import re import aiohttp -import jarvis from discord.ext import commands from discord_slash import cog_ext from discord_slash.utils.manage_commands import create_option + +import jarvis from jarvis.config import get_config from jarvis.data.dbrand import shipping_lookup from jarvis.utils import build_embed from jarvis.utils.field import Field +guild_ids = [578757004059738142, 520021794380447745, 862402786116763668] + class DbrandCog(commands.Cog): """ @@ -29,7 +32,7 @@ class DbrandCog(commands.Cog): @cog_ext.cog_subcommand( base="db", name="skin", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, description="See what skins are available", ) async def _skin(self, ctx): @@ -38,7 +41,7 @@ class DbrandCog(commands.Cog): @cog_ext.cog_subcommand( base="db", name="robotcamo", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, description="Get some robot camo. Make Tony Stark proud", ) async def _camo(self, ctx): @@ -47,7 +50,7 @@ class DbrandCog(commands.Cog): @cog_ext.cog_subcommand( base="db", name="grip", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, description="See devices with Grip support", ) async def _grip(self, ctx): @@ -56,7 +59,7 @@ class DbrandCog(commands.Cog): @cog_ext.cog_subcommand( base="db", name="contact", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, description="Contact support", ) async def _contact(self, ctx): @@ -67,7 +70,7 @@ class DbrandCog(commands.Cog): @cog_ext.cog_subcommand( base="db", name="support", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, description="Contact support", ) async def _support(self, ctx): @@ -78,7 +81,7 @@ class DbrandCog(commands.Cog): @cog_ext.cog_subcommand( base="db", name="orderstat", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, description="Get your order status", ) async def _orderstat(self, ctx): @@ -87,7 +90,7 @@ class DbrandCog(commands.Cog): @cog_ext.cog_subcommand( base="db", name="orders", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, description="Get your order status", ) async def _orders(self, ctx): @@ -96,7 +99,7 @@ class DbrandCog(commands.Cog): @cog_ext.cog_subcommand( base="db", name="status", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, description="dbrand status", ) async def _status(self, ctx): @@ -105,7 +108,7 @@ class DbrandCog(commands.Cog): @cog_ext.cog_subcommand( base="db", name="buy", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, description="Give us your money!", ) async def _buy(self, ctx): @@ -114,7 +117,7 @@ class DbrandCog(commands.Cog): @cog_ext.cog_subcommand( base="db", name="extortion", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, description="(not) extortion", ) async def _extort(self, ctx): @@ -126,7 +129,7 @@ class DbrandCog(commands.Cog): base="db", name="ship", description="Get shipping information for your country", - guild_ids=[862402786116763668, 578757004059738142], + guild_ids=guild_ids, options=[ ( create_option( diff --git a/jarvis/cogs/dev.py b/jarvis/cogs/dev.py index a8ebbb7..cc1d31e 100644 --- a/jarvis/cogs/dev.py +++ b/jarvis/cogs/dev.py @@ -1,13 +1,8 @@ import base64 import hashlib -import os import re import subprocess -import sys -import traceback import uuid -from inspect import getsource -from time import time import discord import ulid @@ -18,7 +13,6 @@ from discord_slash import cog_ext import jarvis from jarvis.utils import build_embed, convert_bytesize from jarvis.utils.field import Field -from jarvis.utils.permissions import user_is_bot_admin supported_hashes = { x for x in hashlib.algorithms_guaranteed if "shake" not in x @@ -113,7 +107,6 @@ class DevCog(commands.Cog): @cog_ext.cog_slash( name="hash", description="Hash some data", - guild_ids=[862402786116763668, 578757004059738142], ) async def _hash_slash(self, ctx, method: str, *, data: str = None): await self._hash(ctx, method, data=data) @@ -150,7 +143,6 @@ class DevCog(commands.Cog): @cog_ext.cog_slash( name="uuid", description="Generate a UUID", - guild_ids=[862402786116763668, 578757004059738142], ) async def _uuid_slash(self, ctx, version: str = None, data: str = None): await self._uuid(ctx, version, data) @@ -166,7 +158,6 @@ class DevCog(commands.Cog): @cog_ext.cog_slash( name="objectid", description="Generate an ObjectID", - guild_ids=[862402786116763668, 578757004059738142], ) async def _objectid_slash(self, ctx): await self._objectid(ctx) @@ -182,7 +173,6 @@ class DevCog(commands.Cog): @cog_ext.cog_slash( name="ulid", description="Generate a ULID", - guild_ids=[862402786116763668, 578757004059738142], ) async def _ulid_slash(self, ctx): await self._ulid(ctx) @@ -202,7 +192,6 @@ class DevCog(commands.Cog): @cog_ext.cog_slash( name="uuid2ulid", description="Convert a UUID to a ULID", - guild_ids=[862402786116763668, 578757004059738142], ) async def _uuid2ulid_slash(self, ctx, u: str): await self._uuid2ulid(ctx, u) @@ -222,7 +211,6 @@ class DevCog(commands.Cog): @cog_ext.cog_slash( name="ulid2uuid", description="Convert a ULID to a UUID", - guild_ids=[862402786116763668, 578757004059738142], ) async def _ulid2uuid_slash(self, ctx, u): await self._ulid2uuid(ctx, u) @@ -249,7 +237,6 @@ class DevCog(commands.Cog): @cog_ext.cog_slash( name="encode", description="Encode using the base64 module", - guild_ids=[862402786116763668, 578757004059738142], ) async def _encode_slash(self, ctx, method: str, *, data: str): await self._encode(ctx, method, data) @@ -274,7 +261,6 @@ class DevCog(commands.Cog): @cog_ext.cog_slash( name="decode", description="Decode using the base64 module", - guild_ids=[862402786116763668, 578757004059738142], ) async def _decode_slash(self, ctx, method: str, *, data: str): await self._decode(ctx, method, data) @@ -292,73 +278,11 @@ class DevCog(commands.Cog): @cog_ext.cog_slash( name="cloc", description="Get J.A.R.V.I.S. lines of code", - guild_ids=[862402786116763668, 578757004059738142], ) async def _cloc_slash(self, ctx): await ctx.defer() await self._cloc(ctx) - def resolve_variable(self, variable): - if hasattr(variable, "__iter__"): - var_length = len(list(variable)) - if (var_length > 100) and (not isinstance(variable, str)): - return f"" - elif not var_length: - return f"" - - if (not variable) and (not isinstance(variable, bool)): - return f"" - return ( - variable - if (len(f"{variable}") <= 1000) - else f"" - ) - - def prepare(self, string): - arr = ( - string.strip("```") - .replace("py\n", "") - .replace("python\n", "") - .split("\n") - ) - if not arr[::-1][0].replace(" ", "").startswith("return"): - arr[len(arr) - 1] = "return " + arr[::-1][0] - return "".join(f"\n\t{i}" for i in arr) - - @commands.command(pass_context=True, aliases=["eval", "exec", "evaluate"]) - @user_is_bot_admin() - async def _eval(self, ctx, *, code: str): - code = self.prepare(code) - args = { - "discord": discord, - "sauce": getsource, - "sys": sys, - "os": os, - "imp": __import__, - "this": self, - "ctx": ctx, - } - - try: - exec(f"async def func():{code}", globals().update(args), locals()) - a = time() - response = await eval("func()", globals().update(args), locals()) - if response is None or isinstance(response, discord.Message): - del args, code - return - - if isinstance(response, str): - response = response.replace("`", "") - - await ctx.send( - f"```py\n{self.resolve_variable(response)}```" - + f"`{type(response).__name__} | {(time() - a) / 1000} ms`" - ) - except Exception: - await ctx.send(f"Error occurred:```\n{traceback.format_exc()}```") - - del args, code - def setup(bot): bot.add_cog(DevCog(bot)) diff --git a/jarvis/cogs/error.py b/jarvis/cogs/error.py index a62cdbc..615dda5 100644 --- a/jarvis/cogs/error.py +++ b/jarvis/cogs/error.py @@ -12,9 +12,7 @@ class ErrorHandlerCog(commands.Cog): if isinstance(error, commands.errors.MissingPermissions): await ctx.send("I'm afraid I can't let you do that.") elif isinstance(error, commands.errors.CommandNotFound): - await ctx.send( - "Command does not exist. Run `>help` to get a list of commands" - ) + return else: await ctx.send(f"Error processing command:\n```{error}```") @@ -23,13 +21,13 @@ class ErrorHandlerCog(commands.Cog): if isinstance(error, commands.errors.MissingPermissions) or isinstance( error, commands.errors.CheckFailure ): - await ctx.send("I'm afraid I can't let you do that.") + await ctx.send("I'm afraid I can't let you do that.", hidden=True) elif isinstance(error, commands.errors.CommandNotFound): - await ctx.send( - "Command does not exist. Run `>help` to get a list of commands" - ) + return else: - await ctx.send(f"Error processing command:\n```{error}```") + await ctx.send( + f"Error processing command:\n```{error}```", hidden=True + ) def setup(bot): diff --git a/jarvis/cogs/jokes.py b/jarvis/cogs/jokes.py index 409bb3b..e1deabe 100644 --- a/jarvis/cogs/jokes.py +++ b/jarvis/cogs/jokes.py @@ -131,7 +131,6 @@ class JokeCog(commands.Cog): @cog_ext.cog_slash( name="joke", description="Hear a joke", - guild_ids=[862402786116763668, 578757004059738142], ) async def _joke_slash(self, ctx, id: str = None): await self._joke(ctx, id) diff --git a/jarvis/cogs/modlog.py b/jarvis/cogs/modlog.py index b24b5a9..c48153d 100644 --- a/jarvis/cogs/modlog.py +++ b/jarvis/cogs/modlog.py @@ -2,12 +2,13 @@ import asyncio from datetime import datetime, timedelta import discord -import jarvis import pymongo from discord import DMChannel from discord.ext import commands from discord.utils import find from discord_slash import SlashContext + +import jarvis from jarvis.config import get_config from jarvis.utils import build_embed from jarvis.utils.db import DBManager @@ -356,43 +357,44 @@ class ModlogCog(commands.Cog): async def on_message_edit( self, before: discord.Message, after: discord.Message ): - modlog = self.db.jarvis.settings.find_one( - {"guild": after.guild.id, "setting": "modlog"} - ) - if modlog: - if before.content == after.content or before.content is None: - return - channel = before.guild.get_channel(modlog["value"]) - fields = [ - Field( - "Original Message", - before.content if before.content else "N/A", - False, - ), - Field( - "New Message", - after.content if after.content else "N/A", - False, - ), - ] - embed = build_embed( - title="Message Edited", - description=f"{before.author.mention} edited a message", - fields=fields, - color="#fc9e3f", - timestamp=after.edited_at, - url=after.jump_url, + if before.author != self.bot.client.id: + modlog = self.db.jarvis.settings.find_one( + {"guild": after.guild.id, "setting": "modlog"} ) - embed.set_author( - name=before.author.name, - icon_url=before.author.avatar_url, - url=after.jump_url, - ) - embed.set_footer( - text=f"{before.author.name}#{before.author.discriminator}" - + f" | {before.author.id}" - ) - await channel.send(embed=embed) + if modlog: + if before.content == after.content or before.content is None: + return + channel = before.guild.get_channel(modlog["value"]) + fields = [ + Field( + "Original Message", + before.content if before.content else "N/A", + False, + ), + Field( + "New Message", + after.content if after.content else "N/A", + False, + ), + ] + embed = build_embed( + title="Message Edited", + description=f"{before.author.mention} edited a message", + fields=fields, + color="#fc9e3f", + timestamp=after.edited_at, + url=after.jump_url, + ) + embed.set_author( + name=before.author.name, + icon_url=before.author.avatar_url, + url=after.jump_url, + ) + embed.set_footer( + text=f"{before.author.name}#{before.author.discriminator}" + + f" | {before.author.id}" + ) + await channel.send(embed=embed) @commands.Cog.listener() async def on_message_delete(self, message: discord.Message): diff --git a/jarvis/cogs/owner.py b/jarvis/cogs/owner.py index 12311e3..0677ef1 100644 --- a/jarvis/cogs/owner.py +++ b/jarvis/cogs/owner.py @@ -1,5 +1,11 @@ +import os +import sys +import traceback +from inspect import getsource +from time import time + import discord -from discord import User +from discord import DMChannel, User from discord.ext import commands import jarvis @@ -192,6 +198,79 @@ class OwnerCog(commands.Cog): reload_config() await ctx.send(f"{user.mention} is no longer an admin.") + def resolve_variable(self, variable): + if hasattr(variable, "__iter__"): + var_length = len(list(variable)) + if (var_length > 100) and (not isinstance(variable, str)): + return f"" + elif not var_length: + return f"" + + if (not variable) and (not isinstance(variable, bool)): + return f"" + return ( + variable + if (len(f"{variable}") <= 1000) + else f"" + ) + + def prepare(self, string): + arr = ( + string.strip("```") + .replace("py\n", "") + .replace("python\n", "") + .split("\n") + ) + if not arr[::-1][0].replace(" ", "").startswith("return"): + arr[len(arr) - 1] = "return " + arr[::-1][0] + return "".join(f"\n\t{i}" for i in arr) + + @commands.command( + pass_context=True, aliases=["eval", "exec", "evaluate"] + ) + @user_is_bot_admin() + async def _eval(self, ctx, *, code: str): + if not isinstance(ctx.message.channel, DMChannel): + return + code = self.prepare(code) + args = { + "discord": discord, + "sauce": getsource, + "sys": sys, + "os": os, + "imp": __import__, + "this": self, + "ctx": ctx, + } + + try: + exec( + f"async def func():{code}", + globals().update(args), + locals(), + ) + a = time() + response = await eval( + "func()", globals().update(args), locals() + ) + if response is None or isinstance(response, discord.Message): + del args, code + return + + if isinstance(response, str): + response = response.replace("`", "") + + await ctx.send( + f"```py\n{self.resolve_variable(response)}```" + + f"`{type(response).__name__} | {(time() - a) / 1000} ms`" + ) + except Exception: + await ctx.send( + f"Error occurred:```\n{traceback.format_exc()}```" + ) + + del args, code + def setup(bot): bot.add_cog(OwnerCog(bot)) diff --git a/jarvis/cogs/settings.py b/jarvis/cogs/settings.py index 7b45d07..f285fdc 100644 --- a/jarvis/cogs/settings.py +++ b/jarvis/cogs/settings.py @@ -31,7 +31,6 @@ class SettingsCog(commands.Cog): base="settings", name="mute", description="Set mute role", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="role", @@ -51,7 +50,6 @@ class SettingsCog(commands.Cog): base="settings", name="modlog", description="Set modlog channel", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="channel", @@ -63,7 +61,9 @@ class SettingsCog(commands.Cog): ) @commands.has_permissions(administrator=True) async def _modlog(self, ctx, channel: TextChannel): - await ctx.defer() + if not isinstance(channel, TextChannel): + await ctx.send("Channel must be a TextChannel", hidden=True) + return self.update_settings("modlog", channel.id, ctx.guild.id) await ctx.send( f"Settings applied. New modlog channel is {channel.mention}" @@ -73,7 +73,6 @@ class SettingsCog(commands.Cog): base="settings", name="userlog", description="Set userlog channel", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="channel", @@ -85,7 +84,9 @@ class SettingsCog(commands.Cog): ) @commands.has_permissions(administrator=True) async def _userlog(self, ctx, channel: TextChannel): - await ctx.defer() + if not isinstance(channel, TextChannel): + await ctx.send("Channel must be a TextChannel", hidden=True) + return self.update_settings("userlog", channel.id, ctx.guild.id) await ctx.send( f"Settings applied. New userlog channel is {channel.mention}" @@ -95,7 +96,6 @@ class SettingsCog(commands.Cog): base="settings", name="massmention", description="Set massmention amount", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="amount", @@ -115,7 +115,6 @@ class SettingsCog(commands.Cog): base="settings", name="verified", description="Set verified role", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="role", @@ -135,7 +134,6 @@ class SettingsCog(commands.Cog): base="settings", name="unverified", description="Set unverified role", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="role", diff --git a/jarvis/cogs/starboard.py b/jarvis/cogs/starboard.py index 1b1401a..1649c2a 100644 --- a/jarvis/cogs/starboard.py +++ b/jarvis/cogs/starboard.py @@ -2,12 +2,13 @@ from datetime import datetime import aiohttp import discord -import jarvis from discord import Message, TextChannel from discord.ext import commands from discord.utils import find from discord_slash import SlashContext, cog_ext from discord_slash.utils.manage_commands import create_option + +import jarvis from jarvis.config import get_config from jarvis.utils import build_embed from jarvis.utils.db import DBManager @@ -32,7 +33,6 @@ class StarboardCog(commands.Cog): base="starboard", name="list", description="Lists all Starboards", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], ) @commands.has_permissions(administrator=True) async def _list(self, ctx): @@ -51,7 +51,6 @@ class StarboardCog(commands.Cog): base="starboard", name="create", description="Create a starboard", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="target", @@ -69,6 +68,9 @@ class StarboardCog(commands.Cog): hidden=True, ) return + if not isinstance(target, TextChannel): + await ctx.send("Target must be a TextChannel", hidden=True) + return exists = self.db.jarvis.starboard.find_one( {"target": target.id, "guild": ctx.guild.id} ) @@ -92,7 +94,6 @@ class StarboardCog(commands.Cog): base="starboard", name="delete", description="Delete a starboard", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="channel", @@ -103,28 +104,27 @@ class StarboardCog(commands.Cog): ], ) @commands.has_permissions(administrator=True) - async def _delete(self, ctx, target: TextChannel): + async def _delete(self, ctx, channel: TextChannel): deleted = self.db.jarvis.starboard.delete_one( { - "target": target.id, + "target": channel.id, "guild": ctx.guild.id, } ) if deleted: - self.db.jarvis.stars.delete_many({"starboard": target.id}) + self.db.jarvis.stars.delete_many({"starboard": channel.id}) await ctx.send( - f"Starboard deleted from {target.mention}.", hidden=True + f"Starboard deleted from {channel.mention}.", hidden=True ) else: await ctx.send( - f"Starboard not found in {target.mention}.", hidden=True + f"Starboard not found in {channel.mention}.", hidden=True ) @cog_ext.cog_subcommand( base="star", name="add", description="Star a message", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], options=[ create_option( name="message", @@ -238,6 +238,70 @@ class StarboardCog(commands.Cog): "Message saved to Starboard.\n" + f"See it in {starboard.mention}" ) + @cog_ext.cog_subcommand( + base="star", + name="delete", + description="Delete a starred message", + guild_ids=[ + 862402786116763668, + 418094694325813248, + 578757004059738142, + ], + options=[ + create_option( + name="id", + description="Star to delete", + option_type=4, + required=True, + ), + create_option( + name="starboard", + description="Starboard to delete star from", + option_type=7, + required=True, + ), + ], + ) + async def _star_get( + self, + ctx: SlashContext, + id: int, + starboard: TextChannel, + ): + exists = self.db.jarvis.starboard.find_one( + {"target": starboard.id, "guild": ctx.guild.id} + ) + if not exists: + await ctx.send( + f"Starboard does not exist in {starboard.mention}. " + + "Please create it first", + hidden=True, + ) + return + + star = self.db.jarvis.stars.find_one( + { + "starboard": starboard.id, + "id": id, + "guild": ctx.guild.id, + "active": True, + } + ) + if not star: + await ctx.send(f"No star exists with id {id}", hidden=True) + return + + message = await starboard.fetch_message(star["star"]) + if message: + await message.delete() + + self.db.jarvis.stars.update_one( + {"starboard": starboard.id, "id": id, "guild": ctx.guild.id}, + {"$set": {"active": False}}, + ) + + await ctx.send(f"Star {id} deleted") + def setup(bot): bot.add_cog(StarboardCog(bot)) diff --git a/jarvis/cogs/util.py b/jarvis/cogs/util.py index 89e1631..a081b40 100644 --- a/jarvis/cogs/util.py +++ b/jarvis/cogs/util.py @@ -25,7 +25,6 @@ class UtilCog(commands.Cog): @cog_ext.cog_slash( name="status", description="Retrieve J.A.R.V.I.S. status", - guild_ids=[862402786116763668, 578757004059738142], ) async def _status(self, ctx): title = "J.A.R.V.I.S. Status" @@ -51,7 +50,6 @@ class UtilCog(commands.Cog): @cog_ext.cog_slash( name="logo", description="Get the current logo", - guild_ids=[862402786116763668, 578757004059738142], ) async def _logo(self, ctx): lo = logo.get_logo(self.config.logo) @@ -60,7 +58,6 @@ class UtilCog(commands.Cog): @cog_ext.cog_slash( name="rcauto", description="Automates robot camo letters", - guild_ids=[862402786116763668, 578757004059738142], options=[ create_option( name="text", @@ -72,7 +69,9 @@ class UtilCog(commands.Cog): ) async def _rcauto(self, ctx: SlashContext, text: str): to_send = "" - if len(text) == 1 and not re.match(r"^[A-Z0-9-()$@!?^'#. ]$", text): + if len(text) == 1 and not re.match( + r"^[A-Z0-9-()$@!?^'#. ]$", text.upper() + ): await ctx.send("Please use ASCII characters.", hidden=True) return for letter in text.upper(): diff --git a/jarvis/cogs/verify.py b/jarvis/cogs/verify.py index 3d4caaf..83d4d9f 100644 --- a/jarvis/cogs/verify.py +++ b/jarvis/cogs/verify.py @@ -38,7 +38,6 @@ class VerifyCog(commands.Cog): @cog_ext.cog_slash( name="verify", description="Verify that you've read the rules", - guild_ids=[862402786116763668, 418094694325813248, 578757004059738142], ) async def _verify(self, ctx: SlashContext): await ctx.defer()