from ctypes import util import os, oss2, time, redis, requests, shutil, sys, subprocess, json, qrcode from PIL import Image, ImageDraw, ImageFont def gen_qrcode(pid): fontHeightMax = 40 fontsize = 1 qr = qrcode.QRCode() qr.border = 2 qr.add_data(pid) img = qr.make_image(fit=True) img = img.transform((250, 294), Image.Transform.EXTENT, (0, 0, 250, 294), fillcolor='white') cwd = os.path.dirname(os.path.abspath(__file__)) fontfile = os.path.join(cwd, 'fonts', 'Helvetica.ttf') font = ImageFont.truetype(fontfile, fontsize) while font.getsize(pid)[1] <= fontHeightMax and font.getsize(pid)[0] <= 240: fontsize += 1 font = ImageFont.truetype(fontfile, fontsize) fontsize -= 1 captionx = (250 - font.getsize(pid)[0]) / 2 draw = ImageDraw.Draw(img) draw.text((captionx, 242), pid, font=font) # img.show() path = os.path.join(workdir, 'print', pid) img.save(f'{path}/{pid}.png') def down_obj_fromoss(pid, print_type=1): # print_type:// 打印状态 1:正常打印 2:重打 3:加打,4: 样品 print('开始下载obj文件...' , pid) if not os.path.exists(os.path.join(workdir, 'print')): os.mkdir(os.path.join(workdir, 'print')) path = os.path.join(workdir, 'print', pid) if not os.path.exists(path): os.mkdir(path) # 根据前缀获取文件列表 prefix = f'objs/print/{pid}/' filelist = oss2.ObjectIteratorV2(oss_client, prefix=prefix) find = False for file in filelist: filename = file.key.split('/')[-1] if filename == '': continue if filename.endswith(f'{pid}.obj'): find = True print('正在下载:', file.key) localfile = os.path.join(path, filename) oss_client.get_object_to_file(file.key, localfile) if not find and print_type == 3: for file in os.listdir(path): if file.endswith('.obj'): print('找到其他obj文件,采用这个文件来生成需要的尺寸', file) shutil.copy(os.path.join(path, file), os.path.join(path, f'{pid}.obj')) find = True break if not find: print('找不到obj文件,异常退出') sys.exit(1) def getPidFromOrderId(orderId): getPidFromOrderId_url = 'https://mp.api.suwa3d.com/api/printOrder/info' print(f'{getPidFromOrderId_url}?id={orderId}') res = requests.get(f'{getPidFromOrderId_url}?id={orderId}') print(res.text) return res.json()['data'] def detect_obj4print(pid): for file in os.listdir(os.path.join(workdir, 'print', pid)): if file.endswith('.obj') and 'x' in file: return True def make3d4print_task(r): try: if r.llen('model:printOrder') == 0: time.sleep(5) return except Exception as e: print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), 'redis连接异常,重新连接') print(e) time.sleep(5) r = redis.Redis(host='106.14.158.208', password='kcV2000', port=6379, db=6) return orderId = r.lpop('model:printOrder') if orderId is None: return orderId = orderId.decode('utf-8') res = getPidFromOrderId(orderId) pid = str(res['pid']) print_type = res['print_type'] digital_type = res['digital_type'] # 0: 只有手办 1: 只有数字模型 2: 手办+数字模型 print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 生成待打印模型 start', ) down_obj_fromoss(pid, print_type) gen_qrcode(pid) os.system(f'{blenderbin} -b -P d:\\apps\\blender\\resize_model.py -- {orderId}') if not detect_obj4print(pid): print('obj文件生成异常,退出') sys.exit(1) print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 生成待打印模型 end') print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 上传生成的模型 start', ) for file in os.listdir(os.path.join(workdir, 'print', pid)): if file.endswith('.obj') and (not file.endswith(f'{pid}.obj')): oss_client.put_object_from_file(f'objs/print/{pid}/{file}', os.path.join(workdir, 'print', pid, file)) if file.endswith('.glb'): oss_client.put_object_from_file(f'glbs/3d/{pid}.glb', os.path.join(workdir, 'print', pid, file)) oss_client.delete_object(f'objs/print/{pid}/{pid}.obj') shutil.rmtree(os.path.join(workdir, 'print', pid), ignore_errors=True) print(f'{update_makeprintobj_status_url}?id={orderId}') if digital_type == 1: print('只有数字模型,不需要推送手办打印任务') else: res = requests.get(f'{update_makeprintobj_status_url}?id={orderId}') print('更新打印状态:', res.text) if res.json()['code'] != 1000: print('更新打印状态失败') sys.exit(1) print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 上传生成的模型 end') def team_check(r): try: if r.llen('model:IndependentRepairTeamcheckGLBQueue') == 0: time.sleep(5) return except Exception as e: print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), 'redis连接异常,5秒后重试') print(e) time.sleep(5) r = redis.Redis(host='106.14.158.208', password='kcV2000', port=6379, db=6) return repair_id = r.lpop('model:IndependentRepairTeamcheckGLBQueue') if repair_id is None: return repair_id = repair_id.decode('utf-8') res = requests.get(f'{getRepairInfo_url}?id={repair_id}') print(res.text) pid = res.json()['data']['pid'] pid = str(pid) print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'pid:{pid} 生成团队审核模型 start', ) down_obj_fromoss(pid) obj_filename = f'{pid}.obj' glb_filename = f'{pid}.glb' print('开始转换obj文件为glb文件...') os.system(f'gltfpack -c -i {os.path.join(workdir, "print", pid, obj_filename)} -o {os.path.join(workdir, "print", pid, glb_filename)}') print('上传glb文件到oss...') oss_client.put_object_from_file(f'glbs/print/{glb_filename}', os.path.join(workdir, "print", pid, glb_filename)) print(f'{update_repair_status_url}?id={repair_id}') res = requests.get(f'{update_repair_status_url}?id={repair_id}') print('更新团队审核状态:', res.text) shutil.rmtree(os.path.join(workdir, 'print', pid), ignore_errors=True) print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'pid:{pid} 生成团队审核模型 end') def platform_check(r): try: if r.llen('model:modelRepairGLBQueue') == 0: time.sleep(5) return except Exception as e: print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), 'redis连接异常,5秒后重试') print(e) time.sleep(5) r = redis.Redis(host='106.14.158.208', password='kcV2000', port=6379, db=6) return pid = r.lpop('model:modelRepairGLBQueue') if pid is None: return print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'pid:{pid} 生成平台审核模型 start', ) pid = pid.decode('utf-8') down_obj_fromoss(pid) obj_filename = f'{pid}.obj' glb_filename = f'{pid}.glb' os.system(f'gltfpack -c -i {os.path.join(workdir, "print", pid, obj_filename)} -o {os.path.join(workdir, "print", pid, glb_filename)}') oss_client.put_object_from_file(f'glbs/print/{glb_filename}', os.path.join(workdir, "print", pid, glb_filename)) print(f'{update_check_url}?id={pid}') res = requests.get(f'{update_check_url}?id={pid}') print(res.text) shutil.rmtree(os.path.join(workdir, 'print', pid), ignore_errors=True) print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'pid:{pid} 生成平台审核模型 end') def main(r): print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '模型生成程序 start') while True: # team_check(r) # platform_check(r) make3d4print_task(r) if __name__ == '__main__': AccessKeyId = 'LTAI5tSReWm8hz7dSYxxth8f' AccessKeySecret = '8ywTDF9upPAtvgXtLKALY2iMYHIxdS' Endpoint = 'oss-cn-shanghai.aliyuncs.com' Bucket = 'suwa3d-securedata' oss_client = oss2.Bucket(oss2.Auth(AccessKeyId, AccessKeySecret), Endpoint, Bucket) update_check_url = 'https://mp.api.suwa3d.com/api/customerP3dLog/updateStatusToWaitingPlatformCheckingStatus' update_team_check_url = 'https://mp.api.suwa3d.com/api/customerP3dLog/updateStatusToWaitingTeamCheckingStatus' update_status_printstatus_url = 'https://mp.api.suwa3d.com/api/customerP3dLog/updateBuildPrintModelStatus' update_makeprintobj_status_url = 'https://mp.api.suwa3d.com/api/printOrder/updateMakePrintObjSucceed' getRepairInfo_url = 'https://repair.api.suwa3d.com/api/modelRepairOrder/teamCheckGLBInfo' update_repair_status_url = 'https://repair.api.suwa3d.com/api/modelRepairOrder/updateStatusToWaitingTeamCheckingStatus' workdir = 'D:\\' blenderbin = '"C:\\Program Files\\Blender Foundation\\Blender 3.3\\blender.exe"' r = redis.Redis(host='106.14.158.208', password='kcV2000', port=6379, db=6) main(r)