1
0
Fork 0

Update calendar

This commit is contained in:
Ethanell 2021-02-08 15:12:10 +01:00
parent fef4ee45b1
commit ca7a30c7e7
3 changed files with 108 additions and 129 deletions

View file

@ -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

View file

@ -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")

View file

@ -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 <name> <url>", 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 <name>", value="Remove a server calendar", inline=False)
embed.add_field(name="calendar day <name> [date]", value="show the current day or the given day", inline=False)
embed.add_field(name="calendar week <name> [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 <name> [#channel]",
value="Notify you or the giver channel of calendar events", inline=False)
embed.add_field(name="calendar notify remove <name> [#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()