def create_patch(dir_src, dir_all_release, create_patch_for_latest_n_version, dir_github_action_artifact, get_final_patch_path_only=False) -> str: latest_version = now_version path_bz = os.path.join(dir_src, "utils/bandizip_portable", "bz.exe") old_cwd = os.getcwd() os.chdir(dir_all_release) if not get_final_patch_path_only: logger.info(f"工作目录已调整为{os.getcwd()},最新版本为v{latest_version}") uploader = Uploader() if not get_final_patch_path_only: logger.info( f"尝试从网盘查找在{latest_version}版本之前最近{create_patch_for_latest_n_version}个版本的信息" ) old_version_infos = [] # type: List[HistoryVersionFileInfo] # 获取当前网盘的最新版本,若比当前发布版本低,也加入 netdisk_latest_version_fileinfo = uploader.find_latest_version() netdisk_latest_version = uploader.parse_version_from_djc_helper_file_name( netdisk_latest_version_fileinfo.name) if version_less(netdisk_latest_version, latest_version): old_version_infos.append( HistoryVersionFileInfo(netdisk_latest_version_fileinfo, netdisk_latest_version)) # 从历史版本网盘中查找旧版本 for page in range_from_one(100): folder_info = uploader.get_folder_info_by_url( uploader.folder_history_files.url, get_this_page=page) for file in folder_info.files: filename = file.name # type: str if not filename.startswith(uploader.history_version_prefix): # 跳过非历史版本的文件 continue file_version = uploader.parse_version_from_djc_helper_file_name( filename) info = HistoryVersionFileInfo(file, file_version) if not version_less(file_version, latest_version): continue if info in old_version_infos: # 已经加入过(可能重复) continue old_version_infos.append(info) if len(old_version_infos) >= create_patch_for_latest_n_version + 2: # 已经找到超过前n+2个版本,因为网盘返回的必定是按上传顺序排列的,不过为了保险起见,多考虑一些 break if create_patch_for_latest_n_version > len(old_version_infos): create_patch_for_latest_n_version = len(old_version_infos) old_version_infos = sorted( old_version_infos)[-create_patch_for_latest_n_version:] # 确认最终文件名 patch_oldest_version = old_version_infos[0].version patch_newest_version = old_version_infos[-1].version patches_dir = f"DNF蚊子腿小助手_增量更新文件_v{patch_oldest_version}_to_v{patch_newest_version}" temp_dir = "patches_temp" patch_7z_file = f"{patches_dir}.7z" if get_final_patch_path_only: return patch_7z_file logger.info(f"需要制作补丁包的版本为{old_version_infos}") # 确保版本都在本地 logger.info(f"确保以上版本均已下载并解压到本地~") for info in old_version_infos: local_folder_path = os.path.join(dir_all_release, f"DNF蚊子腿小助手_v{info.version}_by风之凌殇") local_7z_path = local_folder_path + ".7z" if os.path.isdir(local_folder_path): # 本地已存在对应版本,跳过 continue logger.info(f"本地发布目录不存在 {local_folder_path}") if not os.path.isfile(local_7z_path): logger.info(f"本地不存在{info.fileinfo.name}的7z文件,将从网盘下载") uploader.download_file(info.fileinfo, dir_all_release) logger.info(f"尝试解压 {info.fileinfo.name} 到 {local_folder_path}") decompress_dir_with_bandizip(local_7z_path, dir_src) # --------------------------- 实际只做补丁包 --------------------------- logger.info(color("bold_yellow") + f"将为【{old_version_infos}】版本制作补丁包") shutil.rmtree(patches_dir, ignore_errors=True) os.mkdir(patches_dir) shutil.rmtree(temp_dir, ignore_errors=True) os.mkdir(temp_dir) def temp_path(dir_name): return os.path.realpath(os.path.join(temp_dir, dir_name)) def preprocess_before_patch(temp_version_path): for filename in ["config.toml", "utils/auto_updater.exe"]: filepath = os.path.join(temp_version_path, filename) if os.path.isfile(filepath): os.remove(filepath) # 为旧版本创建patch文件 target_version_dir = f"DNF蚊子腿小助手_v{latest_version}_by风之凌殇" logger.info(f"目标版本目录为{target_version_dir}") shutil.copytree(target_version_dir, temp_path(target_version_dir)) preprocess_before_patch(temp_path(target_version_dir)) for idx, version_info in enumerate(old_version_infos): version = version_info.version patch_file = f"{patches_dir}/{version}.patch" logger.info("-" * 80) logger.info( color("bold_yellow") + f"[{idx + 1}/{len(old_version_infos)}] 创建从v{version}升级到v{latest_version}的补丁{patch_file}" ) version_dir = f"DNF蚊子腿小助手_v{version}_by风之凌殇" shutil.copytree(version_dir, temp_path(version_dir)) preprocess_before_patch(temp_path(version_dir)) subprocess.call([ os.path.realpath(os.path.join(dir_src, "utils/hdiffz.exe")), f"-p-{multiprocessing.cpu_count()}", # 设置系统最大cpu数 os.path.realpath(os.path.join(temp_dir, version_dir)), os.path.realpath(os.path.join(temp_dir, target_version_dir)), patch_file, ]) filesize = os.path.getsize(patch_file) logger.info(f"创建补丁{patch_file}结束,最终大小为{human_readable_size(filesize)}") # 移除临时目录 shutil.rmtree(temp_dir, ignore_errors=True) # 压缩打包 compress_dir_with_bandizip(patches_dir, patch_7z_file, dir_src) # 额外备份一份最新的供github action 使用 shutil.copyfile( patch_7z_file, os.path.join(dir_github_action_artifact, 'djc_helper_patches.7z')) os.chdir(old_cwd) return patch_7z_file
def decompress(filepath, target_dir): decompress_dir_with_bandizip(filepath, ".", target_dir)
def check_and_download_chrome_ahead(self): """ 尝试预先下载解压缩chrome的driver和便携版 主要用于处理多进程模式下,可能多个进程同时尝试该操作导致的问题 :return: """ logger.info("检查chrome相关内容是否ok") logger.info( color("bold_yellow") + f"如果自动下载失败,可能是网络问题,请根据提示下载的内容,自行去网盘下载该内容到utils目录下 https://fzls.lanzoui.com/s/djc-tools" ) chrome_driver_exe_name = os.path.basename( self.chrome_driver_executable_path()) zip_name = os.path.basename(self.chrome_binary_7z()) chrome_root_directory = self.chrome_root_directory() logger.info("检查driver是否存在") if not os.path.isfile(self.chrome_driver_executable_path()): logger.info( color("bold_yellow") + f"未在小助手utils目录里发现 {chrome_driver_exe_name} ,将尝试从网盘下载") uploader = Uploader() uploader.download_file_in_folder(uploader.folder_djc_helper_tools, chrome_driver_exe_name, chrome_root_directory) options = Options() options.headless = True options.add_experimental_option("excludeSwitches", ["enable-logging"]) if not self.cfg.force_use_portable_chrome: try: logger.info("检查系统自带的chrome是否可用") self.driver = webdriver.Chrome( executable_path=self.chrome_driver_executable_path(), options=options) self.driver.quit() return except: logger.info("走到这里说明系统自带的chrome不可用") pass else: logger.info("当前配置为强制使用便携版chrome") # 尝试从网盘下载合适版本的便携版chrome if not os.path.isfile(self.chrome_binary_7z()): logger.info( color("bold_yellow") + f"本地未发现便携版chrome的压缩包,尝试自动从网盘下载 {zip_name},需要下载大概80MB的压缩包,请耐心等候" ) uploader = Uploader() uploader.download_file_in_folder(uploader.folder_djc_helper_tools, zip_name, chrome_root_directory) # 尝试解压 if not os.path.isdir(self.chrome_binary_directory()): logger.info(f"自动解压便携版chrome到当前目录") decompress_dir_with_bandizip( self.chrome_binary_7z(), dst_parent_folder=chrome_root_directory) logger.info("检查便携版chrome是否有效") try: options.binary_location = self.chrome_binary_location() # you may need some other options options.add_argument('--no-sandbox') options.add_argument('--no-default-browser-check') options.add_argument('--no-first-run') self.driver = webdriver.Chrome( executable_path=self.chrome_driver_executable_path(), options=options) self.driver.quit() return except: pass # 走到这里,大概率是多线程并行下载导致文件出错了,尝试重新下载 logger.info(color("bold_yellow") + "似乎chrome相关文件损坏了,尝试重新下载并解压") uploader = Uploader() uploader.download_file_in_folder(uploader.folder_djc_helper_tools, chrome_driver_exe_name, chrome_root_directory, cache_max_seconds=0) uploader.download_file_in_folder(uploader.folder_djc_helper_tools, zip_name, chrome_root_directory, cache_max_seconds=0) shutil.rmtree(self.chrome_binary_directory(), ignore_errors=True) decompress_dir_with_bandizip(self.chrome_binary_7z(), dst_parent_folder=chrome_root_directory)