You can now customize the message sent to Discord

This commit is contained in:
2023-01-13 23:05:20 +01:00
parent eec71c65a6
commit 16319ed5e1
5 changed files with 234 additions and 3 deletions

View File

@ -0,0 +1,95 @@
from reader import Entry, Feed, Reader, TagNotFoundError
from discord_rss_bot.settings import get_reader
def try_to_replace(custom_message: str, template: str, replace_with: str) -> str:
"""Try to replace a tag in custom_message.
Args:
custom_message: The custom_message to replace tags in.
feed: The feed to get the tags from.
entry: The entry to get the tags from.
tag: The tag to replace.
Returns:
Returns the custom_message with the tag replaced.
"""
if not template:
return custom_message
if not replace_with:
return custom_message
try:
print(f"custom_message: {custom_message}")
print(f"template: {template}")
print(f"replace_with: {replace_with}")
return custom_message.replace(template, replace_with)
except TypeError:
return custom_message
def replace_tags(feed: Feed, entry: Entry) -> str:
"""Replace tags in custom_message.
Args:
feed: The feed to get the tags from.
entry: The entry to get the tags from.
Returns:
Returns the custom_message with the tags replaced.
"""
custom_reader: Reader = get_reader()
custom_message: str = get_custom_message(feed=feed, custom_reader=custom_reader)
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}}": entry.content},
{"{{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}}": entry.summary},
{"{{entry_title}}": entry.title},
{"{{entry_updated}}": entry.updated},
]
for replacement in list_of_replacements:
for template, replace_with in replacement.items():
custom_message: str = try_to_replace(custom_message, template, replace_with)
print(f"custom_message: {custom_message}")
return custom_message
def get_custom_message(custom_reader: Reader, feed: Feed) -> str:
"""Get custom_message tag from feed.
Args:
custom_reader: What Reader to use.
feed: The feed to get the tag from.
Returns:
Returns the contents from the custom_message tag.
"""
try:
custom_message: str = custom_reader.get_tag(feed, "custom_message") # type: ignore
except TagNotFoundError:
custom_message: str = ""
except ValueError:
custom_message: str = ""
return custom_message

View File

@ -4,10 +4,10 @@ from discord_webhook import DiscordWebhook
from reader import Entry, Feed, Reader from reader import Entry, Feed, Reader
from requests import Response from requests import Response
from discord_rss_bot import settings from discord_rss_bot import custom_message, settings
from discord_rss_bot.filter.blacklist import should_be_skipped from discord_rss_bot.filter.blacklist import should_be_skipped
from discord_rss_bot.settings import get_reader
from discord_rss_bot.filter.whitelist import has_white_tags, should_be_sent from discord_rss_bot.filter.whitelist import has_white_tags, should_be_sent
from discord_rss_bot.settings import get_reader
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:
@ -50,6 +50,11 @@ def send_to_discord(custom_reader: Reader | None = None, feed: Feed | None = Non
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)
if custom_message.get_custom_message(reader, entry.feed) != "":
print("Custom message found, replacing tags.")
webhook.content = custom_message.replace_tags(entry=entry, feed=entry.feed)
print(f"Webhook content: {webhook.content}")
if feed is not None and has_white_tags(reader, feed): if feed is not None and has_white_tags(reader, feed):
# Only send the entry if it is whitelisted, otherwise, mark it as read and continue. # Only send the entry if it is whitelisted, otherwise, mark it as read and continue.
if should_be_sent(reader, entry): if should_be_sent(reader, entry):

View File

@ -12,6 +12,7 @@ from reader import Entry, EntryCounts, EntrySearchCounts, EntrySearchResult, Fee
from starlette.responses import RedirectResponse from starlette.responses import RedirectResponse
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
from discord_rss_bot.feeds import send_to_discord 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.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
@ -115,6 +116,8 @@ async def create_feed(feed_url: str = Form(), webhook_dropdown: str = Form()):
""" """
clean_feed_url: str = feed_url.strip() clean_feed_url: str = feed_url.strip()
# TODO: Check if the feed is valid, if not return an error or fix it.
# For example, if the feed is missing the protocol, add it.
reader.add_feed(clean_feed_url) reader.add_feed(clean_feed_url)
reader.update_feed(clean_feed_url) reader.update_feed(clean_feed_url)
@ -304,6 +307,62 @@ async def get_blacklist(feed_url: str, request: Request):
return templates.TemplateResponse("blacklist.html", context) # type: ignore return templates.TemplateResponse("blacklist.html", context) # type: ignore
@app.post("/custom")
async def set_custom(custom_message: str = Form(""), feed_url: str = Form()):
"""
Set the custom message, this is used when sending the message.
Args:
custom_message: The custom message.
feed_url: The feed we should set the custom message for.
Returns:
Redirect to the feed.
"""
# Add the custom_message to the feed.
if custom_message:
reader.set_tag(feed_url, "custom_message", custom_message)
print(f"Set custom message for {feed_url} to {custom_message}")
else:
print(f"Removing custom message for {feed_url}")
reader.delete_tag(feed_url, "custom_message", missing_ok=True)
# 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.get("/custom", response_class=HTMLResponse)
async def get_custom(feed_url: str, 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.
custom_message: str = get_custom_message(reader, feed)
# Get the first entry, this is used to show the user what the custom message will look like.
first_entry: Entry = reader.get_entries(feed=feed, limit=1)
for entry in first_entry:
first_entry = entry
context = {"request": request, "feed": feed, "custom_message": custom_message, "entry": first_entry}
return templates.TemplateResponse("custom.html", context) # type: ignore
@app.get("/add", response_class=HTMLResponse) @app.get("/add", response_class=HTMLResponse)
def get_add(request: Request): def get_add(request: Request):
""" """

View File

@ -0,0 +1,70 @@
{% extends "base.html" %}(
{% block title %} | Custom message{% endblock %}
{% block content %}
<div class="p-2 border border-dark">
<form action="/custom" method="post">
<!-- Feed URL -->
<div class="row pb-2">
<div class="col-sm-12">
<div class="form-text">
<ul class="list-inline">
<li>You can modify the message that is sent to Discord.</li>
<br>
<li><code>{% raw %}{{feed_url}}{% endraw %}</code> will be replaced with the feed URL. You can use <code>\n</code> for new lines.</li>
<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>
<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}}</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}}</li>
<li><code>{% raw %}{{entry_title}}{% endraw %}</code> - {{entry.title}}</li>
<li><code>{% raw %}{{entry_updated}}{% endraw %}</code> - {{entry.updated}}</li>
</ul>
<ul class="list-inline">
<li>Examples:</li>
<li><code>{% raw %}Hello {{entry_author}}\n{{feed_title}}\n{{entry_read}}{% endraw %}</code></li>
<br>
<li>Will become:</li>
<li><code style="white-space: pre-line">
Hello {{entry.author}}
{{feed.title}}
{{entry.read}}
</code></li>
</ul>
</div>
<label for="custom_message" class="col-sm-6 col-form-label">Message</label>
<input name="custom_message" type="text" class="form-control bg-dark border-dark text-muted"
id="custom_message" value="{% if custom_message %}{{ custom_message }}{% 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 message</button>
</div>
</form>
</div>
{% endblock %}

View File

@ -26,6 +26,7 @@
{% endif %} {% endif %}
<a class="text-muted" href="/whitelist?feed_url={{ feed.url|encode_url }}">Whitelist</a> <a class="text-muted" href="/whitelist?feed_url={{ feed.url|encode_url }}">Whitelist</a>
<a class="text-muted" href="/blacklist?feed_url={{ feed.url|encode_url }}">Blacklist</a> <a class="text-muted" 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> </div>
{% for entry in entries %} {% for entry in entries %}
@ -46,7 +47,8 @@
{% if entry.published %} {% if entry.published %}
@ {{ entry.published.strftime('%Y-%m-%d, %T') }} @ {{ entry.published.strftime('%Y-%m-%d, %T') }}
{% endif %} {% endif %}
{# TODO: Only show one if both are the same #}
{% if entry.summary %} {% if entry.summary %}
<details> <details>
<summary>Summary</summary> <summary>Summary</summary>