fix: 完善
This commit is contained in:
@@ -26,4 +26,13 @@ min_denominator = 3
|
|||||||
nucleon_dir = "./data/nucleon"
|
nucleon_dir = "./data/nucleon"
|
||||||
electron_dir = "./data/electron"
|
electron_dir = "./data/electron"
|
||||||
orbital_dir = "./data/orbital"
|
orbital_dir = "./data/orbital"
|
||||||
cache_dir = "./data/cache"
|
cache_dir = "./data/cache"
|
||||||
|
|
||||||
|
[services] # 定义服务到提供者的映射
|
||||||
|
audio = "playsound" # 可选项: playsound(通用), termux(仅用于支持 Android Termux), mpg123(TODO)
|
||||||
|
tts = "edgetts" # 可选项: edgetts
|
||||||
|
llm = "openai" # 可选项: openai
|
||||||
|
|
||||||
|
[providers.llm.openai] # 与 OpenAI 相容的语言模型接口服务设置
|
||||||
|
url = ""
|
||||||
|
key = ""
|
||||||
@@ -3,7 +3,7 @@ from heurams.context import rootdir, workdir, config_var
|
|||||||
from textual.app import App
|
from textual.app import App
|
||||||
from textual.widgets import Button
|
from textual.widgets import Button
|
||||||
from .screens.dashboard import DashboardScreen
|
from .screens.dashboard import DashboardScreen
|
||||||
from .screens.nucleon_creator import NucleonCreatorScreen
|
from .screens.nucreator import NucleonCreatorScreen
|
||||||
from .screens.precache import PrecachingScreen
|
from .screens.precache import PrecachingScreen
|
||||||
|
|
||||||
class HeurAMSApp(App):
|
class HeurAMSApp(App):
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ class DashboardScreen(Screen):
|
|||||||
def on_button_pressed(self, event) -> None:
|
def on_button_pressed(self, event) -> None:
|
||||||
if event.button.id == "new_nucleon_button":
|
if event.button.id == "new_nucleon_button":
|
||||||
# 切换到创建单元
|
# 切换到创建单元
|
||||||
from .nucleon_creator import NucleonCreatorScreen
|
from .nucreator import NucleonCreatorScreen
|
||||||
newscr = NucleonCreatorScreen()
|
newscr = NucleonCreatorScreen()
|
||||||
self.app.push_screen(newscr)
|
self.app.push_screen(newscr)
|
||||||
elif event.button.id == "precache_all_button":
|
elif event.button.id == "precache_all_button":
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class AtomState(Enum):
|
|||||||
class MemScreen(Screen):
|
class MemScreen(Screen):
|
||||||
BINDINGS = [
|
BINDINGS = [
|
||||||
("q", "pop_screen", "返回"),
|
("q", "pop_screen", "返回"),
|
||||||
#("p", "prev", "上一个"),
|
("p", "prev", "复习上一个"),
|
||||||
("d", "toggle_dark", "改变色调"),
|
("d", "toggle_dark", "改变色调"),
|
||||||
("v", "play_voice", "朗读"),
|
("v", "play_voice", "朗读"),
|
||||||
]
|
]
|
||||||
@@ -58,6 +58,7 @@ class MemScreen(Screen):
|
|||||||
|
|
||||||
def on_button_pressed(self, event):
|
def on_button_pressed(self, event):
|
||||||
event.stop()
|
event.stop()
|
||||||
|
if
|
||||||
|
|
||||||
def action_play_voice(self):
|
def action_play_voice(self):
|
||||||
"""朗读当前内容"""
|
"""朗读当前内容"""
|
||||||
|
|||||||
@@ -12,8 +12,10 @@ from textual.widgets import (
|
|||||||
from textual.containers import Container
|
from textual.containers import Container
|
||||||
from textual.screen import Screen
|
from textual.screen import Screen
|
||||||
|
|
||||||
|
from heurams.services.version import ver
|
||||||
|
|
||||||
class NucleonCreatorScreen(Screen):
|
class NucleonCreatorScreen(Screen):
|
||||||
BINDINGS = [("q", "go_back", "返回"), ("escape", "quit_app", "退出")]
|
BINDINGS = [("q", "go_back", "返回")]
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(name=None, id=None, classes=None)
|
super().__init__(name=None, id=None, classes=None)
|
||||||
@@ -21,30 +23,34 @@ class NucleonCreatorScreen(Screen):
|
|||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Header(show_clock=True)
|
yield Header(show_clock=True)
|
||||||
with Container(id="vice_container"):
|
with Container(id="vice_container"):
|
||||||
yield Label(f"[b]新建空的单元集\n")
|
yield Label(f"[b]空白单元集创建向导\n")
|
||||||
|
yield Markdown("> 提示: 你可能注意到当选中文本框时底栏和操作按键绑定将被覆盖 \n只需选中(使用鼠标或 Tab)选择框即可恢复底栏功能")
|
||||||
yield Markdown("1. 键入单元集名称")
|
yield Markdown("1. 键入单元集名称")
|
||||||
yield Input(placeholder="单元集名称")
|
yield Input(placeholder="单元集名称")
|
||||||
yield Markdown("> 单元集名称不应与现有单元集重复, 新的单元集文件将创建在 ./nucleon/你输入的名称.toml")
|
yield Markdown("> 单元集名称不应与现有单元集重复. \n> 新的单元集文件将创建在 ./nucleon/你输入的名称.toml")
|
||||||
yield Label(f"\n")
|
yield Label(f"\n")
|
||||||
yield Markdown("2. 选择单元集类型")
|
yield Markdown("2. 选择单元集模板")
|
||||||
LINES = """
|
LINES = f"""带有宏支持的空白单元集 ({ver})
|
||||||
单一字符串
|
古诗词模板单元集 ({ver})
|
||||||
主字符串(带有附加属性)
|
英语词汇和短语模板单元集 ({ver})
|
||||||
动态单元集(使用宏)
|
|
||||||
""".splitlines()
|
""".splitlines()
|
||||||
yield Select.from_values(LINES, prompt="选择类型")
|
yield Select.from_values(LINES, prompt="选择类型")
|
||||||
|
yield Markdown("> 新单元集的版本号将和主程序版本保持同步")
|
||||||
yield Label(f"\n")
|
yield Label(f"\n")
|
||||||
yield Markdown("3. 输入附加元数据 (可选)")
|
yield Markdown("3. 输入常见附加元数据 (可选)")
|
||||||
yield Input(placeholder="作者")
|
yield Input(placeholder="作者")
|
||||||
yield Input(placeholder="内容描述")
|
yield Input(placeholder="内容描述")
|
||||||
yield Button(
|
yield Button(
|
||||||
"新建空单元集",
|
"新建空白单元集",
|
||||||
id="submit_button",
|
id="submit_button",
|
||||||
variant="primary",
|
variant="primary",
|
||||||
classes="start-button",
|
classes="start-button",
|
||||||
)
|
)
|
||||||
yield Footer()
|
yield Footer()
|
||||||
|
|
||||||
|
def on_mount(self):
|
||||||
|
self.query_one("#submit_button").focus()
|
||||||
|
|
||||||
def action_go_back(self):
|
def action_go_back(self):
|
||||||
self.app.pop_screen()
|
self.app.pop_screen()
|
||||||
|
|
||||||
@@ -177,26 +177,16 @@ class PrecachingScreen(Screen):
|
|||||||
nu = list()
|
nu = list()
|
||||||
for file in nucleon_files:
|
for file in nucleon_files:
|
||||||
try:
|
try:
|
||||||
nu += pt.load_nucleon(file)[0]
|
for i in pt.load_nucleon(file):
|
||||||
self.total = len(nu)
|
nu.append(i[0])
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
|
self.total = len(nu)
|
||||||
self.processed = 0
|
for i in nu:
|
||||||
self.is_precaching = True
|
i: pt.Nucleon
|
||||||
|
i.do_eval()
|
||||||
for file in nucleon_files:
|
return self.precache_by_list(nu)
|
||||||
try:
|
|
||||||
nu += pt.load_nucleon(file)[0]
|
|
||||||
if not self.precache_by_list(nu):
|
|
||||||
break # 用户取消
|
|
||||||
except Exception as e:
|
|
||||||
print(f"处理文件失败 {file}: {e}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.is_precaching = False
|
|
||||||
self.update_status("完成", "所有单元的音频已被预缓存", 100)
|
|
||||||
|
|
||||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||||
event.stop()
|
event.stop()
|
||||||
if event.button.id == "start_precache" and not self.is_precaching:
|
if event.button.id == "start_precache" and not self.is_precaching:
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
# 音频播放器, 必须基于文件操作
|
# 音频播放器, 必须基于文件操作
|
||||||
from .termux_audio import player as termux_player
|
from . import termux_audio
|
||||||
|
from . import playsound_audio
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"termux_player"
|
"termux_audio",
|
||||||
|
"playsound_audio",
|
||||||
]
|
]
|
||||||
|
|
||||||
players = {
|
providers = {
|
||||||
"termux": termux_player
|
"termux": termux_audio,
|
||||||
|
"playsound": playsound_audio
|
||||||
}
|
}
|
||||||
@@ -2,3 +2,10 @@
|
|||||||
基于 playsound 库的音频播放器, 在绝大多数 python 环境上提供音频服务
|
基于 playsound 库的音频播放器, 在绝大多数 python 环境上提供音频服务
|
||||||
注意: 在未配置 pulseaudio 的 termux 不可用
|
注意: 在未配置 pulseaudio 的 termux 不可用
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
import playsound
|
||||||
|
|
||||||
|
def play_by_path(path: pathlib.Path):
|
||||||
|
playsound.playsound(str(path))
|
||||||
5
src/heurams/providers/audio/protocol.py
Normal file
5
src/heurams/providers/audio/protocol.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from typing import Protocol
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
class PlayFunctionProtocol(Protocol):
|
||||||
|
def __call__(self, path: pathlib.Path) -> None: ...
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
|
#from .protocol import PlayFunctionProtocol
|
||||||
|
|
||||||
def player(path: pathlib.Path):
|
def play_by_path(path: pathlib.Path):
|
||||||
os.system(f"play-audio {path}")
|
os.system(f"play-audio {path}")
|
||||||
@@ -6,7 +6,7 @@ __all__ = [
|
|||||||
"EdgeTTS",
|
"EdgeTTS",
|
||||||
]
|
]
|
||||||
|
|
||||||
TTSs = {
|
providers = {
|
||||||
"BaseTTS": BaseTTS,
|
"basetts": BaseTTS,
|
||||||
"EdgeTTS": EdgeTTS,
|
"edgetts": EdgeTTS,
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user