Initial pre-commit update with formatting

This commit is contained in:
Zeva Rose 2021-08-06 17:47:06 -06:00
parent 4c3dc49f7d
commit a87783db16
46 changed files with 465 additions and 957 deletions

View file

@ -1,4 +1,5 @@
import asyncio
import logging
from pathlib import Path
from typing import Union
@ -9,9 +10,13 @@ from discord_slash import SlashCommand
from mongoengine import connect
from psutil import Process
from jarvis import logo, tasks, utils
from jarvis import logo
from jarvis import tasks
from jarvis import utils
from jarvis.config import get_config
from jarvis.events import guild, member, message
from jarvis.events import guild
from jarvis.events import member
from jarvis.events import message
if asyncio.get_event_loop().is_closed():
asyncio.set_event_loop(asyncio.new_event_loop())
@ -47,9 +52,7 @@ async def on_ready():
if "guild" in restart_ctx:
guild = find(lambda x: x.id == restart_ctx["guild"], jarvis.guilds)
if guild:
channel = find(
lambda x: x.id == restart_ctx["channel"], guild.channels
)
channel = find(lambda x: x.id == restart_ctx["channel"], guild.channels)
elif "user" in restart_ctx:
channel = jarvis.get_user(restart_ctx["user"])
if channel:
@ -78,9 +81,7 @@ def run(ctx=None):
jarvis.load_extension(extension)
print(
" https://discord.com/api/oauth2/authorize?client_id="
+ "{}&permissions=8&scope=bot%20applications.commands".format(
jconfig.client_id
)
+ "{}&permissions=8&scope=bot%20applications.commands".format(jconfig.client_id)
)
jarvis.max_messages = jconfig.max_messages

View file

@ -1,13 +1,11 @@
from jarvis.cogs.admin import (
ban,
kick,
lock,
lockdown,
mute,
purge,
roleping,
warning,
)
from jarvis.cogs.admin import ban
from jarvis.cogs.admin import kick
from jarvis.cogs.admin import lock
from jarvis.cogs.admin import lockdown
from jarvis.cogs.admin import mute
from jarvis.cogs.admin import purge
from jarvis.cogs.admin import roleping
from jarvis.cogs.admin import warning
def setup(bot):

View file

@ -1,15 +1,19 @@
import re
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
from ButtonPaginator import Paginator
from discord import User
from discord.ext import commands
from discord.utils import find
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.model import ButtonStyle
from discord_slash.utils.manage_commands import create_choice, create_option
from discord_slash.utils.manage_commands import create_choice
from discord_slash.utils.manage_commands import create_option
from jarvis.db.models import Ban, Unban
from jarvis.db.models import Ban
from jarvis.db.models import Unban
from jarvis.utils import build_embed
from jarvis.utils.cachecog import CacheCog
from jarvis.utils.field import Field
@ -57,9 +61,7 @@ class BanCog(CacheCog):
await ctx.send(embed=embed)
async def discord_apply_unban(
self, ctx: SlashContext, user: User, reason: str
):
async def discord_apply_unban(self, ctx: SlashContext, user: User, reason: str):
await ctx.guild.unban(user, reason=reason)
_ = Unban(
user=user.id,
@ -134,22 +136,16 @@ class BanCog(CacheCog):
await ctx.send("I'm afraid I can't let you do that", hidden=True)
return
if type == "temp" and duration < 0:
await ctx.send(
"You cannot set a temp ban to < 0 hours.", hidden=True
)
await ctx.send("You cannot set a temp ban to < 0 hours.", hidden=True)
return
elif type == "temp" and duration > 744:
await ctx.send(
"You cannot set a temp ban to > 1 month", hidden=True
)
await ctx.send("You cannot set a temp ban to > 1 month", 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."
)
reason = "Mr. Stark is displeased with your presence. Please leave."
await ctx.defer()
@ -158,10 +154,7 @@ class BanCog(CacheCog):
mtype = "perma"
guild_name = ctx.guild.name
user_message = (
f"You have been {mtype}banned from {guild_name}."
+ f" Reason:\n{reason}"
)
user_message = f"You have been {mtype}banned from {guild_name}." + f" Reason:\n{reason}"
if mtype == "temp":
user_message += f"\nDuration: {duration} hours"
@ -202,9 +195,7 @@ class BanCog(CacheCog):
if type == "soft":
active = False
await self.discord_apply_ban(
ctx, reason, user, duration, active, fields
)
await self.discord_apply_ban(ctx, reason, user, duration, active, fields)
@cog_ext.cog_slash(
name="unban",
@ -251,23 +242,16 @@ class BanCog(CacheCog):
user, discrim = user.split("#")
if discrim:
discord_ban_info = find(
lambda x: x.user.name == user
and x.user.discriminator == discrim,
lambda x: x.user.name == user and x.user.discriminator == discrim,
bans,
)
else:
results = [
x for x in filter(lambda x: x.user.name == user, bans)
]
results = [x for x in filter(lambda x: x.user.name == user, bans)]
if results:
if len(results) > 1:
active_bans = []
for ban in bans:
active_bans.append(
"{0} ({1}): {2}".format(
ban.user.name, ban.user.id, ban.reason
)
)
active_bans.append("{0} ({1}): {2}".format(ban.user.name, ban.user.id, ban.reason))
message = (
"More than one result. "
+ "Please use one of the following IDs:\n```"
@ -284,9 +268,7 @@ class BanCog(CacheCog):
# We take advantage of the previous checks to save CPU cycles
if not discord_ban_info:
if isinstance(user, int):
database_ban_info = Ban.objects(
guild=ctx.guild.id, user=user, active=True
).first()
database_ban_info = Ban.objects(guild=ctx.guild.id, user=user, active=True).first()
else:
search = {
"guild": ctx.guild.id,
@ -303,13 +285,9 @@ class BanCog(CacheCog):
elif discord_ban_info:
await self.discord_apply_unban(ctx, discord_ban_info.user, reason)
else:
discord_ban_info = find(
lambda x: x.user.id == database_ban_info["id"], bans
)
discord_ban_info = find(lambda x: x.user.id == database_ban_info["id"], bans)
if discord_ban_info:
await self.discord_apply_unban(
ctx, discord_ban_info.user, reason
)
await self.discord_apply_unban(ctx, discord_ban_info.user, reason)
else:
database_ban_info.active = False
database_ban_info.save()
@ -321,10 +299,7 @@ class BanCog(CacheCog):
admin=ctx.author.id,
reason=reason,
).save()
await ctx.send(
"Unable to find user in Discord, "
+ "but removed entry from database."
)
await ctx.send("Unable to find user in Discord, " + "but removed entry from database.")
@cog_ext.cog_subcommand(
base="bans",
@ -356,16 +331,13 @@ class BanCog(CacheCog):
],
)
@admin_or_permissions(ban_members=True)
async def _bans_list(
self, ctx: SlashContext, type: int = 0, active: int = 1
):
async def _bans_list(self, ctx: SlashContext, type: int = 0, active: int = 1):
active = bool(active)
exists = self.check_cache(ctx, type=type, active=active)
if exists:
await ctx.defer(hidden=True)
await ctx.send(
"Please use existing interaction: "
+ f"{exists['paginator']._message.jump_url}",
"Please use existing interaction: " + f"{exists['paginator']._message.jump_url}",
hidden=True,
)
return
@ -399,8 +371,7 @@ class BanCog(CacheCog):
if ban.user.id not in db_bans:
fields.append(
Field(
name=f"Username: {ban.user.name}#"
+ f"{ban.user.discriminator}",
name=f"Username: {ban.user.name}#" + f"{ban.user.discriminator}",
value="Date: [unknown]\n"
+ f"User ID: {ban.user.id}\n"
+ f"Reason: {ban.reason}\n"
@ -426,9 +397,7 @@ class BanCog(CacheCog):
pages.append(embed)
else:
for i in range(0, len(bans), 5):
embed = build_embed(
title=title, description="", fields=fields[i : i + 5]
)
embed = build_embed(title=title, description="", fields=fields[i : i + 5])
embed.set_thumbnail(url=ctx.guild.icon_url)
pages.append(embed)

View file

@ -1,5 +1,6 @@
from discord import User
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_option
from jarvis.db.models import Kick
@ -43,9 +44,7 @@ class KickCog(CacheCog):
await ctx.send("Reason must be < 100 characters", hidden=True)
return
if not reason:
reason = (
"Mr. Stark is displeased with your presence. Please leave."
)
reason = "Mr. Stark is displeased with your presence. Please leave."
guild_name = ctx.guild.name
embed = build_embed(
title=f"You have been kicked from {guild_name}",

View file

@ -1,8 +1,12 @@
from typing import Union
from discord import Role, TextChannel, User, VoiceChannel
from discord import Role
from discord import TextChannel
from discord import User
from discord import VoiceChannel
from discord.ext import commands
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_option
from jarvis.db.models import Lock
@ -120,9 +124,7 @@ class LockCog(CacheCog):
):
if not channel:
channel = ctx.channel
lock = Lock.objects(
guild=ctx.guild.id, channel=channel.id, active=True
).first()
lock = Lock.objects(guild=ctx.guild.id, channel=channel.id, active=True).first()
if not lock:
await ctx.send(f"{channel.mention} not locked.", hidden=True)
return

View file

@ -1,7 +1,8 @@
from datetime import datetime
from discord.ext import commands
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_option
from jarvis.db.models import Lock
@ -96,7 +97,5 @@ class LockdownCog(CacheCog):
continue # Just continue on error
update = True
if update:
Lock.objects(guild=ctx.guild.id, active=True).update(
set__active=False
)
Lock.objects(guild=ctx.guild.id, active=True).update(set__active=False)
await ctx.send("Server unlocked")

View file

@ -1,10 +1,12 @@
from discord import Member
from discord.ext import commands
from discord.utils import get
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_option
from jarvis.db.models import Mute, Setting
from jarvis.db.models import Mute
from jarvis.db.models import Setting
from jarvis.utils import build_embed
from jarvis.utils.field import Field
from jarvis.utils.permissions import admin_or_permissions
@ -39,9 +41,7 @@ class MuteCog(commands.Cog):
],
)
@admin_or_permissions(mute_members=True)
async def _mute(
self, ctx: SlashContext, user: Member, reason: str, duration: int = 30
):
async def _mute(self, ctx: SlashContext, user: Member, reason: str, duration: int = 30):
if user == ctx.author:
await ctx.send("You cannot mute yourself.", hidden=True)
return
@ -51,13 +51,10 @@ class MuteCog(commands.Cog):
if len(reason) > 100:
await ctx.send("Reason must be < 100 characters", hidden=True)
return
mute_setting = Setting.objects(
guild=ctx.guild.id, setting="mute"
).first()
mute_setting = Setting.objects(guild=ctx.guild.id, setting="mute").first()
if not mute_setting:
await ctx.send(
"Please configure a mute role "
+ "with /settings mute <role> first",
"Please configure a mute role " + "with /settings mute <role> first",
hidden=True,
)
return
@ -104,13 +101,10 @@ class MuteCog(commands.Cog):
)
@admin_or_permissions(mute_members=True)
async def _unmute(self, ctx: SlashContext, user: Member):
mute_setting = Setting.objects(
guild=ctx.guild.id, setting="mute"
).first()
mute_setting = Setting.objects(guild=ctx.guild.id, setting="mute").first()
if not mute_setting:
await ctx.send(
"Please configure a mute role with "
+ "/settings mute <role> first.",
"Please configure a mute role with " + "/settings mute <role> first.",
hidden=True,
)
return
@ -122,9 +116,7 @@ class MuteCog(commands.Cog):
await ctx.send("User is not muted.", hidden=True)
return
_ = Mute.objects(guild=ctx.guild.id, user=user.id).update(
set__active=False
)
_ = Mute.objects(guild=ctx.guild.id, user=user.id).update(set__active=False)
embed = build_embed(
title="User Unmuted",
description=f"{user.mention} has been unmuted",

View file

@ -1,9 +1,11 @@
from discord import TextChannel
from discord.ext import commands
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_option
from jarvis.db.models import Autopurge, Purge
from jarvis.db.models import Autopurge
from jarvis.db.models import Purge
from jarvis.utils.permissions import admin_or_permissions
@ -61,9 +63,7 @@ class PurgeCog(commands.Cog):
],
)
@admin_or_permissions(manage_messages=True)
async def _autopurge_add(
self, ctx: SlashContext, channel: TextChannel, delay: int = 30
):
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
@ -73,9 +73,7 @@ class PurgeCog(commands.Cog):
elif delay > 300:
await ctx.send("Delay must be < 5 minutes", hidden=True)
return
autopurge = Autopurge.objects(
guild=ctx.guild.id, channel=channel.id
).first()
autopurge = Autopurge.objects(guild=ctx.guild.id, channel=channel.id).first()
if autopurge:
await ctx.send("Autopurge already exists.", hidden=True)
return
@ -85,10 +83,7 @@ class PurgeCog(commands.Cog):
admin=ctx.author.id,
delay=delay,
).save()
await ctx.send(
f"Autopurge set up on {channel.mention}, "
+ f"delay is {delay} seconds"
)
await ctx.send(f"Autopurge set up on {channel.mention}, " + f"delay is {delay} seconds")
@cog_ext.cog_subcommand(
base="autopurge",
@ -132,15 +127,11 @@ class PurgeCog(commands.Cog):
],
)
@admin_or_permissions(manage_messages=True)
async def _autopurge_update(
self, ctx: SlashContext, channel: TextChannel, delay: int
):
async def _autopurge_update(self, ctx: SlashContext, channel: TextChannel, delay: int):
autopurge = Autopurge.objects(guild=ctx.guild.id, channel=channel.id)
if not autopurge:
await ctx.send("Autopurge does not exist.", hidden=True)
return
autopurge.delay = delay
autopurge.save()
await ctx.send(
f"Autopurge delay updated to {delay} seconds on {channel.mention}."
)
await ctx.send(f"Autopurge delay updated to {delay} seconds on {channel.mention}.")

View file

@ -1,8 +1,11 @@
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
from ButtonPaginator import Paginator
from discord import Member, Role
from discord_slash import SlashContext, cog_ext
from discord import Member
from discord import Role
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.model import ButtonStyle
from discord_slash.utils.manage_commands import create_option
@ -34,9 +37,7 @@ class RolepingCog(CacheCog):
async def _roleping_add(self, ctx: SlashContext, role: Role):
roleping = Roleping.objects(guild=ctx.guild.id, role=role.id).first()
if roleping:
await ctx.send(
f"Role `{role.name}` already in roleping.", hidden=True
)
await ctx.send(f"Role `{role.name}` already in roleping.", hidden=True)
return
_ = Roleping(
role=role.id,
@ -80,8 +81,7 @@ class RolepingCog(CacheCog):
if exists:
await ctx.defer(hidden=True)
await ctx.send(
"Please use existing interaction: "
+ f"{exists['paginator']._message.jump_url}",
"Please use existing interaction: " + f"{exists['paginator']._message.jump_url}",
hidden=True,
)
return
@ -94,18 +94,9 @@ class RolepingCog(CacheCog):
embeds = []
for roleping in rolepings:
role = ctx.guild.get_role(roleping.role)
bypass_roles = list(
filter(
lambda x: x.id in roleping.bypass["roles"], ctx.guild.roles
)
)
bypass_roles = [
r.mention or "||`[redacted]`||" for r in bypass_roles
]
bypass_users = [
ctx.guild.get_member(u).mention or "||`[redacted]`||"
for u in roleping.bypass["users"]
]
bypass_roles = list(filter(lambda x: x.id in roleping.bypass["roles"], ctx.guild.roles))
bypass_roles = [r.mention or "||`[redacted]`||" for r in bypass_roles]
bypass_users = [ctx.guild.get_member(u).mention or "||`[redacted]`||" for u in roleping.bypass["users"]]
bypass_roles = bypass_roles or ["None"]
bypass_users = bypass_users or ["None"]
embed = build_embed(
@ -115,9 +106,7 @@ class RolepingCog(CacheCog):
fields=[
Field(
name="Created At",
value=roleping.created_at.strftime(
"%a, %b %d, %Y %I:%M %p"
),
value=roleping.created_at.strftime("%a, %b %d, %Y %I:%M %p"),
inline=False,
),
Field(name="Active", value=str(roleping.active)),
@ -136,12 +125,8 @@ class RolepingCog(CacheCog):
if not admin:
admin = self.bot.user
embed.set_author(
name=admin.nick or admin.name, icon_url=admin.avatar_url
)
embed.set_footer(
text=f"{admin.name}#{admin.discriminator} | {admin.id}"
)
embed.set_author(name=admin.nick or admin.name, icon_url=admin.avatar_url)
embed.set_footer(text=f"{admin.name}#{admin.discriminator} | {admin.id}")
embeds.append(embed)
@ -191,14 +176,10 @@ class RolepingCog(CacheCog):
],
)
@admin_or_permissions(manage_guild=True)
async def _roleping_bypass_user(
self, ctx: SlashContext, user: Member, rping: Role
):
async def _roleping_bypass_user(self, ctx: SlashContext, user: Member, rping: Role):
roleping = Roleping.objects(guild=ctx.guild.id, role=rping.id).first()
if not roleping:
await ctx.send(
f"Roleping not configured for {rping.mention}", hidden=True
)
await ctx.send(f"Roleping not configured for {rping.mention}", hidden=True)
return
if user.id in roleping.bypass["users"]:
@ -207,29 +188,23 @@ class RolepingCog(CacheCog):
if len(roleping.bypass["users"]) == 10:
await ctx.send(
"Already have 10 users in bypass. "
"Please consider using roles for roleping bypass",
"Already have 10 users in bypass. " "Please consider using roles for roleping bypass",
hidden=True,
)
return
matching_role = list(
filter(lambda x: x.id in roleping.bypass["roles"], user.roles)
)
matching_role = list(filter(lambda x: x.id in roleping.bypass["roles"], user.roles))
if matching_role:
await ctx.send(
f"{user.mention} already has bypass "
f"via {matching_role[0].mention}",
f"{user.mention} already has bypass " f"via {matching_role[0].mention}",
hidden=True,
)
return
roleping.bypass["users"].append(user.id)
roleping.save()
await ctx.send(
f"{user.nick or user.name} user bypass added for `{rping.name}`"
)
await ctx.send(f"{user.nick or user.name} user bypass added for `{rping.name}`")
@cog_ext.cog_subcommand(
base="roleping",
@ -254,14 +229,10 @@ class RolepingCog(CacheCog):
],
)
@admin_or_permissions(manage_guild=True)
async def _roleping_bypass_role(
self, ctx: SlashContext, role: Role, rping: Role
):
async def _roleping_bypass_role(self, ctx: SlashContext, role: Role, rping: Role):
roleping = Roleping.objects(guild=ctx.guild.id, role=rping.id).first()
if not roleping:
await ctx.send(
f"Roleping not configured for {rping.mention}", hidden=True
)
await ctx.send(f"Roleping not configured for {rping.mention}", hidden=True)
return
if role.id in roleping.bypass["roles"]:
@ -270,8 +241,7 @@ class RolepingCog(CacheCog):
if len(roleping.bypass["roles"]) == 10:
await ctx.send(
"Already have 10 roles in bypass. "
"Please consider consolidating roles for roleping bypass",
"Already have 10 roles in bypass. " "Please consider consolidating roles for roleping bypass",
hidden=True,
)
return
@ -303,14 +273,10 @@ class RolepingCog(CacheCog):
],
)
@admin_or_permissions(manage_guild=True)
async def _roleping_restore_user(
self, ctx: SlashContext, user: Member, rping: Role
):
async def _roleping_restore_user(self, ctx: SlashContext, user: Member, rping: Role):
roleping = Roleping.objects(guild=ctx.guild.id, role=rping.id).first()
if not roleping:
await ctx.send(
f"Roleping not configured for {rping.mention}", hidden=True
)
await ctx.send(f"Roleping not configured for {rping.mention}", hidden=True)
return
if user.id not in roleping.bypass["users"]:
@ -319,9 +285,7 @@ class RolepingCog(CacheCog):
roleping.bypass["users"].delete(user.id)
roleping.save()
await ctx.send(
f"{user.nick or user.name} user bypass removed for `{rping.name}`"
)
await ctx.send(f"{user.nick or user.name} user bypass removed for `{rping.name}`")
@cog_ext.cog_subcommand(
base="roleping",
@ -346,14 +310,10 @@ class RolepingCog(CacheCog):
],
)
@admin_or_permissions(manage_guild=True)
async def _roleping_restore_role(
self, ctx: SlashContext, role: Role, rping: Role
):
async def _roleping_restore_role(self, ctx: SlashContext, role: Role, rping: Role):
roleping = Roleping.objects(guild=ctx.guild.id, role=rping.id).first()
if not roleping:
await ctx.send(
f"Roleping not configured for {rping.mention}", hidden=True
)
await ctx.send(f"Roleping not configured for {rping.mention}", hidden=True)
return
if role.id in roleping.bypass["roles"]:
@ -362,8 +322,7 @@ class RolepingCog(CacheCog):
if len(roleping.bypass["roles"]) == 10:
await ctx.send(
"Already have 10 roles in bypass. "
"Please consider consolidating roles for roleping bypass",
"Already have 10 roles in bypass. " "Please consider consolidating roles for roleping bypass",
hidden=True,
)
return

View file

@ -1,10 +1,13 @@
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
from ButtonPaginator import Paginator
from discord import User
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.model import ButtonStyle
from discord_slash.utils.manage_commands import create_choice, create_option
from discord_slash.utils.manage_commands import create_choice
from discord_slash.utils.manage_commands import create_option
from jarvis.db.models import Warning
from jarvis.utils import build_embed
@ -42,9 +45,7 @@ class WarningCog(CacheCog):
],
)
@admin_or_permissions(manage_guild=True)
async def _warn(
self, ctx: SlashContext, user: User, reason: str, duration: int = 24
):
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
@ -106,8 +107,7 @@ class WarningCog(CacheCog):
if exists:
await ctx.defer(hidden=True)
await ctx.send(
"Please use existing interaction: "
+ f"{exists['paginator']._message.jump_url}",
"Please use existing interaction: " + f"{exists['paginator']._message.jump_url}",
hidden=True,
)
return
@ -115,9 +115,7 @@ class WarningCog(CacheCog):
user=user.id,
guild=ctx.guild.id,
).order_by("-created_at")
active_warns = Warning.objects(
user=user.id, guild=ctx.guild.id, active=True
).order_by("-created_at")
active_warns = Warning.objects(user=user.id, guild=ctx.guild.id, active=True).order_by("-created_at")
pages = []
if active:
@ -139,20 +137,15 @@ class WarningCog(CacheCog):
admin_name = f"{admin.name}#{admin.discriminator}"
fields.append(
Field(
name=warn.created_at.strftime(
"%Y-%m-%d %H:%M:%S UTC"
),
value=f"{warn.reason}\n"
+ f"Admin: {admin_name}\n"
+ "\u200b",
name=warn.created_at.strftime("%Y-%m-%d %H:%M:%S UTC"),
value=f"{warn.reason}\n" + f"Admin: {admin_name}\n" + "\u200b",
inline=False,
)
)
for i in range(0, len(fields), 5):
embed = build_embed(
title="Warnings",
description=f"{warnings.count()} total | "
+ f"{active_warns.count()} currently active",
description=f"{warnings.count()} total | " + f"{active_warns.count()} currently active",
fields=fields[i : i + 5],
)
embed.set_author(
@ -160,9 +153,7 @@ class WarningCog(CacheCog):
icon_url=user.avatar_url,
)
embed.set_thumbnail(url=ctx.guild.icon_url)
embed.set_footer(
text=f"{user.name}#{user.discriminator} | {user.id}"
)
embed.set_footer(text=f"{user.name}#{user.discriminator} | {user.id}")
pages.append(embed)
else:
fields = []
@ -179,8 +170,7 @@ class WarningCog(CacheCog):
for i in range(0, len(fields), 5):
embed = build_embed(
title="Warnings",
description=f"{warnings.count()} total | "
+ f"{active_warns.count()} currently active",
description=f"{warnings.count()} total | " + f"{active_warns.count()} currently active",
fields=fields[i : i + 5],
)
embed.set_author(

View file

@ -3,7 +3,8 @@ import re
from discord import TextChannel
from discord.ext import commands
from discord.utils import find
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_option
from jarvis.data.unicode import emoji_list
@ -34,13 +35,9 @@ class AutoReactCog(commands.Cog):
if not isinstance(channel, TextChannel):
await ctx.send("Channel must be a text channel", hidden=True)
return
exists = Autoreact.objects(
guild=ctx.guild.id, channel=channel.id
).first()
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
if exists:
await ctx.send(
f"Autoreact already exists for {channel.mention}.", hidden=True
)
await ctx.send(f"Autoreact already exists for {channel.mention}.", hidden=True)
return
_ = Autoreact(
@ -66,15 +63,11 @@ class AutoReactCog(commands.Cog):
)
@admin_or_permissions(manage_guild=True)
async def _autoreact_delete(self, ctx, channel: TextChannel):
exists = Autoreact.objects(
guild=ctx.guild.id, channel=channel.id
).delete()
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).delete()
if exists:
await ctx.send(f"Autoreact removed from {channel.mention}")
else:
await ctx.send(
f"Autoreact not found on {channel.mention}", hidden=True
)
await ctx.send(f"Autoreact not found on {channel.mention}", hidden=True)
@cog_ext.cog_subcommand(
base="autoreact",
@ -102,26 +95,18 @@ class AutoReactCog(commands.Cog):
standard_emoji = emote in emoji_list
if not custom_emoji and not standard_emoji:
await ctx.send(
"Please use either an emote from this server"
+ " or a unicode emoji.",
"Please use either an emote from this server" + " or a unicode emoji.",
hidden=True,
)
return
if custom_emoji:
emoji_id = int(custom_emoji.group(1))
if not find(lambda x: x.id == emoji_id, ctx.guild.emojis):
await ctx.send(
"Please use a custom emote from this server.", hidden=True
)
await ctx.send("Please use a custom emote from this server.", hidden=True)
return
exists = Autoreact.objects(
guild=ctx.guild.id, channel=channel.id
).first()
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
if not exists:
await ctx.send(
"Please create autoreact first with "
+ f"/autoreact create {channel.mention}"
)
await ctx.send("Please create autoreact first with " + f"/autoreact create {channel.mention}")
return
if emote in exists.reactions:
await ctx.send(
@ -131,8 +116,7 @@ class AutoReactCog(commands.Cog):
return
if len(exists.reactions) >= 5:
await ctx.send(
"Max number of reactions hit. "
+ "Remove a different one to add this one",
"Max number of reactions hit. " + "Remove a different one to add this one",
hidden=True,
)
return
@ -161,13 +145,10 @@ class AutoReactCog(commands.Cog):
)
@admin_or_permissions(manage_guild=True)
async def _autoreact_remove(self, ctx, channel: TextChannel, emote: str):
exists = Autoreact.objects(
guild=ctx.guild.id, channel=channel.id
).first()
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
if not exists:
await ctx.send(
"Please create autoreact first with "
+ f"/autoreact create {channel.mention}",
"Please create autoreact first with " + f"/autoreact create {channel.mention}",
hidden=True,
)
return
@ -196,22 +177,16 @@ class AutoReactCog(commands.Cog):
)
@admin_or_permissions(manage_guild=True)
async def _autoreact_list(self, ctx, channel: TextChannel):
exists = Autoreact.objects(
guild=ctx.guild.id, channel=channel.id
).first()
exists = Autoreact.objects(guild=ctx.guild.id, channel=channel.id).first()
if not exists:
await ctx.send(
"Please create autoreact first with "
+ f"/autoreact create {channel.mention}",
"Please create autoreact first with " + f"/autoreact create {channel.mention}",
hidden=True,
)
return
message = ""
if len(exists.reactions) > 0:
message = (
f"Current active autoreacts on {channel.mention}:\n"
+ "\n".join(exists.reactions)
)
message = f"Current active autoreacts on {channel.mention}:\n" + "\n".join(exists.reactions)
else:
message = f"No reactions set on {channel.mention}"
await ctx.send(message)

View file

@ -1,14 +1,17 @@
import re
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
import aiohttp
import pymongo
from ButtonPaginator import Paginator
from discord import Member, User
from discord import Member
from discord import User
from discord.ext import commands
from discord.ext.tasks import loop
from discord.utils import find
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.model import ButtonStyle
from jarvis.db.models import Guess
@ -51,22 +54,19 @@ class CTCCog(CacheCog):
async def _pw(self, ctx: SlashContext, guess: str):
if len(guess) > 800:
await ctx.send(
"Listen here, dipshit. Don't be like "
+ "<@256110768724901889>. Make your guesses < 800 characters.",
"Listen here, dipshit. Don't be like " + "<@256110768724901889>. Make your guesses < 800 characters.",
hidden=True,
)
return
elif not valid.fullmatch(guess):
await ctx.send(
"Listen here, dipshit. Don't be like "
+ "<@256110768724901889>. Make your guesses *readable*.",
"Listen here, dipshit. Don't be like " + "<@256110768724901889>. Make your guesses *readable*.",
hidden=True,
)
return
elif invites.search(guess):
await ctx.send(
"Listen here, dipshit. "
+ "No using this to bypass sending invite links.",
"Listen here, dipshit. " + "No using this to bypass sending invite links.",
hidden=True,
)
return
@ -77,9 +77,7 @@ class CTCCog(CacheCog):
result = await self._session.post(self.url, data=guess)
correct = False
if 200 <= result.status < 400:
await ctx.send(
f"{ctx.author.mention} got it! Password is {guess}!"
)
await ctx.send(f"{ctx.author.mention} got it! Password is {guess}!")
correct = True
else:
await ctx.send("Nope.", hidden=True)
@ -97,8 +95,7 @@ class CTCCog(CacheCog):
if exists:
await ctx.defer(hidden=True)
await ctx.send(
"Please use existing interaction: "
+ f"{exists['paginator']._message.jump_url}",
"Please use existing interaction: " + f"{exists['paginator']._message.jump_url}",
hidden=True,
)
return

View file

@ -66,9 +66,7 @@ class DbrandCog(commands.Cog):
)
@commands.cooldown(1, 30, commands.BucketType.channel)
async def _contact(self, ctx):
await ctx.send(
"Contact dbrand support here: " + self.base_url + "contact"
)
await ctx.send("Contact dbrand support here: " + self.base_url + "contact")
@cog_ext.cog_subcommand(
base="db",
@ -78,9 +76,7 @@ class DbrandCog(commands.Cog):
)
@commands.cooldown(1, 30, commands.BucketType.channel)
async def _support(self, ctx):
await ctx.send(
"Contact dbrand support here: " + self.base_url + "contact"
)
await ctx.send("Contact dbrand support here: " + self.base_url + "contact")
@cog_ext.cog_subcommand(
base="db",
@ -130,9 +126,7 @@ class DbrandCog(commands.Cog):
)
@commands.cooldown(1, 30, commands.BucketType.channel)
async def _extort(self, ctx):
await ctx.send(
"Be (not) extorted here: " + self.base_url + "not-extortion"
)
await ctx.send("Be (not) extorted here: " + self.base_url + "not-extortion")
@cog_ext.cog_subcommand(
base="db",
@ -142,9 +136,7 @@ class DbrandCog(commands.Cog):
)
@commands.cooldown(1, 30, commands.BucketType.channel)
async def _wallpapers(self, ctx):
await ctx.send(
"Get robot camo wallpapers here: https://db.io/wallpapers"
)
await ctx.send("Get robot camo wallpapers here: https://db.io/wallpapers")
@cog_ext.cog_subcommand(
base="db",
@ -155,8 +147,7 @@ class DbrandCog(commands.Cog):
(
create_option(
name="search",
description="Country search query (2 character code, "
+ "country name, emoji)",
description="Country search query (2 character code, " + "country name, emoji)",
option_type=3,
required=True,
)
@ -174,9 +165,7 @@ class DbrandCog(commands.Cog):
):
# Magic number, subtract from flag char to get ascii char
uni2ascii = 127365
search = chr(ord(search[0]) - uni2ascii) + chr(
ord(search[1]) - uni2ascii
)
search = chr(ord(search[0]) - uni2ascii) + chr(ord(search[1]) - uni2ascii)
elif search == "🏳️":
search = "fr"
else:
@ -184,11 +173,7 @@ class DbrandCog(commands.Cog):
await ctx.send("Please use text to search for shipping.")
return
if len(search) > 2:
matches = [
x["code"]
for x in shipping_lookup
if search.lower() in x["country"]
]
matches = [x["code"] for x in shipping_lookup if search.lower() in x["country"]]
if len(matches) > 0:
search = matches[0]
dest = search.lower()
@ -202,17 +187,11 @@ class DbrandCog(commands.Cog):
data = None
self.cache[dest] = data
fields = None
if (
data is not None
and data["is_valid"]
and data["shipping_available"]
):
if data is not None and data["is_valid"] and data["shipping_available"]:
fields = []
fields.append(Field(data["short-name"], data["time-title"]))
for service in data["shipping_services_available"][1:]:
service_data = await self._session.get(
self.api_url + dest + "/" + service["url"]
)
service_data = await self._session.get(self.api_url + dest + "/" + service["url"])
if service_data.status > 400:
continue
service_data = await service_data.json()
@ -222,23 +201,12 @@ class DbrandCog(commands.Cog):
service_data["time-title"],
)
)
country = "-".join(
x for x in data["country"].split(" ") if x != "the"
)
country = "-".join(x for x in data["country"].split(" ") if x != "the")
country_urlsafe = country.replace("-", "%20")
description = (
"Click the link above to "
+ "see shipping time to {data['country']}."
)
description += (
"\n[View all shipping destinations]"
+ "(https://dbrand.com/shipping)"
)
description = "Click the link above to " + "see shipping time to {data['country']}."
description += "\n[View all shipping destinations]" + "(https://dbrand.com/shipping)"
description += " | [Check shipping status]"
description += (
"(https://dbrand.com/status"
+ f"#main-content:~:text={country_urlsafe})"
)
description += "(https://dbrand.com/status" + f"#main-content:~:text={country_urlsafe})"
embed = build_embed(
title="Shipping to {}".format(data["country"]),
description=description,

View file

@ -8,35 +8,23 @@ import ulid as ulidpy
from bson import ObjectId
from discord.ext import commands
from discord_slash import cog_ext
from discord_slash.utils.manage_commands import create_choice, create_option
from discord_slash.utils.manage_commands import create_choice
from discord_slash.utils.manage_commands import create_option
from jarvis.utils import build_embed, convert_bytesize
from jarvis.utils import build_embed
from jarvis.utils import convert_bytesize
from jarvis.utils.field import Field
supported_hashes = {
x for x in hashlib.algorithms_guaranteed if "shake" not in x
}
supported_hashes = {x for x in hashlib.algorithms_guaranteed if "shake" not in x}
OID_VERIFY = re.compile(r"^([1-9][0-9]{0,3}|0)(\.([1-9][0-9]{0,3}|0)){5,13}$")
URL_VERIFY = re.compile(
r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]"
+ r"|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+"
)
URL_VERIFY = re.compile(r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]" + r"|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+")
DN_VERIFY = re.compile(
r"^(?:(?P<cn>CN=(?P<name>[^,]*)),)"
+ r"?(?:(?P<path>(?:(?:CN|OU)=[^,]+,?)+),)"
+ r"?(?P<domain>(?:DC=[^,]+,?)+)$"
r"^(?:(?P<cn>CN=(?P<name>[^,]*)),)" + r"?(?:(?P<path>(?:(?:CN|OU)=[^,]+,?)+),)" + r"?(?P<domain>(?:DC=[^,]+,?)+)$"
)
ULID_VERIFY = re.compile(r"^[0-9a-z]{26}$", re.IGNORECASE)
UUID_VERIFY = re.compile(
(
"[a-f0-9]{8}-"
+ "[a-f0-9]{4}-"
+ "[1-5]"
+ "[a-f0-9]{3}-"
+ "[89ab][a-f0-9]{3}-"
+ "[a-f0-9]{12}$"
),
("[a-f0-9]{8}-" + "[a-f0-9]{4}-" + "[1-5]" + "[a-f0-9]{3}-" + "[89ab][a-f0-9]{3}-" + "[a-f0-9]{12}$"),
re.IGNORECASE,
)
@ -79,9 +67,7 @@ class DevCog(commands.Cog):
description="Hash method",
option_type=3,
required=True,
choices=[
create_choice(name=x, value=x) for x in supported_hashes
],
choices=[create_choice(name=x, value=x) for x in supported_hashes],
),
create_option(
name="data",
@ -111,9 +97,7 @@ class DevCog(commands.Cog):
Field("Hash", f"`{hex}`", False),
]
embed = build_embed(
title=title, description=description, fields=fields
)
embed = build_embed(title=title, description=description, fields=fields)
await ctx.send(embed=embed)
@cog_ext.cog_slash(
@ -125,9 +109,7 @@ class DevCog(commands.Cog):
description="UUID version",
option_type=3,
required=True,
choices=[
create_choice(name=x, value=x) for x in ["3", "4", "5"]
],
choices=[create_choice(name=x, value=x) for x in ["3", "4", "5"]],
),
create_option(
name="data",
@ -211,9 +193,7 @@ class DevCog(commands.Cog):
description="Encode method",
option_type=3,
required=True,
choices=[
create_choice(name=x, value=x) for x in base64_methods
],
choices=[create_choice(name=x, value=x) for x in base64_methods],
),
create_option(
name="data",
@ -237,9 +217,7 @@ class DevCog(commands.Cog):
description="Decode method",
option_type=3,
required=True,
choices=[
create_choice(name=x, value=x) for x in base64_methods
],
choices=[create_choice(name=x, value=x) for x in base64_methods],
),
create_option(
name="data",
@ -267,9 +245,7 @@ class DevCog(commands.Cog):
)
@commands.cooldown(1, 30, commands.BucketType.channel)
async def _cloc(self, ctx):
output = subprocess.check_output(
["tokei", "-C", "--sort", "code"]
).decode("UTF-8")
output = subprocess.check_output(["tokei", "-C", "--sort", "code"]).decode("UTF-8")
await ctx.send(f"```\n{output}\n```")

View file

@ -16,8 +16,7 @@ class ErrorHandlerCog(commands.Cog):
return
elif isinstance(error, commands.errors.CommandOnCooldown):
await ctx.send(
"Command on cooldown. "
+ f"Please wait {error.retry_after:0.2f}s before trying again",
"Command on cooldown. " + f"Please wait {error.retry_after:0.2f}s before trying again",
)
else:
await ctx.send(f"Error processing command:\n```{error}```")
@ -25,16 +24,13 @@ class ErrorHandlerCog(commands.Cog):
@commands.Cog.listener()
async def on_slash_command_error(self, ctx: SlashContext, error):
if isinstance(error, commands.errors.MissingPermissions) or isinstance(
error, commands.errors.CheckFailure
):
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.", hidden=True)
elif isinstance(error, commands.errors.CommandNotFound):
return
elif isinstance(error, commands.errors.CommandOnCooldown):
await ctx.send(
"Command on cooldown. "
+ f"Please wait {error.retry_after:0.2f}s before trying again",
"Command on cooldown. " + f"Please wait {error.retry_after:0.2f}s before trying again",
hidden=True,
)
else:

View file

@ -1,13 +1,16 @@
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
import gitlab
from ButtonPaginator import Paginator
from discord.ext import commands
from discord.ext.tasks import loop
from discord.utils import find
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.model import ButtonStyle
from discord_slash.utils.manage_commands import create_choice, create_option
from discord_slash.utils.manage_commands import create_choice
from discord_slash.utils.manage_commands import create_option
from jarvis.config import get_config
from jarvis.utils import build_embed
@ -21,9 +24,7 @@ class GitlabCog(CacheCog):
def __init__(self, bot):
super().__init__(bot)
config = get_config()
self._gitlab = gitlab.Gitlab(
"https://git.zevaryx.com", private_token=config.gitlab_token
)
self._gitlab = gitlab.Gitlab("https://git.zevaryx.com", private_token=config.gitlab_token)
# J.A.R.V.I.S. GitLab ID is 29
self.project = self._gitlab.projects.get(29)
@ -32,11 +33,7 @@ class GitlabCog(CacheCog):
name="issue",
description="Get an issue from GitLab",
guild_ids=guild_ids,
options=[
create_option(
name="id", description="Issue ID", option_type=4, required=True
)
],
options=[create_option(name="id", description="Issue ID", option_type=4, required=True)],
)
async def _issue(self, ctx: SlashContext, id: int):
try:
@ -50,9 +47,7 @@ class GitlabCog(CacheCog):
else:
assignee = "None"
created_at = datetime.strptime(
issue.created_at, "%Y-%m-%dT%H:%M:%S.%fZ"
).strftime("%Y-%m-%d %H:%M:%S UTC")
created_at = datetime.strptime(issue.created_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
labels = issue.labels
if labels:
@ -61,25 +56,20 @@ class GitlabCog(CacheCog):
labels = "None"
fields = [
Field(
name="State", value=issue.state[0].upper() + issue.state[1:]
),
Field(name="State", value=issue.state[0].upper() + issue.state[1:]),
Field(name="Assignee", value=assignee),
Field(name="Labels", value=labels),
]
color = self.project.labels.get(issue.labels[0]).color
fields.append(Field(name="Created At", value=created_at))
if issue.state == "closed":
closed_at = datetime.strptime(
issue.closed_at, "%Y-%m-%dT%H:%M:%S.%fZ"
).strftime("%Y-%m-%d %H:%M:%S UTC")
closed_at = datetime.strptime(issue.closed_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
fields.append(Field(name="Closed At", value=closed_at))
if issue.milestone:
fields.append(
Field(
name="Milestone",
value=f"[{issue.milestone['title']}]"
+ f"({issue.milestone['web_url']})",
value=f"[{issue.milestone['title']}]" + f"({issue.milestone['web_url']})",
inline=False,
)
)
@ -97,10 +87,7 @@ class GitlabCog(CacheCog):
icon_url=issue.author["avatar_url"],
url=issue.author["web_url"],
)
embed.set_thumbnail(
url="https://about.gitlab.com/images"
+ "/press/logo/png/gitlab-icon-rgb.png"
)
embed.set_thumbnail(url="https://about.gitlab.com/images" + "/press/logo/png/gitlab-icon-rgb.png")
await ctx.send(embed=embed)
@cog_ext.cog_subcommand(
@ -124,9 +111,7 @@ class GitlabCog(CacheCog):
await ctx.send("Milestone does not exist.", hidden=True)
return
created_at = datetime.strptime(
milestone.created_at, "%Y-%m-%dT%H:%M:%S.%fZ"
).strftime("%Y-%m-%d %H:%M:%S UTC")
created_at = datetime.strptime(milestone.created_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
fields = [
Field(
@ -139,9 +124,9 @@ class GitlabCog(CacheCog):
]
if milestone.updated_at:
updated_at = datetime.strptime(
milestone.updated_at, "%Y-%m-%dT%H:%M:%S.%fZ"
).strftime("%Y-%m-%d %H:%M:%S UTC")
updated_at = datetime.strptime(milestone.updated_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime(
"%Y-%m-%d %H:%M:%S UTC"
)
fields.append(Field(name="Updated At", value=updated_at))
if len(milestone.title) > 200:
@ -157,13 +142,9 @@ class GitlabCog(CacheCog):
embed.set_author(
name="J.A.R.V.I.S.",
url="https://git.zevaryx.com/jarvis",
icon_url="https://git.zevaryx.com/uploads/-"
+ "/system/user/avatar/11/avatar.png",
)
embed.set_thumbnail(
url="https://about.gitlab.com/images"
+ "/press/logo/png/gitlab-icon-rgb.png"
icon_url="https://git.zevaryx.com/uploads/-" + "/system/user/avatar/11/avatar.png",
)
embed.set_thumbnail(url="https://about.gitlab.com/images" + "/press/logo/png/gitlab-icon-rgb.png")
await ctx.send(embed=embed)
@cog_ext.cog_subcommand(
@ -192,9 +173,7 @@ class GitlabCog(CacheCog):
else:
assignee = "None"
created_at = datetime.strptime(
mr.created_at, "%Y-%m-%dT%H:%M:%S.%fZ"
).strftime("%Y-%m-%d %H:%M:%S UTC")
created_at = datetime.strptime(mr.created_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
labels = mr.labels
if labels:
@ -213,21 +192,16 @@ class GitlabCog(CacheCog):
color = "#00FFEE"
fields.append(Field(name="Created At", value=created_at))
if mr.state == "merged":
merged_at = datetime.strptime(
mr.merged_at, "%Y-%m-%dT%H:%M:%S.%fZ"
).strftime("%Y-%m-%d %H:%M:%S UTC")
merged_at = datetime.strptime(mr.merged_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
fields.append(Field(name="Merged At", value=merged_at))
elif mr.state == "closed":
closed_at = datetime.strptime(
mr.closed_at, "%Y-%m-%dT%H:%M:%S.%fZ"
).strftime("%Y-%m-%d %H:%M:%S UTC")
closed_at = datetime.strptime(mr.closed_at, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S UTC")
fields.append(Field(name="Closed At", value=closed_at))
if mr.milestone:
fields.append(
Field(
name="Milestone",
value=f"[{mr.milestone['title']}]"
+ f"({mr.milestone['web_url']})",
value=f"[{mr.milestone['title']}]" + f"({mr.milestone['web_url']})",
inline=False,
)
)
@ -245,10 +219,7 @@ class GitlabCog(CacheCog):
icon_url=mr.author["avatar_url"],
url=mr.author["web_url"],
)
embed.set_thumbnail(
url="https://about.gitlab.com/images"
+ "/press/logo/png/gitlab-icon-rgb.png"
)
embed.set_thumbnail(url="https://about.gitlab.com/images" + "/press/logo/png/gitlab-icon-rgb.png")
await ctx.send(embed=embed)
def build_embed_page(self, api_list: list, t_state: str, name: str):
@ -261,8 +232,7 @@ class GitlabCog(CacheCog):
fields.append(
Field(
name=f"[#{item.iid}] {item.title}",
value=item.description
+ f"\n\n[View this {name}]({item.web_url})",
value=item.description + f"\n\n[View this {name}]({item.web_url})",
inline=False,
)
)
@ -271,19 +241,14 @@ class GitlabCog(CacheCog):
title=title,
description="",
fields=fields,
url="https://git.zevaryx.com/stark-industries/j.a.r.v.i.s./"
+ f"{name.replace(' ', '_')}s",
url="https://git.zevaryx.com/stark-industries/j.a.r.v.i.s./" + f"{name.replace(' ', '_')}s",
)
embed.set_author(
name="J.A.R.V.I.S.",
url="https://git.zevaryx.com/jarvis",
icon_url="https://git.zevaryx.com/uploads/-"
+ "/system/user/avatar/11/avatar.png",
)
embed.set_thumbnail(
url="https://about.gitlab.com/images"
+ "/press/logo/png/gitlab-icon-rgb.png"
icon_url="https://git.zevaryx.com/uploads/-" + "/system/user/avatar/11/avatar.png",
)
embed.set_thumbnail(url="https://about.gitlab.com/images" + "/press/logo/png/gitlab-icon-rgb.png")
return embed
@cog_ext.cog_subcommand(
@ -310,8 +275,7 @@ class GitlabCog(CacheCog):
if exists:
await ctx.defer(hidden=True)
await ctx.send(
"Please use existing interaction: "
+ f"{exists['paginator']._message.jump_url}",
"Please use existing interaction: " + f"{exists['paginator']._message.jump_url}",
hidden=True,
)
return
@ -347,11 +311,7 @@ class GitlabCog(CacheCog):
pages = []
t_state = t_state[0].upper() + t_state[1:]
for i in range(0, len(issues), 5):
pages.append(
self.build_embed_page(
issues[i : i + 5], t_state=t_state, name="issue"
)
)
pages.append(self.build_embed_page(issues[i : i + 5], t_state=t_state, name="issue"))
paginator = Paginator(
bot=self.bot,
@ -402,8 +362,7 @@ class GitlabCog(CacheCog):
if exists:
await ctx.defer(hidden=True)
await ctx.send(
"Please use existing interaction: "
+ f"{exists['paginator']._message.jump_url}",
"Please use existing interaction: " + f"{exists['paginator']._message.jump_url}",
hidden=True,
)
return
@ -439,11 +398,7 @@ class GitlabCog(CacheCog):
pages = []
t_state = t_state[0].upper() + t_state[1:]
for i in range(0, len(merges), 5):
pages.append(
self.build_embed_page(
merges[i : i + 5], t_state=t_state, name="merge request"
)
)
pages.append(self.build_embed_page(merges[i : i + 5], t_state=t_state, name="merge request"))
paginator = Paginator(
bot=self.bot,
@ -480,8 +435,7 @@ class GitlabCog(CacheCog):
if exists:
await ctx.defer(hidden=True)
await ctx.send(
"Please use existing interaction: "
+ f"{exists['paginator']._message.jump_url}",
"Please use existing interaction: " + f"{exists['paginator']._message.jump_url}",
hidden=True,
)
return
@ -509,11 +463,7 @@ class GitlabCog(CacheCog):
pages = []
for i in range(0, len(milestones), 5):
pages.append(
self.build_embed_page(
milestones[i : i + 5], t_state=None, name="milestone"
)
)
pages.append(self.build_embed_page(milestones[i : i + 5], t_state=None, name="milestone"))
paginator = Paginator(
bot=self.bot,

View file

@ -7,7 +7,9 @@ import numpy as np
from discord import File
from discord.ext import commands
from jarvis.utils import build_embed, convert_bytesize, unconvert_bytesize
from jarvis.utils import build_embed
from jarvis.utils import convert_bytesize
from jarvis.utils import unconvert_bytesize
from jarvis.utils.field import Field
@ -21,9 +23,7 @@ class ImageCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self._session = aiohttp.ClientSession()
self.tgt_match = re.compile(
r"([0-9]*\.?[0-9]*?) ?([KMGTP]?B)", re.IGNORECASE
)
self.tgt_match = re.compile(r"([0-9]*\.?[0-9]*?) ?([KMGTP]?B)", re.IGNORECASE)
async def _resize(self, ctx, target: str, url: str = None):
if not target:
@ -32,24 +32,16 @@ class ImageCog(commands.Cog):
tgt = self.tgt_match.match(target)
if not tgt:
await ctx.send(
"Invalid target format ({}).".format(target)
+ " Expected format like 200KB"
)
await ctx.send("Invalid target format ({}).".format(target) + " Expected format like 200KB")
return
tgt_size = unconvert_bytesize(float(tgt.groups()[0]), tgt.groups()[1])
if tgt_size > unconvert_bytesize(8, "MB"):
await ctx.send(
"Target too large to send. Please make target < 8MB"
)
await ctx.send("Target too large to send. Please make target < 8MB")
return
file = None
filename = None
if (
ctx.message.attachments is not None
and len(ctx.message.attachments) > 0
):
if ctx.message.attachments is not None and len(ctx.message.attachments) > 0:
file = await ctx.message.attachments[0].read()
filename = ctx.message.attachments[0].filename
elif url is not None:
@ -69,9 +61,7 @@ class ImageCog(commands.Cog):
accuracy = 0.0
# TODO: Optimize to not run multiple times
while len(file) > tgt_size or (
len(file) <= tgt_size and accuracy < 0.65
):
while len(file) > tgt_size or (len(file) <= tgt_size and accuracy < 0.65):
old_file = file
buffer = np.frombuffer(file, dtype=np.uint8)

View file

@ -6,8 +6,8 @@ from random import randint
from discord.ext import commands
from discord_slash import cog_ext
from discord_slash import SlashContext
import jarvis
from jarvis.db.models import Joke
from jarvis.utils import build_embed
from jarvis.utils.field import Field
@ -24,7 +24,13 @@ class JokeCog(commands.Cog):
self.bot = bot
# TODO: Make this a command group with subcommands
async def _joke(self, ctx, id: str = None):
@cog_ext.cog_slash(
name="joke",
description="Hear a joke",
)
@commands.cooldown(1, 10, commands.BucketType.channel)
async def _joke(self, ctx: SlashContext, id: str = None):
"""Get a joke from the database"""
try:
if randint(1, 100_000) == 5779 and id is None:
await ctx.send(f"<@{ctx.message.author.id}>")
@ -44,20 +50,14 @@ class JokeCog(commands.Cog):
result = Joke.objects().aggregate(pipeline).next()
if result is None:
await ctx.send(
"Humor module failed. Please try again later.", hidden=True
)
await ctx.send("Humor module failed. Please try again later.", hidden=True)
return
emotes = re.findall(r"(&#x[a-fA-F0-9]*;)", result["body"])
for match in emotes:
result["body"] = result["body"].replace(
match, html.unescape(match)
)
result["body"] = result["body"].replace(match, html.unescape(match))
emotes = re.findall(r"(&#x[a-fA-F0-9]*;)", result["title"])
for match in emotes:
result["title"] = result["title"].replace(
match, html.unescape(match)
)
result["title"] = result["title"].replace(match, html.unescape(match))
body_chunks = []
body = ""
@ -105,19 +105,9 @@ class JokeCog(commands.Cog):
)
await ctx.send(embed=embed)
except Exception:
await ctx.send(
"Encountered error:\n```\n" + traceback.format_exc() + "\n```"
)
await ctx.send("Encountered error:\n```\n" + traceback.format_exc() + "\n```")
# await ctx.send(f"**{result['title']}**\n\n{result['body']}")
@cog_ext.cog_slash(
name="joke",
description="Hear a joke",
)
@commands.cooldown(1, 10, commands.BucketType.channel)
async def _joke_slash(self, ctx, id: str = None):
await self._joke(ctx, id)
def setup(bot):
bot.add_cog(JokeCog(bot))

View file

@ -1,4 +1,6 @@
from jarvis.cogs.modlog import command, member, message
from jarvis.cogs.modlog import command
from jarvis.cogs.modlog import member
from jarvis.cogs.modlog import message
def setup(bot):

View file

@ -14,18 +14,14 @@ class ModlogCommandCog(commands.Cog):
@commands.Cog.listener()
async def on_slash_command(self, ctx: SlashContext):
if not isinstance(ctx.channel, DMChannel) and ctx.name not in ["pw"]:
modlog = Setting.objects(
guild=ctx.guild.id, setting="modlog"
).first()
modlog = Setting.objects(guild=ctx.guild.id, setting="modlog").first()
if modlog:
channel = ctx.guild.get_channel(modlog.value)
fields = [
Field("Command", ctx.name),
]
if ctx.kwargs:
kwargs_string = " ".join(
f"{k}: {str(ctx.kwargs[k])}" for k in ctx.kwargs
)
kwargs_string = " ".join(f"{k}: {str(ctx.kwargs[k])}" for k in ctx.kwargs)
fields.append(
Field(
"Keyword Args",
@ -45,8 +41,5 @@ class ModlogCommandCog(commands.Cog):
name=ctx.author.name,
icon_url=ctx.author.avatar_url,
)
embed.set_footer(
text=f"{ctx.author.name}#{ctx.author.discriminator}"
+ f" | {ctx.author.id}"
)
embed.set_footer(text=f"{ctx.author.name}#{ctx.author.discriminator}" + f" | {ctx.author.id}")
await channel.send(embed=embed)

View file

@ -1,13 +1,19 @@
import asyncio
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
import discord
from discord.ext import commands
from discord.utils import find
from jarvis.cogs.modlog.utils import get_latest_log, modlog_embed
from jarvis.cogs.modlog.utils import get_latest_log
from jarvis.cogs.modlog.utils import modlog_embed
from jarvis.config import get_config
from jarvis.db.models import Ban, Kick, Mute, Setting, Unban
from jarvis.db.models import Ban
from jarvis.db.models import Kick
from jarvis.db.models import Mute
from jarvis.db.models import Setting
from jarvis.db.models import Unban
from jarvis.utils import build_embed
from jarvis.utils.field import Field
@ -243,50 +249,30 @@ class ModlogMemberCog(commands.Cog):
)
@commands.Cog.listener()
async def on_member_update(
self, before: discord.Member, after: discord.Member
):
async def on_member_update(self, before: discord.Member, after: discord.Member):
h = hash(hash(before) * hash(after))
if h not in self.cache:
self.cache.append(h)
else:
return
modlog = Setting.objects(
guild=before.guild.id, setting="modlog"
).first()
modlog = Setting.objects(guild=before.guild.id, setting="modlog").first()
if modlog:
channel = after.guild.get_channel(modlog.value)
await asyncio.sleep(0.5) # Need to wait for audit log
embed = None
mute = Setting.objects(
guild=before.guild.id, setting="mute"
).first()
verified = Setting.objects(
guild=before.guild.id, setting="verified"
).first()
mute = Setting.objects(guild=before.guild.id, setting="mute").first()
verified = Setting.objects(guild=before.guild.id, setting="verified").first()
mute_role = None
verified_role = None
if mute:
mute_role = before.guild.get_role(mute.value)
if verified:
verified_role = before.guild.get_role(verified.value)
if (
mute
and mute_role in after.roles
and mute_role not in before.roles
):
if mute and mute_role in after.roles and mute_role not in before.roles:
embed = await self.process_mute(before, after)
elif (
mute
and mute_role in before.roles
and mute_role not in after.roles
):
elif mute and mute_role in before.roles and mute_role not in after.roles:
embed = await self.process_unmute(before, after)
elif (
verified
and verified_role not in before.roles
and verified_role in after.roles
):
elif verified and verified_role not in before.roles and verified_role in after.roles:
embed = await self.process_verify(before, after)
elif before.nick != after.nick:
auditlog = await before.guild.audit_logs(
@ -301,21 +287,18 @@ class ModlogMemberCog(commands.Cog):
fields = [
Field(
name="Before",
value=f"{bname} ({before.name}"
+ f"#{before.discriminator})",
value=f"{bname} ({before.name}" + f"#{before.discriminator})",
),
Field(
name="After",
value=f"{aname} ({after.name}"
+ f"#{after.discriminator})",
value=f"{aname} ({after.name}" + f"#{after.discriminator})",
),
]
if log.user.id != before.id:
fields.append(
Field(
name="Moderator",
value=f"{log.user.mention} ({log.user.name}"
+ f"#{log.user.discriminator})",
value=f"{log.user.mention} ({log.user.name}" + f"#{log.user.discriminator})",
)
)
if log.reason:
@ -333,9 +316,7 @@ class ModlogMemberCog(commands.Cog):
name=f"{after.name}",
icon_url=after.avatar_url,
)
embed.set_footer(
text=f"{after.name}#{after.discriminator} | {after.id}"
)
embed.set_footer(text=f"{after.name}#{after.discriminator} | {after.id}")
elif len(before.roles) != len(after.roles):
# TODO: User got a new role
embed = await self.process_rolechange(before, after)

View file

@ -11,13 +11,9 @@ class ModlogMessageCog(commands.Cog):
self.bot = bot
@commands.Cog.listener()
async def on_message_edit(
self, before: discord.Message, after: discord.Message
):
async def on_message_edit(self, before: discord.Message, after: discord.Message):
if not before.author.bot:
modlog = Setting.objects(
guild=after.guild.id, setting="modlog"
).first()
modlog = Setting.objects(guild=after.guild.id, setting="modlog").first()
if modlog:
if before.content == after.content or before.content is None:
return
@ -47,26 +43,17 @@ class ModlogMessageCog(commands.Cog):
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}"
)
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):
modlog = Setting.objects(
guild=message.guild.id, setting="modlog"
).first()
modlog = Setting.objects(guild=message.guild.id, setting="modlog").first()
if modlog:
fields = [
Field("Original Message", message.content or "N/A", False)
]
fields = [Field("Original Message", message.content or "N/A", False)]
if message.attachments:
value = "\n".join(
[f"[{x.filename}]({x.url})" for x in message.attachments]
)
value = "\n".join([f"[{x.filename}]({x.url})" for x in message.attachments])
fields.append(
Field(
name="Attachments",
@ -76,9 +63,7 @@ class ModlogMessageCog(commands.Cog):
)
if message.stickers:
value = "\n".join(
[f"[{x.name}]({x.image_url})" for x in message.stickers]
)
value = "\n".join([f"[{x.name}]({x.image_url})" for x in message.stickers])
fields.append(
Field(
name="Stickers",
@ -110,8 +95,5 @@ class ModlogMessageCog(commands.Cog):
icon_url=message.author.avatar_url,
url=message.jump_url,
)
embed.set_footer(
text=f"{message.author.name}#{message.author.discriminator}"
+ f" | {message.author.id}"
)
embed.set_footer(text=f"{message.author.name}#{message.author.discriminator}" + f" | {message.author.id}")
await channel.send(embed=embed)

View file

@ -1,4 +1,5 @@
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
import discord
from discord.utils import find
@ -17,8 +18,7 @@ def modlog_embed(
fields = [
Field(
name="Moderator",
value=f"{admin.mention} ({admin.name}"
+ f"#{admin.discriminator})",
value=f"{admin.mention} ({admin.name}" + f"#{admin.discriminator})",
),
]
if log.reason:
@ -34,9 +34,7 @@ def modlog_embed(
name=f"{member.name}",
icon_url=member.avatar_url,
)
embed.set_footer(
text=f"{member.name}#{member.discriminator} | {member.id}"
)
embed.set_footer(text=f"{member.name}#{member.discriminator} | {member.id}")
return embed

View file

@ -5,7 +5,8 @@ from inspect import getsource
from time import time
import discord
from discord import DMChannel, User
from discord import DMChannel
from discord import User
from discord.ext import commands
import jarvis
@ -30,10 +31,7 @@ class OwnerCog(commands.Cog):
@user_is_bot_admin()
async def _load_cog(self, ctx, *, cog: str):
info = await self.bot.application_info()
if (
ctx.message.author == info.owner
or ctx.message.author.id in self.admins.value
):
if ctx.message.author == info.owner or ctx.message.author.id in self.admins.value:
try:
if "jarvis.cogs." not in cog:
cog = "jarvis.cogs." + cog.split(".")[-1]
@ -41,9 +39,7 @@ class OwnerCog(commands.Cog):
except commands.errors.ExtensionAlreadyLoaded:
await ctx.send(f"Cog `{cog}` already loaded")
except Exception as e:
await ctx.send(
f"Failed to load new cog `{cog}`: {type(e).name} - {e}"
)
await ctx.send(f"Failed to load new cog `{cog}`: {type(e).name} - {e}")
else:
await ctx.send(f"Successfully loaded new cog `{cog}`")
else:
@ -56,10 +52,7 @@ class OwnerCog(commands.Cog):
await ctx.send("Cannot unload `owner` cog")
return
info = await self.bot.application_info()
if (
ctx.message.author == info.owner
or ctx.message.author.id in self.admins.value
):
if ctx.message.author == info.owner or ctx.message.author.id in self.admins.value:
try:
if "jarvis.cogs." not in cog:
cog = "jarvis.cogs." + cog.split(".")[-1]
@ -67,9 +60,7 @@ class OwnerCog(commands.Cog):
except commands.errors.ExtensionNotLoaded:
await ctx.send(f"Cog `{cog}` not loaded")
except Exception as e:
await ctx.send(
f"Failed to unload cog `{cog}` {type(e).__name__} - {e}"
)
await ctx.send(f"Failed to unload cog `{cog}` {type(e).__name__} - {e}")
else:
await ctx.send(f"Successfully unloaded cog `{cog}`")
else:
@ -82,10 +73,7 @@ class OwnerCog(commands.Cog):
await ctx.send("Cannot reload `owner` cog")
return
info = await self.bot.application_info()
if (
ctx.message.author == info.owner
or ctx.message.author.id in self.admins.value
):
if ctx.message.author == info.owner or ctx.message.author.id in self.admins.value:
try:
if "jarvis.cogs." not in cog:
cog = "jarvis.cogs." + cog.split(".")[-1]
@ -95,9 +83,7 @@ class OwnerCog(commands.Cog):
pass
self.bot.unload_extension(cog)
except Exception as e:
await ctx.send(
f"Failed to reload cog `{cog}` {type(e).__name__} - {e}"
)
await ctx.send(f"Failed to reload cog `{cog}` {type(e).__name__} - {e}")
else:
await ctx.send(f"Successfully reloaded cog `{cog}`")
else:
@ -107,19 +93,13 @@ class OwnerCog(commands.Cog):
@user_is_bot_admin()
async def _system(self, ctx):
if ctx.invoked_subcommand is None:
await ctx.send(
"Usage: `system <subcommand>`\n"
+ "Subcommands: `restart`, `update`"
)
await ctx.send("Usage: `system <subcommand>`\n" + "Subcommands: `restart`, `update`")
@_system.command(name="restart", hidden=True)
@user_is_bot_admin()
async def _restart(self, ctx):
info = await self.bot.application_info()
if (
ctx.message.author == info.owner
or ctx.message.author.id in self.admins.value
):
if ctx.message.author == info.owner or ctx.message.author.id in self.admins.value:
await ctx.send("Restarting core systems...")
if isinstance(ctx.channel, discord.channel.DMChannel):
jarvis.restart_ctx = {
@ -139,10 +119,7 @@ class OwnerCog(commands.Cog):
@user_is_bot_admin()
async def _update(self, ctx):
info = await self.bot.application_info()
if (
ctx.message.author == info.owner
or ctx.message.author.id in self.admins.value
):
if ctx.message.author == info.owner or ctx.message.author.id in self.admins.value:
await ctx.send("Updating core systems...")
status = update()
if status == 0:
@ -161,9 +138,7 @@ class OwnerCog(commands.Cog):
elif status == 1:
await ctx.send("Core systems already up to date.")
elif status == 2:
await ctx.send(
"Core system update available, but core is dirty."
)
await ctx.send("Core system update available, but core is dirty.")
else:
await ctx.send("I'm afraid I can't let you do that")
@ -177,10 +152,7 @@ class OwnerCog(commands.Cog):
@commands.is_owner()
async def _admin(self, ctx):
if ctx.invoked_subcommand is None:
await ctx.send(
"Usage: `admin <subcommand>`\n"
+ "Subcommands: `add`, `remove`"
)
await ctx.send("Usage: `admin <subcommand>`\n" + "Subcommands: `add`, `remove`")
@_admin.command(name="add", hidden=True)
@commands.is_owner()
@ -191,9 +163,7 @@ class OwnerCog(commands.Cog):
self.admins.value.append(user.id)
self.admins.save()
reload_config()
await ctx.send(
f"{user.mention} is now an admin. Use this power carefully."
)
await ctx.send(f"{user.mention} is now an admin. Use this power carefully.")
@_admin.command(name="remove", hidden=True)
@commands.is_owner()
@ -210,10 +180,7 @@ class OwnerCog(commands.Cog):
if hasattr(variable, "__iter__"):
var_length = len(list(variable))
if (var_length > 100) and (not isinstance(variable, str)):
return (
f"<a {type(variable).__name__} iterable "
+ f"with more than 100 values ({var_length})>"
)
return f"<a {type(variable).__name__} iterable " + f"with more than 100 values ({var_length})>"
elif not var_length:
return f"<an empty {type(variable).__name__} iterable>"
@ -222,17 +189,11 @@ class OwnerCog(commands.Cog):
return (
variable
if (len(f"{variable}") <= 1000)
else f"<a long {type(variable).__name__} object "
+ f"with the length of {len(f'{variable}'):,}>"
else f"<a long {type(variable).__name__} object " + f"with the length of {len(f'{variable}'):,}>"
)
def prepare(self, string):
arr = (
string.strip("```")
.replace("py\n", "")
.replace("python\n", "")
.split("\n")
)
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)

View file

@ -1,20 +1,20 @@
import asyncio
import re
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
from typing import Optional
from bson import ObjectId
from discord.ext import commands
from discord.ext.tasks import loop
from discord.utils import find
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_option
from discord_slash.utils.manage_components import (
create_actionrow,
create_select,
create_select_option,
wait_for_component,
)
from discord_slash.utils.manage_components import create_actionrow
from discord_slash.utils.manage_components import create_select
from discord_slash.utils.manage_components import create_select_option
from discord_slash.utils.manage_components import wait_for_component
from jarvis.db.models import Reminder
from jarvis.utils import build_embed
@ -88,9 +88,7 @@ class RemindmeCog(CacheCog):
)
return
elif not valid.fullmatch(message):
await ctx.send(
"Hey, you should probably make this readable", hidden=True
)
await ctx.send("Hey, you should probably make this readable", hidden=True)
return
if not any([weeks, days, hours, minutes]):
@ -107,21 +105,15 @@ class RemindmeCog(CacheCog):
return
elif days and days > 6:
await ctx.send(
"Use weeks instead of 7+ days, please.", hidden=True
)
await ctx.send("Use weeks instead of 7+ days, please.", hidden=True)
return
elif hours and hours > 23:
await ctx.send(
"Use days instead of 24+ hours, please.", hidden=True
)
await ctx.send("Use days instead of 24+ hours, please.", hidden=True)
return
elif minutes and minutes > 59:
await ctx.send(
"Use hours instead of 59+ minutes, please.", hidden=True
)
await ctx.send("Use hours instead of 59+ minutes, please.", hidden=True)
return
reminders = Reminder.objects(user=ctx.author.id, active=True).count()
@ -205,8 +197,7 @@ class RemindmeCog(CacheCog):
if exists:
await ctx.defer(hidden=True)
await ctx.send(
"Please use existing interaction: "
+ f"{exists['paginator']._message.jump_url}",
"Please use existing interaction: " + f"{exists['paginator']._message.jump_url}",
hidden=True,
)
return
@ -263,18 +254,14 @@ class RemindmeCog(CacheCog):
timeout=60 * 5,
)
for to_delete in context.selected_options:
_ = Reminder.objects(
user=ctx.author.id, id=ObjectId(to_delete)
).delete()
_ = Reminder.objects(user=ctx.author.id, id=ObjectId(to_delete)).delete()
for row in components:
for component in row["components"]:
component["disabled"] = True
fields = []
for reminder in filter(
lambda x: str(x._id) in context.selected_options, reminders
):
for reminder in filter(lambda x: str(x._id) in context.selected_options, reminders):
fields.append(
Field(
name=reminder.remind_at.strftime("%Y-%m-%d %H:%M UTC"),
@ -307,9 +294,7 @@ class RemindmeCog(CacheCog):
@loop(seconds=15)
async def _remind(self):
reminders = Reminder.objects(
remind_at__lte=datetime.utcnow() + timedelta(seconds=30)
)
reminders = Reminder.objects(remind_at__lte=datetime.utcnow() + timedelta(seconds=30))
for reminder in reminders:
if reminder.remind_at <= datetime.utcnow():
user = await self.bot.fetch_user(reminder.user)
@ -330,9 +315,7 @@ class RemindmeCog(CacheCog):
await user.send(embed=embed)
except:
guild = self.bot.fetch_guild(reminder.guild)
channel = (
guild.get_channel(reminder.channel) if guild else None
)
channel = guild.get_channel(reminder.channel) if guild else None
if channel:
await channel.send(f"{user.mention}", embed=embed)
finally:

View file

@ -1,6 +1,7 @@
from discord import Role
from discord.ext import commands
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_option
from jarvis.db.models import Setting
@ -28,17 +29,13 @@ class RolegiverCog(commands.Cog):
)
@admin_or_permissions(manage_guild=True)
async def _rolegiver_add(self, ctx: SlashContext, role: Role):
setting = Setting.objects(
guild=ctx.guild.id, setting="rolegiver"
).first()
setting = Setting.objects(guild=ctx.guild.id, setting="rolegiver").first()
if setting and role.id in setting.value:
await ctx.send("Role already in rolegiver", hidden=True)
return
if not setting:
setting = Setting(
guild=ctx.guild.id, setting="rolegiver", value=[]
)
setting = Setting(guild=ctx.guild.id, setting="rolegiver", value=[])
roles = []
for role_id in setting.value:
@ -67,10 +64,7 @@ class RolegiverCog(commands.Cog):
icon_url=ctx.author.avatar_url,
)
embed.set_footer(
text=f"{ctx.author.name}#{ctx.author.discriminator} "
+ f"| {ctx.author.id}"
)
embed.set_footer(text=f"{ctx.author.name}#{ctx.author.discriminator} " + f"| {ctx.author.id}")
await ctx.send(embed=embed)
@ -89,9 +83,7 @@ class RolegiverCog(commands.Cog):
)
@admin_or_permissions(manage_guild=True)
async def _rolegiver_remove(self, ctx: SlashContext, role: Role):
setting = Setting.objects(
guild=ctx.guild.id, setting="rolegiver"
).first()
setting = Setting.objects(guild=ctx.guild.id, setting="rolegiver").first()
if not setting or (setting and not setting.value):
await ctx.send("Rolegiver has no roles", hidden=True)
return
@ -128,10 +120,7 @@ class RolegiverCog(commands.Cog):
icon_url=ctx.author.avatar_url,
)
embed.set_footer(
text=f"{ctx.author.name}#{ctx.author.discriminator} "
+ f"| {ctx.author.id}"
)
embed.set_footer(text=f"{ctx.author.name}#{ctx.author.discriminator} " + f"| {ctx.author.id}")
await ctx.send(embed=embed)
@ -141,9 +130,7 @@ class RolegiverCog(commands.Cog):
description="List roles rolegiver",
)
async def _rolegiver_list(self, ctx: SlashContext):
setting = Setting.objects(
guild=ctx.guild.id, setting="rolegiver"
).first()
setting = Setting.objects(guild=ctx.guild.id, setting="rolegiver").first()
if not setting or (setting and not setting.value):
await ctx.send("Rolegiver has no roles", hidden=True)
return
@ -170,10 +157,7 @@ class RolegiverCog(commands.Cog):
icon_url=ctx.author.avatar_url,
)
embed.set_footer(
text=f"{ctx.author.name}#{ctx.author.discriminator} "
+ f"| {ctx.author.id}"
)
embed.set_footer(text=f"{ctx.author.name}#{ctx.author.discriminator} " + f"| {ctx.author.id}")
await ctx.send(embed=embed)
@ -192,9 +176,7 @@ class RolegiverCog(commands.Cog):
)
@commands.cooldown(1, 10, commands.BucketType.user)
async def _role_get(self, ctx: SlashContext, role: Role):
setting = Setting.objects(
guild=ctx.guild.id, setting="rolegiver"
).first()
setting = Setting.objects(guild=ctx.guild.id, setting="rolegiver").first()
if not setting or (setting and not setting.value):
await ctx.send("Rolegiver has no roles", hidden=True)
return
@ -230,10 +212,7 @@ class RolegiverCog(commands.Cog):
icon_url=ctx.author.avatar_url,
)
embed.set_footer(
text=f"{ctx.author.name}#{ctx.author.discriminator} "
+ f"| {ctx.author.id}"
)
embed.set_footer(text=f"{ctx.author.name}#{ctx.author.discriminator} " + f"| {ctx.author.id}")
await ctx.send(embed=embed)
@ -252,9 +231,7 @@ class RolegiverCog(commands.Cog):
)
@commands.cooldown(1, 10, commands.BucketType.user)
async def _role_forfeit(self, ctx: SlashContext, role: Role):
setting = Setting.objects(
guild=ctx.guild.id, setting="rolegiver"
).first()
setting = Setting.objects(guild=ctx.guild.id, setting="rolegiver").first()
if not setting or (setting and not setting.value):
await ctx.send("Rolegiver has no roles", hidden=True)
return
@ -290,10 +267,7 @@ class RolegiverCog(commands.Cog):
icon_url=ctx.author.avatar_url,
)
embed.set_footer(
text=f"{ctx.author.name}#{ctx.author.discriminator} "
+ f"| {ctx.author.id}"
)
embed.set_footer(text=f"{ctx.author.name}#{ctx.author.discriminator} " + f"| {ctx.author.id}")
await ctx.send(embed=embed)

View file

@ -1,7 +1,9 @@
from discord import Role, TextChannel
from discord import Role
from discord import TextChannel
from discord.ext import commands
from discord.utils import find
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_option
from jarvis.db.models import Setting
@ -67,9 +69,7 @@ class SettingsCog(commands.Cog):
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}"
)
await ctx.send(f"Settings applied. New modlog channel is {channel.mention}")
@cog_ext.cog_subcommand(
base="settings",
@ -91,9 +91,7 @@ class SettingsCog(commands.Cog):
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}"
)
await ctx.send(f"Settings applied. New userlog channel is {channel.mention}")
@cog_ext.cog_subcommand(
base="settings",
@ -153,9 +151,7 @@ class SettingsCog(commands.Cog):
async def _set_unverified(self, ctx, role: Role):
await ctx.defer()
self.update_settings("unverified", role.id, ctx.guild.id)
await ctx.send(
f"Settings applied. New unverified role is `{role.name}`"
)
await ctx.send(f"Settings applied. New unverified role is `{role.name}`")
@cog_ext.cog_subcommand(
base="settings",
@ -228,9 +224,7 @@ class SettingsCog(commands.Cog):
self.delete_settings("unverified", ctx.guild.id)
await ctx.send("Setting removed.")
@cog_ext.cog_subcommand(
base="settings", name="view", description="View settings"
)
@cog_ext.cog_subcommand(base="settings", name="view", description="View settings")
@admin_or_permissions(manage_guild=True)
async def _view(self, ctx: SlashContext):
settings = Setting.objects(guild=ctx.guild.id)
@ -260,15 +254,11 @@ class SettingsCog(commands.Cog):
value += "\n||`[redacted]`||"
fields.append(Field(name=setting.setting, value=value or "N/A"))
embed = build_embed(
title="Current Settings", description="", fields=fields
)
embed = build_embed(title="Current Settings", description="", fields=fields)
await ctx.send(embed=embed)
@cog_ext.cog_subcommand(
base="settings", name="clear", description="Clear all settings"
)
@cog_ext.cog_subcommand(base="settings", name="clear", description="Clear all settings")
@admin_or_permissions(manage_guild=True)
async def _clear(self, ctx: SlashContext):
deleted = Setting.objects(guild=ctx.guild.id).delete()

View file

@ -1,16 +1,16 @@
from discord import TextChannel
from discord.ext import commands
from discord.utils import find
from discord_slash import SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_option
from discord_slash.utils.manage_components import (
create_actionrow,
create_select,
create_select_option,
wait_for_component,
)
from discord_slash.utils.manage_components import create_actionrow
from discord_slash.utils.manage_components import create_select
from discord_slash.utils.manage_components import create_select_option
from discord_slash.utils.manage_components import wait_for_component
from jarvis.db.models import Star, Starboard
from jarvis.db.models import Star
from jarvis.db.models import Starboard
from jarvis.utils import build_embed
from jarvis.utils.permissions import admin_or_permissions
@ -68,13 +68,9 @@ class StarboardCog(commands.Cog):
await ctx.send("Channel must be a TextChannel", hidden=True)
return
exists = Starboard.objects(
channel=channel.id, guild=ctx.guild.id
).first()
exists = Starboard.objects(channel=channel.id, guild=ctx.guild.id).first()
if exists:
await ctx.send(
f"Starboard already exists at {channel.mention}.", hidden=True
)
await ctx.send(f"Starboard already exists at {channel.mention}.", hidden=True)
return
count = Starboard.objects(guild=ctx.guild.id).count()
@ -87,9 +83,7 @@ class StarboardCog(commands.Cog):
channel=channel.id,
admin=ctx.author.id,
).save()
await ctx.send(
f"Starboard created. Check it out at {channel.mention}."
)
await ctx.send(f"Starboard created. Check it out at {channel.mention}.")
@cog_ext.cog_subcommand(
base="starboard",
@ -106,18 +100,12 @@ class StarboardCog(commands.Cog):
)
@admin_or_permissions(manage_guild=True)
async def _delete(self, ctx, channel: TextChannel):
deleted = Starboard.objects(
channel=channel.id, guild=ctx.guild.id
).delete()
deleted = Starboard.objects(channel=channel.id, guild=ctx.guild.id).delete()
if deleted:
_ = Star.objects(starboard=channel.id).delete()
await ctx.send(
f"Starboard deleted from {channel.mention}.", hidden=True
)
await ctx.send(f"Starboard deleted from {channel.mention}.", hidden=True)
else:
await ctx.send(
f"Starboard not found in {channel.mention}.", hidden=True
)
await ctx.send(f"Starboard not found in {channel.mention}.", hidden=True)
@cog_ext.cog_subcommand(
base="star",
@ -132,8 +120,7 @@ class StarboardCog(commands.Cog):
),
create_option(
name="channel",
description="Channel that has the message, "
+ "required if different than command message",
description="Channel that has the message, " + "required if different than command message",
option_type=7,
required=False,
),
@ -156,14 +143,9 @@ class StarboardCog(commands.Cog):
await ctx.defer()
channel_list = []
for starboard in starboards:
channel_list.append(
find(lambda x: x.id == starboard.channel, ctx.guild.channels)
)
channel_list.append(find(lambda x: x.id == starboard.channel, ctx.guild.channels))
select_channels = [
create_select_option(label=x.name, value=str(idx))
for idx, x in enumerate(channel_list)
]
select_channels = [create_select_option(label=x.name, value=str(idx)) for idx, x in enumerate(channel_list)]
select = create_select(
options=select_channels,
@ -173,9 +155,7 @@ class StarboardCog(commands.Cog):
components = [create_actionrow(select)]
msg = await ctx.send(
content="Choose a starboard", components=components
)
msg = await ctx.send(content="Choose a starboard", components=components)
com_ctx = await wait_for_component(
self.bot,
@ -205,9 +185,7 @@ class StarboardCog(commands.Cog):
)
return
count = Star.objects(
guild=message.guild.id, starboard=starboard.id
).count()
count = Star.objects(guild=message.guild.id, starboard=starboard.id).count()
content = message.content
attachments = message.attachments
@ -232,9 +210,7 @@ class StarboardCog(commands.Cog):
url=message.jump_url,
icon_url=message.author.avatar_url,
)
embed.set_footer(
text=message.guild.name + " | " + message.channel.name
)
embed.set_footer(text=message.guild.name + " | " + message.channel.name)
if image_url:
embed.set_image(url=image_url)
@ -254,8 +230,7 @@ class StarboardCog(commands.Cog):
components[0]["components"][0]["disabled"] = True
await com_ctx.edit_origin(
content="Message saved to Starboard.\n"
+ f"See it in {starboard.mention}",
content="Message saved to Starboard.\n" + f"See it in {starboard.mention}",
components=components,
)
@ -288,13 +263,10 @@ class StarboardCog(commands.Cog):
if not isinstance(starboard, TextChannel):
await ctx.send("Channel must be a TextChannel", hidden=True)
return
exists = Starboard.objects(
channel=starboard.id, guild=ctx.guild.id
).first()
exists = Starboard.objects(channel=starboard.id, guild=ctx.guild.id).first()
if not exists:
await ctx.send(
f"Starboard does not exist in {starboard.mention}. "
+ "Please create it first",
f"Starboard does not exist in {starboard.mention}. " + "Please create it first",
hidden=True,
)
return

View file

@ -3,17 +3,28 @@ import secrets
import string
from io import BytesIO
from discord import File, Guild, Role, User
from discord import File
from discord import Guild
from discord import Role
from discord import User
from discord.ext import commands
from discord_slash import SlashContext, cog_ext
from discord_slash.utils.manage_commands import create_choice, create_option
from PIL import Image, ImageDraw
from discord_slash import cog_ext
from discord_slash import SlashContext
from discord_slash.utils.manage_commands import create_choice
from discord_slash.utils.manage_commands import create_option
from PIL import Image
from PIL import ImageDraw
import jarvis
from jarvis import jarvis_self, logo
from jarvis import jarvis_self
from jarvis import logo
from jarvis.config import get_config
from jarvis.data.robotcamo import emotes, hk, names
from jarvis.utils import build_embed, convert_bytesize, get_repo_hash
from jarvis.data.robotcamo import emotes
from jarvis.data.robotcamo import hk
from jarvis.data.robotcamo import names
from jarvis.utils import build_embed
from jarvis.utils import convert_bytesize
from jarvis.utils import get_repo_hash
from jarvis.utils.field import Field
@ -49,9 +60,7 @@ class UtilCog(commands.Cog):
fields.append(Field("PID", jarvis_self.pid))
fields.append(Field("Version", jarvis.__version__, False))
fields.append(Field("Git Hash", get_repo_hash(), False))
embed = build_embed(
title=title, description=desc, fields=fields, color=color
)
embed = build_embed(title=title, description=desc, fields=fields, color=color)
await ctx.send(embed=embed)
@cog_ext.cog_slash(
@ -81,9 +90,7 @@ 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.upper()
):
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():
@ -118,13 +125,9 @@ class UtilCog(commands.Cog):
user = ctx.author
avatar = user.avatar_url
embed = build_embed(
title="Avatar", description="", fields=[], color="#00FFEE"
)
embed = build_embed(title="Avatar", description="", fields=[], color="#00FFEE")
embed.set_image(url=avatar)
embed.set_author(
name=f"{user.name}#{user.discriminator}", icon_url=avatar
)
embed.set_author(name=f"{user.name}#{user.discriminator}", icon_url=avatar)
await ctx.send(embed=embed)
@cog_ext.cog_slash(
@ -148,9 +151,7 @@ class UtilCog(commands.Cog):
Field(name="Mention", value=f"`{role.mention}`"),
Field(name="Hoisted", value="Yes" if role.hoist else "No"),
Field(name="Position", value=str(role.position)),
Field(
name="Mentionable", value="Yes" if role.mentionable else "No"
),
Field(name="Mentionable", value="Yes" if role.mentionable else "No"),
]
embed = build_embed(
@ -210,9 +211,7 @@ class UtilCog(commands.Cog):
),
Field(
name=f"Roles [{len(user_roles)}]",
value=" ".join([x.mention for x in user_roles])
if user_roles
else "None",
value=" ".join([x.mention for x in user_roles]) if user_roles else "None",
inline=False,
),
]
@ -224,9 +223,7 @@ class UtilCog(commands.Cog):
color=str(user_roles[0].color) if user_roles else "#FF0000",
)
embed.set_author(
name=f"{user.name}#{user.discriminator}", icon_url=user.avatar_url
)
embed.set_author(name=f"{user.name}#{user.discriminator}", icon_url=user.avatar_url)
embed.set_thumbnail(url=user.avatar_url)
embed.set_footer(text=f"ID: {user.id}")
@ -236,11 +233,7 @@ class UtilCog(commands.Cog):
async def _server_info(self, ctx: SlashContext):
guild: Guild = ctx.guild
owner = (
f"{guild.owner.name}#{guild.owner.discriminator}"
if guild.owner
else "||`[redacted]`||"
)
owner = f"{guild.owner.name}#{guild.owner.discriminator}" if guild.owner else "||`[redacted]`||"
region = guild.region
categories = len(guild.categories)
@ -260,13 +253,9 @@ class UtilCog(commands.Cog):
Field(name="Roles", value=roles),
]
if len(role_list) < 1024:
fields.append(
Field(name="Role List", value=role_list, inline=False)
)
fields.append(Field(name="Role List", value=role_list, inline=False))
embed = build_embed(
title="", description="", fields=fields, timestamp=guild.created_at
)
embed = build_embed(title="", description="", fields=fields, timestamp=guild.created_at)
embed.set_author(name=guild.name, icon_url=guild.icon_url)
embed.set_thumbnail(url=guild.icon_url)
@ -302,13 +291,9 @@ class UtilCog(commands.Cog):
],
)
@commands.cooldown(1, 15, type=commands.BucketType.user)
async def _pw_gen(
self, ctx: SlashContext, length: int = 32, chars: int = 3
):
async def _pw_gen(self, ctx: SlashContext, length: int = 32, chars: int = 3):
if length > 256:
await ctx.send(
"Please limit password to 256 characters", hidden=True
)
await ctx.send("Please limit password to 256 characters", hidden=True)
return
choices = [
string.ascii_letters,

View file

@ -1,7 +1,9 @@
from random import randint
from discord.ext import commands
from discord_slash import ComponentContext, SlashContext, cog_ext
from discord_slash import cog_ext
from discord_slash import ComponentContext
from discord_slash import SlashContext
from discord_slash.model import ButtonStyle
from discord_slash.utils import manage_components
@ -39,17 +41,14 @@ class VerifyCog(commands.Cog):
await ctx.defer()
role = Setting.objects(guild=ctx.guild.id, setting="verified").first()
if not role:
await ctx.send(
"This guild has not enabled verification", delete_after=5
)
await ctx.send("This guild has not enabled verification", delete_after=5)
return
if ctx.guild.get_role(role.value) in ctx.author.roles:
await ctx.send("You are already verified.", delete_after=5)
return
components = create_layout()
message = await ctx.send(
content=f"{ctx.author.mention}, "
+ "please press the button that says `YES`.",
content=f"{ctx.author.mention}, " + "please press the button that says `YES`.",
components=components,
)
await message.delete(delay=15)
@ -68,31 +67,21 @@ class VerifyCog(commands.Cog):
for c in components:
for c2 in c["components"]:
c2["disabled"] = True
setting = Setting.objects(
guild=ctx.guild.id, setting="verified"
).first()
setting = Setting.objects(guild=ctx.guild.id, setting="verified").first()
role = ctx.guild.get_role(setting.value)
await ctx.author.add_roles(role, reason="Verification passed")
setting = Setting.objects(
guild=ctx.guild.id, setting="unverified"
).first()
setting = Setting.objects(guild=ctx.guild.id, setting="unverified").first()
if setting:
role = ctx.guild.get_role(setting.value)
await ctx.author.remove_roles(
role, reason="Verification passed"
)
await ctx.author.remove_roles(role, reason="Verification passed")
await ctx.edit_origin(
content=f"Welcome, {ctx.author.mention}. "
+ "Please enjoy your stay.",
components=manage_components.spread_to_rows(
*components, max_in_row=5
),
content=f"Welcome, {ctx.author.mention}. " + "Please enjoy your stay.",
components=manage_components.spread_to_rows(*components, max_in_row=5),
)
await ctx.origin_message.delete(delay=5)
else:
await ctx.edit_origin(
content=f"{ctx.author.mention}, incorrect. "
+ "Please press the button that says `YES`",
content=f"{ctx.author.mention}, incorrect. " + "Please press the button that says `YES`",
)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,16 +1,14 @@
from datetime import datetime
from mongoengine import Document
from mongoengine.fields import (
BooleanField,
DateTimeField,
DictField,
DynamicField,
IntField,
ListField,
LongField,
StringField,
)
from mongoengine.fields import BooleanField
from mongoengine.fields import DateTimeField
from mongoengine.fields import DictField
from mongoengine.fields import DynamicField
from mongoengine.fields import IntField
from mongoengine.fields import ListField
from mongoengine.fields import LongField
from mongoengine.fields import StringField
class SnowflakeField(LongField):

View file

@ -21,9 +21,7 @@ class GuildEventHandler(object):
+ "24 hours a day, seven days a week."
)
await asyncio.sleep(1)
await general.send(
"Importing all preferences from home interface..."
)
await general.send("Importing all preferences from home interface...")
# Set some default settings
_ = Setting(guild=guild.id, setting="massmention", value=5).save()

View file

@ -1,6 +1,7 @@
from discord import Member
from jarvis.db.models import Mute, Setting
from jarvis.db.models import Mute
from jarvis.db.models import Setting
class MemberEventHandler(object):
@ -14,15 +15,9 @@ class MemberEventHandler(object):
if mute:
mute_role = Setting.objects(guild=guild.id, setting="mute").first()
role = guild.get_role(mute_role.value)
await user.add_roles(
role, reason="User is still muted from prior mute"
)
unverified = Setting.objects(
guild=guild.id, setting="unverified"
).first()
await user.add_roles(role, reason="User is still muted from prior mute")
unverified = Setting.objects(guild=guild.id, setting="unverified").first()
if unverified:
role = guild.get_role(unverified.value)
if role not in user.roles:
await user.add_roles(
role, reason="User just joined and is unverified"
)
await user.add_roles(role, reason="User just joined and is unverified")

View file

@ -1,10 +1,15 @@
import re
from discord import DMChannel, Message
from discord import DMChannel
from discord import Message
from discord.utils import find
from jarvis.config import get_config
from jarvis.db.models import Autopurge, Autoreact, Roleping, Setting, Warning
from jarvis.db.models import Autopurge
from jarvis.db.models import Autoreact
from jarvis.db.models import Roleping
from jarvis.db.models import Setting
from jarvis.db.models import Warning
from jarvis.utils import build_embed
from jarvis.utils.field import Field
@ -21,9 +26,7 @@ class MessageEventHandler(object):
self.bot.add_listener(self.on_message_edit)
async def autopurge(self, message: Message):
autopurge = Autopurge.objects(
guild=message.guild.id, channel=message.channel.id
).first()
autopurge = Autopurge.objects(guild=message.guild.id, channel=message.channel.id).first()
if autopurge:
await message.delete(delay=autopurge.delay)
@ -38,13 +41,10 @@ class MessageEventHandler(object):
async def checks(self, message: Message):
# #tech
channel = find(
lambda x: x.id == 599068193339736096, message.channel_mentions
)
channel = find(lambda x: x.id == 599068193339736096, message.channel_mentions)
if channel and message.author.id == 293795462752894976:
await channel.send(
content="https://cdn.discordapp.com/attachments/"
+ "664621130044407838/805218508866453554/tech.gif"
content="https://cdn.discordapp.com/attachments/" + "664621130044407838/805218508866453554/tech.gif"
)
content = re.sub(r"\s+", "", message.content)
match = invites.search(content)
@ -78,15 +78,11 @@ class MessageEventHandler(object):
fields=fields,
)
embed.set_author(
name=message.author.nick
if message.author.nick
else message.author.name,
name=message.author.nick if message.author.nick else message.author.name,
icon_url=message.author.avatar_url,
)
embed.set_footer(
text=f"{message.author.name}#"
+ f"{message.author.discriminator} "
+ f"| {message.author.id}"
text=f"{message.author.name}#" + f"{message.author.discriminator} " + f"| {message.author.id}"
)
await message.channel.send(embed=embed)
@ -98,9 +94,7 @@ class MessageEventHandler(object):
if (
massmention
and massmention.value > 0
and len(message.mentions)
- (1 if message.author in message.mentions else 0)
> massmention.value
and len(message.mentions) - (1 if message.author in message.mentions else 0) > massmention.value
):
_ = Warning(
active=True,
@ -117,15 +111,10 @@ class MessageEventHandler(object):
fields=fields,
)
embed.set_author(
name=message.author.nick
if message.author.nick
else message.author.name,
name=message.author.nick if message.author.nick else message.author.name,
icon_url=message.author.avatar_url,
)
embed.set_footer(
text=f"{message.author.name}#{message.author.discriminator} "
+ f"| {message.author.id}"
)
embed.set_footer(text=f"{message.author.name}#{message.author.discriminator} " + f"| {message.author.id}")
await message.channel.send(embed=embed)
async def roleping(self, message: Message):
@ -152,9 +141,7 @@ class MessageEventHandler(object):
role_in_rolepings = list(filter(lambda x: x in roleping_ids, roles))
# Check if the user has the role, so they are allowed to ping it
user_missing_role = any(
x.id not in roleping_ids for x in message.author.roles
)
user_missing_role = any(x.id not in roleping_ids for x in message.author.roles)
# Admins can ping whoever
user_is_admin = message.author.guild_permissions.administrator
@ -165,19 +152,11 @@ class MessageEventHandler(object):
if message.author.id in roleping.bypass["users"]:
user_has_bypass = True
break
if any(
role.id in roleping.bypass["roles"]
for role in message.author.roles
):
if any(role.id in roleping.bypass["roles"] for role in message.author.roles):
user_has_bypass = True
break
if (
role_in_rolepings
and user_missing_role
and not user_is_admin
and not user_has_bypass
):
if role_in_rolepings and user_missing_role and not user_is_admin and not user_has_bypass:
_ = Warning(
active=True,
admin=get_config().client_id,
@ -199,22 +178,14 @@ class MessageEventHandler(object):
fields=fields,
)
embed.set_author(
name=message.author.nick
if message.author.nick
else message.author.name,
name=message.author.nick if message.author.nick else message.author.name,
icon_url=message.author.avatar_url,
)
embed.set_footer(
text=f"{message.author.name}#{message.author.discriminator} "
+ f"| {message.author.id}"
)
embed.set_footer(text=f"{message.author.name}#{message.author.discriminator} " + f"| {message.author.id}")
await message.channel.send(embed=embed)
async def on_message(self, message: Message):
if (
not isinstance(message.channel, DMChannel)
and not message.author.bot
):
if not isinstance(message.channel, DMChannel) and not message.author.bot:
await self.autoreact(message)
await self.massmention(message)
await self.roleping(message)

View file

@ -1,4 +1,7 @@
from jarvis.tasks import unban, unlock, unmute, unwarn
from jarvis.tasks import unban
from jarvis.tasks import unlock
from jarvis.tasks import unmute
from jarvis.tasks import unwarn
def init():

View file

@ -1,10 +1,12 @@
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
from discord.ext.tasks import loop
import jarvis
from jarvis.config import get_config
from jarvis.db.models import Ban, Unban
from jarvis.db.models import Ban
from jarvis.db.models import Unban
jarvis_id = get_config().client_id
@ -14,9 +16,7 @@ async def unban():
bans = Ban.objects(type="temp", active=True)
unbans = []
for ban in bans:
if ban.created_at + timedelta(
hours=ban.duration
) < datetime.utcnow() + timedelta(minutes=10):
if ban.created_at + timedelta(hours=ban.duration) < datetime.utcnow() + timedelta(minutes=10):
guild = await jarvis.jarvis.fetch_guild(ban.guild)
user = await jarvis.jarvis.fetch_user(ban.user)
if user:

View file

@ -1,4 +1,5 @@
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
from discord.ext.tasks import loop
@ -10,10 +11,7 @@ from jarvis.db.models import Lock
async def unlock():
locks = Lock.objects(active=True)
for lock in locks:
if (
lock.created_at + timedelta(minutes=lock.duration)
< datetime.utcnow()
):
if lock.created_at + timedelta(minutes=lock.duration) < datetime.utcnow():
guild = await jarvis.jarvis.fetch_guild(lock.guild)
channel = await jarvis.jarvis.fetch_channel(lock.channel)
if channel:
@ -21,8 +19,6 @@ async def unlock():
for role in roles:
overrides = channel.overwrites_for(role)
overrides.send_messages = None
await channel.set_permissions(
role, overwrite=overrides, reason="Lock expired"
)
await channel.set_permissions(role, overwrite=overrides, reason="Lock expired")
lock.active = False
lock.save()

View file

@ -1,9 +1,11 @@
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
from discord.ext.tasks import loop
import jarvis
from jarvis.db.models import Mute, Setting
from jarvis.db.models import Mute
from jarvis.db.models import Setting
@loop(minutes=1)
@ -11,13 +13,8 @@ async def unmute():
mutes = Mute.objects(duration__gt=0, active=True)
mute_roles = Setting.objects(setting="mute")
for mute in mutes:
if (
mute.created_at + timedelta(minutes=mute.duration)
< datetime.utcnow()
):
mute_role = [x.value for x in mute_roles if x.guild == mute.guild][
0
]
if mute.created_at + timedelta(minutes=mute.duration) < datetime.utcnow():
mute_role = [x.value for x in mute_roles if x.guild == mute.guild][0]
guild = await jarvis.jarvis.fetch_guild(mute.guild)
role = guild.get_role(mute_role)
user = await guild.fetch_member(mute.user)

View file

@ -1,4 +1,5 @@
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
from discord.ext.tasks import loop
@ -10,9 +11,6 @@ from jarvis.db.models import Warning
async def unwarn():
warns = Warning.objects(active=True)
for warn in warns:
if (
warn.created_at + timedelta(hours=warn.duration)
< datetime.utcnow()
):
if warn.created_at + timedelta(hours=warn.duration) < datetime.utcnow():
warn.active = False
warn.save()

View file

@ -2,7 +2,8 @@ from datetime import datetime
from pkgutil import iter_modules
import git
from discord import Color, Embed
from discord import Color
from discord import Embed
from discord.ext import commands
import jarvis.cogs

View file

@ -1,4 +1,5 @@
from datetime import datetime, timedelta
from datetime import datetime
from datetime import timedelta
from discord.ext import commands
from discord.ext.tasks import loop
@ -27,7 +28,5 @@ class CacheCog(commands.Cog):
async def _expire_interaction(self):
keys = list(self.cache.keys())
for key in keys:
if self.cache[key]["timeout"] <= datetime.utcnow() + timedelta(
minutes=1
):
if self.cache[key]["timeout"] <= datetime.utcnow() + timedelta(minutes=1):
del self.cache[key]

View file

@ -17,8 +17,6 @@ def admin_or_permissions(**perms):
original = commands.has_permissions(**perms).predicate
async def extended_check(ctx):
return await commands.has_permissions(administrator=True).predicate(
ctx
) or await original(ctx)
return await commands.has_permissions(administrator=True).predicate(ctx) or await original(ctx)
return commands.check(extended_check)

View file

@ -1,12 +1,12 @@
discord-py>=1.7, <2
psutil>=5.8, <6
GitPython>=3.1, <4
PyYaml>=5.4, <6
discord-py-slash-command>=2.3.2, <3
pymongo>=3.12.0, <4
opencv-python>=4.5, <5
ButtonPaginator>=0.0.3
Pillow>=8.2.0, <9
python-gitlab>=2.9.0, <3
ulid-py>=1.1.0, <2
discord-py>=1.7, <2
discord-py-slash-command>=2.3.2, <3
GitPython>=3.1, <4
mongoengine>=0.23, <1
opencv-python>=4.5, <5
Pillow>=8.2.0, <9
psutil>=5.8, <6
pymongo>=3.12.0, <4
python-gitlab>=2.9.0, <3
PyYaml>=5.4, <6
ulid-py>=1.1.0, <2

4
run.py
View file

@ -1,6 +1,8 @@
#!/bin/python3
from importlib import reload as ireload
from multiprocessing import Process, Value, freeze_support
from multiprocessing import freeze_support
from multiprocessing import Process
from multiprocessing import Value
from pathlib import Path
from time import sleep