mirror of
https://github.com/TriM-Organization/LiteyukiBot-TriM.git
synced 2025-09-06 20:26:24 +00:00
✔❤大更新!
This commit is contained in:
@ -4,8 +4,8 @@ from git import Repo
|
||||
from src.utils.base.config import get_config
|
||||
|
||||
remote_urls = [
|
||||
"https://github.com/LiteyukiStudio/LiteyukiBot.git",
|
||||
"https://gitee.com/snowykami/LiteyukiBot.git"
|
||||
"https://github.com/TriM-Organization/LiteyukiBot-TriM.git",
|
||||
"https://github.com/TriM-Organization/LiteyukiBot-TriM.git"
|
||||
]
|
||||
|
||||
|
||||
|
@ -31,6 +31,20 @@ driver = get_driver()
|
||||
markdown_image = common_db.where_one(StoredConfig(), default=StoredConfig()).config.get("markdown_image", False)
|
||||
|
||||
|
||||
@on_alconna(
|
||||
command=Alconna(
|
||||
"ryounecho",
|
||||
Args["text", str, ""],
|
||||
),
|
||||
permission=SUPERUSER
|
||||
).handle()
|
||||
# Satori OK
|
||||
async def _(bot: T_Bot, matcher: Matcher, result: Arparma):
|
||||
if result.main_args.get("text"):
|
||||
await matcher.finish(Message(unescape(result.main_args.get("text"))))
|
||||
else:
|
||||
await matcher.finish(f"君安!灵温向你问好~\n此机 {bot.self_id}")
|
||||
|
||||
@on_alconna(
|
||||
command=Alconna(
|
||||
"liteecho",
|
||||
@ -43,13 +57,13 @@ async def _(bot: T_Bot, matcher: Matcher, result: Arparma):
|
||||
if result.main_args.get("text"):
|
||||
await matcher.finish(Message(unescape(result.main_args.get("text"))))
|
||||
else:
|
||||
await matcher.finish(f"Hello, Liteyuki!\nBot {bot.self_id}")
|
||||
await matcher.finish(f"Hello! TriM-Liteyuki!\nRyBot {bot.self_id}")
|
||||
|
||||
|
||||
@on_alconna(
|
||||
aliases={"更新轻雪"},
|
||||
aliases={"更新灵温"},
|
||||
command=Alconna(
|
||||
"update-liteyuki"
|
||||
"update-ryoun"
|
||||
),
|
||||
permission=SUPERUSER
|
||||
).handle()
|
||||
@ -59,7 +73,7 @@ async def _(bot: T_Bot, event: T_MessageEvent):
|
||||
|
||||
ulang = get_user_lang(str(event.user.id if isinstance(event, satori.event.Event) else event.user_id))
|
||||
success, logs = update_liteyuki()
|
||||
reply = "Liteyuki updated!\n"
|
||||
reply = "尹灵温 更新完成!\n"
|
||||
reply += f"```\n{logs}\n```\n"
|
||||
btn_restart = md.btn_cmd(ulang.get("liteyuki.restart_now"), "reload-liteyuki")
|
||||
pip.main(["install", "-r", "requirements.txt"])
|
||||
@ -68,15 +82,15 @@ async def _(bot: T_Bot, event: T_MessageEvent):
|
||||
|
||||
|
||||
@on_alconna(
|
||||
aliases={"重启轻雪"},
|
||||
aliases={"重启灵温","重启尹灵温", "重载灵温"},
|
||||
command=Alconna(
|
||||
"reload-liteyuki"
|
||||
"reload-ryoun",
|
||||
),
|
||||
permission=SUPERUSER
|
||||
).handle()
|
||||
# Satori OK
|
||||
async def _(matcher: Matcher, bot: T_Bot, event: T_MessageEvent):
|
||||
await matcher.send("Liteyuki reloading")
|
||||
await matcher.send("尹灵温 正在重载")
|
||||
temp_data = common_db.where_one(TempConfig(), default=TempConfig())
|
||||
|
||||
temp_data.data.update(
|
||||
@ -179,15 +193,15 @@ async def _(event: T_MessageEvent, matcher: Matcher):
|
||||
ulang.get("liteyuki.image_mode_on" if stored_config.config["markdown_image"] else "liteyuki.image_mode_off"))
|
||||
|
||||
|
||||
@on_alconna(
|
||||
command=Alconna(
|
||||
"liteyuki-docs",
|
||||
),
|
||||
aliases={"轻雪文档"},
|
||||
).handle()
|
||||
# Satori OK
|
||||
async def _(matcher: Matcher):
|
||||
await matcher.finish("https://bot.liteyuki.icu/usage")
|
||||
# @on_alconna(
|
||||
# command=Alconna(
|
||||
# "liteyuki-docs",
|
||||
# ),
|
||||
# aliases={"轻雪文档"},
|
||||
# ).handle()
|
||||
# # Satori OK
|
||||
# async def _(matcher: Matcher):
|
||||
# await matcher.finish("https://bot.liteyuki.icu/usage")
|
||||
|
||||
|
||||
@on_alconna(
|
||||
@ -350,7 +364,7 @@ async def _(bot: T_Bot):
|
||||
if isinstance(bot, satori.Bot):
|
||||
await bot.send_message(
|
||||
channel_id=reload_session_id,
|
||||
message="Liteyuki reloaded in %.2f s" % delta_time
|
||||
message="灵温 重载耗时 %.2f 秒" % delta_time
|
||||
)
|
||||
else:
|
||||
await bot.call_api(
|
||||
@ -358,7 +372,7 @@ async def _(bot: T_Bot):
|
||||
message_type=reload_session_type,
|
||||
user_id=reload_session_id,
|
||||
group_id=reload_session_id,
|
||||
message="Liteyuki reloaded in %.2f s" % delta_time
|
||||
message="灵温 重载耗时 %.2f 秒" % delta_time
|
||||
)
|
||||
|
||||
|
||||
@ -369,8 +383,8 @@ async def every_day_update():
|
||||
result, logs = update_liteyuki()
|
||||
pip.main(["install", "-r", "requirements.txt"])
|
||||
if result:
|
||||
await broadcast_to_superusers(f"Liteyuki updated: ```\n{logs}\n```")
|
||||
nonebot.logger.info(f"Liteyuki updated: {logs}")
|
||||
await broadcast_to_superusers(f"灵温已更新: ```\n{logs}\n```")
|
||||
nonebot.logger.info(f"灵温已更新: {logs}")
|
||||
Reloader.reload(5)
|
||||
else:
|
||||
nonebot.logger.info(logs)
|
||||
|
@ -1,18 +0,0 @@
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from .monitors import *
|
||||
from .matchers import *
|
||||
|
||||
|
||||
__author__ = "snowykami"
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
name="轻雪智障回复",
|
||||
description="",
|
||||
usage="",
|
||||
type="application",
|
||||
homepage="https://github.com/snowykami/LiteyukiBot",
|
||||
extra={
|
||||
"liteyuki": True,
|
||||
"toggleable" : True,
|
||||
"default_enable" : True,
|
||||
}
|
||||
)
|
@ -1,106 +0,0 @@
|
||||
import asyncio
|
||||
import random
|
||||
|
||||
import nonebot
|
||||
from nonebot import Bot, on_message, get_driver, require
|
||||
from nonebot.internal.matcher import Matcher
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.typing import T_State
|
||||
|
||||
from src.utils.base.ly_typing import T_MessageEvent
|
||||
from .utils import get_keywords
|
||||
from src.utils.base.word_bank import get_reply
|
||||
from src.utils.event import get_message_type
|
||||
from src.utils.base.permission import GROUP_ADMIN, GROUP_OWNER
|
||||
from src.utils.base.data_manager import group_db, Group
|
||||
|
||||
require("nonebot_plugin_alconna")
|
||||
from nonebot_plugin_alconna import on_alconna, Alconna, Args, Arparma
|
||||
|
||||
nicknames = set()
|
||||
driver = get_driver()
|
||||
group_reply_probability: dict[str, float] = {
|
||||
}
|
||||
default_reply_probability = 0.05
|
||||
cut_probability = 0.4 # 分几句话的概率
|
||||
|
||||
|
||||
@on_alconna(
|
||||
Alconna(
|
||||
"set-reply-probability",
|
||||
Args["probability", float, default_reply_probability],
|
||||
),
|
||||
aliases={"设置回复概率"},
|
||||
permission=SUPERUSER | GROUP_ADMIN | GROUP_OWNER,
|
||||
).handle()
|
||||
async def _(result: Arparma, event: T_MessageEvent, matcher: Matcher):
|
||||
# 修改内存和数据库的概率值
|
||||
if get_message_type(event) == "group":
|
||||
group_id = event.group_id
|
||||
probability = result.main_args.get("probability")
|
||||
# 保存到数据库
|
||||
group: Group = group_db.where_one(Group(), "group_id = ?", group_id, default=Group(group_id=str(group_id)))
|
||||
group.config["reply_probability"] = probability
|
||||
group_db.save(group)
|
||||
|
||||
await matcher.send(f"已将群组{group_id}的回复概率设置为{probability}")
|
||||
return
|
||||
|
||||
|
||||
@group_db.on_save
|
||||
def _(model: Group):
|
||||
"""
|
||||
在数据库更新时,更新内存中的回复概率
|
||||
Args:
|
||||
model:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
group_reply_probability[model.group_id] = model.config.get("reply_probability", default_reply_probability)
|
||||
|
||||
|
||||
@driver.on_bot_connect
|
||||
async def _(bot: Bot):
|
||||
global nicknames
|
||||
nicknames.update(bot.config.nickname)
|
||||
# 从数据库加载群组的回复概率
|
||||
groups = group_db.where_all(Group(), default=[])
|
||||
for group in groups:
|
||||
group_reply_probability[group.group_id] = group.config.get("reply_probability", default_reply_probability)
|
||||
|
||||
|
||||
@on_message(priority=100).handle()
|
||||
async def _(event: T_MessageEvent, bot: Bot, state: T_State, matcher: Matcher):
|
||||
kws = await get_keywords(event.message.extract_plain_text())
|
||||
|
||||
tome = False
|
||||
if await to_me()(event=event, bot=bot, state=state):
|
||||
tome = True
|
||||
else:
|
||||
for kw in kws:
|
||||
if kw in nicknames:
|
||||
tome = True
|
||||
break
|
||||
|
||||
# 回复概率
|
||||
message_type = get_message_type(event)
|
||||
if tome or message_type == "private":
|
||||
p = 1.0
|
||||
else:
|
||||
p = group_reply_probability.get(event.group_id, default_reply_probability)
|
||||
|
||||
if random.random() < p:
|
||||
if reply := get_reply(kws):
|
||||
if random.random() < cut_probability:
|
||||
reply = reply.replace("。", "||").replace(",", "||").replace("!", "||").replace("?", "||")
|
||||
replies = reply.split("||")
|
||||
for r in replies:
|
||||
if r: # 防止空字符串
|
||||
await asyncio.sleep(random.random() * 2)
|
||||
await matcher.send(r)
|
||||
else:
|
||||
await asyncio.sleep(random.random() * 3)
|
||||
await matcher.send(reply)
|
||||
return
|
@ -1,13 +0,0 @@
|
||||
from jieba import lcut
|
||||
from nonebot.utils import run_sync
|
||||
|
||||
|
||||
@run_sync
|
||||
def get_keywords(text: str) -> list[str, ...]:
|
||||
"""
|
||||
获取关键词
|
||||
Args:
|
||||
text: 文本
|
||||
Returns:
|
||||
"""
|
||||
return lcut(text)
|
@ -8,22 +8,22 @@ __plugin_meta__ = PluginMetadata(
|
||||
name="统计信息",
|
||||
description="统计机器人的信息,包括消息、群聊等,支持排名、图表等功能",
|
||||
usage=(
|
||||
"```\nstatistic message 查看统计消息\n"
|
||||
"可选参数:\n"
|
||||
" -g|--group [group_id] 指定群聊\n"
|
||||
" -u|--user [user_id] 指定用户\n"
|
||||
" -d|--duration [duration] 指定时长\n"
|
||||
" -p|--period [period] 指定次数统计周期\n"
|
||||
" -b|--bot [bot_id] 指定机器人\n"
|
||||
"命令别名:\n"
|
||||
" statistic|stat message|msg|m\n"
|
||||
"```"
|
||||
"```\nstatistic message 查看统计消息\n"
|
||||
"可选参数:\n"
|
||||
" -g|--group [group_id] 指定群聊\n"
|
||||
" -u|--user [user_id] 指定用户\n"
|
||||
" -d|--duration [duration] 指定时长\n"
|
||||
" -p|--period [period] 指定次数统计周期\n"
|
||||
" -b|--bot [bot_id] 指定机器人\n"
|
||||
"命令别名:\n"
|
||||
" statistic|stat message|msg|m\n"
|
||||
"```"
|
||||
),
|
||||
type="application",
|
||||
homepage="https://github.com/snowykami/LiteyukiBot",
|
||||
extra={
|
||||
"liteyuki" : True,
|
||||
"toggleable" : False,
|
||||
"default_enable": True,
|
||||
}
|
||||
"liteyuki": True,
|
||||
"toggleable": False,
|
||||
"default_enable": True,
|
||||
},
|
||||
)
|
||||
|
@ -93,6 +93,7 @@ async def generate_status_card(
|
||||
hardware: dict,
|
||||
liteyuki: dict,
|
||||
lang="zh-CN",
|
||||
motto={"text":"风朗气清","source":"成语一则"},
|
||||
bot_id="0",
|
||||
) -> bytes:
|
||||
return await template2image(
|
||||
@ -103,6 +104,7 @@ async def generate_status_card(
|
||||
"hardware": hardware,
|
||||
"liteyuki": liteyuki,
|
||||
"localization": get_local_data(lang),
|
||||
"motto": motto,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -1,15 +1,33 @@
|
||||
import zhDateTime
|
||||
import requests
|
||||
import random
|
||||
|
||||
from src.utils import event as event_utils
|
||||
from src.utils.base.language import get_user_lang
|
||||
from src.utils.base.language import get_user_lang, get_default_lang_code, Language
|
||||
from src.utils.base.ly_typing import T_Bot, T_MessageEvent
|
||||
from .api import *
|
||||
|
||||
require("nonebot_plugin_alconna")
|
||||
from nonebot_plugin_alconna import on_alconna, Alconna, Subcommand, UniMessage
|
||||
from nonebot_plugin_alconna import (
|
||||
on_alconna,
|
||||
Alconna,
|
||||
Subcommand,
|
||||
UniMessage,
|
||||
Option,
|
||||
store_true,
|
||||
AlconnaQuery,
|
||||
Query,
|
||||
Arparma,
|
||||
)
|
||||
|
||||
require("nonebot_plugin_apscheduler")
|
||||
from nonebot_plugin_apscheduler import scheduler
|
||||
|
||||
status_alc = on_alconna(
|
||||
aliases={"状态"},
|
||||
command=Alconna(
|
||||
"status",
|
||||
Option("-r|--refresh", alias={"refr", "r", "刷新"}, action=store_true),
|
||||
Subcommand(
|
||||
"memory",
|
||||
alias={"mem", "m", "内存"},
|
||||
@ -18,23 +36,95 @@ status_alc = on_alconna(
|
||||
"process",
|
||||
alias={"proc", "p", "进程"},
|
||||
),
|
||||
Subcommand(
|
||||
"refresh",
|
||||
alias={"refr", "r", "刷新"},
|
||||
),
|
||||
# Subcommand(
|
||||
# "refresh",
|
||||
# alias={"refr", "r", "刷新"},
|
||||
# ),
|
||||
),
|
||||
)
|
||||
|
||||
yanlun = on_alconna(
|
||||
aliases={"yanlun", "言·论", "yan_lun"},
|
||||
command=Alconna(
|
||||
"言论",
|
||||
Option(
|
||||
"-r|--refresh",
|
||||
default=False,
|
||||
alias={"刷新", "更新", "update"},
|
||||
action=store_true,
|
||||
),
|
||||
Option("-c|--count", default=False, alias={"统计"}, action=store_true),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# 每天4点更新
|
||||
@scheduler.scheduled_job("cron", hour=4)
|
||||
async def every_day_update():
|
||||
ulang = Language(get_default_lang_code(), "zh-WY")
|
||||
nonebot.logger.success(ulang.get("yanlun.refresh.success", COUNT=update_yanlun()))
|
||||
|
||||
|
||||
def update_yanlun():
|
||||
global yanlun_texts
|
||||
|
||||
solar_datetime = zhDateTime.DateTime.now()
|
||||
lunar_datetime = solar_datetime.to_lunar()
|
||||
solar_date = (solar_datetime.month, solar_datetime.day)
|
||||
lunar_date = (lunar_datetime.lunar_month, lunar_datetime.lunar_day)
|
||||
|
||||
if solar_date == (4, 3):
|
||||
yanlun_texts = ["金羿ELS 生日快乐~!"]
|
||||
elif solar_date == (8, 6):
|
||||
yanlun_texts = ["诸葛八卦 生日快乐~!"]
|
||||
|
||||
else:
|
||||
try:
|
||||
yanlun_texts = (
|
||||
requests.get(
|
||||
"https://gitee.com/TriM-Organization/LinglunStudio/raw/master/resources/myWords.txt",
|
||||
)
|
||||
.text.strip("\n")
|
||||
.split("\n")
|
||||
)
|
||||
except (ConnectionError, requests.HTTPError, requests.RequestException) as E:
|
||||
nonebot.logger.warning(f"读取言·论信息发生 互联网连接 错误:\n{E}")
|
||||
yanlun_texts = ["以梦想为驱使 创造属于自己的未来"]
|
||||
# noinspection PyBroadException
|
||||
except BaseException as E:
|
||||
nonebot.logger.warning(f"读取言·论信息发生 未知 错误:\n{E}")
|
||||
yanlun_texts = ["灵光焕发 深艺献心"]
|
||||
|
||||
return len(yanlun_texts)
|
||||
|
||||
|
||||
update_yanlun()
|
||||
|
||||
|
||||
def random_yanlun() -> tuple:
|
||||
seq = random.choice(yanlun_texts).replace(" ", "\t").split("\t——", 1)
|
||||
return seq[0], "" if len(seq) == 1 else seq[1]
|
||||
|
||||
|
||||
status_card_cache = {} # lang -> bytes
|
||||
|
||||
|
||||
@status_alc.handle()
|
||||
async def _(event: T_MessageEvent, bot: T_Bot):
|
||||
ulang = get_user_lang(event_utils.get_user_id(event))
|
||||
async def _(
|
||||
result: Arparma,
|
||||
event: T_MessageEvent,
|
||||
bot: T_Bot,
|
||||
# refresh: Query[bool] = AlconnaQuery("refresh.value", False),
|
||||
):
|
||||
ulang = get_user_lang(event_utils.get_user_id(event)) # type: ignore
|
||||
global status_card_cache
|
||||
if ulang.lang_code not in status_card_cache.keys() or (
|
||||
ulang.lang_code in status_card_cache.keys()
|
||||
and time.time() - status_card_cache[ulang.lang_code][1] > 60
|
||||
if (
|
||||
result.options["refresh"].value
|
||||
or ulang.lang_code not in status_card_cache.keys()
|
||||
or (
|
||||
ulang.lang_code in status_card_cache.keys()
|
||||
and time.time() - status_card_cache[ulang.lang_code][1] > 60
|
||||
)
|
||||
):
|
||||
status_card_cache[ulang.lang_code] = (
|
||||
await generate_status_card(
|
||||
@ -42,6 +132,7 @@ async def _(event: T_MessageEvent, bot: T_Bot):
|
||||
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,
|
||||
),
|
||||
time.time(),
|
||||
@ -58,3 +149,100 @@ async def _():
|
||||
@status_alc.assign("process")
|
||||
async def _():
|
||||
print("process")
|
||||
|
||||
|
||||
@yanlun.handle()
|
||||
async def _(
|
||||
result: Arparma,
|
||||
event: T_MessageEvent,
|
||||
bot: T_Bot,
|
||||
# refresh: Query[bool] = AlconnaQuery("refresh.value", False),
|
||||
# count: Query[bool] = AlconnaQuery("count.value", False),
|
||||
):
|
||||
# print(result.options)
|
||||
if result.options["refresh"].value:
|
||||
ulang = get_user_lang(event_utils.get_user_id(event)) # type: ignore
|
||||
global yanlun_texts
|
||||
try:
|
||||
yanlun_texts = (
|
||||
requests.get(
|
||||
"https://gitee.com/TriM-Organization/LinglunStudio/raw/master/resources/myWords.txt",
|
||||
)
|
||||
.text.strip("\n")
|
||||
.split("\n")
|
||||
)
|
||||
await yanlun.send(
|
||||
UniMessage.text(
|
||||
ulang.get("yanlun.refresh.success", COUNT=len(yanlun_texts))
|
||||
)
|
||||
)
|
||||
except (ConnectionError, requests.HTTPError, requests.RequestException) as E:
|
||||
await yanlun.send(
|
||||
UniMessage.text(
|
||||
ulang.get(
|
||||
"yanlun.refresh.failed",
|
||||
ERR=ulang.get("yanlun.errtype.net"),
|
||||
ERRCODE=f"\n{E}",
|
||||
)
|
||||
)
|
||||
)
|
||||
yanlun_texts = ["以梦想为驱使 创造属于自己的未来"]
|
||||
# noinspection PyBroadException
|
||||
except BaseException as E:
|
||||
await yanlun.send(
|
||||
UniMessage.text(
|
||||
ulang.get(
|
||||
"yanlun.refresh.failed",
|
||||
ERR=ulang.get("yanlun.errtype.unknown"),
|
||||
ERRCODE=f"\n{E}",
|
||||
)
|
||||
)
|
||||
)
|
||||
yanlun_texts = ["灵光焕发 深艺献心"]
|
||||
if result.options["count"].value:
|
||||
ulang = get_user_lang(event_utils.get_user_id(event)) # type: ignore
|
||||
authors = [
|
||||
(
|
||||
("B站")
|
||||
if ("\t——B站" in i.upper() or " ——B站" in i.upper())
|
||||
else (
|
||||
i.split("\t——")[1].replace(" ", "")
|
||||
if "\t——" in i
|
||||
else (
|
||||
i.split(" ——")[1].replace(" ", "")
|
||||
if " ——" in i
|
||||
else ("MYH")
|
||||
)
|
||||
)
|
||||
)
|
||||
for i in yanlun_texts
|
||||
]
|
||||
|
||||
total = len(yanlun_texts)
|
||||
|
||||
chart = sorted(
|
||||
[(i, authors.count(i)) for i in set(authors)],
|
||||
key=lambda x: x[1],
|
||||
reverse=True,
|
||||
)
|
||||
|
||||
await yanlun.send(
|
||||
UniMessage.text(
|
||||
ulang.get("yanlun.count.head").replace("ttt", "\t")
|
||||
+ "\n"
|
||||
+ "".join(
|
||||
[
|
||||
(
|
||||
"{}\t{}({}%)\n".format(
|
||||
aut, cnt, int(cnt * 10000 / total + 0.5) / 100
|
||||
)
|
||||
if cnt * 100 / total >= chart[10][1] * 100 / total
|
||||
else ""
|
||||
)
|
||||
for aut, cnt in chart
|
||||
]
|
||||
)
|
||||
+ ulang.get("yanlun.count.tail", NUM=total)
|
||||
)
|
||||
)
|
||||
await yanlun.finish(UniMessage.text(random.choice(yanlun_texts)))
|
||||
|
@ -1,4 +1,12 @@
|
||||
.sign-chart {
|
||||
height: 400px;
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
#addition-info {
|
||||
font-size: 36px;
|
||||
word-wrap: break-word;
|
||||
color: var(--main-text-color);
|
||||
text-align: center;
|
||||
margin: 30px 0 10px 0;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
#addition-info {
|
||||
font-size: 36px;
|
||||
word-wrap: break-word;
|
||||
color: var(--main-text-color);
|
||||
text-align: center;
|
||||
margin: 30px 0 10px 0;
|
||||
}
|
@ -51,4 +51,7 @@ function timestampToTime(timestamp) {
|
||||
let m = date.getMinutes() + ':'
|
||||
let s = date.getSeconds()
|
||||
return M + D + h + m + s
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('addition-info').innerText = '感谢 锅炉 云裳工作室 提供服务器支持'
|
@ -23,3 +23,5 @@ data["ranking"].forEach((item) => {
|
||||
document.body.appendChild(row)
|
||||
})
|
||||
|
||||
|
||||
document.getElementById('addition-info').innerText = '感谢 锅炉 云裳工作室 提供服务器支持'
|
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns="http://www.w3.org/1999/html">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Liteyuki Stats Message</title>
|
||||
@ -10,13 +11,15 @@
|
||||
|
||||
<body>
|
||||
|
||||
<template id="sign-chart-template">
|
||||
<div class="info-box sign-chart">
|
||||
</div>
|
||||
</template>
|
||||
<div class="data-storage" id="data">{{ data | tojson }}</div>
|
||||
<template id="sign-chart-template">
|
||||
<div class="info-box sign-chart">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
|
||||
<script src="./js/stat_msg.js"></script>
|
||||
<script src="./js/card.js"></script>
|
||||
<div class="data-storage" id="data">{{ data | tojson }}</div>
|
||||
|
||||
<div class="info-box" id="addition-info"></div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
|
||||
<script src="./js/stat_msg.js"></script>
|
||||
<script src="./js/card.js"></script>
|
||||
</body>
|
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns="http://www.w3.org/1999/html">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Liteyuki Stats Message</title>
|
||||
@ -15,19 +16,19 @@
|
||||
margin-bottom: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
.row-name {
|
||||
font-size: 40px;
|
||||
align-content: center;
|
||||
width: 100px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
.row-icon {
|
||||
border-radius: 50%;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
|
||||
.row-count {
|
||||
align-content: center;
|
||||
font-size: 40px;
|
||||
@ -39,16 +40,18 @@
|
||||
|
||||
<body>
|
||||
|
||||
<template id="row-template">
|
||||
<div class="row">
|
||||
<img src="./img/arrow-up.svg" alt="up" class="row-icon">
|
||||
<div class="row-name"></div>
|
||||
<div class="row-count"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template id="row-template">
|
||||
<div class="row">
|
||||
<img src="./img/arrow-up.svg" alt="up" class="row-icon">
|
||||
<div class="row-name"></div>
|
||||
<div class="row-count"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="data-storage" id="data">{{ data | tojson }}</div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
|
||||
<script src="./js/stat_rank.js"></script>
|
||||
<script src="./js/card.js"></script>
|
||||
<div class="data-storage" id="data">{{ data | tojson }}</div>
|
||||
|
||||
<div class="info-box" id="addition-info"></div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
|
||||
<script src="./js/stat_rank.js"></script>
|
||||
<script src="./js/card.js"></script>
|
||||
</body>
|
@ -156,4 +156,11 @@ status.seconds=秒
|
||||
status.cores=核心
|
||||
status.threads=线程
|
||||
status.process=进程
|
||||
status.description=轻雪机器人状态面板
|
||||
status.description=轻雪机器人状态面板
|
||||
|
||||
yanlun.refresh.success=言·论 更新成功,共 {COUNT} 条
|
||||
yanlun.refresh.failed=更新 言·论 信息发生 {ERR} 错误:{ERRCODE}
|
||||
yanlun.errtype.net=互联网连接
|
||||
yanlun.errtype.unknown=未知
|
||||
yanlun.count.head=出处ttt数量(占比)
|
||||
yanlun.count.tail=...(共 {NUM} 条)
|
@ -156,4 +156,11 @@ status.seconds=秒
|
||||
status.cores=轮核
|
||||
status.threads=程线
|
||||
status.process=行轨
|
||||
status.description=轻雪灵机台
|
||||
status.description=轻雪灵机台
|
||||
|
||||
yanlun.refresh.success=言·论 方新,合{COUNT}条
|
||||
yanlun.refresh.failed=言·论 因{ERR}而无以新:{ERRCODE}
|
||||
yanlun.errtype.net=遥讯不得
|
||||
yanlun.errtype.unknown=无名之亏
|
||||
yanlun.count.head=所缘ttt几何(比率)
|
||||
yanlun.count.tail=...(合{NUM}条)
|
@ -125,3 +125,10 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#addition-info {
|
||||
font-size: 36px;
|
||||
word-wrap: break-word;
|
||||
color: var(--main-text-color);
|
||||
text-align: center;
|
||||
margin: 30px 0 10px 0;
|
||||
}
|
@ -3,7 +3,7 @@ body {
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
color: white;
|
||||
/ / 上10px,左右10px,下0px / / margin: 24 px;
|
||||
/* // 上10px,左右10px,下0px // margin: 24 px; */
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
@ -55,7 +55,8 @@ body {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.bot-name, .bot-tag {
|
||||
.bot-name,
|
||||
.bot-tag {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
@ -98,4 +99,9 @@ body {
|
||||
font-size: 30px;
|
||||
font-style: italic;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.addition-info {
|
||||
font-size: 36px;
|
||||
color: #fff;
|
||||
}
|
@ -3,6 +3,7 @@ const bot_data = data['bot']; // 机器人数据
|
||||
const hardwareData = data['hardware']; // 硬件数据
|
||||
const liteyukiData = data['liteyuki']; // LiteYuki数据
|
||||
const localData = data['localization']; // 本地化语言数据
|
||||
const motto_ = data['motto']; // 言论数据
|
||||
|
||||
/**
|
||||
* 创建CPU/内存/交换饼图
|
||||
@ -61,10 +62,10 @@ function createPieChartOption(title, data) {
|
||||
}
|
||||
|
||||
|
||||
function convertSize(size, precision = 2, addUnit = true, suffix = " XiB") {
|
||||
function convertSize(size, precision = 2, addUnit = true, suffix = " X字节") {
|
||||
let isNegative = size < 0;
|
||||
size = Math.abs(size);
|
||||
let units = ["", "K", "M", "G", "T", "P", "E", "Z"];
|
||||
let units = ["", "千", "兆", "吉", "太", "拍", "艾", "泽"];
|
||||
let unit = "";
|
||||
|
||||
for (let i = 0; i < units.length; i++) {
|
||||
@ -254,20 +255,20 @@ function main() {
|
||||
|
||||
|
||||
cpuChart.setOption(createPieChartOption(`${localData['cpu']}\n${cpuData['percent'].toFixed(1)}%`, [
|
||||
{name: 'used', value: cpuData['percent']},
|
||||
{name: 'free', value: 100 - cpuData['percent']}
|
||||
{ name: 'used', value: cpuData['percent'] },
|
||||
{ name: 'free', value: 100 - cpuData['percent'] }
|
||||
]))
|
||||
|
||||
memChart.setOption(createPieChartOption(`${localData['memory']}\n${memData['percent'].toFixed(1)}%`, [
|
||||
{name: 'process', value: memData['usedProcess']},
|
||||
{name: 'used', value: memData['used'] - memData['usedProcess']},
|
||||
{name: 'free', value: memData['free']}
|
||||
{ name: 'process', value: memData['usedProcess'] },
|
||||
{ name: 'used', value: memData['used'] - memData['usedProcess'] },
|
||||
{ name: 'free', value: memData['free'] }
|
||||
]))
|
||||
|
||||
|
||||
swapChart.setOption(createPieChartOption(`${localData['swap']}\n${swapData['percent'].toFixed(1)}%`, [
|
||||
{name: 'used', value: swapData['used']},
|
||||
{name: 'free', value: swapData['free']}
|
||||
{ name: 'used', value: swapData['used'] },
|
||||
{ name: 'free', value: swapData['free'] }
|
||||
]))
|
||||
|
||||
|
||||
@ -284,12 +285,12 @@ function main() {
|
||||
document.getElementById('disk-info').appendChild(createBarChart(diskTitle, disk['percent']))
|
||||
})
|
||||
// 随机一言
|
||||
let motto = mottos[Math.floor(Math.random() * mottos.length)]
|
||||
let mottoText = motto['text']
|
||||
let mottoFrom = `${motto['author']} ${motto['source']}`
|
||||
let mottoText = motto_['text']
|
||||
let mottoFrom = motto_['source']
|
||||
document.getElementById('motto-text').innerText = mottoText
|
||||
document.getElementById('motto-from').innerText = mottoFrom
|
||||
|
||||
// 致谢
|
||||
document.getElementById('addition-info').innerText = '感谢 锅炉 云裳工作室 提供服务器支持'
|
||||
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@
|
||||
)
|
||||
|
||||
// 从/js/motto.js中读取mottos{},随机选择一句
|
||||
let motto = mottos[Math.floor(Math.random() * mottos.length)];
|
||||
// let motto = mottos[Math.floor(Math.random() * mottos.length)];
|
||||
// 正文在中间,作者和来源格式为--作者 来源,在右下方
|
||||
let mottoDiv = document.getElementById('motto-info');
|
||||
let mottoText = document.createElement('div');
|
||||
@ -113,13 +113,13 @@
|
||||
let mottoAuthor = document.createElement('div');
|
||||
mottoAuthor.className = 'motto-author';
|
||||
// motto.author和motto.source可能不存在为空,所以要判断
|
||||
if (!motto.author) {
|
||||
motto.author = '';
|
||||
}
|
||||
// if (!motto.author) {
|
||||
// motto.author = '';
|
||||
// }
|
||||
if (!motto.source) {
|
||||
motto.source = '';
|
||||
}
|
||||
mottoAuthor.innerText = `\n--${motto.author} ${motto.source}`;
|
||||
mottoAuthor.innerText = `\n${motto.source}`;
|
||||
mottoAuthor.style.textAlign = 'right';
|
||||
mottoDiv.appendChild(mottoAuthor);
|
||||
|
||||
|
@ -10,31 +10,33 @@
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.3.0/echarts.min.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div class="info-box" id="hardware-info">
|
||||
<div class="pie-info" id="cpu-info">
|
||||
<div class="pie-chart" id="cpu-chart"></div>
|
||||
<div class="info-box" id="hardware-info">
|
||||
<div class="pie-info" id="cpu-info">
|
||||
<div class="pie-chart" id="cpu-chart"></div>
|
||||
</div>
|
||||
<div class="pie-info" id="mem-info">
|
||||
<div class="pie-chart" id="mem-chart"></div>
|
||||
</div>
|
||||
<div class="pie-info" id="swap-info">
|
||||
<div class="pie-chart" id="swap-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pie-info" id="mem-info">
|
||||
<div class="pie-chart" id="mem-chart"></div>
|
||||
|
||||
<div class="info-box" id="disks-info">
|
||||
</div>
|
||||
<div class="pie-info" id="swap-info">
|
||||
<div class="pie-chart" id="swap-chart"></div>
|
||||
|
||||
<div class="info-box" id="motto-info">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-box" id="disks-info">
|
||||
</div>
|
||||
|
||||
<div class="info-box" id="motto-info">
|
||||
</div>
|
||||
|
||||
<!--储存数据div,不显示-->
|
||||
<div id="data" style="display: none">{{ data | tojson }}</div>
|
||||
<script src="js/bg.js"></script>
|
||||
<script src="js/motto.js"></script>
|
||||
<script src="js/style.js"></script>
|
||||
<!--储存数据div,不显示-->
|
||||
<div id="data" style="display: none">{{ data | tojson }}</div>
|
||||
<script src="js/bg.js"></script>
|
||||
<!-- <script src="js/motto.js"></script> -->
|
||||
<script src="js/style.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Liteyuki Status</title>
|
||||
@ -8,43 +9,46 @@
|
||||
<link rel="stylesheet" href="./css/fonts.css">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<template id="bot-template">
|
||||
<div class="info-box bot-info">
|
||||
<div class="bot-icon">
|
||||
<img class="bot-icon-img" src="" alt="bot-icon">
|
||||
</div>
|
||||
<div class="bot-detail">
|
||||
<div class="bot-name">
|
||||
Liteyuki
|
||||
<template id="bot-template">
|
||||
<div class="info-box bot-info">
|
||||
<div class="bot-icon">
|
||||
<img class="bot-icon-img" src="" alt="bot-icon">
|
||||
</div>
|
||||
<hr>
|
||||
<div class="bot-tags">
|
||||
<!-- tag span-->
|
||||
<div class="bot-detail">
|
||||
<div class="bot-name">
|
||||
TriM-Liteyuki
|
||||
</div>
|
||||
<hr>
|
||||
<div class="bot-tags">
|
||||
<!-- tag span-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template id="device-info">
|
||||
<div class="device-info">
|
||||
<div class="device-chart">
|
||||
<template id="device-info">
|
||||
<div class="device-info">
|
||||
<div class="device-chart">
|
||||
</div>
|
||||
<div class="device-tags">
|
||||
</div>
|
||||
</div>
|
||||
<div class="device-tags">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<div class="data-storage" id="data">{{ data | tojson }}</div>
|
||||
<div class="info-box" id="hardware-info"></div>
|
||||
<div class="info-box" id="disk-info"></div>
|
||||
<div class="info-box" id="motto-info">
|
||||
<div id="motto-text"></div>
|
||||
<div id="motto-from"></div>
|
||||
</div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
|
||||
<script src="./js/motto.js"></script>
|
||||
<script src="./js/card.js"></script>
|
||||
<script src="./js/status.js"></script>
|
||||
<div class="data-storage" id="data">{{ data | tojson }}</div>
|
||||
<div class="info-box" id="hardware-info"></div>
|
||||
<div class="info-box" id="disk-info"></div>
|
||||
<div class="info-box" id="motto-info">
|
||||
<div id="motto-text"></div>
|
||||
<div id="motto-from"></div>
|
||||
</div>
|
||||
<div class="info-box" id="addition-info"></div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
|
||||
<!-- <script src="./js/motto.js"></script> -->
|
||||
<script src="./js/card.js"></script>
|
||||
<script src="./js/status.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -49,7 +49,8 @@
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.bot-name, .bot-tag {
|
||||
.bot-name,
|
||||
.bot-tag {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
@ -93,35 +94,36 @@
|
||||
font-style: italic;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@4.3.0/dist/echarts.min.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div class="info-box" id="hardware-info">
|
||||
<div class="pie-info" id="cpu-info">
|
||||
<div class="pie-chart" id="cpu-chart"></div>
|
||||
<div class="info-box" id="hardware-info">
|
||||
<div class="pie-info" id="cpu-info">
|
||||
<div class="pie-chart" id="cpu-chart"></div>
|
||||
</div>
|
||||
<div class="pie-info" id="mem-info">
|
||||
<div class="pie-chart" id="mem-chart"></div>
|
||||
</div>
|
||||
<div class="pie-info" id="swap-info">
|
||||
<div class="pie-chart" id="swap-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pie-info" id="mem-info">
|
||||
<div class="pie-chart" id="mem-chart"></div>
|
||||
|
||||
<div class="info-box" id="disks-info">
|
||||
</div>
|
||||
<div class="pie-info" id="swap-info">
|
||||
<div class="pie-chart" id="swap-chart"></div>
|
||||
|
||||
<div class="info-box" id="motto-info">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-box" id="disks-info">
|
||||
</div>
|
||||
|
||||
<div class="info-box" id="motto-info">
|
||||
</div>
|
||||
|
||||
<!--储存数据div,不显示-->
|
||||
<div id="data" style="display: none">{{ data | tojson }}</div>
|
||||
<script src="js/motto.js"></script>
|
||||
<script src="js/style.js"></script>
|
||||
<!--储存数据div,不显示-->
|
||||
<div id="data" style="display: none">{{ data | tojson }}</div>
|
||||
<!-- <script src="js/motto.js"></script> -->
|
||||
<script src="js/style.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
@ -1,23 +1,143 @@
|
||||
import os.path
|
||||
import time
|
||||
|
||||
# import time
|
||||
from os import getcwd
|
||||
|
||||
import aiofiles
|
||||
import nonebot
|
||||
|
||||
from nonebot_plugin_htmlrender import *
|
||||
from .tools import random_hex_string
|
||||
|
||||
# import imgkit
|
||||
# from typing import Any, Dict, Literal, Optional, Union
|
||||
# import uuid
|
||||
|
||||
# import jinja2
|
||||
# from pathlib import Path
|
||||
|
||||
# TEMPLATES_PATH = str(Path(__file__).parent / "templates")
|
||||
# env = jinja2.Environment( # noqa: S701
|
||||
# extensions=["jinja2.ext.loopcontrols"],
|
||||
# loader=jinja2.FileSystemLoader(TEMPLATES_PATH),
|
||||
# enable_async=True,
|
||||
# )
|
||||
|
||||
|
||||
# async def template_to_html(
|
||||
# template_path: str,
|
||||
# template_name: str,
|
||||
# **kwargs,
|
||||
# ) -> str:
|
||||
# """使用jinja2模板引擎通过html生成图片
|
||||
|
||||
# Args:
|
||||
# template_path (str): 模板路径
|
||||
# template_name (str): 模板名
|
||||
# **kwargs: 模板内容
|
||||
# Returns:
|
||||
# str: html
|
||||
# """
|
||||
|
||||
# template_env = jinja2.Environment( # noqa: S701
|
||||
# loader=jinja2.FileSystemLoader(template_path),
|
||||
# enable_async=True,
|
||||
# )
|
||||
# template = template_env.get_template(template_name)
|
||||
|
||||
# return await template.render_async(**kwargs)
|
||||
|
||||
|
||||
# async def template_to_pic(
|
||||
# template_path: str,
|
||||
# template_name: str,
|
||||
# templates: Dict[Any, Any],
|
||||
# pages: Optional[Dict[Any, Any]] = None,
|
||||
# wait: int = 0,
|
||||
# type: Literal["jpeg", "png"] = "png", # noqa: A002
|
||||
# quality: Union[int, None] = None,
|
||||
# device_scale_factor: float = 2,
|
||||
# ) -> bytes:
|
||||
# """使用jinja2模板引擎通过html生成图片
|
||||
|
||||
# Args:
|
||||
# template_path (str): 模板路径
|
||||
# template_name (str): 模板名
|
||||
# templates (Dict[Any, Any]): 模板内参数 如: {"name": "abc"}
|
||||
# pages (Optional[Dict[Any, Any]]): 网页参数 Defaults to
|
||||
# {"base_url": f"file://{getcwd()}", "viewport": {"width": 500, "height": 10}}
|
||||
# wait (int, optional): 网页载入等待时间. Defaults to 0.
|
||||
# type (Literal["jpeg", "png"]): 图片类型, 默认 png
|
||||
# quality (int, optional): 图片质量 0-100 当为`png`时无效
|
||||
# device_scale_factor: 缩放比例,类型为float,值越大越清晰(真正想让图片清晰更优先请调整此选项)
|
||||
# Returns:
|
||||
# bytes: 图片 可直接发送
|
||||
# """
|
||||
# if pages is None:
|
||||
# pages = {
|
||||
# "viewport": {"width": 500, "height": 10},
|
||||
# "base_url": f"file://{getcwd()}", # noqa: PTH109
|
||||
# }
|
||||
|
||||
# template_env = jinja2.Environment( # noqa: S701
|
||||
# loader=jinja2.FileSystemLoader(template_path),
|
||||
# enable_async=True,
|
||||
# )
|
||||
# template = template_env.get_template(template_name)
|
||||
|
||||
# open(
|
||||
# filename := os.path.join(
|
||||
# template_path,
|
||||
# str(uuid.uuid4())+".html",
|
||||
# ),
|
||||
# "w",
|
||||
# ).write(await template.render_async(**templates))
|
||||
|
||||
# print(pages,filename)
|
||||
|
||||
|
||||
# img = imgkit.from_file(
|
||||
# filename,
|
||||
# output_path=False,
|
||||
# options={
|
||||
# "format": type,
|
||||
# "quality": quality if (quality and type == "jpeg") else 94,
|
||||
# "allow": pages["base_url"],
|
||||
# # "viewport-size": "{} {}".format(pages["viewport"]["width"],pages["viewport"]["height"]),
|
||||
# "zoom": device_scale_factor,
|
||||
# # "load-error-handling": "ignore",
|
||||
# "enable-local-file-access": None,
|
||||
# "no-stop-slow-scripts": None,
|
||||
# "transparent": None,
|
||||
# },
|
||||
# ) # type: ignore
|
||||
|
||||
|
||||
# # os.remove(filename)
|
||||
|
||||
# return img
|
||||
|
||||
# return await html_to_pic(
|
||||
# template_path=f"file://{template_path}",
|
||||
# html=await template.render_async(**templates),
|
||||
# wait=wait,
|
||||
# type=type,
|
||||
# quality=quality,
|
||||
# device_scale_factor=device_scale_factor,
|
||||
# **pages,
|
||||
# )
|
||||
|
||||
|
||||
async def html2image(
|
||||
html: str,
|
||||
wait: int = 0,
|
||||
html: str,
|
||||
wait: int = 0,
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
async def template2html(
|
||||
template: str,
|
||||
templates: dict,
|
||||
template: str,
|
||||
templates: dict,
|
||||
) -> str:
|
||||
"""
|
||||
Args:
|
||||
@ -32,12 +152,12 @@ async def template2html(
|
||||
|
||||
|
||||
async def template2image(
|
||||
template: str,
|
||||
templates: dict,
|
||||
pages=None,
|
||||
wait: int = 0,
|
||||
scale_factor: float = 1,
|
||||
debug: bool = False,
|
||||
template: str,
|
||||
templates: dict,
|
||||
pages=None,
|
||||
wait: int = 0,
|
||||
scale_factor: float = 1,
|
||||
debug: bool = False,
|
||||
) -> bytes:
|
||||
"""
|
||||
template -> html -> image
|
||||
@ -53,11 +173,8 @@ async def template2image(
|
||||
"""
|
||||
if pages is None:
|
||||
pages = {
|
||||
"viewport": {
|
||||
"width" : 1080,
|
||||
"height": 10
|
||||
},
|
||||
"base_url": f"file://{getcwd()}",
|
||||
"viewport": {"width": 1080, "height": 10},
|
||||
"base_url": f"file://{getcwd()}",
|
||||
}
|
||||
template_path = os.path.dirname(template)
|
||||
template_name = os.path.basename(template)
|
||||
@ -70,7 +187,9 @@ async def template2image(
|
||||
**templates,
|
||||
)
|
||||
random_file_name = f"debug-{random_hex_string(6)}.html"
|
||||
async with aiofiles.open(os.path.join(template_path, random_file_name), "w", encoding="utf-8") as f:
|
||||
async with aiofiles.open(
|
||||
os.path.join(template_path, random_file_name), "w", encoding="utf-8"
|
||||
) as f:
|
||||
await f.write(raw_html)
|
||||
nonebot.logger.info("Debug HTML: %s" % f"{random_file_name}")
|
||||
|
||||
@ -84,30 +203,30 @@ async def template2image(
|
||||
)
|
||||
|
||||
|
||||
async def url2image(
|
||||
url: str,
|
||||
wait: int = 0,
|
||||
scale_factor: float = 1,
|
||||
type: str = "png",
|
||||
quality: int = 100,
|
||||
**kwargs
|
||||
) -> bytes:
|
||||
"""
|
||||
Args:
|
||||
quality:
|
||||
type:
|
||||
url: str: URL
|
||||
wait: int: 等待时间
|
||||
scale_factor: float: 缩放因子
|
||||
**kwargs: page 参数
|
||||
Returns:
|
||||
图片二进制数据
|
||||
"""
|
||||
async with get_new_page(scale_factor) as page:
|
||||
await page.goto(url)
|
||||
await page.wait_for_timeout(wait)
|
||||
return await page.screenshot(
|
||||
full_page=True,
|
||||
type=type,
|
||||
quality=quality
|
||||
)
|
||||
# async def url2image(
|
||||
# url: str,
|
||||
# wait: int = 0,
|
||||
# scale_factor: float = 1,
|
||||
# type: str = "png",
|
||||
# quality: int = 100,
|
||||
# **kwargs
|
||||
# ) -> bytes:
|
||||
# """
|
||||
# Args:
|
||||
# quality:
|
||||
# type:
|
||||
# url: str: URL
|
||||
# wait: int: 等待时间
|
||||
# scale_factor: float: 缩放因子
|
||||
# **kwargs: page 参数
|
||||
# Returns:
|
||||
# 图片二进制数据
|
||||
# """
|
||||
# async with get_new_page(scale_factor) as page:
|
||||
# await page.goto(url)
|
||||
# await page.wait_for_timeout(wait)
|
||||
# return await page.screenshot(
|
||||
# full_page=True,
|
||||
# type=type,
|
||||
# quality=quality
|
||||
# )
|
||||
|
@ -75,8 +75,8 @@ class MarkdownMessage:
|
||||
group_id = event.group_id if message_type == "group" else None
|
||||
user_id = event.user.id if isinstance(event, satori.event.Event) else event.user_id
|
||||
session_id = user_id if message_type == "private" else group_id
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
try:
|
||||
raise TencentBannedMarkdownError("Tencent banned markdown")
|
||||
forward_id = await bot.call_api(
|
||||
|
Reference in New Issue
Block a user