diff --git a/db/__init__.py b/db/__init__.py index 6bbcfe8..ae556f5 100644 --- a/db/__init__.py +++ b/db/__init__.py @@ -1,4 +1,4 @@ -from bot_bde.config import config +from administrator.config import config from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base diff --git a/extensions/__init__.py b/extensions/__init__.py index 7418384..1f22235 100644 --- a/extensions/__init__.py +++ b/extensions/__init__.py @@ -1,4 +1,4 @@ -from bot_bde import bot +from administrator import bot bot.load_extension("extensions.help") bot.load_extension("extensions.speak") @@ -13,7 +13,6 @@ bot.load_extension("extensions.warn") bot.load_extension("extensions.pcp") bot.load_extension("extensions.tex") bot.load_extension("extensions.invite") -bot.load_extension("extensions.speak") bot.load_extension("extensions.utils") bot.load_extension("extensions.tomuss") bot.load_extension("extensions.calendar") diff --git a/extensions/calendar.py b/extensions/calendar.py index 21b7e1e..4a56905 100644 --- a/extensions/calendar.py +++ b/extensions/calendar.py @@ -5,12 +5,16 @@ from operator import xor import ics import requests from discord import Embed, DMChannel, TextChannel +from discord.abc import GuildChannel from discord.ext import commands from discord.ext import tasks -from discord.ext.commands import CommandNotFound, BadArgument, MissingRequiredArgument, MissingPermissions +from discord.ext.commands import BadArgument, MissingPermissions +from discord_slash import cog_ext, SlashCommandOptionType, SlashContext +from discord_slash.utils import manage_commands -from bot_bde import db -from bot_bde.logger import logger +from administrator import db, slash +from administrator.check import guild_only, has_permissions, is_enabled +from administrator.logger import logger extension_name = "calendar" @@ -28,46 +32,19 @@ def query_calendar(name: str, guild: int) -> db.Calendar: return c -async def get_one_text_channel(ctx: commands.Context): - if ctx.message.channel_mentions: - if not ctx.channel.permissions_for(ctx.author).manage_channels: - raise MissingPermissions(["manage_channels"]) - elif len(ctx.message.channel_mentions) > 1: - raise BadArgument() - else: - m = ctx.message.channel_mentions[0].id - else: - if not ctx.author.dm_channel: - await ctx.author.create_dm() - m = ctx.author.dm_channel.id - return m - - class Calendar(commands.Cog): def __init__(self, bot: commands.Bot): self.bot = bot + slash.get_cog_commands(self) - @commands.group("calendar", pass_context=True) - async def calendar(self, ctx: commands.Context): - if ctx.invoked_subcommand is None: - await ctx.invoke(self.calendar_help) - - @calendar.group("help", pass_context=True) - async def calendar_help(self, ctx: commands.Context): - embed = Embed(title="Calendar help") - embed.add_field(name="calendar define ", value="Define a calendar", inline=False) - embed.add_field(name="calendar list", value="List all server calendar", inline=False) - embed.add_field(name="calendar remove ", value="Remove a server calendar", inline=False) - embed.add_field(name="calendar day [date]", value="show the current day or the given day", inline=False) - embed.add_field(name="calendar week [date]", value="Show the week or the given week", inline=False) - embed.add_field(name="calendar notify", - value="Command group to manage calendar notifications", inline=False) - await ctx.send(embed=embed) - - @calendar.group("define", pass_context=True) - @commands.guild_only() - @commands.has_permissions(manage_channels=True) - async def calendar_define(self, ctx: commands.Context, name: str, url: str): + @cog_ext.cog_subcommand(base="calendar", name="define", description="Define a calendar", options=[ + manage_commands.create_option("name", "The name of the calendar", SlashCommandOptionType.STRING, True), + manage_commands.create_option("url", "The url of the calendar", SlashCommandOptionType.STRING, True) + ]) + @is_enabled() + @guild_only() + @has_permissions(manage_channels=True) + async def calendar_define(self, ctx: SlashContext, name: str, url: str): try: ics.Calendar(requests.get(url).text) except Exception: @@ -83,39 +60,43 @@ class Calendar(commands.Cog): s.add(db.Calendar(name, int(m[0][0]), int(m[0][1]), ctx.guild.id)) s.commit() s.close() - await ctx.message.add_reaction("\U0001f44d") + await ctx.send(content="\U0001f44d") - @calendar.group("list", pass_context=True) - @commands.guild_only() - async def calendar_list(self, ctx: commands.Context): + @cog_ext.cog_subcommand(base="calendar", name="list", description="List all server calendar") + @is_enabled() + @guild_only() + async def calendar_list(self, ctx: SlashContext): embed = Embed(title="Calendar list") s = db.Session() for c in s.query(db.Calendar).filter(db.Calendar.server == ctx.guild.id).all(): embed.add_field(name=c.name, value=f"resources: {c.resources} | project id: {c.project_id}", inline=False) s.close() - await ctx.send(embed=embed) + await ctx.send(embeds=[embed]) - @calendar.group("remove", pass_context=True) - @commands.guild_only() - @commands.has_permissions(manage_channels=True) - async def calendar_remove(self, ctx: commands.Context, name: str = None): - if name is None: - await ctx.invoke(self.calendar_list) + @cog_ext.cog_subcommand(base="calendar", name="remove", description="Remove a server calendar", options=[ + manage_commands.create_option("name", "The name of the calendar", SlashCommandOptionType.STRING, True) + ]) + @guild_only() + @has_permissions(manage_channels=True) + async def calendar_remove(self, ctx: SlashContext, name: str): + s = db.Session() + c = s.query(db.Calendar).filter(db.Calendar.server == ctx.guild.id).filter(db.Calendar.name == name).first() + if c: + s.delete(c) + s.commit() + s.close() + await ctx.send(content="\U0001f44d") else: - s = db.Session() - c = s.query(db.Calendar).filter(db.Calendar.server == ctx.guild.id).filter(db.Calendar.name == name).first() - if c: - s.delete(c) - s.commit() - s.close() - await ctx.message.add_reaction("\U0001f44d") - else: - s.close() - raise BadArgument() + s.close() + raise BadArgument() - @calendar.group("day", pass_context=True) - @commands.guild_only() - async def calendar_day(self, ctx: commands.Context, name: str, day: str = None): + @cog_ext.cog_subcommand(base="calendar", name="day", description="Show the current day or the given day", options=[ + manage_commands.create_option("name", "The name of the calendar", SlashCommandOptionType.STRING, True), + manage_commands.create_option("date", "A target date", SlashCommandOptionType.STRING, False) + ]) + @is_enabled() + @guild_only() + async def calendar_day(self, ctx: SlashContext, name: str, day: str = None): c = query_calendar(name, ctx.guild.id) if day is None: date = datetime.now().date() @@ -132,11 +113,15 @@ class Calendar(commands.Cog): s.add(c) s.commit() s.close() - await ctx.send(embed=embed) + await ctx.send(embeds=[embed]) - @calendar.group("week", pass_context=True) - @commands.guild_only() - async def calendar_week(self, ctx: commands.Context, name: str, day: str = None): + @cog_ext.cog_subcommand(base="calendar", name="week", description="Show the week or the given week", options=[ + manage_commands.create_option("name", "The name of the calendar", SlashCommandOptionType.STRING, True), + manage_commands.create_option("date", "A target date", SlashCommandOptionType.STRING, False) + ]) + @is_enabled() + @guild_only() + async def calendar_week(self, ctx: SlashContext, name: str, day: str = None): c = query_calendar(name, ctx.guild.id) if day is None: date = datetime.now().date() @@ -153,64 +138,76 @@ class Calendar(commands.Cog): s.add(c) s.commit() s.close() - await ctx.send(embed=embed) + await ctx.send(embeds=[embed]) - @calendar.group("notify", pass_context=True) - async def calendar_notify(self, ctx: commands.Context): - if ctx.invoked_subcommand is None: - await ctx.invoke(self.calendar_notify_help) + @cog_ext.cog_subcommand(base="calendar", subcommand_group="notify", name="add", + description="Notify you or the giver channel of calendar events", + options=[ + manage_commands.create_option("name", "The name of the calendar", + SlashCommandOptionType.STRING, True), + manage_commands.create_option("channel", "A target channel", + SlashCommandOptionType.CHANNEL, False) + ]) + @is_enabled() + @guild_only() + async def calendar_notify_set(self, ctx: SlashContext, name: str, channel: GuildChannel = None): + await self.add_remove_calendar(ctx, name, channel, True) - @calendar_notify.group("help", pass_context=True) - async def calendar_notify_help(self, ctx: commands.Context): - embed = Embed(title="Calendar notify help") - embed.add_field(name="calendar notify add [#channel]", - value="Notify you or the giver channel of calendar events", inline=False) - embed.add_field(name="calendar notify remove [#channel]", - value="Remove the calendar notify of the current user or the given channel", - inline=False) - embed.add_field(name="calendar notify list [name]", - value="List all notify of all calendar or the given one", inline=False) - await ctx.send(embed=embed) + @cog_ext.cog_subcommand(base="calendar", subcommand_group="notify", name="remove", + description="Remove the calendar notify of the current user or the given channel", + options=[ + manage_commands.create_option("name", "The name of the calendar", + SlashCommandOptionType.STRING, True), + manage_commands.create_option("channel", "A target channel", + SlashCommandOptionType.CHANNEL, False) + ]) + @is_enabled() + @guild_only() + async def calendar_notify_remove(self, ctx: SlashContext, name: str, channel: GuildChannel = None): + await self.add_remove_calendar(ctx, name, channel, False) - @calendar_notify.group("add", pass_context=True) - @commands.guild_only() - async def calendar_notify_set(self, ctx: commands.Context, name: str): - m = await get_one_text_channel(ctx) - s = db.Session() - c = query_calendar(name, ctx.guild.id) - n = s.query(db.CalendarNotify).filter(db.CalendarNotify.channel == m) \ - .filter(db.CalendarNotify.calendar_id == c.id) \ - .first() - if not n: - s.add(db.CalendarNotify(m, c.id)) + @staticmethod + async def add_remove_calendar(ctx: SlashContext, name: str, channel: GuildChannel, action: bool): + if channel: + if not isinstance(channel, TextChannel): + raise BadArgument() + if not channel.permissions_for(ctx.author).manage_channels: + raise MissingPermissions(["manage_channels"]) + else: + m = channel.id else: - s.close() - raise BadArgument() - s.commit() - s.close() - await ctx.message.add_reaction("\U0001f44d") + if not ctx.author.dm_channel: + await ctx.author.create_dm() + m = ctx.author.dm_channel.id - @calendar_notify.group("remove", pass_context=True) - @commands.guild_only() - async def calendar_notify_remove(self, ctx: commands.Context, name: str): - m = await get_one_text_channel(ctx) s = db.Session() c = query_calendar(name, ctx.guild.id) n = s.query(db.CalendarNotify).filter(db.CalendarNotify.channel == m) \ .filter(db.CalendarNotify.calendar_id == c.id) \ .first() - if n: + + if action and not n: + s.add(db.CalendarNotify(m, c.id)) + elif not action and n: s.delete(n) else: s.close() raise BadArgument() s.commit() s.close() - await ctx.message.add_reaction("\U0001f44d") - @calendar_notify.group("list") - @commands.guild_only() - async def calendar_notify_list(self, ctx: commands.Context, name: str = None): + await ctx.send(content="\U0001f44d") + + @cog_ext.cog_subcommand(base="calendar", subcommand_group="notify", name="list", + description="List all notify of all calendar or the given one", + options=[ + manage_commands.create_option("name", "The name of the calendar", + SlashCommandOptionType.STRING, True) + ]) + @is_enabled() + @guild_only() + @has_permissions(manage_channels=True) + async def calendar_notify_list(self, ctx: SlashContext, name: str = None): s = db.Session() embed = Embed(title="Notify list") if name is None: @@ -226,7 +223,7 @@ class Calendar(commands.Cog): elif type(ch) == DMChannel: notify.append(ch.recipient.mention) embed.add_field(name=c.name, value="\n".join(notify) or "Nothing here", inline=False) - await ctx.send(embed=embed) + await ctx.send(embeds=[embed]) @tasks.loop(minutes=1) async def calendar_notify_loop(self): @@ -257,25 +254,8 @@ class Calendar(commands.Cog): await n.notify(self.bot, e) break - s.close() - @commands.Cog.listener() - async def on_command_error(self, ctx: commands.Context, error): - if ctx.invoked_with == extension_name or \ - (ctx.command.root_parent and ctx.command.root_parent.name == extension_name): - if isinstance(error, CommandNotFound) \ - or isinstance(error, BadArgument) \ - or isinstance(error, MissingRequiredArgument): - await ctx.message.add_reaction("\u2753") - await ctx.message.delete(delay=30) - elif isinstance(error, MissingPermissions): - await ctx.message.add_reaction("\u274c") - await ctx.message.delete(delay=30) - else: - await ctx.send("An error occurred !") - raise error - def cog_unload(self): self.calendar_notify_loop.stop()