from ..generate_goods_no_detail_pic.data import DataModeUploadPic import os import threading import time import concurrent.futures import re from PIL import Image from io import BytesIO from middleware import UnicornException # 详情图上传 class UploadPic(): # signal_data = Signal(dict) # run_end_sign = Signal(dict) # show_progress_detail_sign = Signal(str) def __init__(self, windows, to_deal_dir, config_data,token): super().__init__() self.windows = windows self.data_mode_upload_pic = DataModeUploadPic(token) self.goods_no_data = {} # ------------------ # 0未选择文件,1已选文件未开始,2进行中 self.state = 0 self.state_change(self.state) self.to_deal_dir = to_deal_dir self.config_data = config_data def check_path(self, _path): if not os.path.exists(_path): os.mkdir(_path) return True def run_by_thread(self): self.run_by_thread_real() self.config_data["sign_text"] = "结束" self.run_end_sign.emit(self.config_data) def run(self): self.run_by_thread_real() def run_by_thread_real(self, *args): self.show_info("====开始处理====") # 统计哪些需要处理 total_num = 0 flag = True # group_folders 分组文件夹 for group_folders in os.listdir(self.to_deal_dir): path = "{}\{}".format(self.to_deal_dir, group_folders) if not os.path.isdir(path): continue for goods_no in os.listdir(path): # 检测是不是货号或款号文件夹 goods_no_path = "{}\{}\{}".format(self.to_deal_dir, group_folders, goods_no) if not os.path.isdir(goods_no_path): continue total_num += 1 # 检查每个款号文件夹是不是合规 # 款的一级目录文件 files = os.listdir(goods_no_path) if "details" not in files: continue not_goods_art_msg = "" for f in files: f_path = "{}\{}\{}\{}".format(self.to_deal_dir, group_folders, goods_no, f) if os.path.isdir(f_path): # 处理货号文件夹 if "details" != f and "货号素材" not in f and "main" not in f and "拼接图" not in f: # 是否货号文件夹判断 if not self.is_goods_art_dir(f, goods_no): self.show_info("{}文件夹下 {} {} 疑似不是货号".format(group_folders, goods_no, f)) not_goods_art_msg += ( "{}文件夹下 {} {} 疑似不是货号".format( group_folders, goods_no, f ) + "\n" ) flag = False if not flag: self.show_info("请解决以上问题后重试") raise UnicornException(f"请解决:\n{not_goods_art_msg}\n以上问题后重试") return if total_num == 0: self.show_info("没有任何款号文件夹 需要上传") raise UnicornException("没有任何款号文件夹 需要上传") return self.lock = threading.Lock() error_data = [] n = 0 for group_folders in os.listdir(self.to_deal_dir): path = "{}\{}".format(self.to_deal_dir, group_folders) if not os.path.isdir(path): continue for goods_no in os.listdir(path): goods_no_path = "{}\{}\{}".format(self.to_deal_dir, group_folders, goods_no) if not os.path.isdir(goods_no_path): self.show_info("{} 不是文件夹".format(goods_no)) continue if goods_no in self.data_mode_upload_pic.is_deal_goods_no: continue else: self.data_mode_upload_pic.is_deal_goods_no.append(goods_no) # ================处理单个款号信息,图片上传处理============ self.show_info("开始处理 {}".format(goods_no)) # try: if self.deal_goods_pic(goods_no, goods_no_path): # 移动文件到已完成 # dest = "{}\{}\{}".format(self.is_deal_dir, group_folders, goods_no) # if os.path.exists(dest): # self.show_info("{} 文件夹在目标目录已存在".format(goods_no)) # else: # shutil.move(goods_no_path, dest) self.show_info("{} 上传成功".format(goods_no)) else: self.show_info("{} 处理失败".format(goods_no)) error_data.append(goods_no) pass # except BaseException as e: # self.show_info("上传异常:{},{}".format(goods_no, e)) # raise UnicornException("上传异常:{},{}".format(goods_no, e)) # n += 1 # self.show_info({"type": "show_p", # "data": int(n * 100 / total_num)}) self.show_info("========已结束========== ") if error_data: self.show_info("以下编号/款号处理失败") error_msg = "" for data in error_data: self.show_info("{}".format(data)) error_msg += data+"\n" raise UnicornException(f"以下编号/款号处理失败\n{error_msg}") # self.show_info({"type": "change_state", # "data": 2}) def deal_goods_pic(self, goods_no, goods_no_path): """ 两种模式:货号模式、编号模式 :param goods_no: :param goods_no_path: :return: """ print("==========开始上传系统=============") s = time.time() self.show_info("{} 开始上传 ".format(goods_no)) if "NUM" in goods_no.upper(): mode = "编号" else: mode = "货号" # 校验所有编号是否存在,是否是同个款 _numbers = [] if mode == "编号": _numbers.append(goods_no) self.goods_no_data[goods_no] = {} # 收集该款号下可能存在的货号或编号 files = os.listdir(goods_no_path) if "details" not in files: self.show_info("{} 缺少details 文件夹".format(goods_no, )) raise UnicornException("{} 缺少details 文件夹".format(goods_no)) return False for f in files: f_path = "{}\{}".format(goods_no_path, f) if os.path.isdir(f_path): if "details" != f and "货号素材" not in f and "main" not in f and "拼接图" not in f: if not self.is_goods_art_dir(f, goods_no): self.show_info("{} {} 疑似不是货号".format(goods_no, f)) # return False continue else: _numbers.append(f) if "货号素材" in f: if "_" not in f: self.show_info("{} 货号素材文件夹 格式错误".format(goods_no)) raise UnicornException("{} 货号素材文件夹 格式错误".format(goods_no)) return False # 校验所有编号是否存在,是否是同个款 if mode == "编号": _numbers = [x.replace("KNUM", "").replace("NUM", "") for x in _numbers] _numbers = list(set(_numbers)) goods_number_data = self.data_mode_upload_pic.get_goods_art_no_info(numbers_list=_numbers) else: goods_number_data = self.data_mode_upload_pic.get_goods_art_no_info(goods_art_list=_numbers) t = True for num in _numbers: if num not in goods_number_data: t = False if mode == "编号": self.show_info("{} 编号在系统中不存在".format(num)) else: self.show_info("{} 货号在系统中不存在".format(num)) else: if self.config_data["upload_is_pass"]: if self.data_mode_upload_pic.check_is_uploaded(num): t = False self.show_info("{} 货号在系统已有详情页,已跳过".format(num)) return True if not t: return False _ = set([goods_number_data[x]["款号"] for x in goods_number_data]) if len(_) != 1: self.show_info("{} 存在多个不同的款号".format(_)) raise UnicornException("{} 存在多个不同的款号".format(_)) return False # 重新定义款号 goods_no = _.pop() # 上传所有图片 self.pic_data = {} ignore_text = ["main", "拼接图", "货号素材"] _Type = ['.png', '.PNG', '.jpg', '.JPG', '.gif', '.GIF'] for dirpath, dirnames, filenames in os.walk(goods_no_path): for file in filenames: if os.path.splitext(file)[1] in _Type: # 获取当前路径的文件夹名称 f_path = dirpath + '/' + file f = True for i in ignore_text: if i in f_path: f = False break if f: print(f_path) f_path = f_path.replace("\\", "/") self.pic_data[f_path] = {"url": ""} with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor: for key in self.pic_data: if "货号素材" in key: # 货号素材图不上传 is_resize = False continue else: is_resize = True executor.submit(self.to_upload_pic, file_path=key, is_resize=is_resize) for key in self.pic_data: if "货号素材" in key: is_resize = False continue if not self.pic_data[key]["url"]: self.show_info("{} {} 图片未上传完成".format(key, goods_no)) raise UnicornException("{} {} 图片未上传完成".format(key, goods_no)) return up_data = {"goods_art_no": [], "details": [], "goods_no": [], "goods_art_no_material": [] } details_index = 0 goods_no_index = 0 # 款号转换 # files 为当前款下的所有文件或文件夹 for f in files: f_path = "{}\{}".format(goods_no_path, f) f_path = f_path.replace("\\", "/") # 如果为文件夹则 if os.path.isdir(f_path): if "details" == f: # 处理详情图 for pic in os.listdir(f_path): pic_path = "{}\{}".format(f_path, pic) pic_path = pic_path.replace("\\", "/") details_index += 1 data = { "index": details_index, "name": goods_no, "number": goods_no, "status": "success", "type": "2", # 2 为详情图 "uid": "", "url": self.pic_data[pic_path]["url"], } up_data["details"].append(data) pass elif "货号素材" in f: continue x = f.split("_")[0] if mode == "编号": x = f.replace("NUM", "") x = x.replace("_货号素材", "") goods_art_no = goods_number_data[x]["商品货号"] else: goods_art_no = x n = 0 for pic in os.listdir(f_path): pic_path = "{}\{}".format(f_path, pic) pic_path = pic_path.replace("\\", "/") n += 1 data = { "index": n, "name": goods_art_no, "number": goods_art_no, "status": "success", "type": "3", "uid": "", "url": self.pic_data[pic_path]["url"], } up_data["goods_art_no_material"].append(data) else: if "拼接图" in f: continue if "main" in f: continue # 处理货号图 if mode == "编号": x = f.replace("NUM", "") goods_art_no = goods_number_data[x]["商品货号"] else: goods_art_no = f for pic in os.listdir(f_path): pic_path = "{}\{}".format(f_path, pic) pic_path = pic_path.replace("\\", "/") data = { "index": 1, "name": goods_art_no, "number": goods_art_no, "status": "success", "type": "0", # 0为货号图 "uid": "", "url": self.pic_data[pic_path]["url"], } up_data["goods_art_no"].append(data) break else: # 处理款号图 goods_no_index += 1 data = { "index": goods_no_index, "name": goods_no, "number": goods_no, "status": "success", "type": "1", "uid": "", "url": self.pic_data[f_path]["url"], } up_data["goods_no"].append(data) pass # -----------上传数据----------------- # print(up_data["goods_no"]) # print(up_data["goods_art_no_material"]) # print(up_data["details"]) # 上传图片 for key, value in up_data.items(): if value: if not self.data_mode_upload_pic.upload_pic_list_data(data={"images": value}): self.show_info("{} {}上传错误".format(goods_no, key)) raise UnicornException("{} {}上传错误".format(goods_no, key)) return False print("---{} {} 完成".format(goods_no, time.time() - s)) return True def to_upload_pic(self, file_path, is_resize=True): file_name = os.path.split(file_path)[1] e = os.path.splitext(file_name)[1][1:] im = Picture(file_path) if im.x > 1200: im.resize(width=1200) # print(file_name, e) # if e == "png": # im.im.show() # return _ = {"jpg": "JPEG", "JPG": "JPEG", "JPEG": "JPEG", "jpeg": "JPEG", "png": "PNG", "PNG": "PNG", } e = _[e] image_io = im.save_to_io(e) # if is_resize: # im = Picture(file_path) # if im.x > 1200: # im.resize(width=1200) # image_io = im.save_to_io() # e = "JPEG" # else: # file_name = os.path.split(file_path)[1] # e = os.path.splitext(file_name)[0][1:] # image_io = open(file_path, 'rb') # image_io = open(file_path, 'rb') # self.lock.acquire() # self.pic_data[file_path]["url"] = "1111" # self.lock.release() # return goods_data = {"file_path": os.path.split(file_path)[1], "image_io": image_io, "e": e } url = self.data_mode_upload_pic.upload_pic(goods_data=goods_data) self.lock.acquire() self.pic_data[file_path]["url"] = url self.lock.release() def is_goods_art_dir(self, file, goods_no): if goods_no in file: return True # 判断是不是货号文件夹 _r_text = re.findall("[a-zA-Z0-9]+", file) if _r_text: # print(_r_text) if _r_text[0] != file: # 文件夹中包含有非字母或数字判断不是货号 return False else: return True else: # 非字母和数字 判断为非货号 return False def show_info(self, text: str): # self.show_progress_detail_sign.emit(text) # self.windows.show_progress_detail(text) print("upload_pic=====>", text) def show_text_browser(self, text): pass def state_change(self, to_state: int): self.state = to_state class Picture: def __init__(self, in_path): self.im = Image.open(in_path) self.x, self.y = self.im.size # print(self.x, self.y) def resize(self, width): re_x = int(width) re_y = int(self.y * re_x / self.x) self.im = self.im.resize((re_x, re_y), Image.Resampling.LANCZOS) self.x, self.y = self.im.size def save_to_io(self, format): img = BytesIO() self.im.save(img, format=format) # format: PNG or JPEG img.seek(0) # rewind to the start return img