From bf3028e7d6f51db9a4fe5ddd2fb8977d945816f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Wed, 10 Jun 2026 22:30:53 +0300 Subject: [PATCH] re-add rss feeds --- app/lib/babycode.py | 10 +++++++++- app/routes/threads.py | 24 ++++++++++++++++++------ app/routes/topics.py | 21 +++++++++++++++++---- app/templates/base.atom | 20 ++++++++++++++++++++ app/templates/base.html | 3 +++ app/templates/common/macros.html | 4 ++++ app/templates/threads/thread.atom | 20 ++++++++++++++++++++ app/templates/topics/topic.atom | 21 +++++++++++++++++++++ app/templates/topics/topic.html | 2 +- 9 files changed, 113 insertions(+), 12 deletions(-) create mode 100644 app/templates/base.atom create mode 100644 app/templates/threads/thread.atom create mode 100644 app/templates/topics/topic.atom diff --git a/app/lib/babycode.py b/app/lib/babycode.py index 110c5a7..db00866 100644 --- a/app/lib/babycode.py +++ b/app/lib/babycode.py @@ -6,7 +6,7 @@ from pygments.lexers import get_lexer_by_name from pygments.util import ClassNotFound as PygmentsClassNotFound import re -BABYCODE_VERSION = 11 +BABYCODE_VERSION = 13 class BabycodeError(Exception): @@ -406,6 +406,13 @@ def tag_quote(children, attr): return f'
{quotee}
{children}
' +def tag_quote_rss(children, attr): + if attr: + quotee = f'Quoting: {attr.strip()}' + return f'
{children}
{quotee}
' + else: + return f'
{children}
' + TAGS = { "b": lambda children, attr: f"{children}", "i": lambda children, attr: f"{children}", @@ -462,6 +469,7 @@ RSS_TAGS = { 'url': tag_url_rss, 'spoiler': lambda children, attr: f'
{attr or "Spoiler"} (click to reveal){children}
', 'code': tag_code_rss, + 'quote': tag_quote_rss, 'big': lambda children, attr: f'{children}', 'small': lambda children, attr: f'{children}' diff --git a/app/routes/threads.py b/app/routes/threads.py index 5a5f5cf..751726d 100644 --- a/app/routes/threads.py +++ b/app/routes/threads.py @@ -1,8 +1,10 @@ -from flask import Blueprint, redirect, url_for, render_template, request, abort +from flask import Blueprint, redirect, url_for, render_template, request, abort, current_app from functools import wraps +from app import cache from ..auth import login_required, get_active_user, is_logged_in from ..db import db from ..models import Threads, Posts, Topics, Users, Reactions, Subscriptions +from ..lib.render_atom import render_atom_template from ..util import get_form_checkbox, time_now import math @@ -70,9 +72,23 @@ def thread(thread_id, slug): posts=posts, page=page, page_count=page_count, topic=topic, started_by=started_by, topics=Topics.get_list(), - Reactions=Reactions, last_post=last_post + Reactions=Reactions, last_post=last_post, + __feedlink=url_for('.feed', thread_id=thread_id, _external=True), + __feedtitle=f'replies to {thread.title}', ) +@bp.get('//feed.atom/') +@cache.cached(timeout=5 * 60, unless=lambda: current_app.config['DEBUG']) +def feed(thread_id): + thread = Threads.find({'id': thread_id}) + if not thread: + abort(404) + + topic = Topics.find({'id': thread.topic_id}) + posts = thread.get_posts_rss() + + return render_atom_template('threads/thread.atom', thread=thread, topic=topic, posts=posts) + @bp.post('//') @login_required def reply(thread_id): @@ -195,10 +211,6 @@ def mark_read(): return redirect(url_for('users.inbox', username=user.username)) -@bp.get('//feed.atom/') -def feed(thread_id): - return 'stub' - @bp.get('/new/') @login_required def new(): diff --git a/app/routes/topics.py b/app/routes/topics.py index 4476b58..7c42a7f 100644 --- a/app/routes/topics.py +++ b/app/routes/topics.py @@ -1,5 +1,6 @@ -from flask import Blueprint, redirect, url_for, render_template, request, session, abort - +from flask import Blueprint, redirect, url_for, render_template, request, session, abort, current_app +from app import cache +from ..lib.render_atom import render_atom_template from ..models import Topics, Threads, Subscriptions from ..auth import get_active_user import math @@ -42,8 +43,20 @@ def topic(topic_id, slug): subscription = Subscriptions.find({'user_id': user.id, 'thread_id': thread['id']}) if subscription: subscriptions[thread['id']] = subscription.get_unread_count() - return render_template('topics/topic.html', topic=topic, threads=threads, sort_by=sort_by, page=page, page_count=page_count, subscriptions=subscriptions) + return render_template( + 'topics/topic.html', topic=topic, + threads=threads, sort_by=sort_by, + page=page, page_count=page_count, subscriptions=subscriptions, + __feedlink=url_for('.feed', topic_id=topic_id, _external=True), + __feedtitle=f'latest threads in {topic.name}', + ) @bp.get('//feed.atom/') +@cache.cached(timeout=5 * 60, unless=lambda: current_app.config['DEBUG']) def feed(topic_id): - return 'stub' + topic = Topics.find({'id': topic_id}) + if not topic: + abort(404) + + threads_list = topic.get_threads_with_op_rss() + return render_atom_template('topics/topic.atom', topic=topic, threads_list=threads_list) diff --git a/app/templates/base.atom b/app/templates/base.atom new file mode 100644 index 0000000..21aa7e1 --- /dev/null +++ b/app/templates/base.atom @@ -0,0 +1,20 @@ + + + {%- if self.title() -%} + {%- block title -%}{%- endblock -%} + {%- else -%} + {{- config.SITE_NAME -}} + {%- endif -%} + {%- if self.feed_updated() -%} + {%- block feed_updated -%}{%- endblock -%} + {%- else -%} + {{- get_time_now() | iso8601 -}} + {%- endif -%} + {{- __current_page -}} + + + {%- if self.feed_author() -%} + {%- block feed_author -%}{%- endblock -%} + {%- endif -%} + {%- block content -%}{%- endblock -%} + diff --git a/app/templates/base.html b/app/templates/base.html index 37f6c13..f413ab0 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -11,6 +11,9 @@ {%- else -%} {{ config.SITE_NAME }} {%- endif -%} + {%- if __feedlink -%} + + {%- endif -%} diff --git a/app/templates/common/macros.html b/app/templates/common/macros.html index 0eabf79..e7be0ee 100644 --- a/app/templates/common/macros.html +++ b/app/templates/common/macros.html @@ -302,3 +302,7 @@
{{ caller() }}
{%- endmacro %} + +{% macro rss_html_content(html) -%} +{{ html }} +{%- endmacro %} diff --git a/app/templates/threads/thread.atom b/app/templates/threads/thread.atom new file mode 100644 index 0000000..63772c8 --- /dev/null +++ b/app/templates/threads/thread.atom @@ -0,0 +1,20 @@ +{% from 'common/macros.html' import rss_html_content %} +{%- extends 'base.atom' -%} +{%- block title -%}replies to {{thread.title}}{%- endblock -%} +{%- block canonical_link -%}{{ url_for('threads.thread_by_id', thread_id=thread.id, _external=true) }}{%- endblock -%} +{%- block content -%} + {%- for post in posts -%} + {%- set post_url = get_post_url(post.id, _anchor=true, external=true) -%} + + Re: {{ thread.title | escape }} + + {{ post_url }} + {{ post.edited_at | iso8601 }} + {{ rss_html_content(post.content_rss) }} + + {{ post.display_name | escape }} @{{ post.username }} + {{ url_for('users.user_page', username=post.username, _external=true) }} + + + {%- endfor -%} +{%- endblock -%} diff --git a/app/templates/topics/topic.atom b/app/templates/topics/topic.atom new file mode 100644 index 0000000..208c322 --- /dev/null +++ b/app/templates/topics/topic.atom @@ -0,0 +1,21 @@ +{% from 'common/macros.html' import rss_html_content %} +{%- extends 'base.atom' -%} +{%- block title -%}latest threads in {{topic.name | escape}}{%- endblock -%} +{%- block canonical_link -%}{{ url_for('topics.topic_by_id', topic_id=topic.id, _external=true) }}{%- endblock -%} +{%- block content -%} + {{ topic.description | escape }} + {%- for thread in threads_list -%} + + {{ thread.title | escape }} + + + {{ url_for('threads.thread_by_id', thread_id=thread.id, _external=true) }} + {{ rss_html_content(thread.original_post_content) }} + {{ thread.created_at | iso8601 }} + + {{ thread.started_by_display_name | escape }} @{{ thread.started_by }} + {{ url_for('users.user_page', username=thread.started_by, _external=true) }} + + + {%- endfor -%} +{%- endblock -%} diff --git a/app/templates/topics/topic.html b/app/templates/topics/topic.html index b7e2427..43585bb 100644 --- a/app/templates/topics/topic.html +++ b/app/templates/topics/topic.html @@ -20,7 +20,7 @@ Subscribe via RSS