Compare commits
2 commits
32a5228174
...
f56451d056
| Author | SHA1 | Date | |
|---|---|---|---|
|
f56451d056 |
|||
|
6b881e8a1c |
2 changed files with 34 additions and 23 deletions
|
|
@ -16,6 +16,7 @@ import contextlib
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
import time
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from typing import ClassVar
|
from typing import ClassVar
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
@ -102,6 +103,36 @@ def fetch_post(post_id: str) -> JsonObject | None:
|
||||||
http_ok: int = 200
|
http_ok: int = 200
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# In-memory cache for Hoyolab post data.
|
||||||
|
# Key: post_id (str)
|
||||||
|
# Value: tuple of (JsonObject | None, expiry_timestamp)
|
||||||
|
#
|
||||||
|
# Prevents redundant API calls when the same post is processed by both
|
||||||
|
# ``process_entry()`` and ``modify_webhook()`` within a short timeframe.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
_POST_CACHE: dict[str, tuple[JsonObject | None, float]] = {}
|
||||||
|
|
||||||
|
#: Cache TTL in seconds. Entries older than this are re-fetched.
|
||||||
|
_CACHE_TTL_SECONDS: int = 300 # 5 minutes
|
||||||
|
|
||||||
|
|
||||||
|
def _cached_fetch_post(post_id: str) -> JsonObject | None:
|
||||||
|
"""Return cached post data if fresh, otherwise fetch and cache."""
|
||||||
|
now: float = time.time()
|
||||||
|
if post_id in _POST_CACHE:
|
||||||
|
cached_data, expiry = _POST_CACHE[post_id]
|
||||||
|
if now < expiry:
|
||||||
|
logger.debug("Cache hit for Hoyolab post %s", post_id)
|
||||||
|
return cached_data
|
||||||
|
logger.debug("Cache expired for Hoyolab post %s", post_id)
|
||||||
|
|
||||||
|
# Cache miss or expired — fetch fresh data.
|
||||||
|
post_data: JsonObject | None = fetch_post(post_id)
|
||||||
|
_POST_CACHE[post_id] = (post_data, now + _CACHE_TTL_SECONDS)
|
||||||
|
return post_data
|
||||||
|
|
||||||
|
|
||||||
def _as_json_object(value: JsonValue) -> JsonObject:
|
def _as_json_object(value: JsonValue) -> JsonObject:
|
||||||
return cast("JsonObject", value) if isinstance(value, dict) else {}
|
return cast("JsonObject", value) if isinstance(value, dict) else {}
|
||||||
|
|
||||||
|
|
@ -148,7 +179,7 @@ class HoyolabExtension(FeedExtension):
|
||||||
if not post_id:
|
if not post_id:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
post_data: JsonObject | None = fetch_post(post_id)
|
post_data: JsonObject | None = _cached_fetch_post(post_id)
|
||||||
if not post_data:
|
if not post_data:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
@ -202,7 +233,7 @@ class HoyolabExtension(FeedExtension):
|
||||||
if not post_id:
|
if not post_id:
|
||||||
return webhook
|
return webhook
|
||||||
|
|
||||||
post_data: JsonObject | None = fetch_post(post_id)
|
post_data: JsonObject | None = _cached_fetch_post(post_id)
|
||||||
if not post_data:
|
if not post_data:
|
||||||
return webhook
|
return webhook
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,6 @@ from discord_rss_bot.custom_message import replace_tags_in_embed
|
||||||
from discord_rss_bot.custom_message import replace_tags_in_text_message
|
from discord_rss_bot.custom_message import replace_tags_in_text_message
|
||||||
from discord_rss_bot.extensions import auto_enable_extensions_for_feed
|
from discord_rss_bot.extensions import auto_enable_extensions_for_feed
|
||||||
from discord_rss_bot.extensions import run_modify_webhook
|
from discord_rss_bot.extensions import run_modify_webhook
|
||||||
from discord_rss_bot.extensions.steam import extract_app_id as steam_extract_app_id
|
|
||||||
from discord_rss_bot.extensions.steam import get_icon_file_for_app as steam_get_icon_file
|
|
||||||
from discord_rss_bot.extensions.steam import is_steam_url
|
|
||||||
from discord_rss_bot.filter.evaluator import get_entry_filter_decision_from_reader
|
from discord_rss_bot.filter.evaluator import get_entry_filter_decision_from_reader
|
||||||
from discord_rss_bot.is_url_valid import is_url_valid
|
from discord_rss_bot.is_url_valid import is_url_valid
|
||||||
from discord_rss_bot.settings import default_custom_embed
|
from discord_rss_bot.settings import default_custom_embed
|
||||||
|
|
@ -1765,7 +1762,7 @@ def create_components_v2_webhook(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_embed_webhook( # ruff:ignore[complex-structure, too-many-branches, too-many-statements]
|
def create_embed_webhook( # ruff:ignore[complex-structure, too-many-branches]
|
||||||
webhook_url: str,
|
webhook_url: str,
|
||||||
entry: Entry,
|
entry: Entry,
|
||||||
reader: Reader,
|
reader: Reader,
|
||||||
|
|
@ -1842,20 +1839,6 @@ def create_embed_webhook( # ruff:ignore[complex-structure, too-many-branches, t
|
||||||
if custom_embed.thumbnail_url:
|
if custom_embed.thumbnail_url:
|
||||||
discord_embed.set_thumbnail(url=custom_embed.thumbnail_url)
|
discord_embed.set_thumbnail(url=custom_embed.thumbnail_url)
|
||||||
|
|
||||||
# Steam feed: override thumbnail with the game's capsule image when enabled.
|
|
||||||
steam_thumbnail_file: WebhookFile | None = None
|
|
||||||
if custom_embed.show_steam_game_icon_in_thumbnail and is_steam_url(feed.url or ""):
|
|
||||||
app_id: str | None = steam_extract_app_id(feed.url) or steam_extract_app_id(str(entry.link or ""))
|
|
||||||
if app_id:
|
|
||||||
icon_file: WebhookFile | None = steam_get_icon_file(app_id)
|
|
||||||
if icon_file:
|
|
||||||
steam_thumbnail_file = icon_file
|
|
||||||
discord_embed.set_thumbnail(url=f"attachment://{icon_file.filename}")
|
|
||||||
else:
|
|
||||||
discord_embed.set_thumbnail(
|
|
||||||
url=f"https://cdn.cloudflare.steamstatic.com/steam/apps/{app_id}/capsule_sm_120.jpg",
|
|
||||||
)
|
|
||||||
|
|
||||||
if custom_embed.image_url:
|
if custom_embed.image_url:
|
||||||
discord_embed.set_image(url=custom_embed.image_url)
|
discord_embed.set_image(url=custom_embed.image_url)
|
||||||
|
|
||||||
|
|
@ -1868,9 +1851,6 @@ def create_embed_webhook( # ruff:ignore[complex-structure, too-many-branches, t
|
||||||
if custom_embed.footer_icon_url and not custom_embed.footer_text:
|
if custom_embed.footer_icon_url and not custom_embed.footer_text:
|
||||||
discord_embed.set_footer(text="-", icon_url=custom_embed.footer_icon_url)
|
discord_embed.set_footer(text="-", icon_url=custom_embed.footer_icon_url)
|
||||||
|
|
||||||
if steam_thumbnail_file:
|
|
||||||
webhook.add_file(file=steam_thumbnail_file.content, filename=steam_thumbnail_file.filename)
|
|
||||||
|
|
||||||
webhook.add_embed(discord_embed)
|
webhook.add_embed(discord_embed)
|
||||||
return webhook
|
return webhook
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue