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( """""", 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'
Scenes
{len(storyboard)}
', unsafe_allow_html=True) m2.markdown(f'
Dialogue Lines
{len(script)}
', unsafe_allow_html=True) m3.markdown(f'
Avg Effectiveness
{mean_score}/10
', unsafe_allow_html=True) m4.markdown(f'
Improvements
{len(analysis.get("timestamp_improvements", []) or [])}
', 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")}', unsafe_allow_html=True) st.markdown(""); st.caption("Psychological Triggers"); st.markdown(f'{va.get("psychological_triggers","N/A")}', unsafe_allow_html=True) st.markdown(""); st.caption("Target Audience"); st.markdown(f'{va.get("target_audience","N/A")}', 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' )