feat: support optional start/end time on events

event_start_date / event_end_date now accept either YYYY-MM-DD (date-only)
or YYYY-MM-DDTHH:MM (ISO datetime). The NIP-52 publisher switches kind
on the "T" delimiter: kind 31922 (date-based, YYYY-MM-DD start/end) when
absent, kind 31923 (time-based, unix-timestamp start/end + day-granularity
D tags) when present. Delete events match the original publish kind.

Closing-date parsing accepts both formats. The LNbits admin form gains
optional HH:MM inputs alongside each date picker; they fold into the
wire-format string on submit and split back on edit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-05-20 01:22:38 +02:00
commit 4aa90d80ad
5 changed files with 137 additions and 32 deletions

View file

@ -140,9 +140,15 @@ async def api_get_event(event_id: str) -> Event:
# closing_date is filled in by create_event (defaults to end_date or
# start_date) but the field is typed Optional, so guard for the typechecker.
closing_date = event.closing_date or event.event_end_date or event.event_start_date
is_window_open = datetime.now(timezone.utc) < datetime.strptime(
closing_date, "%Y-%m-%d"
).replace(tzinfo=timezone.utc)
# Accept either YYYY-MM-DD or full ISO 8601 datetime (e.g. event_end_date
# may carry a time component since v1.3.0-aio.3).
try:
closing_dt = datetime.fromisoformat(closing_date)
except ValueError:
closing_dt = datetime.strptime(closing_date[:10], "%Y-%m-%d")
if closing_dt.tzinfo is None:
closing_dt = closing_dt.replace(tzinfo=timezone.utc)
is_window_open = datetime.now(timezone.utc) < closing_dt
is_min_tickets_met = (
event.sold >= event.extra.min_tickets if event.extra.conditional else True
)