mirror of
https://github.com/TriM-Organization/LiteyukiBot-TriM.git
synced 2025-01-31 07:32:59 +08:00
小范围优化,综合性改动
This commit is contained in:
parent
b44ac220df
commit
f6941b534d
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
123
src/nonebot_plugins/liteyuki_status/md_status_utils.py
Normal file
123
src/nonebot_plugins/liteyuki_status/md_status_utils.py
Normal file
@ -0,0 +1,123 @@
|
||||
markdown_status_bot_card_text = """
|
||||
### **{bot_name} | <img src="{bot_icon}" width="40">**
|
||||
|
||||
- {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 = """
|
||||
<h1 style="text-align: center;"> {local_description} </h1>
|
||||
|
||||
<h2> <img src="https://p.qlogo.cn/gh/861684859/861684859/" width="50" alt="bot-icon"> {liteyuki_name} - 睿乐 </h2>
|
||||
|
||||
- 灵温 {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}
|
||||
|
||||
<div align="right">——{motto_source}</div>
|
||||
|
||||
#### <div align="center">{acknowledgement}</div>
|
||||
|
||||
#### <div align="center">该页样式由 <img src="https://q.qlogo.cn/g?b=qq&nk=3657522512&s=640" width=40>金羿Eilles 设计</div>
|
||||
"""
|
||||
|
||||
|
||||
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,
|
||||
)
|
@ -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(),
|
||||
)
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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-)的格式。
|
||||
|
@ -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-。
|
||||
|
@ -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
|
||||
|
@ -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=言·论数量不可为非整数
|
||||
|
@ -155,4 +155,33 @@ status.minutes=分鐘
|
||||
status.seconds=秒
|
||||
status.cores=核心
|
||||
status.threads=線程
|
||||
status.process=進程
|
||||
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=言·論數目不可謂為小數
|
||||
|
@ -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}条
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 3.2 MiB After Width: | Height: | Size: 197 KiB |
Binary file not shown.
Before Width: | Height: | Size: 449 KiB After Width: | Height: | Size: 2.4 MiB |
@ -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);
|
||||
});
|
||||
});
|
||||
*/
|
||||
*/
|
||||
|
50
src/resources/vanilla_resource/templates/status.md
Normal file
50
src/resources/vanilla_resource/templates/status.md
Normal file
@ -0,0 +1,50 @@
|
||||
|
||||
|
||||
<h1 style="text-align: center;"> {local_description} </h1>
|
||||
|
||||
<h2> <img src="./img/litetrimo.png" width="50"> {liteyuki_name} - 睿乐 </h2>
|
||||
|
||||
- 灵温 {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} | <img src="{bot_icon}" width="40">**
|
||||
|
||||
- {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}
|
||||
|
||||
-----------------------
|
||||
<div align="right">END.</div>
|
||||
|
||||
### {motto_text}
|
||||
|
||||
<div align="right">——{motto_source}</div>
|
||||
|
||||
#### <div align="center">{acknowledgement}</div>
|
||||
|
||||
#### <div align="center">该页样式由 <img src="https://q.qlogo.cn/g?b=qq&nk=3657522512&s=640" width=40>金羿Eilles 设计</div>
|
@ -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:
|
||||
|
@ -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]:
|
||||
"""
|
||||
获取所有语言
|
||||
|
@ -20,18 +20,18 @@ def default_filter(record: "Record"):
|
||||
|
||||
# DEBUG日志格式
|
||||
debug_format: str = (
|
||||
"<c>{time:YYYY-MM-DD HH:mm:ss}</c> "
|
||||
"<lvl>[{level.icon}]</lvl> "
|
||||
"<c><{name}.{module}.{function}:{line}></c> "
|
||||
"{message}"
|
||||
"<c>{time:YYYY-MM-DD HH:mm:ss}</c> "
|
||||
"<lvl>[{level.icon}]</lvl> "
|
||||
"<c><{name}.{module}.{function}:{line}></c> "
|
||||
"{message}"
|
||||
)
|
||||
|
||||
# 默认日志格式
|
||||
default_format: str = (
|
||||
"<c>{time:MM-DD HH:mm:ss}</c> "
|
||||
"<lvl>[{level.icon}]</lvl> "
|
||||
"<c><{name}></c> "
|
||||
"{message}"
|
||||
"<c>{time:MM-DD HH:mm:ss}</c> "
|
||||
"<lvl>[{level.icon}]</lvl> "
|
||||
"<c><{name}></c> "
|
||||
"{message}"
|
||||
)
|
||||
|
||||
|
||||
@ -74,6 +74,10 @@ def init_log():
|
||||
|
||||
logger.level("DEBUG", color="<blue>", icon=f"{'🐛' if show_icon else ''}{debug}")
|
||||
logger.level("INFO", color="<normal>", icon=f"{'ℹ️' if show_icon else ''}{info}")
|
||||
logger.level("SUCCESS", color="<green>", icon=f"{'✅' if show_icon else ''}{success}")
|
||||
logger.level("WARNING", color="<yellow>", icon=f"{'⚠️' if show_icon else ''}{warning}")
|
||||
logger.level(
|
||||
"SUCCESS", color="<green>", icon=f"{'✅' if show_icon else ''}{success}"
|
||||
)
|
||||
logger.level(
|
||||
"WARNING", color="<yellow>", icon=f"{'⚠️' if show_icon else ''}{warning}"
|
||||
)
|
||||
logger.level("ERROR", color="<red>", icon=f"{'⭕' if show_icon else ''}{error}")
|
||||
|
Loading…
x
Reference in New Issue
Block a user