Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #9800 -- Allow "isPermaLink" attribute in <guid> element of an …

…RSS item.

Thanks @rtnpro for the patch!
  • Loading branch information...
commit 5449240c548bb6877923791d02e800c6b25393f5 1 parent 2390fe3
Simon Charette authored
2  django/contrib/syndication/views.py
@@ -184,6 +184,8 @@ def get_feed(self, obj, request):
184 184
                 link = link,
185 185
                 description = description,
186 186
                 unique_id = self.__get_dynamic_attr('item_guid', item, link),
  187
+                unique_id_is_permalink = self.__get_dynamic_attr(
  188
+                    'item_guid_is_permalink', item),
187 189
                 enclosure = enc,
188 190
                 pubdate = pubdate,
189 191
                 author_name = author_name,
11  django/utils/feedgenerator.py
@@ -113,8 +113,8 @@ def __init__(self, title, link, description, language=None, author_email=None,
113 113
 
114 114
     def add_item(self, title, link, description, author_email=None,
115 115
         author_name=None, author_link=None, pubdate=None, comments=None,
116  
-        unique_id=None, enclosure=None, categories=(), item_copyright=None,
117  
-        ttl=None, **kwargs):
  116
+        unique_id=None, unique_id_is_permalink=None, enclosure=None,
  117
+        categories=(), item_copyright=None, ttl=None, **kwargs):
118 118
         """
119 119
         Adds an item to the feed. All args are expected to be Python Unicode
120 120
         objects except pubdate, which is a datetime.datetime object, and
@@ -136,6 +136,7 @@ def add_item(self, title, link, description, author_email=None,
136 136
             'pubdate': pubdate,
137 137
             'comments': to_unicode(comments),
138 138
             'unique_id': to_unicode(unique_id),
  139
+            'unique_id_is_permalink': unique_id_is_permalink,
139 140
             'enclosure': enclosure,
140 141
             'categories': categories or (),
141 142
             'item_copyright': to_unicode(item_copyright),
@@ -280,7 +281,11 @@ def add_item_elements(self, handler, item):
280 281
         if item['comments'] is not None:
281 282
             handler.addQuickElement("comments", item['comments'])
282 283
         if item['unique_id'] is not None:
283  
-            handler.addQuickElement("guid", item['unique_id'])
  284
+            guid_attrs = {}
  285
+            if isinstance(item.get('unique_id_is_permalink'), bool):
  286
+                guid_attrs['isPermaLink'] = str(
  287
+                    item['unique_id_is_permalink']).lower()
  288
+            handler.addQuickElement("guid", item['unique_id'], guid_attrs)
284 289
         if item['ttl'] is not None:
285 290
             handler.addQuickElement("ttl", item['ttl'])
286 291
 
12  docs/ref/contrib/syndication.txt
@@ -624,6 +624,18 @@ This example illustrates all possible attributes and methods for a
624 624
             Takes an item, as return by items(), and returns the item's ID.
625 625
             """
626 626
 
  627
+        # ITEM_GUID_IS_PERMALINK -- The following method is optional. If
  628
+        # provided, it sets the 'isPermaLink' attribute of an item's
  629
+        # GUID element. This method is used only when 'item_guid' is
  630
+        # specified.
  631
+
  632
+        def item_guid_is_permalink(self, obj):
  633
+            """
  634
+            Takes an item, as returned by items(), and returns a boolean.
  635
+            """
  636
+
  637
+        item_guid_is_permalink = False  # Hard coded value
  638
+
627 639
         # ITEM AUTHOR NAME -- One of the following three is optional. The
628 640
         # framework looks for them in this order.
629 641
 
13  tests/regressiontests/syndication/feeds.py
@@ -42,6 +42,19 @@ def item_pubdate(self, item):
42 42
     item_copyright = 'Copyright (c) 2007, Sally Smith'
43 43
 
44 44
 
  45
+class TestRss2FeedWithGuidIsPermaLinkTrue(TestRss2Feed):
  46
+    def item_guid_is_permalink(self, item):
  47
+        return True
  48
+
  49
+
  50
+class TestRss2FeedWithGuidIsPermaLinkFalse(TestRss2Feed):
  51
+    def item_guid(self, item):
  52
+        return str(item.pk)
  53
+
  54
+    def item_guid_is_permalink(self, item):
  55
+        return False
  56
+
  57
+
45 58
 class TestRss091Feed(TestRss2Feed):
46 59
     feed_type = feedgenerator.RssUserland091Feed
47 60
 
36  tests/regressiontests/syndication/tests.py
@@ -103,9 +103,43 @@ def test_rss2_feed(self):
103 103
             'author': 'test@example.com (Sally Smith)',
104 104
         })
105 105
         self.assertCategories(items[0], ['python', 'testing'])
106  
-
107 106
         for item in items:
108 107
             self.assertChildNodes(item, ['title', 'link', 'description', 'guid', 'category', 'pubDate', 'author'])
  108
+            # Assert that <guid> does not have any 'isPermaLink' attribute
  109
+            self.assertIsNone(item.getElementsByTagName(
  110
+                'guid')[0].attributes.get('isPermaLink'))
  111
+
  112
+    def test_rss2_feed_guid_permalink_false(self):
  113
+        """
  114
+        Test if the 'isPermaLink' attribute of <guid> element of an item
  115
+        in the RSS feed is 'false'.
  116
+        """
  117
+        response = self.client.get(
  118
+            '/syndication/rss2/guid_ispermalink_false/')
  119
+        doc = minidom.parseString(response.content)
  120
+        chan = doc.getElementsByTagName(
  121
+            'rss')[0].getElementsByTagName('channel')[0]
  122
+        items = chan.getElementsByTagName('item')
  123
+        for item in items:
  124
+            self.assertEqual(
  125
+                item.getElementsByTagName('guid')[0].attributes.get(
  126
+                    'isPermaLink').value, "false")
  127
+
  128
+    def test_rss2_feed_guid_permalink_true(self):
  129
+        """
  130
+        Test if the 'isPermaLink' attribute of <guid> element of an item
  131
+        in the RSS feed is 'true'.
  132
+        """
  133
+        response = self.client.get(
  134
+            '/syndication/rss2/guid_ispermalink_true/')
  135
+        doc = minidom.parseString(response.content)
  136
+        chan = doc.getElementsByTagName(
  137
+            'rss')[0].getElementsByTagName('channel')[0]
  138
+        items = chan.getElementsByTagName('item')
  139
+        for item in items:
  140
+            self.assertEqual(
  141
+                item.getElementsByTagName('guid')[0].attributes.get(
  142
+                    'isPermaLink').value, "true")
109 143
 
110 144
     def test_rss091_feed(self):
111 145
         """
4  tests/regressiontests/syndication/urls.py
@@ -8,6 +8,10 @@
8 8
 urlpatterns = patterns('django.contrib.syndication.views',
9 9
     (r'^syndication/complex/(?P<foo>.*)/$', feeds.ComplexFeed()),
10 10
     (r'^syndication/rss2/$', feeds.TestRss2Feed()),
  11
+    (r'^syndication/rss2/guid_ispermalink_true/$',
  12
+        feeds.TestRss2FeedWithGuidIsPermaLinkTrue()),
  13
+    (r'^syndication/rss2/guid_ispermalink_false/$',
  14
+        feeds.TestRss2FeedWithGuidIsPermaLinkFalse()),
11 15
     (r'^syndication/rss091/$', feeds.TestRss091Feed()),
12 16
     (r'^syndication/no_pubdate/$', feeds.TestNoPubdateFeed()),
13 17
     (r'^syndication/atom/$', feeds.TestAtomFeed()),

0 notes on commit 5449240

Please sign in to comment.
Something went wrong with that request. Please try again.