π Sync ICS Feeds to Your CalDAV Calendar with Emojis, Deduplication, and Docker
If you’re like me and obsessively track everything β from Austrian public holidays to Formula 1 races and even trash pickup days β you know how painful it can be managing all of that across calendars.
So I built a simple solution: a Python-based tool that syncs ICS feeds directly into a CalDAV calendar (like mailbox.org), complete with:
- β Emoji support
- β Deduplication of events
- β Location-based filtering for Austria
- β Docker support
- β Dry-run mode so nothing breaks π₯
π₯ Check out the console output in action
π‘ Why I Built This
There are lots of calendar tools, but none let me do exactly what I wanted:
- Pull in multiple
.ics
feeds - Filter events based on location (e.g., only KΓ€rnten, Steiermark)
- Add emojis to event names (ποΈ for trash, π¦πΉ for public holidays)
- Avoid duplicate imports (using UID hashing)
- Easily run as a scheduled task on my Synology NAS
It started as a quick utility for my own use. Now it’s open source and available for anyone to use!
π οΈ Features at a Glance
- π Sync any
.ics
feed to CalDAV - π All-day events handled properly
- π¦πΉ Support for Austrian public holiday feed, with filtering by Bundesland
- π§ Deterministic UID generation using hashed content
- π Dry-run support to preview changes
- π³ Docker & Docker Compose support
- π₯ Built-in cleanup option for previously imported events
π§ How It Works
- Loads your
config.json
with ICS feeds and emoji mappings - Connects to your CalDAV calendar (e.g., mailbox.org)
- Checks for duplicate events using a unique hash-based UID
- Applies emoji mappings to the event title
- Filters events based on date range and, if set,
import_locations
- Imports events, replacing duplicates if needed
You can even preview everything with:
docker-compose run --rm calendar-sync --import --dry-run
βοΈ Example Config
{
"caldav_url": "https://dav-sso.mailbox.org/caldav/...",
"username": "you@mailbox.org",
"password": "your-app-password",
"timezone": "Europe/Vienna",
"uid_prefix": "ICS-",
"future_event_limit_days": 365,
"ics_feeds": [
{
"url": "https://example.com/feiertage.ics",
"import_locations": "K,St",
"emoji_mapping": {
"Β§": "π¦πΉ",
"default": "ποΈ"
}
}
]
}
If you set "import_locations": "K,St"
, the log output will show you which events are skipped due to unmatched regions like this:
INFO: βοΈ Skipping 'St. Florian' (2025-05-04) due to unmatched location: OΓ
π§ͺ Use on Synology or Server
I run this on my Synology via a scheduled task:
cd /volume2/docker/appdata/calendar-sync
docker-compose run --rm calendar-sync --cleanup
docker-compose run --rm calendar-sync --import
Runs every day at 01:00 π β and my calendar is always up to date.
π¦ Where to Get It
Youβll find the source, Dockerfile, instructions and everything here:
π GitHub – magicdude4eva/calendar-sync
π€ Support & Contributions
This project is MIT-licensed and open to PRs, ideas, or feedback.
If you found this useful, consider supporting my work:
πΊ Pay it forward:Β If any of my content helped you in any way, send me some coins:
(CRO) 0xBAdB43af444055c4031B79a76F74895469BA0CD7 (Cronos)
(USDC) 0xBAdB43af444055c4031B79a76F74895469BA0CD7
(ETH) 0xfc316ba7d8dc325250f1adfafafc320ad75d87c0
(BTC) 1Mhq9SY6DzPhs7PNDx7idXFDWsGtyn7GWM
(BNB) 0xfc316ba7d8dc325250f1adfafafc320ad75d87c0
Crypto.com PayString: magicdude$paystring.crypto.com
π Use my referral link https://crypto.com/app/ref6ayzqvp to sign up for Crypto.com and we both get $25 USD πΈ
𧨠During signup use my referral code ref6ayzqvp to claim your reward π§¨
Go to Curve.com to add your Crypto.com card to ApplePay (get 1% cashback)
Recent Comments