Ben Sturmfels
b7e2ce2a4d
The relative imports make it clearer what code is within the project and where it's coming from.
260 lines
8.4 KiB
Python
260 lines
8.4 KiB
Python
from datetime import datetime
|
|
from functools import reduce
|
|
import itertools
|
|
import operator
|
|
|
|
from django.conf import settings
|
|
from django.contrib.syndication.views import Feed
|
|
from django.shortcuts import render
|
|
from django.utils.feedgenerator import Rss201rev2Feed
|
|
|
|
from .apps.blog.models import Entry as BlogEntry
|
|
from .apps.news.models import PressRelease
|
|
|
|
|
|
class ConservancyFeedBase(Feed):
|
|
def copyright_holder(self): return "Software Freedom Conservancy"
|
|
|
|
def license_no_html(self): return "Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License."
|
|
|
|
def item_copyright(self, item):
|
|
year = 2008
|
|
for attr in ('pub_date', 'date_created', 'date_last_modified'):
|
|
if hasattr(item, attr):
|
|
if hasattr(getattr(item, attr), 'year'):
|
|
year = getattr(getattr(item, attr), 'year')
|
|
break
|
|
return 'Copyright (C) %d, %s. %s' % (year, self.copyright_holder(), self.license_no_html())
|
|
|
|
def item_extra_kwargs(self, item):
|
|
year = 2008
|
|
for attr in ('pub_date', 'date_created', 'date_last_modified'):
|
|
if hasattr(item, attr):
|
|
if hasattr(getattr(item, attr), 'year'):
|
|
year = getattr(getattr(item, attr), 'year')
|
|
break
|
|
return { 'year' : year }
|
|
|
|
class PressReleaseFeed(Feed):
|
|
get_absolute_url = '/feeds/news/'
|
|
title = "Software Freedom Conservancy News"
|
|
link = "/news/"
|
|
description = ""
|
|
|
|
def items(self):
|
|
return PressRelease.objects.filter(pub_date__lte=datetime.now(),
|
|
sites__id__exact=settings.SITE_ID).order_by('-pub_date')[:10]
|
|
def item_title(self, item):
|
|
return item.headline
|
|
|
|
def item_description(self, item):
|
|
return item.summary
|
|
|
|
def item_pubdate(self, item):
|
|
return item.pub_date
|
|
|
|
class OmnibusFeedType(Rss201rev2Feed):
|
|
def root_attributes(self):
|
|
attrs = super().root_attributes()
|
|
attrs['xmlns:itunes'] = 'http://www.itunes.com/dtds/podcast-1.0.dtd'
|
|
attrs['xmlns:atom'] = 'http://www.w3.org/2005/Atom'
|
|
attrs['xmlns:media'] = 'http://search.yahoo.com/mrss/'
|
|
attrs['xmlns:dc'] = "http://purl.org/dc/elements/1.1/"
|
|
return attrs
|
|
|
|
def add_root_elements(self, handler):
|
|
super().add_root_elements(handler)
|
|
|
|
def add_item_elements(self, handler, item):
|
|
super().add_item_elements(handler, item)
|
|
# Block things that don't have an enclosure from iTunes in
|
|
# case someone uploads this feed there.
|
|
handler.addQuickElement("itunes:block", 'Yes')
|
|
|
|
class OmnibusFeed(ConservancyFeedBase):
|
|
get_absolute_url = '/feeds/omnibus/'
|
|
feed_type = OmnibusFeedType
|
|
link ="/news/"
|
|
title = "The Software Freedom Conservancy"
|
|
description = "An aggregated feed of all RSS content available from the Software Freedom Conservancy, including both news items and blogs."
|
|
title_template = "feeds/omnibus_title.html"
|
|
description_template = "feeds/omnibus_description.html"
|
|
author_email = "info@sfconservancy.org"
|
|
author_link = "https://sfconservancy.org/"
|
|
author_name = "Software Freedom Conservancy"
|
|
|
|
def item_title(self, item):
|
|
return item.headline
|
|
|
|
def item_description(self, item):
|
|
return item.summary
|
|
|
|
def item_enclosure_mime_type(self): return "audio/mpeg"
|
|
|
|
def item_enclosure_url(self, item):
|
|
if hasattr(item, 'mp3_path'):
|
|
return "https://sfconservancy.org" + item.mp3_path
|
|
def item_enclosure_length(self, item):
|
|
if hasattr(item, 'mp3_path'):
|
|
return item.mp3_length
|
|
|
|
def item_pubdate(self, item):
|
|
return item.pub_date
|
|
|
|
def item_author_name(self, item):
|
|
if item.omnibus_type == "blog":
|
|
return item.author.formal_name
|
|
else:
|
|
return "Software Freedom Conservancy"
|
|
|
|
def item_author_link(self, obj):
|
|
return "https://sfconservancy.org"
|
|
|
|
def item_author_email(self, item):
|
|
if item.omnibus_type == "news":
|
|
return "info@sfconservancy.org"
|
|
elif hasattr(item, 'author'):
|
|
return "%s@sfconservancy.org" % item.author
|
|
else:
|
|
return "info@sfconservancy.org"
|
|
|
|
def item_pubdate(self, item):
|
|
if item.omnibus_type == "event":
|
|
return item.date_created
|
|
else:
|
|
return item.pub_date
|
|
|
|
def item_link(self, item):
|
|
return item.get_absolute_url()
|
|
|
|
# http://groups.google.ca/group/django-users/browse_thread/thread/d22e8a8f378cf0e2
|
|
|
|
def items(self):
|
|
blogs = BlogEntry.objects.filter(pub_date__lte=datetime.now()).order_by('-pub_date')[:25]
|
|
for bb in blogs:
|
|
bb.omnibus_type = "blog"
|
|
bb.omnibus_feed_description_template = "feeds/blog_description.html"
|
|
bb.omnibus_feed_title_template = "feeds/blog_title.html"
|
|
|
|
news = PressRelease.objects.filter(pub_date__lte=datetime.now(),
|
|
sites__id__exact=settings.SITE_ID).order_by('-pub_date')[:25]
|
|
for nn in news:
|
|
nn.omnibus_type = "news"
|
|
nn.omnibus_feed_description_template = "feeds/news_description.html"
|
|
nn.omnibus_feed_title_template = "feeds/news_title.html"
|
|
|
|
a = [ ii for ii in itertools.chain(blogs, news)]
|
|
a.sort(key=operator.attrgetter('pub_date'), reverse=True)
|
|
return a
|
|
|
|
|
|
def item_extra_kwargs(self, item):
|
|
return super().item_extra_kwargs(item)
|
|
|
|
class BlogFeed(ConservancyFeedBase):
|
|
link = "/blog/"
|
|
get_absolute_url = '/feeds/blog/'
|
|
|
|
def get_object(self, request):
|
|
return request
|
|
|
|
def title(self, obj):
|
|
answer = "The Software Freedom Conservancy Blog"
|
|
|
|
GET = obj.GET
|
|
tags = []
|
|
if 'author' in GET:
|
|
tags = GET.getlist('author')
|
|
if 'tag' in GET:
|
|
tags += GET.getlist('tag')
|
|
|
|
if len(tags) == 1:
|
|
answer += " (" + tags[0] + ")"
|
|
elif len(tags) > 1:
|
|
firstTime = True
|
|
done = {}
|
|
for tag in tags:
|
|
if tag in done: continue
|
|
if firstTime:
|
|
answer += " ("
|
|
firstTime = False
|
|
else:
|
|
answer += ", "
|
|
answer += tag
|
|
done[tag] = tag
|
|
answer += ")"
|
|
else:
|
|
answer += "."
|
|
return answer
|
|
|
|
def description(self, obj):
|
|
answer = "Blogs at the Software Freedom Conservancy"
|
|
|
|
GET = obj.GET
|
|
tags = []
|
|
if 'author' in GET: tags = GET.getlist('author')
|
|
if 'tag' in GET: tags += GET.getlist('tag')
|
|
|
|
done = {}
|
|
if len(tags) == 1:
|
|
answer += " tagged with " + tags[0]
|
|
elif len(tags) > 1:
|
|
firstTime = True
|
|
for tag in tags:
|
|
if tag in done: continue
|
|
if firstTime:
|
|
answer += " tagged with "
|
|
firstTime = False
|
|
else:
|
|
answer += " or "
|
|
answer += tag
|
|
done[tag] = tag
|
|
else:
|
|
answer = "All blogs at the Software Freedom Conservancy"
|
|
answer += "."
|
|
|
|
return answer
|
|
|
|
def item_title(self, item):
|
|
return item.headline
|
|
|
|
def item_description(self, item):
|
|
return item.summary
|
|
|
|
def item_author_name(self, item):
|
|
return item.author.formal_name
|
|
|
|
def item_author_email(self, item):
|
|
return "%s@sfconservancy.org" % item.author
|
|
|
|
def item_pubdate(self, item):
|
|
return item.pub_date
|
|
|
|
def items(self, obj):
|
|
GET = obj.GET
|
|
|
|
def OR_filter(field_name, subfield_name, objs):
|
|
from django.db.models import Q
|
|
return reduce(lambda x, y: x | y,
|
|
[Q(**{'{}__{}'.format(field_name, subfield_name): x})
|
|
for x in objs])
|
|
|
|
queryset = BlogEntry.objects.filter(pub_date__lte=datetime.now())
|
|
|
|
if 'author' in GET:
|
|
authors = GET.getlist('author')
|
|
queryset = queryset.filter(OR_filter('author', 'username', authors))
|
|
|
|
if 'tag' in GET:
|
|
tags = GET.getlist('tag')
|
|
queryset = queryset.filter(OR_filter('tags', 'slug', tags))
|
|
|
|
return queryset.order_by('-pub_date')[:10]
|
|
|
|
|
|
def view(request):
|
|
"""Listing of all available feeds
|
|
"""
|
|
|
|
feeds = (PressReleaseFeed, BlogFeed, OmnibusFeed)
|
|
return render(request, "feeds.html", {'feeds': feeds})
|