OpenData-Bordeaux-IA-RSE / export_doc.py
Ilyas KHIAT
emission export fin fin
fb9bb4a
import streamlit as st
import markdown2
import pdfkit
from io import BytesIO
from IPython.display import display, FileLink
import base64
from langchain_core.messages import AIMessage, HumanMessage
from datetime import datetime
from download_chart import construct_plot
from kaleido.scopes.plotly import PlotlyScope
import pandas as pd
import markdown
from comparateur import get_table_empreintes_detailed
from empreinte_export import get_carbon_footprint_html
def colored_circle(color):
return f'<span style="display: inline-block; width: 15px; height: 15px; border-radius: 50%; background-color: {color};"></span>'
def list_to_markdown(lst):
return "\n".join([f'<p>{colored_circle(item["color"])} <b>{item["name"]}</b>: Pouvoir:{item["y"]}% Influence:{item["x"]}%</p>' for item in lst[:20]])
def categorize(row):
if 50 <= row['pouvoir'] <= 100 and 0 <= row['influence'] < 50:
return 'Rendre satisfait'
elif 50 <= row['pouvoir'] <= 100 and 50 <= row['influence'] <= 100:
return 'Gérer étroitement'
elif 0 <= row['pouvoir'] < 50 and 0 <= row['influence'] < 50:
return 'Suivre de près'
elif 0 <= row['pouvoir'] < 50 and 50 <= row['influence'] <= 100:
return 'Tenir informé'
else:
return 'Non catégorisé'
@st.cache_data
def convert_pp_to_csv(pp_grouped):
if pp_grouped is None or len(pp_grouped) == 0:
st.error("Aucune partie prenante n'a été définie")
return None
pp_df = pd.DataFrame(pp_grouped)
pp_df.index.name = 'N°'
pp_df.rename(columns={"name": "parties prenantes", "x": "influence", "y": "pouvoir"}, inplace=True)
pp_df.drop(columns=['color'], inplace=True)
# Apply the function to the DataFrame to create a new column 'categorie'
pp_df['categorie'] = pp_df.apply(categorize, axis=1)
pp_df = pp_df[["parties prenantes","categorie", "pouvoir", "influence"]]
pp_df.rename_axis('N°', axis=1)
return pp_df.to_csv(index=True,encoding="utf-8")
@st.cache_data
def create_pdf_from_markdown(logo_path, conversation,summary,brand_name,graph_html,app_url,list_pps,used_models=None):
# Convertir la conversation en markdown
markdown_text = "\n".join([f"### {entry['speaker']}:\n {entry['text']}\n ---" for entry in conversation])
if not used_models:
used_models = ["Aucun modèle IA n'a été utilisé"]
html_used_models = "".join([f"<p>{model}</p>" for model in used_models])
markdown_summary = f"{summary}\n --- \n ---"
markdown_list_pps = list_to_markdown(list_pps)
# Convertir le markdown en HTML
html_content = markdown.markdown(markdown_text,extensions=['markdown.extensions.tables'])
html_summary = markdown2.markdown(markdown_summary)
html_list_pps = markdown2.markdown(markdown_list_pps)
analysis_date = datetime.now().strftime("%Y-%m-%d")
# image_base64 = base64.b64encode(image_path).decode('utf-8')
graph_html.update_layout(showlegend=False)
img_bytes = PlotlyScope().transform(
figure=graph_html,
format="png",
)
fig1 = f"data:image/png;base64,{base64.b64encode(img_bytes).decode('utf8')}"
# Créer le HTML complet avec les images et le texte
html_template = f"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Cartographie des parties prenantes {brand_name}</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
<style>
body {{
font-family: 'Roboto', sans-serif;
margin: 20px;
}}
h1, h2, h3, h4, h5, h6 {{
font-weight: bold;
}}
.page-break {{
page-break-before: always;
margin: 50px;
height: 50px;
}}
</style>
</head>
<body>
<div style="text-align: center;">
<h1>Cartographie des parties prenantes "{brand_name}"</h1>
<p>Date de l'analyse IA RSE : {analysis_date}</p>
<p>IA utilisées :</p>
{html_used_models}
<img src="{logo_path}" alt="Logo" style="width: 150px;"/>
</div>
<div class="page-break"></div>
<div style="text-align: center; margin-top: 20px;">
<img src="{fig1}">
</div>
{html_list_pps}
<div class="page-break"></div>
<h2>RESUME</h2>
{html_summary}
<div class="page-break"></div>
<h2>Historique de la Conversation</h2>
{html_content}
<div class="page-break"></div>
{get_carbon_footprint_html()}
</body>
</html>
"""
with open("temp.html", "w",encoding="utf-8") as f:
f.write(html_template)
# Create the footer HTML with the logo and app_url
footer_html = f"""
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
<meta charset="UTF-8">
<style>
body {{
font-family: 'Roboto', sans-serif;
margin-top: 20px;
}}
.footer {{
width: 100%;
font-size: 16px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 20px;
}}
.footer img {{
width: 100px;
vertical-align: middle;
margin-bottom: 0px;
padding-bottom: 0px;
}}
.footer .center-text {{
text-align: center;
}}
.footer .page-number {{
text-align: right;
}}
.footer a {{
color: #0000EE;
text-decoration: none;
}}
.page {{
font-weight: bold;
font-size: 10px;
margin-bottom: 0px;
padding-bottom: 0px;
}}
</style>
</head>
<body>
<div class="footer">
<img src="{logo_path}" alt="Logo" />
<div class="center-text">
bziiit | Open data & IA RSE | <a href="{app_url}">{app_url}</a>
</div>
<div class="page-number">
<span class="page"></span>
</div>
</div>
</body>
</html>
"""
# Save the footer HTML to a temporary file
with open("footer.html", "w",encoding="utf-8") as f:
f.write(footer_html)
# Convert HTML to PDF with header and footer
pdf = pdfkit.from_file("temp.html", options={
'footer-html': 'footer.html',
'footer-right': '[page]/[toPage]',
'footer-font-size': '10',
'footer-spacing': '5',
'footer-line': True,
'margin-top': '5',
})
return pdf
def get_conversation():
conversation = []
for message in st.session_state.chat_history:
if isinstance(message, AIMessage):
conversation.append({"speaker": "AI", "text": message.content})
elif isinstance(message, HumanMessage):
conversation.append({"speaker": "Moi", "text": message.content})
return conversation
def export_conversation(summary,used_models=None):
brand_name = st.session_state["Nom de la marque"]
app_url = "https://huggingface.co/spaces/bziiit/OpenData-Bordeaux-RSE"
logo_path = "https://static.wixstatic.com/media/d7d3da_b69e03ae99224f7d8b6e358918e60071~mv2.png/v1/crop/x_173,y_0,w_1906,h_938/fill/w_242,h_119,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/BZIIIT_LOGO-HORIZ-COULEUR.png" # Replace with your image path
list_pps = st.session_state['pp_grouped']
with st.spinner("Génération du PDF..."):
conversation = get_conversation()
image_path = "newplot.png"
try:
graph = construct_plot()
# graph = graph.to_html(full_html=False, include_plotlyjs='cdn')
except Exception as e:
st.error("Erreur lors de la génération de la cartographie")
graph = ""
try:
pdf = create_pdf_from_markdown(logo_path=logo_path, conversation=conversation,summary=summary,brand_name=brand_name,graph_html=graph,app_url=app_url,list_pps=list_pps,used_models=used_models)
except Exception as e:
pdf = None
if pdf:
st.success("PDF généré avec succès!}")
else:
st.error("Erreur lors de la génération du PDF")
return pdf