nonebot-plugin-group-historian 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nonebot_plugin_group_historian-0.1.0/PKG-INFO +13 -0
- nonebot_plugin_group_historian-0.1.0/nonebot_plugin_group_historian/__init__.py +168 -0
- nonebot_plugin_group_historian-0.1.0/nonebot_plugin_group_historian/config.py +14 -0
- nonebot_plugin_group_historian-0.1.0/nonebot_plugin_group_historian/data.py +113 -0
- nonebot_plugin_group_historian-0.1.0/nonebot_plugin_group_historian/image.py +140 -0
- nonebot_plugin_group_historian-0.1.0/nonebot_plugin_group_historian.egg-info/PKG-INFO +13 -0
- nonebot_plugin_group_historian-0.1.0/nonebot_plugin_group_historian.egg-info/SOURCES.txt +10 -0
- nonebot_plugin_group_historian-0.1.0/nonebot_plugin_group_historian.egg-info/dependency_links.txt +1 -0
- nonebot_plugin_group_historian-0.1.0/nonebot_plugin_group_historian.egg-info/requires.txt +7 -0
- nonebot_plugin_group_historian-0.1.0/nonebot_plugin_group_historian.egg-info/top_level.txt +1 -0
- nonebot_plugin_group_historian-0.1.0/pyproject.toml +22 -0
- nonebot_plugin_group_historian-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nonebot-plugin-group-historian
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 统计每日群聊发言字数 生成话痨榜图片的NoneBot2插件
|
|
5
|
+
Author-email: Wojusensei <3442006415@qq.com>
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: nonebot2>=2.3.0
|
|
8
|
+
Requires-Dist: nonebot-adapter-onebot>=2.0.0
|
|
9
|
+
Requires-Dist: nonebot-plugin-orm[default]>=0.7.0
|
|
10
|
+
Requires-Dist: nonebot-plugin-apscheduler>=0.5.0
|
|
11
|
+
Requires-Dist: nonebot-plugin-localstore>=0.5.0
|
|
12
|
+
Requires-Dist: Pillow>=10.0.0
|
|
13
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from datetime import datetime, timedelta
|
|
3
|
+
from nonebot import on_command, on_message, on_notice, require, get_plugin_config, get_driver
|
|
4
|
+
from nonebot.adapters.onebot.v11 import (
|
|
5
|
+
Bot,
|
|
6
|
+
GroupMessageEvent,
|
|
7
|
+
GroupRecallNoticeEvent,
|
|
8
|
+
MessageSegment,
|
|
9
|
+
)
|
|
10
|
+
from nonebot.plugin import PluginMetadata
|
|
11
|
+
from nonebot.log import logger
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# ————————————————————————————
|
|
15
|
+
# 依赖声明
|
|
16
|
+
# ————————————————————————————
|
|
17
|
+
|
|
18
|
+
require("nonebot_plugin_orm")
|
|
19
|
+
require("nonebot_plugin_apscheduler")
|
|
20
|
+
require("nonebot_plugin_localstore")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# ————————————————————————————
|
|
24
|
+
# 元数据 插件身份证
|
|
25
|
+
# ————————————————————————————
|
|
26
|
+
|
|
27
|
+
__plugin_meta__ = PluginMetadata(
|
|
28
|
+
name="群聊史官",
|
|
29
|
+
description="统计每日群聊发言字数 生成话痨榜图片",
|
|
30
|
+
usage="在群里发送 话痨榜 查看昨日排行\n发送 今日话痨榜 查看今日实时排行\n可加页码 例如 话痨榜 2",
|
|
31
|
+
type="application",
|
|
32
|
+
homepage="https://github.com/Wojusensei/nonebot-plugin-group-historian",
|
|
33
|
+
config=None,
|
|
34
|
+
supported_adapters={"~onebot.v11"},
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# ————————————————————————————
|
|
39
|
+
# 导入插件内部模块 放在元数据之后
|
|
40
|
+
# ————————————————————————————
|
|
41
|
+
|
|
42
|
+
from .config import Config
|
|
43
|
+
from .data import add_message, delete_last_message, get_daily_ranking, clean_old_data
|
|
44
|
+
from .image import create_ranking_image
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# ————————————————————————————
|
|
48
|
+
# 加载配置 使用 get_plugin_config
|
|
49
|
+
# ————————————————————————————
|
|
50
|
+
|
|
51
|
+
config = get_plugin_config(Config)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# ————————————————————————————
|
|
55
|
+
# 消息缓存 用于撤回时扣除字数
|
|
56
|
+
# key 是消息ID value 是 (群号, QQ号, 字数)
|
|
57
|
+
# ————————————————————————————
|
|
58
|
+
|
|
59
|
+
message_cache = {}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# ————————————————————————————
|
|
63
|
+
# 监听群消息 记录字数
|
|
64
|
+
# ————————————————————————————
|
|
65
|
+
|
|
66
|
+
msg_handler = on_message(block=False)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@msg_handler.handle()
|
|
70
|
+
async def handle_message(event: GroupMessageEvent):
|
|
71
|
+
text = event.get_plaintext()
|
|
72
|
+
|
|
73
|
+
# 过滤纯图片表情等无文字消息
|
|
74
|
+
if not text or not text.strip():
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
length = len(text.replace(" ", ""))
|
|
78
|
+
group_id = str(event.group_id)
|
|
79
|
+
user_id = str(event.user_id)
|
|
80
|
+
nickname = event.sender.card or event.sender.nickname or user_id
|
|
81
|
+
|
|
82
|
+
await add_message(group_id, user_id, nickname, length)
|
|
83
|
+
|
|
84
|
+
# 存入缓存 供撤回时扣除
|
|
85
|
+
message_cache[str(event.message_id)] = (group_id, user_id, length)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# ————————————————————————————
|
|
89
|
+
# 监听群撤回 扣除字数
|
|
90
|
+
# ————————————————————————————
|
|
91
|
+
|
|
92
|
+
recall_handler = on_notice(block=False)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@recall_handler.handle()
|
|
96
|
+
async def handle_recall(event: GroupRecallNoticeEvent):
|
|
97
|
+
msg_id = str(event.message_id)
|
|
98
|
+
if msg_id in message_cache:
|
|
99
|
+
group_id, user_id, length = message_cache[msg_id]
|
|
100
|
+
await delete_last_message(group_id, user_id, length)
|
|
101
|
+
del message_cache[msg_id]
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# ————————————————————————————
|
|
105
|
+
# 话痨榜命令
|
|
106
|
+
# 默认查昨日 加今日查今天
|
|
107
|
+
# ————————————————————————————
|
|
108
|
+
|
|
109
|
+
rank_cmd = on_command("话痨榜", aliases={"今日话痨榜"}, block=True)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@rank_cmd.handle()
|
|
113
|
+
async def handle_rank(event: GroupMessageEvent, bot: Bot):
|
|
114
|
+
raw = event.get_plaintext().strip()
|
|
115
|
+
parts = raw.split()
|
|
116
|
+
|
|
117
|
+
# 判断查今天还是昨天
|
|
118
|
+
is_today = "今日" in raw
|
|
119
|
+
|
|
120
|
+
# 解析页码
|
|
121
|
+
page = 1
|
|
122
|
+
for p in parts:
|
|
123
|
+
if p.isdigit():
|
|
124
|
+
page = int(p)
|
|
125
|
+
if page < 1:
|
|
126
|
+
page = 1
|
|
127
|
+
break
|
|
128
|
+
|
|
129
|
+
# 确定日期
|
|
130
|
+
date = datetime.now().date() if is_today else (datetime.now().date() - timedelta(days=1))
|
|
131
|
+
|
|
132
|
+
# 获取排行榜
|
|
133
|
+
ranking = await get_daily_ranking(str(event.group_id), date)
|
|
134
|
+
|
|
135
|
+
if not ranking:
|
|
136
|
+
day_text = "今天" if is_today else "昨天"
|
|
137
|
+
await rank_cmd.finish(f"{day_text}还没有人说话呢", at_sender=True)
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
# 生成图片 放入线程池避免阻塞事件循环
|
|
141
|
+
rank_count = config.historian_rank_count
|
|
142
|
+
img_bytes = await asyncio.to_thread(
|
|
143
|
+
create_ranking_image,
|
|
144
|
+
ranking,
|
|
145
|
+
page=page,
|
|
146
|
+
rank_count=rank_count,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
await rank_cmd.send(MessageSegment.image(img_bytes))
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# ————————————————————————————
|
|
153
|
+
# 定时任务 每日凌晨清理旧数据
|
|
154
|
+
# ————————————————————————————
|
|
155
|
+
|
|
156
|
+
from nonebot_plugin_apscheduler import scheduler
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@scheduler.scheduled_job("cron", hour=0, minute=0, id="clean_old_historian_data")
|
|
160
|
+
async def scheduled_clean():
|
|
161
|
+
await clean_old_data(config.historian_data_retention_days)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
# ————————————————————————————
|
|
165
|
+
# 启动日志
|
|
166
|
+
# ————————————————————————————
|
|
167
|
+
|
|
168
|
+
logger.info("群聊史官 插件已加载")
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from pydantic import BaseModel, Field
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Config(BaseModel):
|
|
5
|
+
"""插件配置,用户可在 .env 文件中设置"""
|
|
6
|
+
|
|
7
|
+
historian_rank_count: int = Field(
|
|
8
|
+
default=10,
|
|
9
|
+
description="排行榜每页显示的人数"
|
|
10
|
+
)
|
|
11
|
+
historian_data_retention_days: int = Field(
|
|
12
|
+
default=30,
|
|
13
|
+
description="数据保留天数,超过自动清理"
|
|
14
|
+
)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
from datetime import datetime, timedelta
|
|
2
|
+
from sqlalchemy import Column, Integer, String, Date, func
|
|
3
|
+
from nonebot_plugin_orm import Model
|
|
4
|
+
from nonebot import require
|
|
5
|
+
|
|
6
|
+
require("nonebot_plugin_orm")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# ————————————————————————————
|
|
10
|
+
# 每日发言记录表
|
|
11
|
+
# ————————————————————————————
|
|
12
|
+
|
|
13
|
+
class DailyMessage(Model):
|
|
14
|
+
__tablename__ = "daily_messages"
|
|
15
|
+
|
|
16
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
17
|
+
group_id = Column(String, nullable=False)
|
|
18
|
+
user_id = Column(String, nullable=False)
|
|
19
|
+
nickname = Column(String)
|
|
20
|
+
message_length = Column(Integer, default=0)
|
|
21
|
+
timestamp = Column(Date, nullable=False)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# ————————————————————————————
|
|
25
|
+
# 记录
|
|
26
|
+
# ————————————————————————————
|
|
27
|
+
|
|
28
|
+
async def add_message(group_id: str, user_id: str, nickname: str, length: int):
|
|
29
|
+
from nonebot_plugin_orm import get_scoped_session
|
|
30
|
+
|
|
31
|
+
async with get_scoped_session() as session:
|
|
32
|
+
record = DailyMessage(
|
|
33
|
+
group_id=group_id,
|
|
34
|
+
user_id=user_id,
|
|
35
|
+
nickname=nickname,
|
|
36
|
+
message_length=length,
|
|
37
|
+
timestamp=datetime.now().date(),
|
|
38
|
+
)
|
|
39
|
+
session.add(record)
|
|
40
|
+
await session.commit()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# ————————————————————————————
|
|
44
|
+
# 撤回消息时扣除最近一条匹配的字数
|
|
45
|
+
# ————————————————————————————
|
|
46
|
+
|
|
47
|
+
async def delete_last_message(group_id: str, user_id: str, length: int):
|
|
48
|
+
from nonebot_plugin_orm import get_scoped_session
|
|
49
|
+
|
|
50
|
+
today = datetime.now().date()
|
|
51
|
+
async with get_scoped_session() as session:
|
|
52
|
+
record = await session.execute(
|
|
53
|
+
DailyMessage.__table__.select()
|
|
54
|
+
.where(
|
|
55
|
+
DailyMessage.group_id == group_id,
|
|
56
|
+
DailyMessage.user_id == user_id,
|
|
57
|
+
DailyMessage.message_length == length,
|
|
58
|
+
DailyMessage.timestamp == today,
|
|
59
|
+
)
|
|
60
|
+
.order_by(DailyMessage.id.desc())
|
|
61
|
+
.limit(1)
|
|
62
|
+
)
|
|
63
|
+
row = record.fetchone()
|
|
64
|
+
if row:
|
|
65
|
+
await session.execute(
|
|
66
|
+
DailyMessage.__table__.delete().where(DailyMessage.id == row.id)
|
|
67
|
+
)
|
|
68
|
+
await session.commit()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# ————————————————————————————
|
|
72
|
+
# 获取指定日期的字数排行榜
|
|
73
|
+
# 返回 [(user_id, nickname, total), ...]
|
|
74
|
+
# ————————————————————————————
|
|
75
|
+
|
|
76
|
+
async def get_daily_ranking(group_id: str, date=None) -> list:
|
|
77
|
+
from nonebot_plugin_orm import get_scoped_session
|
|
78
|
+
|
|
79
|
+
if date is None:
|
|
80
|
+
date = datetime.now().date()
|
|
81
|
+
|
|
82
|
+
async with get_scoped_session() as session:
|
|
83
|
+
result = await session.execute(
|
|
84
|
+
DailyMessage.__table__.select()
|
|
85
|
+
.with_only_columns(
|
|
86
|
+
DailyMessage.user_id,
|
|
87
|
+
func.max(DailyMessage.nickname).label("nickname"),
|
|
88
|
+
func.sum(DailyMessage.message_length).label("total"),
|
|
89
|
+
)
|
|
90
|
+
.where(
|
|
91
|
+
DailyMessage.group_id == group_id,
|
|
92
|
+
DailyMessage.timestamp == date,
|
|
93
|
+
)
|
|
94
|
+
.group_by(DailyMessage.user_id)
|
|
95
|
+
.order_by(func.sum(DailyMessage.message_length).desc())
|
|
96
|
+
)
|
|
97
|
+
rows = result.fetchall()
|
|
98
|
+
return [(row.user_id, row.nickname, row.total) for row in rows]
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# ————————————————————————————
|
|
102
|
+
# 删除超过保留天数的旧数据
|
|
103
|
+
# ————————————————————————————
|
|
104
|
+
|
|
105
|
+
async def clean_old_data(retention_days: int):
|
|
106
|
+
from nonebot_plugin_orm import get_scoped_session
|
|
107
|
+
|
|
108
|
+
cutoff = datetime.now().date() - timedelta(days=retention_days)
|
|
109
|
+
async with get_scoped_session() as session:
|
|
110
|
+
await session.execute(
|
|
111
|
+
DailyMessage.__table__.delete().where(DailyMessage.timestamp < cutoff)
|
|
112
|
+
)
|
|
113
|
+
await session.commit()
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import io
|
|
2
|
+
from PIL import Image, ImageDraw, ImageFont
|
|
3
|
+
from nonebot.log import logger
|
|
4
|
+
from nonebot_plugin_localstore import get_plugin_data_dir
|
|
5
|
+
from nonebot import require
|
|
6
|
+
|
|
7
|
+
require("nonebot_plugin_localstore")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# ————————————————————————————
|
|
11
|
+
# 资源路径
|
|
12
|
+
# 字体和背景图放在插件数据目录下
|
|
13
|
+
# ————————————————————————————
|
|
14
|
+
|
|
15
|
+
DATA_DIR = get_plugin_data_dir()
|
|
16
|
+
FONT_PATH = DATA_DIR / "font.ttf"
|
|
17
|
+
BG_PATH = DATA_DIR / "background.png"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# ————————————————————————————
|
|
21
|
+
# 荣誉图标
|
|
22
|
+
# ————————————————————————————
|
|
23
|
+
|
|
24
|
+
ICONS = {
|
|
25
|
+
1: "👑",
|
|
26
|
+
2: "💎",
|
|
27
|
+
3: "⭐",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# ————————————————————————————
|
|
32
|
+
# 生成排行榜图片
|
|
33
|
+
# ranking: [(user_id, nickname, total), ...]
|
|
34
|
+
# page: 页码1开始
|
|
35
|
+
# rank_count: 每页人数
|
|
36
|
+
# 返回图片的 bytes
|
|
37
|
+
# ————————————————————————————
|
|
38
|
+
|
|
39
|
+
def create_ranking_image(ranking, page=1, rank_count=10):
|
|
40
|
+
# ———————— 计算分页 ————————
|
|
41
|
+
start = (page - 1) * rank_count
|
|
42
|
+
end = start + rank_count
|
|
43
|
+
page_data = ranking[start:end]
|
|
44
|
+
|
|
45
|
+
# ———————— 画布尺寸 ————————
|
|
46
|
+
width = 800
|
|
47
|
+
header_height = 120
|
|
48
|
+
row_height = 90
|
|
49
|
+
footer_height = 80
|
|
50
|
+
height = header_height + row_height * rank_count + footer_height
|
|
51
|
+
|
|
52
|
+
# ———————— 背景图 ————————
|
|
53
|
+
if BG_PATH.exists():
|
|
54
|
+
bg = Image.open(BG_PATH).convert("RGBA")
|
|
55
|
+
bg = bg.resize((width, height), Image.LANCZOS)
|
|
56
|
+
# 蒙灰:降低饱和度并加半透明遮罩
|
|
57
|
+
bg = bg.convert("L").convert("RGBA")
|
|
58
|
+
overlay = Image.new("RGBA", (width, height), (0, 0, 0, 140))
|
|
59
|
+
bg = Image.alpha_composite(bg, overlay)
|
|
60
|
+
else:
|
|
61
|
+
bg = Image.new("RGBA", (width, height), (30, 30, 50, 255))
|
|
62
|
+
|
|
63
|
+
# ———————— 字体 ————————
|
|
64
|
+
if FONT_PATH.exists():
|
|
65
|
+
font_title = ImageFont.truetype(str(FONT_PATH), 36)
|
|
66
|
+
font_name = ImageFont.truetype(str(FONT_PATH), 24)
|
|
67
|
+
font_small = ImageFont.truetype(str(FONT_PATH), 18)
|
|
68
|
+
else:
|
|
69
|
+
font_title = ImageFont.load_default()
|
|
70
|
+
font_name = ImageFont.load_default()
|
|
71
|
+
font_small = ImageFont.load_default()
|
|
72
|
+
|
|
73
|
+
# ———————— 创建画布 ————————
|
|
74
|
+
img = Image.new("RGBA", (width, height), (0, 0, 0, 0))
|
|
75
|
+
img.paste(bg, (0, 0))
|
|
76
|
+
draw = ImageDraw.Draw(img)
|
|
77
|
+
|
|
78
|
+
# ———————— 标题 ————————
|
|
79
|
+
title = f"话痨榜 第{page}页"
|
|
80
|
+
draw.text(
|
|
81
|
+
(width // 2, 40),
|
|
82
|
+
title,
|
|
83
|
+
fill=(255, 215, 0),
|
|
84
|
+
font=font_title,
|
|
85
|
+
anchor="ma",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# ———————— 分割线 ————————
|
|
89
|
+
draw.line(
|
|
90
|
+
(40, header_height - 10, width - 40, header_height - 10),
|
|
91
|
+
fill=(255, 215, 0, 200),
|
|
92
|
+
width=2,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
# ———————— 排行榜条目 ————————
|
|
96
|
+
for i, (user_id, nickname, total) in enumerate(page_data):
|
|
97
|
+
rank = start + i + 1
|
|
98
|
+
y = header_height + i * row_height
|
|
99
|
+
|
|
100
|
+
# 排名
|
|
101
|
+
icon = ICONS.get(rank, "")
|
|
102
|
+
rank_text = f"{icon} {rank}" if icon else str(rank)
|
|
103
|
+
draw.text((60, y + row_height // 2), rank_text, fill=(255, 255, 255), font=font_name, anchor="lm")
|
|
104
|
+
|
|
105
|
+
# 昵称
|
|
106
|
+
draw.text((140, y + 25), nickname, fill=(255, 255, 255), font=font_name)
|
|
107
|
+
|
|
108
|
+
# QQ号
|
|
109
|
+
draw.text((140, y + 55), user_id, fill=(180, 180, 180), font=font_small)
|
|
110
|
+
|
|
111
|
+
# 字数
|
|
112
|
+
count_text = f"{total} 字"
|
|
113
|
+
bbox = draw.textbbox((0, 0), count_text, font=font_name)
|
|
114
|
+
text_w = bbox[2] - bbox[0]
|
|
115
|
+
draw.text(
|
|
116
|
+
(width - 60 - text_w, y + row_height // 2),
|
|
117
|
+
count_text,
|
|
118
|
+
fill=(255, 215, 0),
|
|
119
|
+
font=font_name,
|
|
120
|
+
anchor="lm",
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# ———————— 页脚 ————————
|
|
124
|
+
draw.text(
|
|
125
|
+
(width // 2, height - 50),
|
|
126
|
+
"排行由群聊史官自动生成 | 记录昨日话痨数据",
|
|
127
|
+
fill=(150, 150, 150),
|
|
128
|
+
font=font_small,
|
|
129
|
+
anchor="ma",
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
# ———————— 输出 ————————
|
|
133
|
+
buf = io.BytesIO()
|
|
134
|
+
img.save(buf, format="PNG")
|
|
135
|
+
buf.seek(0)
|
|
136
|
+
return buf.read()
|
|
137
|
+
|
|
138
|
+
logger.info("群聊史官 图片生成模块已就绪")
|
|
139
|
+
|
|
140
|
+
#累死了
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nonebot-plugin-group-historian
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 统计每日群聊发言字数 生成话痨榜图片的NoneBot2插件
|
|
5
|
+
Author-email: Wojusensei <3442006415@qq.com>
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: nonebot2>=2.3.0
|
|
8
|
+
Requires-Dist: nonebot-adapter-onebot>=2.0.0
|
|
9
|
+
Requires-Dist: nonebot-plugin-orm[default]>=0.7.0
|
|
10
|
+
Requires-Dist: nonebot-plugin-apscheduler>=0.5.0
|
|
11
|
+
Requires-Dist: nonebot-plugin-localstore>=0.5.0
|
|
12
|
+
Requires-Dist: Pillow>=10.0.0
|
|
13
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
pyproject.toml
|
|
2
|
+
nonebot_plugin_group_historian/__init__.py
|
|
3
|
+
nonebot_plugin_group_historian/config.py
|
|
4
|
+
nonebot_plugin_group_historian/data.py
|
|
5
|
+
nonebot_plugin_group_historian/image.py
|
|
6
|
+
nonebot_plugin_group_historian.egg-info/PKG-INFO
|
|
7
|
+
nonebot_plugin_group_historian.egg-info/SOURCES.txt
|
|
8
|
+
nonebot_plugin_group_historian.egg-info/dependency_links.txt
|
|
9
|
+
nonebot_plugin_group_historian.egg-info/requires.txt
|
|
10
|
+
nonebot_plugin_group_historian.egg-info/top_level.txt
|
nonebot_plugin_group_historian-0.1.0/nonebot_plugin_group_historian.egg-info/dependency_links.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nonebot_plugin_group_historian
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "nonebot-plugin-group-historian"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "统计每日群聊发言字数 生成话痨榜图片的NoneBot2插件"
|
|
5
|
+
authors = [{name = "Wojusensei", email = "3442006415@qq.com"}]
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"nonebot2>=2.3.0",
|
|
9
|
+
"nonebot-adapter-onebot>=2.0.0",
|
|
10
|
+
"nonebot-plugin-orm[default]>=0.7.0",
|
|
11
|
+
"nonebot-plugin-apscheduler>=0.5.0",
|
|
12
|
+
"nonebot-plugin-localstore>=0.5.0",
|
|
13
|
+
"Pillow>=10.0.0",
|
|
14
|
+
"aiohttp>=3.9.0",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[tool.setuptools]
|
|
18
|
+
packages = ["nonebot_plugin_group_historian"]
|
|
19
|
+
|
|
20
|
+
[build-system]
|
|
21
|
+
requires = ["setuptools>=64.0", "wheel"]
|
|
22
|
+
build-backend = "setuptools.build_meta"
|