mirror of
https://github.com/TriM-Organization/LiteyukiBot-TriM.git
synced 2024-11-28 16:24:51 +08:00
feat: 更多的字体
This commit is contained in:
parent
edc0a16cad
commit
71faffaa44
@ -108,7 +108,7 @@ async def _(bot: T_Bot, event: T_MessageEvent):
|
|||||||
nonebot.logger.error(f"Pull from {origin} failed: {e}")
|
nonebot.logger.error(f"Pull from {origin} failed: {e}")
|
||||||
reply = "Liteyuki updated!\n"
|
reply = "Liteyuki updated!\n"
|
||||||
reply += f"```\n{logs}\n```\n"
|
reply += f"```\n{logs}\n```\n"
|
||||||
btn_restart = md.button(ulang.get("liteyuki.restart_now"), "reload-liteyuki")
|
btn_restart = md.cmd(ulang.get("liteyuki.restart_now"), "reload-liteyuki")
|
||||||
pip.main(["install", "-r", "requirements.txt"])
|
pip.main(["install", "-r", "requirements.txt"])
|
||||||
reply += f"{ulang.get('liteyuki.update_restart', RESTART=btn_restart)}"
|
reply += f"{ulang.get('liteyuki.update_restart', RESTART=btn_restart)}"
|
||||||
await md.send_md(reply, bot, event=event, at_sender=False)
|
await md.send_md(reply, bot, event=event, at_sender=False)
|
||||||
|
@ -7,7 +7,7 @@ from cpuinfo import get_cpu_info
|
|||||||
from nonebot import on_command
|
from nonebot import on_command
|
||||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||||
from nonebot.permission import SUPERUSER
|
from nonebot.permission import SUPERUSER
|
||||||
|
from playwright.async_api import async_playwright
|
||||||
from liteyuki.utils import __NAME__, __VERSION__, load_from_yaml
|
from liteyuki.utils import __NAME__, __VERSION__, load_from_yaml
|
||||||
from liteyuki.utils.htmlrender import template2image
|
from liteyuki.utils.htmlrender import template2image
|
||||||
from liteyuki.utils.language import Language, get_default_lang, get_user_lang
|
from liteyuki.utils.language import Language, get_default_lang, get_user_lang
|
||||||
@ -29,6 +29,8 @@ protocol_names = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@stats.handle()
|
@stats.handle()
|
||||||
async def _(bot: T_Bot, event: T_MessageEvent):
|
async def _(bot: T_Bot, event: T_MessageEvent):
|
||||||
ulang = get_user_lang(str(event.user_id))
|
ulang = get_user_lang(str(event.user_id))
|
||||||
|
@ -157,14 +157,14 @@ class Minesweeper:
|
|||||||
print([d.value for d in row])
|
print([d.value for d in row])
|
||||||
for dot in row:
|
for dot in row:
|
||||||
if dot.mask and not dot.flagged:
|
if dot.mask and not dot.flagged:
|
||||||
text += md.button(self.MASK, f"minesweeper reveal {dot.row} {dot.col}")
|
text += md.cmd(self.MASK, f"minesweeper reveal {dot.row} {dot.col}")
|
||||||
elif dot.flagged:
|
elif dot.flagged:
|
||||||
text += md.button(self.FLAG, f"minesweeper mark {dot.row} {dot.col}")
|
text += md.cmd(self.FLAG, f"minesweeper mark {dot.row} {dot.col}")
|
||||||
else:
|
else:
|
||||||
text += self.NUMS[dot.value]
|
text += self.NUMS[dot.value]
|
||||||
text += dis
|
text += dis
|
||||||
text += "\n"
|
text += "\n"
|
||||||
btn_mark = md.button("标记", f"minesweeper mark ", enter=False)
|
btn_mark = md.cmd("标记", f"minesweeper mark ", enter=False)
|
||||||
btn_end = md.button("结束", "minesweeper end", enter=True)
|
btn_end = md.cmd("结束", "minesweeper end", enter=True)
|
||||||
text += f" {btn_mark} {btn_end}"
|
text += f" {btn_mark} {btn_end}"
|
||||||
return text
|
return text
|
||||||
|
@ -71,7 +71,7 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot):
|
|||||||
if len(rs):
|
if len(rs):
|
||||||
reply = f"{ulang.get('npm.search_result')} | {ulang.get('npm.total', TOTAL=len(rs))}\n***"
|
reply = f"{ulang.get('npm.search_result')} | {ulang.get('npm.total', TOTAL=len(rs))}\n***"
|
||||||
for plugin in rs[:min(max_show, len(rs))]:
|
for plugin in rs[:min(max_show, len(rs))]:
|
||||||
btn_install = md.button(ulang.get("npm.install"), "npm install %s" % plugin.module_name)
|
btn_install = md.cmd(ulang.get("npm.install"), "npm install %s" % plugin.module_name)
|
||||||
link_page = md.link(ulang.get("npm.homepage"), plugin.homepage)
|
link_page = md.link(ulang.get("npm.homepage"), plugin.homepage)
|
||||||
link_pypi = md.link(ulang.get("npm.pypi"), plugin.homepage)
|
link_pypi = md.link(ulang.get("npm.pypi"), plugin.homepage)
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot):
|
|||||||
if not store_plugin:
|
if not store_plugin:
|
||||||
await npm_alc.finish(ulang.get("npm.plugin_not_found", NAME=plugin_module_name))
|
await npm_alc.finish(ulang.get("npm.plugin_not_found", NAME=plugin_module_name))
|
||||||
|
|
||||||
homepage_btn = md.button(ulang.get("npm.homepage"), store_plugin.homepage)
|
homepage_btn = md.cmd(ulang.get("npm.homepage"), store_plugin.homepage)
|
||||||
if r:
|
if r:
|
||||||
|
|
||||||
r_load = nonebot.load_plugin(plugin_module_name) # 加载插件
|
r_load = nonebot.load_plugin(plugin_module_name) # 加载插件
|
||||||
|
@ -67,7 +67,7 @@ async def _(event: T_MessageEvent, bot: T_Bot, result: Arparma):
|
|||||||
for plugin in loaded_plugin_list[(page - 1) * num_per_page: min(page * num_per_page, len(loaded_plugin_list))]:
|
for plugin in loaded_plugin_list[(page - 1) * num_per_page: min(page * num_per_page, len(loaded_plugin_list))]:
|
||||||
# 检查是否有 metadata 属性
|
# 检查是否有 metadata 属性
|
||||||
# 添加帮助按钮
|
# 添加帮助按钮
|
||||||
btn_usage = md.button(lang.get("npm.usage"), f"help {plugin.module_name}", False)
|
btn_usage = md.cmd(lang.get("npm.usage"), f"help {plugin.module_name}", False)
|
||||||
store_plugin = await get_store_plugin(plugin.module_name)
|
store_plugin = await get_store_plugin(plugin.module_name)
|
||||||
|
|
||||||
session_enable = get_plugin_session_enable(event, plugin.module_name)
|
session_enable = get_plugin_session_enable(event, plugin.module_name)
|
||||||
@ -98,7 +98,7 @@ async def _(event: T_MessageEvent, bot: T_Bot, result: Arparma):
|
|||||||
cmd_toggle = f"{'disable' if session_enable else 'enable'} {plugin.module_name}"
|
cmd_toggle = f"{'disable' if session_enable else 'enable'} {plugin.module_name}"
|
||||||
text_toggle = lang.get("npm.disable" if session_enable else "npm.enable")
|
text_toggle = lang.get("npm.disable" if session_enable else "npm.enable")
|
||||||
can_be_toggle = get_plugin_can_be_toggle(plugin.module_name)
|
can_be_toggle = get_plugin_can_be_toggle(plugin.module_name)
|
||||||
btn_toggle = text_toggle if not can_be_toggle else md.button(text_toggle, cmd_toggle)
|
btn_toggle = text_toggle if not can_be_toggle else md.cmd(text_toggle, cmd_toggle)
|
||||||
|
|
||||||
reply += f" {btn_toggle}"
|
reply += f" {btn_toggle}"
|
||||||
|
|
||||||
@ -107,12 +107,12 @@ async def _(event: T_MessageEvent, bot: T_Bot, result: Arparma):
|
|||||||
# 添加移除插件和全局切换按钮
|
# 添加移除插件和全局切换按钮
|
||||||
global_enable = get_plugin_global_enable(plugin.module_name)
|
global_enable = get_plugin_global_enable(plugin.module_name)
|
||||||
btn_uninstall = (
|
btn_uninstall = (
|
||||||
md.button(lang.get("npm.uninstall"), f'npm uninstall {plugin.module_name}')) if plugin_in_database else lang.get(
|
md.cmd(lang.get("npm.uninstall"), f'npm uninstall {plugin.module_name}')) if plugin_in_database else lang.get(
|
||||||
'npm.uninstall')
|
'npm.uninstall')
|
||||||
|
|
||||||
btn_toggle_global_text = lang.get("npm.disable_global" if global_enable else "npm.enable_global")
|
btn_toggle_global_text = lang.get("npm.disable_global" if global_enable else "npm.enable_global")
|
||||||
cmd_toggle_global = f"{'disable-global' if global_enable else 'enable-global'} {plugin.module_name}"
|
cmd_toggle_global = f"{'disable-global' if global_enable else 'enable-global'} {plugin.module_name}"
|
||||||
btn_toggle_global = btn_toggle_global_text if not can_be_toggle else md.button(btn_toggle_global_text, cmd_toggle_global)
|
btn_toggle_global = btn_toggle_global_text if not can_be_toggle else md.cmd(btn_toggle_global_text, cmd_toggle_global)
|
||||||
|
|
||||||
reply += f" {btn_uninstall} {btn_toggle_global}"
|
reply += f" {btn_uninstall} {btn_toggle_global}"
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ async def _(result: Arparma, event: T_MessageEvent, bot: T_Bot):
|
|||||||
continue
|
continue
|
||||||
val = profile.dict()[key]
|
val = profile.dict()[key]
|
||||||
key_text = ulang.get(f"user.profile.{key}")
|
key_text = ulang.get(f"user.profile.{key}")
|
||||||
btn_set = md.button(ulang.get("user.profile.edit"), f"profile set {key}",
|
btn_set = md.cmd(ulang.get("user.profile.edit"), f"profile set {key}",
|
||||||
enter=True if key in enter_attr else False)
|
enter=True if key in enter_attr else False)
|
||||||
reply += (f"\n**{key_text}** **{val}**\n"
|
reply += (f"\n**{key_text}** **{val}**\n"
|
||||||
f"\n> {ulang.get(f'user.profile.{key}.desc')}"
|
f"\n> {ulang.get(f'user.profile.{key}.desc')}"
|
||||||
@ -117,11 +117,11 @@ def get_profile_menu(key: str, ulang: Language) -> Optional[str]:
|
|||||||
reply = f"**{setting_name} {ulang.get('user.profile.settings')}**\n***\n"
|
reply = f"**{setting_name} {ulang.get('user.profile.settings')}**\n***\n"
|
||||||
if key == "lang":
|
if key == "lang":
|
||||||
for lang_code, lang_name in get_all_lang().items():
|
for lang_code, lang_name in get_all_lang().items():
|
||||||
btn_set = md.button(ulang.get("user.profile.set"), f"profile set {key} {lang_code}")
|
btn_set = md.cmd(ulang.get("user.profile.set"), f"profile set {key} {lang_code}")
|
||||||
reply += f"\n{btn_set} | **{lang_name}** - {lang_code}\n***\n"
|
reply += f"\n{btn_set} | **{lang_name}** - {lang_code}\n***\n"
|
||||||
elif key == "timezone":
|
elif key == "timezone":
|
||||||
for tz in representative_timezones_list:
|
for tz in representative_timezones_list:
|
||||||
btn_set_tz = md.button(tz, f"profile set {key} {tz}")
|
btn_set_tz = md.cmd(tz, f"profile set {key} {tz}")
|
||||||
reply += f"{btn_set_tz}\n"
|
reply += f"{btn_set_tz}\n"
|
||||||
return reply
|
return reply
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
63
liteyuki/resources/templates/js/motto.js
Normal file
63
liteyuki/resources/templates/js/motto.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// 存放格言
|
||||||
|
const mottos = [
|
||||||
|
{
|
||||||
|
"text": "人生自古谁无死,留取丹心照汗青。",
|
||||||
|
"author": "文天祥",
|
||||||
|
"source": "《正气歌》"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "同是天涯沦落人,相逢何必曾相识。",
|
||||||
|
"author": "白居易",
|
||||||
|
"source": "《琵琶行》"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "海Memory知己,天涯若比邻。",
|
||||||
|
"author": "王勃",
|
||||||
|
"source": "《送杜少府之任蜀州》"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "人生到处知何似,应似飞鸿踏雪泥。",
|
||||||
|
"author": "苏轼",
|
||||||
|
"source": "《水调歌头》"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "大鹏一日同风起,扶摇直上九万里。",
|
||||||
|
"author": "李白",
|
||||||
|
"source": "《将进酒》"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "银烛秋光冷画屏,轻罗小扇扑流萤。",
|
||||||
|
"author": "陆游",
|
||||||
|
"source": "《秋夕》"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "明月几时有,把酒问青天。",
|
||||||
|
"author": "辛弃疾",
|
||||||
|
"source": "《水龙吟》"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "逸一时,误一世,逸久逸久罢已龄",
|
||||||
|
"author": "田所浩二",
|
||||||
|
"source": "《仲夏夜之淫梦》"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "你知道吗,轻雪只能在Python3.10以上的版本中使用。",
|
||||||
|
"author": "SnowyKami",
|
||||||
|
"source": "轻雪文档"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "你知道吗,轻雪可以通过自定义资源包来扩展主题和语言",
|
||||||
|
"author": "SnowyKami",
|
||||||
|
"source": "轻雪文档"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "你知道吗,轻雪交流群的群号是 775840726",
|
||||||
|
"author": "SnowyKami",
|
||||||
|
"source": "轻雪文档"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "你知道吗,轻雪运行过程中会启动一个node.js运行环境",
|
||||||
|
"author": "SnowyKami",
|
||||||
|
"source": "轻雪文档"
|
||||||
|
},
|
||||||
|
]
|
244
liteyuki/resources/templates/js/stats.js
Normal file
244
liteyuki/resources/templates/js/stats.js
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
{
|
||||||
|
// 环形图
|
||||||
|
|
||||||
|
let bgs = ["bg1.jpg", "bg2.jpg", "bg3.jpg", "bg4.jpg"]
|
||||||
|
// 随机选择背景图片
|
||||||
|
document.body.style.backgroundImage = `url(./img/${bgs[Math.floor(Math.random() * bgs.length)]})`;
|
||||||
|
|
||||||
|
|
||||||
|
let cpuInfo = echarts.init(document.getElementById('cpu-chart'));
|
||||||
|
let memInfo = echarts.init(document.getElementById('mem-chart'));
|
||||||
|
let swapInfo = echarts.init(document.getElementById('swap-chart'));
|
||||||
|
|
||||||
|
let data = JSON.parse(document.getElementById('data').innerText);
|
||||||
|
|
||||||
|
let cpuData = data.cpu;
|
||||||
|
let memData = data.mem;
|
||||||
|
let swapData = data.swap;
|
||||||
|
let diskData = data.disk;
|
||||||
|
let sub_tag_data = {
|
||||||
|
cpu: data.cpuTags,
|
||||||
|
mem: data.memTags,
|
||||||
|
swap: data.swapTags
|
||||||
|
}
|
||||||
|
for (let key in sub_tag_data) {
|
||||||
|
let infoDiv = document.getElementById(key + '-info');
|
||||||
|
sub_tag_data[key].forEach(tag => {
|
||||||
|
let tagSpan = document.createElement('div');
|
||||||
|
tagSpan.innerText = tag;
|
||||||
|
tagSpan.className = 'chart-label';
|
||||||
|
infoDiv.appendChild(tagSpan);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
cpuInfo.setOption(getPieOption(data.cpu_trans, cpuData));
|
||||||
|
memInfo.setOption(getPieOption(data.mem_trans, memData));
|
||||||
|
swapInfo.setOption(getPieOption(data.swap_trans, swapData));
|
||||||
|
|
||||||
|
|
||||||
|
// 在disks-info中插入每个disk的div,用横向柱状图表示用量,每一行div显示一个disk,不加info-box
|
||||||
|
diskData.forEach(disk => {
|
||||||
|
let diskDiv = document.createElement('div');
|
||||||
|
document.getElementById('disks-info').appendChild(diskDiv);
|
||||||
|
let diskChart = document.createElement('div');
|
||||||
|
diskChart.style.width = '100%';
|
||||||
|
diskChart.style.height = '100px';
|
||||||
|
diskDiv.appendChild(diskChart);
|
||||||
|
let diskInfo = echarts.init(diskChart);
|
||||||
|
// let diskTitle = disk.name + ' {{ FREE }} ' + disk.free + ' {{ TOTAL }} ' + disk.total;
|
||||||
|
let diskTitle = `${disk.name} ${data.free_trans} ${disk.free} ${data.total_trans} ${disk.total}`;
|
||||||
|
diskInfo.setOption(getBarOption(diskTitle, disk.percent));
|
||||||
|
});
|
||||||
|
|
||||||
|
let botData = data.bot;
|
||||||
|
// 清空bot-info
|
||||||
|
let botInfos = document.getElementsByClassName('bot-info');
|
||||||
|
while (botInfos.length > 0) {
|
||||||
|
botInfos[0].remove();
|
||||||
|
}
|
||||||
|
botData.forEach(bot => {
|
||||||
|
// 在hardware-info前面插入一个div
|
||||||
|
let botDiv = document.createElement('div');
|
||||||
|
botDiv.className = 'info-box bot-info';
|
||||||
|
// 在body内的hardware-info前面插入botDiv
|
||||||
|
document.body.insertBefore(botDiv, document.getElementById('hardware-info'));
|
||||||
|
|
||||||
|
let botIconBlock = document.createElement('div');
|
||||||
|
let botIcon = document.createElement('img');
|
||||||
|
botIcon.src = bot.icon;
|
||||||
|
botIcon.className = 'bot-icon';
|
||||||
|
botIconBlock.appendChild(botIcon);
|
||||||
|
botDiv.appendChild(botIconBlock);
|
||||||
|
|
||||||
|
let botDetail = document.createElement('div');
|
||||||
|
let botName = document.createElement('div');
|
||||||
|
botName.className = 'bot-name';
|
||||||
|
botName.innerText = bot.name;
|
||||||
|
if (bot.self) {
|
||||||
|
// 添加颜色
|
||||||
|
botName.style.color = '#d0e9ff';
|
||||||
|
}
|
||||||
|
botDetail.appendChild(botName);
|
||||||
|
|
||||||
|
let botTags = document.createElement('div');
|
||||||
|
botTags.className = 'bot-tag';
|
||||||
|
botDetail.appendChild(botTags)
|
||||||
|
|
||||||
|
bot.tags.forEach((tag, index) => {
|
||||||
|
if (!tag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let tagSpan = document.createElement('span');
|
||||||
|
|
||||||
|
tagSpan.innerText = tag;
|
||||||
|
tagSpan.className = 'tag';
|
||||||
|
if (bot.self) {
|
||||||
|
// 添加颜色
|
||||||
|
tagSpan.style.color = '#a2d8f4';
|
||||||
|
}
|
||||||
|
botTags.appendChild(tagSpan);
|
||||||
|
if (index === bot.tags.length - 1) {
|
||||||
|
tagSpan.setAttribute("suffix", "0")
|
||||||
|
} else {
|
||||||
|
tagSpan.setAttribute("suffix", "1")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
botDiv.appendChild(botDetail);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 从/js/motto.js中读取mottos{},随机选择一句
|
||||||
|
let motto = mottos[Math.floor(Math.random() * mottos.length)];
|
||||||
|
// 正文在中间,作者和来源格式为--作者 来源,在右下方
|
||||||
|
let mottoDiv = document.getElementById('motto-info');
|
||||||
|
let mottoText = document.createElement('div');
|
||||||
|
mottoText.className = 'motto-text';
|
||||||
|
mottoText.innerText = motto.text;
|
||||||
|
mottoDiv.appendChild(mottoText);
|
||||||
|
let mottoAuthor = document.createElement('div');
|
||||||
|
mottoAuthor.className = 'motto-author';
|
||||||
|
// motto.author和motto.source可能不存在为空,所以要判断
|
||||||
|
if (!motto.author) {
|
||||||
|
motto.author = '';
|
||||||
|
}
|
||||||
|
if (!motto.source) {
|
||||||
|
motto.source = '';
|
||||||
|
}
|
||||||
|
mottoAuthor.innerText = `\n--${motto.author} ${motto.source}`;
|
||||||
|
mottoAuthor.style.textAlign = 'right';
|
||||||
|
mottoDiv.appendChild(mottoAuthor);
|
||||||
|
|
||||||
|
|
||||||
|
function getPieOption(title, data) {
|
||||||
|
return {
|
||||||
|
animation: false,
|
||||||
|
title: {
|
||||||
|
text: title,
|
||||||
|
left: 'center',
|
||||||
|
top: 'center',
|
||||||
|
textStyle: {
|
||||||
|
//文字颜色
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 30
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
show: true,
|
||||||
|
trigger: "item",
|
||||||
|
backgroundColor: "#ffffff00",
|
||||||
|
// {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
|
||||||
|
},
|
||||||
|
color: ['#a2d8f4', "#ffffff44", '#00a6ff'],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: 'info',
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['80%', '100%'],
|
||||||
|
center: ['50%', '50%'],
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: '50',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: data
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBarOption(title, percent) {
|
||||||
|
// data为百分比,最大值为100
|
||||||
|
return {
|
||||||
|
background: '#d0e9ff',
|
||||||
|
title: {
|
||||||
|
text: title,
|
||||||
|
left: '5%',
|
||||||
|
top: 'center',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 30
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
show: true,
|
||||||
|
trigger: "item",
|
||||||
|
backgroundColor: "#ffffff",
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '0',
|
||||||
|
right: '0',
|
||||||
|
top: '10%',
|
||||||
|
bottom: '10%'
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'value',
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: [''],
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: 'Used',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
data: [percent],
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#a2d8f4',
|
||||||
|
barBorderRadius: [50, 0, 0, 50]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Free',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
data: [100 - percent],
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#d0e9ff',
|
||||||
|
barBorderRadius: [0, 50, 50, 0]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
0
liteyuki/resources/templates/static/motto.txt
Normal file
0
liteyuki/resources/templates/static/motto.txt
Normal file
@ -6,6 +6,7 @@
|
|||||||
<meta name="viewport" content="width=1080, initial-scale=1.0">
|
<meta name="viewport" content="width=1080, initial-scale=1.0">
|
||||||
<title>Liteyuki Stats</title>
|
<title>Liteyuki Stats</title>
|
||||||
<link rel="stylesheet" href="css/fonts.css">
|
<link rel="stylesheet" href="css/fonts.css">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@ -53,7 +54,13 @@
|
|||||||
#disks-info {
|
#disks-info {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#motto-info {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
text-align: center;
|
||||||
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bot-icon {
|
.bot-icon {
|
||||||
@ -96,11 +103,24 @@
|
|||||||
color: #ccc;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.motto-text {
|
||||||
|
font-size: 36px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.motto-author {
|
||||||
|
font-size: 30px;
|
||||||
|
font-style: italic;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@4.3.0/dist/echarts.min.js"></script>
|
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@4.3.0/dist/echarts.min.js"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|
||||||
<div class="info-box" id="hardware-info">
|
<div class="info-box" id="hardware-info">
|
||||||
<div class="pie-info" id="cpu-info">
|
<div class="pie-info" id="cpu-info">
|
||||||
<div class="pie-chart" id="cpu-chart"></div>
|
<div class="pie-chart" id="cpu-chart"></div>
|
||||||
@ -116,233 +136,12 @@
|
|||||||
<div class="info-box" id="disks-info">
|
<div class="info-box" id="disks-info">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="info-box" id="motto-info">
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--储存数据div,不显示-->
|
<!--储存数据div,不显示-->
|
||||||
<div id="data" style="display: none">{{ data | tojson }}</div>
|
<div id="data" style="display: none">{{ data | tojson }}</div>
|
||||||
<script>
|
<script src="js/motto.js"></script>
|
||||||
{
|
<script type="text/javascript" src="js/stats.js"></script>
|
||||||
// 环形图
|
|
||||||
|
|
||||||
let bgs = ["bg1.jpg", "bg2.jpg", "bg3.jpg", "bg4.jpg"]
|
|
||||||
// 随机选择背景图片
|
|
||||||
document.body.style.backgroundImage = `url(./img/${bgs[Math.floor(Math.random() * bgs.length)]})`;
|
|
||||||
|
|
||||||
|
|
||||||
let cpuInfo = echarts.init(document.getElementById('cpu-chart'));
|
|
||||||
let memInfo = echarts.init(document.getElementById('mem-chart'));
|
|
||||||
let swapInfo = echarts.init(document.getElementById('swap-chart'));
|
|
||||||
|
|
||||||
let data = JSON.parse(document.getElementById('data').innerText);
|
|
||||||
|
|
||||||
let cpuData = data.cpu;
|
|
||||||
let memData = data.mem;
|
|
||||||
let swapData = data.swap;
|
|
||||||
let diskData = data.disk;
|
|
||||||
let sub_tag_data = {
|
|
||||||
cpu: data.cpuTags,
|
|
||||||
mem: data.memTags,
|
|
||||||
swap: data.swapTags
|
|
||||||
}
|
|
||||||
for (let key in sub_tag_data) {
|
|
||||||
console.log(key, sub_tag_data[key])
|
|
||||||
let infoDiv = document.getElementById(key + '-info');
|
|
||||||
sub_tag_data[key].forEach(tag => {
|
|
||||||
let tagSpan = document.createElement('div');
|
|
||||||
tagSpan.innerText = tag;
|
|
||||||
tagSpan.className = 'chart-label';
|
|
||||||
infoDiv.appendChild(tagSpan);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
cpuInfo.setOption(getPieOption(data.cpu_trans, cpuData));
|
|
||||||
memInfo.setOption(getPieOption(data.mem_trans, memData));
|
|
||||||
swapInfo.setOption(getPieOption(data.swap_trans, swapData));
|
|
||||||
|
|
||||||
|
|
||||||
// 在disks-info中插入每个disk的div,用横向柱状图表示用量,每一行div显示一个disk,不加info-box
|
|
||||||
diskData.forEach(disk => {
|
|
||||||
let diskDiv = document.createElement('div');
|
|
||||||
document.getElementById('disks-info').appendChild(diskDiv);
|
|
||||||
let diskChart = document.createElement('div');
|
|
||||||
diskChart.style.width = '100%';
|
|
||||||
diskChart.style.height = '100px';
|
|
||||||
diskDiv.appendChild(diskChart);
|
|
||||||
let diskInfo = echarts.init(diskChart);
|
|
||||||
// let diskTitle = disk.name + ' {{ FREE }} ' + disk.free + ' {{ TOTAL }} ' + disk.total;
|
|
||||||
let diskTitle = `${disk.name} ${data.free_trans} ${disk.free} ${data.total_trans} ${disk.total}`;
|
|
||||||
diskInfo.setOption(getBarOption(diskTitle, disk.percent));
|
|
||||||
});
|
|
||||||
|
|
||||||
let botData = data.bot;
|
|
||||||
// 清空bot-info
|
|
||||||
let botInfos = document.getElementsByClassName('bot-info');
|
|
||||||
while (botInfos.length > 0) {
|
|
||||||
botInfos[0].remove();
|
|
||||||
}
|
|
||||||
botData.forEach(bot => {
|
|
||||||
// 在hardware-info前面插入一个div
|
|
||||||
let botDiv = document.createElement('div');
|
|
||||||
botDiv.className = 'info-box bot-info';
|
|
||||||
// 在body内的hardware-info前面插入botDiv
|
|
||||||
document.body.insertBefore(botDiv, document.getElementById('hardware-info'));
|
|
||||||
|
|
||||||
let botIconBlock = document.createElement('div');
|
|
||||||
let botIcon = document.createElement('img');
|
|
||||||
botIcon.src = bot.icon;
|
|
||||||
botIcon.className = 'bot-icon';
|
|
||||||
botIconBlock.appendChild(botIcon);
|
|
||||||
botDiv.appendChild(botIconBlock);
|
|
||||||
|
|
||||||
let botDetail = document.createElement('div');
|
|
||||||
let botName = document.createElement('div');
|
|
||||||
botName.className = 'bot-name';
|
|
||||||
botName.innerText = bot.name;
|
|
||||||
if (bot.self) {
|
|
||||||
// 添加颜色
|
|
||||||
botName.style.color = '#d0e9ff';
|
|
||||||
}
|
|
||||||
botDetail.appendChild(botName);
|
|
||||||
|
|
||||||
let botTags = document.createElement('div');
|
|
||||||
botTags.className = 'bot-tag';
|
|
||||||
botDetail.appendChild(botTags)
|
|
||||||
|
|
||||||
bot.tags.forEach((tag, index) => {
|
|
||||||
if (!tag) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let tagSpan = document.createElement('span');
|
|
||||||
|
|
||||||
tagSpan.innerText = tag;
|
|
||||||
tagSpan.className = 'tag';
|
|
||||||
if (bot.self) {
|
|
||||||
// 添加颜色
|
|
||||||
tagSpan.style.color = '#a2d8f4';
|
|
||||||
}
|
|
||||||
botTags.appendChild(tagSpan);
|
|
||||||
if (index === bot.tags.length - 1) {
|
|
||||||
tagSpan.setAttribute("suffix", "0")
|
|
||||||
} else {
|
|
||||||
tagSpan.setAttribute("suffix", "1")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
botDiv.appendChild(botDetail);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
function getPieOption(title, data) {
|
|
||||||
return {
|
|
||||||
animation: false,
|
|
||||||
title: {
|
|
||||||
text: title,
|
|
||||||
left: 'center',
|
|
||||||
top: 'center',
|
|
||||||
textStyle: {
|
|
||||||
//文字颜色
|
|
||||||
color: '#fff',
|
|
||||||
fontSize: 30
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
show: true,
|
|
||||||
trigger: "item",
|
|
||||||
backgroundColor: "#ffffff00",
|
|
||||||
// {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
|
|
||||||
},
|
|
||||||
color: ['#a2d8f4', "#ffffff44", '#00a6ff'],
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: 'info',
|
|
||||||
type: 'pie',
|
|
||||||
radius: ['80%', '100%'],
|
|
||||||
center: ['50%', '50%'],
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
label: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
labelLine: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
emphasis: {
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
textStyle: {
|
|
||||||
fontSize: '50',
|
|
||||||
fontWeight: 'bold'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: data
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBarOption(title, percent) {
|
|
||||||
// data为百分比,最大值为100
|
|
||||||
return {
|
|
||||||
background: '#d0e9ff',
|
|
||||||
title: {
|
|
||||||
text: title,
|
|
||||||
left: '5%',
|
|
||||||
top: 'center',
|
|
||||||
textStyle: {
|
|
||||||
color: '#fff',
|
|
||||||
fontSize: 30
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
show: true,
|
|
||||||
trigger: "item",
|
|
||||||
backgroundColor: "#ffffff",
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: '0',
|
|
||||||
right: '0',
|
|
||||||
top: '10%',
|
|
||||||
bottom: '10%'
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'value',
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'category',
|
|
||||||
data: [''],
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: 'Used',
|
|
||||||
type: 'bar',
|
|
||||||
stack: 'total',
|
|
||||||
data: [percent],
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
color: '#a2d8f4',
|
|
||||||
barBorderRadius: [50, 0, 0, 50]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Free',
|
|
||||||
type: 'bar',
|
|
||||||
stack: 'total',
|
|
||||||
data: [100 - percent],
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
color: '#d0e9ff',
|
|
||||||
barBorderRadius: [0, 50, 50, 0]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -185,7 +185,7 @@ class Markdown:
|
|||||||
# 等林文轩修好Lagrange.OneBot再说
|
# 等林文轩修好Lagrange.OneBot再说
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def button(name: str, cmd: str, reply: bool = False, enter: bool = True) -> str:
|
def cmd(name: str, cmd: str, reply: bool = False, enter: bool = True) -> str:
|
||||||
"""生成点击回调按钮
|
"""生成点击回调按钮
|
||||||
Args:
|
Args:
|
||||||
name: 按钮显示内容
|
name: 按钮显示内容
|
||||||
|
Loading…
Reference in New Issue
Block a user