HOPStudio commited on
Commit
790cdd9
·
verified ·
1 Parent(s): 72dfe1a

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +347 -3
main.py CHANGED
@@ -3,6 +3,9 @@ import subprocess
3
  import threading
4
  import shutil
5
  import json
 
 
 
6
  import requests
7
  import gradio as gr
8
 
@@ -14,6 +17,22 @@ FRP_VERSION = "0.69.0"
14
  CURRENT_DIR = REPO_PATH
15
  LAST_OUTPUT = ""
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  def clone_repository():
19
  if os.path.exists(REPO_PATH):
@@ -174,16 +193,13 @@ def create_frpc_toml():
174
  toml_content = """
175
  serverAddr = "103.71.69.203"
176
  serverPort = 7000
177
-
178
  auth.token = "hop20030219"
179
-
180
  [[proxies]]
181
  name = "jupyterlab"
182
  type = "tcp"
183
  localIP = "127.0.0.1"
184
  localPort = 18888
185
  remotePort = 18888
186
-
187
  [[proxies]]
188
  name = "comfyui"
189
  type = "tcp"
@@ -370,6 +386,325 @@ def start_jupyterlab_process():
370
  print(f"启动 JupyterLab 失败: {e}")
371
 
372
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
373
  def start_gradio():
374
  with gr.Blocks() as demo:
375
  gr.Markdown("# InternLM 控制台")
@@ -480,6 +815,15 @@ def main():
480
  except Exception as e:
481
  print(f"JupyterLab 线程启动失败: {e}")
482
 
 
 
 
 
 
 
 
 
 
483
  print("准备启动 Gradio...")
484
  start_gradio()
485
 
 
3
  import threading
4
  import shutil
5
  import json
6
+ import sys
7
+ import time
8
+ import zipfile
9
  import requests
10
  import gradio as gr
11
 
 
17
  CURRENT_DIR = REPO_PATH
18
  LAST_OUTPUT = ""
19
 
20
+ # ===== 新增:ModelScope 下载并启动 ComfyUI 的配置 =====
21
+ MODELSCOPE_MODEL_ID = "HOPStudio/forgeui"
22
+ MODELSCOPE_DOWNLOAD_DIR = os.path.join(REPO_PATH, "modelscope_download")
23
+ OFFLINE_BUILD_DIR = os.path.join(REPO_PATH, "offline_build")
24
+ COMFYUI_PORT = 8188
25
+ COMFYUI_LOG_PATH = os.path.join(REPO_PATH, "comfyui.log")
26
+ PROXY_URL = "http://103.71.69.203:17890"
27
+
28
+ # 兼容可能的文件名拼写:用户当前指定 offlinbuild.zip,
29
+ # 同时兼容 offlinebuild.zip / offline_build.zip,避免文件名略有差异时直接失败。
30
+ OFFLINE_BUILD_ZIP_CANDIDATES = [
31
+ "offlinbuild.zip",
32
+ "offlinebuild.zip",
33
+ "offline_build.zip"
34
+ ]
35
+
36
 
37
  def clone_repository():
38
  if os.path.exists(REPO_PATH):
 
193
  toml_content = """
194
  serverAddr = "103.71.69.203"
195
  serverPort = 7000
 
196
  auth.token = "hop20030219"
 
197
  [[proxies]]
198
  name = "jupyterlab"
199
  type = "tcp"
200
  localIP = "127.0.0.1"
201
  localPort = 18888
202
  remotePort = 18888
 
203
  [[proxies]]
204
  name = "comfyui"
205
  type = "tcp"
 
386
  print(f"启动 JupyterLab 失败: {e}")
387
 
388
 
389
+
390
+ # ===== 新增:ModelScope 下载 offline_build 并启动 ComfyUI =====
391
+ def get_proxy_env():
392
+ env = os.environ.copy()
393
+
394
+ env["http_proxy"] = PROXY_URL
395
+ env["https_proxy"] = PROXY_URL
396
+ env["HTTP_PROXY"] = PROXY_URL
397
+ env["HTTPS_PROXY"] = PROXY_URL
398
+ env["ALL_PROXY"] = PROXY_URL
399
+ env["no_proxy"] = "localhost,127.0.0.1"
400
+ env["NO_PROXY"] = "localhost,127.0.0.1"
401
+
402
+ return env
403
+
404
+
405
+ def configure_git_proxy():
406
+ try:
407
+ subprocess.run(
408
+ ["git", "config", "--global", "http.proxy", PROXY_URL],
409
+ check=False,
410
+ stdout=subprocess.DEVNULL,
411
+ stderr=subprocess.DEVNULL,
412
+ timeout=10
413
+ )
414
+ subprocess.run(
415
+ ["git", "config", "--global", "https.proxy", PROXY_URL],
416
+ check=False,
417
+ stdout=subprocess.DEVNULL,
418
+ stderr=subprocess.DEVNULL,
419
+ timeout=10
420
+ )
421
+ print("git 代理已配置。")
422
+ except Exception as e:
423
+ print(f"配置 git 代理失败: {e}")
424
+
425
+
426
+ def is_valid_zip(path):
427
+ if not os.path.exists(path):
428
+ return False
429
+
430
+ try:
431
+ if not zipfile.is_zipfile(path):
432
+ return False
433
+
434
+ with zipfile.ZipFile(path, "r") as zf:
435
+ # 只读取目录,不做全量 testzip,避免大压缩包校验耗时过长。
436
+ return len(zf.namelist()) > 0
437
+ except Exception:
438
+ return False
439
+
440
+
441
+ def find_existing_offline_zip():
442
+ search_dirs = [MODELSCOPE_DOWNLOAD_DIR, REPO_PATH]
443
+
444
+ for directory in search_dirs:
445
+ if not os.path.isdir(directory):
446
+ continue
447
+
448
+ for zip_name in OFFLINE_BUILD_ZIP_CANDIDATES:
449
+ zip_path = os.path.join(directory, zip_name)
450
+ if is_valid_zip(zip_path):
451
+ return zip_path
452
+
453
+ for root, _, files in os.walk(directory):
454
+ for filename in files:
455
+ lower_name = filename.lower()
456
+ if lower_name.endswith(".zip") and "offlin" in lower_name:
457
+ zip_path = os.path.join(root, filename)
458
+ if is_valid_zip(zip_path):
459
+ return zip_path
460
+
461
+ return None
462
+
463
+
464
+ def install_modelscope_cli():
465
+ if shutil.which("modelscope"):
466
+ print("检测到 modelscope 命令。")
467
+ return True
468
+
469
+ print("未检测到 modelscope 命令,尝试安装 modelscope。")
470
+
471
+ install_commands = [
472
+ [
473
+ sys.executable,
474
+ "-m",
475
+ "pip",
476
+ "install",
477
+ "-U",
478
+ "modelscope",
479
+ "-i",
480
+ "https://pypi.tuna.tsinghua.edu.cn/simple"
481
+ ],
482
+ [
483
+ sys.executable,
484
+ "-m",
485
+ "pip",
486
+ "install",
487
+ "-U",
488
+ "modelscope"
489
+ ]
490
+ ]
491
+
492
+ for command in install_commands:
493
+ try:
494
+ result = subprocess.run(
495
+ command,
496
+ stdout=subprocess.PIPE,
497
+ stderr=subprocess.PIPE,
498
+ text=True,
499
+ timeout=300
500
+ )
501
+
502
+ if result.returncode == 0 and shutil.which("modelscope"):
503
+ print("modelscope 安装成功。")
504
+ return True
505
+
506
+ print("modelscope 安装尝试失败。")
507
+ if result.stdout.strip():
508
+ print(result.stdout[-1000:])
509
+ if result.stderr.strip():
510
+ print(result.stderr[-1000:])
511
+
512
+ except subprocess.TimeoutExpired:
513
+ print("modelscope 安装超时。")
514
+ except Exception as e:
515
+ print(f"modelscope 安装异常: {e}")
516
+
517
+ print("modelscope 不可用,无法继续���载 offline_build。")
518
+ return False
519
+
520
+
521
+ def download_offline_build_from_modelscope():
522
+ os.makedirs(MODELSCOPE_DOWNLOAD_DIR, exist_ok=True)
523
+
524
+ existing_zip = find_existing_offline_zip()
525
+ if existing_zip:
526
+ print(f"检测到已有 offline_build 压缩包: {existing_zip}")
527
+ return existing_zip
528
+
529
+ if not install_modelscope_cli():
530
+ return None
531
+
532
+ print(f"开始从 ModelScope 下载 {MODELSCOPE_MODEL_ID} 的 offline_build 压缩包。")
533
+
534
+ env = get_proxy_env()
535
+ download_commands = []
536
+
537
+ # 优先按指定文件下载,避免把整个仓库全部拉下来。
538
+ for zip_name in OFFLINE_BUILD_ZIP_CANDIDATES:
539
+ download_commands.append([
540
+ "modelscope",
541
+ "download",
542
+ "--model",
543
+ MODELSCOPE_MODEL_ID,
544
+ zip_name,
545
+ "--local_dir",
546
+ MODELSCOPE_DOWNLOAD_DIR
547
+ ])
548
+
549
+ # 如果指定文件名不匹配,则退回下载整个模型仓库。
550
+ download_commands.append([
551
+ "modelscope",
552
+ "download",
553
+ "--model",
554
+ MODELSCOPE_MODEL_ID,
555
+ "--local_dir",
556
+ MODELSCOPE_DOWNLOAD_DIR
557
+ ])
558
+
559
+ for command in download_commands:
560
+ try:
561
+ print("执行下载命令: " + " ".join(command))
562
+
563
+ result = subprocess.run(
564
+ command,
565
+ env=env,
566
+ stdout=subprocess.PIPE,
567
+ stderr=subprocess.PIPE,
568
+ text=True,
569
+ timeout=3600
570
+ )
571
+
572
+ if result.stdout.strip():
573
+ print(result.stdout[-2000:])
574
+ if result.stderr.strip():
575
+ print(result.stderr[-2000:])
576
+
577
+ zip_path = find_existing_offline_zip()
578
+ if result.returncode == 0 and zip_path:
579
+ print(f"offline_build 压缩包下载成功: {zip_path}")
580
+ return zip_path
581
+
582
+ print("本次下载未找到有效 offline_build 压缩包,继续尝试下一个命令。")
583
+
584
+ except subprocess.TimeoutExpired:
585
+ print("ModelScope 下载超时,继续尝试下一个命令。")
586
+ except Exception as e:
587
+ print(f"ModelScope 下载异常: {e}")
588
+
589
+ print("ModelScope 下载失败,未找到有效 offline_build 压缩包。")
590
+ return None
591
+
592
+
593
+ def locate_offline_build_dir():
594
+ expected_main = os.path.join(OFFLINE_BUILD_DIR, "ComfyUI", "main.py")
595
+ if os.path.exists(expected_main):
596
+ return OFFLINE_BUILD_DIR
597
+
598
+ for root, dirs, files in os.walk(REPO_PATH):
599
+ if "main.py" in files and os.path.basename(root) == "ComfyUI":
600
+ parent_dir = os.path.dirname(root)
601
+ venv_activate = os.path.join(parent_dir, "venv", "bin", "activate")
602
+ if os.path.exists(venv_activate):
603
+ return parent_dir
604
+
605
+ return None
606
+
607
+
608
+ def extract_offline_build(zip_path):
609
+ existing_dir = locate_offline_build_dir()
610
+ if existing_dir:
611
+ print(f"检测到已解压的 offline_build: {existing_dir}")
612
+ return existing_dir
613
+
614
+ if not zip_path or not is_valid_zip(zip_path):
615
+ print(f"offline_build 压缩包无效: {zip_path}")
616
+ return None
617
+
618
+ try:
619
+ print(f"正在解压 offline_build: {zip_path}")
620
+
621
+ with zipfile.ZipFile(zip_path, "r") as zf:
622
+ zf.extractall(REPO_PATH)
623
+
624
+ extracted_dir = locate_offline_build_dir()
625
+ if extracted_dir:
626
+ print(f"offline_build 解压完成: {extracted_dir}")
627
+ return extracted_dir
628
+
629
+ print("解压完成,但未找到 offline_build/ComfyUI/main.py。")
630
+ return None
631
+
632
+ except Exception as e:
633
+ print(f"解压 offline_build 失败: {e}")
634
+ return None
635
+
636
+
637
+ def prepare_offline_build():
638
+ existing_dir = locate_offline_build_dir()
639
+ if existing_dir:
640
+ print(f"offline_build 已存在,跳过下载解压: {existing_dir}")
641
+ return existing_dir
642
+
643
+ zip_path = download_offline_build_from_modelscope()
644
+ if not zip_path:
645
+ return None
646
+
647
+ return extract_offline_build(zip_path)
648
+
649
+
650
+ def start_comfyui_process():
651
+ offline_build_dir = prepare_offline_build()
652
+
653
+ if not offline_build_dir:
654
+ print("offline_build 准备失败,跳过 ComfyUI 启动。")
655
+ return
656
+
657
+ venv_activate = os.path.join(offline_build_dir, "venv", "bin", "activate")
658
+ comfyui_main = os.path.join(offline_build_dir, "ComfyUI", "main.py")
659
+
660
+ if not os.path.exists(venv_activate):
661
+ print(f"未找到虚拟环境激活脚本: {venv_activate}")
662
+ return
663
+
664
+ if not os.path.exists(comfyui_main):
665
+ print(f"未找到 ComfyUI main.py: {comfyui_main}")
666
+ return
667
+
668
+ configure_git_proxy()
669
+
670
+ command = f'''
671
+ set -e
672
+ source "{venv_activate}"
673
+ export http_proxy={PROXY_URL}
674
+ export https_proxy={PROXY_URL}
675
+ export HTTP_PROXY={PROXY_URL}
676
+ export HTTPS_PROXY={PROXY_URL}
677
+ export ALL_PROXY={PROXY_URL}
678
+ export no_proxy=localhost,127.0.0.1
679
+ export NO_PROXY=localhost,127.0.0.1
680
+ git config --global http.proxy {PROXY_URL}
681
+ git config --global https.proxy {PROXY_URL}
682
+ cd "{os.path.join(offline_build_dir, "ComfyUI")}"
683
+ python main.py --listen 0.0.0.0 --port {COMFYUI_PORT}
684
+ '''
685
+
686
+ try:
687
+ os.makedirs(REPO_PATH, exist_ok=True)
688
+ log_file = open(COMFYUI_LOG_PATH, "a", encoding="utf-8")
689
+
690
+ process = subprocess.Popen(
691
+ ["bash", "-lc", command],
692
+ cwd=offline_build_dir,
693
+ env=get_proxy_env(),
694
+ stdout=log_file,
695
+ stderr=subprocess.STDOUT
696
+ )
697
+
698
+ time.sleep(3)
699
+
700
+ if process.poll() is None:
701
+ print(f"ComfyUI 已启动,端口: {COMFYUI_PORT},日志: {COMFYUI_LOG_PATH}")
702
+ else:
703
+ print(f"ComfyUI 启动后立即退出,返回码: {process.returncode},请查看日志: {COMFYUI_LOG_PATH}")
704
+
705
+ except Exception as e:
706
+ print(f"启动 ComfyUI 失败: {e}")
707
+
708
  def start_gradio():
709
  with gr.Blocks() as demo:
710
  gr.Markdown("# InternLM 控制台")
 
815
  except Exception as e:
816
  print(f"JupyterLab 线程启动失败: {e}")
817
 
818
+ try:
819
+ comfyui_thread = threading.Thread(
820
+ target=start_comfyui_process,
821
+ daemon=True
822
+ )
823
+ comfyui_thread.start()
824
+ except Exception as e:
825
+ print(f"ComfyUI 线程启动失败: {e}")
826
+
827
  print("准备启动 Gradio...")
828
  start_gradio()
829