Commit ·
ba35fb6
1
Parent(s): 8143bed
add save and exit, fix vace attachments
Browse files
wgp.py
CHANGED
|
@@ -31,6 +31,7 @@ from PIL import Image
|
|
| 31 |
import zipfile
|
| 32 |
import tempfile
|
| 33 |
import atexit
|
|
|
|
| 34 |
global_queue_ref = []
|
| 35 |
AUTOSAVE_FILENAME = "queue.zip"
|
| 36 |
PROMPT_VARS_MAX = 10
|
|
@@ -364,21 +365,23 @@ def save_queue_action(state):
|
|
| 364 |
|
| 365 |
if not queue or len(queue) <=1 :
|
| 366 |
gr.Info("Queue is empty. Nothing to save.")
|
| 367 |
-
return
|
| 368 |
|
| 369 |
zip_buffer = io.BytesIO()
|
| 370 |
|
| 371 |
with tempfile.TemporaryDirectory() as tmpdir:
|
| 372 |
queue_manifest = []
|
| 373 |
-
|
| 374 |
|
| 375 |
for task_index, task in enumerate(queue):
|
| 376 |
-
if task is None or not isinstance(task, dict) or
|
| 377 |
|
| 378 |
params_copy = task.get('params', {}).copy()
|
| 379 |
task_id_s = task.get('id', f"task_{task_index}")
|
| 380 |
|
| 381 |
image_keys = ["image_start", "image_end", "image_refs"]
|
|
|
|
|
|
|
| 382 |
for key in image_keys:
|
| 383 |
images_pil = params_copy.get(key)
|
| 384 |
if images_pil is None:
|
|
@@ -395,8 +398,8 @@ def save_queue_action(state):
|
|
| 395 |
continue
|
| 396 |
|
| 397 |
img_id = id(pil_image)
|
| 398 |
-
if img_id in
|
| 399 |
-
image_filenames_for_json.append(
|
| 400 |
continue
|
| 401 |
|
| 402 |
img_filename_in_zip = f"task{task_id_s}_{key}_{img_index}.png"
|
|
@@ -405,7 +408,8 @@ def save_queue_action(state):
|
|
| 405 |
try:
|
| 406 |
pil_image.save(img_save_path, "PNG")
|
| 407 |
image_filenames_for_json.append(img_filename_in_zip)
|
| 408 |
-
|
|
|
|
| 409 |
except Exception as e:
|
| 410 |
print(f"Error saving image {img_filename_in_zip} for task {task_id_s}: {e}")
|
| 411 |
|
|
@@ -414,17 +418,47 @@ def save_queue_action(state):
|
|
| 414 |
else:
|
| 415 |
params_copy.pop(key, None)
|
| 416 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 417 |
|
| 418 |
params_copy.pop('state', None)
|
| 419 |
params_copy.pop('start_image_data_base64', None)
|
| 420 |
params_copy.pop('end_image_data_base64', None)
|
| 421 |
params_copy.pop('start_image_data', None)
|
| 422 |
params_copy.pop('end_image_data', None)
|
|
|
|
|
|
|
| 423 |
|
| 424 |
manifest_entry = {
|
| 425 |
"id": task.get('id'),
|
| 426 |
"params": params_copy,
|
| 427 |
}
|
|
|
|
| 428 |
queue_manifest.append(manifest_entry)
|
| 429 |
|
| 430 |
manifest_path = os.path.join(tmpdir, "queue.json")
|
|
@@ -440,12 +474,13 @@ def save_queue_action(state):
|
|
| 440 |
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zf:
|
| 441 |
zf.write(manifest_path, arcname="queue.json")
|
| 442 |
|
| 443 |
-
for
|
| 444 |
-
|
| 445 |
-
if os.path.exists(
|
| 446 |
-
zf.write(
|
|
|
|
| 447 |
else:
|
| 448 |
-
print(f"Warning:
|
| 449 |
|
| 450 |
zip_buffer.seek(0)
|
| 451 |
zip_binary_content = zip_buffer.getvalue()
|
|
@@ -464,6 +499,8 @@ def load_queue_action(filepath, state):
|
|
| 464 |
global task_id
|
| 465 |
gen = get_gen_info(state)
|
| 466 |
original_queue = gen.get("queue", [])
|
|
|
|
|
|
|
| 467 |
|
| 468 |
if not filepath or not hasattr(filepath, 'name') or not Path(filepath.name).is_file():
|
| 469 |
print("[load_queue_action] Warning: No valid file selected or file not found.")
|
|
@@ -476,6 +513,9 @@ def load_queue_action(filepath, state):
|
|
| 476 |
|
| 477 |
try:
|
| 478 |
print(f"[load_queue_action] Attempting to load queue from: {filepath.name}")
|
|
|
|
|
|
|
|
|
|
| 479 |
with tempfile.TemporaryDirectory() as tmpdir:
|
| 480 |
with zipfile.ZipFile(filepath.name, 'r') as zf:
|
| 481 |
if "queue.json" not in zf.namelist(): raise ValueError("queue.json not found in zip file")
|
|
@@ -497,21 +537,29 @@ def load_queue_action(filepath, state):
|
|
| 497 |
params = task_data.get('params', {})
|
| 498 |
task_id_loaded = task_data.get('id', 0)
|
| 499 |
max_id_in_file = max(max_id_in_file, task_id_loaded)
|
| 500 |
-
loaded_pil_images = {}
|
| 501 |
-
image_keys = ["image_start", "image_end", "image_refs"]
|
| 502 |
params['state'] = state
|
| 503 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 504 |
for key in image_keys:
|
| 505 |
image_filenames = params.get(key)
|
| 506 |
if image_filenames is None: continue
|
|
|
|
| 507 |
is_list = isinstance(image_filenames, list)
|
| 508 |
if not is_list: image_filenames = [image_filenames]
|
|
|
|
| 509 |
loaded_pils = []
|
| 510 |
for img_filename_in_zip in image_filenames:
|
| 511 |
-
if not isinstance(img_filename_in_zip, str):
|
|
|
|
|
|
|
| 512 |
img_load_path = os.path.join(tmpdir, img_filename_in_zip)
|
| 513 |
if not os.path.exists(img_load_path):
|
| 514 |
-
print(f"[load_queue_action] Image file not found
|
| 515 |
continue
|
| 516 |
try:
|
| 517 |
pil_image = Image.open(img_load_path)
|
|
@@ -519,30 +567,53 @@ def load_queue_action(filepath, state):
|
|
| 519 |
converted_image = convert_image(pil_image)
|
| 520 |
loaded_pils.append(converted_image)
|
| 521 |
pil_image.close()
|
|
|
|
| 522 |
except Exception as img_e:
|
| 523 |
print(f"[load_queue_action] Error loading image {img_filename_in_zip}: {img_e}")
|
| 524 |
if loaded_pils:
|
| 525 |
params[key] = loaded_pils if is_list else loaded_pils[0]
|
| 526 |
loaded_pil_images[key] = params[key]
|
| 527 |
-
else:
|
|
|
|
| 528 |
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 533 |
|
| 534 |
-
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 540 |
|
| 541 |
start_b64 = [pil_to_base64_uri(primary_preview_pil, format="jpeg", quality=70)] if primary_preview_pil else None
|
| 542 |
end_b64 = [pil_to_base64_uri(secondary_preview_pil, format="jpeg", quality=70)] if secondary_preview_pil else None
|
| 543 |
|
| 544 |
-
top_level_start_image =
|
| 545 |
-
top_level_end_image =
|
| 546 |
|
| 547 |
runtime_task = {
|
| 548 |
"id": task_id_loaded,
|
|
@@ -557,19 +628,20 @@ def load_queue_action(filepath, state):
|
|
| 557 |
"end_image_data_base64": end_b64,
|
| 558 |
}
|
| 559 |
newly_loaded_queue.append(runtime_task)
|
| 560 |
-
print(f"[load_queue_action]
|
| 561 |
|
| 562 |
with lock:
|
| 563 |
print("[load_queue_action] Acquiring lock to update state...")
|
| 564 |
gen["queue"] = newly_loaded_queue[:]
|
| 565 |
local_queue_copy_for_global_ref = gen["queue"][:]
|
| 566 |
-
current_max_id_in_new_queue = max([t['id'] for t in newly_loaded_queue if 'id' in t] + [0])
|
| 567 |
|
| 568 |
-
if
|
| 569 |
-
|
| 570 |
-
|
|
|
|
|
|
|
| 571 |
else:
|
| 572 |
-
print(f"[load_queue_action] Global task_id ({task_id}) is >
|
| 573 |
|
| 574 |
gen["prompts_max"] = len(newly_loaded_queue)
|
| 575 |
print("[load_queue_action] State update complete. Releasing lock.")
|
|
@@ -593,11 +665,14 @@ def load_queue_action(filepath, state):
|
|
| 593 |
return update_queue_data(original_queue)
|
| 594 |
finally:
|
| 595 |
if filepath and hasattr(filepath, 'name') and filepath.name and os.path.exists(filepath.name):
|
| 596 |
-
|
| 597 |
-
|
| 598 |
-
|
| 599 |
-
|
| 600 |
-
|
|
|
|
|
|
|
|
|
|
| 601 |
|
| 602 |
def clear_queue_action(state):
|
| 603 |
gen = get_gen_info(state)
|
|
@@ -636,6 +711,12 @@ def clear_queue_action(state):
|
|
| 636 |
|
| 637 |
return update_queue_data([])
|
| 638 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 639 |
def autosave_queue():
|
| 640 |
global global_queue_ref
|
| 641 |
if not global_queue_ref:
|
|
@@ -649,14 +730,20 @@ def autosave_queue():
|
|
| 649 |
|
| 650 |
def _save_queue_to_file(queue_to_save, output_filename):
|
| 651 |
if not queue_to_save: return None
|
|
|
|
| 652 |
with tempfile.TemporaryDirectory() as tmpdir:
|
| 653 |
queue_manifest = []
|
| 654 |
-
|
|
|
|
| 655 |
for task_index, task in enumerate(queue_to_save):
|
| 656 |
-
if task is None or not isinstance(task, dict): continue
|
|
|
|
| 657 |
params_copy = task.get('params', {}).copy()
|
| 658 |
task_id_s = task.get('id', f"task_{task_index}")
|
|
|
|
| 659 |
image_keys = ["image_start", "image_end", "image_refs"]
|
|
|
|
|
|
|
| 660 |
for key in image_keys:
|
| 661 |
images_pil = params_copy.get(key)
|
| 662 |
if images_pil is None: continue
|
|
@@ -666,36 +753,70 @@ def autosave_queue():
|
|
| 666 |
for img_index, pil_image in enumerate(images_pil):
|
| 667 |
if not isinstance(pil_image, Image.Image): continue
|
| 668 |
img_id = id(pil_image)
|
| 669 |
-
if img_id in
|
| 670 |
-
image_filenames_for_json.append(
|
| 671 |
continue
|
| 672 |
img_filename_in_zip = f"task{task_id_s}_{key}_{img_index}.png"
|
| 673 |
img_save_path = os.path.join(tmpdir, img_filename_in_zip)
|
| 674 |
try:
|
| 675 |
pil_image.save(img_save_path, "PNG")
|
| 676 |
image_filenames_for_json.append(img_filename_in_zip)
|
| 677 |
-
|
| 678 |
except Exception as e:
|
| 679 |
print(f"Autosave error saving image {img_filename_in_zip}: {e}")
|
| 680 |
if image_filenames_for_json:
|
| 681 |
params_copy[key] = image_filenames_for_json if is_list else image_filenames_for_json[0]
|
| 682 |
else:
|
| 683 |
params_copy.pop(key, None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 684 |
params_copy.pop('state', None)
|
| 685 |
params_copy.pop('start_image_data_base64', None)
|
| 686 |
params_copy.pop('end_image_data_base64', None)
|
|
|
|
|
|
|
|
|
|
| 687 |
manifest_entry = {
|
| 688 |
-
"id": task.get('id'),
|
|
|
|
| 689 |
}
|
|
|
|
| 690 |
queue_manifest.append(manifest_entry)
|
|
|
|
| 691 |
manifest_path = os.path.join(tmpdir, "queue.json")
|
| 692 |
with open(manifest_path, 'w', encoding='utf-8') as f: json.dump(queue_manifest, f, indent=4)
|
| 693 |
with zipfile.ZipFile(output_filename, 'w', zipfile.ZIP_DEFLATED) as zf:
|
| 694 |
zf.write(manifest_path, arcname="queue.json")
|
| 695 |
-
for
|
| 696 |
-
|
| 697 |
-
if os.path.exists(
|
| 698 |
-
zf.write(
|
|
|
|
|
|
|
| 699 |
return output_filename
|
| 700 |
return None
|
| 701 |
|
|
@@ -1160,7 +1281,6 @@ text_encoder_choices = ["ckpts/models_t5_umt5-xxl-enc-bf16.safetensors", "ckpts/
|
|
| 1160 |
server_config_filename = "wgp_config.json"
|
| 1161 |
|
| 1162 |
if not os.path.isfile(server_config_filename) and os.path.isfile("gradio_config.json"):
|
| 1163 |
-
import shutil
|
| 1164 |
shutil.move("gradio_config.json", server_config_filename)
|
| 1165 |
|
| 1166 |
if not Path(server_config_filename).is_file():
|
|
@@ -2965,7 +3085,6 @@ def download_loras():
|
|
| 2965 |
lora_dir = get_lora_dir(get_model_filename("i2v"), quantizeTransformer)
|
| 2966 |
log_path = os.path.join(lora_dir, "log.txt")
|
| 2967 |
if not os.path.isfile(log_path):
|
| 2968 |
-
import shutil
|
| 2969 |
tmp_path = os.path.join(lora_dir, "tmp_lora_dowload")
|
| 2970 |
import glob
|
| 2971 |
snapshot_download(repo_id="DeepBeepMeep/Wan2.1", allow_patterns="loras_i2v/*", local_dir= tmp_path)
|
|
@@ -3483,6 +3602,7 @@ def generate_video_tab(update_form = False, state_dict = None, ui_defaults = Non
|
|
| 3483 |
save_queue_btn = gr.DownloadButton("Save Queue", size="sm")
|
| 3484 |
load_queue_btn = gr.UploadButton("Load Queue", file_types=[".zip"], size="sm")
|
| 3485 |
clear_queue_btn = gr.Button("Clear Queue", size="sm", variant="stop")
|
|
|
|
| 3486 |
trigger_zip_download_js = """
|
| 3487 |
(base64String) => {
|
| 3488 |
if (!base64String) {
|
|
@@ -3567,6 +3687,11 @@ def generate_video_tab(update_form = False, state_dict = None, ui_defaults = Non
|
|
| 3567 |
inputs=None,
|
| 3568 |
outputs=[current_gen_column, queue_accordion]
|
| 3569 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3570 |
|
| 3571 |
extra_inputs = prompt_vars + [wizard_prompt, wizard_variables_var, wizard_prompt_activated_var, video_prompt_column, image_prompt_column,
|
| 3572 |
prompt_column_advanced, prompt_column_wizard_vars, prompt_column_wizard, lset_name, advanced_row] # show_advanced presets_column,
|
|
|
|
| 31 |
import zipfile
|
| 32 |
import tempfile
|
| 33 |
import atexit
|
| 34 |
+
import shutil
|
| 35 |
global_queue_ref = []
|
| 36 |
AUTOSAVE_FILENAME = "queue.zip"
|
| 37 |
PROMPT_VARS_MAX = 10
|
|
|
|
| 365 |
|
| 366 |
if not queue or len(queue) <=1 :
|
| 367 |
gr.Info("Queue is empty. Nothing to save.")
|
| 368 |
+
return ""
|
| 369 |
|
| 370 |
zip_buffer = io.BytesIO()
|
| 371 |
|
| 372 |
with tempfile.TemporaryDirectory() as tmpdir:
|
| 373 |
queue_manifest = []
|
| 374 |
+
file_paths_in_zip = {}
|
| 375 |
|
| 376 |
for task_index, task in enumerate(queue):
|
| 377 |
+
if task is None or not isinstance(task, dict) or task.get('id') is None: continue
|
| 378 |
|
| 379 |
params_copy = task.get('params', {}).copy()
|
| 380 |
task_id_s = task.get('id', f"task_{task_index}")
|
| 381 |
|
| 382 |
image_keys = ["image_start", "image_end", "image_refs"]
|
| 383 |
+
video_keys = ["video_guide", "video_mask"]
|
| 384 |
+
|
| 385 |
for key in image_keys:
|
| 386 |
images_pil = params_copy.get(key)
|
| 387 |
if images_pil is None:
|
|
|
|
| 398 |
continue
|
| 399 |
|
| 400 |
img_id = id(pil_image)
|
| 401 |
+
if img_id in file_paths_in_zip:
|
| 402 |
+
image_filenames_for_json.append(file_paths_in_zip[img_id])
|
| 403 |
continue
|
| 404 |
|
| 405 |
img_filename_in_zip = f"task{task_id_s}_{key}_{img_index}.png"
|
|
|
|
| 408 |
try:
|
| 409 |
pil_image.save(img_save_path, "PNG")
|
| 410 |
image_filenames_for_json.append(img_filename_in_zip)
|
| 411 |
+
file_paths_in_zip[img_id] = img_filename_in_zip
|
| 412 |
+
print(f"Saved image: {img_filename_in_zip}")
|
| 413 |
except Exception as e:
|
| 414 |
print(f"Error saving image {img_filename_in_zip} for task {task_id_s}: {e}")
|
| 415 |
|
|
|
|
| 418 |
else:
|
| 419 |
params_copy.pop(key, None)
|
| 420 |
|
| 421 |
+
for key in video_keys:
|
| 422 |
+
video_path_orig = params_copy.get(key)
|
| 423 |
+
if video_path_orig is None or not isinstance(video_path_orig, str):
|
| 424 |
+
continue
|
| 425 |
+
|
| 426 |
+
if video_path_orig in file_paths_in_zip:
|
| 427 |
+
params_copy[key] = file_paths_in_zip[video_path_orig]
|
| 428 |
+
continue
|
| 429 |
+
|
| 430 |
+
if not os.path.isfile(video_path_orig):
|
| 431 |
+
print(f"Warning: Video file not found for key '{key}' in task {task_id_s}: {video_path_orig}. Skipping video.")
|
| 432 |
+
params_copy.pop(key, None)
|
| 433 |
+
continue
|
| 434 |
+
|
| 435 |
+
_, extension = os.path.splitext(video_path_orig)
|
| 436 |
+
vid_filename_in_zip = f"task{task_id_s}_{key}{extension if extension else '.mp4'}"
|
| 437 |
+
vid_save_path = os.path.join(tmpdir, vid_filename_in_zip)
|
| 438 |
+
|
| 439 |
+
try:
|
| 440 |
+
shutil.copy2(video_path_orig, vid_save_path)
|
| 441 |
+
params_copy[key] = vid_filename_in_zip
|
| 442 |
+
file_paths_in_zip[video_path_orig] = vid_filename_in_zip
|
| 443 |
+
print(f"Copied video: {video_path_orig} -> {vid_filename_in_zip}")
|
| 444 |
+
except Exception as e:
|
| 445 |
+
print(f"Error copying video {video_path_orig} to {vid_filename_in_zip} for task {task_id_s}: {e}")
|
| 446 |
+
params_copy.pop(key, None)
|
| 447 |
+
|
| 448 |
|
| 449 |
params_copy.pop('state', None)
|
| 450 |
params_copy.pop('start_image_data_base64', None)
|
| 451 |
params_copy.pop('end_image_data_base64', None)
|
| 452 |
params_copy.pop('start_image_data', None)
|
| 453 |
params_copy.pop('end_image_data', None)
|
| 454 |
+
task.pop('start_image_data', None)
|
| 455 |
+
task.pop('end_image_data', None)
|
| 456 |
|
| 457 |
manifest_entry = {
|
| 458 |
"id": task.get('id'),
|
| 459 |
"params": params_copy,
|
| 460 |
}
|
| 461 |
+
manifest_entry = {k: v for k, v in manifest_entry.items() if v is not None}
|
| 462 |
queue_manifest.append(manifest_entry)
|
| 463 |
|
| 464 |
manifest_path = os.path.join(tmpdir, "queue.json")
|
|
|
|
| 474 |
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zf:
|
| 475 |
zf.write(manifest_path, arcname="queue.json")
|
| 476 |
|
| 477 |
+
for file_id, saved_file_rel_path in file_paths_in_zip.items():
|
| 478 |
+
saved_file_abs_path = os.path.join(tmpdir, saved_file_rel_path)
|
| 479 |
+
if os.path.exists(saved_file_abs_path):
|
| 480 |
+
zf.write(saved_file_abs_path, arcname=saved_file_rel_path)
|
| 481 |
+
print(f"Adding to zip: {saved_file_rel_path}")
|
| 482 |
else:
|
| 483 |
+
print(f"Warning: File {saved_file_rel_path} (ID: {file_id}) not found during zipping.")
|
| 484 |
|
| 485 |
zip_buffer.seek(0)
|
| 486 |
zip_binary_content = zip_buffer.getvalue()
|
|
|
|
| 499 |
global task_id
|
| 500 |
gen = get_gen_info(state)
|
| 501 |
original_queue = gen.get("queue", [])
|
| 502 |
+
save_path_base = server_config.get("save_path", "outputs")
|
| 503 |
+
loaded_cache_dir = os.path.join(save_path_base, "_loaded_queue_cache")
|
| 504 |
|
| 505 |
if not filepath or not hasattr(filepath, 'name') or not Path(filepath.name).is_file():
|
| 506 |
print("[load_queue_action] Warning: No valid file selected or file not found.")
|
|
|
|
| 513 |
|
| 514 |
try:
|
| 515 |
print(f"[load_queue_action] Attempting to load queue from: {filepath.name}")
|
| 516 |
+
os.makedirs(loaded_cache_dir, exist_ok=True)
|
| 517 |
+
print(f"[load_queue_action] Using cache directory: {loaded_cache_dir}")
|
| 518 |
+
|
| 519 |
with tempfile.TemporaryDirectory() as tmpdir:
|
| 520 |
with zipfile.ZipFile(filepath.name, 'r') as zf:
|
| 521 |
if "queue.json" not in zf.namelist(): raise ValueError("queue.json not found in zip file")
|
|
|
|
| 537 |
params = task_data.get('params', {})
|
| 538 |
task_id_loaded = task_data.get('id', 0)
|
| 539 |
max_id_in_file = max(max_id_in_file, task_id_loaded)
|
|
|
|
|
|
|
| 540 |
params['state'] = state
|
| 541 |
|
| 542 |
+
image_keys = ["image_start", "image_end", "image_refs"]
|
| 543 |
+
video_keys = ["video_guide", "video_mask"]
|
| 544 |
+
|
| 545 |
+
loaded_pil_images = {}
|
| 546 |
+
loaded_video_paths = {}
|
| 547 |
+
|
| 548 |
for key in image_keys:
|
| 549 |
image_filenames = params.get(key)
|
| 550 |
if image_filenames is None: continue
|
| 551 |
+
|
| 552 |
is_list = isinstance(image_filenames, list)
|
| 553 |
if not is_list: image_filenames = [image_filenames]
|
| 554 |
+
|
| 555 |
loaded_pils = []
|
| 556 |
for img_filename_in_zip in image_filenames:
|
| 557 |
+
if not isinstance(img_filename_in_zip, str):
|
| 558 |
+
print(f"[load_queue_action] Warning: Non-string filename found for image key '{key}'. Skipping.")
|
| 559 |
+
continue
|
| 560 |
img_load_path = os.path.join(tmpdir, img_filename_in_zip)
|
| 561 |
if not os.path.exists(img_load_path):
|
| 562 |
+
print(f"[load_queue_action] Image file not found in extracted data: {img_load_path}. Skipping.")
|
| 563 |
continue
|
| 564 |
try:
|
| 565 |
pil_image = Image.open(img_load_path)
|
|
|
|
| 567 |
converted_image = convert_image(pil_image)
|
| 568 |
loaded_pils.append(converted_image)
|
| 569 |
pil_image.close()
|
| 570 |
+
print(f"Loaded image: {img_filename_in_zip} for key {key}")
|
| 571 |
except Exception as img_e:
|
| 572 |
print(f"[load_queue_action] Error loading image {img_filename_in_zip}: {img_e}")
|
| 573 |
if loaded_pils:
|
| 574 |
params[key] = loaded_pils if is_list else loaded_pils[0]
|
| 575 |
loaded_pil_images[key] = params[key]
|
| 576 |
+
else:
|
| 577 |
+
params.pop(key, None)
|
| 578 |
|
| 579 |
+
for key in video_keys:
|
| 580 |
+
video_filename_in_zip = params.get(key)
|
| 581 |
+
if video_filename_in_zip is None or not isinstance(video_filename_in_zip, str):
|
| 582 |
+
continue
|
| 583 |
+
|
| 584 |
+
video_load_path = os.path.join(tmpdir, video_filename_in_zip)
|
| 585 |
+
if not os.path.exists(video_load_path):
|
| 586 |
+
print(f"[load_queue_action] Video file not found in extracted data: {video_load_path}. Skipping.")
|
| 587 |
+
params.pop(key, None)
|
| 588 |
+
continue
|
| 589 |
+
|
| 590 |
+
persistent_video_path = os.path.join(loaded_cache_dir, video_filename_in_zip)
|
| 591 |
+
try:
|
| 592 |
+
shutil.copy2(video_load_path, persistent_video_path)
|
| 593 |
+
params[key] = persistent_video_path
|
| 594 |
+
loaded_video_paths[key] = persistent_video_path
|
| 595 |
+
print(f"Loaded video: {video_filename_in_zip} -> {persistent_video_path}")
|
| 596 |
+
except Exception as vid_e:
|
| 597 |
+
print(f"[load_queue_action] Error copying video {video_filename_in_zip} to cache: {vid_e}")
|
| 598 |
+
params.pop(key, None)
|
| 599 |
|
| 600 |
+
|
| 601 |
+
primary_preview_pil_list = loaded_pil_images.get("image_start") or loaded_pil_images.get("image_refs")
|
| 602 |
+
secondary_preview_pil_list = loaded_pil_images.get("image_end")
|
| 603 |
+
|
| 604 |
+
primary_preview_pil = None
|
| 605 |
+
if primary_preview_pil_list:
|
| 606 |
+
primary_preview_pil = primary_preview_pil_list[0] if isinstance(primary_preview_pil_list, list) else primary_preview_pil_list
|
| 607 |
+
|
| 608 |
+
secondary_preview_pil = None
|
| 609 |
+
if secondary_preview_pil_list:
|
| 610 |
+
secondary_preview_pil = secondary_preview_pil_list[0] if isinstance(secondary_preview_pil_list, list) else secondary_preview_pil_list
|
| 611 |
|
| 612 |
start_b64 = [pil_to_base64_uri(primary_preview_pil, format="jpeg", quality=70)] if primary_preview_pil else None
|
| 613 |
end_b64 = [pil_to_base64_uri(secondary_preview_pil, format="jpeg", quality=70)] if secondary_preview_pil else None
|
| 614 |
|
| 615 |
+
top_level_start_image = params.get("image_start") or params.get("image_refs")
|
| 616 |
+
top_level_end_image = params.get("image_end")
|
| 617 |
|
| 618 |
runtime_task = {
|
| 619 |
"id": task_id_loaded,
|
|
|
|
| 628 |
"end_image_data_base64": end_b64,
|
| 629 |
}
|
| 630 |
newly_loaded_queue.append(runtime_task)
|
| 631 |
+
print(f"[load_queue_action] Reconstructed task {task_index+1}/{len(loaded_manifest)}, ID: {task_id_loaded}")
|
| 632 |
|
| 633 |
with lock:
|
| 634 |
print("[load_queue_action] Acquiring lock to update state...")
|
| 635 |
gen["queue"] = newly_loaded_queue[:]
|
| 636 |
local_queue_copy_for_global_ref = gen["queue"][:]
|
|
|
|
| 637 |
|
| 638 |
+
current_max_id_in_new_queue = max([t['id'] for t in newly_loaded_queue if 'id' in t] + [0])
|
| 639 |
+
if current_max_id_in_new_queue >= task_id:
|
| 640 |
+
new_task_id = current_max_id_in_new_queue + 1
|
| 641 |
+
print(f"[load_queue_action] Updating global task_id from {task_id} to {new_task_id}")
|
| 642 |
+
task_id = new_task_id
|
| 643 |
else:
|
| 644 |
+
print(f"[load_queue_action] Global task_id ({task_id}) is > max in file ({current_max_id_in_new_queue}). Not changing task_id.")
|
| 645 |
|
| 646 |
gen["prompts_max"] = len(newly_loaded_queue)
|
| 647 |
print("[load_queue_action] State update complete. Releasing lock.")
|
|
|
|
| 665 |
return update_queue_data(original_queue)
|
| 666 |
finally:
|
| 667 |
if filepath and hasattr(filepath, 'name') and filepath.name and os.path.exists(filepath.name):
|
| 668 |
+
if tempfile.gettempdir() in os.path.abspath(filepath.name):
|
| 669 |
+
try:
|
| 670 |
+
os.remove(filepath.name)
|
| 671 |
+
print(f"[load_queue_action] Removed temporary upload file: {filepath.name}")
|
| 672 |
+
except OSError as e:
|
| 673 |
+
print(f"[load_queue_action] Info: Could not remove temp file {filepath.name}: {e}")
|
| 674 |
+
else:
|
| 675 |
+
print(f"[load_queue_action] Info: Did not remove non-temporary file: {filepath.name}")
|
| 676 |
|
| 677 |
def clear_queue_action(state):
|
| 678 |
gen = get_gen_info(state)
|
|
|
|
| 711 |
|
| 712 |
return update_queue_data([])
|
| 713 |
|
| 714 |
+
def quit_application():
|
| 715 |
+
print("Save and Quit requested...")
|
| 716 |
+
autosave_queue()
|
| 717 |
+
import signal
|
| 718 |
+
os.kill(os.getpid(), signal.SIGINT)
|
| 719 |
+
|
| 720 |
def autosave_queue():
|
| 721 |
global global_queue_ref
|
| 722 |
if not global_queue_ref:
|
|
|
|
| 730 |
|
| 731 |
def _save_queue_to_file(queue_to_save, output_filename):
|
| 732 |
if not queue_to_save: return None
|
| 733 |
+
|
| 734 |
with tempfile.TemporaryDirectory() as tmpdir:
|
| 735 |
queue_manifest = []
|
| 736 |
+
file_paths_in_zip = {}
|
| 737 |
+
|
| 738 |
for task_index, task in enumerate(queue_to_save):
|
| 739 |
+
if task is None or not isinstance(task, dict) or task.get('id') is None: continue
|
| 740 |
+
|
| 741 |
params_copy = task.get('params', {}).copy()
|
| 742 |
task_id_s = task.get('id', f"task_{task_index}")
|
| 743 |
+
|
| 744 |
image_keys = ["image_start", "image_end", "image_refs"]
|
| 745 |
+
video_keys = ["video_guide", "video_mask"]
|
| 746 |
+
|
| 747 |
for key in image_keys:
|
| 748 |
images_pil = params_copy.get(key)
|
| 749 |
if images_pil is None: continue
|
|
|
|
| 753 |
for img_index, pil_image in enumerate(images_pil):
|
| 754 |
if not isinstance(pil_image, Image.Image): continue
|
| 755 |
img_id = id(pil_image)
|
| 756 |
+
if img_id in file_paths_in_zip:
|
| 757 |
+
image_filenames_for_json.append(file_paths_in_zip[img_id])
|
| 758 |
continue
|
| 759 |
img_filename_in_zip = f"task{task_id_s}_{key}_{img_index}.png"
|
| 760 |
img_save_path = os.path.join(tmpdir, img_filename_in_zip)
|
| 761 |
try:
|
| 762 |
pil_image.save(img_save_path, "PNG")
|
| 763 |
image_filenames_for_json.append(img_filename_in_zip)
|
| 764 |
+
file_paths_in_zip[img_id] = img_filename_in_zip
|
| 765 |
except Exception as e:
|
| 766 |
print(f"Autosave error saving image {img_filename_in_zip}: {e}")
|
| 767 |
if image_filenames_for_json:
|
| 768 |
params_copy[key] = image_filenames_for_json if is_list else image_filenames_for_json[0]
|
| 769 |
else:
|
| 770 |
params_copy.pop(key, None)
|
| 771 |
+
|
| 772 |
+
for key in video_keys:
|
| 773 |
+
video_path_orig = params_copy.get(key)
|
| 774 |
+
if video_path_orig is None or not isinstance(video_path_orig, str):
|
| 775 |
+
continue
|
| 776 |
+
|
| 777 |
+
if video_path_orig in file_paths_in_zip:
|
| 778 |
+
params_copy[key] = file_paths_in_zip[video_path_orig]
|
| 779 |
+
continue
|
| 780 |
+
|
| 781 |
+
if not os.path.isfile(video_path_orig):
|
| 782 |
+
print(f"Warning (Autosave): Video file not found for key '{key}' in task {task_id_s}: {video_path_orig}. Skipping.")
|
| 783 |
+
params_copy.pop(key, None)
|
| 784 |
+
continue
|
| 785 |
+
|
| 786 |
+
_, extension = os.path.splitext(video_path_orig)
|
| 787 |
+
vid_filename_in_zip = f"task{task_id_s}_{key}{extension if extension else '.mp4'}"
|
| 788 |
+
vid_save_path = os.path.join(tmpdir, vid_filename_in_zip)
|
| 789 |
+
|
| 790 |
+
try:
|
| 791 |
+
shutil.copy2(video_path_orig, vid_save_path)
|
| 792 |
+
params_copy[key] = vid_filename_in_zip
|
| 793 |
+
file_paths_in_zip[video_path_orig] = vid_filename_in_zip
|
| 794 |
+
except Exception as e:
|
| 795 |
+
print(f"Error (Autosave) copying video {video_path_orig} to {vid_filename_in_zip} for task {task_id_s}: {e}")
|
| 796 |
+
params_copy.pop(key, None)
|
| 797 |
params_copy.pop('state', None)
|
| 798 |
params_copy.pop('start_image_data_base64', None)
|
| 799 |
params_copy.pop('end_image_data_base64', None)
|
| 800 |
+
params_copy.pop('start_image_data', None)
|
| 801 |
+
params_copy.pop('end_image_data', None)
|
| 802 |
+
|
| 803 |
manifest_entry = {
|
| 804 |
+
"id": task.get('id'),
|
| 805 |
+
"params": params_copy,
|
| 806 |
}
|
| 807 |
+
manifest_entry = {k: v for k, v in manifest_entry.items() if v is not None}
|
| 808 |
queue_manifest.append(manifest_entry)
|
| 809 |
+
|
| 810 |
manifest_path = os.path.join(tmpdir, "queue.json")
|
| 811 |
with open(manifest_path, 'w', encoding='utf-8') as f: json.dump(queue_manifest, f, indent=4)
|
| 812 |
with zipfile.ZipFile(output_filename, 'w', zipfile.ZIP_DEFLATED) as zf:
|
| 813 |
zf.write(manifest_path, arcname="queue.json")
|
| 814 |
+
for saved_file_rel_path in file_paths_in_zip.values():
|
| 815 |
+
saved_file_abs_path = os.path.join(tmpdir, saved_file_rel_path)
|
| 816 |
+
if os.path.exists(saved_file_abs_path):
|
| 817 |
+
zf.write(saved_file_abs_path, arcname=saved_file_rel_path)
|
| 818 |
+
else:
|
| 819 |
+
print(f"Warning (Autosave): File {saved_file_rel_path} not found during zipping.")
|
| 820 |
return output_filename
|
| 821 |
return None
|
| 822 |
|
|
|
|
| 1281 |
server_config_filename = "wgp_config.json"
|
| 1282 |
|
| 1283 |
if not os.path.isfile(server_config_filename) and os.path.isfile("gradio_config.json"):
|
|
|
|
| 1284 |
shutil.move("gradio_config.json", server_config_filename)
|
| 1285 |
|
| 1286 |
if not Path(server_config_filename).is_file():
|
|
|
|
| 3085 |
lora_dir = get_lora_dir(get_model_filename("i2v"), quantizeTransformer)
|
| 3086 |
log_path = os.path.join(lora_dir, "log.txt")
|
| 3087 |
if not os.path.isfile(log_path):
|
|
|
|
| 3088 |
tmp_path = os.path.join(lora_dir, "tmp_lora_dowload")
|
| 3089 |
import glob
|
| 3090 |
snapshot_download(repo_id="DeepBeepMeep/Wan2.1", allow_patterns="loras_i2v/*", local_dir= tmp_path)
|
|
|
|
| 3602 |
save_queue_btn = gr.DownloadButton("Save Queue", size="sm")
|
| 3603 |
load_queue_btn = gr.UploadButton("Load Queue", file_types=[".zip"], size="sm")
|
| 3604 |
clear_queue_btn = gr.Button("Clear Queue", size="sm", variant="stop")
|
| 3605 |
+
quit_button = gr.Button("Save and Quit", size="sm", variant="secondary")
|
| 3606 |
trigger_zip_download_js = """
|
| 3607 |
(base64String) => {
|
| 3608 |
if (!base64String) {
|
|
|
|
| 3687 |
inputs=None,
|
| 3688 |
outputs=[current_gen_column, queue_accordion]
|
| 3689 |
)
|
| 3690 |
+
quit_button.click(
|
| 3691 |
+
fn=quit_application,
|
| 3692 |
+
inputs=[],
|
| 3693 |
+
outputs=[]
|
| 3694 |
+
)
|
| 3695 |
|
| 3696 |
extra_inputs = prompt_vars + [wizard_prompt, wizard_variables_var, wizard_prompt_activated_var, video_prompt_column, image_prompt_column,
|
| 3697 |
prompt_column_advanced, prompt_column_wizard_vars, prompt_column_wizard, lset_name, advanced_row] # show_advanced presets_column,
|