From 3a0ad786120b2c7b3f01fc0dedd72aeb9c25dcb5 Mon Sep 17 00:00:00 2001 From: Gilbert Brault Date: Tue, 2 Dec 2025 15:04:27 +0100 Subject: [PATCH 01/37] Refactor log retrieval in get_logs endpoint and improve log formatting in add_log_file function --- main.py | 8 +++----- utils.py | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index 5ab7792..4f89c34 100644 --- a/main.py +++ b/main.py @@ -48,11 +48,9 @@ async def get_jobs(job_id: int, request: Request, db: Session = Depends(get_db)) @app.get("/logs/{job_id}") async def get_logs(job_id: int, request: Request, db: Session = Depends(get_db)): - job = db.query(Job).filter(Job.id == job_id) - update_log = {"log": load_logs(job.first().name)} - job.update(update_log) - db.commit() - output = {"request": request, "job": update_log} + job = db.query(Job).filter(Job.id == job_id).first() + log_content = load_logs(job.name) + output = {"request": request, "job": {"log": log_content}} return templates.TemplateResponse("logs.html", output) diff --git a/utils.py b/utils.py index c557cac..f45ccb9 100644 --- a/utils.py +++ b/utils.py @@ -7,7 +7,7 @@ def add_log_file(command: Command, name: Name) -> str: log_file_name = name.replace(" ", "") - return f"{{{command} || echo Failed }} 2>&1 | ts >> logs/{log_file_name}.log" + return f"{{ {command} || echo Failed; }} 2>&1 | ts >> logs/{log_file_name}.log" def delete_log_file(name: Name) -> None: From 56eb25e91da2a4b255f8bd997a047261fbd719d0 Mon Sep 17 00:00:00 2001 From: Gilbert Brault Date: Tue, 2 Dec 2025 16:03:04 +0100 Subject: [PATCH 02/37] =?UTF-8?q?Synchroniser=20les=20jobs=20de=20la=20bas?= =?UTF-8?q?e=20de=20donn=C3=A9es=20avec=20le=20crontab=20syst=C3=A8me=20au?= =?UTF-8?q?=20d=C3=A9marrage=20et=20ajouter=20la=20fonction=20de=20synchro?= =?UTF-8?q?nisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cronservice.py | 19 +++++++++++++++++++ main.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/cronservice.py b/cronservice.py index dda92cd..900a699 100644 --- a/cronservice.py +++ b/cronservice.py @@ -48,3 +48,22 @@ def get_next_schedule(name: Name) -> str: return schedule.get_next().strftime("%d/%m/%Y %H:%M:%S").replace("/", "-") except IndexError: return None + + +def sync_job_to_cron(comm: Command, name: Name, sched: Schedule) -> None: + """Synchronise un job de la DB vers le crontab système""" + # Vérifier si le job existe déjà dans le crontab + existing_jobs = list(_cron.find_comment(name)) + + if existing_jobs: + # Mettre à jour le job existant + job = existing_jobs[0] + job.setall(sched) + job.set_command(add_log_file(comm, name)) + else: + # Créer un nouveau job + if croniter.is_valid(sched): + job = _cron.new(command=add_log_file(comm, name), comment=name) + job.setall(sched) + + _cron.write() diff --git a/main.py b/main.py index 4f89c34..92d9df3 100644 --- a/main.py +++ b/main.py @@ -2,6 +2,7 @@ from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from sqlalchemy.orm import Session +import logging import models import cronservice @@ -9,6 +10,10 @@ from utils import watch_status, load_logs from database import SessionLocal, engine, JobRequest +# Configuration du logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + app = FastAPI() app.mount("/static", StaticFiles(directory="static"), name="static") @@ -24,6 +29,36 @@ def get_db(): db.close() +@app.on_event("startup") +async def startup_event(): + """Synchronise la base de données avec le crontab système au démarrage""" + logger.info("🚀 Application démarrée - Synchronisation des jobs cron...") + + db = SessionLocal() + try: + # Récupérer tous les jobs de la base de données + jobs = db.query(Job).all() + + if jobs: + logger.info(f"📋 Synchronisation de {len(jobs)} job(s) avec le crontab système...") + + for job in jobs: + try: + cronservice.sync_job_to_cron(job.command, job.name, job.schedule) + logger.info(f" ✅ Job '{job.name}' synchronisé") + except Exception as e: + logger.error(f" ❌ Erreur lors de la synchronisation du job '{job.name}': {e}") + + logger.info("✅ Synchronisation terminée avec succès") + else: + logger.info("ℹ️ Aucun job à synchroniser") + + except Exception as e: + logger.error(f"❌ Erreur lors de la synchronisation au démarrage: {e}") + finally: + db.close() + + def update_displayed_schedule(db: Session = Depends(get_db)) -> None: jobs = db.query(Job).all() for job in jobs: From 499813f44eb7e95bf1a78661defb8d4c58b4994e Mon Sep 17 00:00:00 2001 From: Gilbert Brault Date: Tue, 2 Dec 2025 16:22:47 +0100 Subject: [PATCH 03/37] =?UTF-8?q?Am=C3=A9liorer=20la=20mise=20en=20forme?= =?UTF-8?q?=20du=20tableau=20des=20jobs=20et=20ajouter=20des=20information?= =?UTF-8?q?s=20sur=20le=20programme=20dans=20la=20popup=20de=20planificati?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/home.html | 169 +++++++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 82 deletions(-) diff --git a/templates/home.html b/templates/home.html index f406e2f..47a266b 100644 --- a/templates/home.html +++ b/templates/home.html @@ -1,12 +1,12 @@ {% extends "layout.html" %} {% block content %} - + -
- - - +
+
+ + @@ -16,85 +16,90 @@ - - {% for job in jobs %} - - - - - - - - - - {% endfor %} -
Command Command NameAction Logs
-
Show Command
- -
-
{{ job.name }}
-
-
{{ job.schedule }}
-
-
{{ job.next_run }}
-
-
{{ job.status }}
-
- - - - - - - - - - - - - -
-

- -

-
+ + {% for job in jobs %} + + +
Show Command
+ + + +
{{ job.name }}
+ + +
+
{{ job.schedule }}
+
+ + + +
{{ job.next_run }}
+ + +
{{ job.status }}
+ + + + + + + + + + + + + + + + + + + {% endfor %} + +

+ +

+ -