From 54d31c943a99599bf678f3dd9f95e4977097d1f2 Mon Sep 17 00:00:00 2001 From: Stijn De Clercq Date: Fri, 6 Aug 2021 20:52:56 +0200 Subject: [PATCH] Support to show the schedule for a requested day AFTER holidays --- cogs/school.py | 8 ++- data/schedule.py | 54 ++++++++++----- files/config.json | 2 +- files/schedules/31.json | 134 ++++++++++++++++++++++++++++++++++++ functions/les_rework.py | 30 +------- functions/timeFormatters.py | 38 ++++++++-- 6 files changed, 211 insertions(+), 55 deletions(-) create mode 100644 files/schedules/31.json diff --git a/cogs/school.py b/cogs/school.py index 89e68fe..72fd9a4 100644 --- a/cogs/school.py +++ b/cogs/school.py @@ -1,12 +1,12 @@ import random -from data import constants +from data import constants, schedule 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, les +from functions import checks, eten, les, les_rework import json @@ -44,7 +44,9 @@ class School(commands.Cog): @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): + async def les(self, ctx, day=None): + date = les_rework.find_target_date(day) + s = schedule.Schedule(date, day is not None) return # parsed = les.parseArgs(day) # diff --git a/data/schedule.py b/data/schedule.py index 45cdcd2..d489539 100644 --- a/data/schedule.py +++ b/data/schedule.py @@ -1,32 +1,31 @@ -import json from dacite import from_dict from dataclasses import dataclass, field from datetime import datetime, timedelta from enums.platforms import Platforms from functions.config import get +from functions.timeFormatters import fromArray, forward_to_weekday +import json from typing import Dict, Optional, List -from functions.timeFormatters import fromArray - @dataclass class Holiday: - start_list: List[int] - end_list: List[int] - start_date: datetime = field(init=False) - end_date: datetime = field(init=False) + start_date: List[int] + end_date: List[int] + start_date_parsed: datetime = field(init=False) + end_date_parsed: datetime = field(init=False) duration: timedelta = field(init=False) def __post_init__(self): - self.start_date = fromArray(self.start_list) - self.end_date = fromArray(self.end_list) - self.duration = self.end_date - self.start_date + self.start_date_parsed = fromArray(self.start_date) + self.end_date_parsed = fromArray(self.end_date) + self.duration = self.end_date_parsed - self.start_date_parsed def has_passed(self, current_day: datetime) -> bool: """ Check if a holiday has passed already """ - return current_day > self.end_date + return current_day > self.end_date_parsed @dataclass @@ -58,12 +57,14 @@ class Timeslot: @dataclass class Schedule: day: datetime + targetted_weekday: bool = False schedule_dict: Dict = field(init=False) - start_date: datetime - end_date: datetime + start_date: datetime = field(init=False) + end_date: datetime = field(init=False) semester_over: bool = False holiday_offset: int = 0 current_holiday: Optional[Holiday] = None + _weekday_str: str = field(init=False) def __post_init__(self): self.schedule_dict: Dict = self.load_schedule_file() @@ -77,9 +78,20 @@ class Schedule: self.check_holidays() + # Store the target weekday (in case it exists) so we can ask for the next + # friday after the holiday, for example + target_weekday = -1 if not self.targetted_weekday else self.day.weekday() + # Show schedule for after holidays if self.current_holiday is not None: - self.day = self.current_holiday.end_date + timedelta(days=1) + # Set day to day after holiday + self.day = self.current_holiday.end_date_parsed + timedelta(days=1) + + # Find the next [DAY] after the holidays + if target_weekday != -1: + self.day = forward_to_weekday(self.day, target_weekday) + + print(self.day) def check_holidays(self): """ @@ -89,13 +101,13 @@ class Schedule: holiday: Holiday = from_dict(Holiday, hol_entry) # Hasn't happened yet, don't care - if holiday.start_date > self.day: + if holiday.start_date_parsed > self.day: continue # In the past: add the offset if holiday.has_passed(self.day): - self.holiday_offset += (self.day - holiday.end_date) // 7 - elif holiday.start_date <= self.day <= holiday.end_date: + self.holiday_offset += (self.day - holiday.end_date_parsed) // 7 + elif holiday.start_date_parsed <= self.day <= holiday.end_date_parsed: self.current_holiday = holiday def load_schedule_file(self) -> Dict: @@ -105,7 +117,7 @@ class Schedule: semester = get("semester") year = get("year") - with open(f"files/{year}{semester}.json", "r") as fp: + with open(f"files/schedules/{year}{semester}.json", "r") as fp: return json.load(fp) def get_week(self) -> int: @@ -121,6 +133,12 @@ class Schedule: # Add +1 at the end because week 1 would be 0 as it's not over yet return (diff.days // 7) + self.holiday_offset + 1 + def find_slot_for_course(self, course_dict: Dict) -> List[Timeslot]: + """ + Create time timeslots for a course + """ + pass + def create_schedule(self): """ Create the schedule for the current week diff --git a/files/config.json b/files/config.json index dd9aec4..3d513ac 100644 --- a/files/config.json +++ b/files/config.json @@ -1 +1 @@ -{"semester": "2", "year": "2", "years": 2, "jpl": 161733, "jpl_day": 24} \ No newline at end of file +{"semester": "1", "year": "3", "years": 3, "jpl": 161733, "jpl_day": 24} \ No newline at end of file diff --git a/files/schedules/31.json b/files/schedules/31.json new file mode 100644 index 0000000..105e311 --- /dev/null +++ b/files/schedules/31.json @@ -0,0 +1,134 @@ +{ + "semester_start": [1, 7, 2021], + "semester_end": [16, 8, 2021], + "holidays": [ + { + "start_date": [2, 7, 2021], + "end_date": [10, 8, 2021] + } + ], + "schedule": [ + { + "course": "Computerarchitectuur", + "zoom": "https://ufora.ugent.be/d2l/ext/rp/228912/lti/framedlaunch/556e197e-e87b-4c27-be5d-53adc7a41826", + "msteams": "https://teams.microsoft.com/l/team/19%3ad7295f0bc4634a61b461504d4a7134b3%40thread.tacv2/conversations?groupId=8755cb96-1ef5-4ea3-b806-eeebf8a85ae8&tenantId=d7811cde-ecef-496c-8f91-a1786241b99c", + "slots": [ + ] + }, + { + "course": "Multimedia", + "zoom": "https://ugent-be.zoom.us/j/94248831947?pwd=ZCt4UnBLSzViZnFEQmkzWE5SYnF2QT09", + "slots": [ + { + "campus": "Sterre", + "building": "S9", + "room": "A3", + "time": [ + "woensdag", + 1130, + 1330 + ] + }, + { + "online": "ZOOM", + "time": [ + "vrijdag", + 1300, + 1530 + ] + } + ] + }, + { + "course": "Wetenschappelijk Rekenen", + "zoom": "https://ufora.ugent.be/d2l/ext/rp/236404/lti/framedlaunch/556e197e-e87b-4c27-be5d-53adc7a41826", + "slots": [ + { + "online": "ZOOM", + "time": [ + "dinsdag", + 1130, + 1300 + ] + }, + { + "online": "ZOOM", + "time": [ + "woensdag", + 1500, + 1800 + ] + }, + { + "online": "ZOOM", + "time": [ + "donderdag", + 830, + 1000 + ] + } + ] + }, + { + "course": "Software Engineering Lab 1", + "zoom": "https://ufora.ugent.be/d2l/ext/rp/235800/lti/framedlaunch/556e197e-e87b-4c27-be5d-53adc7a41826", + "msteams": "https://teams.microsoft.com/l/team/19%3a4dfd5b2fb1ae4aa9b72706aa3a0d6867%40thread.tacv2/conversations?groupId=256d5c58-5d53-43f5-9436-497b0c852c75&tenantId=d7811cde-ecef-496c-8f91-a1786241b99c", + "slots": [ + { + "online": "MS Teams", + "time": [ + "dinsdag", + 1430, + 1700 + ] + }, + { + "online": "MS Teams", + "time": [ + "vrijdag", + 830, + 1130 + ] + } + ] + }, + { + "course": "Webdevelopment", + "zoom": "https://ugent-be.zoom.us/j/93166767783?pwd=MWdvb1BnNnlPSnAyNk52QmRzdjcwdz09", + "slots": [ + { + "campus": "Sterre", + "building": "S9", + "room": "A3", + "time": [ + "woensdag", + 900, + 1100 + ] + }, + { + "weeks": [ + 1 + ], + "canceled": true, + "campus": "Sterre", + "building": "S9", + "room": "A3", + "time": [ + "woensdag", + 900, + 1100 + ] + }, + { + "online": "ZOOM", + "time": [ + "donderdag", + 1000, + 1300 + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/functions/les_rework.py b/functions/les_rework.py index 6646a4a..1682150 100644 --- a/functions/les_rework.py +++ b/functions/les_rework.py @@ -1,5 +1,5 @@ from datetime import datetime, timedelta -from timeFormatters import dateTimeNow, weekdayToInt +from functions.timeFormatters import dateTimeNow, weekdayToInt, forward_to_weekday, skip_weekends from typing import Optional @@ -28,31 +28,3 @@ def find_target_date(arg: Optional[str]) -> datetime: day = skip_weekends(day) return day - - -def skip_weekends(day: datetime) -> datetime: - """ - Increment the current date if it's not a weekday - """ - weekday = day.weekday() - - # Friday is weekday 4 - if weekday > 4: - return day + timedelta(days=(7 - weekday)) - - return day - - -def forward_to_weekday(day: datetime, weekday: int) -> datetime: - """ - Increment a date until the weekday is the same as the one provided - Finds the "next" [weekday] - """ - current = day.weekday() - - # This avoids negative numbers below, and shows - # next week in case the days are the same - if weekday >= current: - weekday += 7 - - return day + timedelta(days=(weekday - current)) diff --git a/functions/timeFormatters.py b/functions/timeFormatters.py index 58e6712..3d49476 100644 --- a/functions/timeFormatters.py +++ b/functions/timeFormatters.py @@ -138,13 +138,15 @@ def getPlural(amount, unit): return dic[unit.lower()]["s" if amount == 1 else "p"] -def weekdayToInt(day) -> int: +def weekdayToInt(day: str) -> int: days = {"maandag": 0, "dinsdag": 1, "woensdag": 2, "donderdag": 3, "vrijdag": 4, "zaterdag": 5, "zondag": 6} - if day.lower() not in days: - return -1 + # Allow abbreviations + for d, i in days.items(): + if d.startswith(day): + return i - return days[day.lower()] + return -1 def intToWeekday(day): @@ -164,3 +166,31 @@ def fromArray(data: List[int]) -> datetime: year = str(data[2]) return fromString(f"{day}/{month}/{year}") + + +def skip_weekends(day: datetime) -> datetime: + """ + Increment the current date if it's not a weekday + """ + weekday = day.weekday() + + # Friday is weekday 4 + if weekday > 4: + return day + datetime.timedelta(days=(7 - weekday)) + + return day + + +def forward_to_weekday(day: datetime, weekday: int) -> datetime: + """ + Increment a date until the weekday is the same as the one provided + Finds the "next" [weekday] + """ + current = day.weekday() + + # This avoids negative numbers below, and shows + # next week in case the days are the same + if weekday <= current: + weekday += 7 + + return day + datetime.timedelta(days=(weekday - current))