Spaces:
Runtime error
Runtime error
Upload 7 files
Browse files- waifuc_gui/__init__.py +0 -0
- waifuc_gui/action_manager.py +50 -0
- waifuc_gui/config_manager.py +64 -0
- waifuc_gui/exporter_manager.py +17 -0
- waifuc_gui/file_handler.py +29 -0
- waifuc_gui/interface.py +244 -0
- waifuc_gui/source_manager.py +86 -0
waifuc_gui/__init__.py
ADDED
File without changes
|
waifuc_gui/action_manager.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import inspect
|
2 |
+
import waifuc.action
|
3 |
+
import gradio as gr
|
4 |
+
from .config_manager import ConfigManager
|
5 |
+
|
6 |
+
class ActionManager:
|
7 |
+
def __init__(self, config_manager: ConfigManager):
|
8 |
+
self.config_manager = config_manager
|
9 |
+
self.action_classes = [
|
10 |
+
cls for name, cls in inspect.getmembers(waifuc.action, inspect.isclass)
|
11 |
+
if name.endswith("Action") and not inspect.isabstract(cls)
|
12 |
+
]
|
13 |
+
self.action_names = [cls.__name__ for cls in self.action_classes]
|
14 |
+
|
15 |
+
def get_action_params(self, action_name):
|
16 |
+
action_cls = next(cls for cls in self.action_classes if cls.__name__ == action_name)
|
17 |
+
sig = inspect.signature(action_cls.__init__)
|
18 |
+
return [p for p in sig.parameters.values() if p.name != 'self']
|
19 |
+
|
20 |
+
def create_action_param_inputs(self, selected_actions):
|
21 |
+
params = {}
|
22 |
+
for action in selected_actions:
|
23 |
+
params[action] = {}
|
24 |
+
for param in self.get_action_params(action):
|
25 |
+
if param.name == "size" and action == "ResizeAction":
|
26 |
+
params[action][param.name] = gr.Number(
|
27 |
+
label="Resize Size" if self.config_manager.get_config("language") == "en" else "调整大小",
|
28 |
+
value=self.config_manager.get_config("default_resize_size"),
|
29 |
+
info="Image resize dimension" if self.config_manager.get_config("language") == "en" else "图片调整尺寸"
|
30 |
+
)
|
31 |
+
elif param.annotation == int:
|
32 |
+
params[action][param.name] = gr.Number(label=param.name)
|
33 |
+
else:
|
34 |
+
params[action][param.name] = gr.Textbox(label=param.name)
|
35 |
+
return params
|
36 |
+
|
37 |
+
def instantiate_actions(self, selected_actions, action_params):
|
38 |
+
actions = []
|
39 |
+
for name in selected_actions:
|
40 |
+
action_cls = next(cls for cls in self.action_classes if cls.__name__ == name)
|
41 |
+
params = action_params.get(name, {})
|
42 |
+
if name == "FaceCountAction":
|
43 |
+
actions.append(action_cls(params.get("count", 1)))
|
44 |
+
elif name == "AlignMinSizeAction":
|
45 |
+
actions.append(action_cls(params.get("size", 800)))
|
46 |
+
elif name == "ResizeAction":
|
47 |
+
actions.append(action_cls(size=params.get("size", self.config_manager.get_config("default_resize_size"))))
|
48 |
+
else:
|
49 |
+
actions.append(action_cls(**params))
|
50 |
+
return actions
|
waifuc_gui/config_manager.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import json
|
3 |
+
import uuid
|
4 |
+
from typing import Dict, Any
|
5 |
+
|
6 |
+
class ConfigManager:
|
7 |
+
def __init__(self, session_id: str):
|
8 |
+
self.session_id = session_id
|
9 |
+
self.config_dir = f"/tmp/user_{session_id}"
|
10 |
+
self.config_file = os.path.join(self.config_dir, "config.json")
|
11 |
+
self.config: Dict[str, Any] = {}
|
12 |
+
self.load_configs()
|
13 |
+
|
14 |
+
def load_configs(self):
|
15 |
+
self.config = {
|
16 |
+
"pixiv_refresh_token": "",
|
17 |
+
"output_dir": f"/tmp/user_{self.session_id}/output",
|
18 |
+
"default_num_items": 100,
|
19 |
+
"default_resize_size": 512,
|
20 |
+
"language": "zh"
|
21 |
+
}
|
22 |
+
if os.path.exists(self.config_file):
|
23 |
+
try:
|
24 |
+
with open(self.config_file, 'r') as f:
|
25 |
+
self.config.update(json.load(f))
|
26 |
+
except Exception as e:
|
27 |
+
print(f"Failed to load session config: {e}")
|
28 |
+
|
29 |
+
def save_configs(self):
|
30 |
+
os.makedirs(self.config_dir, exist_ok=True)
|
31 |
+
try:
|
32 |
+
with open(self.config_file, 'w') as f:
|
33 |
+
json.dump(self.config, f, indent=2)
|
34 |
+
except Exception as e:
|
35 |
+
print(f"Failed to save session config: {e}")
|
36 |
+
|
37 |
+
def get_config(self, key: str, default: Any = None) -> Any:
|
38 |
+
return self.config.get(key, default)
|
39 |
+
|
40 |
+
def set_config(self, key: str, value: Any):
|
41 |
+
self.config[key] = value
|
42 |
+
self.save_configs()
|
43 |
+
|
44 |
+
def get_all_configs(self) -> Dict[str, Any]:
|
45 |
+
return self.config.copy()
|
46 |
+
|
47 |
+
def export_config(self) -> str:
|
48 |
+
export_path = os.path.join(self.config_dir, "config_export.json")
|
49 |
+
with open(export_path, 'w') as f:
|
50 |
+
json.dump(self.config, f, indent=2)
|
51 |
+
return export_path
|
52 |
+
|
53 |
+
def import_config(self, config_file):
|
54 |
+
with open(config_file, 'r') as f:
|
55 |
+
new_config = json.load(f)
|
56 |
+
self.config.update(new_config)
|
57 |
+
self.save_configs()
|
58 |
+
return "Configuration imported" if self.config.get("language") == "en" else "配置已导入"
|
59 |
+
|
60 |
+
def cleanup(self):
|
61 |
+
try:
|
62 |
+
shutil.rmtree(self.config_dir, ignore_errors=True)
|
63 |
+
except Exception as e:
|
64 |
+
print(f"Failed to cleanup session: {e}")
|
waifuc_gui/exporter_manager.py
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import inspect
|
2 |
+
import waifuc.export
|
3 |
+
from .config_manager import ConfigManager
|
4 |
+
|
5 |
+
class ExporterManager:
|
6 |
+
def __init__(self, config_manager: ConfigManager):
|
7 |
+
self.config_manager = config_manager
|
8 |
+
self.exporter_classes = [
|
9 |
+
cls for name, cls in inspect.getmembers(waifuc.export, inspect.isclass)
|
10 |
+
if name.endswith("Exporter") and not inspect.isabstract(cls)
|
11 |
+
]
|
12 |
+
self.exporter_names = [cls.__name__ for cls in self.exporter_classes]
|
13 |
+
|
14 |
+
def instantiate_exporter(self, selected_exporter, dataset_name):
|
15 |
+
exporter_cls = next(cls for cls in self.exporter_classes if cls.__name__ == selected_exporter)
|
16 |
+
output_dir = self.config_manager.get_config("output_dir")
|
17 |
+
return exporter_cls(dataset_name, path=output_dir)
|
waifuc_gui/file_handler.py
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import zipfile
|
3 |
+
import shutil
|
4 |
+
|
5 |
+
class FileHandler:
|
6 |
+
def extract_zip(self, uploaded_file):
|
7 |
+
extract_dir = "/tmp/input"
|
8 |
+
shutil.rmtree(extract_dir, ignore_errors=True)
|
9 |
+
os.makedirs(extract_dir)
|
10 |
+
with zipfile.ZipFile(uploaded_file, 'r') as zip_ref:
|
11 |
+
zip_ref.extractall(extract_dir)
|
12 |
+
return extract_dir
|
13 |
+
|
14 |
+
def create_zip(self, dataset_name):
|
15 |
+
output_dir = f"/tmp/{dataset_name}"
|
16 |
+
zip_path = f"/tmp/{dataset_name}.zip"
|
17 |
+
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
18 |
+
for root, dirs, files in os.walk(dataset_name):
|
19 |
+
for file in files:
|
20 |
+
file_path = os.path.join(root, file)
|
21 |
+
arcname = os.path.relpath(file_path, '.')
|
22 |
+
zipf.write(file_path, arcname)
|
23 |
+
return zip_path
|
24 |
+
|
25 |
+
def save_log(self, log_content):
|
26 |
+
log_path = "/tmp/waifuc_log.txt"
|
27 |
+
with open(log_path, 'w') as f:
|
28 |
+
f.write(log_content)
|
29 |
+
return log_path
|
waifuc_gui/interface.py
ADDED
@@ -0,0 +1,244 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from .source_manager import SourceManager
|
3 |
+
from .action_manager import ActionManager
|
4 |
+
from .exporter_manager import ExporterManager
|
5 |
+
from .config_manager import ConfigManager
|
6 |
+
|
7 |
+
class Interface:
|
8 |
+
def __init__(self, source_manager: SourceManager, action_manager: ActionManager, exporter_manager: ExporterManager, config_manager: ConfigManager):
|
9 |
+
self.source_manager = source_manager
|
10 |
+
self.action_manager = action_manager
|
11 |
+
self.exporter_manager = exporter_manager
|
12 |
+
self.config_manager = config_manager
|
13 |
+
self.params = source_manager.create_param_inputs()
|
14 |
+
self.param_components = [param_input for source_params in self.params.values() for param_input in source_params.values()]
|
15 |
+
self.language_dict = {
|
16 |
+
"zh": {
|
17 |
+
"title": "Waifuc 数据收集工具",
|
18 |
+
"data_collection": "数据收集",
|
19 |
+
"config": "配置",
|
20 |
+
"logs": "日志",
|
21 |
+
"select_source": "选择数据源",
|
22 |
+
"select_actions": "选择动作",
|
23 |
+
"dataset_name": "数据集名称",
|
24 |
+
"select_exporter": "选择导出器",
|
25 |
+
"start_collection": "开始收集",
|
26 |
+
"status": "状态",
|
27 |
+
"download_data": "下载收集的数据",
|
28 |
+
"config_management": "配置管理",
|
29 |
+
"pixiv_token": "Pixiv刷新令牌",
|
30 |
+
"output_dir": "输出目录",
|
31 |
+
"num_items": "默认图片数量",
|
32 |
+
"resize_size": "默认调整大小",
|
33 |
+
"language": "语言",
|
34 |
+
"save_config": "保存配置",
|
35 |
+
"export_config": "导出配置",
|
36 |
+
"import_config": "导入配置",
|
37 |
+
"config_status": "配置状态",
|
38 |
+
"view_logs": "查看日志",
|
39 |
+
"download_log": "下载日志"
|
40 |
+
},
|
41 |
+
"en": {
|
42 |
+
"title": "Waifuc Data Collection Tool",
|
43 |
+
"data_collection": "Data Collection",
|
44 |
+
"config": "Configuration",
|
45 |
+
"logs": "Logs",
|
46 |
+
"select_source": "Select Data Source",
|
47 |
+
"select_actions": "Select Actions",
|
48 |
+
"dataset_name": "Dataset Name",
|
49 |
+
"select_exporter": "Select Exporter",
|
50 |
+
"start_collection": "Start Collection",
|
51 |
+
"status": "Status",
|
52 |
+
"download_data": "Download Collected Data",
|
53 |
+
"config_management": "Configuration Management",
|
54 |
+
"pixiv_token": "Pixiv Refresh Token",
|
55 |
+
"output_dir": "Output Directory",
|
56 |
+
"num_items": "Default Number of Items",
|
57 |
+
"resize_size": "Default Resize Size",
|
58 |
+
"language": "Language",
|
59 |
+
"save_config": "Save Configuration",
|
60 |
+
"export_config": "Export Configuration",
|
61 |
+
"import_config": "Import Configuration",
|
62 |
+
"config_status": "Configuration Status",
|
63 |
+
"view_logs": "View Logs",
|
64 |
+
"download_log": "Download Log"
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
def get_text(self, key):
|
69 |
+
return self.language_dict[self.config_manager.get_config("language")][key]
|
70 |
+
|
71 |
+
def update_params_visibility(self, selected_source):
|
72 |
+
updates = []
|
73 |
+
for source, source_params in self.params.items():
|
74 |
+
for param_name, param_input in source_params.items():
|
75 |
+
updates.append(param_input.update(visible=(source == selected_source)))
|
76 |
+
return updates
|
77 |
+
|
78 |
+
def collect_params(self, selected_source, *param_values):
|
79 |
+
collected = {}
|
80 |
+
source_params = self.params.get(selected_source, {})
|
81 |
+
for param_name, param_value in zip(source_params.keys(), param_values):
|
82 |
+
collected[param_name] = param_value
|
83 |
+
return collected
|
84 |
+
|
85 |
+
def update_action_params(self, selected_actions):
|
86 |
+
action_params = self.action_manager.create_action_param_inputs(selected_actions)
|
87 |
+
components = []
|
88 |
+
for action, params in action_params.items():
|
89 |
+
for param_name, param_input in params.items():
|
90 |
+
components.append(param_input)
|
91 |
+
return components, action_params
|
92 |
+
|
93 |
+
def build(self):
|
94 |
+
with gr.Blocks(title=self.get_text("title")) as demo:
|
95 |
+
language_dropdown = gr.Dropdown(
|
96 |
+
choices=["zh", "en"],
|
97 |
+
label=self.get_text("language"),
|
98 |
+
value=self.config_manager.get_config("language")
|
99 |
+
)
|
100 |
+
with gr.Tab(self.get_text("data_collection")):
|
101 |
+
gr.Markdown("### " + self.get_text("data_collection"))
|
102 |
+
source_dropdown = gr.Dropdown(
|
103 |
+
choices=self.source_manager.source_names,
|
104 |
+
label=self.get_text("select_source"),
|
105 |
+
value=self.source_manager.source_names[0] if self.source_manager.source_names else None,
|
106 |
+
info="Choose a data source like DanbooruSource or LocalSource" if self.config_manager.get_config("language") == "en" else "选择数据源,如DanbooruSource或LocalSource"
|
107 |
+
)
|
108 |
+
param_components = self.param_components
|
109 |
+
action_checkboxes = gr.CheckboxGroup(
|
110 |
+
choices=self.action_manager.action_names,
|
111 |
+
label=self.get_text("select_actions"),
|
112 |
+
value=[],
|
113 |
+
info="Select actions to process images, e.g., NoMonochromeAction" if self.config_manager.get_config("language") == "en" else "选择处理图片的动作,例如NoMonochromeAction"
|
114 |
+
)
|
115 |
+
action_param_components = gr.State(value={})
|
116 |
+
action_param_inputs = []
|
117 |
+
dataset_name_input = gr.Textbox(
|
118 |
+
label=self.get_text("dataset_name"),
|
119 |
+
value="waifuc_dataset",
|
120 |
+
info="Name for the output dataset" if self.config_manager.get_config("language") == "en" else "输出数据集的名称"
|
121 |
+
)
|
122 |
+
exporter_dropdown = gr.Dropdown(
|
123 |
+
choices=self.exporter_manager.exporter_names,
|
124 |
+
label=self.get_text("select_exporter"),
|
125 |
+
value=self.exporter_manager.exporter_names[0] if self.exporter_manager.exporter_names else None,
|
126 |
+
info="Choose an exporter like TextualInversionExporter" if self.config_manager.get_config("language") == "en" else "选择导出器,如TextualInversionExporter"
|
127 |
+
)
|
128 |
+
start_btn = gr.Button(self.get_text("start_collection"))
|
129 |
+
status = gr.Textbox(label=self.get_text("status"), interactive=False)
|
130 |
+
output_file = gr.File(label=self.get_text("download_data"))
|
131 |
+
with gr.Tab(self.get_text("config")):
|
132 |
+
gr.Markdown("### " + self.get_text("config_management"))
|
133 |
+
pixiv_token_input = gr.Textbox(
|
134 |
+
label=self.get_text("pixiv_token"),
|
135 |
+
value=self.config_manager.get_config("pixiv_refresh_token"),
|
136 |
+
type="password",
|
137 |
+
info="Required for PixivSearchSource, stored in session only" if self.config_manager.get_config("language") == "en" else "PixivSearchSource所需,仅存储在会话中"
|
138 |
+
)
|
139 |
+
output_dir_input = gr.Textbox(
|
140 |
+
label=self.get_text("output_dir"),
|
141 |
+
value=self.config_manager.get_config("output_dir"),
|
142 |
+
info="Directory for output data, session-specific" if self.config_manager.get_config("language") == "en" else "输出数据的目录,会话专用"
|
143 |
+
)
|
144 |
+
num_items_input = gr.Number(
|
145 |
+
label=self.get_text("num_items"),
|
146 |
+
value=self.config_manager.get_config("default_num_items"),
|
147 |
+
info="Default number of images to collect" if self.config_manager.get_config("language") == "en" else "默认收集的图片数量"
|
148 |
+
)
|
149 |
+
resize_size_input = gr.Number(
|
150 |
+
label=self.get_text("resize_size"),
|
151 |
+
value=self.config_manager.get_config("default_resize_size"),
|
152 |
+
info="Default size for ResizeAction" if self.config_manager.get_config("language") == "en" else "ResizeAction的默认尺寸"
|
153 |
+
)
|
154 |
+
config_export_btn = gr.Button(self.get_text("export_config"))
|
155 |
+
config_import_file = gr.File(label=self.get_text("import_config"))
|
156 |
+
save_config_btn = gr.Button(self.get_text("save_config"))
|
157 |
+
config_status = gr.Textbox(label=self.get_text("config_status"), interactive=False)
|
158 |
+
with gr.Tab(self.get_text("logs")):
|
159 |
+
gr.Markdown("### " + self.get_text("view_logs"))
|
160 |
+
log_output = gr.Textbox(label=self.get_text("view_logs"), interactive=False, lines=10)
|
161 |
+
log_download_btn = gr.Button(self.get_text("download_log"))
|
162 |
+
log_download_file = gr.File(label=self.get_text("download_log"))
|
163 |
+
def update_language(language):
|
164 |
+
self.config_manager.set_config("language", language)
|
165 |
+
return {
|
166 |
+
"demo": demo.update(title=self.get_text("title")),
|
167 |
+
"language_dropdown": language_dropdown.update(label=self.get_text("language")),
|
168 |
+
"source_dropdown": source_dropdown.update(label=self.get_text("select_source")),
|
169 |
+
"action_checkboxes": action_checkboxes.update(label=self.get_text("select_actions")),
|
170 |
+
"dataset_name_input": dataset_name_input.update(label=self.get_text("dataset_name")),
|
171 |
+
"exporter_dropdown": exporter_dropdown.update(label=self.get_text("select_exporter")),
|
172 |
+
"start_btn": start_btn.update(value=self.get_text("start_collection")),
|
173 |
+
"status": status.update(label=self.get_text("status")),
|
174 |
+
"output_file": output_file.update(label=self.get_text("download_data")),
|
175 |
+
"pixiv_token_input": pixiv_token_input.update(label=self.get_text("pixiv_token")),
|
176 |
+
"output_dir_input": output_dir_input.update(label=self.get_text("output_dir")),
|
177 |
+
"num_items_input": num_items_input.update(label=self.get_text("num_items")),
|
178 |
+
"resize_size_input": resize_size_input.update(label=self.get_text("resize_size")),
|
179 |
+
"config_export_btn": config_export_btn.update(value=self.get_text("export_config")),
|
180 |
+
"config_import_file": config_import_file.update(label=self.get_text("import_config")),
|
181 |
+
"save_config_btn": save_config_btn.update(value=self.get_text("save_config")),
|
182 |
+
"config_status": config_status.update(label=self.get_text("config_status")),
|
183 |
+
"log_output": log_output.update(label=self.get_text("view_logs")),
|
184 |
+
"log_download_btn": log_download_btn.update(value=self.get_text("download_log")),
|
185 |
+
"log_download_file": log_download_file.update(label=self.get_text("download_log"))
|
186 |
+
}
|
187 |
+
language_dropdown.change(
|
188 |
+
fn=update_language,
|
189 |
+
inputs=language_dropdown,
|
190 |
+
outputs=[
|
191 |
+
demo, language_dropdown, source_dropdown, action_checkboxes,
|
192 |
+
dataset_name_input, exporter_dropdown, start_btn, status,
|
193 |
+
output_file, pixiv_token_input, output_dir_input, num_items_input,
|
194 |
+
resize_size_input, config_export_btn, config_import_file,
|
195 |
+
save_config_btn, config_status, log_output, log_download_btn,
|
196 |
+
log_download_file
|
197 |
+
]
|
198 |
+
)
|
199 |
+
source_dropdown.change(
|
200 |
+
fn=self.update_params_visibility,
|
201 |
+
inputs=source_dropdown,
|
202 |
+
outputs=param_components
|
203 |
+
)
|
204 |
+
action_checkboxes.change(
|
205 |
+
fn=self.update_action_params,
|
206 |
+
inputs=action_checkboxes,
|
207 |
+
outputs=[gr.State(), gr.State()]
|
208 |
+
)
|
209 |
+
def save_configs(pixiv_token, output_dir, num_items, resize_size):
|
210 |
+
self.config_manager.set_config("pixiv_refresh_token", pixiv_token)
|
211 |
+
self.config_manager.set_config("output_dir", output_dir)
|
212 |
+
self.config_manager.set_config("default_num_items", int(num_items))
|
213 |
+
self.config_manager.set_config("default_resize_size", int(resize_size))
|
214 |
+
return self.get_text("config_status") + ": " + ("Configuration saved" if self.config_manager.get_config("language") == "en" else "配置已保存")
|
215 |
+
save_config_btn.click(
|
216 |
+
fn=save_configs,
|
217 |
+
inputs=[pixiv_token_input, output_dir_input, num_items_input, resize_size_input],
|
218 |
+
outputs=config_status
|
219 |
+
)
|
220 |
+
config_export_btn.click(
|
221 |
+
fn=self.config_manager.export_config,
|
222 |
+
inputs=[],
|
223 |
+
outputs=gr.File(label=self.get_text("export_config"))
|
224 |
+
)
|
225 |
+
config_import_file.upload(
|
226 |
+
fn=self.config_manager.import_config,
|
227 |
+
inputs=config_import_file,
|
228 |
+
outputs=config_status
|
229 |
+
)
|
230 |
+
return {
|
231 |
+
"demo": demo,
|
232 |
+
"source_dropdown": source_dropdown,
|
233 |
+
"param_components": param_components,
|
234 |
+
"action_checkboxes": action_checkboxes,
|
235 |
+
"action_param_components": action_param_components,
|
236 |
+
"dataset_name_input": dataset_name_input,
|
237 |
+
"exporter_dropdown": exporter_dropdown,
|
238 |
+
"start_btn": start_btn,
|
239 |
+
"status": status,
|
240 |
+
"output_file": output_file,
|
241 |
+
"log_output": log_output,
|
242 |
+
"log_download_btn": log_download_btn,
|
243 |
+
"log_download_file": log_download_file
|
244 |
+
}
|
waifuc_gui/source_manager.py
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import inspect
|
2 |
+
import waifuc.source
|
3 |
+
import gradio as gr
|
4 |
+
from .config_manager import ConfigManager
|
5 |
+
|
6 |
+
class SourceManager:
|
7 |
+
def __init__(self, config_manager: ConfigManager):
|
8 |
+
self.config_manager = config_manager
|
9 |
+
self.source_classes = [
|
10 |
+
cls for name, cls in inspect.getmembers(waifuc.source, inspect.isclass)
|
11 |
+
if name.endswith("Source") and not inspect.isabstract(cls)
|
12 |
+
]
|
13 |
+
self.source_names = [cls.__name__ for cls in self.source_classes]
|
14 |
+
|
15 |
+
def get_source_params(self, selected_source):
|
16 |
+
source_cls = next(cls for cls in self.source_classes if cls.__name__ == selected_source)
|
17 |
+
sig = inspect.signature(source_cls.__init__)
|
18 |
+
return [p for p in sig.parameters.values() if p.name != 'self']
|
19 |
+
|
20 |
+
def create_param_inputs(self):
|
21 |
+
params = {}
|
22 |
+
for source in self.source_names:
|
23 |
+
if source == "LocalSource":
|
24 |
+
params[source] = {
|
25 |
+
"file": gr.File(
|
26 |
+
label="Upload ZIP file" if self.config_manager.get_config("language") == "en" else "上传zip文件",
|
27 |
+
info="Upload a ZIP file containing images for LocalSource" if self.config_manager.get_config("language") == "en" else "上传包含图片的zip文件用于LocalSource",
|
28 |
+
visible=False
|
29 |
+
)
|
30 |
+
}
|
31 |
+
else:
|
32 |
+
source_cls = next(cls for cls in self.source_classes if cls.__name__ == source)
|
33 |
+
sig = inspect.signature(source_cls.__init__)
|
34 |
+
for param in sig.parameters.values():
|
35 |
+
if param.name != 'self':
|
36 |
+
if param.name == "refresh_token":
|
37 |
+
params.setdefault(source, {})[param.name] = gr.Textbox(
|
38 |
+
label="Pixiv Refresh Token" if self.config_manager.get_config("language") == "en" else "Pixiv刷新令牌",
|
39 |
+
type="password",
|
40 |
+
visible=False,
|
41 |
+
value=self.config_manager.get_config("pixiv_refresh_token"),
|
42 |
+
info="Set in Config tab or here" if self.config_manager.get_config("language") == "en" else "在配置选项卡或此处设置"
|
43 |
+
)
|
44 |
+
elif param.name == "num_items":
|
45 |
+
params.setdefault(source, {})[param.name] = gr.Number(
|
46 |
+
label="Number of Items" if self.config_manager.get_config("language") == "en" else "图片数量",
|
47 |
+
visible=False,
|
48 |
+
value=self.config_manager.get_config("default_num_items"),
|
49 |
+
info="Number of images to collect" if self.config_manager.get_config("language") == "en" else "要收集的图片数量"
|
50 |
+
)
|
51 |
+
elif param.annotation == list:
|
52 |
+
params.setdefault(source, {})[param.name] = gr.Textbox(
|
53 |
+
label=param.name,
|
54 |
+
placeholder="Comma-separated tags, e.g., tag1,tag2" if self.config_manager.get_config("language") == "en" else "逗号分隔的标签,例如:tag1,tag2",
|
55 |
+
visible=False
|
56 |
+
)
|
57 |
+
elif param.annotation == int:
|
58 |
+
params.setdefault(source, {})[param.name] = gr.Number(
|
59 |
+
label=param.name,
|
60 |
+
visible=False
|
61 |
+
)
|
62 |
+
else:
|
63 |
+
params.setdefault(source, {})[param.name] = gr.Textbox(
|
64 |
+
label=param.name,
|
65 |
+
visible=False
|
66 |
+
)
|
67 |
+
return params
|
68 |
+
|
69 |
+
def instantiate_source(self, selected_source, params, file_handler):
|
70 |
+
if selected_source == "LocalSource":
|
71 |
+
uploaded_file = params.get("file", None)
|
72 |
+
if not uploaded_file:
|
73 |
+
raise ValueError(
|
74 |
+
"Please upload a ZIP file for LocalSource" if self.config_manager.get_config("language") == "en" else
|
75 |
+
"请上传LocalSource的zip文件"
|
76 |
+
)
|
77 |
+
extract_dir = file_handler.extract_zip(uploaded_file)
|
78 |
+
return waifuc.source.LocalSource(extract_dir)
|
79 |
+
else:
|
80 |
+
source_cls = next(cls for cls in self.source_classes if cls.__name__ == selected_source)
|
81 |
+
source_params = {k: v for k, v in params.items() if k in [p.name for p in self.get_source_params(selected_source)]}
|
82 |
+
if "tags" in source_params:
|
83 |
+
source_params["tags"] = [tag.strip() for tag in source_params["tags"].split(',')]
|
84 |
+
if "refresh_token" in source_params and not source_params["refresh_token"]:
|
85 |
+
source_params["refresh_token"] = self.config_manager.get_config("pixiv_refresh_token")
|
86 |
+
return source_cls(**source_params)
|