| |
| |
|
|
| from pathlib import Path |
| from datetime import datetime |
| import re |
| import shutil |
|
|
| root = Path(__file__).resolve().parent |
| candidates = [root / "_system" / "portrait_generator.py", root / "portrait_generator.py"] |
| app = next((p for p in candidates if p.exists()), None) |
| if app is None: |
| print("ERROR: portrait_generator.py not found. Put this file next to INSTALLER.bat / LANCER.bat.") |
| input("Press Enter to close...") |
| raise SystemExit(1) |
|
|
| print(f"Patching: {app}") |
| backup = app.with_name(app.name + ".bak_" + datetime.now().strftime("%Y%m%d_%H%M%S")) |
| shutil.copy2(app, backup) |
| print(f"Backup created: {backup}") |
|
|
| s = app.read_text(encoding="utf-8") |
| changed = False |
|
|
| |
| if "autosaved_paths" not in s: |
| pattern = re.compile( |
| r'(current_params\["seeds"\] = seeds\s+' |
| r'current_params\["seed"\] = current_seed\s+' |
| r'current_params\["generation_mode"\] = generation_mode\s+' |
| r'current_params\["num_images"\] = num_images\s+)' |
| r'(progress\(1\.0, desc=.*?\))', |
| re.DOTALL, |
| ) |
| autosave = r'''\1 |
| # Auto-save: save every generated image immediately. |
| autosaved_paths = [] |
| for auto_idx, auto_img in enumerate(images): |
| try: |
| auto_params = deepcopy(current_params) |
| auto_params["autosave_index"] = auto_idx + 1 |
| if auto_idx < len(seeds): |
| auto_params["autosave_seed"] = seeds[auto_idx] |
| autosaved_paths.append(save_portrait(auto_img, positive_prompt, auto_params)) |
| except Exception as save_err: |
| print(f"Auto-save image {auto_idx+1} failed: {save_err}") |
| current_params["autosaved_paths"] = autosaved_paths |
| |
| progress(1.0, desc="Generation complete and images auto-saved")''' |
| s2, n = pattern.subn(autosave, s, count=1) |
| if n: |
| s = s2 |
| changed = True |
| print("OK: auto-save added") |
| else: |
| print("WARNING: auto-save anchor not found") |
| else: |
| print("Auto-save already present") |
|
|
| |
| if "openpose_note" not in s: |
| pattern = re.compile( |
| r'(mode_note = .*?\n)' |
| r'(\s*info_text = \(f".*?\n\s*f".*?"\))', |
| re.DOTALL, |
| ) |
| repl = r'''\1 openpose_note = " | OpenPose ignored in FLUX.2 Klein" if (is_flux2 and pose_image is not None) else "" |
| info_text = (f"OK {len(images)} image(s) auto-saved | Mode: {mode_note} | Final: {width}x{height} | LLM: {llm_used} | " |
| f"Style: {art_style} | Steps: {steps} | CFG: {cfg}{openpose_note}")''' |
| s2, n = pattern.subn(repl, s, count=1) |
| if n: |
| s = s2 |
| changed = True |
| print("OK: OpenPose/Flux2 info added") |
| else: |
| print("WARNING: info_text anchor not found") |
| else: |
| print("OpenPose note already present") |
|
|
| |
| s2, n = re.subn( |
| r'final_btn = gr\.Button\([^\n]*variant="primary", interactive=False, scale=1\)', |
| 'final_btn = gr.Button("Save selected as favorite copy", variant="primary", interactive=False, scale=1)', |
| s, |
| count=1, |
| ) |
| if n: |
| s = s2 |
| changed = True |
| print("OK: favorite button label patched") |
|
|
| |
| s2, n = re.subn( |
| r'pose_image = gr\.Image\(label=.*?type="pil", height=180\)', |
| 'pose_image = gr.Image(label="Pose reference image (OpenPose - SDXL only)", type="pil", height=180)', |
| s, |
| count=1, |
| ) |
| if n: |
| s = s2 |
| changed = True |
| print("OK: OpenPose image label patched") |
|
|
| s2, n = re.subn( |
| r'pose_strength = gr\.Slider\(0\.0, 1\.5, value=0\.8, step=0\.05, label="Force OpenPose", info=.*?\)', |
| 'pose_strength = gr.Slider(0.0, 1.5, value=0.8, step=0.05, label="Force OpenPose", info="OpenPose works with SDXL fast/quality only. It is ignored in FLUX.2 Klein because SDXL ControlNet is not compatible with FLUX.2.")', |
| s, |
| count=1, |
| ) |
| if n: |
| s = s2 |
| changed = True |
| print("OK: OpenPose help text patched") |
|
|
| |
| s2 = s.replace('final_info = gr.Textbox(label="Statut", interactive=False)', 'final_info = gr.Textbox(label="Status / Favorite", interactive=False)') |
| if s2 != s: |
| s = s2 |
| changed = True |
| print("OK: status label patched") |
|
|
| if changed: |
| app.write_text(s, encoding="utf-8") |
| print("Patch applied successfully.") |
| else: |
| print("No changes applied. File may already be patched or anchors differ.") |
|
|
| print("Restart LANCER.bat to use the patched app.") |
| input("Press Enter to close...") |
|
|