Spaces:
Running
Running
Upload ai_runtime_patch_fast.py
Browse files- ai_runtime_patch_fast.py +65 -4
ai_runtime_patch_fast.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
-
"""Final patch v2: fix topic rewrite, remove duplicate short slide, full short interaction buttons.
|
|
|
|
| 2 |
import re, threading, time, json, os, asyncio
|
| 3 |
import ai_runtime_final6 as f6
|
| 4 |
from ai_runtime_final6 import app, rt, f5, HTMLResponse, JSONResponse, Request, Query
|
|
@@ -27,6 +28,35 @@ def _cleanup():
|
|
| 27 |
def _scrape(url,mc=8000):
|
| 28 |
try:d=f5.base.scrape_any_url(url);return(d.get('title',''),((d.get('summary','')+'\n'+d.get('text','')).strip())[:mc],d.get('image') or d.get('og_image') or '')
|
| 29 |
except:return('','','')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
_bg_home={"t":0,"d":[]};_bg_shorts={"t":0,"d":[]};_bg_lock=False
|
| 31 |
def _bg():
|
| 32 |
global _bg_lock
|
|
@@ -75,6 +105,8 @@ async def _ask(request:Request):
|
|
| 75 |
if not raw:raw=ctx[:12000]
|
| 76 |
ans=await f5.base.qwen_generate(f'Bạn là VNEWS AI. Nội dung: "{title}"\n{raw[:9000]}\n\nHỏi: "{q}"\n\nTrả lời tự nhiên bằng tiếng Việt.',max_tokens=1200)
|
| 77 |
return JSONResponse({'answer':ans or 'Chưa trả lời được.','title':title})
|
|
|
|
|
|
|
| 78 |
@app.post('/api/rewrite_share')
|
| 79 |
@app.post('/api/url_wall')
|
| 80 |
async def _rw(request:Request):
|
|
@@ -83,12 +115,41 @@ async def _rw(request:Request):
|
|
| 83 |
title,raw,img=_scrape(url,14000)
|
| 84 |
if len(raw)<50:raw=ctx[:14000]
|
| 85 |
if len(raw)<50:return JSONResponse({'error':'Không đọc được bài'},status_code=422)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
text=None
|
| 87 |
try:text=await asyncio.wait_for(f5.base.qwen_generate(f'Tóm tắt đăng Tường AI:\nTiêu đề: {title}\n{raw[:14000]}\n\n4-6 ý chính. Cuối ghi nguồn.',image_url=img or None,max_tokens=1000),timeout=30)
|
| 88 |
except:pass
|
| 89 |
if not text or len(text)<80:text=f"Tóm tắt: {title}\n\n{raw[:1200]}\n\nNguồn: {_domain(url)}"
|
| 90 |
-
|
| 91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
@app.post('/api/topic/rewrite')
|
| 93 |
async def _tr(request:Request):
|
| 94 |
b=await request.json();pid=str(b.get('post_id','')).strip()
|
|
@@ -185,4 +246,4 @@ async def _index():
|
|
| 185 |
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
|
| 186 |
body+=getattr(f6,'FINAL6_INJECT','');body+=getattr(f6,'FINAL6_FAST_HOME_INJECT','');body+=getattr(f6,'FINAL6E_INJECT','')
|
| 187 |
body+=PATCH_INJECT
|
| 188 |
-
return HTMLResponse(html.replace('</body>',body+'\n</body>') if '</body>' in html else html+body)
|
|
|
|
| 1 |
+
"""Final patch v2: fix topic rewrite, remove duplicate short slide, full short interaction buttons.
|
| 2 |
+
FIX: rewrite endpoint now includes slides with images + auto short video trigger."""
|
| 3 |
import re, threading, time, json, os, asyncio
|
| 4 |
import ai_runtime_final6 as f6
|
| 5 |
from ai_runtime_final6 import app, rt, f5, HTMLResponse, JSONResponse, Request, Query
|
|
|
|
| 28 |
def _scrape(url,mc=8000):
|
| 29 |
try:d=f5.base.scrape_any_url(url);return(d.get('title',''),((d.get('summary','')+'\n'+d.get('text','')).strip())[:mc],d.get('image') or d.get('og_image') or '')
|
| 30 |
except:return('','','')
|
| 31 |
+
def _scrape_full(url):
|
| 32 |
+
"""Get title, text, images ALL from scrape_any_url."""
|
| 33 |
+
try:
|
| 34 |
+
d = f5.base.scrape_any_url(url)
|
| 35 |
+
if d:
|
| 36 |
+
imgs = d.get('images', [])
|
| 37 |
+
if not imgs and d.get('og_image'):
|
| 38 |
+
imgs = [d.get('og_image', '')]
|
| 39 |
+
return d.get('title', ''), d.get('text', ''), imgs, d.get('og_image', '')
|
| 40 |
+
except:
|
| 41 |
+
pass
|
| 42 |
+
return '', '', [], ''
|
| 43 |
+
def _make_slides(text, images, og_img, max_slides=8):
|
| 44 |
+
"""Build slides array from text paragraphs + images."""
|
| 45 |
+
slides = []
|
| 46 |
+
paragraphs = [p.strip() for p in text.split('\n') if len(p.strip()) > 60]
|
| 47 |
+
all_imgs = images[:] if images else []
|
| 48 |
+
if not all_imgs and og_img:
|
| 49 |
+
all_imgs = [og_img]
|
| 50 |
+
if not all_imgs:
|
| 51 |
+
all_imgs = ['https://image.pollinations.ai/prompt/Vietnamese%20news%20update']
|
| 52 |
+
for i, pt in enumerate(paragraphs[:max_slides]):
|
| 53 |
+
slide_img = all_imgs[i] if i < len(all_imgs) else all_imgs[-1]
|
| 54 |
+
slides.append({'text': pt, 'image': slide_img, 'index': i + 1})
|
| 55 |
+
if not slides:
|
| 56 |
+
for i, im in enumerate(all_imgs[:3]):
|
| 57 |
+
slides.append({'text': '', 'image': im, 'index': i + 1})
|
| 58 |
+
return slides
|
| 59 |
+
|
| 60 |
_bg_home={"t":0,"d":[]};_bg_shorts={"t":0,"d":[]};_bg_lock=False
|
| 61 |
def _bg():
|
| 62 |
global _bg_lock
|
|
|
|
| 105 |
if not raw:raw=ctx[:12000]
|
| 106 |
ans=await f5.base.qwen_generate(f'Bạn là VNEWS AI. Nội dung: "{title}"\n{raw[:9000]}\n\nHỏi: "{q}"\n\nTrả lời tự nhiên bằng tiếng Việt.',max_tokens=1200)
|
| 107 |
return JSONResponse({'answer':ans or 'Chưa trả lời được.','title':title})
|
| 108 |
+
|
| 109 |
+
# ===== REWRITE with SLIDES + IMAGES + SHORT =====
|
| 110 |
@app.post('/api/rewrite_share')
|
| 111 |
@app.post('/api/url_wall')
|
| 112 |
async def _rw(request:Request):
|
|
|
|
| 115 |
title,raw,img=_scrape(url,14000)
|
| 116 |
if len(raw)<50:raw=ctx[:14000]
|
| 117 |
if len(raw)<50:return JSONResponse({'error':'Không đọc được bài'},status_code=422)
|
| 118 |
+
|
| 119 |
+
# Get full article data with images
|
| 120 |
+
full_title, full_text, all_images, og_img = _scrape_full(url)
|
| 121 |
+
if not all_images and img:
|
| 122 |
+
all_images = [img]
|
| 123 |
+
if not all_images and og_img:
|
| 124 |
+
all_images = [og_img]
|
| 125 |
+
if not all_images:
|
| 126 |
+
all_images = ['https://image.pollinations.ai/prompt/Vietnamese%20news%20update']
|
| 127 |
+
|
| 128 |
+
# Generate AI summary
|
| 129 |
text=None
|
| 130 |
try:text=await asyncio.wait_for(f5.base.qwen_generate(f'Tóm tắt đăng Tường AI:\nTiêu đề: {title}\n{raw[:14000]}\n\n4-6 ý chính. Cuối ghi nguồn.',image_url=img or None,max_tokens=1000),timeout=30)
|
| 131 |
except:pass
|
| 132 |
if not text or len(text)<80:text=f"Tóm tắt: {title}\n\n{raw[:1200]}\n\nNguồn: {_domain(url)}"
|
| 133 |
+
|
| 134 |
+
# Build slides from full text
|
| 135 |
+
slides = _make_slides(full_text or raw, all_images, og_img)
|
| 136 |
+
|
| 137 |
+
main_img = all_images[0] if all_images else ''
|
| 138 |
+
post=f5.base.make_post(title or 'Bài viết',text,main_img,url,'rewrite',sources=[{'title':title,'url':url,'via':_domain(url)}])
|
| 139 |
+
post['images'] = all_images
|
| 140 |
+
post['slides'] = slides
|
| 141 |
+
ps=f5.base._load_ai_wall();ps.insert(0,post);f5.base._save_ai_wall(ps)
|
| 142 |
+
|
| 143 |
+
# Try generate short video in background
|
| 144 |
+
if len(text) > 100:
|
| 145 |
+
try:
|
| 146 |
+
import auto_scheduler
|
| 147 |
+
threading.Thread(target=lambda: auto_scheduler._try_generate_short(post), daemon=True).start()
|
| 148 |
+
except:
|
| 149 |
+
pass
|
| 150 |
+
|
| 151 |
+
return JSONResponse({'post':post})
|
| 152 |
+
|
| 153 |
@app.post('/api/topic/rewrite')
|
| 154 |
async def _tr(request:Request):
|
| 155 |
b=await request.json();pid=str(b.get('post_id','')).strip()
|
|
|
|
| 246 |
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
|
| 247 |
body+=getattr(f6,'FINAL6_INJECT','');body+=getattr(f6,'FINAL6_FAST_HOME_INJECT','');body+=getattr(f6,'FINAL6E_INJECT','')
|
| 248 |
body+=PATCH_INJECT
|
| 249 |
+
return HTMLResponse(html.replace('</body>',body+'\n</body>') if '</body>' in html else html+body)
|