Skip to main content

ICS to CalDAV synchronisation.

Project description

ICS to CalDAV synchronisation

PyPI version Docker Pulls Licence

Downloads a calendar in ICS format and uploads it to a CalDAV server, regularly. Your employee, school, or whoever shares a calendar as a link to an ICS file, and you'd like to have it on another CalDAV server? Look no further.

Standalone usage

Install the script with pip install ics_caldav_sync (or, if installing from source, pip install .) and run ics_caldav_sync script which should be on your PATH now. Python 3.9 or higher is required.

There also exist Dockerfile and docker-compose.yml files so you can run it on your Docker server.

The Docker images are published to Docker Hub, repository przemub/ics_caldav_sync tagged by short commit hashes and versions.

Set the settings as environment variables:

Variable Type Required Default Description
REMOTE_URL string Yes - ICS file URL. You can provide multiple URLs, separated by a space character.
LOCAL_URL string Yes - CalDAV server URL.
LOCAL_CALENDAR_NAME string Yes - The name of your CalDAV calendar.
LOCAL_USERNAME string Yes - CalDAV username.
LOCAL_PASSWORD string Yes - CalDAV password.
LOCAL_AUTH string No basic CalDAV authentication method (either basic or digest).
REMOTE_USERNAME string No - ICS host username.
REMOTE_PASSWORD string No - ICS host password.
REMOTE_AUTH string No basic ICS host authentication method (either basic or digest).
TIMEZONE string No - Override events timezone. Examples: Utc, Europe/Warsaw, Asia/Tokyo.
SYNC_EVERY string No - How often should the synchronisation occur? Examples: 2 minutes, 1 hour. Synchronise once if empty.
DEBUG boolean No false Set to any non-empty value to print debugging messages. Please set this when reporting an error.
SYNC_ALL boolean No false If set, all events in the calendar will be synced. Otherwise, only the ones occurring in the future will be.
KEEP_LOCAL boolean No false Do not delete events on the CalDAV server that do not exist in the ICS file.

Library usage

This script can be also used as a library in your Python script using ICSToCalDAVSync class and its synchronise method.

from ics_caldav_sync import ICSToCalDAVSync

sync = ICSToCalDAVSync(
    remote_url="https://example.com/calendar.ics",
    local_url="https://caldav.example.com",
    local_calendar_name="My Calendar",
    local_username="username",
    local_password="password",
    # remote_username="",
    # remote_password="",
    # remote_auth="basic|digest",
    # sync_all=False,
    # keep_local=False
    # timezone=None,
)

sync.synchronise()

Examples

Command-line usage

ics_caldav_sync can be used from the command line when installed with pip. An example:

REMOTE_URL=https://example.com/path/to/calendar_file.ics \
  LOCAL_URL=https://example.net/caldav \
  LOCAL_CALENDAR_NAME="My Calendar" \
  LOCAL_USERNAME=myusername \
  LOCAL_PASSWORD=mypassword \
  ics_caldav_sync

Docker

You can also do the same as a Docker one-liner - to avoid installing dependencies yourself.

docker run --rm \
  -e REMOTE_URL=https://example.com/path/to/calendar_file.ics \
  -e LOCAL_URL=https://example.net/caldav \
  -e LOCAL_CALENDAR_NAME="My Calendar" \
  -e LOCAL_USERNAME=myusername \
  -e LOCAL_PASSWORD=mypassword \
  przemub/ics_caldav_sync

Docker Compose

When setting up a long-running, periodic sync, Docker Compose can be helpful.

This example also shows settings needed by a CalDAV server Baïkal.

services:
  ics_caldav_sync:
    image: ics_caldav_sync
    restart: unless-stopped
    environment:
      - REMOTE_URL=https://example.com/path/to/calendar_file.ics
      - LOCAL_URL=https://baikal.myserver.com/dav.php/
      - LOCAL_CALENDAR_NAME=My Calendar
      - LOCAL_USERNAME=myusername
      - LOCAL_PASSWORD=mypassword
      - LOCAL_AUTH=digest  # Required by Baikal - try removing if getting Unauthorized error
      - SYNC_EVERY=30 minutes

Tested with

On the local side (CalDAV server):

On the remote site (ICS file generator):

Please feel free to open a PR against this section to add your configuration!

Rationale

In my case, my new shiny Bluetooth wristwatch, Casio Edifice ECB-10, did not support synchronisation with calendar subscriptions. And so this script was created.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ics_caldav_sync-1.1.tar.gz (8.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ics_caldav_sync-1.1-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file ics_caldav_sync-1.1.tar.gz.

File metadata

  • Download URL: ics_caldav_sync-1.1.tar.gz
  • Upload date:
  • Size: 8.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.10

File hashes

Hashes for ics_caldav_sync-1.1.tar.gz
Algorithm Hash digest
SHA256 84c1cfd6c90b5ecedf51103d134a66476840abe82f1a8fab9e5ed50faa077449
MD5 d127ebee82ab727574ddf365a2d7dc05
BLAKE2b-256 93abc6ab18a3dbc25a6a3e1f980172a98a9d3a056c11ab7ae6cc6587bcb7bde5

See more details on using hashes here.

File details

Details for the file ics_caldav_sync-1.1-py3-none-any.whl.

File metadata

  • Download URL: ics_caldav_sync-1.1-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.10

File hashes

Hashes for ics_caldav_sync-1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8a4dd0f7b298d0cdb827fbaeac716a96f53e90de9b3ea00f0f31d5864afc4090
MD5 9eca5e03e552de226a02665d39c68d15
BLAKE2b-256 72d25489694eb8ee6a6da631dae6d2384288eb5cfa6b625f76d52d0be343bddf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page