diff --git a/discord_rss_bot/custom_message.py b/discord_rss_bot/custom_message.py index b51d73c..1f1f01a 100644 --- a/discord_rss_bot/custom_message.py +++ b/discord_rss_bot/custom_message.py @@ -6,11 +6,12 @@ from discord_rss_bot.custom_filters import convert_to_md from discord_rss_bot.settings import get_reader -def get_images_from_string(string: str) -> tuple[str, list[str]]: - """Get images from a string. This will also remove the images from the string. +def get_images_from_entry(entry: Entry, summary: bool = False) -> list[str]: + """Get images from a entry. Args: - string: The string to get the images from. + entry: The entry to get the images from. + summary: Whether to get the images from the summary or the content. Returns: Returns a list of images. @@ -18,13 +19,9 @@ def get_images_from_string(string: str) -> tuple[str, list[str]]: # This regex will match any markdown image that follows the format of . image_regex = r"!\[(.*)\]\((.*)\)" - # Remove them from the string - new_string: str = re.sub(image_regex, "", string) - - # Get the images - images: list[str] = re.findall(image_regex, string) - - return new_string, images + if summary: + return re.findall(image_regex, convert_to_md(entry.summary)) if entry.summary else [] + return re.findall(image_regex, convert_to_md(entry.content[0].value)) if entry.content else [] def try_to_replace(custom_message: str, template: str, replace_with: str) -> str: @@ -49,7 +46,19 @@ def try_to_replace(custom_message: str, template: str, replace_with: str) -> str return custom_message -def replace_tags(feed: Feed, entry: Entry) -> tuple[str, list[str]]: +def remove_image_tags(message: str) -> str: + """Remove image tags from message. + + Args: + message: The message to remove the tags from. + + Returns: + Returns the message with the image tags removed. + """ + return re.sub(r"!\[(.*)\]\((.*)\)", "", message) + + +def replace_tags(feed: Feed, entry: Entry) -> str: """Replace tags in custom_message. Args: @@ -66,8 +75,17 @@ def replace_tags(feed: Feed, entry: Entry) -> tuple[str, list[str]]: content = "" if entry.summary: summary: str = entry.summary + summary = remove_image_tags(message=summary) + if entry.content: - content: str = entry.content[0]["value"] # type: ignore + for content_item in entry.content: + content: str = content_item.value + content = remove_image_tags(message=content) + + if images := get_images_from_entry(entry=entry): + first_image: str = images[0][1] + else: + first_image = "" list_of_replacements = [ {"{{feed_author}}": feed.author}, @@ -84,7 +102,7 @@ def replace_tags(feed: Feed, entry: Entry) -> tuple[str, list[str]]: {"{{feed_version}}": feed.version}, {"{{entry_added}}": entry.added}, {"{{entry_author}}": entry.author}, - {"{{entry_content}}": convert_to_md(content)}, + {"{{entry_content}}": content}, {"{{entry_content_raw}}": content}, {"{{entry_id}}": entry.id}, {"{{entry_important}}": str(entry.important)}, @@ -92,19 +110,18 @@ def replace_tags(feed: Feed, entry: Entry) -> tuple[str, list[str]]: {"{{entry_published}}": entry.published}, {"{{entry_read}}": str(entry.read)}, {"{{entry_read_modified}}": entry.read_modified}, - {"{{entry_summary}}": convert_to_md(summary)}, + {"{{entry_summary}}": summary}, {"{{entry_summary_raw}}": summary}, {"{{entry_title}}": entry.title}, {"{{entry_updated}}": entry.updated}, + {"{{image_1}}": first_image}, ] for replacement in list_of_replacements: for template, replace_with in replacement.items(): custom_message = try_to_replace(custom_message, template, replace_with) - custom_message, images = get_images_from_string(custom_message) - - return custom_message, images + return custom_message def get_custom_message(custom_reader: Reader, feed: Feed) -> str: diff --git a/discord_rss_bot/main.py b/discord_rss_bot/main.py index 3ab3a4b..299de62 100644 --- a/discord_rss_bot/main.py +++ b/discord_rss_bot/main.py @@ -13,7 +13,7 @@ from starlette.responses import RedirectResponse from discord_rss_bot import settings from discord_rss_bot.custom_filters import convert_to_md, encode_url, entry_is_blacklisted, entry_is_whitelisted -from discord_rss_bot.custom_message import get_custom_message +from discord_rss_bot.custom_message import get_custom_message, get_images_from_entry, remove_image_tags from discord_rss_bot.feeds import send_to_discord from discord_rss_bot.filter.blacklist import get_blacklist_content, get_blacklist_summary, get_blacklist_title from discord_rss_bot.filter.whitelist import get_whitelist_content, get_whitelist_summary, get_whitelist_title @@ -360,10 +360,10 @@ async def get_custom(feed_url, request: Request): # Get the first entry, this is used to show the user what the custom message will look like. entries: Iterable[Entry] = reader.get_entries(feed=feed, limit=1) + for entry in entries: # Append to context. context["entry"] = entry - return templates.TemplateResponse("custom.html", context) @@ -405,10 +405,58 @@ async def get_feed(feed_url, request: Request): # Get the entries in the feed. feed_counts: FeedCounts = reader.get_feed_counts(feed=url) - context = {"request": request, "feed": feed, "entries": entries, "feed_counts": feed_counts} + # Create the html for the entries. + html: str = create_html_for_feed(entries) + + context = {"request": request, "feed": feed, "entries": entries, "feed_counts": feed_counts, "html": html} return templates.TemplateResponse("feed.html", context) +def create_html_for_feed(entries: Iterable[Entry]) -> str: + """Create HTML for the search results. + + Args: + search_results: The search results. + custom_reader: The reader. If None, we will get the reader from the settings. + + Returns: + str: The HTML. + """ + html: str = "" + for entry in entries: + + # Get first image. + if images := get_images_from_entry(entry=entry): + first_image: str = images[0][1] + first_image_text: str = images[0][0] + else: + first_image = "" + first_image_text = "" + + if entry.summary: + summary: str = convert_to_md(entry.summary) + summary = remove_image_tags(message=summary) + text: str = f"<div class='text-muted'>{summary}</div>" + elif entry.content: + content: str = convert_to_md(entry.content[0].value) + content = remove_image_tags(message=content) + text = f"<div class='text-muted'>{content}</div>" + else: + text = "<div class='text-muted'>No content available.</div>" + + html += f""" + <div class="p-2 mb-2 border border-dark"> + <h2> + <a class="text-muted text-decoration-none" href="{entry.link}">{entry.title}</a> + </h2> + {f"By { entry.author } @" if entry.author else ""} + {text} + {f"<img src='{first_image}' class='img-fluid' alt='{first_image_text}'>" if first_image else ""} + </div> + """ + return html + + @app.get("/webhooks", response_class=HTMLResponse) async def get_webhooks(request: Request): """ diff --git a/discord_rss_bot/templates/custom.html b/discord_rss_bot/templates/custom.html index 6d32ace..91926b0 100644 --- a/discord_rss_bot/templates/custom.html +++ b/discord_rss_bot/templates/custom.html @@ -196,6 +196,14 @@ {% endraw %} </code>{{ entry.updated }} </li> + <br/> + <li> + <code> + {% raw %} + {{ image_1 }} + {% endraw %} + </code>First image in the entry if it exists + </li> </ul> <ul class="list-inline"> <li>Examples:</li> diff --git a/discord_rss_bot/templates/feed.html b/discord_rss_bot/templates/feed.html index bacb4fe..c956260 100644 --- a/discord_rss_bot/templates/feed.html +++ b/discord_rss_bot/templates/feed.html @@ -37,24 +37,6 @@ href="/blacklist?feed_url={{ feed.url|encode_url }}">Blacklist</a> <a class="text-muted" href="/custom?feed_url={{ feed.url|encode_url }}">Custom message</a> </div> - {% for entry in entries %} - <div class="p-2 mb-2 border border-dark"> - {% if entry|entry_is_blacklisted %}<span class="text-danger">Blacklisted</span>{% endif %} - {% if entry|entry_is_whitelisted %}<span class="text-success">Whitelisted</span>{% endif %} - <h2> - <a class="text-muted text-decoration-none" href="{{ entry.link }}">{{ entry.title }}</a> - </h2> - {% if entry.author %}By {{ entry.author }} @{% endif %} - {% if entry.published %} - {{ entry.published.strftime('%Y-%m-%d, %T') }} - {% endif %} - {% if entry.summary %} - <div class="text-muted">{{ entry.summary|discord_markdown }}</div> - {% elif entry.content[0].value %} - <div class="text-muted">{{ entry.content[0].value|discord_markdown }}</div> - {% else %} - <div class="text-muted">No content available.</div> - {% endif %} - </div> - {% endfor %} + {# HTML is created in main.create_html_for_feed #} + {{ html|safe }} {% endblock content %}