mirror of
https://github.com/ChenXu233/nonebot_plugin_dialectlist.git
synced 2026-01-25 21:22:16 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b36e32fe19 | ||
|
|
bd195ac87a | ||
|
|
152128391c | ||
|
|
eee9ac2ab3 | ||
|
|
4970a47b83 | ||
|
|
383a3f602a |
133
README.md
133
README.md
@@ -6,14 +6,15 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
# 📃话痨排行榜
|
||||
# 📃 话痨排行榜
|
||||
|
||||
nonebot-plugin-dialectlist
|
||||
|
||||
<p align="center">
|
||||
<a href="https://pypi.python.org/pypi/nonebot-plugin-dialectlist">
|
||||
<img src="https://img.shields.io/pypi/v/nonebot-plugin-dialectlist.svg" alt="pypi">
|
||||
</a>
|
||||
|
||||
|
||||
<img src="https://img.shields.io/badge/python-3.9+-blue.svg" alt="python">
|
||||
|
||||
<a href="https://qm.qq.com/q/Yty2yc9Bee">
|
||||
@@ -21,22 +22,28 @@ nonebot-plugin-dialectlist
|
||||
</a>
|
||||
</p>
|
||||
|
||||
[](https://wakatime.com/badge/user/114aee90-a5f9-49aa-b441-9eca7eebfda3/project/68aaa2a1-fb8a-4b00-bb66-ee67e8a3f3b0)
|
||||
|
||||
\>💬**看看群友们这些天在群里水了多少话**💬<
|
||||
|
||||
</div>
|
||||
|
||||
## 💿 安装
|
||||
|
||||
通过`pip`或`nb`安装:
|
||||
|
||||
- 通过 pip 安装
|
||||
|
||||
```bash
|
||||
pip install nonebot-plugin-dialectlist
|
||||
```
|
||||
|
||||
- 通过 nb-cli 安装
|
||||
|
||||
```bash
|
||||
nb plugin install nonebot-plugin-dialectlist
|
||||
```
|
||||
|
||||
|
||||
### ✅ 插件依赖于
|
||||
|
||||
1. [nonebot-plugin-datastore](https://github.com/he0119/nonebot-plugin-datastore) ————本地化储存
|
||||
@@ -46,13 +53,14 @@ nb plugin install nonebot-plugin-dialectlist
|
||||
5. [nonebot-plugin-chatrecorder](https://github.com/noneplugin/nonebot-plugin-chatrecorder) ————实现消息储存
|
||||
6. [nonebot-plugin-cesaa](https://github.com/MountainDash/nonebot-plugin-send-anything-anywhere) ————实现多平台
|
||||
|
||||
**⚠注意** 若先前没有安装过```nonebot-plugin-chatrecorder```或者```nonebot-plugin-orm```,则会在启动时报错,请按报错的提示安装数据库!
|
||||
|
||||
**⚠ 注意** 若先前没有安装过`nonebot-plugin-chatrecorder`或者`nonebot-plugin-orm`,则会在启动时报错,请按报错的提示安装数据库!
|
||||
|
||||
## ⚙ 配置
|
||||
|
||||
需要**提前配置**本插件所**依赖的插件**!
|
||||
|
||||
在 .env 中,可以添加以下配置项
|
||||
|
||||
```python
|
||||
dialectlist__get_num: int = 5 # 获取人数数量
|
||||
dialectlist__font: str = "SimHei" # 字体格式
|
||||
@@ -60,73 +68,74 @@ dialectlist__suffix: bool = True # 是否显示后缀
|
||||
dialectlist__excluded_self: bool = True # 是否排除自己
|
||||
dialectlist__visualization: bool = True # 是否可视化
|
||||
dialectlist__show_text_rank: bool = True # 是否显示文本排名
|
||||
dialectlist__counting_cache: bool = False # 计数缓存(能够提高回复速度)
|
||||
dialectlist__excluded_people: List[str] = [] # 排除的人的QQ号
|
||||
dialectlist__excluded_people: List[str] = [] # 排除的人的 QQ 号
|
||||
dialectlist__use_user_info_cache: bool = False # 是否使用用户信息缓存
|
||||
dialectlist__aggregate_transmission: bool = False # 是否聚合转发消息
|
||||
dialectlist__timezone: Optional[str] = "Asia/Shanghai" # 时区,影响统计时间
|
||||
dialectlist__string_suffix: str = "统计花费时间:{timecost}秒" # 消息格式后缀
|
||||
dialectlist__string_suffix: str = "统计花费时间:{timecost}秒" # 消息格式后缀
|
||||
dialectlist__template_path: str = "./template/rank_template.j2" # 模板路径
|
||||
dialectlist__string_format: str = "第{index}名:\n{nickname},{chatdatanum}条消息\n" # 消息格式
|
||||
dialectlist__string_format: str = "第{index}名:\n{nickname},{chatdatanum}条消息、n" # 消息格式
|
||||
```
|
||||
💭也可以不进行配置,这将会使插件按照默认配置运行
|
||||
|
||||
### ⚠ 注意!!
|
||||
💭 也可以不进行配置,这将会使插件按照默认配置运行
|
||||
|
||||
### ⚠ 注意!!
|
||||
|
||||
> 在旧版插件(2.0.0 以下)中,dialectlist 与后面的配置项只隔了一个下划线,若更新到新版本以后需要俩个下划线。
|
||||
|
||||
> 由于插件依赖chatrecord多次引入爆炸性修改,建议在遇到问题后优先尝试降级chatrecord插件
|
||||
> 由于插件依赖 chatrecord 多次引入爆炸性修改,建议在遇到问题后优先尝试降级 chatrecord 插件
|
||||
|
||||
## 🗨命令
|
||||
__!!注意!!__
|
||||
## 🗨 命令
|
||||
|
||||
**!!注意!!**
|
||||
新版本指令调用方式改变,改为更易理解也更好打的 B 话榜。
|
||||
同时也可以用类似 `/今日废话榜` 的方式(只要改前面的就好了)(算是给 [盘古之白](https://github.com/vinta/pangu.js) 风格爱好者的福利吧?)
|
||||
|
||||
### 🎨一般用法
|
||||
### 🎨 一般用法
|
||||
|
||||
#### B话榜
|
||||
#### B 话榜
|
||||
|
||||
-`/B话榜` ————看看有史以来(机器人存在以来)群友们发了多少消息! (好像没写)
|
||||
-`/B 话榜` ————看看有史以来(机器人存在以来)群友们发了多少消息! (好像没写)
|
||||
|
||||
-`/今日B话榜` ————看看今天的群友发了多少消息!
|
||||
-`/今日 B 话榜` ————看看今天的群友发了多少消息!
|
||||
|
||||
-`/昨日B话榜` ————看看昨天的群友发了多少消息!
|
||||
-`/昨日 B 话榜` ————看看昨天的群友发了多少消息!
|
||||
|
||||
-`/前日B话榜` ————看看前天的群友发了多少消息!
|
||||
-`/前日 B 话榜` ————看看前天的群友发了多少消息!
|
||||
|
||||
-`/本周B话榜` ————看看本周的群友发了多少消息!
|
||||
|
||||
-`/上周B话榜` ————看看上周的群友发了多少消息!
|
||||
-`/本周 B 话榜` ————看看本周的群友发了多少消息!
|
||||
|
||||
-`/本月B话榜` ————看看这个月的群友发了多少消息!
|
||||
-`/上周 B 话榜` ————看看上周的群友发了多少消息!
|
||||
|
||||
-`/年度B话榜` ————看看今年的群友发了多少消息!
|
||||
-`/本月 B 话榜` ————看看这个月的群友发了多少消息!
|
||||
|
||||
-`/历史B话榜` ————看看历史上(机器人存在以来)的群友发了多少消息!
|
||||
-`/年度 B 话榜` ————看看今年的群友发了多少消息!
|
||||
|
||||
#### 看看B话(kkb)
|
||||
-`/历史 B 话榜` ————看看历史上(机器人存在以来)的群友发了多少消息!
|
||||
|
||||
-`/看看B话 [@某人|QQ号]` ————看看这个b人在这个b群发了多少b话!
|
||||
#### 看看 B 话(kkb)
|
||||
|
||||
### 🚀进阶用法
|
||||
-`/看看 B 话 [@某人|QQ 号]` ————看看这个 b 人在这个 b 群发了多少 b 话!
|
||||
|
||||
#### B话榜
|
||||
### 🚀 进阶用法
|
||||
|
||||
`/{时间类型(今日|年度)?}{B话榜|废话榜} {时间类型?} {ISO8601 格式时间 ?} {群号} {关键词}`
|
||||
#### B 话榜
|
||||
|
||||
如:`/B话榜 历史 2024-01-01~2024-01-02 12345678 女装`
|
||||
`/{时间类型(今日|年度)?}{B 话榜|废话榜} {时间类型?} {ISO8601 格式时间 ?} {群号} {关键词}`
|
||||
|
||||
也可以 `/{时间类型(今日|年度)?}{B话榜|废话榜} {时间类型?} {ISO8601 格式时间 ?} -g {群号} -k {关键词}`
|
||||
如:`/B 话榜 历史 2024-01-01~2024-01-02 12345678 女装`
|
||||
|
||||
也可以 `/{时间类型(今日|年度)?}{B 话榜|废话榜} {时间类型?} {ISO8601 格式时间 ?} -g {群号} -k {关键词}`
|
||||
|
||||
以下调用方法均合法:
|
||||
|
||||
`/今日B话榜 -g 12345678 -k 女装`
|
||||
`/昨日B话榜 -k 女装`
|
||||
`/本周B话榜 -g 12345678`
|
||||
`/今日 B 话榜 -g 12345678 -k 女装`
|
||||
`/昨日 B 话榜 -k 女装`
|
||||
`/本周 B 话榜 -g 12345678`
|
||||
|
||||
#### 看看B话
|
||||
#### 看看 B 话
|
||||
|
||||
`/看看B话 {@|QQ号} {群号?} {关键词?}`
|
||||
`/看看 B 话 {@|QQ 号} {群号?} {关键词?}`
|
||||
|
||||
以下调用方法均合法:
|
||||
|
||||
@@ -138,28 +147,28 @@ __!!注意!!__
|
||||
|
||||
## 💪 目前支持的平台
|
||||
|
||||
| 平台 | 是否经过测试 | 是否能够正常工作 | 测试环境 |
|
||||
|:-----:|:----:|:----:| :----: |
|
||||
| Onebot | ✅ | ✅ | NapCat + Window11|
|
||||
| 飞书 | ❌ | ❓ | 🤔 |
|
||||
| Red | ❌ | ❓ | 🤔 |
|
||||
| DoDo | ❌ | ❓ | 🤔 |
|
||||
| Mirai | ❌ | ❓ | 🤔 |
|
||||
| 开黑啦 | ❌ | ❓ | 🤔 |
|
||||
| Kritor | ❌ | ❓ | 🤔 |
|
||||
| Ntchat | ❌ | ❓ | 🤔 |
|
||||
| Satori | ❌ | ❓ | 🤔 |
|
||||
| Telegram | ❌ | ❓ | 🤔 |
|
||||
| Discord | ❌ | ❓ | 🤔 |
|
||||
| Tailchat | ❌ | ❓ | 🤔 |
|
||||
| QQ 官方接口 | ❌ | ❓ | 🤔 |
|
||||
| Rocket.Chat | ❌ | ❓ | 🤔 |
|
||||
| 平台 | 是否经过测试 | 是否能够正常工作 | 测试环境 |
|
||||
| :---------: | :----------: | :--------------: | :---------------: |
|
||||
| Onebot | ✅ | ✅ | NapCat + Window11 |
|
||||
| 飞书 | ❌ | ❓ | 🤔 |
|
||||
| Red | ❌ | ❓ | 🤔 |
|
||||
| DoDo | ❌ | ❓ | 🤔 |
|
||||
| Mirai | ❌ | ❓ | 🤔 |
|
||||
| 开黑啦 | ❌ | ❓ | 🤔 |
|
||||
| Kritor | ❌ | ❓ | 🤔 |
|
||||
| Ntchat | ❌ | ❓ | 🤔 |
|
||||
| Satori | ❌ | ❓ | 🤔 |
|
||||
| Telegram | ❌ | ❓ | 🤔 |
|
||||
| Discord | ❌ | ❓ | 🤔 |
|
||||
| Tailchat | ❌ | ❓ | 🤔 |
|
||||
| QQ 官方接口 | ❌ | ❓ | 🤔 |
|
||||
| Rocket.Chat | ❌ | ❓ | 🤔 |
|
||||
|
||||
- 如果你测试过能够使用,请在 Issue 中指出
|
||||
|
||||
## 📦另外
|
||||
## 📦 另外
|
||||
|
||||
### 😳加入作者的 BUG 反馈群 ~~(🥵女装粉丝群)~~
|
||||
### 😳 加入作者的 BUG 反馈群 ~~(🥵 女装粉丝群)~~
|
||||
|
||||
[群连接](https://qm.qq.com/q/Yty2yc9Bee)
|
||||
|
||||
@@ -172,10 +181,9 @@ __!!注意!!__
|
||||
|
||||

|
||||
|
||||
### 💕 感谢
|
||||
|
||||
### 💕感谢
|
||||
|
||||
本插件的__init__.py 中的处理函数参考了词云中的方法 ~~(其实大部分都是 Ctrl+C Ctr+V)~~
|
||||
本插件的**init**.py 中的处理函数参考了词云中的方法 ~~(其实大部分都是 Ctrl+C Ctr+V)~~
|
||||
|
||||
[nonebot-plugin-wordcloud](https://github.com/he0119/nonebot-plugin-wordcloud)
|
||||
|
||||
@@ -192,7 +200,6 @@ __!!注意!!__
|
||||
- [x] 更好看的图片渲染
|
||||
|
||||
- [x] 添加一些全新的可配置项
|
||||
|
||||
- [x] 尝试利用 jinja2 模板引擎制作可视化图片
|
||||
|
||||
- [x] 私聊的查询(超级用户可以任意查询群聊的信息)一半完成
|
||||
@@ -202,9 +209,9 @@ __!!注意!!__
|
||||
- [x] 查询带某关键词的消息量
|
||||
|
||||
- [x] 合并转发
|
||||
|
||||
待补充。.....
|
||||
|
||||
待补充。.....
|
||||
|
||||
### 👾 题外话
|
||||
|
||||
### 👾题外话
|
||||
~~整个项目快被我写成屎山了~~
|
||||
|
||||
@@ -16,7 +16,6 @@ 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.adapters import Bot, Event
|
||||
from nonebot.log import logger
|
||||
from nonebot.params import Arg, Depends
|
||||
@@ -31,11 +30,11 @@ from nonebot_plugin_alconna import (
|
||||
Option,
|
||||
on_alconna,
|
||||
)
|
||||
from nonebot_plugin_chatrecorder import get_message_records
|
||||
from nonebot_plugin_uninfo import Session, Uninfo, get_session
|
||||
|
||||
from .config import Config, plugin_config
|
||||
from .storage import build_cache, get_cache
|
||||
|
||||
# from .storage import build_cache, get_cache
|
||||
from .time import (
|
||||
get_datetime_fromisoformat_with_timezone,
|
||||
get_datetime_now_with_timezone,
|
||||
@@ -46,8 +45,8 @@ from .utils import (
|
||||
get_rank_image,
|
||||
get_user_infos,
|
||||
got_rank,
|
||||
msg_counter,
|
||||
persist_id2user_id,
|
||||
get_user_message_counts,
|
||||
)
|
||||
|
||||
__plugin_meta__ = PluginMetadata(
|
||||
@@ -80,16 +79,6 @@ 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)
|
||||
|
||||
|
||||
b_cmd = on_alconna(
|
||||
Alconna(
|
||||
'看看B话',
|
||||
@@ -121,18 +110,16 @@ async def handle_b_cmd(
|
||||
if not gid:
|
||||
await b_cmd.finish('请指定群号。')
|
||||
|
||||
if keyword.available:
|
||||
keywords = keyword.result
|
||||
else:
|
||||
keywords = None
|
||||
_keyword = keyword.result
|
||||
|
||||
messages = await get_message_records(
|
||||
d = await get_user_message_counts(
|
||||
keyword=_keyword,
|
||||
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(
|
||||
@@ -301,23 +288,16 @@ async def handle_rank(
|
||||
|
||||
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}')
|
||||
t1 = t.time()
|
||||
raw_rank = await get_user_message_counts(
|
||||
keyword=keyword,
|
||||
scene_ids=[id],
|
||||
types=['message'], # 排除机器人自己发的消息
|
||||
time_start=start,
|
||||
time_stop=stop,
|
||||
exclude_user_ids=plugin_config.excluded_people,
|
||||
)
|
||||
logger.debug(f'获取计数消息花费时间:{t.time() - t1}')
|
||||
|
||||
if not raw_rank:
|
||||
await saa.Text(
|
||||
|
||||
@@ -5,24 +5,25 @@ from pydantic import BaseModel
|
||||
|
||||
|
||||
class ScopedConfig(BaseModel):
|
||||
get_num: int = 5 # 获取人数数量
|
||||
font: str = "SimHei" # 字体格式
|
||||
suffix: bool = True # 是否显示后缀
|
||||
excluded_self: bool = True # 是否排除自己
|
||||
visualization: bool = True # 是否可视化
|
||||
show_text_rank: bool = True # 是否显示文本排名
|
||||
counting_cache: bool = False # 计数缓存(能够提高回复速度)
|
||||
excluded_people: List[str] = [] # 排除的人的QQ号
|
||||
use_user_info_cache: bool = False # 是否使用用户信息缓存
|
||||
aggregate_transmission: 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" # 消息格式
|
||||
get_num: int = 5 # 获取人数数量
|
||||
font: str = 'SimHei' # 字体格式
|
||||
suffix: bool = True # 是否显示后缀
|
||||
excluded_self: bool = True # 是否排除自己
|
||||
visualization: bool = True # 是否可视化
|
||||
show_text_rank: bool = True # 是否显示文本排名
|
||||
excluded_people: List[str] = [] # 排除的人的QQ号
|
||||
use_user_info_cache: bool = False # 是否使用用户信息缓存
|
||||
aggregate_transmission: 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' # 消息格式
|
||||
)
|
||||
|
||||
|
||||
class Config(BaseModel):
|
||||
dialectlist: ScopedConfig = ScopedConfig()
|
||||
dialectlist: ScopedConfig = ScopedConfig()
|
||||
|
||||
|
||||
global_config = get_driver().config
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
"""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,23 +0,0 @@
|
||||
from datetime import datetime
|
||||
from typing import Union
|
||||
|
||||
from nonebot_plugin_orm import Model
|
||||
from nonebot_plugin_userinfo import UserInfo
|
||||
from sqlalchemy import Integer
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
|
||||
class UserRankInfo(UserInfo):
|
||||
user_bnum: int
|
||||
user_proportion: float
|
||||
user_nickname: str
|
||||
user_index: Union[int, str]
|
||||
user_avatar_bytes: bytes
|
||||
|
||||
|
||||
class MessageCountCache(Model):
|
||||
__table_args__ = {"extend_existing": True}
|
||||
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
||||
time: Mapped[datetime]
|
||||
session_id: Mapped[int] = mapped_column(Integer, index=True)
|
||||
session_bnum: Mapped[int] = mapped_column(Integer)
|
||||
11
nonebot_plugin_dialectlist/schema.py
Normal file
11
nonebot_plugin_dialectlist/schema.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from typing import Union
|
||||
|
||||
from nonebot_plugin_userinfo import UserInfo
|
||||
|
||||
|
||||
class UserRankInfo(UserInfo):
|
||||
user_bnum: int
|
||||
user_proportion: float
|
||||
user_nickname: str
|
||||
user_index: Union[int, str]
|
||||
user_avatar_bytes: bytes
|
||||
@@ -1,133 +0,0 @@
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
from nonebot import get_driver
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.log import logger
|
||||
from nonebot.message import event_postprocessor
|
||||
from nonebot.params import Depends
|
||||
from nonebot_plugin_chatrecorder import get_message_records
|
||||
from nonebot_plugin_chatrecorder.utils import remove_timezone
|
||||
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):
|
||||
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,7 +1,7 @@
|
||||
from inspect import cleandoc
|
||||
|
||||
__usage__ = cleandoc(
|
||||
"""
|
||||
"""
|
||||
快速调用:
|
||||
/今日B话榜 ————看看今天群友发了多少消息。
|
||||
|
||||
@@ -18,7 +18,7 @@ __usage__ = cleandoc(
|
||||
-`/前日B话榜` ————看看前天的群友发了多少消息!
|
||||
|
||||
-`/本周B话榜` ————看看本周的群友发了多少消息!
|
||||
|
||||
|
||||
-`/上周B话榜` ————看看上周的群友发了多少消息!
|
||||
|
||||
-`/本月B话榜` ————看看这个月的群友发了多少消息!
|
||||
|
||||
@@ -2,9 +2,11 @@ import asyncio
|
||||
import os
|
||||
import re
|
||||
import unicodedata
|
||||
from typing import Dict, List, Optional
|
||||
from typing import Dict, List, Optional, Any
|
||||
|
||||
import httpx
|
||||
from sqlalchemy import select, func
|
||||
|
||||
from nonebot.adapters import Bot, Event
|
||||
from nonebot.compat import model_dump
|
||||
from nonebot.log import logger
|
||||
@@ -20,10 +22,11 @@ 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 nonebot_plugin_chatrecorder.record import filter_statement
|
||||
|
||||
|
||||
from .config import plugin_config
|
||||
from .model import UserRankInfo
|
||||
from .schema import UserRankInfo
|
||||
|
||||
cache_path = get_cache_dir('nonebot_plugin_dialectlist')
|
||||
|
||||
@@ -38,65 +41,29 @@ async def ensure_group(
|
||||
|
||||
async def persist_id2user_id(ids: List) -> List[str]:
|
||||
user_ids = []
|
||||
user_persist_ids = []
|
||||
if not ids:
|
||||
return user_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)
|
||||
statement = (
|
||||
select(UserModel.user_id)
|
||||
.join(SessionModel, UserModel.id == SessionModel.user_persist_id)
|
||||
.where(SessionModel.id.in_(ids))
|
||||
)
|
||||
result = await db_session.scalars(statement)
|
||||
user_ids = result.all()
|
||||
|
||||
return user_ids
|
||||
return list(user_ids)
|
||||
|
||||
|
||||
def msg_counter(
|
||||
msg_list: List[MessageRecord], keyword: Optional[str]
|
||||
) -> Dict[str, int]:
|
||||
"""### 计算每个人的消息量
|
||||
|
||||
Args:
|
||||
msg_list (list[MessageRecord]): 需要处理的消息列表
|
||||
|
||||
Returns:
|
||||
(dict[str,int]): 处理后的消息数量字典,键为用户,值为消息数量
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
logger.debug(f'finish counting, result is {lst}')
|
||||
|
||||
return lst
|
||||
|
||||
|
||||
def got_rank(msg_dict: Dict[str, int]) -> List:
|
||||
def got_rank(msg_dict: Dict[int, int]) -> List[List[Any]]:
|
||||
"""### 获得排行榜
|
||||
|
||||
Args:
|
||||
msg_dict (Dict[str,int]): 要处理的字典
|
||||
msg_dict (Dict[int,int]): 要处理的字典
|
||||
|
||||
Returns:
|
||||
List[Tuple[str,int]]: 排行榜列表(已排序)
|
||||
List[Tuple[int,int]]: 排行榜列表(已排序)
|
||||
"""
|
||||
rank = []
|
||||
while len(rank) < plugin_config.get_num:
|
||||
@@ -261,3 +228,42 @@ async def get_user_infos(
|
||||
rank2.append(user)
|
||||
|
||||
return rank2
|
||||
|
||||
|
||||
async def get_user_message_counts(
|
||||
keyword: Optional[str] = None, **kwargs
|
||||
) -> Dict[int, int]:
|
||||
"""获取每个用户的消息数量(直接在数据库层面统计)
|
||||
|
||||
参数:
|
||||
* ``keyword``: 可选,关键词,只统计包含该关键词的消息
|
||||
* ``**kwargs``: 筛选参数,具体查看 `filter_statement` 中的定义
|
||||
|
||||
返回值:
|
||||
* ``Dict[str, int]``: 键为user_persist_id,值为该用户的消息数量
|
||||
"""
|
||||
whereclause = filter_statement(**kwargs)
|
||||
|
||||
# 如果提供了关键词,添加关键词过滤条件
|
||||
if keyword:
|
||||
# 构造LIKE条件,类似于msg_counter函数中的正则匹配
|
||||
# 根据数据库类型不同,可能需要调整LIKE的语法
|
||||
keyword_condition = MessageRecord.plain_text.ilike(f'%{keyword}%')
|
||||
whereclause.append(keyword_condition)
|
||||
|
||||
# 使用SQL的GROUP BY和COUNT进行分组统计
|
||||
statement = (
|
||||
select(
|
||||
SessionModel.user_persist_id,
|
||||
func.count(MessageRecord.id).label('message_count'),
|
||||
)
|
||||
.select_from(MessageRecord)
|
||||
.join(SessionModel, SessionModel.id == MessageRecord.session_persist_id)
|
||||
.where(*whereclause)
|
||||
.group_by(SessionModel.user_persist_id)
|
||||
)
|
||||
|
||||
async with get_session() as db_session:
|
||||
result = await db_session.execute(statement)
|
||||
# 转换为字典格式返回
|
||||
return {user_id: count for user_id, count in result.all()}
|
||||
|
||||
235
pdm.lock
generated
235
pdm.lock
generated
@@ -5,7 +5,7 @@
|
||||
groups = ["default", "dev"]
|
||||
strategy = []
|
||||
lock_version = "4.5.0"
|
||||
content_hash = "sha256:42cf686b0618c9e80b1aae28a90a3d694e17da96b6a208ff2720f11d88ef4e4f"
|
||||
content_hash = "sha256:1e8f0e2bc32d8cf861a8342b7d90d683f0efc9cd94ac461dc65363788a365902"
|
||||
|
||||
[[metadata.targets]]
|
||||
requires_python = ">=3.9,<3.13"
|
||||
@@ -33,16 +33,17 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "alembic"
|
||||
version = "1.13.1"
|
||||
version = "1.16.4"
|
||||
summary = ""
|
||||
dependencies = [
|
||||
"mako",
|
||||
"sqlalchemy",
|
||||
"tomli; python_full_version < \"3.11\"",
|
||||
"typing-extensions",
|
||||
]
|
||||
files = [
|
||||
{file = "alembic-1.13.1-py3-none-any.whl", hash = "sha256:2edcc97bed0bd3272611ce3a98d98279e9c209e7186e43e75bbb1b2bdfdbcc43"},
|
||||
{file = "alembic-1.13.1.tar.gz", hash = "sha256:4932c8558bf68f2ee92b9bbcb8218671c627064d5b08939437af6d77dc05e595"},
|
||||
{file = "alembic-1.16.4-py3-none-any.whl", hash = "sha256:b05e51e8e82efc1abd14ba2af6392897e145930c3e0a2faf2b0da2f7f7fd660d"},
|
||||
{file = "alembic-1.16.4.tar.gz", hash = "sha256:efab6ada0dd0fae2c92060800e0bf5c1dc26af15a10e02fb4babff164b4725e2"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -866,7 +867,7 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "nonebot-plugin-alconna"
|
||||
version = "0.57.2"
|
||||
version = "0.59.0"
|
||||
summary = ""
|
||||
dependencies = [
|
||||
"arclet-alconna",
|
||||
@@ -878,8 +879,8 @@ dependencies = [
|
||||
"tarina",
|
||||
]
|
||||
files = [
|
||||
{file = "nonebot_plugin_alconna-0.57.2-py3-none-any.whl", hash = "sha256:189d558b8f7cb79329662795e3622b7fe4066962bf0431faee309fae3d1cdd58"},
|
||||
{file = "nonebot_plugin_alconna-0.57.2.tar.gz", hash = "sha256:fcfbd80bfe2e5a70ab644d95b8c4dd73dda6d41c3feb6deeb71dba1e44565b40"},
|
||||
{file = "nonebot_plugin_alconna-0.59.0-py3-none-any.whl", hash = "sha256:b84e3f8cb5eb7f4ead7e6aca91488d3df8077ea8d93c78fdfbb76b42cd60a483"},
|
||||
{file = "nonebot_plugin_alconna-0.59.0.tar.gz", hash = "sha256:9d164ce3fc6e46c211582a5a4e00fd033e397d5afcb5b54b88f39c8a9fcdb368"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -927,7 +928,7 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "nonebot-plugin-htmlrender"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
summary = ""
|
||||
dependencies = [
|
||||
"aiofiles",
|
||||
@@ -940,27 +941,28 @@ dependencies = [
|
||||
"python-markdown-math",
|
||||
]
|
||||
files = [
|
||||
{file = "nonebot_plugin_htmlrender-0.6.5-py3-none-any.whl", hash = "sha256:cdfecac75eecc9509021b20482fde5058935d9797b0efd69738b4855b7ee1458"},
|
||||
{file = "nonebot_plugin_htmlrender-0.6.5.tar.gz", hash = "sha256:1a7061f38b4817c79e8a0ca510e683a740ae350797a9575ad8207e155fe61062"},
|
||||
{file = "nonebot_plugin_htmlrender-0.6.6-py3-none-any.whl", hash = "sha256:b0dc4130b4740fe6fda7b6c2424f277ea9d13713c74949a040512fddda92bd9a"},
|
||||
{file = "nonebot_plugin_htmlrender-0.6.6.tar.gz", hash = "sha256:3cf3594431d995d6d960dbf445e13a88f8580f799eedc303a652f12540b8198c"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nonebot-plugin-localstore"
|
||||
version = "0.6.0"
|
||||
version = "0.7.4"
|
||||
summary = ""
|
||||
dependencies = [
|
||||
"nonebot2",
|
||||
"nonestorage",
|
||||
"pydantic",
|
||||
"typing-extensions",
|
||||
]
|
||||
files = [
|
||||
{file = "nonebot_plugin_localstore-0.6.0-py3-none-any.whl", hash = "sha256:59f0126d85680601166a9a62cca886a33e1b0a8fef7cd67fff52747bd47f42d3"},
|
||||
{file = "nonebot_plugin_localstore-0.6.0.tar.gz", hash = "sha256:7eb4039cb2e76c54b860b2b98f2b90cd25284919603e81dedec367f215662fcd"},
|
||||
{file = "nonebot_plugin_localstore-0.7.4-py3-none-any.whl", hash = "sha256:3b08030878eadcdd8b9ce3d079da0dc2d0e41dc91f0b2d8cf7fa862a27de9090"},
|
||||
{file = "nonebot_plugin_localstore-0.7.4.tar.gz", hash = "sha256:85ddc13814bfcd484ab311306823651390020bf44f4fb4733b343a58e72723ce"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nonebot-plugin-orm"
|
||||
version = "0.7.7"
|
||||
version = "0.8.1"
|
||||
summary = ""
|
||||
dependencies = [
|
||||
"alembic",
|
||||
@@ -970,25 +972,25 @@ dependencies = [
|
||||
"nonebot-plugin-localstore",
|
||||
"nonebot2",
|
||||
"sqlalchemy",
|
||||
"typing-extensions; python_full_version < \"3.11\"",
|
||||
"typing-extensions",
|
||||
]
|
||||
files = [
|
||||
{file = "nonebot_plugin_orm-0.7.7-py3-none-any.whl", hash = "sha256:645ba90f24969ce8bebb6841cdd0a0fb823e27a5d256989e332ec9f6608bbde5"},
|
||||
{file = "nonebot_plugin_orm-0.7.7.tar.gz", hash = "sha256:61705c59bbac51521738259efbe51223847a0e0389807267fff7a5167f8c8c85"},
|
||||
{file = "nonebot_plugin_orm-0.8.1-py3-none-any.whl", hash = "sha256:ac10a48b8c8ef90d4506acd6f5f46c02cf9ab76935856532ba15ab9c00684cd7"},
|
||||
{file = "nonebot_plugin_orm-0.8.1.tar.gz", hash = "sha256:5c90c84ce7ebd8da5244b72ede85d3c4f08e94190526066c8955fd94bde6ffdf"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nonebot-plugin-orm"
|
||||
version = "0.7.7"
|
||||
version = "0.8.1"
|
||||
extras = ["default"]
|
||||
summary = ""
|
||||
dependencies = [
|
||||
"nonebot-plugin-orm==0.7.7",
|
||||
"nonebot-plugin-orm==0.8.1",
|
||||
"sqlalchemy",
|
||||
]
|
||||
files = [
|
||||
{file = "nonebot_plugin_orm-0.7.7-py3-none-any.whl", hash = "sha256:645ba90f24969ce8bebb6841cdd0a0fb823e27a5d256989e332ec9f6608bbde5"},
|
||||
{file = "nonebot_plugin_orm-0.7.7.tar.gz", hash = "sha256:61705c59bbac51521738259efbe51223847a0e0389807267fff7a5167f8c8c85"},
|
||||
{file = "nonebot_plugin_orm-0.8.1-py3-none-any.whl", hash = "sha256:ac10a48b8c8ef90d4506acd6f5f46c02cf9ab76935856532ba15ab9c00684cd7"},
|
||||
{file = "nonebot_plugin_orm-0.8.1.tar.gz", hash = "sha256:5c90c84ce7ebd8da5244b72ede85d3c4f08e94190526066c8955fd94bde6ffdf"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1009,15 +1011,15 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "nonebot-plugin-uninfo"
|
||||
version = "0.7.3"
|
||||
version = "0.8.2"
|
||||
summary = ""
|
||||
dependencies = [
|
||||
"importlib-metadata",
|
||||
"nonebot2",
|
||||
]
|
||||
files = [
|
||||
{file = "nonebot_plugin_uninfo-0.7.3-py3-none-any.whl", hash = "sha256:d45e97aaaebaf6b41ec0c625859216e61700e6a2929cbe0ee659a71b470fdd08"},
|
||||
{file = "nonebot_plugin_uninfo-0.7.3.tar.gz", hash = "sha256:254922908d8b8c60ba63c7216d4d8de54ebb7e56ef91b3b360ebd810dcff4d48"},
|
||||
{file = "nonebot_plugin_uninfo-0.8.2-py3-none-any.whl", hash = "sha256:c1c0b1152cc3a22b85d1973441d08e93dd73d2a9b5d54dad9ba89507eb68b488"},
|
||||
{file = "nonebot_plugin_uninfo-0.8.2.tar.gz", hash = "sha256:143fc4150a4d372c1996fbb499ca64500af2233cab94b62fb241892ec213d83f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1080,6 +1082,15 @@ files = [
|
||||
{file = "noneprompt-0.1.9.tar.gz", hash = "sha256:338b8bb89a8d22ef35f1dedb3aa7c1b228cf139973bdc43c5ffc3eef64457db9"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nonestorage"
|
||||
version = "0.1.0"
|
||||
summary = ""
|
||||
files = [
|
||||
{file = "nonestorage-0.1.0-py3-none-any.whl", hash = "sha256:35811adf67c680c272bcb71fa9d6c3613cc2d1bb79f5bfc7d83c4412a79537cb"},
|
||||
{file = "nonestorage-0.1.0.tar.gz", hash = "sha256:818232236455c79cabbb69e716f73aa1b9c21d579f1c1fcbdba273b60bac72d9"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "25.0"
|
||||
@@ -1091,68 +1102,68 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pillow"
|
||||
version = "11.2.1"
|
||||
version = "11.3.0"
|
||||
summary = ""
|
||||
files = [
|
||||
{file = "pillow-11.2.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:d57a75d53922fc20c165016a20d9c44f73305e67c351bbc60d1adaf662e74047"},
|
||||
{file = "pillow-11.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:127bf6ac4a5b58b3d32fc8289656f77f80567d65660bc46f72c0d77e6600cc95"},
|
||||
{file = "pillow-11.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4ba4be812c7a40280629e55ae0b14a0aafa150dd6451297562e1764808bbe61"},
|
||||
{file = "pillow-11.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8bd62331e5032bc396a93609982a9ab6b411c05078a52f5fe3cc59234a3abd1"},
|
||||
{file = "pillow-11.2.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:562d11134c97a62fe3af29581f083033179f7ff435f78392565a1ad2d1c2c45c"},
|
||||
{file = "pillow-11.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:c97209e85b5be259994eb5b69ff50c5d20cca0f458ef9abd835e262d9d88b39d"},
|
||||
{file = "pillow-11.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0c3e6d0f59171dfa2e25d7116217543310908dfa2770aa64b8f87605f8cacc97"},
|
||||
{file = "pillow-11.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc1c3bc53befb6096b84165956e886b1729634a799e9d6329a0c512ab651e579"},
|
||||
{file = "pillow-11.2.1-cp310-cp310-win32.whl", hash = "sha256:312c77b7f07ab2139924d2639860e084ec2a13e72af54d4f08ac843a5fc9c79d"},
|
||||
{file = "pillow-11.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9bc7ae48b8057a611e5fe9f853baa88093b9a76303937449397899385da06fad"},
|
||||
{file = "pillow-11.2.1-cp310-cp310-win_arm64.whl", hash = "sha256:2728567e249cdd939f6cc3d1f049595c66e4187f3c34078cbc0a7d21c47482d2"},
|
||||
{file = "pillow-11.2.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35ca289f712ccfc699508c4658a1d14652e8033e9b69839edf83cbdd0ba39e70"},
|
||||
{file = "pillow-11.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0409af9f829f87a2dfb7e259f78f317a5351f2045158be321fd135973fff7bf"},
|
||||
{file = "pillow-11.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4e5c5edee874dce4f653dbe59db7c73a600119fbea8d31f53423586ee2aafd7"},
|
||||
{file = "pillow-11.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b93a07e76d13bff9444f1a029e0af2964e654bfc2e2c2d46bfd080df5ad5f3d8"},
|
||||
{file = "pillow-11.2.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:e6def7eed9e7fa90fde255afaf08060dc4b343bbe524a8f69bdd2a2f0018f600"},
|
||||
{file = "pillow-11.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8f4f3724c068be008c08257207210c138d5f3731af6c155a81c2b09a9eb3a788"},
|
||||
{file = "pillow-11.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a0a6709b47019dff32e678bc12c63008311b82b9327613f534e496dacaefb71e"},
|
||||
{file = "pillow-11.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f6b0c664ccb879109ee3ca702a9272d877f4fcd21e5eb63c26422fd6e415365e"},
|
||||
{file = "pillow-11.2.1-cp311-cp311-win32.whl", hash = "sha256:cc5d875d56e49f112b6def6813c4e3d3036d269c008bf8aef72cd08d20ca6df6"},
|
||||
{file = "pillow-11.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:0f5c7eda47bf8e3c8a283762cab94e496ba977a420868cb819159980b6709193"},
|
||||
{file = "pillow-11.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:4d375eb838755f2528ac8cbc926c3e31cc49ca4ad0cf79cff48b20e30634a4a7"},
|
||||
{file = "pillow-11.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:78afba22027b4accef10dbd5eed84425930ba41b3ea0a86fa8d20baaf19d807f"},
|
||||
{file = "pillow-11.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78092232a4ab376a35d68c4e6d5e00dfd73454bd12b230420025fbe178ee3b0b"},
|
||||
{file = "pillow-11.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25a5f306095c6780c52e6bbb6109624b95c5b18e40aab1c3041da3e9e0cd3e2d"},
|
||||
{file = "pillow-11.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c7b29dbd4281923a2bfe562acb734cee96bbb129e96e6972d315ed9f232bef4"},
|
||||
{file = "pillow-11.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:3e645b020f3209a0181a418bffe7b4a93171eef6c4ef6cc20980b30bebf17b7d"},
|
||||
{file = "pillow-11.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b2dbea1012ccb784a65349f57bbc93730b96e85b42e9bf7b01ef40443db720b4"},
|
||||
{file = "pillow-11.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:da3104c57bbd72948d75f6a9389e6727d2ab6333c3617f0a89d72d4940aa0443"},
|
||||
{file = "pillow-11.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:598174aef4589af795f66f9caab87ba4ff860ce08cd5bb447c6fc553ffee603c"},
|
||||
{file = "pillow-11.2.1-cp312-cp312-win32.whl", hash = "sha256:1d535df14716e7f8776b9e7fee118576d65572b4aad3ed639be9e4fa88a1cad3"},
|
||||
{file = "pillow-11.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:14e33b28bf17c7a38eede290f77db7c664e4eb01f7869e37fa98a5aa95978941"},
|
||||
{file = "pillow-11.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:21e1470ac9e5739ff880c211fc3af01e3ae505859392bf65458c224d0bf283eb"},
|
||||
{file = "pillow-11.2.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:7491cf8a79b8eb867d419648fff2f83cb0b3891c8b36da92cc7f1931d46108c8"},
|
||||
{file = "pillow-11.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b02d8f9cb83c52578a0b4beadba92e37d83a4ef11570a8688bbf43f4ca50909"},
|
||||
{file = "pillow-11.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:014ca0050c85003620526b0ac1ac53f56fc93af128f7546623cc8e31875ab928"},
|
||||
{file = "pillow-11.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3692b68c87096ac6308296d96354eddd25f98740c9d2ab54e1549d6c8aea9d79"},
|
||||
{file = "pillow-11.2.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:f781dcb0bc9929adc77bad571b8621ecb1e4cdef86e940fe2e5b5ee24fd33b35"},
|
||||
{file = "pillow-11.2.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:2b490402c96f907a166615e9a5afacf2519e28295f157ec3a2bb9bd57de638cb"},
|
||||
{file = "pillow-11.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dd6b20b93b3ccc9c1b597999209e4bc5cf2853f9ee66e3fc9a400a78733ffc9a"},
|
||||
{file = "pillow-11.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4b835d89c08a6c2ee7781b8dd0a30209a8012b5f09c0a665b65b0eb3560b6f36"},
|
||||
{file = "pillow-11.2.1-cp39-cp39-win32.whl", hash = "sha256:b10428b3416d4f9c61f94b494681280be7686bda15898a3a9e08eb66a6d92d67"},
|
||||
{file = "pillow-11.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:6ebce70c3f486acf7591a3d73431fa504a4e18a9b97ff27f5f47b7368e4b9dd1"},
|
||||
{file = "pillow-11.2.1-cp39-cp39-win_arm64.whl", hash = "sha256:c27476257b2fdcd7872d54cfd119b3a9ce4610fb85c8e32b70b42e3680a29a1e"},
|
||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9b7b0d4fd2635f54ad82785d56bc0d94f147096493a79985d0ab57aedd563156"},
|
||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:aa442755e31c64037aa7c1cb186e0b369f8416c567381852c63444dd666fb772"},
|
||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0d3348c95b766f54b76116d53d4cb171b52992a1027e7ca50c81b43b9d9e363"},
|
||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85d27ea4c889342f7e35f6d56e7e1cb345632ad592e8c51b693d7b7556043ce0"},
|
||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bf2c33d6791c598142f00c9c4c7d47f6476731c31081331664eb26d6ab583e01"},
|
||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e616e7154c37669fc1dfc14584f11e284e05d1c650e1c0f972f281c4ccc53193"},
|
||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39ad2e0f424394e3aebc40168845fee52df1394a4673a6ee512d840d14ab3013"},
|
||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:80f1df8dbe9572b4b7abdfa17eb5d78dd620b1d55d9e25f834efdbee872d3aed"},
|
||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ea926cfbc3957090becbcbbb65ad177161a2ff2ad578b5a6ec9bb1e1cd78753c"},
|
||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:738db0e0941ca0376804d4de6a782c005245264edaa253ffce24e5a15cbdc7bd"},
|
||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db98ab6565c69082ec9b0d4e40dd9f6181dab0dd236d26f7a50b8b9bfbd5076"},
|
||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:036e53f4170e270ddb8797d4c590e6dd14d28e15c7da375c18978045f7e6c37b"},
|
||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:14f73f7c291279bd65fda51ee87affd7c1e097709f7fdd0188957a16c264601f"},
|
||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:208653868d5c9ecc2b327f9b9ef34e0e42a4cdd172c2988fd81d62d2bc9bc044"},
|
||||
{file = "pillow-11.2.1.tar.gz", hash = "sha256:a64dd61998416367b7ef979b73d3a85853ba9bec4c2925f74e588879a58716b6"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f"},
|
||||
{file = "pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac"},
|
||||
{file = "pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d"},
|
||||
{file = "pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-win32.whl", hash = "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada"},
|
||||
{file = "pillow-11.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a"},
|
||||
{file = "pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7"},
|
||||
{file = "pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8"},
|
||||
{file = "pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1528,27 +1539,27 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.11.6"
|
||||
version = "0.12.2"
|
||||
summary = ""
|
||||
files = [
|
||||
{file = "ruff-0.11.6-py3-none-linux_armv6l.whl", hash = "sha256:d84dcbe74cf9356d1bdb4a78cf74fd47c740bf7bdeb7529068f69b08272239a1"},
|
||||
{file = "ruff-0.11.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9bc583628e1096148011a5d51ff3c836f51899e61112e03e5f2b1573a9b726de"},
|
||||
{file = "ruff-0.11.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f2959049faeb5ba5e3b378709e9d1bf0cab06528b306b9dd6ebd2a312127964a"},
|
||||
{file = "ruff-0.11.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63c5d4e30d9d0de7fedbfb3e9e20d134b73a30c1e74b596f40f0629d5c28a193"},
|
||||
{file = "ruff-0.11.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26a4b9a4e1439f7d0a091c6763a100cef8fbdc10d68593df6f3cfa5abdd9246e"},
|
||||
{file = "ruff-0.11.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b5edf270223dd622218256569636dc3e708c2cb989242262fe378609eccf1308"},
|
||||
{file = "ruff-0.11.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f55844e818206a9dd31ff27f91385afb538067e2dc0beb05f82c293ab84f7d55"},
|
||||
{file = "ruff-0.11.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d8f782286c5ff562e4e00344f954b9320026d8e3fae2ba9e6948443fafd9ffc"},
|
||||
{file = "ruff-0.11.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:01c63ba219514271cee955cd0adc26a4083df1956d57847978383b0e50ffd7d2"},
|
||||
{file = "ruff-0.11.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15adac20ef2ca296dd3d8e2bedc6202ea6de81c091a74661c3666e5c4c223ff6"},
|
||||
{file = "ruff-0.11.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4dd6b09e98144ad7aec026f5588e493c65057d1b387dd937d7787baa531d9bc2"},
|
||||
{file = "ruff-0.11.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:45b2e1d6c0eed89c248d024ea95074d0e09988d8e7b1dad8d3ab9a67017a5b03"},
|
||||
{file = "ruff-0.11.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bd40de4115b2ec4850302f1a1d8067f42e70b4990b68838ccb9ccd9f110c5e8b"},
|
||||
{file = "ruff-0.11.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:77cda2dfbac1ab73aef5e514c4cbfc4ec1fbef4b84a44c736cc26f61b3814cd9"},
|
||||
{file = "ruff-0.11.6-py3-none-win32.whl", hash = "sha256:5151a871554be3036cd6e51d0ec6eef56334d74dfe1702de717a995ee3d5b287"},
|
||||
{file = "ruff-0.11.6-py3-none-win_amd64.whl", hash = "sha256:cce85721d09c51f3b782c331b0abd07e9d7d5f775840379c640606d3159cae0e"},
|
||||
{file = "ruff-0.11.6-py3-none-win_arm64.whl", hash = "sha256:3567ba0d07fb170b1b48d944715e3294b77f5b7679e8ba258199a250383ccb79"},
|
||||
{file = "ruff-0.11.6.tar.gz", hash = "sha256:bec8bcc3ac228a45ccc811e45f7eb61b950dbf4cf31a67fa89352574b01c7d79"},
|
||||
{file = "ruff-0.12.2-py3-none-linux_armv6l.whl", hash = "sha256:093ea2b221df1d2b8e7ad92fc6ffdca40a2cb10d8564477a987b44fd4008a7be"},
|
||||
{file = "ruff-0.12.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:09e4cf27cc10f96b1708100fa851e0daf21767e9709e1649175355280e0d950e"},
|
||||
{file = "ruff-0.12.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ae64755b22f4ff85e9c52d1f82644abd0b6b6b6deedceb74bd71f35c24044cc"},
|
||||
{file = "ruff-0.12.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eb3a6b2db4d6e2c77e682f0b988d4d61aff06860158fdb413118ca133d57922"},
|
||||
{file = "ruff-0.12.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:73448de992d05517170fc37169cbca857dfeaeaa8c2b9be494d7bcb0d36c8f4b"},
|
||||
{file = "ruff-0.12.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b94317cbc2ae4a2771af641739f933934b03555e51515e6e021c64441532d"},
|
||||
{file = "ruff-0.12.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:45fc42c3bf1d30d2008023a0a9a0cfb06bf9835b147f11fe0679f21ae86d34b1"},
|
||||
{file = "ruff-0.12.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce48f675c394c37e958bf229fb5c1e843e20945a6d962cf3ea20b7a107dcd9f4"},
|
||||
{file = "ruff-0.12.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793d8859445ea47591272021a81391350205a4af65a9392401f418a95dfb75c9"},
|
||||
{file = "ruff-0.12.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6932323db80484dda89153da3d8e58164d01d6da86857c79f1961934354992da"},
|
||||
{file = "ruff-0.12.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6aa7e623a3a11538108f61e859ebf016c4f14a7e6e4eba1980190cacb57714ce"},
|
||||
{file = "ruff-0.12.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2a4a20aeed74671b2def096bdf2eac610c7d8ffcbf4fb0e627c06947a1d7078d"},
|
||||
{file = "ruff-0.12.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:71a4c550195612f486c9d1f2b045a600aeba851b298c667807ae933478fcef04"},
|
||||
{file = "ruff-0.12.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4987b8f4ceadf597c927beee65a5eaf994c6e2b631df963f86d8ad1bdea99342"},
|
||||
{file = "ruff-0.12.2-py3-none-win32.whl", hash = "sha256:369ffb69b70cd55b6c3fc453b9492d98aed98062db9fec828cdfd069555f5f1a"},
|
||||
{file = "ruff-0.12.2-py3-none-win_amd64.whl", hash = "sha256:dca8a3b6d6dc9810ed8f328d406516bf4d660c00caeaef36eb831cf4871b0639"},
|
||||
{file = "ruff-0.12.2-py3-none-win_arm64.whl", hash = "sha256:48d6c6bfb4761df68bc05ae630e24f506755e702d4fb08f08460be778c7ccb12"},
|
||||
{file = "ruff-0.12.2.tar.gz", hash = "sha256:d7b4f55cd6f325cb7621244f19c873c565a08aff5a4ba9c69aa7355f3f7afd3e"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1566,11 +1577,11 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "78.1.1"
|
||||
version = "80.9.0"
|
||||
summary = ""
|
||||
files = [
|
||||
{file = "setuptools-78.1.1-py3-none-any.whl", hash = "sha256:c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561"},
|
||||
{file = "setuptools-78.1.1.tar.gz", hash = "sha256:fcc17fd9cd898242f6b4adfaca46137a9edef687f43e6f78469692a5e70d851d"},
|
||||
{file = "setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922"},
|
||||
{file = "setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1794,7 +1805,7 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "twine"
|
||||
version = "6.1.0"
|
||||
version = "6.2.0"
|
||||
summary = ""
|
||||
dependencies = [
|
||||
"id",
|
||||
@@ -1809,8 +1820,8 @@ dependencies = [
|
||||
"urllib3",
|
||||
]
|
||||
files = [
|
||||
{file = "twine-6.1.0-py3-none-any.whl", hash = "sha256:a47f973caf122930bf0fbbf17f80b83bc1602c9ce393c7845f289a3001dc5384"},
|
||||
{file = "twine-6.1.0.tar.gz", hash = "sha256:be324f6272eff91d07ee93f251edf232fc647935dd585ac003539b42404a8dbd"},
|
||||
{file = "twine-6.2.0-py3-none-any.whl", hash = "sha256:418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8"},
|
||||
{file = "twine-6.2.0.tar.gz", hash = "sha256:e5ed0d2fd70c9959770dce51c8f39c8945c574e18173a7b81802dab51b4b75cf"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1824,11 +1835,11 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.12.2"
|
||||
version = "4.14.1"
|
||||
summary = ""
|
||||
files = [
|
||||
{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.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76"},
|
||||
{file = "typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "nonebot-plugin-dialectlist"
|
||||
version = "2.7.0"
|
||||
version = "3.0.1"
|
||||
description = "看看你群群友有多能说"
|
||||
authors = [{ name = "Chen_Xu233", email = "woyerpa@outlook.com" }]
|
||||
dependencies = [
|
||||
@@ -12,7 +12,7 @@ dependencies = [
|
||||
"nonebot-plugin-userinfo>=0.2.6",
|
||||
"nonebot-plugin-htmlrender>=0.3.3",
|
||||
"nonebot2>=2.3.2",
|
||||
"pillow>=10.4.0",
|
||||
"pillow>=11.3.0",
|
||||
"nonebot-plugin-uninfo>=0.1.1",
|
||||
]
|
||||
requires-python = ">=3.9,<4.0"
|
||||
@@ -23,9 +23,9 @@ license = { text = "MIT" }
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"ruff>=0.5.5",
|
||||
"setuptools>=71.1.0",
|
||||
"twine>=5.1.0",
|
||||
"nb-cli>=0.7.6",
|
||||
"setuptools>=80.9.0",
|
||||
"twine>=6.2.0",
|
||||
"nb-cli>=1.4.2",
|
||||
"py-spy>=0.3.14",
|
||||
]
|
||||
Test = ["nonebot-adapter-onebot>=2.4.4"]
|
||||
|
||||
Reference in New Issue
Block a user