Spaces:
Running
Running
Replace video slider with featured news carousel on homepage (no extra fetch, instant)
Browse files
app.py
CHANGED
|
@@ -391,35 +391,6 @@ def _bdp_relates(soup):
|
|
| 391 |
rels.append({"title":t,"link":h})
|
| 392 |
return rels[:5]
|
| 393 |
|
| 394 |
-
# ββ Video aggregator βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 395 |
-
def fetch_latest_videos():
|
| 396 |
-
"""Fetch latest videos from BDP carousel + 24h highlights for the homepage slider."""
|
| 397 |
-
videos = []
|
| 398 |
-
# BDP carousel
|
| 399 |
-
try:
|
| 400 |
-
soup = _get(f"{BASE_BDP}/video")
|
| 401 |
-
first_link = None
|
| 402 |
-
for a in soup.find_all("a", href=True):
|
| 403 |
-
href = a.get("href", "")
|
| 404 |
-
if "/video/" in href and re.search(r'-\d{6,}\.html', href):
|
| 405 |
-
first_link = href if href.startswith("http") else BASE_BDP + href; break
|
| 406 |
-
if first_link:
|
| 407 |
-
vid_id = _extract_bdp_video_id(first_link)
|
| 408 |
-
if vid_id:
|
| 409 |
-
embed = fetch_bdp_embed_data(vid_id)
|
| 410 |
-
if embed:
|
| 411 |
-
for rel in embed.get("related", []):
|
| 412 |
-
videos.append({"title": rel["title"], "link": rel["link"], "img": rel["poster"], "source": "bdp"})
|
| 413 |
-
except: pass
|
| 414 |
-
# 24h highlights
|
| 415 |
-
try:
|
| 416 |
-
h24 = scrape_24h_video_list()[:10]
|
| 417 |
-
for a in h24:
|
| 418 |
-
if a.get("img"):
|
| 419 |
-
videos.append({"title": a["title"], "link": a["link"], "img": a["img"], "source": "24h"})
|
| 420 |
-
except: pass
|
| 421 |
-
return videos[:20]
|
| 422 |
-
|
| 423 |
def fetch_video_list():
|
| 424 |
"""Fetch videos from BDP + 24h combined."""
|
| 425 |
bdp_videos = scrape_bdp_video_list()
|
|
@@ -525,24 +496,35 @@ def read_article(url):
|
|
| 525 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 526 |
# HTML RENDERERS
|
| 527 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 528 |
-
|
| 529 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 530 |
items = []
|
| 531 |
-
for i,
|
| 532 |
-
img = safe_url(
|
| 533 |
-
link =
|
| 534 |
-
title =
|
| 535 |
-
aid = make_id(link)
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
|
| 541 |
items.append(f'''<div class="vslide-item" onclick="{click_js}">
|
| 542 |
-
<div class="vslide-thumb"><img src="{img}" alt="" class="bdp-lazy-img">
|
|
|
|
| 543 |
<p class="vslide-title">{title}</p></div>''')
|
| 544 |
return f'''<div class="vslide-wrap">
|
| 545 |
-
<div class="vslide-header"><span class="vslide-label">
|
| 546 |
<div class="vslide-nav"><button class="vslide-btn" onclick="window.bdpSlideScroll(-1)">β</button>
|
| 547 |
<button class="vslide-btn" onclick="window.bdpSlideScroll(1)">βΆ</button></div></div>
|
| 548 |
<div class="vslide-track" id="vslide-track">{''.join(items)}</div></div>'''
|
|
@@ -550,12 +532,10 @@ def render_video_slider_html(videos):
|
|
| 550 |
def render_homepage_html(articles):
|
| 551 |
if not articles: return "<p class='bdp-empty'>KhΓ΄ng tΓ¬m thαΊ₯y tin tα»©c.</p>"
|
| 552 |
now=datetime.now().strftime("%H:%M:%S %d/%m/%Y")
|
| 553 |
-
|
| 554 |
-
except: videos = []
|
| 555 |
-
slider_html = render_video_slider_html(videos)
|
| 556 |
groups={}
|
| 557 |
for a in articles: groups.setdefault(a.get("group","KhΓ‘c"),[]).append(a)
|
| 558 |
-
parts=[f'<div class="bdp-wrap">{
|
| 559 |
for gn in ["Thα»i Sα»±","ThαΊΏ Giα»i","Kinh Doanh","CΓ΄ng Nghα»","Thα» Thao","GiαΊ£i TrΓ","BΓ³ng ΔΓ‘"]:
|
| 560 |
arts=groups.get(gn,[])
|
| 561 |
if not arts: continue
|
|
|
|
| 391 |
rels.append({"title":t,"link":h})
|
| 392 |
return rels[:5]
|
| 393 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 394 |
def fetch_video_list():
|
| 395 |
"""Fetch videos from BDP + 24h combined."""
|
| 396 |
bdp_videos = scrape_bdp_video_list()
|
|
|
|
| 496 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 497 |
# HTML RENDERERS
|
| 498 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 499 |
+
|
| 500 |
+
def render_featured_carousel_html(articles):
|
| 501 |
+
"""Carousel tin nα»i bαΊt + mα»i nhαΊ₯t, lαΊ₯y tα»« articles ΔΓ£ fetch sαΊ΅n (khΓ΄ng fetch thΓͺm)."""
|
| 502 |
+
# LαΊ₯y bΓ i featured cΓ³ αΊ£nh, Ζ°u tiΓͺn bΓ i ΔαΊ§u mα»i nhΓ³m
|
| 503 |
+
top = []
|
| 504 |
+
seen = set()
|
| 505 |
+
for a in articles:
|
| 506 |
+
if a.get("img") and a.get("link","#") != "#" and a["link"] not in seen:
|
| 507 |
+
top.append(a)
|
| 508 |
+
seen.add(a["link"])
|
| 509 |
+
if len(top) >= 15: break
|
| 510 |
+
if not top: return ""
|
| 511 |
items = []
|
| 512 |
+
for i, a in enumerate(top):
|
| 513 |
+
img = safe_url(a.get("img",""))
|
| 514 |
+
link = a.get("link","#")
|
| 515 |
+
title = a.get("title","")
|
| 516 |
+
aid = make_id(link); sl = slug(title)
|
| 517 |
+
grp = a.get("group","")
|
| 518 |
+
src = a.get("source","")
|
| 519 |
+
badge_cls = "vslide-badge-vne" if src=="vne" else "vslide-badge-bdp" if src=="bdp" else "vslide-badge-24h"
|
| 520 |
+
badge_txt = grp or ("VnExpress" if src=="vne" else "BDP" if src=="bdp" else "24h")
|
| 521 |
+
click_js = f"window.bdpOpen('{esc(link)}','{aid}','{sl}')"
|
| 522 |
items.append(f'''<div class="vslide-item" onclick="{click_js}">
|
| 523 |
+
<div class="vslide-thumb"><img src="{img}" alt="" class="bdp-lazy-img">
|
| 524 |
+
<span class="vslide-badge {badge_cls}">{badge_txt}</span></div>
|
| 525 |
<p class="vslide-title">{title}</p></div>''')
|
| 526 |
return f'''<div class="vslide-wrap">
|
| 527 |
+
<div class="vslide-header"><span class="vslide-label">π₯ Tin Nα»i BαΊt</span>
|
| 528 |
<div class="vslide-nav"><button class="vslide-btn" onclick="window.bdpSlideScroll(-1)">β</button>
|
| 529 |
<button class="vslide-btn" onclick="window.bdpSlideScroll(1)">βΆ</button></div></div>
|
| 530 |
<div class="vslide-track" id="vslide-track">{''.join(items)}</div></div>'''
|
|
|
|
| 532 |
def render_homepage_html(articles):
|
| 533 |
if not articles: return "<p class='bdp-empty'>KhΓ΄ng tΓ¬m thαΊ₯y tin tα»©c.</p>"
|
| 534 |
now=datetime.now().strftime("%H:%M:%S %d/%m/%Y")
|
| 535 |
+
carousel_html = render_featured_carousel_html(articles)
|
|
|
|
|
|
|
| 536 |
groups={}
|
| 537 |
for a in articles: groups.setdefault(a.get("group","KhΓ‘c"),[]).append(a)
|
| 538 |
+
parts=[f'<div class="bdp-wrap">{carousel_html}<div class="bdp-topbar"><span>β± {now}</span><span>π° Tin nα»i bαΊt</span></div>']
|
| 539 |
for gn in ["Thα»i Sα»±","ThαΊΏ Giα»i","Kinh Doanh","CΓ΄ng Nghα»","Thα» Thao","GiαΊ£i TrΓ","BΓ³ng ΔΓ‘"]:
|
| 540 |
arts=groups.get(gn,[])
|
| 541 |
if not arts: continue
|