feat(interface): 改进状态显示
This commit is contained in:
@@ -7,6 +7,11 @@ from textual.widgets import Button, Footer, Header, Label, Markdown, Static
|
||||
|
||||
import heurams.services.version as version
|
||||
from heurams.context import *
|
||||
import platform
|
||||
import shutil
|
||||
import psutil
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
class AboutScreen(Screen):
|
||||
@@ -18,6 +23,15 @@ class AboutScreen(Screen):
|
||||
yield Header(show_clock=True)
|
||||
with ScrollableContainer(id="about_container"):
|
||||
yield Label("[b]关于与版本信息[/b]")
|
||||
|
||||
# 获取系统信息
|
||||
textual_version = self._get_textual_version()
|
||||
terminal_info = self._get_terminal_info()
|
||||
python_version = self._get_python_version()
|
||||
os_version = self._get_os_version()
|
||||
disk_usage = self._get_disk_usage()
|
||||
memory_info = self._get_memory_info()
|
||||
|
||||
about_text = f"""
|
||||
# 关于 "潜进"
|
||||
|
||||
@@ -33,6 +47,10 @@ class AboutScreen(Screen):
|
||||
|
||||
如果您觉得这个软件有用, 请给它添加一个星标 :)
|
||||
|
||||
我们的共同目标是为人人带来高品质的辅助记忆 & 学习软件.
|
||||
|
||||
不管您来自何方, 我们都欢迎您加入社区并做出贡献.
|
||||
|
||||
开发人员:
|
||||
|
||||
- Wang Zhiyu([@pluvium27](https://github.com/pluvium27)): 项目作者
|
||||
@@ -43,40 +61,22 @@ class AboutScreen(Screen):
|
||||
- [Kazuaki Tanida](https://github.com/slaypni): SM-15 算法的 CoffeeScript 实现
|
||||
- [Thoughts Memo](https://www.zhihu.com/people/L.M.Sherlock): 文献参考
|
||||
|
||||
# 参与贡献
|
||||
|
||||
我们是一个年轻且包容的社区, 由技术人员, 设计师, 文书工作者, 以及创意人员共同构成,
|
||||
# 运行环境信息
|
||||
|
||||
通过我们协力开发的软件为所有人谋取福祉.
|
||||
Textual 框架版本: {textual_version}
|
||||
|
||||
终端模拟器: {terminal_info}
|
||||
|
||||
Python 解释器版本: {python_version}
|
||||
|
||||
操作系统版本: {os_version}
|
||||
|
||||
存储余量: {disk_usage}
|
||||
|
||||
内存大小: {memory_info}
|
||||
|
||||
上述工作不可避免地让我们确立了下列价值观 (取自 KDE 宣言):
|
||||
|
||||
- 开放治理 确保更多人能参与我们的领导和决策进程;
|
||||
|
||||
- 自由软件 确保我们的工作成果随时能为所有人所用;
|
||||
|
||||
- 多样包容 确保所有人都能加入社区并参加工作;
|
||||
|
||||
- 创新精神 确保新思路能不断涌现并服务于所有人;
|
||||
|
||||
- 共同产权 确保我们能团结一致;
|
||||
|
||||
- 迎合用户 确保我们的成果对所有人有用.
|
||||
|
||||
综上所述, 在为我们共同目标奋斗的过程中, 我们认为上述价值观反映了我们社区的本质, 是我们始终如一地保持初心的关键所在.
|
||||
|
||||
这是一项立足于协作精神的事业, 它的运作和产出不受任何单一个人或者机构的操纵.
|
||||
|
||||
我们的共同目标是为人人带来高品质的辅助记忆 & 学习软件.
|
||||
|
||||
不管您来自何方, 我们都欢迎您加入社区并做出贡献.
|
||||
"""
|
||||
|
||||
# """
|
||||
# 学术数据
|
||||
|
||||
# "潜进" 的用户数据可用于科学方面的研究, 我们将在未来版本添加学术数据的收集和展示平台
|
||||
# """
|
||||
yield Markdown(about_text, classes="about-markdown")
|
||||
|
||||
yield Button(
|
||||
@@ -94,3 +94,68 @@ class AboutScreen(Screen):
|
||||
event.stop()
|
||||
if event.button.id == "back_button":
|
||||
self.action_go_back()
|
||||
|
||||
def _get_textual_version(self) -> str:
|
||||
"""获取 Textual 框架版本"""
|
||||
try:
|
||||
import textual
|
||||
return textual.__version__
|
||||
except (ImportError, AttributeError):
|
||||
return "未知"
|
||||
|
||||
def _get_terminal_info(self) -> str:
|
||||
"""获取终端模拟器信息"""
|
||||
terminal = shutil.which("terminal")
|
||||
if terminal:
|
||||
return terminal
|
||||
# 尝试从环境变量获取
|
||||
terminal_env = os.environ.get('TERM_PROGRAM') or os.environ.get('TERM')
|
||||
return terminal_env or "未知"
|
||||
|
||||
def _get_python_version(self) -> str:
|
||||
"""获取 Python 解释器版本"""
|
||||
return platform.python_version()
|
||||
|
||||
def _get_os_version(self) -> str:
|
||||
"""获取操作系统版本"""
|
||||
try:
|
||||
if platform.system() == "Darwin":
|
||||
# macOS
|
||||
import subprocess
|
||||
result = subprocess.run(['sw_vers', '-productVersion'],
|
||||
capture_output=True, text=True)
|
||||
return f"macOS {result.stdout.strip()}"
|
||||
elif platform.system() == "Windows":
|
||||
# Windows
|
||||
return f"Windows {platform.release()}"
|
||||
elif platform.system() == "Linux":
|
||||
# Linux - 尝试获取发行版信息
|
||||
try:
|
||||
import distro
|
||||
return f"{distro.name()} {distro.version()}"
|
||||
except (ImportError, AttributeError):
|
||||
return platform.platform()
|
||||
else:
|
||||
return platform.platform()
|
||||
except Exception:
|
||||
return platform.platform()
|
||||
|
||||
def _get_disk_usage(self) -> str:
|
||||
"""获取磁盘使用情况"""
|
||||
try:
|
||||
usage = psutil.disk_usage('/')
|
||||
free_gb = usage.free / (1024 ** 3)
|
||||
total_gb = usage.total / (1024 ** 3)
|
||||
percent_free = (free_gb / total_gb) * 100
|
||||
return f"{free_gb:.1f} GB ({percent_free:.1f}%)"
|
||||
except Exception:
|
||||
return "未知"
|
||||
|
||||
def _get_memory_info(self) -> str:
|
||||
"""获取内存信息"""
|
||||
try:
|
||||
memory = psutil.virtual_memory()
|
||||
total_gb = memory.total / (1024 ** 3)
|
||||
return f"{total_gb:.1f} GB"
|
||||
except Exception:
|
||||
return "未知"
|
||||
@@ -1,6 +1,3 @@
|
||||
"""LLM 聊天界面"""
|
||||
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
@@ -19,7 +16,7 @@ logger = get_logger(__name__)
|
||||
class LLMChatScreen(Screen):
|
||||
"""LLM 聊天屏幕"""
|
||||
|
||||
SUB_TITLE = "AI 聊天"
|
||||
SUB_TITLE = "语言模型集成"
|
||||
BINDINGS = [
|
||||
("q", "go_back", "返回"),
|
||||
("ctrl+s", "save_session", "保存会话"),
|
||||
|
||||
@@ -5,7 +5,7 @@ from textual.containers import ScrollableContainer
|
||||
from textual.reactive import reactive
|
||||
from textual.screen import Screen
|
||||
from textual.widget import Widget
|
||||
from textual.widgets import Button, Footer, Header, Label, Markdown, Static
|
||||
from textual.widgets import Button, Footer, Header, Label, Markdown, Static, Rule, Sparkline
|
||||
|
||||
import heurams.kernel.particles as pt
|
||||
import heurams.services.hasher as hasher
|
||||
@@ -34,6 +34,7 @@ class PreparationScreen(Screen):
|
||||
super().__init__(name=None, id=None, classes=None)
|
||||
self.repo = repo
|
||||
self.repostat = repostat
|
||||
self.load_data()
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Header(show_clock=True)
|
||||
@@ -43,7 +44,7 @@ class PreparationScreen(Screen):
|
||||
f"仓库路径: {config_var.get()['paths']['data']}/repo/[b]{self.repostat['dirname']}[/b]"
|
||||
)
|
||||
yield Label(f"\n单元数量: {len(self.repo)}\n")
|
||||
yield Label(f"单次记忆数量: {self.scheduled_num}", id="schnum_label")
|
||||
yield Label(f"最小记忆分组: {self.scheduled_num}\n", id="schnum_label")
|
||||
|
||||
yield Button(
|
||||
"开始记忆",
|
||||
@@ -58,11 +59,15 @@ class PreparationScreen(Screen):
|
||||
classes="precache-button",
|
||||
)
|
||||
|
||||
yield Static(f"\n单元预览:\n")
|
||||
for i in self._get_full_content().replace("/", "").splitlines():
|
||||
yield Static()
|
||||
yield Sparkline(self.spark_line_arr, summary_function=max)
|
||||
yield Rule()
|
||||
#yield Static(str(self.spark_line_arr))
|
||||
yield Static(f"单元状态预览:\n")
|
||||
for i in self.content.splitlines():
|
||||
yield Static(i, classes="full")
|
||||
yield Footer()
|
||||
|
||||
|
||||
# def watch_scheduled_num(self, old_scheduled_num, new_scheduled_num):
|
||||
# logger.debug("响应", old_scheduled_num, "->", new_scheduled_num)
|
||||
# try:
|
||||
@@ -71,14 +76,27 @@ class PreparationScreen(Screen):
|
||||
# except:
|
||||
# pass
|
||||
|
||||
def _get_full_content(self):
|
||||
def load_data(self):
|
||||
content = ""
|
||||
spark_line_arr = []
|
||||
for i in self.repo.ident_index:
|
||||
n = pt.Nucleon.create_on_nucleonic_data(
|
||||
nucleonic_data=self.repo.nucleonic_data_lict.get_itemic_unit(i)
|
||||
)
|
||||
content += f" • {n['content']} \n"
|
||||
return content
|
||||
e = pt.Electron.create_on_electonic_data(electronic_data=self.repo.electronic_data_lict.get_itemic_unit(i))
|
||||
statstr = ""
|
||||
|
||||
if e.is_activated():
|
||||
statstr = '[#00ff00]A[/]'
|
||||
if e.is_due():
|
||||
statstr = '[#ffff00]R[/]'
|
||||
#statstr += ('[dim]' + str(e.rept(real_rept=True)).zfill(2)+'[/]')
|
||||
else:
|
||||
statstr = '[#ff0000]U[/]'
|
||||
spark_line_arr.append(e.rept(real_rept=True))
|
||||
content += f" {statstr} {n['content'].replace('/', '')} \n"
|
||||
self.content = content
|
||||
self.spark_line_arr = spark_line_arr
|
||||
|
||||
def action_go_back(self):
|
||||
self.app.pop_screen()
|
||||
|
||||
Reference in New Issue
Block a user