Corentin Dautrême
Portfolio
When I'm not working, I
code create learn

I've made a thing or two over the years. Some to bring an idea to life, some to learn cool new stuff.

On this page, you can read a bit about some of them, check out some pretty screenshots, or even find links to online demos.

Background pattern: 3d Wavy by Temani Afif
Feb 28, 2026
The 76th Festival di Sanremo will take place from February 24 to February 28,
Saturday, Feb 28, 2026
areena.yle.fi/suorat
08
Mar
20:00
Sweden
Melodifestivalen
Final
2 link(s)
2 VOD
Photo: Alma Bengtsson/EBU
Eurovoix
May 16, 2025

🇫🇮 Finland: Uuden Musiikin Kilpailu 2026 on February 28 - Eurovoix

Yle, the Finnish national broadcaster, has confirmed that Uuden Musiikin Kilpailu 2026 will take place on February 28.
Mar 7, 2026
Technical
Fetcher
Last on Jan 1
Dump
Last on Jan 1
Refresh
Last on Jan 1

Add link

1970-01-01T00:00:00.014Z END RequestId: 00000001-ffff-ffff-ffff-abcdef012345
1970-01-01T00:00:00.013Z REPORT RequestId: 00000001-ffff-ffff-ffff-abcdef012345 Duration: 4.00 ms Billed Duration: 4 ms Memory Size: 128 MB Max Memory Used: 89 MB
1970-01-01T00:00:00.012ZRun date 1970-01-01T00:00:00 is outside of NF season range - exiting
1970-01-01T00:00:00.011Zdaily|twitter
1970-01-01T00:00:00.010ZSTART RequestId: 00000001-ffff-ffff-ffff-abcdef012345 Version: $LATEST
1970-01-01T00:00:00.004ZEND RequestId: 00000000-ffff-ffff-ffff-abcdef012345
1970-01-01T00:00:00.003ZREPORT RequestId: 00000000-ffff-ffff-ffff-abcdef012345 Duration: 4.00 ms Billed Duration: 4 ms Memory Size: 128 MB Max Memory Used: 89 MB
1970-01-01T00:00:00.002ZRun date 1970-01-01T00:00:00 is outside of NF season range - exiting
1970-01-01T00:00:00.001Zdaily|twitter
1970-01-01T00:00:00.000ZSTART RequestId: 00000000-ffff-ffff-ffff-abcdef012345 Version: $LATEST
Bluesky
now
Lys
🚨5 MINUTES REMINDER!
Bluesky
now
Lys
TONIGHT | 3 selection shows across Europe!
Background pattern: Curvy by Temani Afif
Lys
Live
A calendar-based Python social media bot running on AWS, and managed & monitored through a Next.js webapp.
Python 3
AWS Lambda, DynamoDB, CloudWatch, Javascript SDK, Java SDK
Next.js 15 React, Typescript, Tailwind CSS
Android SDK Kotlin, Java
CI/CD GitHub Actions, Vercel
A Eurovision-flavored bot

Lys is a bot that publishes scheduled reminders about upcoming Eurovision national selection shows to social media. The reminders include the show's date and time, as well as links to watch it.

Launched on Twitter back in 2019, Lys has since found its way to Bluesky and Threads.

Next
The AWS Python bot
The AWS Python bot

At the core of the app is the bot itself. Lambdas, triggered on a schedule defined through CloudWatch Cron Triggers, read events from a DynamoDB table, then build & publish posts to social media via their public APIs.

The Python code base is modular and makes it easy to support new platforms and customize posts.

Next
The event fetcher
The event fetcher

Once live, maintaining the calendar table in DynamoDB turned out to be the most time consuming.

A nightly Python script parses the Eurovoix RSS feed to extract show dates and compile them into meaningful suggestions to review manually in the management app.

Once accepted, suggestions are enriched with static data to generate events.

Next
The management app
Sep 1, 2025
Feb 12, 2026
Feb 14, 2026
[...] Final of Benidorm Fest 2026 will be held on February 14
Saturday, Feb 14, 2026
The management app

Initially a native Kotlin app for Android, the Lys management application was later rewritten from scratch as a 100% responsive Next.js webapp.

It relies on the v3 of the AWS Javascript SDK to offer data read/write and monitoring tools.

Next
The management app (cont.)
The management app (cont.)

The app is publicly hosted through Vercel, with a custom authorization filter based on Github authentication to restrict access.

Next
To go further
To go further
Marijin Dvor
1
2
5
6
Skenderija
6
1
Baš.
2
Baš.
5
Baš.
101
103
102
Oto.
105
Trg. A.
107
Dob.
Pošta
1
Baš.
2
Baš.
5
Baš.
Drvenija
1
Baš.
2
Baš.
5
Baš.
101
103
105
Latinska Ćuprija
1
Baš.
2
Baš.
5
Baš.
Vijećnica
1
Baš.
2
Baš.
5
Baš.
Park
1
Želj. S.
2
Čen. V.
5
Nedž.
Banka
1
Želj. S.
2
Čen. V.
5
Nedž.
Katedrala
1
Želj. S.
2
Čen. V.
5
Nedž.
Baščaršija
1
2
5
Otoka
3
4
5
6
102
108
Skenderija
3
Baščaršija
now
4 min
8 min
$
curl -X GET https://transitplanner/lines
[ { "name""3", "type""tram", "directions": [ "Baščaršija", "Ilidža" ] }, { "name""107", "type""trolleybus", "directions": [ "Dobrinja", "Jezero" ] }, { "name""105", "type""trolleybus", "directions": [ "Vogošća Terminal", "Trg Austrije" ] }, { "name""101", "type""trolleybus", "directions": [ "Otoka", "Trg Austrije" ] }, { "name""102", "type""trolleybus", "directions": [ "Otoka", "Jezero" ] }, { "name""103", "type""trolleybus", "directions": [ "Dobrinja", "Trg Austrije" ] }, { "name""108", "type""trolleybus", "directions": [ "Otoka", "Dobrinja" ] }, { "name""1", "type""tram", "directions": [ "Željeznička Stanica", "Baščaršija" ] }, { "name""2", "type""tram", "directions": [ "Baščaršija", "Čengić Vila" ] }, { "name""4", "type""tram", "directions": [ "Željeznička Stanica", "Ilidža" ] }, { "name""5", "type""tram", "directions": [ "Baščaršija", "Nedžarići" ] }, { "name""6", "type""tram", "directions": [ "Ilidža", "Skenderija" ] }, { "name""200E", "type""bus", "directions": [ "Bentbaša", "Međunarodni Aerodrom Sarajevo" ] }, { "name""31E", "type""bus", "directions": [ "Vijećnica", "Dobrinja" ] } ]
Background pattern: Diagonal Arrows by Temani Afif
Transit planner
A Node.js backend API to expose public transport data - and a simple Next.js demo webapp.
Node.js Typescript, Express, Prisma ORM, OpenAPI, Swagger, Jest
Next.js 15 React, Typescript, Tailwind CSS
PostgreSQL
Getting around Sarajevo

I got the idea for this project shortly after moving to Sarajevo. The city is served by a competent transport network, but it sadly lacks a centralized app that provides all sorts of information (line routes, departures, etc.).

Since I was looking for an excuse to try my hand at Node.js backend development, I thought I'd give making such an app a go.

Next
Gathering data
Gathering data

Not only is there no centralized source of data, sometimes the data is at best hard to find, at worst inexistent, and most often inaccurate.

Finding even the list of stops for a line turned out to be a challenge. I ended up focusing on the main lines (so I could at least write a bit of code!)

Next
The app
The app

Although the main focus of this project was the Node.js backend, I couldn't help using my recently acquired Next.js knowledge to build a small web app to display all that exposed data.

It turned out to be a good idea: there's no better way to design a good API than being one of its users. I ended up re-designing my endpoints more than once, because my initial approach didn't turn out very practical in the end.

Next
Line routes
Line routes

The first endpoints I implemented are to describe lines and the routes they take.

This one, describe-line, returns the type of the line, its directions, and all stops alongside each direction - along with the available connections at that stop.

GET
/lines/describe-line
{
  "name": string,
  "type": "tram" | "trolleybus" | "bus",
  "directions": string[],
  "routes": [
    {
      "direction": string,
      "stops": [
        {
          "id": number,
          "name": string,
          "connections": [
            {
              "line": string,
              "type": "tram" | "trolleybus" | "bus",
              "directions": string[]
            }
          ]
        }
      ]
    }
  ]
}
                  
Next
Departures
Departures

I then moved on to endpoints exposing departures.

The /departures/next endpoint returns the desired number of upcoming departures at a stop, per line and direction, for the remainder of the day. It also offers the possibility to filter by line and direction.

The output includes a list of lines served at the stop, as well as some extra decoration data (line type, directions...) for display purposes.

GET
/departures/next
{
  "stop": {
    "id": number,
    "name": string,
    "connections": [
      {
        "line": string,
        "type": "tram" | "trolleybus" | "bus",
        "directions": string[]
      }
    ]
  },
  "departures": {
    [line: string]: {
      "type": "tram" | "trolleybus" | "bus",
      "departures": {
        [direction: string]: [
          {
            "scheduledAt": string
          }
      }
    }
  }
}
                  
Next
Departures (cont.)
Departures (cont.)

No no, you're not seeing double - the /departures/scheduled endpoint looks exactly like its /departures/next neighbour, but this one is meant to expose scheduled departures - while /next would (for an ideal network that publicly exposes real-time data) return live data.

GET
/departures/scheduled
{
  "stop": {
    "id": number,
    "name": string,
    "connections": [
      {
        "line": string,
        "type": "tram" | "trolleybus" | "bus",
        "directions": string[]
      }
    ]
  },
  "departures": {
    [line: string]: {
      "type": "tram" | "trolleybus" | "bus",
      "departures": {
        [direction: string]: [
          {
            "scheduledAt": string
          }
      }
    }
  }
}
                  
Background pattern: Cross by Jim Raptis
ESC 2021 logo generator
A Javascript and HTML/CSS interactive playground based on the logo of the Eurovision Song Contest 2021 designed by CLEVER ° FRANKE.
CSS
Javascript jQuery
HTML
A data-based logo

The logo of the 2021 Eurovision Song Contest was algorithmically designed by CLEVER ° FRANKE. It represents the distance between the host city, Rotterdam, and the capital of each participating country.

I found this ridiculously cool and clever, and wanted to see if it could be programatically recreated.

Next
Custom Slice Styling (CSS)
Custom Slice Styling (CSS)

I had previously recreated the logos of the 2021 and 2020 contests (both designed by the same team and following a similar concept).

Making it work for this project would only require a few adjsutments.

Next
Computing distances
Computing distances

The goal of this project is to generate alternative 2021 logos, using any city as the center.

For that, we first need to compute angles and distances between the selected city and all others - which we can do using GPS coordinates.

We then group cities by angle ranges - or "slices". For example, from Lisbon, Portugal we can group Brussels, Amsterdam, and Oslo within a single slice at ~40°.

Next
Coordinates to slice
Lisbon
Brussels
Amsterdam
Oslo
Coordinates to slice

Using CSS variables, slices can be dynamically configured with normalized values of the computed distances and angles.

GPS coordinates are hardcoded, and the generator simply regenerates all slices on the fly when a city is selected.

Next
To go further
BE
1710.5km
NL
+163.5km
NO
+875.3km
Lisbon
To go further