From 04f0d70113e9f5d894100bb8807cd61f8abc5d36 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Tue, 17 Oct 2023 19:00:03 +0200 Subject: [PATCH] RSS: Add support for $content/$summary_detail/$title_detail --- plugins/RSS/plugin.py | 29 ++++++++++++++ plugins/RSS/test.py | 93 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/plugins/RSS/plugin.py b/plugins/RSS/plugin.py index 6f136d928..9685241ee 100644 --- a/plugins/RSS/plugin.py +++ b/plugins/RSS/plugin.py @@ -497,6 +497,35 @@ class RSS(callbacks.Plugin): isinstance(v, str)} kwargs["feed_name"] = feed.name kwargs.update(entry) + for (key, value) in list(kwargs.items()): + # First look for plain text + if isinstance(value, list): + for item in value: + if isinstance(item, dict) and 'value' in item and \ + item.get('type') == 'text/plain': + value = item['value'] + break + # Then look for HTML text or URL + if isinstance(value, list): + for item in value: + if isinstance(item, dict) and item.get('type') in \ + ('text/html', 'application/xhtml+xml'): + if 'value' in item: + value = utils.web.htmlToText(item['value']) + elif 'href' in item: + value = item['href'] + # Then fall back to any URL + if isinstance(value, list): + for item in value: + if isinstance(item, dict) and 'href' in item: + value = item['href'] + break + # Finally, as a last resort, use the value as-is + if isinstance(value, list): + for item in value: + if isinstance(item, dict) and 'value' in item: + value = item['value'] + kwargs[key] = value s = string.Template(template).safe_substitute(entry, **kwargs, date=date) return self._normalize_entry(s) diff --git a/plugins/RSS/test.py b/plugins/RSS/test.py index a3e67a9ba..d5cdc9f6b 100644 --- a/plugins/RSS/test.py +++ b/plugins/RSS/test.py @@ -59,7 +59,6 @@ not_well_formed = """ """ - class MockResponse: headers = {} url = '' @@ -359,6 +358,98 @@ class RSSTestCase(ChannelPluginTestCase): self.assertRegexp('rss http://xkcd.com/rss.xml', 'On the other hand, the refractor\'s') + @mock_urllib + def testContentHtmlOnly(self, mock): + timeFastForward(1.1) + with conf.supybot.plugins.RSS.format.context('$content'): + mock._data = """ + + + Recent Commits to anope:2.0 + 2023-10-04T16:14:39Z + + title with <pre>HTML<pre> + 2023-10-04T16:14:39Z + + content with <pre>HTML<pre> + + +""" + self.assertRegexp('rss https://example.org', + 'content with HTML') + + @mock_urllib + def testContentXhtmlOnly(self, mock): + timeFastForward(1.1) + with conf.supybot.plugins.RSS.format.context('$content'): + mock._data = """ + + + Recent Commits to anope:2.0 + 2023-10-04T16:14:39Z + + title with <pre>HTML<pre> + 2023-10-04T16:14:39Z + +
+ content with
XHTML
+      
+
+
+
""" + self.assertRegexp('rss https://example.org', + 'content with XHTML') + + @mock_urllib + def testContentHtmlAndPlaintext(self, mock): + timeFastForward(1.1) + with conf.supybot.plugins.RSS.format.context('$content'): + mock._data = """ + + + Recent Commits to anope:2.0 + 2023-10-04T16:14:39Z + + title with <pre>HTML<pre> + 2023-10-04T16:14:39Z + + + content with <pre>HTML<pre> + + + content with plaintext + + +""" + self.assertRegexp('rss https://example.org', + 'content with plaintext') + + @mock_urllib + def testContentPlaintextAndHtml(self, mock): + timeFastForward(1.1) + with conf.supybot.plugins.RSS.format.context('$content'): + mock._data = """ + + + Recent Commits to anope:2.0 + 2023-10-04T16:14:39Z + + title with <pre>HTML<pre> + 2023-10-04T16:14:39Z + + + content with plaintext + + + content with <pre>HTML<pre> + + +""" + self.assertRegexp('rss https://example.org', + 'content with plaintext') + @mock_urllib def testFeedAttribute(self, mock): timeFastForward(1.1)