AdGenesis-App / components /render_analysis.py
userIdc2024's picture
Update components/render_analysis.py
3a70dec verified
import json, pandas as pd, streamlit as st
from typing import Dict, Any
from helpers_function.helpers import _mean_effectiveness
def _normalize_list(v):
if v is None: return []
if isinstance(v, list): return [str(x) for x in v]
return [s for s in str(v).splitlines() if s.strip()]
def _to_dataframe(items, columns_map):
import pandas as pd
if not isinstance(items, list) or not items:
return pd.DataFrame(columns=list(columns_map.values()))
df = pd.DataFrame(items).rename(columns=columns_map)
ordered_cols = [columns_map[k] for k in columns_map.keys() if columns_map[k] in df.columns]
return df.reindex(columns=ordered_cols)
def _search_dataframe(df, query):
if not query or df.empty: return df
mask = df.apply(lambda col: col.astype(str).str.contains(query, case=False, na=False))
return df[mask.any(axis=1)]
def render_analyzer_results(analysis: Dict[str, Any]) -> None:
if not isinstance(analysis, dict) or not analysis:
st.warning("No analysis available."); return
st.markdown(
"""<style>
.metric-card{background:#0f172a;padding:14px 16px;border-radius:14px;border:1px solid #1f2937}
.label{font-size:12px;color:#94a3b8;margin-bottom:6px}
.value{font-size:16px;color:#e2e8f0}
</style>""",
unsafe_allow_html=True,
)
va = analysis.get("video_analysis", {}) or {}
storyboard = analysis.get("storyboard", []) or []
script = analysis.get("script", []) or []
metrics = va.get("video_metrics", []) or []
mean_score = _mean_effectiveness(metrics)
m1,m2,m3,m4 = st.columns([1,1,1,1])
m1.markdown(f'<div class="metric-card"><div class="label">Scenes</div><div class="value">{len(storyboard)}</div></div>', unsafe_allow_html=True)
m2.markdown(f'<div class="metric-card"><div class="label">Dialogue Lines</div><div class="value">{len(script)}</div></div>', unsafe_allow_html=True)
m3.markdown(f'<div class="metric-card"><div class="label">Avg Effectiveness</div><div class="value">{mean_score}/10</div></div>', unsafe_allow_html=True)
m4.markdown(f'<div class="metric-card"><div class="label">Improvements</div><div class="value">{len(analysis.get("timestamp_improvements", []) or [])}</div></div>', unsafe_allow_html=True)
colA, colB = st.columns([1.3,1])
with colA:
st.markdown("### Executive Summary")
c1,c2 = st.columns(2)
with c1:
with st.expander("Brief", expanded=True): st.write(analysis.get("brief", "N/A"))
with st.expander("Caption Details", expanded=False): st.write(analysis.get("caption_details", "N/A"))
with c2:
hook = analysis.get("hook", {}) or {}
with st.expander("Hook", expanded=True):
st.markdown(f"**Opening:** {hook.get('hook_text','N/A')}")
st.markdown(f"**Principle:** {hook.get('principle','N/A')}")
adv = _normalize_list(hook.get("advantages"))
if adv:
st.markdown("**Advantages:**")
st.markdown("\n".join([f"- {a}" for a in adv]))
st.divider()
st.markdown("### Narrative & Copy Frameworks")
with st.expander("Framework Analysis", expanded=True): st.write(analysis.get("framework_analysis", "N/A"))
with colB:
st.markdown("### Snapshot")
st.caption("Top Drivers"); st.markdown(f'{va.get("effectiveness_factors","N/A")}</div>', unsafe_allow_html=True)
st.markdown(""); st.caption("Psychological Triggers"); st.markdown(f'{va.get("psychological_triggers","N/A")}</div>', unsafe_allow_html=True)
st.markdown(""); st.caption("Target Audience"); st.markdown(f'{va.get("target_audience","N/A")}</div>', unsafe_allow_html=True)
st.divider()
tabs = st.tabs(["Storyboard","Script","Scored Metrics","Improvements","Raw JSON"])
with tabs[0]:
q = st.text_input("Search storyboard")
if storyboard:
df = _to_dataframe(
storyboard,
{"timeline":"Timeline","scene":"Scene","visuals":"Visuals","dialogue":"Dialogue","camera":"Camera","sound_effects":"Sound Effects"}
)
st.dataframe(_search_dataframe(df, q), width='stretch', height=480)
else:
st.info("No storyboard available.")
with tabs[1]:
q2 = st.text_input("Search script")
if script:
df = _to_dataframe(script, {"timeline":"Timeline","dialogue":"Dialogue"})
st.dataframe(_search_dataframe(df, q2), width='stretch', height=480)
else:
st.info("No script breakdown available.")
with tabs[2]:
q3 = st.text_input("Search metrics")
if metrics:
dfm = _to_dataframe(
metrics,
{"timestamp":"Timestamp","element":"Element","current_approach":"Current Approach","effectiveness_score":"Effectiveness Score","notes":"Notes"}
)
st.dataframe(_search_dataframe(dfm, q3), width='stretch', height=480)
else:
st.info("No video metrics available.")
with tabs[3]:
improvements = analysis.get("timestamp_improvements", []) or []
q4 = st.text_input("Search improvements")
if improvements:
imp_df = _to_dataframe(
improvements,
{"timestamp":"Timestamp","current_element":"Current Element","improvement_type":"Improvement Type",
"recommended_change":"Recommended Change","expected_impact":"Expected Impact","priority":"Priority"}
)
if "Priority" in imp_df.columns:
order = pd.CategoricalDtype(["High","Medium","Low"], ordered=True)
imp_df["Priority"] = imp_df["Priority"].astype(order)
if "Timestamp" in imp_df.columns:
imp_df = imp_df.sort_values(["Priority","Timestamp"])
st.dataframe(_search_dataframe(imp_df, q4), width='stretch', height=480)
else:
st.info("No timestamp-based improvements available.")
with tabs[4]:
res = json.dumps(analysis, indent=2, ensure_ascii=False)
st.code(res, language="json")
st.download_button(
"Download JSON",
data=res.encode("utf-8"),
file_name="ad_analysis.json",
mime="application/json",
width='stretch'
)