Spaces:
Running
Running
Fix slow homepage with fast RSS endpoints
Browse files- ai_runtime_final6.py +102 -0
ai_runtime_final6.py
CHANGED
|
@@ -653,3 +653,105 @@ Yêu cầu:
|
|
| 653 |
post['images']=[img]
|
| 654 |
posts=f5.base._load_ai_wall();posts.insert(0,post);f5.base._save_ai_wall(posts)
|
| 655 |
return JSONResponse({'post':post,'mode':'fast_rss','sources_count':len(sources)})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 653 |
post['images']=[img]
|
| 654 |
posts=f5.base._load_ai_wall();posts.insert(0,post);f5.base._save_ai_wall(posts)
|
| 655 |
return JSONResponse({'post':post,'mode':'fast_rss','sources_count':len(sources)})
|
| 656 |
+
|
| 657 |
+
|
| 658 |
+
# ===== FINAL6D: FAST HOME LOAD =====
|
| 659 |
+
_FAST_HOME_CACHE={"t":0,"d":[]}
|
| 660 |
+
_FAST_DT_CACHE={"t":0,"d":[]}
|
| 661 |
+
_FAST_VNEGO_CACHE={"t":0,"d":[]}
|
| 662 |
+
_FAST_HL_CACHE={"t":0,"d":[]}
|
| 663 |
+
|
| 664 |
+
def _rss_articles_fast(feed_url, group, source='vne', limit=6):
|
| 665 |
+
out=[]
|
| 666 |
+
try:
|
| 667 |
+
r=requests.get(feed_url,headers=UA,timeout=4);r.encoding='utf-8'
|
| 668 |
+
soup=BeautifulSoup(r.text,'xml')
|
| 669 |
+
for it in soup.find_all('item')[:limit*2]:
|
| 670 |
+
title=clean(it.find('title').get_text(' ',strip=True) if it.find('title') else '')
|
| 671 |
+
link=clean(it.find('link').get_text(strip=True) if it.find('link') else '')
|
| 672 |
+
desc_raw=it.find('description').get_text(' ',strip=True) if it.find('description') else ''
|
| 673 |
+
ds=BeautifulSoup(desc_raw,'lxml')
|
| 674 |
+
im=ds.find('img'); img=im.get('src','') if im else ''
|
| 675 |
+
desc=clean(ds.get_text(' ',strip=True))[:160]
|
| 676 |
+
if title and link:
|
| 677 |
+
out.append({'title':title,'link':link,'img':img,'summary':desc,'source':source,'group':group})
|
| 678 |
+
if len(out)>=limit:break
|
| 679 |
+
except Exception:pass
|
| 680 |
+
return out
|
| 681 |
+
|
| 682 |
+
def _fast_homepage():
|
| 683 |
+
now=time.time()
|
| 684 |
+
if _FAST_HOME_CACHE['d'] and now-_FAST_HOME_CACHE['t']<600:return _FAST_HOME_CACHE['d']
|
| 685 |
+
feeds=[('Thời Sự','https://vnexpress.net/rss/thoi-su.rss'),('Thế Giới','https://vnexpress.net/rss/the-gioi.rss'),('Kinh Doanh','https://vnexpress.net/rss/kinh-doanh.rss'),('Công Nghệ','https://vnexpress.net/rss/so-hoa.rss'),('Thể Thao','https://vnexpress.net/rss/the-thao.rss'),('Giải Trí','https://vnexpress.net/rss/giai-tri.rss'),('Sức Khỏe','https://vnexpress.net/rss/suc-khoe.rss'),('Giáo Dục','https://vnexpress.net/rss/giao-duc.rss'),('Pháp Luật','https://vnexpress.net/rss/phap-luat.rss'),('Du Lịch','https://vnexpress.net/rss/du-lich.rss')]
|
| 686 |
+
arts=[]
|
| 687 |
+
try:
|
| 688 |
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
| 689 |
+
with ThreadPoolExecutor(max_workers=6) as ex:
|
| 690 |
+
futs=[ex.submit(_rss_articles_fast,u,g,'vne',6) for g,u in feeds]
|
| 691 |
+
for f in as_completed(futs,timeout=7):
|
| 692 |
+
try:arts.extend(f.result() or [])
|
| 693 |
+
except Exception:pass
|
| 694 |
+
except Exception:
|
| 695 |
+
for g,u in feeds[:5]:arts.extend(_rss_articles_fast(u,g,'vne',4))
|
| 696 |
+
if arts:_FAST_HOME_CACHE.update({'t':now,'d':arts})
|
| 697 |
+
return _FAST_HOME_CACHE['d'] or arts
|
| 698 |
+
|
| 699 |
+
def _fast_dantri_hot():
|
| 700 |
+
now=time.time()
|
| 701 |
+
if _FAST_DT_CACHE['d'] and now-_FAST_DT_CACHE['t']<900:return _FAST_DT_CACHE['d']
|
| 702 |
+
data=_rss_articles_fast('https://dantri.com.vn/rss/home.rss','Tin Nổi Bật','dantri',12)
|
| 703 |
+
if data:_FAST_DT_CACHE.update({'t':now,'d':data})
|
| 704 |
+
return data
|
| 705 |
+
|
| 706 |
+
def _fast_vnego():
|
| 707 |
+
now=time.time()
|
| 708 |
+
if _FAST_VNEGO_CACHE['d'] and now-_FAST_VNEGO_CACHE['t']<900:return _FAST_VNEGO_CACHE['d']
|
| 709 |
+
out=[]
|
| 710 |
+
try:
|
| 711 |
+
r=requests.get('https://vnexpress.net/vne-go',headers=UA,timeout=4);r.encoding='utf-8'
|
| 712 |
+
soup=BeautifulSoup(r.text,'lxml');seen=set()
|
| 713 |
+
for a in soup.find_all('a',href=True):
|
| 714 |
+
href=a.get('href','');title=clean(a.get('title','') or a.get_text(' ',strip=True))
|
| 715 |
+
if not title or len(title)<8 or not href.startswith('http') or href in seen:continue
|
| 716 |
+
if '/vne-go' not in href and '/video/' not in href:continue
|
| 717 |
+
seen.add(href);img='';im=a.find('img') or (a.parent.find('img') if a.parent else None)
|
| 718 |
+
if im:img=im.get('data-src') or im.get('src','')
|
| 719 |
+
out.append({'title':title,'link':href,'img':img,'source':'vne-video'})
|
| 720 |
+
if len(out)>=10:break
|
| 721 |
+
except Exception:pass
|
| 722 |
+
_FAST_VNEGO_CACHE.update({'t':now,'d':out})
|
| 723 |
+
return out
|
| 724 |
+
|
| 725 |
+
def _fast_highlights():
|
| 726 |
+
now=time.time()
|
| 727 |
+
if _FAST_HL_CACHE['d'] and now-_FAST_HL_CACHE['t']<900:return _FAST_HL_CACHE['d']
|
| 728 |
+
_FAST_HL_CACHE.update({'t':now,'d':[]})
|
| 729 |
+
return []
|
| 730 |
+
|
| 731 |
+
for _p in ['/api/homepage','/api/dantri_hot','/api/vne_video','/api/highlights']:
|
| 732 |
+
app.router.routes=[r for r in app.router.routes if not (getattr(r,'path',None)==_p and 'GET' in getattr(r,'methods',set()))]
|
| 733 |
+
@app.get('/api/homepage')
|
| 734 |
+
def api_homepage_fast():return JSONResponse(_fast_homepage())
|
| 735 |
+
@app.get('/api/dantri_hot')
|
| 736 |
+
def api_dantri_hot_fast():return JSONResponse(_fast_dantri_hot())
|
| 737 |
+
@app.get('/api/vne_video')
|
| 738 |
+
def api_vne_video_fast():return JSONResponse(_fast_vnego())
|
| 739 |
+
@app.get('/api/highlights')
|
| 740 |
+
def api_highlights_fast():return JSONResponse(_fast_highlights())
|
| 741 |
+
|
| 742 |
+
FINAL6_FAST_HOME_INJECT = """
|
| 743 |
+
<script>
|
| 744 |
+
(function(){
|
| 745 |
+
const oldFetch=window.fetch;
|
| 746 |
+
window.__allowShortRefresh=false;
|
| 747 |
+
window.fetch=function(url,opts){try{let u=String(url||'');if(u.includes('/api/shorts?refresh=1')&&!window.__allowShortRefresh)url='/api/shorts';}catch(e){}return oldFetch.call(this,url,opts)};
|
| 748 |
+
setTimeout(()=>{window.__allowShortRefresh=true;},7000);
|
| 749 |
+
})();
|
| 750 |
+
</script>
|
| 751 |
+
"""
|
| 752 |
+
app.router.routes=[r for r in app.router.routes if not (getattr(r,'path',None)=='/' and 'GET' in getattr(r,'methods',set()))]
|
| 753 |
+
@app.get('/')
|
| 754 |
+
async def index_final6_fast_home():
|
| 755 |
+
html=f5.f4.f3.f2.f1._load_index_html()
|
| 756 |
+
body=getattr(rt.old,'PATCH_INJECT','')+f5.f4.f3.f2.f1.FINAL_INJECT+f5.f4.f3.FINAL3_INJECT+f5.f4.FINAL4_INJECT+f5.FINAL5_INJECT+FINAL6_INJECT+FINAL6_FAST_HOME_INJECT
|
| 757 |
+
return HTMLResponse(html.replace('</body>',body+'\n</body>') if '</body>' in html else html+body)
|