Changeset - 28e3f8384184
[Not reviewed]
0 5 2
Bradley Kuhn (bkuhn) - 13 years ago 2010-10-04 16:15:53
bkuhn@ebb.org
Got Blog working; Fixed feeds added content to front page; switch blog template style.
7 files changed with 256 insertions and 15 deletions:
0 comments (0 inline, 0 general)
www/conservancy/feeds.py
Show inline comments
 
from django.contrib.syndication.feeds import Feed
 
from django.utils.feedgenerator import Rss201rev2Feed 
 
from conservancy.apps.news.models import PressRelease
 
from conservancy.apps.blog.models import Entry as BlogEntry
 

	
 
from django.shortcuts import render_to_response
 
from django.conf import settings
 
import datetime
 
from datetime import datetime
 

	
 
import itertools
 
import operator
 

	
 
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):
 
    title = "Software Freedom Conservancy News"
...
 
@@ -11,17 +39,213 @@ class PressReleaseFeed(Feed):
 
    description = ""
 

	
 
    def items(self):
 
        return PressRelease.objects.filter(pub_date__lte=datetime.datetime.now(),
 
        return PressRelease.objects.filter(pub_date__lte=datetime.now(),
 
                                           sites__id__exact=settings.SITE_ID).order_by('-pub_date')[:10]
 

	
 
    def item_pubdate(self, item):
 
        return item.pub_date
 

	
 
class OmnibusFeedType(Rss201rev2Feed):
 
    def root_attributes(self):
 
        attrs = super(OmnibusFeedType, self).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(OmnibusFeedType, self).add_root_elements(handler)
 

	
 
    def add_item_elements(self, handler, item):
 
        super(OmnibusFeedType, self).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):
 
    feed_type = OmnibusFeedType
 
    link ="/omnibus/"
 
    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 = "http://sfconservancy.org/"
 
    author_name = "Software Freedom Conservancy"
 

	
 
    def item_enclosure_mime_type(self): return "audio/mpeg"
 

	
 
    def item_enclosure_url(self, item):
 
        if hasattr(item, 'mp3_path'):
 
            return "http://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 "http://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(OmnibusFeed, self).item_extra_kwargs(item)
 

	
 
class BlogFeed(ConservancyFeedBase):
 
    link = "/blog/"
 

	
 
    def title(self):
 
        answer = "The Software Freedom Conservancy Blog"
 

	
 
        GET = self.request.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 done.has_key(tag): continue
 
                if firstTime:
 
                    answer += " ("
 
                    firstTime = False
 
                else:
 
                    answer += ", "
 
                answer += tag
 
                done[tag] = tag
 
            answer += ")"
 
        else:
 
            answer += "."
 
        return answer
 
        
 
    def description(self):
 
        answer = "Blogs at the Software Freedom Conservancy"
 

	
 
        GET = self.request.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 done.has_key(tag): 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_author_name(self, item):
 
        return item.author.formal_name
 

	
 
    def item_author_email(self, item):
 
        GET = self.request.GET
 
        if not 'author' in GET:
 
            return "%s@sfconservancy.org" % item.author
 
        else:
 
            answer = ""
 
            authors = GET.getlist('author')
 
            firstTime = True
 
            for author in authors:
 
                if not firstTime:
 
                    answer = "%s@sfconservancy.org" % author
 
                    firstTime = False
 
                else:
 
                    answer += ",%s@sfconservancy.org" % author
 

	
 
    def item_pubdate(self, item):
 
        return item.pub_date
 
    def items(self):
 
        GET = self.request.GET
 

	
 
        def OR_filter(field_name, subfield_name, objs):
 
            from django.db.models import Q
 
            return reduce(lambda x, y: x | y,
 
                          [Q(**{'%s__%s' % (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]
 

	
 

	
 
feed_dict = {
 
    'blog': BlogFeed,
 
    'news': PressReleaseFeed,
 
    'omnibus': OmnibusFeed,
 
#    'event-media': RecentEventMediaFeed,
 
}
 

	
 
# make each feed know its canonical url
 

	
 
for k, v in feed_dict.items():
 
    v.get_absolute_url = '/feeds/%s/' % k
 

	
...
 
@@ -29,4 +253,5 @@ def view(request):
 
    """Listing of all available feeds
 
    """
 

	
 
    return render_to_response("feeds.html", {'feeds': feed_dict.values()})
 
    feeds = feed_dict.values()
 
    return render_to_response("feeds.html", {'feeds': feeds})
www/conservancy/templates/base_blog.html
Show inline comments
 
{% extends "base_standard.html" %}
 
{% extends "base_conservancy.html" %}
 

	
 
{% block category %}blog{% endblock %}
 

	
...
 
@@ -6,9 +6,10 @@
 
<link rel="alternate" type="application/rss+xml" title="RSS" href="/feeds/blog/" />
 
{% endblock %}
 

	
 
{% block internal_navigate %}
 

	
 
<h3>Authors</h3>
 
{% block outercontent %}
 
 <div id="container">
 
         <div id="sidebar" class="{% block submenuselection %}other{% endblock %}">
 
<h2>Authors</h2>
 
<ul>
 
{% for author in all_authors %}
 
<li><a href="/blog/?author={{ author.username }}">{{ author.formal_name }}</a>
...
 
@@ -16,7 +17,7 @@
 
{% endfor %}
 
</ul>
 

	
 
<h3>Tags</h3>
 
<h2>Tags</h2>
 
<ul>
 
{% for tag in all_tags %}
 
<li><a href="{{ tag.get_absolute_url }}">{{ tag.label }}</a>
...
 
@@ -24,7 +25,10 @@
 
{% endfor %}
 
</ul>
 

	
 
<p><a href="/blog/">All posts...</a></p>
 
<p><a href="/blog/query/">Query...</a></p>
 

	
 
<h2><a href="/blog/">See all posts&hellip;</a></h2>
 
<!-- <p><a href="/blog/query/">Query...</a></p> !--->
 
         </div>
 
               <div id="mainContent">{% block content %}{% endblock %}
 
               </div>
 
   </div>
 
{% endblock %}
www/conservancy/templates/base_conservancy.html
Show inline comments
...
 
@@ -31,7 +31,7 @@
 
    </div>
 
      {% block outercontent %}<div id="mainContent">{% block content %}{% endblock %}</div>{% endblock %}
 
    <div id="conservancyfooter">
 
      <p><a href="/">Main Page</a> | <a href="/about/contact/">Contact</a> | <a href="/privacy-policy/">Privacy Policy</a> | <a href="/feeds/news/">News Feed</a></p>
 
      <p><a href="/">Main Page</a> | <a href="/about/contact/">Contact</a> | <a href="/privacy-policy/">Privacy Policy</a> | <a href="/feeds/omnibus/">RSS Feed</a></p>
 
      <p class="copyright_info">
 
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="/img/cc-by-sa_88x31.png" /></a> 
 
      <br />This page is licensed under a
www/conservancy/templates/feeds/blog_description.html
Show inline comments
 
new file 100644
 
<p><i>Blog post by <strong>{{ obj.author.formal_name }}</strong>.  Please email any comments on this entry to <a href="mailto:{{ obj.author.username }}@softwarefreedom.org">&lt;{{ obj.author.username }}@softwarefreedom.org&gt;</a>.</i></p>
 
{{ obj.body|safe }}
www/conservancy/templates/feeds/blog_title.html
Show inline comments
 
new file 100644
 
{{ obj.headline|striptags|safe }}
www/conservancy/templates/frontpage.html
Show inline comments
...
 
@@ -2,7 +2,9 @@
 
{% load date_within %}
 

	
 
{% block head %}
 
<link rel="alternate" type="application/rss+xml" title="Software Freedom Conservancy Complete Feed " href="/feeds/omnibus/" />
 
<link rel="alternate" type="application/rss+xml" title="Software Freedom Conservancy News" href="/feeds/news/" />
 
<link rel="alternate" type="application/rss+xml" title="Software Freedom Conservancy Blogs" href="/feeds/blog/" />
 
{% endblock %}
 

	
 
{% block content %}
...
 
@@ -29,7 +31,13 @@
 
<span class="continued"><a href="/members/current/">Conservancy's current member projects&hellip;</a></span>
 
<span class="continued"><a href="/members/services/">Services that Conservancy provides to its member projects&hellip;</a></span>
 
</p>
 
<h2>Support Conservancy!</h2>
 
<h2>Follow Conservancy RSS Feeds</h2>
 

	
 
<p>There is a <a href="/feeds/ominibus/">full site feed available</a>, as
 
  well as separate feeds for the <a href="/feeds/news/">news items</a> and
 
  <a href="/feeds/blog/">blog posts</a>.</p>
 

	
 
<h2>Support Conservancy</h2>
 
<p>As a 501(c)(3) non-profit organization, Conservancy relies on
 
  charitable donations for its operations.
 
  Please <a href="/donate/">donate generously</a> to help our work!
www/conservancy/templates/news/pressrelease_detail.html
Show inline comments
...
 
@@ -4,6 +4,7 @@
 

	
 
{% block content %}
 

	
 
<div id="mainContent">
 
<p class="date">{{ object.pub_date|date:"F j, Y" }}</p>
 
<h2>{{ object.headline|safe }}</h2>
 
{% if object.subhead %}
...
 
@@ -13,5 +14,5 @@
 
{{ object.summary|safe }}
 

	
 
{{ object.body|safe }}
 

	
 
</div>
 
{% endblock %}
0 comments (0 inline, 0 general)