first running version
This commit is contained in:
parent
62ad8686d9
commit
b71ab8d8ae
4 changed files with 110 additions and 0 deletions
4
.env.default
Normal file
4
.env.default
Normal file
|
@ -0,0 +1,4 @@
|
|||
CALDAV_USERNAME=
|
||||
CALDAV_PASSWORD=
|
||||
CALDAV_URL=
|
||||
NEXT_DAYS=10
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -162,3 +162,4 @@ cython_debug/
|
|||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
.env
|
80
caldav-reminder.py
Normal file
80
caldav-reminder.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
"""calendar reminder
|
||||
|
||||
this logs into a caldav server and get a digest of all of the
|
||||
events scheduled for next days. Good candidate to run from cron
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from datetime import timedelta, date
|
||||
from os import environ
|
||||
from urllib.parse import quote_plus
|
||||
import caldav
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# read parameters from dot env
|
||||
USERNAME = os.getenv('CALDAV_USERNAME')
|
||||
PASSWORD = os.getenv('CALDAV_PASSWORD')
|
||||
BASE_URL = os.getenv('CALDAV_URL')
|
||||
NEXT_DAYS = int(os.getenv('NEXT_DAYS'))
|
||||
|
||||
|
||||
def fill_event(component, calendar) -> dict[str, str]:
|
||||
# quite some data is tossed away here - like, the recurring rule.
|
||||
cur = {}
|
||||
cur["calendar"] = f"{calendar}"
|
||||
cur["summary"] = component.get("summary")
|
||||
cur["description"] = component.get("description")
|
||||
# month/day/year time? Never ever do that!
|
||||
# It's one of the most confusing date formats ever!
|
||||
# Use year-month-day time instead ... https://xkcd.com/1179/
|
||||
cur["start"] = component.start.strftime("%m/%d/%Y %H:%M")
|
||||
endDate = component.end
|
||||
if endDate:
|
||||
cur["end"] = endDate.strftime("%m/%d/%Y %H:%M")
|
||||
return cur
|
||||
|
||||
|
||||
def fill_todo(component, calendar) -> dict[str, str]:
|
||||
cur = {}
|
||||
cur["calendar"] = f"{calendar}"
|
||||
cur["summary"] = component.get("summary")
|
||||
cur["description"] = component.get("description")
|
||||
return cur
|
||||
|
||||
|
||||
def display_event(event: dict[str, str]):
|
||||
print(event["start"] + " " + event["calendar"] + "/" + event["summary"])
|
||||
|
||||
|
||||
def display_todo(todo: dict[str, str]):
|
||||
print("Todo : " + todo["summary"])
|
||||
|
||||
|
||||
url = 'https://' + quote_plus(USERNAME) + ":" + quote_plus(PASSWORD) \
|
||||
+ '@' + BASE_URL + quote_plus(USERNAME) + '/'
|
||||
start = date.today()
|
||||
end = start + timedelta(days=NEXT_DAYS)
|
||||
client = caldav.DAVClient(url)
|
||||
calendars = client.principal().calendars()
|
||||
|
||||
if not calendars:
|
||||
print("No calendars defined for " + USERNAME)
|
||||
sys.exit(0)
|
||||
|
||||
for cal in calendars:
|
||||
events = cal.search(event=True, start=start, end=end, expand=True) \
|
||||
+ cal.search(todo=True)
|
||||
for event in events:
|
||||
for component in event.icalendar_instance.walk():
|
||||
if component.name == "VEVENT":
|
||||
display_event(fill_event(component, cal))
|
||||
elif component.name == "VTODO":
|
||||
display_todo(fill_todo(component, cal))
|
||||
|
||||
print(".")
|
25
pyproject.toml
Normal file
25
pyproject.toml
Normal file
|
@ -0,0 +1,25 @@
|
|||
[project]
|
||||
name = "caldav-reminder"
|
||||
version = "1.0"
|
||||
description = "CalDav Reminder"
|
||||
readme = "README.md"
|
||||
authors = [
|
||||
{ name = "Yax" }
|
||||
]
|
||||
requires-python = ">=3.13.1"
|
||||
dependencies = [
|
||||
"caldav>=2.0.1",
|
||||
"python-dotenv>=1.1.1",
|
||||
]
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
]
|
||||
|
||||
[tool.setuptools]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=61.0"]
|
||||
build-backend = "setuptools.build_meta"
|
Loading…
Add table
Reference in a new issue