Optimize Progress Bar, again...
Fix "Changing Destination Path" bug, provided by YXRain05
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -4,3 +4,4 @@ settings.json | ||||
| venv/ | ||||
| venv_win/ | ||||
| test/ | ||||
| modules/test/ | ||||
| @@ -212,7 +212,10 @@ def get_lyric_from_folder(self): | ||||
|         while True: | ||||
|             print(f"\n发现{len(ncm_files)}个ncm加密文件!") | ||||
|             print("请问解密后的文件保存在哪里?\n" | ||||
|                   "[1] 保存在相同文件夹内\n[2] 保存在程序设定的下载文件夹中\n[3] 保存在自定义文件夹内\n[q] 取消解密,下载歌词时将忽略这些文件") | ||||
|                   "[1] 保存在相同文件夹内\n" | ||||
|                   "[2] 保存在程序设定的下载文件夹中\n" | ||||
|                   "[3] 保存在自定义文件夹内\n" | ||||
|                   "[q] 取消解密,下载歌词时将忽略这些文件") | ||||
|             select = rinput("请选择: ") | ||||
|             if select == 'q': | ||||
|                 target_path = "NOT_DECRYPT" | ||||
| @@ -237,11 +240,11 @@ def get_lyric_from_folder(self): | ||||
|             current_process = 0  # 当前正在活动的进程数 | ||||
|             passed = 0  # 总共结束的进程数 | ||||
|             with CompactBar(f"正在破解 %(index){len(str(len(ncm_files)))}d/%(max)d", | ||||
|                             suffix="", max=len(ncm_files), color="blue") as bar: | ||||
|                             suffix="", max=len(ncm_files), color="blue", width=9999) as bar: | ||||
|                 total = len(ncm_files) | ||||
|                 allocated = 0  # 已经分配的任务数量 | ||||
|                 while True:  # 进入循环,执行  新建进程->检测队列->检测任务完成  的循环 | ||||
|                     sleep(0) | ||||
|                     sleep(0.05) | ||||
|                     if current_process <= max_process and allocated < total:  # 分配进程 | ||||
|                         Process(target=process_work, | ||||
|                                 args=(os.path.join(path, ncm_files[allocated]), | ||||
| @@ -249,9 +252,9 @@ def get_lyric_from_folder(self): | ||||
|                                       target_path, | ||||
|                                       q_err, | ||||
|                                       q_info)).start() | ||||
|                         bar.print_onto_bar("已分配: %s" % ncm_files[allocated]) | ||||
|                         allocated += 1 | ||||
|                         current_process += 1 | ||||
|                         bar.update() | ||||
|                     while True:  # 错误队列检测 | ||||
|                         try: | ||||
|                             errors.append(q_err.get_nowait()) | ||||
| @@ -267,8 +270,9 @@ def get_lyric_from_folder(self): | ||||
|                             musics.append({"id": r['musicId'], "name": r["musicName"], "artists": r["artist"]}) | ||||
|                             passed += 1 | ||||
|                             current_process -= 1 | ||||
|                             bar.print_onto_bar(f"已完成: {r['musicName']} - " | ||||
|                                                f"{''.join([x + ', ' for x in [x[0] for x in r['artist']]])[:-2]}") | ||||
|                             bar.print_onto_bar(f"\"{r['musicName']} - " | ||||
|                                                f"{''.join([x + ', ' for x in [x[0] for x in r['artist']]])[:-2]}" | ||||
|                                                "\" 已完成!") | ||||
|                             bar.next() | ||||
|                         except Empty: | ||||
|                             break | ||||
|   | ||||
| @@ -84,6 +84,10 @@ def __set_lyric_path(self): | ||||
|     if r[-1] != "/": | ||||
|         r += "/" | ||||
|     path = "" | ||||
|     for i in r.split("/"): | ||||
|         if len(i) >= 30: | ||||
|             input("抱歉, 目标或子目录名过长!至多30字符\n问题的目录: %s" % i) | ||||
|             return | ||||
|     for i in r.split("/"): | ||||
|         path += i+"/" | ||||
|         if not os.path.exists(path): | ||||
|   | ||||
| @@ -2,17 +2,68 @@ | ||||
| from os import get_terminal_size | ||||
|  | ||||
| from progress.bar import Bar | ||||
| from progress.colors import color | ||||
|  | ||||
| from modules.utils.length import get_more_length | ||||
| from modules.utils.length import get_more_length, len_abs | ||||
|  | ||||
|  | ||||
| class CompactBar(Bar): | ||||
|     def print_onto_bar(self, message: str): | ||||
|         print() | ||||
|         self.update() | ||||
|         print(f"\x1b[1A\x1b[{get_terminal_size().columns}D{(get_terminal_size().columns-1) * ' '}" | ||||
|               f"\x1b[{get_terminal_size().columns}D"+message[:(get_terminal_size().columns - get_more_length(message))]) | ||||
|         self.update() | ||||
|         """在进度条的上方打印消息,进度条保持在下方""" | ||||
|         # 光标移动到行首,并通过打印空格清空残留的进度条 ↓ | ||||
|         print(f"\x1b[{get_terminal_size().columns}D{(get_terminal_size().columns - 1) * ' '}" | ||||
|               # 光标移动到该行的首部(\x1b[nD, n为前移个数),将需要的信息打印出来,再将光标移动到下一行 ↓ | ||||
|               f"\x1b[{get_terminal_size().columns}D" + message) | ||||
|         self.update()  # 更新进度条 | ||||
|  | ||||
|     def next_without_newline(self): | ||||
|         self.next() | ||||
|     def writeln(self, line, shorten=False): | ||||
|         """覆写writeln配合修改过后的update""" | ||||
|         if self.file and self.is_tty(): | ||||
|             width = len_abs(line) | ||||
|             if shorten: | ||||
|                 self._max_width = shorten | ||||
|             elif width < self._max_width: | ||||
|                 # Add padding to cover previous contents | ||||
|                 line += ' ' * (self._max_width - width) | ||||
|             else: | ||||
|                 self._max_width = width | ||||
|             print('\r' + line, end='', file=self.file) | ||||
|             self.file.flush() | ||||
|  | ||||
|     def update(self): | ||||
|         """ | ||||
|         覆写原有的update方法,自适应终端宽度 | ||||
|         支持中文 | ||||
|         """ | ||||
|         filled_length = int(self.width * self.progress) | ||||
|         empty_length = self.width - filled_length | ||||
|  | ||||
|         message = self.message % self | ||||
|         bar = color(self.fill * filled_length, fg=self.color) | ||||
|         empty = self.empty_fill * empty_length | ||||
|         suffix = self.suffix % self | ||||
|         line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix, | ||||
|                         suffix]) | ||||
|         # 以上为原本update代码 | ||||
|         term_size = get_terminal_size().columns | ||||
|         shorten = False | ||||
|         if len_abs(line) > term_size:  # 检测完整长度是否小于终端长度 | ||||
|             if len_abs(line) - len_abs(''.join([bar, empty])) <= term_size:  # 检测无进度条时是否小于终端长度 | ||||
|                 width = term_size - (len_abs(line) - len_abs("".join([bar, empty]))) - 1 | ||||
|                 filled_length = int(width * self.progress) | ||||
|                 empty_length = width - filled_length | ||||
|                 bar = color(self.fill * filled_length, fg=self.color) | ||||
|                 empty = self.empty_fill * empty_length | ||||
|                 line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix, | ||||
|                                 suffix]) | ||||
|                 shorten = len_abs(line) | ||||
|             elif len_abs(''.join([message, suffix])) <= term_size:  # 检测仅有前缀后缀时是否小于终端长度 | ||||
|                 line = ''.join([message, suffix]) | ||||
|                 shorten = len_abs(line) | ||||
|             else:  # 全部不符合时,以仅有前缀后缀的模式,直接截断 | ||||
|                 display_length = term_size-get_more_length(''.join([message, suffix])[:term_size])-3 | ||||
|                 if display_length < 0: | ||||
|                     display_length = 0 | ||||
|                 line = ''.join([message, suffix])[:display_length]+"..." | ||||
|                 shorten = len_abs(line) | ||||
|         self.writeln(line, shorten=shorten) | ||||
|   | ||||
| @@ -1,12 +1,11 @@ | ||||
| """一些有关计算长度的工具""" | ||||
|  | ||||
|  | ||||
| def len_abs(content): | ||||
|     """针对中文:将一个汉字识别为2个长度,而不是1个""" | ||||
|  | ||||
|     return len(content) + (len(content.encode("utf-8")) - len(content)) // 2 | ||||
|  | ||||
|  | ||||
| def get_more_length(content): | ||||
|     """将相对于正常长度的超出值返回""" | ||||
|     return (len(content.encode("utf-8")) - len(content)) // 2 | ||||
|  | ||||
|  | ||||
| def len_abs(content): | ||||
|     """针对中文:将一个汉字识别为2个长度,而不是1个""" | ||||
|     return len(content) + get_more_length(content) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user