summaryrefslogtreecommitdiff
path: root/django/utils/feedgenerator.py
diff options
context:
space:
mode:
authorUnai Zalakain <unai@gisa-elkartea.org>2015-08-21 11:50:43 +0200
committerTim Graham <timograham@gmail.com>2015-09-18 18:31:58 -0400
commitaac2a2d2ae2486342058db0c72ed7ba2c7c8eb1e (patch)
tree9d36cf0b889eceb832aee1ffbeea0a826a557b22 /django/utils/feedgenerator.py
parent71ebcb85b931f43865df5b322b2cf06d3da23f69 (diff)
Fixed #13110 -- Added support for multiple enclosures in Atom feeds.
The ``item_enclosures`` hook returns a list of ``Enclosure`` objects which is then used by the feed builder. If the feed is a RSS feed, an exception is raised as RSS feeds don't allow multiple enclosures per feed item. The ``item_enclosures`` hook defaults to an empty list or, if the ``item_enclosure_url`` hook is defined, to a list with a single ``Enclosure`` built from the ``item_enclosure_url``, ``item_enclosure_length``, and ``item_enclosure_mime_type`` hooks.
Diffstat (limited to 'django/utils/feedgenerator.py')
-rw-r--r--django/utils/feedgenerator.py52
1 files changed, 37 insertions, 15 deletions
diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py
index 9b1421160b..c67fedb277 100644
--- a/django/utils/feedgenerator.py
+++ b/django/utils/feedgenerator.py
@@ -118,11 +118,13 @@ class SyndicationFeed(object):
def add_item(self, title, link, description, author_email=None,
author_name=None, author_link=None, pubdate=None, comments=None,
unique_id=None, unique_id_is_permalink=None, enclosure=None,
- categories=(), item_copyright=None, ttl=None, updateddate=None, **kwargs):
+ categories=(), item_copyright=None, ttl=None, updateddate=None,
+ enclosures=None, **kwargs):
"""
Adds an item to the feed. All args are expected to be Python Unicode
objects except pubdate and updateddate, which are datetime.datetime
- objects, and enclosure, which is an instance of the Enclosure class.
+ objects, and enclosures, which is an iterable of instances of the
+ Enclosure class.
"""
to_unicode = lambda s: force_text(s, strings_only=True)
if categories:
@@ -130,6 +132,16 @@ class SyndicationFeed(object):
if ttl is not None:
# Force ints to unicode
ttl = force_text(ttl)
+ if enclosure is None:
+ enclosures = [] if enclosures is None else enclosures
+ else:
+ warnings.warn(
+ "The enclosure keyword argument is deprecated, "
+ "use enclosures instead.",
+ RemovedInDjango20Warning,
+ stacklevel=2,
+ )
+ enclosures = [enclosure]
item = {
'title': to_unicode(title),
'link': iri_to_uri(link),
@@ -142,7 +154,7 @@ class SyndicationFeed(object):
'comments': to_unicode(comments),
'unique_id': to_unicode(unique_id),
'unique_id_is_permalink': unique_id_is_permalink,
- 'enclosure': enclosure,
+ 'enclosures': enclosures,
'categories': categories or (),
'item_copyright': to_unicode(item_copyright),
'ttl': ttl,
@@ -317,10 +329,19 @@ class Rss201rev2Feed(RssFeed):
handler.addQuickElement("ttl", item['ttl'])
# Enclosure.
- if item['enclosure'] is not None:
- handler.addQuickElement("enclosure", '',
- {"url": item['enclosure'].url, "length": item['enclosure'].length,
- "type": item['enclosure'].mime_type})
+ if item['enclosures']:
+ enclosures = list(item['enclosures'])
+ if len(enclosures) > 1:
+ raise ValueError(
+ "RSS feed items may only have one enclosure, see "
+ "http://www.rssboard.org/rss-profile#element-channel-item-enclosure"
+ )
+ enclosure = enclosures[0]
+ handler.addQuickElement('enclosure', '', {
+ 'url': enclosure.url,
+ 'length': enclosure.length,
+ 'type': enclosure.mime_type,
+ })
# Categories.
for cat in item['categories']:
@@ -328,7 +349,7 @@ class Rss201rev2Feed(RssFeed):
class Atom1Feed(SyndicationFeed):
- # Spec: http://atompub.org/2005/07/11/draft-ietf-atompub-format-10.html
+ # Spec: https://tools.ietf.org/html/rfc4287
content_type = 'application/atom+xml; charset=utf-8'
ns = "http://www.w3.org/2005/Atom"
@@ -405,13 +426,14 @@ class Atom1Feed(SyndicationFeed):
if item['description'] is not None:
handler.addQuickElement("summary", item['description'], {"type": "html"})
- # Enclosure.
- if item['enclosure'] is not None:
- handler.addQuickElement("link", '',
- {"rel": "enclosure",
- "href": item['enclosure'].url,
- "length": item['enclosure'].length,
- "type": item['enclosure'].mime_type})
+ # Enclosures.
+ for enclosure in item.get('enclosures') or []:
+ handler.addQuickElement('link', '', {
+ 'rel': 'enclosure',
+ 'href': enclosure.url,
+ 'length': enclosure.length,
+ 'type': enclosure.mime_type,
+ })
# Categories.
for cat in item['categories']: