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 import create_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base 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.help")
bot.load_extension("extensions.speak") bot.load_extension("extensions.speak")
@ -13,7 +13,6 @@ bot.load_extension("extensions.warn")
bot.load_extension("extensions.pcp") bot.load_extension("extensions.pcp")
bot.load_extension("extensions.tex") bot.load_extension("extensions.tex")
bot.load_extension("extensions.invite") bot.load_extension("extensions.invite")
bot.load_extension("extensions.speak")
bot.load_extension("extensions.utils") bot.load_extension("extensions.utils")
bot.load_extension("extensions.tomuss") bot.load_extension("extensions.tomuss")
bot.load_extension("extensions.calendar") bot.load_extension("extensions.calendar")

View file

@ -5,12 +5,16 @@ from operator import xor
import ics import ics
import requests import requests
from discord import Embed, DMChannel, TextChannel from discord import Embed, DMChannel, TextChannel
from discord.abc import GuildChannel
from discord.ext import commands from discord.ext import commands
from discord.ext import tasks 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 administrator import db, slash
from bot_bde.logger import logger from administrator.check import guild_only, has_permissions, is_enabled
from administrator.logger import logger
extension_name = "calendar" extension_name = "calendar"
@ -28,46 +32,19 @@ def query_calendar(name: str, guild: int) -> db.Calendar:
return c 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): class Calendar(commands.Cog):
def __init__(self, bot: commands.Bot): def __init__(self, bot: commands.Bot):
self.bot = bot self.bot = bot
slash.get_cog_commands(self)
@commands.group("calendar", pass_context=True) @cog_ext.cog_subcommand(base="calendar", name="define", description="Define a calendar", options=[
async def calendar(self, ctx: commands.Context): manage_commands.create_option("name", "The name of the calendar", SlashCommandOptionType.STRING, True),
if ctx.invoked_subcommand is None: manage_commands.create_option("url", "The url of the calendar", SlashCommandOptionType.STRING, True)
await ctx.invoke(self.calendar_help) ])
@is_enabled()
@calendar.group("help", pass_context=True) @guild_only()
async def calendar_help(self, ctx: commands.Context): @has_permissions(manage_channels=True)
embed = Embed(title="Calendar help") async def calendar_define(self, ctx: SlashContext, name: str, url: str):
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):
try: try:
ics.Calendar(requests.get(url).text) ics.Calendar(requests.get(url).text)
except Exception: 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.add(db.Calendar(name, int(m[0][0]), int(m[0][1]), ctx.guild.id))
s.commit() s.commit()
s.close() s.close()
await ctx.message.add_reaction("\U0001f44d") await ctx.send(content="\U0001f44d")
@calendar.group("list", pass_context=True) @cog_ext.cog_subcommand(base="calendar", name="list", description="List all server calendar")
@commands.guild_only() @is_enabled()
async def calendar_list(self, ctx: commands.Context): @guild_only()
async def calendar_list(self, ctx: SlashContext):
embed = Embed(title="Calendar list") embed = Embed(title="Calendar list")
s = db.Session() s = db.Session()
for c in s.query(db.Calendar).filter(db.Calendar.server == ctx.guild.id).all(): 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) embed.add_field(name=c.name, value=f"resources: {c.resources} | project id: {c.project_id}", inline=False)
s.close() s.close()
await ctx.send(embed=embed) await ctx.send(embeds=[embed])
@calendar.group("remove", pass_context=True) @cog_ext.cog_subcommand(base="calendar", name="remove", description="Remove a server calendar", options=[
@commands.guild_only() manage_commands.create_option("name", "The name of the calendar", SlashCommandOptionType.STRING, True)
@commands.has_permissions(manage_channels=True) ])
async def calendar_remove(self, ctx: commands.Context, name: str = None): @guild_only()
if name is None: @has_permissions(manage_channels=True)
await ctx.invoke(self.calendar_list) async def calendar_remove(self, ctx: SlashContext, name: str):
else:
s = db.Session() s = db.Session()
c = s.query(db.Calendar).filter(db.Calendar.server == ctx.guild.id).filter(db.Calendar.name == name).first() c = s.query(db.Calendar).filter(db.Calendar.server == ctx.guild.id).filter(db.Calendar.name == name).first()
if c: if c:
s.delete(c) s.delete(c)
s.commit() s.commit()
s.close() s.close()
await ctx.message.add_reaction("\U0001f44d") await ctx.send(content="\U0001f44d")
else: else:
s.close() s.close()
raise BadArgument() raise BadArgument()
@calendar.group("day", pass_context=True) @cog_ext.cog_subcommand(base="calendar", name="day", description="Show the current day or the given day", options=[
@commands.guild_only() manage_commands.create_option("name", "The name of the calendar", SlashCommandOptionType.STRING, True),
async def calendar_day(self, ctx: commands.Context, name: str, day: str = None): 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) c = query_calendar(name, ctx.guild.id)
if day is None: if day is None:
date = datetime.now().date() date = datetime.now().date()
@ -132,11 +113,15 @@ class Calendar(commands.Cog):
s.add(c) s.add(c)
s.commit() s.commit()
s.close() s.close()
await ctx.send(embed=embed) await ctx.send(embeds=[embed])
@calendar.group("week", pass_context=True) @cog_ext.cog_subcommand(base="calendar", name="week", description="Show the week or the given week", options=[
@commands.guild_only() manage_commands.create_option("name", "The name of the calendar", SlashCommandOptionType.STRING, True),
async def calendar_week(self, ctx: commands.Context, name: str, day: str = None): 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) c = query_calendar(name, ctx.guild.id)
if day is None: if day is None:
date = datetime.now().date() date = datetime.now().date()
@ -153,64 +138,76 @@ class Calendar(commands.Cog):
s.add(c) s.add(c)
s.commit() s.commit()
s.close() s.close()
await ctx.send(embed=embed) await ctx.send(embeds=[embed])
@calendar.group("notify", pass_context=True) @cog_ext.cog_subcommand(base="calendar", subcommand_group="notify", name="add",
async def calendar_notify(self, ctx: commands.Context): description="Notify you or the giver channel of calendar events",
if ctx.invoked_subcommand is None: options=[
await ctx.invoke(self.calendar_notify_help) 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) @cog_ext.cog_subcommand(base="calendar", subcommand_group="notify", name="remove",
async def calendar_notify_help(self, ctx: commands.Context): description="Remove the calendar notify of the current user or the given channel",
embed = Embed(title="Calendar notify help") options=[
embed.add_field(name="calendar notify add <name> [#channel]", manage_commands.create_option("name", "The name of the calendar",
value="Notify you or the giver channel of calendar events", inline=False) SlashCommandOptionType.STRING, True),
embed.add_field(name="calendar notify remove <name> [#channel]", manage_commands.create_option("channel", "A target channel",
value="Remove the calendar notify of the current user or the given channel", SlashCommandOptionType.CHANNEL, False)
inline=False) ])
embed.add_field(name="calendar notify list [name]", @is_enabled()
value="List all notify of all calendar or the given one", inline=False) @guild_only()
await ctx.send(embed=embed) 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) @staticmethod
@commands.guild_only() async def add_remove_calendar(ctx: SlashContext, name: str, channel: GuildChannel, action: bool):
async def calendar_notify_set(self, ctx: commands.Context, name: str): if channel:
m = await get_one_text_channel(ctx) if not isinstance(channel, TextChannel):
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))
else:
s.close()
raise BadArgument() raise BadArgument()
s.commit() if not channel.permissions_for(ctx.author).manage_channels:
s.close() raise MissingPermissions(["manage_channels"])
await ctx.message.add_reaction("\U0001f44d") else:
m = channel.id
else:
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() s = db.Session()
c = query_calendar(name, ctx.guild.id) c = query_calendar(name, ctx.guild.id)
n = s.query(db.CalendarNotify).filter(db.CalendarNotify.channel == m) \ n = s.query(db.CalendarNotify).filter(db.CalendarNotify.channel == m) \
.filter(db.CalendarNotify.calendar_id == c.id) \ .filter(db.CalendarNotify.calendar_id == c.id) \
.first() .first()
if n:
if action and not n:
s.add(db.CalendarNotify(m, c.id))
elif not action and n:
s.delete(n) s.delete(n)
else: else:
s.close() s.close()
raise BadArgument() raise BadArgument()
s.commit() s.commit()
s.close() s.close()
await ctx.message.add_reaction("\U0001f44d")
@calendar_notify.group("list") await ctx.send(content="\U0001f44d")
@commands.guild_only()
async def calendar_notify_list(self, ctx: commands.Context, name: str = None): @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() s = db.Session()
embed = Embed(title="Notify list") embed = Embed(title="Notify list")
if name is None: if name is None:
@ -226,7 +223,7 @@ class Calendar(commands.Cog):
elif type(ch) == DMChannel: elif type(ch) == DMChannel:
notify.append(ch.recipient.mention) notify.append(ch.recipient.mention)
embed.add_field(name=c.name, value="\n".join(notify) or "Nothing here", inline=False) 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) @tasks.loop(minutes=1)
async def calendar_notify_loop(self): async def calendar_notify_loop(self):
@ -257,25 +254,8 @@ class Calendar(commands.Cog):
await n.notify(self.bot, e) await n.notify(self.bot, e)
break break
s.close() 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): def cog_unload(self):
self.calendar_notify_loop.stop() self.calendar_notify_loop.stop()