From fbc9bbe820182279394b893b8dfa525777f13417 Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 20:49:30 +0200 Subject: [PATCH 01/14] Fix Big D prefixes because discord still doesn't check prefixes properly --- didier.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/didier.py b/didier.py index 0e882c3..78eed74 100644 --- a/didier.py +++ b/didier.py @@ -9,8 +9,8 @@ load_dotenv(verbose=True) # All possible prefixes # When_mentioned_or doesn't count for spaces so can't use that -prefixes = ["didier ", "Didier ", "DIDIER ", "big d ", "<@!680510935164911730> ", - "didier", "Didier", "DIDIER", "big d", "<@!680510935164911730>"] +prefixes = ["didier ", "Didier ", "DIDIER ", "big d ", "Big d ", "Big D ", "BIG D ", "<@!680510935164911730> ", + "didier", "Didier", "DIDIER", "big d", "Big d", "Big D", "BIG D", "<@!680510935164911730>"] # Configure intents (1.5.0) intents = discord.Intents.default() From caf595010be55d61d611fd94a768288256c09940 Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 20:56:20 +0200 Subject: [PATCH 02/14] Create remind task, add docstring comments, update ignored.md --- cogs/tasks.py | 34 ++++++++++++++++++++++++++++++++++ ignored.md | 3 ++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/cogs/tasks.py b/cogs/tasks.py index 80ada4b..d161462 100644 --- a/cogs/tasks.py +++ b/cogs/tasks.py @@ -18,9 +18,13 @@ class Tasks(commands.Cog): # self.resetPoke.start() self.checkBirthdays.start() self.updateMessageCounts.start() + self.sendReminders.start() @tasks.loop(hours=1.0) async def bankInterest(self): + """ + Task that gives daily interest + """ # Don't do it multiple times a day if bot dc's, ... with open("files/lastTasks.json", "r") as fp: lastTasks = json.load(fp) @@ -58,6 +62,9 @@ class Tasks(commands.Cog): @tasks.loop(hours=1.0) async def resetLost(self): + """ + Task that resets Lost Today + """ # Don't do it multiple times a day if bot dc's, ... with open("files/lastTasks.json", "r") as fp: lastTasks = json.load(fp) @@ -79,6 +86,9 @@ class Tasks(commands.Cog): @tasks.loop(hours=6.0) async def resetPoke(self): + """ + Task that resets Poke + """ if int(time.time()) - int(poke.get()[1]) > 259200: await self.client.get_guild(int(self.client.constants.CallOfCode))\ .get_channel(int(self.client.constants.DidierPosting))\ @@ -90,6 +100,9 @@ class Tasks(commands.Cog): @tasks.loop(hours=1.0) async def resetPrison(self): + """ + Task that lowers prison time daily + """ # Don't do it multiple times a day if bot dc's, ... with open("files/lastTasks.json", "r") as fp: lastTasks = json.load(fp) @@ -107,6 +120,9 @@ class Tasks(commands.Cog): @tasks.loop(hours=1.0) async def checkBirthdays(self): + """ + Task that wishes people a happy birthday + """ # Don't do it multiple times a day if bot dc's, ... with open("files/lastTasks.json", "r") as fp: lastTasks = json.load(fp) @@ -138,6 +154,9 @@ class Tasks(commands.Cog): @tasks.loop(hours=1.0) async def updateMessageCounts(self): + """ + Task that updates the activity counter for channels + """ # Don't do it multiple times a day if bot dc's, ... with open("files/lastTasks.json", "r") as fp: lastTasks = json.load(fp) @@ -154,6 +173,21 @@ class Tasks(commands.Cog): async def beforeupdateMessageCounts(self): await self.client.wait_until_ready() + @tasks.loop(hours=1.0) + async def sendReminders(self): + """ + Task that sends people daily reminders + """ + # Don't do it multiple times a day if bot dc's, ... + with open("files/lastTasks.json", "r") as fp: + lastTasks = json.load(fp) + if int(self.getCurrentHour()) == 0 and int(time.time()) - int(lastTasks["remind"]) > 10000: + pass + + # with open("files/lastTasks.json", "w") as fp: + # lastTasks["remind"] = round(time.time()) + # json.dump(lastTasks, fp) + def getCurrentHour(self): return timeFormatters.dateTimeNow().hour diff --git a/ignored.md b/ignored.md index 503fe79..483e923 100644 --- a/ignored.md +++ b/ignored.md @@ -48,7 +48,8 @@ Contains timestamps for when every `task` in `cogs/tasks.py` ran for the last ti "interest": 0, "lost": 0, "prison": 0, - "poke": 0 + "poke": 0, + "remind": 0 } ``` From 250c2d40c7b7135635de8e7d37d8a68167d3fe6d Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 21:34:10 +0200 Subject: [PATCH 03/14] Create reminder task & command, fix Les aliases --- cogs/remind.py | 52 ++++++++++++++++++++++++++++++++++++ cogs/school.py | 2 +- cogs/tasks.py | 20 ++++++++++++-- data/remind.py | 16 +++++++++++ files/help.json | 4 ++- functions/database/remind.py | 43 +++++++++++++++++++++++++++++ 6 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 cogs/remind.py create mode 100644 data/remind.py create mode 100644 functions/database/remind.py diff --git a/cogs/remind.py b/cogs/remind.py new file mode 100644 index 0000000..5ca428c --- /dev/null +++ b/cogs/remind.py @@ -0,0 +1,52 @@ +import discord +from discord.ext import commands +from decorators import help +from enums.help_categories import Category +from functions.database import remind + + +class Remind(commands.Cog): + def __init__(self, client): + self.client = client + + # Don't allow any commands to work when locked + def cog_check(self, ctx): + return not self.client.locked + + @commands.group(name="Remind", aliases=["Remindme"], usage="[Categorie]", case_insensitive=True, invoke_without_command=True) + async def remind(self, ctx): + """ + Command group to remind the user of a certain thing every day. + :param ctx: Discord Context + """ + categories = ["Les", "Nightly"] + embed = discord.Embed(colour=discord.Colour.blue()) + + embed.set_author(name="Remind Categorieën") + embed.description = "\n".join(sorted(categories)) + + await ctx.send(embed=embed) + + @remind.command(name="Nightly") + async def nightly(self, ctx): + """ + Command to get a daily Nightly reminder + """ + if remind.switchReminder(ctx.author.id, "nightly"): + await ctx.send("Vanaf nu wordt je er dagelijks aan herinnerd om Didier Nightly te doen.") + else: + await ctx.send("Je zal er niet langer aan herinnerd worden om Didier Nightly te doen.") + + @remind.command(name="Les", aliases=["Class", "Classes", "Sched", "Schedule"]) + async def les(self, ctx): + """ + Command to get a daily reminder with an embed of your schedule + """ + if remind.switchReminder(ctx.author.id, "les"): + await ctx.send("Vanaf nu krijg je dagelijks je lessenrooster toegestuurd.") + else: + await ctx.send("Je zal je lessenrooster niet langer toegestuurd krijgen.") + + +def setup(client): + client.add_cog(Remind(client)) diff --git a/cogs/school.py b/cogs/school.py index aa12d3d..36fe585 100644 --- a/cogs/school.py +++ b/cogs/school.py @@ -41,7 +41,7 @@ class School(commands.Cog): embed.set_footer(text="Omwille van de coronamaatregelen is er een beperkter aanbod, en kan je enkel nog eten afhalen. Ter plaatse eten is niet meer mogelijk.") await ctx.send(embed=embed) - @commands.command(name="Les", aliases=["Sched", "Schedule", "Class"], usage="[Jaargang]* [Dag]*") + @commands.command(name="Les", aliases=["Class", "Classes", "Sched", "Schedule"], usage="[Jaargang]* [Dag]*") @commands.check(checks.allowedChannels) @help.Category(category=Category.School) async def les(self, ctx, *day): diff --git a/cogs/tasks.py b/cogs/tasks.py index d161462..2acccb3 100644 --- a/cogs/tasks.py +++ b/cogs/tasks.py @@ -1,9 +1,11 @@ from data import constants +from data.remind import Reminders from discord.ext import commands, tasks from enums.numbers import Numbers from functions import timeFormatters from functions.database import currency, poke, prison, birthdays, stats import json +from random import random import requests import time @@ -181,8 +183,22 @@ class Tasks(commands.Cog): # Don't do it multiple times a day if bot dc's, ... with open("files/lastTasks.json", "r") as fp: lastTasks = json.load(fp) - if int(self.getCurrentHour()) == 0 and int(time.time()) - int(lastTasks["remind"]) > 10000: - pass + if int(self.getCurrentHour()) == 21 and int(time.time()) - int(lastTasks["remind"]) > 10000: + reminders = Reminders() + + for category in reminders.categories: + for user in category["users"]: + userInstance = await self.client.fetch_user(user) + + # User can't be fetched for whatever reason, ignore instead of crashing + if userInstance is None: + continue + + # Check if a special embed has to be attached for this reminder + if "embed" not in category: + await userInstance.send(random.choice(category["messages"])) + else: + await userInstance.send(random.choice(category["messages"]), embed=category["embed"]) # with open("files/lastTasks.json", "w") as fp: # lastTasks["remind"] = round(time.time()) diff --git a/data/remind.py b/data/remind.py new file mode 100644 index 0000000..7fbb69a --- /dev/null +++ b/data/remind.py @@ -0,0 +1,16 @@ +from functions.database import remind + + +class Reminders: + def __init__(self): + rows = remind.getAllRows() + + self._nightlyUsers = [int(user[0]) for user in rows if user[1]] + self._nightlyMessages = ["Dagelijkse herinnering om Didier Nightly te doen.", "Vrees niet, Nightly-streak-liefhebber! 't Zenne kik, Didier, me ne reminder!"] + self.nightly = {"users": self._nightlyUsers, "messages": self._nightlyMessages} + + self._les = [int(user[0]) for user in rows if user[2]] + self._lesMessages = ["Lessenrooster voor vandaag:"] + self.les = {"users": self._les, "messages": self._lesMessages, "embed": None} + + self.categories = [self.nightly, self.les] diff --git a/files/help.json b/files/help.json index 64ff0c9..4cfabbe 100644 --- a/files/help.json +++ b/files/help.json @@ -86,7 +86,9 @@ "releases": "Lijst van de games die in de volgende 30 dagen uitkomen.\nGeef een getal op om volgende/vorige pagina's te bekijken (standaard pagina 1).", "releases info": "Geeft gedetailleerde informatie over de game met de opgegeven id.", "reload": "Verwijdert [Cog] & voegt hem daarna terug toe.", - "remind": "Krijg een dagelijkse herinnering om Didier Nightly te doen.\nMeer categorieën en usages komen later:tm:.", + "remind": "Krijg een lijst van categorieën waaraan je dagelijks herinnerd kan worden.\nOm deze herinneringen niet langer te krijgen, kan je opnieuw Didier Remind [Categorie] doen.", + "remind les": "Krijg dagelijks het lessenrooster voor die dag toegestuurd.", + "remind nightly": "Krijg dagelijks een herinnering om Didier Nightly te doen.", "reverse": "Returnt tekst achterstevoren.", "rhyme": "Stuurt de 15 beste suggesties voor woorden die rijmen op [Woord].", "rob": "Probeer Didier Dinks te stelen van [Persoon].", diff --git a/functions/database/remind.py b/functions/database/remind.py new file mode 100644 index 0000000..ebbebf5 --- /dev/null +++ b/functions/database/remind.py @@ -0,0 +1,43 @@ +from functions.database import utils + + +def getAllRows(): + connection = utils.connect() + cursor = connection.cursor() + + cursor.execute("SELECT * FROM remind") + return cursor.fetchall() + + +def getOrAddUser(userid): + connection = utils.connect() + cursor = connection.cursor() + + cursor.execute("SELECT * FROM remind WHERE userid = %s", (int(userid),)) + res = cursor.fetchall() + + if not res: + cursor.execute("INSERT INTO remind(userid) VALUES %s", (int(userid),)) + connection.commit() + + return getOrAddUser(userid) + + return res[0] + + +def switchReminder(userid, column): + connection = utils.connect() + cursor = connection.cursor() + + columns = ["id", "nightly", "les"] + + res = getOrAddUser(userid) + + # Switch the column value + to = not (res[columns.index(column)]) + + cursor.execute("UPDATE remind SET %s = %s WHERE userid = %s", (column, to, int(userid),)) + connection.commit() + + return to + From 0e92948cf8002a51c4e7dc5da54164b8d4eaf508 Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 21:34:41 +0200 Subject: [PATCH 04/14] Add remind help category decorator --- cogs/remind.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/remind.py b/cogs/remind.py index 5ca428c..3d3def5 100644 --- a/cogs/remind.py +++ b/cogs/remind.py @@ -14,6 +14,7 @@ class Remind(commands.Cog): return not self.client.locked @commands.group(name="Remind", aliases=["Remindme"], usage="[Categorie]", case_insensitive=True, invoke_without_command=True) + @help.Category(Category.Other) async def remind(self, ctx): """ Command group to remind the user of a certain thing every day. From 6682327f1ea1e62c73ddd8b6b69f5955d6550e17 Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 22:01:51 +0200 Subject: [PATCH 05/14] Move all Les code into a separate file to allow Reminder to access it --- cogs/school.py | 242 +++------------------------------------------ functions/les.py | 252 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 263 insertions(+), 231 deletions(-) create mode 100644 functions/les.py diff --git a/cogs/school.py b/cogs/school.py index 36fe585..a2ca9b9 100644 --- a/cogs/school.py +++ b/cogs/school.py @@ -1,12 +1,10 @@ from data import constants -import datetime from decorators import help import discord from discord.ext import commands from enums.courses import years from enums.help_categories import Category -from functions import checks, eten, timeFormatters, config, stringFormatters -from functions.numbers import clamp +from functions import checks, eten, les import json @@ -45,245 +43,27 @@ class School(commands.Cog): @commands.check(checks.allowedChannels) @help.Category(category=Category.School) async def les(self, ctx, *day): - semester = int(config.get("semester")) - year = int(config.get("year")) - years_counter = int(config.get("years")) - # Check if a schedule or a day was called - if len(day) == 0: - day = [] - else: - # Only either of them was passed - if len(day) == 1: - # Called a schedule - if day[0].isdigit(): - if 0 < int(day[0]) < years_counter + 1: - year = int(day[0]) - day = [] - else: - return await ctx.send("Dit is geen geldige jaargang.") - # elif: calling a weekday is automatically handled below, - # so checking is obsolete - else: - # Both were passed - if day[0].isdigit(): - if 0 < int(day[0]) < years_counter + 1: - year = int(day[0]) - day = [] - else: - return await ctx.send("Dit is geen geldige jaargang.") - # Cut the schedule from the string - day = day[1:] + parsed = les.parseArgs(day) - day = self.getWeekDay(None if len(day) == 0 else day)[1] - dayDatetime = self.findDate(timeFormatters.weekdayToInt(day)) + # Invalid arguments + if not parsed[0]: + return await ctx.send(parsed[1]) + day, dayDatetime, semester, year = parsed[1:] + + # Customize the user's schedule schedule = self.customizeSchedule(ctx, year, semester) - # Create a date object to check the current week - startDate = 1600041600 - currentTime = dayDatetime.timestamp() - week = clamp(timeFormatters.timeIn(currentTime - startDate, "weeks")[0], 1, 13) + # Create the embed + embed = les.createEmbed(day, dayDatetime, semester, year, schedule) - title, week = self.getTitle(day, dayDatetime, week) - - # Add all courses & their corresponding times + locations of today - courses, extras, prev, online = self.getCourses(schedule, day, week) - - embed = discord.Embed(colour=discord.Colour.blue(), title=title) - embed.set_author(name="Lessenrooster voor {}{} Bachelor".format(year, "ste" if year == 1 else "de")) - - if len(courses) == 0: - embed.add_field(name="Geen Les", value="Geen Les", inline=False) - else: - courseString = self.createCourseString(courses) - courseString += "\nGroep {} heeft vandaag online les.".format(1 if week % 2 == 0 else 2) - embed.description = courseString - - if prev: - embed.add_field(name="Vakken uit vorige jaren", value=self.createCourseString(prev), inline=False) - - if extras: - embed.add_field(name="Extra", value="\n".join(self.getExtras(extra) for extra in extras), inline=False) - - # Add online links if not commnet - if online: - embed.add_field(name="Online Links", value="\n".join(self.getLink(onlineClass) for onlineClass in online)) - - embed.set_footer(text="Semester {} | Lesweek {}".format(semester, round(week))) await ctx.send(embed=embed) - def getLink(self, onlineClass): - return "{}: **[{}]({})**".format(onlineClass["course"], onlineClass["online"], onlineClass["link"]) - - def createCourseString(self, courses): - courseString = "" - for course in sorted(courses, key=lambda item: item["slot"]["time"][1]): - # Add a ":" to the hour + add a leading "0" if needed - start = timeFormatters.timeFromInt(course["slot"]["time"][1]) - end = timeFormatters.timeFromInt(course["slot"]["time"][2]) - courseString += "{} - {}: {} {}\n".format(start, end, - str(course["course"]), self.getLocation(course["slot"])) - return courseString - - # Returns the day of the week, while keeping track of weekends - def getWeekDay(self, day=None): - weekDays = ["maandag", "dinsdag", "woensdag", "donderdag", "vrijdag"] - - # Get current day of the week - dayNumber = datetime.datetime.today().weekday() - # If a day or a modifier was passed, show that day instead - if day is not None: - if day[0] == "morgen": - dayNumber += 1 - elif day[0] == "overmorgen": - dayNumber += 2 - else: - for i in range(5): - if weekDays[i].startswith(day): - dayNumber = i - # Weekends should be skipped - dayNumber = dayNumber % 7 - if dayNumber > 4: - dayNumber = 0 - - # Get daystring - return dayNumber, weekDays[dayNumber] - - def getLocation(self, slot): - if "canceled" in slot: - return None - - if "online" in slot: - return "online @ **[{}]({})**".format(slot["online"], slot["zoom"] if slot["online"] == "ZOOM" else slot["bongo"]) - - # Check for courses in multiple locations - if "locations" in slot: - # Language - 'en' for the last one - return ", ".join(self.getLocation(location) for location in slot["locations"][:-1]) \ - + " en " + self.getLocation(slot["locations"][-1]) - return "in {} {} {}".format(slot["campus"], slot["building"], slot["room"]) - - def getCourses(self, schedule, day, week): - # Add all courses & their corresponding times + locations of today - courses = [] - - extras = [] - - prev = [] - - onlineLinks = [] - - for course in schedule: - for slot in course["slots"]: - if day in slot["time"]: - classDic = {"course": course["course"], "slot": slot} - - # Class was canceled - if "canceled" in slot and "weeks" in slot and week in slot["weeks"]: - extras.append(classDic) - continue - - # Add online links for those at home - if not any(el["course"] == course["course"] for el in onlineLinks): - if "bongo" in course: - onlineDic = {"course": course["course"], "online": "Bongo Virtual Classroom", "link": course["bongo"]} - onlineLinks.append(onlineDic) - elif "zoom" in course: - onlineDic = {"course": course["course"], "online": "Zoom", "link": course["zoom"]} - onlineLinks.append(onlineDic) - - # Add this class' bongo & zoom links - if "bongo" in course: - classDic["slot"]["bongo"] = course["bongo"] - - if "zoom" in course: - classDic["slot"]["zoom"] = course["zoom"] - - if "custom" in course: - prev.append(classDic) - - # Check for special classes - if "weeks" in slot and "online" not in slot: - if week in slot["weeks"]: - if "custom" not in course: - courses.append(classDic) - extras.append(classDic) - elif "weeks" in slot and "online" in slot and "group" not in slot: - if week in slot["weeks"]: - if "custom" not in course: - courses.append(classDic) - extras.append(classDic) - - else: - if "custom" not in course: - courses.append(classDic) - - # Filter out normal courses that are replaced with special courses - for extra in extras: - for course in courses: - if course["slot"]["time"] == extra["slot"]["time"] and course != extra: - courses.remove(course) - break - - # Sort online links alphabetically - onlineLinks.sort(key=lambda x: x["course"]) - - # Remove links of canceled classes - for element in onlineLinks: - if not any(c["course"] == element["course"] for c in courses): - onlineLinks.remove(element) - - return courses, extras, prev, onlineLinks - - def getTitle(self, day, dayDT, week): - # now = timeFormatters.dateTimeNow() - # if timeFormatters.weekdayToInt(day) < now.weekday(): - # week += 1 - - day = day[0].upper() + day[1:].lower() - - titleString = "{} {}/{}/{}".format(day, stringFormatters.leadingZero(dayDT.day), - stringFormatters.leadingZero(dayDT.month), dayDT.year) - return titleString, week - - def getExtras(self, extra): - start = timeFormatters.timeFromInt(extra["slot"]["time"][1]) - end = timeFormatters.timeFromInt(extra["slot"]["time"][2]) - - location = self.getLocation(extra["slot"]) - - if "canceled" in extra["slot"]: - return "De les **{}** van **{}** tot **{}** gaat vandaag uitzonderlijk **niet** door.".format( - extra["course"], start, end - ) - - if "group" in extra["slot"]: - return "**Groep {}** heeft vandaag uitzonderlijk **{}** **{}** van **{} tot {}**.".format( - extra["slot"]["group"], extra["course"], location, - start, end - ) - elif "online" in extra["slot"]: - return "**{}** gaat vandaag uitzonderlijk online door {} van **{} tot {}**.".format( - extra["course"], location[7:], - start, end - ) - else: - return "**{}** vindt vandaag uitzonderlijk plaats **{}** van **{} tot {}**.".format( - extra["course"], location, - start, end - ) - - def findDate(self, targetWeekday): - now = timeFormatters.dateTimeNow() - while now.weekday() != targetWeekday: - now = now + datetime.timedelta(days=1) - return now - # Add all the user's courses def customizeSchedule(self, ctx, year, semester): with open("files/schedules/{}{}.json".format(year, semester), "r") as fp: schedule = json.load(fp) - return schedule + member = self.client.get_guild(int(constants.CallOfCode)).get_member(ctx.author.id) for role in member.roles: for univYear in years: diff --git a/functions/les.py b/functions/les.py new file mode 100644 index 0000000..437d730 --- /dev/null +++ b/functions/les.py @@ -0,0 +1,252 @@ +import datetime +import discord +from functions import config, timeFormatters, stringFormatters +from functions.numbers import clamp +import json + +def createCourseString(courses): + courseString = "" + for course in sorted(courses, key=lambda item: item["slot"]["time"][1]): + # Add a ":" to the hour + add a leading "0" if needed + start = timeFormatters.timeFromInt(course["slot"]["time"][1]) + end = timeFormatters.timeFromInt(course["slot"]["time"][2]) + courseString += "{} - {}: {} {}\n".format(start, end, + str(course["course"]), getLocation(course["slot"])) + return courseString + + +def createEmbed(day, dayDatetime, semester, year, schedule): + # Create a date object to check the current week + startDate = 1600041600 + currentTime = dayDatetime.timestamp() + week = clamp(timeFormatters.timeIn(currentTime - startDate, "weeks")[0], 1, 13) + + title, week = getTitle(day, dayDatetime, week) + + # Add all courses & their corresponding times + locations of today + courses, extras, prev, online = getCourses(schedule, day, week) + + embed = discord.Embed(colour=discord.Colour.blue(), title=title) + embed.set_author(name="Lessenrooster voor {}{} Bachelor".format(year, "ste" if year == 1 else "de")) + + if len(courses) == 0: + embed.add_field(name="Geen Les", value="Geen Les", inline=False) + else: + courseString = createCourseString(courses) + courseString += "\nGroep {} heeft vandaag online les.".format(1 if week % 2 == 0 else 2) + embed.description = courseString + + if prev: + embed.add_field(name="Vakken uit vorige jaren", value=createCourseString(prev), inline=False) + + if extras: + embed.add_field(name="Extra", value="\n".join(getExtras(extra) for extra in extras), inline=False) + + # Add online links + if online: + embed.add_field(name="Online Links", value="\n".join(getLink(onlineClass) for onlineClass in online)) + + embed.set_footer(text="Semester {} | Lesweek {}".format(semester, round(week))) + return embed + + +def findDate(targetWeekday): + now = timeFormatters.dateTimeNow() + while now.weekday() != targetWeekday: + now = now + datetime.timedelta(days=1) + return now + + +def getCourses(schedule, day, week): + # Add all courses & their corresponding times + locations of today + courses = [] + extras = [] + prev = [] + onlineLinks = [] + for course in schedule: + for slot in course["slots"]: + if day in slot["time"]: + classDic = {"course": course["course"], "slot": slot} + + # Class was canceled + if "canceled" in slot and "weeks" in slot and week in slot["weeks"]: + extras.append(classDic) + continue + + # Add online links for those at home + if not any(el["course"] == course["course"] for el in onlineLinks): + if "bongo" in course: + onlineDic = {"course": course["course"], "online": "Bongo Virtual Classroom", "link": course["bongo"]} + onlineLinks.append(onlineDic) + elif "zoom" in course: + onlineDic = {"course": course["course"], "online": "Zoom", "link": course["zoom"]} + onlineLinks.append(onlineDic) + + # Add this class' bongo & zoom links + if "bongo" in course: + classDic["slot"]["bongo"] = course["bongo"] + + if "zoom" in course: + classDic["slot"]["zoom"] = course["zoom"] + + if "custom" in course: + prev.append(classDic) + + # Check for special classes + if "weeks" in slot and "online" not in slot: + if week in slot["weeks"]: + if "custom" not in course: + courses.append(classDic) + extras.append(classDic) + elif "weeks" in slot and "online" in slot and "group" not in slot: + if week in slot["weeks"]: + if "custom" not in course: + courses.append(classDic) + extras.append(classDic) + else: + if "custom" not in course: + courses.append(classDic) + + # Filter out normal courses that are replaced with special courses + for extra in extras: + for course in courses: + if course["slot"]["time"] == extra["slot"]["time"] and course != extra: + courses.remove(course) + break + + # Sort online links alphabetically + onlineLinks.sort(key=lambda x: x["course"]) + + # Remove links of canceled classes + for element in onlineLinks: + if not any(c["course"] == element["course"] for c in courses): + onlineLinks.remove(element) + + return courses, extras, prev, onlineLinks + + +def getExtras(extra): + start = timeFormatters.timeFromInt(extra["slot"]["time"][1]) + end = timeFormatters.timeFromInt(extra["slot"]["time"][2]) + + location = getLocation(extra["slot"]) + + if "canceled" in extra["slot"]: + return "De les **{}** van **{}** tot **{}** gaat vandaag uitzonderlijk **niet** door.".format( + extra["course"], start, end + ) + + if "group" in extra["slot"]: + return "**Groep {}** heeft vandaag uitzonderlijk **{}** **{}** van **{} tot {}**.".format( + extra["slot"]["group"], extra["course"], location, + start, end + ) + elif "online" in extra["slot"]: + return "**{}** gaat vandaag uitzonderlijk online door {} van **{} tot {}**.".format( + extra["course"], location[7:], + start, end + ) + else: + return "**{}** vindt vandaag uitzonderlijk plaats **{}** van **{} tot {}**.".format( + extra["course"], location, + start, end + ) + + +def getLink(onlineClass): + return "{}: **[{}]({})**".format(onlineClass["course"], onlineClass["online"], onlineClass["link"]) + + +def getLocation(slot): + if "canceled" in slot: + return None + + if "online" in slot: + return "online @ **[{}]({})**".format(slot["online"], slot["zoom"] if slot["online"] == "ZOOM" else slot["bongo"]) + + # Check for courses in multiple locations + if "locations" in slot: + # Language - 'en' for the last one + return ", ".join(getLocation(location) for location in slot["locations"][:-1]) \ + + " en " + getLocation(slot["locations"][-1]) + return "in {} {} {}".format(slot["campus"], slot["building"], slot["room"]) + + +def getSchedule(semester, year): + with open("files/schedules/{}{}.json".format(year, semester), "r") as fp: + schedule = json.load(fp) + + return schedule + + +def getTitle(day, dayDT, week): + # now = timeFormatters.dateTimeNow() + # if timeFormatters.weekdayToInt(day) < now.weekday(): + # week += 1 + + day = day[0].upper() + day[1:].lower() + + titleString = "{} {}/{}/{}".format(day, stringFormatters.leadingZero(dayDT.day), + stringFormatters.leadingZero(dayDT.month), dayDT.year) + return titleString, week + + +# Returns the day of the week, while keeping track of weekends +def getWeekDay(day=None): + weekDays = ["maandag", "dinsdag", "woensdag", "donderdag", "vrijdag"] + + # Get current day of the week + dayNumber = datetime.datetime.today().weekday() + # If a day or a modifier was passed, show that day instead + if day is not None: + if day[0] == "morgen": + dayNumber += 1 + elif day[0] == "overmorgen": + dayNumber += 2 + else: + for i in range(5): + if weekDays[i].startswith(day): + dayNumber = i + # Weekends should be skipped + dayNumber = dayNumber % 7 + if dayNumber > 4: + dayNumber = 0 + + # Get daystring + return dayNumber, weekDays[dayNumber] + + +def parseArgs(day): + semester = int(config.get("semester")) + year = int(config.get("year")) + years_counter = int(config.get("years")) + # Check if a schedule or a day was called + if len(day) == 0: + day = [] + else: + # Only either of them was passed + if len(day) == 1: + # Called a schedule + if day[0].isdigit(): + if 0 < int(day[0]) < years_counter + 1: + year = int(day[0]) + day = [] + else: + return [False, "Dit is geen geldige jaargang."] + # elif: calling a weekday is automatically handled below, + # so checking is obsolete + else: + # Both were passed + if day[0].isdigit(): + if 0 < int(day[0]) < years_counter + 1: + year = int(day[0]) + day = [] + else: + return [False, "Dit is geen geldige jaargang."] + # Cut the schedule from the string + day = day[1:] + + day = getWeekDay(None if len(day) == 0 else day)[1] + dayDatetime = findDate(timeFormatters.weekdayToInt(day)) + + return [True, day, dayDatetime, semester, year] From 95bdc576e16627e1dab5003414991d050486bfe6 Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 22:12:05 +0200 Subject: [PATCH 06/14] Reminders work --- cogs/school.py | 3 +-- cogs/tasks.py | 10 +++++----- data/remind.py | 10 +++++++++- functions/database/remind.py | 4 ++-- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/cogs/school.py b/cogs/school.py index a2ca9b9..fd12d13 100644 --- a/cogs/school.py +++ b/cogs/school.py @@ -61,8 +61,7 @@ class School(commands.Cog): # Add all the user's courses def customizeSchedule(self, ctx, year, semester): - with open("files/schedules/{}{}.json".format(year, semester), "r") as fp: - schedule = json.load(fp) + schedule = les.getSchedule(semester, year) member = self.client.get_guild(int(constants.CallOfCode)).get_member(ctx.author.id) for role in member.roles: diff --git a/cogs/tasks.py b/cogs/tasks.py index 2acccb3..32175af 100644 --- a/cogs/tasks.py +++ b/cogs/tasks.py @@ -5,7 +5,7 @@ from enums.numbers import Numbers from functions import timeFormatters from functions.database import currency, poke, prison, birthdays, stats import json -from random import random +import random import requests import time @@ -183,7 +183,7 @@ class Tasks(commands.Cog): # Don't do it multiple times a day if bot dc's, ... with open("files/lastTasks.json", "r") as fp: lastTasks = json.load(fp) - if int(self.getCurrentHour()) == 21 and int(time.time()) - int(lastTasks["remind"]) > 10000: + if int(self.getCurrentHour()) == 22 and int(time.time()) - int(lastTasks["remind"]) > 10000: reminders = Reminders() for category in reminders.categories: @@ -200,9 +200,9 @@ class Tasks(commands.Cog): else: await userInstance.send(random.choice(category["messages"]), embed=category["embed"]) - # with open("files/lastTasks.json", "w") as fp: - # lastTasks["remind"] = round(time.time()) - # json.dump(lastTasks, fp) + with open("files/lastTasks.json", "w") as fp: + lastTasks["remind"] = round(time.time()) + json.dump(lastTasks, fp) def getCurrentHour(self): return timeFormatters.dateTimeNow().hour diff --git a/data/remind.py b/data/remind.py index 7fbb69a..8b3bc58 100644 --- a/data/remind.py +++ b/data/remind.py @@ -1,3 +1,4 @@ +from functions import les from functions.database import remind @@ -11,6 +12,13 @@ class Reminders: self._les = [int(user[0]) for user in rows if user[2]] self._lesMessages = ["Lessenrooster voor vandaag:"] - self.les = {"users": self._les, "messages": self._lesMessages, "embed": None} + self.les = {"users": self._les, "messages": self._lesMessages, "embed": self.lesEmbed()} self.categories = [self.nightly, self.les] + + def lesEmbed(self): + day, dayDatetime, semester, year = les.parseArgs([])[1:] + + schedule = les.getSchedule(semester, year) + + return les.createEmbed(day, dayDatetime, semester, year, schedule) \ No newline at end of file diff --git a/functions/database/remind.py b/functions/database/remind.py index ebbebf5..83dd632 100644 --- a/functions/database/remind.py +++ b/functions/database/remind.py @@ -17,7 +17,7 @@ def getOrAddUser(userid): res = cursor.fetchall() if not res: - cursor.execute("INSERT INTO remind(userid) VALUES %s", (int(userid),)) + cursor.execute("INSERT INTO remind(userid) VALUES(%s)", (int(userid),)) connection.commit() return getOrAddUser(userid) @@ -36,7 +36,7 @@ def switchReminder(userid, column): # Switch the column value to = not (res[columns.index(column)]) - cursor.execute("UPDATE remind SET %s = %s WHERE userid = %s", (column, to, int(userid),)) + cursor.execute("UPDATE remind SET {} = %s WHERE userid = %s".format(column), (to, int(userid),)) connection.commit() return to From 3cc08f4afd9845cb4312e9bc666c355980f17871 Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 22:12:36 +0200 Subject: [PATCH 07/14] Send reminders at 7 am instead of 10 pm --- cogs/tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/tasks.py b/cogs/tasks.py index 32175af..6d6e718 100644 --- a/cogs/tasks.py +++ b/cogs/tasks.py @@ -183,7 +183,7 @@ class Tasks(commands.Cog): # Don't do it multiple times a day if bot dc's, ... with open("files/lastTasks.json", "r") as fp: lastTasks = json.load(fp) - if int(self.getCurrentHour()) == 22 and int(time.time()) - int(lastTasks["remind"]) > 10000: + if int(self.getCurrentHour()) == 7 and int(time.time()) - int(lastTasks["remind"]) > 10000: reminders = Reminders() for category in reminders.categories: From 3b0ebde8ead85954b86e8084b60f8b1498b383c0 Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 22:15:22 +0200 Subject: [PATCH 08/14] wait til ready for reminders --- cogs/tasks.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cogs/tasks.py b/cogs/tasks.py index 6d6e718..064dae3 100644 --- a/cogs/tasks.py +++ b/cogs/tasks.py @@ -204,6 +204,10 @@ class Tasks(commands.Cog): lastTasks["remind"] = round(time.time()) json.dump(lastTasks, fp) + @sendReminders.before_loop + async def beforeSendReminders(self): + await self.client.wait_until_ready() + def getCurrentHour(self): return timeFormatters.dateTimeNow().hour From 83abca911eec501f4d1ecabc16a5ab3a9bc8fff5 Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 22:17:41 +0200 Subject: [PATCH 09/14] Update databases.md --- databases.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/databases.md b/databases.md index 1015841..1e42101 100644 --- a/databases.md +++ b/databases.md @@ -140,6 +140,14 @@ Used in dinks.py - Prison commands. Contains information on who is in prison. 2 days: integer | The remaining days this user has to spend in prison 3 daily: numeric | The amount of Didier Dinks that [daily] decreases by every day +### remind + +Used in tasks.py - sendReminders task. + + 0 userid: bigint, unique, primary key | The user's Discord id + 1 nightly: boolean, default false | A boolean indicating whether or not the user wants Nightly reminders + 2 les: boolean, default false | A boolean indicating whether or not the user wants Les reminders + ### store Used in store.py - Store commands. Contains info on items that are available for purchase. From 474ad85a46b69d83405a34e0f74e85cf7b4e645e Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 22:20:40 +0200 Subject: [PATCH 10/14] Fix missing function --- cogs/school.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/school.py b/cogs/school.py index fd12d13..94a57dd 100644 --- a/cogs/school.py +++ b/cogs/school.py @@ -21,7 +21,7 @@ class School(commands.Cog): @commands.check(checks.allowedChannels) @help.Category(category=Category.School) async def eten(self, ctx, *day): - day = self.getWeekDay(None if len(day) == 0 else day)[1] + day = les.getWeekDay(None if len(day) == 0 else day)[1] # Create embed menu = eten.etenScript(day) From f77e465076dfef5adb85cf82dd3edb078dc162ee Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 23:37:24 +0200 Subject: [PATCH 11/14] Fixed incorrect links in schedules, schedules now show all links of this day --- files/schedules/21.json | 103 ++++++-------------------------------- functions/les.py | 106 +++++++++++++++++++++++++++++++++++----- 2 files changed, 108 insertions(+), 101 deletions(-) diff --git a/files/schedules/21.json b/files/schedules/21.json index a0145f4..2a68ca4 100644 --- a/files/schedules/21.json +++ b/files/schedules/21.json @@ -6,16 +6,10 @@ "slots": [ { "online": "Bongo Virtual Classroom", - "campus": "Sterre", - "building": "S8", - "room": "LES 3.1", "time": ["maandag", 1000, 1230] }, { "online": "ZOOM", - "campus": "Sterre", - "building": "S8", - "room": "LES 2.4", "time": ["vrijdag", 1300, 1530] } ] @@ -24,34 +18,14 @@ "course": "Systeemprogrammeren", "bongo": "https://ufora.ugent.be/d2l/ext/rp/222035/lti/framedlaunch/7f4120b3-8827-44ad-8b02-a79066c396cf", "slots": [ - { - "campus": "Sterre", - "building": "S8", - "room": "LES 2.1", - "time": ["donderdag", 1430, 1700] - }, { "online": "Bongo Virtual Classroom", - "weeks": [1], - "group": 1, - "campus": "Sterre", - "building": "S4", - "room": "LES 0.1", "time": ["maandag", 1430, 1700] }, { "online": "Bongo Virtual Classroom", - "weeks": [1], "time": ["donderdag", 1430, 1700] }, - { - "weeks": [2], - "group": 2, - "campus": "Sterre", - "building": "S4", - "room": "LES 0.1", - "time": ["maandag", 1430, 1700] - }, { "weeks": [3], "canceled": true, @@ -73,73 +47,44 @@ } ], "time": ["maandag", 1430, 1700] - }, - { - "weeks": [5], - "group": 1, - "locations": [ - { - "campus": "Sterre", - "building": "S8", - "room": "LES 0.1 Victor Van Straelen" - }, - { - "campus": "Sterre", - "building": "S9", - "room": "3.1 Konrad Zuse" - } - ], - "time": ["maandag", 1430, 1700] } ] }, { "course": "AD 2", "bongo": "https://ufora.ugent.be/d2l/ext/rp/222018/lti/framedlaunch/7f4120b3-8827-44ad-8b02-a79066c396cf", + "msteams": "https://teams.microsoft.com/_?culture=nl-nl&country=NL&lm=deeplink&lmsrc=homePageWeb&cmpid=WebSignIn#/conversations/19:8ee7593d50924201a43ed9373dd6b05d@thread.v2?ctx=chat", + "zoom": "https://ufora.ugent.be/d2l/ext/rp/222018/lti/framedlaunch/556e197e-e87b-4c27-be5d-53adc7a41826", "slots": [ { - "campus": "Sterre", - "building": "S9", - "room": "A3", - "time": ["dinsdag", 1300, 1530] + "online": "Bongo Virtual Classroom", + "time": ["dinsdag", 1300, 1400] }, { - "campus": "Sterre", - "building": "S9", - "room": "A3", + "online": "ZOOM", + "time": ["dinsdag", 1400, 1530] + }, + { + "online": "Bongo Virtual Classroom", "time": ["vrijdag", 830, 930] }, { - "locations": [ - { - "campus": "Sterre", - "building": "S8", - "room": "Victor Van Straelen" - }, - { - "campus": "Sterre", - "building": "S9", - "room": "3.1 Konrad Zuse" - } - ], + "online": "MS Teams", "time": ["vrijdag", 1000, 1100] } ] }, { "course": "Communicatienetwerken", + "zoom": "https://ufora.ugent.be/d2l/ext/rp/221184/lti/framedlaunch/556e197e-e87b-4c27-be5d-53adc7a41826", "slots": [ { - "campus": "Ardoyen", - "building": "Locus", - "room": "Resto Locus", - "time": ["woensdag", 1000, 1230] + "online": "ZOOM", + "time": ["woensdag", 1100, 1200] }, { - "campus": "Ardoyen", - "building": "Locus", - "room": "Resto Locus", - "time": ["woensdag", 1430, 1700] + "online": "ZOOM", + "time": ["woensdag", 1430, 1600] }, { "weeks": [4, 7], @@ -170,32 +115,14 @@ "slots": [ { "online": "Bongo Virtual Classroom", - "campus": "Sterre", - "building": "S12", - "room": "Auditorium 1", "time": ["dinsdag", 1600, 1700] }, { - "locations": [ - { - "campus": "Sterre", - "building": "S9", - "room": "1.1 Alan Turing" - }, - { - "campus": "Sterre", - "building": "S9", - "room": "3.1 Konrad Zuse" - } - ], "online": "Bongo Virtual Classroom", "time": ["donderdag", 830, 1100] }, { "online": "Bongo Virtual Classroom", - "campus": "Sterre", - "building": "S9", - "room": "A2", "time": ["donderdag", 1300, 1400] } ] diff --git a/functions/les.py b/functions/les.py index 437d730..df4c394 100644 --- a/functions/les.py +++ b/functions/les.py @@ -4,6 +4,10 @@ from functions import config, timeFormatters, stringFormatters from functions.numbers import clamp import json + +# TODO use constants & enums instead of hardcoding platform names +# also make the naming in the jsons more consistent + def createCourseString(courses): courseString = "" for course in sorted(courses, key=lambda item: item["slot"]["time"][1]): @@ -42,15 +46,23 @@ def createEmbed(day, dayDatetime, semester, year, schedule): if extras: embed.add_field(name="Extra", value="\n".join(getExtras(extra) for extra in extras), inline=False) - # Add online links + # TODO uncomment this when covid rules slow down + # Add online links - temporarily removed because everything is online right now if online: - embed.add_field(name="Online Links", value="\n".join(getLink(onlineClass) for onlineClass in online)) + uniqueLinks: dict = getUniqueLinks(online) + embed.add_field(name="Online Links", value="\n".join( + sorted(getLinks(onlineClass, links) for onlineClass, links in uniqueLinks.items()))) embed.set_footer(text="Semester {} | Lesweek {}".format(semester, round(week))) return embed def findDate(targetWeekday): + """ + Function that finds the datetime object that corresponds to + the next occurence of [targetWeekday]. + :param targetWeekday: The weekday to find + """ now = timeFormatters.dateTimeNow() while now.weekday() != targetWeekday: now = now + datetime.timedelta(days=1) @@ -58,14 +70,23 @@ def findDate(targetWeekday): def getCourses(schedule, day, week): + """ + Function that creates a list of all courses of this day, + a list of all online links, and extra information for these courses. + :param schedule: A user's (customized) schedule + :param day: The current weekday + :param week: The current week + """ # Add all courses & their corresponding times + locations of today courses = [] extras = [] prev = [] onlineLinks = [] + for course in schedule: for slot in course["slots"]: if day in slot["time"]: + # Basic dict containing the course name & the class' time slot classDic = {"course": course["course"], "slot": slot} # Class was canceled @@ -74,18 +95,34 @@ def getCourses(schedule, day, week): continue # Add online links for those at home - if not any(el["course"] == course["course"] for el in onlineLinks): - if "bongo" in course: - onlineDic = {"course": course["course"], "online": "Bongo Virtual Classroom", "link": course["bongo"]} - onlineLinks.append(onlineDic) - elif "zoom" in course: - onlineDic = {"course": course["course"], "online": "Zoom", "link": course["zoom"]} + # Check if link hasn't been added yet + if not any(el["course"] == course["course"] and + # Avoid KeyErrors: if either of these don't have an online link yet, + # add it as well + ("online" not in el or "online" not in slot or el["online"] == slot["online"]) + for el in onlineLinks): + # Some courses have multiple links on the same day, + # add all of them + if "bongo" in slot["online"].lower(): + onlineDic = {"course": course["course"], "online": "Bongo Virtual Classroom", + "link": course["bongo"]} onlineLinks.append(onlineDic) - # Add this class' bongo & zoom links + if "zoom" in slot["online"].lower(): + onlineDic = {"course": course["course"], "online": "ZOOM", "link": course["zoom"]} + onlineLinks.append(onlineDic) + + if "teams" in slot["online"].lower(): + onlineDic = {"course": course["course"], "online": "MS Teams", "link": course["msteams"]} + onlineLinks.append(onlineDic) + + # Add this class' bongo, msteams & zoom links if "bongo" in course: classDic["slot"]["bongo"] = course["bongo"] + if "msteams" in course: + classDic["slot"]["msteams"] = course["msteams"] + if "zoom" in course: classDic["slot"]["zoom"] = course["zoom"] @@ -99,11 +136,14 @@ def getCourses(schedule, day, week): courses.append(classDic) extras.append(classDic) elif "weeks" in slot and "online" in slot and "group" not in slot: + # This class is only online for this week if week in slot["weeks"]: if "custom" not in course: courses.append(classDic) extras.append(classDic) else: + # Nothing special happening, just add it to the list of courses + # in case this is a course for everyone in this year if "custom" not in course: courses.append(classDic) @@ -126,6 +166,10 @@ def getCourses(schedule, day, week): def getExtras(extra): + """ + Function that returns a formatted string giving clear info + when a course is happening somewhere else (or canceled). + """ start = timeFormatters.timeFromInt(extra["slot"]["time"][1]) end = timeFormatters.timeFromInt(extra["slot"]["time"][2]) @@ -153,16 +197,52 @@ def getExtras(extra): ) -def getLink(onlineClass): - return "{}: **[{}]({})**".format(onlineClass["course"], onlineClass["online"], onlineClass["link"]) +def getUniqueLinks(onlineClasses): + """ + Function that returns a dict of all online unique online links for every class + in case some classes have multiple links on the same day. + """ + # Create a list of all unique course names + courseNames = list(set(oc["course"] for oc in onlineClasses)) + uniqueLinks: dict = {} + + # Add every link of every class into the dict + for name in courseNames: + uniqueLinks[name] = {} + for oc in onlineClasses: + if oc["course"] == name: + # Add the link for this platform + uniqueLinks[name][oc["online"]] = oc["link"] + + return uniqueLinks + + +def getLinks(onlineClass, links): + """ + Function that returns a formatted string giving a hyperlink + to every online link for this class today. + """ + return "{}: {}".format(onlineClass, + " | ".join( + ["**[{}]({})**".format(platform, url) for platform, url in + links.items()]) + ) def getLocation(slot): + """ + Function that returns a formatted string indicating where this course + is happening. + """ if "canceled" in slot: return None + # TODO fix this because it's ugly if "online" in slot: - return "online @ **[{}]({})**".format(slot["online"], slot["zoom"] if slot["online"] == "ZOOM" else slot["bongo"]) + return "online @ **[{}]({})**".format(slot["online"], + slot["zoom"] if slot["online"] == "ZOOM" else slot["msteams"] if slot[ + "online"] == "MS Teams" else + slot["bongo"]) # Check for courses in multiple locations if "locations" in slot: @@ -187,7 +267,7 @@ def getTitle(day, dayDT, week): day = day[0].upper() + day[1:].lower() titleString = "{} {}/{}/{}".format(day, stringFormatters.leadingZero(dayDT.day), - stringFormatters.leadingZero(dayDT.month), dayDT.year) + stringFormatters.leadingZero(dayDT.month), dayDT.year) return titleString, week From 68405963eb572ade5686dd7e902b5d8b9bcd3bc8 Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 23:50:37 +0200 Subject: [PATCH 12/14] Add old schedule back in & mark covid-online classes as special classes, add a check to customizeSchedule so I don't have to patch the error every 3 minutes --- cogs/school.py | 8 ++++- files/schedules/21.json | 71 ++++++++++++++++++++++++++++------------- functions/les.py | 2 +- 3 files changed, 57 insertions(+), 24 deletions(-) diff --git a/cogs/school.py b/cogs/school.py index 94a57dd..52fd18d 100644 --- a/cogs/school.py +++ b/cogs/school.py @@ -63,7 +63,13 @@ class School(commands.Cog): def customizeSchedule(self, ctx, year, semester): schedule = les.getSchedule(semester, year) - member = self.client.get_guild(int(constants.CallOfCode)).get_member(ctx.author.id) + COC = self.client.get_guild(int(constants.CallOfCode)) + + if COC is None: + return schedule + + member = COC.get_member(ctx.author.id) + for role in member.roles: for univYear in years: for course in univYear: diff --git a/files/schedules/21.json b/files/schedules/21.json index 2a68ca4..8dfbea0 100644 --- a/files/schedules/21.json +++ b/files/schedules/21.json @@ -58,17 +58,49 @@ "slots": [ { "online": "Bongo Virtual Classroom", + "campus": "Sterre", + "building": "S9", + "room": "A3", "time": ["dinsdag", 1300, 1400] }, { "online": "ZOOM", - "time": ["dinsdag", 1400, 1530] + "campus": "Sterre", + "building": "S9", + "room": "A3", + "time": ["dinsdag", 1430, 1530] }, { + "online": "Bongo Virtual Classroom", + "campus": "Sterre", + "building": "S9", + "room": "A3", + "time": ["vrijdag", 830, 930] + }, + { + "online": "MS Teams", + "campus": "Sterre", + "building": "S9", + "room": "3.1 Kondrad Zuse", + "time": ["vrijdag", 1000, 1100] + }, + { + "weeks": [6, 7, 8, 9, 10, 11, 12], + "online": "Bongo Virtual Classroom", + "time": ["dinsdag", 1300, 1400] + }, + { + "weeks": [6, 7, 8, 9, 10, 11, 12], + "online": "ZOOM", + "time": ["dinsdag", 1430, 1530] + }, + { + "weeks": [6, 7, 8, 9, 10, 11, 12], "online": "Bongo Virtual Classroom", "time": ["vrijdag", 830, 930] }, { + "weeks": [6, 7, 8, 9, 10, 11, 12], "online": "MS Teams", "time": ["vrijdag", 1000, 1100] } @@ -80,32 +112,27 @@ "slots": [ { "online": "ZOOM", - "time": ["woensdag", 1100, 1200] + "campus": "Ardoyen", + "building": "Locus", + "room": "Resto Locus", + "time": ["woensdag", 1000, 1230] }, { "online": "ZOOM", - "time": ["woensdag", 1430, 1600] + "campus": "Ardoyen", + "building": "Locus", + "room": "Resto Locus", + "time": ["woensdag", 1430, 1700] }, { - "weeks": [4, 7], - "locations": [ - { - "campus": "Ardoyen", - "building": "iGent", - "room": "0.1" - }, - { - "campus": "Ardoyen", - "building": "iGent", - "room": "0.1 PRA" - }, - { - "campus": "Ardoyen", - "building": "iGent", - "room": "0.2" - } - ], - "time": ["woensdag", 1430, 1700] + "weeks": [6, 7, 8, 9, 10, 11, 12], + "online": "ZOOM", + "time": ["woensdag", 1100, 1200] + }, + { + "weeks": [6, 7, 8, 9, 10, 11, 12], + "online": "ZOOM", + "time": ["woensdag", 1430, 1600] } ] }, diff --git a/functions/les.py b/functions/les.py index df4c394..9afb75b 100644 --- a/functions/les.py +++ b/functions/les.py @@ -186,7 +186,7 @@ def getExtras(extra): start, end ) elif "online" in extra["slot"]: - return "**{}** gaat vandaag uitzonderlijk online door {} van **{} tot {}**.".format( + return "**{}** gaat vandaag uitzonderlijk **online** door {} van **{} tot {}**.".format( extra["course"], location[7:], start, end ) From 3967ae3a6cb86fd589ba09c058e1741dde3771ea Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 23:52:23 +0200 Subject: [PATCH 13/14] Comment online links & online groups because they are pointless right now --- functions/les.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/functions/les.py b/functions/les.py index 9afb75b..22fd8fd 100644 --- a/functions/les.py +++ b/functions/les.py @@ -37,7 +37,8 @@ def createEmbed(day, dayDatetime, semester, year, schedule): embed.add_field(name="Geen Les", value="Geen Les", inline=False) else: courseString = createCourseString(courses) - courseString += "\nGroep {} heeft vandaag online les.".format(1 if week % 2 == 0 else 2) + # TODO uncomment this when covid rules slow down + # courseString += "\nGroep {} heeft vandaag online les.".format(1 if week % 2 == 0 else 2) embed.description = courseString if prev: @@ -48,10 +49,10 @@ def createEmbed(day, dayDatetime, semester, year, schedule): # TODO uncomment this when covid rules slow down # Add online links - temporarily removed because everything is online right now - if online: - uniqueLinks: dict = getUniqueLinks(online) - embed.add_field(name="Online Links", value="\n".join( - sorted(getLinks(onlineClass, links) for onlineClass, links in uniqueLinks.items()))) + # if online: + # uniqueLinks: dict = getUniqueLinks(online) + # embed.add_field(name="Online Links", value="\n".join( + # sorted(getLinks(onlineClass, links) for onlineClass, links in uniqueLinks.items()))) embed.set_footer(text="Semester {} | Lesweek {}".format(semester, round(week))) return embed From 89adae5ec11b88975a79e4371a7e80c8ce0a81b2 Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 23 Oct 2020 23:54:58 +0200 Subject: [PATCH 14/14] Change old commnet hours to avoid a ton of ugly code to fix this --- files/schedules/21.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/schedules/21.json b/files/schedules/21.json index 8dfbea0..577dea9 100644 --- a/files/schedules/21.json +++ b/files/schedules/21.json @@ -115,14 +115,14 @@ "campus": "Ardoyen", "building": "Locus", "room": "Resto Locus", - "time": ["woensdag", 1000, 1230] + "time": ["woensdag", 1100, 1200] }, { "online": "ZOOM", "campus": "Ardoyen", "building": "Locus", "room": "Resto Locus", - "time": ["woensdag", 1430, 1700] + "time": ["woensdag", 1430, 1600] }, { "weeks": [6, 7, 8, 9, 10, 11, 12],