From 9c443a64781210552de2ea295799242d3dd2fea6 Mon Sep 17 00:00:00 2001 From: flifloo Date: Thu, 28 May 2020 13:58:45 +0200 Subject: [PATCH] Add calendar notify command and CalendarNotify DB object --- db/Calendar.py | 28 +++++++++++++++++++++++-- db/__init__.py | 2 +- extensions/calendar.py | 46 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 6 deletions(-) diff --git a/db/Calendar.py b/db/Calendar.py index 5dbe11d..df001a5 100644 --- a/db/Calendar.py +++ b/db/Calendar.py @@ -1,12 +1,14 @@ import re from datetime import datetime, timezone +from discord import Embed +from discord.ext.commands import Bot import ics import requests +from sqlalchemy.orm import relationship, Session from db import Base -from sqlalchemy import Column, Integer, String, BigInteger - +from sqlalchemy import Column, Integer, String, BigInteger, ForeignKey name_re = re.compile(r"([A-Z]+ [A-Z]+)") @@ -26,6 +28,8 @@ class Calendar(Base): project_id = Column(Integer, nullable=False) server = Column(BigInteger, nullable=False) + calendars_notify = relationship("CalendarNotify", backref="calendar", lazy="subquery") + def __init__(self, name: str, resources: int, project_id: int, server: int): self.name = name self.resources = resources @@ -43,3 +47,23 @@ class Calendar(Base): e.organizer = name_re.findall(e.description)[0] events.append(e) return events + + async def notify(self, bot: Bot, event: ics.Event): + for n in self.calendars_notify: + bot.loop.create_task(n.notify(bot, event)) + + +class CalendarNotify(Base): + __tablename__ = "calendars_notify" + channel = Column(BigInteger, primary_key=True) + calendar_id = Column(Integer, ForeignKey("calendars.id"), primary_key=True) + + def __init__(self, channel: int, calender: int): + self.channel = channel + self.calendar_id = calender + + async def notify(self, bot: Bot, event: ics.Event): + embed = Embed(title="Event is coming !") + embed.add_field(name=f"{event.begin.strftime('%H:%M')} - {event.end.strftime('%H:%M')}", + value=f"{event.name} | {event.location} - {event.organizer}") + await bot.get_channel(self.channel).send(embed=embed) diff --git a/db/__init__.py b/db/__init__.py index 3fd40b3..6bbcfe8 100644 --- a/db/__init__.py +++ b/db/__init__.py @@ -16,5 +16,5 @@ from db.InviteRole import InviteRole from db.Tomuss import Tomuss from db.PCP import PCP from db.Extension import Extension, ExtensionState -from db.Calendar import Calendar +from db.Calendar import Calendar, CalendarNotify Base.metadata.create_all(engine) diff --git a/extensions/calendar.py b/extensions/calendar.py index 1f65eb0..8b6a860 100644 --- a/extensions/calendar.py +++ b/extensions/calendar.py @@ -41,11 +41,14 @@ class Calendar(commands.Cog): 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 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 [#channel|@user]", + value="Notify the current channel or the giver channel/user of calendar events", inline=False) await ctx.send(embed=embed) @calendar.group("define", pass_context=True) + @commands.guild_only() async def calendar_define(self, ctx: commands.Context, name: str, url: str): try: ics.Calendar(requests.get(url).text) @@ -65,6 +68,7 @@ class Calendar(commands.Cog): await ctx.message.add_reaction("\U0001f44d") @calendar.group("list", pass_context=True) + @commands.guild_only() async def calendar_list(self, ctx: commands.Context): embed = Embed(title="Calendar list") s = db.Session() @@ -74,6 +78,7 @@ class Calendar(commands.Cog): await ctx.send(embed=embed) @calendar.group("remove", pass_context=True) + @commands.guild_only() async def calendar_remove(self, ctx: commands.Context, name: str = None): if name is None: await ctx.invoke(self.calendar_list) @@ -90,6 +95,7 @@ class Calendar(commands.Cog): raise BadArgument() @calendar.group("day", pass_context=True) + @commands.guild_only() async def calendar_day(self, ctx: commands.Context, name: str, day: str = None): c = query_calendar(name, ctx.guild.id) if day is None: @@ -101,11 +107,12 @@ class Calendar(commands.Cog): raise BadArgument() embed = Embed(title=f"Day calendar: {c.name}", description=date.strftime("%d/%m/%Y")) for e in c.events(date, date): - embed.add_field(name=f"{e.begin.strftime('%M:%H')} - {e.end.strftime('%M:%H')}", + embed.add_field(name=f"{e.begin.strftime('%H:%M')} - {e.end.strftime('%H:%M')}", value=f"{e.name} | {e.location} - {e.organizer}", inline=False) await ctx.send(embed=embed) @calendar.group("week", pass_context=True) + @commands.guild_only() async def calendar_week(self, ctx: commands.Context, name: str, day: str = None): c = query_calendar(name, ctx.guild.id) if day is None: @@ -127,6 +134,39 @@ class Calendar(commands.Cog): date = date + timedelta(days=1) await ctx.send(embed=embed) + @calendar.group("notify", pass_context=True) + @commands.guild_only() + async def calendar_notify(self, ctx: commands.Context, name: str): + if ctx.message.channel_mentions and ctx.message.mentions: + raise BadArgument() + elif ctx.message.channel_mentions: + if len(ctx.message.channel_mentions) > 1: + raise BadArgument() + else: + m = ctx.message.channel_mentions[0].id + elif ctx.message.mentions: + if len(ctx.message.mentions) > 1: + raise BadArgument() + else: + m = ctx.message.mentions[0] + if not m.dm_channel: + await m.create_dm() + m = m.dm_channel.id + else: + m = ctx.channel.id + s = db.Session() + s.add(db.CalendarNotify(m, query_calendar(name, ctx.guild.id).id)) + s.commit() + s.close() + await ctx.message.add_reaction("\U0001f44d") + + @calendar.group("trigger", pass_context=True) + @commands.guild_only() + async def calendar_trigger(self, ctx: commands.Context, name: str): + c = query_calendar(name, ctx.guild.id) + now = datetime.now() + await c.notify(self.bot, c.events(now, now)[0]) + @commands.Cog.listener() async def on_command_error(self, ctx: commands.Context, error): if ctx.invoked_with == extension_name or \