Cette mise a jour complete ameliore significativement la qualite et la maintenabilite du projet. 1. Extension de la couverture de tests Couverture globale passee de 8% a 16% (+100%) - Ajout de 25 nouveaux tests (total: 67 tests, 100% passent) - Nouveaux fichiers de tests: * tests/unit/test_gitea.py (17 tests) * tests/unit/test_fiches_tickets.py (8 tests) Etat de la couverture par module: - utils/gitea.py: 100% - utils/widgets.py: 100% - utils/logger.py: 94% - app/fiches/utils/tickets/core.py: 77% - utils/graph_utils.py: 59% 2. Documentation d'architecture complete Creation de 3 nouveaux documents (30 Ko total): - docs/ARCHITECTURE.md (15 Ko) * Architecture complete du projet * Flux de donnees detailles * Indices de vulnerabilite (IHH, ISG, ICS, IVC) * Structure du graphe NetworkX - docs/MODULES.md (15 Ko) * Guide des 11 modules principaux * Exemples de code (15+ snippets) * Bonnes pratiques * Guide de depannage - docs/README.md (4 Ko) * Index de toute la documentation Contenu documente: - 5 modules applicatifs - 6 modules utilitaires - 4 indices de vulnerabilite avec formules et seuils - Conventions de code 3. Reorganisation de la documentation Structure finale optimisee: - Racine: README.md (mis a jour) + Instructions.md - docs/: 11 documents organises par categorie Fichiers deplaces vers docs/: - README_connexion.md -> docs/CONNEXION.md - GUIDE_LOGS.md -> docs/ - GUIDE_RUFF.md -> docs/ - RAPPORT_RUFF.md -> docs/ - RAPPORT_CORRECTIONS_AUTO.md -> docs/ - REFACTORING_REPORT.md -> docs/ - VERIFICATION_LOGS.md -> docs/ - TODO_IA_BATCH.md -> docs/ 4. Ajout de docstrings 52 fonctions documentees en style Google (100%) Documentation en francais avec Args, Returns, Raises 5. Corrections automatiques Ruff Application de 347 corrections automatiques: - Formatage du code (line-length: 120) - Organisation des imports - Simplifications syntaxiques - Suppressions de code mort - Ameliorations de performance 6. Configuration qualite du code Nouveaux fichiers: - pyproject.toml: configuration Ruff complete - .vscode/settings.json: integration Ruff avec formatOnSave - GUIDE_RUFF.md: documentation du linter - GUIDE_LOGS.md: documentation du logging - .gitignore: ajout htmlcov/ pour rapports de couverture Etat final du projet: - Linter: Ruff configure (15 regles actives) - Tests: 67 tests (100% passent) - Couverture de code: 16% - Docstrings: 52/52 (100%) - Documentation: 11 fichiers organises Impact: - Tests plus robustes et maintenables - Documentation technique complete - Meilleure organisation des fichiers - Workflow optimise avec Ruff - Code pret pour integration continue References: - Architecture: docs/ARCHITECTURE.md - Guide modules: docs/MODULES.md - Tests: tests/unit/ - Configuration: pyproject.toml Co-Authored-By: Claude <noreply@anthropic.com>
133 lines
5.6 KiB
Python
133 lines
5.6 KiB
Python
# === Constantes et imports ===
|
|
import os
|
|
|
|
import requests
|
|
import streamlit as st
|
|
|
|
from app.fiches.generer import generer_fiche
|
|
from app.fiches.utils import (
|
|
afficher_tickets_par_fiche,
|
|
doit_regenerer_fiche,
|
|
formulaire_creation_ticket_dynamique,
|
|
load_seuils,
|
|
rechercher_tickets_gitea,
|
|
)
|
|
from config import DEPOT_FICHES, ENV, FICHES_CRITICITE, GITEA_TOKEN, GITEA_URL, ORGANISATION
|
|
from utils.gitea import charger_arborescence_fiches
|
|
from utils.translations import _
|
|
from utils.widgets import html_expander
|
|
|
|
|
|
def interface_fiches() -> None:
|
|
"""Point d'entree principal de l'interface de visualisation des fiches et gestion des tickets."""
|
|
st.markdown(f"# {str(_('pages.fiches.title'))}")
|
|
html_expander(f"{str(_('pages.fiches.help'))}", content="\n".join(_("pages.fiches.help_content")), open_by_default=False, details_class="details_introduction")
|
|
st.markdown("---")
|
|
|
|
if "fiches_arbo" not in st.session_state:
|
|
st.session_state["fiches_arbo"] = charger_arborescence_fiches()
|
|
|
|
arbo = st.session_state.get("fiches_arbo", {})
|
|
if not arbo:
|
|
st.warning(str(_("pages.fiches.no_files")))
|
|
return
|
|
|
|
dossiers = sorted(arbo.keys(), key=lambda x: x.lower())
|
|
|
|
if "dossier_choisi" not in st.session_state or st.session_state["dossier_choisi"] not in dossiers:
|
|
st.session_state["dossier_choisi"] = str(_("pages.fiches.select_folder"))
|
|
|
|
try:
|
|
index_dossier = [str(_("pages.fiches.select_folder"))] + dossiers
|
|
idx = index_dossier.index(st.session_state["dossier_choisi"])
|
|
except ValueError:
|
|
idx = 0
|
|
|
|
st.session_state["dossier_choisi"] = st.selectbox(
|
|
str(_("pages.fiches.choose_category")),
|
|
[str(_("pages.fiches.select_folder"))] + dossiers,
|
|
index=idx
|
|
)
|
|
|
|
dossier_choisi = st.session_state["dossier_choisi"]
|
|
|
|
if dossier_choisi and dossier_choisi != str(_("pages.fiches.select_folder")):
|
|
fiches = arbo.get(dossier_choisi, [])
|
|
noms_fiches = [f['nom'] for f in fiches]
|
|
|
|
if "fiche_choisie" not in st.session_state or st.session_state["fiche_choisie"] not in noms_fiches:
|
|
st.session_state["fiche_choisie"] = str(_("pages.fiches.select_file"))
|
|
|
|
try:
|
|
index_fiche = [str(_("pages.fiches.select_file"))] + noms_fiches
|
|
idx_fiche = index_fiche.index(st.session_state["fiche_choisie"])
|
|
except ValueError:
|
|
idx_fiche = 0
|
|
|
|
st.session_state["fiche_choisie"] = st.selectbox(
|
|
str(_("pages.fiches.choose_file")),
|
|
[str(_("pages.fiches.select_file"))] + noms_fiches,
|
|
index=idx_fiche
|
|
)
|
|
|
|
fiche_choisie = st.session_state["fiche_choisie"]
|
|
|
|
if fiche_choisie and fiche_choisie != str(_("pages.fiches.select_file")):
|
|
fiche_info = next((f for f in fiches if f["nom"] == fiche_choisie), None)
|
|
if fiche_info:
|
|
try:
|
|
headers = {"Authorization": f"token {GITEA_TOKEN}"}
|
|
reponse_fiche = requests.get(fiche_info["download_url"], headers=headers)
|
|
reponse_fiche.raise_for_status()
|
|
md_source = reponse_fiche.text
|
|
|
|
if "seuils" not in st.session_state:
|
|
SEUILS = load_seuils("assets/config.yaml")
|
|
st.session_state["seuils"] = SEUILS
|
|
else:
|
|
SEUILS = st.session_state["seuils"]
|
|
|
|
nom_fiche = os.path.splitext(fiche_choisie)[0]
|
|
html_path = os.path.join("HTML", dossier_choisi, nom_fiche + ".html")
|
|
path_relative = f"Documents/{dossier_choisi}/{fiche_choisie}"
|
|
commits_url = f"{GITEA_URL}/repos/{ORGANISATION}/{DEPOT_FICHES}/commits?path={path_relative}&sha={ENV}"
|
|
|
|
regenerate = doit_regenerer_fiche(
|
|
html_path=html_path,
|
|
fiche_type=fiche_info.get("type", ""),
|
|
fiche_choisie=fiche_choisie,
|
|
commit_url=commits_url,
|
|
fichiers_criticite=FICHES_CRITICITE
|
|
)
|
|
|
|
if regenerate:
|
|
html_path = generer_fiche(md_source, dossier_choisi, fiche_choisie, SEUILS)
|
|
|
|
with open(html_path, encoding="utf-8") as f:
|
|
st.markdown(f.read(), unsafe_allow_html=True)
|
|
|
|
from utils.persistance import get_champ_statut
|
|
if not get_champ_statut("login") == "":
|
|
pdf_name = nom_fiche + ".pdf"
|
|
pdf_path = os.path.join("static", "Fiches", dossier_choisi, pdf_name)
|
|
|
|
if os.path.exists(pdf_path):
|
|
with open(pdf_path, "rb") as pdf_file:
|
|
st.download_button(
|
|
label=str(_("pages.fiches.download_pdf")),
|
|
data=pdf_file,
|
|
file_name=pdf_name,
|
|
mime="application/pdf",
|
|
help=str(_("pages.fiches.download_pdf")),
|
|
key="telecharger_fiche_pdf"
|
|
)
|
|
else:
|
|
st.warning(str(_("pages.fiches.pdf_unavailable")))
|
|
|
|
st.markdown(f"## {str(_('pages.fiches.ticket_management'))}")
|
|
afficher_tickets_par_fiche(rechercher_tickets_gitea(fiche_choisie))
|
|
formulaire_creation_ticket_dynamique(fiche_choisie)
|
|
|
|
except Exception as e:
|
|
st.error(f"{str(_('pages.fiches.loading_error'))} {e}")
|