CI / test-and-package (push) Successful in 33s
- meal-cron now runs send_reminders_cron.sh (simple wget loop, no DB mount) - New /api/cron-tick endpoint handles all timezone logic server-side - base_url captured from request.host_url when user saves ntfy settings, stored per-user — no APP_BASE_URL env var needed - Cron endpoint protected by CRON_SECRET shared env var - Removed send_reminders_cron.py, DB volume from cron container - tests: 3 new cron-tick + base_url capture tests (69 total)
68 lines
2.5 KiB
Python
68 lines
2.5 KiB
Python
"""Meal Tracker — Flask application entry point."""
|
|
|
|
import os
|
|
from datetime import date
|
|
|
|
import click
|
|
from flask import Flask
|
|
|
|
from models import init_db, get_users_with_ntfy, get_all_households
|
|
from auth import auth_bp
|
|
from meals import meals_bp
|
|
from i18n import init_i18n
|
|
from ntfy import send_meal_reminder
|
|
|
|
|
|
def create_app() -> Flask:
|
|
app = Flask(__name__)
|
|
app.secret_key = os.environ.get("SECRET_KEY", "dev-secret-change-me")
|
|
|
|
app.register_blueprint(auth_bp)
|
|
app.register_blueprint(meals_bp)
|
|
|
|
with app.app_context():
|
|
init_db()
|
|
|
|
init_i18n(app)
|
|
|
|
# ── CLI commands ──
|
|
@app.cli.command("send-reminders")
|
|
@click.option("--date", default=None, help="Date to send reminders for (YYYY-MM-DD, default: today)")
|
|
@click.option("--meal", default="both", type=click.Choice(["lunch", "dinner", "both"]),
|
|
help="Which meal to send reminders for (default: both)")
|
|
@click.option("--base-url", default=None, help="Base URL of the app (default: $APP_BASE_URL or http://localhost:5000)")
|
|
def send_reminders_command(date, meal, base_url):
|
|
"""Send ntfy meal reminders to all users who have ntfy configured."""
|
|
target_date = date and __import__("datetime").datetime.strptime(date, "%Y-%m-%d").date() or date.today()
|
|
fallback_url = base_url or os.environ.get("APP_BASE_URL", "http://localhost:5000")
|
|
|
|
meal_types = ["lunch", "dinner"] if meal == "both" else [meal]
|
|
total_sent = 0
|
|
|
|
for household in get_all_households():
|
|
for user in get_users_with_ntfy(household["id"]):
|
|
user_base_url = user.get("base_url") or fallback_url
|
|
for mt in meal_types:
|
|
ok = send_meal_reminder(
|
|
ntfy_url=user["ntfy_url"],
|
|
ntfy_token=user["ntfy_token"],
|
|
callback_token=user["callback_token"],
|
|
meal_type=mt,
|
|
for_date=target_date,
|
|
app_base_url=user_base_url,
|
|
)
|
|
if ok:
|
|
total_sent += 1
|
|
click.echo(f" ✓ {user['username']} ({mt})")
|
|
else:
|
|
click.echo(f" ✗ {user['username']} ({mt}) — failed")
|
|
|
|
click.echo(f"\nSent {total_sent} reminder(s) for {target_date.isoformat()}.")
|
|
|
|
return app
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app = create_app()
|
|
app.run(host="0.0.0.0", port=5000, debug=True)
|