diff --git a/.gitignore b/.gitignore index 90bbdef7..d9da460e 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ _config.yml config.yml config.example.yml compile.bat -.cache/ liteyuki/resources/templates/latest-debug.html # vuepress .github @@ -32,4 +31,7 @@ main.cmd docs/.vuepress/.cache/ docs/.vuepress/.temp/ docs/.vuepress/dist/ -prompt.txt \ No newline at end of file +prompt.txt + +# js +**/echarts.js \ No newline at end of file diff --git a/liteyuki/plugins/liteyuki_uniblacklist/api.py b/liteyuki/plugins/liteyuki_uniblacklist/api.py index be1383e5..f5fb49e3 100644 --- a/liteyuki/plugins/liteyuki_uniblacklist/api.py +++ b/liteyuki/plugins/liteyuki_uniblacklist/api.py @@ -1,5 +1,6 @@ import datetime +import aiohttp import httpx import nonebot from nonebot import require @@ -33,9 +34,9 @@ async def request_for_blacklist(): for plat in platforms: for url in urls: url += f"{plat}.txt" - async with httpx.AsyncClient() as client: + async with aiohttp.ClientSession() as client: resp = await client.get(url) - blacklist_data[plat] = set(resp.text.splitlines()) + blacklist_data[plat] = set((await resp.text()).splitlines()) blacklist = get_uni_set() nonebot.logger.info("blacklists updated") diff --git a/liteyuki/plugins/liteyuki_weather/qw_api.py b/liteyuki/plugins/liteyuki_weather/qw_api.py index ed95813b..9f9afee5 100644 --- a/liteyuki/plugins/liteyuki_weather/qw_api.py +++ b/liteyuki/plugins/liteyuki_weather/qw_api.py @@ -1,3 +1,5 @@ +import aiohttp + from .qw_models import * import httpx @@ -27,7 +29,7 @@ async def check_key_dev(key: str) -> bool: } async with httpx.AsyncClient() as client: resp = await client.get(url, params=params) - return resp.json().get("code") != "200" # 查询不到付费数据为开发版 + return (resp.json()).get("code") != "200" # 查询不到付费数据为开发版 def get_local_data(ulang_code: str) -> dict: diff --git a/liteyuki/plugins/sign_status.py b/liteyuki/plugins/sign_status.py index 751ab748..80824473 100644 --- a/liteyuki/plugins/sign_status.py +++ b/liteyuki/plugins/sign_status.py @@ -1,19 +1,19 @@ import datetime -import json import time -from urllib.parse import urlparse -import httpx +import aiohttp from nonebot import require from nonebot.plugin import PluginMetadata from liteyuki.utils.base.config import get_config from liteyuki.utils.base.data import Database, LiteModel +from liteyuki.utils.base.resource import get_path +from liteyuki.utils.message.html_tool import template2image require("nonebot_plugin_alconna") require("nonebot_plugin_apscheduler") from nonebot_plugin_apscheduler import scheduler -from nonebot_plugin_alconna import Alconna, Subcommand, on_alconna +from nonebot_plugin_alconna import Alconna, AlconnaResult, CommandResult, Subcommand, UniMessage, on_alconna, Args __author__ = "snowykami" __plugin_meta__ = PluginMetadata( @@ -46,7 +46,8 @@ sign_db.auto_migrate(SignCount()) sign_status = on_alconna(Alconna( "sign", Subcommand( - "chart" + "chart", + Args["limit", int, 60] ), Subcommand( "count" @@ -83,8 +84,10 @@ async def _(): @sign_status.assign("chart") -async def _(): - pass +async def _(arp: CommandResult = AlconnaResult()): + limit = arp.result.main_args.get("limit", 60) + img = await generate_chart(limit) + await sign_status.send(UniMessage.image(raw=img)) @scheduler.scheduled_job("interval", seconds=SIGN_COUNT_DURATION, next_run_time=datetime.datetime.now()) @@ -104,11 +107,11 @@ async def get_now_sign() -> dict[str, tuple[float, int]]: """ data = {} now = time.time() - async with httpx.AsyncClient() as client: + async with aiohttp.ClientSession() as client: for name, url in SIGN_COUNT_URLS.items(): - resp = await client.get(url) - count = resp.json()["count"] - data[name] = (now, count) + async with client.get(url) as resp: + count = (await resp.json())["count"] + data[name] = (now, count) return data @@ -123,5 +126,25 @@ async def save_sign_count(timestamp: float, count: int, sid: str): sign_db.save(SignCount(time=timestamp, count=count, sid=sid)) -async def generate_chart(duration: int = 60): - pass +async def generate_chart(limit): + data = [] + for name, url in SIGN_COUNT_URLS.items(): + count_rows = sign_db.all(SignCount(), "sid = ? LIMIT ?", url, limit) + data.append( + { + "name" : name, + # "data": [[row.time, row.count] for row in count_rows] + "times" : [row.time for row in count_rows], + "counts": [row.count for row in count_rows] + } + ) + + img = await template2image( + template=get_path("templates/sign_status.html", debug=True), + templates={ + "data": data + }, + debug=True + ) + + return img diff --git a/liteyuki/resources/lagrange_sign/metadata.yml b/liteyuki/resources/lagrange_sign/metadata.yml new file mode 100644 index 00000000..a7ea1ff4 --- /dev/null +++ b/liteyuki/resources/lagrange_sign/metadata.yml @@ -0,0 +1,3 @@ +name: Sign Status +description: for Lagrange +version: 2024.4.26 \ No newline at end of file diff --git a/liteyuki/resources/lagrange_sign/templates/css/sign_status.css b/liteyuki/resources/lagrange_sign/templates/css/sign_status.css new file mode 100644 index 00000000..7d43a4bb --- /dev/null +++ b/liteyuki/resources/lagrange_sign/templates/css/sign_status.css @@ -0,0 +1,4 @@ +.sign-chart { + height: 400px; + background-color: rgba(255, 255, 255, 0.7); +} \ No newline at end of file diff --git a/liteyuki/resources/lagrange_sign/templates/js/sign_status.js b/liteyuki/resources/lagrange_sign/templates/js/sign_status.js new file mode 100644 index 00000000..ae1bbd17 --- /dev/null +++ b/liteyuki/resources/lagrange_sign/templates/js/sign_status.js @@ -0,0 +1,41 @@ +// 数据类型声明 +// import * as echarts from 'echarts'; + +let data = JSON.parse(document.getElementById("data").innerText) // object +const signChartDivTemplate = document.importNode(document.getElementById("sign-chart-template").content, true) +data.forEach((item) => { + let signChartDiv = signChartDivTemplate.cloneNode(true) + let chartID = item["name"] + // 初始化ECharts实例 + // 设置id + signChartDiv.querySelector(".sign-chart").id = chartID + document.body.appendChild(signChartDiv) + + let signChart = echarts.init(document.getElementById(chartID)) + + signChart.setOption( + { + animation: false, + title: { + text: item["name"], + textStyle: { + color: '#000000' // 设置标题文本颜色为红色 + } + }, + xAxis: { + type: 'category', + data: item["times"], + }, + yAxis: { + type: 'value', + min: Math.min(...item["counts"]), + }, + series: [ + { + data: item["counts"], + type: 'line' + } + ] + } + ) +}) \ No newline at end of file diff --git a/liteyuki/resources/lagrange_sign/templates/sign_status.html b/liteyuki/resources/lagrange_sign/templates/sign_status.html new file mode 100644 index 00000000..eebac37d --- /dev/null +++ b/liteyuki/resources/lagrange_sign/templates/sign_status.html @@ -0,0 +1,22 @@ + + +
+ +