mirror of
https://github.com/ChenXu233/nonebot_plugin_dialectlist.git
synced 2025-06-01 10:25:20 +00:00
Compare commits
5 Commits
0348a5d66c
...
b0e84c778b
Author | SHA1 | Date | |
---|---|---|---|
|
b0e84c778b | ||
|
1cb2be770d | ||
|
d19d65f75e | ||
|
a7bdd6033e | ||
|
0d4f69356a |
@ -1,369 +1,372 @@
|
||||
from nonebot import require
|
||||
|
||||
require("nonebot_plugin_chatrecorder")
|
||||
require("nonebot_plugin_apscheduler")
|
||||
require("nonebot_plugin_htmlrender")
|
||||
require("nonebot_plugin_userinfo")
|
||||
require("nonebot_plugin_alconna")
|
||||
require("nonebot_plugin_uninfo")
|
||||
require("nonebot_plugin_cesaa")
|
||||
require('nonebot_plugin_chatrecorder')
|
||||
require('nonebot_plugin_apscheduler')
|
||||
require('nonebot_plugin_htmlrender')
|
||||
require('nonebot_plugin_userinfo')
|
||||
require('nonebot_plugin_alconna')
|
||||
require('nonebot_plugin_uninfo')
|
||||
require('nonebot_plugin_cesaa')
|
||||
|
||||
import re
|
||||
import time as t
|
||||
import nonebot_plugin_saa as saa
|
||||
|
||||
from typing import Union, Optional
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional, Union
|
||||
|
||||
import nonebot_plugin_saa as saa
|
||||
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.params import Arg, Depends
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.log import logger
|
||||
from nonebot.params import Arg, Depends
|
||||
from nonebot.plugin import PluginMetadata, inherit_supported_adapters
|
||||
from nonebot.typing import T_State
|
||||
from nonebot_plugin_alconna import (
|
||||
At,
|
||||
Args,
|
||||
Field,
|
||||
Match,
|
||||
Option,
|
||||
Alconna,
|
||||
on_alconna,
|
||||
Alconna,
|
||||
Args,
|
||||
At,
|
||||
Field,
|
||||
Match,
|
||||
Option,
|
||||
on_alconna,
|
||||
)
|
||||
from nonebot_plugin_chatrecorder import get_message_records
|
||||
from nonebot_plugin_session import Session, SessionIdType, extract_session
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from nonebot_plugin_uninfo import Session, Uninfo, get_session
|
||||
|
||||
from .storage import get_cache, build_cache
|
||||
from .config import Config, plugin_config
|
||||
from .usage import __usage__
|
||||
from .storage import build_cache, get_cache
|
||||
from .time import (
|
||||
get_datetime_fromisoformat_with_timezone,
|
||||
get_datetime_now_with_timezone,
|
||||
parse_datetime,
|
||||
get_datetime_fromisoformat_with_timezone,
|
||||
get_datetime_now_with_timezone,
|
||||
parse_datetime,
|
||||
)
|
||||
from .usage import __usage__
|
||||
from .utils import (
|
||||
got_rank,
|
||||
msg_counter,
|
||||
get_rank_image,
|
||||
persist_id2user_id,
|
||||
get_user_infos,
|
||||
get_rank_image,
|
||||
get_user_infos,
|
||||
got_rank,
|
||||
msg_counter,
|
||||
persist_id2user_id,
|
||||
)
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
name="B话排行榜",
|
||||
description="调查群U的B话数量,以一定的顺序排序后排序出来。",
|
||||
usage=__usage__,
|
||||
homepage="https://github.com/ChenXu233/nonebot_plugin_dialectlist",
|
||||
type="application",
|
||||
supported_adapters=inherit_supported_adapters(
|
||||
"nonebot_plugin_chatrecorder", "nonebot_plugin_saa", "nonebot_plugin_alconna"
|
||||
),
|
||||
config=Config,
|
||||
name='B话排行榜',
|
||||
description='调查群U的B话数量,以一定的顺序排序后排序出来。',
|
||||
usage=__usage__,
|
||||
homepage='https://github.com/ChenXu233/nonebot_plugin_dialectlist',
|
||||
type='application',
|
||||
supported_adapters=inherit_supported_adapters(
|
||||
'nonebot_plugin_chatrecorder',
|
||||
'nonebot_plugin_saa',
|
||||
'nonebot_plugin_alconna',
|
||||
),
|
||||
config=Config,
|
||||
)
|
||||
|
||||
|
||||
# 抄的词云,不过真的很适合B话榜。
|
||||
class SameTime(ArparmaBehavior):
|
||||
def operate(self, interface: Arparma):
|
||||
type = interface.query("type")
|
||||
time = interface.query("time")
|
||||
if type is None and time:
|
||||
interface.behave_fail()
|
||||
def operate(self, interface: Arparma):
|
||||
type = interface.query('type')
|
||||
time = interface.query('time')
|
||||
if type is None and time:
|
||||
interface.behave_fail()
|
||||
|
||||
|
||||
def wrapper(slot: Union[int, str], content: Optional[str], context) -> str:
|
||||
if slot == "type" and content:
|
||||
return content
|
||||
return "" # pragma: no cover
|
||||
if slot == 'type' and content:
|
||||
return content
|
||||
return '' # pragma: no cover
|
||||
|
||||
|
||||
build_cache_cmd = on_command("build_cache", aliases={"重建缓存"}, block=True)
|
||||
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)
|
||||
await saa.Text('正在重建缓存,请稍等。').send(reply=True)
|
||||
await build_cache()
|
||||
await saa.Text('重建缓存完成。').send(reply=True)
|
||||
|
||||
|
||||
b_cmd = on_alconna(
|
||||
Alconna(
|
||||
"看看B话",
|
||||
Args["at", [str, At], Field(completion=lambda: "请想要查询的人的QQ号")],
|
||||
Option("-g|--group_id", Args["group_id?", str]),
|
||||
Option("-k|--keyword", Args["keyword?", str]),
|
||||
),
|
||||
aliases={"kkb"},
|
||||
use_cmd_start=True,
|
||||
Alconna(
|
||||
'看看B话',
|
||||
Args['at', [str, At], Field(completion=lambda: '请想要查询的人的QQ号')],
|
||||
Option('-g|--group_id', Args['group_id?', str]),
|
||||
Option('-k|--keyword', Args['keyword?', str]),
|
||||
),
|
||||
aliases={'kkb'},
|
||||
use_cmd_start=True,
|
||||
)
|
||||
|
||||
|
||||
@b_cmd.handle()
|
||||
async def handle_b_cmd(
|
||||
at: Match[str | At],
|
||||
group_id: Match[str],
|
||||
keyword: Match[str],
|
||||
uninfo: Uninfo,
|
||||
session: Session = Depends(extract_session),
|
||||
at: Match[str | At],
|
||||
group_id: Match[str],
|
||||
keyword: Match[str],
|
||||
uninfo: Uninfo,
|
||||
session: Session = Depends(get_session),
|
||||
):
|
||||
id = at.result
|
||||
if isinstance(id, At):
|
||||
id = id.target
|
||||
if group_id.available:
|
||||
gid = group_id.result
|
||||
else:
|
||||
gid = session.id2
|
||||
id = at.result
|
||||
if isinstance(id, At):
|
||||
id = id.target
|
||||
if group_id.available:
|
||||
gid = group_id.result
|
||||
else:
|
||||
gid = session.scene.id
|
||||
|
||||
if not gid:
|
||||
await b_cmd.finish("请指定群号。")
|
||||
if not gid:
|
||||
await b_cmd.finish('请指定群号。')
|
||||
|
||||
if keyword.available:
|
||||
keywords = keyword.result
|
||||
else:
|
||||
keywords = None
|
||||
if keyword.available:
|
||||
keywords = keyword.result
|
||||
else:
|
||||
keywords = None
|
||||
|
||||
messages = await get_message_records(
|
||||
id1s=[id],
|
||||
id2s=[gid],
|
||||
id_type=SessionIdType.GROUP,
|
||||
include_bot_id=False,
|
||||
include_bot_type=False,
|
||||
types=["message"], # 排除机器人自己发的消息
|
||||
exclude_id1s=plugin_config.excluded_people,
|
||||
)
|
||||
d = msg_counter(messages, keywords)
|
||||
rank = got_rank(d)
|
||||
if not rank:
|
||||
await b_cmd.finish(
|
||||
f"该用户在群“{uninfo.scene.name}”关于“{keyword}”的B话数量为0。"
|
||||
)
|
||||
messages = await get_message_records(
|
||||
scene_ids=[gid],
|
||||
user_ids=[id],
|
||||
types=['message'], # 排除机器人自己发的消息
|
||||
exclude_user_ids=plugin_config.excluded_people,
|
||||
)
|
||||
d = msg_counter(messages, keywords)
|
||||
rank = got_rank(d)
|
||||
if not rank:
|
||||
await b_cmd.finish(
|
||||
f'该用户在群“{uninfo.scene.name}”关于“{keyword.result}”的B话数量为0。'
|
||||
)
|
||||
|
||||
await saa.Text(
|
||||
f"该用户在群“{uninfo.scene.name}”关于“{keyword}”的B话数量为{rank[0][1]}。"
|
||||
).send(reply=True)
|
||||
await saa.Text(
|
||||
f'该用户在群“{uninfo.scene.name}”关于“{keyword.result}”的B话数量为{rank[0][1]}。'
|
||||
).send(reply=True)
|
||||
|
||||
|
||||
rank_cmd = on_alconna(
|
||||
Alconna(
|
||||
"B话榜",
|
||||
Args["type?", ["今日", "昨日", "本周", "上周", "本月", "上月", "年度", "历史"]][
|
||||
"time?",
|
||||
str,
|
||||
],
|
||||
Option("-g|--group_id", Args["group_id?", str]),
|
||||
Option("-k|--keyword", Args["keyword?", str]),
|
||||
behaviors=[SameTime()],
|
||||
),
|
||||
aliases={"废话榜"},
|
||||
use_cmd_start=True,
|
||||
block=True,
|
||||
Alconna(
|
||||
'B话榜',
|
||||
Args[
|
||||
'type?',
|
||||
['今日', '昨日', '本周', '上周', '本月', '上月', '年度', '历史'],
|
||||
][
|
||||
'time?',
|
||||
str,
|
||||
],
|
||||
Option('-g|--group_id', Args['group_id?', str]),
|
||||
Option('-k|--keyword', Args['keyword?', str]),
|
||||
behaviors=[SameTime()],
|
||||
),
|
||||
aliases={'废话榜'},
|
||||
use_cmd_start=True,
|
||||
block=True,
|
||||
)
|
||||
|
||||
|
||||
rank_cmd.shortcut(
|
||||
r"(?P<type>今日|昨日|本周|上周|本月|上月|年度|历史)B话榜",
|
||||
{
|
||||
"prefix": True,
|
||||
"command": "B话榜",
|
||||
"wrapper": wrapper,
|
||||
"args": ["{type}"],
|
||||
},
|
||||
r'(?P<type>今日|昨日|本周|上周|本月|上月|年度|历史)B话榜',
|
||||
{
|
||||
'prefix': True,
|
||||
'command': 'B话榜',
|
||||
'wrapper': wrapper,
|
||||
'args': ['{type}'],
|
||||
},
|
||||
)
|
||||
rank_cmd.shortcut(
|
||||
r"(?P<type>今日|昨日|本周|上周|本月|上月|年度|历史)废话榜",
|
||||
{
|
||||
"prefix": True,
|
||||
"command": "废话榜",
|
||||
"wrapper": wrapper,
|
||||
"args": ["{type}"],
|
||||
},
|
||||
r'(?P<type>今日|昨日|本周|上周|本月|上月|年度|历史)废话榜',
|
||||
{
|
||||
'prefix': True,
|
||||
'command': '废话榜',
|
||||
'wrapper': wrapper,
|
||||
'args': ['{type}'],
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
# 这段函数完全抄的词云
|
||||
@rank_cmd.handle()
|
||||
async def _group_message(
|
||||
state: T_State,
|
||||
session: Session = Depends(extract_session),
|
||||
type: Optional[str] = None,
|
||||
time: Optional[str] = None,
|
||||
group_id: Optional[str] = None,
|
||||
keyword: Optional[str] = None,
|
||||
state: T_State,
|
||||
session: Session = Depends(get_session),
|
||||
type: Optional[str] = None,
|
||||
time: Optional[str] = None,
|
||||
group_id: Optional[str] = None,
|
||||
keyword: Optional[str] = None,
|
||||
):
|
||||
t1 = t.time()
|
||||
state["t1"] = t1
|
||||
dt = get_datetime_now_with_timezone()
|
||||
t1 = t.time()
|
||||
state['t1'] = t1
|
||||
dt = get_datetime_now_with_timezone()
|
||||
|
||||
if not group_id:
|
||||
group_id = session.id2
|
||||
logger.debug(f"session id2: {group_id}")
|
||||
if group_id:
|
||||
state["group_id"] = group_id
|
||||
if not group_id:
|
||||
group_id = session.scene.id
|
||||
logger.debug(f'session id2: {group_id}')
|
||||
if group_id:
|
||||
state['group_id'] = group_id
|
||||
|
||||
state["keyword"] = keyword
|
||||
state['keyword'] = keyword
|
||||
|
||||
if not type:
|
||||
await rank_cmd.finish(__plugin_meta__.usage)
|
||||
if not type:
|
||||
await rank_cmd.finish(__plugin_meta__.usage)
|
||||
|
||||
dt = get_datetime_now_with_timezone()
|
||||
dt = get_datetime_now_with_timezone()
|
||||
|
||||
if type == "今日":
|
||||
state["start"] = dt.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
state["stop"] = dt
|
||||
elif type == "昨日":
|
||||
state["stop"] = dt.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
state["start"] = state["stop"] - timedelta(days=1)
|
||||
elif type == "本周":
|
||||
state["start"] = dt.replace(
|
||||
hour=0, minute=0, second=0, microsecond=0
|
||||
) - timedelta(days=dt.weekday())
|
||||
state["stop"] = dt
|
||||
elif type == "上周":
|
||||
state["stop"] = dt.replace(
|
||||
hour=0, minute=0, second=0, microsecond=0
|
||||
) - timedelta(days=dt.weekday())
|
||||
state["start"] = state["stop"] - timedelta(days=7)
|
||||
elif type == "本月":
|
||||
state["start"] = dt.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
|
||||
state["stop"] = dt
|
||||
elif type == "上月":
|
||||
state["stop"] = dt.replace(
|
||||
day=1, hour=0, minute=0, second=0, microsecond=0
|
||||
) - timedelta(microseconds=1)
|
||||
state["start"] = state["stop"].replace(
|
||||
day=1, hour=0, minute=0, second=0, microsecond=0
|
||||
)
|
||||
elif type == "年度":
|
||||
state["start"] = dt.replace(
|
||||
month=1, day=1, hour=0, minute=0, second=0, microsecond=0
|
||||
)
|
||||
state["stop"] = dt
|
||||
elif type == "历史":
|
||||
if time:
|
||||
plaintext = time
|
||||
if match := re.match(r"^(.+?)(?:~(.+))?$", plaintext):
|
||||
start = match[1]
|
||||
stop = match[2]
|
||||
try:
|
||||
state["start"] = get_datetime_fromisoformat_with_timezone(start)
|
||||
if stop:
|
||||
state["stop"] = get_datetime_fromisoformat_with_timezone(stop)
|
||||
else:
|
||||
# 如果没有指定结束日期,则认为是所给日期的当天的词云
|
||||
state["start"] = state["start"].replace(
|
||||
hour=0, minute=0, second=0, microsecond=0
|
||||
)
|
||||
state["stop"] = state["start"] + timedelta(days=1)
|
||||
except ValueError:
|
||||
await rank_cmd.finish("请输入正确的日期,不然我没法理解呢!")
|
||||
if type == '今日':
|
||||
state['start'] = dt.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
state['stop'] = dt
|
||||
elif type == '昨日':
|
||||
state['stop'] = dt.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
state['start'] = state['stop'] - timedelta(days=1)
|
||||
elif type == '本周':
|
||||
state['start'] = dt.replace(
|
||||
hour=0, minute=0, second=0, microsecond=0
|
||||
) - timedelta(days=dt.weekday())
|
||||
state['stop'] = dt
|
||||
elif type == '上周':
|
||||
state['stop'] = dt.replace(
|
||||
hour=0, minute=0, second=0, microsecond=0
|
||||
) - timedelta(days=dt.weekday())
|
||||
state['start'] = state['stop'] - timedelta(days=7)
|
||||
elif type == '本月':
|
||||
state['start'] = dt.replace(
|
||||
day=1, hour=0, minute=0, second=0, microsecond=0
|
||||
)
|
||||
state['stop'] = dt
|
||||
elif type == '上月':
|
||||
state['stop'] = dt.replace(
|
||||
day=1, hour=0, minute=0, second=0, microsecond=0
|
||||
) - timedelta(microseconds=1)
|
||||
state['start'] = state['stop'].replace(
|
||||
day=1, hour=0, minute=0, second=0, microsecond=0
|
||||
)
|
||||
elif type == '年度':
|
||||
state['start'] = dt.replace(
|
||||
month=1, day=1, hour=0, minute=0, second=0, microsecond=0
|
||||
)
|
||||
state['stop'] = dt
|
||||
elif type == '历史':
|
||||
if time:
|
||||
plaintext = time
|
||||
if match := re.match(r'^(.+?)(?:~(.+))?$', plaintext):
|
||||
start = match[1]
|
||||
stop = match[2]
|
||||
try:
|
||||
state['start'] = get_datetime_fromisoformat_with_timezone(
|
||||
start
|
||||
)
|
||||
if stop:
|
||||
state['stop'] = (
|
||||
get_datetime_fromisoformat_with_timezone(stop)
|
||||
)
|
||||
else:
|
||||
# 如果没有指定结束日期,则认为是所给日期的当天的词云
|
||||
state['start'] = state['start'].replace(
|
||||
hour=0, minute=0, second=0, microsecond=0
|
||||
)
|
||||
state['stop'] = state['start'] + timedelta(days=1)
|
||||
except ValueError:
|
||||
await rank_cmd.finish(
|
||||
'请输入正确的日期,不然我没法理解呢!'
|
||||
)
|
||||
|
||||
|
||||
@rank_cmd.got(
|
||||
"start",
|
||||
prompt="请输入你要查询的起始日期(如 2022-01-01)",
|
||||
parameterless=[Depends(parse_datetime("start"))],
|
||||
'start',
|
||||
prompt='请输入你要查询的起始日期(如 2022-01-01)',
|
||||
parameterless=[Depends(parse_datetime('start'))],
|
||||
)
|
||||
@rank_cmd.got(
|
||||
"stop",
|
||||
prompt="请输入你要查询的结束日期(如 2022-02-22)",
|
||||
parameterless=[Depends(parse_datetime("stop"))],
|
||||
'stop',
|
||||
prompt='请输入你要查询的结束日期(如 2022-02-22)',
|
||||
parameterless=[Depends(parse_datetime('stop'))],
|
||||
)
|
||||
@rank_cmd.got("group_id", prompt="请输入你要查询的群号。")
|
||||
@rank_cmd.got('group_id', prompt='请输入你要查询的群号。')
|
||||
async def handle_rank(
|
||||
state: T_State,
|
||||
bot: Bot,
|
||||
event: Event,
|
||||
session: Session = Depends(extract_session),
|
||||
start: datetime = Arg(),
|
||||
stop: datetime = Arg(),
|
||||
state: T_State,
|
||||
bot: Bot,
|
||||
event: Event,
|
||||
session: Session = Depends(get_session),
|
||||
start: datetime = Arg(),
|
||||
stop: datetime = Arg(),
|
||||
):
|
||||
if id := state['group_id']:
|
||||
id = str(id)
|
||||
logger.debug(f'group_id: {id}')
|
||||
else:
|
||||
id = session.scene.id
|
||||
logger.debug(f'group_id: {id}')
|
||||
|
||||
if id := state["group_id"]:
|
||||
id = str(id)
|
||||
logger.debug(f"group_id: {id}")
|
||||
else:
|
||||
id = session.id2
|
||||
logger.debug(f"group_id: {id}")
|
||||
if not id:
|
||||
await saa.Text('没有指定群哦').finish()
|
||||
|
||||
if not id:
|
||||
await saa.Text("没有指定群哦").finish()
|
||||
keyword = state['keyword']
|
||||
|
||||
keyword = state["keyword"]
|
||||
if plugin_config.counting_cache:
|
||||
if keyword:
|
||||
await saa.Text('已开启缓存~缓存不支持关键词查询哦').finish()
|
||||
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(
|
||||
scene_ids=[id],
|
||||
types=['message'], # 排除机器人自己发的消息
|
||||
time_start=start,
|
||||
time_stop=stop,
|
||||
exclude_user_ids=plugin_config.excluded_people,
|
||||
)
|
||||
raw_rank = msg_counter(messages, keyword)
|
||||
logger.debug(f'获取计数消息花费时间:{t.time() - t1}')
|
||||
|
||||
if plugin_config.counting_cache:
|
||||
if keyword:
|
||||
await saa.Text("已开启缓存~缓存不支持关键词查询哦").finish()
|
||||
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,
|
||||
include_bot_id=False,
|
||||
include_bot_type=False,
|
||||
types=["message"], # 排除机器人自己发的消息
|
||||
time_start=start,
|
||||
time_stop=stop,
|
||||
exclude_id1s=plugin_config.excluded_people,
|
||||
)
|
||||
raw_rank = msg_counter(messages, keyword)
|
||||
logger.debug(f"获取计数消息花费时间:{t.time() - t1}")
|
||||
if not raw_rank:
|
||||
await saa.Text(
|
||||
'没有获取到排行榜数据哦,请确认时间范围和群号是否正确或者关键词是否存在~'
|
||||
).finish()
|
||||
|
||||
if not raw_rank:
|
||||
await saa.Text(
|
||||
"没有获取到排行榜数据哦,请确认时间范围和群号是否正确或者关键词是否存在~"
|
||||
).finish()
|
||||
rank = got_rank(raw_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])
|
||||
logger.debug(rank[i])
|
||||
|
||||
rank = got_rank(raw_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])
|
||||
logger.debug(rank[i])
|
||||
t1 = t.time()
|
||||
rank2 = await get_user_infos(bot, event, rank)
|
||||
logger.debug(f'获取用户信息花费时间:{t.time() - t1}')
|
||||
|
||||
t1 = t.time()
|
||||
rank2 = await get_user_infos(bot, event, rank)
|
||||
logger.debug(f"获取用户信息花费时间:{t.time() - t1}")
|
||||
string: str = ''
|
||||
if plugin_config.show_text_rank:
|
||||
if keyword:
|
||||
string += f'关于{keyword}的话痨榜结果:\n'
|
||||
else:
|
||||
string += '话痨榜:\n'
|
||||
|
||||
string: str = ""
|
||||
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
|
||||
|
||||
if keyword:
|
||||
string += f"关于{keyword}的话痨榜结果:\n"
|
||||
else:
|
||||
string += "话痨榜:\n"
|
||||
msg = saa.Text(string)
|
||||
|
||||
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.visualization:
|
||||
t1 = t.time()
|
||||
image = await get_rank_image(rank2)
|
||||
msg += saa.Image(image)
|
||||
logger.debug(f'群聊消息渲染图片花费时间:{t.time() - t1}')
|
||||
|
||||
msg = saa.Text(string)
|
||||
if plugin_config.suffix:
|
||||
timecost = t.time() - state['t1']
|
||||
suffix = saa.Text(plugin_config.string_suffix.format(timecost=timecost))
|
||||
msg += suffix
|
||||
if not msg:
|
||||
await saa.Text('你把可视化都关了哪来的排行榜?').finish()
|
||||
|
||||
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
|
||||
if not msg:
|
||||
await saa.Text("你把可视化都关了哪来的排行榜?").finish()
|
||||
|
||||
if plugin_config.aggregate_transmission:
|
||||
await saa.AggregatedMessageFactory([msg]).finish()
|
||||
else:
|
||||
await msg.finish(reply=True)
|
||||
if plugin_config.aggregate_transmission:
|
||||
await saa.AggregatedMessageFactory([msg]).finish()
|
||||
else:
|
||||
await msg.finish(reply=True)
|
||||
|
@ -1,6 +1,7 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional, List
|
||||
from typing import List, Optional
|
||||
|
||||
from nonebot import get_driver, get_plugin_config
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class ScopedConfig(BaseModel):
|
||||
|
@ -1,61 +0,0 @@
|
||||
"""empty message
|
||||
|
||||
迁移 ID: 873ad3421460
|
||||
父迁移:
|
||||
创建时间: 2025-03-29 14:30:11.910461
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
revision: str = "873ad3421460"
|
||||
down_revision: str | Sequence[str] | None = None
|
||||
branch_labels: str | Sequence[str] | None = ("nonebot_plugin_dialectlist",)
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade(name: str = "") -> None:
|
||||
if name:
|
||||
return
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table(
|
||||
"nonebot_plugin_dialectlist_messagecountcache",
|
||||
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
|
||||
sa.Column("time", sa.DateTime(), nullable=False),
|
||||
sa.Column("session_id", sa.Integer(), nullable=False),
|
||||
sa.Column("session_bnum", sa.Integer(), nullable=False),
|
||||
sa.PrimaryKeyConstraint(
|
||||
"id", name=op.f("pk_nonebot_plugin_dialectlist_messagecountcache")
|
||||
),
|
||||
info={"bind_key": "nonebot_plugin_dialectlist"},
|
||||
)
|
||||
with op.batch_alter_table(
|
||||
"nonebot_plugin_dialectlist_messagecountcache", schema=None
|
||||
) as batch_op:
|
||||
batch_op.create_index(
|
||||
batch_op.f("ix_nonebot_plugin_dialectlist_messagecountcache_session_id"),
|
||||
["session_id"],
|
||||
unique=False,
|
||||
)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade(name: str = "") -> None:
|
||||
if name:
|
||||
return
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table(
|
||||
"nonebot_plugin_dialectlist_messagecountcache", schema=None
|
||||
) as batch_op:
|
||||
batch_op.drop_index(
|
||||
batch_op.f("ix_nonebot_plugin_dialectlist_messagecountcache_session_id")
|
||||
)
|
||||
|
||||
op.drop_table("nonebot_plugin_dialectlist_messagecountcache")
|
||||
# ### end Alembic commands ###
|
@ -0,0 +1,47 @@
|
||||
"""update dialectlist
|
||||
|
||||
迁移 ID: fb88e4d27eb8
|
||||
父迁移: 60daff81fcdc
|
||||
创建时间: 2025-04-20 11:00:50.931679
|
||||
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision: str = 'fb88e4d27eb8'
|
||||
down_revision: str | Sequence[str] | None = '60daff81fcdc'
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade(name: str = "") -> None:
|
||||
if name:
|
||||
return
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('sessionmodel',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('bot_id', sa.String(length=64), nullable=False),
|
||||
sa.Column('bot_type', sa.String(length=32), nullable=False),
|
||||
sa.Column('platform', sa.String(length=32), nullable=False),
|
||||
sa.Column('level', sa.Integer(), nullable=False),
|
||||
sa.Column('id1', sa.String(length=64), nullable=False),
|
||||
sa.Column('id2', sa.String(length=64), nullable=False),
|
||||
sa.Column('id3', sa.String(length=64), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id', name=op.f('pk_sessionmodel')),
|
||||
sa.UniqueConstraint('bot_id', 'bot_type', 'platform', 'level', 'id1', 'id2', 'id3', name='unique_session'),
|
||||
info={'bind_key': ''}
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade(name: str = "") -> None:
|
||||
if name:
|
||||
return
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table('sessionmodel')
|
||||
# ### end Alembic commands ###
|
@ -1,8 +1,9 @@
|
||||
from datetime import datetime
|
||||
from typing import Union
|
||||
from sqlalchemy import Integer
|
||||
|
||||
from nonebot_plugin_orm import Model
|
||||
from nonebot_plugin_userinfo import UserInfo
|
||||
from sqlalchemy import Integer
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
|
||||
|
@ -1,23 +1,22 @@
|
||||
import os
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
from sqlalchemy import delete, or_, select
|
||||
|
||||
from nonebot import get_driver
|
||||
from nonebot.adapters import Bot, Event
|
||||
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.params import Depends
|
||||
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_localstore import get_data_file
|
||||
from nonebot_plugin_orm import get_session
|
||||
from nonebot_plugin_session import Session, extract_session
|
||||
from nonebot_plugin_session_orm import SessionModel, get_session_persist_id
|
||||
from sqlalchemy import delete, or_, select
|
||||
|
||||
from .config import plugin_config
|
||||
from .model import MessageCountCache
|
||||
|
||||
|
||||
async def get_cache(time_start: datetime, time_stop: datetime, group_id: str):
|
||||
|
@ -1,13 +1,12 @@
|
||||
from zoneinfo import ZoneInfo
|
||||
from typing import Optional, Union
|
||||
from datetime import datetime, time, tzinfo
|
||||
from typing import Optional, Union
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from nonebot.adapters import Message
|
||||
from nonebot.params import Arg
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters import Message
|
||||
|
||||
from nonebot_plugin_apscheduler import scheduler
|
||||
from nonebot_plugin_alconna import AlconnaMatcher
|
||||
from nonebot_plugin_apscheduler import scheduler
|
||||
|
||||
from .config import plugin_config
|
||||
|
||||
|
@ -1,279 +1,263 @@
|
||||
import asyncio
|
||||
import os
|
||||
import re
|
||||
import httpx
|
||||
import asyncio
|
||||
import unicodedata
|
||||
|
||||
from typing import Dict, List, Optional
|
||||
from sqlalchemy import or_, select
|
||||
from sqlalchemy.sql import ColumnElement
|
||||
|
||||
from nonebot.log import logger
|
||||
from nonebot.params import Depends
|
||||
from nonebot.compat import model_dump
|
||||
from nonebot.matcher import Matcher
|
||||
import httpx
|
||||
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
|
||||
from nonebot.compat import model_dump
|
||||
from nonebot.log import logger
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import Depends
|
||||
from nonebot_plugin_chatrecorder import MessageRecord
|
||||
from nonebot_plugin_htmlrender import template_to_pic
|
||||
from nonebot_plugin_localstore import get_cache_dir
|
||||
from nonebot_plugin_orm import get_session
|
||||
from nonebot_plugin_userinfo import UserInfo, get_user_info
|
||||
from nonebot_plugin_uninfo import Session
|
||||
from nonebot_plugin_uninfo.model import SceneType
|
||||
from nonebot_plugin_uninfo.orm import SessionModel, UserModel
|
||||
from nonebot_plugin_uninfo import get_session as extract_session
|
||||
from nonebot_plugin_userinfo.exception import NetworkError
|
||||
from sqlalchemy import or_, select
|
||||
|
||||
|
||||
from .model import UserRankInfo
|
||||
from .config import plugin_config
|
||||
from .model import UserRankInfo
|
||||
|
||||
cache_path = get_cache_dir("nonebot_plugin_dialectlist")
|
||||
cache_path = get_cache_dir('nonebot_plugin_dialectlist')
|
||||
|
||||
|
||||
async def ensure_group(matcher: Matcher, session: Session = Depends(extract_session)):
|
||||
"""确保在群组中使用"""
|
||||
if session.level not in [SessionLevel.LEVEL2, SessionLevel.LEVEL3]:
|
||||
await matcher.finish("请在群组中使用!")
|
||||
async def ensure_group(
|
||||
matcher: Matcher, session: Session = Depends(extract_session)
|
||||
):
|
||||
"""确保在群组中使用"""
|
||||
if session.scene.type not in [SceneType.GROUP, SceneType.GUILD]:
|
||||
await matcher.finish('请在群组中使用!')
|
||||
|
||||
|
||||
async def persist_id2user_id(ids: List) -> List[str]:
|
||||
user_ids = []
|
||||
async with get_session() as db_session:
|
||||
for i in ids:
|
||||
user_id = (await db_session.scalar(select(SessionModel).where(or_(*[SessionModel.id == i])))).id1 # type: ignore
|
||||
user_ids.append(user_id)
|
||||
return user_ids
|
||||
user_ids = []
|
||||
user_persist_ids = []
|
||||
async with get_session() as db_session:
|
||||
for i in ids:
|
||||
session = await db_session.scalar(
|
||||
select(SessionModel).where(or_(*[SessionModel.id == i]))
|
||||
)
|
||||
if session is not None:
|
||||
user_persist_id = session.user_persist_id
|
||||
user_persist_ids.append(user_persist_id)
|
||||
for i in user_persist_ids:
|
||||
user = await db_session.scalar(
|
||||
select(UserModel).where(UserModel.id == i)
|
||||
)
|
||||
if user is not None:
|
||||
user_ids.append(user.user_id)
|
||||
|
||||
|
||||
async def user_id2persist_id(ids: List[str]) -> List[int]:
|
||||
whereclause: List[ColumnElement[bool]] = []
|
||||
whereclause.append(or_(*[SessionModel.id1 == id for id in ids]))
|
||||
statement = (
|
||||
select(SessionModel).where(*whereclause)
|
||||
# .join(SessionModel, SessionModel.id == MessageRecord.session_persist_id)
|
||||
)
|
||||
async with get_session() as db_session:
|
||||
records = (await db_session.scalars(statement)).all()
|
||||
return [i.id for i in records]
|
||||
|
||||
|
||||
async def group_id2persist_id(ids: List[str]) -> List[int]:
|
||||
persist_ids = []
|
||||
async with get_session() as db_session:
|
||||
for i in ids:
|
||||
persist_id = (await db_session.scalar(select(SessionModel).where(or_(*[SessionModel.id2 == i])))).id # type: ignore
|
||||
persist_ids.append(persist_id)
|
||||
return persist_ids
|
||||
|
||||
|
||||
async def persist_id2group_id(ids: List[str]) -> List[str]:
|
||||
whereclause: List[ColumnElement[bool]] = []
|
||||
whereclause.append(or_(*[SessionModel.id == id for id in ids]))
|
||||
statement = (
|
||||
select(SessionModel).where(*whereclause)
|
||||
# .join(SessionModel, SessionModel.id == MessageRecord.session_persist_id)
|
||||
)
|
||||
async with get_session() as db_session:
|
||||
records = (await db_session.scalars(statement)).all()
|
||||
return [i.id2 for i in records]
|
||||
return user_ids
|
||||
|
||||
|
||||
def msg_counter(
|
||||
msg_list: List[MessageRecord], keyword: Optional[str]
|
||||
msg_list: List[MessageRecord], keyword: Optional[str]
|
||||
) -> Dict[str, int]:
|
||||
"""### 计算每个人的消息量
|
||||
"""### 计算每个人的消息量
|
||||
|
||||
Args:
|
||||
msg_list (list[MessageRecord]): 需要处理的消息列表
|
||||
Args:
|
||||
msg_list (list[MessageRecord]): 需要处理的消息列表
|
||||
|
||||
Returns:
|
||||
(dict[str,int]): 处理后的消息数量字典,键为用户,值为消息数量
|
||||
"""
|
||||
Returns:
|
||||
(dict[str,int]): 处理后的消息数量字典,键为用户,值为消息数量
|
||||
"""
|
||||
|
||||
lst: Dict[str, int] = {}
|
||||
msg_len = len(msg_list)
|
||||
logger.info("wow , there are {} msgs to count !!!".format(msg_len))
|
||||
lst: Dict[str, int] = {}
|
||||
msg_len = len(msg_list)
|
||||
logger.info('wow , there are {} msgs to count !!!'.format(msg_len))
|
||||
|
||||
for i in msg_list:
|
||||
# logger.debug(f"processing msg {i.plain_text}")
|
||||
if keyword:
|
||||
match = re.search(keyword, i.plain_text)
|
||||
if not match:
|
||||
continue
|
||||
try:
|
||||
lst[str(i.session_persist_id)] += 1
|
||||
except KeyError:
|
||||
lst[str(i.session_persist_id)] = 1
|
||||
for i in msg_list:
|
||||
# logger.debug(f"processing msg {i.plain_text}")
|
||||
if keyword:
|
||||
match = re.search(keyword, i.plain_text)
|
||||
if not match:
|
||||
continue
|
||||
try:
|
||||
lst[str(i.session_persist_id)] += 1
|
||||
except KeyError:
|
||||
lst[str(i.session_persist_id)] = 1
|
||||
|
||||
logger.debug(f"finish counting, result is {lst}")
|
||||
logger.debug(f'finish counting, result is {lst}')
|
||||
|
||||
return lst
|
||||
return lst
|
||||
|
||||
|
||||
def got_rank(msg_dict: Dict[str, int]) -> List:
|
||||
"""### 获得排行榜
|
||||
"""### 获得排行榜
|
||||
|
||||
Args:
|
||||
msg_dict (Dict[str,int]): 要处理的字典
|
||||
Args:
|
||||
msg_dict (Dict[str,int]): 要处理的字典
|
||||
|
||||
Returns:
|
||||
List[Tuple[str,int]]: 排行榜列表(已排序)
|
||||
"""
|
||||
rank = []
|
||||
while len(rank) < plugin_config.get_num:
|
||||
try:
|
||||
max_key = max(msg_dict.items(), key=lambda x: x[1])
|
||||
rank.append(list(max_key))
|
||||
msg_dict.pop(max_key[0])
|
||||
except ValueError:
|
||||
logger.error(
|
||||
"群内拥有聊天记录的人数不足,无法获取到长度为{}的排行榜,已将长度变化为:{}".format(
|
||||
plugin_config.get_num, len(rank)
|
||||
)
|
||||
)
|
||||
break
|
||||
Returns:
|
||||
List[Tuple[str,int]]: 排行榜列表(已排序)
|
||||
"""
|
||||
rank = []
|
||||
while len(rank) < plugin_config.get_num:
|
||||
try:
|
||||
max_key = max(msg_dict.items(), key=lambda x: x[1])
|
||||
rank.append(list(max_key))
|
||||
msg_dict.pop(max_key[0])
|
||||
except ValueError:
|
||||
logger.error(
|
||||
'群内拥有聊天记录的人数不足,无法获取到长度为{}的排行榜,已将长度变化为:{}'.format(
|
||||
plugin_config.get_num, len(rank)
|
||||
)
|
||||
)
|
||||
break
|
||||
|
||||
return rank
|
||||
return rank
|
||||
|
||||
|
||||
def remove_control_characters(string: str) -> str:
|
||||
"""### 将字符串中的控制符去除
|
||||
"""### 将字符串中的控制符去除
|
||||
|
||||
Args:
|
||||
string (str): 需要去除的字符串
|
||||
Args:
|
||||
string (str): 需要去除的字符串
|
||||
|
||||
Returns:
|
||||
(str): 经过处理的字符串
|
||||
"""
|
||||
return "".join(ch for ch in string if unicodedata.category(ch)[0] != "C")
|
||||
Returns:
|
||||
(str): 经过处理的字符串
|
||||
"""
|
||||
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)
|
||||
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)
|
||||
|
||||
if plugin_config.template_path[:2] == "./":
|
||||
path = (
|
||||
os.path.dirname(os.path.abspath(__file__)) + plugin_config.template_path[1:]
|
||||
)
|
||||
else:
|
||||
path = plugin_config.template_path
|
||||
if plugin_config.template_path[:2] == './':
|
||||
path = (
|
||||
os.path.dirname(os.path.abspath(__file__))
|
||||
+ plugin_config.template_path[1:]
|
||||
)
|
||||
else:
|
||||
path = plugin_config.template_path
|
||||
|
||||
path_dir, filename = os.path.split(path)
|
||||
logger.debug(
|
||||
os.path.dirname(os.path.abspath(__file__)) + plugin_config.template_path[1:]
|
||||
)
|
||||
return await template_to_pic(
|
||||
path_dir,
|
||||
filename,
|
||||
{
|
||||
"users": rank,
|
||||
"cache_path": cache_path,
|
||||
"file_path": os.path.dirname(os.path.abspath(__file__)),
|
||||
},
|
||||
pages={"viewport": {"width": 1000, "height": 10}},
|
||||
)
|
||||
path_dir, filename = os.path.split(path)
|
||||
logger.debug(
|
||||
os.path.dirname(os.path.abspath(__file__))
|
||||
+ plugin_config.template_path[1:]
|
||||
)
|
||||
return await template_to_pic(
|
||||
path_dir,
|
||||
filename,
|
||||
{
|
||||
'users': rank,
|
||||
'cache_path': cache_path,
|
||||
'file_path': os.path.dirname(os.path.abspath(__file__)),
|
||||
},
|
||||
pages={'viewport': {'width': 1000, 'height': 10}},
|
||||
)
|
||||
|
||||
|
||||
def _get_user_nickname(user_info: UserInfo) -> str:
|
||||
user_nickname = (
|
||||
user_info.user_displayname
|
||||
if user_info.user_displayname
|
||||
else user_info.user_name if user_info.user_name else user_info.user_id
|
||||
)
|
||||
return user_nickname
|
||||
user_nickname = (
|
||||
user_info.user_displayname
|
||||
if user_info.user_displayname
|
||||
else user_info.user_name
|
||||
if user_info.user_name
|
||||
else user_info.user_id
|
||||
)
|
||||
return user_nickname
|
||||
|
||||
|
||||
async def _get_user_default_avatar() -> bytes:
|
||||
img = open(
|
||||
os.path.dirname(os.path.abspath(__file__)) + "/template/avatar/default.jpg",
|
||||
"rb",
|
||||
).read()
|
||||
return img
|
||||
img = open(
|
||||
os.path.dirname(os.path.abspath(__file__))
|
||||
+ '/template/avatar/default.jpg',
|
||||
'rb',
|
||||
).read()
|
||||
return img
|
||||
|
||||
|
||||
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} 下载失败!")
|
||||
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
|
||||
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 = plugin_config.use_user_info_cache,
|
||||
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)
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
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()
|
||||
|
||||
for i in user_avatars:
|
||||
if not i:
|
||||
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()
|
||||
|
||||
total = sum([i[1] for i in rank])
|
||||
rank2 = []
|
||||
for i in range(len(rank)):
|
||||
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_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)
|
||||
|
||||
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_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
|
||||
return rank2
|
||||
|
@ -1,12 +1,10 @@
|
||||
[project]
|
||||
name = "nonebot-plugin-dialectlist"
|
||||
version = "2.6.2"
|
||||
version = "2.7.0"
|
||||
description = "看看你群群友有多能说"
|
||||
authors = [
|
||||
{name = "Chen_Xu233", email = "woyerpa@outlook.com"},
|
||||
]
|
||||
authors = [{ name = "Chen_Xu233", email = "woyerpa@outlook.com" }]
|
||||
dependencies = [
|
||||
"nonebot-plugin-chatrecorder>=0.6.0,<0.7.0",
|
||||
"nonebot-plugin-chatrecorder>=0.7.0",
|
||||
"nonebot-plugin-orm[default]",
|
||||
"nonebot-plugin-apscheduler>=0.4.0",
|
||||
"nonebot-plugin-alconna>=0.50.2",
|
||||
@ -19,7 +17,7 @@ dependencies = [
|
||||
]
|
||||
requires-python = ">=3.9,<4.0"
|
||||
readme = "README.md"
|
||||
license = {text = "MIT"}
|
||||
license = { text = "MIT" }
|
||||
|
||||
|
||||
[project.optional-dependencies]
|
||||
@ -30,9 +28,7 @@ dev = [
|
||||
"nb-cli>=0.7.6",
|
||||
"py-spy>=0.3.14",
|
||||
]
|
||||
Test = [
|
||||
"nonebot-adapter-onebot>=2.4.4",
|
||||
]
|
||||
Test = ["nonebot-adapter-onebot>=2.4.4"]
|
||||
|
||||
[tool.pdm]
|
||||
distribution = true
|
||||
|
Loading…
x
Reference in New Issue
Block a user