diff --git a/konabot/plugins/kona_ph/__init__.py b/konabot/plugins/kona_ph/__init__.py index ca9da4d..f60da5a 100644 --- a/konabot/plugins/kona_ph/__init__.py +++ b/konabot/plugins/kona_ph/__init__.py @@ -10,7 +10,9 @@ from nonebot_plugin_alconna import (Alconna, Args, UniMessage, UniMsg, on_alconna) from nonebot_plugin_apscheduler import scheduler +from konabot.common import username from konabot.common.longtask import DepLongTaskTarget +from konabot.common.pager import PagerQuery from konabot.plugins.kona_ph.core.message import (get_daily_report, get_daily_report_v2, get_puzzle_description, @@ -76,7 +78,7 @@ async def _(target: DepLongTaskTarget): cmd_history = on_alconna(Alconna( - "历史题目", + "re:历史(题目|谜题)", Args["page?", int], Args["index_id?", str], ), rule=to_me()) @@ -118,6 +120,24 @@ async def _(target: DepLongTaskTarget, index_id: str = "", page: int = 1): await target.send_message(msg) +cmd_leadboard = on_alconna(Alconna( + "re:此方(解谜|谜题)排行榜", + Args["page?", int], +)) + +@cmd_leadboard.handle() +async def _(target: DepLongTaskTarget, page: int = 1): + async with puzzle_manager() as manager: + result = manager.get_leadboard(PagerQuery(page, 10)) + await target.send_message(result.to_unimessage( + title="此方解谜排行榜", + formatter=lambda data: ( + f"✨ {data[1]} 已完成 | " + f"{username.get_username(data[0])}" + ) + )) + + @scheduler.scheduled_job("cron", hour="8") async def _(): async with puzzle_manager() as manager: diff --git a/konabot/plugins/kona_ph/core/message.py b/konabot/plugins/kona_ph/core/message.py index 5267579..d919703 100644 --- a/konabot/plugins/kona_ph/core/message.py +++ b/konabot/plugins/kona_ph/core/message.py @@ -33,7 +33,7 @@ def get_puzzle_description(puzzle: Puzzle, with_answer: bool = False) -> UniMess ) result = result.text(f"\n\n出题者:{get_username(puzzle.author_id)}") - + if with_answer: result = result.text(f"\n\n题目答案:{puzzle.flag}") else: diff --git a/konabot/plugins/kona_ph/core/storage.py b/konabot/plugins/kona_ph/core/storage.py index 0c6cac3..8d2dc6e 100644 --- a/konabot/plugins/kona_ph/core/storage.py +++ b/konabot/plugins/kona_ph/core/storage.py @@ -1,5 +1,6 @@ import asyncio import datetime +import functools import random import re from contextlib import asynccontextmanager @@ -7,6 +8,7 @@ from contextlib import asynccontextmanager import nanoid from pydantic import BaseModel, Field, ValidationError +from konabot.common.pager import PagerQuery from konabot.plugins.kona_ph.core.path import KONAPH_DATA_JSON @@ -112,6 +114,10 @@ class PuzzleManager(BaseModel): index_id_counter: int = 1 submissions: dict[str, dict[str, list[PuzzleSubmission]]] = {} + """ + 类型:{ [raw_id: str]: { [user_id: str]: PuzzleSubmission[] } } + """ + last_checked_date: datetime.date = Field( default_factory=lambda: get_today_date() - datetime.timedelta(days=1) ) @@ -235,6 +241,20 @@ class PuzzleManager(BaseModel): if p.author_id == user ], key=lambda p: p.created_at, reverse=True) + def get_leadboard(self, pager: PagerQuery): + return pager.apply(sorted([ + (user, sum(( + len([ + s for s in sl.get(user, []) + if s.success + ]) for sl in self.submissions.values() + ))) + for user in functools.reduce( + lambda x, y: x | y, + (set(sl.keys()) for sl in self.submissions.values()), + ) + ], key=lambda t: t[1], reverse=True)) + lock = asyncio.Lock() diff --git a/konabot/plugins/kona_ph/manager.py b/konabot/plugins/kona_ph/manager.py index f6a14b3..4eada29 100644 --- a/konabot/plugins/kona_ph/manager.py +++ b/konabot/plugins/kona_ph/manager.py @@ -10,7 +10,6 @@ from pydantic import BaseModel from konabot.common.longtask import DepLongTaskTarget from konabot.common.nb.exc import BotExceptionMessage from konabot.common.nb.extract_image import download_image_bytes -from konabot.common.nb.qq_broadcast import qq_broadcast from konabot.common.username import get_username from konabot.plugins.kona_ph.core.image import get_image_manager from konabot.plugins.kona_ph.core.message import (get_puzzle_description, get_puzzle_hint_list, @@ -19,6 +18,7 @@ from konabot.plugins.kona_ph.core.message import (get_puzzle_description, get_pu from konabot.plugins.kona_ph.core.storage import (Puzzle, PuzzleHint, PuzzleManager, get_today_date, puzzle_manager) +from konabot.plugins.poster.service import broadcast PUZZLE_PAGE_SIZE = 10 @@ -344,7 +344,7 @@ def create_admin_commands(): p = manager.get_today_puzzle(strong=True) if p is None: return await target.send_message("上架失败了orz,可能是没题了") - await qq_broadcast(config.plugin_puzzle_playgroup, get_puzzle_description(p)) + await broadcast("每日谜题", get_puzzle_description(p)) return await target.send_message("Ok!") @cmd_admin.assign("preview")