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'
'
+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 @@