Hi, Looking for a way to list calendar events at the terminal, I ran across plann. It simply dumps out times and labels for calendar events. Nothing fancy at all. My criteria was:
- Access over remote CallDav, no local sync
- Ablity to access to iCloud calendars, Apples CalDav implementation looks to be broken
- Fewest number of steps to view the next few days of calendar items.
- Run it as a binary, not using pip.
There are alternatives like calcurse which looked great visually but setting it up was a PITA.
Plann’s documentation isn’t great so I’m documenting how I got it work for me.
First step, set up a python3 virtual environment. Then check out the plann GitHub repo. Move into the plann directory and run the following:
pip install setuptools && pip install pyinstaller && python setup.py installCompile and generate a binary:
pyinstaller --onefile plann/cli.pyMove the dist/cli to somewhere in your path, rename it to something like ‘plann’ and make it executable.
iCloud
If you are using iCloud, you’ll have to figure out the path of your calendars. There are 2 ways of doing this.
First way, linto icloud.com, go to Calendar, try to make a calendar public and you’ll see a URL like:
https://pXX-caldave.icloud.com:443/\<SOME_NUMBER\>/calendars...
You only care about SOME_NUMBER.
Remember to unpublish your calendar so no one else can see it.
FOr security purposes, create a a one-time password to use with plann. Log into appleid.apple.com and generatre one.
Sqlite
The second way is pull some information for Sqlite file that stores calendar data. You can use some tool like SQLPro or TablePlus if you want or use Litecli in the terminal. No matter which tool you use, open up ~/Library/Calendars/Calendar.sqlitedb (OSX 14 Sonoma at least). Run the following SQL:
select `ROWID`, title, external_id from `Calendar`The title’s should look familiar. Their corresponding external_ids should look like /<SOME_NUMBER>/calendars/Home. You only care about that <SOME_NUMBER>.
Configuraation
Next, you’ll need a configuration file. The default location is ~/.config/calendar.conf. You can define a different location if you want, when running plann. Here is what my calendar.conf looks like:
default:
caldav_url: "https://caldav.icloud.com:443/<SOME_NUBMER/calendars"
caldav_user: <icloud username>
caldav_pass: <icloud one-time password>
some-domain-name:
caldav_url: "https://mail.example.com/SOGo/dav/some@email.com/Calendar"
caldav_user: some@email.com
caldav_pass: <PASSOWRD>
all:
contains: ['default', 'some-domain-name']
A default section is required. I’ve added a second one as well. Note, this will pull all the events in all the calendars in your iCloud account and from mail.example.com.
Now let’s try to pull some events. At the terminal:
plann --config-section all select --event --start 2024-05-01 --end 2024-05-14 list- —config-section: if you don’t define this, it will show the default section. If there is no default section, it will throw an error.
I wanted to simpify this but gassing in the number days. So Write a zsh function that I tuck into my .zshrc:
Zsh function
Here is something you can stick into your .zshrc if you want to see upcoming events by passing the number of days ahead.
plann_events() {
# Check if the number of days is provided
if [ -z "$1" ]; then
echo "Usage: plann_events <number_of_days>"
return 1
fi
# Number of days
local days=$1
# Get the current date
local start_date=$(date +%Y-%m-%d)
# Get the date 'days' from now
local end_date=$(date -v +${days}d +%Y-%m-%d)
# Run the plann command with the calculated dates
plann --config-section all select --event --start "$start_date" --end "$end_date" list
}Restart your shell and type in somethig like ‘plann_events 7’.