diff --git a/tildes/tildes/routes.py b/tildes/tildes/routes.py index e0a197c..bd8b8f4 100644 --- a/tildes/tildes/routes.py +++ b/tildes/tildes/routes.py @@ -19,6 +19,8 @@ from tildes.resources.user import user_by_username def includeme(config: Configurator) -> None: """Set up application routes.""" config.add_route("home", "/") + config.add_route("home_atom", "/topics.atom") + config.add_route("home_rss", "/topics.rss") config.add_route("search", "/search") @@ -37,6 +39,8 @@ def includeme(config: Configurator) -> None: config.add_route("new_topic", "/new_topic", factory=group_by_path) config.add_route("group_topics", "/topics", factory=group_by_path) + config.add_route("group_topics_atom", "/topics.atom", factory=group_by_path) + config.add_route("group_topics_rss", "/topics.rss", factory=group_by_path) config.add_route("group_search", "/search", factory=group_by_path) diff --git a/tildes/tildes/templates/base.atom.jinja2 b/tildes/tildes/templates/base.atom.jinja2 new file mode 100644 index 0000000..f238459 --- /dev/null +++ b/tildes/tildes/templates/base.atom.jinja2 @@ -0,0 +1,14 @@ +{# Copyright (c) 2021 Tildes contributors #} +{# SPDX-License-Identifier: AGPL-3.0-or-later #} + + + + + {% block feed_title %}Tildes Atom feed{% endblock %} + {% block feed_id %}{{ request.current_route_url() }}{% endblock %} + + {% block feed_updated %}{{ current_time.strftime("%Y-%m-%dT%H:%M:%SZ") }}{% endblock %} + + {% block feed_entries %}{% endblock %} + + diff --git a/tildes/tildes/templates/base.jinja2 b/tildes/tildes/templates/base.jinja2 index e434a03..20c7b1b 100644 --- a/tildes/tildes/templates/base.jinja2 +++ b/tildes/tildes/templates/base.jinja2 @@ -55,6 +55,9 @@ + {# RSS/Atom feeds #} + {% block link_alternate_feeds %}{% endblock %} + {% block title_full %}{% block title %}{% endblock %} - Tildes{% endblock %} {% block templates %}{% endblock %} diff --git a/tildes/tildes/templates/base.rss.jinja2 b/tildes/tildes/templates/base.rss.jinja2 new file mode 100644 index 0000000..81e9309 --- /dev/null +++ b/tildes/tildes/templates/base.rss.jinja2 @@ -0,0 +1,15 @@ +{# Copyright (c) 2021 Tildes contributors #} +{# SPDX-License-Identifier: AGPL-3.0-or-later #} + + + + + + {% block channel_title %}Tildes{% endblock %} + {% block channel_link %}https://tildes.net/{% endblock %} + {% block channel_description %}Tildes RSS feed{% endblock %} + + {% block channel_items %}{% endblock %} + + + diff --git a/tildes/tildes/templates/home.atom.jinja2 b/tildes/tildes/templates/home.atom.jinja2 new file mode 100644 index 0000000..31ba90e --- /dev/null +++ b/tildes/tildes/templates/home.atom.jinja2 @@ -0,0 +1,6 @@ +{# Copyright (c) 2021 Tildes contributors #} +{# SPDX-License-Identifier: AGPL-3.0-or-later #} + +{% extends 'topic_listing.atom.jinja2' %} + +{% block feed_title %}Tildes Atom feed{% endblock %} diff --git a/tildes/tildes/templates/home.rss.jinja2 b/tildes/tildes/templates/home.rss.jinja2 new file mode 100644 index 0000000..a353007 --- /dev/null +++ b/tildes/tildes/templates/home.rss.jinja2 @@ -0,0 +1,8 @@ +{# Copyright (c) 2021 Tildes contributors #} +{# SPDX-License-Identifier: AGPL-3.0-or-later #} + +{% extends 'topic_listing.rss.jinja2' %} + +{% block channel_title %}Tildes{% endblock %} +{% block channel_link %}https://tildes.net/{% endblock %} +{% block channel_description %}Topics RSS feed{% endblock %} diff --git a/tildes/tildes/templates/topic_listing.atom.jinja2 b/tildes/tildes/templates/topic_listing.atom.jinja2 new file mode 100644 index 0000000..06f5150 --- /dev/null +++ b/tildes/tildes/templates/topic_listing.atom.jinja2 @@ -0,0 +1,39 @@ +{# Copyright (c) 2021 Tildes contributors #} +{# SPDX-License-Identifier: AGPL-3.0-or-later #} + +{% extends 'base.atom.jinja2' %} + +{% block feed_title %}~{{ group.path }} - Tildes{% endblock %} + +{% block feed_entries %} + + {% for topic in topics %} + + <![CDATA[{{ topic.title }}]]> + https://tildes.net{{ topic.permalink }} + {% if topic.is_link_type %} + + {% else %} + + {% endif %} + Link URL: {{ topic.link }}

+ {% elif topic.is_text_type %} + {{ topic.rendered_html|safe }} +
+ {% endif %} +

Comments URL: https://tildes.net{{ topic.permalink }}

+

Votes: {{ topic.num_votes }}

+

Comments: {{ topic.num_comments }}

+ ]]>
+ {{ topic.user.username }} + {% if topic.last_edited_time %} + {{ topic.last_edited_time.strftime("%Y-%m-%dT%H:%M:%SZ") }} + {% else %} + {{ topic.created_time.strftime("%Y-%m-%dT%H:%M:%SZ") }} + {% endif %} +
+ {% endfor %} + +{% endblock %} diff --git a/tildes/tildes/templates/topic_listing.jinja2 b/tildes/tildes/templates/topic_listing.jinja2 index 1f194b4..5d0a1c0 100644 --- a/tildes/tildes/templates/topic_listing.jinja2 +++ b/tildes/tildes/templates/topic_listing.jinja2 @@ -10,6 +10,11 @@ {% block title %}Topics in ~{{ group.path }}{% endblock %} +{% block link_alternate_feeds %} + + +{% endblock %} + {% block header_context_link %} {{ group_segmented_link(group) }} {% endblock %} diff --git a/tildes/tildes/templates/topic_listing.rss.jinja2 b/tildes/tildes/templates/topic_listing.rss.jinja2 new file mode 100644 index 0000000..4baf187 --- /dev/null +++ b/tildes/tildes/templates/topic_listing.rss.jinja2 @@ -0,0 +1,37 @@ +{# Copyright (c) 2021 Tildes contributors #} +{# SPDX-License-Identifier: AGPL-3.0-or-later #} + +{% extends 'base.rss.jinja2' %} + +{% block channel_title %}~{{ group.path }} - Tildes{% endblock %} +{% block channel_link %}https://tildes.net/~{{ group.path }}{% endblock %} +{% block channel_description %}Topics in ~{{ group.path }}{% endblock %} + +{% block channel_items %} + + {% for topic in topics %} + + <![CDATA[{{ topic.title }}]]> + {% if topic.is_link_type %} + {{ topic.link }} + {% else %} + {{ topic.permalink }} + {% endif %} + Link URL: {{ topic.link }}

+ {% elif topic.is_text_type %} + {{ topic.rendered_html|safe }} +
+ {% endif %} +

Comments URL: https://tildes.net{{ topic.permalink }}

+

Votes: {{ topic.num_votes }}

+

Comments: {{ topic.num_comments }}

+ ]]>
+ {{ topic.user.username }} + {{ topic.permalink }} + {{ topic.created_time.strftime("%a, %d %b %Y %T %z") }} +
+ {% endfor %} + +{% endblock %} diff --git a/tildes/tildes/views/topic.py b/tildes/tildes/views/topic.py index faef389..675144e 100644 --- a/tildes/tildes/views/topic.py +++ b/tildes/tildes/views/topic.py @@ -142,7 +142,11 @@ def post_group_topics( @view_config(route_name="home", renderer="home.jinja2") +@view_config(route_name="home_atom", renderer="home.atom.jinja2") +@view_config(route_name="home_rss", renderer="home.rss.jinja2") @view_config(route_name="group", renderer="topic_listing.jinja2") +@view_config(route_name="group_topics_atom", renderer="topic_listing.atom.jinja2") +@view_config(route_name="group_topics_rss", renderer="topic_listing.rss.jinja2") @use_kwargs(TopicListingSchema()) def get_group_topics( # noqa request: Request, @@ -159,7 +163,9 @@ def get_group_topics( # noqa # period needs special treatment so we can distinguish between missing and None period = kwargs.get("period", missing) - is_home_page = request.matched_route.name == "home" + is_home_page = request.matched_route.name in ["home", "home_atom", "home_rss"] + is_atom = request.matched_route.name in ["home_atom", "group_topics_atom"] + is_rss = request.matched_route.name in ["home_rss", "group_topics_rss"] if is_home_page: # on the home page, include topics from the user's subscribed groups @@ -192,6 +198,11 @@ def get_group_topics( # noqa if period is missing: period = default_settings.period + # force Newest sort order, and All Time period, for RSS feeds + if is_atom or is_rss: + order = TopicSortOption.NEW + period = None + # set up the basic query for topics query = ( request.query(Topic) @@ -285,6 +296,11 @@ def get_group_topics( # noqa else: financial_data = None + if is_atom: + request.response.content_type = "application/atom+xml" + if is_rss: + request.response.content_type = "application/rss+xml" + return { "group": request.context, "groups": groups,