Firemedic15 commited on
Commit
667fb71
·
verified ·
1 Parent(s): b5299d1

Upload 7 files

Browse files
Files changed (2) hide show
  1. app.py +43 -13
  2. tools.py +21 -3
app.py CHANGED
@@ -144,21 +144,34 @@ Today's date: {datetime.utcnow().strftime('%Y-%m-%d')}
144
  # ---------------------------------------------------------------------------
145
 
146
  RSS_SOURCE_OPTIONS = [
147
- ("BBC World", "bbc_world"),
148
- ("Al Jazeera", "al_jazeera"),
149
- ("NPR World", "npr_world"),
150
- ("Sky News", "sky_news"),
151
- ("Middle East Eye", "middle_east_eye"),
152
- ("Bellingcat", "bellingcat"),
153
- ("Crisis Group", "crisis_group"),
154
- ("Radio Free Asia", "radio_free_asia"),
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  ]
156
 
157
  EXAMPLE_QUERIES = [
158
- ["Sudan", ["bbc_world", "al_jazeera", "middle_east_eye"], 14],
159
- ["Myanmar", ["bbc_world", "crisis_group", "radio_free_asia"], 21],
160
- ["Ukraine", ["bbc_world", "npr_world", "sky_news"], 7],
161
- ["Haiti", ["bbc_world", "al_jazeera", "npr_world"], 14],
162
  ]
163
 
164
  CSS = """
@@ -191,9 +204,12 @@ with gr.Blocks(title="OSINT Threat Analyst", css=CSS, theme=gr.themes.Soft()) as
191
  max_lines=1,
192
  )
193
 
 
 
 
194
  rss_sources = gr.CheckboxGroup(
195
  choices=RSS_SOURCE_OPTIONS,
196
- value=["bbc_world", "al_jazeera", "npr_world"],
197
  label="RSS News Sources",
198
  )
199
 
@@ -254,6 +270,20 @@ with gr.Blocks(title="OSINT Threat Analyst", css=CSS, theme=gr.themes.Soft()) as
254
  label="Example Queries",
255
  )
256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  analyze_btn.click(
258
  fn=run_analysis,
259
  inputs=[country_input, rss_sources, days_back],
 
144
  # ---------------------------------------------------------------------------
145
 
146
  RSS_SOURCE_OPTIONS = [
147
+ # General world news
148
+ ("BBC World", "bbc_world"),
149
+ ("Al Jazeera", "al_jazeera"),
150
+ ("France 24", "france24"),
151
+ ("NPR World", "npr_world"),
152
+ ("Sky News", "sky_news"),
153
+ ("UN News", "un_news"),
154
+ # Regional / specialist
155
+ ("Middle East Eye", "middle_east_eye"),
156
+ ("Radio Free Asia", "radio_free_asia"),
157
+ # OSINT / investigative
158
+ ("Bellingcat", "bellingcat"),
159
+ ("The Intercept", "the_intercept"),
160
+ ("OCCRP", "occrp"),
161
+ # Policy / security analysis
162
+ ("Crisis Group", "crisis_group"),
163
+ ("War on the Rocks", "war_on_rocks"),
164
+ ("Just Security", "just_security"),
165
+ # Human rights
166
+ ("Human Rights Watch", "hrw"),
167
+ ("Amnesty Intl", "amnesty"),
168
  ]
169
 
170
  EXAMPLE_QUERIES = [
171
+ ["Sudan", ["bbc_world", "al_jazeera", "middle_east_eye", "hrw"], 14],
172
+ ["Myanmar", ["bbc_world", "crisis_group", "radio_free_asia", "hrw"], 21],
173
+ ["Ukraine", ["bbc_world", "npr_world", "sky_news", "war_on_rocks"], 7],
174
+ ["Haiti", ["bbc_world", "al_jazeera", "un_news", "amnesty"], 14],
175
  ]
176
 
177
  CSS = """
 
204
  max_lines=1,
205
  )
206
 
207
+ with gr.Row():
208
+ select_all_btn = gr.Button("Deselect All", size="sm", scale=1)
209
+
210
  rss_sources = gr.CheckboxGroup(
211
  choices=RSS_SOURCE_OPTIONS,
212
+ value=[v for _, v in RSS_SOURCE_OPTIONS], # all selected by default
213
  label="RSS News Sources",
214
  )
215
 
 
270
  label="Example Queries",
271
  )
272
 
273
+ _ALL_SOURCE_KEYS = [v for _, v in RSS_SOURCE_OPTIONS]
274
+
275
+ def toggle_sources(current_values):
276
+ """Select all if any are unchecked; deselect all if all are checked."""
277
+ if len(current_values) == len(_ALL_SOURCE_KEYS):
278
+ return gr.update(value=[]), gr.update(value="Select All")
279
+ return gr.update(value=_ALL_SOURCE_KEYS), gr.update(value="Deselect All")
280
+
281
+ select_all_btn.click(
282
+ fn=toggle_sources,
283
+ inputs=[rss_sources],
284
+ outputs=[rss_sources, select_all_btn],
285
+ )
286
+
287
  analyze_btn.click(
288
  fn=run_analysis,
289
  inputs=[country_input, rss_sources, days_back],
tools.py CHANGED
@@ -177,14 +177,32 @@ def fetch_acled_events(country: str, days_back: int = 14, limit: int = 25) -> st
177
 
178
  RSS_FEED_REGISTRY = {
179
  # Verified working as of 2026-05
 
 
180
  "bbc_world": "https://feeds.bbci.co.uk/news/world/rss.xml",
181
  "al_jazeera": "https://www.aljazeera.com/xml/rss/all.xml",
182
- "bellingcat": "https://www.bellingcat.com/feed/",
183
- "crisis_group": "https://www.crisisgroup.org/rss.xml",
184
  "npr_world": "https://feeds.npr.org/1004/rss.xml",
185
- "middle_east_eye": "https://www.middleeasteye.net/rss",
186
  "sky_news": "https://feeds.skynews.com/feeds/rss/world.xml",
 
 
 
 
187
  "radio_free_asia": "https://www.rfa.org/english/rss2.xml",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  }
189
 
190
  SCAN_LIMIT = 50
 
177
 
178
  RSS_FEED_REGISTRY = {
179
  # Verified working as of 2026-05
180
+
181
+ # --- General world news ---
182
  "bbc_world": "https://feeds.bbci.co.uk/news/world/rss.xml",
183
  "al_jazeera": "https://www.aljazeera.com/xml/rss/all.xml",
184
+ "france24": "https://www.france24.com/en/rss",
 
185
  "npr_world": "https://feeds.npr.org/1004/rss.xml",
 
186
  "sky_news": "https://feeds.skynews.com/feeds/rss/world.xml",
187
+ "un_news": "https://news.un.org/feed/subscribe/en/news/all/rss.xml",
188
+
189
+ # --- Regional / specialist ---
190
+ "middle_east_eye": "https://www.middleeasteye.net/rss",
191
  "radio_free_asia": "https://www.rfa.org/english/rss2.xml",
192
+
193
+ # --- OSINT / investigative ---
194
+ "bellingcat": "https://www.bellingcat.com/feed/",
195
+ "the_intercept": "https://theintercept.com/feed/?rss",
196
+ "occrp": "https://www.occrp.org/en/component/rssfeed/index.xml",
197
+
198
+ # --- Policy / security analysis ---
199
+ "crisis_group": "https://www.crisisgroup.org/rss.xml",
200
+ "war_on_rocks": "https://warontherocks.com/feed/",
201
+ "just_security": "https://www.justsecurity.org/feed/",
202
+
203
+ # --- Human rights ---
204
+ "hrw": "https://www.hrw.org/rss.xml",
205
+ "amnesty": "https://www.amnesty.org/en/feed/",
206
  }
207
 
208
  SCAN_LIMIT = 50