Added support for RSS and Atom feeds, because why not
This commit is contained in:
parent
c34ec965a1
commit
730a2bcb9d
7 changed files with 106 additions and 3 deletions
79
entries/feeds.py
Normal file
79
entries/feeds.py
Normal 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
|
|
@ -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',
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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' %}" />
|
||||||
|
|
Loading…
Reference in a new issue