|
|
|
|
@ -4,16 +4,60 @@ import redis
@@ -4,16 +4,60 @@ import redis
|
|
|
|
|
import logging |
|
|
|
|
from typing import cast |
|
|
|
|
import requests |
|
|
|
|
import json |
|
|
|
|
from download_print import download_datas_by_pre_layout |
|
|
|
|
from download_print import BatchModelInfo |
|
|
|
|
from print_factory_type_setting_obj_run import print_type_setting_obj |
|
|
|
|
|
|
|
|
|
from config import print_factory_type_dir |
|
|
|
|
from config import oss_config |
|
|
|
|
from config import url_get_info_by_printIds |
|
|
|
|
from config import local_data |
|
|
|
|
from config import redis_config |
|
|
|
|
from config import print_data_dir |
|
|
|
|
|
|
|
|
|
from general import is_run_local_data |
|
|
|
|
|
|
|
|
|
def find_free_display(): |
|
|
|
|
""" |
|
|
|
|
寻找一个可用的显示编号。 |
|
|
|
|
从 99 开始尝试,最大尝试到 199。 |
|
|
|
|
""" |
|
|
|
|
display_num = 99 |
|
|
|
|
max_attempts = 100 # 最大尝试次数,避免无限循环 |
|
|
|
|
|
|
|
|
|
for attempt in range(max_attempts): |
|
|
|
|
display = f":{display_num}" |
|
|
|
|
lock_file = f"/tmp/.X{display_num}-lock" |
|
|
|
|
|
|
|
|
|
# 检查锁文件是否存在 |
|
|
|
|
if os.path.exists(lock_file): |
|
|
|
|
print(f"显示设备 {display} 被锁定,尝试下一个...") |
|
|
|
|
display_num += 1 |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
# 尝试启动一个短暂的Xvfb进程来测试端口是否真的空闲 |
|
|
|
|
test_proc = subprocess.Popen( |
|
|
|
|
["Xvfb", display, "-screen", "0", "1x1x1"], |
|
|
|
|
stdout=subprocess.DEVNULL, |
|
|
|
|
stderr=subprocess.PIPE |
|
|
|
|
) |
|
|
|
|
sleep(0.5) # 稍等片刻 |
|
|
|
|
|
|
|
|
|
# 如果进程很快结束了,通常意味着启动失败(可能是端口被占用或其他错误) |
|
|
|
|
return_code = test_proc.poll() |
|
|
|
|
if return_code is not None: |
|
|
|
|
# 启动失败,尝试下一个端口 |
|
|
|
|
display_num += 1 |
|
|
|
|
test_proc.terminate() |
|
|
|
|
continue |
|
|
|
|
else: |
|
|
|
|
# 启动成功!终止测试进程,并返回这个可用的显示编号 |
|
|
|
|
test_proc.terminate() |
|
|
|
|
return display_num |
|
|
|
|
|
|
|
|
|
raise RuntimeError(f"在尝试了 {max_attempts} 次后,未能找到可用的显示设备端口。") |
|
|
|
|
|
|
|
|
|
# 如果没有 DISPLAY,自动启动 Xvfb |
|
|
|
|
if "DISPLAY" not in os.environ: |
|
|
|
|
import atexit |
|
|
|
|
@ -24,14 +68,24 @@ if "DISPLAY" not in os.environ:
@@ -24,14 +68,24 @@ if "DISPLAY" not in os.environ:
|
|
|
|
|
os.makedirs(runtime_dir, exist_ok=True) |
|
|
|
|
os.environ["XDG_RUNTIME_DIR"] = runtime_dir |
|
|
|
|
|
|
|
|
|
# 启动 Xvfb |
|
|
|
|
xvfb_cmd = ["Xvfb", ":99", "-screen", "0", "1024x768x24", "-nolisten", "tcp"] |
|
|
|
|
# 使用函数查找空闲的显示端口 |
|
|
|
|
free_display_num = find_free_display() |
|
|
|
|
display_env = f":{free_display_num}" |
|
|
|
|
|
|
|
|
|
# 启动 Xvfb,使用找到的空闲端口 |
|
|
|
|
xvfb_cmd = ["Xvfb", display_env, "-screen", "0", "1024x768x24", "-nolisten", "tcp"] |
|
|
|
|
xvfb_proc = subprocess.Popen(xvfb_cmd) |
|
|
|
|
atexit.register(lambda: xvfb_proc.terminate()) # 退出时关闭 Xvfb |
|
|
|
|
|
|
|
|
|
# 确保程序退出时终止 Xvfb 进程 |
|
|
|
|
def cleanup_xvfb(): |
|
|
|
|
xvfb_proc.terminate() |
|
|
|
|
xvfb_proc.wait() # 等待进程完全结束 |
|
|
|
|
atexit.register(cleanup_xvfb) |
|
|
|
|
|
|
|
|
|
# 设置 DISPLAY |
|
|
|
|
os.environ["DISPLAY"] = ":99" |
|
|
|
|
sleep(0.5) # 等待 Xvfb 启动 |
|
|
|
|
# 设置环境变量 |
|
|
|
|
os.environ["DISPLAY"] = display_env |
|
|
|
|
sleep(1) # 给予 Xvfb 足够的启动时间 |
|
|
|
|
print(f"已启动 Xvfb 在显示器 {display_env}") |
|
|
|
|
|
|
|
|
|
import sys |
|
|
|
|
class RedisTaskQueue: |
|
|
|
|
@ -99,7 +153,6 @@ class RedisTaskQueue:
@@ -99,7 +153,6 @@ class RedisTaskQueue:
|
|
|
|
|
|
|
|
|
|
# 假设存储的是 JSON 格式的字符串 |
|
|
|
|
try: |
|
|
|
|
import json |
|
|
|
|
return json.loads(data.decode('utf-8')) |
|
|
|
|
except (json.JSONDecodeError, UnicodeDecodeError): |
|
|
|
|
# 如果不是 JSON,返回原始字符串作为值 |
|
|
|
|
@ -120,7 +173,6 @@ import time
@@ -120,7 +173,6 @@ import time
|
|
|
|
|
import gc |
|
|
|
|
def main(): |
|
|
|
|
redis_queue_name = "pb:print_order_type_setting" |
|
|
|
|
# while True: |
|
|
|
|
try: |
|
|
|
|
redis_queue = RedisTaskQueue(redis_queue_name) |
|
|
|
|
task_num = redis_queue.get_length() |
|
|
|
|
@ -193,8 +245,6 @@ def process_clound_print(data):
@@ -193,8 +245,6 @@ def process_clound_print(data):
|
|
|
|
|
selected_machine = "大机型" |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
import json |
|
|
|
|
# parsed = json.loads(data.decode('utf-8')) |
|
|
|
|
parsed = data |
|
|
|
|
|
|
|
|
|
pre_batch_id = parsed["pre_batch_id"] |
|
|
|
|
@ -247,8 +297,7 @@ def process_clound_print(data):
@@ -247,8 +297,7 @@ def process_clound_print(data):
|
|
|
|
|
# 如果不是 JSON,返回原始字符串作为值 |
|
|
|
|
print("error!") |
|
|
|
|
|
|
|
|
|
url = f"https://mp.api.suwa3d.com/api/printOrder/getInfoByPrintIds?print_ids={print_ids}" |
|
|
|
|
res = requests.get(url) |
|
|
|
|
res = requests.get(f"{url_get_info_by_printIds}{print_ids}") |
|
|
|
|
|
|
|
|
|
data = res.json()["data"] |
|
|
|
|
|
|
|
|
|
@ -285,9 +334,9 @@ def process_clound_print(data):
@@ -285,9 +334,9 @@ def process_clound_print(data):
|
|
|
|
|
|
|
|
|
|
print("-" * 40) |
|
|
|
|
|
|
|
|
|
workdir = f"{print_factory_type_dir}/data/{pre_batch_id}" |
|
|
|
|
workdir = f"{print_data_dir}{pre_batch_id}" |
|
|
|
|
|
|
|
|
|
clear_directory_recursive(f"{print_factory_type_dir}/data/") |
|
|
|
|
clear_directory_recursive(f"{print_data_dir}") |
|
|
|
|
clear_directory_recursive(f"{print_factory_type_dir}/full/") |
|
|
|
|
|
|
|
|
|
start_time = time.time() |
|
|
|
|
@ -301,7 +350,7 @@ def process_clound_print(data):
@@ -301,7 +350,7 @@ def process_clound_print(data):
|
|
|
|
|
src_dir = pre_batch_id |
|
|
|
|
selected_mode="紧凑" # 标准 紧凑 |
|
|
|
|
output_format="JSON" # 模型 JSON |
|
|
|
|
base_original_obj_dir = f"{print_factory_type_dir}/data/{src_dir}" |
|
|
|
|
base_original_obj_dir = f"{print_data_dir}{src_dir}" |
|
|
|
|
print_type_setting_obj(base_original_obj_dir=base_original_obj_dir,batch_id=pre_batch_id, |
|
|
|
|
selected_mode=selected_mode,output_format=output_format,selected_machine=selected_machine) |
|
|
|
|
#排版结束 |
|
|
|
|
|