import datetime import os.path from .base import Job # Wrap imports to prevent crashing if dependencies are missing try: import requests import icalendar import recurring_ical_events import pytz HAS_ICAL_DEPS = True except ImportError: HAS_ICAL_DEPS = False class TasksJob(Job): def __init__(self): self.days_to_print = 1 def get_name(self): return "UKOLY DNE" def configure(self): print("\n--- Configure Calendar URL ---") print("To find your Google Calendar URL:") print("1. Go to Settings > Select Calendar > Integrate calendar") print("2. Copy 'Secret address in iCal format'") print("-" * 30) print("Enter the public or secret address in iCal format (.ics).") print("Example: https://calendar.google.com/calendar/ical/.../basic.ics") url = input("URL: ").strip() if url: with open('calendar_url.txt', 'w') as f: f.write(url) print("URL saved.") print("-" * 30) try: d_input = input(f"Number of days to print [{self.days_to_print}]: ").strip() if d_input: self.days_to_print = int(d_input) except ValueError: pass def print_body(self, p): if not HAS_ICAL_DEPS: print("Error: Missing iCal Libraries.") p.text("Error: Missing iCal Libraries.\n") p.text("Run: pip install requests icalendar recurring-ical-events pytz\n") return if not os.path.exists('calendar_url.txt'): print("Error: Calendar URL not configured.") p.text("Error: Calendar URL not configured.\n") p.text("Run configuration in TUI first.\n") return with open('calendar_url.txt', 'r') as f: url = f.read().strip() try: # 1. Fetch the .ics file # Timeout is important so the printer doesn't hang forever response = requests.get(url, timeout=30) response.raise_for_status() # 2. Parse Calendar cal = icalendar.Calendar.from_ical(response.content) # 3. Loop over days base_now = datetime.datetime.now().astimezone() for i in range(self.days_to_print): p.cut() target_date = base_now + datetime.timedelta(days=i) # Print Calendar Name cal_name = cal.get('X-WR-CALNAME') if cal_name: p.set(align='center', bold=True) p.text(f"{str(cal_name)}\n") days_cz = ["Pondělí", "Úterý", "Středa", "Čtvrtek", "Pátek", "Sobota", "Neděle"] p.text(f"{days_cz[target_date.weekday()]} {target_date.strftime('%d.%m.%Y')}\n") p.set(align='left', bold=False) p.text("-" * 32 + "\n") start_of_day = target_date.replace(hour=0, minute=0, second=0, microsecond=0) end_of_day = target_date.replace(hour=23, minute=59, second=59, microsecond=0) # 4. Expand Recurring Events events = recurring_ical_events.of(cal).between(start_of_day, end_of_day) # 5. Sort by start time def get_start_time(e): dt = e.get('DTSTART').dt if not isinstance(dt, datetime.datetime): return datetime.datetime.combine(dt, datetime.time.min).replace(tzinfo=base_now.tzinfo) return dt events.sort(key=get_start_time) if not events: p.text("Zadne ukoly.\n") else: for event in events: summary = str(event.get('SUMMARY', '(bez nazvu)')) dtstart = event.get('DTSTART').dt if not isinstance(dtstart, datetime.datetime): time_str = "Cely den" else: local_dt = dtstart.astimezone(base_now.tzinfo) time_str = local_dt.strftime('%H:%M') p.set(bold=True) p.text(f"{time_str} [_]") p.set(bold=False) p.text(f" {summary}\n") location = event.get('LOCATION') if location: p.text(f" @ {str(location)}\n") p.text("-" * 32 + "\n") except Exception as e: print(f"Error: {e}") p.text(f"Error: {e}\n")