Add button to send entry to Discord
This commit is contained in:
@ -75,11 +75,13 @@ def replace_tags(feed: Feed, entry: Entry) -> str:
|
||||
content = ""
|
||||
if entry.summary:
|
||||
summary: str = entry.summary
|
||||
summary = convert_to_md(summary)
|
||||
summary = remove_image_tags(message=summary)
|
||||
|
||||
if entry.content:
|
||||
for content_item in entry.content:
|
||||
content: str = content_item.value
|
||||
content = convert_to_md(content)
|
||||
content = remove_image_tags(message=content)
|
||||
|
||||
if images := get_images_from_entry(entry=entry):
|
||||
@ -103,7 +105,7 @@ def replace_tags(feed: Feed, entry: Entry) -> str:
|
||||
{"{{entry_added}}": entry.added},
|
||||
{"{{entry_author}}": entry.author},
|
||||
{"{{entry_content}}": content},
|
||||
{"{{entry_content_raw}}": 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},
|
||||
@ -111,7 +113,7 @@ def replace_tags(feed: Feed, entry: Entry) -> str:
|
||||
{"{{entry_read}}": str(entry.read)},
|
||||
{"{{entry_read_modified}}": entry.read_modified},
|
||||
{"{{entry_summary}}": summary},
|
||||
{"{{entry_summary_raw}}": summary},
|
||||
{"{{entry_summary_raw}}": entry.summary if entry.summary else ""},
|
||||
{"{{entry_title}}": entry.title},
|
||||
{"{{entry_updated}}": entry.updated},
|
||||
{"{{image_1}}": first_image},
|
||||
@ -121,7 +123,10 @@ def replace_tags(feed: Feed, entry: Entry) -> str:
|
||||
for template, replace_with in replacement.items():
|
||||
custom_message = try_to_replace(custom_message, template, replace_with)
|
||||
|
||||
return custom_message
|
||||
# Replace \\n with newlines.
|
||||
custom_message_with_newlines = custom_message.replace("\\n", "\n")
|
||||
|
||||
return custom_message_with_newlines
|
||||
|
||||
|
||||
def get_custom_message(custom_reader: Reader, feed: Feed) -> str:
|
||||
|
@ -10,6 +10,53 @@ from discord_rss_bot.filter.whitelist import has_white_tags, should_be_sent
|
||||
from discord_rss_bot.settings import default_custom_message, get_reader
|
||||
|
||||
|
||||
def get_entry_from_id(entry_id: str, custom_reader: Reader | None = None) -> Entry | None:
|
||||
"""
|
||||
Get an entry from an ID.
|
||||
|
||||
Args:
|
||||
entry_id: The ID of the entry.
|
||||
custom_reader: If we should use a custom reader instead of the default one.
|
||||
|
||||
Returns:
|
||||
Entry: The entry with the ID. None if it doesn't exist.
|
||||
"""
|
||||
# Get the default reader if we didn't get a custom one.
|
||||
reader: Reader = get_reader() if custom_reader is None else custom_reader
|
||||
|
||||
# Get the entry from the ID, or return None if it doesn't exist.
|
||||
return next((entry for entry in reader.get_entries() if entry.id == entry_id), None)
|
||||
|
||||
|
||||
def send_entry_to_discord(entry: Entry, custom_reader: Reader | None = None):
|
||||
"""
|
||||
Send a single entry to Discord.
|
||||
|
||||
Args:
|
||||
entry: The entry to send to Discord.
|
||||
"""
|
||||
# Get the default reader if we didn't get a custom one.
|
||||
reader: Reader = get_reader() if custom_reader is None else custom_reader
|
||||
|
||||
# Get the webhook URL for the entry.
|
||||
webhook_url: str = settings.get_webhook_for_entry(reader, entry)
|
||||
if not webhook_url:
|
||||
return "No webhook URL found."
|
||||
|
||||
# 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) != "":
|
||||
webhook_message = custom_message.replace_tags(entry=entry, feed=entry.feed) # type: ignore
|
||||
else:
|
||||
webhook_message: str = default_custom_message
|
||||
|
||||
# Create the webhook.
|
||||
webhook: DiscordWebhook = DiscordWebhook(url=webhook_url, content=webhook_message, rate_limit_retry=True)
|
||||
|
||||
response: Response = webhook.execute()
|
||||
if not response.ok:
|
||||
return f"Error sending entry to Discord: {response.text}"
|
||||
|
||||
|
||||
def send_to_discord(custom_reader: Reader | None = None, feed: Feed | None = None, do_once: bool = False) -> None:
|
||||
"""
|
||||
Send entries to Discord.
|
||||
|
@ -14,7 +14,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, get_images_from_entry, remove_image_tags
|
||||
from discord_rss_bot.feeds import 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.whitelist import get_whitelist_content, get_whitelist_summary, get_whitelist_title
|
||||
from discord_rss_bot.search import create_html_for_search_results
|
||||
@ -426,13 +426,14 @@ def create_html_for_feed(entries: Iterable[Entry]) -> str:
|
||||
for entry in entries:
|
||||
|
||||
# Get first image.
|
||||
first_image = ""
|
||||
first_image_text = ""
|
||||
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 = ""
|
||||
|
||||
# Get the text from the entry.
|
||||
text = "<div class='text-muted'>No content available.</div>"
|
||||
if entry.summary:
|
||||
summary: str = convert_to_md(entry.summary)
|
||||
summary = remove_image_tags(message=summary)
|
||||
@ -441,32 +442,30 @@ def create_html_for_feed(entries: Iterable[Entry]) -> str:
|
||||
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>"
|
||||
|
||||
published = ""
|
||||
if entry.published:
|
||||
published: str = entry.published.strftime("%Y-%m-%d %H:%M:%S")
|
||||
else:
|
||||
published = ""
|
||||
|
||||
blacklisted = ""
|
||||
if entry_is_blacklisted(entry):
|
||||
blacklisted = "<span class='badge bg-danger'>Blacklisted</span>"
|
||||
else:
|
||||
blacklisted = ""
|
||||
|
||||
whitelisted = ""
|
||||
if entry_is_whitelisted(entry):
|
||||
whitelisted = "<span class='badge bg-success'>Whitelisted</span>"
|
||||
else:
|
||||
whitelisted = ""
|
||||
|
||||
entry_id: str = urllib.parse.quote(entry.id)
|
||||
to_disord_html: str = f"<a class='text-muted' href='/post_entry?entry_id={entry_id}'>Send to Discord</a>"
|
||||
|
||||
html += f"""
|
||||
<div class="p-2 mb-2 border border-dark">
|
||||
{blacklisted}
|
||||
{whitelisted}
|
||||
<h2>
|
||||
<a class="text-muted text-decoration-none" href="{entry.link}">{entry.title}</a>
|
||||
</h2>
|
||||
{f"By { entry.author } @" if entry.author else ""} {published}
|
||||
|
||||
<a class="text-muted text-decoration-none" href="{entry.link}"><h2>{entry.title}</h2></a>
|
||||
|
||||
{f"By { entry.author } @" if entry.author else ""} {published} - {to_disord_html}
|
||||
{text}
|
||||
{f"<img src='{first_image}' class='img-fluid' alt='{first_image_text}'>" if first_image else ""}
|
||||
</div>
|
||||
@ -591,6 +590,30 @@ async def search(request: Request, query: str):
|
||||
return templates.TemplateResponse("search.html", context)
|
||||
|
||||
|
||||
@app.get("/post_entry", response_class=HTMLResponse)
|
||||
async def post_entry(entry_id: str):
|
||||
"""
|
||||
Send a feed to Discord.
|
||||
|
||||
Returns:
|
||||
HTMLResponse: The HTML response.
|
||||
"""
|
||||
# Unquote the entry id.
|
||||
unquoted_entry_id: str = urllib.parse.unquote(entry_id)
|
||||
|
||||
print(f"Sending entry '{unquoted_entry_id}' to Discord.")
|
||||
entry: Entry | None = get_entry_from_id(entry_id=unquoted_entry_id)
|
||||
if entry is None:
|
||||
return {"error": f"Failed to get entry '{entry_id}' when posting to Discord."}
|
||||
|
||||
if result := send_entry_to_discord(entry=entry):
|
||||
return result
|
||||
|
||||
# Redirect to the feed page.
|
||||
clean_url: str = entry.feed.url.strip()
|
||||
return RedirectResponse(url=f"/feed/?feed_url={clean_url}", status_code=303)
|
||||
|
||||
|
||||
@app.on_event("startup")
|
||||
def startup() -> None:
|
||||
"""This is called when the server starts.
|
||||
|
@ -11,196 +11,198 @@
|
||||
<div class="form-text">
|
||||
<ul class="list-inline">
|
||||
<li>You can modify the message that is sent to Discord.</li>
|
||||
<li> You can use \n to create a new line.</li>
|
||||
<li> You can remove the embed from links by adding < and > around the link. (For example <{% raw %}{{entry_link}}{% endraw %}>)</li>
|
||||
<br/>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_author }}
|
||||
{{feed_author}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.author }}
|
||||
</code>{{feed.author}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_added }}
|
||||
{{feed_added}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.added }}
|
||||
</code>{{feed.added}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_last_exception }}
|
||||
{{feed_last_exception}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.last_exception }}
|
||||
</code>{{feed.last_exception}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_last_updated }}
|
||||
{{feed_last_updated}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.last_updated }}
|
||||
</code>{{feed.last_updated}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_link }}
|
||||
{{feed_link}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.link }}
|
||||
</code>{{feed.link}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_subtitle }}
|
||||
{{feed_subtitle}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.subtitle }}
|
||||
</code>{{feed.subtitle}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_title }}
|
||||
{{feed_title}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.title }}
|
||||
</code>{{feed.title}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_updated }}
|
||||
{{feed_updated}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.updated }}
|
||||
</code>{{feed.updated}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_updates_enabled }}
|
||||
{{feed_updates_enabled}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.updates_enabled }}
|
||||
</code>{{feed.updates_enabled}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_url }}
|
||||
{{feed_url}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.url }}
|
||||
</code>{{feed.url}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_user_title }}
|
||||
{{feed_user_title}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.user_title }}
|
||||
</code>{{feed.user_title}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ feed_version }}
|
||||
{{feed_version}}
|
||||
{% endraw %}
|
||||
</code>{{ feed.version }}
|
||||
</code>{{feed.version}}
|
||||
</li>
|
||||
<br/>
|
||||
{% if entry %}
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_added }}
|
||||
{{entry_added}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.added }}
|
||||
</code>{{entry.added}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_author }}
|
||||
{{entry_author}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.author }}
|
||||
</code>{{entry.author}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_content }}
|
||||
{{entry_content}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.content[0].value|discord_markdown|remove_image_tags }}
|
||||
</code>{{entry.content[0].value|discord_markdown|remove_image_tags}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_content_raw }}
|
||||
{{entry_content_raw}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.content[0].value }}
|
||||
</code>{{entry.content[0].value}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_id }}
|
||||
{{entry_id}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.id }}
|
||||
</code>{{entry.id}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_important }}
|
||||
{{entry_important}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.important }}
|
||||
</code>{{entry.important}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_link }}
|
||||
{{entry_link}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.link }}
|
||||
</code>{{entry.link}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_published }}
|
||||
{{entry_published}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.published }}
|
||||
</code>{{entry.published}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_read }}
|
||||
{{entry_read}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.read }}
|
||||
</code>{{entry.read}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_read_modified }}
|
||||
{{entry_read_modified}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.read_modified }}
|
||||
</code>{{entry.read_modified}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_summary }}
|
||||
{{entry_summary}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.summary|discord_markdown|remove_image_tags }}
|
||||
</code>{{entry.summary|discord_markdown|remove_image_tags}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_summary_raw }}
|
||||
{{entry_summary_raw}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.summary }}
|
||||
</code>{{entry.summary}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_title }}
|
||||
{{entry_title}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.title }}
|
||||
</code>{{entry.title}}
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ entry_updated }}
|
||||
{{entry_updated}}
|
||||
{% endraw %}
|
||||
</code>{{ entry.updated }}
|
||||
</code>{{entry.updated}}
|
||||
</li>
|
||||
<br/>
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
{{ image_1 }}
|
||||
{{image_1}}
|
||||
{% endraw %}
|
||||
</code>First image in the entry if it exists
|
||||
</li>
|
||||
@ -210,7 +212,7 @@
|
||||
<li>
|
||||
<code>
|
||||
{% raw %}
|
||||
Hello {{ entry_author }}\n{{ feed_title }}\n{{ entry_read }}
|
||||
{{feed_title}}\n{{entry_content}}
|
||||
{% endraw %}
|
||||
</code>
|
||||
</li>
|
||||
@ -219,9 +221,8 @@
|
||||
<li>
|
||||
<code>
|
||||
<pre>
|
||||
Hello {{ entry.author }}
|
||||
{{ feed.title }}
|
||||
{{ entry.read }}
|
||||
{{feed.title -}}
|
||||
{{- entry.content[0].value|discord_markdown|remove_image_tags -}}
|
||||
</pre>
|
||||
</code>
|
||||
</li>
|
||||
@ -241,7 +242,7 @@ Hello {{ entry.author }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Add a hidden feed_url field to the form -->
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}"/>
|
||||
<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>
|
||||
|
Reference in New Issue
Block a user