Files
@ 541f423a3d1c
Branch filter:
Location: website/conservancy/podjango/feeds.py
541f423a3d1c
11.8 KiB
text/x-python
Add transparent background to T-shirt image
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | # Copyright (C) 2008, 2010 Bradley M. Kuhn <bkuhn@ebb.org>
# 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 <http://www.gnu.org/licenses/>.
#
from datetime import datetime
from django.contrib.sites.shortcuts import get_current_site
from django.contrib.syndication.views import Feed, add_domain
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.utils.feedgenerator import Rss201rev2Feed
from .models import Cast, Podcast
from .templatetags.podjango import episode_url
# 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': add_domain(self.current_site.domain, obj.icon.url, self.is_secure),
'width': '300', 'height': '300'},
'webMaster': 'oggcast@faif.us (Bradley and Karen)',
'dcCreator': 'oggcast@faif.us (Bradley and Karen)',
'iTunesExplicit': 'No',
'iTunesBlock': 'No',
'iTunesImage': {'url': add_domain(self.current_site.domain, obj.icon.url, self.is_secure),
'title': obj.title,
'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': 'Software Freedom Conservancy',
'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', 'https://sfconservancy.org/')
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})
# 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
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 = "https://sfconservancy.org/"
author_name = "Software Freedom Conservancy"
title_template = "feed_title.html"
description_template = "feed_description.html"
def get_feed(self, obj, request):
# Enclosure (media) URLs don't automatically get the protocol and
# domain, but these are required for the podcast to work
# properly. added. This provides current_site and is_secure to the feed
# so that we have it in context for use in `item_enclosure_url`.
self.current_site = get_current_site(request)
self.is_secure = request.is_secure()
return super().get_feed(obj, request)
def get_object(self, request, podcast_slug):
self.podcast = Podcast.objects.get(slug=podcast_slug)
self.title = self.podcast.title
return self.podcast
def items(self, obj):
return Cast.objects.filter(podcast=obj, pub_date__lte=datetime.now()).order_by('-pub_date')
def item_pubdate(self, item):
return item.pub_date
def item_link(self, item):
return episode_url(self.podcast, item)
def item_author_email(self, obj):
return "oggcast@faif.us"
def item_author_name(self, obj):
return "Software Freedom Conservancy"
def item_author_link(self, obj):
return "https://sfconservancy.org"
def item_categories(self, item):
return ('Technology',)
def copyright_holder(self):
return "Software Freedom Conservancy"
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!!!
# <itunes:author>
# 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 add_domain(self.current_site.domain, item.mp3_path, self.is_secure)
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 add_domain(self.current_site.domain, item.ogg_path, self.is_secure)
def item_enclosure_length(self, item):
return item.ogg_length
def view(request, podcast_slug):
"""Listing of all available feeds
"""
feed_dict = {
'feed-ogg': OggCastFeed,
'feed-mp3': Mp3CastFeed,
}
podcast = get_object_or_404(Podcast, slug=podcast_slug)
# make each feed know its canonical url
for k, v in feed_dict.items():
v.get_absolute_url = reverse(f'podjango:{k}', kwargs={'podcast_slug': podcast.slug})
feeds = feed_dict.values()
return render(request, "feeds.html", {'podcast': podcast,
'feeds': feeds})
|