fix: persist short URLs in alert history, regenerate on expiry

Store shortened URLs in the results DB at poll time alongside the
original URL. History output uses the stored short URL directly,
only regenerating (and persisting) when no short URL exists yet.
Original URL always preserved for re-shortening if needed.
This commit is contained in:
user
2026-02-16 23:24:26 +01:00
parent c92fdbfc30
commit 3c505dd825

View File

@@ -109,12 +109,16 @@ def _db() -> sqlite3.Connection:
short_id TEXT NOT NULL DEFAULT ''
)
""")
try:
_conn.execute(
"ALTER TABLE results ADD COLUMN short_id TEXT NOT NULL DEFAULT ''"
)
except sqlite3.OperationalError:
pass # column already exists
for col, default in [
("short_id", "''"),
("short_url", "''"),
]:
try:
_conn.execute(
f"ALTER TABLE results ADD COLUMN {col} TEXT NOT NULL DEFAULT {default}"
)
except sqlite3.OperationalError:
pass # column already exists
_conn.execute(
"CREATE INDEX IF NOT EXISTS idx_results_alert ON results(channel, alert)"
)
@@ -133,14 +137,16 @@ def _db() -> sqlite3.Connection:
return _conn
def _save_result(channel: str, alert: str, backend: str, item: dict) -> str:
def _save_result(channel: str, alert: str, backend: str, item: dict,
short_url: str = "") -> str:
"""Persist a matched result to the history database. Returns short_id."""
short_id = _make_short_id(backend, item.get("id", ""))
db = _db()
db.execute(
"INSERT INTO results"
" (channel, alert, backend, item_id, title, url, date, found_at, short_id)"
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
" (channel, alert, backend, item_id, title, url, date, found_at,"
" short_id, short_url)"
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
(
channel,
alert,
@@ -151,6 +157,7 @@ def _save_result(channel: str, alert: str, backend: str, item: dict) -> str:
item.get("date", ""),
datetime.now(timezone.utc).isoformat(),
short_id,
short_url,
),
)
db.commit()
@@ -1755,23 +1762,31 @@ async def _poll_once(bot, key: str, announce: bool = True) -> None:
name = data["name"]
fp = bot.registry._modules.get("flaskpaste")
for item in matched:
short_id = _save_result(channel, name, tag, item)
title = _truncate(item["title"]) if item["title"] else "(no title)"
url = item["url"]
display_url = url
short_url = ""
if fp and url:
try:
url = await loop.run_in_executor(
short_url = await loop.run_in_executor(
None, fp.shorten_url, bot, url,
)
if short_url != url:
display_url = short_url
else:
short_url = ""
except Exception:
pass
short_id = _save_result(
channel, name, tag, item, short_url=short_url,
)
title = _truncate(item["title"]) if item["title"] else "(no title)"
date = item.get("date", "")
line = f"[{name}/{tag}/{short_id}]"
if date:
line += f" ({date})"
line += f" {title}"
if url:
line += f" -- {url}"
if display_url:
line += f" -- {display_url}"
await bot.send(channel, line)
for item in new_items:
@@ -1937,7 +1952,8 @@ async def cmd_alert(bot, message):
limit = 5
db = _db()
rows = db.execute(
"SELECT backend, title, url, date, found_at, short_id FROM results"
"SELECT id, backend, title, url, date, found_at, short_id,"
" short_url FROM results"
" WHERE channel = ? AND alert = ? ORDER BY id DESC LIMIT ?",
(channel, name, limit),
).fetchall()
@@ -1946,19 +1962,27 @@ async def cmd_alert(bot, message):
return
loop = asyncio.get_running_loop()
fp = bot.registry._modules.get("flaskpaste")
for backend, title, url, date, found_at, short_id in reversed(rows):
for row_id, backend, title, url, date, found_at, short_id, short_url in reversed(rows):
ts = found_at[:10]
title = _truncate(title) if title else "(no title)"
if fp and url:
display_url = short_url or url
if fp and url and not short_url:
try:
url = await loop.run_in_executor(
new_short = await loop.run_in_executor(
None, fp.shorten_url, bot, url,
)
if new_short != url:
display_url = new_short
db.execute(
"UPDATE results SET short_url = ? WHERE id = ?",
(new_short, row_id),
)
db.commit()
except Exception:
pass
line = f"[{name}/{backend}/{short_id}] ({date or ts}) {title}"
if url:
line += f" -- {url}"
if display_url:
line += f" -- {display_url}"
await bot.reply(message, line)
return