Spaces:
Running
Running
Patch: fast home, source thumbnails, rewrite button in articles and topics
Browse files- ai_runtime_patch_fast.py +49 -0
ai_runtime_patch_fast.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Patch over b9b6ba4 final6: faster home, source thumbnails in topic, rewrite button everywhere."""
|
| 2 |
+
import ai_runtime_final6 as f6
|
| 3 |
+
from ai_runtime_final6 import app, rt, f5, HTMLResponse
|
| 4 |
+
|
| 5 |
+
# Only override root route to inject additional frontend fixes.
|
| 6 |
+
app.router.routes=[r for r in app.router.routes if not (getattr(r,'path',None)=='/' and 'GET' in getattr(r,'methods',set()))]
|
| 7 |
+
|
| 8 |
+
PATCH_INJECT=r'''
|
| 9 |
+
<script>
|
| 10 |
+
(function(){
|
| 11 |
+
function esc(s){return String(s||'').replace(/[&<>"']/g,m=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m]));}
|
| 12 |
+
// 1) Faster home: defer hot_topics and shorts refresh to after main content loads.
|
| 13 |
+
let _hotLoaded=false;
|
| 14 |
+
function deferHotTopics(){if(_hotLoaded)return;_hotLoaded=true;setTimeout(()=>{if(typeof ensureHotTopics==='function')ensureHotTopics();if(typeof ensureNewsShortsHome==='function')ensureNewsShortsHome();},3000);}
|
| 15 |
+
if(document.readyState==='complete')deferHotTopics();else window.addEventListener('load',deferHotTopics);
|
| 16 |
+
|
| 17 |
+
// 2) Source links in topic posts show thumbnail from og:image or first image.
|
| 18 |
+
function patchSourceDetails(){document.querySelectorAll('.source-detail-item').forEach(el=>{if(el.dataset.patched)return;el.dataset.patched='1';let a=el.querySelector('a[href]');if(!a)return;let url=a.href;if(!url)return;let img=el.querySelector('img.src-thumb');if(img)return;let thumb=document.createElement('img');thumb.className='src-thumb';thumb.style.cssText='width:80px;height:50px;object-fit:cover;border-radius:6px;float:left;margin-right:8px;background:#222';thumb.loading='lazy';thumb.src='/api/proxy/img?url='+encodeURIComponent(url.replace(/\/[^\/]*$/,'/').replace(/https?:\/\//,'')); thumb.onerror=function(){this.style.display='none'};el.prepend(thumb)});}
|
| 19 |
+
|
| 20 |
+
// 3) Add rewrite button to every article view (including topic articles).
|
| 21 |
+
function addRewriteButton(){let art=document.querySelector('#view-article .article-view');if(!art||art.querySelector('.rewrite-injected'))return;let actions=art.querySelector('.article-actions');if(!actions){actions=document.createElement('div');actions.className='article-actions';art.appendChild(actions);}if(actions.querySelector('[data-rewrite]'))return;let btn=document.createElement('button');btn.className='primary rewrite-injected';btn.setAttribute('data-rewrite','1');btn.textContent='🤖 AI viết lại & đăng tường';btn.onclick=function(){if(typeof rewriteCurrentArticle==='function')rewriteCurrentArticle();else if(typeof window.rewriteCurrentArticle==='function')window.rewriteCurrentArticle();else alert('Chức năng rewrite chưa sẵn sàng.')};actions.insertBefore(btn,actions.firstChild);}
|
| 22 |
+
|
| 23 |
+
// 4) Also add rewrite for topic wall articles (readLiveTopicWall).
|
| 24 |
+
let oldReadLive=window.readLiveTopicWall;
|
| 25 |
+
if(oldReadLive){window.readLiveTopicWall=function(){let ret=oldReadLive.apply(this,arguments);setTimeout(()=>{let art=document.querySelector('#view-article .article-view');if(!art)return;let actions=art.querySelector('.article-actions');if(!actions){actions=document.createElement('div');actions.className='article-actions';art.appendChild(actions);}if(!actions.querySelector('[data-rewrite-topic]')){let btn=document.createElement('button');btn.className='primary';btn.setAttribute('data-rewrite-topic','1');btn.textContent='🤖 AI viết lại & đăng tường';btn.onclick=function(){let url=(window._currentArticle&&window._currentArticle.url)||'';if(!url){let links=art.querySelectorAll('a[href*="://"]');if(links.length)url=links[0].href;}if(url&&typeof rewriteCurrentArticle==='function'){window._currentArticle={url};rewriteCurrentArticle();}else alert('Không có URL để rewrite.')};actions.appendChild(btn);}},500);return ret;}}
|
| 26 |
+
|
| 27 |
+
// 5) Patch topic source items to show article thumbnail from og:image via proxy.
|
| 28 |
+
function patchTopicSourceImages(){document.querySelectorAll('.source-detail-item').forEach(el=>{if(el.dataset.imgPatched)return;el.dataset.imgPatched='1';let a=el.querySelector('a[href]');if(!a||!a.href)return;let url=a.href;fetch('/api/article?url='+encodeURIComponent(url)).then(r=>r.json()).then(d=>{if(d&&(d.og_image||d.img)){let img=document.createElement('img');img.style.cssText='width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:6px;margin-bottom:6px;background:#222';img.loading='lazy';img.src=d.og_image||d.img;img.onerror=function(){this.style.display='none'};el.prepend(img);}}).catch(()=>{});});}
|
| 29 |
+
|
| 30 |
+
// Run periodically to catch dynamically rendered content.
|
| 31 |
+
setInterval(()=>{addRewriteButton();patchSourceDetails();patchTopicSourceImages();},1500);
|
| 32 |
+
setTimeout(addRewriteButton,800);
|
| 33 |
+
})();
|
| 34 |
+
</script>
|
| 35 |
+
'''
|
| 36 |
+
|
| 37 |
+
@app.get('/')
|
| 38 |
+
async def index_patched():
|
| 39 |
+
# Call original final6 index handler logic directly.
|
| 40 |
+
html=f5.f4.f3.f2.f1._load_index_html()
|
| 41 |
+
# Collect all previous injections from the chain.
|
| 42 |
+
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
|
| 43 |
+
# Add final6's own injections (FINAL6_INJECT + FINAL6_FAST_HOME_INJECT + FINAL6E_INJECT if present).
|
| 44 |
+
body+=getattr(f6,'FINAL6_INJECT','')
|
| 45 |
+
body+=getattr(f6,'FINAL6_FAST_HOME_INJECT','')
|
| 46 |
+
body+=getattr(f6,'FINAL6E_INJECT','')
|
| 47 |
+
# Add our new patch.
|
| 48 |
+
body+=PATCH_INJECT
|
| 49 |
+
return HTMLResponse(html.replace('</body>',body+'\n</body>') if '</body>' in html else html+body)
|