From 0f1b60f520f94118905071e24de89a76f789f67a Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Thu, 6 Apr 2023 12:06:30 +0200 Subject: support formatting special events This is usefull to include events like holidays or semester end in the formatted output. I use the following config ```toml [special_events.Notenschluss] pattern = "Notenschluss*" fmt = '''\\rowcolor{{yellow!30}} \\multicolumn{{5}}{{c}}{{{event.start.date().strftime('%d.%m')} {event.summary}}} \\\\''' [special_events.Ferien] pattern = "*ferien*" fmt = '''\\rowcolor{{yellow!30}} \\multicolumn{{5}}{{c}}{{{event.start.date().strftime('%d.%m')}-{event.end.date().strftime('%d.%m')} {event.summary}}} \\\\''' ``` to include any holidays as well as the semester end in my formatted latex table. --- lessons.py | 61 +++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/lessons.py b/lessons.py index cd9b4d9..71a90e6 100755 --- a/lessons.py +++ b/lessons.py @@ -4,6 +4,7 @@ import argparse from dataclasses import dataclass import datetime +import fnmatch from getpass import getpass import pathlib import os @@ -72,6 +73,26 @@ def load_events(config: dict) -> list[icalevents.icalparser.Event]: return evs +def filter_special_events( + evs: list[icalevents.icalparser.Event], + special_events_definitions: dict[str, dict[str, str]] +) -> list[tuple[icalevents.icalparser.Event, str]]: + """Filter all events for special events and return a sorted list""" + + special_events = [] + for special_event in special_events_definitions: + pattern, fmt = special_events_definitions[special_event].values() + for event in evs: + if not fnmatch.fnmatch(event.summary, pattern): + continue + + special_events.append((event, eval('f' + f'"{fmt}"'))) # pylint: disable=eval-used + + # Sort the special events by their start datetime + special_events.sort(key=lambda t: t[0].start) + return special_events + + def format_period(period: webuntis.objects.PeriodObject, evs: list[icalevents.icalparser.Event], config: dict) -> str: """Format a given period""" @@ -175,21 +196,37 @@ def main(): start=config['start'], end=config['end']) - evs = [] - if args.show_events: - evs = load_events(config) + periods = filter_periods(timetable, config) + + # load ICS events + evs = load_events(config) + + # filter special events + special_events = filter_special_events(evs, + config.get('special_events', {})) + + lines = [] + for period in periods: + # Insert formatted prior special event + if special_events and special_events[0][0].start.timestamp( + ) <= period.start.timestamp(): + lines.append(special_events[0][1]) + special_events = special_events[1:] + + if period.code: + print(f'WARNING: period {period.start} is {period.code}', + file=sys.stderr) + + lines.append(format_period(period, evs, config)) - if 'output_header' in config: - print(config['output_header']) + if 'output_header' in config: + print(config['output_header']) - for period in filter_periods(timetable, config): - if period.code: - print(f'WARNING: period {period.start} is {period.code}', - file=sys.stderr) - print(format_period(period, evs, config)) + for line in lines: + print(line) - if 'output_footer' in config: - print(config['output_footer']) + if 'output_footer' in config: + print(config['output_footer']) if __name__ == '__main__': -- cgit v1.2.3