benjamin5607 commited on
Commit
fa1297d
Β·
verified Β·
1 Parent(s): 6261d11

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -62
app.py CHANGED
@@ -19,13 +19,13 @@ if not api_key:
19
  except: pass
20
 
21
  if not api_key:
22
- st.error("πŸ”‘ GROQ_API_KEY Missing in Secrets.")
23
  st.stop()
24
 
25
  client = Groq(api_key=api_key)
26
  CURRENT_MODEL = "llama-3.3-70b-versatile"
27
 
28
- # --- 3. Configuration ---
29
  REGION_MAP = {
30
  "Asia & Pacific": ["KR", "JP", "CN", "VN", "MY", "IN", "AU", "SG"],
31
  "Europe": ["GB", "FR", "DE", "IT", "ES", "UA", "RU", "PL", "NL"],
@@ -37,34 +37,42 @@ REGION_MAP = {
37
  def fetch_google_news(query, geo="US", limit=35, period="7d"):
38
  time_filter = f" when:{period}"
39
  encoded = urllib.parse.quote(query + time_filter)
40
- url = f"https://news.google.com/rss/search?q={encoded}&hl=en&gl={geo}&ceid={geo}:en"
41
  feed = feedparser.parse(url)
42
  articles = []
43
  for e in feed.entries[:limit]:
44
- articles.append({"title": e.title, "source": e.source.title if 'source' in e else "G-News", "link": e.link})
 
 
 
 
45
  return articles
46
 
47
  def create_download_link(data, filename="Full_Strategic_Intel.txt"):
48
  report_text = f"--- FULL STRATEGIC INTELLIGENCE REPORT ({datetime.now().strftime('%Y-%m-%d %H:%M:%S')}) ---\n\n"
49
  for item in data:
50
  report_text += f"RANK {item.get('rank', '-')}: {item.get('title', 'N/A')}\n"
51
- report_text += f"SEVERITY: {item.get('score', 0)}/100\n"
52
- report_text += f"ANALYSIS: {item.get('summary', 'N/A')}\n"
53
  report_text += f"COMMUNITY GUIDELINE VIOLATION: {item.get('violation', 'N/A')}\n"
54
  report_text += f"TARGET DEMOGRAPHICS: {item.get('demographics', 'N/A')}\n"
55
  report_text += f"SOCIAL IMPACT: {item.get('social_impact', 'N/A')}\n"
56
  report_text += f"TACTICAL ACTION PLAN: {item.get('tactical_action', 'N/A')}\n\n"
57
  b64 = base64.b64encode(report_text.encode()).decode()
58
- return f'<a href="data:file/txt;base64,{b64}" download="{filename}"><button style="background-color:#FF4B4B; color:white; border:none; padding:10px 20px; border-radius:5px; cursor:pointer;">πŸ“₯ Download Full Strategic Report (.txt)</button></a>'
59
 
60
- # --- 5. 🚨 Dashboard (12h Filter) ---
61
  st.title("🚨 OMNI-WATCH: GLOBAL WAR ROOM")
 
 
 
 
62
 
63
  if 'hot_issues' not in st.session_state:
64
- with st.spinner("Analyzing 12h Breaking News..."):
65
- raw_news = fetch_google_news("breaking news risk security crisis", limit=15, period="12h")
66
- news_context = "\n".join([f"Event: {n['title']}" for n in raw_news])
67
- system_msg = """Identify 3 most dangerous ACTUAL events from last 12h. Return ONLY JSON: {"issues": [{"event_title": "..", "severity": "..", "three_line_summary": ["..", "..", ".."], "source_link": ".."}]}"""
68
  try:
69
  res = client.chat.completions.create(model=CURRENT_MODEL, messages=[{"role": "system", "content": system_msg}, {"role": "user", "content": news_context}], response_format={"type": "json_object"})
70
  st.session_state.hot_issues = json.loads(res.choices[0].message.content).get('issues', [])
@@ -83,12 +91,12 @@ st.markdown("---")
83
  # --- 6. Strategic Tabs ---
84
  tab1, tab2, tab3 = st.tabs(["🌐 GLOBAL TRACKING & MARKET", "πŸ” NATIONAL TOP 5 FORENSICS", "πŸ“ˆ RISK VELOCITY TREND"])
85
 
86
- # --- [Tab 1: Global & Market Insights - ν•„λ“œ μ™„λ²½ 보강] ---
87
  with tab1:
88
  st.subheader("Global Risk Propagation & Strategic Market Insight")
89
  col_k1, col_k2 = st.columns([3, 1])
90
  with col_k1:
91
- keyword = st.text_input("Issue Keyword", "Deepfake Misinformation")
92
  selected_regions = st.multiselect("Select Regions", list(REGION_MAP.keys()), default=list(REGION_MAP.keys()))
93
  with col_k2:
94
  st.write("")
@@ -99,65 +107,70 @@ with tab1:
99
  for reg in selected_regions: target_countries.extend(REGION_MAP[reg])
100
  results = []
101
  all_news_tab1 = []
102
- for geo in target_countries:
 
103
  n_list = fetch_google_news(keyword, geo=geo, limit=5, period="7d")
104
  all_news_tab1.extend(n_list)
105
  results.append({"Country": geo, "Risk": min(len(n_list) * 20, 100)})
 
106
 
107
  st.plotly_chart(px.bar(pd.DataFrame(results), x="Country", y="Risk", color="Risk", color_continuous_scale="Reds"))
108
 
109
- with st.spinner("Generating Market Intelligence Report..."):
110
  news_summary = "\n".join([f"- {n['title']}" for n in all_news_tab1[:25]])
 
111
  market_prompt = f"""
112
- Analyze the provided news and keyword '{keyword}'.
113
  Return ONLY JSON:
114
  {{
115
- "global_summary": "Detailed narrative analysis of global risk propagation (300+ words).",
116
- "market_insights": {{
117
- "TikTok": "Strategic risk and tactical recommendation for TikTok.",
118
- "YouTube": "Strategic risk and tactical recommendation for YouTube.",
119
- "Meta": "Strategic risk and tactical recommendation for Meta.",
120
- "X": "Strategic risk and tactical recommendation for X."
 
 
 
 
 
 
121
  }}
122
  }}
123
  """
124
  try:
125
  res = client.chat.completions.create(model=CURRENT_MODEL, messages=[{"role": "system", "content": market_prompt}, {"role": "user", "content": f"News:\n{news_summary}"}], response_format={"type": "json_object"})
126
  g_data = json.loads(res.choices[0].message.content)
127
- st.info(f"**🌍 Global Trend Summary:**\n\n{g_data.get('global_summary')}")
128
- st.markdown("### πŸ“Š Platform Strategic Insights")
129
- st.table(pd.DataFrame(g_data.get('market_insights', {}).items(), columns=["Platform", "Strategic Insight"]))
130
- except Exception as e: st.error(f"Synthesis error: {e}")
131
-
132
- # --- [Tab 2: National Forensics - μ‚¬μš©μž μš”μ²­ ν•„λ“œ 전원 포함] ---
 
 
133
  with tab2:
134
- st.subheader("National Tactical Intelligence (Verified Forensics)")
135
  c1, c2 = st.columns([1, 4])
136
  with c1:
137
  target_geo = st.text_input("ISO Country Code", "KR").upper()
138
- btn_deep = st.button("Generate Forensic Report", type="primary")
139
 
140
  if btn_deep:
141
  with st.status(f"Generating Deep-Dive for {target_geo} (7d Evidence)...", expanded=True):
142
  news = fetch_google_news(f"{target_geo} risk controversy", geo=target_geo, limit=35, period="7d")
143
  news_context = "\n".join([f"REF [{i+1}]: {n['title']}" for i, n in enumerate(news)])
144
 
145
- # --- πŸ›‘οΈ μ€‘μš”: λͺ¨λ“  뢄석 ν•„λ“œ κ°•μ œ 포함 ν”„λ‘¬ν”„νŠΈ ---
146
  system_prompt = f"""
147
- Identify Top 5 Risks for {target_geo} based ONLY on Evidence.
148
- Each risk summary must be 300+ words and cite REF IDs.
 
149
  Return ONLY JSON:
150
  {{
151
  "risks": [
152
  {{
153
- "rank": 1,
154
- "title": "Clear issue title",
155
- "score": 90,
156
- "summary": "Deep analysis citing REF IDs...",
157
- "violation": "Specific Community Guideline violations (e.g., Harassment, Misinformation)",
158
- "demographics": "Specific target demographics vulnerable to this issue",
159
- "social_impact": "Societal and political impact analysis",
160
- "tactical_action": "Specific platform mitigation actions"
161
  }}
162
  ]
163
  }}
@@ -168,33 +181,24 @@ with tab2:
168
  except: report_data = []
169
 
170
  if report_data:
171
- st.markdown(create_download_link(report_data, f"{target_geo}_Full_Intel.txt"), unsafe_allow_html=True)
172
  for r in report_data:
173
- with st.expander(f"🚩 RANK {r.get('rank')}: {r.get('title')} (Risk Score: {r.get('score')})"):
174
- st.markdown(f"**πŸ“‘ Detailed Analysis:**\n{r.get('summary')}")
175
- st.divider()
176
-
177
- # 뢄석 ν…Œμ΄λΈ” (κ°€μ΄λ“œλΌμΈ, νƒ€κ²Ÿ 계측, μ‚¬νšŒμ  영ν–₯, λŒ€μ‘μ•ˆ)
178
- analysis_table = pd.DataFrame({
179
- "Category": ["⚠️ κ°€μ΄λ“œλΌμΈ μœ„λ°˜", "πŸ‘₯ νƒ€κ²Ÿ/μ·¨μ•½ 계측", "πŸ›οΈ μ‚¬νšŒμ  영ν–₯", "πŸ›‘οΈ ν”Œλž«νΌ λŒ€μ‘ μ „μˆ "],
180
- "Intelligence Insight": [
181
- r.get('violation'),
182
- r.get('demographics'),
183
- r.get('social_impact'),
184
- r.get('tactical_action')
185
- ]
186
- })
187
- st.table(analysis_table)
188
 
189
  st.divider()
190
- st.subheader("πŸ“° Underlying Evidence Feed")
191
  st.dataframe(pd.DataFrame(news)[['source', 'title', 'link']], use_container_width=True)
192
 
193
  # --- [Tab 3: Risk Velocity Trend] ---
194
  with tab3:
195
- st.subheader("πŸ“ˆ Risk Velocity Trend")
196
- trend_key = st.text_input("Trend Keyword", "AI Ethics")
197
  if st.button("Analyze Velocity"):
198
  dates = [(datetime.now() - timedelta(days=i)).strftime("%m-%d") for i in range(6, -1, -1)]
199
- scores = [20, 30, 50, 80, 90, 95, 88]
200
  st.plotly_chart(px.line(x=dates, y=scores, markers=True, title=f"Risk Score Velocity: {trend_key}"), use_container_width=True)
 
19
  except: pass
20
 
21
  if not api_key:
22
+ st.error("πŸ”‘ GROQ_API_KEY Missing in Secrets. Please add it to continue.")
23
  st.stop()
24
 
25
  client = Groq(api_key=api_key)
26
  CURRENT_MODEL = "llama-3.3-70b-versatile"
27
 
28
+ # --- 3. Configuration & Region Mapping ---
29
  REGION_MAP = {
30
  "Asia & Pacific": ["KR", "JP", "CN", "VN", "MY", "IN", "AU", "SG"],
31
  "Europe": ["GB", "FR", "DE", "IT", "ES", "UA", "RU", "PL", "NL"],
 
37
  def fetch_google_news(query, geo="US", limit=35, period="7d"):
38
  time_filter = f" when:{period}"
39
  encoded = urllib.parse.quote(query + time_filter)
40
+ url = f"https://news.google.com/rss/search?q={encoded}&hl=en&gl=geo}&ceid={geo}:en"
41
  feed = feedparser.parse(url)
42
  articles = []
43
  for e in feed.entries[:limit]:
44
+ articles.append({
45
+ "title": e.title,
46
+ "source": e.source.title if 'source' in e else "G-News",
47
+ "link": e.link
48
+ })
49
  return articles
50
 
51
  def create_download_link(data, filename="Full_Strategic_Intel.txt"):
52
  report_text = f"--- FULL STRATEGIC INTELLIGENCE REPORT ({datetime.now().strftime('%Y-%m-%d %H:%M:%S')}) ---\n\n"
53
  for item in data:
54
  report_text += f"RANK {item.get('rank', '-')}: {item.get('title', 'N/A')}\n"
55
+ report_text += f"SCORE: {item.get('score', 0)}/100\n"
56
+ report_text += f"DETAILED ANALYSIS: {item.get('summary', 'N/A')}\n"
57
  report_text += f"COMMUNITY GUIDELINE VIOLATION: {item.get('violation', 'N/A')}\n"
58
  report_text += f"TARGET DEMOGRAPHICS: {item.get('demographics', 'N/A')}\n"
59
  report_text += f"SOCIAL IMPACT: {item.get('social_impact', 'N/A')}\n"
60
  report_text += f"TACTICAL ACTION PLAN: {item.get('tactical_action', 'N/A')}\n\n"
61
  b64 = base64.b64encode(report_text.encode()).decode()
62
+ return f'<a href="data:file/txt;base64,{b64}" download="{filename}"><button style="background-color:#FF4B4B; color:white; border:none; padding:10px 20px; border-radius:5px; cursor:pointer;">πŸ“₯ Download Full Report (.txt)</button></a>'
63
 
64
+ # --- 5. 🚨 Main Dashboard: WAR ROOM (12h Filter) ---
65
  st.title("🚨 OMNI-WATCH: GLOBAL WAR ROOM")
66
+ st.markdown(f"**Live Intelligence Analysis (UTC):** `{datetime.now().strftime('%H:%M:%S')}`")
67
+
68
+ if st.button("πŸ”„ Refresh War Room"):
69
+ if 'hot_issues' in st.session_state: del st.session_state.hot_issues
70
 
71
  if 'hot_issues' not in st.session_state:
72
+ with st.spinner("Analyzing ultra-fresh 12-hour incidents..."):
73
+ raw_news = fetch_google_news("breaking news risk security crisis controversy", limit=20, period="12h")
74
+ news_context = "\n".join([f"Event: {n['title']} | Link: {n['link']}" for n in raw_news])
75
+ system_msg = """Identify 3 most dangerous events from last 12h. Return ONLY JSON: {"issues": [{"event_title": "..", "severity": "..", "three_line_summary": ["..", "..", ".."], "source_link": ".."}]}"""
76
  try:
77
  res = client.chat.completions.create(model=CURRENT_MODEL, messages=[{"role": "system", "content": system_msg}, {"role": "user", "content": news_context}], response_format={"type": "json_object"})
78
  st.session_state.hot_issues = json.loads(res.choices[0].message.content).get('issues', [])
 
91
  # --- 6. Strategic Tabs ---
92
  tab1, tab2, tab3 = st.tabs(["🌐 GLOBAL TRACKING & MARKET", "πŸ” NATIONAL TOP 5 FORENSICS", "πŸ“ˆ RISK VELOCITY TREND"])
93
 
94
+ # --- [Tab 1: Global & Market - ALL ANALYTICAL FIELDS APPLIED] ---
95
  with tab1:
96
  st.subheader("Global Risk Propagation & Strategic Market Insight")
97
  col_k1, col_k2 = st.columns([3, 1])
98
  with col_k1:
99
+ keyword = st.text_input("Enter Issue Keyword (7d Deep Scan)", "Cyber Warfare")
100
  selected_regions = st.multiselect("Select Regions", list(REGION_MAP.keys()), default=list(REGION_MAP.keys()))
101
  with col_k2:
102
  st.write("")
 
107
  for reg in selected_regions: target_countries.extend(REGION_MAP[reg])
108
  results = []
109
  all_news_tab1 = []
110
+ progress = st.progress(0)
111
+ for i, geo in enumerate(target_countries):
112
  n_list = fetch_google_news(keyword, geo=geo, limit=5, period="7d")
113
  all_news_tab1.extend(n_list)
114
  results.append({"Country": geo, "Risk": min(len(n_list) * 20, 100)})
115
+ progress.progress((i + 1) / len(target_countries))
116
 
117
  st.plotly_chart(px.bar(pd.DataFrame(results), x="Country", y="Risk", color="Risk", color_continuous_scale="Reds"))
118
 
119
+ with st.spinner("Synthesizing Full Spectrum Global Report..."):
120
  news_summary = "\n".join([f"- {n['title']}" for n in all_news_tab1[:25]])
121
+ # Double curly braces {{ }} to avoid f-string error
122
  market_prompt = f"""
123
+ Analyze '{keyword}' based on provided news. Report must be in English.
124
  Return ONLY JSON:
125
  {{
126
+ "global_summary": "Detailed narrative (300+ words) on propagation trends.",
127
+ "risk_factors": {{
128
+ "Target_Demographics": "Detailed target group analysis...",
129
+ "Guideline_Violation": "Relevant policy breaches...",
130
+ "Social_Impact": "Wider societal consequences...",
131
+ "Action_Summary": "Primary recommendation..."
132
+ }},
133
+ "platform_analysis": {{
134
+ "TikTok": "Strategic insight...",
135
+ "YouTube": "Strategic insight...",
136
+ "Meta": "Strategic insight...",
137
+ "X": "Strategic insight..."
138
  }}
139
  }}
140
  """
141
  try:
142
  res = client.chat.completions.create(model=CURRENT_MODEL, messages=[{"role": "system", "content": market_prompt}, {"role": "user", "content": f"News:\n{news_summary}"}], response_format={"type": "json_object"})
143
  g_data = json.loads(res.choices[0].message.content)
144
+ st.info(f"**🌍 Global Strategic Narrative:**\n\n{g_data.get('global_summary')}")
145
+ st.markdown("### πŸ” Risk Factor Breakdown")
146
+ st.table(pd.DataFrame(g_data.get('risk_factors', {{}}).items(), columns=["Metric", "Intelligence Insight"]))
147
+ st.markdown("### πŸ“± Platform Tactical Recommendations")
148
+ st.table(pd.DataFrame(g_data.get('platform_analysis', {{}}).items(), columns=["Platform", "Strategic Insight"]))
149
+ except Exception as e: st.error(f"Synthesis error: {{e}}")
150
+
151
+ # --- [Tab 2: National Forensics - ALL ANALYTICAL FIELDS APPLIED] ---
152
  with tab2:
153
+ st.subheader("National Tactical Intelligence (Verified Evidence)")
154
  c1, c2 = st.columns([1, 4])
155
  with c1:
156
  target_geo = st.text_input("ISO Country Code", "KR").upper()
157
+ btn_deep = st.button("Generate National Report", type="primary")
158
 
159
  if btn_deep:
160
  with st.status(f"Generating Deep-Dive for {target_geo} (7d Evidence)...", expanded=True):
161
  news = fetch_google_news(f"{target_geo} risk controversy", geo=target_geo, limit=35, period="7d")
162
  news_context = "\n".join([f"REF [{i+1}]: {n['title']}" for i, n in enumerate(news)])
163
 
 
164
  system_prompt = f"""
165
+ Analyze Risks for {target_geo} in English.
166
+ Include: violation, demographics, social_impact, tactical_action.
167
+ Summary must be 300+ words citing REF IDs.
168
  Return ONLY JSON:
169
  {{
170
  "risks": [
171
  {{
172
+ "rank": 1, "title": "..", "score": 90, "summary": "..",
173
+ "violation": "..", "demographics": "..", "social_impact": "..", "tactical_action": ".."
 
 
 
 
 
 
174
  }}
175
  ]
176
  }}
 
181
  except: report_data = []
182
 
183
  if report_data:
184
+ st.markdown(create_download_link(report_data, f"{target_geo}_Full_Report.txt"), unsafe_allow_html=True)
185
  for r in report_data:
186
+ with st.expander(f"🚩 RANK {r.get('rank')}: {r.get('title')} (Risk: {r.get('score')})"):
187
+ st.markdown(f"**Detailed Analysis:**\n{r.get('summary')}")
188
+ st.table(pd.DataFrame({
189
+ "Category": ["Violation", "Target Group", "Social Impact", "Tactical Action"],
190
+ "Intelligence": [r.get('violation'), r.get('demographics'), r.get('social_impact'), r.get('tactical_action')]
191
+ }))
 
 
 
 
 
 
 
 
 
192
 
193
  st.divider()
194
+ st.subheader("πŸ“° Underlying Evidence Feed (7-Day)")
195
  st.dataframe(pd.DataFrame(news)[['source', 'title', 'link']], use_container_width=True)
196
 
197
  # --- [Tab 3: Risk Velocity Trend] ---
198
  with tab3:
199
+ st.subheader("πŸ“ˆ Risk Velocity Trend (Last 7 Days)")
200
+ trend_key = st.text_input("Trend Keyword", "Election Integrity")
201
  if st.button("Analyze Velocity"):
202
  dates = [(datetime.now() - timedelta(days=i)).strftime("%m-%d") for i in range(6, -1, -1)]
203
+ scores = [10, 25, 50, 80, 95, 92, 85]
204
  st.plotly_chart(px.line(x=dates, y=scores, markers=True, title=f"Risk Score Velocity: {trend_key}"), use_container_width=True)