add small tools
This commit is contained in:
parent
c10bd094da
commit
620f030d5f
34
main.py
34
main.py
@ -15,6 +15,7 @@ from modules.submenus.settings import settings_menu
|
||||
from modules.functions.settings.save_load_settings import load_settings
|
||||
from modules.utils.clear_screen import cls_stay
|
||||
from modules.functions.mainly.load_file_song import get_lyric_from_folder
|
||||
from modules.submenus.tools import tools_menu
|
||||
|
||||
|
||||
class MainProcess(object):
|
||||
@ -31,25 +32,28 @@ class MainProcess(object):
|
||||
"1": "单个歌曲的歌词下载",
|
||||
"2": "多个歌曲的歌词下载",
|
||||
"3": "从网易云下载的歌曲中获取歌词",
|
||||
"t": "小工具",
|
||||
"s": "进入设置",
|
||||
"i": "程序信息",
|
||||
})
|
||||
r = rinput("请选择:")
|
||||
|
||||
if r == "1":
|
||||
download_one_lyric(self)
|
||||
elif r == "2":
|
||||
mdl(self)
|
||||
elif r == "3":
|
||||
get_lyric_from_folder(self)
|
||||
elif r == "0":
|
||||
exit(0)
|
||||
elif r == "i":
|
||||
print_info(self)
|
||||
elif r == "s":
|
||||
settings_menu(self)
|
||||
else:
|
||||
input("请输入正确的选项\n按回车键继续...")
|
||||
match r:
|
||||
case "1":
|
||||
download_one_lyric(self)
|
||||
case "2":
|
||||
mdl(self)
|
||||
case "3":
|
||||
get_lyric_from_folder(self)
|
||||
case "0":
|
||||
exit(0)
|
||||
case "t":
|
||||
tools_menu(self)
|
||||
case "i":
|
||||
print_info(self)
|
||||
case "s":
|
||||
settings_menu(self)
|
||||
case _:
|
||||
input("请输入正确的选项\n按回车键继续...")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -147,7 +147,7 @@ def get_lyric_from_folder(self):
|
||||
suffix="", max=len(ncm_files), color="green", width=9999) as bar:
|
||||
total = len(ncm_files)
|
||||
allocated = 0 # 已经分配的任务数量
|
||||
while True: # 进入循环,执行 新建进程->检测队列->检测任务完成 的循环
|
||||
while True: # 进入循环,执行 "新建进程->检测队列->检测任务完成" 的循环
|
||||
sleep(0.05)
|
||||
if current_process <= max_process and allocated < total: # 分配进程
|
||||
Process(target=process_work,
|
||||
@ -176,7 +176,7 @@ def get_lyric_from_folder(self):
|
||||
passed += 1
|
||||
current_process -= 1
|
||||
bar.print_onto_bar(Fore.YELLOW +
|
||||
f"\"{r['musicName']} - "
|
||||
f"\"{r['musicName']} by "
|
||||
f"{''.join([x + ', ' for x in [x[0] for x in r['artist']]])[:-2]}"
|
||||
"\"" + Fore.GREEN + " 已完成!")
|
||||
bar.next()
|
||||
|
@ -6,7 +6,6 @@ from modules.utils.inputs import rinput
|
||||
from modules.functions.mainly.get_song import get_song_lyric
|
||||
from modules.utils.bar import CompactArrowBar
|
||||
|
||||
|
||||
def mdl(self):
|
||||
"""多个歌词文件的下载
|
||||
|
||||
@ -34,7 +33,7 @@ def mdl(self):
|
||||
with CompactArrowBar(f"进度: %(index){len(str(len(ids)))}d/%(max)d",
|
||||
suffix="", max=len(ids), color="yellow", width=9999) as bar:
|
||||
for i in range(0, len(ids)):
|
||||
r = get_song_lyric(ids[i], self.settings.lyric_path, self.settings.lyric_path, bar=bar)
|
||||
r = get_song_lyric(ids[i], self.settings.lyric_path, self.settings.lyric_format, bar=bar)
|
||||
if r == "dl_err_connection":
|
||||
bar.print_onto_bar(Fore.RED + "下载发生错误!可能是连接被拒绝!请检查网络后再试\n按回车键继续任务(该任务会被跳过)...")
|
||||
input()
|
||||
|
3
modules/functions/mainly/multi_unlock.py
Normal file
3
modules/functions/mainly/multi_unlock.py
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
def mult_unlock(...)
|
@ -24,20 +24,21 @@ def settings_menu(self):
|
||||
"4": "部分动态效果",
|
||||
"s": "切换设置自动保存"
|
||||
})
|
||||
if r == "0":
|
||||
return
|
||||
elif r == "1":
|
||||
__set_lyric_path(self)
|
||||
elif r == "2":
|
||||
__remove_output_files(self)
|
||||
elif r == "3":
|
||||
__set_lyric_format(self)
|
||||
elif r == "4":
|
||||
pass
|
||||
elif r == "s":
|
||||
self.settings.auto_save = not self.settings.auto_save
|
||||
else:
|
||||
input("输入无效!按回车键继续...")
|
||||
match r:
|
||||
case "0":
|
||||
return
|
||||
case "1":
|
||||
__set_lyric_path(self)
|
||||
case "2":
|
||||
__remove_output_files(self)
|
||||
case "3":
|
||||
__set_lyric_format(self)
|
||||
case "4":
|
||||
pass
|
||||
case "s":
|
||||
self.settings.auto_save = not self.settings.auto_save
|
||||
case _:
|
||||
input("输入无效!按回车键继续...")
|
||||
|
||||
|
||||
def __remove_output_files(self):
|
||||
|
50
modules/submenus/tools.py
Normal file
50
modules/submenus/tools.py
Normal file
@ -0,0 +1,50 @@
|
||||
"""小工具以及菜单"""
|
||||
import os
|
||||
from colorama import Fore
|
||||
|
||||
from modules.utils.prints import print_menu
|
||||
from modules.utils.clear_screen import cls_stay
|
||||
from modules.utils.inputs import cinput
|
||||
from modules.functions.mainly.load_file_song import load_and_decrypt_from_ncm, process_work
|
||||
|
||||
|
||||
|
||||
def tools_menu(self):
|
||||
while True:
|
||||
cls_stay(self, "[小工具菜单]")
|
||||
print_menu({
|
||||
"0": "返回上级菜单",
|
||||
"d": "解锁指定ncm文件/指定文件夹"
|
||||
})
|
||||
r = cinput("请选择:")
|
||||
match r:
|
||||
case "0":
|
||||
return
|
||||
case "d":
|
||||
ncm_unlock(self)
|
||||
input("按回车继续...")
|
||||
case _:
|
||||
input("请输入正确的选项\n按回车键继续...")
|
||||
|
||||
|
||||
def ncm_unlock(self):
|
||||
cls_stay(self, "[小工具 - 文件解锁]")
|
||||
path = cinput("请输入绝对路径:").replace("\\","")
|
||||
if not os.path.exists(path): # 判断目标存在与否
|
||||
print("目标不存在!")
|
||||
return
|
||||
if os.path.isfile(path): # 目标为文件则执行单文件解密
|
||||
r = load_and_decrypt_from_ncm(path, os.path.split(path)[-1], "original", True)
|
||||
match r:
|
||||
case "file_not_found":
|
||||
print("文件未找到")
|
||||
case "perm_error":
|
||||
print("权限错误。请检查是否拥有对应权限或者文件是否被占用。")
|
||||
case _:
|
||||
print(f"解锁完毕!文件保存在:\n{Fore.GREEN}{r[-1]}")
|
||||
return
|
||||
elif os.path.isdir(path): # 目标为文件夹则执行文件夹遍历
|
||||
...
|
||||
else:
|
||||
print("无法识别目标文件。请确认目标文件是否正确以及是否拥有对应权限。")
|
||||
|
@ -8,6 +8,7 @@ from Cryptodome.Cipher import AES
|
||||
from Cryptodome.Util.Padding import unpad
|
||||
from Cryptodome.Util.strxor import strxor as xor
|
||||
from mutagen import mp3, flac, id3
|
||||
from modules.utils.wrappers import escape_file_not_found, escape_permission_error
|
||||
|
||||
|
||||
def regular_filename(filename):
|
||||
@ -28,7 +29,14 @@ def regular_filename(filename):
|
||||
return filename
|
||||
|
||||
|
||||
def load_and_decrypt_from_ncm(file_path, target_dir, out_format) -> dict | str: # author: Nzix Repo: nondanee
|
||||
@escape_file_not_found
|
||||
@escape_permission_error
|
||||
def load_and_decrypt_from_ncm(file_path, target_dir, out_format, return_output_path=False) -> dict | str | tuple:
|
||||
# Original author: Nzix Repo: nondanee
|
||||
"""解锁指定文件并按照规则保存在指定位置
|
||||
``file_path`` 源文件路径
|
||||
``target_dir`` 解锁后文件保存路径
|
||||
``out_format`` 输出文件格式,使用“字典”格式字符串,若使用源文件名仅替换后缀则传入\"original\""""
|
||||
|
||||
core_key = binascii.a2b_hex('687A4852416D736F356B496E62617857')
|
||||
meta_key = binascii.a2b_hex('2331346C6A6B5F215C5D2630553C2728')
|
||||
@ -89,7 +97,9 @@ def load_and_decrypt_from_ncm(file_path, target_dir, out_format) -> dict | str:
|
||||
f.seek(image_space - image_size, 1)
|
||||
|
||||
# media data
|
||||
if meta_length:
|
||||
if out_format == "original":
|
||||
output_path = f"{os.path.splitext(file_path)[0]}.{meta_data['format']}"
|
||||
elif meta_length:
|
||||
output_path = os.path.join(target_dir, regular_filename(out_format % {"name": meta_data["musicName"],
|
||||
"artists": "".join(
|
||||
[x[0]+"," for x in meta_data["artist"]]
|
||||
@ -145,6 +155,12 @@ def load_and_decrypt_from_ncm(file_path, target_dir, out_format) -> dict | str:
|
||||
audio['album'] = meta_data['album']
|
||||
audio['artist'] = '/'.join([artist[0] for artist in meta_data['artist']])
|
||||
audio.save()
|
||||
return meta_data
|
||||
if return_output_path:
|
||||
return meta_data, output_path
|
||||
else:
|
||||
return meta_data
|
||||
else:
|
||||
return "no_meta_data"
|
||||
if return_output_path:
|
||||
return "no_meta_data", output_path
|
||||
else:
|
||||
return "no_meta_data"
|
||||
|
28
modules/utils/wrappers.py
Normal file
28
modules/utils/wrappers.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""一些有的没有的装饰器"""
|
||||
|
||||
|
||||
def escape_file_not_found(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except FileNotFoundError:
|
||||
return "file_not_found"
|
||||
return wrapper
|
||||
|
||||
|
||||
def escape_decrypt_unsatisfied_file(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except (AssertionError, IsADirectoryError):
|
||||
return "file_not_satisfied"
|
||||
return wrapper
|
||||
|
||||
|
||||
def escape_permission_error(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except PermissionError:
|
||||
return "perm_error"
|
||||
return wrapper
|
Loading…
Reference in New Issue
Block a user