diff --git a/flake.nix b/flake.nix index 443d6ab..47bb495 100644 --- a/flake.nix +++ b/flake.nix @@ -4,15 +4,81 @@ let pkgs = nixpkgs.legacyPackages.x86_64-linux; my-python = pkgs.python3; + tkcalendar = pkgs.python3Packages.buildPythonPackage rec { + pname = "tkcalendar"; + version = "1.6.1"; + + src = pkgs.fetchFromGitHub { + owner = "j4321"; + repo = "tkcalendar"; + rev = "v${version}"; + sha256 = "Z5Sg1kT9VS0WNyJ3nXXhKbzL1VEXwkbF4bV8OwprYfE="; + }; + + propagatedBuildInputs = [ + pkgs.python310Packages.tkinter + pkgs.python310Packages.babel + ]; + + doCheck = false; + pythonImportsCheck = [ "tkcalendar" ]; + }; + + calcure = pkgs.python3Packages.buildPythonApplication rec { + pname = "calcure"; + version = "2.6"; + + src = pkgs.fetchFromGitHub { + owner = "anufrievroman"; + repo = "calcure"; + rev = "${version}"; + sha256 = "VvK8kLQd8JKaLQoxtMbweOKnR9nKMEnlj0103DeLXRI="; + }; + + propagatedBuildInputs = [ + pkgs.python310Packages.holidays + pkgs.python310Packages.jdatetime + ]; + + # doCheck = false; + }; + + ttkbootstrap = pkgs.python3Packages.buildPythonPackage rec { + pname = "ttkbootstrap"; + version = "1.10.0"; + + src = pkgs.fetchFromGitHub { + owner = "israel-dryer"; + repo = "ttkbootstrap"; + rev = "v${version}"; + sha256 = "tWzpgNv54uuB9hntO/iek6zrH4RWk9MrREXdwpDRDPw="; + }; + + propagatedBuildInputs = [ + pkgs.python310Packages.pillow + pkgs.python310Packages.tkinter + ]; + + # doCheck = false; + pythonImportsCheck = [ "ttkbootstrap" ]; + }; + python-with-my-packages = my-python.withPackages (p: with p; [ tkinter + tkcalendar + ttkbootstrap + ical ]); in { + packages.tkcalendar = pkgs.callPackage tkcalendar { }; + packages.ttkbootsrap = pkgs.callPackage ttkbootstrap { }; + packages.calcure = pkgs.callPackage calcure { }; devShell.x86_64-linux = pkgs.mkShell { buildInputs = with pkgs; [ yad python-with-my-packages + calcure ]; }; }; diff --git a/tkinter-caldav-calendar.py b/tkinter-caldav-calendar.py index 40209a4..4cd4867 100644 --- a/tkinter-caldav-calendar.py +++ b/tkinter-caldav-calendar.py @@ -1,54 +1,66 @@ from tkinter import * from tkinter import ttk -import sys -import subprocess +from pydantic import ValidationError +from tkcalendar import Calendar +from datetime import datetime +from os import listdir +from ical.calendar_stream import IcsCalendarStream -calendar = subprocess.check_output(["cal", "-m"]) -calendar = calendar.decode("utf-8") -calendar = calendar.split("\n") -calendar = [x.split() for x in calendar] +# Later on... +# Import all ICS events into Tkinter Events +# for e in c.events: +# print(e.name) -today = subprocess.check_output(["date", "+\"%d\""]) -today = today.decode("utf-8")[:-1] -today = today.strip("\"") - -month_year = calendar[0] -calendar_fields = [calendar[1], calendar[2], calendar[3], calendar[4], calendar[5], calendar[6]] +### TKINTER Setup root = Tk() -root.geometry("+0+0") -root.attributes("-type", "dialog") +root.geometry("+0+0") # TODO set location of tkinter dialog +root.attributes("-type", "dialog") + +style = ttk.Style(root) +style.theme_use("clam") frame = ttk.Frame(root) frame.grid() -date_label = ttk.Label(frame, text=" ".join(month_year)).grid(row=0, columnspan=7) -prev_month_button = ttk.Button(frame, text="<", command=exit, width=1).grid(row=0, column=0) -next_month_button = ttk.Button(frame, text=">", command=exit, width=1).grid(row=0, column=6) +calendar = Calendar(frame) +calendar.grid(row=0,columnspan=7) +calendar.calevent_create(date=datetime(2022, 12, 16), text="today") -def get_agenda(date): - date = "2022-12-" + date - agenda = subprocess.check_output(["khal", "list", date, date]) - agenda = agenda.decode("utf-8")[:-1] - agenda = agenda.split("\n")[1] - return agenda +### ICS setup +# List calendar folder (~/.calendar/) +calendar_folder = '/home/anish/.calendar/' +# Recurse through each folder +for c in listdir(calendar_folder): + files = listdir(calendar_folder + c) + full_text: str = "" + for file in files: + try: + with open(calendar_folder + c + "/" + file, 'r') as in_file: + cal = IcsCalendarStream.calendar_from_ics(in_file.read()) + for e in cal.events: + calendar.calevent_create(date=e.dtstart, text=e.summary) + except ValidationError: + print(f"Could not parse file: {calendar_folder}{c}") -row_count = 1 -column_count = 0 -for r in calendar_fields: - for c in r: - if c == today: - label = ttk.Label(frame, text=c, background="green").grid(row=row_count, column=column_count) - else: - label = ttk.Label(frame, text=c).grid(row=row_count, column=column_count) - column_count += 1 - column_count = 0 - row_count += 1 +agenda_var = StringVar() +agenda_var.set("") -agenda_label = ttk.Label(frame, text=get_agenda(today)).grid(row=row_count+1, columnspan=7) +def update_agenda(_): + date = calendar.selection_get() + new_agenda = calendar.get_calevents(date) + if new_agenda: + new_agenda = calendar.calevent_cget(new_agenda[0], "text") # TODO list *all* events + agenda_var.set(new_agenda) + root.update_idletasks() + else: + agenda_var.set("") -def exit(): - sys.exit() +agenda_label = ttk.Label(frame, textvariable=agenda_var) +agenda_label.grid(rowspan=13, columnspan=7) # TODO make agenda bigger to accomodate multiple events + +update_agenda("") # initial set of agenda +root.bind("<>", update_agenda) root.mainloop()