Commit 5449240c authored by Simon Charette's avatar Simon Charette
Browse files

Fixed #9800 -- Allow "isPermaLink" attribute in <guid> element of an RSS item.

Thanks @rtnpro for the patch!
parent 2390fe3f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -184,6 +184,8 @@ class Feed(object):
                link = link,
                description = description,
                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,
                pubdate = pubdate,
                author_name = author_name,
+8 −3
Original line number Diff line number Diff line
@@ -113,8 +113,8 @@ 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, enclosure=None, categories=(), item_copyright=None,
        ttl=None, **kwargs):
        unique_id=None, unique_id_is_permalink=None, enclosure=None,
        categories=(), item_copyright=None, ttl=None, **kwargs):
        """
        Adds an item to the feed. All args are expected to be Python Unicode
        objects except pubdate, which is a datetime.datetime object, and
@@ -136,6 +136,7 @@ class SyndicationFeed(object):
            'pubdate': pubdate,
            'comments': to_unicode(comments),
            'unique_id': to_unicode(unique_id),
            'unique_id_is_permalink': unique_id_is_permalink,
            'enclosure': enclosure,
            'categories': categories or (),
            'item_copyright': to_unicode(item_copyright),
@@ -280,7 +281,11 @@ class Rss201rev2Feed(RssFeed):
        if item['comments'] is not None:
            handler.addQuickElement("comments", item['comments'])
        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:
            handler.addQuickElement("ttl", item['ttl'])

+12 −0
Original line number Diff line number Diff line
@@ -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.
            """

        # 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
        # framework looks for them in this order.

+13 −0
Original line number Diff line number Diff line
@@ -42,6 +42,19 @@ class TestRss2Feed(views.Feed):
    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):
    feed_type = feedgenerator.RssUserland091Feed

+35 −1
Original line number Diff line number Diff line
@@ -103,9 +103,43 @@ class SyndicationFeedTest(FeedTestCase):
            'author': 'test@example.com (Sally Smith)',
        })
        self.assertCategories(items[0], ['python', 'testing'])

        for item in items:
            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):
        """
Loading