Spaces:
Running
Running
Fix ai_runtime.py - restore from c93b544
Browse files- ai_runtime.py +11 -0
ai_runtime.py
CHANGED
|
@@ -24,6 +24,7 @@ def _domain(url):
|
|
| 24 |
|
| 25 |
|
| 26 |
def _strip_bullet_prefix(s):
|
|
|
|
| 27 |
return clean(re.sub(r'^[\s鈥-\*路鈻柅鈼忊棆\d\.\)\(]+', '', s or ''))
|
| 28 |
|
| 29 |
|
|
@@ -59,6 +60,7 @@ def _collect_all_images(data):
|
|
| 59 |
|
| 60 |
def _scrape_url_with_images(url):
|
| 61 |
data=base.scrape_any_url(url)
|
|
|
|
| 62 |
try:
|
| 63 |
import requests
|
| 64 |
from bs4 import BeautifulSoup
|
|
@@ -69,6 +71,7 @@ def _scrape_url_with_images(url):
|
|
| 69 |
src=im.get('data-src') or im.get('data-original') or im.get('data-lazy-src') or im.get('src') or ''
|
| 70 |
if src.startswith('//'):src='https:'+src
|
| 71 |
if src and 'base64' not in src and src not in extra:
|
|
|
|
| 72 |
low=src.lower()
|
| 73 |
if any(x in low for x in ['logo','icon','avatar','sprite']):
|
| 74 |
continue
|
|
@@ -110,9 +113,11 @@ def postprocess(text):
|
|
| 110 |
out=old._postprocess_ai_text(text, max_units=7)
|
| 111 |
else:
|
| 112 |
out=clean(text)
|
|
|
|
| 113 |
return out
|
| 114 |
|
| 115 |
|
|
|
|
| 116 |
_PATCH={('/api/topic_post','POST'),('/api/url_wall','POST'),('/api/rewrite_share','POST'),('/api/ai/url','POST'),('/api/ai/short/{post_id}','POST'),('/api/ai/short-file/{file_id}','GET'),('/','GET')}
|
| 117 |
app.router.routes=[r for r in app.router.routes if not any(getattr(r,'path',None)==p and m in getattr(r,'methods',set()) for p,m in _PATCH)]
|
| 118 |
|
|
@@ -232,6 +237,7 @@ def make_frame(post,seg,idx,total,img_path,out_path):
|
|
| 232 |
fs=ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',30)
|
| 233 |
fsmall=ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf',28)
|
| 234 |
except Exception:fb=ft=fs=fsmall=None
|
|
|
|
| 235 |
badge='Ngu峄搉: '+_source_badge(post)
|
| 236 |
try:
|
| 237 |
b=draw.textbbox((0,0),badge,font=fsmall);bw=b[2]-b[0];bh=b[3]-b[1]
|
|
@@ -240,7 +246,9 @@ def make_frame(post,seg,idx,total,img_path,out_path):
|
|
| 240 |
bx=W-bw-42;by=24
|
| 241 |
draw.rounded_rectangle((bx-16,by-8,W-24,by+bh+14),radius=18,fill=(0,0,0,170))
|
| 242 |
draw.text((bx,by),badge,fill=(255,255,255),font=fsmall)
|
|
|
|
| 243 |
draw.rectangle((0,hero_h-20,W,H),fill=(12,12,12))
|
|
|
|
| 244 |
total_w=total*38-14;start=(W-total_w)//2
|
| 245 |
for i in range(total):
|
| 246 |
fill=(92,184,122) if i==idx else (70,70,70)
|
|
@@ -255,6 +263,7 @@ def make_frame(post,seg,idx,total,img_path,out_path):
|
|
| 255 |
block_h=len(lines)*74
|
| 256 |
y=max(980, 1250-block_h//2)
|
| 257 |
_draw_center(draw,lines,fb,y,(255,255,255),W,74)
|
|
|
|
| 258 |
title_lines=wrap_text(draw,_strip_bullet_prefix(post.get('title','')),fs,W-120,3)
|
| 259 |
y2=1640
|
| 260 |
draw.line((80,y2-26,W-80,y2-26),fill=(70,70,70),width=2)
|
|
@@ -313,12 +322,14 @@ def short_file(file_id:str):
|
|
| 313 |
return FileResponse(path,media_type='video/mp4',filename=f'vnews-ai-{file_id}.mp4')
|
| 314 |
|
| 315 |
|
|
|
|
| 316 |
app.router.routes=[r for r in app.router.routes if not (getattr(r,'path',None)=='/' and 'GET' in getattr(r,'methods',set()))]
|
| 317 |
@app.get('/')
|
| 318 |
async def index_runtime():
|
| 319 |
with open('/app/static/index.html','r',encoding='utf-8') as f:html=f.read()
|
| 320 |
inject=getattr(old,'PATCH_INJECT','')+r'''
|
| 321 |
<style>
|
|
|
|
| 322 |
#ai-topic-input{display:none!important}
|
| 323 |
#ai-topic-input,*[onclick*="createTopicPost"]{display:none!important}
|
| 324 |
.ai-topic-row,.topic-row,.ai-compose-topic{display:none!important}
|
|
|
|
| 24 |
|
| 25 |
|
| 26 |
def _strip_bullet_prefix(s):
|
| 27 |
+
# remove bullets, numbered prefixes, leading dots commonly produced by AI summaries
|
| 28 |
return clean(re.sub(r'^[\s鈥-\*路鈻柅鈼忊棆\d\.\)\(]+', '', s or ''))
|
| 29 |
|
| 30 |
|
|
|
|
| 60 |
|
| 61 |
def _scrape_url_with_images(url):
|
| 62 |
data=base.scrape_any_url(url)
|
| 63 |
+
# extra pass: collect every useful image from original HTML, because some readers only return one image
|
| 64 |
try:
|
| 65 |
import requests
|
| 66 |
from bs4 import BeautifulSoup
|
|
|
|
| 71 |
src=im.get('data-src') or im.get('data-original') or im.get('data-lazy-src') or im.get('src') or ''
|
| 72 |
if src.startswith('//'):src='https:'+src
|
| 73 |
if src and 'base64' not in src and src not in extra:
|
| 74 |
+
# skip tiny icons/logos as much as possible
|
| 75 |
low=src.lower()
|
| 76 |
if any(x in low for x in ['logo','icon','avatar','sprite']):
|
| 77 |
continue
|
|
|
|
| 113 |
out=old._postprocess_ai_text(text, max_units=7)
|
| 114 |
else:
|
| 115 |
out=clean(text)
|
| 116 |
+
# keep wall text readable, but ensure short generation later won't show bullets
|
| 117 |
return out
|
| 118 |
|
| 119 |
|
| 120 |
+
# Remove old routes we must override.
|
| 121 |
_PATCH={('/api/topic_post','POST'),('/api/url_wall','POST'),('/api/rewrite_share','POST'),('/api/ai/url','POST'),('/api/ai/short/{post_id}','POST'),('/api/ai/short-file/{file_id}','GET'),('/','GET')}
|
| 122 |
app.router.routes=[r for r in app.router.routes if not any(getattr(r,'path',None)==p and m in getattr(r,'methods',set()) for p,m in _PATCH)]
|
| 123 |
|
|
|
|
| 237 |
fs=ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',30)
|
| 238 |
fsmall=ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf',28)
|
| 239 |
except Exception:fb=ft=fs=fsmall=None
|
| 240 |
+
# source badge on top image corner
|
| 241 |
badge='Ngu峄搉: '+_source_badge(post)
|
| 242 |
try:
|
| 243 |
b=draw.textbbox((0,0),badge,font=fsmall);bw=b[2]-b[0];bh=b[3]-b[1]
|
|
|
|
| 246 |
bx=W-bw-42;by=24
|
| 247 |
draw.rounded_rectangle((bx-16,by-8,W-24,by+bh+14),radius=18,fill=(0,0,0,170))
|
| 248 |
draw.text((bx,by),badge,fill=(255,255,255),font=fsmall)
|
| 249 |
+
# bottom text area
|
| 250 |
draw.rectangle((0,hero_h-20,W,H),fill=(12,12,12))
|
| 251 |
+
# progress bars centered
|
| 252 |
total_w=total*38-14;start=(W-total_w)//2
|
| 253 |
for i in range(total):
|
| 254 |
fill=(92,184,122) if i==idx else (70,70,70)
|
|
|
|
| 263 |
block_h=len(lines)*74
|
| 264 |
y=max(980, 1250-block_h//2)
|
| 265 |
_draw_center(draw,lines,fb,y,(255,255,255),W,74)
|
| 266 |
+
# small title centered near bottom
|
| 267 |
title_lines=wrap_text(draw,_strip_bullet_prefix(post.get('title','')),fs,W-120,3)
|
| 268 |
y2=1640
|
| 269 |
draw.line((80,y2-26,W-80,y2-26),fill=(70,70,70),width=2)
|
|
|
|
| 322 |
return FileResponse(path,media_type='video/mp4',filename=f'vnews-ai-{file_id}.mp4')
|
| 323 |
|
| 324 |
|
| 325 |
+
# Rebuild / with old UI injection plus final UI overrides.
|
| 326 |
app.router.routes=[r for r in app.router.routes if not (getattr(r,'path',None)=='/' and 'GET' in getattr(r,'methods',set()))]
|
| 327 |
@app.get('/')
|
| 328 |
async def index_runtime():
|
| 329 |
with open('/app/static/index.html','r',encoding='utf-8') as f:html=f.read()
|
| 330 |
inject=getattr(old,'PATCH_INJECT','')+r'''
|
| 331 |
<style>
|
| 332 |
+
/* Hide old topic UI, keep URL input only */
|
| 333 |
#ai-topic-input{display:none!important}
|
| 334 |
#ai-topic-input,*[onclick*="createTopicPost"]{display:none!important}
|
| 335 |
.ai-topic-row,.topic-row,.ai-compose-topic{display:none!important}
|