rss: Replace crashy double-formatting with standard format_token_replace (#370)

* rss: Simplify entry formatting

* Use format_token_replace

* Apply suggestions

* add `rss-format` config migration

---------

Co-authored-by: David Schultz <me@zpld.me>
This commit is contained in:
Val Lorentz 2023-06-14 04:12:18 +02:00 committed by GitHub
parent 0addf135ce
commit ababe8428a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,7 +1,7 @@
#--depends-on config #--depends-on config
#--depends-on shorturl #--depends-on shorturl
import difflib, hashlib, time import difflib, hashlib, time, re
from src import ModuleManager, utils from src import ModuleManager, utils
import feedparser import feedparser
@ -13,22 +13,39 @@ SETTING_BIND = utils.Setting("rss-bindhost",
"Interval (in seconds) between RSS polls", example="120")) "Interval (in seconds) between RSS polls", example="120"))
@utils.export("channelset", utils.BoolSetting("rss-shorten", @utils.export("channelset", utils.BoolSetting("rss-shorten",
"Whether or not to shorten RSS urls")) "Whether or not to shorten RSS urls"))
@utils.export("channelset", utils.Setting("rss-format", "Format of RSS announcements", example="$longtitle: $title - $link [$author]")) @utils.export("channelset", utils.Setting("rss-format", "Format of RSS announcements", example="${longtitle}: ${title} - ${link} [${author}]"))
@utils.export("serverset", SETTING_BIND) @utils.export("serverset", SETTING_BIND)
@utils.export("channelset", SETTING_BIND) @utils.export("channelset", SETTING_BIND)
class Module(ModuleManager.BaseModule): class Module(ModuleManager.BaseModule):
_name = "RSS" _name = "RSS"
def _migrate_formats(self):
count = 0
migration_sub = re.compile(r"(?:\$|{)+(?P<variable>[^}\s]+)(?:})?")
old_formats = self.bot.database.execute_fetchall("""
SELECT channel_id, value FROM channel_settings
WHERE setting = 'rss-format'
""")
for channel_id, format in old_formats:
new_format = migration_re.sub(r"${\1}", format)
self.bot.database.execute("""
UPDATE channel_settings SET value = ?
WHERE setting = 'rss-format'
AND channel_id = ?
""", [new_format, channel_id])
count += 1
self.log.info("Successfully migrated %d rss-format settings" % count)
def on_load(self): def on_load(self):
if self.bot.get_setting("rss-fmt-migration", False):
self.log.info("Attempting to migrate old rss-format settings")
self._migrate_formats()
self.bot.set_setting("rss-fmt-migration", True)
self.timers.add("rss-feeds", self._timer, self.timers.add("rss-feeds", self._timer,
self.bot.get_setting("rss-interval", RSS_INTERVAL)) self.bot.get_setting("rss-interval", RSS_INTERVAL))
def _format_entry(self, server, channel, feed_title, entry, shorten): def _format_entry(self, server, channel, feed_title, entry, shorten):
title = utils.parse.line_normalise(utils.http.strip_html(
entry["title"]))
author = entry.get("author", "unknown author")
author = "%s" % author if author else ""
link = entry.get("link", None) link = entry.get("link", None)
if shorten: if shorten:
try: try:
@ -37,16 +54,21 @@ class Module(ModuleManager.BaseModule):
pass pass
link = "%s" % link if link else "" link = "%s" % link if link else ""
feed_title_str = "%s" % feed_title if feed_title else "" variables = dict(
longtitle=feed_title or "",
title=utils.parse.line_normalise(utils.http.strip_html(
entry["title"])),
link=link or "",
author=entry.get("author", "unknown author") or "",
)
variables.update(entry)
# just in case the format starts keyerroring and you're not sure why # just in case the format starts keyerroring and you're not sure why
self.log.trace("RSS Entry: " + str(entry)) self.log.trace("RSS Entry: " + str(entry))
try: template = channel.get_setting("rss-format", "${longtitle}: ${title} by ${author} - ${link}")
format = channel.get_setting("rss-format", "$longtitle: $title by $author - $link").replace("$longtitle", feed_title_str).replace("$title", title).replace("$link", link).replace("$author", author).format(**entry) _, formatted = utils.parse.format_token_replace(template, variables)
except KeyError: return formatted
self.log.warn(f"Failed to format RSS entry for {channel}. Falling back to default format.")
format = f"{feed_title_str}: {title} by {author} - {link}"
return format
def _timer(self, timer): def _timer(self, timer):
start_time = time.monotonic() start_time = time.monotonic()