bep40 commited on
Commit
6efe66f
·
verified ·
1 Parent(s): cf610cf

Override root to add fast hashtag UI + topic input same flow"

Browse files
Files changed (1) hide show
  1. app_run.py +92 -7
app_run.py CHANGED
@@ -1,16 +1,101 @@
1
- """Wrapper over app_final: faster hashtag sources + topic input same flow."""
2
  from app_final import *
3
- from app_final import app, f6, HIGHLIGHT_FULL_OVERRIDE
4
- from fastapi.responses import JSONResponse
5
  from fastapi import Query
6
 
7
- # Override /api/hashtag/sources to NOT scrape og:image (fast response)
8
- app.router.routes=[r for r in app.router.routes if not (getattr(r,'path',None)=='/api/hashtag/sources' and 'GET' in getattr(r,'methods',set()))]
 
 
 
9
 
10
  @app.get('/api/hashtag/sources')
11
  def _hashtag_fast(topic:str=Query(...)):
12
- """Return sources FAST — only title/url/via from RSS cache. No og:image scrape."""
13
  research=f6._fast_context(topic) if hasattr(f6,'_fast_context') else f6._web_research_context(topic)
14
  sources=research.get('sources',[])
15
- # Return immediately without scraping images — frontend will lazy-load them
16
  return JSONResponse({'sources':[{'title':s.get('title',''),'url':s.get('url',''),'via':s.get('via',s.get('source','')),'snippet':s.get('snippet',s.get('excerpt',''))[:200]} for s in sources[:8]],'topic':topic})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Wrapper: faster hashtag + spinner + topic input same flow."""
2
  from app_final import *
3
+ from app_final import app, f6, f5, rt, PATCH_INJECT, UNIFIED_INJECT_FIXED, HIGHLIGHT_FULL_OVERRIDE, EXTRA_WALL_FIX
4
+ from fastapi.responses import HTMLResponse, JSONResponse
5
  from fastapi import Query
6
 
7
+ # Override /api/hashtag/sources NO og:image scrape, instant from RSS cache
8
+ app.router.routes=[r for r in app.router.routes if not (
9
+ (getattr(r,'path',None)=='/api/hashtag/sources' and 'GET' in getattr(r,'methods',set())) or
10
+ (getattr(r,'path',None)=='/' and 'GET' in getattr(r,'methods',set()))
11
+ )]
12
 
13
  @app.get('/api/hashtag/sources')
14
  def _hashtag_fast(topic:str=Query(...)):
 
15
  research=f6._fast_context(topic) if hasattr(f6,'_fast_context') else f6._web_research_context(topic)
16
  sources=research.get('sources',[])
 
17
  return JSONResponse({'sources':[{'title':s.get('title',''),'url':s.get('url',''),'via':s.get('via',s.get('source','')),'snippet':s.get('snippet',s.get('excerpt',''))[:200]} for s in sources[:8]],'topic':topic})
18
+
19
+ # Extra JS: override showHashtagSources with spinner + lazy img + topic input integration
20
+ FAST_HASHTAG_JS = r'''
21
+ <style>
22
+ .hashtag-loading{display:flex;align-items:center;gap:8px;padding:12px;color:#888;font-size:12px}
23
+ .hashtag-spinner{width:16px;height:16px;border:2px solid #333;border-top-color:#5cb87a;border-radius:50%;animation:ht-spin .8s linear infinite}
24
+ @keyframes ht-spin{to{transform:rotate(360deg)}}
25
+ .hashtag-src-item img{width:100%;height:100%;object-fit:cover}
26
+ </style>
27
+ <script>
28
+ (function(){
29
+ function esc(s){return String(s||'').replace(/[&<>"']/g,function(m){return{'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[m]});}
30
+
31
+ // Override showHashtagSources: spinner + lazy image from /api/article
32
+ window.showHashtagSources=async function(topic){
33
+ var home=document.getElementById('view-home');if(!home)return;
34
+ document.getElementById('hashtag-sources-box')?.remove();
35
+ var box=document.createElement('div');box.id='hashtag-sources-box';box.className='hashtag-sources';
36
+ box.innerHTML='<h3>🔍 '+esc(topic)+'</h3><div class="hashtag-loading"><div class="hashtag-spinner"></div>Đang tìm nguồn nhanh...</div>';
37
+ var compose=home.querySelector('.ai-compose');
38
+ if(compose)compose.after(box);else home.prepend(box);
39
+ box.scrollIntoView({behavior:'smooth',block:'start'});
40
+ try{
41
+ var r=await fetch('/api/hashtag/sources?topic='+encodeURIComponent(topic));
42
+ var j=await r.json();var sources=j.sources||[];
43
+ if(!sources.length){box.innerHTML='<h3>🔍 '+esc(topic)+'</h3><div style="color:#888;font-size:12px;padding:8px">Không tìm được nguồn cho chủ đề này</div>';return;}
44
+ var h='<h3>🔍 '+esc(topic)+' <span style="font-size:10px;color:#888">('+sources.length+' nguồn)</span></h3>';
45
+ sources.forEach(function(s,i){
46
+ h+='<div class="hashtag-src-item" onclick="if(typeof readArticle===\'function\')readArticle(\''+esc(s.url||'')+'\')">';
47
+ h+='<div class="hashtag-src-img" id="ht-img-'+i+'"></div>';
48
+ h+='<div class="hashtag-src-text"><div class="hashtag-src-title">'+esc(s.title)+'</div><div class="hashtag-src-via">'+esc(s.via||'')+'</div>'+(s.snippet?'<div style="font-size:10px;color:#999;margin-top:2px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden">'+esc(s.snippet)+'</div>':'')+'</div>';
49
+ h+='</div>';
50
+ });
51
+ h+='<button class="hashtag-rewrite-btn" onclick="rewriteHashtagTopic(\''+esc(topic)+'\')">🤖 Rewrite AI tổng hợp nguồn & đăng tường</button>';
52
+ box.innerHTML=h;
53
+ // Lazy load images from /api/article (non-blocking)
54
+ sources.forEach(function(s,i){
55
+ if(!s.url)return;
56
+ fetch('/api/article?url='+encodeURIComponent(s.url)).then(function(r){return r.json()}).then(function(d){
57
+ if(d&&(d.og_image||d.img)){
58
+ var el=document.getElementById('ht-img-'+i);
59
+ if(el)el.innerHTML='<img src="'+esc(d.og_image||d.img)+'" onerror="this.style.display=\'none\'" loading="lazy">';
60
+ }
61
+ }).catch(function(){});
62
+ });
63
+ }catch(e){box.innerHTML='<h3>🔍 '+esc(topic)+'</h3><div style="color:#e74c3c;font-size:12px;padding:8px">Lỗi: '+esc(e.message)+'</div>';}
64
+ };
65
+
66
+ // Override topic input button to use same flow (show sources first)
67
+ window.createTopicPost=function(){
68
+ var inp=document.getElementById('ai-topic-input');
69
+ var topic=(inp&&inp.value||'').trim();
70
+ if(!topic){alert('Nhập chủ đề trước');return;}
71
+ showHashtagSources(topic);
72
+ if(inp)inp.value='';
73
+ };
74
+
75
+ // Override the final5 topic button too
76
+ window.createTopicPostFinal5=function(){
77
+ var inp=document.getElementById('ai-topic-input-final5')||document.getElementById('ai-topic-input');
78
+ var topic=(inp&&inp.value||'').trim();
79
+ if(!topic){alert('Nhập chủ đề trước');return;}
80
+ showHashtagSources(topic);
81
+ if(inp)inp.value='';
82
+ };
83
+ })();
84
+ </script>
85
+ '''
86
+
87
+ @app.get('/')
88
+ async def _index_run():
89
+ html=f5.f4.f3.f2.f1._load_index_html()
90
+ body=''
91
+ body+=getattr(rt.old,'PATCH_INJECT','')
92
+ body+=f5.f4.f3.f2.f1.FINAL_INJECT+f5.f4.f3.FINAL3_INJECT+f5.f4.FINAL4_INJECT+f5.FINAL5_INJECT
93
+ body+=getattr(f6,'FINAL6_INJECT','')
94
+ body+=getattr(f6,'FINAL6_FAST_HOME_INJECT','')
95
+ body+=getattr(f6,'FINAL6E_INJECT','')
96
+ body+=PATCH_INJECT
97
+ body+=UNIFIED_INJECT_FIXED
98
+ body+=HIGHLIGHT_FULL_OVERRIDE
99
+ body+=EXTRA_WALL_FIX
100
+ body+=FAST_HASHTAG_JS # Last: overrides showHashtagSources and createTopicPost
101
+ return HTMLResponse(html.replace('</body>',body+'\n</body>') if '</body>' in html else html+body)