def demo(): logger.info( color("bold_yellow") + "尝试启动更新器,等待其执行完毕。若版本有更新,则会干掉这个进程并下载更新文件,之后重新启动进程...(请稍作等待)") dlc_path = os.path.realpath("auto_updater.py") p = subprocess.Popen([ dlc_path, "--pid", str(os.getpid()), "--version", str(now_version), "--cwd", os.getcwd(), "--exe_name", os.path.realpath("DNF蚊子腿小助手.exe"), ], cwd="utils", shell=True, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.DETACHED_PROCESS, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.wait() if p.returncode != 0: last_modify_time = parse_timestamp(os.stat(dlc_path).st_mtime) logger.error( f"DLC出错了,错误码为{p.returncode},DLC最后一次修改时间为{last_modify_time}") uploader = Uploader() netdisk_latest_dlc_info = uploader.find_latest_dlc_version() latest_version_time = parse_time(netdisk_latest_dlc_info.time) if latest_version_time > last_modify_time: logger.info( f"网盘中最新版本dlc上传于{latest_version_time}左右,在当前版本最后修改时间{last_modify_time}之后,有可能已经修复dlc的该问题,将尝试更新dlc为最新版本" ) uploader.download_file(netdisk_latest_dlc_info, "utils") else: logger.warning( f"网盘中最新版本dlc上传于{latest_version_time}左右,在当前版本最后修改时间{last_modify_time}之前,请耐心等待修复该问题的新版本发布~" )
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