Add support for webhook embeds

This commit is contained in:
2023-01-22 23:00:03 +01:00
parent 4bc2a7dc6f
commit 269948303e
9 changed files with 804 additions and 42 deletions

View File

@ -1,3 +1,6 @@
import json
from dataclasses import dataclass
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from reader import Entry, Feed, Reader, TagNotFoundError from reader import Entry, Feed, Reader, TagNotFoundError
@ -5,6 +8,20 @@ from discord_rss_bot.markdown import convert_html_to_md
from discord_rss_bot.settings import get_reader from discord_rss_bot.settings import get_reader
@dataclass()
class CustomEmbed:
title: str
description: str
color: str
author_name: str
author_url: str
author_icon_url: str
image_url: str
thumbnail_url: str
footer_text: str
footer_icon_url: str
def get_images_from_entry(entry: Entry): def get_images_from_entry(entry: Entry):
"""Get images from a entry. """Get images from a entry.
@ -16,7 +33,7 @@ def get_images_from_entry(entry: Entry):
""" """
def return_image(found_images): def return_image(found_images):
soup: BeautifulSoup = BeautifulSoup(found_images, "html.parser") soup: BeautifulSoup = BeautifulSoup(found_images, features="lxml")
images = soup.find_all("img") images = soup.find_all("img")
for image in images: for image in images:
image_src = image["src"] or "" image_src = image["src"] or ""
@ -43,9 +60,8 @@ def try_to_replace(custom_message: str, template: str, replace_with: str) -> str
Args: Args:
custom_message: The custom_message to replace tags in. custom_message: The custom_message to replace tags in.
feed: The feed to get the tags from. template: The tag to replace.
entry: The entry to get the tags from. replace_with: What to replace the tag with.
tag: The tag to replace.
Returns: Returns:
Returns the custom_message with the tag replaced. Returns the custom_message with the tag replaced.
@ -56,7 +72,7 @@ def try_to_replace(custom_message: str, template: str, replace_with: str) -> str
return custom_message return custom_message
def replace_tags(feed: Feed, entry: Entry) -> str: def replace_tags_in_text_message(feed: Feed, entry: Entry) -> str:
"""Replace tags in custom_message. """Replace tags in custom_message.
Args: Args:
@ -122,6 +138,82 @@ def replace_tags(feed: Feed, entry: Entry) -> str:
return custom_message.replace("\\n", "\n") return custom_message.replace("\\n", "\n")
def replace_tags_in_embed(feed: Feed, entry: Entry) -> CustomEmbed:
"""Replace tags in embed.
Args:
feed: The feed to get the tags from.
entry: The entry to get the tags from.
Returns:
Returns the embed with the tags replaced.
"""
custom_reader: Reader = get_reader()
embed: CustomEmbed = get_embed(feed=feed, custom_reader=custom_reader)
summary = ""
content = ""
if entry.summary:
summary: str = entry.summary
summary = convert_html_to_md(summary)
if entry.content:
for content_item in entry.content:
content: str = content_item.value
content = convert_html_to_md(content)
if images := get_images_from_entry(entry=entry):
first_image: str = images[0][0]
else:
first_image = ""
list_of_replacements = [
{"{{feed_author}}": feed.author},
{"{{feed_added}}": feed.added},
{"{{feed_last_exception}}": feed.last_exception},
{"{{feed_last_updated}}": feed.last_updated},
{"{{feed_link}}": feed.link},
{"{{feed_subtitle}}": feed.subtitle},
{"{{feed_title}}": feed.title},
{"{{feed_updated}}": feed.updated},
{"{{feed_updates_enabled}}": str(feed.updates_enabled)},
{"{{feed_url}}": feed.url},
{"{{feed_user_title}}": feed.user_title},
{"{{feed_version}}": feed.version},
{"{{entry_added}}": entry.added},
{"{{entry_author}}": entry.author},
{"{{entry_content}}": content},
{"{{entry_content_raw}}": entry.content[0].value if entry.content else ""},
{"{{entry_id}}": entry.id},
{"{{entry_important}}": str(entry.important)},
{"{{entry_link}}": entry.link},
{"{{entry_published}}": entry.published},
{"{{entry_read}}": str(entry.read)},
{"{{entry_read_modified}}": entry.read_modified},
{"{{entry_summary}}": summary},
{"{{entry_summary_raw}}": entry.summary or ""},
{"{{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():
embed.title = try_to_replace(embed.title, template, replace_with)
embed.description = try_to_replace(embed.description, template, replace_with)
embed.color = try_to_replace(embed.color, template, replace_with)
embed.author_name = try_to_replace(embed.author_name, template, replace_with)
embed.author_url = try_to_replace(embed.author_url, template, replace_with)
embed.author_icon_url = try_to_replace(embed.author_icon_url, template, replace_with)
embed.image_url = try_to_replace(embed.image_url, template, replace_with)
embed.thumbnail_url = try_to_replace(embed.thumbnail_url, template, replace_with)
embed.footer_text = try_to_replace(embed.footer_text, template, replace_with)
embed.footer_icon_url = try_to_replace(embed.footer_icon_url, template, replace_with)
return embed
def get_custom_message(custom_reader: Reader, feed: Feed) -> str: def get_custom_message(custom_reader: Reader, feed: Feed) -> str:
"""Get custom_message tag from feed. """Get custom_message tag from feed.
@ -140,3 +232,102 @@ def get_custom_message(custom_reader: Reader, feed: Feed) -> str:
custom_message = "" custom_message = ""
return custom_message return custom_message
def save_embed(custom_reader: Reader, feed: Feed, embed: CustomEmbed) -> None:
"""Set embed tag in feed.
Args:
custom_reader: What Reader to use.
feed: The feed to set the tag in.
embed: The embed to set.
"""
embed_dict: dict[str, str] = {
"title": embed.title,
"description": embed.description,
"color": embed.color.replace("#", "").replace("0x", ""),
"author_name": embed.author_name,
"author_url": embed.author_url,
"author_icon_url": embed.author_icon_url,
"image_url": embed.image_url,
"thumbnail_url": embed.thumbnail_url,
"footer_text": embed.footer_text,
"footer_icon_url": embed.footer_icon_url,
}
custom_reader.set_tag(feed, "embed", json.dumps(embed_dict)) # type: ignore
def get_embed(custom_reader: Reader, feed: Feed) -> CustomEmbed:
"""Get embed tag from feed.
Args:
custom_reader: What Reader to use.
feed: The feed to get the tag from.
Returns:
Returns the contents from the embed tag.
"""
embed_json: dict[str, str] = {}
try:
embed: str = str(custom_reader.get_tag(feed, "embed"))
except TagNotFoundError:
embed = ""
except ValueError:
embed = ""
if embed:
try:
embed_json = json.loads(embed)
except json.decoder.JSONDecodeError:
embed_json = "" # type: ignore
if embed_json:
return get_embed_data(embed_json)
return CustomEmbed(
title="",
description="",
color="",
author_name="",
author_url="",
author_icon_url="",
image_url="",
thumbnail_url="",
footer_text="",
footer_icon_url="",
)
def get_embed_data(embed_data) -> CustomEmbed:
"""Get embed data from embed_data.
Args:
embed_data: The embed_data to get the data from.
Returns:
Returns the embed data.
"""
title: str = embed_data.get("title", "")
description: str = embed_data.get("description", "")
color: str = embed_data.get("color", "")
author_name: str = embed_data.get("author_name", "")
author_url: str = embed_data.get("author_url", "")
author_icon_url: str = embed_data.get("author_icon_url", "")
image_url: str = embed_data.get("image_url", "")
thumbnail_url: str = embed_data.get("thumbnail_url", "")
footer_text: str = embed_data.get("footer_text", "")
footer_icon_url: str = embed_data.get("footer_icon_url", "")
return CustomEmbed(
title=title,
description=description,
color=color,
author_name=author_name,
author_url=author_url,
author_icon_url=author_icon_url,
image_url=image_url,
thumbnail_url=thumbnail_url,
footer_text=footer_text,
footer_icon_url=footer_icon_url,
)

View File

@ -1,6 +1,6 @@
from typing import Iterable from typing import Iterable
from discord_webhook import DiscordWebhook from discord_webhook import DiscordEmbed, DiscordWebhook
from reader import Entry, Feed, Reader from reader import Entry, Feed, Reader
from requests import Response from requests import Response
@ -45,18 +45,61 @@ def send_entry_to_discord(entry: Entry, custom_reader: Reader | None = None):
# Try to get the custom message for the feed. If the user has none, we will use the default message. # Try to get the custom message for the feed. If the user has none, we will use the default message.
if custom_message.get_custom_message(reader, entry.feed) != "": if custom_message.get_custom_message(reader, entry.feed) != "":
webhook_message = custom_message.replace_tags(entry=entry, feed=entry.feed) # type: ignore webhook_message = custom_message.replace_tags_in_text_message(entry=entry, feed=entry.feed) # type: ignore
else: else:
webhook_message: str = default_custom_message webhook_message: str = default_custom_message
# Create the webhook. # Create the webhook.
webhook: DiscordWebhook = DiscordWebhook(url=webhook_url, content=webhook_message, rate_limit_retry=True) if bool(reader.get_tag(entry.feed, "should_send_embed")):
webhook = create_embed_webhook(webhook_url, entry)
else:
webhook: DiscordWebhook = DiscordWebhook(url=webhook_url, content=webhook_message, rate_limit_retry=True)
response: Response = webhook.execute() response: Response = webhook.execute()
if not response.ok: if not response.ok:
return f"Error sending entry to Discord: {response.text}" return f"Error sending entry to Discord: {response.text}"
def create_embed_webhook(webhook_url: str, entry: Entry) -> DiscordWebhook:
webhook: DiscordWebhook = DiscordWebhook(url=webhook_url, rate_limit_retry=True)
feed: Feed = entry.feed
# Get the embed data from the database.
custom_embed: custom_message.CustomEmbed = custom_message.replace_tags_in_embed(feed=feed, entry=entry)
discord_embed: DiscordEmbed = DiscordEmbed()
if custom_embed.title:
discord_embed.set_title(custom_embed.title)
if custom_embed.description:
discord_embed.set_description(custom_embed.description)
if custom_embed.color:
discord_embed.set_color(custom_embed.color)
if custom_embed.author_name and not custom_embed.author_url and not custom_embed.author_icon_url:
discord_embed.set_author(name=custom_embed.author_name)
if custom_embed.author_name and custom_embed.author_url and not custom_embed.author_icon_url:
discord_embed.set_author(name=custom_embed.author_name, url=custom_embed.author_url)
if custom_embed.author_name and not custom_embed.author_url and custom_embed.author_icon_url:
discord_embed.set_author(name=custom_embed.author_name, icon_url=custom_embed.author_icon_url)
if custom_embed.author_name and custom_embed.author_url and custom_embed.author_icon_url:
discord_embed.set_author(name=custom_embed.author_name, url=custom_embed.author_url, icon_url=custom_embed.author_icon_url) # noqa: E501
if custom_embed.thumbnail_url:
discord_embed.set_thumbnail(url=custom_embed.thumbnail_url)
if custom_embed.image_url:
discord_embed.set_image(url=custom_embed.image_url)
if custom_embed.footer_text:
discord_embed.set_footer(text=custom_embed.footer_text)
if custom_embed.footer_icon_url and custom_embed.footer_text:
discord_embed.set_footer(text=custom_embed.footer_text, icon_url=custom_embed.footer_icon_url)
if custom_embed.footer_icon_url and not custom_embed.footer_text:
# TODO: Can this be done without a text?
discord_embed.set_footer(icon_url=custom_embed.footer_icon_url)
webhook.add_embed(discord_embed)
return webhook
def send_to_discord(custom_reader: Reader | None = None, feed: Feed | None = None, do_once: bool = False) -> None: def send_to_discord(custom_reader: Reader | None = None, feed: Feed | None = None, do_once: bool = False) -> None:
""" """
Send entries to Discord. Send entries to Discord.
@ -93,15 +136,18 @@ def send_to_discord(custom_reader: Reader | None = None, feed: Feed | None = Non
if not webhook_url: if not webhook_url:
continue continue
# If the user has set the custom message to an empty string, we will use the default message, otherwise we will if bool(reader.get_tag(entry.feed, "should_send_embed")):
# use the custom message. webhook = create_embed_webhook(webhook_url, entry)
if custom_message.get_custom_message(reader, entry.feed) != "":
webhook_message = custom_message.replace_tags(entry=entry, feed=entry.feed) # type: ignore
else: else:
webhook_message: str = default_custom_message # If the user has set the custom message to an empty string, we will use the default message, otherwise we
# will use the custom message.
if custom_message.get_custom_message(reader, entry.feed) != "":
webhook_message = custom_message.replace_tags_in_text_message(entry=entry, feed=entry.feed)
else:
webhook_message: str = default_custom_message
# Create the webhook. # Create the webhook.
webhook: DiscordWebhook = DiscordWebhook(url=webhook_url, content=webhook_message, rate_limit_retry=True) webhook: DiscordWebhook = DiscordWebhook(url=webhook_url, content=webhook_message, rate_limit_retry=True)
# Check if the feed has a whitelist, and if it does, check if the entry is whitelisted. # Check if the feed has a whitelist, and if it does, check if the entry is whitelisted.
if feed is not None and has_white_tags(reader, feed): if feed is not None and has_white_tags(reader, feed):

View File

@ -13,11 +13,19 @@ from starlette.responses import RedirectResponse
from discord_rss_bot import settings from discord_rss_bot import settings
from discord_rss_bot.custom_filters import encode_url, entry_is_blacklisted, entry_is_whitelisted from discord_rss_bot.custom_filters import encode_url, entry_is_blacklisted, entry_is_whitelisted
from discord_rss_bot.custom_message import get_custom_message, get_images_from_entry, replace_tags from discord_rss_bot.custom_message import (
CustomEmbed,
get_custom_message,
get_embed,
get_images_from_entry,
replace_tags_in_text_message,
save_embed,
)
from discord_rss_bot.feeds import get_entry_from_id, send_entry_to_discord, send_to_discord from discord_rss_bot.feeds import get_entry_from_id, send_entry_to_discord, send_to_discord
from discord_rss_bot.filter.blacklist import get_blacklist_content, get_blacklist_summary, get_blacklist_title 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 from discord_rss_bot.filter.whitelist import get_whitelist_content, get_whitelist_summary, get_whitelist_title
from discord_rss_bot.markdown import convert_html_to_md from discord_rss_bot.markdown import convert_html_to_md
from discord_rss_bot.missing_tags import add_missing_tags
from discord_rss_bot.search import create_html_for_search_results from discord_rss_bot.search import create_html_for_search_results
from discord_rss_bot.settings import default_custom_message, get_reader, list_webhooks from discord_rss_bot.settings import default_custom_message, get_reader, list_webhooks
@ -367,6 +375,125 @@ async def get_custom(feed_url, request: Request):
return templates.TemplateResponse("custom.html", context) return templates.TemplateResponse("custom.html", context)
@app.get("/embed", response_class=HTMLResponse)
async def get_embed_page(feed_url, request: Request):
"""Get the custom message. This is used when sending the message to Discord.
Args:
feed_url: What feed we should get the custom message for.
request: The HTTP request.
Returns:
custom.html
"""
# Make feed_url a valid URL.
url: str = urllib.parse.unquote(feed_url)
feed: Feed = reader.get_feed(url)
# Get previous data, this is used when creating the form.
embed: CustomEmbed = get_embed(reader, feed)
context = {
"request": request,
"feed": feed,
"title": embed.title,
"description": embed.description,
"color": embed.color,
"image_url": embed.image_url,
"thumbnail_url": embed.thumbnail_url,
"author_name": embed.author_name,
"author_url": embed.author_url,
"author_icon_url": embed.author_icon_url,
"footer_text": embed.footer_text,
"footer_icon_url": embed.footer_icon_url,
}
# 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)
if custom_embed := get_embed(reader, feed_url):
context["custom_embed"] = custom_embed
for entry in entries:
# Append to context.
context["entry"] = entry
return templates.TemplateResponse("embed.html", context)
@app.post("/embed", response_class=HTMLResponse)
async def set_embed_page(
feed_url=Form(),
title=Form(""),
description=Form(""),
color=Form(""),
image_url=Form(""),
thumbnail_url=Form(""),
author_name=Form(""),
author_url=Form(""),
author_icon_url=Form(""),
footer_text=Form(""),
footer_icon_url=Form(""),
):
"""Set the embed settings.
Args:
feed_url: What feed we should get the custom message for.
request: The HTTP request.
Returns:
custom.html
"""
# Make feed_url a valid URL.
url: str = urllib.parse.unquote(feed_url)
feed: Feed = reader.get_feed(url)
custom_embed: CustomEmbed = get_embed(reader, feed)
# Get the data from the form.
custom_embed.title = title
custom_embed.description = description
custom_embed.color = color
custom_embed.image_url = image_url
custom_embed.thumbnail_url = thumbnail_url
custom_embed.author_name = author_name
custom_embed.author_url = author_url
custom_embed.author_icon_url = author_icon_url
custom_embed.footer_text = footer_text
custom_embed.footer_icon_url = footer_icon_url
# Save the data.
save_embed(reader, feed_url, custom_embed)
# Clean URL is used to redirect to the feed page.
clean_url: str = urllib.parse.quote(feed_url)
return RedirectResponse(url=f"/feed/?feed_url={clean_url}", status_code=303)
@app.post("/use_embed")
async def set_should_use_embed(feed_url=Form()):
url: str = urllib.parse.unquote(feed_url)
print(f"Setting should_send_embed to True for {url}")
feed: Feed = reader.get_feed(url)
reader.set_tag(feed, "should_send_embed", True) # type: ignore
return RedirectResponse(url=f"/feed/?feed_url={feed_url}", status_code=303)
@app.post("/use_text")
async def set_should_use_text(feed_url=Form()):
url: str = urllib.parse.unquote(feed_url)
print(f"Setting should_send_embed to False for {url}")
feed: Feed = reader.get_feed(url)
reader.set_tag(feed, "should_send_embed", False) # type: ignore
return RedirectResponse(url=f"/feed/?feed_url={feed_url}", status_code=303)
@app.get("/add", response_class=HTMLResponse) @app.get("/add", response_class=HTMLResponse)
def get_add(request: Request): def get_add(request: Request):
""" """
@ -408,7 +535,16 @@ async def get_feed(feed_url, request: Request):
# Create the html for the entries. # Create the html for the entries.
html: str = create_html_for_feed(entries) html: str = create_html_for_feed(entries)
context = {"request": request, "feed": feed, "entries": entries, "feed_counts": feed_counts, "html": html} should_send_embed: bool = bool(reader.get_tag(feed, "should_send_embed"))
context = {
"request": request,
"feed": feed,
"entries": entries,
"feed_counts": feed_counts,
"html": html,
"should_send_embed": should_send_embed,
}
return templates.TemplateResponse("feed.html", context) return templates.TemplateResponse("feed.html", context)
@ -433,7 +569,7 @@ def create_html_for_feed(entries: Iterable[Entry]) -> str:
first_image_text: str = images[0][1] first_image_text: str = images[0][1]
# Get the text from the entry. # Get the text from the entry.
text = replace_tags(entry.feed, entry) text = replace_tags_in_text_message(entry.feed, entry)
if not text: if not text:
text = "<div class='text-muted'>No content available.</div>" text = "<div class='text-muted'>No content available.</div>"
@ -611,23 +747,7 @@ def startup() -> None:
"""This is called when the server starts. """This is called when the server starts.
It reads the settings file and starts the scheduler.""" It reads the settings file and starts the scheduler."""
# Add default feed message if it doesn't exist. add_missing_tags(reader=reader)
# This was added in version 0.2.0.
for feed in reader.get_feeds():
try:
reader.get_tag(feed, "custom_message")
except TagNotFoundError:
reader.set_tag(feed.url, "custom_message", default_custom_message) # type: ignore
reader.set_tag(feed.url, "has_custom_message", True) # type: ignore
# Add has_custom_message tag if it doesn't exist.
try:
reader.get_tag(feed, "has_custom_message")
except TagNotFoundError:
if reader.get_tag(feed, "custom_message") == default_custom_message:
reader.set_tag(feed.url, "has_custom_message", False) # type: ignore
else:
reader.set_tag(feed.url, "has_custom_message", True) # type: ignore
scheduler: BackgroundScheduler = BackgroundScheduler() scheduler: BackgroundScheduler = BackgroundScheduler()

View File

@ -0,0 +1,76 @@
from reader import Feed, Reader, TagNotFoundError
from discord_rss_bot.settings import default_custom_embed, default_custom_message
def add_custom_message(reader: Reader, feed: Feed) -> None:
try:
reader.get_tag(feed, "custom_message")
except TagNotFoundError:
print(f"Adding custom_message tag to '{feed.url}'")
reader.set_tag(feed.url, "custom_message", default_custom_message) # type: ignore
reader.set_tag(feed.url, "has_custom_message", True) # type: ignore
def add_has_custom_message(reader: Reader, feed: Feed) -> None:
try:
reader.get_tag(feed, "has_custom_message")
except TagNotFoundError:
if reader.get_tag(feed, "custom_message") == default_custom_message:
print(f"Setting has_custom_message tag to False for '{feed.url}'")
reader.set_tag(feed.url, "has_custom_message", False) # type: ignore
else:
print(f"Setting has_custom_message tag to True for '{feed.url}'")
reader.set_tag(feed.url, "has_custom_message", True) # type: ignore
def add_if_embed(reader: Reader, feed: Feed) -> None:
try:
reader.get_tag(feed, "if_embed")
except TagNotFoundError:
print(f"Setting if_embed tag to True for '{feed.url}'")
reader.set_tag(feed.url, "if_embed", True) # type: ignore
def add_custom_embed(reader: Reader, feed: Feed) -> None:
try:
reader.get_tag(feed, "embed")
except TagNotFoundError:
print(f"Setting embed tag to default for '{feed.url}'")
reader.set_tag(feed.url, "embed", default_custom_embed) # type: ignore
reader.set_tag(feed.url, "has_custom_embed", True) # type: ignore
def add_has_custom_embed(reader: Reader, feed: Feed) -> None:
try:
reader.get_tag(feed, "has_custom_embed")
except TagNotFoundError:
if reader.get_tag(feed, "embed") == default_custom_embed:
print(f"Setting has_custom_embed tag to False for '{feed.url}'")
reader.set_tag(feed.url, "has_custom_embed", False) # type: ignore
else:
print(f"Setting has_custom_embed tag to True for '{feed.url}'")
reader.set_tag(feed.url, "has_custom_embed", True) # type: ignore
def add_should_send_embed(reader: Reader, feed: Feed) -> None:
try:
reader.get_tag(feed, "should_send_embed")
except TagNotFoundError:
print(f"Setting should_send_embed tag to True for '{feed.url}'")
reader.set_tag(feed.url, "should_send_embed", True) # type: ignore
def add_missing_tags(reader: Reader) -> None:
"""Add missing tags to feeds.
Args:
reader: What Reader to use.
"""
for feed in reader.get_feeds():
add_custom_message(reader, feed)
add_has_custom_message(reader, feed)
add_if_embed(reader, feed)
add_custom_embed(reader, feed)
add_has_custom_embed(reader, feed)
add_should_send_embed(reader, feed)

View File

@ -6,9 +6,7 @@ from reader import EntrySearchResult, Feed, HighlightedString, Reader
from discord_rss_bot.settings import get_reader from discord_rss_bot.settings import get_reader
def create_html_for_search_results( def create_html_for_search_results(search_results: Iterable[EntrySearchResult], custom_reader: Reader | None = None) -> str:
search_results: Iterable[EntrySearchResult], custom_reader: Reader | None = None
) -> str:
"""Create HTML for the search results. """Create HTML for the search results.
Args: Args:

View File

@ -7,7 +7,15 @@ from reader import Entry, Reader, TagNotFoundError, make_reader # type: ignore
data_dir: str = user_data_dir(appname="discord_rss_bot", appauthor="TheLovinator", roaming=True) data_dir: str = user_data_dir(appname="discord_rss_bot", appauthor="TheLovinator", roaming=True)
os.makedirs(data_dir, exist_ok=True) os.makedirs(data_dir, exist_ok=True)
# TODO: Add default things to the database and make the edible.
default_custom_message: str = "{{entry_title}}\n{{entry_link}}" default_custom_message: str = "{{entry_title}}\n{{entry_link}}"
default_custom_embed = {
"title": "{{entry_title}}",
"description": "{{entry_content}}",
"url": "{{entry_link}}",
"image": "{{entry_image}}",
"color": 0x008080,
}
def get_webhook_for_entry(custom_reader: Reader, entry: Entry) -> str: def get_webhook_for_entry(custom_reader: Reader, entry: Entry) -> str:

View File

@ -236,9 +236,9 @@
type="text" type="text"
class="form-control bg-dark border-dark text-muted" class="form-control bg-dark border-dark text-muted"
id="custom_message" id="custom_message"
value="{% if custom_message %} {% if custom_message %}
{{- custom_message -}} value="{{- custom_message -}}"
{% endif %}"/> {% endif %}/>
</div> </div>
</div> </div>
<!-- Add a hidden feed_url field to the form --> <!-- Add a hidden feed_url field to the form -->

View File

@ -0,0 +1,301 @@
{% extends "base.html" %}
{% block title %}
| Embed
{% endblock title %}
{% block content %}
<div class="p-2 border border-dark">
<form action="/embed" method="post">
<div class="row pb-2">
<div class="col-sm-12">
<div class="form-text">
<ul class="list-inline">
<br/>
<li>
<code>
{% raw %}
{{feed_author}}
{% endraw %}
</code>{{feed.author}}
</li>
<li>
<code>
{% raw %}
{{feed_added}}
{% endraw %}
</code>{{feed.added}}
</li>
<li>
<code>
{% raw %}
{{feed_last_exception}}
{% endraw %}
</code>{{feed.last_exception}}
</li>
<li>
<code>
{% raw %}
{{feed_last_updated}}
{% endraw %}
</code>{{feed.last_updated}}
</li>
<li>
<code>
{% raw %}
{{feed_link}}
{% endraw %}
</code>{{feed.link}}
</li>
<li>
<code>
{% raw %}
{{feed_subtitle}}
{% endraw %}
</code>{{feed.subtitle}}
</li>
<li>
<code>
{% raw %}
{{feed_title}}
{% endraw %}
</code>{{feed.title}}
</li>
<li>
<code>
{% raw %}
{{feed_updated}}
{% endraw %}
</code>{{feed.updated}}
</li>
<li>
<code>
{% raw %}
{{feed_updates_enabled}}
{% endraw %}
</code>{{feed.updates_enabled}}
</li>
<li>
<code>
{% raw %}
{{feed_url}}
{% endraw %}
</code>{{feed.url}}
</li>
<li>
<code>
{% raw %}
{{feed_user_title}}
{% endraw %}
</code>{{feed.user_title}}
</li>
<li>
<code>
{% raw %}
{{feed_version}}
{% endraw %}
</code>{{feed.version}}
</li>
<br/>
{% if entry %}
<li>
<code>
{% raw %}
{{entry_added}}
{% endraw %}
</code>{{entry.added}}
</li>
<li>
<code>
{% raw %}
{{entry_author}}
{% endraw %}
</code>{{entry.author}}
</li>
<li>
<code>
{% raw %}
{{entry_content}}
{% endraw %}
</code>{{entry.content[0].value|discord_markdown}}
</li>
<li>
<code>
{% raw %}
{{entry_content_raw}}
{% endraw %}
</code>{{entry.content[0].value}}
</li>
<li>
<code>
{% raw %}
{{entry_id}}
{% endraw %}
</code>{{entry.id}}
</li>
<li>
<code>
{% raw %}
{{entry_important}}
{% endraw %}
</code>{{entry.important}}
</li>
<li>
<code>
{% raw %}
{{entry_link}}
{% endraw %}
</code>{{entry.link}}
</li>
<li>
<code>
{% raw %}
{{entry_published}}
{% endraw %}
</code>{{entry.published}}
</li>
<li>
<code>
{% raw %}
{{entry_read}}
{% endraw %}
</code>{{entry.read}}
</li>
<li>
<code>
{% raw %}
{{entry_read_modified}}
{% endraw %}
</code>{{entry.read_modified}}
</li>
<li>
<code>
{% raw %}
{{entry_summary}}
{% endraw %}
</code>{{entry.summary|discord_markdown}}
</li>
<li>
<code>
{% raw %}
{{entry_summary_raw}}
{% endraw %}
</code>{{entry.summary}}
</li>
<li>
<code>
{% raw %}
{{entry_title}}
{% endraw %}
</code>{{entry.title}}
</li>
<li>
<code>
{% raw %}
{{entry_updated}}
{% endraw %}
</code>{{entry.updated}}
</li>
<br/>
<li>
<code>
{% raw %}
{{image_1}}
{% endraw %}
</code>First image in the entry if it exists
</li>
</ul>
{% else %}
Something went wrong, there was no entry found. If this feed has entries and you still see this message, please contact the developer.
{% endif %}
</div>
<label for="title" class="col-sm-6 col-form-label">Title</label>
<input name="title"
type="text"
class="form-control bg-dark border-dark text-muted"
id="title"
{% if title %}
value="{{- title -}}"
{% endif %}/>
<label for="description" class="col-sm-6 col-form-label">Description</label>
<input name="description"
type="text"
class="form-control bg-dark border-dark text-muted"
id="description"
{% if description %}
value="{{- description -}}"
{% endif %}/>
<label for="color" class="col-sm-6 col-form-label">Embed color</label>
<input name="color"
type="color"
class="form-control form-control-color bg-dark border-dark text-muted"
id="color"
{% if color %}
value="{{- color -}}"
{% endif %}/>
<label for="author_name" class="col-sm-6 col-form-label">Author name</label>
<input name="author_name"
type="text"
class="form-control bg-dark border-dark text-muted"
id="author_name"
{% if author_name %}
value="{{- author_name -}}"
{% endif %}/>
<label for="author_url" class="col-sm-6 col-form-label">Author URL</label>
<input name="author_url"
type="text"
class="form-control bg-dark border-dark text-muted"
id="author_url"
{% if author_url %}
value="{{- author_url -}}"
{% endif %}/>
<label for="author_icon_url" class="col-sm-6 col-form-label">Author icon URL</label>
<input name="author_icon_url"
type="text"
class="form-control bg-dark border-dark text-muted"
id="author_icon_url"
{% if author_icon_url %}
value="{{- author_icon_url -}}"
{% endif %}/>
<label for="image_url" class="col-sm-6 col-form-label">Image URL - Add {% raw %}{{image_1}}{% endraw %} for first image</label>
<input name="image_url"
type="text"
class="form-control bg-dark border-dark text-muted"
id="image_url"
{% if image_url %}
value="{{- image_url -}}"
{% endif %}/>
<label for="thumbnail_url" class="col-sm-6 col-form-label">Thumbnail</label>
<input name="thumbnail_url"
type="text"
class="form-control bg-dark border-dark text-muted"
id="thumbnail_url"
{% if thumbnail_url %}
value="{{- thumbnail_url -}}"
{% endif %}/>
<label for="footer_text" class="col-sm-6 col-form-label">Footer text</label>
<input name="footer_text"
type="text"
class="form-control bg-dark border-dark text-muted"
id="footer_text"
{% if footer_text %}
value="{{- footer_text -}}"
{% endif %}/>
<label for="footer_icon_url" class="col-sm-6 col-form-label">Footer icon</label>
<input name="footer_icon_url"
type="text"
class="form-control bg-dark border-dark text-muted"
id="footer_icon_url"
{% if footer_icon_url %}
value="{{- footer_icon_url -}}"
{% endif %}/>
</div>
</div>
<!-- Add a hidden feed_url field to the form -->
<input type="hidden" name="feed_url" value="{{ feed.url }}"/>
<!-- Submit button -->
<div class="d-md-flex">
<button class="btn btn-dark btn-sm">Update embed</button>
</div>
</form>
</div>
{% endblock content %}

View File

@ -31,11 +31,33 @@
<button class="btn btn-danger btn-sm" name="feed_url" value="{{ feed.url }}">Pause</button> <button class="btn btn-danger btn-sm" name="feed_url" value="{{ feed.url }}">Pause</button>
</form> </form>
{% endif %} {% endif %}
{% if should_send_embed == True %}
<form action="/use_text" method="post">
<button class="btn btn-dark btn-sm" name="feed_url" value="{{ feed.url }}">
Send text messages instead of embeds
</button>
</form>
{% else %}
<form action="/use_embed" method="post">
<button class="btn btn-dark btn-sm" name="feed_url" value="{{ feed.url }}">
Send embeds instead of text messages
</button>
</form>
{% endif %}
<a class="text-muted" <a class="text-muted"
href="/whitelist?feed_url={{ feed.url|encode_url }}">Whitelist</a> href="/whitelist?feed_url={{ feed.url|encode_url }}">Whitelist</a>
<br/>
<a class="text-muted" <a class="text-muted"
href="/blacklist?feed_url={{ feed.url|encode_url }}">Blacklist</a> 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> <br/>
<a class="text-muted" href="/custom?feed_url={{ feed.url|encode_url }}">Customize message
{% if not should_send_embed %}(Active){% endif %}
</a>
<br/>
<a class="text-muted" href="/embed?feed_url={{ feed.url|encode_url }}">Customize embed
{% if should_send_embed %}(Active){% endif %}
</a>
<br/>
</div> </div>
{# HTML is created in main.create_html_for_feed #} {# HTML is created in main.create_html_for_feed #}
<pre> <pre>