First_agent_template / tools /dora_ict_asset_log.py
Dave67350's picture
Create dora_ict_asset_log.py
6d2a671 verified
Raw
History Blame Contribute Delete
4.89 kB
# dora_ict_asset_log.py
import datetime
import re
from fpdf import FPDF
from langdetect import detect
import gradio as gr
from tools.common import prepend_metadata_questions
# === PDF Export ===
def export_text_to_pdf(text, metadata=None, output_path=None, language="en"):
if output_path is None:
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
output_path = f"dora_ict_asset_log_{timestamp}.pdf"
pdf = FPDF()
pdf.add_page()
pdf.set_auto_page_break(auto=True, margin=15)
pdf.set_font("Arial", 'B', 16)
pdf.set_text_color(0, 51, 102)
title = "ICT Asset Inventory Log - DORA" if language == "en" else "Inventaire des Actifs TIC - DORA"
pdf.cell(0, 15, title, ln=True, align='C')
pdf.ln(10)
if metadata:
pdf.set_font("Arial", '', 12)
pdf.set_text_color(90, 90, 90)
pdf.multi_cell(0, 10, f"Organization: {metadata.get('organization_name', 'N/A')}")
pdf.multi_cell(0, 10, f"Completed by: {metadata.get('user_name', 'N/A')} ({metadata.get('user_role', 'N/A')})")
pdf.multi_cell(0, 10, f"Timestamp: {metadata.get('timestamp', 'N/A')}")
pdf.ln(5)
pdf.set_font("Arial", '', 12)
pdf.set_text_color(0, 0, 0)
for line in text.strip().split('\n'):
line = line.strip()
if line.startswith("## "):
section = line.replace("## ", "").strip()
pdf.set_font("Arial", 'B', 13)
pdf.set_text_color(30, 30, 120)
pdf.ln(8)
pdf.cell(0, 10, section, ln=True)
pdf.set_font("Arial", '', 12)
pdf.set_text_color(0, 0, 0)
elif line.startswith("- **"):
match = re.match(r"- \*\*(.+?)\*\*: (.+)", line)
if match:
label, value = match.groups()
pdf.set_font("Arial", 'B', 12)
pdf.cell(0, 10, f"{label}:", ln=True)
pdf.set_font("Arial", '', 12)
pdf.multi_cell(0, 10, value)
else:
pdf.multi_cell(0, 10, line)
pdf.output(output_path)
return output_path
# === Questions ===
QUESTIONS = prepend_metadata_questions([
("asset_type", "What type of ICT asset is being logged?"),
("location", "Where is this asset physically or virtually located?"),
("ownership", "Who owns or manages this asset?"),
("usage", "What is the primary usage of this asset?"),
("sensitive_data", "Does this asset process or store sensitive data? If so, specify."),
("security_measures", "What security measures are in place to protect this asset?"),
("maintenance_schedule", "What is the maintenance/update schedule for this asset?"),
("decommission_plan", "What is the decommissioning plan for this asset?")
])
def get_questions():
return QUESTIONS
def run_tool():
state = {"step": 0, "answers": {}}
def step_by_step_agent(user_input, state):
step = state["step"]
answers = state["answers"]
if step > 0:
key, _ = QUESTIONS[step - 1]
answers[key] = user_input
if step < len(QUESTIONS):
next_q = QUESTIONS[step][1]
state["step"] += 1
return next_q, state, None
metadata = {
"user_name": answers.get("user_name", "N/A"),
"user_role": answers.get("user_role", "N/A"),
"organization_name": answers.get("organization_name", "N/A"),
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
content = "\n".join([f"- **{label}**: {answers.get(key, '')}" for key, label in QUESTIONS])
lang = detect(content[:100]) if len(content) > 20 else "en"
pdf_path = export_text_to_pdf(content, metadata=metadata, language=lang)
return "✅ ICT Asset log completed. Download your PDF below.", {"done": True}, pdf_path
with gr.Blocks(title="DORA ICT Asset Inventory") as demo:
chatbot = gr.Chatbot(label="🖥️ ICT Asset Assistant", value=[{"role": "assistant", "content": QUESTIONS[0][1]}], type="messages")
msg = gr.Textbox(label="Your answer")
state_var = gr.State(state)
file_output = gr.File(label="Download PDF")
reset_btn = gr.Button("🔁 Restart")
def chat_logic(msg_in, state_in):
reply, updated_state, file = step_by_step_agent(msg_in, state_in)
messages = [{"role": "user", "content": msg_in}]
if reply:
messages.append({"role": "assistant", "content": reply})
return messages, updated_state, file
def reset():
return [{"role": "assistant", "content": QUESTIONS[0][1]}], {"step": 0, "answers": {}}, None
msg.submit(chat_logic, [msg, state_var], [chatbot, state_var, file_output])
reset_btn.click(reset, outputs=[chatbot, state_var, file_output])
demo.launch(show_api=False)