diff --git a/libs/common.py b/libs/common.py index 062f241..e971592 100644 --- a/libs/common.py +++ b/libs/common.py @@ -1,4 +1,4 @@ -import redis,sys,os,re,oss2 +import redis,sys,os,re,oss2,shutil,time import platform import xml.etree.ElementTree as ET from PIL import ImageGrab @@ -223,7 +223,29 @@ def uploadControlPointsOss(pid): #截屏保存 def saveScreenImg(pid): #获取当前的日志 - if not os.path.exists(os.path.join("D:/screen/",time.strftime("%y-%m-%d", time.localtime()))): - os.makedirs(os.path.join("D:/screen/",time.strftime("%Y-%m-%d", time.localtime()))) + 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("D:/screen/",time.strftime("%Y-%-%d'time .localtime()"),str(pid)+".png")) \ No newline at end of file + 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) \ No newline at end of file diff --git a/libs/libs.py b/libs/libs.py index 0163d48..5b7f7ec 100644 --- a/libs/libs.py +++ b/libs/libs.py @@ -183,9 +183,11 @@ def down_obj_from_oss(workdir, pid, action): prefix = f'objs/{action}/{pid}/' filelist = oss2.ObjectIteratorV2(config.oss_bucket, prefix=prefix) print('正在下载:', prefix) + obj_filename = "" for file in filelist: filename = file.key.split('/')[-1] - if filename.endswith('.obj'): obj_filename = filename + if filename.endswith('.obj'): + obj_filename = filename # print('正在下载:', file.key) localfile = os.path.join(workdir, action, pid, filename) config.oss_bucket.get_object_to_file(file.key, localfile) diff --git a/libs/libs_db.py b/libs/libs_db.py index 19c96ba..abbcfc9 100644 --- a/libs/libs_db.py +++ b/libs/libs_db.py @@ -18,7 +18,7 @@ def get_task(task_type): with pymysqlAlias() as conn: cursor = conn.cursor() - sql = f'select task_key from tasks where task_type = "{task_type}" and status = 0 order by priority desc, id asc limit 1' + sql = f'select task_key from tasks where status = 0 order by priority desc, id asc limit 1' # print(f'sql: {sql}') cursor.execute(sql) data = cursor.fetchone() @@ -40,7 +40,7 @@ def add_task(data): if data["psid"] == '85': sql = f'insert into tasks (task_type, task_key,studio_id) values ("{data["task_type"]}", "{data["task_key"]}","{data["psid"]}")' else: - sql = f'insert into tasks (task_type, task_key, priority,studio_id) values ("{data["task_type"]}", "{data["task_key"]}", 1,"{data["psid"]}")' + sql = f'insert into tasks (task_type, task_key, priority,studio_id) values ("{data["task_type"]}", "{data["task_key"]}", {data["priority"]},"{data["psid"]}")' # print(f'sql: {sql}') cursor.execute(sql) conn.commit() @@ -66,7 +66,7 @@ def start_task(data): cursor = conn.cursor() hostname = socket.gethostname() - sql = f'update tasks set status = 1, hostname = "{hostname}", started_at = now(), updated_at = now() where task_type = "{data["task_type"]}" and task_key = "{data["task_key"]}"' + sql = f'update tasks set status = 1, hostname = "{hostname}", started_at = now(), updated_at = now() where task_key = "{data["task_key"]} and status = 0"' # print(f'sql: {sql}') cursor.execute(sql) conn.commit() @@ -80,7 +80,7 @@ def finish_task(data): cursor = conn.cursor() hostname = socket.gethostname() - sql = f'update tasks set status = 2, hostname = "{hostname}", finished_at = now(), updated_at = now() where task_type = "{data["task_type"]}" and task_key = "{data["task_key"]}"' + sql = f'update tasks set status = 2, hostname = "{hostname}", finished_at = now(), updated_at = now() where status = 1 and task_key = "{data["task_key"]}" ' # print(f'sql: {sql}') cursor.execute(sql) conn.commit() diff --git a/manual_service.py b/manual_service.py new file mode 100644 index 0000000..50a98be --- /dev/null +++ b/manual_service.py @@ -0,0 +1,129 @@ +import os, sys, time, shlex, subprocess, shutil, requests, cv2, numpy as np +from PIL import Image +import platform +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, libs_db,main_service_db +# 2. 手动操作建模做成建模 +# 2.0 检测是否存在项目,不存在就下载,存在就清除项目其它无用的文件 +# 2.1 初始化工程, 根据参数 加入 photo1 或者 photo 2 的 照片, 对齐 , 导出坐标, 将坐标复制到 另外一个文件夹, 测距, 重建区域, 然后调用step2 + +#根据pid 检测是否存在项目,不存在就下载,存在就清除项目其它无用的文件 +def check_pid_file(pid): + #检测是否存在目录 + path = os.path.join(config.workdir, pid) + if not os.path.exists(path): + #不存在就在就下载目录 + print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 开始计算相机位姿...') + start_time = time.time() + libs.down_from_oss(config.oss_bucket, config.workdir, pid) + print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} 图片下载完成,共费时{libs.diff_time(start_time)}') + else: + #存在的话就检测是否有photo1 和 photo2 之外的目录或者文件,有的话就删除 + for file in os.listdir(path): + if file != 'photo1' and file != 'photo2': + if os.path.isfile(os.path.join(path, file)): + os.remove(os.path.join(path, file)) + else: + shutil.rmtree(os.path.join(path, file)) + + #判断photo1 和 photo2 目录里的文件是否存在xmp 文件,不存在的话就删除 + for file in os.listdir(os.path.join(path, 'photo1')): + if not file.endswith('.xmp'): + os.remove(os.path.join(path, 'photo1', file)) + + for file in os.listdir(os.path.join(path, 'photo2')): + if not file.endswith('.xmp'): + os.remove(os.path.join(path, 'photo2', file)) + + +#根据参数初始化操作 +def cmd_run(pid,usePhoto = "1",lock=False): + + start_time = time.time() + #文件路径 + photo1_path = os.path.join(config.workdir, pid, 'photo1') + photo2_path = os.path.join(config.workdir, pid, 'photo2') + #计算文件里的数量 + photos1_count = len(os.listdir(photo1_path)) + photos2_count = len(os.listdir(photo2_path)) + print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} photo1数量{photos1_count} photo2数量{photos2_count}') + + #xmp 坐标是要用 lock的 还是 unlock 的 + if lock: + exportxmp = ' -exportXMP "D:\\make2\\config\\exportXMP.config.lock.xml" ' + else: + exportxmp = ' -exportXMP "D:\\make2\\config\\exportXMP.config.xml" ' + + usePhoto = "photo"+str(usePhoto) + + #执行命令 + cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \ + -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" \ + -addFolder "{os.path.join(config.workdir, pid, usePhoto)}" -selectAllImages \ + -detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \ + -align -align \ + {exportxmp} \ + -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit' + print(cmd) + cmd = shlex.split(cmd) + res = subprocess.run(cmd) + + #根据参数转变路劲,复制photo1 里的xmp 文件到 photo2 里,或者 photo2 里的xmp 文件到 photo1 里 + sourceFile = photo1_path + targetFile = photo2_path + if usePhoto == "photo2": + sourceFile = photo2_path + targetFile = photo1_path + #复制xmp文件 + for xmp in os.listdir(sourceFile): + if xmp.endswith('.xmp'): + shutil.copy(os.path.join(sourceFile, xmp), os.path.join(targetFile,xmp)) + + + #将两组图片进行重新对齐 然后重建区域 + psid = libs.getPSid(pid) + cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \ + -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" {config.r["setTextureFalse"]} \ + -addFolder "{targetFile}" -selectAllImages \ + -detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \ + {libs.get_defineDistances(psid)} -update -align -align {config.r2["setRegion"]} \ + {exportxmp} \ + -exportReconstructionRegion "{os.path.join(config.workdir, pid, f"{pid}.rcbox")}" \ + -selectImage "'+os.path.join(config.workdir,pid,'photo2')+'\*" -enableTexturingAndColoring true' + -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}"' + print(cmd) + cmd = shlex.split(cmd) + res = subprocess.run(cmd) + print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} step1完成,共费时{libs.diff_time(start_time)}') + + #调用step2 + time.sleep(2) + os.system(f'python main_step2.py {pid}') + + +if __name__ == '__main__': + if len(sys.argv) == 2: + pids = sys.argv[1].split(',') + for pid in pids: + cmd_run(pid,usePhoto = "1",lock=False) + elif len(sys.argv) == 3: + pids = sys.argv[1].split(',') + for pid in pids: + if sys.argv[2] == '2': + cmd_run(pid,usePhoto = "2",lock=False) + else: + cmd_run(pid,usePhoto = "1",lock=False) + elif len(sys.argv) == 4: + pids = sys.argv[1].split(',') + usePhoto = sys.argv[2] + lock = sys.argv[3] + for pid in pids: + cmd_run(pid,usePhoto = usePhoto,lock=lock) + + else: + print(f'useage: python {sys.argv[0]} pid1,pid2,pid3 photo = 1/2 lock = True/False') + sys.exit(1) \ No newline at end of file diff --git a/test.py b/test.py index 3615d8a..3e4fa86 100644 --- a/test.py +++ b/test.py @@ -10,28 +10,51 @@ else: import config, libs, libs_db,common -if __name__ == '__main__': +if __name__ == '__main__': + + #遍历oss 指定文件夹下指定日期的文件 + for obj in config.bucket.list_objects(prefix="auto/"): + #判断是否是文件夹 并且 日期是否在 2023-11-08 之后的 + if obj.key[-1] == "/" and obj.key.split("/")[1] >= "2023-11-08": + #判断是否存在这个目录 + if not os.path.exists(os.path.join(config.workdir,obj.key.split("/")[1])): + os.mkdir(os.path.join(config.workdir,obj.key.split("/")[1])) + #拷贝文件到本地 + for obj2 in config.bucket.list_objects(prefix=obj.key): + if obj2.key[-1] != "/": + print(obj2.key) + #判断文件是否存在 + if not os.path.exists(os.path.join(config.workdir,obj2.key)): + #下载文件 + config.bucket.get_object_to_file(obj2.key,os.path.join(config.workdir,obj2.key)) + #判断文件是否下载成功 + if os.path.exists(os.path.join(config.workdir,obj2.key)): + print("下载成功") + else: + print("下载失败") + else: + print("文件已存在") # 解析XML文件 - pid = "112322" - file_path = os.path.join(config.workdir, pid, f'{pid}.rcproj') - 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) + # pid = "112322" + # file_path = os.path.join(config.workdir, pid, f'{pid}.rcproj') + # 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]) + # for i in range(len(components_with_model)-1): + # reconstruction.remove(components_with_model[i]) - # 保存修改后的XML文件 - tree.write(file_path) + # # 保存修改后的XML文件 + # tree.write(file_path) diff --git a/timer/get_task_to_db.py b/timer/get_task_to_db.py index 9212c46..2a47c44 100644 --- a/timer/get_task_to_db.py +++ b/timer/get_task_to_db.py @@ -37,15 +37,23 @@ def readTask(key): #默认走原来的数据表tasks,现在要切入一些数据过来走分布式建模系统 taskData = {"task_type":key,"task_key":pid,"psid":psid,"priority":1} - if int(psid) == 41 or int(psid) == 85: - taskData["priority"] = 0 - - if libs_db.isStudioConfigDistribute(psid): - print("走分布式建模系统插入",key,pid,psid) - libs_db.add_task_distributed(taskData) - else: - print("走新的建模系统不是分布式插入",key,pid,psid) + + if key == "rebuild": + taskData["priority"] = 100 + print("走新的建模系统不是分布式插入-重建工单",key,pid,psid) libs_db.add_task(taskData) + else: + + if int(psid) == 41 or int(psid) == 85: + taskData["priority"] = 0 + print("走分布式建模系统插入",key,pid,psid) + libs_db.add_task_distributed(taskData) + if libs_db.isStudioConfigDistribute(psid): + print("走分布式建模系统插入",key,pid,psid) + libs_db.add_task_distributed(taskData) + else: + print("走新的建模系统不是分布式插入",key,pid,psid) + libs_db.add_task(taskData) #程序主入口 if __name__ == '__main__': @@ -59,4 +67,5 @@ if __name__ == '__main__': readTask('make10') time.sleep(10) readTask('make') - time.sleep(10) \ No newline at end of file + time.sleep(10) + readTask("rebuild") \ No newline at end of file diff --git a/tools/auto_distance.py b/tools/auto_distance.py index ec2434e..393e813 100644 --- a/tools/auto_distance.py +++ b/tools/auto_distance.py @@ -5,7 +5,7 @@ if platform.system() == 'Windows': sys.path.append('e:\\libs\\') else: sys.path.append('/data/deploy/make3d/make2/libs/') -import config, libs,libs_db +import config, libs,libs_db,common redisLocal = config.redis_local def find_and_maximize_window(window_title): windows = [] @@ -23,6 +23,16 @@ def find_and_maximize_window(window_title): print(f'found {window_title} hwnd:{hwnd}') left, top, right, bottom = win32gui.GetWindowRect(hwnd) return pid, left, top, right, bottom + + if "screen" in win32gui.GetWindowText(hwnd): + pid = win32gui.GetWindowText(hwnd).split('screen')[0].split(' ')[0].split('-')[0].split('*')[0].split('_')[0] + time.sleep(3) + #截屏 + if pid != "": + common.saveScreenImg(pid) + time.sleep(3) + ag.hotkey('alt', 'f4') + return '0', 0, 0, 0, 0 # def get_defineDistances(pid, left, top, right, bottom): diff --git a/tools/push_cmd.py b/tools/push_cmd.py index 07b4413..1092449 100644 --- a/tools/push_cmd.py +++ b/tools/push_cmd.py @@ -9,7 +9,7 @@ import config, libs,libs_db def main(cmd, order_id): if cmd == 'print': #order_id key = 'model:printOrder' - elif cmd == 'repair': #order_id + elif cmd == 'repair': #reqpair_order_id key = 'model:IndependentRepairTeamcheckGLBQueue' elif cmd == 'make3d': #pid key = 'model:make' @@ -33,7 +33,7 @@ def cmd(cmdName,pid): key = "" if cmdName == 'print': #order_id key = 'model:printOrder' - elif cmdName == 'repair': #order_id + elif cmdName == 'repair': #repair_order_id key = 'model:IndependentRepairTeamcheckGLBQueue' elif cmdName == 'make3d': #pid key = 'model:make' @@ -54,7 +54,7 @@ def cmd(cmdName,pid): exit(1) data = res["data"] - if cmdName == 'print' or cmdName == 'repair': + if cmdName == 'print': #需要去吃查询pid 对应的order_id #遍历data for i in data: @@ -75,7 +75,26 @@ def cmd(cmdName,pid): break except ValueError: print("输入不满足要求,请重新输入") - + elif cmdName == "repair": + #需要去吃查询pid 对应的repair_order_id + #遍历data + for i in data: + #获取 pid 对应的数据 + tempData = data[i] + if len(tempData) == 1: + #pid 只有对应的一笔数据就可以直接插入了 + main(cmdName, str(tempData[0]["model_repair_order_id"])) + else: + while True: + try: + tempDataStrings = listDataToStr(tempData,cmdName) + model_repair_order_id = int(input("pid-"+i+"对应有多个数据,请从下列中选择正确的model_repair_order_id填入\r\n"+tempDataStrings+"\r\n->")) + # 在这里处理用户输入的整数 + print("输入的是: ", model_repair_order_id) + main(cmdName, str(model_repair_order_id)) + break + except ValueError: + print("输入不满足要求,请重新输入") elif cmdName == 'foot': #遍历data @@ -106,6 +125,8 @@ def listDataToStr(data,cmdName): for i in data: if cmdName == "foot": strMessage += i['createTime']+" print_id:"+str(i['print_id'])+"\r\n" + elif cmdName == "repair": + strMessage += i['createTime']+" model_repair_order_id:"+str(i['model_repair_order_id'])+"\r\n" else: strMessage += i['createTime']+" order_id:"+str(i['order_id'])+"\r\n" return strMessage