import streamlit as st
import re
# Configuration Gitea
from config import INSTRUCTIONS
from utils.gitea import (
charger_instructions_depuis_gitea
)
# Import du module de traductions
from utils.translations import init_translations, _, set_language
def afficher_instructions_avec_expanders(markdown_content):
"""
Affiche le contenu markdown avec les sections de niveau 2 (## Titre) dans des expanders
"""
# Extraction du titre principal (niveau 1)
titre_pattern = r'^# (.+)$'
titre_match = re.search(titre_pattern, markdown_content, re.MULTILINE)
# Affichage du titre principal
if titre_match:
titre_principal = titre_match.group(1)
st.markdown(f"# {titre_principal}")
# Division en sections de niveau 2
sections = re.split(r'^## ', markdown_content, flags=re.MULTILINE)
# Affichage du contenu avant la première section de niveau 2 (sans le titre principal)
introduction = sections[0]
if titre_match:
# Supprimer le titre principal de l'introduction car on l'a déjà affiché
introduction = re.sub(titre_pattern, '', introduction, flags=re.MULTILINE).strip()
if introduction:
st.markdown(introduction, unsafe_allow_html=True)
# Affichage des sections dans des expanders
for i, section in enumerate(sections[1:], 1):
# Extraction du titre de la section
lignes = section.split('\n', 1)
titre_section = lignes[0].strip()
# Garder le titre dans le contenu
contenu_section = f"## {titre_section}"
if len(lignes) > 1:
contenu_section += "\n\n" + lignes[1].strip()
# Affichage dans un expander
status = True if i == 1 else False
with st.expander(f"## {titre_section}", expanded=status):
st.markdown(contenu_section, unsafe_allow_html=True)
from utils.graph_utils import (
charger_graphe
)
from components.sidebar import (
afficher_menu,
afficher_impact
)
from components.header import afficher_entete
from components.footer import afficher_pied_de_page
from app.fiches import interface_fiches
from app.visualisations import interface_visualisations
from app.personnalisation import interface_personnalisation
from app.analyse import interface_analyse
st.set_page_config(
page_title="Fabnum – Analyse de chaîne",
page_icon="assets/weakness.png", # ajout
layout="centered",
initial_sidebar_state="expanded"
)
# Initialisation des traductions (langue française par défaut)
init_translations()
# Pour tester d'autres langues, décommenter cette ligne :
set_language("fr")
session_id = st.context.headers.get("x-session-id")
def get_total_bytes_for_session(session_id):
total_bytes = 0
try:
with open("/var/log/nginx/fabnum-dev.access.log", "r") as f:
for line in f:
if session_id in line:
match = re.search(r'"GET.*?" \d+ (\d+)', line)
if match:
bytes_sent = int(match.group(1))
total_bytes += bytes_sent
except Exception as e:
st.error(f"Erreur lecture log: {e}")
return total_bytes
def charger_theme():
# Chargement des fichiers CSS (une seule fois)
if "base_css_content" not in st.session_state:
with open("assets/styles/base.css") as f:
st.session_state["base_css_content"] = f.read()
if "theme_css_content_light" not in st.session_state:
with open("assets/styles/theme-light.css") as f:
st.session_state["theme_css_content_light"] = f.read()
if "theme_css_content_dark" not in st.session_state:
with open("assets/styles/theme-dark.css") as f:
st.session_state["theme_css_content_dark"] = f.read()
# Mappage des noms traduits vers les noms internes
theme_mapping = {
"clair": "light",
"sombre": "dark",
"light": "light",
"dark": "dark"
}
# Thème en cours (conversion du nom traduit vers l'identifiant interne)
current_theme_display = st.session_state.get("theme_mode", "Clair").lower()
current_theme = theme_mapping.get(current_theme_display, "light") # Par défaut light si non trouvé
theme_css = st.session_state[f"theme_css_content_{current_theme}"]
# Injection des CSS dans le bon ordre
# 1. D'abord les variables du thème
st.markdown(f"", unsafe_allow_html=True)
# 2. Ensuite le CSS de base
st.markdown(f"", unsafe_allow_html=True)
def ouvrir_page():
charger_theme()
afficher_entete()
afficher_menu()
st.markdown("""
""", unsafe_allow_html=True)
def fermer_page():
st.markdown("", unsafe_allow_html=True)
st.markdown("""""", unsafe_allow_html=True)
st.markdown("", unsafe_allow_html=True)
total_bytes = get_total_bytes_for_session(session_id)
afficher_pied_de_page()
afficher_impact(total_bytes)
ouvrir_page()
dot_file_path = None
# Obtenir les noms traduits des onglets
instructions_tab = _("navigation.instructions")
fiches_tab = _("navigation.fiches")
personnalisation_tab = _("navigation.personnalisation")
analyse_tab = _("navigation.analyse")
visualisations_tab = _("navigation.visualisations")
if st.session_state.onglet == instructions_tab:
markdown_content = charger_instructions_depuis_gitea(INSTRUCTIONS)
if markdown_content:
afficher_instructions_avec_expanders(markdown_content)
elif st.session_state.onglet == fiches_tab:
interface_fiches()
else:
# Charger le graphe une seule fois
# Le graphe n'est pas nécessaire pour Instructions ou Fiches
G_temp, G_temp_ivc, dot_file_path = charger_graphe()
if dot_file_path and st.session_state.onglet == analyse_tab:
interface_analyse(G_temp)
elif dot_file_path and st.session_state.onglet == visualisations_tab:
interface_visualisations(G_temp, G_temp_ivc)
elif dot_file_path and st.session_state.onglet == personnalisation_tab:
G_temp = interface_personnalisation(G_temp)
fermer_page()