diff options
| -rw-r--r-- | app/Item.py | 10 | ||||
| -rw-r--r-- | plugins/DigestPlugin.py | 1 | ||||
| -rw-r--r-- | plugins/FacebookSourcePlugin.py | 1 | ||||
| -rw-r--r-- | plugins/FeedSinkPlugin.py | 32 | ||||
| -rw-r--r-- | plugins/FeedSourcePlugin.py | 13 | ||||
| -rw-r--r-- | plugins/ScraperSourcePlugin.py | 16 |
6 files changed, 67 insertions, 6 deletions
diff --git a/app/Item.py b/app/Item.py index a7af6ce..08411ea 100644 --- a/app/Item.py +++ b/app/Item.py @@ -1,5 +1,6 @@ from dataclasses import dataclass from datetime import datetime +from typing import Literal @dataclass @@ -20,6 +21,14 @@ class ItemGUID: @dataclass +class ItemMediaContent: + """RSS Item media:content object""" + + url: str + medium: Literal["video", "image"] + + +@dataclass class Item: """RSS Item""" @@ -32,3 +41,4 @@ class Item: comments: str | None enclosures: list[ItemEnclosure] guid: ItemGUID + media_content: ItemMediaContent | None diff --git a/plugins/DigestPlugin.py b/plugins/DigestPlugin.py index f1debeb..cf9a108 100644 --- a/plugins/DigestPlugin.py +++ b/plugins/DigestPlugin.py @@ -184,6 +184,7 @@ class Plugin(PluginInterface): comments=None, enclosures=[], guid=ItemGUID(f"aggro__{self.id}__{digest_pub_date.isoformat()}"), + media_content=None, ) digest_items.append(digest_item) diff --git a/plugins/FacebookSourcePlugin.py b/plugins/FacebookSourcePlugin.py index a8b6d58..8d9a8e4 100644 --- a/plugins/FacebookSourcePlugin.py +++ b/plugins/FacebookSourcePlugin.py @@ -192,6 +192,7 @@ def fetch_page_posts(email: str, password: str, page_id: str, limit: int) -> lis comments=None, enclosures=[], pub_date=pub_date, + media_content=None, ) items.append(item) diff --git a/plugins/FeedSinkPlugin.py b/plugins/FeedSinkPlugin.py index f126b6d..6785a28 100644 --- a/plugins/FeedSinkPlugin.py +++ b/plugins/FeedSinkPlugin.py @@ -20,16 +20,41 @@ class Plugin(PluginInterface): print(f"[FeedSinkPlugin#{self.id}] feed will be served at path /{self.feed_id}") def build_xml(self, items: list[Item]): - rss = ET.Element("rss", {"version": "2.0"}) + rss = ET.Element( + "rss", {"version": "2.0", "xmlns:media": "http://search.yahoo.com/mrss/"} + ) channel = ET.SubElement(rss, "channel") title = ET.SubElement(channel, "title") title.text = self.feed_title + if self.feed_link is not None: link = ET.SubElement(channel, "link") link.text = self.feed_link + favicon_url = f"https://www.google.com/s2/favicons?domain={self.feed_link}" + else: + favicon_url = None + description = ET.SubElement(channel, "description") description.text = self.feed_description + # TODO favicons + # <image> + # <link>https://www.aaniwalli.fi/</link> + # <url> + # https://www.google.com/s2/favicons?domain=https://www.aaniwalli.fi + # </url> + # <title>Ääniwalli</title> + # </image> + + if favicon_url is not None: + favicon_image_elem = ET.SubElement(channel, "image") + favicon_link_elem = ET.SubElement(favicon_image_elem, "link") + favicon_link_elem.text = self.feed_link + favicon_url_elem = ET.SubElement(favicon_image_elem, "url") + favicon_url_elem.text = favicon_url + favicon_title_elem = ET.SubElement(favicon_image_elem, "title") + favicon_title_elem.text = self.feed_title + for item in items: item_elem = ET.SubElement(channel, "item") if item.title is not None: @@ -63,6 +88,11 @@ class Plugin(PluginInterface): ) item_guid.text = item.guid.value + if item.media_content is not None: + item_media_content = ET.SubElement(item_elem, "media:content") + item_media_content.set("url", item.media_content.url) + item_media_content.set("medium", item.media_content.medium) + for enc in item.enclosures: ET.SubElement( item_elem, diff --git a/plugins/FeedSourcePlugin.py b/plugins/FeedSourcePlugin.py index 9eba538..01692b3 100644 --- a/plugins/FeedSourcePlugin.py +++ b/plugins/FeedSourcePlugin.py @@ -2,7 +2,7 @@ import feedparser # type: ignore import time from datetime import datetime, timezone from typing import Any -from app.Item import Item, ItemEnclosure, ItemGUID +from app.Item import Item, ItemEnclosure, ItemGUID, ItemMediaContent from app.PluginInterface import Params, PluginInterface from app.utils import ItemDict, get_config @@ -35,6 +35,15 @@ class Plugin(PluginInterface): f"[FeedSourcePlugin#{self.id}] malformed XML in feed {self.feed_url}" ) + if "image" in feed: + image_url = feed["image"]["href"] + media_content = ItemMediaContent( + url=image_url, + medium="image", + ) + else: + media_content = None + for _d in feed.entries: d: ItemDict = _d item_enclosures: list[ItemEnclosure] = [] @@ -57,6 +66,7 @@ class Plugin(PluginInterface): ) link: str = d["link"] # type: ignore + result_items.append( Item( title=d.get("title", None), # type: ignore @@ -68,6 +78,7 @@ class Plugin(PluginInterface): comments=d.get("comments"), # type: ignore enclosures=item_enclosures, guid=ItemGUID(link, is_perma_link=True), + media_content=media_content, ) ) diff --git a/plugins/ScraperSourcePlugin.py b/plugins/ScraperSourcePlugin.py index b51943b..e8d777a 100644 --- a/plugins/ScraperSourcePlugin.py +++ b/plugins/ScraperSourcePlugin.py @@ -4,7 +4,7 @@ from datetime import datetime, timezone from typing import Any import re import requests -from app.Item import Item, ItemEnclosure, ItemGUID +from app.Item import Item, ItemEnclosure, ItemGUID, ItemMediaContent from app.PluginInterface import Params, PluginInterface from app.utils import ItemDict, get_config, get_config_or_default @@ -158,12 +158,19 @@ class Plugin(PluginInterface): if image_src is not None: image_src = self.absolute_link(image_src) - image_html = f'<br><br><img src="{image_src}">' + image_html = f'<img src="{image_src}"><br><br>' if description: - description += image_html + description = image_html + description else: description = image_html + media_content = ItemMediaContent( + url=image_src, + medium="image", + ) + else: + media_content = None + if description: description = description.replace('src="/', f'src="{self.url}/') description = description.replace('href="/', f'href="{self.url}/') @@ -172,12 +179,13 @@ class Plugin(PluginInterface): title=f"{date} – {title}", link=detail_page_url, description=description, - pub_date=datetime.now(), + pub_date=None, # TODO pub_date parsing author=author, category=None, comments=None, enclosures=[], guid=guid, + media_content=media_content, ) result_items.append(item) |
