194 lines
6.2 KiB
Python
194 lines
6.2 KiB
Python
import streamlit as st
|
||
|
||
st.set_page_config(
|
||
page_title="Fabnum – Analyse de chaîne",
|
||
page_icon="assets/weakness.png", # ajout
|
||
layout="centered",
|
||
initial_sidebar_state="expanded"
|
||
)
|
||
|
||
import re
|
||
|
||
# Configuration Gitea
|
||
from config import INSTRUCTIONS, ENV
|
||
|
||
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
|
||
|
||
# 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")
|
||
|
||
#
|
||
# Important
|
||
# Avec Selinux, il faut mettre les bons droits :
|
||
#
|
||
# sudo semanage fcontext -a -t var_log_t '/var/log/nginx/fabnum-public\.access\.log'
|
||
# sudo restorecon -v /var/log/nginx/fabnum-public.access.log
|
||
#
|
||
def get_total_bytes_for_session(session_id):
|
||
total_bytes = 0
|
||
try:
|
||
with open(f"/var/log/nginx/fabnum-{ENV}.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"<style>{theme_css}</style>", unsafe_allow_html=True)
|
||
# 2. Ensuite le CSS de base
|
||
st.markdown(f"<style>{st.session_state['base_css_content']}</style>", unsafe_allow_html=True)
|
||
|
||
def ouvrir_page():
|
||
charger_theme()
|
||
afficher_entete()
|
||
afficher_menu()
|
||
st.markdown("""
|
||
<main role="main">
|
||
""", unsafe_allow_html=True)
|
||
|
||
def fermer_page():
|
||
st.markdown("</div>", unsafe_allow_html=True)
|
||
st.markdown("""</section>""", unsafe_allow_html=True)
|
||
st.markdown("</main>", 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()
|