Update Makefile, README and service file for remindme_caldav
- The Makefile now includes installation instructions for Debian/Ubuntu based systems. - The README has been updated with more detailed descriptions of the script's purpose, how it works, and how to use it. - The service file has been added to manage the remindme_caldav daemon on a systemd-based system.
This commit is contained in:
parent
740ac039dd
commit
8fe759673d
|
@ -0,0 +1,18 @@
|
|||
install:
|
||||
sudo apt-get update && sudo apt-get install -y python3.11 python3.11-venv
|
||||
python3.11 -m venv /opt/remindme_caldav/.venv
|
||||
source /opt/remindme_caldav/.venv/bin/activate && pip install --upgrade pip && pip install -r requirements.txt
|
||||
cp remindme_caldav.py /opt/remindme_caldav/
|
||||
sudo cp remindme_caldav.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable remindme_caldav.service
|
||||
sudo systemctl start remindme_caldav.service
|
||||
|
||||
uninstall:
|
||||
sudo systemctl stop remindme_caldav.service
|
||||
sudo systemctl disable remindme_caldav.service
|
||||
rm -rf /opt/remindme_caldav
|
||||
rm /etc/systemd/system/remindme_caldav.service
|
||||
|
||||
clean:
|
||||
deactivate
|
66
README.md
66
README.md
|
@ -1,3 +1,67 @@
|
|||
# remindme_caldav
|
||||
## A Calendar Alerting Daemon
|
||||
|
||||
## Purpose
|
||||
This script is a simple calendar alerting daemon written in Python. It monitors
|
||||
.ics files for changes and sends alerts based on the events' start times,
|
||||
recurrence rules, and alert triggers defined within these files. The main
|
||||
purpose of this script is to provide reminders or notifications about upcoming
|
||||
events.
|
||||
|
||||
## How it Works
|
||||
The script works by parsing .ics files using the `icalendar` library, which
|
||||
converts them into a Python dictionary format for easier manipulation. It then
|
||||
processes each event and calculates when the next alert should be triggered
|
||||
based on the event's start time, recurrence rules, and alert triggers. If an
|
||||
alert is due to trigger, it sends a notification via email or XMPP (an instant
|
||||
messaging protocol).
|
||||
|
||||
The script also monitors for changes in the directory containing .ics files
|
||||
using the `watchdog` library. When a file is modified, created, or deleted, it
|
||||
updates its internal list of events accordingly.
|
||||
|
||||
## How to Use It
|
||||
This script should be used with a calendar syncing service such as vdirsyncer.
|
||||
vdirsyncer can be scheduled using cron to sync regularly from the CalDav
|
||||
server.
|
||||
|
||||
To use this script, you need Python 3 installed on your system. You can install
|
||||
the required libraries by running:
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
You also need a .toml configuration file with the following structure:
|
||||
```toml
|
||||
[app]
|
||||
calendar_dir = "/path/to/your/ics/files"
|
||||
email_address = "your-email@example.com"
|
||||
smtp_server = "smtp.example.com"
|
||||
smtp_port = 587
|
||||
smtp_username = "your-username"
|
||||
smtp_password = "your-password"
|
||||
...
|
||||
```
|
||||
|
||||
You can then run the script with:
|
||||
```bash
|
||||
python3 remindme_caldav.py --config /path/to/your/config.toml
|
||||
```
|
||||
|
||||
## Installation
|
||||
A Makefile and systemd service file is also included for Debian/Ubuntu based
|
||||
systems.
|
||||
|
||||
This Makefile does the following:
|
||||
- install: Installs Python 3.11, creates a virtual environment in
|
||||
/opt/remindme_caldav/.venv, installs dependencies from requirements.txt
|
||||
into this virtual environment, copies your script to /opt/remindme_caldav/,
|
||||
and sets up the systemd service file.
|
||||
|
||||
- uninstall: Stops and disables the systemd service, removes the installation
|
||||
directory (/opt/remindme_caldav/), and deletes the systemd service file.
|
||||
|
||||
- clean: Deactivates the virtual environment.
|
||||
|
||||
|
||||
A simple script to send alerts/reminders for caldav events.
|
|
@ -131,15 +131,6 @@ class FileChangeHandler(FileSystemEventHandler):
|
|||
class RecurringEventGenerator:
|
||||
"""
|
||||
A class to generate recurring events based on a start date and a recurrence rule.
|
||||
|
||||
Attributes:
|
||||
dtstart (datetime): The starting date of the event series.
|
||||
rrule (rrule): The recurrence rule for the event series.
|
||||
|
||||
Methods:
|
||||
__init__(self, dtstart, rrule): Initializes the class with a start date and a recurrence rule.
|
||||
generate(self): Generates the recurring events based on the start date and recurrence rule.
|
||||
Returns a dictionary containing information about the recurring events.
|
||||
"""
|
||||
def __init__(self, dtstart, rrule):
|
||||
self.dtstart = dtstart
|
||||
|
@ -212,15 +203,6 @@ class CalendarParser:
|
|||
def parse_calendar(self, cal_str):
|
||||
"""
|
||||
Parse a calendar string and process each event.
|
||||
|
||||
Args:
|
||||
cal_str (str): The iCalendar string to be parsed.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing information about the processed events.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If there are no dates returned for an event or if there is an error calculating the event hash.
|
||||
"""
|
||||
# Parse the calendar
|
||||
cal = self.parse_icalendar(cal_str)
|
||||
|
@ -261,15 +243,6 @@ class CalendarParser:
|
|||
def parse_icalendar(self, cal_str):
|
||||
"""
|
||||
Parse a calendar string into an iCalendar object.
|
||||
|
||||
Args:
|
||||
cal_str (str): The iCalendar string to be parsed.
|
||||
|
||||
Returns:
|
||||
Calendar: An iCalendar object representing the parsed calendar.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If there is an error parsing the calendar.
|
||||
"""
|
||||
try:
|
||||
return Calendar.from_ical(cal_str)
|
||||
|
@ -279,12 +252,6 @@ class CalendarParser:
|
|||
def process_event(self, event):
|
||||
"""
|
||||
Process an event from a parsed calendar and extract relevant information.
|
||||
|
||||
Args:
|
||||
event (Event): An iCalendar event object to be processed.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing the extracted event information.
|
||||
"""
|
||||
event_info = {
|
||||
"uid": None,
|
||||
|
@ -307,15 +274,6 @@ class CalendarParser:
|
|||
def dtstart_to_datetime(self, dtstart):
|
||||
"""
|
||||
Convert a date or datetime object into a datetime object with UTC timezone.
|
||||
|
||||
Args:
|
||||
dtstart (date/datetime): The date or datetime to be converted.
|
||||
|
||||
Returns:
|
||||
datetime: A datetime object representing the input date or datetime in UTC timezone.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If there is an error converting the input to a datetime object.
|
||||
"""
|
||||
# Ensure dates are always as datetime
|
||||
try:
|
||||
|
@ -329,16 +287,6 @@ class CalendarParser:
|
|||
def remove_exdates(self, exdates, recur_dates):
|
||||
"""
|
||||
Remove dates from a list of recurring event dates that are in the exdate list.
|
||||
|
||||
Args:
|
||||
exdates (list): A list of datetime objects representing excluded dates.
|
||||
recur_dates (list): A list of datetime objects representing recurring event dates.
|
||||
|
||||
Returns:
|
||||
list: A list of datetime objects representing the remaining recurring event dates after removing the exdate dates.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If there is an error processing the exdates.
|
||||
"""
|
||||
if exdates != []:
|
||||
try:
|
||||
|
@ -355,12 +303,6 @@ class CalendarParser:
|
|||
def process_valarm(self, event):
|
||||
"""
|
||||
Process VALARM components from an iCalendar event and extract trigger times.
|
||||
|
||||
Args:
|
||||
event (Event): An iCalendar event object to be processed.
|
||||
|
||||
Returns:
|
||||
list: A list of datetime objects representing the extracted trigger times.
|
||||
"""
|
||||
valarms = []
|
||||
for subcomponent in event.walk("valarm"):
|
||||
|
@ -371,7 +313,7 @@ class CalendarParser:
|
|||
|
||||
def get_next_alert(event, current_time):
|
||||
"""
|
||||
This function returns the next alert that should be processed based on the current time.
|
||||
Returns the next alert that should be processed based on the current time.
|
||||
"""
|
||||
event_dates = event["event_dates"]
|
||||
valarm_deltas = event["valarms"]
|
||||
|
@ -387,7 +329,7 @@ def get_next_alert(event, current_time):
|
|||
|
||||
def process_alert(current_time, next_alert, next_event, event, config):
|
||||
"""
|
||||
This function processes a given alert and passes it to a messaging client.
|
||||
Processes a given alert and passes it to a messaging client.
|
||||
"""
|
||||
if current_time >= next_alert and current_time < next_alert + dt.timedelta(seconds=15):
|
||||
if len(event["alert_history"]) == 0:
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
[Unit]
|
||||
Description=Calendar Alerting Daemon
|
||||
After=network.target
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
RestartSec=1
|
||||
User=root
|
||||
ExecStart=/opt/remindme_caldav/.venv/bin/python3 /opt/remindme_caldav/remindme_caldav.py --config /etc/remindme_caldav/config.toml
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
Loading…
Reference in New Issue