mirror of
https://github.com/ChenXu233/nonebot_plugin_dialectlist.git
synced 2024-12-04 02:54:46 +08:00
✨ 话痨榜的图片渲染!
This commit is contained in:
parent
e08e1d2392
commit
cff3a951b4
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -4,6 +4,7 @@
|
|||||||
"apscheduler",
|
"apscheduler",
|
||||||
"arclet",
|
"arclet",
|
||||||
"Arparma",
|
"Arparma",
|
||||||
|
"bnum",
|
||||||
"cesaa",
|
"cesaa",
|
||||||
"chatdatanum",
|
"chatdatanum",
|
||||||
"chatrecorder",
|
"chatrecorder",
|
||||||
@ -15,6 +16,7 @@
|
|||||||
"pygal",
|
"pygal",
|
||||||
"sqlalchemy",
|
"sqlalchemy",
|
||||||
"userinfo",
|
"userinfo",
|
||||||
|
"whereclause",
|
||||||
"xaxis",
|
"xaxis",
|
||||||
"yaxis"
|
"yaxis"
|
||||||
]
|
]
|
||||||
|
@ -8,12 +8,9 @@ require("nonebot_plugin_alconna")
|
|||||||
require("nonebot_plugin_cesaa")
|
require("nonebot_plugin_cesaa")
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import os
|
||||||
import nonebot_plugin_saa as saa
|
import nonebot_plugin_saa as saa
|
||||||
|
|
||||||
from pyecharts.charts import Bar
|
|
||||||
from pyecharts import options as opts
|
|
||||||
from pyecharts.globals import ThemeType
|
|
||||||
|
|
||||||
from typing import Union, Optional, List
|
from typing import Union, Optional, List
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from arclet.alconna import ArparmaBehavior
|
from arclet.alconna import ArparmaBehavior
|
||||||
@ -50,13 +47,13 @@ from nonebot_plugin_session import Session, SessionIdType, extract_session
|
|||||||
# from .function import *
|
# from .function import *
|
||||||
from .config import Config, plugin_config
|
from .config import Config, plugin_config
|
||||||
from .usage import __usage__
|
from .usage import __usage__
|
||||||
|
from .time import get_datetime_fromisoformat_with_timezone, get_datetime_now_with_timezone,parse_datetime
|
||||||
|
from .model import UserRankInfo
|
||||||
from .utils import (
|
from .utils import (
|
||||||
get_datetime_fromisoformat_with_timezone,
|
|
||||||
get_datetime_now_with_timezone,
|
|
||||||
got_rank,
|
got_rank,
|
||||||
msg_counter,
|
msg_counter,
|
||||||
persist_id2user_id,
|
persist_id2user_id,
|
||||||
parse_datetime,
|
get_rank_image
|
||||||
)
|
)
|
||||||
|
|
||||||
__plugin_meta__ = PluginMetadata(
|
__plugin_meta__ = PluginMetadata(
|
||||||
@ -92,9 +89,9 @@ rank_cmd = on_alconna(
|
|||||||
Alconna(
|
Alconna(
|
||||||
"B话榜",
|
"B话榜",
|
||||||
Args["type?", ["今日", "昨日", "本周", "上周", "本月", "上月", "年度", "历史"]][
|
Args["type?", ["今日", "昨日", "本周", "上周", "本月", "上月", "年度", "历史"]][
|
||||||
"time?",
|
"time?",str,][
|
||||||
str,
|
"group_id?", str
|
||||||
]["group_id?", str],
|
],
|
||||||
behaviors=[SameTime()],
|
behaviors=[SameTime()],
|
||||||
),
|
),
|
||||||
aliases={"废话榜"},
|
aliases={"废话榜"},
|
||||||
@ -223,42 +220,45 @@ async def handle_rank(
|
|||||||
time_stop=stop,
|
time_stop=stop,
|
||||||
exclude_id1s=plugin_config.excluded_people,
|
exclude_id1s=plugin_config.excluded_people,
|
||||||
)
|
)
|
||||||
|
|
||||||
rank = got_rank(msg_counter(messages))
|
rank = got_rank(msg_counter(messages))
|
||||||
|
rank2: List[UserRankInfo] = []
|
||||||
ids = await persist_id2user_id([int(i[0]) for i in rank])
|
ids = await persist_id2user_id([int(i[0]) for i in rank])
|
||||||
for i in range(len(rank)):
|
for i in range(len(rank)):
|
||||||
rank[i][0] = str(ids[i])
|
rank[i][0] = str(ids[i])
|
||||||
|
logger.debug(rank[i])
|
||||||
|
|
||||||
|
total = sum([i[1] for i in rank])
|
||||||
|
|
||||||
string: str = ""
|
|
||||||
nicknames: List = []
|
|
||||||
for i in rank:
|
for i in rank:
|
||||||
if user_info := await get_user_info(bot, event, user_id=str(i[0])):
|
if user_info := await get_user_info(bot, event, user_id=str(i[0])):
|
||||||
(
|
user_nickname = user_info.user_displayname\
|
||||||
nicknames.append(user_info.user_displayname)
|
if user_info.user_displayname\
|
||||||
if user_info.user_displayname
|
else user_info.user_name\
|
||||||
else (
|
if user_info.user_name\
|
||||||
nicknames.append(user_info.user_name)
|
else\
|
||||||
if user_info.user_name
|
user_info.user_id
|
||||||
else nicknames.append(user_info.user_id)
|
user_avatar = await user_info.user_avatar.get_image()\
|
||||||
|
if user_info.user_avatar\
|
||||||
|
else open(os.path.dirname(os.path.abspath(__file__))+"/template/avatar/default.jpg", "rb").read()
|
||||||
|
user = UserRankInfo(**user_info.model_dump(),
|
||||||
|
user_bnum=i[1],
|
||||||
|
user_proportion= round(i[1] / total * 100, 2),
|
||||||
|
user_index= rank.index(i) + 1,
|
||||||
|
user_nickname=user_nickname,
|
||||||
|
user_avatar_bytes= user_avatar,
|
||||||
)
|
)
|
||||||
)
|
user.user_gender="她" if user_info.user_gender == "female" else "他" if user_info.user_gender == "male" else "ta"
|
||||||
else:
|
rank2.append(user)
|
||||||
nicknames.append(None)
|
|
||||||
logger.debug(nicknames)
|
string: str = ""
|
||||||
for i in range(len(rank)):
|
for i in range(len(rank)):
|
||||||
index = i + 1
|
|
||||||
nickname, chatdatanum = nicknames[i], rank[i][1]
|
|
||||||
str_example = plugin_config.string_format.format(
|
str_example = plugin_config.string_format.format(
|
||||||
index=index, nickname=nickname, chatdatanum=chatdatanum
|
index=rank2[i].user_index,
|
||||||
|
nickname=rank2[i].user_nickname,
|
||||||
|
chatdatanum=rank2[i].user_bnum
|
||||||
)
|
)
|
||||||
string += str_example
|
string += str_example
|
||||||
|
|
||||||
bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
|
image = await get_rank_image(rank2)
|
||||||
bar.add_xaxis(nicknames)
|
|
||||||
bar.add_yaxis("B话数量", [i[1] for i in rank]) # type: ignore
|
|
||||||
bar.render(str(get_cache_file("nonebot_plugin_dialectlist", "cache.html")))
|
|
||||||
with open(get_cache_file("nonebot_plugin_dialectlist", "cache.html")) as f:
|
|
||||||
a = f.read()
|
|
||||||
image = await html_to_pic(a, device_scale_factor=3.2)
|
|
||||||
|
|
||||||
await (saa.Text(string) + saa.Image(image)).finish(reply=True)
|
await (saa.Text(string) + saa.Image(image)).finish(reply=True)
|
||||||
|
@ -9,6 +9,7 @@ class ScopedConfig(BaseModel):
|
|||||||
timezone: Optional[str] = "Asia/Shanghai"
|
timezone: Optional[str] = "Asia/Shanghai"
|
||||||
excluded_self: bool = True
|
excluded_self: bool = True
|
||||||
string_format: str = "第{index}名:\n{nickname},{chatdatanum}条消息\n" # 消息格式
|
string_format: str = "第{index}名:\n{nickname},{chatdatanum}条消息\n" # 消息格式
|
||||||
|
template_path: str = "./template/rank_template.j2" # 模板路径
|
||||||
visualization: bool = True # 是否可视化
|
visualization: bool = True # 是否可视化
|
||||||
excluded_people: List[str] = [] # 排除的人的QQ号
|
excluded_people: List[str] = [] # 排除的人的QQ号
|
||||||
visualization_type: Literal["饼图", "圆环图", "柱状图"] = "圆环图" # 可视化方案
|
visualization_type: Literal["饼图", "圆环图", "柱状图"] = "圆环图" # 可视化方案
|
||||||
|
11
nonebot_plugin_dialectlist/model.py
Normal file
11
nonebot_plugin_dialectlist/model.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
from typing import Optional, Literal, List, Union
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from nonebot_plugin_userinfo import get_user_info, UserInfo
|
||||||
|
|
||||||
|
|
||||||
|
class UserRankInfo(UserInfo):
|
||||||
|
user_bnum: int
|
||||||
|
user_proportion: float
|
||||||
|
user_nickname: str
|
||||||
|
user_index: Union[int,str]
|
||||||
|
user_avatar_bytes: bytes
|
@ -1 +0,0 @@
|
|||||||
# TODO 更好的图片渲染,支持自定义模板渲染。
|
|
BIN
nonebot_plugin_dialectlist/template/avatar/default.jpg
Normal file
BIN
nonebot_plugin_dialectlist/template/avatar/default.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
@ -1,10 +1,11 @@
|
|||||||
body {
|
body {
|
||||||
background-image: url('../img/background.jpg');
|
background-image: url('https://image.anosu.top/pixiv/direct?size=regular');
|
||||||
background-attachment: scroll;
|
background-attachment: scroll;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
width: 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@ -74,8 +75,8 @@ body {
|
|||||||
border-radius: 2rem;
|
border-radius: 2rem;
|
||||||
/* padding: 20px 40px; */
|
/* padding: 20px 40px; */
|
||||||
align-content: center;
|
align-content: center;
|
||||||
backdrop-filter: blur(30px);
|
backdrop-filter: blur(10px);
|
||||||
-webkit-backdrop-filter: blur(30px);
|
-webkit-backdrop-filter: blur(10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile{
|
.profile{
|
||||||
@ -88,8 +89,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.profile2{
|
.profile2{
|
||||||
width: 4%;
|
width: 8%;
|
||||||
height: 4%;
|
height: 8%;
|
||||||
border: 3px solid rgba(255, 255, 255, 0.61);
|
border: 3px solid rgba(255, 255, 255, 0.61);
|
||||||
border-radius: 2000px;
|
border-radius: 2000px;
|
||||||
background-size: cover;
|
background-size: cover;
|
39
nonebot_plugin_dialectlist/template/rank_template.j2
Normal file
39
nonebot_plugin_dialectlist/template/rank_template.j2
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>
|
||||||
|
在 title 里夹一点私货应该不会被发现吧?——ddl 真是太厉害啦!
|
||||||
|
</title>
|
||||||
|
<link rel="stylesheet" href="./css/style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="card" >
|
||||||
|
<p class="center_text">话痨排行榜</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rank_container">
|
||||||
|
|
||||||
|
{% for i in users %}
|
||||||
|
<div class="rank_card">
|
||||||
|
<img class="profile" src="{{ cache_path }}/{{ i.user_id }}.jpg"/>
|
||||||
|
<div class="rank_card_info">
|
||||||
|
<h1>第{{ i.user_index }}名:{{ i.user_name }}</h1>
|
||||||
|
<div class="g-container">
|
||||||
|
<div class="g-progress" style="width: {{ i.user_proportion }}%"></div>
|
||||||
|
</div>
|
||||||
|
<p>{{ i.user_gender }}一共废话了{{ i.user_bnum }}句,占比{{ i.user_proportion }}%</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card2">
|
||||||
|
<img class="profile2" src="{{ file_path }}/template/avatar/master.jpg"/>
|
||||||
|
<p class="center_text2">Designed By ChenXu233</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Binary file not shown.
Before Width: | Height: | Size: 543 KiB |
Binary file not shown.
Before Width: | Height: | Size: 38 KiB |
@ -1,104 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>
|
|
||||||
在 title 里夹一点私货应该不会被发现吧?——ddl 真是太厉害啦!
|
|
||||||
</title>
|
|
||||||
<link rel="stylesheet" href="./css/style.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<div class="card" >
|
|
||||||
<p class="center_text">话痨排行榜</p>
|
|
||||||
</div>
|
|
||||||
<div class="rank_container">
|
|
||||||
<div class="rank_card">
|
|
||||||
<img class="profile" src="./cache/头像.jpg"/>
|
|
||||||
<div class="rank_card_info">
|
|
||||||
<h1>第一名:ChenXu233</h1>
|
|
||||||
<div class="g-container">
|
|
||||||
<div class="g-progress" style="width: 100%"></div>
|
|
||||||
</div>
|
|
||||||
<p>ta一共废话了12131231句,占比100%</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rank_card">
|
|
||||||
<img class="profile" src="./cache/头像.jpg"/>
|
|
||||||
<div class="rank_card_info">
|
|
||||||
<h1>第一名:ChenXu233</h1>
|
|
||||||
<div class="g-container">
|
|
||||||
<div class="g-progress"></div>
|
|
||||||
</div>
|
|
||||||
<p>ta一共废话了12131231句,占比100%</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rank_card">
|
|
||||||
<img class="profile" src="./cache/头像.jpg"/>
|
|
||||||
<div class="rank_card_info">
|
|
||||||
<h1>第一名:ChenXu233</h1>
|
|
||||||
<div class="g-container">
|
|
||||||
<div class="g-progress"></div>
|
|
||||||
</div>
|
|
||||||
<p>ta一共废话了12131231句,占比100%</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rank_card">
|
|
||||||
<img class="profile" src="./cache/头像.jpg"/>
|
|
||||||
<div class="rank_card_info">
|
|
||||||
<h1>第一名:ChenXu233</h1>
|
|
||||||
<div class="g-container">
|
|
||||||
<div class="g-progress"></div>
|
|
||||||
</div>
|
|
||||||
<p>ta一共废话了12131231句,占比100%</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rank_card">
|
|
||||||
<img class="profile" src="./cache/头像.jpg"/>
|
|
||||||
<div class="rank_card_info">
|
|
||||||
<h1>第一名:ChenXu233</h1>
|
|
||||||
<div class="g-container">
|
|
||||||
<div class="g-progress"></div>
|
|
||||||
</div>
|
|
||||||
<p>ta一共废话了12131231句,占比100%</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rank_card">
|
|
||||||
<img class="profile" src="./cache/头像.jpg"/>
|
|
||||||
<div class="rank_card_info">
|
|
||||||
<h1>第一名:ChenXu233</h1>
|
|
||||||
<div class="g-container">
|
|
||||||
<div class="g-progress"></div>
|
|
||||||
</div>
|
|
||||||
<p>ta一共废话了12131231句,占比100%</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rank_card">
|
|
||||||
<img class="profile" src="./cache/头像.jpg"/>
|
|
||||||
<div class="rank_card_info">
|
|
||||||
<h1>第一名:ChenXu233</h1>
|
|
||||||
<div class="g-container">
|
|
||||||
<div class="g-progress" style="width: 100%"></div>
|
|
||||||
</div>
|
|
||||||
<p>ta一共废话了12131231句,占比100%</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rank_card">
|
|
||||||
<img class="profile" src="./cache/头像.jpg"/>
|
|
||||||
<div class="rank_card_info">
|
|
||||||
<h1>第一名:ChenXu233</h1>
|
|
||||||
<div class="g-container">
|
|
||||||
<div class="g-progress"></div>
|
|
||||||
</div>
|
|
||||||
<p>ta一共废话了12131231句,占比100%</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="card2">
|
|
||||||
<img class="profile2" src="./img/头像.jpg"/>
|
|
||||||
<p class="center_text2">Designed By ChenXu233</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1 +1,80 @@
|
|||||||
# TODO 时间处理模块,用于处理时间相关操作。
|
# TODO 时间处理模块,用于处理时间相关操作。
|
||||||
|
from datetime import datetime, time, tzinfo
|
||||||
|
from typing import Optional, Union
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
|
from nonebot.typing import T_State
|
||||||
|
from nonebot.params import Arg
|
||||||
|
from nonebot.adapters import Message
|
||||||
|
|
||||||
|
from nonebot_plugin_apscheduler import scheduler
|
||||||
|
from nonebot_plugin_alconna import AlconnaMatcher
|
||||||
|
|
||||||
|
|
||||||
|
from .config import plugin_config
|
||||||
|
|
||||||
|
|
||||||
|
def parse_datetime(key: str):
|
||||||
|
"""解析数字,并将结果存入 state 中"""
|
||||||
|
|
||||||
|
async def _key_parser(
|
||||||
|
matcher: AlconnaMatcher,
|
||||||
|
state: T_State,
|
||||||
|
input: Union[datetime, Message] = Arg(key),
|
||||||
|
):
|
||||||
|
if isinstance(input, datetime):
|
||||||
|
return
|
||||||
|
|
||||||
|
plaintext = input.extract_plain_text()
|
||||||
|
try:
|
||||||
|
state[key] = get_datetime_fromisoformat_with_timezone(plaintext)
|
||||||
|
except ValueError:
|
||||||
|
await matcher.reject_arg(key, "请输入正确的日期,不然我没法理解呢!")
|
||||||
|
|
||||||
|
return _key_parser
|
||||||
|
|
||||||
|
|
||||||
|
def get_datetime_now_with_timezone() -> datetime:
|
||||||
|
"""获取当前时间,并包含时区信息"""
|
||||||
|
if plugin_config.timezone:
|
||||||
|
return datetime.now(ZoneInfo(plugin_config.timezone))
|
||||||
|
else:
|
||||||
|
return datetime.now().astimezone()
|
||||||
|
|
||||||
|
|
||||||
|
def get_datetime_fromisoformat_with_timezone(date_string: str) -> datetime:
|
||||||
|
"""从 ISO-8601 格式字符串中获取时间,并包含时区信息"""
|
||||||
|
if not plugin_config.timezone:
|
||||||
|
return datetime.fromisoformat(date_string).astimezone()
|
||||||
|
raw = datetime.fromisoformat(date_string)
|
||||||
|
return (
|
||||||
|
raw.astimezone(ZoneInfo(plugin_config.timezone))
|
||||||
|
if raw.tzinfo
|
||||||
|
else raw.replace(tzinfo=ZoneInfo(plugin_config.timezone))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def time_astimezone(time: time, tz: Optional[tzinfo] = None) -> time:
|
||||||
|
"""将 time 对象转换为指定时区的 time 对象
|
||||||
|
|
||||||
|
如果 tz 为 None,则转换为本地时区
|
||||||
|
"""
|
||||||
|
local_time = datetime.combine(datetime.today(), time)
|
||||||
|
return local_time.astimezone(tz).timetz()
|
||||||
|
|
||||||
|
|
||||||
|
def get_time_fromisoformat_with_timezone(time_string: str) -> time:
|
||||||
|
"""从 iso8601 格式字符串中获取时间,并包含时区信息"""
|
||||||
|
if not plugin_config.timezone:
|
||||||
|
return time_astimezone(time.fromisoformat(time_string))
|
||||||
|
raw = time.fromisoformat(time_string)
|
||||||
|
return (
|
||||||
|
time_astimezone(raw, ZoneInfo(plugin_config.timezone))
|
||||||
|
if raw.tzinfo
|
||||||
|
else raw.replace(tzinfo=ZoneInfo(plugin_config.timezone))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_time_with_scheduler_timezone(time: time) -> time:
|
||||||
|
"""获取转换到 APScheduler 时区的时间"""
|
||||||
|
return time_astimezone(time, scheduler.timezone)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
from datetime import datetime, time, tzinfo
|
import os
|
||||||
|
import unicodedata
|
||||||
|
|
||||||
from typing import Optional, Dict, List, Union
|
from typing import Optional, Dict, List, Union
|
||||||
from zoneinfo import ZoneInfo
|
from pathlib import Path
|
||||||
from sqlalchemy import or_, select
|
from sqlalchemy import or_, select
|
||||||
from sqlalchemy.sql import ColumnElement
|
from sqlalchemy.sql import ColumnElement
|
||||||
|
|
||||||
@ -14,79 +16,17 @@ from nonebot_plugin_orm import get_session
|
|||||||
from nonebot_plugin_session import Session, SessionLevel, extract_session
|
from nonebot_plugin_session import Session, SessionLevel, extract_session
|
||||||
from nonebot_plugin_session_orm import SessionModel
|
from nonebot_plugin_session_orm import SessionModel
|
||||||
from nonebot_plugin_userinfo import EventUserInfo, UserInfo
|
from nonebot_plugin_userinfo import EventUserInfo, UserInfo
|
||||||
|
from nonebot_plugin_htmlrender import html_to_pic,template_to_pic
|
||||||
from nonebot_plugin_apscheduler import scheduler
|
from nonebot_plugin_apscheduler import scheduler
|
||||||
from nonebot_plugin_chatrecorder import MessageRecord
|
from nonebot_plugin_chatrecorder import MessageRecord
|
||||||
|
from nonebot_plugin_localstore import get_cache_dir
|
||||||
from nonebot_plugin_alconna import AlconnaMatcher
|
from nonebot_plugin_alconna import AlconnaMatcher
|
||||||
|
|
||||||
|
|
||||||
from .config import plugin_config
|
from .config import plugin_config
|
||||||
|
from .model import UserRankInfo
|
||||||
|
|
||||||
|
cache_path = get_cache_dir("nonebot_plugin_dialectlist")
|
||||||
def parse_datetime(key: str):
|
|
||||||
"""解析数字,并将结果存入 state 中"""
|
|
||||||
|
|
||||||
async def _key_parser(
|
|
||||||
matcher: AlconnaMatcher,
|
|
||||||
state: T_State,
|
|
||||||
input: Union[datetime, Message] = Arg(key),
|
|
||||||
):
|
|
||||||
if isinstance(input, datetime):
|
|
||||||
return
|
|
||||||
|
|
||||||
plaintext = input.extract_plain_text()
|
|
||||||
try:
|
|
||||||
state[key] = get_datetime_fromisoformat_with_timezone(plaintext)
|
|
||||||
except ValueError:
|
|
||||||
await matcher.reject_arg(key, "请输入正确的日期,不然我没法理解呢!")
|
|
||||||
|
|
||||||
return _key_parser
|
|
||||||
|
|
||||||
|
|
||||||
def get_datetime_now_with_timezone() -> datetime:
|
|
||||||
"""获取当前时间,并包含时区信息"""
|
|
||||||
if plugin_config.timezone:
|
|
||||||
return datetime.now(ZoneInfo(plugin_config.timezone))
|
|
||||||
else:
|
|
||||||
return datetime.now().astimezone()
|
|
||||||
|
|
||||||
|
|
||||||
def get_datetime_fromisoformat_with_timezone(date_string: str) -> datetime:
|
|
||||||
"""从 ISO-8601 格式字符串中获取时间,并包含时区信息"""
|
|
||||||
if not plugin_config.timezone:
|
|
||||||
return datetime.fromisoformat(date_string).astimezone()
|
|
||||||
raw = datetime.fromisoformat(date_string)
|
|
||||||
return (
|
|
||||||
raw.astimezone(ZoneInfo(plugin_config.timezone))
|
|
||||||
if raw.tzinfo
|
|
||||||
else raw.replace(tzinfo=ZoneInfo(plugin_config.timezone))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def time_astimezone(time: time, tz: Optional[tzinfo] = None) -> time:
|
|
||||||
"""将 time 对象转换为指定时区的 time 对象
|
|
||||||
|
|
||||||
如果 tz 为 None,则转换为本地时区
|
|
||||||
"""
|
|
||||||
local_time = datetime.combine(datetime.today(), time)
|
|
||||||
return local_time.astimezone(tz).timetz()
|
|
||||||
|
|
||||||
|
|
||||||
def get_time_fromisoformat_with_timezone(time_string: str) -> time:
|
|
||||||
"""从 iso8601 格式字符串中获取时间,并包含时区信息"""
|
|
||||||
if not plugin_config.timezone:
|
|
||||||
return time_astimezone(time.fromisoformat(time_string))
|
|
||||||
raw = time.fromisoformat(time_string)
|
|
||||||
return (
|
|
||||||
time_astimezone(raw, ZoneInfo(plugin_config.timezone))
|
|
||||||
if raw.tzinfo
|
|
||||||
else raw.replace(tzinfo=ZoneInfo(plugin_config.timezone))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_time_with_scheduler_timezone(time: time) -> time:
|
|
||||||
"""获取转换到 APScheduler 时区的时间"""
|
|
||||||
return time_astimezone(time, scheduler.timezone)
|
|
||||||
|
|
||||||
|
|
||||||
# 暂时不做考虑
|
# 暂时不做考虑
|
||||||
# def admin_permission():
|
# def admin_permission():
|
||||||
@ -154,7 +94,7 @@ def msg_counter(msg_list: List[MessageRecord]) -> Dict[str, int]:
|
|||||||
return lst
|
return lst
|
||||||
|
|
||||||
|
|
||||||
def got_rank(msg_dict: Dict[str, int]) -> List[List[Union[str, int]]]:
|
def got_rank(msg_dict: Dict[str, int]) -> List:
|
||||||
"""### 获得排行榜
|
"""### 获得排行榜
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -179,30 +119,33 @@ def got_rank(msg_dict: Dict[str, int]) -> List[List[Union[str, int]]]:
|
|||||||
|
|
||||||
return rank
|
return rank
|
||||||
|
|
||||||
# def remove_control_characters(string: str) -> str:
|
def remove_control_characters(string: str) -> str:
|
||||||
# """### 将字符串中的控制符去除
|
"""### 将字符串中的控制符去除
|
||||||
|
|
||||||
# Args:
|
Args:
|
||||||
# string (str): 需要去除的字符串
|
string (str): 需要去除的字符串
|
||||||
|
|
||||||
# Returns:
|
Returns:
|
||||||
# (str): 经过处理的字符串
|
(str): 经过处理的字符串
|
||||||
# """
|
"""
|
||||||
# return "".join(ch for ch in string if unicodedata.category(ch)[0] != "C")
|
return "".join(ch for ch in string if unicodedata.category(ch)[0] != "C")
|
||||||
|
|
||||||
|
async def get_rank_image(rank: List[UserRankInfo]) -> bytes:
|
||||||
|
for i in rank:
|
||||||
|
if i.user_avatar:
|
||||||
|
try:
|
||||||
|
user_avatar = i.user_avatar_bytes
|
||||||
|
except NotImplementedError:
|
||||||
|
user_avatar = open(os.path.dirname(os.path.abspath(__file__))+"/template/avatar/default.jpg", "rb").read()
|
||||||
|
# if not os.path.exists(cache_path / str(i.user_id)):
|
||||||
|
with open(cache_path / (str(i.user_id) + ".jpg"), "wb") as f:
|
||||||
|
f.write(user_avatar)
|
||||||
|
|
||||||
# async def render_template_pic(self) -> bytes:
|
if plugin_config.template_path[:2] == './':
|
||||||
# if plugin_config.dialectlist_visualization_type == "圆环图":
|
path = os.path.dirname(os.path.abspath(__file__)) + plugin_config.template_path[1:]
|
||||||
# view = pygal.Pie(inner_radius=0.6, style=style)
|
else:
|
||||||
# elif plugin_config.dialectlist_visualization_type == "饼图":
|
path = plugin_config.template_path
|
||||||
# view = pygal.Pie(style=style)
|
|
||||||
# else:
|
|
||||||
# view = pygal.Bar(style=style)
|
|
||||||
|
|
||||||
# view.title = "消息可视化"
|
path_dir, filename = os.path.split(path)
|
||||||
# for i, j in zip(self.rank, await self.get_nickname_list()): # type: ignore
|
logger.debug(os.path.dirname(os.path.abspath(__file__)) + plugin_config.template_path[1:])
|
||||||
# view.add(str(j), int(i[1]))
|
return await template_to_pic(path_dir,filename,{'users': rank, 'cache_path': cache_path, 'file_path': os.path.dirname(os.path.abspath(__file__))})
|
||||||
|
|
||||||
# png: bytes = view.render_to_png() # type: ignore
|
|
||||||
# self.img = png
|
|
||||||
# return png
|
|
283
pdm.lock
283
pdm.lock
@ -5,7 +5,7 @@
|
|||||||
groups = ["default", "dev"]
|
groups = ["default", "dev"]
|
||||||
strategy = ["cross_platform", "inherit_metadata"]
|
strategy = ["cross_platform", "inherit_metadata"]
|
||||||
lock_version = "4.4.1"
|
lock_version = "4.4.1"
|
||||||
content_hash = "sha256:fdb46c5e66cf97af4806bb28cc369a5cfee536532eb9a1b05d581d5856ffcf6d"
|
content_hash = "sha256:74fd9abb0888f1ded1c2cef549dd45e68a73c42bab5d7e37c1d3f2e5880a4cdb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiofiles"
|
name = "aiofiles"
|
||||||
@ -39,7 +39,7 @@ name = "annotated-types"
|
|||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Reusable constraint types to use with typing.Annotated"
|
summary = "Reusable constraint types to use with typing.Annotated"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
|
{file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
|
||||||
{file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
|
{file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
|
||||||
@ -50,7 +50,7 @@ name = "anyio"
|
|||||||
version = "4.4.0"
|
version = "4.4.0"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "High level compatibility layer for multiple asynchronous event loop implementations"
|
summary = "High level compatibility layer for multiple asynchronous event loop implementations"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"exceptiongroup>=1.0.2; python_version < \"3.11\"",
|
"exceptiongroup>=1.0.2; python_version < \"3.11\"",
|
||||||
"idna>=2.8",
|
"idna>=2.8",
|
||||||
@ -109,6 +109,21 @@ files = [
|
|||||||
{file = "arclet_alconna_tools-0.7.6.tar.gz", hash = "sha256:7cb7dc54c1c2198529c63227739423401051b8489374f1a7a3efa0c4e70b2a22"},
|
{file = "arclet_alconna_tools-0.7.6.tar.gz", hash = "sha256:7cb7dc54c1c2198529c63227739423401051b8489374f1a7a3efa0c4e70b2a22"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrow"
|
||||||
|
version = "1.3.0"
|
||||||
|
requires_python = ">=3.8"
|
||||||
|
summary = "Better dates & times for Python"
|
||||||
|
groups = ["dev"]
|
||||||
|
dependencies = [
|
||||||
|
"python-dateutil>=2.7.0",
|
||||||
|
"types-python-dateutil>=2.8.10",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"},
|
||||||
|
{file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backports-tarfile"
|
name = "backports-tarfile"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -121,6 +136,19 @@ files = [
|
|||||||
{file = "backports_tarfile-1.2.0.tar.gz", hash = "sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991"},
|
{file = "backports_tarfile-1.2.0.tar.gz", hash = "sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "binaryornot"
|
||||||
|
version = "0.4.4"
|
||||||
|
summary = "Ultra-lightweight pure Python package to check if a file is binary or text."
|
||||||
|
groups = ["dev"]
|
||||||
|
dependencies = [
|
||||||
|
"chardet>=3.0.2",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"},
|
||||||
|
{file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cachetools"
|
name = "cachetools"
|
||||||
version = "5.3.3"
|
version = "5.3.3"
|
||||||
@ -132,6 +160,17 @@ files = [
|
|||||||
{file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"},
|
{file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cashews"
|
||||||
|
version = "7.1.0"
|
||||||
|
requires_python = ">=3.8"
|
||||||
|
summary = "cache tools with async power"
|
||||||
|
groups = ["dev"]
|
||||||
|
files = [
|
||||||
|
{file = "cashews-7.1.0-py3-none-any.whl", hash = "sha256:b7c1ae4d49df6fdbff88e5025d3c1156515f58724c5b96fc9a9d081afada82a8"},
|
||||||
|
{file = "cashews-7.1.0.tar.gz", hash = "sha256:058df55a39cb15697d331e7e41c2882b58d0d323f5671316105cc78668af7705"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "certifi"
|
name = "certifi"
|
||||||
version = "2024.6.2"
|
version = "2024.6.2"
|
||||||
@ -189,6 +228,17 @@ files = [
|
|||||||
{file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"},
|
{file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chardet"
|
||||||
|
version = "5.2.0"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "Universal encoding detector for Python 3"
|
||||||
|
groups = ["dev"]
|
||||||
|
files = [
|
||||||
|
{file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
|
||||||
|
{file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "charset-normalizer"
|
name = "charset-normalizer"
|
||||||
version = "3.3.2"
|
version = "3.3.2"
|
||||||
@ -250,7 +300,7 @@ name = "click"
|
|||||||
version = "8.1.7"
|
version = "8.1.7"
|
||||||
requires_python = ">=3.7"
|
requires_python = ">=3.7"
|
||||||
summary = "Composable command line interface toolkit"
|
summary = "Composable command line interface toolkit"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"colorama; platform_system == \"Windows\"",
|
"colorama; platform_system == \"Windows\"",
|
||||||
]
|
]
|
||||||
@ -264,13 +314,34 @@ name = "colorama"
|
|||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||||
summary = "Cross-platform colored terminal text."
|
summary = "Cross-platform colored terminal text."
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
marker = "sys_platform == \"win32\" or platform_system == \"Windows\""
|
marker = "sys_platform == \"win32\" or platform_system == \"Windows\""
|
||||||
files = [
|
files = [
|
||||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookiecutter"
|
||||||
|
version = "2.6.0"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template."
|
||||||
|
groups = ["dev"]
|
||||||
|
dependencies = [
|
||||||
|
"Jinja2<4.0.0,>=2.7",
|
||||||
|
"arrow",
|
||||||
|
"binaryornot>=0.4.4",
|
||||||
|
"click<9.0.0,>=7.0",
|
||||||
|
"python-slugify>=4.0.0",
|
||||||
|
"pyyaml>=5.3.1",
|
||||||
|
"requests>=2.23.0",
|
||||||
|
"rich",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "cookiecutter-2.6.0-py3-none-any.whl", hash = "sha256:a54a8e37995e4ed963b3e82831072d1ad4b005af736bb17b99c2cbd9d41b6e2d"},
|
||||||
|
{file = "cookiecutter-2.6.0.tar.gz", hash = "sha256:db21f8169ea4f4fdc2408d48ca44859349de2647fbe494a9d6c3edfc0542c21c"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cryptography"
|
name = "cryptography"
|
||||||
version = "42.0.8"
|
version = "42.0.8"
|
||||||
@ -316,6 +387,16 @@ files = [
|
|||||||
{file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"},
|
{file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "distlib"
|
||||||
|
version = "0.3.8"
|
||||||
|
summary = "Distribution utilities"
|
||||||
|
groups = ["dev"]
|
||||||
|
files = [
|
||||||
|
{file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"},
|
||||||
|
{file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dnspython"
|
name = "dnspython"
|
||||||
version = "2.6.1"
|
version = "2.6.1"
|
||||||
@ -372,7 +453,7 @@ name = "exceptiongroup"
|
|||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
requires_python = ">=3.7"
|
requires_python = ">=3.7"
|
||||||
summary = "Backport of PEP 654 (exception groups)"
|
summary = "Backport of PEP 654 (exception groups)"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
marker = "python_version < \"3.11\""
|
marker = "python_version < \"3.11\""
|
||||||
files = [
|
files = [
|
||||||
{file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"},
|
{file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"},
|
||||||
@ -417,6 +498,17 @@ files = [
|
|||||||
{file = "fastapi_cli-0.0.4.tar.gz", hash = "sha256:e2e9ffaffc1f7767f488d6da34b6f5a377751c996f397902eb6abb99a67bde32"},
|
{file = "fastapi_cli-0.0.4.tar.gz", hash = "sha256:e2e9ffaffc1f7767f488d6da34b6f5a377751c996f397902eb6abb99a67bde32"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filelock"
|
||||||
|
version = "3.15.4"
|
||||||
|
requires_python = ">=3.8"
|
||||||
|
summary = "A platform independent file lock."
|
||||||
|
groups = ["dev"]
|
||||||
|
files = [
|
||||||
|
{file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"},
|
||||||
|
{file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetype"
|
name = "filetype"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -469,7 +561,7 @@ name = "h11"
|
|||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
requires_python = ">=3.7"
|
requires_python = ">=3.7"
|
||||||
summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
|
summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
|
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
|
||||||
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
|
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
|
||||||
@ -480,7 +572,7 @@ name = "httpcore"
|
|||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "A minimal low-level HTTP client."
|
summary = "A minimal low-level HTTP client."
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"certifi",
|
"certifi",
|
||||||
"h11<0.15,>=0.13",
|
"h11<0.15,>=0.13",
|
||||||
@ -526,7 +618,7 @@ name = "httpx"
|
|||||||
version = "0.27.0"
|
version = "0.27.0"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "The next generation HTTP client."
|
summary = "The next generation HTTP client."
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyio",
|
"anyio",
|
||||||
"certifi",
|
"certifi",
|
||||||
@ -635,7 +727,7 @@ name = "jinja2"
|
|||||||
version = "3.1.4"
|
version = "3.1.4"
|
||||||
requires_python = ">=3.7"
|
requires_python = ">=3.7"
|
||||||
summary = "A very fast and expressive template engine."
|
summary = "A very fast and expressive template engine."
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"MarkupSafe>=2.0",
|
"MarkupSafe>=2.0",
|
||||||
]
|
]
|
||||||
@ -723,7 +815,7 @@ name = "markupsafe"
|
|||||||
version = "2.1.5"
|
version = "2.1.5"
|
||||||
requires_python = ">=3.7"
|
requires_python = ">=3.7"
|
||||||
summary = "Safely add untrusted strings to HTML/XML markup."
|
summary = "Safely add untrusted strings to HTML/XML markup."
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
|
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
|
||||||
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
|
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
|
||||||
@ -836,6 +928,33 @@ files = [
|
|||||||
{file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"},
|
{file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nb-cli"
|
||||||
|
version = "1.4.1"
|
||||||
|
requires_python = "<4.0,>=3.9"
|
||||||
|
summary = "CLI for nonebot2"
|
||||||
|
groups = ["dev"]
|
||||||
|
dependencies = [
|
||||||
|
"anyio<5.0,>=3.6",
|
||||||
|
"cashews<8.0,>=6.0",
|
||||||
|
"click~=8.1",
|
||||||
|
"cookiecutter~=2.2",
|
||||||
|
"httpx~=0.18",
|
||||||
|
"jinja2~=3.0",
|
||||||
|
"noneprompt<1.0.0,>=0.1.9",
|
||||||
|
"pydantic!=2.5.0,!=2.5.1,<3.0.0,>=1.10.0",
|
||||||
|
"pyfiglet<2.0.0,>=1.0.1",
|
||||||
|
"tomlkit~=0.10",
|
||||||
|
"typing-extensions~=4.4",
|
||||||
|
"virtualenv~=20.21",
|
||||||
|
"watchfiles~=0.16",
|
||||||
|
"wcwidth~=0.2",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "nb_cli-1.4.1-py3-none-any.whl", hash = "sha256:57b6111773202bce29c0520f4a281edb8a7643fa33692d4afc70ca5b51b10f70"},
|
||||||
|
{file = "nb_cli-1.4.1.tar.gz", hash = "sha256:908dd4cbbf66bf46fe879c23ad1377332f63385cebca1912b627aa686d1816f3"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nepattern"
|
name = "nepattern"
|
||||||
version = "0.7.4"
|
version = "0.7.4"
|
||||||
@ -1119,6 +1238,20 @@ files = [
|
|||||||
{file = "nonebot2-2.3.1.tar.gz", hash = "sha256:ac5a1a1759f15310e9183b606ce6bdbe52a90287bf36a69201be548e23d41e6c"},
|
{file = "nonebot2-2.3.1.tar.gz", hash = "sha256:ac5a1a1759f15310e9183b606ce6bdbe52a90287bf36a69201be548e23d41e6c"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "noneprompt"
|
||||||
|
version = "0.1.9"
|
||||||
|
requires_python = ">=3.8,<4.0"
|
||||||
|
summary = "Prompt toolkit for console interaction"
|
||||||
|
groups = ["dev"]
|
||||||
|
dependencies = [
|
||||||
|
"prompt-toolkit<4.0.0,>=3.0.19",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "noneprompt-0.1.9-py3-none-any.whl", hash = "sha256:a54f1e6a19a3da2dedf7f365f80420e9ae49326a0ffe60a8a9c7afdee6b6eeb3"},
|
||||||
|
{file = "noneprompt-0.1.9.tar.gz", hash = "sha256:338b8bb89a8d22ef35f1dedb3aa7c1b228cf139973bdc43c5ffc3eef64457db9"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "orjson"
|
name = "orjson"
|
||||||
version = "3.10.5"
|
version = "3.10.5"
|
||||||
@ -1167,6 +1300,17 @@ files = [
|
|||||||
{file = "pkginfo-1.11.1.tar.gz", hash = "sha256:2e0dca1cf4c8e39644eed32408ea9966ee15e0d324c62ba899a393b3c6b467aa"},
|
{file = "pkginfo-1.11.1.tar.gz", hash = "sha256:2e0dca1cf4c8e39644eed32408ea9966ee15e0d324c62ba899a393b3c6b467aa"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "platformdirs"
|
||||||
|
version = "4.2.2"
|
||||||
|
requires_python = ">=3.8"
|
||||||
|
summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
|
||||||
|
groups = ["dev"]
|
||||||
|
files = [
|
||||||
|
{file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"},
|
||||||
|
{file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "playwright"
|
name = "playwright"
|
||||||
version = "1.44.0"
|
version = "1.44.0"
|
||||||
@ -1201,6 +1345,20 @@ files = [
|
|||||||
{file = "prettytable-3.10.0.tar.gz", hash = "sha256:9665594d137fb08a1117518c25551e0ede1687197cf353a4fdc78d27e1073568"},
|
{file = "prettytable-3.10.0.tar.gz", hash = "sha256:9665594d137fb08a1117518c25551e0ede1687197cf353a4fdc78d27e1073568"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prompt-toolkit"
|
||||||
|
version = "3.0.47"
|
||||||
|
requires_python = ">=3.7.0"
|
||||||
|
summary = "Library for building powerful interactive command lines in Python"
|
||||||
|
groups = ["dev"]
|
||||||
|
dependencies = [
|
||||||
|
"wcwidth",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"},
|
||||||
|
{file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pycparser"
|
name = "pycparser"
|
||||||
version = "2.22"
|
version = "2.22"
|
||||||
@ -1218,7 +1376,7 @@ name = "pydantic"
|
|||||||
version = "2.7.4"
|
version = "2.7.4"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Data validation using Python type hints"
|
summary = "Data validation using Python type hints"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"annotated-types>=0.4.0",
|
"annotated-types>=0.4.0",
|
||||||
"pydantic-core==2.18.4",
|
"pydantic-core==2.18.4",
|
||||||
@ -1234,7 +1392,7 @@ name = "pydantic-core"
|
|||||||
version = "2.18.4"
|
version = "2.18.4"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Core functionality for Pydantic validation and serialization"
|
summary = "Core functionality for Pydantic validation and serialization"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"typing-extensions!=4.7.0,>=4.6.0",
|
"typing-extensions!=4.7.0,>=4.6.0",
|
||||||
]
|
]
|
||||||
@ -1325,6 +1483,17 @@ files = [
|
|||||||
{file = "pyee-11.1.0.tar.gz", hash = "sha256:b53af98f6990c810edd9b56b87791021a8f54fd13db4edd1142438d44ba2263f"},
|
{file = "pyee-11.1.0.tar.gz", hash = "sha256:b53af98f6990c810edd9b56b87791021a8f54fd13db4edd1142438d44ba2263f"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyfiglet"
|
||||||
|
version = "1.0.2"
|
||||||
|
requires_python = ">=3.9"
|
||||||
|
summary = "Pure-python FIGlet implementation"
|
||||||
|
groups = ["dev"]
|
||||||
|
files = [
|
||||||
|
{file = "pyfiglet-1.0.2-py3-none-any.whl", hash = "sha256:889b351d79c99e50a3f619c8f8e6ffdb27fd8c939fc43ecbd7559bd57d5f93ea"},
|
||||||
|
{file = "pyfiglet-1.0.2.tar.gz", hash = "sha256:758788018ab8faaddc0984e1ea05ff330d3c64be663c513cc1f105f6a3066dab"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pygal"
|
name = "pygal"
|
||||||
version = "3.0.4"
|
version = "3.0.4"
|
||||||
@ -1375,6 +1544,20 @@ files = [
|
|||||||
{file = "pymdown_extensions-10.8.1.tar.gz", hash = "sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940"},
|
{file = "pymdown_extensions-10.8.1.tar.gz", hash = "sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-dateutil"
|
||||||
|
version = "2.9.0.post0"
|
||||||
|
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||||
|
summary = "Extensions to the standard Python datetime module"
|
||||||
|
groups = ["dev"]
|
||||||
|
dependencies = [
|
||||||
|
"six>=1.5",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
|
||||||
|
{file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-dotenv"
|
name = "python-dotenv"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@ -1411,6 +1594,20 @@ files = [
|
|||||||
{file = "python_multipart-0.0.9.tar.gz", hash = "sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026"},
|
{file = "python_multipart-0.0.9.tar.gz", hash = "sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-slugify"
|
||||||
|
version = "8.0.4"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "A Python slugify application that also handles Unicode"
|
||||||
|
groups = ["dev"]
|
||||||
|
dependencies = [
|
||||||
|
"text-unidecode>=1.3",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"},
|
||||||
|
{file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytz"
|
name = "pytz"
|
||||||
version = "2024.1"
|
version = "2024.1"
|
||||||
@ -1438,7 +1635,7 @@ name = "pyyaml"
|
|||||||
version = "6.0.1"
|
version = "6.0.1"
|
||||||
requires_python = ">=3.6"
|
requires_python = ">=3.6"
|
||||||
summary = "YAML parser and emitter for Python"
|
summary = "YAML parser and emitter for Python"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
|
{file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
|
||||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
|
{file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
|
||||||
@ -1658,7 +1855,7 @@ name = "six"
|
|||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
summary = "Python 2 and 3 compatibility utilities"
|
summary = "Python 2 and 3 compatibility utilities"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||||
@ -1669,7 +1866,7 @@ name = "sniffio"
|
|||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
requires_python = ">=3.7"
|
requires_python = ">=3.7"
|
||||||
summary = "Sniff out which async library your code is running under"
|
summary = "Sniff out which async library your code is running under"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
|
{file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
|
||||||
{file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
|
{file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
|
||||||
@ -1779,6 +1976,16 @@ files = [
|
|||||||
{file = "tarina-0.5.2.tar.gz", hash = "sha256:7d5d93d73422e97b2409e6a43bf4d11296fe2dac90a5b4dcbc19e56bc1b55298"},
|
{file = "tarina-0.5.2.tar.gz", hash = "sha256:7d5d93d73422e97b2409e6a43bf4d11296fe2dac90a5b4dcbc19e56bc1b55298"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "text-unidecode"
|
||||||
|
version = "1.3"
|
||||||
|
summary = "The most basic Text::Unidecode port"
|
||||||
|
groups = ["dev"]
|
||||||
|
files = [
|
||||||
|
{file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"},
|
||||||
|
{file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tomli"
|
name = "tomli"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
@ -1791,6 +1998,17 @@ files = [
|
|||||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tomlkit"
|
||||||
|
version = "0.12.5"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "Style preserving TOML library"
|
||||||
|
groups = ["dev"]
|
||||||
|
files = [
|
||||||
|
{file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"},
|
||||||
|
{file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "twine"
|
name = "twine"
|
||||||
version = "5.1.0"
|
version = "5.1.0"
|
||||||
@ -1830,12 +2048,23 @@ files = [
|
|||||||
{file = "typer-0.12.3.tar.gz", hash = "sha256:49e73131481d804288ef62598d97a1ceef3058905aa536a1134f90891ba35482"},
|
{file = "typer-0.12.3.tar.gz", hash = "sha256:49e73131481d804288ef62598d97a1ceef3058905aa536a1134f90891ba35482"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "types-python-dateutil"
|
||||||
|
version = "2.9.0.20240316"
|
||||||
|
requires_python = ">=3.8"
|
||||||
|
summary = "Typing stubs for python-dateutil"
|
||||||
|
groups = ["dev"]
|
||||||
|
files = [
|
||||||
|
{file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"},
|
||||||
|
{file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typing-extensions"
|
name = "typing-extensions"
|
||||||
version = "4.12.2"
|
version = "4.12.2"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Backported and Experimental Type Hints for Python 3.8+"
|
summary = "Backported and Experimental Type Hints for Python 3.8+"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
|
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
|
||||||
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
|
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
|
||||||
@ -2012,12 +2241,28 @@ files = [
|
|||||||
{file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"},
|
{file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "virtualenv"
|
||||||
|
version = "20.26.3"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "Virtual Python Environment builder"
|
||||||
|
groups = ["dev"]
|
||||||
|
dependencies = [
|
||||||
|
"distlib<1,>=0.3.7",
|
||||||
|
"filelock<4,>=3.12.2",
|
||||||
|
"platformdirs<5,>=3.9.1",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"},
|
||||||
|
{file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "watchfiles"
|
name = "watchfiles"
|
||||||
version = "0.22.0"
|
version = "0.22.0"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Simple, modern and high performance file watching and code reload in python."
|
summary = "Simple, modern and high performance file watching and code reload in python."
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyio>=3.0.0",
|
"anyio>=3.0.0",
|
||||||
]
|
]
|
||||||
@ -2079,7 +2324,7 @@ files = [
|
|||||||
name = "wcwidth"
|
name = "wcwidth"
|
||||||
version = "0.2.13"
|
version = "0.2.13"
|
||||||
summary = "Measures the displayed width of unicode strings in a terminal"
|
summary = "Measures the displayed width of unicode strings in a terminal"
|
||||||
groups = ["default"]
|
groups = ["default", "dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
|
{file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
|
||||||
{file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
|
{file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "nonebot_plugin_dialectlist"
|
name = "nonebot_plugin_dialectlist"
|
||||||
version = "2.0.4"
|
version = "2.1.4"
|
||||||
description = "Default template for PDM package"
|
description = "看看你群群友有多能说"
|
||||||
authors = [
|
authors = [
|
||||||
{name = "Chen_Xu233", email = "woyerpa@outlook.com"},
|
{name = "Chen_Xu233", email = "woyerpa@outlook.com"},
|
||||||
]
|
]
|
||||||
@ -27,6 +27,7 @@ dev = [
|
|||||||
"ruff>=0.4.9",
|
"ruff>=0.4.9",
|
||||||
"setuptools>=70.0.0",
|
"setuptools>=70.0.0",
|
||||||
"twine>=5.1.0",
|
"twine>=5.1.0",
|
||||||
|
"nb-cli>=0.7.6"
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.pdm]
|
[tool.pdm]
|
||||||
|
@ -4,7 +4,9 @@ with sync_playwright() as p:
|
|||||||
for browser_type in [p.chromium, p.firefox, p.webkit]:
|
for browser_type in [p.chromium, p.firefox, p.webkit]:
|
||||||
browser = browser_type.launch(headless=True)
|
browser = browser_type.launch(headless=True)
|
||||||
page = browser.new_page()
|
page = browser.new_page()
|
||||||
page.goto('file:///H:/Bot/%E7%8E%B0%E5%BD%B9Bot/mybot/src/nonebot_plugin_dialectlist/nonebot_plugin_dialectlist/temple/rank_temple.html')
|
page.goto(
|
||||||
page.screenshot(path=f'screenshot-{browser_type.name}.png',full_page=True)
|
"file:///H:/Bot/%E7%8E%B0%E5%BD%B9Bot/mybot/src/nonebot_plugin_dialectlist/nonebot_plugin_dialectlist/temple/rank_temple.html"
|
||||||
|
)
|
||||||
|
page.screenshot(path=f"screenshot-{browser_type.name}.png", full_page=True)
|
||||||
print(page.title())
|
print(page.title())
|
||||||
browser.close()
|
browser.close()
|
Loading…
Reference in New Issue
Block a user