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.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 | ||||
| 
 | ||||
| feed_dict = { | ||||
|     'news': PressReleaseFeed, | ||||
| } | ||||
| 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}) | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| {% 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…</a></h2> | ||||
| <!-- <p><a href="/blog/query/">Query...</a></p> !---> | ||||
|          </div> | ||||
|                <div id="mainContent">{% block content %}{% endblock %} | ||||
|                </div> | ||||
|    </div> | ||||
| {% endblock %} | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										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 %} | ||||
| 
 | ||||
| {% 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…</a></span> | ||||
| <span class="continued"><a href="/members/services/">Services that Conservancy provides to its member projects…</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! | ||||
|  |  | |||
|  | @ -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 %} | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue