diff --git a/liteyuki/utils.py b/liteyuki/utils.py
index 629f5d7..50fe7f5 100644
--- a/liteyuki/utils.py
+++ b/liteyuki/utils.py
@@ -7,7 +7,7 @@ import inspect
import multiprocessing
import threading
from pathlib import Path
-from typing import Any, Callable, Coroutine
+from typing import Any, Callable, Coroutine, Sequence
from liteyuki.log import logger
@@ -104,3 +104,23 @@ def async_wrapper(func: Callable[..., Any]) -> Callable[..., Coroutine]:
wrapper.__signature__ = inspect.signature(func)
return wrapper
+
+
+def for_in(
+ elements: Sequence,
+ test_list: Sequence,
+):
+ """
+ 判断元素是否在列表中
+ Args:
+ elements: 元素列表
+ test_list: 测试列表
+ Returns:
+ List 在列表中的元素
+ """
+ return [element for element in elements if element in test_list]
+ # for element in elements:
+ # if element in test_list:
+ # return True
+
+ # return False
diff --git a/src/nonebot_plugins/liteyuki_status/__init__.py b/src/nonebot_plugins/liteyuki_status/__init__.py
index dc1e9d5..4e4699b 100644
--- a/src/nonebot_plugins/liteyuki_status/__init__.py
+++ b/src/nonebot_plugins/liteyuki_status/__init__.py
@@ -3,18 +3,18 @@ from .status import *
__author__ = "神羽SnowyKami & 金羿Eilles"
__plugin_meta__ = PluginMetadata(
- name="状态查看器",
+ name="灵温状态查看",
description="",
usage=(
"MARKDOWN### 状态查看器\n"
"查看机器人的状态\n"
"### 用法\n"
"- `/status` 查看基本情况\n"
- "- `/status memory` 查看内存使用情况\n"
- "- `/status process` 查看进程情况\n"
+ "- `/status -r` 强制刷新状态情况\n"
+ "- `/status -d` 使用简化markdown渲染状态\n"
),
type="application",
- homepage="https://github.com/snowykami/LiteyukiBot",
+ homepage="https://gitee.com/TriM-Organization/LiteyukiBot-TriM",
extra={
"liteyuki": True,
"toggleable": False,
diff --git a/src/nonebot_plugins/liteyuki_status/api.py b/src/nonebot_plugins/liteyuki_status/api.py
index d847708..179a0e4 100644
--- a/src/nonebot_plugins/liteyuki_status/api.py
+++ b/src/nonebot_plugins/liteyuki_status/api.py
@@ -4,16 +4,16 @@ import time
import nonebot
import psutil
from cpuinfo import cpuinfo
-from nonebot import require
from nonebot.adapters import satori
-from src.utils import __NAME__
from liteyuki import __version__
+from liteyuki.utils import for_in
+from src.utils import __NAME__
from src.utils.base.config import get_config
from src.utils.base.data_manager import TempConfig, common_db
from src.utils.base.language import Language
from src.utils.base.resource import get_loaded_resource_packs, get_path
-from src.utils.message.html_tool import template2image
+from src.utils.message.html_tool import template2image, md_to_pic
from src.utils import satori_utils
from .counter_for_satori import satori_counter
from git import Repo
@@ -32,6 +32,7 @@ protocol_names = {
6: "安卓平板",
}
+
"""
Universal Interface
data
@@ -87,6 +88,207 @@ data
# )
+# 用markdown文字展示状态卡片
+async def generate_status_card_markdown(
+ bot: dict,
+ hardware: dict,
+ liteyuki: dict,
+ lang="zh-CN",
+ motto={"text": "风朗气清", "source": "成语一则"},
+) -> bytes:
+ from .md_status_utils import (
+ markdown_status_bot_card_text,
+ markdown_status_card_text,
+ markdown_status_disk_card_text,
+ convert_size,
+ seconds2texttime,
+ )
+
+ local_dt = await get_local_data(lang)
+ bytes_suffix = " X" + local_dt["units"]["Byte"]
+ bin_units = local_dt["units"]["Bin_Units"]
+
+ markdown_status_bot_card_text__ = (
+ markdown_status_bot_card_text.replace(
+ r"{local_groups}",
+ local_dt["groups"],
+ )
+ .replace(
+ r"{local_friends}",
+ local_dt["friends"],
+ )
+ .replace(
+ r"{local_message_sent}",
+ local_dt["message_sent"],
+ )
+ .replace(
+ r"{local_message_received}",
+ local_dt["message_received"],
+ )
+ )
+
+ markdown_status_disk_card_text__ = (
+ markdown_status_disk_card_text.replace(
+ r"{local_used}",
+ local_dt["used"],
+ )
+ .replace(
+ r"{local_free}",
+ local_dt["free"],
+ )
+ .replace(
+ r"{local_total}",
+ local_dt["total"],
+ )
+ )
+
+ fnl_text = markdown_status_card_text.format(
+ local_description=local_dt["description"],
+ liteyuki_name=liteyuki["name"],
+ liteyuki_version=liteyuki["version"],
+ liteyuki_nonebot=liteyuki["nonebot"],
+ liteyuki_system=liteyuki["system"],
+ liteyuki_python=liteyuki["python"],
+ local_plugins=local_dt["plugins"],
+ liteyuki_plugins=liteyuki["plugins"],
+ local_resources=local_dt["resources"],
+ liteyuki_resources=liteyuki["resources"],
+ local_bots=local_dt["bots"],
+ liteyuki_bots=liteyuki["bots"],
+ local_runtime=local_dt["runtime"],
+ liteyuki_runtime=seconds2texttime(
+ liteyuki["runtime"],
+ unit_days=local_dt["days"],
+ unit_hours=local_dt["hours"],
+ unit_minutes=local_dt["minutes"],
+ unit_seconds=local_dt["seconds"],
+ ),
+ for_bots="\n".join(
+ [
+ markdown_status_bot_card_text__.format(
+ bot_name=s_bot["name"],
+ bot_icon=s_bot["icon"],
+ bot_app_name=s_bot["app_name"],
+ bot_protocol_name=s_bot["protocol_name"],
+ bot_groups=s_bot["groups"],
+ bot_friends=s_bot["friends"],
+ bot_message_sent=s_bot["message_sent"],
+ bot_message_received=s_bot["message_received"],
+ )
+ for s_bot in bot["bots"]
+ ]
+ ),
+ local_cpu=local_dt["cpu"],
+ hardware_cpu_percent=hardware["cpu"]["percent"],
+ hardware_cpu_name=hardware["cpu"]["name"],
+ hardware_cpu_cores=hardware["cpu"]["cores"],
+ local_cores=local_dt["cores"],
+ hardware_cpu_threads=hardware["cpu"]["threads"],
+ local_threads=local_dt["threads"],
+ hardware_cpu_freq=hardware["cpu"]["freq"] / 1000,
+ local_units_GHz=local_dt["units"]["GHz"],
+ local_memory=local_dt["memory"],
+ hardware_memory_percent=hardware["memory"]["percent"],
+ local_process=local_dt["process"],
+ hardware_memory_processmem=convert_size(
+ hardware["memory"]["usedProcess"],
+ precision=2,
+ is_unit_added=True,
+ suffix=bytes_suffix,
+ bin_units=bin_units,
+ ),
+ local_used=local_dt["used"],
+ hardware_memory_usedmem=convert_size(
+ hardware["memory"]["used"],
+ precision=2,
+ is_unit_added=True,
+ suffix=bytes_suffix,
+ bin_units=bin_units,
+ ),
+ local_free=local_dt["free"],
+ hardware_memory_freemem=convert_size(
+ hardware["memory"]["free"],
+ precision=2,
+ is_unit_added=True,
+ suffix=bytes_suffix,
+ bin_units=bin_units,
+ ),
+ local_total=local_dt["total"],
+ hardware_memory_totalmem=convert_size(
+ hardware["memory"]["total"],
+ precision=2,
+ is_unit_added=True,
+ suffix=bytes_suffix,
+ bin_units=bin_units,
+ ),
+ local_swap=local_dt["swap"],
+ hardware_swap_percent=hardware["swap"]["percent"],
+ hardware_swap_usedswap=convert_size(
+ hardware["swap"]["used"],
+ precision=2,
+ is_unit_added=True,
+ suffix=bytes_suffix,
+ bin_units=bin_units,
+ ),
+ hardware_swap_freeswap=convert_size(
+ hardware["swap"]["free"],
+ precision=2,
+ is_unit_added=True,
+ suffix=bytes_suffix,
+ bin_units=bin_units,
+ ),
+ hardware_swap_totalswap=convert_size(
+ hardware["swap"]["total"],
+ precision=2,
+ is_unit_added=True,
+ suffix=bytes_suffix,
+ bin_units=bin_units,
+ ),
+ local_disk=local_dt["disk"],
+ for_disk="\n".join(
+ [
+ markdown_status_disk_card_text__.format(
+ hardware_disk_name=s_disk["name"],
+ hardware_disk_percent=s_disk["percent"],
+ hardware_disk_useddisk=convert_size(
+ s_disk["used"],
+ precision=2,
+ is_unit_added=True,
+ suffix=bytes_suffix,
+ bin_units=bin_units,
+ ),
+ hardware_disk_freedisk=convert_size(
+ s_disk["free"],
+ precision=2,
+ is_unit_added=True,
+ suffix=bytes_suffix,
+ bin_units=bin_units,
+ ),
+ hardware_disk_totaldisk=convert_size(
+ s_disk["total"],
+ precision=2,
+ is_unit_added=True,
+ suffix=bytes_suffix,
+ bin_units=bin_units,
+ ),
+ )
+ for s_disk in hardware["disk"]
+ ]
+ ),
+ motto_text=motto["text"],
+ motto_source=motto["source"],
+ acknowledgement=get_config("status_acknowledgement"),
+ )
+
+ return await md_to_pic(fnl_text, width=540, device_scale_factor=4)
+
+
+# def gogop(x):
+# from rich.console import Console
+# Console().print(x)
+# return x
+
+
# 获取状态卡片
# bot_id 参数已经是bot参数的一部分了,不需要保留,但为了“兼容性”……
async def generate_status_card(
@@ -95,8 +297,9 @@ async def generate_status_card(
liteyuki: dict,
lang="zh-CN",
motto={"text": "风朗气清", "source": "成语一则"},
- bot_id="0",
+ bot_id="0", # 兼容性
) -> bytes:
+ # print(get_config("status_acknowledgement"))
return await template2image(
get_path("templates/status.html", abs_path=True),
{
@@ -104,15 +307,17 @@ async def generate_status_card(
"bot": bot,
"hardware": hardware,
"liteyuki": liteyuki,
- "localization": get_local_data(lang),
+ "localization": await get_local_data(lang),
"motto": motto,
+ "acknowledgement": get_config("status_acknowledgement"),
}
},
)
-def get_local_data(lang_code) -> dict:
+async def get_local_data(lang_code) -> dict:
lang = Language(lang_code)
+ bin_forcase = lang.get("status.unit.binary_middile")
return {
"friends": lang.get("status.friends"),
"groups": lang.get("status.groups"),
@@ -138,6 +343,18 @@ def get_local_data(lang_code) -> dict:
"process": lang.get("status.process"),
"resources": lang.get("status.resources"),
"description": lang.get("status.description"),
+ "units": {
+ "GHz": lang.get("status.unit.GHz"),
+ "Byte": lang.get("status.unit.Byte"),
+ "Bin_Units": [
+ (
+ ((bin_forcase + i) if "zh" in lang_code else (i + bin_forcase))
+ if i.strip()
+ else ""
+ )
+ for i in lang.get("status.unit.Bit_Units").split(";")
+ ],
+ },
}
@@ -161,7 +378,7 @@ async def get_bots_data(self_id: str = "0") -> dict:
groups = str(await satori_utils.count_groups(bot))
friends = str(await satori_utils.count_friends(bot))
status = {}
- version_info = await bot.get_version_info()
+ version_info = await bot.get_version_info() # type: ignore
except Exception:
pass
else:
@@ -210,7 +427,8 @@ async def get_bots_data(self_id: str = "0") -> dict:
return result
-async def get_hardware_data() -> dict:
+async def get_hardware_data(lang_code) -> dict:
+ lang = Language(lang_code)
mem = psutil.virtual_memory()
all_processes = psutil.Process().children(recursive=True)
all_processes.append(psutil.Process())
@@ -227,30 +445,27 @@ async def get_hardware_data() -> dict:
except Exception:
pass
swap = psutil.swap_memory()
- cpu_brand_raw = cpuinfo.get_cpu_info().get("brand_raw", "未知处理器")
- if "amd" in cpu_brand_raw.lower():
- brand = "AMD"
- elif "intel" in cpu_brand_raw.lower():
- brand = "英特尔"
- elif "apple" in cpu_brand_raw.lower():
- brand = "苹果"
- elif "qualcomm" in cpu_brand_raw.lower():
- brand = "高通"
- elif "mediatek" in cpu_brand_raw.lower():
- brand = "联发科"
- elif "samsung" in cpu_brand_raw.lower():
- brand = "三星"
- elif "nvidia" in cpu_brand_raw.lower():
- brand = "英伟达"
+ cpu_infos = cpuinfo.get_cpu_info()
+ cpu_brand_raw = cpu_infos.get(
+ "hardware_raw",
+ cpu_infos.get("brand_raw", "未知处理器"), # 此处之汉文不会被直接使用
+ ).lower()
+ if cpu_brand_selected := for_in(
+ ("amd", "intel", "apple", "qualcomm", "mediatek", "samsung", "nvidia"),
+ cpu_brand_raw,
+ ):
+ brand = lang.get("status.cpubrand." + cpu_brand_selected[0])
else:
- brand = "未知处理器"
+ brand = lang.get("status.cpubrand.unknown")
result = {
"cpu": {
"percent": psutil.cpu_percent(),
- "name": f"{brand} {cpuinfo.get_cpu_info().get('arch', '未知架构')}",
+ "name": "{} {}".format(
+ brand, cpu_infos.get("arch_string_raw", lang.get("status.arch.unknown"))
+ ),
"cores": psutil.cpu_count(logical=False),
"threads": psutil.cpu_count(logical=True),
- "freq": psutil.cpu_freq().current, # MHz
+ "freq": psutil.cpu_freq().current, # 单位 MHz
},
"memory": {
"percent": mem.percent,
@@ -268,25 +483,39 @@ async def get_hardware_data() -> dict:
"disk": [],
}
+ other_disk = {
+ "name": lang.get("status.disk.other"),
+ "percent": 0,
+ "total": 0,
+ "used": 0,
+ "free": 0,
+ }
for disk in psutil.disk_partitions(all=True):
try:
disk_usage = psutil.disk_usage(disk.mountpoint)
if disk_usage.total == 0 or disk.mountpoint.startswith(
("/var", "/boot", "/run", "/proc", "/sys", "/dev", "/tmp", "/snap")
):
- continue # 虚拟磁盘
- result["disk"].append(
- {
- "name": disk.mountpoint,
- "percent": disk_usage.percent,
- "total": disk_usage.total,
- "used": disk_usage.used,
- "free": disk_usage.free,
- }
- )
+ other_disk["percent"] = (other_disk["percent"] + disk_usage.percent) / 2
+ other_disk["total"] += disk_usage.total
+ other_disk["used"] += disk_usage.used
+ other_disk["free"] += disk_usage.free
+ else:
+ result["disk"].append(
+ {
+ "name": disk.mountpoint,
+ "percent": disk_usage.percent,
+ "total": disk_usage.total,
+ "used": disk_usage.used,
+ "free": disk_usage.free,
+ }
+ )
except:
pass
+ if other_disk["total"] > 0: # 避免除零错误
+ result["disk"].append(other_disk)
+
return result
diff --git a/src/nonebot_plugins/liteyuki_status/md_status_utils.py b/src/nonebot_plugins/liteyuki_status/md_status_utils.py
new file mode 100644
index 0000000..7486929
--- /dev/null
+++ b/src/nonebot_plugins/liteyuki_status/md_status_utils.py
@@ -0,0 +1,123 @@
+markdown_status_bot_card_text = """
+### **{bot_name} |
**
+
+ - {bot_app_name} : {bot_protocol_name}
+ - {local_groups}{bot_groups} | {local_friends}{bot_friends} | {local_message_sent}{bot_message_sent} | {local_message_received}{bot_message_received}
+"""
+
+markdown_status_disk_card_text = """ - {hardware_disk_name}
+
+\t{local_used} {hardware_disk_useddisk} {hardware_disk_percent}% | {local_free} {hardware_disk_freedisk} | {local_total} {hardware_disk_totaldisk}"""
+
+markdown_status_card_text = """
+
{local_description}
+
+
{liteyuki_name} - 睿乐
+
+ - 灵温 {liteyuki_version} | Nonebot {liteyuki_nonebot}
+ - {liteyuki_system} {liteyuki_python}
+ - {local_plugins}{liteyuki_plugins} | {local_resources}{liteyuki_resources} | {local_bots}{liteyuki_bots}
+ - {local_runtime}{liteyuki_runtime}
+
+{for_bots}
+
+## {local_cpu} : {hardware_cpu_percent}%
+
+ - {hardware_cpu_name} | {hardware_cpu_cores}{local_cores} {hardware_cpu_threads}{local_threads} | {hardware_cpu_freq}{local_units_GHz}
+
+
+## {local_memory} : {hardware_memory_percent}%
+
+ - {local_process} {hardware_memory_processmem}
+ - {local_used} {hardware_memory_usedmem}
+ - {local_free} {hardware_memory_freemem}
+ - {local_total} {hardware_memory_totalmem}
+
+## {local_swap} : {hardware_swap_percent}%
+
+ - {local_used} {hardware_swap_usedswap}
+ - {local_free} {hardware_swap_freeswap}
+ - {local_total} {hardware_swap_totalswap}
+
+## {local_disk}
+
+{for_disk}
+
+-----------------------
+
+### {motto_text}
+
+——{motto_source}
+
+#### {acknowledgement}
+
+#### 该页样式由
![](https://q.qlogo.cn/g?b=qq&nk=3657522512&s=640)
金羿Eilles 设计
+"""
+
+
+def convert_size(
+ size: int | float,
+ precision: int = 2,
+ is_unit_added: bool = True,
+ suffix: str = " X字节",
+ bin_units: list[str] = ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"],
+):
+ """
+ 将字节转换为带单位的大小
+
+ :param size: 要转换的字节大小
+ :param precision: 保留小数位数
+ :param is_unit_added: 是否添加单位
+ :param suffix: 单位后缀
+ :param bin_units: 单位列表
+ :return: 转换后的大小字符串
+ """
+ is_negative = size < 0
+ size = abs(size)
+ # let units = ["", "千", "兆", "吉", "太", "拍", "艾", "泽"];
+ unit = ""
+
+ for sg_unit in bin_units:
+ if size < 1024:
+ unit = sg_unit
+ break
+ size /= 1024
+
+ if is_negative:
+ size = -size
+
+ if is_unit_added:
+ return ("{" + ":.{}f".format(precision) + "}").format(size) + suffix.replace(
+ "X", unit
+ )
+ else:
+ return size
+
+
+def seconds2texttime(
+ seconds: int,
+ unit_days: str = "日",
+ unit_hours: str = "时",
+ unit_minutes: str = "分",
+ unit_seconds: str = "秒",
+):
+ """
+ 将秒数转换为时间文本
+
+ :param seconds: 要转换的秒数
+ :param unit_days: 天的单位
+ :param unit_hours: 小时的单位
+ :param unit_minutes: 分钟的单位
+ :param unit_seconds: 秒的单位
+ :return: 转换后的时间文本
+ """
+ return "{dt}{ld} {ht}{lh} {mt}{lm} {st}{ls}".format(
+ dt=seconds // 86400,
+ ld=unit_days,
+ ht=(seconds % 86400) // 3600,
+ lh=unit_hours,
+ mt=(seconds % 3600) // 60,
+ lm=unit_minutes,
+ st=seconds % 60,
+ ls=unit_seconds,
+ )
diff --git a/src/nonebot_plugins/liteyuki_status/status.py b/src/nonebot_plugins/liteyuki_status/status.py
index ecf9c26..12a4102 100644
--- a/src/nonebot_plugins/liteyuki_status/status.py
+++ b/src/nonebot_plugins/liteyuki_status/status.py
@@ -2,6 +2,7 @@ import random
import aiohttp
import zhDateTime
+from nonebot import require
from src.utils import event as event_utils
from src.utils.base.language import get_user_lang, get_default_lang_code, Language
@@ -35,6 +36,12 @@ status_alc = on_alconna(
alias={"refr", "r", "刷新"},
action=store_true,
),
+ Option(
+ "-t|-md|--markdown",
+ default=False,
+ # alias={"refr", "r", "刷新"},
+ action=store_true,
+ ),
Subcommand(
"memory",
alias={"mem", "m", "内存"},
@@ -72,7 +79,7 @@ yanlun_path = "https://nd.liteyuki.icu/api/v3/share/content/Xpue?path=null"
# 每天4点更新
@scheduler.scheduled_job("cron", hour=4)
async def every_day_update():
- ulang = Language(get_default_lang_code(), "zh-WY")
+ ulang = Language(get_default_lang_code(), "zh-CN")
nonebot.logger.success(
ulang.get("yanlun.refresh.success", COUNT=await update_yanlun())
)
@@ -88,7 +95,7 @@ async def update_yanlun():
resp = await client.get(yanlun_path, timeout=15)
yanlun_texts = (await resp.text()).strip("\n").split("\n")
except (ConnectionError, aiohttp.ClientError, aiohttp.WebSocketError) as err:
- nonebot.logger.warning("读取言·论信息发生 客户端或通道 错误:\n{}".format(err))
+ nonebot.logger.warning("读取言·论信息发生 连接 错误:\n{}".format(err))
yanlun_texts = ["以梦想为驱使 创造属于自己的未来"]
# noinspection PyBroadException
except BaseException as err:
@@ -117,14 +124,22 @@ async def _():
yanlun_seqs = yanlun_texts = ["金羿ELS 生日快乐~!", "Happy Birthday, Eilles!"]
elif solar_date == (8, 6):
yanlun_seqs = yanlun_texts = [
- "诸葛亮与八卦阵 生日快乐~!",
- "Happy Birthday, bgArray~!",
+ "玉衡 生日快乐~!",
+ "Happy Birthday, Alioth~!",
]
elif solar_date == (8, 16):
yanlun_seqs = yanlun_texts = [
"鱼旧梦 生日快乐~!",
"Happy Birthday, ElapsingDreams~!",
]
+ elif lunar_date == (1, 1):
+ yanlun_seqs = yanlun_texts = [
+ "新春快乐~",
+ "千门万户曈曈日,总把新桃换旧符\t——王安石《元日》",
+ "爆竹声中一岁除,春风送暖入屠苏\t——王安石《元日》",
+ "半盏屠苏犹未举,灯前小草写桃符\t—— 陆游《除夜雪》",
+ "愿得长如此,年年物候新\t—— 卢照邻《元日述怀》",
+ ]
else:
await update_yanlun()
@@ -163,13 +178,25 @@ async def _(
)
):
status_card_cache[ulang.lang_code] = (
- await generate_status_card(
- bot=await get_bots_data(),
- hardware=await get_hardware_data(),
- liteyuki=await get_liteyuki_data(),
- lang=ulang.lang_code,
- motto=dict(zip(["text", "source"], random_yanlun())),
- bot_id=bot.self_id,
+ (
+ await generate_status_card_markdown(
+ bot=await get_bots_data(),
+ hardware=await get_hardware_data(ulang.lang_code),
+ liteyuki=await get_liteyuki_data(),
+ lang=ulang.lang_code,
+ motto=dict(zip(["text", "source"], random_yanlun())),
+ )
+ if result.options["markdown"].value
+ else (
+ await generate_status_card(
+ bot=await get_bots_data(),
+ hardware=await get_hardware_data(ulang.lang_code),
+ liteyuki=await get_liteyuki_data(),
+ lang=ulang.lang_code,
+ motto=dict(zip(["text", "source"], random_yanlun())),
+ bot_id=bot.self_id,
+ )
+ )
),
time.time(),
)
diff --git a/src/nonebot_plugins/trimo_plugin_msctconverter/mspvexec.py b/src/nonebot_plugins/trimo_plugin_msctconverter/mspvexec.py
index 47e2922..c0f7edb 100644
--- a/src/nonebot_plugins/trimo_plugin_msctconverter/mspvexec.py
+++ b/src/nonebot_plugins/trimo_plugin_msctconverter/mspvexec.py
@@ -53,6 +53,7 @@ from .msctexec import (
add_memory_to_temporary,
read_memory_from_temporary,
get_stored_path,
+ get_user_lang,
)
from .utils import hanzi_timeid
@@ -116,6 +117,7 @@ async def _(
nonebot.logger.info(result.options)
usr_id = event.get_user_id()
+ ulang = get_user_lang(usr_id)
superuser_permission = await SUPERUSER(bot, event)
@@ -124,9 +126,10 @@ async def _(
):
await mspv_sync.finish(
UniMessage.text(
- "转换点数不足,当前剩余:⌊p⌋≈{:.2f}|{}".format(
- qres[1],
- configdict["maxPersonConvert"]["music"],
+ ulang.get(
+ "convet.not_enough_point",
+ NOW=qres[1],
+ TOTAL=configdict["maxPersonConvert"]["music"],
)
),
at_sender=True,
@@ -168,12 +171,18 @@ async def _(
)
):
await mspv_sync.finish(
- UniMessage.text("服务器内未存入你的任何文件,请先上传midi文件吧")
+ UniMessage.text(ulang.get("convert.no_file", TYPE="midi"))
)
if _args["mode"] not in [0, 1, 2, 3, 4]:
await mspv_sync.finish(
- UniMessage.text("模式 {} 不存在,请详阅文档。".format(_args["mode"]))
+ UniMessage.text(
+ ulang.get(
+ "convert.something_not_exist",
+ WHAT="模式",
+ NAME=_args["mode"],
+ )
+ )
)
if _args["get-value-method"] not in [
@@ -182,7 +191,11 @@ async def _(
]:
await mspv_sync.finish(
UniMessage.text(
- "取值法 {} 不存在,请详阅文档。".format(_args["get-value-method"])
+ ulang.get(
+ "convert.something_not_exist",
+ WHAT="取值法",
+ NAME=_args["get-value-method"],
+ )
)
)
@@ -212,7 +225,11 @@ async def _(
pitched_notechart.update(json.load(_ppnt.open("r")))
else:
await mspv_sync.finish(
- UniMessage.text("乐器对照表 {} 不存在".format(_args["pitched-note-table"]))
+ ulang.get(
+ "convert.something_not_exist",
+ WHAT="乐音乐器对照表",
+ NAME=_args["pitched-note-table"],
+ )
)
return
@@ -240,7 +257,11 @@ async def _(
else:
await mspv_sync.finish(
UniMessage.text(
- "乐器对照表 {} 不存在".format(_args["percussion-note-table"])
+ ulang.get(
+ "convert.something_not_exist",
+ WHAT="打击乐器对照表",
+ NAME=_args["percussion-note-table"],
+ )
)
)
return
@@ -257,7 +278,11 @@ async def _(
else:
await mspv_sync.finish(
UniMessage.text(
- "音量处理曲线 {} 不存在".format(_args["volume-processing-function"])
+ ulang.get(
+ "convert.something_not_exist",
+ WHAT="音量处理曲线",
+ NAME=_args["volume-processing-function"],
+ )
)
)
return
@@ -274,10 +299,10 @@ async def _(
random.random() % 1.6 + 1.3,
)
if not res:
- buffer.write("中途退出,转换点不足:{}\n".format(pnt))
+ buffer.write(ulang.get("convert.break.not_enough_point", NOW=pnt))
return res
- await mspv_sync.send(UniMessage.text("转换开始……"))
+ await mspv_sync.send(UniMessage.text(ulang.get("convert.start")))
try:
diff --git a/src/resources/trim_plugin_msctconverter/lang/zh-CN.lang b/src/resources/trim_plugin_msctconverter/lang/zh-CN.lang
index a0df149..47e2e89 100644
--- a/src/resources/trim_plugin_msctconverter/lang/zh-CN.lang
+++ b/src/resources/trim_plugin_msctconverter/lang/zh-CN.lang
@@ -12,7 +12,7 @@ writefile.write_success=文件{NAME}已写入{SIZE}字节
convet.not_enough_point=转换点数不足,当前剩余:⌊p⌋≈{NOW:.2f}|{TOTAL}
convert.break.not_enough_point=中途退出,转换点不足:{NOW}
convert.no_file=服务器内未存入你的任何文件,请先上传{TYPE}文件吧
-convert.something_not_exist={WHAT} {NAME} 不存在
+convert.something_not_exist={WHAT} {NAME} 不存在,请详阅文档。
convert.start=转换开始……
cmd2struct.axis_wrong=生成结构的生成方向格式错误,输入数据应符合“轴正负”(如x+、z-)的格式。
diff --git a/src/resources/trim_plugin_msctconverter/lang/zh-WY.lang b/src/resources/trim_plugin_msctconverter/lang/zh-WY.lang
index 308470c..20b0ffb 100644
--- a/src/resources/trim_plugin_msctconverter/lang/zh-WY.lang
+++ b/src/resources/trim_plugin_msctconverter/lang/zh-WY.lang
@@ -13,6 +13,6 @@ convet.not_enough_point=点阙,余{NOW:.2f},满{TOTAL}
convert.break.not_enough_point=点阙而不可继,现{NOW}
convert.no_file=无案机内,先传之{TYPE}
convert.table_not_exist={WHAT}曰 {NAME} 者虚
-convert.start=始……
+convert.start=始变之……
cmd2struct.axis_wrong=产型误指,应合此法,曰“轴正负”,类x+、z-。
diff --git a/src/resources/vanilla_language/lang/en.lang b/src/resources/vanilla_language/lang/en.lang
index 8c31470..2de85f2 100644
--- a/src/resources/vanilla_language/lang/en.lang
+++ b/src/resources/vanilla_language/lang/en.lang
@@ -30,8 +30,8 @@ liteyuki.list_resources=Resource Pack List
liteyuki.reload_resources_success=Resource reload successful, {NUM} resource packs in total
liteyuki.loaded_resources={NUM} resource packs loaded, sorted by priority
liteyuki.unloaded_resources=Unloaded resource packs
-liteyuki.load_resource_success=Resource pack {NAME} loaded successfully
-liteyuki.unload_resource_success=Resource pack {NAME} unloaded successfully
+liteyuki.load_resource_success=Resource pack {NAME} successfully loaded
+liteyuki.unload_resource_success=Resource pack {NAME} successfully unloaded
liteyuki.load_resource_failed=Failed to load resource pack {NAME}
liteyuki.unload_resource_failed=Failed to unload resource pack {NAME}
liteyuki.resource_not_found=Resource pack {NAME} does not exist or is not operable
@@ -39,12 +39,12 @@ liteyuki.resource_already_loaded=Resource pack {NAME} already loaded, do not rep
liteyuki.resource_already_unloaded=Resource pack {NAME} already unloaded, do not repeat operation
liteyuki.need_reload=Please {BTN} reload to apply these updates
liteyuki.dont_repeat=Do not repeat operation
-liteyuki.change_priority_success=Resource pack {NAME} priority changed successfully
+liteyuki.change_priority_success=Resource pack {NAME} priority successfully changed
liteyuki.change_priority_failed=Failed to change priority of resource pack {NAME}
liteyuki.group_already=Group {GROUP} is already {STATUS}, no need to repeat operation
liteyuki.group_success=Group {GROUP} {STATUS} successful
liteyuki.permission_denied=Permission denied
-liteyuki.config_remove_success=Configuration {KEY} removed successfully
+liteyuki.config_remove_success=Configuration {KEY} successfully removed
main.current_language=Current configuration language is: {LANG}
main.enable_webdash=Web monitoring panel enabled: {URL}
@@ -75,14 +75,14 @@ npm.uninstall=Uninstall
npm.installing=Installing {NAME}
npm.cannot_uninstall=Cannot Uninstall
npm.no_description=No Description
-npm.store_update_success=Plugin store data updated successfully
+npm.store_update_success=Plugin store data successfully updated
npm.store_update_failed=Plugin store data update failed
npm.search_result=Search Result
npm.search_no_result=No search result
npm.too_many_results=Too many items, {HIDE_NUM} items hidden, please limit the keyword search
-npm.install_success={NAME} installed successfully
+npm.install_success={NAME} has been successfully installed
npm.install_failed={NAME} installation failed, please check the log for detailed information. If you cannot resolve it, visit {HOMEPAGE} for help
-npm.uninstall_success={NAME} uninstalled successfully, effective next restart
+npm.uninstall_success={NAME} successfully uninstalled, effective after next restart
npm.uninstall_failed={NAME} uninstallation failed
npm.load_failed={NAME} loading failed, please check the console for detailed information, check if dependencies or configurations are correct, if cannot resolve, visit {HOMEPAGE} for help
npm.plugin_not_found={NAME} not found in the store, please try updating the store information or checking the spelling
@@ -122,7 +122,7 @@ user.profile.location.desc=Set user location information
user.profile.nickname=Nickname
user.profile.nickname.desc=Set how the bot calls the user
user.profile.input_value=Please enter the value of {ATTR}
-user.profile.set_success={ATTR} set to {VALUE} successfully
+user.profile.set_success={ATTR} has been successfully set to {VALUE}
user.profile.set_failed=Failed to set {ATTR}, please check the input legality
rpm.move_up=Move Up
@@ -157,3 +157,31 @@ status.cores=Core(s)
status.threads=Thread(s)
status.process=Processe(s)
status.description=Liteyuki Dashboard
+
+status.cpubrand.amd=AMD
+status.cpubrand.intel=Intel
+status.cpubrand.apple=Apple
+status.cpubrand.qualcomm=Qualcomm
+status.cpubrand.mediatek=MediaTeK
+status.cpubrand.samsung=SamSung
+status.cpubrand.nvidia=NVidia
+status.cpubrand.huawei=Huawei
+status.cpubrand.unknown=Unknown
+
+status.arch.unknown=??
+status.disk.other=Virtual and Other Disk
+
+status.unit.GHz=GHz
+status.unit.Byte=B
+status.unit.binary_middile=i
+status.unit.Bit_Units= ;K;M;G;T;P;E;Z;Y;R;Q
+
+yanlun.refresh.success=Yanlun cuccessfully updated to {COUNT} pieces now.
+yanlun.refresh.failed=Error {ERR} occured in updating Yanlun with code {ERRCODE}
+yanlun.errtype.net=Connection Error
+yanlun.errtype.unknown=Unknown Error
+yanlun.count.head=FromtttCount(Percentage)
+yanlun.count.tail=...({NUM} in Total)
+yanlun.length.toolong=Too many Yanlun to display
+yanlun.length.tooshort=Too few Yanlun to display
+yanlun.length.float=The number of Yanlun must be an integer, not a float
diff --git a/src/resources/vanilla_language/lang/zh-CN.lang b/src/resources/vanilla_language/lang/zh-CN.lang
index bf93aa6..62c91d0 100644
--- a/src/resources/vanilla_language/lang/zh-CN.lang
+++ b/src/resources/vanilla_language/lang/zh-CN.lang
@@ -155,15 +155,33 @@ status.minutes=分
status.seconds=秒
status.cores=核心
status.threads=线程
-status.process=进程
+status.process=进程占用
status.description=轻雪机器人状态面板
+status.cpubrand.amd=超微
+status.cpubrand.intel=英特尔
+status.cpubrand.apple=苹果
+status.cpubrand.qualcomm=高通
+status.cpubrand.mediatek=联发科
+status.cpubrand.samsung=三星
+status.cpubrand.nvidia=英伟达
+status.cpubrand.huawei=华为
+status.cpubrand.unknown=未知处理器
+
+status.arch.unknown=未知架构
+status.disk.other=虚拟磁盘及其他
+
+status.unit.GHz=吉赫兹
+status.unit.Byte=字节
+status.unit.binary_middile=二幂
+status.unit.Bit_Units= ;千;兆;吉;太;拍;艾;泽;尧;容;昆
+
yanlun.refresh.success=言·论 更新成功,共 {COUNT} 条
yanlun.refresh.failed=更新 言·论 信息发生 {ERR} 错误:{ERRCODE}
yanlun.errtype.net=互联网连接
yanlun.errtype.unknown=未知
yanlun.count.head=出处ttt数量(占比)
yanlun.count.tail=...(共 {NUM} 条)
-yanlun.length.toolong=言·论过长
-yanlun.length.tooshort=言·论过短
-yanlun.length.float=言·论不可是非整数长度
+yanlun.length.toolong=言·论过多
+yanlun.length.tooshort=言·论过少
+yanlun.length.float=言·论数量不可为非整数
diff --git a/src/resources/vanilla_language/lang/zh-HK.lang b/src/resources/vanilla_language/lang/zh-HK.lang
index de108fa..aa812dc 100644
--- a/src/resources/vanilla_language/lang/zh-HK.lang
+++ b/src/resources/vanilla_language/lang/zh-HK.lang
@@ -155,4 +155,33 @@ status.minutes=分鐘
status.seconds=秒
status.cores=核心
status.threads=線程
-status.process=進程
\ No newline at end of file
+status.process=進程所占用
+status.description=轻雪 Bot 狀態面板
+
+status.cpubrand.amd=超威
+status.cpubrand.intel=英特爾
+status.cpubrand.apple=蘋果
+status.cpubrand.qualcomm=高通
+status.cpubrand.mediatek=聯發科
+status.cpubrand.samsung=三星
+status.cpubrand.nvidia=英偉達
+status.cpubrand.huawei=華為
+status.cpubrand.unknown=未知處理器
+
+status.arch.unknown=未知架構
+status.disk.other=虛擬磁碟和其他
+
+status.unit.GHz=吉赫茲
+status.unit.Byte=位元組
+status.unit.binary_middile=二進
+status.unit.Bit_Units= ;千;百萬;吉;兆;拍;艾;皆;佑;羅;昆
+
+yanlun.refresh.success=言·論 成功更新得 {COUNT} 條
+yanlun.refresh.failed=言·論因 {ERR} 其 {ERRCODE} 而無法更新
+yanlun.errtype.net=網際網路連結
+yanlun.errtype.unknown=不可知
+yanlun.count.head=出處ttt數目(比例)
+yanlun.count.tail=...(縂 {NUM} 條)
+yanlun.length.toolong=言·論數目不可過多
+yanlun.length.tooshort=言·論數目不可為無或負
+yanlun.length.float=言·論數目不可謂為小數
diff --git a/src/resources/vanilla_language/lang/zh-WY.lang b/src/resources/vanilla_language/lang/zh-WY.lang
index 772c5ac..58c17c7 100644
--- a/src/resources/vanilla_language/lang/zh-WY.lang
+++ b/src/resources/vanilla_language/lang/zh-WY.lang
@@ -148,14 +148,14 @@ status.usage=计用
status.total=合
status.used=占
status.free=余
-status.runtime=所启时分
+status.runtime=运期
status.days=日
status.hours=小时
status.minutes=分
status.seconds=秒
-status.cores=轮核
-status.threads=程线
-status.process=行轨
+status.cores=核
+status.threads=线程
+status.process=进程占
status.description=轻雪灵机台
yanlun.refresh.success=言·论 方新,合{COUNT}条
diff --git a/src/resources/vanilla_resource/templates/img/bg1.jpg b/src/resources/vanilla_resource/templates/img/bg1.jpg
index 3c884f7..809a8ef 100644
Binary files a/src/resources/vanilla_resource/templates/img/bg1.jpg and b/src/resources/vanilla_resource/templates/img/bg1.jpg differ
diff --git a/src/resources/vanilla_resource/templates/img/bg4.jpg b/src/resources/vanilla_resource/templates/img/bg4.jpg
index 5e93522..21986bc 100644
Binary files a/src/resources/vanilla_resource/templates/img/bg4.jpg and b/src/resources/vanilla_resource/templates/img/bg4.jpg differ
diff --git a/src/resources/vanilla_resource/templates/js/status.js b/src/resources/vanilla_resource/templates/js/status.js
index 4344c7a..b6747d9 100644
--- a/src/resources/vanilla_resource/templates/js/status.js
+++ b/src/resources/vanilla_resource/templates/js/status.js
@@ -1,9 +1,12 @@
const data = JSON.parse(document.getElementById("data").innerText);
const bot_data = data["bot"]; // 机器人数据
-const hardwareData = data["hardware"]; // 硬件数据
-const liteyukiData = data["liteyuki"]; // LiteYuki数据
-const localData = data["localization"]; // 本地化语言数据
+const hardware_data = data["hardware"]; // 硬件数据
+const liteyuki_data = data["liteyuki"]; // LiteYuki数据
+const local_data = data["localization"]; // 本地化语言数据
const motto_ = data["motto"]; // 言论数据
+const acknowledgement = data["acknowledgement"]; // 鸣谢内容数据
+const o_units = local_data["units"]; // 单位的翻译
+const bin_units = o_units["Bin_Units"]; // 字节单位(千、兆…)
/**
* 创建CPU/内存/交换饼图
@@ -64,15 +67,20 @@ function createPieChartOption(title, data) {
};
}
-function convertSize(size, precision = 2, addUnit = true, suffix = " X字节") {
+function convertSize(
+ size,
+ precision = 2,
+ addUnit = true,
+ suffix = ` X${o_units["Byte"]}`
+) {
let isNegative = size < 0;
size = Math.abs(size);
- let units = ["", "千", "兆", "吉", "太", "拍", "艾", "泽"];
+ // let units = ["", "千", "兆", "吉", "太", "拍", "艾", "泽"];
let unit = "";
- for (let i = 0; i < units.length; i++) {
+ for (let i = 0; i < bin_units.length; i++) {
if (size < 1024) {
- unit = units[i];
+ unit = bin_units[i];
break;
}
size /= 1024;
@@ -125,7 +133,7 @@ function secondsToTextTime(seconds) {
let hours = Math.floor((seconds % 86400) / 3600);
let minutes = Math.floor((seconds % 3600) / 60);
let seconds_ = Math.floor(seconds % 60);
- return `${days}${localData["days"]} ${hours}${localData["hours"]} ${minutes}${localData["minutes"]} ${seconds_}${localData["seconds"]}`;
+ return `${days}${local_data["days"]} ${hours}${local_data["hours"]} ${minutes}${local_data["minutes"]} ${seconds_}${local_data["seconds"]}`;
}
// 主函数
@@ -140,15 +148,17 @@ function main() {
// 设置机器人信息
botInfoDiv.className = "info-box bot-info";
- botInfoDiv.querySelector(".bot-icon-img").setAttribute("src", bot["icon"]);
+ botInfoDiv
+ .querySelector(".bot-icon-img")
+ .setAttribute("src", bot["icon"]);
botInfoDiv.querySelector(".bot-name").innerText = bot["name"];
let tagArray = [
bot["protocol_name"],
`${bot["app_name"]}`,
- `${localData["groups"]}${bot["groups"]}`,
- `${localData["friends"]}${bot["friends"]}`,
- `${localData["message_sent"]}${bot["message_sent"]}`,
- `${localData["message_received"]}${bot["message_received"]}`,
+ `${local_data["groups"]}${bot["groups"]}`,
+ `${local_data["friends"]}${bot["friends"]}`,
+ `${local_data["message_sent"]}${bot["message_sent"]}`,
+ `${local_data["message_received"]}${bot["message_received"]}`,
];
// 添加一些标签
tagArray.forEach((tag, index) => {
@@ -156,7 +166,10 @@ function main() {
tagSpan.className = "bot-tag";
tagSpan.innerText = tag;
// 给最后一个标签不添加后缀
- tagSpan.setAttribute("suffix", index === 0 || tag[0] == "\n" ? "0" : "1");
+ tagSpan.setAttribute(
+ "suffix",
+ index === 0 || tag[0] == "\n" ? "0" : "1"
+ );
botInfoDiv.querySelector(".bot-tags").appendChild(tagSpan);
});
document.body.insertBefore(
@@ -176,24 +189,27 @@ function main() {
.setAttribute("src", "./img/litetrimo.png");
liteyukiInfoDiv.querySelector(
".bot-name"
- ).innerText = `${liteyukiData["name"]} - 睿乐`;
+ ).innerText = `${liteyuki_data["name"]} - 睿乐`;
let tagArray = [
- `灵温 ${liteyukiData["version"]}`,
- `Nonebot ${liteyukiData["nonebot"]}`,
- `${liteyukiData["python"]}`,
- liteyukiData["system"],
- `${localData["plugins"]}${liteyukiData["plugins"]}`,
- `${localData["resources"]}${liteyukiData["resources"]}`,
- `${localData["bots"]}${liteyukiData["bots"]}`,
- `${localData["runtime"]} ${secondsToTextTime(liteyukiData["runtime"])}`,
+ `灵温 ${liteyuki_data["version"]}`,
+ `Nonebot ${liteyuki_data["nonebot"]}`,
+ `${liteyuki_data["python"]}`,
+ liteyuki_data["system"],
+ `${local_data["plugins"]}${liteyuki_data["plugins"]}`,
+ `${local_data["resources"]}${liteyuki_data["resources"]}`,
+ `${local_data["bots"]}${liteyuki_data["bots"]}`,
+ `${local_data["runtime"]} ${secondsToTextTime(liteyuki_data["runtime"])}`,
];
tagArray.forEach((tag, index) => {
let tagSpan = document.createElement("span");
tagSpan.className = "bot-tag";
tagSpan.innerText = tag;
// 给最后一个标签不添加后缀
- tagSpan.setAttribute("suffix", index === 0 || tag[0] == "\n" ? "0" : "1");
+ tagSpan.setAttribute(
+ "suffix",
+ index === 0 || tag[0] == "\n" ? "0" : "1"
+ );
liteyukiInfoDiv.querySelector(".bot-tags").appendChild(tagSpan);
});
document.body.insertBefore(
@@ -202,27 +218,27 @@ function main() {
); // 插入对象
// 添加硬件信息
- const cpuData = hardwareData["cpu"];
- const memData = hardwareData["memory"];
- const swapData = hardwareData["swap"];
+ const cpuData = hardware_data["cpu"];
+ const memData = hardware_data["memory"];
+ const swapData = hardware_data["swap"];
const cpuTagArray = [
cpuData["name"],
- `${cpuData["cores"]}${localData["cores"]} ${cpuData["threads"]}${localData["threads"]}`,
- `${(cpuData["freq"] / 1000).toFixed(2)}吉赫兹`,
+ `${cpuData["cores"]}${local_data["cores"]} ${cpuData["threads"]}${local_data["threads"]}`,
+ `${(cpuData["freq"] / 1000).toFixed(2)}${o_units["GHz"]}`,
];
const memTagArray = [
- `${localData["process"]} ${convertSize(memData["usedProcess"])}`,
- `${localData["used"]} ${convertSize(memData["used"])}`,
- `${localData["free"]} ${convertSize(memData["free"])}`,
- `${localData["total"]} ${convertSize(memData["total"])}`,
+ `${local_data["process"]} ${convertSize(memData["usedProcess"])}`,
+ `${local_data["used"]} ${convertSize(memData["used"])}`,
+ `${local_data["free"]} ${convertSize(memData["free"])}`,
+ `${local_data["total"]} ${convertSize(memData["total"])}`,
];
const swapTagArray = [
- `${localData["used"]} ${convertSize(swapData["used"])}`,
- `${localData["free"]} ${convertSize(swapData["free"])}`,
- `${localData["total"]} ${convertSize(swapData["total"])}`,
+ `${local_data["used"]} ${convertSize(swapData["used"])}`,
+ `${local_data["free"]} ${convertSize(swapData["free"])}`,
+ `${local_data["total"]} ${convertSize(swapData["total"])}`,
];
let cpuDeviceInfoDiv = document.importNode(
document.getElementById("device-info").content,
@@ -237,8 +253,12 @@ function main() {
true
);
- cpuDeviceInfoDiv.querySelector(".device-info").setAttribute("id", "cpu-info");
- memDeviceInfoDiv.querySelector(".device-info").setAttribute("id", "mem-info");
+ cpuDeviceInfoDiv
+ .querySelector(".device-info")
+ .setAttribute("id", "cpu-info");
+ memDeviceInfoDiv
+ .querySelector(".device-info")
+ .setAttribute("id", "mem-info");
swapDeviceInfoDiv
.querySelector(".device-info")
.setAttribute("id", "swap-info");
@@ -276,7 +296,10 @@ function main() {
tagDiv.className = "device-tag";
tagDiv.innerText = tag;
// 给最后一个标签不添加后缀
- tagDiv.setAttribute("suffix", index === tagArray.length - 1 ? "0" : "1");
+ tagDiv.setAttribute(
+ "suffix",
+ index === tagArray.length - 1 ? "0" : "1"
+ );
devices[device].querySelector(".device-tags").appendChild(tagDiv);
});
}
@@ -292,7 +315,7 @@ function main() {
cpuChart.setOption(
createPieChartOption(
- `${localData["cpu"]}\n${cpuData["percent"].toFixed(1)}%`,
+ `${local_data["cpu"]}\n${cpuData["percent"].toFixed(1)}%`,
[
{ name: "used", value: cpuData["percent"] },
{ name: "free", value: 100 - cpuData["percent"] },
@@ -302,10 +325,13 @@ function main() {
memChart.setOption(
createPieChartOption(
- `${localData["memory"]}\n${memData["percent"].toFixed(1)}%`,
+ `${local_data["memory"]}\n${memData["percent"].toFixed(1)}%`,
[
{ name: "process", value: memData["usedProcess"] },
- { name: "used", value: memData["used"] - memData["usedProcess"] },
+ {
+ name: "used",
+ value: memData["used"] - memData["usedProcess"],
+ },
{ name: "free", value: memData["free"] },
]
)
@@ -313,7 +339,7 @@ function main() {
swapChart.setOption(
createPieChartOption(
- `${localData["swap"]}\n${swapData["percent"].toFixed(1)}%`,
+ `${local_data["swap"]}\n${swapData["percent"].toFixed(1)}%`,
[
{ name: "used", value: swapData["used"] },
{ name: "free", value: swapData["free"] },
@@ -322,24 +348,28 @@ function main() {
);
// 磁盘信息
- const diskData = hardwareData["disk"];
+ const diskData = hardware_data["disk"];
diskData.forEach((disk) => {
- let diskTitle = `${localData['free']} ${convertSize(disk['free'])} ${localData['total']} ${convertSize(disk['total'])}`;
- let diskDiv = createBarChart(diskTitle, disk['percent'], disk['name']);
+ let diskTitle = `${local_data["free"]} ${convertSize(disk["free"])} ${
+ local_data["total"]
+ } ${convertSize(disk["total"])}`;
+ let diskDiv = createBarChart(diskTitle, disk["percent"], disk["name"]);
// 最后一个把margin-bottom去掉
if (disk === diskData[diskData.length - 1]) {
diskDiv.style.marginBottom = "0";
}
- document.getElementById('disk-info').appendChild(diskDiv);
+ document.getElementById("disk-info").appendChild(diskDiv);
});
// 随机一言
- let mottoText = motto_["text"];
- let mottoFrom = motto_["source"];
- document.getElementById("motto-text").innerText = mottoText;
- document.getElementById("motto-from").innerText = mottoFrom;
+ // let mottoText = ;
+ // let mottoFrom = ;
+ document.getElementById("motto-text").innerText = motto_["text"];
+ document.getElementById("motto-from").innerText = motto_["source"];
// 致谢
- document.getElementById("addition-info").innerText =
- "感谢 锅炉 云裳工作室 提供服务器支持";
+ if (acknowledgement.length > 0) {
+ document.getElementById("addition-info").innerText = acknowledgement;
+ // "感谢 锅炉 云裳工作室 提供服务器支持";
+ }
}
main();
@@ -351,4 +381,4 @@ window.addEventListener('resize', () => {
updateDiskNameWidth(diskInfo);
});
});
-*/
\ No newline at end of file
+*/
diff --git a/src/resources/vanilla_resource/templates/status.md b/src/resources/vanilla_resource/templates/status.md
new file mode 100644
index 0000000..fb1b9dc
--- /dev/null
+++ b/src/resources/vanilla_resource/templates/status.md
@@ -0,0 +1,50 @@
+
+
+ {local_description}
+
+
{liteyuki_name} - 睿乐
+
+ - 灵温 {liteyuki_version} | Nonebot {liteyuki_nonebot}
+ - {liteyuki_system} {liteyuki_python}
+ - {local_plugins}{liteyuki_plugins} | {local_resources}{liteyuki_resources}
+ - {local_bots}{liteyuki_bots}
+ - {local_runtime}{liteyuki_runtime}
+
+
+### **{bot_name} |
**
+
+ - {bot_app_name} : {bot_protocol_name}
+ - {local_groups}{bot_groups} | {local_friends}{bot_friends} | {local_message_sent}{bot_message_sent} | {local_message_received}{bot_message_received}
+
+## {local_cpu} : {hardware_cpu_percent}%
+
+ - {hardware_cpu_name} | {hardware_cpu_cores}{local_cores} {hardware_cpu_threads}{local_threads} | {hardware_cpu_freq}{local_units_GHz}
+
+
+## {local_memory} : {hardware_memory_percent}%
+
+ - {local_process} {hardware_memory_processmem}
+ - {local_used} {hardware_memory_usedmem}
+ - {local_free} {hardware_memory_freemem}
+ - {local_total} {hardware_memory_totalmem}
+
+## {local_swap} : {hardware_swap_percent}%
+
+ - {local_used} {hardware_swap_usedswap}
+ - {local_free} {hardware_swap_freeswap}
+ - {local_total} {hardware_swap_totalswap}
+
+## {local_disk}
+
+ - {hardware_disk_name} - {local_used} {hardware_disk_useddisk} | {hardware_disk_freedisk} | {local_total} {hardware_disk_totaldisk}
+
+-----------------------
+END.
+
+### {motto_text}
+
+——{motto_source}
+
+#### {acknowledgement}
+
+#### 该页样式由
![](https://q.qlogo.cn/g?b=qq&nk=3657522512&s=640)
金羿Eilles 设计
\ No newline at end of file
diff --git a/src/utils/base/config.py b/src/utils/base/config.py
index 85737e4..0f0a63c 100644
--- a/src/utils/base/config.py
+++ b/src/utils/base/config.py
@@ -32,6 +32,7 @@ class BasicConfig(BaseModel):
command_start: list[str] = ["/", ""]
nickname: list[str] = [f"灵温-{random_hex_string(6)}"]
default_language: str = "zh-WY"
+ default_interact_language: str = "zh-CN"
satori: SatoriConfig = SatoriConfig()
data_path: str = "data/liteyuki"
chromium_path: str = (
@@ -43,6 +44,7 @@ class BasicConfig(BaseModel):
else "/usr/bin/chromium-browser"
)
)
+ status_acknowledgement: str = ""
def load_from_yaml(file_: str) -> dict:
diff --git a/src/utils/base/language.py b/src/utils/base/language.py
index 5c4071b..d5d277c 100644
--- a/src/utils/base/language.py
+++ b/src/utils/base/language.py
@@ -104,7 +104,7 @@ def load_from_dict(data: dict, lang_code: str):
class Language:
# 三重fallback
- # 用户语言 > 默认语言/系统语言 > zh-CN
+ # 用户语言 > 默认语言/系统语言 > zh-CN | en
def __init__(self, lang_code: str = None, fallback_lang_code: str = None):
self.lang_code = lang_code
@@ -117,6 +117,12 @@ class Language:
"default_language", get_system_lang_code()
)
+ self.__fallback_list = (
+ self.lang_code,
+ self.fallback_lang_code,
+ "en" if "en" in self.lang_code else "zh-CN",
+ )
+
def _get(self, item: str, *args, **kwargs) -> str | Any:
"""
获取当前语言文本,kwargs中的default参数为默认文本
@@ -133,15 +139,14 @@ class Language:
"""
default = kwargs.pop("default", None)
- fallback = (self.lang_code, self.fallback_lang_code, "zh-CN")
- for lang_code in fallback:
+ for lang_code in self.__fallback_list:
if lang_code in _language_data and item in _language_data[lang_code]:
trans: str = _language_data[lang_code][item]
try:
return trans.format(*args, **kwargs)
except Exception as e:
- nonebot.logger.warning(f"Failed to format language data: {e}")
+ nonebot.logger.warning("因 {} 无法格式化本地化数据".format(e))
return trans
return default or item
@@ -203,7 +208,7 @@ def get_user_lang(user_id: str) -> Language:
user_id,
default=User(user_id=user_id, username="Unknown"),
)
- lang_code = user.profile.get("lang", get_default_lang_code())
+ lang_code = user.profile.get("lang", get_default_user_lang_code())
_user_lang[user_id] = lang_code
return Language(_user_lang[user_id])
@@ -225,6 +230,13 @@ def get_default_lang_code() -> str:
return get_config("default_language", default=get_system_lang_code())
+def get_default_user_lang_code() -> str:
+ """
+ 获取默认用户语言代码,和上面的默认语言不同,此处为显示给用户的语言
+ """
+ return get_config("default_interact_language", default=get_default_lang_code())
+
+
def get_all_lang() -> dict[str, str]:
"""
获取所有语言
diff --git a/src/utils/base/log.py b/src/utils/base/log.py
index 65362bf..1b96900 100644
--- a/src/utils/base/log.py
+++ b/src/utils/base/log.py
@@ -20,18 +20,18 @@ def default_filter(record: "Record"):
# DEBUG日志格式
debug_format: str = (
- "{time:YYYY-MM-DD HH:mm:ss} "
- "[{level.icon}] "
- "<{name}.{module}.{function}:{line}> "
- "{message}"
+ "{time:YYYY-MM-DD HH:mm:ss} "
+ "[{level.icon}] "
+ "<{name}.{module}.{function}:{line}> "
+ "{message}"
)
# 默认日志格式
default_format: str = (
- "{time:MM-DD HH:mm:ss} "
- "[{level.icon}] "
- "<{name}> "
- "{message}"
+ "{time:MM-DD HH:mm:ss} "
+ "[{level.icon}] "
+ "<{name}> "
+ "{message}"
)
@@ -74,6 +74,10 @@ def init_log():
logger.level("DEBUG", color="", icon=f"{'🐛' if show_icon else ''}{debug}")
logger.level("INFO", color="", icon=f"{'ℹ️' if show_icon else ''}{info}")
- logger.level("SUCCESS", color="", icon=f"{'✅' if show_icon else ''}{success}")
- logger.level("WARNING", color="", icon=f"{'⚠️' if show_icon else ''}{warning}")
+ logger.level(
+ "SUCCESS", color="", icon=f"{'✅' if show_icon else ''}{success}"
+ )
+ logger.level(
+ "WARNING", color="", icon=f"{'⚠️' if show_icon else ''}{warning}"
+ )
logger.level("ERROR", color="", icon=f"{'⭕' if show_icon else ''}{error}")