Skip to content

About

Reads an iCal URL, parses it according to user defined rules and serves a filtered version

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

ical-filter-proxy

Got an iCal feed full of nonsense that you don't need? Does your calendar client have piss-poor filtering options (looking at your Google Calendar)?

Use ical-filter-proxy to (you guessed it) proxy and filter your iCal feed. Define your source calendar and filtering options in config.yml and you're good to go.

In addition, display alarms can be created or cleared.

Gwinnett School Calendar (this fork)

This fork runs an unofficial, filtered Gwinnett County Public Schools calendar on Vercel. See CHANGELOG.md for releases.

What Where
Subscribe page (share this) https://gcps-school-calendar.vercel.app
Feed https://gcps-school-calendar.vercel.app/gwinnett-school.ics
Source feed https://www.gcpsk12.org/fs/calendar-manager/events.ics?calendar_ids=1
Config gwinnett-school in config.yml
Subscribe page source public/index.html

What it keeps: school-specific dates: breaks, early release days, digital learning days, teacher planning days, first/last day, semester start/end and the 100th day. General holidays (Labor Day, MLK Day, Christmas Day...), board meetings and observances are dropped, since subscribers already have those. The filter is an allowlist on event titles, so new kinds of district noise never get through. extra_events adds dates the district feed leaves out.

Deployment: the Vercel project gcps-school-calendar deploys every push to master to production automatically, so test changes before merging. Other branches get protected preview deployments.

Yearly update checklist (when the next school-year PDF is published):

  1. Compare the PDF against the live feed (titles and date spans).
  2. Add any school dates missing from the district feed to extra_events, and remove last year's entries.
  3. Update the year in name, the page <title>/heading and the fixture-based spec (spec/gwinnett_config_spec.rb) with a fresh feed snapshot.
  4. Run bundle exec rake, add a CHANGELOG entry, bump the version, merge to master and tag the release.

Configuration

my_calendar_name:
   ical_url: https://source-calendar.com/my_calendar.ics # Source calendar
   api_key: myapikey # (optional) append ?key=myapikey to your URL to grant access
   name: My Calendar # (optional) calendar name shown by subscribing clients
   timezone: Europe/London # (optional) ensure all time comparisons are done in this TZ
   rules:
      - field: start_time # start_time and end_time supported
        operator: not-equals # equals and not-equals supported
        val: "09:00" # A time in 24hour format, zero-padded
      - field: summary # summary and description supported
        operator: startswith # (not-)startswith, (not-)equals and (not-)includes supported
        val: # array of values also supported
          - Planning
          - Daily Standup
      - field: summary # summary and description supported
        operator: matches # match against regex pattern
        val: # array of values also supported
          - '/Team A/i'
      - field: blocking # blocking (TRANSP) field supported
        operator: equals
        val: true # true will filter out non-blocking events
   alarms: # (optional) create/clear alarms for filtered events
     clear_existing: true # (optional) if true, existing alarms will be removed, default: false
     triggers: # (optional) triggers for new alarms. Description will be the alarm summary, action is 'DISPLAY'
       - '-P1DT0H0M0S' # iso8601 supported
       - 2 days # supports full day[s], hour[s], minute[s], no combination in one trigger
   extra_events: # (optional) all-day events missing from the source, added after filtering
     - summary: No School
       date: '2027-01-04' # YYYY-MM-DD
       end_date: '2027-01-05' # (optional) inclusive, defaults to date
       description: Teacher planning day # (optional)

Variable substitution

It might be useful to inject configuration values as environment variable. Variables are substituted if they begin with ICAL_FILTER_PROXY_<value> and are defined in the configuration like ${ICAL_FILTER_PROXY_<value>}.

Example:

api_key: ${ICAL_FILTER_PROXY_API_KEY}

If a placeholder is defined but environment variable is missing, it is substituted with an empty string!

Additional Rules

At the moment rules are pretty simple, supporting only start times, end times, equals and not-equals as that satisfies my use case. To add support for additional rules please extend lib/ical_filter_proxy/filter_rule.rb. Pull requests welcome.

Installing/Running

After you've created a config.yml simply bundle and run rackup.

bundle install
bundle exec rackup -p 8000

Voila! Your calendar will now be available at http://localhost:8000/my_calendar_name?key=myapikey.

I'd recommend running it behind something like nginx, but you can do what you like.

Docker

Create a config.yml as shown above.

docker build -t ical-filter-proxy .
docker run -d --name ical-filter-proxy -v $(pwd)/config.yml:/app/config.yml -p 8000:8000 ical-filter-proxy

Vercel

Commit your config.yml and import the repo as a Vercel project. api/index.rb runs on Vercel's Ruby runtime, and vercel.json limits static files to public/ so the config and source aren't served. Calendars are available at https://<project>.vercel.app/api?calendar=my_calendar_name&key=my_api_key. Add a rewrite in vercel.json for a clean .ics URL. Note that Vercel Authentication protects preview deployments, so share the production domain.

Lambda

ical-filter-proxy can be run as an AWS Lambda process using their API Gateway.

Create a new API Gateway in the AWS Console and link to to a new Lambda process. This should create all of the permissions required in AWS land.

Next we need to package the app up ready for Lambda. First of all, craft your config.yml and place it in the root of the source directory. A handy rake task is included which will fetch any dependencies and zip them up ready to be uploaded.

bundle exec rake lamba:build

This task will output the file ical-filter-proxy.zip. Note that you must have the zip utility installed locally to use this task.

When prompted during the Lambda setup, provide this zip file and set the handler to lambda.handle.

That's it! Your calendar should now be available at https://aws-api-gateway-host/default/gateway_name?calendar=my_calendar_name&key=my_api_key

About

Reads an iCal URL, parses it according to user defined rules and serves a filtered version

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages