Spaces:
Running
Running
Upload rewrite_slide.py
Browse files- rewrite_slide.py +43 -10
rewrite_slide.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
"""Fast rewrite as slides -
|
| 2 |
from main import app
|
| 3 |
from fastapi import Request
|
| 4 |
from fastapi.responses import JSONResponse
|
|
@@ -30,6 +30,34 @@ except:
|
|
| 30 |
def _clean(s): return re.sub(r'\s+', ' ', str(s or '')).strip()
|
| 31 |
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
def _scrape_article_full(url):
|
| 34 |
"""Scrape article: extract paragraphs + ALL images."""
|
| 35 |
try:
|
|
@@ -84,7 +112,7 @@ def _scrape_article_full(url):
|
|
| 84 |
return None
|
| 85 |
|
| 86 |
|
| 87 |
-
def _extract_key_points(paragraphs, max_points=
|
| 88 |
"""Extract key points: take first sentence of each significant paragraph."""
|
| 89 |
points = []
|
| 90 |
for p in paragraphs:
|
|
@@ -108,12 +136,12 @@ def _extract_key_points(paragraphs, max_points=5):
|
|
| 108 |
@app.post("/api/rewrite_slide")
|
| 109 |
async def api_rewrite_slide(request: Request):
|
| 110 |
"""
|
| 111 |
-
Fast rewrite as SLIDES:
|
| 112 |
-
- Extract key points from article (1 sentence each
|
| 113 |
-
-
|
|
|
|
| 114 |
- Return as slides array for frontend to display
|
| 115 |
- Save to Tường AI
|
| 116 |
-
NO AI NEEDED - instant response.
|
| 117 |
"""
|
| 118 |
body = await request.json()
|
| 119 |
url = _clean(body.get("url", ""))
|
|
@@ -140,16 +168,21 @@ async def api_rewrite_slide(request: Request):
|
|
| 140 |
if not points:
|
| 141 |
return JSONResponse({"error": "Không tìm được ý chính"}, status_code=422)
|
| 142 |
|
| 143 |
-
# Build slides:
|
| 144 |
images = data.get('images', [])
|
| 145 |
slides = []
|
| 146 |
for i, point in enumerate(points):
|
| 147 |
img = images[i] if i < len(images) else (images[-1] if images else '')
|
| 148 |
-
# Proxy
|
| 149 |
-
if img and 'cdnphoto.dantri' in img:
|
| 150 |
img = '/api/proxy/img?url=' + quote(img, safe='')
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
slides.append({
|
| 152 |
-
'text':
|
|
|
|
| 153 |
'image': img,
|
| 154 |
'index': i + 1
|
| 155 |
})
|
|
|
|
| 1 |
+
"""Fast rewrite as slides - AI rewrites each key point line-by-line."""
|
| 2 |
from main import app
|
| 3 |
from fastapi import Request
|
| 4 |
from fastapi.responses import JSONResponse
|
|
|
|
| 30 |
def _clean(s): return re.sub(r'\s+', ' ', str(s or '')).strip()
|
| 31 |
|
| 32 |
|
| 33 |
+
def _ai_rewrite_line(text, title=""):
|
| 34 |
+
"""Rewrite a single line using AI - keep meaning, rephrase naturally."""
|
| 35 |
+
hf_token = os.environ.get("HF_TOKEN", "")
|
| 36 |
+
if not hf_token:
|
| 37 |
+
return None
|
| 38 |
+
try:
|
| 39 |
+
api_url = "https://api-inference.huggingface.co/models/google/flan-t5-large"
|
| 40 |
+
headers = {"Authorization": f"Bearer {hf_token}"}
|
| 41 |
+
prompt = f"paraphrase keeping meaning: {text}"
|
| 42 |
+
payload = {
|
| 43 |
+
"inputs": prompt,
|
| 44 |
+
"parameters": {"max_length": 256, "temperature": 0.7, "do_sample": True}
|
| 45 |
+
}
|
| 46 |
+
r = requests.post(api_url, headers=headers, json=payload, timeout=20)
|
| 47 |
+
if r.status_code == 200:
|
| 48 |
+
result = r.json()
|
| 49 |
+
if isinstance(result, list) and len(result) > 0:
|
| 50 |
+
rewritten = result[0].get("generated_text", "").strip()
|
| 51 |
+
# Validate: must be different but similar length, in Vietnamese
|
| 52 |
+
if rewritten and len(rewritten) > 20 and rewritten != text:
|
| 53 |
+
# Make sure it's not English
|
| 54 |
+
if re.search(r'[àáạảãâầấậẩẫăằắặẳẵèéẹẻẽêềếệểễìíịỉĩòóọỏõôồốộổỗơờớợởỡùúụủũưừứựửữỳýỵỷỹđ]', rewritten):
|
| 55 |
+
return rewritten
|
| 56 |
+
except:
|
| 57 |
+
pass
|
| 58 |
+
return None
|
| 59 |
+
|
| 60 |
+
|
| 61 |
def _scrape_article_full(url):
|
| 62 |
"""Scrape article: extract paragraphs + ALL images."""
|
| 63 |
try:
|
|
|
|
| 112 |
return None
|
| 113 |
|
| 114 |
|
| 115 |
+
def _extract_key_points(paragraphs, max_points=6):
|
| 116 |
"""Extract key points: take first sentence of each significant paragraph."""
|
| 117 |
points = []
|
| 118 |
for p in paragraphs:
|
|
|
|
| 136 |
@app.post("/api/rewrite_slide")
|
| 137 |
async def api_rewrite_slide(request: Request):
|
| 138 |
"""
|
| 139 |
+
Fast rewrite as SLIDES with AI:
|
| 140 |
+
- Extract key points from article (1 sentence each)
|
| 141 |
+
- AI rewrites EACH line individually (keep meaning, rephrase)
|
| 142 |
+
- Pair each rewritten point with an image from the article
|
| 143 |
- Return as slides array for frontend to display
|
| 144 |
- Save to Tường AI
|
|
|
|
| 145 |
"""
|
| 146 |
body = await request.json()
|
| 147 |
url = _clean(body.get("url", ""))
|
|
|
|
| 168 |
if not points:
|
| 169 |
return JSONResponse({"error": "Không tìm được ý chính"}, status_code=422)
|
| 170 |
|
| 171 |
+
# Build slides: AI rewrite each line individually, pair with image
|
| 172 |
images = data.get('images', [])
|
| 173 |
slides = []
|
| 174 |
for i, point in enumerate(points):
|
| 175 |
img = images[i] if i < len(images) else (images[-1] if images else '')
|
| 176 |
+
# Proxy images that need it
|
| 177 |
+
if img and ('cdnphoto.dantri' in img or 'xemlaibongda' in img):
|
| 178 |
img = '/api/proxy/img?url=' + quote(img, safe='')
|
| 179 |
+
|
| 180 |
+
# AI rewrite this line only (keep meaning, rephrase naturally)
|
| 181 |
+
rewritten = _ai_rewrite_line(point, data.get('title', '')) or point
|
| 182 |
+
|
| 183 |
slides.append({
|
| 184 |
+
'text': rewritten,
|
| 185 |
+
'original': point,
|
| 186 |
'image': img,
|
| 187 |
'index': i + 1
|
| 188 |
})
|