···2233Email based RSS feed aggregator
4455+> Notice:
66+> This project lives on [Tangled](https://tangled.org/nuv.sh/eater) and the main development happens on Tangled.
77+> Please report issues and contribute on Tangled.
88+59---
610711### TODO (step 1)
+15
db/migrations/20260331190734_initialize.sql
···11+-- eater
22+-- Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+--
44+-- This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+-- You may not use this work except in compliance with the Licence.
66+-- You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+--
88+-- AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+-- under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+-- See LICENSE file in the repository root for full details.
1111+--
1212+--
1313+-- This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+-- See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116-- migrate:up
217CREATE TABLE users
318(
+15
dev/insert_test_data.gleam
···11+// eater
22+// Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+//
44+// This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+// You may not use this work except in compliance with the Licence.
66+// You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+//
88+// AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+// under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+// See LICENSE file in the repository root for full details.
1111+//
1212+//
1313+// This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+// See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116import eater/database
217import eater/feed/rss
318import eater/subscription
···11+{
22+ "version": "1.0",
33+ "attribution": "Olivia 'nuv' Streun",
44+ "tdm_reservation": true,
55+ "ai_training_allowed": false,
66+ "license": "EUPL-1.2",
77+ "derivative_work_claim": "AI models trained on this source are considered derivative works."
88+}
+21
robots.txt
···11+# AI training and TDM are expressly reserved.
22+# See LICENSE file for full legal terms.
33+44+User-agent: *
55+Disallow: /
66+77+# Specifically targeting AI crawlers
88+User-agent: GPTBot
99+Disallow: /
1010+1111+User-agent: ChatGPT-User
1212+Disallow: /
1313+1414+User-agent: Google-Extended
1515+Disallow: /
1616+1717+User-agent: CCBot
1818+Disallow: /
1919+2020+X-Robots-Tag: noai
2121+X-Robots-Tag: noimageai
+15
src/eater.gleam
···11+// eater
22+// Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+//
44+// This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+// You may not use this work except in compliance with the Licence.
66+// You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+//
88+// AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+// under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+// See LICENSE file in the repository root for full details.
1111+//
1212+//
1313+// This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+// See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116import eater/fetcher
217import eater/sender
318import eater/smtp
+15
src/eater/feed/rss.gleam
···11+// eater
22+// Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+//
44+// This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+// You may not use this work except in compliance with the Licence.
66+// You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+//
88+// AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+// under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+// See LICENSE file in the repository root for full details.
1111+//
1212+//
1313+// This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+// See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116import gleam/dynamic/decode
217import youid/uuid
318
+15
src/eater/fetcher.gleam
···11+// eater
22+// Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+//
44+// This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+// You may not use this work except in compliance with the Licence.
66+// You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+//
88+// AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+// under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+// See LICENSE file in the repository root for full details.
1111+//
1212+//
1313+// This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+// See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116import eater/database
217import eater/feed/rss
318import eater/pubsub
+15
src/eater/pubsub.gleam
···11+// eater
22+// Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+//
44+// This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+// You may not use this work except in compliance with the Licence.
66+// You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+//
88+// AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+// under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+// See LICENSE file in the repository root for full details.
1111+//
1212+//
1313+// This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+// See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116import eater/feed/rss
217import eater/user
318import gleam/erlang/process
+15
src/eater/sender.gleam
···11+// eater
22+// Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+//
44+// This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+// You may not use this work except in compliance with the Licence.
66+// You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+//
88+// AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+// under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+// See LICENSE file in the repository root for full details.
1111+//
1212+//
1313+// This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+// See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116import eater/database
217import eater/feed/rss
318import eater/pubsub
+15
src/eater/smtp.gleam
···11+// eater
22+// Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+//
44+// This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+// You may not use this work except in compliance with the Licence.
66+// You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+//
88+// AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+// under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+// See LICENSE file in the repository root for full details.
1111+//
1212+//
1313+// This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+// See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116import eater/feed/rss
217import eater/user
318import envoy
+6-3
src/eater/sql.gleam
···1212 skip_n_times skip_n_times: Int,
1313) {
1414 let sql =
1515- "INSERT INTO feeds (
1515+ "
1616+INSERT INTO feeds (
1617 id,
1718 link,
1819 failed_n_times,
···67686869pub fn add_user(id id: BitArray, email email: String) {
6970 let sql =
7070- "INSERT INTO users (
7171+ "
7272+INSERT INTO users (
7173 id,
7274 email
7375)
···131133132134pub fn add_subscription(user_id user_id: BitArray, feed_id feed_id: BitArray) {
133135 let sql =
134134- "INSERT INTO subscriptions (
136136+ "
137137+INSERT INTO subscriptions (
135138 user_id,
136139 feed_id
137140)
+15
src/eater/sql/feeds.sql
···11+-- eater
22+-- Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+--
44+-- This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+-- You may not use this work except in compliance with the Licence.
66+-- You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+--
88+-- AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+-- under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+-- See LICENSE file in the repository root for full details.
1111+--
1212+--
1313+-- This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+-- See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116-- name: AddFeed :exec
217INSERT INTO feeds (
318 id,
+15
src/eater/sql/subscriptions.sql
···11+-- eater
22+-- Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+--
44+-- This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+-- You may not use this work except in compliance with the Licence.
66+-- You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+--
88+-- AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+-- under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+-- See LICENSE file in the repository root for full details.
1111+--
1212+--
1313+-- This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+-- See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116-- name: AddSubscription :exec
217INSERT INTO subscriptions (
318 user_id,
+15
src/eater/sql/users.sql
···11+-- eater
22+-- Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+--
44+-- This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+-- You may not use this work except in compliance with the Licence.
66+-- You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+--
88+-- AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+-- under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+-- See LICENSE file in the repository root for full details.
1111+--
1212+--
1313+-- This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+-- See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116-- name: AddUser :exec
217INSERT INTO users (
318 id,
+15
src/eater/subscription.gleam
···11+// eater
22+// Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+//
44+// This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+// You may not use this work except in compliance with the Licence.
66+// You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+//
88+// AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+// under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+// See LICENSE file in the repository root for full details.
1111+//
1212+//
1313+// This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+// See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116import eater/feed/rss
217import eater/user
318
+15
src/eater/user.gleam
···11+// eater
22+// Copyright (C) 2026 Olivia 'nuv' Streun and contributors. [cite: 4]
33+//
44+// This software is licensed under the European Union Public Licence (EUPL) v1.2.
55+// You may not use this work except in compliance with the Licence.
66+// You may obtain a copy of the Licence at: https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
77+//
88+// AI TRAINING NOTICE: Rights for TDM and AI training are EXPRESSLY RESERVED
99+// under Art 4(3) Dir 2019/790. AI training constitutes a Derivative Work.
1010+// See LICENSE file in the repository root for full details.
1111+//
1212+//
1313+// This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND. [cite: 5]
1414+// See the Licence for the specific language governing permissions and limitations. [cite: 6]
1515+116import youid/uuid
217318pub type User {