diff --git a/db/Calendar.py b/db/Calendar.py index df001a5..1b93571 100644 --- a/db/Calendar.py +++ b/db/Calendar.py @@ -1,5 +1,5 @@ import re -from datetime import datetime, timezone +from datetime import datetime, timezone, timedelta from discord import Embed from discord.ext.commands import Bot @@ -8,7 +8,7 @@ import requests from sqlalchemy.orm import relationship, Session from db import Base -from sqlalchemy import Column, Integer, String, BigInteger, ForeignKey +from sqlalchemy import Column, Integer, String, BigInteger, ForeignKey, Text, DateTime name_re = re.compile(r"([A-Z]+ [A-Z]+)") @@ -27,6 +27,8 @@ class Calendar(Base): resources = Column(Integer, nullable=False) project_id = Column(Integer, nullable=False) server = Column(BigInteger, nullable=False) + calendar = Column(Text) + calendar_update = Column(DateTime) calendars_notify = relationship("CalendarNotify", backref="calendar", lazy="subquery") @@ -36,17 +38,24 @@ class Calendar(Base): self.project_id = project_id self.server = server - def cal(self, first_date: datetime, last_date: datetime) -> ics.Calendar: - return ics.Calendar(requests.get(url(self.resources, self.project_id, first_date, last_date)).text) + def cal(self) -> ics.Calendar: + now = datetime.now() + if not self.calendar or self.calendar_update <= now - timedelta(minutes=30): + first_date = now - timedelta(days=now.weekday()) + last_date = now + timedelta(days=31) + self.calendar = requests.get(url(self.resources, self.project_id, first_date, last_date)).text + self.calendar_update = now - def events(self, first_date: datetime, last_date: datetime) -> [ics.Event]: + return ics.Calendar(self.calendar) + + def events(self, first_date: datetime.date, last_date: datetime.date) -> [ics.Event]: events = [] - for e in sorted(list(self.cal(first_date, last_date).events), key=lambda x: x.begin): + for e in sorted(list(self.cal().events), key=lambda x: x.begin): e.begin = e.begin.replace(tzinfo=timezone.utc).astimezone(tz=None) e.end = e.begin.replace(tzinfo=timezone.utc).astimezone(tz=None) e.organizer = name_re.findall(e.description)[0] events.append(e) - return events + return list(filter(lambda x: x.begin.date() >= first_date and x.end.date() <= last_date, events)) async def notify(self, bot: Bot, event: ics.Event): for n in self.calendars_notify: diff --git a/extensions/calendar.py b/extensions/calendar.py index 410cb5e..788b286 100644 --- a/extensions/calendar.py +++ b/extensions/calendar.py @@ -118,16 +118,21 @@ class Calendar(commands.Cog): async def calendar_day(self, ctx: commands.Context, name: str, day: str = None): c = query_calendar(name, ctx.guild.id) if day is None: - date = datetime.now() + date = datetime.now().date() else: try: - date = datetime.strptime(day, "%d/%m/%Y") + date = datetime.strptime(day, "%d/%m/%Y").date() except ValueError: 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('%H:%M')} - {e.end.strftime('%H:%M')}", value=f"{e.name} | {e.location} - {e.organizer}", inline=False) + s = db.Session() + if s.is_modified(c): + s.add(c) + s.commit() + s.close() await ctx.send(embed=embed) @calendar.group("week", pass_context=True) @@ -135,10 +140,10 @@ class Calendar(commands.Cog): async def calendar_week(self, ctx: commands.Context, name: str, day: str = None): c = query_calendar(name, ctx.guild.id) if day is None: - date = datetime.now() + date = datetime.now().date() else: try: - date = datetime.strptime(day, "%d/%m/%Y") + date = datetime.strptime(day, "%d/%m/%Y").date() except ValueError: raise BadArgument() date -= timedelta(days=date.weekday()) @@ -151,6 +156,11 @@ class Calendar(commands.Cog): f"**{e.name}** | {e.location} - {e.organizer}") embed.add_field(name=date.strftime("%d/%m/%Y"), value="\n".join(events) or "Nothing !", inline=False) date = date + timedelta(days=1) + s = db.Session() + if s.is_modified(c): + s.add(c) + s.commit() + s.close() await ctx.send(embed=embed) @calendar.group("notify", pass_context=True) @@ -231,9 +241,13 @@ class Calendar(commands.Cog): s = db.Session() now = datetime.now().replace(tzinfo=timezone.utc).astimezone(tz=None) for c in s.query(db.Calendar).all(): - for e in c.events(now, now): + for e in c.events(now.date(), now.date()): if xor(e.begin >= now - timedelta(minutes=30), e.begin >= now - timedelta(minutes=10)): self.bot.loop.create_task(await c.notify(self.bot, e)) + if s.is_modified(c): + s.add(c) + s.commit() + s.close() @commands.Cog.listener() async def on_command_error(self, ctx: commands.Context, error):