Add hard-to-guess public URLs (/public/<token>) that show a read-only meal status dashboard for each household. Only people with the link can see the data — no login required. - models.py: public_token + public_enabled columns on households, get_household_by_public_token(), generate_public_token(), set_public_enabled() - meals.py: /public/<token> route, /admin/public-link for generate/disable/enable/regenerate - templates/public.html: clean read-only public dashboard - templates/public-not-found.html: 404 for invalid/disabled links - templates/dashboard.html: admin UI with copy/regenerate/disable - static/style.css: public page and URL box styles - i18n.py: 18 new translation keys (en/fr/de)
This commit is contained in:
@@ -86,6 +86,10 @@ def init_db() -> None:
|
||||
db.execute("ALTER TABLE households ADD COLUMN last_lunch_reminder TEXT DEFAULT ''")
|
||||
if "last_dinner_reminder" not in hh_cols:
|
||||
db.execute("ALTER TABLE households ADD COLUMN last_dinner_reminder TEXT DEFAULT ''")
|
||||
if "public_token" not in hh_cols:
|
||||
db.execute("ALTER TABLE households ADD COLUMN public_token TEXT DEFAULT ''")
|
||||
if "public_enabled" not in hh_cols:
|
||||
db.execute("ALTER TABLE households ADD COLUMN public_enabled INTEGER DEFAULT 1")
|
||||
|
||||
|
||||
# ── Households ────────────────────────────────────────────────────────────────
|
||||
@@ -156,6 +160,39 @@ def update_reminder_sent(household_id: int, meal_type: str, date_str: str) -> No
|
||||
(date_str, household_id))
|
||||
|
||||
|
||||
# ── Public sharing ───────────────────────────────────────────────────────────
|
||||
|
||||
def get_household_by_public_token(token: str) -> dict | None:
|
||||
"""Look up a household by its public sharing token."""
|
||||
with get_db() as db:
|
||||
row = db.execute(
|
||||
"SELECT * FROM households WHERE public_token = ? AND public_enabled = 1",
|
||||
(token,),
|
||||
).fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
|
||||
def generate_public_token(household_id: int) -> str:
|
||||
"""Generate a new hard-to-guess public token for a household."""
|
||||
import secrets
|
||||
token = secrets.token_urlsafe(32)
|
||||
with get_db() as db:
|
||||
db.execute(
|
||||
"UPDATE households SET public_token = ?, public_enabled = 1 WHERE id = ?",
|
||||
(token, household_id),
|
||||
)
|
||||
return token
|
||||
|
||||
|
||||
def set_public_enabled(household_id: int, enabled: bool) -> None:
|
||||
"""Enable or disable the public sharing link for a household."""
|
||||
with get_db() as db:
|
||||
db.execute(
|
||||
"UPDATE households SET public_enabled = ? WHERE id = ?",
|
||||
(int(enabled), household_id),
|
||||
)
|
||||
|
||||
|
||||
# ── Users ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
def get_user_by_id(user_id: int) -> dict | None:
|
||||
|
||||
Reference in New Issue
Block a user