Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -158,7 +158,7 @@ function copyToClipboard(text) {
|
|
| 158 |
with gr.Blocks(theme=gr.themes.Soft(), title="AI 图像标签分析器", css=custom_css, js=_js_functions) as demo:
|
| 159 |
with gr.Row():
|
| 160 |
login_button = gr.LoginButton()
|
| 161 |
-
user_info = gr.Markdown("
|
| 162 |
|
| 163 |
gr.Markdown("# 🖼️ AI 图像标签分析器")
|
| 164 |
gr.Markdown("上传图片自动识别标签,支持中英文显示和一键复制。[NovelAI在线绘画](https://nai.idlecloud.cc/)")
|
|
@@ -229,7 +229,7 @@ with gr.Blocks(theme=gr.themes.Soft(), title="AI 图像标签分析器", css=cus
|
|
| 229 |
if show_translation_in_list and i < len(translations_list) and translations_list[i]:
|
| 230 |
tag_display_html += f'<span class="tag-zh">({translations_list[i]})</span>'
|
| 231 |
html += f'<div>{tag_display_html}</div>'
|
| 232 |
-
if show_scores: html += f'<span class
|
| 233 |
html += '</div>'
|
| 234 |
html += '</div>'
|
| 235 |
return html
|
|
@@ -257,21 +257,37 @@ with gr.Blocks(theme=gr.themes.Soft(), title="AI 图像标签分析器", css=cus
|
|
| 257 |
joiner = "\n\n" if separator != "\n" and len(summary_parts) > 1 else separator
|
| 258 |
final_summary = joiner.join(summary_parts)
|
| 259 |
return final_summary if final_summary else "选定的类别中没有找到标签。"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 260 |
|
| 261 |
def process_image_and_generate_outputs(img, g_th, c_th, s_scores, s_gen, s_char, s_rat, s_sep, s_zh_in_sum, guest_tc_id, guest_tc_key, guest_bd_json, profile: gr.OAuthProfile | None):
|
|
|
|
|
|
|
| 262 |
if profile is None:
|
| 263 |
gr.Warning("请先登录后再进行分析!")
|
| 264 |
-
yield (gr.update(), gr.update(visible=False), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update())
|
| 265 |
return
|
| 266 |
|
| 267 |
if img is None:
|
| 268 |
-
yield (gr.update(interactive=True, value="🚀 开始分析"), gr.update(visible=True, value="❌ 请先上传图片。"), "", "", "",
|
| 269 |
return
|
| 270 |
if tagger_instance is None:
|
| 271 |
-
yield (gr.update(interactive=True, value="🚀 开始分析"), gr.update(visible=True, value="❌ 分析器未成功初始化,请检查控制台错误。"), "", "", "",
|
| 272 |
return
|
| 273 |
|
| 274 |
-
yield (gr.update(interactive=False, value="🔄 处理中..."), gr.update(visible=True, value="🔄 正在分析图像..."), gr.HTML(value="<p>分析中...</p>"), gr.HTML(value="<p>分析中...</p>"), gr.HTML(value="<p>分析中...</p>"), gr.update(value="分析中..."), {}, {}, {})
|
| 275 |
|
| 276 |
try:
|
| 277 |
res, tag_categories_original_order = tagger_instance.predict(img, g_th, c_th)
|
|
@@ -303,42 +319,39 @@ with gr.Blocks(theme=gr.themes.Soft(), title="AI 图像标签分析器", css=cus
|
|
| 303 |
rating_html = format_tags_html(res.get("ratings", {}), current_translations_dict.get("ratings", []), "ratings", s_scores)
|
| 304 |
summary_text = generate_summary_text_content(res, current_translations_dict, s_gen, s_char, s_rat, s_sep, s_zh_in_sum)
|
| 305 |
|
| 306 |
-
yield (gr.update(interactive=True, value="🚀 开始分析"), gr.update(visible=True, value="✅ 分析完成!"), general_html, char_html, rating_html, gr.update(value=summary_text), res, current_translations_dict, tag_categories_original_order)
|
| 307 |
|
| 308 |
except Exception as e:
|
| 309 |
import traceback
|
| 310 |
tb_str = traceback.format_exc()
|
| 311 |
print(f"处理时发生错误: {e}\n{tb_str}")
|
| 312 |
-
yield (gr.update(interactive=True, value="🚀 开始分析"), gr.update(visible=True, value=f"❌ 处理失败: {str(e)}"), "<p>处理出错</p>", "<p>处理出错</p>", "<p>处理出错</p>", gr.update(value=f"错误: {str(e)}", placeholder="分析失败..."), {}, {}, {})
|
| 313 |
|
| 314 |
def update_summary_display(s_gen, s_char, s_rat, s_sep, s_zh_in_sum, current_res, current_translations):
|
| 315 |
if not current_res: return gr.update(placeholder="请先完成一次图像分析以生成汇总。", value="")
|
| 316 |
new_summary_text = generate_summary_text_content(current_res, current_translations, s_gen, s_char, s_rat, s_sep, s_zh_in_sum)
|
| 317 |
return gr.update(value=new_summary_text)
|
| 318 |
|
| 319 |
-
def check_user_auth(profile: gr.OAuthProfile | None):
|
| 320 |
if not OWNER_USERNAME: print("⚠️ 警告: 未设置 OWNER_USERNAME 环境变量。所有用户都将被视为访客。")
|
| 321 |
|
| 322 |
if profile is None:
|
| 323 |
print("- [Auth] 用户未登录。")
|
| 324 |
-
return gr.update(visible=True), "请先登录..."
|
| 325 |
-
|
| 326 |
-
username = profile.username.lower()
|
| 327 |
-
if username == OWNER_USERNAME:
|
| 328 |
-
print(f"- [Auth] 所有者 '{profile.username}' 已连接。")
|
| 329 |
-
user_info_md = f"✅ **所有者模式**: 欢迎, {profile.name}! 将使用预置翻译服务。"
|
| 330 |
-
return gr.update(visible=False), user_info_md
|
| 331 |
else:
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
|
| 336 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 337 |
|
| 338 |
btn.click(
|
| 339 |
process_image_and_generate_outputs,
|
| 340 |
inputs=[img_in, gen_slider, char_slider, show_tag_scores, sum_general, sum_char, sum_rating, sum_sep, sum_show_zh, guest_tencent_id, guest_tencent_key, guest_baidu_json, login_button],
|
| 341 |
-
outputs=[btn, processing_info, out_general, out_char, out_rating, out_summary, state_res, state_translations_dict, state_tag_categories_for_translation]
|
| 342 |
)
|
| 343 |
|
| 344 |
summary_controls = [sum_general, sum_char, sum_rating, sum_sep, sum_show_zh]
|
|
|
|
| 158 |
with gr.Blocks(theme=gr.themes.Soft(), title="AI 图像标签分析器", css=custom_css, js=_js_functions) as demo:
|
| 159 |
with gr.Row():
|
| 160 |
login_button = gr.LoginButton()
|
| 161 |
+
user_info = gr.Markdown("正在检查登录状态...", visible=True)
|
| 162 |
|
| 163 |
gr.Markdown("# 🖼️ AI 图像标签分析器")
|
| 164 |
gr.Markdown("上传图片自动识别标签,支持中英文显示和一键复制。[NovelAI在线绘画](https://nai.idlecloud.cc/)")
|
|
|
|
| 229 |
if show_translation_in_list and i < len(translations_list) and translations_list[i]:
|
| 230 |
tag_display_html += f'<span class="tag-zh">({translations_list[i]})</span>'
|
| 231 |
html += f'<div>{tag_display_html}</div>'
|
| 232 |
+
if show_scores: html += f'<span class.tag-score">{score:.3f}</span>'
|
| 233 |
html += '</div>'
|
| 234 |
html += '</div>'
|
| 235 |
return html
|
|
|
|
| 257 |
joiner = "\n\n" if separator != "\n" and len(summary_parts) > 1 else separator
|
| 258 |
final_summary = joiner.join(summary_parts)
|
| 259 |
return final_summary if final_summary else "选定的类别中没有找到标签。"
|
| 260 |
+
|
| 261 |
+
def update_auth_ui(profile: gr.OAuthProfile | None):
|
| 262 |
+
if profile is None:
|
| 263 |
+
return gr.update(visible=True), "请先登录..."
|
| 264 |
+
|
| 265 |
+
username = profile.username.lower()
|
| 266 |
+
is_owner = username == OWNER_USERNAME
|
| 267 |
+
|
| 268 |
+
if is_owner:
|
| 269 |
+
user_info_md = f"✅ **所有者模式**: 欢迎, {profile.name}! 将使用预置翻译服务。"
|
| 270 |
+
else:
|
| 271 |
+
user_info_md = f"👋 **访客模式**: 欢迎, {profile.name}! 请在高级设置中提供您自己的翻译密钥。"
|
| 272 |
+
|
| 273 |
+
return gr.update(visible=not is_owner), user_info_md
|
| 274 |
|
| 275 |
def process_image_and_generate_outputs(img, g_th, c_th, s_scores, s_gen, s_char, s_rat, s_sep, s_zh_in_sum, guest_tc_id, guest_tc_key, guest_bd_json, profile: gr.OAuthProfile | None):
|
| 276 |
+
guest_api_update, user_info_update = update_auth_ui(profile)
|
| 277 |
+
|
| 278 |
if profile is None:
|
| 279 |
gr.Warning("请先登录后再进行分析!")
|
| 280 |
+
yield (gr.update(), gr.update(visible=False), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), guest_api_update, user_info_update)
|
| 281 |
return
|
| 282 |
|
| 283 |
if img is None:
|
| 284 |
+
yield (gr.update(interactive=True, value="🚀 开始分析"), gr.update(visible=True, value="❌ 请先上传图片。"), "", "", "", gr.update(placeholder="请先上传图片并开始分析..."), {}, {}, {}, guest_api_update, user_info_update)
|
| 285 |
return
|
| 286 |
if tagger_instance is None:
|
| 287 |
+
yield (gr.update(interactive=True, value="🚀 开始分析"), gr.update(visible=True, value="❌ 分析器未成功初始化,请检查控制台错误。"), "", "", "", gr.update(placeholder="分析器初始化失败..."), {}, {}, {}, guest_api_update, user_info_update)
|
| 288 |
return
|
| 289 |
|
| 290 |
+
yield (gr.update(interactive=False, value="🔄 处理中..."), gr.update(visible=True, value="🔄 正在分析图像..."), gr.HTML(value="<p>分析中...</p>"), gr.HTML(value="<p>分析中...</p>"), gr.HTML(value="<p>分析中...</p>"), gr.update(value="分析中..."), {}, {}, {}, guest_api_update, user_info_update)
|
| 291 |
|
| 292 |
try:
|
| 293 |
res, tag_categories_original_order = tagger_instance.predict(img, g_th, c_th)
|
|
|
|
| 319 |
rating_html = format_tags_html(res.get("ratings", {}), current_translations_dict.get("ratings", []), "ratings", s_scores)
|
| 320 |
summary_text = generate_summary_text_content(res, current_translations_dict, s_gen, s_char, s_rat, s_sep, s_zh_in_sum)
|
| 321 |
|
| 322 |
+
yield (gr.update(interactive=True, value="🚀 开始分析"), gr.update(visible=True, value="✅ 分析完成!"), general_html, char_html, rating_html, gr.update(value=summary_text), res, current_translations_dict, tag_categories_original_order, guest_api_update, user_info_update)
|
| 323 |
|
| 324 |
except Exception as e:
|
| 325 |
import traceback
|
| 326 |
tb_str = traceback.format_exc()
|
| 327 |
print(f"处理时发生错误: {e}\n{tb_str}")
|
| 328 |
+
yield (gr.update(interactive=True, value="🚀 开始分析"), gr.update(visible=True, value=f"❌ 处理失败: {str(e)}"), "<p>处理出错</p>", "<p>处理出错</p>", "<p>处理出错</p>", gr.update(value=f"错误: {str(e)}", placeholder="分析失败..."), {}, {}, {}, guest_api_update, user_info_update)
|
| 329 |
|
| 330 |
def update_summary_display(s_gen, s_char, s_rat, s_sep, s_zh_in_sum, current_res, current_translations):
|
| 331 |
if not current_res: return gr.update(placeholder="请先完成一次图像分析以生成汇总。", value="")
|
| 332 |
new_summary_text = generate_summary_text_content(current_res, current_translations, s_gen, s_char, s_rat, s_sep, s_zh_in_sum)
|
| 333 |
return gr.update(value=new_summary_text)
|
| 334 |
|
| 335 |
+
def check_user_auth(profile: gr.OAuthProfile | None, request: gr.Request = None):
|
| 336 |
if not OWNER_USERNAME: print("⚠️ 警告: 未设置 OWNER_USERNAME 环境变量。所有用户都将被视为访客。")
|
| 337 |
|
| 338 |
if profile is None:
|
| 339 |
print("- [Auth] 用户未登录。")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 340 |
else:
|
| 341 |
+
if profile.username.lower() == OWNER_USERNAME:
|
| 342 |
+
print(f"- [Auth] 所有者 '{profile.username}' 已连接。")
|
| 343 |
+
else:
|
| 344 |
+
print(f"- [Auth] 访客 '{profile.username}' 已连接,显示 API Key 输入框。")
|
| 345 |
+
return update_auth_ui(profile)
|
| 346 |
+
|
| 347 |
+
demo.load(fn=check_user_auth, inputs=[login_button], outputs=[guest_api_group, user_info])
|
| 348 |
+
|
| 349 |
+
img_in.upload(fn=update_auth_ui, inputs=[login_button], outputs=[guest_api_group, user_info])
|
| 350 |
|
| 351 |
btn.click(
|
| 352 |
process_image_and_generate_outputs,
|
| 353 |
inputs=[img_in, gen_slider, char_slider, show_tag_scores, sum_general, sum_char, sum_rating, sum_sep, sum_show_zh, guest_tencent_id, guest_tencent_key, guest_baidu_json, login_button],
|
| 354 |
+
outputs=[btn, processing_info, out_general, out_char, out_rating, out_summary, state_res, state_translations_dict, state_tag_categories_for_translation, guest_api_group, user_info]
|
| 355 |
)
|
| 356 |
|
| 357 |
summary_controls = [sum_general, sum_char, sum_rating, sum_sep, sum_show_zh]
|