Spaces:
Sleeping
Sleeping
import os | |
import json | |
import gradio as gr | |
from openai import OpenAI | |
############################################################################## | |
# 1. 读取外部文件: furry_species.json & gender_rules.json | |
############################################################################## | |
try: | |
with open("furry_species.json", "r", encoding="utf-8") as f: | |
FURRY_DATA = json.load(f) | |
except: | |
FURRY_DATA = {} | |
try: | |
with open("gender_rules.json", "r", encoding="utf-8") as f: | |
GENDER_RULES = json.load(f) | |
except: | |
GENDER_RULES = {} | |
############################################################################## | |
# 2. 多级菜单构造函数 | |
############################################################################## | |
def get_top_categories(furry_data): | |
return sorted(list(furry_data.keys())) | |
def get_sub_categories(furry_data, top_category): | |
if top_category in furry_data: | |
return sorted(list(furry_data[top_category].keys())) | |
return [] | |
def get_species_list(furry_data, top_category, sub_category): | |
if top_category in furry_data and sub_category in furry_data[top_category]: | |
return sorted(furry_data[top_category][sub_category]) | |
return [] | |
############################################################################## | |
# 3. 核心调用:GPT 或 DeepSeek | |
############################################################################## | |
def generate_transformed_output( | |
prompt, # 原始 Prompt,如 "1girl, butterfly, solo..." | |
gender_option, # 转换目标 | |
top_cat, sub_cat, species_item, | |
api_mode, api_key | |
): | |
""" | |
根据指定的性别/物种等规则,让 GPT/DeepSeek 输出仅两段内容: | |
(转化后tags) | |
转化后描述 (3~6句) | |
不展示原始 prompt/base_prompt/gender: ... 等信息。 | |
""" | |
if not api_key: | |
return "Error: No API Key provided." | |
# 根据 gender_option 选对应的 rule | |
if gender_option == "Trans_to_Male": | |
rule_text = GENDER_RULES.get("male", "") | |
elif gender_option == "Trans_to_Female": | |
rule_text = GENDER_RULES.get("female", "") | |
elif gender_option == "Trans_to_Mannequin": | |
rule_text = GENDER_RULES.get("genderless", "") | |
elif gender_option == "Trans_to_Intersex": | |
rule_text = GENDER_RULES.get("intersex", "") | |
else: | |
# Furry | |
# 你可以综合 male/female/intersex/genderless,也可以有专门 furry 的说明 | |
rule_text = ( | |
GENDER_RULES.get("male", "") + "\n\n" | |
+ GENDER_RULES.get("female", "") + "\n\n" | |
+ GENDER_RULES.get("intersex", "") + "\n\n" | |
+ GENDER_RULES.get("genderless", "") | |
) | |
# 如果想在规则中附加选定的物种信息: | |
if top_cat and sub_cat and species_item: | |
rule_text += f"\nFurry species: {top_cat} > {sub_cat} > {species_item}\n" | |
# 选定 GPT or DeepSeek | |
if api_mode == "GPT": | |
base_url = None | |
model_name = "gpt-3.5-turbo" # 可改成 "gpt-4" | |
else: | |
base_url = "https://api.deepseek.com" | |
model_name = "deepseek-chat" | |
client = OpenAI(api_key=api_key) | |
if base_url: | |
client.base_url = base_url | |
# 构造 System Prompt:要求只输出两段;第一行(转化后tags),空行,随后3~6句描述 | |
# 让它把 prompt 中的 tags 进行「合并、替换、去重、增加」等处理 | |
system_prompt = f""" | |
You are a creative assistant that modifies the user's base prompt tags | |
to reflect the correct gender/furry transformations, following these rules: | |
{rule_text} | |
Steps: | |
1) The original prompt tags are: {prompt} | |
2) Convert them into NEW combined tags that reflect the requested transformation. | |
(Remove or replace conflicting tags, unify synonyms, add any essential tags | |
for {gender_option} or for the selected furry species.) | |
3) Output EXACTLY two parts: | |
- First line: the final, consolidated tags in parentheses (e.g. (male, solo, ...)). | |
- Then a blank line. | |
- Then a short imaginative scene description (3 to 6 sentences). | |
4) Do NOT include 'gender:' or 'base_prompt:' or any headings or extra lines. | |
5) Output everything in English. | |
6) Do not reference these steps in the final answer. | |
""".strip() | |
try: | |
resp = client.chat.completions.create( | |
model=model_name, | |
messages=[ | |
{"role": "system", "content": system_prompt}, | |
{"role": "user", "content": "Generate the final tags and description now."}, | |
], | |
) | |
# 结果中仅包含 (tags)\n\n(description) | |
result = resp.choices[0].message.content.strip() | |
return result | |
except Exception as e: | |
return f"{api_mode} generation failed. Error: {e}" | |
def translate_text(content, lang, api_mode, api_key): | |
""" | |
对上一步的 (tags)\n\n(description) 做翻译,保持格式 | |
""" | |
if not api_key: | |
return "Error: No API Key provided." | |
if not content.strip(): | |
return "" | |
if api_mode == "GPT": | |
base_url = None | |
model_name = "gpt-3.5-turbo" | |
else: | |
base_url = "https://api.deepseek.com" | |
model_name = "deepseek-chat" | |
client = OpenAI(api_key=api_key) | |
if base_url: | |
client.base_url = base_url | |
translate_system_prompt = f""" | |
You are a translator. Translate the following text to {lang}, | |
preserving the parentheses line and blank lines if present. | |
Do not add extra headings. | |
""".strip() | |
try: | |
resp = client.chat.completions.create( | |
model=model_name, | |
messages=[ | |
{"role": "system", "content": translate_system_prompt}, | |
{"role": "user", "content": content}, | |
], | |
) | |
return resp.choices[0].message.content.strip() | |
except Exception as e: | |
return f"{api_mode} translation failed. Error: {e}" | |
############################################################################## | |
# 4. Gradio 前端 | |
############################################################################## | |
def build_interface(): | |
with gr.Blocks() as demo: | |
gr.Markdown("## Prompt Transformer Tool- 提示词物种性别转化器(GPT/DeepSeek)") | |
with gr.Row(): | |
with gr.Column(): | |
# 选择 GPT/DeepSeek | |
api_mode = gr.Radio( | |
label="Choose API (GPT or DeepSeek)", | |
choices=["GPT", "DeepSeek"], | |
value="GPT" | |
) | |
# 输入 API Key | |
api_key = gr.Textbox( | |
label="API Key-API密匙", | |
type="password", | |
placeholder="Enter your GPT or DeepSeek Key here" | |
) | |
# 性别/Furry | |
gender_option = gr.Radio( | |
label="Gender / Furry Conversion 选择物种性别", | |
choices=[ | |
"Trans_to_Male", | |
"Trans_to_Female", | |
"Trans_to_Mannequin", | |
"Trans_to_Intersex", | |
"Trans_to_Furry" | |
], | |
value="Trans_to_Male" | |
) | |
# 若选 Furry -> 多级菜单 | |
top_cat_dd = gr.Dropdown( | |
label="Furry: Top Category", | |
choices=get_top_categories(FURRY_DATA), | |
value=None, | |
visible=False | |
) | |
sub_cat_dd = gr.Dropdown( | |
label="Furry: Sub Category", | |
choices=[], | |
value=None, | |
visible=False | |
) | |
species_dd = gr.Dropdown( | |
label="Furry: Species", | |
choices=[], | |
value=None, | |
visible=False | |
) | |
# 当性别选项切到 Furry 时,显示下拉,否则隐藏 | |
def show_furry_options(chosen): | |
if chosen == "Trans_to_Furry": | |
return (gr.update(visible=True), | |
gr.update(visible=True), | |
gr.update(visible=True)) | |
else: | |
return (gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=False)) | |
gender_option.change( | |
fn=show_furry_options, | |
inputs=[gender_option], | |
outputs=[top_cat_dd, sub_cat_dd, species_dd] | |
) | |
# 主分类 -> 子分类 | |
def on_top_cat_select(selected): | |
subs = get_sub_categories(FURRY_DATA, selected) | |
return gr.update(choices=subs, value=None) | |
top_cat_dd.change( | |
fn=on_top_cat_select, | |
inputs=[top_cat_dd], | |
outputs=[sub_cat_dd] | |
) | |
# 子分类 -> 物种 | |
def on_sub_cat_select(top_c, sub_c): | |
sp = get_species_list(FURRY_DATA, top_c, sub_c) | |
return gr.update(choices=sp, value=None) | |
sub_cat_dd.change( | |
fn=on_sub_cat_select, | |
inputs=[top_cat_dd, sub_cat_dd], | |
outputs=[species_dd] | |
) | |
# 输入 prompt & 输出 | |
with gr.Column(): | |
user_prompt = gr.Textbox( | |
label="原始 Prompt (Base Tags)", | |
lines=5, | |
placeholder="Your Prompts" | |
) | |
final_output = gr.Textbox( | |
label="(转化后Tags)\n\n(转化后描述)", | |
lines=10 | |
) | |
# 翻译 | |
with gr.Row(): | |
translate_lang = gr.Dropdown( | |
label="翻译语言 Translater", | |
choices=["English", "Chinese", "Japanese", "French", "German", "Spanish"], | |
value="English" | |
) | |
translated_result = gr.Textbox( | |
label="翻译后的结果 Trans-Language Result", | |
lines=10 | |
) | |
###################################################################### | |
# 事件 | |
###################################################################### | |
def on_generate(prompt, gender, tc, sc, sp, mode, key, lang): | |
# 1) 生成新的 (tags) + 描述 | |
merged = generate_transformed_output(prompt, gender, tc, sc, sp, mode, key) | |
# 2) 翻译 | |
trans = translate_text(merged, lang, mode, key) | |
return merged, trans | |
# 回车提交 | |
user_prompt.submit( | |
fn=on_generate, | |
inputs=[user_prompt, gender_option, top_cat_dd, sub_cat_dd, species_dd, api_mode, api_key, translate_lang], | |
outputs=[final_output, translated_result] | |
) | |
# 点击按钮 | |
btn = gr.Button("生成 / Generate") | |
btn.click( | |
fn=on_generate, | |
inputs=[user_prompt, gender_option, top_cat_dd, sub_cat_dd, species_dd, api_mode, api_key, translate_lang], | |
outputs=[final_output, translated_result] | |
) | |
return demo | |
if __name__ == "__main__": | |
demo = build_interface() | |
demo.launch() |