Spaces:
Running
Running
fix: guarantee 6 top stories with 30-day fallback and regional expansion
Browse files
src/api/routes/top_stories.py
CHANGED
|
@@ -232,16 +232,25 @@ async def fetch_live_stories(n: int = 6, adapter: DuckDuckGoAdapter = None) -> L
|
|
| 232 |
if not adapter:
|
| 233 |
return []
|
| 234 |
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
query = "Ethiopia latest news breaking world"
|
| 238 |
results = await adapter.search(query)
|
| 239 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 240 |
stories = []
|
| 241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 242 |
stories.append(TopStory(
|
| 243 |
title=r.get("title", "Untitled"),
|
| 244 |
-
url=
|
| 245 |
source=r.get("source", "Live News"),
|
| 246 |
published_at=r.get("published_at", datetime.utcnow().isoformat()),
|
| 247 |
category="BREAKING",
|
|
@@ -250,6 +259,7 @@ async def fetch_live_stories(n: int = 6, adapter: DuckDuckGoAdapter = None) -> L
|
|
| 250 |
origin="live",
|
| 251 |
))
|
| 252 |
|
|
|
|
| 253 |
return stories
|
| 254 |
except Exception as e:
|
| 255 |
logger.error(f"Live top stories error: {e}")
|
|
@@ -307,10 +317,14 @@ async def get_top_stories(
|
|
| 307 |
# ββ FALLBACK: If still less than 6, pull from Vector DB (Qdrant) ββββββββββ
|
| 308 |
if len(all_stories) < 6:
|
| 309 |
needed = 6 - len(all_stories)
|
| 310 |
-
logger.info(f"Top stories fallback: pulling {needed} from Vector DB")
|
| 311 |
try:
|
| 312 |
-
|
| 313 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 314 |
payload = p.payload or {}
|
| 315 |
title = payload.get("title") or payload.get("content", "")[:100]
|
| 316 |
url = payload.get("url") or "#"
|
|
@@ -331,6 +345,7 @@ async def get_top_stories(
|
|
| 331 |
except Exception as e:
|
| 332 |
logger.error(f"Top stories DB fallback failed: {e}")
|
| 333 |
|
|
|
|
| 334 |
now_iso = datetime.utcnow().isoformat()
|
| 335 |
final_stories = all_stories[:6]
|
| 336 |
|
|
|
|
| 232 |
if not adapter:
|
| 233 |
return []
|
| 234 |
|
| 235 |
+
# Focus on Ethiopia news
|
| 236 |
+
query = "Ethiopia breaking news latest"
|
|
|
|
| 237 |
results = await adapter.search(query)
|
| 238 |
|
| 239 |
+
# If very few results, try a broader regional search
|
| 240 |
+
if len(results) < 3:
|
| 241 |
+
logger.info("Live search yielded few results, trying broader regional query")
|
| 242 |
+
results += await adapter.search("East Africa breaking news today")
|
| 243 |
+
|
| 244 |
stories = []
|
| 245 |
+
seen_urls = set()
|
| 246 |
+
for r in results:
|
| 247 |
+
url = r.get("url", "#")
|
| 248 |
+
if url in seen_urls: continue
|
| 249 |
+
seen_urls.add(url)
|
| 250 |
+
|
| 251 |
stories.append(TopStory(
|
| 252 |
title=r.get("title", "Untitled"),
|
| 253 |
+
url=url,
|
| 254 |
source=r.get("source", "Live News"),
|
| 255 |
published_at=r.get("published_at", datetime.utcnow().isoformat()),
|
| 256 |
category="BREAKING",
|
|
|
|
| 259 |
origin="live",
|
| 260 |
))
|
| 261 |
|
| 262 |
+
logger.info(f"Live top stories: fetched {len(stories)}")
|
| 263 |
return stories
|
| 264 |
except Exception as e:
|
| 265 |
logger.error(f"Live top stories error: {e}")
|
|
|
|
| 317 |
# ββ FALLBACK: If still less than 6, pull from Vector DB (Qdrant) ββββββββββ
|
| 318 |
if len(all_stories) < 6:
|
| 319 |
needed = 6 - len(all_stories)
|
| 320 |
+
logger.info(f"Top stories fallback: only have {len(all_stories)}, pulling {needed} from Vector DB")
|
| 321 |
try:
|
| 322 |
+
# Try 30 days back to be safe
|
| 323 |
+
db_res = vector_store.browse(limit=needed * 4, days_back=30)
|
| 324 |
+
db_articles = db_res.get("articles", [])
|
| 325 |
+
logger.info(f"Vector DB returned {len(db_articles)} potential fallback articles")
|
| 326 |
+
|
| 327 |
+
for p in db_articles:
|
| 328 |
payload = p.payload or {}
|
| 329 |
title = payload.get("title") or payload.get("content", "")[:100]
|
| 330 |
url = payload.get("url") or "#"
|
|
|
|
| 345 |
except Exception as e:
|
| 346 |
logger.error(f"Top stories DB fallback failed: {e}")
|
| 347 |
|
| 348 |
+
logger.info(f"Final top stories count: {len(all_stories)}")
|
| 349 |
now_iso = datetime.utcnow().isoformat()
|
| 350 |
final_stories = all_stories[:6]
|
| 351 |
|