{ pkgs, ... }@all: with all; { systemd.timers."nx_cal_dicos" = { enable = true; wantedBy = [ "timers.target" ]; timerConfig = { OnBootSec = "40m"; OnUnitActiveSec = "12h"; Unit = "nx_cal_dicos.service"; }; }; systemd.services."nx_cal_dicos" = { script = let nx_cal_dicos = (pkgs.writers.writePython3Bin "nx_cal_dicos" { libraries = with pkgs.python3Packages; [ ics ]; flakeIgnore = [ "E302" "E305" "E226" "E501" ]; } /* python */ '' import os from glob import glob from ics import Calendar from ics.event import datetime NETTO_STUNDE = 18.46 WEEKLY = 12 # week_dict = {} # latest_week = 0 # latest_goal = WEEKLY deficit = 0 def fraction_to_unicode(frac): div, rem = divmod(frac, 1) if rem == 0.5: unicode = "½" elif rem == 0.25: unicode = "¼" elif rem == 0.75: unicode = "¾" elif rem == 0: unicode = "" else: unicode = rem if div == 0: h = "" else: h = int(div) return f"{h}{unicode}" def modify_event(event): """Modify the event if it contains 'DICOS' in the SUMMARY.""" # global week_dict # global latest_goal # global latest_week # global deficit if event.name is not None and "DICOS" in event.name: length = (event.end - event.begin).seconds / 3600 money_made = divmod(length * NETTO_STUNDE, 1) # Calculate total hours for DICOS events in the same week year, week, _ = event.begin.isocalendar() # if week != latest_week: # try: # deficit = latest_goal - week_dict[f"{year}_{latest_week}"] # except KeyError: # deficit = 0 # week_dict[f"{year}_{week}"] = length + (week_dict[f"{year}_{week}"] if f"{year}_{week}" in week_dict else 0) # progress = week_dict[f"{year}_{week}"] # goal = WEEKLY + deficit # if week != latest_week: # latest_goal = goal # latest_week = week try: new_description = [event.description.split("\n")[0]] except AttributeError: new_description = ["::"] new_description.append("") new_description.append(f"Netto: {money_made[0]:.0f},{int(money_made[1] * 10):02d}€") # new_description.append(f"This weeks porgress: ({fraction_to_unicode(progress)}/{fraction_to_unicode(goal)})") # new_description.append(f"You're {fraction_to_unicode(abs(deficit))}h in the {'plus' if deficit < 0 else 'minus'} this week.") event.description = "\n".join(new_description) event.name = f"DICOS {fraction_to_unicode(length)}" return event def process_ics_file(filepath): """Read, modify, and overwrite an ICS file.""" with open(filepath, 'r') as f: calendar = Calendar(f.read()) modified = False for event in calendar.events: if event.name is not None and 'DICOS' in event.name: event = modify_event(event) modified = True if modified: with open(filepath, 'w') as f: f.writelines(calendar.serialize_iter()) def get_event_start_time(filepath): """Extract the event's start time from an ICS file.""" with open(filepath, 'r') as f: calendar = Calendar(f.read()) for event in calendar.events: return event.begin.datetime else: return datetime(year=1, month=1, day=1) if __name__ == "__main__": directory = "/var/lib/radicale/collections/collection-root/nx2/experience" ics_files = glob(os.path.join(directory, "*.ics")) if not ics_files: print("No ICS files found in the directory.") sorted_files = sorted(ics_files, key=get_event_start_time) for ics_file in sorted_files: process_ics_file(ics_file) print("Processing complete.") ''); in '' ${nx_cal_dicos}/bin/nx_cal_dicos ''; serviceConfig = { Type = "oneshot"; User = "radicale"; }; }; }