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 .blog.models import Entry as BlogEntry
|
|
from .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})
|