class Uploader: folder_dnf_calc = Folder("魔改计算器", "1810329") folder_djc_helper = Folder("蚊子腿小助手", "2290618") folder_history_files = Folder("历史版本", "2303716") folder_online_files = Folder("在线文件存储", "2866929") folder_online_files_history_files = Folder("历史版本", "2867307") history_version_prefix = "DNF蚊子腿小助手_v" history_patches_prefix = "DNF蚊子腿小助手_增量更新文件_" regex_version = r'DNF蚊子腿小助手_v(.+)_by风之凌殇.7z' regex_patches = r'DNF蚊子腿小助手_增量更新文件_v(.+)_to_v(.+).7z' # 保存购买了自动更新工具的用户信息 buy_auto_updater_users_filename = "buy_auto_updater_users.txt" # 保存用户的付费信息 user_monthly_pay_info_filename = "user_monthly_pay_info.txt" # 卡密操作的付费信息 cs_buy_auto_updater_users_filename = "cs_buy_auto_updater_users.txt" cs_user_monthly_pay_info_filename = "cs_user_monthly_pay_info.txt" def __init__(self, cookie): self.lzy = LanZouCloud() self.login_ok = self.lzy.login_by_cookie(cookie) == LanZouCloud.SUCCESS def upload_to_lanzouyun(self, filepath, target_folder, history_file_prefix=""): logger.warning( f"开始上传 {os.path.basename(filepath)} 到 {target_folder.name}") run_start_time = datetime.now() def on_uploaded(fid, is_file): if not is_file: return logger.info(f"上传完成,fid={fid}") prefix = history_file_prefix if prefix == "": prefix = self.history_version_prefix folder_history_files = self.folder_history_files if target_folder.id == self.folder_online_files.id: folder_history_files = self.folder_online_files_history_files files = self.lzy.get_file_list(target_folder.id) for file in files: if file.name.startswith(prefix): self.lzy.move_file(file.id, folder_history_files.id) logger.info( f"将{file.name}移动到目录({folder_history_files.name})") logger.info(f"将文件移到目录({target_folder.name})中") self.lzy.move_file(fid, target_folder.id) # 上传到指定的文件夹中 retCode = self.lzy.upload_file(filepath, -1, callback=self.show_progress, uploaded_handler=on_uploaded) if retCode != LanZouCloud.SUCCESS: logger.error(f"上传失败,retCode={retCode}") return False logger.warning(f"上传当前文件总计耗时{datetime.now() - run_start_time}") return True def latest_version(self) -> str: """ 返回形如"1.0.0"的最新版本信息 """ latest_version_file = self.find_latest_version() # DNF蚊子腿小助手_v4.6.6_by风之凌殇.7z match = re.search(self.regex_version, latest_version_file.name) if match is not None: latest_version = match.group(1) return latest_version # 保底返回1.0.0 return "1.0.0" def download_latest_version(self, download_dir) -> str: """ 下载最新版本压缩包到指定目录,并返回最终压缩包的完整路径 """ return self.download_file(self.find_latest_version(), download_dir) def find_latest_version(self): """ 查找最新版本,如找到,返回lanzouyun提供的file信息,否则抛出异常 """ files = self.lzy.get_file_list(self.folder_djc_helper.id) for file in files: if file.name.startswith(self.history_version_prefix): return file raise FileNotFoundError("latest version not found") def latest_patches_range(self): """ 返回形如("1.0.0", "1.1.2")的补丁范围 """ latest_patches_file = self.find_latest_patches() # DNF蚊子腿小助手_增量更新文件_v4.6.5_to_v4.6.6.7z match = re.search(self.regex_patches, latest_patches_file.name) if match is not None: version_left, version_right = match.group(1), match.group(2) return (version_left, version_right) # 保底返回 return ("1.0.0", "1.0.0") def download_latest_patches(self, download_dir) -> str: """ 下载最新版本压缩包到指定目录,并返回最终压缩包的完整路径 """ return self.download_file(self.find_latest_patches(), download_dir) def find_latest_patches(self): """ 查找最新版本的补丁,如找到,返回lanzouyun提供的file信息,否则抛出异常 """ files = self.lzy.get_file_list(self.folder_djc_helper.id) for file in files: if file.name.startswith(self.history_patches_prefix): return file raise FileNotFoundError("latest patches not found") def download_file_in_folder(self, folder, name, download_dir, overwrite=True, show_log=True) -> str: """ 下载网盘指定文件夹的指定文件到本地指定目录,并返回最终本地文件的完整路径 """ return self.download_file(self.find_file(folder, name), download_dir, overwrite=overwrite, show_log=show_log) def find_file(self, folder, name): """ 在对应目录查找指定名称的文件,如找到,返回lanzouyun提供的file信息,否则抛出异常 """ files = self.lzy.get_file_list(folder.id) for file in files: if file.name == name: return file raise FileNotFoundError( f"file={name} not found in folder={folder.name}") def download_file(self, fileinfo, download_dir, overwrite=True, show_log=True) -> str: """ 下载最新版本压缩包到指定目录,并返回最终压缩包的完整路径 """ if not os.path.isdir(download_dir): os.mkdir(download_dir) download_dir = os.path.realpath(download_dir) target_path = os.path.join(download_dir, fileinfo.name) def after_downloaded(file_name): """下载完成后的回调函数""" target_path = file_name if show_log: logger.info(f"最终下载文件路径为 {file_name}") if show_log: logger.info(f"即将开始下载 {target_path}") callback = None if show_log: callback = self.show_progress retCode = self.lzy.down_file_by_id(fileinfo.id, download_dir, callback=callback, downloaded_handler=after_downloaded, overwrite=overwrite) if retCode != LanZouCloud.SUCCESS: if show_log: logger.error(f"下载失败,retCode={retCode}") if retCode == LanZouCloud.NETWORK_ERROR: if show_log: logger.warning( color("bold_yellow") + ("蓝奏云api返回网络错误,这很可能是由于dns的问题导致的\n" "分别尝试在浏览器中访问下列两个网页,是否一个打的开一个打不开?\n" "https://fzls.lanzoux.com/s/djc-helper\n" "https://fzls.lanzous.com/s/djc-helper\n" "\n" "如果是这样,请按照下面这个链接,修改本机的dns,使用阿里、腾讯、百度、谷歌dns中的任意一个应该都可以解决。\n" "https://www.ypojie.com/9830.html\n" "\n" "如果两个都打不开,大概率是蓝奏云挂了-。-可选择忽略后面的弹框,继续运行旧版本,或者手动去QQ群或github下载最新版本" )) raise Exception("下载失败") return target_path def show_progress(self, file_name, total_size, now_size): """显示进度的回调函数""" percent = now_size / total_size bar_len = 40 # 进度条长总度 bar_str = '>' * round(bar_len * percent) + '=' * round(bar_len * (1 - percent)) show_percent = percent * 100 now_mb = now_size / 1048576 total_mb = total_size / 1048576 print( f'\r{show_percent:.2f}%\t[{bar_str}] {now_mb:.2f}/{total_mb:.2f}MB | {file_name} ', end='') if total_size == now_size: print('') # 下载完成换行
class Uploader: folder_dnf_calc = Folder("魔改计算器", "1810329") folder_djc_helper = Folder("蚊子腿小助手", "2290618") folder_history_files = Folder("历史版本", "2303716") history_version_prefix = "DNF蚊子腿小助手_v" history_patches_prefix = "DNF蚊子腿小助手_增量更新文件_" regex_version = r'DNF蚊子腿小助手_v(.+)_by风之凌殇.7z' regex_patches = r'DNF蚊子腿小助手_增量更新文件_v(.+)_to_v(.+).7z' def __init__(self, cookie): self.lzy = LanZouCloud() self.login_ok = self.lzy.login_by_cookie(cookie) == LanZouCloud.SUCCESS def upload_to_lanzouyun(self, filepath, target_folder, history_file_prefix=""): logger.warning("开始上传 {} 到 {}".format(os.path.basename(filepath), target_folder.name)) run_start_time = datetime.now() def on_uploaded(fid, is_file): if not is_file: return logger.info("下载完成,fid={}".format(fid)) prefix = history_file_prefix if prefix == "": prefix = self.history_version_prefix files = self.lzy.get_file_list(target_folder.id) for file in files: if file.name.startswith(prefix): self.lzy.move_file(file.id, self.folder_history_files.id) logger.info("将{}移动到目录({})".format( file.name, self.folder_history_files.name)) logger.info("将文件移到目录({})中".format(target_folder.name)) self.lzy.move_file(fid, target_folder.id) # 上传到指定的文件夹中 retCode = self.lzy.upload_file(filepath, -1, callback=self.show_progress, uploaded_handler=on_uploaded) if retCode != LanZouCloud.SUCCESS: logger.error("上传失败,retCode={}".format(retCode)) return False logger.warning("上传当前文件总计耗时{}".format(datetime.now() - run_start_time)) return True def latest_version(self) -> str: """ 返回形如"1.0.0"的最新版本信息 """ latest_version_file = self.find_latest_version() # DNF蚊子腿小助手_v4.6.6_by风之凌殇.7z match = re.search(self.regex_version, latest_version_file.name) if match is not None: latest_version = match.group(1) return latest_version # 保底返回1.0.0 return "1.0.0" def download_latest_version(self, download_dir) -> str: """ 下载最新版本压缩包到指定目录,并返回最终压缩包的完整路径 """ return self.download_file(self.find_latest_version(), download_dir) def find_latest_version(self): """ 查找最新版本,如找到,返回lanzouyun提供的file信息,否则抛出异常 """ files = self.lzy.get_file_list(self.folder_djc_helper.id) for file in files: if file.name.startswith(self.history_version_prefix): return file raise FileNotFoundError("latest version not found") def latest_patches_range(self): """ 返回形如("1.0.0", "1.1.2")的补丁范围 """ latest_patches_file = self.find_latest_patches() # DNF蚊子腿小助手_增量更新文件_v4.6.5_to_v4.6.6.7z match = re.search(self.regex_patches, latest_patches_file.name) if match is not None: version_left, version_right = match.group(1), match.group(2) return (version_left, version_right) # 保底返回 return ("1.0.0", "1.0.0") def download_latest_patches(self, download_dir) -> str: """ 下载最新版本压缩包到指定目录,并返回最终压缩包的完整路径 """ return self.download_file(self.find_latest_patches(), download_dir) def find_latest_patches(self): """ 查找最新版本的补丁,如找到,返回lanzouyun提供的file信息,否则抛出异常 """ files = self.lzy.get_file_list(self.folder_djc_helper.id) for file in files: if file.name.startswith(self.history_patches_prefix): return file raise FileNotFoundError("latest patches not found") def download_file(self, fileinfo, download_dir) -> str: """ 下载最新版本压缩包到指定目录,并返回最终压缩包的完整路径 """ if not os.path.isdir(download_dir): os.mkdir(download_dir) download_dir = os.path.realpath(download_dir) target_path = os.path.join(download_dir, fileinfo.name) def after_downloaded(file_name): """下载完成后的回调函数""" target_path = file_name logger.info("最终下载文件路径为 {}".format(file_name)) logger.info("即将开始下载 {}".format(target_path)) retCode = self.lzy.down_file_by_id(fileinfo.id, download_dir, callback=self.show_progress, downloaded_handler=after_downloaded) if retCode != LanZouCloud.SUCCESS: logger.error("下载失败,retCode={}".format(retCode)) raise Exception("下载失败") return target_path def show_progress(self, file_name, total_size, now_size): """显示进度的回调函数""" percent = now_size / total_size bar_len = 40 # 进度条长总度 bar_str = '>' * round(bar_len * percent) + '=' * round(bar_len * (1 - percent)) print('\r{:.2f}%\t[{}] {:.1f}/{:.1f}MB | {} '.format( percent * 100, bar_str, now_size / 1048576, total_size / 1048576, file_name), end='') if total_size == now_size: print('') # 下载完成换行