From 6d94b38c5345fc2fef9de5926baa13cb11fbe63c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Gajdu=C5=A1ek?= Date: Fri, 18 Aug 2023 11:28:59 +0200 Subject: [PATCH 1/2] Improve sensor based on feeds provided by the community in GH issues * get the image from the feed if it is one of its attributes * add link processing in case link is not an attribute of the feed entry * use dateutil.parser in case the parsedate_to_datetime is not able to provide timezone info * parse image also from summary * add tests for the above mentioned --- .gitignore | 1 + .pre-commit-config.yaml | 2 +- custom_components/feedparser/sensor.py | 85 ++-- pyproject.toml | 2 +- tests/constants.py | 37 ++ tests/data/anp_nieuws.json | 16 + tests/data/anp_nieuws.xml | 572 +++++++++++++++++++++++++ tests/data/api_met_no_metalerts.json | 14 + tests/data/api_met_no_metalerts.xml | 29 ++ tests/data/buienradar_nl.json | 11 + tests/data/buienradar_nl.xml | 30 ++ tests/data/skolmaten_se_ede_skola.json | 15 + tests/data/skolmaten_se_ede_skola.xml | 1 + tests/feedsource.py | 20 + tests/test_sensors.py | 34 +- 15 files changed, 827 insertions(+), 42 deletions(-) create mode 100644 tests/data/anp_nieuws.json create mode 100644 tests/data/anp_nieuws.xml create mode 100644 tests/data/api_met_no_metalerts.json create mode 100644 tests/data/api_met_no_metalerts.xml create mode 100644 tests/data/buienradar_nl.json create mode 100644 tests/data/buienradar_nl.xml create mode 100644 tests/data/skolmaten_se_ede_skola.json create mode 100644 tests/data/skolmaten_se_ede_skola.xml diff --git a/.gitignore b/.gitignore index f2e5e13..1359d06 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.pyc build/ *.egg-info/ +custom_components/hacs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0548980..ff307b1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: - id: mypy additional_dependencies: [ - homeassistant-stubs, + homeassistant-stubs==2023.8.1, voluptuous-stubs, types-python-dateutil, types-PyYAML, diff --git a/custom_components/feedparser/sensor.py b/custom_components/feedparser/sensor.py index 3931192..b79ba30 100644 --- a/custom_components/feedparser/sensor.py +++ b/custom_components/feedparser/sensor.py @@ -3,6 +3,7 @@ import email.utils import logging +import re from datetime import datetime, timedelta, timezone from typing import TYPE_CHECKING @@ -173,12 +174,19 @@ def _generate_sensor_entry( if key in ["published", "updated", "created", "expired"]: parsed_date: datetime = self._parse_date(value) sensor_entry[key] = parsed_date.strftime(self._date_format) + elif key == "image": + sensor_entry["image"] = value.get("href") else: sensor_entry[key] = value - self._process_image(feed_entry, sensor_entry) - - _LOGGER.debug("Feed %s: Generated sensor entry: %s", self.name, sensor_entry) + if "image" in self._inclusions and "image" not in sensor_entry: + sensor_entry["image"] = self._process_image(feed_entry) + if ( + "link" in self._inclusions + and "link" not in sensor_entry + and (processed_link := self._process_link(feed_entry)) + ): + sensor_entry["link"] = processed_link return sensor_entry def _parse_date(self: FeedParserSensor, date: str) -> datetime: @@ -194,42 +202,63 @@ def _parse_date(self: FeedParserSensor, date: str) -> datetime: self.name, date, ) + # best effort to parse the date using dateutil + parsed_time = parser.parse(date) + + if not parsed_time.tzinfo: + # best effort to parse the date using dateutil parsed_time = parser.parse(date) - if not parsed_time.tzname(): - # replace tzinfo with UTC offset if tzinfo does not contain a TZ name - parsed_time = parsed_time.replace( - tzinfo=timezone(parsed_time.utcoffset()), # type: ignore[arg-type] + if not parsed_time.tzinfo: + msg = ( + f"Feed {self.name}: Unable to parse date {date}, " + "caused by an incorrect date format" ) + raise ValueError(msg) + if not parsed_time.tzname(): + # replace tzinfo with UTC offset if tzinfo does not contain a TZ name + parsed_time = parsed_time.replace( + tzinfo=timezone(parsed_time.utcoffset()), # type: ignore[arg-type] + ) + if self._local_time: parsed_time = dt.as_local(parsed_time) _LOGGER.debug("Feed %s: Parsed date: %s", self.name, parsed_time) return parsed_time - def _process_image( - self: FeedParserSensor, - feed_entry: FeedParserDict, - sensor_entry: dict[str, str], - ) -> None: - if "image" in self._inclusions and "image" not in sensor_entry.keys(): - if "enclosures" in feed_entry: - images = [ - enc - for enc in feed_entry["enclosures"] - if enc.type.startswith("image/") - ] - else: - images = [] + def _process_image(self: FeedParserSensor, feed_entry: FeedParserDict) -> str: + if "enclosures" in feed_entry and feed_entry["enclosures"]: + images = [ + enc for enc in feed_entry["enclosures"] if enc.type.startswith("image/") + ] if images: - sensor_entry["image"] = images[0]["href"] # pick the first image found - else: - _LOGGER.debug( - "Feed %s: Image is in inclusions, but no image was found for %s", + # pick the first image found + return images[0]["href"] + elif "summary" in feed_entry: + images = re.findall( + r"", + feed_entry["summary"], + ) + if images: + # pick the first image found + return images[0] + _LOGGER.debug( + "Feed %s: Image is in inclusions, but no image was found for %s", + self.name, + feed_entry, + ) + return DEFAULT_THUMBNAIL # use default image if no image found + + def _process_link(self: FeedParserSensor, feed_entry: FeedParserDict) -> str: + """Return link from feed entry.""" + if "links" in feed_entry: + if len(feed_entry["links"]) > 1: + _LOGGER.warning( + "Feed %s: More than one link found for %s. Using the first link.", self.name, feed_entry, ) - sensor_entry[ - "image" - ] = DEFAULT_THUMBNAIL # use default image if no image found + return feed_entry["links"][0]["href"] + return "" @property def feed_entries(self: FeedParserSensor) -> list[dict[str, str]]: diff --git a/pyproject.toml b/pyproject.toml index bac2809..a41f208 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ dependencies = ["python-dateutil", "feedparser==6.0.10", "homeassistant"] [project.optional-dependencies] dev = [ "black", - "homeassistant-stubs", + "homeassistant-stubs==2023.8.1", "pytest==7.4.0", "mypy", "ruff", diff --git a/tests/constants.py b/tests/constants.py index 8197424..5f814c3 100644 --- a/tests/constants.py +++ b/tests/constants.py @@ -51,6 +51,43 @@ "show_topn": 1, }, }, + { + "has_images": True, + "all_entries_have_images": False, + "has_unique_links": False, + "sensor_config": { + "name": "buienradar_nl", + "feed_url": "https://data.buienradar.nl/1.0/feed/xml/rssbuienradar", + "date_format": "%Y-%m-%d %H:%M:%S.%f", + }, + }, + { + "has_images": False, + "has_unique_links": False, + "sensor_config": { + "name": "skolmaten_se_ede_skola", + "feed_url": "https://skolmaten.se/ede-skola/rss/weeks/?limit=2", + "inclusions": ["title", "link", "published", "summary"], + }, + }, + { + "has_images": False, + "sensor_config": { + "name": "api_met_no_metalerts", + "feed_url": "https://api.met.no/weatherapi/metalerts/1.1/", + "inclusions": ["title", "link", "published", "summary"], + }, + }, + { + "has_images": True, + "has_unique_images": False, + "has_unique_titles": False, + "sensor_config": { + "name": "anp_nieuws", + "feed_url": "https://www.omnycontent.com/d/playlist/56ccbbb7-0ff7-4482-9d99-a88800f49f6c/a49c87f6-d567-4189-8692-a8e2009eaf86/9fea2041-fccd-4fcf-8cec-a8e2009eeca2/podcast.rss", + "inclusions": ["title", "link", "published", "summary"], + }, + }, ] DEFAULT_EXCLUSIONS: list[str] = [] diff --git a/tests/data/anp_nieuws.json b/tests/data/anp_nieuws.json new file mode 100644 index 0000000..3191622 --- /dev/null +++ b/tests/data/anp_nieuws.json @@ -0,0 +1,16 @@ +{ + "has_images": true, + "has_unique_images": false, + "has_unique_titles": false, + "sensor_config": { + "name": "anp_nieuws", + "feed_url": "https://www.omnycontent.com/d/playlist/56ccbbb7-0ff7-4482-9d99-a88800f49f6c/a49c87f6-d567-4189-8692-a8e2009eaf86/9fea2041-fccd-4fcf-8cec-a8e2009eeca2/podcast.rss", + "inclusions": [ + "title", + "link", + "published", + "summary" + ] + }, + "download_date": "2023-08-18T09:22:14.164244+00:00" +} diff --git a/tests/data/anp_nieuws.xml b/tests/data/anp_nieuws.xml new file mode 100644 index 0000000..70e2cb6 --- /dev/null +++ b/tests/data/anp_nieuws.xml @@ -0,0 +1,572 @@ + + + + 56ccbbb7-0ff7-4482-9d99-a88800f49f6c + 9086a42f-669b-49e7-b86f-aa400012afff + a49c87f6-d567-4189-8692-a8e2009eaf86 + 9fea2041-fccd-4fcf-8cec-a8e2009eeca2 + nl + + + + 538 Nieuws + https://www.anp.nl/ + Het laatste 538 radionieuws bulletin.

]]>
+ episodic + Het laatste 538 radionieuws bulletin. + + 538 Nieuws + info@538.nl + + 538 Nieuws + 2023 Talpa Radio + no + + + + https://www.omnycontent.com/d/programs/56ccbbb7-0ff7-4482-9d99-a88800f49f6c/a49c87f6-d567-4189-8692-a8e2009eaf86/image.jpg?t=1684833921&size=Large + 538 Nieuws + https://www.anp.nl/ + + + Het 538-nieuws van 11 uur + Het 538-nieuws van 11 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 48eb9341-4a07-4b2e-b52f-b062009098ac + 48eb9341-4a07-4b2e-b52f-b062009098ac + Fri, 18 Aug 2023 08:46:49 +0000 + 88 + +
+ + Het 538-nieuws van 10 uur + Het 538-nieuws van 10 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 28a8e434-7a8a-499f-abce-b062008058a6 + 28a8e434-7a8a-499f-abce-b062008058a6 + Fri, 18 Aug 2023 07:47:34 +0000 + 88 + +
+ + Het 538-nieuws van 10 uur + Het 538-nieuws van 10 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + f6c2b847-76b7-49bc-b7c1-b062007f6e19 + f6c2b847-76b7-49bc-b7c1-b062007f6e19 + Fri, 18 Aug 2023 07:44:13 +0000 + 87 + +
+ + Het 538-nieuws van 09 uur + Het 538-nieuws van 09 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + f46ff43a-faa4-46b9-b36a-b062006fbee6 + f46ff43a-faa4-46b9-b36a-b062006fbee6 + Fri, 18 Aug 2023 06:47:07 +0000 + 87 + +
+ + Het 538-nieuws van 08 uur + Het 538-nieuws van 08 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + f4f4c4b3-8b41-419c-90f8-b06200607646 + f4f4c4b3-8b41-419c-90f8-b06200607646 + Fri, 18 Aug 2023 05:51:32 +0000 + 87 + +
+ + Het 538-nieuws van 07 uur + Het 538-nieuws van 07 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 579050bc-59d3-46e8-9833-b062004f542c + 579050bc-59d3-46e8-9833-b062004f542c + Fri, 18 Aug 2023 04:49:06 +0000 + 92 + +
+ + Het 538-nieuws van 06 uur + Het 538-nieuws van 06 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 20001a78-7735-4aa4-bce7-b062003e6a2d + 20001a78-7735-4aa4-bce7-b062003e6a2d + Fri, 18 Aug 2023 03:47:30 +0000 + 89 + +
+ + Het 538-nieuws van 04 uur + Het 538-nieuws van 04 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + cb84afe9-8781-4154-851a-b062001eaf53 + cb84afe9-8781-4154-851a-b062001eaf53 + Fri, 18 Aug 2023 01:52:11 +0000 + 110 + +
+ + Het 538-nieuws van 03 uur + Het 538-nieuws van 03 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 659b4e4a-d10b-4844-b993-b062000dda4d + 659b4e4a-d10b-4844-b993-b062000dda4d + Fri, 18 Aug 2023 00:50:47 +0000 + 106 + +
+ + Het 538-nieuws van 02 uur + Het 538-nieuws van 02 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + d9bf3f76-7047-4466-895f-b061018a232f + d9bf3f76-7047-4466-895f-b061018a232f + Thu, 17 Aug 2023 23:55:27 +0000 + 105 + +
+ + Het 538-nieuws van 02 uur + Het 538-nieuws van 02 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 1563bc42-e4d4-4023-b387-b06101899147 + 1563bc42-e4d4-4023-b387-b06101899147 + Thu, 17 Aug 2023 23:53:18 +0000 + 107 + +
+ + Het 538-nieuws van 01 uur + Het 538-nieuws van 01 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + a3ac2355-8b62-42c8-ab8b-b061017832c8 + a3ac2355-8b62-42c8-ab8b-b061017832c8 + Thu, 17 Aug 2023 22:50:00 +0000 + 109 + +
+ + Het 538-nieuws van 00 uur + Het 538-nieuws van 00 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 091e36c2-a974-4e75-9546-b0610168674c + 091e36c2-a974-4e75-9546-b0610168674c + Thu, 17 Aug 2023 21:52:44 +0000 + 108 + +
+ + Het 538-nieuws van 23 uur + Het 538-nieuws van 23 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 4479ef54-859d-4f9c-9e26-b0610158682b + 4479ef54-859d-4f9c-9e26-b0610158682b + Thu, 17 Aug 2023 20:54:15 +0000 + 101 + +
+ + Het 538-nieuws van 23 uur + Het 538-nieuws van 23 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 7b4065e4-144b-442d-950f-b061015822f9 + 7b4065e4-144b-442d-950f-b061015822f9 + Thu, 17 Aug 2023 20:53:13 +0000 + 101 + +
+ + Het 538-nieuws van 22 uur + Het 538-nieuws van 22 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 07fe6543-b4b5-4f98-b883-b0610147cab6 + 07fe6543-b4b5-4f98-b883-b0610147cab6 + Thu, 17 Aug 2023 19:53:44 +0000 + 94 + +
+ + Het 538-nieuws van 21 uur + Het 538-nieuws van 21 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + b534679f-2e9f-42b4-b89f-b06101385c76 + b534679f-2e9f-42b4-b89f-b06101385c76 + Thu, 17 Aug 2023 18:57:31 +0000 + 94 + +
+ + Het 538-nieuws van 21 uur + Het 538-nieuws van 21 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 6f709b32-54ec-48dd-8338-b0610136f8a6 + 6f709b32-54ec-48dd-8338-b0610136f8a6 + Thu, 17 Aug 2023 18:52:30 +0000 + 92 + +
+ + Het 538-nieuws van 20 uur + Het 538-nieuws van 20 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 647463ae-741b-4c29-80b9-b061012624a0 + 647463ae-741b-4c29-80b9-b061012624a0 + Thu, 17 Aug 2023 17:51:14 +0000 + 91 + +
+ + Het 538-nieuws van 19 uur + Het 538-nieuws van 19 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + bfc5c09c-4673-4f7e-97b1-b06101165f6e + bfc5c09c-4673-4f7e-97b1-b06101165f6e + Thu, 17 Aug 2023 16:53:48 +0000 + 89 + +
+ + Het 538-nieuws van 19 uur + Het 538-nieuws van 19 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 131b9e12-5a08-431c-883a-b0610116146b + 131b9e12-5a08-431c-883a-b0610116146b + Thu, 17 Aug 2023 16:52:46 +0000 + 89 + +
+ + Het 538-nieuws van 18 uur + Het 538-nieuws van 18 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + d6804c91-7f48-48f1-a9b4-b06101058765 + d6804c91-7f48-48f1-a9b4-b06101058765 + Thu, 17 Aug 2023 15:52:31 +0000 + 89 + +
+ + Het 538-nieuws van 17 uur + Het 538-nieuws van 17 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 426662c9-a0d8-4184-b88e-b06100f54410 + 426662c9-a0d8-4184-b88e-b06100f54410 + Thu, 17 Aug 2023 14:53:16 +0000 + 86 + +
+ + Het 538-nieuws van 16 uur + Het 538-nieuws van 16 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 65d4e71d-1447-4ac5-8838-b06100e4a7a5 + 65d4e71d-1447-4ac5-8838-b06100e4a7a5 + Thu, 17 Aug 2023 13:52:48 +0000 + 96 + +
+ + Het 538-nieuws van 15 uur + Het 538-nieuws van 15 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 5f11a32a-6554-4e9b-9b0e-b06100d4acc6 + 5f11a32a-6554-4e9b-9b0e-b06100d4acc6 + Thu, 17 Aug 2023 12:54:40 +0000 + 93 + +
+ + Het 538-nieuws van 15 uur + Het 538-nieuws van 15 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + a6dee0a6-5191-42da-a50a-b06100d45582 + a6dee0a6-5191-42da-a50a-b06100d45582 + Thu, 17 Aug 2023 12:53:23 +0000 + 93 + +
+ + Het 538-nieuws van 14 uur + Het 538-nieuws van 14 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 226e16a0-6cd2-42da-bf29-b06100c14aad + 226e16a0-6cd2-42da-bf29-b06100c14aad + Thu, 17 Aug 2023 11:44:08 +0000 + 97 + +
+ + Het 538-nieuws van 13 uur + Het 538-nieuws van 13 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + fd38ccf6-ed96-41b3-b624-b06100b154db + fd38ccf6-ed96-41b3-b624-b06100b154db + Thu, 17 Aug 2023 10:46:01 +0000 + 98 + +
+ + Het 538-nieuws van 13 uur + Het 538-nieuws van 13 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + 8c7d349b-d993-440d-bc2a-b06100b1009c + 8c7d349b-d993-440d-bc2a-b06100b1009c + Thu, 17 Aug 2023 10:44:51 +0000 + 98 + +
+ + Het 538-nieuws van 12 uur + Het 538-nieuws van 12 uur + See omnystudio.com/listener for privacy information.

]]>
+ See omnystudio.com/listener for privacy information.

]]>
+ full + 538 Nieuws + + + + + + df65e876-7ed5-407d-8ce2-b06100a0aa9a + df65e876-7ed5-407d-8ce2-b06100a0aa9a + Thu, 17 Aug 2023 09:45:19 +0000 + 99 + +
+
+
diff --git a/tests/data/api_met_no_metalerts.json b/tests/data/api_met_no_metalerts.json new file mode 100644 index 0000000..5fbcc3f --- /dev/null +++ b/tests/data/api_met_no_metalerts.json @@ -0,0 +1,14 @@ +{ + "has_images": false, + "sensor_config": { + "name": "api_met_no_metalerts", + "feed_url": "https://api.met.no/weatherapi/metalerts/1.1/", + "inclusions": [ + "title", + "link", + "published", + "summary" + ] + }, + "download_date": "2023-08-18T09:22:14.164244+00:00" +} diff --git a/tests/data/api_met_no_metalerts.xml b/tests/data/api_met_no_metalerts.xml new file mode 100644 index 0000000..e699001 --- /dev/null +++ b/tests/data/api_met_no_metalerts.xml @@ -0,0 +1,29 @@ + + + + MET farevarsel + https://api.met.no + Farevarsler fra Meteorologisk institutt + no + Copyright The Norwegian Meteorological Institute, licensed under Norwegian license for public data (NLOD) and Creative Commons 4.0 BY + Fri, 18 Aug 2023 09:22:00 +0000 + Fri, 18 Aug 2023 09:22:00 +0000 + Met + XML::LibXML::Generator 0.1 + http://blogs.law.harvard.edu/tech/rss + + MET farevarsel + https://api.met.no + https://api.met.no/images/logo_2013_no.png + + + Kuling, gult nivå, Loppa - Slettnes fyr, 18 August 05:00 UTC til 18 August 10:00 UTC. + Update: Fredag morgen forbigående sørvest stiv kuling 15 m/s. + https://api.met.no/weatherapi/metalerts/1.1/?cap=2.49.0.1.578.0.230818043729845.1412 + post@met.no (The Norwegian Meteorological Institute) + Met + 2.49.0.1.578.0.230818043729845.1412 + Fri, 18 Aug 2023 04:37:29 +0000 + + + diff --git a/tests/data/buienradar_nl.json b/tests/data/buienradar_nl.json new file mode 100644 index 0000000..e3620fe --- /dev/null +++ b/tests/data/buienradar_nl.json @@ -0,0 +1,11 @@ +{ + "has_images": true, + "all_entries_have_images": false, + "has_unique_links": false, + "sensor_config": { + "name": "buienradar_nl", + "feed_url": "https://data.buienradar.nl/1.0/feed/xml/rssbuienradar", + "date_format": "%Y-%m-%d %H:%M:%S.%f" + }, + "download_date": "2023-08-18T09:22:14.164244+00:00" +} diff --git a/tests/data/buienradar_nl.xml b/tests/data/buienradar_nl.xml new file mode 100644 index 0000000..bdaaefe --- /dev/null +++ b/tests/data/buienradar_nl.xml @@ -0,0 +1,30 @@ + + + + Buienradar.nl weerbericht en actuele radar + https://www.buienradar.nl + Buienradar.nl weerbericht en actuele radar + nl-nl + Copyright 2005 - 2023 RTL. Alle rechten voorbehouden. + + Buienradar.nl weerbericht en actuele radar + https://www.buienradar.nl/nederland/weerbericht/weerbericht + http://www.buienradar.nl/images/logo2.jpg + 144 + 20 + + https://www.buienradar.nl/nederland/weerbericht/weerbericht + + Actueel weerbericht + Fri, 18 Aug 2023 07:30:00 +00:00 + https://www.buienradar.nl + + + + Actueel radarbeeld + Fri, 18 Aug 2023 09:20:00 +00:00 + https://www.buienradar.nl +

]]>
+
+
+
diff --git a/tests/data/skolmaten_se_ede_skola.json b/tests/data/skolmaten_se_ede_skola.json new file mode 100644 index 0000000..4840252 --- /dev/null +++ b/tests/data/skolmaten_se_ede_skola.json @@ -0,0 +1,15 @@ +{ + "has_images": false, + "has_unique_links": false, + "sensor_config": { + "name": "skolmaten_se_ede_skola", + "feed_url": "https://skolmaten.se/ede-skola/rss/weeks/?limit=2", + "inclusions": [ + "title", + "link", + "published", + "summary" + ] + }, + "download_date": "2023-08-18T09:22:14.164244+00:00" +} diff --git a/tests/data/skolmaten_se_ede_skola.xml b/tests/data/skolmaten_se_ede_skola.xml new file mode 100644 index 0000000..f60154a --- /dev/null +++ b/tests/data/skolmaten_se_ede_skola.xml @@ -0,0 +1 @@ +Skolmaten - Ede skolahttp://skolmaten.se/ede-skola/Skolmaten för Ede skola© skolmaten.sehttps://lh3.googleusercontent.com/HGCQ4huogidlTIKbeKp_Xr9U2Q-q0Oix2hfjYCeaxRI3_QfiTBL-VhUDCvD60uqiq0tdY6D8cbffkUZoNQSkolmaten - Ede skolahttp://skolmaten.se/ede-skola/Måndag - Vecka 34http://skolmaten.se/ede-skola/Skolrestaurangens val]]>Mon, 21 Aug 2023 00:00:00 GMTMon, 21 Aug 2023 00:00:00 GMTTisdag - Vecka 34http://skolmaten.se/ede-skola/Spagetti, köttfärssås]]>Tue, 22 Aug 2023 00:00:00 GMTTue, 22 Aug 2023 00:00:00 GMTOnsdag - Vecka 34http://skolmaten.se/ede-skola/Skolrestaurangens gröna val]]>Wed, 23 Aug 2023 00:00:00 GMTWed, 23 Aug 2023 00:00:00 GMTTorsdag - Vecka 34http://skolmaten.se/ede-skola/Örtbakad fisk, kall sås, potatis]]>Thu, 24 Aug 2023 00:00:00 GMTThu, 24 Aug 2023 00:00:00 GMTFredag - Vecka 34http://skolmaten.se/ede-skola/Skolrestaurangens val]]>Fri, 25 Aug 2023 00:00:00 GMTFri, 25 Aug 2023 00:00:00 GMT diff --git a/tests/feedsource.py b/tests/feedsource.py index ead1ce9..0e5e5a8 100644 --- a/tests/feedsource.py +++ b/tests/feedsource.py @@ -84,6 +84,26 @@ def has_images(self: "FeedSource") -> bool: """Return has_images.""" return self.metadata.get("has_images", False) + @property + def all_entries_have_images(self: "FeedSource") -> bool: + """Return all_entries_have_images.""" + return self.metadata.get("all_entries_have_images", True) + + @property + def has_unique_links(self: "FeedSource") -> bool: + """Return has_unique_links.""" + return self.metadata.get("has_unique_links", True) + + @property + def has_unique_titles(self: "FeedSource") -> bool: + """Return has_unique_titles.""" + return self.metadata.get("has_unique_titles", True) + + @property + def has_unique_images(self: "FeedSource") -> bool: + """Return has_unique_images.""" + return self.metadata.get("has_unique_images", True) + @property def _common_config(self: "FeedSource") -> dict[str, str | int | bool | list[str]]: """Return common config.""" diff --git a/tests/test_sensors.py b/tests/test_sensors.py index f34e47e..279e0c7 100644 --- a/tests/test_sensors.py +++ b/tests/test_sensors.py @@ -53,20 +53,27 @@ def test_update_sensor(feed: FeedSource) -> None: assert all(e["published"] for e in feed_sensor.feed_entries) # assert that all entries have non-default image - if feed.has_images: - assert all(e["image"] != DEFAULT_THUMBNAIL for e in feed_sensor.feed_entries) - else: - assert all(e["image"] == DEFAULT_THUMBNAIL for e in feed_sensor.feed_entries) + if feed.all_entries_have_images: + if feed.has_images: + assert all( + e["image"] != DEFAULT_THUMBNAIL for e in feed_sensor.feed_entries + ) + else: + assert all( + e["image"] == DEFAULT_THUMBNAIL for e in feed_sensor.feed_entries + ) # assert that all entries have a unique link - assert len({e["link"] for e in feed_sensor.feed_entries}) == len( - feed_sensor.feed_entries, - ), "Duplicate links found" + if feed.has_unique_links: + assert len({e["link"] for e in feed_sensor.feed_entries}) == len( + feed_sensor.feed_entries, + ), "Duplicate links found" # assert that all entries have a unique title - assert len({e["title"] for e in feed_sensor.feed_entries}) == len( - feed_sensor.feed_entries, - ), "Duplicate titles found" + if feed.has_unique_titles: + assert len({e["title"] for e in feed_sensor.feed_entries}) == len( + feed_sensor.feed_entries, + ), "Duplicate titles found" # assert that all entries have a unique published date assert len({e["published"] for e in feed_sensor.feed_entries}) == len( @@ -74,7 +81,7 @@ def test_update_sensor(feed: FeedSource) -> None: ), "Duplicate published dates found" # assert that all entries have a unique image - if feed.has_images: + if feed.has_images and feed.has_unique_images: assert len({e["image"] for e in feed_sensor.feed_entries}) == len( feed_sensor.feed_entries, ), "Duplicate images found" @@ -82,7 +89,7 @@ def test_update_sensor(feed: FeedSource) -> None: def test_update_sensor_with_topn(feed: FeedSource) -> None: """Test that the sensor stores only the topn entries.""" - show_topn = 3 + show_topn = 1 feed_sensor = FeedParserSensor( feed=feed.path.absolute().as_uri(), name=feed.name, @@ -134,6 +141,9 @@ def test_update_sensor_entries_time( feed.sensor_config.date_format, ) + if not first_sensor_entry_time.tzinfo: + first_sensor_entry_time = first_sensor_entry_time.replace(tzinfo=UTC) + # assert that the time of the first entry in the sensor is equal to # the time of the first entry in the feed assert first_entry_time == first_sensor_entry_time From 2c786ca670f826214a1870836767073ee0f4a179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Gajdu=C5=A1ek?= Date: Fri, 18 Aug 2023 11:45:46 +0200 Subject: [PATCH 2/2] Add debug log back --- custom_components/feedparser/sensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/feedparser/sensor.py b/custom_components/feedparser/sensor.py index b79ba30..b4259b2 100644 --- a/custom_components/feedparser/sensor.py +++ b/custom_components/feedparser/sensor.py @@ -187,6 +187,7 @@ def _generate_sensor_entry( and (processed_link := self._process_link(feed_entry)) ): sensor_entry["link"] = processed_link + _LOGGER.debug("Feed %s: Generated sensor entry: %s", self.name, sensor_entry) return sensor_entry def _parse_date(self: FeedParserSensor, date: str) -> datetime: