From 5abb379af0228b1b7aaa9d3391dffb18d252168e Mon Sep 17 00:00:00 2001 From: Leon Date: Sat, 19 Jul 2025 19:12:15 +0200 Subject: [PATCH] feat: LetterFeed logo for feed --- README.md | 1 + backend/app/services/feed_generator.py | 2 ++ backend/app/tests/test_routers.py | 3 +++ backend/app/tests/test_services.py | 1 + 4 files changed, 7 insertions(+) diff --git a/README.md b/README.md index 139d851..021eacf 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ LetterFeed is a self-hosted application that transforms your email newsletters i - **Content Extraction:** Optionally, LetterFeed can extract the main article content from the email body. - **Email Management:** Can automatically move processed emails to a specified folder in your inbox to keep things organized. - **Easy to Use Interface:** A simple web interface to manage your newsletters and feeds. +- **Authentication:** Optional username + password auth. ## How It Works diff --git a/backend/app/services/feed_generator.py b/backend/app/services/feed_generator.py index 8f9e785..7d8d21d 100644 --- a/backend/app/services/feed_generator.py +++ b/backend/app/services/feed_generator.py @@ -16,10 +16,12 @@ def generate_feed(db: Session, newsletter_id: str): entries = get_entries_by_newsletter(db, newsletter_id) feed_url = f"{settings.app_base_url}/feeds/{newsletter_id}" + logo_url = f"{settings.app_base_url}/logo.png" fg = FeedGenerator() fg.id(f"urn:letterfeed:newsletter:{newsletter.id}") fg.title(newsletter.name) + fg.logo(logo_url) fg.link(href=feed_url, rel="self") sender_emails = ", ".join([s.email for s in newsletter.senders]) fg.description(f"A feed of newsletters from {sender_emails}") diff --git a/backend/app/tests/test_routers.py b/backend/app/tests/test_routers.py index 053aabb..2a3dcc1 100644 --- a/backend/app/tests/test_routers.py +++ b/backend/app/tests/test_routers.py @@ -182,6 +182,9 @@ def test_get_newsletter_feed(client: TestClient): root = ET.fromstring(response.text) # Atom feed uses a namespace, so we need to include it in our tag searches ns = {"atom": "http://www.w3.org/2005/Atom"} + logo = root.find("atom:logo", ns) + assert logo is not None + assert logo.text == "http://localhost:8000/logo.png" entry_titles = [ entry.find("atom:title", ns).text for entry in root.findall("atom:entry", ns) ] diff --git a/backend/app/tests/test_services.py b/backend/app/tests/test_services.py index 1e5b49d..0e7dd36 100644 --- a/backend/app/tests/test_services.py +++ b/backend/app/tests/test_services.py @@ -40,6 +40,7 @@ def test_generate_feed(db_session: Session): # In a real scenario, you'd use an XML parser to validate structure and content more thoroughly assert f"{newsletter.name}" in feed_xml.decode() assert f"urn:letterfeed:newsletter:{newsletter.id}" in feed_xml.decode() + assert "http://localhost:8000/logo.png" in feed_xml.decode() assert "First Entry" in feed_xml.decode() assert "Second Entry" in feed_xml.decode() assert (