From a5c8d284ee60e12ba08e2e075e06749c239f6dbf Mon Sep 17 00:00:00 2001 From: "Lennart J. Kurzweg (Nx2)" Date: Thu, 30 Jan 2025 13:41:27 +0100 Subject: [PATCH] calendar-lec --- configuration.nix | 1 + home-modules/calendar.nix | 2 +- system-modules/calendar-lec.nix | 97 +++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 system-modules/calendar-lec.nix diff --git a/configuration.nix b/configuration.nix index fdc5800..5a4cde4 100644 --- a/configuration.nix +++ b/configuration.nix @@ -44,6 +44,7 @@ ./system-modules/postgres.nix ./system-modules/nx2site/proxy.nix ./system-modules/calendar-publish.nix + ./system-modules/calendar-lec.nix ./system-modules/nx2site/audiobookshelf.nix ./system-modules/nx2site/gitea.nix ./system-modules/nx2site/open-web-calendar.nix diff --git a/home-modules/calendar.nix b/home-modules/calendar.nix index 27069f5..c728d35 100644 --- a/home-modules/calendar.nix +++ b/home-modules/calendar.nix @@ -35,7 +35,7 @@ } { name = "LEC"; - url = "https://zlypher.github.io/lol-events/cal/league-of-legends-lec.ical"; + url = "https://${domain}/lec.ics"; color = "#A87000"; read-only = true; type = "ics"; diff --git a/system-modules/calendar-lec.nix b/system-modules/calendar-lec.nix new file mode 100644 index 0000000..0fd5742 --- /dev/null +++ b/system-modules/calendar-lec.nix @@ -0,0 +1,97 @@ +{ config, pkgs, user, domain, ... }: +{ + systemd.timers."nx_cal_lec" = { + enable = true; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = "40m"; + OnUnitActiveSec = "24h"; + Unit = "nx_cal_lec.service"; + }; + }; + + systemd.services."nx_cal_lec" = { + script = let + nx_cal_lec = (pkgs.writers.writePython3Bin "nx_cal_lec" { + libraries = with pkgs.python3Packages; [ + ical + ics + requests + dateutils + ]; + flakeIgnore = [ "E302" "E305" "E226" "E501" ]; + } /*python */ '' +import hashlib +from ics import Calendar +import requests +from datetime import timedelta + +def get_event_hash(event): + """ + Generate a unique hash for an event based on its details. + """ + event_data = f"{event.name}{event.begin}{event.end}{event.description}" + return hashlib.md5(event_data.encode('utf-8')).hexdigest() + +def adjust_events(events): + """ + Adjust overlapping events to ensure they do not conflict. + """ + sorted_events = sorted(events, key=lambda e: e.begin) + for i in range(1, len(sorted_events)): + previous_event = sorted_events[i - 1] + current_event = sorted_events[i] + + if current_event.begin < previous_event.end: + # Adjust the start time of the current event to just after the previous event + current_event.begin = previous_event.end + timedelta(minutes=1) + print(f"Adjusted event '{current_event.name}' to start at {current_event.begin} and end at {current_event.end}") + return sorted_events + +def fetch_and_save_ical_events(ical_url, save_path): + """ + Fetch events from an iCal URL and save them as a single combined calendar. + """ + try: + # Fetch the iCal data + response = requests.get(ical_url) + response.raise_for_status() + + # Parse the iCal data + calendar = Calendar(response.text) + + # Adjust events + adjusted_events = adjust_events(list(calendar.events)) + + # Create a new combined calendar + combined_calendar = Calendar() + for event in adjusted_events: + combined_calendar.events.add(event) + + # Save the combined calendar to a single .ics file + with open(save_path, 'w') as file: + file.writelines(combined_calendar.serialize_iter()) + + print(f"Saved combined calendar to {save_path}") + + except requests.exceptions.RequestException as e: + print(f"Error fetching iCal data: {e}") + except Exception as e: + print(f"Error processing iCal data: {e}") + +if __name__ == "__main__": + # Replace with your iCal URL and target file path + ICAL_URL = "https://zlypher.github.io/lol-events/cal/league-of-legends-lec.ical" + SAVE_PATH = "${config.services.nginx.virtualHosts."${domain}".root}/lec.ics" + + fetch_and_save_ical_events(ICAL_URL, SAVE_PATH) +''); + in '' + ${nx_cal_lec}/bin/nx_cal_lec + ''; + serviceConfig = { + Type = "oneshot"; + User = "nx2"; + }; + }; +}