diff --git a/tests/test_web.py b/tests/test_web.py index 9f6fc7e0..8311f9e5 100644 --- a/tests/test_web.py +++ b/tests/test_web.py @@ -1901,6 +1901,31 @@ def test_poll_feed_rss(self, mock_create_task, mock_get, _): self.assert_task(mock_create_task, 'poll-feed', '/queue/poll-feed', domain='user.com', eta_seconds=expected_eta) + @patch('oauth_dropins.webutil.appengine_config.tasks_client.create_task') + def test_poll_feed_xml_content_type(self, mock_create_task, mock_get, _): + common.RUN_TASKS_INLINE = False + self.user.obj.mf2 = ACTOR_MF2_REL_FEED_URL + self.user.obj.put() + + feed = """\ + + +https://user.com/post +I hereby ☕ post + +""" + mock_get.return_value = requests_response( + feed, headers={'Content-Type': 'application/xml; charset=utf-8'}) + + got = self.post('/queue/poll-feed', data={'domain': 'user.com'}) + self.assertEqual(200, got.status_code) + self.assertEqual(NOW, self.user.key.get().last_polled_feed) + + mock_get.assert_has_calls(( + self.req('https://foo/atom'), + )) + assert Object.get_by_id('https://user.com/post') + def test_poll_feed_fails(self, mock_get, _): common.RUN_TASKS_INLINE = False self.user.obj.mf2 = { diff --git a/web.py b/web.py index c1616558..e3aeb278 100644 --- a/web.py +++ b/web.py @@ -59,6 +59,7 @@ FEED_TYPES = { atom.CONTENT_TYPE.split(';')[0]: 'atom', rss.CONTENT_TYPE.split(';')[0]: 'rss', + 'application/xml': 'xml', } MIN_FEED_POLL_PERIOD = timedelta(hours=2) MAX_FEED_POLL_PERIOD = timedelta(weeks=1) @@ -628,8 +629,8 @@ def poll_feed_task(): # discover feed URL for url, info in user.obj.mf2.get('rel-urls', {}).items(): - if ('alternate' in info.get('rels', []) - and info.get('type', '').split(';')[0] in FEED_TYPES.keys()): + rel_type = FEED_TYPES.get(info.get('type', '').split(';')[0]) + if 'alternate' in info.get('rels', []) and rel_type: break else: msg = f"User {user.key.id()} has no feed URL, can't fetch feed" @@ -640,10 +641,10 @@ def poll_feed_task(): resp = util.requests_get(url) content_type = resp.headers.get('Content-Type') type = FEED_TYPES.get(content_type.split(';')[0]) - if type == 'atom': + if type == 'atom' or (type == 'xml' and rel_type == 'atom'): activities = atom.atom_to_activities(resp.text) obj_feed_prop = {'atom': resp.text} - elif type == 'rss': + elif type == 'rss' or (type == 'xml' and rel_type == 'rss'): activities = rss.to_activities(resp.text) obj_feed_prop = {'rss': resp.text} else: