Skip to content

amattas/ics-combiner

Repository files navigation

ICS Combiner logo

ICS Combiner (FastAPI)

This service combines multiple iCalendar (ICS) feeds into a single calendar, with optional per‑calendar transforms. It runs as a FastAPI app with the same path‑based authentication scheme used by the MCP servers, and supports Redis caching for source ICS files with configurable refresh TTLs.

Key features

  • FastAPI app with optional dual‑factor path auth using ICS_API_KEY and SALT (with legacy MD5_SALT support)
  • Redis‑backed caching of source ICS feeds
  • Per‑calendar refresh TTL with environment overrides
  • Optional show/hide filtering via query params
  • Dockerfile and example env provided

Environment

  • ICS_API_KEY: API key to enable path‑based auth (optional for local/dev)
  • SALT: Optional salt used for API path hash (preferred)
  • MD5_SALT: Legacy name for SALT (still supported)
  • REDIS_HOST, REDIS_SSL_PORT (default 6380), REDIS_KEY: Redis connection
  • ICS_CACHE_NAMESPACE: Optional Redis namespace. Set this when sharing one Redis instance across multiple apps. If omitted, a namespace is derived from ICS_API_KEY when available.
  • ICS_SOURCES: JSON array of calendar configs (see example)
  • ICS_NAME: Combined calendar display name
  • ICS_DAYS_HISTORY: Days of history to include (int)
  • CACHE_TTL_ICS_SOURCE_DEFAULT: Default TTL (seconds) for source ICS caching
  • CACHE_TTL_ICS_SOURCE_LKG: Optional last-known-good fallback TTL (seconds). Leave unset or set to 0 to retain indefinitely.
  • CACHE_TTL_ICS_SOURCE_FAILURE_BACKOFF: Backoff TTL (seconds) after a source fetch failure (minimum 1)

Calendar source config Each object in ICS_SOURCES may include the following keys (compatible with calcomb):

  • Id (required, int): unique numeric ID per calendar
  • Url (required, string): ICS feed URL
  • Duration (optional, minutes): override event duration when DTSTART is datetime
  • PadStartMinutes (optional, minutes): prepend minutes and extend duration accordingly
  • Prefix (optional, string): prefix for SUMMARY
  • MakeUnique (optional, bool): force UID uniqueness per calendar
  • FilterDuplicates (optional, bool): de‑duplicate events by UID
  • RefreshSeconds (optional, int): cache TTL for this calendar’s source ICS
    • Set to 0 to bypass the fresh source cache while still using failure backoff and last-known-good fallback cache when Redis is configured.

Cache behavior

  • Cache keys are scoped by app namespace so multiple apps can share one Redis instance without overwriting each other's source cache. Use a stable ICS_CACHE_NAMESPACE per app if ICS_API_KEY is not set or if several apps intentionally share an API key.
  • Successful source fetches store a last-known-good copy indefinitely by default. A positive CACHE_TTL_ICS_SOURCE_LKG can cap that retention.
  • Removed calendars are not emitted just because their old source data remains in Redis. The app tracks source keys per namespace and prunes cache entries for sources removed from ICS_SOURCES on the next combine request.

Endpoints

  • GET /app/health — health status (no auth)
  • GET /app/{ICS_API_KEY}/{hash}/ics?show=1,2&hide=3 — combined calendar

Run locally

  1. Copy .env.example to .env.local and set values
  2. pip install -r requirements.txt
  3. python -m uvicorn src.server:app --host 0.0.0.0 --port 8080

Run tests

  • pip install -r requirements-dev.txt
  • python -m pytest

Docker

  • Build: docker build -t ics-combiner .
  • Run: docker run --env-file .env.local -p 8080:8080 ics-combiner

About

Self‑hosted FastAPI service that combines multiple iCalendar (ICS) feeds into a single cached calendar, with per‑source transforms and Redis‑backed caching.

Resources

Stars

Watchers

Forks

Sponsor this project

  •  

Packages

 
 
 

Contributors