RALF SPEC/k 🥓

RALF P
6 min readNov 15, 2022

--

Toyoyota, was geht ABAP, liebe RALF Gemeinde? It’s DEMO Time!

Today we want to give you an update on the progress of the RALF project, provide you with a little playground and at the end you can even win one of 4 iPhones 📱 (only while stocks last* ) — read to the end for that.

Wait, what’s RALF again?

Currently, there are many projects about which you need to have an overview. Therefore, we are only a bit angry if you don’t know what RALF is anymore. But don’t worry, in the following a short summary of what RALF is and what you can use it for. Please read it if you are not up to date, because it is very important for the blog post to understand what RALF is.

RALF is a loose acronym and stands for “Room And Lecture Filtering [Proxy]”.

We, the RALF team, have made it our task to make calendars in ICal format (such as RAPLA) filterable with the help of a simple user experience.

The calendar says “Ada” on Tuesdays, but you weren’t planning on taking an instructor’s license? Well, bad luck, because the Ada entry will be with you forever in your calendar.

A simple filtering by keywords may not be enough for many people, so RALF tries to be as less strict as possible and filter your calendar ✨dynamically✨ with the help of rules.

It is important to understand: RALF IS NOT A CALENDAR OF HIS OWN! That was and is never our task — rather RALF acts as a proxy which filters and returns an existing calendar.

RALF SPEC/k

Okay, now that we are all roughly on the same page, I would like to introduce you to the RALF specification. As already mentioned, filtering should be possible via a simple user experience. In the future there will be two possibilities: a way to write a simple YAML, which defines the rules, and a kind of WYSIWYG editor, which tries to display this YAML notation graphically in a web interface. In the backend, these rules are then stored for the user and, if necessary, passed on to the RALF Engine, which processes these rules on request.

Unfortunately we can’t present you a web interface yet, but the RALF engine with the appropriate YAML specification is already in a beta phase. We are happy to finally give you the first productive insight into RALF 😎.

RALF YAML Specification

Actually, not much is needed. Only the following three sections are important:

  • `Source` — URL of the original .ics file
  • `Cache Duration` — How long the source .ics file should be cached.
  • `Flows` — a list of flows, which are executed from top to bottom
---
# name of the filter profile; shown in the RALF-dashboard
name: 'Hello World!'

# time to cache a response from an .ics source to prevent rate limiting
cache-duration: 5m

# flows are executed in order
flows: []
...

Currently there are 4 flow types:

Condition-Flow: Simple if-queries — if the ‘if’-condition evaluates to ‘true’, all flows from ‘then’ are executed, otherwise all from ‘else’. You could nest if statements if you want by adding a new if-flow to a then/else block.

- if: 'Date.IsMonday() or Date.IsFriday()'
then:
- if: 'Date.IsAfter("8:00")'
then: [ ... ]
else: [ ... ]

Action-Flow: Executes a predefined rule or action. Currently there are three predefined rules. See the comments below.

# filters/filter-out: remove event from result
- do: filters/filter-out

# filters/filter-in: add event to result
- do: filters/filter-in

# actions/regex-replace: replace something in some property
- do: actions/regex-replace
with:
match: 'Hello (world)' # regex
replace: 'Hi $1' # required; can contain placeholders like $1, $2, ...
case-sensitive: false # optional
in: [ "summary" ] # optional; list of properties to replace values
# some properties contain additional parameters, for example,
# an organizer can have a "CN" - to apply the rule to the CN-attribute aswell,
# add /CN: [ "SUMMARY/CN" ]
# NOTE: This only checks and replaces the parameter!
# NOTE: If you want to check/replace the value AND the parameter, append a '+' to the property name
# NOTE: like this: [ "SUMMARY+/CN" ]
# multiple attributes can be divided by ",": [ "organizer/CN,OTHER" ]

Return-Flow: Cancels the execution for all subsequent flows for an event

- if: 'true'
then:
- return # execution stops here
- do: filters/filter-out # never executed

Debug-Flow: Outputs a message in the output. Should in no case be used productively, otherwise it will break the iCal format.

- debug: 'hello world!' # show a simple message
- debug: '$ Date.String() + ": " + String(Date.IsAfter("9:00"))' # prefix with '$ ' to allow for advanced messages

Full Example

This example changes the format for course names. TINF21B2 becomes B-21–2, TINF14A2 becomes A-14–2 and so on.

---
# name of the filter profile; shown in the RALF-dashboard
name: >
Rename 'TINF[...][...][...]' to [...]-[...]-[...], e. g. TINF14B1 --> B-14-1
and only include courses on Mondays and Tuesdays after 9 AM"

# time to cache a response from an .ics source to prevent rate limiting
cache-duration: 5m

# flows are executed in order
flows:
# filter out all courses by default.
# we can filter them in later using the `filters/filter-in` action.
- do: filters/filter-out

# only include mondays and tuesdays after 10:00
- if: '(Date.isMonday() or Date.isTuesday()) and Date.isAfter("9:00")'
then:
# filter in course
- do: filters/filter-in

# rename course
- do: actions/regex-replace
with:
match: 'TINF(\d+)([A-Z]+)(\d+)'
in: [ "DESCRIPTION"]
replace: '$2-$1-$3'
...

And this is where the Playground announced at the beginning comes into play: We have already deployed a small test version, which you are welcome to test. Just POST the YAML content to https://engine.ralf.life/process — if something doesn’t work, feel free to post to GitHub Discussions and open a GitHub Issue if you think you’ve found a problem.

You can use tools like cURL, HTTPie, Insomnia or Postman to send the request:

But now we need your help — and here’s your chance to not win an iPhone 14 Pro: What ideas do you have on how to filter your calendar (according to what criteria), what actions are you missing? Is there a filter that you haven’t been able to solve with the current flows? Are there any wishes, which operations can be applied to dates / events in the scripting language? (e.g. Date.IsMonday(), Date.DayOfYear(), …)

🐉 You can find the source code for the engine here (GitHub): http://the.ralf.life/src-engine

What’s Next?

Next we will do the backend (for user management, profile management, etc.), refine the engine and the frontend — here the challenge will be to display the YAML files in a frontend. We don’t have an exact plan yet, how we will implement this, but we are surely at least as excited about it as you are!

And that’s it for today’s blog post — if you have any questions, feel free to leave a comment, or post on GitHub :)

Wo ein Wille ist, ist auch ein RALF.

*) there is no stock, there are no iPhones, but you can still help 🤓.

--

--

RALF P
RALF P

Written by RALF P

Room And Lecture Filtering Proxy

Responses (2)