"""Final patch v2: fix topic rewrite, remove duplicate short slide, full short interaction buttons.""" import re, threading, time, json, os, asyncio import ai_runtime_final6 as f6 from ai_runtime_final6 import app, rt, f5, HTMLResponse, JSONResponse, Request, Query import html as html_lib from urllib.parse import urlparse def clean(s):return re.sub(r"\s+"," ",html_lib.unescape(str(s or ""))).strip() def _domain(u): try:return urlparse(u or '').netloc.replace('www.','') except:return '' DATA_DIR="/data" if os.path.isdir('/data') else "/app/data" os.makedirs(DATA_DIR,exist_ok=True) SHORT_COMMENTS_FILE=os.path.join(DATA_DIR,'short_comments.json') TTL_24H=86400;HAS_PERSISTENT=os.path.isdir('/data') def _lj(p,d): try: if os.path.exists(p):return json.load(open(p,'r',encoding='utf-8')) except:pass return d def _sj(p,d): try:os.makedirs(os.path.dirname(p),exist_ok=True);open(p+'.tmp','w',encoding='utf-8').write(json.dumps(d,ensure_ascii=False));os.replace(p+'.tmp',p) except:pass def _cleanup(): n=int(time.time());ps=f5.base._load_ai_wall();f=[p for p in ps if n-int(p.get('ts') or 0)300 else None);return JSONResponse(_bg_home['d']) if hasattr(f6,'_fast_homepage'):d=f6._fast_homepage();_bg_home.update({"t":n,"d":d or []});return JSONResponse(d or []) return JSONResponse([]) @app.get('/api/shorts') def _sh(refresh:int=Query(default=0)): n=time.time() if _bg_shorts['d'] and (not refresh or n-_bg_shorts['t']<120):(threading.Thread(target=_bg,daemon=True).start() if n-_bg_shorts['t']>600 else None);return JSONResponse(_bg_shorts['d']) return f6.api_shorts_final6(refresh=refresh) if hasattr(f6,'api_shorts_final6') else JSONResponse([]) @app.get('/api/ai_wall') def _w():n=int(time.time());return JSONResponse({'posts':[p for p in f5.base._load_ai_wall() if n-int(p.get('ts') or 0)150 else None) ac='\n---\n'.join(parts) if parts else (p.get('text') or '') title=p.get('title','') text=None try:text=await asyncio.wait_for(f5.base.qwen_generate(f'Viết lại:\nChủ đề: {title}\n{ac[:16000]}\n\nTiêu đề mới + 4-6 ý + nguồn.',image_url=p.get('img'),max_tokens=1200),timeout=35) except:pass if not text or len(text)<100:text=f"Tóm tắt: {title}\n\n{ac[:1500]}\n\nNguồn: VNEWS AI" np=f5.base.make_post('Rewrite: '+title,text,p.get('img',''),'','rewrite_topic',sources=p.get('sources',[]));np['images']=p.get('images',[]) all_p=f5.base._load_ai_wall();all_p.insert(0,np);f5.base._save_ai_wall(all_p);return JSONResponse({'post':np}) @app.post('/api/topic_post') async def _tp(request:Request): b=await request.json();topic=clean(b.get('topic','')) if not topic:return JSONResponse({'error':'missing topic'},status_code=400) img=f6._topic_image(topic);research=f6._fast_context(topic) if hasattr(f6,'_fast_context') else f6._web_research_context(topic) ctx=research.get('context','');src=research.get('sources',[]);det=f6._extract_source_details_from_context(ctx,src) if hasattr(f6,'_extract_source_details_from_context') else [] if not ctx or not src:return JSONResponse({'error':'Không tìm được nội dung.'},status_code=422) sb='\n\n'.join([f"[{i+1}] {d.get('title','')} ({d.get('via','')})\n{d.get('content','')[:1400]}" for i,d in enumerate(det)]) if det else ctx[:18000] text=None try:text=await asyncio.wait_for(f5.base.qwen_generate(f'Viết bài tiếng Việt VỀ: "{topic}"\nNGUỒN:\n{sb[:18000]}\nCHỈ viết về "{topic}". 5-8 đoạn. Cuối có nguồn.',image_url=img,max_tokens=1700),timeout=35) except:pass if not text or len(text)<300:text=f"{topic}: tổng hợp\n\n"+'\n'.join([f"• {d['title']}: {d.get('content','')[:300]}" for d in (det or [])[:6]])+"\n\nNguồn: "+', '.join(sorted({d.get('via','') for d in (det or []) if d.get('via')})) post=f5.base.make_post(topic,text,img,'','topic_focused',sources=[s for s in src if s.get('url')]);post['images']=[img];post['source_details']=det ps=f5.base._load_ai_wall();ps.insert(0,post);f5.base._save_ai_wall(ps);return JSONResponse({'post':post}) PATCH_INJECT=r'''
''' @app.get('/') async def _index(): html=f5.f4.f3.f2.f1._load_index_html() 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 body+=getattr(f6,'FINAL6_INJECT','');body+=getattr(f6,'FINAL6_FAST_HOME_INJECT','');body+=getattr(f6,'FINAL6E_INJECT','') body+=PATCH_INJECT return HTMLResponse(html.replace('',body+'\n') if '' in html else html+body)