bep40 commited on
Commit
2d4dd0f
·
verified ·
1 Parent(s): 81ec5f2

Upload main.py

Browse files
Files changed (1) hide show
  1. main.py +39 -45
main.py CHANGED
@@ -63,9 +63,9 @@ _cache_ttl_yt = 1800
63
  SHORTS_FALLBACK = [
64
  {"id":"nqlLH6chLRo","title":"Tin nóng VTV Nam Bộ | #shorts","channel":"vtvnambo"},
65
  {"id":"E7Kq0v3hG6w","title":"VTV Nam Bộ - Tin tức miền Nam | #shorts","channel":"vtvnambo"},
66
- {"id":"Lu_iCQ5YwNM","title":"Công an lập hồ sơ xử lý người phụ nữ chửi bới tát nam tài xế ô tô Hà Nội","channel":"baodantri7941"},
67
  {"id":"CwWvijF8BOA","title":"Chú rể Ninh Bình bật khóc nhận món quà bí mật người cha quá cố gửi 26 năm trước","channel":"baodantri7941"},
68
- {"id":"tvPewsc2ph4","title":"Tính năng ẩn trên iPhone giúp giảm mỏi mắt","channel":"baodantri7941"},
69
  {"id":"b1Nxzv9ixlU","title":"Y án 3 năm tù với nữ tài xế uống 8 lon bia lái xe tông chủ tịch xã tử vong","channel":"baodantri7941"},
70
  {"id":"Xp5eTwAZAis","title":"Người đánh hàng xóm tại chung cư ở Hà Nội bị tuyên hơn 4 tháng tù","channel":"baodantri7941"},
71
  {"id":"Htzvwg6iOBM","title":"Xe điện Audi S6 Sportback e-tron có gì đặc biệt?","channel":"baodantri7941"},
@@ -75,24 +75,24 @@ SHORTS_FALLBACK = [
75
  {"id":"VAfgNNgZDRs","title":"Khởi tố 4 đối tượng ném bom xăng vào nhà dân ở Đồng Nai","channel":"baodantri7941"},
76
  {"id":"sBH_-zGh0Xw","title":"Vì sao Times New Roman vẫn nổi tiếng sau hàng chục năm?","channel":"baodantri7941"},
77
  {"id":"woKn5f2bLHM","title":"Quảng Ninh ngập sâu diện rộng sau đợt mưa lớn","channel":"baodantri7941"},
78
- {"id":"bcpgRoxbLPw","title":"Giông lốc quật bay mái tôn TP.HCM","channel":"baodantri7941"},
79
  {"id":"ZIIC5osy544","title":"Bé trai Trung Quốc rơi từ tầng 11 vẫn sống sót kỳ diệu","channel":"baodantri7941"},
80
- {"id":"uTMJ49NQpyc","title":"Sau lớp mascot 40kg Câu chuyện mưu sinh của người trẻ ở TPHCM","channel":"baodantri7941"},
81
- {"id":"7Pd6vZ2Lz1M","title":"Hành động ấm lòng của người đàn ông tìm kiếm 5 học sinh tử vong sông Lô","channel":"baosuckhoedoisongboyte"},
82
  {"id":"SlHLt_ZyPiE","title":"Xử phạt người đàn ông xóa số điện thoại cứu hộ trên cao tốc Bắc Nam","channel":"baosuckhoedoisongboyte"},
83
- {"id":"IUOprcJyYr4","title":"Phụ nữ táo bón có phải do lười ăn rau?","channel":"baosuckhoedoisongboyte"},
84
- {"id":"YY8ojFNE-AU","title":"Quái xế tự quay clip nẹt pô đánh võng đăng TikTok bị xử lý","channel":"baosuckhoedoisongboyte"},
85
  {"id":"OV7_oGdQGII","title":"Bố cô dâu khóc sụt sùi rồi quẩy cực sung gây bão mạng","channel":"baosuckhoedoisongboyte"},
86
- {"id":"FoxhFyz2skY","title":"Người đàn ông nước ngoài đập phá ô tô bẻ cần gạt nước ở Đà Nẵng","channel":"baosuckhoedoisongboyte"},
87
- {"id":"R1oC_I8dFPU","title":"Thanh niên buông tay lái đứng trên xe máy khi đổ đèo ở Đắk Lắk","channel":"baosuckhoedoisongboyte"},
88
- {"id":"U0Ft6ChWAIo","title":"Cô giáo kể phút tháo chạy khỏi xe khách trước khi bị vò nát ở Cao Bằng","channel":"baosuckhoedoisongboyte"},
89
  {"id":"hH0ANeze_4E","title":"Liên tiếp hàng chục con bò bị sét đánh chết trong ngày mưa dông","channel":"baosuckhoedoisongboyte"},
90
  {"id":"pXWt0QbAzRQ","title":"Va chạm giao thông người phụ nữ lăng mạ tài xế ô tô","channel":"baosuckhoedoisongboyte"},
91
- {"id":"UWWLPY1OYt4","title":"CSGT chặn xe khách khống chế đối tượng cướp dây chuyền tại Gia Lai","channel":"baosuckhoedoisongboyte"},
92
  {"id":"AxhVTQutsuo","title":"Xuất tinh sớm và những hiểu lầm thường gặp","channel":"baosuckhoedoisongboyte"},
93
  {"id":"cNy6FgaNxYM","title":"Cô dâu khóc sưng mắt vì 6 chỉ vàng không cánh mày bay trong ngày cưới","channel":"baosuckhoedoisongboyte"},
94
  {"id":"IDt_S6q59Ro","title":"Chở bạn gái không đội mũ bảo hiểm thanh niên đấm CSGT","channel":"baosuckhoedoisongboyte"},
95
- {"id":"LFxJ9Ik6W0A","title":"Mệnh lệnh từ trái tim CSGT Hà Nội mở đường đưa bé 5 tháng tuổi đi cấp cứu","channel":"baosuckhoedoisongboyte"},
96
  ]
97
  for _v in SHORTS_FALLBACK:
98
  _v.setdefault("link", "https://www.youtube.com/watch?v="+_v["id"])
@@ -119,10 +119,10 @@ def _short_default(): return {"views":0,"likes":0,"shares":0,"comments":[]}
119
  PRIORITY_LEAGUES = ["Ngoại Hạng Anh","FA Cup","Champions League","LaLiga","Copa del Rey","Serie A","Bundesliga","Ligue 1","V-League"]
120
  LEAGUE_IDS = {"nha":27110,"laliga":27233,"seriea":27044,"bundesliga":26891,"ligue1":27212}
121
  HL_LEAGUES = {
122
- "premier-league":{"path":"anh/premier-league","name":"Premier League","emoji":"🏴󠁧󠁢󠁥󠁮󠁧󠁿"},
123
- "fa-cup":{"path":"anh/fa-cup","name":"FA Cup","emoji":"🏆"},
124
  "bundesliga":{"path":"duc/bundesliga","name":"Bundesliga","emoji":"🇩🇪"},
125
- "serie-a":{"path":"italy/serie-a","name":"Serie A","emoji":"🇮🇹"},
126
  "la-liga":{"path":"tay-ban-nha/la-liga","name":"La Liga","emoji":"🇪🇸"},
127
  "champions-league":{"path":"cup-chau-au/uefa-champions-league","name":"Champions League","emoji":"⭐"},
128
  "europa-league":{"path":"cup-chau-au/uefa-europa-league","name":"Europa League","emoji":"🟠"},
@@ -222,7 +222,7 @@ def proxy_img(url: str = Query(...)):
222
  def _scrape_xemlaibongda_page(page_path, limit=20):
223
  """
224
  Scrape video từ xemlaibongda.top - Simple & Reliable
225
- Dùng logic cũ đã test, không fetch từng trang (tránh timeout)
226
  """
227
  try:
228
  url = f"https://xemlaibongda.top/{page_path}" if page_path else "https://xemlaibongda.top/"
@@ -242,7 +242,7 @@ def _scrape_xemlaibongda_page(page_path, limit=20):
242
  if not href.startswith("http"):
243
  href = "https://xemlaibongda.top" + href
244
 
245
- # Bỏ query params
246
  clean_href = href.split("?")[0].split("#")[0]
247
  if clean_href in seen:
248
  continue
@@ -312,7 +312,7 @@ def _scrape_xemlaibongda_page(page_path, limit=20):
312
  if text and len(text) >= 5:
313
  title = text[:100]
314
 
315
- # Fallback: tạo title từ slug
316
  if not title or len(title) < 3:
317
  slug = clean_href.split("/video/")[-1].rstrip("/").split("/xem-lai/")[-1].rstrip("/")
318
  title = slug.replace("-", " ").replace("_", " ").title()
@@ -342,7 +342,7 @@ def _scrape_xemlaibongda_page(page_path, limit=20):
342
  return []
343
 
344
  def _extract_img_src(a_tag):
345
- """Extract image URL từ thẻ <a> và parent elements"""
346
  img = a_tag.find("img")
347
  if not img and a_tag.parent:
348
  img = a_tag.parent.find("img")
@@ -418,7 +418,7 @@ def _extract_title(a_tag, href):
418
  if alt and len(alt) >= 3:
419
  return alt
420
 
421
- # 4. Thử text content của <a> (loại bỏ quá dài)
422
  text = a_tag.get_text(" ", strip=True)
423
  if text and len(text) >= 3:
424
  # Lấy dòng đầu tiên nếu có nhiều dòng
@@ -504,30 +504,24 @@ def _yt_channel_shorts_requests(channel, count=15):
504
  except: return []
505
 
506
  def scrape_shorts():
507
- """Scrape Dantri + SKĐS shorts - optimized with cache fallback"""
508
- # Try to get fresh shorts, but use cached if scrape fails
509
- vids = []
510
- try:
511
- # Import with timeout protection
512
- from yt_scraper import get_vtvnambo_shorts
513
- vids = get_vtvnambo_shorts(30)
514
- except Exception as e:
515
- print(f"scrape_shorts error: {e}")
516
-
517
- # Cache successful result first - then fallback if needed
518
- // Always use fallback if no videos - ensures homepage never breaks
519
- if not vids:
520
- cached = _cached("yt_shorts_fallback")
521
- if cached:
522
- return cached
523
- # Static fallback
524
- vids = [v for v in SHORTS_FALLBACK]
525
-
526
- # Cache the result
527
- _cache["yt_shorts_v3"] = {"d": vids, "t": time.time()}
528
- _cache["yt_shorts_fallback"] = {"d": vids, "t": time.time()}
529
-
530
- return vids
531
 
532
  # ===== VTV NAM BO & WC SHORTS - using yt-dlp =====
533
  from yt_scraper import get_vtvnambo_shorts, get_wc_related_shorts
@@ -731,7 +725,7 @@ def api_bdp_videos():
731
  return JSONResponse(_cached("bdp_videos",_f))
732
 
733
  # ===== NEWS =====
734
- VNE_CATS={"thoi-su":("https://vnexpress.net/thoi-su","Thời Sự"),"the-gioi":("https://vnexpress.net/the-gioi","Thế Giới"),"kinh-doanh":("https://vnexpress.net/kinh-doanh","Kinh Doanh"),"the-thao":("https://vnexpress.net/the-thao","Thể Thao"),"giai-tri":("https://vnexpress.net/giai-tri","Giải Trí"),"suc-khoe":("https://vnexpress.net/suc-khoe","Sức Khỏe"),"phap-luat":("https://vnexpress.net/phap-luat","Pháp Luật"),"giao-duc":("https://vnexpress.net/giao-duc","Giáo Dục"),"du-lich":("https://vnexpress.net/du-lich","Du Lịch"),"doi-song":("https://vnexpress.net/doi-song","Đời Sống")}
735
 
736
  def scrape_vne(cat_url):
737
  try:
 
63
  SHORTS_FALLBACK = [
64
  {"id":"nqlLH6chLRo","title":"Tin nóng VTV Nam Bộ | #shorts","channel":"vtvnambo"},
65
  {"id":"E7Kq0v3hG6w","title":"VTV Nam Bộ - Tin tức miền Nam | #shorts","channel":"vtvnambo"},
66
+ {"id":"Lu_iCQ5YwNM","title":"Công an lập h� sơ xử lý người phụ nữ chửi bới tát nam tài xế ô tô Hà Nội","channel":"baodantri7941"},
67
  {"id":"CwWvijF8BOA","title":"Chú rể Ninh Bình bật khóc nhận món quà bí mật người cha quá cố gửi 26 năm trước","channel":"baodantri7941"},
68
+ {"id":"tvPewsc2ph4","title":"Tính năng �n trên iPhone giúp giảm m�i m�t","channel":"baodantri7941"},
69
  {"id":"b1Nxzv9ixlU","title":"Y án 3 năm tù với nữ tài xế uống 8 lon bia lái xe tông chủ tịch xã tử vong","channel":"baodantri7941"},
70
  {"id":"Xp5eTwAZAis","title":"Người đánh hàng xóm tại chung cư ở Hà Nội bị tuyên hơn 4 tháng tù","channel":"baodantri7941"},
71
  {"id":"Htzvwg6iOBM","title":"Xe điện Audi S6 Sportback e-tron có gì đặc biệt?","channel":"baodantri7941"},
 
75
  {"id":"VAfgNNgZDRs","title":"Khởi tố 4 đối tượng ném bom xăng vào nhà dân ở Đồng Nai","channel":"baodantri7941"},
76
  {"id":"sBH_-zGh0Xw","title":"Vì sao Times New Roman vẫn nổi tiếng sau hàng chục năm?","channel":"baodantri7941"},
77
  {"id":"woKn5f2bLHM","title":"Quảng Ninh ngập sâu diện rộng sau đợt mưa lớn","channel":"baodantri7941"},
78
+ {"id":"bcpgRoxbLPw","title":"Giông lốc quật bay mái tôn TP.HCM","channel":"baodantri7941"},
79
  {"id":"ZIIC5osy544","title":"Bé trai Trung Quốc rơi từ tầng 11 vẫn sống sót kỳ diệu","channel":"baodantri7941"},
80
+ {"id":"uTMJ49NQpyc","title":"Sau lớp mascot 40kg Câu chuyện mưu sinh của người tr� ở TPHCM","channel":"baodantri7941"},
81
+ {"id":"7Pd6vZ2Lz1M","title":"Hành động ấm lòng của người đàn ông tìm kiếm 5 học sinh tử vong sông Lô","channel":"baosuckhoedoisongboyte"},
82
  {"id":"SlHLt_ZyPiE","title":"Xử phạt người đàn ông xóa số điện thoại cứu hộ trên cao tốc Bắc Nam","channel":"baosuckhoedoisongboyte"},
83
+ {"id":"IUOprcJyYr4","title":"Phụ nữ táo bón có phải do lười �n rau?","channel":"baosuckhoedoisongboyte"},
84
+ {"id":"YY8ojFNE-AU","title":"Quái xế tự quay clip n�t pô đánh võng đăng TikTok bị xử lý","channel":"baosuckhoedoisongboyte"},
85
  {"id":"OV7_oGdQGII","title":"Bố cô dâu khóc sụt sùi rồi quẩy cực sung gây bão mạng","channel":"baosuckhoedoisongboyte"},
86
+ {"id":"FoxhFyz2skY","title":"Người đàn ông nước ngoài đập phá ô tô bẻ cần gạt nước ở Đà N�ng","channel":"baosuckhoedoisongboyte"},
87
+ {"id":"R1oC_I8dFPU","title":"Thanh niên buông tay lái đứng trên xe máy khi đổ đèo ở Đ�k L�k","channel":"baosuckhoedoisongboyte"},
88
+ {"id":"U0Ft6ChWAIo","title":"Cô giáo kể phút tháo chạy kh�i xe khách trước khi bị l� vò nát ở Cao Bằng","channel":"baosuckhoedoisongboyte"},
89
  {"id":"hH0ANeze_4E","title":"Liên tiếp hàng chục con bò bị sét đánh chết trong ngày mưa dông","channel":"baosuckhoedoisongboyte"},
90
  {"id":"pXWt0QbAzRQ","title":"Va chạm giao thông người phụ nữ lăng mạ tài xế ô tô","channel":"baosuckhoedoisongboyte"},
91
+ {"id":"UWWLPY1OYt4","title":"CSGT ch�n xe khách khống chế đối tượng cướp dây chuyền tại Gia Lai","channel":"baosuckhoedoisongboyte"},
92
  {"id":"AxhVTQutsuo","title":"Xuất tinh sớm và những hiểu lầm thường gặp","channel":"baosuckhoedoisongboyte"},
93
  {"id":"cNy6FgaNxYM","title":"Cô dâu khóc sưng mắt vì 6 chỉ vàng không cánh mày bay trong ngày cưới","channel":"baosuckhoedoisongboyte"},
94
  {"id":"IDt_S6q59Ro","title":"Chở bạn gái không đội mũ bảo hiểm thanh niên đấm CSGT","channel":"baosuckhoedoisongboyte"},
95
+ {"id":"LFxJ9Ik6W0A","title":"Mệnh lệnh từ trái tim CSGT Hà Nội m� đường đưa bé 5 tháng tuổi đi cấp c�u","channel":"baosuckhoedoisongboyte"},
96
  ]
97
  for _v in SHORTS_FALLBACK:
98
  _v.setdefault("link", "https://www.youtube.com/watch?v="+_v["id"])
 
119
  PRIORITY_LEAGUES = ["Ngoại Hạng Anh","FA Cup","Champions League","LaLiga","Copa del Rey","Serie A","Bundesliga","Ligue 1","V-League"]
120
  LEAGUE_IDS = {"nha":27110,"laliga":27233,"seriea":27044,"bundesliga":26891,"ligue1":27212}
121
  HL_LEAGUES = {
122
+ "premier-league":{"path":"anh/premier-league","name":"Premier League","emoji":"�������"},
123
+ "fa-cup":{"path":"anh/fa-cup","name":"FA Cup","emoji":""},
124
  "bundesliga":{"path":"duc/bundesliga","name":"Bundesliga","emoji":"🇩🇪"},
125
+ "serie-a":{"path":"italy/serie-a","name":"Serie A","emoji":"🇮"},
126
  "la-liga":{"path":"tay-ban-nha/la-liga","name":"La Liga","emoji":"🇪🇸"},
127
  "champions-league":{"path":"cup-chau-au/uefa-champions-league","name":"Champions League","emoji":"⭐"},
128
  "europa-league":{"path":"cup-chau-au/uefa-europa-league","name":"Europa League","emoji":"🟠"},
 
222
  def _scrape_xemlaibongda_page(page_path, limit=20):
223
  """
224
  Scrape video từ xemlaibongda.top - Simple & Reliable
225
+ Dùng logic cũ đã test, không fetch t�ng trang (tránh timeout)
226
  """
227
  try:
228
  url = f"https://xemlaibongda.top/{page_path}" if page_path else "https://xemlaibongda.top/"
 
242
  if not href.startswith("http"):
243
  href = "https://xemlaibongda.top" + href
244
 
245
+ # B� query params
246
  clean_href = href.split("?")[0].split("#")[0]
247
  if clean_href in seen:
248
  continue
 
312
  if text and len(text) >= 5:
313
  title = text[:100]
314
 
315
+ # Fallback: tạo title t� slug
316
  if not title or len(title) < 3:
317
  slug = clean_href.split("/video/")[-1].rstrip("/").split("/xem-lai/")[-1].rstrip("/")
318
  title = slug.replace("-", " ").replace("_", " ").title()
 
342
  return []
343
 
344
  def _extract_img_src(a_tag):
345
+ """Extract image URL từ th� <a> và parent elements"""
346
  img = a_tag.find("img")
347
  if not img and a_tag.parent:
348
  img = a_tag.parent.find("img")
 
418
  if alt and len(alt) >= 3:
419
  return alt
420
 
421
+ # 4. Thử text content của <a> (loại b� quá dài)
422
  text = a_tag.get_text(" ", strip=True)
423
  if text and len(text) >= 3:
424
  # Lấy dòng đầu tiên nếu có nhiều dòng
 
504
  except: return []
505
 
506
  def scrape_shorts():
507
+ vids=[]
508
+ with ThreadPoolExecutor(3) as ex:
509
+ futs=[ex.submit(_yt_channel_shorts_requests,ch,24) for ch in ["baodantri7941","baosuckhoedoisongboyte","vtvnambo"]]
510
+ for f in as_completed(futs):
511
+ try:
512
+ r=f.result()
513
+ if r: vids.extend(r)
514
+ except: pass
515
+ merged=[]; seen=set()
516
+ for v in vids:
517
+ vid=v.get("id")
518
+ if not vid or vid in seen: continue
519
+ seen.add(vid); merged.append(v)
520
+ for v in SHORTS_FALLBACK:
521
+ vid=v.get("id")
522
+ if not vid or vid in seen: continue
523
+ seen.add(vid); merged.append(v)
524
+ return merged[:60]
 
 
 
 
 
 
525
 
526
  # ===== VTV NAM BO & WC SHORTS - using yt-dlp =====
527
  from yt_scraper import get_vtvnambo_shorts, get_wc_related_shorts
 
725
  return JSONResponse(_cached("bdp_videos",_f))
726
 
727
  # ===== NEWS =====
728
+ VNE_CATS={"thoi-su":("https://vnexpress.net/thoi-su","Thời Sự"),"the-gioi":("https://vnexpress.net/the-gioi","Thế Giới"),"kinh-doanh":("https://vnexpress.net/kinh-doanh","Kinh Doanh"),"the-thao":("https://vnexpress.net/the-thao","Thể Thao"),"giai-tri":("https://vnexpress.net/giai-tri","Giải Trí"),"suc-khoe":("https://vnexpress.net/suc-khoe","S�c Kh�e"),"phap-luat":("https://vnexpress.net/phap-luat","Pháp Luật"),"giao-duc":("https://vnexpress.net/giao-duc","Giáo Dục"),"du-lich":("https://vnexpress.net/du-lich","Du Lịch"),"doi-song":("https://vnexpress.net/doi-song","Đời Sống")}
729
 
730
  def scrape_vne(cat_url):
731
  try: