增加软件管理实用程序与音频缓存机制修复

This commit is contained in:
2025-09-10 23:27:02 +08:00
parent 6293b69ef0
commit bb99b0a0b7
8 changed files with 277 additions and 15 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.devflag
.vscode
.directory
__pycache__/

View File

@@ -1,2 +1,5 @@
# for Android/Termux
import os
def playsound(p):
os.system(f"play-audio '{p}'")
print(p)

View File

@@ -4,6 +4,7 @@ import toml
import typing
from playsound import playsound
import threading
import hashlib
import edge_tts as tts
class ConfigFile:
@@ -61,3 +62,6 @@ def get_daystamp() -> int:
return int(time_override)
return int(time.time() // (24 * 3600))
def get_md5(text):
return hashlib.md5(text.encode('utf-8')).hexdigest()

View File

@@ -178,6 +178,8 @@ class NucleonUnion:
all = toml.load(f)
lst = list()
for i in all.keys():
if "attr" in i:
continue
if "data" in i:
continue
lst.append(Nucleon(i, all[i]))

View File

@@ -1,18 +1,20 @@
# 音频预缓存实用程序, 独立于主程序之外, 但依赖 particles 组件
# 音频预缓存实用程序, 独立于主程序之外, 但依赖其他组件
import particles as pt
import auxiliary as aux
import edge_tts as tts
from pathlib import Path
import shutil
import time
def precache(text: str):
"""预缓存单个文本的音频"""
cache_dir = Path("./cache/voice/")
cache_dir.mkdir(parents=True, exist_ok=True)
cache = cache_dir / f"{text}.wav"
cache = cache_dir / f"{aux.get_md5(text)}.wav"
if not cache.exists():
communicate = tts.Communicate(text, "zh-CN-XiaoxiaoNeural")
communicate.save_sync(f"./cache/voice/{text}.wav")
communicate.save_sync(f"./cache/voice/{aux.get_md5(text)}.wav")
def proc_file(path: Path):
@@ -29,14 +31,17 @@ def walk(path_str: str):
"""遍历目录处理所有文件"""
path = Path(path_str)
print(f"正在遍历目录: {path}")
for item in path.iterdir():
if item.is_file() and item.suffix == ".toml":
print(f"正预缓存文件: {item.name}")
proc_file(item)
elif item.is_dir():
print(f"进入目录: {item.name}")
try:
for item in path.iterdir():
if item.is_file() and item.suffix == ".toml":
print(f"正预缓存文件: {item.name}")
proc_file(item)
elif item.is_dir():
print(f"进入目录: {item.name}")
except:
print("发生一个异常, 于 5 秒后自动重新下载")
time.sleep(5)
walk(path_str)
if __name__ == "__main__":
print("音频预缓存实用程序")

View File

@@ -111,14 +111,14 @@ class MemScreen(Screen):
def play():
cache_dir = pathlib.Path(f"./cache/voice/")
cache_dir.mkdir(parents=True, exist_ok=True)
cache = cache_dir / f"{self.reactor.current_atom[1].content.replace('/','')}.wav"
cache = cache_dir / f"{aux.get_md5(self.reactor.current_atom[1].content.replace('/',''))}.wav"
if not cache.exists():
communicate = tts.Communicate(
self.reactor.current_atom[1].content.replace("/", ""),
"zh-CN-XiaoxiaoNeural",
)
communicate.save_sync(
f"./cache/voice/{self.reactor.current_atom[1].content.replace('/','')}.wav"
f"./cache/voice/{aux.get_md5(self.reactor.current_atom[1].content.replace('/',''))}.wav"
)
playsound(str(cache))

247
tweak.py Normal file
View File

@@ -0,0 +1,247 @@
import os
import shutil
import subprocess
import sys
def check_dev_flag():
"""检查是否存在开发标志文件,如果存在则退出程序"""
script_dir = os.path.dirname(os.path.abspath(__file__))
dev_flag_path = os.path.join(script_dir, '.devflag')
if os.path.exists(dev_flag_path):
print("检测到开发标志文件 (.devflag),不得运行此程序")
sys.exit(0)
def main():
# 检查开发标志文件
check_dev_flag()
# 输出标题
print("HeurAMS 更新 & 数据管理工具")
print("君欲何为?")
print("\nR: 全新安装 HeurAMS (删除 nucleon 与 electron 的用户数据, 并从上游同步软件更新)")
print("F: 翻新 HeurAMS (保留 nucleon 与 electron 的用户数据, 并从上游同步软件更新)")
print("U: 卸载 HeurAMS (删除 HeurAMS 程序文件, 保留用户数据)")
print("P: 应用 Termux 音频补丁")
# 获取用户输入
choice = input("\n请输入选择 (R/F/U/P): ").strip().lower()
# 获取脚本所在目录
script_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(script_dir)
if choice == 'r':
# 检查开发标志文件(再次检查,防止在运行时创建)
check_dev_flag()
# 全新安装 - 删除所有文件和文件夹(包括.git
print("正在执行全新安装...")
# 遍历当前目录下的所有文件和文件夹
for item in os.listdir('.'):
# 跳过脚本自身(如果存在)和开发标志文件
if item == os.path.basename(__file__) or item == '.devflag':
continue
item_path = os.path.join(script_dir, item)
try:
if os.path.isfile(item_path) or os.path.islink(item_path):
os.remove(item_path)
elif os.path.isdir(item_path):
shutil.rmtree(item_path)
except Exception as e:
print(f"删除 {item} 时出错: {e}")
# 执行git clone到临时目录然后移动文件
try:
temp_dir = os.path.join(script_dir, 'temp_clone')
subprocess.run(['git', 'clone', 'https://gitea.imwangzhiyu.xyz/ajax/HeurAMS', temp_dir], check=True)
# 移动所有文件到当前目录(除了.git目录
for item in os.listdir(temp_dir):
if item != '.git':
src = os.path.join(temp_dir, item)
dst = os.path.join(script_dir, item)
if os.path.exists(dst):
if os.path.isdir(dst):
shutil.rmtree(dst)
else:
os.remove(dst)
shutil.move(src, dst)
# 删除临时目录
shutil.rmtree(temp_dir)
print("全新安装完成!")
except subprocess.CalledProcessError as e:
print(f"Git clone 失败: {e}")
except Exception as e:
print(f"文件操作失败: {e}")
elif choice == 'f':
# 检查开发标志文件(再次检查,防止在运行时创建)
check_dev_flag()
# 翻新安装 - 保留特定目录
print("正在执行翻新安装...")
# 需要保留的目录列表
preserve_dirs = ['nucleon', 'electron', 'cache']
# 备份需要保留的目录到临时位置
backup_dir = os.path.join(script_dir, 'temp_backup')
os.makedirs(backup_dir, exist_ok=True)
for dir_name in preserve_dirs:
dir_path = os.path.join(script_dir, dir_name)
if os.path.exists(dir_path):
backup_path = os.path.join(backup_dir, dir_name)
if os.path.exists(backup_path):
shutil.rmtree(backup_path)
shutil.copytree(dir_path, backup_path)
# 删除所有文件和文件夹(包括.git
for item in os.listdir('.'):
# 跳过脚本自身、备份目录和开发标志文件
if item == os.path.basename(__file__) or item == 'temp_backup' or item == '.devflag':
continue
item_path = os.path.join(script_dir, item)
try:
if os.path.isfile(item_path) or os.path.islink(item_path):
os.remove(item_path)
elif os.path.isdir(item_path):
shutil.rmtree(item_path)
except Exception as e:
print(f"删除 {item} 时出错: {e}")
# 执行git clone到当前目录
try:
temp_dir = os.path.join(script_dir, 'temp_clone')
subprocess.run(['git', 'clone', 'https://gitea.imwangzhiyu.xyz/ajax/HeurAMS', temp_dir], check=True)
# 移动所有文件到当前目录(除了.git目录
for item in os.listdir(temp_dir):
if item != '.git':
src = os.path.join(temp_dir, item)
dst = os.path.join(script_dir, item)
if os.path.exists(dst):
if os.path.isdir(dst):
shutil.rmtree(dst)
else:
os.remove(dst)
shutil.move(src, dst)
# 删除临时克隆目录
shutil.rmtree(temp_dir)
# 恢复保留的目录覆盖git仓库中的同名目录
for dir_name in preserve_dirs:
backup_path = os.path.join(backup_dir, dir_name)
if os.path.exists(backup_path):
target_path = os.path.join(script_dir, dir_name)
if os.path.exists(target_path):
shutil.rmtree(target_path)
shutil.copytree(backup_path, target_path)
# 删除备份目录
shutil.rmtree(backup_dir)
print("翻新安装完成!")
except subprocess.CalledProcessError as e:
print(f"Git clone 失败: {e}")
except Exception as e:
print(f"文件操作失败: {e}")
elif choice == 'u':
# 检查开发标志文件(再次检查,防止在运行时创建)
check_dev_flag()
# 卸载 HeurAMS - 删除程序文件,保留用户数据
print("正在卸载 HeurAMS保留用户数据...")
# 需要保留的用户数据目录列表
preserve_dirs = ['nucleon', 'electron', 'cache']
# 备份需要保留的目录到临时位置
backup_dir = os.path.join(script_dir, 'temp_backup')
os.makedirs(backup_dir, exist_ok=True)
for dir_name in preserve_dirs:
dir_path = os.path.join(script_dir, dir_name)
if os.path.exists(dir_path):
backup_path = os.path.join(backup_dir, dir_name)
if os.path.exists(backup_path):
shutil.rmtree(backup_path)
shutil.copytree(dir_path, backup_path)
print(f"已备份用户数据: {dir_name}")
# 删除所有文件和文件夹(除了脚本自身、备份目录和开发标志文件)
for item in os.listdir('.'):
# 跳过脚本自身、备份目录和开发标志文件
if item == os.path.basename(__file__) or item == 'temp_backup' or item == '.devflag':
continue
item_path = os.path.join(script_dir, item)
try:
if os.path.isfile(item_path) or os.path.islink(item_path):
os.remove(item_path)
print(f"已删除文件: {item}")
elif os.path.isdir(item_path):
shutil.rmtree(item_path)
print(f"已删除目录: {item}")
except Exception as e:
print(f"删除 {item} 时出错: {e}")
# 恢复保留的用户数据目录
for dir_name in preserve_dirs:
backup_path = os.path.join(backup_dir, dir_name)
if os.path.exists(backup_path):
target_path = os.path.join(script_dir, dir_name)
if os.path.exists(target_path):
shutil.rmtree(target_path)
shutil.copytree(backup_path, target_path)
print(f"已恢复用户数据: {dir_name}")
# 删除备份目录
shutil.rmtree(backup_dir)
print("卸载完成HeurAMS 程序文件已删除,用户数据已保留。")
elif choice == 'p':
# 应用 Termux 音频补丁
print("应用 Termux 音频补丁")
# 询问用户是否使用安卓Termux环境
termux_choice = input("是否使用安卓Termux环境? (y/n): ").strip().lower()
if termux_choice in ['y', 'yes']:
# 创建playsound.py文件
playsound_content = '''import os
def playsound(path):
os.system(f"play-audio '{path}'")
'''
playsound_path = os.path.join(script_dir, 'playsound.py')
try:
with open(playsound_path, 'w', encoding='utf-8') as f:
f.write(playsound_content)
print("已创建 playsound.py 文件")
print("Termux 音频补丁应用成功!")
print("现在可以使用 play-audio 命令播放音频了。")
except Exception as e:
print(f"创建 playsound.py 文件时出错: {e}")
else:
print("已取消应用 Termux 音频补丁。")
else:
print("无效的选择,请输入 R、F、U 或 P。")
sys.exit(1)
if __name__ == "__main__":
main()