import json import os,shutil,time from datetime import datetime from pathlib import Path from zipfile import ZipFile from utils.comic.ComicInfo import comicInfo from utils.Ntfy import ntfy from utils.FileUtils import fileUtils from utils.comic.PathStr import pathStr class CBZUtils: @classmethod def getCBZ_Dir(cls): return comicInfo.getNewCBZComicChapter() @classmethod def getCBZ_Path(cls): return cls.getCBZ_Dir()+".CBZ" @classmethod def readDirsOrFiles(cls,dir,type): data = [] files = os.listdir(dir) for file in files: path = os.path.join(dir,file) if type == "files" and os.path.isfile(path): data.append(path) if type == "dirs" and os.path.isdir(path): data.append(path) return data @classmethod def zip_compression(cls,source_dir=None, target_file=None, remove=True): target_dir = os.path.dirname(target_file) if not os.path.exists(target_dir): os.makedirs(target_dir) if not os.path.exists(target_file) and source_dir != None: with ZipFile(target_file, mode='w') as zf: for path, dir_names, filenames in os.walk(source_dir): path = Path(path) arc_dir = path.relative_to(source_dir) y = 0 for filename in filenames: y = y + 1 print("打包中:" + str(y) + "/" + str(len(filenames)), os.path.join(source_dir, filename)) zf.write(path.joinpath(filename), arc_dir.joinpath(filename)) zf.close() ntfy.sendMsg(f"打包完成:{target_file}") cls.verCBZComic(target_file) return filenames @classmethod def packAutoComicChapterCBZ(cls): chapter_path = comicInfo.getDirComicChapter() if os.path.exists(chapter_path): dirs = os.listdir(chapter_path) for file in dirs: if file.startswith("scramble="): try: os.remove(file) except: print(f"删除 {file} 发生错误,已跳过") cls.zip_compression(comicInfo.getDirComicChapter(), cls.getCBZ_Path()) time.sleep(0.1) fileUtils.remove(comicInfo.getDirComic()) @classmethod def replaceZip(cls,filepath,unpack_dir=None): if not cls.compareFileDate(filepath): return None if unpack_dir == None: unpack_dir = str(filepath).split(".")[0] fz = ZipFile(filepath, 'r') for file in fz.namelist(): if file.endswith(".jpg"): data = fz.read(file) if len(data) < 500 and os.path.exists(filepath): os.remove(filepath) print(f"数据不完整,已删除:{filepath}") if cls.compareFileDate(filepath): os.utime(filepath) print(f"已更新文件时间 {filepath}") if os.path.exists(unpack_dir): shutil.rmtree(unpack_dir) # 删除删除main.ftl文件 #delete_filename = '' #if os.path.exists(delete_filename): # os.remove(delete_filename) # time.sleep(60) # shutil.copy(文件的路径,另一个目录);拷贝main.ftl到准备压缩的目录下 #cls.zip_compression() #小于则运行 @classmethod def compareFileDate(cls,filepath): if os.path.exists(filepath): ctime = os.path.getmtime(filepath) str_ctime = datetime.fromtimestamp(int(ctime)) file_ctime = str(str_ctime.year)+"{:0>2d}".format(str_ctime.month)+"{:0>2d}".format(str_ctime.day)+"{:0>2d}".format(str_ctime.hour) c_ctime = 2023011603 else: return False if int(file_ctime) < c_ctime: return True return False @classmethod def zip_info(cls,path,filter=True): result = None try: with ZipFile(path, "r") as zip_file: result = zip_file.namelist() if filter: result.remove(comicInfo.COMIC_ICON_NAME+".jpg") result.remove(comicInfo.COMIC_INFO_XML) except Exception as e: print(e) return result @classmethod def verCBZComic(cls,path=None,list_img=None): if path == None: path = cls.getCBZ_Path() if list_img == None: list_img = comicInfo.getChapterImgs() if not os.path.exists(path): return False if os.path.exists(path) and len(cls.zip_info(path)) == len(list_img): print(f"文件校验成功:{path}") comicInfo.setProgress(comicInfo.PROGRESS_DONE) return True else: try: print(f"文件删除中:{path}") os.remove(path) comicInfo.setProgress(comicInfo.PROGRESS_NONE) except Exception as e: print(e) return False return False @classmethod def existsUnzipCBZ(cls,filesname,result=False): unzip_base_path = pathStr.base_unzip_path zipfile_path = os.path.join(unzip_base_path,comicInfo.str_comic_name,comicInfo.str_chapter+".CBZ") #判断是否存在已下载CBZ文件 if os.path.exists(zipfile_path) and not os.path.exists(CBZUtils.getCBZ_Path()): print(f"存在CBZ文件{zipfile_path},解压中") zip_file = ZipFile(zipfile_path) #CBZ中文件数量,剔除ComicInfo.xml if len(filesname) == len(zip_file.namelist())-1: unzip_path = comicInfo.getDirComicChapter() zip_file.extractall(unzip_path) zip_file.close() print(f"解压完成: CBZ文件{zipfile_path}") print(f"文件校验中") for file in os.listdir(unzip_path): if file.endswith(".jpg") and not fileUtils.ver_file(os.path.join(unzip_path,file),type="image"): #清空文件 try: shutil.rmtree(unzip_path) except Exception as e: print(e) return False comicInfo.writeComicInfoXML(overlay=True) result = True return result @classmethod def nextCBZ(cls,list_img=None): return not cls.verCBZComic(list_img=list_img) class verUtils: @classmethod def depverNextCBZ(cls,list_img=None): #验证数据是已存在且是否完整 if list_img == None: comicInfo.getChapterImgs() cbz_path = CBZUtils.getCBZ_Path() is_next = False if os.path.exists(cbz_path): try: cbz_size = len(CBZUtils.zip_info(cbz_path)) except: cbz_size = 0 if len(list_img) == cbz_size: ntfy.sendMsg(f"{comicInfo.getComicName()} {comicInfo.getChapter()} 数据完整") is_next = True else: ntfy.sendMsg(f"{comicInfo.getComicName()} {comicInfo.getChapter()} 数据不完整,尝试删除配置CBZ文件后重试") try: if cbz_size > len(list_img) or os.path.getsize(cbz_path) < 300000: ntfy.sendMsg(f"删除 {cbz_path}") os.remove(cbz_path) comicInfo.setProgress(comicInfo.PROGRESS_NONE) else: is_next = True except: ntfy(f"删除失败 {cbz_path}") return is_next @classmethod def existsUnzipCBZ(cls,filesname): result = False unzip_base_path = pathStr.base_unzip_path zipfile_path = os.path.join(unzip_base_path,comicInfo.str_comic_name,comicInfo.str_chapter+".CBZ") #判断是否存在已下载CBZ文件 if os.path.exists(zipfile_path) and not os.path.exists(CBZUtils.getCBZ_Path()): print(f"存在CBZ文件{zipfile_path},解压中") zip_file = ZipFile(zipfile_path) #CBZ中文件数量,剔除ComicInfo.xml if len(filesname) == len(zip_file.namelist())-1: unzip_path = comicInfo.getDirComicChapter() zip_file.extractall(unzip_path) zip_file.close() print(f"解压完成: CBZ文件{zipfile_path}") print(f"文件校验中") for file in os.listdir(unzip_path): if file.endswith(".jpg") and not fileUtils.ver_file(os.path.join(unzip_path,file),type="image"): #清空文件 try: shutil.rmtree(unzip_path) except Exception as e: print(e) return False comicInfo.writeComicInfoXML(overlay=True) result = True return result