publish to the calendar list as well

This commit is contained in:
sakrecoer 2026-10-03 13:47:16 +02:00
parent b0883f398b
commit 6b0fc5ccb3

View file

@ -111,10 +111,20 @@ def ics_str(component: dict, key: str) -> str:
return "" return ""
if hasattr(val, "to_ical"): if hasattr(val, "to_ical"):
try: try:
return val.to_ical().decode("utf-8", errors="replace").strip() raw = val.to_ical().decode("utf-8", errors="replace")
except Exception: except Exception:
pass raw = str(val)
return str(val).strip() else:
raw = str(val)
# Undo ICS text escaping: \, \; \n \\
raw = (
raw.replace("\\,", ",")
.replace("\\;", ";")
.replace("\\n", "\n")
.replace("\\N", "\n")
.replace("\\\\", "\\")
)
return raw.strip()
def ics_dt(component: dict, key: str) -> int | None: def ics_dt(component: dict, key: str) -> int | None:
@ -211,20 +221,25 @@ def record_published(conn, d_tag: str, chash: str, event_id: str):
# Event construction # Event construction
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
def make_calendar_event(cfg: dict) -> Event: def make_calendar_event(cfg: dict, pubkey_hex: str, event_d_tags: list[str]) -> Event:
"""Build the kind 31924 calendar, listing every event via an `a` tag."""
cal = cfg["calendar"] cal = cfg["calendar"]
return Event(
kind=31924,
content=cal["description"],
tags = [ tags = [
["d", cal["d"]], ["d", cal["d"]],
["title", cal["title"]], ["title", cal["title"]],
], ]
for d_tag in event_d_tags:
tags.append(["a", f"31923:{pubkey_hex}:{d_tag}"])
return Event(
kind=31924,
content=cal["description"],
tags=tags,
) )
def make_calendar_event_nostr(cfg, pubkey_hex, title, start, end, location, url, def make_calendar_event_nostr(cfg, pubkey_hex, title, start, end, location, url,
image, tags, d_tag, duration, template) -> Event: image, tags, d_tag, duration, template) -> Event:
"""Build a kind 31923 event."""
cal_coord = f"31924:{pubkey_hex}:{cfg['calendar']['d']}" cal_coord = f"31924:{pubkey_hex}:{cfg['calendar']['d']}"
final_end = end if end is not None else start + duration final_end = end if end is not None else start + duration
@ -347,31 +362,39 @@ def main():
if dry_run: if dry_run:
log.info("DRY RUN complete. Would publish %d, skipped_no_rss=%d", log.info("DRY RUN complete. Would publish %d, skipped_no_rss=%d",
len([x for x in vevents]), skipped_no_rss) len(to_publish), skipped_no_rss)
return return
log.info("Publishing %d new/changed events (skipped %d unchanged, %d without RSS)", log.info("Publishing %d new/changed events (skipped %d unchanged, %d without RSS)",
len(to_publish), skipped, skipped_no_rss) len(to_publish), skipped, skipped_no_rss)
if not to_publish: # Build the full set of d-tags the calendar should reference:
log.info("Nothing to do.") # everything already in the DB, plus everything about to be published.
return rows = conn.execute("SELECT d_tag FROM published").fetchall()
all_d_tags = {row[0] for row in rows}
for d_tag, _, _ in to_publish:
all_d_tags.add(d_tag)
all_d_tags = sorted(all_d_tags)
cal_ev = make_calendar_event(cfg) log.info("Calendar will reference %d events", len(all_d_tags))
cal_ev = make_calendar_event(cfg, pubkey_hex, all_d_tags)
cal_ev.sign(pk.hex()) cal_ev.sign(pk.hex())
relay_manager = RelayManager(timeout=6) relay_manager = RelayManager(timeout=6)
for r in relays: for r in relays:
relay_manager.add_relay(r) relay_manager.add_relay(r)
relay_manager.publish_event(cal_ev) # Publish events first, then the calendar that references them.
log.info("Published calendar kind 31924 (d=%s)", cfg["calendar"]["d"])
for d_tag, chash, ev in to_publish: for d_tag, chash, ev in to_publish:
ev.sign(pk.hex()) ev.sign(pk.hex())
relay_manager.publish_event(ev) relay_manager.publish_event(ev)
log.info("Queued event %s — %s", d_tag, ev.content.split("\n", 1)[0]) log.info("Queued event %s — %s", d_tag, ev.content.split("\n", 1)[0])
relay_manager.publish_event(cal_ev)
log.info("Queued calendar kind 31924 (d=%s) referencing %d events",
cfg["calendar"]["d"], len(all_d_tags))
relay_manager.run_sync() relay_manager.run_sync()
time.sleep(2) time.sleep(2)
relay_manager.close_all_relay_connections() relay_manager.close_all_relay_connections()
@ -379,7 +402,8 @@ def main():
for d_tag, chash, ev in to_publish: for d_tag, chash, ev in to_publish:
record_published(conn, d_tag, chash, ev.id) record_published(conn, d_tag, chash, ev.id)
log.info("Done. %d events published.", len(to_publish)) log.info("Done. %d events published, calendar references %d.",
len(to_publish), len(all_d_tags))
if __name__ == "__main__": if __name__ == "__main__":