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.2.tar.gz (9.2 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.2-py3-none-any.whl (8.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for ics_caldav_sync-1.2.tar.gz
Algorithm Hash digest
SHA256 27ca207301eadcd38e6f81a1351985afb9960dd2ec3f414ea3f30fd18bdffcdd
MD5 6609f87a51a1f13dd1f806dbea8223a6
BLAKE2b-256 5a58890330b6f1551711e88839f598774067de498dc24a73d6a78c54497d9c0e

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for ics_caldav_sync-1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b774de3f830585736e81bf2044726c9593a42798d189b4fe55595543c03c9bac
MD5 ad6ae91621aa8ffe0aae02800dfcbe23
BLAKE2b-256 fa1d163e7d452cbfa0cdb0744510393a12ef07ce394e131426a1e076b5dff726

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