Support to show the schedule for a requested day AFTER holidays

pull/84/head
Stijn De Clercq 2021-08-06 20:52:56 +02:00
parent ee3ee5284d
commit 54d31c943a
6 changed files with 211 additions and 55 deletions

View File

@ -1,12 +1,12 @@
import random import random
from data import constants from data import constants, schedule
from decorators import help from decorators import help
import discord import discord
from discord.ext import commands from discord.ext import commands
from enums.courses import years from enums.courses import years
from enums.help_categories import Category from enums.help_categories import Category
from functions import checks, eten, les from functions import checks, eten, les, les_rework
import json import json
@ -44,7 +44,9 @@ class School(commands.Cog):
@commands.command(name="Les", aliases=["Class", "Classes", "Sched", "Schedule"], usage="[Jaargang]* [Dag]*") @commands.command(name="Les", aliases=["Class", "Classes", "Sched", "Schedule"], usage="[Jaargang]* [Dag]*")
# @commands.check(checks.allowedChannels) # @commands.check(checks.allowedChannels)
@help.Category(category=Category.School) @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 return
# parsed = les.parseArgs(day) # parsed = les.parseArgs(day)
# #

View File

@ -1,32 +1,31 @@
import json
from dacite import from_dict from dacite import from_dict
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime, timedelta from datetime import datetime, timedelta
from enums.platforms import Platforms from enums.platforms import Platforms
from functions.config import get from functions.config import get
from functions.timeFormatters import fromArray, forward_to_weekday
import json
from typing import Dict, Optional, List from typing import Dict, Optional, List
from functions.timeFormatters import fromArray
@dataclass @dataclass
class Holiday: class Holiday:
start_list: List[int] start_date: List[int]
end_list: List[int] end_date: List[int]
start_date: datetime = field(init=False) start_date_parsed: datetime = field(init=False)
end_date: datetime = field(init=False) end_date_parsed: datetime = field(init=False)
duration: timedelta = field(init=False) duration: timedelta = field(init=False)
def __post_init__(self): def __post_init__(self):
self.start_date = fromArray(self.start_list) self.start_date_parsed = fromArray(self.start_date)
self.end_date = fromArray(self.end_list) self.end_date_parsed = fromArray(self.end_date)
self.duration = self.end_date - self.start_date self.duration = self.end_date_parsed - self.start_date_parsed
def has_passed(self, current_day: datetime) -> bool: def has_passed(self, current_day: datetime) -> bool:
""" """
Check if a holiday has passed already Check if a holiday has passed already
""" """
return current_day > self.end_date return current_day > self.end_date_parsed
@dataclass @dataclass
@ -58,12 +57,14 @@ class Timeslot:
@dataclass @dataclass
class Schedule: class Schedule:
day: datetime day: datetime
targetted_weekday: bool = False
schedule_dict: Dict = field(init=False) schedule_dict: Dict = field(init=False)
start_date: datetime start_date: datetime = field(init=False)
end_date: datetime end_date: datetime = field(init=False)
semester_over: bool = False semester_over: bool = False
holiday_offset: int = 0 holiday_offset: int = 0
current_holiday: Optional[Holiday] = None current_holiday: Optional[Holiday] = None
_weekday_str: str = field(init=False)
def __post_init__(self): def __post_init__(self):
self.schedule_dict: Dict = self.load_schedule_file() self.schedule_dict: Dict = self.load_schedule_file()
@ -77,9 +78,20 @@ class Schedule:
self.check_holidays() 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 # Show schedule for after holidays
if self.current_holiday is not None: 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): def check_holidays(self):
""" """
@ -89,13 +101,13 @@ class Schedule:
holiday: Holiday = from_dict(Holiday, hol_entry) holiday: Holiday = from_dict(Holiday, hol_entry)
# Hasn't happened yet, don't care # Hasn't happened yet, don't care
if holiday.start_date > self.day: if holiday.start_date_parsed > self.day:
continue continue
# In the past: add the offset # In the past: add the offset
if holiday.has_passed(self.day): if holiday.has_passed(self.day):
self.holiday_offset += (self.day - holiday.end_date) // 7 self.holiday_offset += (self.day - holiday.end_date_parsed) // 7
elif holiday.start_date <= self.day <= holiday.end_date: elif holiday.start_date_parsed <= self.day <= holiday.end_date_parsed:
self.current_holiday = holiday self.current_holiday = holiday
def load_schedule_file(self) -> Dict: def load_schedule_file(self) -> Dict:
@ -105,7 +117,7 @@ class Schedule:
semester = get("semester") semester = get("semester")
year = get("year") 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) return json.load(fp)
def get_week(self) -> int: 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 # 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 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): def create_schedule(self):
""" """
Create the schedule for the current week Create the schedule for the current week

View File

@ -1 +1 @@
{"semester": "2", "year": "2", "years": 2, "jpl": 161733, "jpl_day": 24} {"semester": "1", "year": "3", "years": 3, "jpl": 161733, "jpl_day": 24}

View File

@ -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
]
}
]
}
]
}

View File

@ -1,5 +1,5 @@
from datetime import datetime, timedelta 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 from typing import Optional
@ -28,31 +28,3 @@ def find_target_date(arg: Optional[str]) -> datetime:
day = skip_weekends(day) day = skip_weekends(day)
return 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))

View File

@ -138,13 +138,15 @@ def getPlural(amount, unit):
return dic[unit.lower()]["s" if amount == 1 else "p"] 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} days = {"maandag": 0, "dinsdag": 1, "woensdag": 2, "donderdag": 3, "vrijdag": 4, "zaterdag": 5, "zondag": 6}
if day.lower() not in days: # Allow abbreviations
return -1 for d, i in days.items():
if d.startswith(day):
return i
return days[day.lower()] return -1
def intToWeekday(day): def intToWeekday(day):
@ -164,3 +166,31 @@ def fromArray(data: List[int]) -> datetime:
year = str(data[2]) year = str(data[2])
return fromString(f"{day}/{month}/{year}") 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))