Spaces:
Sleeping
Sleeping
File size: 4,794 Bytes
6db87f4 5db9ef3 f3aa8db c2bbd91 f3aa8db fe5f164 6db87f4 dce68b5 15cd72a c2bbd91 5db9ef3 d6c2f43 5db9ef3 d6c2f43 8ebc299 d6c2f43 5db9ef3 f3aa8db d6c2f43 fe5f164 d6c2f43 fe5f164 d6c2f43 fe5f164 5db9ef3 d6c2f43 8ebc299 c3f2fbf 8ebc299 cc9ac5d dce68b5 d6c2f43 e09248b 5db9ef3 d6c2f43 5db9ef3 d6c2f43 5db9ef3 d6c2f43 5db9ef3 dce68b5 d6c2f43 fe5f164 d6c2f43 fe5f164 dce68b5 c3f2fbf dce68b5 d6c2f43 fe5f164 dce68b5 fe5f164 d6c2f43 fe5f164 5db9ef3 dce68b5 e09248b fe5f164 5db9ef3 dce68b5 5db9ef3 c2bbd91 dce68b5 c2bbd91 5db9ef3 dce68b5 6db87f4 1258978 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
import gradio as gr
from analyze_email_main import analyze
from weasyprint import HTML
import tempfile
def html_to_pdf(html_content):
"""Convert HTML string to a temporary PDF file and return its path."""
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_pdf:
HTML(string=html_content).write_pdf(tmp_pdf.name)
return tmp_pdf.name
def analyze_email(file_path):
if file_path is None:
return "<p style='color:red;'>Please upload a .eml file to analyze.</p>", None
# Get structured results
summary, details = analyze(file_path)
# Safely extract summary fields
attack_score = summary.get("Attack Score", 0)
try:
score_val = int(round(float(attack_score)))
except Exception:
score_val = 0
score_val = max(0, min(score_val, 100))
attack_type = summary.get("Attack Type", "Unknown")
verdict = summary.get("Final Verdict", "No Verdict")
# Verdict color
verdict_color = "#2ecc71"
v_lower = verdict.lower()
if "malicious" in v_lower:
verdict_color = "#e74c3c"
elif "suspicious" in v_lower:
verdict_color = "#e67e22"
elif "spam" in v_lower:
verdict_color = "#f1c40f"
# Collect details safely
header_findings = details.get("Header Findings", []) or []
body_findings = details.get("Body Findings", []) or []
url_findings = details.get("URL Findings", []) or []
highlighted_body = details.get("Highlighted Body", "") or ""
auth_results = details.get("Auth Results", None)
# Render authentication results safely
if isinstance(auth_results, dict):
auth_html = "<ul>" + "".join(f"<li>{k.upper()}: {v}</li>" for k, v in auth_results.items()) + "</ul>"
elif isinstance(auth_results, str):
auth_html = f"<p>{auth_results}</p>"
else:
auth_html = "<p>No auth results found.</p>"
# Tags
main_tags_str = summary.get("Main Tags", "")
tags = [t.strip() for t in main_tags_str.split(",")] if main_tags_str else []
# HTML Report
html = f"""
<div style='font-family: Arial, sans-serif; padding: 20px; max-width: 900px; margin:auto;'>
<h2 style="color:#2c3e50;">π§ Email Security Report</h2>
<h3 style="margin-bottom:6px;">Attack Score</h3>
<div style="background:#ecf0f1; border-radius:10px; overflow:hidden; height:24px; width:100%; margin-bottom:8px;">
<div style="width:{score_val}%; background:#3498db; height:100%; text-align:center; color:white; line-height:24px;">
{score_val}/100
</div>
</div>
<p><b>Attack Type:</b> {attack_type}</p>
<p><b>Final Verdict:</b> <span style="background:{verdict_color}; color:white; padding:4px 10px; border-radius:6px;">
{verdict}
</span></p>
<details style="margin-top:15px;" open>
<summary>π Attack Analysis Tags ({len(tags)})</summary>
{"<ul>" + "".join(f"<li>{tag}</li>" for tag in tags if tag) + "</ul>" if tags else "<p>No special tags</p>"}
</details>
<details style="margin-top:15px;" open>
<summary>π‘ Authentication Results</summary>
{auth_html}
</details>
<details style="margin-top:15px;" open>
<summary>π΅οΈ Detailed Findings</summary>
<h4>Headers ({len(header_findings)})</h4>
{"<ul>" + "".join(f"<li>{f}</li>" for f in header_findings) + "</ul>" if header_findings else "<p>No header findings.</p>"}
<h4>Body ({len(body_findings)})</h4>
{"<ul>" + "".join(f"<li>{f}</li>" for f in body_findings) + "</ul>" if body_findings else "<p>No body findings.</p>"}
<h4>URLs ({len(url_findings)})</h4>
{"<ul>" + "".join(f"<li>{f}</li>" for f in url_findings) + "</ul>" if url_findings else "<p>No URL findings.</p>"}
</details>
<details style="margin-top:15px;">
<summary>π© Highlighted Email Body</summary>
<div style='border:1px solid #ccc; padding:15px; background:#fdfdfd; border-radius:8px; white-space:pre-wrap;'>
{highlighted_body}
</div>
</details>
</div>
"""
# ALWAYS generate PDF
try:
pdf_path = html_to_pdf(html)
except Exception as e:
pdf_path = None
html += f"<p style='color:#c0392b;'><b>PDF export failed:</b> {e}</p>"
return html, pdf_path
# Gradio Interface (checkbox removed)
demo = gr.Interface(
fn=analyze_email,
inputs=[
gr.File(label="Upload .eml File", type="filepath")
],
outputs=[
gr.HTML(label="Analysis Report"),
gr.File(label="Download PDF Report")
],
title="π§ Email Security Analyzer",
description="Upload an .eml file to detect phishing, spam, or malicious emails. A PDF report will be generated automatically."
)
demo.launch()
|