🔀 Merge pull request #43 from ChenXu233/feat#20#39

Feat#20#39
This commit is contained in:
XuChenXu 2024-11-09 11:25:20 +08:00 committed by GitHub
commit fcce94250c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 88 additions and 126 deletions

View File

@ -96,9 +96,17 @@ __注意__
### 🚀进阶用法 ### 🚀进阶用法
`/{时间类型(今日|年度)?}{B话榜|废话榜} {时间类型?} {ISO8601 格式时间} {群号}` `/{时间类型(今日|年度)?}{B话榜|废话榜} {时间类型?} {ISO8601 格式时间 ?} {群号} {关键词}`
如:`/B话榜 历史 2024-01-01~2024-01-02 12345678` 如:`/B话榜 历史 2024-01-01~2024-01-02 12345678 女装`
也可以 `/{时间类型(今日|年度)?}{B话榜|废话榜} {时间类型?} {ISO8601 格式时间 ?} -g {群号} -k {关键词}`
以下调用方法均合法:
`/今日B话榜 -g 12345678 -k 女装`
`/昨日B话榜 -k 女装`
`/本周B话榜 -g 12345678`
## 💪 目前支持的平台 ## 💪 目前支持的平台
@ -158,13 +166,18 @@ __注意__
- [x] 私聊的查询(超级用户可以任意查询群聊的信息)一半完成 - [x] 私聊的查询(超级用户可以任意查询群聊的信息)一半完成
- [ ] 特殊的储存方案优化消息统计 - [x] 特殊的储存方案优化消息统计
- [ ] 查询带某关键词的消息量 - [x] 查询带某关键词的消息量
- [ ] 合并转发
待补充。..... 待补充。.....
## 📖版本 ## 📖版本日志
<details>
<summary>点我展开</summary>
### V1.0 ### V1.0
@ -199,5 +212,11 @@ __注意__
- 优化代码,添加一些新的可配置项。 - 优化代码,添加一些新的可配置项。
### V2.4
- 添加一些新的可配置项。
</details>
### 👾题外话 ### 👾题外话
~~整个项目快被我写成屎山了~~ ~~整个项目快被我写成屎山了~~

View File

@ -93,6 +93,7 @@ rank_cmd = on_alconna(
str, str,
], ],
Option("-g|--group_id", Args["group_id?", str]), Option("-g|--group_id", Args["group_id?", str]),
Option("-k|--keyword", Args["keyword?", str]),
behaviors=[SameTime()], behaviors=[SameTime()],
), ),
aliases={"废话榜"}, aliases={"废话榜"},
@ -129,6 +130,7 @@ async def _group_message(
type: Optional[str] = None, type: Optional[str] = None,
time: Optional[str] = None, time: Optional[str] = None,
group_id: Optional[str] = None, group_id: Optional[str] = None,
keyword: Optional[str] = None,
): ):
t1 = t.time() t1 = t.time()
state["t1"] = t1 state["t1"] = t1
@ -140,6 +142,8 @@ async def _group_message(
if group_id: if group_id:
state["group_id"] = group_id state["group_id"] = group_id
state["keyword"] = keyword
if not type: if not type:
await rank_cmd.finish(__plugin_meta__.usage) await rank_cmd.finish(__plugin_meta__.usage)
@ -226,7 +230,11 @@ async def handle_rank(
if not id: if not id:
await saa.Text("没有指定群哦").finish() await saa.Text("没有指定群哦").finish()
keyword = state["keyword"]
if plugin_config.counting_cache: if plugin_config.counting_cache:
if keyword:
await saa.Text("已开启缓存~缓存不支持关键词查询哦").finish()
t1 = t.time() t1 = t.time()
raw_rank = await get_cache(start, stop, id) raw_rank = await get_cache(start, stop, id)
logger.debug(f"获取计数消息花费时间:{t.time() - t1}") logger.debug(f"获取计数消息花费时间:{t.time() - t1}")
@ -242,11 +250,13 @@ async def handle_rank(
time_stop=stop, time_stop=stop,
exclude_id1s=plugin_config.excluded_people, exclude_id1s=plugin_config.excluded_people,
) )
raw_rank = msg_counter(messages) raw_rank = msg_counter(messages, keyword)
logger.debug(f"获取计数消息花费时间:{t.time() - t1}") logger.debug(f"获取计数消息花费时间:{t.time() - t1}")
if not raw_rank: if not raw_rank:
await saa.Text("明明这个时间段都没有人说话怎么会有话痨榜呢?").finish() await saa.Text(
"没有获取到排行榜数据哦,请确认时间范围和群号是否正确或者关键词是否存在~"
).finish()
rank = got_rank(raw_rank) rank = got_rank(raw_rank)
ids = await persist_id2user_id([int(i[0]) for i in rank]) ids = await persist_id2user_id([int(i[0]) for i in rank])
@ -259,8 +269,13 @@ async def handle_rank(
logger.debug(f"获取用户信息花费时间:{t.time() - t1}") logger.debug(f"获取用户信息花费时间:{t.time() - t1}")
string: str = "" string: str = ""
if plugin_config.show_text_rank: if plugin_config.show_text_rank:
if keyword:
string += f"关于{keyword}的话痨榜结果:\n"
else:
string += "话痨榜:\n"
for i in rank2: for i in rank2:
logger.debug(i.user_name) logger.debug(i.user_name)
for i in range(len(rank2)): for i in range(len(rank2)):

View File

@ -2,8 +2,42 @@ from inspect import cleandoc
__usage__ = cleandoc( __usage__ = cleandoc(
""" """
/今日B话榜 查看今天群里谁B话最多 快速调用
/昨日B话榜 顾名思义 /今日B话榜 看看今天群友发了多少消息
以此类推有本周本月上周上月年度排行榜
### 🎨一般用法
-`/B话榜` 看看有史以来机器人存在以来群友们发了多少消息 好像没写
-`/今日B话榜` 看看今天的群友发了多少消息
-`/昨日B话榜` 看看昨天的群友发了多少消息
-`/前日B话榜` 看看前天的群友发了多少消息
-`/本周B话榜` 看看本周的群友发了多少消息
-`/上周B话榜` 看看上周的群友发了多少消息
-`/本月B话榜` 看看这个月的群友发了多少消息
-`/年度B话榜` 看看今年的群友发了多少消息
-`/历史B话榜` 看看历史上机器人存在以来的群友发了多少消息
### 🚀进阶用法
`/{时间类型今日|年度?}{B话榜|废话榜} {时间类型} {ISO8601 格式时间 ?} {群号} {关键词}`
`/B话榜 历史 2024-01-01~2024-01-02 12345678 女装`
也可以 `/{时间类型今日|年度?}{B话榜|废话榜} {时间类型} {ISO8601 格式时间 ?} -g {群号} -k {关键词}`
以下调用方法均合法
`/今日B话榜 -g 12345678 -k 女装`
`/昨日B话榜 -k 女装`
`/本周B话榜 -g 12345678`
""" """
) )

View File

@ -3,7 +3,7 @@ import httpx
import asyncio import asyncio
import unicodedata import unicodedata
from typing import Dict, List from typing import Dict, List, Optional
from sqlalchemy import or_, select from sqlalchemy import or_, select
from sqlalchemy.sql import ColumnElement from sqlalchemy.sql import ColumnElement
@ -77,7 +77,9 @@ async def persist_id2group_id(ids: List[str]) -> List[str]:
return [i.id2 for i in records] return [i.id2 for i in records]
def msg_counter(msg_list: List[MessageRecord]) -> Dict[str, int]: def msg_counter(
msg_list: List[MessageRecord], keyword: Optional[str]
) -> Dict[str, int]:
"""### 计算每个人的消息量 """### 计算每个人的消息量
Args: Args:
@ -92,6 +94,10 @@ def msg_counter(msg_list: List[MessageRecord]) -> Dict[str, int]:
logger.info("wow , there are {} msgs to count !!!".format(msg_len)) logger.info("wow , there are {} msgs to count !!!".format(msg_len))
for i in msg_list: for i in msg_list:
logger.debug(f"processing msg {i.plain_text}")
if keyword:
if keyword not in i.plain_text:
continue
try: try:
lst[str(i.session_persist_id)] += 1 lst[str(i.session_persist_id)] += 1
except KeyError: except KeyError:

View File

@ -1,112 +0,0 @@
import PIL
import abc
from typing import List, Tuple, Union, Iterable
from PIL import Image, ImageDraw, ImageFont
class BaseElement(abc.ABC):
def __init__(self, box:Union[Iterable[int],Iterable[float]] = (0, 0, 0, 0)):
self.box = [float(i) for i in box]
self.ux = None
self.ly = None
self.dx = None
self.ry = None
self.hight = None
self.width = None
self.image = None
self.position = (self.ux, self.ly)
self.size = (self.width, self.hight)
@abc.abstractmethod
def render(self):
raise NotImplementedError
def get_box(self):
return self.box
def set_box(self, box:Tuple[float, float, float, float]):
self.box = box
def get_size(self):
self.size = (self.width, self.hight)
return self.size
def get_position(self):
self.position = (self.ux, self.ly)
return self.position
class Board(BaseElement):
def __init__(self, width, hight):
self.width = width
self.hight = hight
self.image = Image.new('RGBA', (self.width, self.hight), (255, 255, 255, 0))
self.elements = []
def render(self):
for i in self.elements:
i.ux = self.width * i.box[0]
i.ly = self.hight * i.box[1]
i.dx = self.width * i.box[2]
i.ry = self.hight * i.box[3]
i.hight = i.dx - i.ux
i.width = i.ry - i.ly
i.position = (i.ux, i.ly)
image = i.render()
self.image.paste(image, i.get_position())
def add_element(self, element:BaseElement):
self.elements.append(element)
class Container(BaseElement):
def __init__(self, box:Union[Iterable[int],Iterable[float]] = (0, 0, 0, 0)):
super().__init__(box)
self.elements:List[BaseElement] = []
def render(self,size:Tuple[int, int] = (100, 100)):
if not self.width and self.hight:
self.width = size[0]
self.hight = size[1]
if not self.image:
self.image = Image.new('RGBA', (self.width, self.hight), (255, 255, 255, 0))
for i in self.elements:
image = i.render()
self.image.paste(image, i.get_position())
class Element(BaseElement):
# class BaseContainer(abc.ABC):
# def __init__(self, width:int, height:int):
# self.width = width
# self.height = height
# self.image = Image.new('RGBA', (self.width, self.height), (255, 255, 255, 0))
# @abc.abstractmethod
# def render(self):
# raise NotImplementedError
# def set_image(self,image):
# self.image = image
# class Elements():
# def __init__(self, width:int, height:int):
# self.width = width
# self.height = height
# self.image = Image.new('RGBA', (self.width, self.height), (255, 255, 255, 0))
# def render(self):
# return self.image
# class Container(BaseContainer):
# def __init__(self, width:int, height:int,elements:List[Union['Container',Elements]] = []):
# super().__init__(width, height)
# self.elements = elements
# def render(self):
# for i in self.elements:
# image = i.render()
# self.image.paste(image, i.position)
# return self.image