Got Blog working; Fixed feeds added content to front page; switch blog template style.
This commit is contained in:
		
							parent
							
								
									9ec1bbe85a
								
							
						
					
					
						commit
						28e3f83841
					
				
					 7 changed files with 258 additions and 17 deletions
				
			
		|  | @ -1,9 +1,37 @@ | ||||||
| from django.contrib.syndication.feeds import Feed | from django.contrib.syndication.feeds import Feed | ||||||
|  | from django.utils.feedgenerator import Rss201rev2Feed  | ||||||
| from conservancy.apps.news.models import PressRelease | 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.shortcuts import render_to_response | ||||||
| from django.conf import settings | 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): | class PressReleaseFeed(Feed): | ||||||
|     title = "Software Freedom Conservancy News" |     title = "Software Freedom Conservancy News" | ||||||
|  | @ -11,17 +39,213 @@ class PressReleaseFeed(Feed): | ||||||
|     description = "" |     description = "" | ||||||
| 
 | 
 | ||||||
|     def items(self): |     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] |                                            sites__id__exact=settings.SITE_ID).order_by('-pub_date')[:10] | ||||||
| 
 | 
 | ||||||
|     def item_pubdate(self, item): |     def item_pubdate(self, item): | ||||||
|         return item.pub_date |         return item.pub_date | ||||||
| 
 | 
 | ||||||
| feed_dict = { | class OmnibusFeedType(Rss201rev2Feed): | ||||||
|     'news': PressReleaseFeed, |     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 | # make each feed know its canonical url | ||||||
|  | 
 | ||||||
| for k, v in feed_dict.items(): | for k, v in feed_dict.items(): | ||||||
|     v.get_absolute_url = '/feeds/%s/' % k |     v.get_absolute_url = '/feeds/%s/' % k | ||||||
| 
 | 
 | ||||||
|  | @ -29,4 +253,5 @@ def view(request): | ||||||
|     """Listing of all available feeds |     """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}) | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| {% extends "base_standard.html" %} | {% extends "base_conservancy.html" %} | ||||||
| 
 | 
 | ||||||
| {% block category %}blog{% endblock %} | {% block category %}blog{% endblock %} | ||||||
| 
 | 
 | ||||||
|  | @ -6,9 +6,10 @@ | ||||||
| <link rel="alternate" type="application/rss+xml" title="RSS" href="/feeds/blog/" /> | <link rel="alternate" type="application/rss+xml" title="RSS" href="/feeds/blog/" /> | ||||||
| {% endblock %} | {% endblock %} | ||||||
| 
 | 
 | ||||||
| {% block internal_navigate %} | {% block outercontent %} | ||||||
| 
 |  <div id="container"> | ||||||
| <h3>Authors</h3> |          <div id="sidebar" class="{% block submenuselection %}other{% endblock %}"> | ||||||
|  | <h2>Authors</h2> | ||||||
| <ul> | <ul> | ||||||
| {% for author in all_authors %} | {% for author in all_authors %} | ||||||
| <li><a href="/blog/?author={{ author.username }}">{{ author.formal_name }}</a> | <li><a href="/blog/?author={{ author.username }}">{{ author.formal_name }}</a> | ||||||
|  | @ -16,7 +17,7 @@ | ||||||
| {% endfor %} | {% endfor %} | ||||||
| </ul> | </ul> | ||||||
| 
 | 
 | ||||||
| <h3>Tags</h3> | <h2>Tags</h2> | ||||||
| <ul> | <ul> | ||||||
| {% for tag in all_tags %} | {% for tag in all_tags %} | ||||||
| <li><a href="{{ tag.get_absolute_url }}">{{ tag.label }}</a> | <li><a href="{{ tag.get_absolute_url }}">{{ tag.label }}</a> | ||||||
|  | @ -24,7 +25,10 @@ | ||||||
| {% endfor %} | {% endfor %} | ||||||
| </ul> | </ul> | ||||||
| 
 | 
 | ||||||
| <p><a href="/blog/">All posts...</a></p> | <h2><a href="/blog/">See all posts…</a></h2> | ||||||
| <p><a href="/blog/query/">Query...</a></p> | <!-- <p><a href="/blog/query/">Query...</a></p> !---> | ||||||
| 
 |          </div> | ||||||
|  |                <div id="mainContent">{% block content %}{% endblock %} | ||||||
|  |                </div> | ||||||
|  |    </div> | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  |  | ||||||
|  | @ -31,7 +31,7 @@ | ||||||
|     </div> |     </div> | ||||||
|       {% block outercontent %}<div id="mainContent">{% block content %}{% endblock %}</div>{% endblock %} |       {% block outercontent %}<div id="mainContent">{% block content %}{% endblock %}</div>{% endblock %} | ||||||
|     <div id="conservancyfooter"> |     <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"> |       <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>  |       <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 |       <br />This page is licensed under a | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								www/conservancy/templates/feeds/blog_description.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								www/conservancy/templates/feeds/blog_description.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | <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"><{{ obj.author.username }}@softwarefreedom.org></a>.</i></p> | ||||||
|  | {{ obj.body|safe }} | ||||||
							
								
								
									
										1
									
								
								www/conservancy/templates/feeds/blog_title.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								www/conservancy/templates/feeds/blog_title.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | {{ obj.headline|striptags|safe }} | ||||||
|  | @ -2,7 +2,9 @@ | ||||||
| {% load date_within %} | {% load date_within %} | ||||||
| 
 | 
 | ||||||
| {% block head %} | {% 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 News" href="/feeds/news/" /> | ||||||
|  | <link rel="alternate" type="application/rss+xml" title="Software Freedom Conservancy Blogs" href="/feeds/blog/" /> | ||||||
| {% endblock %} | {% endblock %} | ||||||
| 
 | 
 | ||||||
| {% block content %} | {% block content %} | ||||||
|  | @ -29,7 +31,13 @@ | ||||||
| <span class="continued"><a href="/members/current/">Conservancy's current member projects…</a></span> | <span class="continued"><a href="/members/current/">Conservancy's current member projects…</a></span> | ||||||
| <span class="continued"><a href="/members/services/">Services that Conservancy provides to its member projects…</a></span> | <span class="continued"><a href="/members/services/">Services that Conservancy provides to its member projects…</a></span> | ||||||
| </p> | </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 | <p>As a 501(c)(3) non-profit organization, Conservancy relies on | ||||||
|   charitable donations for its operations. |   charitable donations for its operations. | ||||||
|   Please <a href="/donate/">donate generously</a> to help our work! |   Please <a href="/donate/">donate generously</a> to help our work! | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| 
 | 
 | ||||||
| {% block content %} | {% block content %} | ||||||
| 
 | 
 | ||||||
|  | <div id="mainContent"> | ||||||
| <p class="date">{{ object.pub_date|date:"F j, Y" }}</p> | <p class="date">{{ object.pub_date|date:"F j, Y" }}</p> | ||||||
| <h2>{{ object.headline|safe }}</h2> | <h2>{{ object.headline|safe }}</h2> | ||||||
| {% if object.subhead %} | {% if object.subhead %} | ||||||
|  | @ -13,5 +14,5 @@ | ||||||
| {{ object.summary|safe }} | {{ object.summary|safe }} | ||||||
| 
 | 
 | ||||||
| {{ object.body|safe }} | {{ object.body|safe }} | ||||||
| 
 | </div> | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Bradley M. Kuhn
						Bradley M. Kuhn