diff --git a/www/conservancy/settings.py b/www/conservancy/settings.py index a478584cdb1891a246d69841dbf1e88777ee0940..40a70b213ce55d7d5fbac68067791e378ca32e87 100644 --- a/www/conservancy/settings.py +++ b/www/conservancy/settings.py @@ -97,6 +97,8 @@ INSTALLED_APPS = [ 'conservancy.apps.fundgoal', 'conservancy.apps.assignment', 'conservancy.apps.fossy', + 'podjango', # Here so that the templates are found + 'podjango.apps.cast', ] DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' diff --git a/www/conservancy/urls.py b/www/conservancy/urls.py index 92127b0516c1270f108dc757b02b5414c1ee3704..791fa473d21e4fc20f10b22a169082c9bc8d39b4 100644 --- a/www/conservancy/urls.py +++ b/www/conservancy/urls.py @@ -67,4 +67,5 @@ urlpatterns = [ url(r'^assignment/', include('conservancy.apps.assignment.urls')), url(r'^fossy/$', static_views.index), url(r'^fossy/', include('conservancy.apps.fossy.urls')), + url(r'^faif/', include('podjango.urls')), ] diff --git a/www/podjango/__init__.py b/www/podjango/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/www/podjango/apps/__init__.py b/www/podjango/apps/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/www/podjango/apps/cast/__init__.py b/www/podjango/apps/cast/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/www/podjango/apps/cast/admin.py b/www/podjango/apps/cast/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..b9623202f4632b8145dfbe8ed8eb1415f0df2e3f --- /dev/null +++ b/www/podjango/apps/cast/admin.py @@ -0,0 +1,37 @@ +# Copyright (C) 2008 Bradley M. Kuhn +# Copyright (C) 2006, 2007 Software Freedom Law Center, Inc. +# +# This software's license gives you freedom; you can copy, convey, +# propogate, redistribute and/or modify this program under the terms of +# the GNU Affero General Public License (AGPL) as published by the Free +# Software Foundation (FSF), either version 3 of the License, or (at your +# option) any later version of the AGPL published by the FSF. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +# General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program in a file in the toplevel directory called +# "AGPLv3". If not, see . +# +from django.contrib import admin + +from .models import CastTag, Cast + +class CastTagAdmin(admin.ModelAdmin): + prepopulated_fields = {'slug': ('label',)} + +admin.site.register(CastTag, CastTagAdmin) + +class CastAdmin(admin.ModelAdmin): + list_display = ('pub_date', 'title') + list_filter = ['pub_date'] + date_hierarchy = 'pub_date' + search_fields = ['title', 'summary', 'body'] + prepopulated_fields = {'slug': ("title",)} + filter_horizontal = ('tags',) + + +admin.site.register(Cast, CastAdmin) diff --git a/www/podjango/apps/cast/migrations/0001_initial.py b/www/podjango/apps/cast/migrations/0001_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..a9cb5a222b67a95c0ad6357f29edfb0d52d332c1 --- /dev/null +++ b/www/podjango/apps/cast/migrations/0001_initial.py @@ -0,0 +1,50 @@ +# Generated by Django 3.2.19 on 2023-09-21 08:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='CastTag', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('label', models.CharField(max_length=100)), + ('slug', models.SlugField()), + ], + options={ + 'db_table': 'cast_tags', + }, + ), + migrations.CreateModel( + name='Cast', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=200)), + ('slug', models.SlugField(unique=True)), + ('summary', models.TextField(help_text='Use raw HTML. This summary is not included at the beginning of the body when the entry is displayed. It used only for the material on the front page.')), + ('body', models.TextField(help_text='Use raw HTML. Include the full body of any show notes or other information about this episode. It will be labelled on the site as Show Notes. It is included on the detail entry, and in the description data on the cast RSS feed.')), + ('pub_date', models.DateTimeField()), + ('ogg_path', models.CharField(blank=True, help_text='Local filename of the Ogg file, relative to webroot. File should be uploaded into the static media area for casts.', max_length=300)), + ('mp3_path', models.CharField(blank=True, help_text='Local filename of the mp3 file, relative to webroot. File should be uploaded into the static media area for casts.', max_length=300)), + ('ogg_length', models.IntegerField(help_text='size in bytes of ogg file')), + ('mp3_length', models.IntegerField(help_text='size in bytes of mp3 file')), + ('duration', models.CharField(help_text='length in hh:mm:ss of mp3 file', max_length=8)), + ('date_created', models.DateTimeField(auto_now_add=True)), + ('date_last_modified', models.DateTimeField(auto_now=True)), + ('tags', models.ManyToManyField(blank=True, to='cast.CastTag')), + ], + options={ + 'verbose_name_plural': 'casts', + 'db_table': 'casts_entries', + 'ordering': ('-pub_date',), + 'get_latest_by': 'pub_date', + }, + ), + ] diff --git a/www/podjango/apps/cast/migrations/__init__.py b/www/podjango/apps/cast/migrations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/www/podjango/apps/cast/models.py b/www/podjango/apps/cast/models.py new file mode 100644 index 0000000000000000000000000000000000000000..151c453ebeeb0225cbb3bb0c50fe2ce23ec585f4 --- /dev/null +++ b/www/podjango/apps/cast/models.py @@ -0,0 +1,76 @@ +# Copyright (C) 2008 Bradley M. Kuhn +# Copyright (C) 2006, 2007 Software Freedom Law Center, Inc. +# +# This software's license gives you freedom; you can copy, convey, +# propogate, redistribute and/or modify this program under the terms of +# the GNU Affero General Public License (AGPL) as published by the Free +# Software Foundation (FSF), either version 3 of the License, or (at your +# option) any later version of the AGPL published by the FSF. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +# General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program in a file in the toplevel directory called +# "AGPLv3". If not, see . +# +from django.db import models +from django.conf import settings +#from podjango.apps.staff.models import Person +from datetime import datetime, timedelta + +class CastTag(models.Model): + """Tagging for casts""" + + label = models.CharField(max_length=100) + slug = models.SlugField() + + class Meta: + db_table = 'cast_tags' # legacy + + def __unicode__(self): + return self.label + + def get_absolute_url(self): + return "/cast/?tag=%s" % self.slug + +class Cast(models.Model): + """Cast""" + + title = models.CharField(max_length=200) + slug = models.SlugField(unique=True) + summary = models.TextField(help_text="Use raw HTML. This summary is not included at the beginning of the body when the entry is displayed. It used only for the material on the front page.") + body = models.TextField(help_text="Use raw HTML. Include the full body of any show notes or other information about this episode. It will be labelled on the site as Show Notes. It is included on the detail entry, and in the description data on the cast RSS feed.") + pub_date = models.DateTimeField() +# poster = models.ForeignKey(Person) + tags = models.ManyToManyField(CastTag, blank=True) + ogg_path = models.CharField(max_length=300, blank=True, + help_text="Local filename of the Ogg file, relative to webroot. File should be uploaded into the static media area for casts.") + mp3_path = models.CharField(max_length=300, blank=True, + help_text="Local filename of the mp3 file, relative to webroot. File should be uploaded into the static media area for casts.") + ogg_length = models.IntegerField(blank=False, help_text="size in bytes of ogg file") + mp3_length = models.IntegerField(blank=False, help_text="size in bytes of mp3 file") + duration = models.CharField(max_length=8, blank=False, help_text="length in hh:mm:ss of mp3 file") + date_created = models.DateTimeField(auto_now_add=True) + date_last_modified = models.DateTimeField(auto_now=True) + + class Meta: + db_table = 'casts_entries' # legacy + verbose_name_plural = 'casts' + ordering = ('-pub_date',) + get_latest_by = 'pub_date' + + def __unicode__(self): + return self.title + + def get_absolute_url(self): + return "/cast/%s/%s/" % (self.pub_date.strftime("%Y/%b/%d").lower(), + self.slug) +# FIXME +# return (u"/cast/%s/" % (self.slug)) + + def is_recent(self): + return self.pub_date > (datetime.now() - timedelta(days=14)) + # question: does datetime.now() do a syscall each time is it called? diff --git a/www/podjango/apps/cast/templatetags/__init__.py b/www/podjango/apps/cast/templatetags/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/www/podjango/apps/cast/templatetags/date_within.py b/www/podjango/apps/cast/templatetags/date_within.py new file mode 100644 index 0000000000000000000000000000000000000000..5213759d2093aea11eac34d56619ecdb7be9fb80 --- /dev/null +++ b/www/podjango/apps/cast/templatetags/date_within.py @@ -0,0 +1,9 @@ +from django import template +from datetime import timedelta, datetime + +register = template.Library() + +@register.filter +def date_within_past_days(value, arg): + # question: does datetime.now() do a syscall each time is it called? + return value > (datetime.now() - timedelta(days=int(arg))) diff --git a/www/podjango/apps/cast/urls.py b/www/podjango/apps/cast/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..d89501ab261a19d7211ff2a85a124fef56e72352 --- /dev/null +++ b/www/podjango/apps/cast/urls.py @@ -0,0 +1,82 @@ +# Copyright (C) 2008 Bradley M. Kuhn +# Copyright (C) 2006, 2007 Software Freedom Law Center, Inc. +# +# This software's license gives you freedom; you can copy, convey, +# propogate, redistribute and/or modify this program under the terms of +# the GNU Affero General Public License (AGPL) as published by the Free +# Software Foundation (FSF), either version 3 of the License, or (at your +# option) any later version of the AGPL published by the FSF. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +# General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program in a file in the toplevel directory called +# "AGPLv3". If not, see . +# +from datetime import datetime + +from django.conf.urls import url +from django.views.generic.dates import DateDetailView, DayArchiveView, MonthArchiveView, YearArchiveView + +from .models import Cast, CastTag +from .views import custom_index, query + +extra_context = {} + +info_dict = { + 'queryset': Cast.objects.all(), + 'date_field': 'pub_date', + 'extra_context': extra_context, +} + +urlpatterns = [ + url(r'^(?P\d{4})/(?P[a-z]{3})/(?P\w{1,2})/(?P[-\w]+)/$', DateDetailView.as_view(**info_dict), name='detail'), + url(r'^(?P\d{4})/(?P[a-z]{3})/(?P\w{1,2})/$', DayArchiveView.as_view(**info_dict), name='day-archive'), + url(r'^(?P\d{4})/(?P[a-z]{3})/$', MonthArchiveView.as_view(**info_dict), name='month-archive'), + url(r'^(?P\d{4})/$', YearArchiveView.as_view(**info_dict), name='year-archive'), +# FIXME HOW DO I MAKE THE SLUG WORK WITH NO DATES IN IT. +# (r'^(?P[-\w]+)/$', 'object_detail', dict(info_dict, slug_field='slug')), +] + +urlpatterns += [ + url(r'^$', custom_index, dict(info_dict, paginate_by=20), name='cast'), + url(r'^query/$', query, name='query'), +] + +# Code to display authors and tags on each blog page + + +def all_tags_by_use_amount(): + """Returns all tags with an added 'cnt' attribute (how many times used) + + Also sorts the tags so most-used tags appear first. + """ + + # tally use amount + retval = [] + current = None + for obj in CastTag.objects.filter(cast__pub_date__lte=datetime.now(), + cast__isnull=False).order_by('label'): + if current is not None and obj.id == current.id: + current.cnt += 1 + else: + if current is not None: + retval.append(current) + current = obj + current.cnt = 1 + if current is not None: + retval.append(current) + + # sort and return + retval.sort(key=lambda x: -x.cnt) + return retval + +# The functions are passed to the context uncalled so they will be +# called for each web request. If we want to only make these database +# queries a single time when a web server process begins, call both +# functions below (i.e. make both lines below end in '()') + +extra_context['all_tags'] = all_tags_by_use_amount diff --git a/www/podjango/apps/cast/views.py b/www/podjango/apps/cast/views.py new file mode 100644 index 0000000000000000000000000000000000000000..27dd58ebb7a03a395bbe10b295bf2337f10fcf56 --- /dev/null +++ b/www/podjango/apps/cast/views.py @@ -0,0 +1,110 @@ +# Copyright (C) 2008 Bradley M. Kuhn +# Copyright (C) 2006, 2007 Software Freedom Law Center, Inc. +# +# This software's license gives you freedom; you can copy, convey, +# propogate, redistribute and/or modify this program under the terms of +# the GNU Affero General Public License (AGPL) as published by the Free +# Software Foundation (FSF), either version 3 of the License, or (at your +# option) any later version of the AGPL published by the FSF. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +# General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program in a file in the toplevel directory called +# "AGPLv3". If not, see . +# +from datetime import datetime + +from django.views.generic.list import ListView +from django.shortcuts import get_object_or_404, render + +from .models import Cast, CastTag + + +def OR_filter(field_name, objs): + from django.db.models import Q + return reduce(lambda x, y: x | y, + [Q(**{field_name: x.id}) for x in objs]) + +def last_name(person): + return person.formal_name.rpartition(' ')[2] + +def custom_index(request, queryset, *args, **kwargs): + """Cast list view that allows scrolling and also shows an index by + year. + """ + + kwargs = kwargs.copy() + kwargs['extra_context'] = kwargs.get('extra_context', {}).copy() + extra_context = kwargs['extra_context'] + + date_field = kwargs['date_field'] + del kwargs['date_field'] + + if not kwargs.get('allow_future', False): + queryset = queryset.filter(**{'%s__lte' % date_field: datetime.now()}) + + authors = [] + if 'author' in request.GET: + authors = [get_object_or_404(Person, username=author) + for author in request.GET.getlist('author')] + extra_context['authors'] = authors + queryset = queryset.filter(OR_filter('author', authors)) + + tags = [] + if 'tag' in request.GET: + tags = [get_object_or_404(CastTag, slug=tag) + for tag in request.GET.getlist('tag')] + extra_context['tags'] = tags + queryset = queryset.filter(OR_filter('tags', tags)) + + if authors or tags: + query_string = '&'.join(['author=%s' % a.username for a in authors] + + ['tag=%s' % t.slug for t in tags]) + extra_context['query_string'] = query_string + + else: + date_list = queryset.dates(date_field, 'year') + extra_context['date_list'] = date_list + + # TODO + return render(request, 'podjango/cast/cast_list.html', {'object_list': queryset}) + +def query(request): + """Page to query the cast based on and tags + """ + + if request.GET: + d = request.GET.copy() + if 'authors' in d.getlist('all'): + d.setlist('author', []) # remove author queries + if 'tags' in d.getlist('all'): + d.setlist('tag', []) # remove tag queries + d.setlist('all', []) # remove "all" from the query string + + base_url = '/cast/' + if 'rss' in d: + base_url = '/feeds/cast/' + d.setlist('rss', []) # remove it + + query_string = d.urlencode() + + return relative_redirect(request, '%s%s%s' % (base_url, '?' if query_string else '', query_string)) + + else: + tags = CastTag.objects.all().order_by('label') + return render(request, 'podjango/cast/query.html', {'tags': tags}) + +def relative_redirect(request, path): + from django import http + from django.conf import settings + + host = http.get_host(request) + if settings.FORCE_CANONICAL_HOSTNAME: + host = settings.FORCE_CANONICAL_HOSTNAME + + url = "%s://%s%s" % (request.is_secure() and 'https' or 'http', host, path) + return http.HttpResponseRedirect(url) diff --git a/www/podjango/feeds.py b/www/podjango/feeds.py new file mode 100644 index 0000000000000000000000000000000000000000..9b6b8d35f42a30fb3bee8c0859d35381833f0dda --- /dev/null +++ b/www/podjango/feeds.py @@ -0,0 +1,277 @@ +# Copyright (C) 2008, 2010 Bradley M. Kuhn +# Copyright (C) 2006, 2007 Software Freedom Law Center, Inc. +# +# This software's license gives you freedom; you can copy, convey, +# propogate, redistribute and/or modify this program under the terms of +# the GNU Affero General Public License (AGPL) as published by the Free +# Software Foundation (FSF), either version 3 of the License, or (at your +# option) any later version of the AGPL published by the FSF. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +# General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program in a file in the toplevel directory called +# "AGPLv3". If not, see . +# + +from django.contrib.syndication.views import Feed +from django.utils.feedgenerator import Rss201rev2Feed +#from podjango.apps.staff.models import Person +from podjango.apps.cast.models import Cast + +from django.shortcuts import render +from django.conf import settings +from datetime import datetime + +import itertools +import operator + +# FIXME: Settings here should not be hard-coded for given casts, but +# should instead have settings from the main screen. + +class CastFeedBase(Feed): + def copyright_holder(self): return "Bradley M. Kuhn, Karen M. Sandler" + + def license_no_html(self): return "Licensed under a Creative Commons Attribution-Share Alike 3.0 USA 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 } + +def for_podcast_feed_extra_kwargs(self, obj): + return { 'managingEditorNames' : 'Bradley and Karen', + 'rssImage' : { 'url' : 'http://faif.us/img/cast/faif_144x144.jpg', + 'width' : '144', 'height' : '144' }, + 'webMaster' : 'oggcast@faif.us (Bradley and Karen)', + 'dcCreator' : 'oggcast@faif.us (Bradley and Karen)', + 'iTunesExplicit' : 'No', + 'iTunesBlock' : 'No', + 'iTunesImage' : { 'url' : 'http://faif.us/img/cast/faif_300x300.jpg', + 'title' : 'Free as in Freedom', + 'link' : self.author_link, + 'type' : 'video/jpg'}, + 'category' : { 'name' : 'Government & Organizations', 'scheme' : 'http://www.itunes.com/dtds/podcast-1.0.dtd', + 'subcats' : [ 'Non-Profit' ] }, + 'keywords' : 'open source, opensource, freesoftware, software freedom, legal, law, linux, free, license, gpl, lgpl, agpl, bsd', + 'iTunesAuthor' : 'Free as in Freedom', + 'iTunesSubtitle' : 'Bi-Weekly Discussion of Legal, Policy, and Any other Issues in the Free, Libre, and Open Source Software (FLOSS) Community', + 'copyrightHolder' : self.copyright_holder(), + 'copyrightLicense' : self.license_no_html() } + +def for_podcast_item_extra_kwargs(self, item): + return { 'duration' : item.duration, + 'year' : item.date_created.year, + 'dcCreator' : 'oggcast@faif.us (Bradley and Karen)', + 'intheitembkuhn' : item.__dict__.__str__()} + +def podcast_helper_add_root_elements(self, handler): + handler.addQuickElement('managingEditor', self.feed['author_email'] + + ' (' + self.feed['managingEditorNames'] + ')') + handler.startElement('image', {}) + handler.addQuickElement('url', self.feed['rssImage']['url']) + handler.addQuickElement('title', self.feed['author_name']) + handler.addQuickElement('link', self.feed['link']) + handler.addQuickElement('width', self.feed['rssImage']['width']) + handler.addQuickElement('height', self.feed['rssImage']['height']) + handler.endElement('image') + + handler.addQuickElement('webMaster', self.feed['webMaster']) +# handler.addQuickElement('dc:creator', self.feed['dcCreator']) + handler.addQuickElement('itunes:explicit', self.feed['iTunesExplicit']) + handler.addQuickElement('itunes:block', self.feed['iTunesBlock']) + handler.addQuickElement('generator', 'http://www.faif.us/code') + + handler.addQuickElement('media:thumbnail', '' , { 'url' : self.feed['rssImage']['url'] }) + handler.addQuickElement('itunes:image', '' , { 'href' : self.feed['iTunesImage']['url']}) +# handler.addQuickElement('itunes:link', '', { 'href' : self.feed['iTunesImage']['url'], +# 'type' : self.feed['iTunesImage']['type']}) + + handler.addQuickElement("media:category", self.feed['category']['name'], + { 'scheme': self.feed['category']['scheme']}) + if not (self.feed['category']['subcats'] and len(self.feed['category']['subcats']) > 0): + handler.addQuickElement("itunes:category", '', { 'text': self.feed['category']['name']}) + else: + handler.startElement("itunes:category", { 'text': self.feed['category']['name']}) + for cc in self.feed['category']['subcats']: + handler.addQuickElement("itunes:category", '', { 'text': cc }) + handler.endElement("itunes:category") + + handler.addQuickElement("media:keywords", self.feed['keywords'].replace(" ", ",")) + + handler.startElement("itunes:owner", {}) + handler.addQuickElement("itunes:email", self.feed['author_email']) + handler.addQuickElement("itunes:name", self.feed['author_name']) + handler.endElement("itunes:owner") + + handler.addQuickElement("itunes:summary", self.feed['description']) + handler.addQuickElement("itunes:subtitle", self.feed['iTunesSubtitle']) + + handler.addQuickElement("itunes:author", self.feed['iTunesAuthor']) + handler.addQuickElement('atom:link', '', { 'rel' : "self", 'href' : self.feed['feed_url'], + 'type' : "application/rss+xml"}) + + years = {} + for ii in self.items: years[ii['year']] = 1 + + copyrightString = "" + ll = years.keys() + sorted(ll) + for yy in ll: copyrightString += "%d, " % yy + copyrightString += "%s. %s" % (self.feed['copyrightHolder'], self.feed['copyrightLicense']) + + handler.addQuickElement('copyright', copyrightString) + handler.addQuickElement('media:copyright', "Copyright (C) " + copyrightString) + +def podcast_helper_add_item_elements(self, handler, item): + handler.addQuickElement("itunes:explicit", self.feed['iTunesExplicit']) + handler.addQuickElement("itunes:block", self.feed['iTunesBlock']) + handler.addQuickElement("itunes:keywords", self.feed['keywords']) +# handler.addQuickElement('dc:creator', self.feed['dcCreator']) + handler.addQuickElement("itunes:author", item['author_name']) + handler.addQuickElement("itunes:duration", item['duration']) + if 'enclosure' in item: + handler.addQuickElement('media:content', '', { 'url' : item['enclosure'].url, + 'fileSize' : item['enclosure'].length, + 'type' : item['enclosure'].mime_type}) + +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) + podcast_helper_add_root_elements(self, handler) + + def add_item_elements(self, handler, item): + super().add_item_elements(handler, item) + + # The below is a bit of a cheat, I assume anything in the ominbus + # feed that has an enclosure must be a podcast. Probably not true + # as such in the general case, but enough for this case, I think. + if item['enclosure']: + podcast_helper_add_item_elements(self, handler, item) + else: + # Block things that don't have an enclosure from iTunes in + # case someone uploads this feed there. + handler.addQuickElement("itunes:block", 'Yes') + + + +# http://www.feedforall.com/itune-tutorial-tags.htm +# http://www.feedforall.com/mediarss.htm +class iTunesFeedType(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) + podcast_helper_add_root_elements(self, handler) + + def add_item_elements(self, handler, item): + super().add_item_elements(handler, item) + podcast_helper_add_item_elements(self, handler, item) + + +class CastFeed(CastFeedBase): + feed_type = iTunesFeedType + title = "Free as in Freedom" + link = "/cast/" + description = "A bi-weekly discussion of legal, policy, and other issues in the open source and software freedom community (including occasional interviews) from Brooklyn, New York, USA. Presented by Karen Sandler and Bradley M. Kuhn." + author_email = "podcast@faif.us" + author_link = "http://www.faif.us/" + author_name = "Free as in Freedom" + title_template = "feeds/podcast_title.html" + description_template = "feeds/podcast_description.html" + def items(self): + return Cast.objects.filter(pub_date__lte=datetime.now()).order_by('-pub_date') + def item_pubdate(self, item): + return item.pub_date + + def item_link(self, item): + return item.get_absolute_url() + + def item_author_email(self, obj): + return "oggcast@faif.us" + + def item_author_name(self, obj): + return "Free as in Freedom" + + def item_author_link(self, obj): + return "http://faif.us" + + def item_categories(self, item): + return ('Technology',) + + def copyright_holder(self): return "Free as in Freedom" + + def license_no_html(self): return "Licensed under a Creative Commons Attribution-Share Alike 3.0 USA License." + + def feed_extra_kwargs(self, obj): + return for_podcast_feed_extra_kwargs(self, obj) + + def item_extra_kwargs(self, item): + return for_podcast_item_extra_kwargs(self, item) + +# FIXME: +# GUEST NAME GOES HERE!!! +# +# If applicable, at the item level, this tag can contain information +# about the person(s) featured on a specific episode. + + +class Mp3CastFeed(CastFeed): + def item_enclosure_mime_type(self): return "audio/mpeg" + def item_enclosure_url(self, item): + return "http://faif.us" + item.mp3_path + def item_enclosure_length(self, item): + return item.mp3_length + +class OggCastFeed(CastFeed): + def item_enclosure_mime_type(self): return "audio/ogg" + def item_enclosure_url(self, item): + return "http://faif.us" + item.ogg_path + def item_enclosure_length(self, item): + return item.ogg_length + +feed_dict = { + 'cast-ogg': OggCastFeed, + 'cast-mp3': Mp3CastFeed, +} + +# make each feed know its canonical url +for k, v in feed_dict.items(): + v.get_absolute_url = '/feeds/%s/' % k + +def view(request): + """Listing of all available feeds + """ + + feeds = feed_dict.values() + return render(request, "feeds.html", {'feeds': feeds}) diff --git a/www/podjango/frontpage.py b/www/podjango/frontpage.py new file mode 100644 index 0000000000000000000000000000000000000000..5b3e6d5823a22bd06a55ad23002161e0db6059a0 --- /dev/null +++ b/www/podjango/frontpage.py @@ -0,0 +1,34 @@ +# Copyright 2010 Bradley M. Kuhn +# Copyright 2005-2008 James Garrison + +# This software's license gives you freedom; you can copy, convey, +# propagate, redistribute, modify and/or redistribute modified versions of +# this program under the terms of the GNU Affero General Public License +# (AGPL) as published by the Free Software Foundation (FSF), either +# version 3 of the License, or (at your option) any later version of the +# AGPL published by the FSF. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +# General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program in a file in the toplevel directory called +# "AGPLv3". If not, see . + +from django.shortcuts import render +from podjango.apps.cast.models import Cast +from datetime import datetime, timedelta + +def view(request): + """Cast front page view + Performs all object queries necessary to render the front page. + """ + + cast = Cast.objects.all().filter(pub_date__lte=datetime.now())[:3] + + c = { + 'cast': cast, + } + return render(request, "podjango/frontpage.html", c) diff --git a/www/podjango/static/img/cast/audio_mp3_button.png b/www/podjango/static/img/cast/audio_mp3_button.png new file mode 100644 index 0000000000000000000000000000000000000000..f362098787a8f75d178c88ffd6fb2021040b1195 GIT binary patch literal 631 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 literal 0 HcmV?d00001 diff --git a/www/podjango/static/img/cast/faif_200x200.jpg b/www/podjango/static/img/cast/faif_200x200.jpg new file mode 100644 index 0000000000000000000000000000000000000000..165389604961e56ff2b04dbdba5469623e7572fa GIT binary patch literal 4752 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 literal 0 HcmV?d00001 diff --git a/www/podjango/static/img/cast/faif_300x300.jpg b/www/podjango/static/img/cast/faif_300x300.jpg new file mode 100644 index 0000000000000000000000000000000000000000..df51528e2481d54dd290ed6e19a393c9e85df881 GIT binary patch literal 8438 zcmeHsbyOVN((m9785}|gVQ>p>2_Xb0cyJ9ixD76W1b2dEfPoOm!FBKn?he7-Ed|v3a?V-ryZ60&*LrKce{M~8ukPNzUA4P*RqdMEw^O%EfO`ru@-hGv6cm8m-4Aek z18|abbn=2&TUxo&u}HGg@pAKUbI`qjn3&sHc+n|w(Y#m%Yd;N%E#y=!xX(3v=R(b<`}-a*_gATHL94s=d#rgqjYR(H*& zUU&VtZf60K08|u|pT{pk!$A8$YvIWBQ@45UuMBxMG14~WlV5RgoOx7;zj|KGCyk_G@^-hDj=I_h1c z9PmyWIx0FA9xett+Rx#j0DejXVqy_L5|p6eQPXe^tiUEAr8jvO7oYigl#G&B;DxD+ zYxywwD^2(aNIf76lF)iP1HebS>j^{y0>lA30MxGrfzJU_0QCP{{(%mpJ6#bYn+W5z zTfnKmzX#Iw7T_>fM-bC@S+mh)du9S{i>07ih8(@wUJRw4Lo{yFcFTaX`ij1^jVp>h z7884%3;f|B>PS&Bhxutq_$_t7%(Q%BvT{|>I-8q_lJL-es`7rE{u|0ttFg(q902Oj zD%~_LBb5f9gVo@^9%QK>O;n5EQY_A~iWkMzcx*El`o^;}p>{1xJZQqc(UtHo(I9SN zP^<6gg7htbe~ALs<)P306?VQ~9Gnnd&rbK-;*x2A%g?O$>2Cq4PI&J`VjH3l$x>R^ z*DfcU2(>(%ZJYkUtN%1v^K5PLi);N&n|0;Xu8AO%;uMn|pGgc(3{99hO3@c#WP^_Q z(XRM(W)h*}>n{St%0`^LL_RKa5{DnR-#$J|dlL~b)L+*&1$m(^MsD07vhU

QjQ| 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 LyFc|3c{}}IG3$~u literal 0 HcmV?d00001 diff --git a/www/podjango/static/img/cast/faif_300x300.xcf b/www/podjango/static/img/cast/faif_300x300.xcf new file mode 100644 index 0000000000000000000000000000000000000000..be55a6906faa04ba3be50e159675aab6d20707b8 GIT binary patch literal 4753 zcmd5=eQaCR6+ey>+p*)s`6y}Hq&T!88Gag|Pub8ww0<(pm;vwLz+CZKZXShE@&MR-1r{fm)HR3vDUQhu?i?zw>M- zaVVnDOzM?>KEHE6&O7(qbKkqy;mE)qZ79^I^+lpO5!tTI0+gsyDs1?v23$QOL;{o= zpcp6tuE}xfw*>ufgY<@BHV}#r4Ct{GbdtuZ>l1n~rT1#zilq9r8@J#3d1>)kT_Xd* zupS5}BE3?F-Zqy%nHrAjS|paz6G=Ukio|2dR=2+|9EwNd3C(YbKq9<5sI6bO-YSmI2kmqIdxOX0}0CzF-6y!~Sb6(s0oRBBf(@&j|OAmK_r~ktj7X_NwL2>nA8KkkwiApv}h`U%7vMRpM4sZ0^|DzGZ_X$sL2qRHScMi|TzTF&Q5U48(hNt#>#U9EgN+RaRo; z9hHFOiaoov=2jJpVSk>e;xup`FtZ)=t8T|46hDrIzZGlU3>?RLV6(ZtgLQoqdoW5= zK7?`K1z@}4cfcQklVT_BqjsPQIFWXiQ3rb#4RySVt_*bx{6i-3xdd)| z2A;Koriv%b3yx(|sf>&@I8Qps)xd{occD}?dyoA)6L%fumNexO@jg)5} zFXu*5?ju|eGs)-|8Q3rHPq#co!`@A5UQo++VbGB*o7V#8)Ple`4`yMO@skadD0T9W*k96 z%z6yO3^PwaXfn1QZ(lQwz#`CJn}qF^2>dZTuZ4_~^vQ~vG;+ocd!7;Y{7xn&c&1|+I;`pFmFC&RXE9T z#?Q&5-?kyc>|9E!@f8Wj21|95s(DR9mbO$6nOj9WYH4L;j=?W=p$I2uJ43x)8vS{# zRkU4s&671FJ-vhnJYh9h^tYgXHvgIxZ)C-IR-DU<83@?>P}o`d>^K0{qOUxtP{KtQ zCMQjx)pPWdbM%XI^!_<|EJqOmY!b@?=zTegFjb$O<;bF?Ru2TT+sttn0y~cNm1jFi z)%_jIBHTf$^;N9D@Dfs?^GFHdMP%4+`V+E7l#GAJ$Qwwk!uk8y{E6jO1*^Yg=T*+e zL=#z+Ud~MR;G8VeEn_u(Gmfa@xQA6{Cyvv?-ByO>TgXrDhqeAk$KRAdyps& zR!7(2Oe`GlBK6!h9JaHHsZm$K+phX!elb7Fm+)%sTg{&)e4A&#(fRLbfXivIkhght z%Os^;IETA%4tL=kj%(U{eJ%aBxGntH3n#}f7*l8db$smMJGx6L?L1P@YvCwMcaFBF zougF%PWPj7;C~XZF5HlEMfU?zRs(W%Ln*lXdwPPQJHv_iV60c#{%^NQF`g@zx=rHT zn=ig!XW6Wqc3cZy#{UWfz%cN=!uHB;{DXnZQROZ`2krvy0qz5S3_Jxq3yc9r0oba1 z9T*4RgFW1qtGqxRfZJ?U8-Oc!)pp=ZKv15C&r9|a<)ed_#Xacn!D4$Zv;TbiSHsx( eK3ooWjvx(3kcJ}%5w1sbkkH+dgK)&x0{suEbgNAO literal 0 HcmV?d00001 diff --git a/www/podjango/static/img/cast/halfbakedmedia-logo.png b/www/podjango/static/img/cast/halfbakedmedia-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9956f78480200d0ebe95a940405b83c21306245d GIT binary patch literal 16925 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 literal 0 HcmV?d00001 diff --git a/www/podjango/static/img/cast/halfbakedmedia-logo_100px.png b/www/podjango/static/img/cast/halfbakedmedia-logo_100px.png new file mode 100644 index 0000000000000000000000000000000000000000..6a51dc0e5d9f1a59e35e25f6727597240b0d88a0 GIT binary patch literal 3833 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 C$UUh5 literal 0 HcmV?d00001 diff --git a/www/podjango/static/img/cast/rss-audiomp3.png b/www/podjango/static/img/cast/rss-audiomp3.png new file mode 100644 index 0000000000000000000000000000000000000000..eb7680493bede92094cc607d72448e176b8aa0e7 GIT binary patch literal 661 zcmV;G0&4w-4InURT+k(q&!nURT^5kh|b%QSQU z(@BS)b@f*btaB*@Wrb}FkQioQU?{MW6=P>$RnTJk`Ih;|8&Qrh1sE38PS^qHn6_4#@6O{b(=H8#ns~PWZXJ-1%$i&FNz{tlou#TiAV1iJL zObndt|39uR`>>_{@Avl{_C>579SmH8{~4M7|NZyx?>{tcWrb~!6awdBGH|KE)Q)B{ zR%00f;xyJOg1P7o3Ii-Kpuv^62l6&aoTB zd^@`G@9+PZZepONw=uneO9T=$#G4F@;lE#h|NF@ix|ECQ--m4_EODDTbi+QLUCSBV z^@mmb&#&hM-A8;3U{y>iKu+5vX=F@GOPe`!=JN(MF5W*J;cHl!7``kCX7-%K%EUyU8D76?Z^M`zcPLN{_oM(-@PZF4Xi7v v2%s^%{`z-3iX0gj7-(EF(+x0=wB8Z`ql_8rjpgQJ00000NkvXXu0mjfX9i6J literal 0 HcmV?d00001 diff --git a/www/podjango/static/img/cast/rss-audioogg.png b/www/podjango/static/img/cast/rss-audioogg.png new file mode 100644 index 0000000000000000000000000000000000000000..0058494276ea38db6a5d35a254671867cb1d00a4 GIT binary patch literal 643 zcmV-}0(||6P)-4InURT+k(q&!nURT^5kh|b%QSQU z(@BS)b@f*btaB*@Wrb}FkQioQU?{MW6=P>$RnTJk`Ih;|8&Qrh1sE38PS^qHn6_4#@6O{b(=H8#ns~PWZXJ-1%$i&FNz{tlou#TiAV1iJL zObndt|39uR`>>_{@Avl{_C>579SmH8{~4M7|NZyx?>{tcWrb~!6awdBGH|KE)Q;b9 zT&CeS1Q&qDFcS;oKUNk#t61hAZ+;)`{VA-%YhTV}Q~h^y=HKsM|NdY`vmTP4;S8(* zmm2)qF=g?XKn8%tFf$`7Co>~6Bdew-PtZ*EKOaBttYwli`L7!A=O@G8-{{)N3tdV8 zu4pIK9H@txSQxmOKmXm7@_CWh&*xXzothZm-unLN9E(BBpIh#({^1B;!@|VyWl1oz=Ok7}<~RH1h(=F(Hz)t~?Mu3IZV!Wc z7}4-}_x+!UFyo)K5x@R1GXG`#wZ8cKPe#UXf1cMm|M~X+{f|Eb>sBfPXdbTF^z_Cf z#y4-6UcF{`{hsyRdxp0k|G)pr^zr+@M_+&Uo_sd2uB0M>#_;;<-|;ANWME)Gtw@J1 dU>s?^B>;8L8DXo`E1>`Y002ovPDHLkV1iowM796` literal 0 HcmV?d00001 diff --git a/www/podjango/static/img/cast/rss-miro.png b/www/podjango/static/img/cast/rss-miro.png new file mode 100644 index 0000000000000000000000000000000000000000..535052480efeec2ab3377378a8ee24ad2218ab61 GIT binary patch literal 3206 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 literal 0 HcmV?d00001 diff --git a/www/podjango/static/img/feed-icon-14x14.png b/www/podjango/static/img/feed-icon-14x14.png new file mode 100644 index 0000000000000000000000000000000000000000..b3c949d2244f2c0c81d65e74719af2a1b56d06a3 GIT binary patch literal 689 zcmV;i0#5yjP)(tky!*UETcH-TCU7SrqEjJM#?B`_A)!p7(kFf9-P@=@15kkTkGK zgFusyy#KECqZzRdBLb=P?$(kUP;>kYTDeG&{|a+iOiRbI6nbQ)j#7bOf>iF=C+|_py<&Fo1F5cC*iEM?zZGC{ejNg4LWYp=S$L6Qaby6y zp$+F`250{%tU{Lg$5*ROH}y!1UKJS4*xqd7P(Y3JQF?lrnf?yerr%&6yGXLG1ur*B z{$&R1@Oj)yl@%rY5rh?j(j10Yz_DBs`AKFU_QnB;)(aqQmGi&ieOS|21^NP9UMpa< zU&p!f6RZ6Owp^X!EXA=0SbN&h?CrQK%Q3(=YBqqHD^9ZUM0Hxt-6-KT;>lf@j?Z+v zHm(}`>85I&E<7e}oz?6UwjAogowzGO8kSN7+2`b^$Az9L{K5*ko87EV45LT-`_##3 z>d3AGh@>=mbg34|6}+-gT9N+6Dr@44VEl44O&{&|w=qpbzC#iWMKa?5)>tI+KLQK@ Xq0QFqn(9Yl00000NkvXXu0mjfZ8tLicense and Source For This Website + +

The software running this website is copyrighted © 2007-2008, + Software Freedom Law Center, Inc. and copyrighted © 2010, 2016 Bradley M. + Kuhn. The software licensed under the terms of + the AGPLv3-or-later. + You can find a copy the sources of the Debian packages on + this site, but it may be more interesting to know that the site is + running on stock Debian lenny with Apache, Django, mod_python, and + sqlite installed, and that the main sources for the site's code itself + is hosted + on Github (temporarily, hopefully).

+ +

The documents on this website are copyrighted © 2010, 2012, 2015, 2016 Bradley + M. Kuhn and Karen M. Sandler, and are licensed + as CC-By-SA-4.0 + International. In some cases, the documents are dual-licensed + (AGPLv3-or-later|CC-By-SA-4.0-International), to make it more + convenient to intermix the document with code.

+ +

Creative
+   Commons LicenseThe content of this + audcast, the accompanying show notes and music are copyrighted + © 2010, 2011, 2012, 2013, 2014, 2015, 2016 by Bradley M. Kuhn, + Karen M. Sandler, Dan Lynch, and Mike + Tarantino. Some speech recording and other materials are + copyrighted by the individual speakers.

+ +

Creative Commons License + The content + of this + audcast, and the accompanying show notes and music are licensed + under the Creative + Commons Attribution-Share-Alike 3.0 USA license (CC BY-SA 4.0). + +

The icons for the RSS audio feeds and direct audio links are borrowed from + the PodPress project + and are licensed under GPLv2.

+ +{% endblock %} diff --git a/www/podjango/static/podjango.css b/www/podjango/static/podjango.css new file mode 100644 index 0000000000000000000000000000000000000000..c952d9f9e15ddd8c2cb35ba0995c60a9086e2b85 --- /dev/null +++ b/www/podjango/static/podjango.css @@ -0,0 +1,241 @@ +* { margin: 0; padding: 0; } +img { border: 0; } +body { margin: 0; padding: 0; } +.clear { clear: both; } +.hidden { display: none; } + +p, h1, h2, h3, h4, h5, h6, #mainContent ul, #mainContent ol { + margin-top: 1em; + margin-bottom: 1em; +} + +body { +/* font-family: "Lucida Grande",Verdana,Lucida,Helvetica,Arial,sans-serif; */ + font-size: 95%; +} + +a { text-decoration: none; color: #146624; } +a:hover { text-decoration: underline; color: #665f14; } + +h1 { margin-top: .75em; margin-bottom: .5em; } +h2 { margin-top: .75em; margin-bottom: .5em; } +h3 { margin-top: .6em; margin-bottom: .4em; } + +#mainContent h1 { border-bottom: 1px solid #00334b; } +#mainContent h2 { border-bottom: 1px solid #aaa; } + +#mainContent ul, #mainContent ol { padding-left: 1.5em; } + +#mainContent img { margin: 3px; } + +.internalNavigate { width: 19%; float: right; } +#mainContent .internalNavigate ul { list-style-type: none; padding-left: 0; } +.internalNavigate ul li { margin-top: .3em; margin-bottom: .3em; } + +.affiliate-link { float: right; } +#affiliate-podjango, #affiliate-mr { + padding: 2px 10px; + white-space: nowrap; + font-size: x-small; + text-align: right; +} +#affiliate-podjango { background: #d4ff9d; } +#affiliate-mr { background: #ddd; } + +/* Header */ + +#podjangoheader { + height: 3.5em; + background-color: #12d5bc; + border-bottom: 1px solid #808080; +} +#podjangoheader h1 { + font-size: 3em; + /* -indent: -5000px; */ + /* margin: 0; /\* hide in favor of image *\/ */ +} +/* #logobutton { */ +/* display: block; */ +/* position: absolute; left: 17px; top: 10px; height: 120px; width: 440px; */ +/* background: url(/img/podjango-header.png) left center no-repeat; */ +/* } */ + + +/* Navigation bar */ +#navbar-outer { background: #CDDBDC; } +#navbar { margin-left: 104px; margin-top: 3px; float: left; display: inline; } +#navbar ul { list-style: none; } +#navbar-clear { clear: both; border-bottom: 1px solid #808080; } +#navbar li a { + display: block; + background: #fafafe; + padding: .2em .8em; + margin-right: 3px; + border: 1px solid #808080; + font-size: .8em; + background: #fff url(/img/nav-bg.png) bottom repeat-x; +} +#navbar li:hover a { background: #fff99d; } +#navbar li { float: left; display: inline; margin-bottom: 3px; } + +#mainContent { + margin-left: 50px; + margin-right: 50px; +} + +#container { + width: 100%; + overflow: hidden; +} +#container #mainContent { + background: #fffff; + margin-left: 210px; + margin-right: 50px; + padding-bottom: 32767px; + margin-bottom: -32767px; +} +#container #sidebar { + width: 200px; + float: left; + padding-bottom: 32767px; + margin-bottom: -32767px; + background-color: #e5e5e5; +} + +#container #sidebar li { + text-align: center; + list-style: none; + padding: 3px 10px 3px 10px; + margin: 5px; + border: 1px solid #CCC; + background: #fff url(/img/nav-bg.png) bottom repeat-x; +} + +#container #sidebar.Directors ul li.Directors, +#container #sidebar.Contact ul li.Contact, +#container #sidebar.Officers ul li.Officers, +#container #sidebar.Staff ul li.Staff, +#container #sidebar.Current ul li.Current, +#container #sidebar.Services ul li.Services, +#container #sidebar.Applying ul li.Applying +{ + color: #000033; + font-weight: bold; + background: #fff url(/img/nav-bg-up.png) top repeat-x; +} +#container #sidebar h2 { + text-align: center; + font-size: 150%; + margin: 1.5em 0 0.8em 0; +} +#container #sidebar hr { + width: 75%; + float: center; + clear: all; +} + +/* Navbar Submenus (currently unused) */ +#navbar li ul { display: none; border: 1px solid #444; } +#navbar li:hover ul { display: block; position: absolute; } +#navbar li ul li { float: none; } +#navbar li ul li a { border: 0px; margin: 0px; } + +.shaded { background: #ffeab7; padding: .1em .5em; margin-bottom: .5em; } + +.columns { + width: 100%; + overflow: hidden; +} + +.column-small { + width: 31%; + padding-bottom: 32767px; + margin-bottom: -32767px; + } +.column-large { + margin-left: 35%; + margin-right: 50px; + padding-bottom: 32767px; + margin-bottom: -32767px; +} + +.column-left { float: left; } +.column-right { float: right; } + +.column h2 { font-size: 1.25em; } +.column h3 { font-size: 1.1em; } + +.column h2 a { text-decoration: none; color: #000000; } +.column h2 a:hover { text-decoration: underline; } + +#podjangofooter { + margin-top: 1em; + border-top: 1px solid #ccc; + text-align: center; + clear: both; +} + +span.continued { + display: block; + font-size: .83em; + font-weight: bold; + margin-top: 1em; + margin-bottom: 1em; +} + +p.date { + font-style: italic; + font-size: .83em; + margin-bottom: .3em; + margin-top: .3em; +} + +a.feedlink /* RSS icon */ { display: block; float: right; font-size: 10pt; } + +blockquote, div.quote /* div.quote is used by podjango whitepaper */ { + margin-left: 2em; + margin-right: 2em; + padding-left: 1em; + padding-right: 1em; + border: 1px solid #fff; + background: #eee; +} + +.newsgraphic { float: right; } +.newsgraphic img { border: 1px solid #000; } + +.secondary_info { font-size: 83%; } +.next_page_button { float: right; } +.document_format { border: 1px solid #888; padding: .2em; background: #fff99d;} +.copyright_info { font-size: 90%; } +hr.footnote-separator { width: 80%; margin-left: auto; margin-right: auto; } + +/* Resources pages */ +div.download-formats { margin-top: 2em; margin-bottom: 2em; } +.download-formats p { display: inline; } +#mainContent .download-formats ul { display: inline; list-style: none; + padding-left: 0; } +.download-formats ul li { display: inline; padding-left: 2em; } + +/* Resources - book styles */ +hr.chapter-separator { display: none; } +h2.likechapterHead { text-align: center; } +h2.chapterHead { text-align: center; } +#mainContent ul.author { list-style-type: none; padding-left: 0; } +#mainContent div.footnotes { font-style: normal; } /* remove italics */ +span.sectionToc { padding-left: 2em; } /* indent TOC properly */ +span.subsectionToc { padding-left: 4em; } +span.subsubsectionToc { padding-left: 6em;} +.js, .js p, .js p.bibitem, .js p.bibitem-p { background-color: #cde7e9; } + +body.podjango-overview #navbar ul li.overview a, +body.podjango-Members #navbar ul li.Members a, +body.podjango-news #navbar ul li.news a, +body.podjango-blog #navbar ul li.blog a, +body.podjango-About #navbar ul li.About a, +body.podjango-donate #navbar ul li.donate a /* NO COMMA HERE! */ +{ + color: #000033; + font-weight: bold; + background: #fff url(/img/nav-bg-up.png) top repeat-x; +} \ No newline at end of file diff --git a/www/podjango/templates/podjango/base_podcast.html b/www/podjango/templates/podjango/base_podcast.html new file mode 100644 index 0000000000000000000000000000000000000000..a9d411d2970b68321252caf81126f4ee3ee734bd --- /dev/null +++ b/www/podjango/templates/podjango/base_podcast.html @@ -0,0 +1,26 @@ + + + + + +{% extends "base_standard.html" %} + +{% block head %} + + +{% endblock %} + +{% block internal_navigate %} + +

Tags

+ + +

All oggcasts…

+ + + +{% endblock %} diff --git a/www/podjango/templates/podjango/base_standard.html b/www/podjango/templates/podjango/base_standard.html new file mode 100644 index 0000000000000000000000000000000000000000..ab00392bce6e50b980359ed14ffbf318f1b21a86 --- /dev/null +++ b/www/podjango/templates/podjango/base_standard.html @@ -0,0 +1,48 @@ + + + + + + {% block title %}{% block subtitle %}{% endblock %}Free as in Freedom{% endblock %} + + + + + + {% block head %}{% endblock %} + + + + + {% block outercontent %}
+

We raised $2,515.72 toward Dan Lynch's trip to a conference to represent + the show and record content! We'll be coordinated with Dan about what + conference he wants to attend.

+ +

If you'd like to further support Free as in Freedom, + please become a supporter of + Software + Freedom Conservancy, the charity where Bradley and Karen work.

+ + {% block content %}{% endblock %}
{% endblock %} +
+ {% block copyright_info %} + +

Free as in Freedom is produced by Dan Lynch + of danlynch.org. Theme + music written and performed + by Mike Tarantino + with Charlie Paxson on drums.

+ +

Main Page | License of show + and website | Ogg Feed | MP3 Feed

+ +{% endblock %} +
+ + diff --git a/www/podjango/templates/podjango/cast/cast_archive_day.html b/www/podjango/templates/podjango/cast/cast_archive_day.html new file mode 100644 index 0000000000000000000000000000000000000000..39676e0d40f13a21ebbbf0371714bf770148f27a --- /dev/null +++ b/www/podjango/templates/podjango/cast/cast_archive_day.html @@ -0,0 +1,34 @@ + + + + +{% extends "podjango/base_podcast.html" %} + +{% block subtitle %}Free as in Freedom Archive: {{ day|date:"F j, Y" }} - {% endblock %} + +{% block content %} + + +

[Ogg/Vorbis Audio RSS] +[MP3 Audio RSS] +Free as in Freedom

+ +

Free as in Freedom Archive: {{ day|date:"F j, Y" }}

+ +{% for object in object_list %} +
+

{{ object.pub_date|date:"F j, Y" }}

+

{{ object.title|safe }}

+ {{ object.summary|safe }} +

Read More...

+

Released on {{ object.pub_date|date:"F j, Y" }}; its running time is {{ object.duration }}

+ {% if object.tags.all %}

Tags: {% for tag in object.tags.all %}{{ tag.label }}{% if not forloop.last %}, {% endif %}{% endfor %}

{% endif %} +
+{% endfor %} + +{% endblock %} diff --git a/www/podjango/templates/podjango/cast/cast_archive_month.html b/www/podjango/templates/podjango/cast/cast_archive_month.html new file mode 100644 index 0000000000000000000000000000000000000000..dd49e03f17c7c0ab31750b5c209b6cffe2fa267d --- /dev/null +++ b/www/podjango/templates/podjango/cast/cast_archive_month.html @@ -0,0 +1,34 @@ + + + + +{% extends "podjango/base_podcast.html" %} + +{% block subtitle %}Free as in Freedom Archive: {{ month|date:"F, Y" }} - {% endblock %} + +{% block content %} + + +

[Ogg/Vorbis Audio RSS] +[MP3 Audio RSS] +Free as in Freedom

+ +

Free as in Freedom Archive: {{ month|date:"F, Y" }}

+ +{% for object in object_list %} +
+

{{ object.pub_date|date:"F j, Y" }}

+

{{ object.title|safe }}

+ {{ object.summary|safe }} +

Read More...

+

Released on {{ object.pub_date|date:"F j, Y" }}; its running time is {{ object.duration }}

+ {% if object.tags.all %}

Tags: {% for tag in object.tags.all %}{{ tag.label }}{% if not forloop.last %}, {% endif %}{% endfor %}

{% endif %} +
+{% endfor %} + +{% endblock %} diff --git a/www/podjango/templates/podjango/cast/cast_archive_year.html b/www/podjango/templates/podjango/cast/cast_archive_year.html new file mode 100644 index 0000000000000000000000000000000000000000..3e59fb3b2bd741c05ef21222dd8eeb426f35c4a1 --- /dev/null +++ b/www/podjango/templates/podjango/cast/cast_archive_year.html @@ -0,0 +1,28 @@ + + + + +{% extends "podjango/base_podcast.html" %} + +{% block subtitle %}Free as in Freedom Archive: {{ year }} - {% endblock %} + +{% block content %} + +

[Ogg/Vorbis Audio RSS] +[MP3 Audio RSS] +Free as in Freedom

+ +

Free as in Freedom Archive: {{ year }}

+ +
    +{% for object in object_list %} +
  • {{ object.title|safe }}
    + {{ object.pub_date|date:"F j, Y" }}; duration: {{ object.duration }}
  • +{% endfor %} +
+ +{% endblock %} diff --git a/www/podjango/templates/podjango/cast/cast_detail.html b/www/podjango/templates/podjango/cast/cast_detail.html new file mode 100644 index 0000000000000000000000000000000000000000..7877827fe8b3718015fb280bbd5e6a7c77cb4772 --- /dev/null +++ b/www/podjango/templates/podjango/cast/cast_detail.html @@ -0,0 +1,57 @@ + + + + +{% extends "podjango/base_podcast.html" %} + +{% block subtitle %}{{ object.title|striptags }} - Free as in Freedom - {% endblock %} + +{% block content %} + +

[Ogg/Vorbis Audio RSS] +[MP3 Audio RSS] +Free as in Freedom

+ +

[Get cast in Ogg/Vorbis
+                                          format] +[Get cast in MP3 format] + + +{{ object.title|safe }}

+ +

{{ object.pub_date|date:"j F Y" }}

+ +

Download

+ +oggmp3 + +

Summary

+ +{{ object.summary|safe }} + +

+This show was released on {{ object.pub_date|date:"l j F Y" }}; its +running time is {{ object.duration}}.

+ +

Show Notes

+{{ object.body|safe }} +
+ +
+ +

Send feedback and comments on the oggcast +to <oggcast@faif.us>. +You can keep in touch with Free as in Freedom +on our IRC channel, #faif on irc.freenode.net, and +by following @faif on identi.ca.

+ +{% if object.tags.all %}

Tags: {% for tag in object.tags.all %}{{ tag.label }}{% if not forloop.last %}, {% endif %}{% endfor %}

{% endif %} + +

Other FaiF oggcasts…

+ +{% endblock %} diff --git a/www/podjango/templates/podjango/cast/cast_list.html b/www/podjango/templates/podjango/cast/cast_list.html new file mode 100644 index 0000000000000000000000000000000000000000..2b6c46834ac8b35369e5cbbcc873b344d37d3f5c --- /dev/null +++ b/www/podjango/templates/podjango/cast/cast_list.html @@ -0,0 +1,62 @@ + + + + +{% extends "podjango/base_podcast.html" %} + +{% block subtitle %}Free as in Freedom - {% endblock %} + +{% block content %} + +

[Ogg/Vorbis Audio RSS] +[MP3 Audio RSS] +Free as in Freedom

+ +{% if tags %} +

Displaying casts +tagged {% for tag in tags %}{% if not forloop.last %}{% if not forloop.first %}, {% endif %}{% endif %}{{ tag.label }}{% ifequal forloop.revcounter 2 %} or {% endifequal %}{% endfor %} +

+{% endif %} + +{% for object in object_list %} +
+

{{ object.pub_date|date:"F j, Y" }}

+

+[Get cast in Ogg/Vorbis
+                                          format] +[Get cast in MP3 format] + +{{ object.title|safe }}

+

Summary

+ + {{ object.summary|safe }} + +

+ This show was released on {{ object.pub_date|date:"l j F Y" }}; its + running time is {{ object.duration}}.

+

Show Notes

+ {{ object.body|safe }} +
+ {% if object.tags.all %}

Tags: {% for tag in object.tags.all %}{{ tag.label }}{% if not forloop.last %}, {% endif %}{% endfor %}

{% endif %} +
+{% endfor %} + +

+{% if has_next %}Next page (older) »{% endif %} +{% if has_previous %}« Previous page (newer){% endif %} +

+
+ +{% if date_list %} +

Index by date

+ +{% endif %} + +{% endblock %} diff --git a/www/podjango/templates/podjango/feeds.html b/www/podjango/templates/podjango/feeds.html new file mode 100644 index 0000000000000000000000000000000000000000..bf568707e44d959c61ba2eb27b17f93667022e4e --- /dev/null +++ b/www/podjango/templates/podjango/feeds.html @@ -0,0 +1,18 @@ +{% extends "base_standard.html" %} + +{% block subtitle %}News Feeds - {% endblock %} + +{% block content %} + +

Feeds Available at faif.us

+ +

All feeds are RSS 2.0.

+ +
    +{% for feed in feeds %} +
  • {{ feed.title }} — +{{ feed.description|safe }}
  • +{% endfor %} +
+ +{% endblock %} diff --git a/www/podjango/templates/podjango/feeds/omnibus_description.html b/www/podjango/templates/podjango/feeds/omnibus_description.html new file mode 100644 index 0000000000000000000000000000000000000000..2edf925f464c3823283578f82ae5da6a0af370fa --- /dev/null +++ b/www/podjango/templates/podjango/feeds/omnibus_description.html @@ -0,0 +1,16 @@ + + + + + +{% ifequal obj.omnibus_type "news" %} +

A news item from SFLC.

+{% endifequal %} +{% ifequal obj.omnibus_type "podcast" %} +

An episode of the Software Freedom Law Show.

+{% endifequal %} +{% ifequal obj.omnibus_type "event" %} +

An upcoming event related to the SFLC .

+{% endifequal %} +{% include obj.omnibus_feed_description_template %} diff --git a/www/podjango/templates/podjango/feeds/omnibus_title.html b/www/podjango/templates/podjango/feeds/omnibus_title.html new file mode 100644 index 0000000000000000000000000000000000000000..66cec083b323716b62289372823a26762277064d --- /dev/null +++ b/www/podjango/templates/podjango/feeds/omnibus_title.html @@ -0,0 +1,5 @@ + + + +{% include obj.omnibus_feed_title_template %} diff --git a/www/podjango/templates/podjango/feeds/podcast_description.html b/www/podjango/templates/podjango/feeds/podcast_description.html new file mode 100644 index 0000000000000000000000000000000000000000..60162ca803eb25452f74fd131aac8237896f71a1 --- /dev/null +++ b/www/podjango/templates/podjango/feeds/podcast_description.html @@ -0,0 +1,38 @@ +

+[Direct download of cast in Ogg/Vorbis
+                                          format] +[Direct download of cast in MP3 format] +

+

+{{ obj.summary|safe }} +

+

Show Notes:

+ +{{ obj.body|safe }} + +
+ +

Send feedback and comments on the cast +to <oggcast@faif.us>. +You can keep in touch with Free as in Freedom on our IRC channel, #faif on irc.freenode.net, and + by following Conservancy on + identi.ca and and Twitter.

+ +

Free as in Freedom is produced by Dan Lynch + of danlynch.org. +Theme + music written and performed + by Mike Tarantino + with Charlie Paxson on drums.

+ +

Creative Commons License + The content + of this + audcast, and the accompanying show notes and music are licensed + under the Creative + Commons Attribution-Share-Alike 4.0 license (CC BY-SA 4.0). +

diff --git a/www/podjango/templates/podjango/feeds/podcast_title.html b/www/podjango/templates/podjango/feeds/podcast_title.html new file mode 100644 index 0000000000000000000000000000000000000000..8d1d5bd500e6adefc631a5821733cef8791991df --- /dev/null +++ b/www/podjango/templates/podjango/feeds/podcast_title.html @@ -0,0 +1 @@ +{{ obj.title|striptags|safe }} diff --git a/www/podjango/templates/podjango/frontpage.html b/www/podjango/templates/podjango/frontpage.html new file mode 100644 index 0000000000000000000000000000000000000000..e8cdc3c2e2d6693f8109224c2681dba4eca43d57 --- /dev/null +++ b/www/podjango/templates/podjango/frontpage.html @@ -0,0 +1,59 @@ +{% extends "podjango/base_podcast.html" %} + +{% block content %} + +
+ + + +

Free as in Freedom

+ +

Free as in Freedom is a bi-weekly oggcast, hosted and presented by +Bradley M. Kuhn and Karen Sandler. +The discussion includes legal, policy, and many other issues in the Free, Libre, +and Open Source Software (FLOSS) world. Occasionally, guests join +Bradley and Karen to discuss various topics regarding FLOSS.

+ +

You can email feedback on the show + to <oggcast@faif.us>, or join + bkuhn and other listeners in our IRC channel, #faif on + irc.freenode.net.

+ + +

Follow FaiF's RSS, and Other Feeds

+ +

There is RSS for both ogg format + and mp3 format. These links might + work if you want to subscribe to the show with proprietary Apple devices.

+ +

If you're interested you can + follow Karen, + and the podcast itself + on Twitter. + Also, Bradley + and Karen both have blogs you can + read.

+ +

+[Ogg/Vorbis Audio RSS] +[MP3 Audio
+       RSS]Recent Free as in Freedom Shows

+ +{% for cc in cast %} +
+[Get cast in Ogg/Vorbis
+                                          format] +[Get cast in MP3 format] +

{{ cc.pub_date|date:"F j, Y" }}

+

{{ cc.title|safe }}

+{{ cc.summary|safe }} +
+{% endfor %} +

All oggcasts…

+
+{% endblock %} diff --git a/www/podjango/urls.py b/www/podjango/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..9372a9b91acbc9e9678004ba412cafefaff97bf6 --- /dev/null +++ b/www/podjango/urls.py @@ -0,0 +1,43 @@ +# Copyright 2010 Bradley M. Kuhn +# Copyright 2005-2008 James Garrison + +# This software's license gives you freedom; you can copy, convey, +# propagate, redistribute, modify and/or redistribute modified versions of +# this program under the terms of the GNU Affero General Public License +# (AGPL) as published by the Free Software Foundation (FSF), either +# version 3 of the License, or (at your option) any later version of the +# AGPL published by the FSF. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero +# General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program in a file in the toplevel directory called +# "AGPLv3". If not, see . + +from django.conf import settings +from django.conf.urls import url, include +from django.contrib import admin +from django.contrib.syndication.views import Feed + +from podjango.feeds import feed_dict, view, OggCastFeed +from podjango import frontpage + +#handler404 = 'modpythoncustom.view404' + +admin.autodiscover() + +app_name = 'podjango' +urlpatterns = [ + url(r'^$', frontpage.view), + url(r'^cast/?', include('podjango.apps.cast.urls')), + url(r'^feeds/cast-ogg/?$', OggCastFeed(), name='feed-ogg'), + url(r'^feeds/cast-mp3/?$', OggCastFeed(), name='feed-mp3'), + url(r'^feeds/$', view, name='feeds'), +] + +if settings.DEBUG: + from django.conf.urls.static import static + urlpatterns += static('/', document_root='podjango/static')