198 lines
6.4 KiB
Python
198 lines
6.4 KiB
Python
import asyncio
|
|
from datetime import datetime, timedelta
|
|
from pathlib import Path
|
|
|
|
import pymongo
|
|
from discord import DMChannel, Intents, Member, Message
|
|
from discord.ext import commands
|
|
from discord.ext.tasks import loop
|
|
from discord.utils import find, get
|
|
from discord_slash import SlashCommand
|
|
from psutil import Process
|
|
|
|
from jarvis import logo, utils
|
|
from jarvis.config import get_config
|
|
from jarvis.utils.db import DBManager
|
|
|
|
if asyncio.get_event_loop().is_closed():
|
|
asyncio.set_event_loop(asyncio.new_event_loop())
|
|
|
|
intents = Intents.default()
|
|
intents.members = True
|
|
restart_ctx = None
|
|
|
|
|
|
jarvis = commands.Bot(command_prefix=utils.get_prefix, intents=intents)
|
|
slash = SlashCommand(jarvis, sync_commands=True, sync_on_cog_reload=True)
|
|
jarvis_self = Process()
|
|
__version__ = "0.6.0"
|
|
|
|
|
|
@jarvis.event
|
|
async def on_ready():
|
|
global restart_ctx
|
|
print(" Logged in as {0.user}".format(jarvis))
|
|
print(" Connected to {} guild(s)".format(len(jarvis.guilds)))
|
|
with jarvis_self.oneshot():
|
|
print(f" Current PID: {jarvis_self.pid}")
|
|
Path(f"jarvis.{jarvis_self.pid}.pid").touch()
|
|
if restart_ctx:
|
|
channel = None
|
|
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
|
|
)
|
|
elif "user" in restart_ctx:
|
|
channel = jarvis.get_user(restart_ctx["user"])
|
|
if channel:
|
|
await channel.send("Core systems restarted and back online.")
|
|
restart_ctx = None
|
|
|
|
|
|
@jarvis.event
|
|
async def on_member_join(user: Member):
|
|
guild = user.guild
|
|
db = DBManager(get_config().mongo).mongo
|
|
mutes = list(
|
|
db.jarvis.mutes.find(
|
|
{"active": True, "user": user.id, "guild": guild.id}
|
|
)
|
|
)
|
|
if mutes and len(mutes) >= 1:
|
|
mute_role = db.jarvis.settings.find_one(
|
|
{"guild": guild.id, "setting": "mute"}
|
|
)
|
|
role = guild.get_role(mute_role["role"])
|
|
await user.add_roles(
|
|
role, reason="User is muted still muted from prior mute"
|
|
)
|
|
|
|
|
|
@jarvis.event
|
|
async def on_message(message: Message):
|
|
if not isinstance(message.channel, DMChannel):
|
|
db = DBManager(get_config().mongo).mongo
|
|
autoreact = db.jarvis.autoreact.find_one(
|
|
{"guild": message.guild.id, "channel": message.channel.id}
|
|
)
|
|
if autoreact:
|
|
for reaction in autoreact["reactions"]:
|
|
await message.add_reaction(reaction)
|
|
massmention = db.jarvis.settings.find_one(
|
|
{"guild": message.guild.id, "setting": "massmention"}
|
|
)
|
|
if (
|
|
massmention["value"] > 0
|
|
and len(message.mentions) > massmention["value"]
|
|
):
|
|
await message.delete()
|
|
# TODO: Implement warnings on massmention
|
|
await message.channel.send("Please do not mass mention.")
|
|
await jarvis.process_commands(message)
|
|
|
|
|
|
@jarvis.event
|
|
async def on_guild_join(guild):
|
|
general = find(lambda x: x.name == "general", guild.channels)
|
|
if general and general.permissions_for(guild.me).send_messages:
|
|
await general.send(
|
|
"Allow me to introduce myself. I am J.A.R.V.I.S., a virtual "
|
|
+ "artificial intelligence, and I'm here to assist you with a "
|
|
+ "variety of tasks as best I can, "
|
|
+ "24 hours a day, seven days a week."
|
|
)
|
|
await asyncio.sleep(1)
|
|
await general.send("Importing all preferences from home interface...")
|
|
|
|
# Set some default settings
|
|
db = DBManager(get_config().mongo).mongo
|
|
db.jarvis.settings.insert_one(
|
|
{"guild": guild.id, "setting": "massmention", "value": 5}
|
|
)
|
|
|
|
await general.send("Systems are now fully operational")
|
|
|
|
|
|
@loop(minutes=1)
|
|
async def unmute():
|
|
db = DBManager(get_config().mongo).mongo
|
|
mutes = list(db.jarvis.mutes.find({"active": True, "length": {"$gt": 0}}))
|
|
mute_roles = list(
|
|
db.jarvis.settings.find({"setting": "mute"}).sort(
|
|
[("guild", pymongo.ASCENDING)]
|
|
)
|
|
)
|
|
updates = []
|
|
for mute in mutes:
|
|
if mute["time"] + timedelta(minutes=mute["length"]) < datetime.now():
|
|
mute_role = [
|
|
x["value"] for x in mute_roles if x["guild"] == mute["guild"]
|
|
][0]
|
|
guild = await jarvis.fetch_guild(mute["guild"])
|
|
role = guild.get_role(mute_role)
|
|
user = await guild.fetch_member(mute["user"])
|
|
if user:
|
|
if role in user.roles:
|
|
await user.remove_roles(role, reason="Unmute")
|
|
updates.append(
|
|
pymongo.UpdateOne(
|
|
{"user": user.id, "guild": guild.id, "time": mute["time"]},
|
|
{"$set": {"active": False}},
|
|
)
|
|
)
|
|
if updates:
|
|
db.jarvis.mutes.bulk_write(updates)
|
|
|
|
|
|
@loop(minutes=10)
|
|
async def unban():
|
|
db = DBManager(get_config().mongo).mongo
|
|
bans = list(db.jarvis.bans.find({"active": True, "type": "temp"}))
|
|
updates = []
|
|
for ban in bans:
|
|
if ban["time"] + timedelta(
|
|
hours=ban["length"]
|
|
) < datetime.now() + timedelta(minutes=10):
|
|
guild = await jarvis.fetch_guild(ban["guild"])
|
|
user = await jarvis.fetch_user(ban["user"])
|
|
if user:
|
|
guild.unban(user)
|
|
updates.append(
|
|
pymongo.UpdateOne(
|
|
{
|
|
"user": user.id,
|
|
"guild": guild.id,
|
|
"time": ban["time"],
|
|
"type": "temp",
|
|
},
|
|
{"$set": {"active": False}},
|
|
)
|
|
)
|
|
if updates:
|
|
db.jarvis.bans.bulk_write(updates)
|
|
|
|
|
|
def run(ctx=None):
|
|
global restart_ctx
|
|
if ctx:
|
|
restart_ctx = ctx
|
|
for extension in utils.get_extensions():
|
|
jarvis.load_extension(extension)
|
|
config = get_config()
|
|
print(
|
|
" https://discord.com/api/oauth2/authorize?client_id="
|
|
+ "{}&permissions=8&scope=bot%20applications.commands".format(
|
|
config.client_id
|
|
)
|
|
)
|
|
unmute.start()
|
|
unban.start()
|
|
jarvis.run(config.token, bot=True, reconnect=True)
|
|
for cog in jarvis.cogs:
|
|
session = getattr(cog, "_session", None)
|
|
if session:
|
|
session.close()
|
|
if restart_ctx:
|
|
return restart_ctx
|