feat: 开发 unifront 前端会话模块
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
zmq_debug = false
|
zmq_debug = true
|
||||||
_zmq_debug_desc = "[调试] ZeroMQ 调试服务器, 这会在 zmq_debug_port 上打开一个服务器\n调试工具可远程在 HeurAMS 内执行任意 python 代码, 无必要请关闭"
|
_zmq_debug_desc = "[调试] ZeroMQ 调试服务器, 这会在 zmq_debug_port 上打开一个服务器\n调试工具可远程在 HeurAMS 内执行任意 python 代码, 无必要请关闭"
|
||||||
zmq_debug_port = 5555
|
zmq_debug_port = 5555
|
||||||
_zmq_debug_port_desc = "[调试] ZeroMQ 调试服务器端口"
|
_zmq_debug_port_desc = "[调试] ZeroMQ 调试服务器端口"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
_global_desc = "用户界面通用设置"
|
_global_desc = "用户界面通用设置"
|
||||||
_widgets_desc = "各组件设置"
|
_widgets_desc = "组件设置"
|
||||||
_screens_desc = "各界面设置"
|
_screens_desc = "界面设置"
|
||||||
_puzzles_desc = "谜题生成器设置"
|
_puzzles_desc = "谜题生成器设置"
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
show_header = true
|
||||||
|
_show_header_desc = "展示界面顶部的标题栏\n如果您想节省这一行空间, 可以禁用它"
|
||||||
|
clock_on_header = true
|
||||||
|
_clock_on_header_desc = "在界面顶部的标题栏显示时间"
|
||||||
|
change_window_title = true
|
||||||
|
_change_window_title_desc = "更改终端模拟器窗口的标题\n如果禁用了 header, 则建议启用"
|
||||||
persist_to_file = true
|
persist_to_file = true
|
||||||
_persist_to_file_desc = "[调试] 将记忆更改保存到文件"
|
_persist_to_file_desc = "[调试] 将记忆更改保存到文件"
|
||||||
quick_pass = true
|
quick_pass = true
|
||||||
@@ -5,13 +11,15 @@ _quick_pass_desc = "[调试] 启用快速应答功能(跳过测验)"
|
|||||||
auto_pass = false
|
auto_pass = false
|
||||||
_auto_pass_desc = "[调试] 自动通过测试模式"
|
_auto_pass_desc = "[调试] 自动通过测试模式"
|
||||||
scheduled_num = 420
|
scheduled_num = 420
|
||||||
_scheduled_num_desc = "默认记忆单元数量(可被单元集设置覆盖)"
|
_scheduled_num_desc = "默认记忆单元数量\n可被单元集设置覆盖"
|
||||||
|
refresh_on_resume = true
|
||||||
|
_refresh_on_resume_desc = "[调试] 每当 Screen 激活后都刷新状态"
|
||||||
algorithm = "SM-2"
|
algorithm = "SM-2"
|
||||||
_algorithm_desc = "默认记忆调度算法(可被单元集设置覆盖)"
|
_algorithm_desc = "默认记忆调度算法\n可被单元集设置覆盖"
|
||||||
|
|
||||||
[_algorithm_candidate]
|
[_algorithm_candidate]
|
||||||
NSP-0 = "筛选用非间隔重复调度器"
|
NSP-0 = "筛选用非间隔重复调度器"
|
||||||
none = "不设置默认调度器"
|
none = "不设置默认调度器"
|
||||||
SM-2 = "第二代 SuperMemo 简单间隔重复调度器"
|
SM-2 = "第二代 SuperMemo 简单间隔重复调度器\nWozniak 于 1987 年提出, Anki 的默认算法"
|
||||||
SM-15M = "第15代 SuperMemo 复杂间隔重复调度器 (不稳定且逆向工程)"
|
SM-15M = "类第15代 SuperMemo 复杂间隔重复调度器\n不稳定且逆向工程"
|
||||||
FSRS = "先进开放间隔重复调度器"
|
FSRS = "先进开放间隔重复调度器"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
schedule = ["quick_review", "recognition", "final_review"]
|
schedule = ["quick_review", "recognition", "final_review"]
|
||||||
|
|
||||||
[phases]
|
[routes]
|
||||||
quick_review = [["FillBlank", "1.0"], ["Recognition", "1.0"]]
|
quick_review = [["FillBlank", "1.0"], ["Recognition", "1.0"]]
|
||||||
recognition = [["FillBlank", "1.0"]]
|
recognition = [["FillBlank", "1.0"]]
|
||||||
final_review = [["FillBlank", "1.0"], ["Recognition", "1.0"]]
|
final_review = [["FillBlank", "1.0"], ["Recognition", "1.0"]]
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ from .screens.navigator import NavigatorScreen
|
|||||||
from .screens.precache import PrecachingScreen
|
from .screens.precache import PrecachingScreen
|
||||||
from .screens.setting import SettingScreen
|
from .screens.setting import SettingScreen
|
||||||
from .screens.synctool import SyncScreen
|
from .screens.synctool import SyncScreen
|
||||||
|
from . import shim
|
||||||
|
|
||||||
_end = perf_counter()
|
_end = perf_counter()
|
||||||
print(f"已完成! (耗时: {round(1000 * (_end - _start))}ms)")
|
print(f"已完成! (耗时: {round(1000 * (_end - _start))}ms)")
|
||||||
@@ -56,6 +57,9 @@ class HeurAMSApp(App):
|
|||||||
"setting": SettingScreen,
|
"setting": SettingScreen,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
self.push_screen("dashboard")
|
self.push_screen("dashboard")
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
.repo-list-item {
|
.repo-list-item {
|
||||||
layout: grid;
|
layout: grid;
|
||||||
grid-size: 2;
|
grid-size: 1;
|
||||||
height: 3;
|
height: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ from textual.containers import ScrollableContainer
|
|||||||
from textual.screen import Screen
|
from textual.screen import Screen
|
||||||
from textual.widgets import Button, Footer, Header, Label, Markdown, Static
|
from textual.widgets import Button, Footer, Header, Label, Markdown, Static
|
||||||
|
|
||||||
|
from textual import events, on
|
||||||
|
|
||||||
import heurams.services.version as version
|
import heurams.services.version as version
|
||||||
from heurams.context import *
|
from heurams.context import *
|
||||||
import platform
|
import platform
|
||||||
@@ -19,8 +21,19 @@ class AboutScreen(Screen):
|
|||||||
("q", "go_back", "返回"),
|
("q", "go_back", "返回"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@on(events.ScreenResume)
|
||||||
|
def post_active(self, event):
|
||||||
|
from heurams.interface import shim
|
||||||
|
|
||||||
|
shim.set_term_title(f"{self.app.TITLE} - {self.SUB_TITLE}")
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Header(show_clock=True)
|
|
||||||
|
if config_var.get()['interface']['global']['show_header']:
|
||||||
|
yield Header(show_clock=config_var.get()['interface']['global']['clock_on_header'])
|
||||||
with ScrollableContainer(id="about_container"):
|
with ScrollableContainer(id="about_container"):
|
||||||
yield Label("[b]关于与版本信息[/b]")
|
yield Label("[b]关于与版本信息[/b]")
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ from textual.containers import ScrollableContainer, Container, Horizontal, Verti
|
|||||||
from textual.screen import Screen
|
from textual.screen import Screen
|
||||||
from textual.widgets import Button, Footer, Header, Label, ListItem, ListView, Static
|
from textual.widgets import Button, Footer, Header, Label, ListItem, ListView, Static
|
||||||
from textual.layouts import horizontal
|
from textual.layouts import horizontal
|
||||||
|
from textual import events, on
|
||||||
|
from textual.reactive import reactive
|
||||||
|
|
||||||
import heurams.kernel.particles as pt
|
import heurams.kernel.particles as pt
|
||||||
import heurams.services.timer as timer
|
import heurams.services.timer as timer
|
||||||
@@ -37,6 +39,8 @@ class DashboardScreen(Screen):
|
|||||||
|
|
||||||
CSS_PATH = rootdir / "interface" / "css" / "screens" / "dashboard.tcss"
|
CSS_PATH = rootdir / "interface" / "css" / "screens" / "dashboard.tcss"
|
||||||
|
|
||||||
|
repolink = reactive({})
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name: str | None = None,
|
name: str | None = None,
|
||||||
@@ -44,12 +48,12 @@ class DashboardScreen(Screen):
|
|||||||
classes: str | None = None,
|
classes: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(name, id, classes)
|
super().__init__(name, id, classes)
|
||||||
self.repolink = {}
|
self._load_data()
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
"""组合界面组件"""
|
"""组合界面组件"""
|
||||||
self._load_data()
|
if config_var.get()['interface']['global']['show_header']:
|
||||||
yield Header(show_clock=True)
|
yield Header(show_clock=config_var.get()['interface']['global']['clock_on_header'])
|
||||||
with ScrollableContainer():
|
with ScrollableContainer():
|
||||||
yield Horizontal( # 顶部的状态
|
yield Horizontal( # 顶部的状态
|
||||||
Vertical(
|
Vertical(
|
||||||
@@ -58,7 +62,7 @@ class DashboardScreen(Screen):
|
|||||||
f"应用时区修正: UTC+{str(config_var.get()['services']['timer']['timezone_offset'] / 3600).rstrip('.0')}"
|
f"应用时区修正: UTC+{str(config_var.get()['services']['timer']['timezone_offset'] / 3600).rstrip('.0')}"
|
||||||
),
|
),
|
||||||
Label(
|
Label(
|
||||||
f"默认算法设置: {config_var.get()['interface']['global']['algorithm']}"
|
f"默认算法设置: {config_var.get()['interface']['global']['algorithm']}",
|
||||||
),
|
),
|
||||||
classes="left",
|
classes="left",
|
||||||
),
|
),
|
||||||
@@ -81,6 +85,13 @@ class DashboardScreen(Screen):
|
|||||||
yield Label(f"版本 {version.ver} {version.stage.capitalize()}") # 版本信息
|
yield Label(f"版本 {version.ver} {version.stage.capitalize()}") # 版本信息
|
||||||
yield Footer()
|
yield Footer()
|
||||||
|
|
||||||
|
@on(events.ScreenResume)
|
||||||
|
def post_active(self, event):
|
||||||
|
from heurams.interface import shim
|
||||||
|
shim.set_term_title(f"{self.app.TITLE} - {self.SUB_TITLE}")
|
||||||
|
# https://github.com/Textualize/textual/discussions/4268
|
||||||
|
# self.refresh(recompose=True) 此函数有问题且官方不管 而且性能低
|
||||||
|
|
||||||
def _load_data(self):
|
def _load_data(self):
|
||||||
repo_dirs = Repo.probe_valid_repos_in_dir(
|
repo_dirs = Repo.probe_valid_repos_in_dir(
|
||||||
Path(config_var.get()["global"]["paths"]["repo"])
|
Path(config_var.get()["global"]["paths"]["repo"])
|
||||||
@@ -154,7 +165,7 @@ class DashboardScreen(Screen):
|
|||||||
for r in self.repos:
|
for r in self.repos:
|
||||||
self.repolink[str(id(r))] = r # 用于规避 ctype id 对象还原
|
self.repolink[str(id(r))] = r # 用于规避 ctype id 对象还原
|
||||||
list_item = ListItem(
|
list_item = ListItem(
|
||||||
Label(r.prompt),
|
*[Label(line) for line in r.prompt.splitlines()],
|
||||||
Button(
|
Button(
|
||||||
f"开始学习",
|
f"开始学习",
|
||||||
flat=True,
|
flat=True,
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import base64
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
|
from textual import events, on
|
||||||
|
|
||||||
from textual.app import ComposeResult
|
from textual.app import ComposeResult
|
||||||
from textual.containers import ScrollableContainer
|
from textual.containers import ScrollableContainer
|
||||||
from textual.screen import Screen
|
from textual.screen import Screen
|
||||||
@@ -18,6 +20,7 @@ from textual.widgets import (
|
|||||||
Static,
|
Static,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from textual import events, on
|
||||||
from heurams.context import config_var
|
from heurams.context import config_var
|
||||||
from heurams.kernel.repolib import Repo
|
from heurams.kernel.repolib import Repo
|
||||||
from heurams.services.favorite_service import FavoriteItem, favorite_manager
|
from heurams.services.favorite_service import FavoriteItem, favorite_manager
|
||||||
@@ -53,7 +56,9 @@ class FavoriteManagerScreen(Screen):
|
|||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
"""组合界面组件"""
|
"""组合界面组件"""
|
||||||
yield Header(show_clock=True)
|
|
||||||
|
if config_var.get()['interface']['global']['show_header']:
|
||||||
|
yield Header(show_clock=config_var.get()['interface']['global']['clock_on_header'])
|
||||||
with ScrollableContainer(id="favorites-container"):
|
with ScrollableContainer(id="favorites-container"):
|
||||||
if not self.favorites:
|
if not self.favorites:
|
||||||
yield Label("暂无收藏", classes="empty-label")
|
yield Label("暂无收藏", classes="empty-label")
|
||||||
@@ -63,6 +68,12 @@ class FavoriteManagerScreen(Screen):
|
|||||||
yield ListView(id="favorites-list")
|
yield ListView(id="favorites-list")
|
||||||
yield Footer()
|
yield Footer()
|
||||||
|
|
||||||
|
@on(events.ScreenResume)
|
||||||
|
def post_active(self, event):
|
||||||
|
from heurams.interface import shim
|
||||||
|
|
||||||
|
shim.set_term_title(f"{self.app.TITLE} - {self.SUB_TITLE}")
|
||||||
|
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
"""挂载后填充列表"""
|
"""挂载后填充列表"""
|
||||||
if self.favorites:
|
if self.favorites:
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ from textual.reactive import reactive
|
|||||||
from textual.screen import Screen
|
from textual.screen import Screen
|
||||||
from textual.widgets import Button, Footer, Header, Label, Static
|
from textual.widgets import Button, Footer, Header, Label, Static
|
||||||
|
|
||||||
|
from textual import events, on
|
||||||
|
|
||||||
import heurams.kernel.particles as pt
|
import heurams.kernel.particles as pt
|
||||||
import heurams.kernel.puzzles as pz
|
import heurams.kernel.puzzles as pz
|
||||||
from heurams.context import config_var, rootdir
|
from heurams.context import config_var, rootdir
|
||||||
@@ -17,10 +19,13 @@ from heurams.kernel.reactor import *
|
|||||||
from heurams.services.favorite_service import favorite_manager
|
from heurams.services.favorite_service import favorite_manager
|
||||||
from heurams.services.logger import get_logger
|
from heurams.services.logger import get_logger
|
||||||
|
|
||||||
|
import pickle
|
||||||
|
|
||||||
from .. import shim
|
from .. import shim
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class MemScreen(Screen):
|
class MemScreen(Screen):
|
||||||
BINDINGS = [
|
BINDINGS = [
|
||||||
("q", "go_back", "返回"),
|
("q", "go_back", "返回"),
|
||||||
@@ -33,7 +38,8 @@ class MemScreen(Screen):
|
|||||||
("z", "block_prompt"),
|
("z", "block_prompt"),
|
||||||
]
|
]
|
||||||
|
|
||||||
CSS_PATH = rootdir / 'interface' / 'css' / 'screens' / 'memoqueue.tcss'
|
SUB_TITLE = "学习中"
|
||||||
|
CSS_PATH = rootdir / "interface" / "css" / "screens" / "memoqueue.tcss"
|
||||||
|
|
||||||
if config_var.get()["interface"]["global"]["quick_pass"]:
|
if config_var.get()["interface"]["global"]["quick_pass"]:
|
||||||
BINDINGS.append(("k", "quick_pass", "正确应答"))
|
BINDINGS.append(("k", "quick_pass", "正确应答"))
|
||||||
@@ -55,8 +61,15 @@ class MemScreen(Screen):
|
|||||||
self.update_state()
|
self.update_state()
|
||||||
self.expander: Expander
|
self.expander: Expander
|
||||||
|
|
||||||
|
@on(events.ScreenResume)
|
||||||
|
def post_active(self, event):
|
||||||
|
from heurams.interface import shim
|
||||||
|
|
||||||
|
shim.set_term_title(f"{self.app.TITLE} - {self.SUB_TITLE}")
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Header(show_clock=True)
|
if config_var.get()['interface']['global']['show_header']:
|
||||||
|
yield Header(show_clock=config_var.get()['interface']['global']['clock_on_header'])
|
||||||
with ScrollableContainer():
|
with ScrollableContainer():
|
||||||
yield Label(self._get_progress_text(), id="head_stat")
|
yield Label(self._get_progress_text(), id="head_stat")
|
||||||
yield ScrollableContainer(id="puzzle_container")
|
yield ScrollableContainer(id="puzzle_container")
|
||||||
@@ -83,7 +96,7 @@ class MemScreen(Screen):
|
|||||||
return Static(f"无法生成谜题 {e}")
|
return Static(f"无法生成谜题 {e}")
|
||||||
|
|
||||||
def _get_progress_text(self):
|
def _get_progress_text(self):
|
||||||
s = f"阶段: {self.procession.phase.name}\n"
|
s = f"阶段: {self.procession.route.name}\n"
|
||||||
# 收藏状态
|
# 收藏状态
|
||||||
if self.repo is not None:
|
if self.repo is not None:
|
||||||
fav_status = "已收藏" if self._is_current_atom_favorited() else "未收藏"
|
fav_status = "已收藏" if self._is_current_atom_favorited() else "未收藏"
|
||||||
@@ -98,7 +111,7 @@ class MemScreen(Screen):
|
|||||||
|
|
||||||
def mount_puzzle(self):
|
def mount_puzzle(self):
|
||||||
"""挂载当前谜题组件"""
|
"""挂载当前谜题组件"""
|
||||||
if self.procession.phase == RouterState.FINISHED:
|
if self.procession.route == RouterState.FINISHED:
|
||||||
self.mount_finished_widget()
|
self.mount_finished_widget()
|
||||||
return
|
return
|
||||||
container = self.query_one("#puzzle_container")
|
container = self.query_one("#puzzle_container")
|
||||||
@@ -144,7 +157,7 @@ class MemScreen(Screen):
|
|||||||
if new_rating == -1: # 安全值
|
if new_rating == -1: # 安全值
|
||||||
return
|
return
|
||||||
self.update_state()
|
self.update_state()
|
||||||
if self.procession.phase == RouterState.FINISHED:
|
if self.procession.route == RouterState.FINISHED:
|
||||||
rating = -1
|
rating = -1
|
||||||
return
|
return
|
||||||
self.expander.report(new_rating)
|
self.expander.report(new_rating)
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ from textual.containers import Grid, ScrollableContainer
|
|||||||
from textual.screen import ModalScreen
|
from textual.screen import ModalScreen
|
||||||
from textual.widgets import Button, Footer, Header, Label, ListItem, ListView, Static
|
from textual.widgets import Button, Footer, Header, Label, ListItem, ListView, Static
|
||||||
|
|
||||||
|
from textual import events, on
|
||||||
|
|
||||||
from heurams.context import *
|
from heurams.context import *
|
||||||
from heurams.services.logger import get_logger
|
from heurams.services.logger import get_logger
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ from textual.screen import Screen
|
|||||||
from textual.widgets import Button, Footer, Header, Label, ProgressBar, Static
|
from textual.widgets import Button, Footer, Header, Label, ProgressBar, Static
|
||||||
from textual.worker import get_current_worker
|
from textual.worker import get_current_worker
|
||||||
|
|
||||||
|
from textual import events, on
|
||||||
|
|
||||||
import heurams.kernel.particles as pt
|
import heurams.kernel.particles as pt
|
||||||
import heurams.services.hasher as hasher
|
import heurams.services.hasher as hasher
|
||||||
from heurams.context import *
|
from heurams.context import *
|
||||||
@@ -80,6 +82,12 @@ class PrecachingScreen(Screen):
|
|||||||
continue
|
continue
|
||||||
return total
|
return total
|
||||||
|
|
||||||
|
@on(events.ScreenResume)
|
||||||
|
def post_active(self, event):
|
||||||
|
from heurams.interface import shim
|
||||||
|
|
||||||
|
shim.set_term_title(f"{self.app.TITLE} - {self.SUB_TITLE}")
|
||||||
|
|
||||||
def _update_cache_stats(self) -> None:
|
def _update_cache_stats(self) -> None:
|
||||||
"""更新缓存统计信息"""
|
"""更新缓存统计信息"""
|
||||||
total_size = 0
|
total_size = 0
|
||||||
@@ -103,7 +111,9 @@ class PrecachingScreen(Screen):
|
|||||||
self.cache_stats["cache_rate"] = cache_rate
|
self.cache_stats["cache_rate"] = cache_rate
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Header(show_clock=True)
|
|
||||||
|
if config_var.get()['interface']['global']['show_header']:
|
||||||
|
yield Header(show_clock=config_var.get()['interface']['global']['clock_on_header'])
|
||||||
with ScrollableContainer(id="precache_container"):
|
with ScrollableContainer(id="precache_container"):
|
||||||
yield Label("[b]音频预缓存[/b]", classes="title-label")
|
yield Label("[b]音频预缓存[/b]", classes="title-label")
|
||||||
with Container():
|
with Container():
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ from textual.widgets import (
|
|||||||
)
|
)
|
||||||
from textual.lazy import Reveal, Lazy
|
from textual.lazy import Reveal, Lazy
|
||||||
|
|
||||||
|
from textual import events, on
|
||||||
|
|
||||||
import heurams.kernel.particles as pt
|
import heurams.kernel.particles as pt
|
||||||
import heurams.services.hasher as hasher
|
import heurams.services.hasher as hasher
|
||||||
from heurams.context import *
|
from heurams.context import *
|
||||||
@@ -34,7 +36,7 @@ class PreparationScreen(Screen):
|
|||||||
|
|
||||||
BINDINGS = [
|
BINDINGS = [
|
||||||
("q", "go_back", "返回"),
|
("q", "go_back", "返回"),
|
||||||
("p", "precache", "预缓存音频"),
|
("p", "precache", "缓存"),
|
||||||
("d", "toggle_dark", ""),
|
("d", "toggle_dark", ""),
|
||||||
("0,1,2,3", "app.push_screen('about')", ""),
|
("0,1,2,3", "app.push_screen('about')", ""),
|
||||||
]
|
]
|
||||||
@@ -46,8 +48,16 @@ class PreparationScreen(Screen):
|
|||||||
self.repo = repo
|
self.repo = repo
|
||||||
self.load_data()
|
self.load_data()
|
||||||
|
|
||||||
|
@on(events.ScreenResume)
|
||||||
|
def post_active(self, event):
|
||||||
|
from heurams.interface import shim
|
||||||
|
|
||||||
|
shim.set_term_title(f"{self.app.TITLE} - {self.SUB_TITLE}")
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Header(show_clock=True)
|
|
||||||
|
if config_var.get()['interface']['global']['show_header']:
|
||||||
|
yield Header(show_clock=config_var.get()['interface']['global']['clock_on_header'])
|
||||||
with ScrollableContainer(id="main_container"):
|
with ScrollableContainer(id="main_container"):
|
||||||
yield Markdown(
|
yield Markdown(
|
||||||
f"**准备就绪**: `{self.repo.manifest['title']}`\n", id="title"
|
f"**准备就绪**: `{self.repo.manifest['title']}`\n", id="title"
|
||||||
@@ -72,7 +82,7 @@ class PreparationScreen(Screen):
|
|||||||
classes="btn",
|
classes="btn",
|
||||||
),
|
),
|
||||||
Button(
|
Button(
|
||||||
"预缓存音频",
|
"管理缓存",
|
||||||
id="precache_button",
|
id="precache_button",
|
||||||
variant="success",
|
variant="success",
|
||||||
classes="btn",
|
classes="btn",
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ from textual.widgets import (
|
|||||||
)
|
)
|
||||||
from textual.layouts import horizontal
|
from textual.layouts import horizontal
|
||||||
|
|
||||||
|
from textual import events, on
|
||||||
|
|
||||||
import heurams.kernel.particles as pt
|
import heurams.kernel.particles as pt
|
||||||
import heurams.services.timer as timer
|
import heurams.services.timer as timer
|
||||||
import heurams.services.version as version
|
import heurams.services.version as version
|
||||||
@@ -54,9 +56,16 @@ class SettingScreen(Screen):
|
|||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(name, id, classes)
|
super().__init__(name, id, classes)
|
||||||
|
|
||||||
|
@on(events.ScreenResume)
|
||||||
|
def post_active(self, event):
|
||||||
|
from heurams.interface import shim
|
||||||
|
|
||||||
|
shim.set_term_title(f"{self.app.TITLE} - {self.SUB_TITLE}")
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
"""组合界面组件"""
|
"""组合界面组件"""
|
||||||
yield Header(show_clock=True)
|
if config_var.get()['interface']['global']['show_header']:
|
||||||
|
yield Header(show_clock=config_var.get()['interface']['global']['clock_on_header'])
|
||||||
with ScrollableContainer():
|
with ScrollableContainer():
|
||||||
yield Label("[b]设置页面[/b]")
|
yield Label("[b]设置页面[/b]")
|
||||||
for i in config_var.get():
|
for i in config_var.get():
|
||||||
@@ -65,7 +74,7 @@ class SettingScreen(Screen):
|
|||||||
a = self._get_subcfg(f"{i}")
|
a = self._get_subcfg(f"{i}")
|
||||||
if a:
|
if a:
|
||||||
yield Collapsible(
|
yield Collapsible(
|
||||||
*a, title=i + f'\n{config_var.get().get(f"_{i}_desc", "")}'
|
*a, title=i + f'\n[d]{config_var.get().get(f"_{i}_desc", "")}[/d]'
|
||||||
)
|
)
|
||||||
yield Label(
|
yield Label(
|
||||||
"退出页面时, 所作的更改会立即保存, 但仍建议重启软件以确保新的配置得到应用",
|
"退出页面时, 所作的更改会立即保存, 但仍建议重启软件以确保新的配置得到应用",
|
||||||
@@ -85,7 +94,7 @@ class SettingScreen(Screen):
|
|||||||
if a:
|
if a:
|
||||||
lst.append(
|
lst.append(
|
||||||
Collapsible(
|
Collapsible(
|
||||||
*a, title=i + f'\n{parent.get(f"_{i}_desc", "")}'
|
*a, title=i + f'\n[d]{parent.get(f"_{i}_desc", "")}[/d]'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return lst
|
return lst
|
||||||
@@ -101,17 +110,17 @@ class SettingScreen(Screen):
|
|||||||
if a:
|
if a:
|
||||||
lst.append(
|
lst.append(
|
||||||
Collapsible(
|
Collapsible(
|
||||||
*a, title=i + f'\n{parent.get(f"_{i}_desc", "")}'
|
*a, title=i + f'\n[d]{parent.get(f"_{i}_desc", "")}[/d]'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif f"_{i}_candidate" in parent: # 选择框模式
|
elif f"_{i}_candidate" in parent: # 选择框模式
|
||||||
if isinstance(parent[f"_{i}_candidate"], dict):
|
if isinstance(parent[f"_{i}_candidate"], dict):
|
||||||
lst.append(
|
lst.append(
|
||||||
Horizontal(
|
Horizontal(
|
||||||
Label(i + f'\n{parent.get(f"_{i}_desc", "")}'),
|
Label(i + f'\n[d]{parent.get(f"_{i}_desc", "")}[/d]'),
|
||||||
Select(
|
Select(
|
||||||
(
|
(
|
||||||
(f"{j} ({k})", j)
|
(f"{j}\n[d]{k}[/d]", j)
|
||||||
for j, k in parent[f"_{i}_candidate"].items()
|
for j, k in parent[f"_{i}_candidate"].items()
|
||||||
),
|
),
|
||||||
prompt=f'{parent.get(f"{i}", "")}',
|
prompt=f'{parent.get(f"{i}", "")}',
|
||||||
@@ -122,7 +131,7 @@ class SettingScreen(Screen):
|
|||||||
elif isinstance(parent[f"_{i}_candidate"], list):
|
elif isinstance(parent[f"_{i}_candidate"], list):
|
||||||
lst.append(
|
lst.append(
|
||||||
Horizontal(
|
Horizontal(
|
||||||
Label(i + f'\n{parent.get(f"_{i}_desc", "")}'),
|
Label(i + f'\n[d]{parent.get(f"_{i}_desc", "")}[/d]'),
|
||||||
Select(
|
Select(
|
||||||
((j, j) for j in parent[f"_{i}_candidate"]),
|
((j, j) for j in parent[f"_{i}_candidate"]),
|
||||||
prompt=f'{parent.get(f"{i}", "")}',
|
prompt=f'{parent.get(f"{i}", "")}',
|
||||||
@@ -134,7 +143,7 @@ class SettingScreen(Screen):
|
|||||||
if isinstance(parent[i], float):
|
if isinstance(parent[i], float):
|
||||||
lst.append(
|
lst.append(
|
||||||
Horizontal(
|
Horizontal(
|
||||||
Label(i + f'\n{parent.get(f"_{i}_desc", "")}'),
|
Label(i + f'\n[d]{parent.get(f"_{i}_desc", "")}[/d]'),
|
||||||
Input(
|
Input(
|
||||||
value=str(parent[i]),
|
value=str(parent[i]),
|
||||||
placeholder="要求一个浮点数",
|
placeholder="要求一个浮点数",
|
||||||
@@ -146,7 +155,7 @@ class SettingScreen(Screen):
|
|||||||
elif isinstance(parent[i], str):
|
elif isinstance(parent[i], str):
|
||||||
lst.append(
|
lst.append(
|
||||||
Horizontal(
|
Horizontal(
|
||||||
Label(i + f'\n{parent.get(f"_{i}_desc", "")}'),
|
Label(i + f'\n[d]{parent.get(f"_{i}_desc", "")}[/d]'),
|
||||||
Input(
|
Input(
|
||||||
value=parent[i],
|
value=parent[i],
|
||||||
placeholder="要求一个字符串",
|
placeholder="要求一个字符串",
|
||||||
@@ -158,7 +167,7 @@ class SettingScreen(Screen):
|
|||||||
elif isinstance(parent[i], bool):
|
elif isinstance(parent[i], bool):
|
||||||
lst.append(
|
lst.append(
|
||||||
Horizontal(
|
Horizontal(
|
||||||
Label(i + f'\n{parent.get(f"_{i}_desc", "")}'),
|
Label(i + f'\n[d]{parent.get(f"_{i}_desc", "")}[/d]'),
|
||||||
Switch(
|
Switch(
|
||||||
value=parent[i], id=domize(f"{parent_epath}.{i}")
|
value=parent[i], id=domize(f"{parent_epath}.{i}")
|
||||||
),
|
),
|
||||||
@@ -167,7 +176,7 @@ class SettingScreen(Screen):
|
|||||||
elif isinstance(parent[i], int):
|
elif isinstance(parent[i], int):
|
||||||
lst.append(
|
lst.append(
|
||||||
Horizontal(
|
Horizontal(
|
||||||
Label(i + f'\n{parent.get(f"_{i}_desc", "")}'),
|
Label(i + f'\n[d]{parent.get(f"_{i}_desc", "")}[/d]'),
|
||||||
Input(
|
Input(
|
||||||
value=str(parent[i]),
|
value=str(parent[i]),
|
||||||
placeholder="要求一个整数",
|
placeholder="要求一个整数",
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ from textual.screen import Screen
|
|||||||
from textual.widgets import Button, Footer, Header, Label, ProgressBar, Static
|
from textual.widgets import Button, Footer, Header, Label, ProgressBar, Static
|
||||||
from textual.worker import get_current_worker
|
from textual.worker import get_current_worker
|
||||||
|
|
||||||
|
from textual import events, on
|
||||||
|
|
||||||
import heurams.kernel.particles as pt
|
import heurams.kernel.particles as pt
|
||||||
import heurams.services.hasher as hasher
|
import heurams.services.hasher as hasher
|
||||||
from heurams.context import *
|
from heurams.context import *
|
||||||
@@ -26,8 +28,16 @@ class SyncScreen(Screen):
|
|||||||
self.log_messages = []
|
self.log_messages = []
|
||||||
self.max_log_lines = 50
|
self.max_log_lines = 50
|
||||||
|
|
||||||
|
@on(events.ScreenResume)
|
||||||
|
def post_active(self, event):
|
||||||
|
from heurams.interface import shim
|
||||||
|
|
||||||
|
shim.set_term_title(f"{self.app.TITLE} - {self.SUB_TITLE}")
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Header(show_clock=True)
|
|
||||||
|
if config_var.get()['interface']['global']['show_header']:
|
||||||
|
yield Header(show_clock=config_var.get()['interface']['global']['clock_on_header'])
|
||||||
with ScrollableContainer(id="sync_container"):
|
with ScrollableContainer(id="sync_container"):
|
||||||
# 标题和连接状态
|
# 标题和连接状态
|
||||||
yield Static("同步工具", classes="title")
|
yield Static("同步工具", classes="title")
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
import heurams.interface.widgets as pzw
|
import heurams.interface.widgets as pzw
|
||||||
import heurams.kernel.puzzles as pz
|
import heurams.kernel.puzzles as pz
|
||||||
|
import platform, os, sys
|
||||||
|
from heurams.context import config_var
|
||||||
|
|
||||||
puzzle2widget = {
|
puzzle2widget = {
|
||||||
pz.RecognitionPuzzle: pzw.Recognition,
|
pz.RecognitionPuzzle: pzw.Recognition,
|
||||||
@@ -9,3 +11,13 @@ puzzle2widget = {
|
|||||||
pz.MCQPuzzle: pzw.MCQPuzzle,
|
pz.MCQPuzzle: pzw.MCQPuzzle,
|
||||||
pz.BasePuzzle: pzw.BasePuzzleWidget,
|
pz.BasePuzzle: pzw.BasePuzzleWidget,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def set_term_title(title):
|
||||||
|
if not config_var.get()['interface']['global']['change_window_title']:
|
||||||
|
return
|
||||||
|
system = platform.system()
|
||||||
|
if system == "Windows":
|
||||||
|
os.system(f"title {title}")
|
||||||
|
else: # Linux, Mac, etc.
|
||||||
|
os.write(2, f"\033]2;{title}\007".encode("utf-8"))
|
||||||
|
|||||||
@@ -1271,7 +1271,7 @@ class SM:
|
|||||||
self.ofm = OFM(self)
|
self.ofm = OFM(self)
|
||||||
|
|
||||||
def _find_index_to_insert(self, item, r=None):
|
def _find_index_to_insert(self, item, r=None):
|
||||||
"""Binary search to find insertion index for sorted queue."""
|
"""Binary search to find insertion index for sorted procession."""
|
||||||
if r is None:
|
if r is None:
|
||||||
r = list(range(len(self.q)))
|
r = list(range(len(self.q)))
|
||||||
|
|
||||||
@@ -1290,7 +1290,7 @@ class SM:
|
|||||||
return self._find_index_to_insert(item, r[i:])
|
return self._find_index_to_insert(item, r[i:])
|
||||||
|
|
||||||
def add_item(self, value):
|
def add_item(self, value):
|
||||||
"""Add a new item to the queue."""
|
"""Add a new item to the procession."""
|
||||||
item = Item(self, value)
|
item = Item(self, value)
|
||||||
index = self._find_index_to_insert(item)
|
index = self._find_index_to_insert(item)
|
||||||
self.q.insert(index, item)
|
self.q.insert(index, item)
|
||||||
@@ -1330,7 +1330,7 @@ class SM:
|
|||||||
item.answer(grade, now)
|
item.answer(grade, now)
|
||||||
|
|
||||||
def discard(self, item):
|
def discard(self, item):
|
||||||
"""Remove item from queue."""
|
"""Remove item from procession."""
|
||||||
if item in self.q:
|
if item in self.q:
|
||||||
self.q.remove(item)
|
self.q.remove(item)
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
orbital, 即轨道, 是定义队列式复习阶段流程的数据结构, 其实就是个字典, 至于为何不用typeddict, 因为懒.
|
orbital, 即轨道, 是定义队列式复习阶段流程的数据结构, 其实就是个字典, 至于为何不用typeddict, 因为懒.
|
||||||
|
|
||||||
orbital_example = {
|
orbital_example = {
|
||||||
"schedule": [列表 存储阶段(phases)名称]
|
"schedule": [列表 存储阶段(routes)名称]
|
||||||
"phases":{
|
"routes":{
|
||||||
阶段名称 = [["谜题(puzzle 现称 Puzzles 评估器)名称", "概率系数 可大于1(整数部分为重复次数) 注意使用字符串包裹(toml 规范)"], ...],
|
阶段名称 = [["谜题(puzzle 现称 Puzzles 评估器)名称", "概率系数 可大于1(整数部分为重复次数) 注意使用字符串包裹(toml 规范)"], ...],
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from .nucleon import Nucleon
|
|||||||
|
|
||||||
orbital_placeholder = {
|
orbital_placeholder = {
|
||||||
"schedule": ["quick_review", "recognition", "final_review"],
|
"schedule": ["quick_review", "recognition", "final_review"],
|
||||||
"phases": {
|
"routes": {
|
||||||
"quick_review": [
|
"quick_review": [
|
||||||
["FillBlank", 1.0],
|
["FillBlank", 1.0],
|
||||||
["SelectMeaning", 0.5],
|
["SelectMeaning", 0.5],
|
||||||
|
|||||||
@@ -83,16 +83,16 @@ Router 的 __repr__ 定义了此对象"官方的显示"用作直观的调试.\
|
|||||||
- current_atom: 当前记忆原子的引用
|
- current_atom: 当前记忆原子的引用
|
||||||
- atoms: 队列中所有原子列表
|
- atoms: 队列中所有原子列表
|
||||||
- cursor: 指针, 是当前原子在 atoms 列表中的索引
|
- cursor: 指针, 是当前原子在 atoms 列表中的索引
|
||||||
- phase: "阶段属性"
|
- route: "阶段属性"
|
||||||
|
|
||||||
> 注意区分 "Router" 和 "Phase", 其中 "Phase" 表示 "Router State".
|
> 注意区分 "Router" 和 "Route", 其中 "Route" 表示 "Router State".
|
||||||
|
|
||||||
- name\_: 阶段的命名
|
- name\_: 阶段的命名
|
||||||
- state: 当前状态属性
|
- state: 当前状态属性
|
||||||
|
|
||||||
### 初始化
|
### 初始化
|
||||||
|
|
||||||
接受一个 atoms 列表与 phase_state (RouterState Enum 类型)对象
|
接受一个 atoms 列表与 route_state (RouterState Enum 类型)对象
|
||||||
|
|
||||||
### 直接输出呈现形式
|
### 直接输出呈现形式
|
||||||
|
|
||||||
@@ -100,12 +100,12 @@ Router 的 __repr__ 定义了此对象"官方的显示"用作直观的调试.\
|
|||||||
与 Router 不同, Procession 显示队列会对过长的 atom.ident 进行缩略(末尾 `>` 符号)
|
与 Router 不同, Procession 显示队列会对过长的 atom.ident 进行缩略(末尾 `>` 符号)
|
||||||
|
|
||||||
```text
|
```text
|
||||||
| Type | Name | State | Progress | Queue | Current Atom |
|
| Type | Name | State | Progress | Procession | Current Atom |
|
||||||
| :--------- | :----- | :----- | :------- | :--------------------- | :---------------------------- |
|
| :--------- | :----- | :----- | :------- | :--------------------- | :---------------------------- |
|
||||||
| Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, |
|
| Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, |
|
||||||
```
|
```
|
||||||
|
|
||||||
| Type | Name | State | Progress | Queue | Current Atom |
|
| Type | Name | State | Progress | Procession | Current Atom |
|
||||||
| :--------- | :----- | :----- | :------- | :--------------------- | :---------------------------- |
|
| :--------- | :----- | :----- | :------- | :--------------------- | :---------------------------- |
|
||||||
| Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, |
|
| Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, |
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ Router 的 __repr__ 定义了此对象"官方的显示"用作直观的调试.\
|
|||||||
|
|
||||||
### 初始化
|
### 初始化
|
||||||
|
|
||||||
接受 atom 对象和 phase 参数
|
接受 atom 对象和 route 参数
|
||||||
|
|
||||||
### 方法
|
### 方法
|
||||||
|
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ logger = get_logger(__name__)
|
|||||||
class Expander(Machine):
|
class Expander(Machine):
|
||||||
"""单原子调度展开器"""
|
"""单原子调度展开器"""
|
||||||
|
|
||||||
def __init__(self, atom: pt.Atom, phase=RouterState.RECOGNITION):
|
def __init__(self, atom: pt.Atom, route=RouterState.RECOGNITION):
|
||||||
self.phase = phase
|
self.route = route
|
||||||
self.cursor = 0
|
self.cursor = 0
|
||||||
self.atom = atom
|
self.atom = atom
|
||||||
self.current_puzzle_inf: dict
|
self.current_puzzle_inf: dict
|
||||||
# phase 为 RouterState 枚举实例, 需要获取其value
|
# route 为 RouterState 枚举实例, 需要获取其value
|
||||||
phase_value = phase.value
|
route_value = route.value
|
||||||
states = [
|
states = [
|
||||||
{"name": ExpanderState.EXAMMODE.value},
|
{"name": ExpanderState.EXAMMODE.value},
|
||||||
{"name": ExpanderState.RETRONLY.value},
|
{"name": ExpanderState.RETRONLY.value},
|
||||||
@@ -35,7 +35,7 @@ class Expander(Machine):
|
|||||||
"dest": ExpanderState.RETRONLY.value,
|
"dest": ExpanderState.RETRONLY.value,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
if phase == RouterState.FINISHED:
|
if route == RouterState.FINISHED:
|
||||||
Machine.__init__(
|
Machine.__init__(
|
||||||
self,
|
self,
|
||||||
states=states,
|
states=states,
|
||||||
@@ -43,7 +43,7 @@ class Expander(Machine):
|
|||||||
initial=ExpanderState.EXAMMODE.value,
|
initial=ExpanderState.EXAMMODE.value,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
orbital_schedule = atom.registry["orbital"]["phases"][phase_value] # type: ignore
|
orbital_schedule = atom.registry["orbital"]["routes"][route_value] # type: ignore
|
||||||
orbital_puzzles = atom.registry["nucleon"]["puzzles"]
|
orbital_puzzles = atom.registry["nucleon"]["puzzles"]
|
||||||
self.puzzles_inf = list()
|
self.puzzles_inf = list()
|
||||||
self.min_ratings = []
|
self.min_ratings = []
|
||||||
@@ -122,7 +122,9 @@ class Expander(Machine):
|
|||||||
"Atom": truncate(self.atom.ident),
|
"Atom": truncate(self.atom.ident),
|
||||||
"State": self.state,
|
"State": self.state,
|
||||||
"Progress": f"{self.cursor + 1} / {len(self.puzzles_inf)}",
|
"Progress": f"{self.cursor + 1} / {len(self.puzzles_inf)}",
|
||||||
"Queue": list(map(lambda f: truncate(f["alia"]), self.puzzles_inf)),
|
"Procession": list(
|
||||||
|
map(lambda f: truncate(f["alia"]), self.puzzles_inf)
|
||||||
|
),
|
||||||
"Current Puzzle": f"{self.current_puzzle_inf['alia']}@{self.current_puzzle_inf['puzzle'].__name__}", # type: ignore
|
"Current Puzzle": f"{self.current_puzzle_inf['alia']}@{self.current_puzzle_inf['puzzle'].__name__}", # type: ignore
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ logger = get_logger(__name__)
|
|||||||
class Procession(Machine):
|
class Procession(Machine):
|
||||||
"""队列: 标识单次记忆流程"""
|
"""队列: 标识单次记忆流程"""
|
||||||
|
|
||||||
def __init__(self, atoms: list, phase_state: RouterState, name_: str = ""):
|
def __init__(self, atoms: list, route_state: RouterState, name_: str = ""):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Procession.__init__: 原子数量=%d, phase=%s, name='%s'",
|
"Procession.__init__: 原子数量=%d, route=%s, name='%s'",
|
||||||
len(atoms),
|
len(atoms),
|
||||||
phase_state.value,
|
route_state.value,
|
||||||
name_,
|
name_,
|
||||||
)
|
)
|
||||||
self.current_atom: pt.Atom | None
|
self.current_atom: pt.Atom | None
|
||||||
@@ -25,7 +25,7 @@ class Procession(Machine):
|
|||||||
self.current_atom = atoms[0] if atoms else None
|
self.current_atom = atoms[0] if atoms else None
|
||||||
self.cursor = 0
|
self.cursor = 0
|
||||||
self.name_ = name_
|
self.name_ = name_
|
||||||
self.phase = phase_state
|
self.route = route_state
|
||||||
|
|
||||||
states = [
|
states = [
|
||||||
{"name": ProcessionState.ACTIVE.value, "on_enter": "on_active"},
|
{"name": ProcessionState.ACTIVE.value, "on_enter": "on_active"},
|
||||||
@@ -114,7 +114,7 @@ class Procession(Machine):
|
|||||||
return empty
|
return empty
|
||||||
|
|
||||||
def get_expander(self):
|
def get_expander(self):
|
||||||
return Expander(atom=self.current_atom, phase=self.phase) # type: ignore
|
return Expander(atom=self.current_atom, route=self.route) # type: ignore
|
||||||
|
|
||||||
def __repr__(self, style="pipe", ends="\n"):
|
def __repr__(self, style="pipe", ends="\n"):
|
||||||
from heurams.services.textproc import truncate
|
from heurams.services.textproc import truncate
|
||||||
@@ -125,7 +125,7 @@ class Procession(Machine):
|
|||||||
"Name": self.name_,
|
"Name": self.name_,
|
||||||
"State": self.state,
|
"State": self.state,
|
||||||
"Progress": f"{self.cursor + 1} / {len(self.atoms)}",
|
"Progress": f"{self.cursor + 1} / {len(self.atoms)}",
|
||||||
"Queue": list(map(lambda f: truncate(f.ident), self.atoms)),
|
"Procession": list(map(lambda f: truncate(f.ident), self.atoms)),
|
||||||
"Current Atom": self.current_atom.ident, # type: ignore
|
"Current Atom": self.current_atom.ident, # type: ignore
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ logger = get_logger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class Router(Machine):
|
class Router(Machine):
|
||||||
"""全局调度阶段管理器"""
|
"""全局调度阶段路由器"""
|
||||||
|
|
||||||
def __init__(self, atoms: list[pt.Atom]) -> None:
|
def __init__(self, atoms: list[pt.Atom]) -> None:
|
||||||
logger.debug("Router.__init__: 原子数量=%d", len(atoms))
|
logger.debug(f"Router.__init__: 原子数量={len(atoms)}")
|
||||||
|
|
||||||
self.atoms = atoms
|
self.atoms = atoms
|
||||||
new_atoms = list()
|
new_atoms = list()
|
||||||
@@ -26,9 +26,10 @@ class Router(Machine):
|
|||||||
else:
|
else:
|
||||||
old_atoms.append(i)
|
old_atoms.append(i)
|
||||||
|
|
||||||
logger.debug("新原子数量=%d, 旧原子数量=%d", len(new_atoms), len(old_atoms))
|
logger.debug(f"新原子数量={len(new_atoms)}, 旧原子数量={len(old_atoms)}")
|
||||||
|
|
||||||
self.processions = list()
|
self.processions = list()
|
||||||
|
"""路由中的所有队列"""
|
||||||
# TODO: 改进为基于配置文件的可选复习阶段
|
# TODO: 改进为基于配置文件的可选复习阶段
|
||||||
if len(old_atoms):
|
if len(old_atoms):
|
||||||
self.processions.append(
|
self.processions.append(
|
||||||
@@ -116,15 +117,15 @@ class Router(Machine):
|
|||||||
for i in self.processions:
|
for i in self.processions:
|
||||||
i: Procession
|
i: Procession
|
||||||
if i.state != ProcessionState.FINISHED.value:
|
if i.state != ProcessionState.FINISHED.value:
|
||||||
# if i.phase == RouterState.UNSURE: 此判断是不必要的 因为没有这种 Procession
|
# if i.route == RouterState.UNSURE: 此判断是不必要的 因为没有这种 Procession
|
||||||
if i.phase == RouterState.QUICK_REVIEW:
|
if i.route == RouterState.QUICK_REVIEW:
|
||||||
self.to_quick_review()
|
self.to_quick_review()
|
||||||
elif i.phase == RouterState.RECOGNITION:
|
elif i.route == RouterState.RECOGNITION:
|
||||||
self.to_recognition()
|
self.to_recognition()
|
||||||
elif i.phase == RouterState.FINAL_REVIEW:
|
elif i.route == RouterState.FINAL_REVIEW:
|
||||||
self.to_final_review()
|
self.to_final_review()
|
||||||
|
|
||||||
logger.debug("找到未完成的 Procession: phase=%s", i.phase)
|
logger.debug("找到未完成的 Procession: route=%s", i.route)
|
||||||
return i
|
return i
|
||||||
|
|
||||||
# 所有Procession都已完成
|
# 所有Procession都已完成
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
"""会话记录模块"""
|
|
||||||
3
src/heurams/unifront/session.py
Normal file
3
src/heurams/unifront/session.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
"""会话模块"""
|
||||||
|
class Session:
|
||||||
|
pass
|
||||||
Reference in New Issue
Block a user