Upload folder using huggingface_hub
Browse files
app.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
import json
|
| 3 |
import base64
|
|
|
|
|
|
|
| 4 |
from data_manager import data_manager
|
| 5 |
|
| 6 |
# ============== 状态管理 (封装逻辑) ==============
|
|
@@ -21,10 +23,55 @@ class ReviewState:
|
|
| 21 |
|
| 22 |
nav_state = ReviewState()
|
| 23 |
|
| 24 |
-
# ============== 工具函数 ==============
|
| 25 |
-
def to_html_frame(html_content):
|
| 26 |
-
if not html_content:
|
| 27 |
return '<div style="padding:20px;text-align:center;">请选择数据进行加载</div>'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
b64_content = base64.b64encode(html_content.encode('utf-8')).decode('utf-8')
|
| 29 |
return f'<iframe src="data:text/html;base64,{b64_content}" style="width:100%;height:600px;border:none;"></iframe>'
|
| 30 |
|
|
@@ -57,7 +104,12 @@ def handle_load(source, c_type, c_id, model):
|
|
| 57 |
nav_state.current_idx = i
|
| 58 |
break
|
| 59 |
|
| 60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
meta_md = "\n".join([f"- **{k}**: {v}" for k, v in chart_data.get('label_info', {}).items()])
|
| 62 |
qa_json = json.dumps([{"id": q.id, "q": q.question, "a": q.answer} for q in qa_list])
|
| 63 |
stats_str = f"✅{stats['correct']} | ❌{stats['incorrect']} | 总{stats['total']}"
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import json
|
| 3 |
import base64
|
| 4 |
+
import re # 【新增】用于正则匹配本地脚本路径
|
| 5 |
+
from pathlib import Path # 【新增】用于处理相对路径
|
| 6 |
from data_manager import data_manager
|
| 7 |
|
| 8 |
# ============== 状态管理 (封装逻辑) ==============
|
|
|
|
| 23 |
|
| 24 |
nav_state = ReviewState()
|
| 25 |
|
| 26 |
+
# ============== 工具函数 (动态内联注入升级版) ==============
|
| 27 |
+
def to_html_frame(html_content, html_path):
|
| 28 |
+
if not html_content or not html_path:
|
| 29 |
return '<div style="padding:20px;text-align:center;">请选择数据进行加载</div>'
|
| 30 |
+
|
| 31 |
+
# 获取当前 html 文件所在的本地绝对路径文件夹
|
| 32 |
+
base_dir = Path(html_path).parent
|
| 33 |
+
|
| 34 |
+
# 1. 动态内联本地 JS 文件
|
| 35 |
+
def script_replacer(match):
|
| 36 |
+
src_path = match.group(1)
|
| 37 |
+
# 如果已经是互联网 CDN 链接,则跳过
|
| 38 |
+
if src_path.startswith("http://") or src_path.startswith("https://") or src_path.startswith("//"):
|
| 39 |
+
return match.group(0)
|
| 40 |
+
|
| 41 |
+
# 拼接并解析出本地 JS 文件的真实路径
|
| 42 |
+
local_file = (base_dir / src_path).resolve()
|
| 43 |
+
try:
|
| 44 |
+
with open(local_file, 'r', encoding='utf-8') as f:
|
| 45 |
+
content = f.read()
|
| 46 |
+
# 关键替换:防止 JS 源码中的 </script> 导致 HTML 提前闭合崩溃
|
| 47 |
+
content = content.replace('</script>', '<\\/script>')
|
| 48 |
+
return f'<script>\n{content}\n</script>'
|
| 49 |
+
except Exception as e:
|
| 50 |
+
print(f"Warning: 未找到依赖的本地脚本 {local_file}")
|
| 51 |
+
return match.group(0) # 失败则保持原样
|
| 52 |
+
|
| 53 |
+
# 正则匹配所有 <script src="..."></script> 标签
|
| 54 |
+
html_content = re.sub(r'<script\b[^>]*?src=["\']([^"\']+)["\'][^>]*></script>', script_replacer, html_content)
|
| 55 |
+
|
| 56 |
+
# 2. 动态内联本地 CSS 文件
|
| 57 |
+
def css_replacer(match):
|
| 58 |
+
href_path = match.group(1)
|
| 59 |
+
if href_path.startswith("http://") or href_path.startswith("https://") or href_path.startswith("//"):
|
| 60 |
+
return match.group(0)
|
| 61 |
+
|
| 62 |
+
local_file = (base_dir / href_path).resolve()
|
| 63 |
+
try:
|
| 64 |
+
with open(local_file, 'r', encoding='utf-8') as f:
|
| 65 |
+
content = f.read()
|
| 66 |
+
return f'<style>\n{content}\n</style>'
|
| 67 |
+
except Exception as e:
|
| 68 |
+
return match.group(0)
|
| 69 |
+
|
| 70 |
+
# 匹配 <link rel="stylesheet" href="...">
|
| 71 |
+
html_content = re.sub(r'<link\b[^>]*?rel=["\']stylesheet["\'][^>]*?href=["\']([^"\']+)["\'][^>]*?>', css_replacer, html_content)
|
| 72 |
+
html_content = re.sub(r'<link\b[^>]*?href=["\']([^"\']+)["\'][^>]*?rel=["\']stylesheet["\'][^>]*?>', css_replacer, html_content)
|
| 73 |
+
|
| 74 |
+
# 3. 转换为最终的自我包裹式 Base64 Iframe
|
| 75 |
b64_content = base64.b64encode(html_content.encode('utf-8')).decode('utf-8')
|
| 76 |
return f'<iframe src="data:text/html;base64,{b64_content}" style="width:100%;height:600px;border:none;"></iframe>'
|
| 77 |
|
|
|
|
| 104 |
nav_state.current_idx = i
|
| 105 |
break
|
| 106 |
|
| 107 |
+
# 【传入参数升级】传入 html_path 用于定位本地依赖
|
| 108 |
+
html_code = to_html_frame(
|
| 109 |
+
chart_data.get('html_content', ''),
|
| 110 |
+
chart_data.get('html_path', '')
|
| 111 |
+
)
|
| 112 |
+
|
| 113 |
meta_md = "\n".join([f"- **{k}**: {v}" for k, v in chart_data.get('label_info', {}).items()])
|
| 114 |
qa_json = json.dumps([{"id": q.id, "q": q.question, "a": q.answer} for q in qa_list])
|
| 115 |
stats_str = f"✅{stats['correct']} | ❌{stats['incorrect']} | 总{stats['total']}"
|