Optimize Progress Bar, again...
Fix "Changing Destination Path" bug, provided by YXRain05
This commit is contained in:
parent
f0ce51e87d
commit
dded74a4a9
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ settings.json
|
|||||||
venv/
|
venv/
|
||||||
venv_win/
|
venv_win/
|
||||||
test/
|
test/
|
||||||
|
modules/test/
|
@ -212,7 +212,10 @@ def get_lyric_from_folder(self):
|
|||||||
while True:
|
while True:
|
||||||
print(f"\n发现{len(ncm_files)}个ncm加密文件!")
|
print(f"\n发现{len(ncm_files)}个ncm加密文件!")
|
||||||
print("请问解密后的文件保存在哪里?\n"
|
print("请问解密后的文件保存在哪里?\n"
|
||||||
"[1] 保存在相同文件夹内\n[2] 保存在程序设定的下载文件夹中\n[3] 保存在自定义文件夹内\n[q] 取消解密,下载歌词时将忽略这些文件")
|
"[1] 保存在相同文件夹内\n"
|
||||||
|
"[2] 保存在程序设定的下载文件夹中\n"
|
||||||
|
"[3] 保存在自定义文件夹内\n"
|
||||||
|
"[q] 取消解密,下载歌词时将忽略这些文件")
|
||||||
select = rinput("请选择: ")
|
select = rinput("请选择: ")
|
||||||
if select == 'q':
|
if select == 'q':
|
||||||
target_path = "NOT_DECRYPT"
|
target_path = "NOT_DECRYPT"
|
||||||
@ -237,11 +240,11 @@ def get_lyric_from_folder(self):
|
|||||||
current_process = 0 # 当前正在活动的进程数
|
current_process = 0 # 当前正在活动的进程数
|
||||||
passed = 0 # 总共结束的进程数
|
passed = 0 # 总共结束的进程数
|
||||||
with CompactBar(f"正在破解 %(index){len(str(len(ncm_files)))}d/%(max)d",
|
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)
|
total = len(ncm_files)
|
||||||
allocated = 0 # 已经分配的任务数量
|
allocated = 0 # 已经分配的任务数量
|
||||||
while True: # 进入循环,执行 新建进程->检测队列->检测任务完成 的循环
|
while True: # 进入循环,执行 新建进程->检测队列->检测任务完成 的循环
|
||||||
sleep(0)
|
sleep(0.05)
|
||||||
if current_process <= max_process and allocated < total: # 分配进程
|
if current_process <= max_process and allocated < total: # 分配进程
|
||||||
Process(target=process_work,
|
Process(target=process_work,
|
||||||
args=(os.path.join(path, ncm_files[allocated]),
|
args=(os.path.join(path, ncm_files[allocated]),
|
||||||
@ -249,9 +252,9 @@ def get_lyric_from_folder(self):
|
|||||||
target_path,
|
target_path,
|
||||||
q_err,
|
q_err,
|
||||||
q_info)).start()
|
q_info)).start()
|
||||||
|
bar.print_onto_bar("已分配: %s" % ncm_files[allocated])
|
||||||
allocated += 1
|
allocated += 1
|
||||||
current_process += 1
|
current_process += 1
|
||||||
bar.update()
|
|
||||||
while True: # 错误队列检测
|
while True: # 错误队列检测
|
||||||
try:
|
try:
|
||||||
errors.append(q_err.get_nowait())
|
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"]})
|
musics.append({"id": r['musicId'], "name": r["musicName"], "artists": r["artist"]})
|
||||||
passed += 1
|
passed += 1
|
||||||
current_process -= 1
|
current_process -= 1
|
||||||
bar.print_onto_bar(f"已完成: {r['musicName']} - "
|
bar.print_onto_bar(f"\"{r['musicName']} - "
|
||||||
f"{''.join([x + ', ' for x in [x[0] for x in r['artist']]])[:-2]}")
|
f"{''.join([x + ', ' for x in [x[0] for x in r['artist']]])[:-2]}"
|
||||||
|
"\" 已完成!")
|
||||||
bar.next()
|
bar.next()
|
||||||
except Empty:
|
except Empty:
|
||||||
break
|
break
|
||||||
|
@ -84,6 +84,10 @@ def __set_lyric_path(self):
|
|||||||
if r[-1] != "/":
|
if r[-1] != "/":
|
||||||
r += "/"
|
r += "/"
|
||||||
path = ""
|
path = ""
|
||||||
|
for i in r.split("/"):
|
||||||
|
if len(i) >= 30:
|
||||||
|
input("抱歉, 目标或子目录名过长!至多30字符\n问题的目录: %s" % i)
|
||||||
|
return
|
||||||
for i in r.split("/"):
|
for i in r.split("/"):
|
||||||
path += i+"/"
|
path += i+"/"
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
|
@ -2,17 +2,68 @@
|
|||||||
from os import get_terminal_size
|
from os import get_terminal_size
|
||||||
|
|
||||||
from progress.bar import Bar
|
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):
|
class CompactBar(Bar):
|
||||||
def print_onto_bar(self, message: str):
|
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) * ' '}"
|
print(f"\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))])
|
# 光标移动到该行的首部(\x1b[nD, n为前移个数),将需要的信息打印出来,再将光标移动到下一行 ↓
|
||||||
self.update()
|
f"\x1b[{get_terminal_size().columns}D" + message)
|
||||||
|
self.update() # 更新进度条
|
||||||
|
|
||||||
def next_without_newline(self):
|
def writeln(self, line, shorten=False):
|
||||||
self.next()
|
"""覆写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):
|
def get_more_length(content):
|
||||||
"""将相对于正常长度的超出值返回"""
|
"""将相对于正常长度的超出值返回"""
|
||||||
return (len(content.encode("utf-8")) - len(content)) // 2
|
return (len(content.encode("utf-8")) - len(content)) // 2
|
||||||
|
|
||||||
|
|
||||||
|
def len_abs(content):
|
||||||
|
"""针对中文:将一个汉字识别为2个长度,而不是1个"""
|
||||||
|
return len(content) + get_more_length(content)
|
||||||
|
Loading…
Reference in New Issue
Block a user