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