Added support for RSS and Atom feeds, because why not

This commit is contained in:
Danielle McLean 2017-11-01 09:29:59 +11:00
parent c34ec965a1
commit 730a2bcb9d
Signed by untrusted user: 00dani
GPG key ID: 5A5D2D1AFF12EEC5
7 changed files with 106 additions and 3 deletions

79
entries/feeds.py Normal file
View file

@ -0,0 +1,79 @@
from django.contrib.sites.models import Site
from django.contrib.syndication.views import Feed
from django.urls import reverse
from django.utils.feedgenerator import Atom1Feed
from urllib.parse import urljoin
from .models import Entry
class EntriesFeed(Feed):
def item_title(self, entry):
return entry.title
def item_description(self, entry):
return entry.content
def item_author_name(self, entry):
return entry.author.name
def item_author_email(self, entry):
return entry.author.email
def item_author_link(self, entry):
base = 'https://' + Site.objects.get_current().domain
return urljoin(base, entry.author.url)
def item_pubdate(self, entry):
return entry.published
def item_updatedate(self, entry):
return entry.updated
class RssByKind(EntriesFeed):
def __init__(self, kind):
self.kind = kind
def title(self):
return "{0} ~ {1}".format(
self.kind.plural,
Site.objects.get_current().name,
)
def link(self):
return reverse('entries:' + self.kind.index)
def description(self):
return "all {0} at {1}".format(
self.kind.plural,
Site.objects.get_current().name,
)
def items(self):
return Entry.objects.filter(kind=self.kind.id)
class AtomByKind(RssByKind):
feed_type = Atom1Feed
subtitle = RssByKind.description
class RssAllEntries(EntriesFeed):
def title(self):
return Site.objects.get_current().name
def link(self):
return reverse('home:index')
def description(self):
return "content from {0}".format(
Site.objects.get_current().name,
)
def items(self):
return Entry.objects.all()
class AtomAllEntries(RssAllEntries):
feed_type = Atom1Feed
subtitle = RssAllEntries.description

View file

@ -13,6 +13,14 @@ class Entry:
def entry(self): def entry(self):
return self.plural + '_entry' return self.plural + '_entry'
@property
def atom(self):
return self.plural + '_atom'
@property
def rss(self):
return self.plural + '_rss'
Note = Entry( Note = Entry(
id='note', id='note',

View file

@ -1,9 +1,11 @@
{% extends 'lemoncurry/layout.html' %} {% extends 'lemoncurry/layout.html' %}
{% load static %} {% load static %}
{% block html_class %}h-feed{% endblock %} {% block html_class %}h-feed{% endblock %}
{% block styles %} {% block styles %}
<link rel="stylesheet" type="text/stylus" href="{% static 'entries/css/h-entry.styl' %}" /> <link rel="stylesheet" type="text/stylus" href="{% static 'entries/css/h-entry.styl' %}" />
{% endblock %} {% endblock %}
{% block main %} {% block main %}
<ol class="container list-unstyled entries"> <ol class="container list-unstyled entries">
{% for entry in entries %} {% for entry in entries %}

View file

@ -1,5 +1,5 @@
from django.conf.urls import url from django.conf.urls import url
from . import kinds, views from . import feeds, kinds, views
from lemoncurry import breadcrumbs as crumbs from lemoncurry import breadcrumbs as crumbs
@ -12,13 +12,18 @@ def prefix(route):
app_name = 'entries' app_name = 'entries'
urlpatterns = [] urlpatterns = [
url('^atom$', feeds.AtomAllEntries(), name='atom'),
url('^rss$', feeds.RssAllEntries(), name='rss'),
]
for k in kinds.all: for k in kinds.all:
kind = k.plural kind = k.plural
id = r'/(?P<id>\d+)' id = r'/(?P<id>\d+)'
slug = r'(?:/(?P<slug>.+))?' slug = r'(?:/(?P<slug>.+))?'
urlpatterns += ( urlpatterns += (
url(to_pat(kind), views.index, name=k.index, kwargs={'kind': k}), url(to_pat(kind), views.index, name=k.index, kwargs={'kind': k}),
url(to_pat(kind, '/atom'), feeds.AtomByKind(k), name=k.atom),
url(to_pat(kind, '/rss'), feeds.RssByKind(k), name=k.rss),
url(to_pat(kind, id, slug), views.entry, name=k.entry), url(to_pat(kind, id, slug), views.entry, name=k.entry),
) )

View file

@ -6,7 +6,12 @@ from .models import Entry
@render_to('entries/index.html') @render_to('entries/index.html')
def index(request, kind): def index(request, kind):
entries = Entry.objects.filter(kind=kind.id) entries = Entry.objects.filter(kind=kind.id)
return {'entries': entries, 'title': kind.plural} return {
'entries': entries,
'atom': 'entries:' + kind.atom,
'rss': 'entries:' + kind.rss,
'title': kind.plural,
}
@render_to('entries/entry.html') @render_to('entries/entry.html')

View file

@ -17,6 +17,8 @@ def index(request):
return { return {
'user': user, 'user': user,
'entries': user.entries.all(), 'entries': user.entries.all(),
'atom': 'entries:atom',
'rss': 'entries:rss',
'meta': user.as_meta(request), 'meta': user.as_meta(request),
} }

View file

@ -6,6 +6,8 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<link rel="canonical" href="{{ uri }}" /> <link rel="canonical" href="{{ uri }}" />
{% if atom %}<link rel="alternate" type="application/atom+xml" href="{% url atom %}" />{% endif %}
{% if rss %}<link rel="alternate" type="application/rss+xml" href="{% url rss %}" /> {% endif %}
{% block head %}{% endblock %} {% block head %}{% endblock %}
<link rel="authorization_endpoint" href="{{ origin }}{% url 'lemonauth:indie' %}" /> <link rel="authorization_endpoint" href="{{ origin }}{% url 'lemonauth:indie' %}" />