Initial commit: aplicatie de cantarire si etichetare
Aplicatie Flask + SQLite pentru productie alimentara: cantarirea componentelor unui produs finit si tiparirea etichetei prin QZ Tray. - produse finite (retete) formate din componente cantarite - designer vizual de etichete (mm/px, zona sigura, campuri variabile, cod QR cu continut din mai multe bucati) - legare produs finit -> sablon de eticheta - navigare pe doua taburi: Cantarire / Setari - administrare: componente, produse finite, sabloane, campuri, istoric - backup, resetare baza de date, checklist de pregatire, /healthz - CLI de administrare si serviciu systemd pentru productie - vendor/syncpulse-scale-bridge (GPL-3.0-or-later) pentru citirea cantarului
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
"""Utilitar de administrare: stare, backup, reset, verificare, date demo.
|
||||
|
||||
Exemple:
|
||||
|
||||
python -m cantarire.tools.admin status
|
||||
python -m cantarire.tools.admin check
|
||||
python -m cantarire.tools.admin backup --keep 10
|
||||
python -m cantarire.tools.admin reset --yes
|
||||
python -m cantarire.tools.admin seed-demo
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from cantarire import create_app
|
||||
from cantarire import maintenance
|
||||
|
||||
|
||||
def _status() -> int:
|
||||
status = maintenance.database_status()
|
||||
print(f"Baza de date : {status['path']}")
|
||||
print(f"Marime : {status['size_human']}")
|
||||
print(f"Integritate : {status['integrity']}")
|
||||
print(f"Schema : v{status['schema_version']}")
|
||||
print(f"Backup-uri : {status['backups']} in {status['backup_dir']}")
|
||||
print("Inregistrari :")
|
||||
for table, count in status["counts"].items():
|
||||
print(f" {table:<14} {count}")
|
||||
return 0
|
||||
|
||||
|
||||
def _check(as_json: bool = False) -> int:
|
||||
summary = maintenance.readiness_summary()
|
||||
if as_json:
|
||||
import json
|
||||
|
||||
print(json.dumps(summary, indent=2, ensure_ascii=False, default=str))
|
||||
return 0 if summary["ready"] else 1
|
||||
|
||||
print("Verificare pregatire productie:\n")
|
||||
for item in summary["checks"]:
|
||||
mark = "OK " if item["ok"] else ("OPT " if item.get("optional") else "LIPSA")
|
||||
print(f"[{mark}] {item['label']:<22} {item['message']}")
|
||||
print()
|
||||
if summary["ready"]:
|
||||
print("Gata de cantarit: toate elementele obligatorii sunt completate.")
|
||||
return 0
|
||||
missing = ", ".join(item["label"] for item in summary["missing"])
|
||||
print(f"De completat: {missing}")
|
||||
return 1
|
||||
|
||||
|
||||
def _backup(keep: int) -> int:
|
||||
path = maintenance.backup_database("manual")
|
||||
removed = maintenance.prune_backups(keep)
|
||||
print(f"Backup creat: {path}")
|
||||
if removed:
|
||||
print(f"Backup-uri vechi sterse: {removed} (pastrez ultimele {keep})")
|
||||
return 0
|
||||
|
||||
|
||||
def _reset(confirmed: bool, keep_backup: bool) -> int:
|
||||
if not confirmed:
|
||||
print("Operatia goleste toate datele (componente, produse finite, pachete, sabloane).")
|
||||
print("Ruleaz-o din nou cu --yes daca esti sigur.")
|
||||
return 2
|
||||
result = maintenance.reset_database(keep_backup=keep_backup)
|
||||
print(maintenance.reset_report(result))
|
||||
return 0
|
||||
|
||||
|
||||
def _seed_demo() -> int:
|
||||
result = maintenance.seed_demo()
|
||||
created = result["created"]
|
||||
print(f"Componente create: {created['components']} · produse finite create: {created['recipes']}")
|
||||
print(f"Componente: {', '.join(result['components']) or '-'}")
|
||||
print(f"Produse finite: {', '.join(result['recipes']) or '-'}")
|
||||
return 0
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None, app=None) -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="cantarire-admin",
|
||||
description="Administrare: stare, backup, reset, verificare.",
|
||||
)
|
||||
sub = parser.add_subparsers(dest="command", required=True)
|
||||
|
||||
sub.add_parser("status", help="starea bazei si numarul de inregistrari")
|
||||
check = sub.add_parser("check", help="verifica daca aplicatia e gata de cantarit")
|
||||
check.add_argument("--json", action="store_true", help="iesire JSON")
|
||||
|
||||
backup = sub.add_parser("backup", help="creeaza un backup al bazei")
|
||||
backup.add_argument("--keep", type=int, default=maintenance.KEEP_BACKUPS,
|
||||
help="cate backup-uri pastreaza (implicit 20)")
|
||||
|
||||
reset = sub.add_parser("reset", help="goleste datele si readuce setarile initiale")
|
||||
reset.add_argument("--yes", action="store_true", help="confirma stergerea")
|
||||
reset.add_argument("--no-backup", action="store_true", help="nu face backup inainte")
|
||||
|
||||
sub.add_parser("seed-demo", help="adauga datele demo (instruire/testare)")
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
application = app or create_app()
|
||||
with application.app_context():
|
||||
maintenance.ensure_instance_dirs()
|
||||
if args.command == "status":
|
||||
return _status()
|
||||
if args.command == "check":
|
||||
return _check(args.json)
|
||||
if args.command == "backup":
|
||||
return _backup(args.keep)
|
||||
if args.command == "reset":
|
||||
return _reset(args.yes, not args.no_backup)
|
||||
if args.command == "seed-demo":
|
||||
return _seed_demo()
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user