Fixed #9800 -- Allow "isPermaLink" attribute in <guid> element of an RSS item.
Thanks @rtnpro for the patch!
This commit is contained in:
parent
2390fe3f4f
commit
5449240c54
|
@ -184,6 +184,8 @@ class Feed(object):
|
||||||
link = link,
|
link = link,
|
||||||
description = description,
|
description = description,
|
||||||
unique_id = self.__get_dynamic_attr('item_guid', item, link),
|
unique_id = self.__get_dynamic_attr('item_guid', item, link),
|
||||||
|
unique_id_is_permalink = self.__get_dynamic_attr(
|
||||||
|
'item_guid_is_permalink', item),
|
||||||
enclosure = enc,
|
enclosure = enc,
|
||||||
pubdate = pubdate,
|
pubdate = pubdate,
|
||||||
author_name = author_name,
|
author_name = author_name,
|
||||||
|
|
|
@ -113,8 +113,8 @@ class SyndicationFeed(object):
|
||||||
|
|
||||||
def add_item(self, title, link, description, author_email=None,
|
def add_item(self, title, link, description, author_email=None,
|
||||||
author_name=None, author_link=None, pubdate=None, comments=None,
|
author_name=None, author_link=None, pubdate=None, comments=None,
|
||||||
unique_id=None, enclosure=None, categories=(), item_copyright=None,
|
unique_id=None, unique_id_is_permalink=None, enclosure=None,
|
||||||
ttl=None, **kwargs):
|
categories=(), item_copyright=None, ttl=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Adds an item to the feed. All args are expected to be Python Unicode
|
Adds an item to the feed. All args are expected to be Python Unicode
|
||||||
objects except pubdate, which is a datetime.datetime object, and
|
objects except pubdate, which is a datetime.datetime object, and
|
||||||
|
@ -136,6 +136,7 @@ class SyndicationFeed(object):
|
||||||
'pubdate': pubdate,
|
'pubdate': pubdate,
|
||||||
'comments': to_unicode(comments),
|
'comments': to_unicode(comments),
|
||||||
'unique_id': to_unicode(unique_id),
|
'unique_id': to_unicode(unique_id),
|
||||||
|
'unique_id_is_permalink': unique_id_is_permalink,
|
||||||
'enclosure': enclosure,
|
'enclosure': enclosure,
|
||||||
'categories': categories or (),
|
'categories': categories or (),
|
||||||
'item_copyright': to_unicode(item_copyright),
|
'item_copyright': to_unicode(item_copyright),
|
||||||
|
@ -280,7 +281,11 @@ class Rss201rev2Feed(RssFeed):
|
||||||
if item['comments'] is not None:
|
if item['comments'] is not None:
|
||||||
handler.addQuickElement("comments", item['comments'])
|
handler.addQuickElement("comments", item['comments'])
|
||||||
if item['unique_id'] is not None:
|
if item['unique_id'] is not None:
|
||||||
handler.addQuickElement("guid", item['unique_id'])
|
guid_attrs = {}
|
||||||
|
if isinstance(item.get('unique_id_is_permalink'), bool):
|
||||||
|
guid_attrs['isPermaLink'] = str(
|
||||||
|
item['unique_id_is_permalink']).lower()
|
||||||
|
handler.addQuickElement("guid", item['unique_id'], guid_attrs)
|
||||||
if item['ttl'] is not None:
|
if item['ttl'] is not None:
|
||||||
handler.addQuickElement("ttl", item['ttl'])
|
handler.addQuickElement("ttl", item['ttl'])
|
||||||
|
|
||||||
|
|
|
@ -624,6 +624,18 @@ This example illustrates all possible attributes and methods for a
|
||||||
Takes an item, as return by items(), and returns the item's ID.
|
Takes an item, as return by items(), and returns the item's ID.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# ITEM_GUID_IS_PERMALINK -- The following method is optional. If
|
||||||
|
# provided, it sets the 'isPermaLink' attribute of an item's
|
||||||
|
# GUID element. This method is used only when 'item_guid' is
|
||||||
|
# specified.
|
||||||
|
|
||||||
|
def item_guid_is_permalink(self, obj):
|
||||||
|
"""
|
||||||
|
Takes an item, as returned by items(), and returns a boolean.
|
||||||
|
"""
|
||||||
|
|
||||||
|
item_guid_is_permalink = False # Hard coded value
|
||||||
|
|
||||||
# ITEM AUTHOR NAME -- One of the following three is optional. The
|
# ITEM AUTHOR NAME -- One of the following three is optional. The
|
||||||
# framework looks for them in this order.
|
# framework looks for them in this order.
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,19 @@ class TestRss2Feed(views.Feed):
|
||||||
item_copyright = 'Copyright (c) 2007, Sally Smith'
|
item_copyright = 'Copyright (c) 2007, Sally Smith'
|
||||||
|
|
||||||
|
|
||||||
|
class TestRss2FeedWithGuidIsPermaLinkTrue(TestRss2Feed):
|
||||||
|
def item_guid_is_permalink(self, item):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class TestRss2FeedWithGuidIsPermaLinkFalse(TestRss2Feed):
|
||||||
|
def item_guid(self, item):
|
||||||
|
return str(item.pk)
|
||||||
|
|
||||||
|
def item_guid_is_permalink(self, item):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class TestRss091Feed(TestRss2Feed):
|
class TestRss091Feed(TestRss2Feed):
|
||||||
feed_type = feedgenerator.RssUserland091Feed
|
feed_type = feedgenerator.RssUserland091Feed
|
||||||
|
|
||||||
|
|
|
@ -103,9 +103,43 @@ class SyndicationFeedTest(FeedTestCase):
|
||||||
'author': 'test@example.com (Sally Smith)',
|
'author': 'test@example.com (Sally Smith)',
|
||||||
})
|
})
|
||||||
self.assertCategories(items[0], ['python', 'testing'])
|
self.assertCategories(items[0], ['python', 'testing'])
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
self.assertChildNodes(item, ['title', 'link', 'description', 'guid', 'category', 'pubDate', 'author'])
|
self.assertChildNodes(item, ['title', 'link', 'description', 'guid', 'category', 'pubDate', 'author'])
|
||||||
|
# Assert that <guid> does not have any 'isPermaLink' attribute
|
||||||
|
self.assertIsNone(item.getElementsByTagName(
|
||||||
|
'guid')[0].attributes.get('isPermaLink'))
|
||||||
|
|
||||||
|
def test_rss2_feed_guid_permalink_false(self):
|
||||||
|
"""
|
||||||
|
Test if the 'isPermaLink' attribute of <guid> element of an item
|
||||||
|
in the RSS feed is 'false'.
|
||||||
|
"""
|
||||||
|
response = self.client.get(
|
||||||
|
'/syndication/rss2/guid_ispermalink_false/')
|
||||||
|
doc = minidom.parseString(response.content)
|
||||||
|
chan = doc.getElementsByTagName(
|
||||||
|
'rss')[0].getElementsByTagName('channel')[0]
|
||||||
|
items = chan.getElementsByTagName('item')
|
||||||
|
for item in items:
|
||||||
|
self.assertEqual(
|
||||||
|
item.getElementsByTagName('guid')[0].attributes.get(
|
||||||
|
'isPermaLink').value, "false")
|
||||||
|
|
||||||
|
def test_rss2_feed_guid_permalink_true(self):
|
||||||
|
"""
|
||||||
|
Test if the 'isPermaLink' attribute of <guid> element of an item
|
||||||
|
in the RSS feed is 'true'.
|
||||||
|
"""
|
||||||
|
response = self.client.get(
|
||||||
|
'/syndication/rss2/guid_ispermalink_true/')
|
||||||
|
doc = minidom.parseString(response.content)
|
||||||
|
chan = doc.getElementsByTagName(
|
||||||
|
'rss')[0].getElementsByTagName('channel')[0]
|
||||||
|
items = chan.getElementsByTagName('item')
|
||||||
|
for item in items:
|
||||||
|
self.assertEqual(
|
||||||
|
item.getElementsByTagName('guid')[0].attributes.get(
|
||||||
|
'isPermaLink').value, "true")
|
||||||
|
|
||||||
def test_rss091_feed(self):
|
def test_rss091_feed(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -8,6 +8,10 @@ from . import feeds
|
||||||
urlpatterns = patterns('django.contrib.syndication.views',
|
urlpatterns = patterns('django.contrib.syndication.views',
|
||||||
(r'^syndication/complex/(?P<foo>.*)/$', feeds.ComplexFeed()),
|
(r'^syndication/complex/(?P<foo>.*)/$', feeds.ComplexFeed()),
|
||||||
(r'^syndication/rss2/$', feeds.TestRss2Feed()),
|
(r'^syndication/rss2/$', feeds.TestRss2Feed()),
|
||||||
|
(r'^syndication/rss2/guid_ispermalink_true/$',
|
||||||
|
feeds.TestRss2FeedWithGuidIsPermaLinkTrue()),
|
||||||
|
(r'^syndication/rss2/guid_ispermalink_false/$',
|
||||||
|
feeds.TestRss2FeedWithGuidIsPermaLinkFalse()),
|
||||||
(r'^syndication/rss091/$', feeds.TestRss091Feed()),
|
(r'^syndication/rss091/$', feeds.TestRss091Feed()),
|
||||||
(r'^syndication/no_pubdate/$', feeds.TestNoPubdateFeed()),
|
(r'^syndication/no_pubdate/$', feeds.TestNoPubdateFeed()),
|
||||||
(r'^syndication/atom/$', feeds.TestAtomFeed()),
|
(r'^syndication/atom/$', feeds.TestAtomFeed()),
|
||||||
|
|
Loading…
Reference in New Issue