Skip to content

Python script to export carddav anniversaries/dates to a caldav calendar. Mainly for baikal. Done with https://antigravity.google/

Notifications You must be signed in to change notification settings

ledakis/baikal-anniversaries

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Baikal Anniversaries Sync

A Docker container that syncs anniversary and "other" dates from Baikal contacts (via CardDAV) to calendar events (via CalDAV).

Features

  • ✅ Connects to CardDAV to fetch contacts
  • ✅ Extracts anniversary and custom date fields (excludes birthdays)
  • ✅ Supports Apple Contacts label format (itemN.X-ABLabel)
  • ✅ Creates whole-day calendar events with format: "Contact Name - Label"
  • ✅ Digest authentication support (required for Baikal)
  • ✅ Separate authentication for CardDAV and CalDAV (works with any DAV server, not just Baikal)
  • ✅ Delete-and-recreate sync strategy (ensures removed/updated dates are reflected)
  • ✅ Configurable date range (only create events within N days from today)
  • ✅ Run-once or continuous sync modes
  • ✅ Lightweight Docker container with non-root user

Prerequisites

  • Docker and Docker Compose installed
  • Baikal server (or any CardDAV/CalDAV compatible server) running and accessible
  • A dedicated calendar in Baikal for anniversaries (will be cleared on each sync)
  • Valid credentials for CardDAV and CalDAV access

Quick Start

1. Clone or Download

cd /path/to/baikal-anniversaries

2. Configure Environment Variables

Copy the example environment file and edit it with your settings:

cp .env.example .env
nano .env  # or use your preferred editor

Required variables:

  • CARDDAV_URL - Base URL of your CardDAV server
  • CARDDAV_USERNAME - Username for CardDAV authentication
  • CARDDAV_PASSWORD - Password for CardDAV authentication
  • CARDDAV_ADDRESSBOOK - Path to your addressbook (e.g., /addressbooks/username/default/)
  • CALDAV_URL - Base URL of your CalDAV server
  • CALDAV_USERNAME - Username for CalDAV authentication
  • CALDAV_PASSWORD - Password for CalDAV authentication
  • CALDAV_CALENDAR - Path to your calendar (e.g., /calendars/username/anniversaries/)

Optional variables:

  • DAYS_IN_FUTURE - Number of days into the future to create events for (default: 365)
  • SYNC_INTERVAL - If set, runs continuously and resyncs every N seconds. If unset, runs once and exits
  • LOG_LEVEL - Logging verbosity: DEBUG, INFO, WARNING, ERROR (default: INFO)

3. Build and Run

Using Docker Compose (recommended):

# Build the image
docker-compose build

# Run once and exit
docker-compose run --rm baikal-anniversaries

# Run continuously (if SYNC_INTERVAL is set in .env)
docker-compose up -d

Using Docker directly:

# Build the image
docker build -t baikal-anniversaries .

# Run with environment file
docker run --rm --env-file .env baikal-anniversaries

Configuration Examples

Run Once Mode (for Cron)

Set up a cron job to run the sync daily:

# .env file
SYNC_INTERVAL=  # Leave unset or comment out

# Crontab entry (runs daily at 3 AM)
0 3 * * * cd /path/to/baikal-anniversaries && docker-compose run --rm baikal-anniversaries

Continuous Mode

Run the container continuously with automatic resyncing:

# .env file
SYNC_INTERVAL=86400  # Resync every 24 hours (in seconds)

# Start the container
docker-compose up -d

# View logs
docker-compose logs -f

Different CardDAV and CalDAV Servers

This tool supports separate authentication for CardDAV and CalDAV, allowing you to sync from one server to another:

# .env file
CARDDAV_URL=https://contacts-server.com
CARDDAV_USERNAME=user1
CARDDAV_PASSWORD=pass1

CALDAV_URL=https://calendar-server.com
CALDAV_USERNAME=user2
CALDAV_PASSWORD=pass2

How It Works

  1. Connect to CardDAV server and fetch all contacts from the specified addressbook
  2. Parse vCard data to extract:
    • ANNIVERSARY fields
    • Custom date fields (X-* properties)
    • Excludes BDAY (birthday) fields
  3. Filter dates to only include those occurring within DAYS_IN_FUTURE days from today
  4. Clear all existing events in the target CalDAV calendar
  5. Create new whole-day events with format: "Contact Name - Label"
  6. Repeat if running in continuous mode

Supported Date Fields

The application extracts the following date types from vCards:

  • ANNIVERSARY - Standard vCard 4.0 anniversary field
  • Custom fields - Any X-* properties containing dates (e.g., X-ANNIVERSARY, X-OTHER, X-ABDATE)
  • Labeled dates - Dates with TYPE or X-ABLABEL parameters for custom labels
  • Apple Contacts format - Properly parses Apple's itemN.X-ABLabel format (e.g., "Anniversary", "Nameday")

Excluded:

  • BDAY (birthday) fields are explicitly excluded

Troubleshooting

Connection Issues

Enable debug logging to see detailed connection information:

LOG_LEVEL=DEBUG

Authentication Errors

  • Verify your credentials are correct
  • Check that the CardDAV/CalDAV URLs are accessible
  • Ensure the addressbook and calendar paths are correct (include leading and trailing slashes)

No Events Created

  • Check that your contacts have ANNIVERSARY or custom date fields
  • Verify dates fall within the DAYS_IN_FUTURE range
  • Enable DEBUG logging to see which dates are being extracted

Calendar Not Clearing

  • Ensure the CalDAV user has write permissions on the target calendar
  • Verify the calendar path is correct
  • Check logs for deletion errors

Finding Your Addressbook and Calendar Paths

To find the correct paths for your Baikal installation:

  1. Log into Baikal web interface
  2. Navigate to your addressbook or calendar
  3. Look at the URL in your browser
  4. The path typically follows this pattern:
    • Addressbook: /addressbooks/{username}/{addressbook-name}/
    • Calendar: /calendars/{username}/{calendar-name}/

Alternatively, use a CardDAV/CalDAV client (like Thunderbird) to inspect the URLs.

Security Notes

  • The Docker container runs as a non-root user (UID 1000) for security
  • Store your .env file securely and never commit it to version control
  • Consider using Docker secrets for production deployments
  • Use HTTPS URLs for CardDAV/CalDAV connections

License

This project is provided as-is for personal and homelab use.

Contributing

Feel free to submit issues or pull requests for improvements!

About

Python script to export carddav anniversaries/dates to a caldav calendar. Mainly for baikal. Done with https://antigravity.google/

Topics

Resources

Stars

Watchers

Forks