96 lines
3.7 KiB
Python
96 lines
3.7 KiB
Python
"""`kadence` — run the server, or poke it from a terminal/cron."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import getpass
|
|
import json
|
|
from datetime import date
|
|
|
|
from app.db import init_db, session_scope
|
|
from app.services import report, settings_service, stats, tasks_service
|
|
from app.timeutil import local_date
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(prog="kadence")
|
|
sub = parser.add_subparsers(dest="command", required=True)
|
|
|
|
serve = sub.add_parser("serve", help="run the API (and the web UI)")
|
|
serve.add_argument("--host", default="0.0.0.0")
|
|
serve.add_argument("--port", type=int, default=8000)
|
|
serve.add_argument("--reload", action="store_true")
|
|
|
|
sub.add_parser("refresh", help="pull every todo source once")
|
|
sub.add_parser("briefing", help="send the morning briefing now")
|
|
report_cmd = sub.add_parser("report", help="build and send today's report")
|
|
report_cmd.add_argument("--date", type=date.fromisoformat, default=None)
|
|
report_cmd.add_argument("--print", action="store_true", help="print, do not send")
|
|
sub.add_parser("stats", help="print a summary as JSON")
|
|
|
|
setpw = sub.add_parser("set-password", help="set or replace the web login password")
|
|
setpw.add_argument("--username", default=None, help="defaults to the current one")
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.command == "serve":
|
|
import uvicorn
|
|
|
|
uvicorn.run("app.main:app", host=args.host, port=args.port, reload=args.reload)
|
|
return 0
|
|
|
|
init_db()
|
|
with session_scope() as session:
|
|
settings = settings_service.load_settings(session)
|
|
|
|
if args.command == "refresh":
|
|
print(json.dumps(tasks_service.refresh_tasks(session, settings), indent=2))
|
|
elif args.command == "briefing":
|
|
from app.services.notify import notify
|
|
|
|
text = report.render_morning_briefing(session, settings)
|
|
print(text)
|
|
print([d.as_dict() for d in notify(settings, text, urgent=True)])
|
|
elif args.command == "report":
|
|
day = args.date or local_date(settings.timezone)
|
|
if args.print:
|
|
_, payload = report.get_or_build_daily(session, settings, day, rebuild=True)
|
|
print(report.render_daily_telegram(payload, settings))
|
|
else:
|
|
result = report.send_daily(session, settings, day, force=True)
|
|
print(result.get("text", ""))
|
|
print([d for d in result.get("deliveries", [])])
|
|
elif args.command == "stats":
|
|
today = local_date(settings.timezone)
|
|
print(
|
|
json.dumps(
|
|
{
|
|
"today": stats.day_metrics(session, settings, today),
|
|
"streak": stats.streak(session, settings),
|
|
"lifetime": stats.lifetime(session, settings),
|
|
},
|
|
indent=2,
|
|
ensure_ascii=False,
|
|
)
|
|
)
|
|
elif args.command == "set-password":
|
|
from app.services import auth_service
|
|
|
|
password = getpass.getpass("New web login password: ")
|
|
if password != getpass.getpass("Confirm: "):
|
|
print("Passwords did not match.")
|
|
return 1
|
|
if len(password) < 8:
|
|
print("Use at least 8 characters.")
|
|
return 1
|
|
if args.username:
|
|
settings.auth.username = args.username
|
|
settings.auth.password_hash = auth_service.hash_password(password)
|
|
settings_service.save_settings(session, settings)
|
|
print(f"Password set for {settings.auth.username!r}.")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__": # pragma: no cover
|
|
raise SystemExit(main())
|