建模程序 多个定时程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

251 lines
9.9 KiB

import redis,sys,os,re,oss2,shutil,time
import platform
import xml.etree.ElementTree as ET
from PIL import ImageGrab
if platform.system() == 'Windows':
#sys.path.append('e:\\libs\\')
sys.path.append('libs')
else:
sys.path.append('/data/deploy/make3d/make2/libs/')
import config,libs
#判断模型是需要高精模 或者是 需要photo3 参与
def task_need_high_model_or_photo3(pid):
resHigh = task_need_high_model(pid)
resPhoto3 = task_need_photo3(pid)
if resHigh or resPhoto3:
return True
else:
return False
#判断是否需要高精模
def task_need_high_model(pid):
redis_conn = config.redis_local_common
#判断在redis中是否有高精模和 需要photo3 参与的 task
if redis_conn.sismember("calculateHighModel",pid):
return True
#判断是否需要高精模
if redis_conn.sismember("calculateHighModel_no",pid):
return False
#判断是否需要高精模
if libs.get_ps_type(pid) == 1:
if libs.aliyun_face(pid):
#calulate_type = 'calculateHighModel'
redis_conn.sadd("calculateHighModel",pid)
return True
else:
redis_conn.sadd("calculateHighModel_no",pid)
return False
#判断是否需要photo3参与建模
def task_need_photo3(pid):
redis_conn = config.redis_local_common
#判断在redis中是否有高精模和 需要photo3 参与的 task
if redis_conn.sismember("photo3",pid):
return True
#判断是否需要photo3参与建模
if redis_conn.sismember("photo3_no",pid):
return False
if os.path.exists(os.path.join(config.workdir, pid, 'photo3')):
redis_conn.sadd("photo3",pid)
return True
else:
redis_conn.sadd("photo3_no",pid)
return False
#拷贝远程主机上的指定目录到本地指定目录
def copy_remote_directory(remote_host, remote_path, local_path):
# 建立 SSH 连接
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(remote_host, username='your_username', password='your_password')
# 创建 SFTP 客户端
sftp = ssh.open_sftp()
# 获取远程目录下的所有文件/子目录
file_list = sftp.listdir(remote_path)
# 遍历远程目录中的每个文件/子目录
for file_name in file_list:
remote_file_path = os.path.join(remote_path, file_name)
local_file_path = os.path.join(local_path, file_name)
# 判断当前项是文件还是目录
if sftp.stat(remote_file_path).st_isdir():
# 如果是目录,递归调用函数进行拷贝
os.makedirs(local_file_path, exist_ok=True)
copy_remote_directory(remote_host, remote_file_path, local_file_path)
else:
# 如果是文件,直接拷贝到指定目录
sftp.get(remote_file_path, local_file_path)
# 关闭 SFTP 客户端和 SSH 连接
sftp.close()
ssh.close()
#移除redis中的高精模和 需要photo3 参与的 task
# def remove_redis_high_model_or_photo3(pid):
# redis_conn = config.redis_local_common
# redis_conn.srem("calculateHighModel",pid)
# redis_conn.srem("photo3",pid)
# if __name__ == '__main__':
# redis_conn = config.redis_local_common
# print(redis_conn.sismember("photo3_no","1"))
#读取rcbox文件进行修改指定的值
def change_rcbox_s(pid,new_value):
rcbox_path = os.path.join(config.workdir, pid, f"{pid}.rcbox")
old_value_pattern = r'<Residual s="([^"]+)"'
#读取文件内容
with open(rcbox_path, 'r') as f:
content = f.read()
#使用正则表达式进行匹配
match = re.search(old_value_pattern,content)
if match:
old_value = match.group(1)
new_content = re.sub(old_value_pattern,f'<Residual s="{new_value}"',content)
#重新写入进去
with open(rcbox_path, 'w') as f:
f.write(new_content)
#读取 rcbox 修改 widthHeightDepth 重建区域的深度
def change_rcbox_deepth(pid,new_value):
rcbox_path = os.path.join(config.workdir, pid, f"{pid}.rcbox")
old_value_pattern = r'<widthHeightDepth>(.*?)</widthHeightDepth>'
#读取文件内容
with open(rcbox_path, 'r') as f:
content = f.read()
#使用正则表达式进行匹配
match = re.search(old_value_pattern,content)
if match:
old_value = match.group(1)
if old_value == "":
return
#分割字符串
arrStr = old_value.split(" ")
#重新拼接字符串
strs = arrStr[0]+" "+arrStr[1]+" "+str(float(arrStr[2])+new_value)
new_content = re.sub(old_value_pattern,f'<widthHeightDepth>{strs}</widthHeightDepth>',content)
#重新写入进去
with open(rcbox_path, 'w') as f:
f.write(new_content)
#修改rcproj文件,删除没有模型的component,保留最多model 的component
def changeRcprojFile(pid):
# 解析XML文件
file_path = os.path.join(config.workdir, pid, f'{pid}.rcproj')
#判断文件是否存在
if not os.path.exists(file_path):
return False
tree = ET.parse(file_path)
root = tree.getroot()
# 遍历所有的reconstructions节点
for reconstruction in root.findall('reconstructions'):
for component in reconstruction.findall('component'):
if component.find('model') == None:
reconstruction.remove(component)
continue
# 获取所有包含model标签的component节点
components_with_model = [component for component in reconstruction.findall('component') if component.find('model') is not None]
print(components_with_model)
# 如果包含model标签的component节点数量大于1,则按照model数量降序排序
if len(components_with_model) > 1:
components_with_model.sort(key=lambda x: len(x.findall('model')), reverse=False)
for i in range(len(components_with_model)-1):
reconstruction.remove(components_with_model[i])
# 保存修改后的XML文件
tree.write(file_path)
return True
#修改 rcproj 文件中的 controlpoints 文件的引用
def changeRcprojControlpointsFile(pid):
psid = libs.getPSid(pid)
# 解析XML文件
file_path = os.path.join(config.workdir, str(pid), f'{pid}.rcproj')
#判断文件是否存在
if not os.path.exists(file_path):
return False
#下载指定的psid的 points文件到本地
flag = down_points_from_oss(pid,psid)
if flag == False:
return False
tree = ET.parse(file_path)
root = tree.getroot()
# 遍历所有的reconstructions节点
for controlpoints in root.findall('controlpoints'):
#修改 controlpoints 标签内容里 双引号的内容 <controlpoints fileName="" />
controlpoints.set('fileName',f'controlpoints_{psid}.dat')
# 保存修改后的XML文件
tree.write(file_path)
return True
def down_points_from_oss(pid,psid):
# 根据前缀获取文件列表
prefix = f'points/{psid}/'
filelist = oss2.ObjectIteratorV2(config.oss_bucket, prefix=prefix)
flag = False
for file in filelist:
filename = file.key.split('/')[-1]
if filename.endswith('.dat'):
# print('正在下载:', file.key)
localfile = os.path.join(config.workdir,str(pid), filename)
config.oss_bucket.get_object_to_file(file.key, localfile)
flag = True
return flag
#判断oss上是否存在指定的controlpoints文件
def isExistControlPointsOss(pid):
return False
psid = libs.getPSid(pid)
filePath = f'points/{psid}/controlpoints_{psid}.dat'
#判断oss上是否存在
if config.oss_bucket.object_exists(filePath):
return True
else:
return False
#将本地的controlpoints文件上传到oss上
def uploadControlPointsOss(pid):
psid = libs.getPSid(pid)
filePath = f'points/{psid}/controlpoints_{psid}.dat'
localfile = os.path.join(config.workdir,str(pid), f'{str(pid)}_wait/controlpoints0.dat')
#进行上传
config.oss_bucket.put_object_from_file(filePath, localfile)
#截屏保存
def saveScreenImg(pid):
#获取当前的日志
if not os.path.exists(os.path.join(config.workdir,"screen", time.strftime("%y%m%d" time.localtime()))):
os.makedirs(os.path.join(config.workdir,"screen", time.strftime("%y%m%d" time.localtime())))
screenshot = ImageGrab .grab()
screenshot.save(os.path.join(config.workdir,"screen", time.strftime("%y%m%d" time.localtime())),str(pid)+".png")
#移动到e盘
if not os.path.exists(os.path.join(config.sharedir,"screen", time.strftime("%y%m%d" time.localtime()))):
os.makedirs(os.path.join(config.sharedir,"screen", time.strftime("%y%m%d" time.localtime())))
shutil.copytree(os.path.join(config.workdir,"screen", time.strftime("%y%m%d" time.localtime())), os.path.join(config.sharedir,"screen", time.strftime("%y%m%d" time.localtime())))
#文件夹的移动和删除
def removeFolder(pid):
#判断是否存在finished文件夹,没有则创建
if not os.path.exists(os.path.join(config.workdir, 'finished')):
os.makedirs(os.path.join(config.workdir, 'finished'))
#移动文件夹到指定路径,如果已经存在了就删除再移动
if os.path.exists(os.path.join(config.workdir, 'finished', pid)):
shutil.rmtree(os.path.join(config.workdir, 'finished', pid), ignore_errors=True)
shutil.move(os.path.join(config.workdir, pid), os.path.join(config.workdir, 'finished'))
#遍历finished 里的文件夹,超过三天的就都删除
for file in os.listdir(os.path.join(config.workdir, 'finished')):
if os.path.isdir(os.path.join(config.workdir, 'finished', file)):
file_time = os.path.getmtime(os.path.join(config.workdir, 'finished', file))
now_time = time.time()
if (now_time - file_time) > 259200:
shutil.rmtree(os.path.join(config.workdir, 'finished', file), ignore_errors=True)