mirror of
https://github.com/ChenXu233/nonebot_plugin_dialectlist.git
synced 2026-01-25 21:22:16 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7baa9b04b | ||
|
|
df2cd495c0 | ||
|
|
d2e185c189 | ||
|
|
a753305282 | ||
|
|
ad5f556229 | ||
|
|
3efaafe81c | ||
|
|
c6b87bf981 | ||
|
|
e62f2ed488 | ||
|
|
e5d107c520 | ||
|
|
bf577b5a31 | ||
|
|
d514d96db6 | ||
|
|
677ec56aeb | ||
|
|
4194097258 | ||
|
|
c94de918e9 | ||
|
|
a765267cf1 | ||
|
|
ea682ef18d | ||
|
|
ed7f1167f2 | ||
|
|
9944ece153 | ||
|
|
8d905cb647 |
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -11,8 +11,10 @@
|
||||
"dialectlist",
|
||||
"displayname",
|
||||
"htmlrender",
|
||||
"httpx",
|
||||
"localstore",
|
||||
"parameterless",
|
||||
"postprocessor",
|
||||
"pyecharts",
|
||||
"pygal",
|
||||
"sqlalchemy",
|
||||
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 ChenXu233
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -158,12 +158,6 @@ __!!注意!!__
|
||||
|
||||
- [x] 私聊的查询(超级用户可以任意查询群聊的信息)一半完成
|
||||
|
||||
- [ ] 提供多样化的渲染器配置(html 渲染,pillow 渲染,统计绘图软件渲染)
|
||||
|
||||
- [ ] 使用管理员权限直接获取 QQ 官方统计的今日消息量以优化代码运行速度
|
||||
|
||||
- [ ] 为 pillow 渲染方式提供插件的加载方式(什么?插件里的插件???)
|
||||
|
||||
- [ ] 特殊的储存方案优化消息统计
|
||||
|
||||
- [ ] 查询带某关键词的消息量
|
||||
|
||||
@@ -8,21 +8,19 @@ require("nonebot_plugin_alconna")
|
||||
require("nonebot_plugin_cesaa")
|
||||
|
||||
import re
|
||||
import os
|
||||
import time as t
|
||||
import nonebot_plugin_saa as saa
|
||||
|
||||
from typing import Union, Optional, List
|
||||
from typing import Union, Optional
|
||||
from datetime import datetime, timedelta
|
||||
from arclet.alconna import ArparmaBehavior
|
||||
from arclet.alconna.arparma import Arparma
|
||||
|
||||
from nonebot import on_command
|
||||
from nonebot.log import logger
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.compat import model_dump
|
||||
from nonebot.params import Arg, Depends
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.plugin import PluginMetadata, inherit_supported_adapters
|
||||
from nonebot_plugin_alconna import (
|
||||
Args,
|
||||
@@ -30,14 +28,10 @@ from nonebot_plugin_alconna import (
|
||||
Alconna,
|
||||
on_alconna,
|
||||
)
|
||||
|
||||
from nonebot_plugin_apscheduler import scheduler
|
||||
from nonebot_plugin_userinfo import get_user_info
|
||||
from nonebot_plugin_chatrecorder import get_message_records
|
||||
from nonebot_plugin_session import Session, SessionIdType, extract_session
|
||||
|
||||
# from . import migrations #抄词云的部分代码,还不知道这有什么用
|
||||
# from .function import *
|
||||
from .storage import get_cache, build_cache
|
||||
from .config import Config, plugin_config
|
||||
from .usage import __usage__
|
||||
from .time import (
|
||||
@@ -45,14 +39,12 @@ from .time import (
|
||||
get_datetime_now_with_timezone,
|
||||
parse_datetime,
|
||||
)
|
||||
from .model import UserRankInfo
|
||||
from .utils import (
|
||||
got_rank,
|
||||
msg_counter,
|
||||
get_rank_image,
|
||||
persist_id2user_id,
|
||||
get_user_infos,
|
||||
# get_user_info2,
|
||||
)
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
@@ -65,7 +57,6 @@ __plugin_meta__ = PluginMetadata(
|
||||
"nonebot_plugin_chatrecorder", "nonebot_plugin_saa", "nonebot_plugin_alconna"
|
||||
),
|
||||
config=Config,
|
||||
# extra={"orm_version_location": migrations},
|
||||
)
|
||||
|
||||
|
||||
@@ -84,6 +75,16 @@ def wrapper(slot: Union[int, str], content: Optional[str], context) -> str:
|
||||
return "" # pragma: no cover
|
||||
|
||||
|
||||
build_cache_cmd = on_command("build_cache", aliases={"重建缓存"}, block=True)
|
||||
|
||||
|
||||
@build_cache_cmd.handle()
|
||||
async def _build_cache(bot: Bot, event: Event):
|
||||
await saa.Text("正在重建缓存,请稍等。").send(reply=True)
|
||||
await build_cache()
|
||||
await saa.Text("重建缓存完成。").send(reply=True)
|
||||
|
||||
|
||||
rank_cmd = on_alconna(
|
||||
Alconna(
|
||||
"B话榜",
|
||||
@@ -194,8 +195,6 @@ async def _group_message(
|
||||
except ValueError:
|
||||
await rank_cmd.finish("请输入正确的日期,不然我没法理解呢!")
|
||||
|
||||
logger.debug(f"命令解析花费时间:{t.time() - t1}")
|
||||
|
||||
|
||||
@rank_cmd.got(
|
||||
"start",
|
||||
@@ -216,7 +215,7 @@ async def handle_rank(
|
||||
start: datetime = Arg(),
|
||||
stop: datetime = Arg(),
|
||||
):
|
||||
|
||||
|
||||
if id := state["group_id"]:
|
||||
id = str(id)
|
||||
logger.debug(f"group_id: {id}")
|
||||
@@ -228,8 +227,11 @@ async def handle_rank(
|
||||
await saa.Text("没有指定群哦").finish()
|
||||
|
||||
if plugin_config.counting_cache:
|
||||
raise Exception("我草缓存功能还没端上来呢,你怎么就先用上了")
|
||||
t1 = t.time()
|
||||
raw_rank = await get_cache(start, stop, id)
|
||||
logger.debug(f"获取计数消息花费时间:{t.time() - t1}")
|
||||
else:
|
||||
t1 = t.time()
|
||||
messages = await get_message_records(
|
||||
id2s=[id],
|
||||
id_type=SessionIdType.GROUP,
|
||||
@@ -240,14 +242,13 @@ async def handle_rank(
|
||||
time_stop=stop,
|
||||
exclude_id1s=plugin_config.excluded_people,
|
||||
)
|
||||
|
||||
if not messages:
|
||||
await saa.Text("明明这个时间段都没有人说话怎么会有话痨榜呢?").finish()
|
||||
|
||||
raw_rank = msg_counter(messages)
|
||||
logger.debug(f"获取计数消息花费时间:{t.time() - t1}")
|
||||
|
||||
if not raw_rank:
|
||||
await saa.Text("明明这个时间段都没有人说话怎么会有话痨榜呢?").finish()
|
||||
|
||||
rank = got_rank(raw_rank)
|
||||
logger.debug(rank)
|
||||
ids = await persist_id2user_id([int(i[0]) for i in rank])
|
||||
for i in range(len(rank)):
|
||||
rank[i][0] = str(ids[i])
|
||||
@@ -256,37 +257,33 @@ async def handle_rank(
|
||||
t1 = t.time()
|
||||
rank2 = await get_user_infos(bot, event, rank)
|
||||
logger.debug(f"获取用户信息花费时间:{t.time() - t1}")
|
||||
|
||||
|
||||
string: str = ""
|
||||
for i in rank2:
|
||||
logger.debug(i.user_name)
|
||||
for i in range(len(rank2)):
|
||||
str_example = plugin_config.string_format.format(
|
||||
index=rank2[i].user_index,
|
||||
nickname=rank2[i].user_nickname,
|
||||
chatdatanum=rank2[i].user_bnum,
|
||||
)
|
||||
string += str_example
|
||||
|
||||
if plugin_config.show_text_rank:
|
||||
for i in rank2:
|
||||
logger.debug(i.user_name)
|
||||
for i in range(len(rank2)):
|
||||
str_example = plugin_config.string_format.format(
|
||||
index=rank2[i].user_index,
|
||||
nickname=rank2[i].user_nickname,
|
||||
chatdatanum=rank2[i].user_bnum,
|
||||
)
|
||||
string += str_example
|
||||
|
||||
msg = saa.Text(string)
|
||||
t1 = t.time()
|
||||
|
||||
if plugin_config.visualization:
|
||||
t1 = t.time()
|
||||
image = await get_rank_image(rank2)
|
||||
msg += saa.Image(image)
|
||||
logger.debug(f"群聊消息渲染图片花费时间:{t.time() - t1}")
|
||||
|
||||
if plugin_config.suffix:
|
||||
timecost = t.time() - state["t1"]
|
||||
suffix = saa.Text(plugin_config.string_suffix.format(timecost=timecost))
|
||||
msg += suffix
|
||||
|
||||
logger.debug(f"群聊消息渲染图片花费时间:{t.time() - t1}")
|
||||
if not msg:
|
||||
await saa.Text("你把可视化都关了哪来的排行榜?").finish()
|
||||
|
||||
await msg.finish(reply=True)
|
||||
|
||||
|
||||
# @scheduler.scheduled_job(
|
||||
# "dialectlist", day="*/2", id="xxx", args=[1], kwargs={"arg2": 2}
|
||||
# )
|
||||
# async def __():
|
||||
# pass
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional, List, Literal
|
||||
from typing import Optional, List
|
||||
from nonebot import get_driver, get_plugin_config
|
||||
|
||||
|
||||
class ScopedConfig(BaseModel):
|
||||
get_num: int = 5 # 获取人数数量
|
||||
font: str = "SimHei" # 字体格式
|
||||
suffix: bool = False # 是否显示后缀
|
||||
excluded_self: bool = True
|
||||
suffix: bool = True # 是否显示后缀
|
||||
excluded_self: bool = True # 是否排除自己
|
||||
visualization: bool = True # 是否可视化
|
||||
counting_cache: bool = False # 计数缓存(没有完工)
|
||||
show_text_rank:bool = True # 是否显示文本排名
|
||||
counting_cache: bool = False # 计数缓存(能够提高回复速度)
|
||||
excluded_people: List[str] = [] # 排除的人的QQ号
|
||||
timezone: Optional[str] = "Asia/Shanghai"
|
||||
use_user_info_cache: bool = False # 是否使用用户信息缓存
|
||||
timezone: Optional[str] = "Asia/Shanghai" # 时区,影响统计时间
|
||||
string_suffix: str = "统计花费时间:{timecost}秒" # 消息格式后缀
|
||||
template_path: str = "./template/rank_template.j2" # 模板路径
|
||||
string_format: str = "第{index}名:\n{nickname},{chatdatanum}条消息\n" # 消息格式
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from datetime import datetime
|
||||
from typing import Union
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import JSON, TEXT, String,Integer
|
||||
from sqlalchemy import Integer
|
||||
from nonebot_plugin_orm import Model
|
||||
from nonebot_plugin_userinfo import UserInfo
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
@@ -15,13 +14,9 @@ class UserRankInfo(UserInfo):
|
||||
user_avatar_bytes: bytes
|
||||
|
||||
|
||||
# class MsgCountDayData(BaseModel):
|
||||
# session_id: str
|
||||
# session_bnum: int
|
||||
|
||||
class MessageCountCache(Model):
|
||||
__table_args__ = {"extend_existing": True}
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
||||
time: Mapped[datetime]
|
||||
session_id: Mapped[int] = mapped_column(Integer)
|
||||
session_id: Mapped[int] = mapped_column(Integer, index=True)
|
||||
session_bnum: Mapped[int] = mapped_column(Integer)
|
||||
|
||||
@@ -1,2 +1,134 @@
|
||||
# TODO 使用计数缓存进行数据库查询优化,避免一次性查询过多消息导致内存爆炸。
|
||||
from nonebot_plugin_orm import Model
|
||||
import os
|
||||
import json
|
||||
from datetime import datetime
|
||||
from sqlalchemy import delete, or_, select
|
||||
|
||||
from nonebot import get_driver
|
||||
from nonebot.log import logger
|
||||
from nonebot.params import Depends
|
||||
from nonebot.adapters import Event, Bot
|
||||
from nonebot.message import event_postprocessor
|
||||
|
||||
from .model import MessageCountCache
|
||||
from .config import plugin_config
|
||||
|
||||
from nonebot_plugin_localstore import get_data_file
|
||||
from nonebot_plugin_chatrecorder import get_message_records
|
||||
from nonebot_plugin_chatrecorder.utils import remove_timezone
|
||||
from nonebot_plugin_session import extract_session, Session
|
||||
from nonebot_plugin_session_orm import SessionModel, get_session_persist_id
|
||||
from nonebot_plugin_orm import get_session
|
||||
|
||||
|
||||
async def get_cache(time_start: datetime, time_stop: datetime, group_id: str):
|
||||
async with get_session() as db_session:
|
||||
where = [or_(SessionModel.id2 == group_id)]
|
||||
statement = select(SessionModel).where(*where)
|
||||
|
||||
sessions = (await db_session.scalars(statement)).all()
|
||||
|
||||
where = [
|
||||
or_(*[MessageCountCache.session_id == session.id for session in sessions])
|
||||
]
|
||||
statement = select(MessageCountCache).where(*where)
|
||||
where.append(or_(MessageCountCache.time >= remove_timezone(time_start)))
|
||||
where.append(or_(MessageCountCache.time <= remove_timezone(time_stop)))
|
||||
statement = select(MessageCountCache).where(*where)
|
||||
|
||||
user_caches = (await db_session.scalars(statement)).all()
|
||||
raw_rank = {}
|
||||
for i in user_caches:
|
||||
raw_rank[i.session_id] = raw_rank.get(i.session_id, 0) + i.session_bnum
|
||||
return raw_rank
|
||||
|
||||
|
||||
async def build_cache():
|
||||
async with get_session() as db_session:
|
||||
await db_session.execute(delete(MessageCountCache))
|
||||
await db_session.commit()
|
||||
logger.info("先前可能存在的缓存已清空")
|
||||
messages = await get_message_records(types=["message"])
|
||||
async with get_session() as db_session:
|
||||
for msg in messages:
|
||||
msg_session_id = msg.session_persist_id
|
||||
|
||||
where = [or_(MessageCountCache.session_id == msg_session_id)]
|
||||
where.append(
|
||||
or_(
|
||||
MessageCountCache.time
|
||||
== remove_timezone(
|
||||
msg.time.replace(hour=1, minute=0, second=0, microsecond=0)
|
||||
)
|
||||
)
|
||||
)
|
||||
statement = select(MessageCountCache).where(*where)
|
||||
|
||||
user_cache = (await db_session.scalars(statement)).all()
|
||||
|
||||
if user_cache:
|
||||
user_cache[0].session_bnum += 1
|
||||
else:
|
||||
user_cache = MessageCountCache(
|
||||
session_id=msg.session_persist_id,
|
||||
time=remove_timezone(
|
||||
msg.time.replace(hour=1, minute=0, second=0, microsecond=0)
|
||||
),
|
||||
session_bnum=1,
|
||||
)
|
||||
db_session.add(user_cache)
|
||||
await db_session.commit()
|
||||
|
||||
logger.info("缓存构建完成")
|
||||
|
||||
|
||||
driver = get_driver()
|
||||
|
||||
|
||||
@driver.on_startup
|
||||
async def _():
|
||||
if not plugin_config.counting_cache:
|
||||
return
|
||||
f_name = get_data_file("nonebot-plugin-dialectlist", "is-pre-cached.json")
|
||||
if not os.path.exists(f_name):
|
||||
with open(f_name, "w", encoding="utf-8") as f:
|
||||
s = json.dumps({"is-pre-cached": False}, ensure_ascii=False, indent=4)
|
||||
f.write(s)
|
||||
|
||||
with open(f_name, "r", encoding="utf-8") as f:
|
||||
if json.load(f)["is-pre-cached"]:
|
||||
return
|
||||
logger.info("未检查到缓存,开始构建缓存")
|
||||
with open(f_name, "w", encoding="utf-8") as f:
|
||||
await build_cache()
|
||||
json.dump({"is-pre-cached": True}, f, ensure_ascii=False, indent=4)
|
||||
|
||||
|
||||
@event_postprocessor
|
||||
async def _(bot: Bot, event: Event, session: Session = Depends(extract_session)):
|
||||
if not plugin_config.counting_cache:
|
||||
return
|
||||
if not session.id2:
|
||||
return
|
||||
if event.get_type() != "message":
|
||||
return
|
||||
now = datetime.now()
|
||||
now = now.replace(hour=1, minute=0, second=0, microsecond=0)
|
||||
|
||||
async with get_session() as db_session:
|
||||
session_id = await get_session_persist_id(session)
|
||||
logger.debug("session_id:" + str(session_id))
|
||||
where = [or_(MessageCountCache.session_id == session_id)]
|
||||
where.append(or_(MessageCountCache.time == remove_timezone(now)))
|
||||
statement = select(MessageCountCache).where(*where)
|
||||
user_cache = (await db_session.scalars(statement)).first()
|
||||
if user_cache:
|
||||
user_cache.session_bnum += 1
|
||||
else:
|
||||
user_cache = MessageCountCache(
|
||||
session_id=session_id,
|
||||
time=remove_timezone(now),
|
||||
session_bnum=1,
|
||||
)
|
||||
db_session.add(user_cache)
|
||||
await db_session.commit()
|
||||
logger.debug("已计入缓存")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# TODO 时间处理模块,用于处理时间相关操作。
|
||||
from zoneinfo import ZoneInfo
|
||||
from typing import Optional, Union
|
||||
from datetime import datetime, time, tzinfo
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import os
|
||||
import httpx
|
||||
import asyncio
|
||||
import unicodedata
|
||||
|
||||
from typing import Dict, List, Optional
|
||||
from typing import Dict, List
|
||||
from sqlalchemy import or_, select
|
||||
from sqlalchemy.sql import ColumnElement
|
||||
|
||||
@@ -15,6 +16,7 @@ from nonebot.adapters import Bot, Event
|
||||
from nonebot_plugin_orm import get_session
|
||||
from nonebot_plugin_session import Session, SessionLevel, extract_session
|
||||
from nonebot_plugin_userinfo import get_user_info, UserInfo
|
||||
from nonebot_plugin_userinfo.exception import NetworkError
|
||||
from nonebot_plugin_localstore import get_cache_dir
|
||||
from nonebot_plugin_htmlrender import template_to_pic
|
||||
from nonebot_plugin_session_orm import SessionModel
|
||||
@@ -26,16 +28,6 @@ from .config import plugin_config
|
||||
|
||||
cache_path = get_cache_dir("nonebot_plugin_dialectlist")
|
||||
|
||||
# 暂时不做考虑
|
||||
# def admin_permission():
|
||||
# permission = SUPERUSER
|
||||
# with contextlib.suppress(ImportError):
|
||||
# from nonebot.adapters.onebot.v11.permission import GROUP_ADMIN, GROUP_OWNER
|
||||
|
||||
# permission = permission | GROUP_ADMIN | GROUP_OWNER
|
||||
|
||||
# return permission
|
||||
|
||||
|
||||
async def ensure_group(matcher: Matcher, session: Session = Depends(extract_session)):
|
||||
"""确保在群组中使用"""
|
||||
@@ -184,7 +176,9 @@ async def get_rank_image(rank: List[UserRankInfo]) -> bytes:
|
||||
},
|
||||
pages={"viewport": {"width": 1000, "height": 10}},
|
||||
)
|
||||
def _get_user_nickname(user_info:UserInfo)->str:
|
||||
|
||||
|
||||
def _get_user_nickname(user_info: UserInfo) -> str:
|
||||
user_nickname = (
|
||||
user_info.user_displayname
|
||||
if user_info.user_displayname
|
||||
@@ -192,56 +186,86 @@ def _get_user_nickname(user_info:UserInfo)->str:
|
||||
)
|
||||
return user_nickname
|
||||
|
||||
async def _get_user_default_avatar()->bytes:
|
||||
|
||||
async def _get_user_default_avatar() -> bytes:
|
||||
img = open(
|
||||
os.path.dirname(os.path.abspath(__file__))
|
||||
+ "/template/avatar/default.jpg",
|
||||
os.path.dirname(os.path.abspath(__file__)) + "/template/avatar/default.jpg",
|
||||
"rb",
|
||||
).read()
|
||||
).read()
|
||||
return img
|
||||
|
||||
def get_default_user_info()->UserInfo:
|
||||
|
||||
async def _get_user_avatar(user: UserInfo, client: httpx.AsyncClient) -> bytes:
|
||||
if not user.user_avatar:
|
||||
return await _get_user_default_avatar()
|
||||
url = user.user_avatar.get_url()
|
||||
for i in range(3):
|
||||
try:
|
||||
resp = await client.get(url, timeout=10)
|
||||
resp.raise_for_status()
|
||||
return resp.content
|
||||
except Exception as e:
|
||||
logger.warning(f"Error downloading {url}, retry {i}/3: {e}")
|
||||
await asyncio.sleep(3)
|
||||
raise NetworkError(f"{url} 下载失败!")
|
||||
|
||||
|
||||
def get_default_user_info() -> UserInfo:
|
||||
user_info = UserInfo(
|
||||
user_id="114514",
|
||||
user_name="鬼知道这谁,bot获取不了",
|
||||
)
|
||||
return user_info
|
||||
|
||||
async def get_user_infos(bot:Bot,event:Event,rank:List,use_cache: bool = True)-> List[UserRankInfo]:
|
||||
|
||||
|
||||
async def get_user_infos(
|
||||
bot: Bot,
|
||||
event: Event,
|
||||
rank: List,
|
||||
use_cache: bool = plugin_config.use_user_info_cache,
|
||||
) -> List[UserRankInfo]:
|
||||
|
||||
user_ids = [i[0] for i in rank]
|
||||
pool = [get_user_info(bot, event, id, use_cache) for id in user_ids]
|
||||
user_infos = (await asyncio.gather(*pool))
|
||||
|
||||
pool = []
|
||||
for i in user_infos:
|
||||
if not i:
|
||||
pool.append(_get_user_default_avatar())
|
||||
continue
|
||||
if i.user_avatar:
|
||||
pool.append(i.user_avatar.get_image())
|
||||
user_avatars = await asyncio.gather(*pool)
|
||||
user_infos = await asyncio.gather(*pool)
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
pool = []
|
||||
for i in user_infos:
|
||||
if not i:
|
||||
pool.append(_get_user_default_avatar())
|
||||
continue
|
||||
if i.user_avatar:
|
||||
pool.append(_get_user_avatar(i, client))
|
||||
user_avatars = await asyncio.gather(*pool)
|
||||
|
||||
for i in user_avatars:
|
||||
if not i:
|
||||
user_avatars[user_avatars.index(i)] = await(_get_user_default_avatar())
|
||||
user_avatars[user_avatars.index(i)] = await _get_user_default_avatar()
|
||||
|
||||
total = sum([i[1] for i in rank])
|
||||
rank2 = []
|
||||
for i in range(len(rank)):
|
||||
|
||||
|
||||
user_info = user_infos[i]
|
||||
if not user_info:
|
||||
user_info = get_default_user_info()
|
||||
|
||||
|
||||
user = UserRankInfo(
|
||||
**model_dump(user_info),
|
||||
user_bnum=rank[i][1],
|
||||
user_proportion=round(rank[i][1] / total * 100, 2),
|
||||
user_index=i+1,
|
||||
user_index=i + 1,
|
||||
user_nickname=_get_user_nickname(user_info),
|
||||
user_avatar_bytes=user_avatars[i],
|
||||
)
|
||||
print(user.user_gender)
|
||||
if user.user_gender == "male":
|
||||
user.user_gender = "♂"
|
||||
elif user.user_gender == "female":
|
||||
user.user_gender = "♀"
|
||||
else:
|
||||
user.user_gender = "🤔"
|
||||
rank2.append(user)
|
||||
|
||||
return rank2
|
||||
|
||||
|
||||
4
pdm.lock
generated
4
pdm.lock
generated
@@ -5,10 +5,10 @@
|
||||
groups = ["default", "Test", "dev"]
|
||||
strategy = ["inherit_metadata"]
|
||||
lock_version = "4.5.0"
|
||||
content_hash = "sha256:f31fbbd00506680ed623e0216a48314dcbb142cebec25ebe15f1dc9a50915b25"
|
||||
content_hash = "sha256:882dfc18d7454ced6bb1f46e04172b14b83f90157475153bf0fff7b13e4d41a2"
|
||||
|
||||
[[metadata.targets]]
|
||||
requires_python = "~=3.9"
|
||||
requires_python = ">=3.9,<3.13"
|
||||
|
||||
[[package]]
|
||||
name = "aiofiles"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "nonebot-plugin-dialectlist"
|
||||
version = "2.3.0"
|
||||
version = "2.4.4"
|
||||
description = "看看你群群友有多能说"
|
||||
authors = [
|
||||
{name = "Chen_Xu233", email = "woyerpa@outlook.com"},
|
||||
@@ -12,13 +12,13 @@ dependencies = [
|
||||
"nonebot-plugin-apscheduler>=0.4.0",
|
||||
"nonebot-plugin-alconna>=0.50.2",
|
||||
"nonebot-plugin-cesaa>=0.4.0",
|
||||
"nonebot-plugin-userinfo>=0.2.4",
|
||||
"nonebot-plugin-userinfo>=0.2.6",
|
||||
"nonebot-plugin-htmlrender>=0.3.3",
|
||||
"nonebot2>=2.3.2",
|
||||
"pillow>=10.4.0",
|
||||
"nonebot-plugin-uninfo>=0.1.1",
|
||||
]
|
||||
requires-python = ">=3.9,<4.0"
|
||||
requires-python = ">=3.9,<3.13"
|
||||
readme = "README.md"
|
||||
license = {text = "MIT"}
|
||||
|
||||
@@ -40,21 +40,10 @@ distribution = true
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 80
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "single"
|
||||
indent-style = "tab"
|
||||
|
||||
[tool.pdm.scripts]
|
||||
|
||||
build = 'pdm run setup.py sdist'
|
||||
publish = 'pdm run python -m twine upload dist/*'
|
||||
|
||||
|
||||
# 以下为智普 AI 生成,还不知道这玩意有啥用。
|
||||
# [tool.pdm.dev-dependencies]
|
||||
# black = "^23.1.0"
|
||||
# isort = "^5.10.1"
|
||||
# pre-commit = "^2.20.0"
|
||||
|
||||
# [tool.pdm.global-options]
|
||||
# --no-pip-version-check = true
|
||||
[tool.ruff.lint]
|
||||
ignore = ["E402"]
|
||||
|
||||
Reference in New Issue
Block a user