KEATS to Google Calendar integration.
adonais
takes publicly accessible data from KEATS, transforms it, then uploads it to a new calendar in your account.
- Login with your Google Account
- Give
adonais
permission to manage your calendar data - Click the Sync Calendar Now button when it turns blue
- Marvel at your new/updated calendar
Note: adonais
will not update your calendar automatically.
To use adonais
, you must grant it access to:
- read/write all your calendars
- read/write all your events
At worst, this means adonais
could delete or make public all your calendar data. There's an alternate design that's much better, which is currently in progress (see Todo List).
However, adonais
is currently designed so that it:
- never deletes calendars, it only creates them
- only reads and writes data to calendars it has created
You should not edit the calendar adonais
creates, as it will overwrite any changes on the next update.
If you think there is a bug in how adonais
behaves, please open a new issue.
- pull event data from keats.kcl.ac.uk
- setup proxy for CORS
- data transformation
- deserialize from keats events
- timezone aware transforms for naive data
- parser for groups syntax
- filter events to relevant subset
- diff events to only those that need updates
- serialize to google events
- deserialize from keats events
- push to user calendar
- create new calendar and store reference
- push events to calendar
- UI
- sync calendar now
- delete account
- change user settings
- group
- make calendars namespaced under service account
- keep track of all calendars centrally
- give user read-only access to calendar that matches their settings
- batch service
- fetch all users & credentials from store
- run sync for a user without interactive login
- schedule to run periodically
- Fetch data from KEATS. Gives unfiltered data for whole year.
- Transform data and generate id from
Event
hash - Filter by user preferences (group) into final event list for a user
- Transform data and generate id from
- Fetch data from GCal. Gives existing event ids from now onwards.
- Compare ids from new and existing events:
- if existing but not new, delete event
- if new but not existing, create event
- if new and existing, no action
- Send all updates to the Google API in bulk
The raw data is available from https://lsm-education.kcl.ac.uk/apicommonstring/api/values/Mod-Module.5MBBSStage2
This is an unsecured endpoint that responds to a plain GET with JSON format data (amazing!)
Schema appears to be constant, with no nesting.
Keys are always present, missing data is represented by null
s.
Initial preferences to hardcode:
- Group: 253
- Calendar: GKT Year 2
Unexpectedly, one of the more challenging parts was parsing the G
field from the KEATS API.
This corresponds to groups
an event is for. The following are all valid examples:
- ``: empty string implies all groups,
[200, 201, ..., 299]
200
: a single group,[200]
200, 210 220
: several single groups,[200, 210, 220]
- delimiter may be spaces, comma or a combination of both
210 - 212, 217-218
: a range of groups (inclusive),[210, 211, 212, 217, 218]
- delimiter dash, with optional spaces
3 7-9, 10
: combinations of the above,[3, 7, 8, 9, 10]
This turns out to be too complex for regex parsing, so...
- fairly verbose. Many function definitions
- small units of grammar are easily testable
- composites nicely together
- mildly confusing documentation at first glance
- compact grammar
- macro based
- parts are not as easily testable
- lots of unwrpping due to grammar structures not testable by the compiler
- smaller
Pair
units are based on token sequences, not rust structs, making parsing less readable - cute logo