diff --git a/handler.py b/handler.py index 205047b2..324e351d 100644 --- a/handler.py +++ b/handler.py @@ -2,25 +2,14 @@ from typing import Optional from telegram.ext import CommandHandler, MessageHandler, filters, CallbackQueryHandler, InlineQueryHandler, Application -from plugins.admin import Admin -from plugins.artifact_rate import ArtifactRate +from logger import Log +from manager import PluginsManager from plugins.auth import Auth from plugins.base import NewChatMembersHandler -from plugins.cookies import Cookies -from plugins.daily_note import DailyNote from plugins.errorhandler import error_handler -from plugins.gacha import Gacha from plugins.help import Help from plugins.inline import Inline -from plugins.post import Post -from plugins.quiz import Quiz -from plugins.sign import Sign from plugins.start import start, ping, reply_keyboard_remove, unknown_command -from plugins.strategy import Strategy -from plugins.uid import Uid -from plugins.weapon import Weapon -from plugins.wiki import Wiki -from plugins.ledger import Ledger from service import BaseService @@ -43,51 +32,39 @@ def register_handlers(application: Application, service: BaseService): application.add_handler(CallbackQueryHandler(handler, pattern=query, block=block)) # 初始化 + + Log.info("正在加载插件管理器") + plugins_manager = PluginsManager() + + plugins_manager.refresh_list("./plugins/*") + + # 忽略内置模块 + plugins_manager.add_exclude(["help", "start", "base", "auth", "inline", "errorhandler"]) + + Log.info("加载插件管理器正在加载插件") + plugins_manager.import_module() + plugins_manager.add_handler(application, (service,)) + + Log.info("正在加载内置插件") + plugins_help = Help() inline = Inline(service) auth = Auth(service) - gacha = Gacha(service) - admin = Admin(service) - weapon = Weapon(service) - strategy = Strategy(service) - wiki = Wiki(service) add_handler(start, command="start") add_handler(plugins_help.command_start, command="help") add_handler(ping, command="ping") - add_handler(wiki.refresh_wiki, command="wiki_refresh") add_handler(auth.query, query=r"^auth_challenge\|") add_handler(auth.admin, query=r"^auth_admin\|") - add_handler(admin.add_admin, command="add_admin") - add_handler(admin.del_admin, command="del_admin") - add_handler(gacha.command_start, command="gacha", regex=r"^抽卡模拟器(.*)") - add_handler(weapon.command_start, command="weapon", regex=r"^武器查询(.*)") - add_handler(strategy.command_start, command="strategy", regex=r"^角色攻略查询(.*)") # 调试功能 add_handler(reply_keyboard_remove, command="reply_keyboard_remove") - add_handler(admin.leave_chat, command="leave_chat") - - cookies_handler = Cookies.create_conversation_handler(service) - uid_handler = Uid.create_conversation_handler(service) - daily_note_handler = DailyNote.create_conversation_handler(service) - sign_handler = Sign.create_conversation_handler(service) - quiz_handler = Quiz.create_conversation_handler(service) - post_handler = Post.create_conversation_handler(service) - artifact_rate_handler = ArtifactRate.create_conversation_handler(service) - ledger_handler = Ledger.create_conversation_handler(service) new_chat_members_handler = NewChatMembersHandler(service, auth.new_mem) application.add_handler(MessageHandler(filters.StatusUpdate.NEW_CHAT_MEMBERS, new_chat_members_handler.new_member, block=False)) - application.add_handler(sign_handler) - application.add_handler(quiz_handler) - application.add_handler(cookies_handler) - application.add_handler(uid_handler) - application.add_handler(daily_note_handler) - application.add_handler(post_handler) - application.add_handler(ledger_handler) - application.add_handler(artifact_rate_handler) application.add_handler(InlineQueryHandler(inline.inline_query, block=False)) application.add_handler(MessageHandler(filters.COMMAND & filters.ChatType.PRIVATE, unknown_command)) application.add_error_handler(error_handler, block=False) + + Log.info("插件加载成功") diff --git a/manager.py b/manager.py new file mode 100644 index 00000000..e5f3819e --- /dev/null +++ b/manager.py @@ -0,0 +1,78 @@ +import os +from glob import glob +from importlib import import_module +from os import path +from typing import Callable, List, Union + +from telegram.ext import Application + +from logger import Log + +PluginsClass: List[Callable] = [] + + +def listener_plugins_class(): + def decorator(func: Callable): + PluginsClass.append( + func + ) + return func + + return decorator + + +class PluginsManager: + def __init__(self): + self.plugin_list: List[str] = [] # 用于存储文件名称 + self.exclude_list: List[str] = [] + + def refresh_list(self, plugin_paths): + self.plugin_list.clear() + plugin_paths = glob(plugin_paths) + for plugin_path in plugin_paths: + if plugin_path.startswith('__'): + continue + module_name = path.basename(path.normpath(plugin_path)) + root, ext = os.path.splitext(module_name) + if ext == ".py": + self.plugin_list.append(root) + + def add_exclude(self, exclude: Union[str, List[str]]): + if type(exclude) == str: + self.exclude_list.append(exclude) + elif type(exclude) == list: + self.exclude_list.extend(exclude) + else: + raise TypeError + + def import_module(self): + for plugin_name in self.plugin_list: + if plugin_name not in self.exclude_list: + try: + import_module(f"plugins.{plugin_name}") + except ImportError as exc: + Log.warning(f"插件 {plugin_name} 导入失败", exc) + except ImportWarning as exc: + Log.warning(f"插件 {plugin_name} 加载成功但有警告", exc) + except BaseException as exc: + Log.warning(f"插件 {plugin_name} 加载失败", exc) + else: + Log.debug(f"插件 {plugin_name} 加载成功") + + @staticmethod + def add_handler(application: Application, args=None): + for pc in PluginsClass: + if callable(pc): + try: + ist = pc(*args) + handlers_list = ist.create_handlers(*args) + for handler in handlers_list: + application.add_handler(handler) + except AttributeError as exc: + if "create_handlers" in str(exc): + Log.error("创建 handlers 函数未找到", exc) + Log.error("初始化Class失败", exc) + except BaseException as exc: + Log.error("初始化Class失败", exc) + finally: + pass diff --git a/plugins/README.md b/plugins/README.md index e475d580..b7377ed5 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -14,15 +14,17 @@ from telegram import Update from telegram.ext import CallbackContext +from manager import listener_plugins_class from plugins.base import BasePlugins, restricts from plugins.errorhandler import conversation_error_handler +@listener_plugins_class() class Example(BasePlugins): @staticmethod - def create_conversation_handler(service: BaseService): + def create_handlers(service: BaseService): example = Example(service) - return CommandHandler('example', example.command_start) + return [CommandHandler('example', example.command_start)] @conversation_error_handler @restricts() @@ -35,7 +37,7 @@ class Example(BasePlugins): plugins 模块下的类需要继承 `BasePlugins` -plugins 模块下的类必须提供 `create_conversation_handler` 静态函数作为构建相应会话过程给 `handle.py` +plugins 模块下的类必须提供 `create_handlers` 静态函数作为构建相应处理程序给 `handle.py` 在函数注册为命令处理过程(如 `CommandHandler` )需要添加 `conversation_error_handler` 修饰器作为错误统一处理 @@ -43,5 +45,9 @@ plugins 模块下的类必须提供 `create_conversation_handler` 静态函数 入口函数必须使用 `@restricts()` 修饰器 防止洪水攻击 +我也不知道从那个版本开始 `plugins` 文件夹下的全部模块无需再次修改 `handler` 文件实现注册处理程序 + +只需在构建的类前加上 `@listener_plugins_class()` 修饰器即可 + **注意:`@restricts()` 修饰器带参,必须带括号,否则会出现调用错误** diff --git a/plugins/admin.py b/plugins/admin.py index 101af604..4f725d2b 100644 --- a/plugins/admin.py +++ b/plugins/admin.py @@ -2,10 +2,12 @@ from typing import Callable from telegram import Update from telegram.error import BadRequest, Forbidden -from telegram.ext import CallbackContext +from telegram.ext import CallbackContext, CommandHandler from logger import Log +from manager import listener_plugins_class from plugins.base import BasePlugins +from service import BaseService def bot_admins_only(func: Callable) -> Callable: # noqa @@ -20,11 +22,21 @@ def bot_admins_only(func: Callable) -> Callable: # noqa return decorator +@listener_plugins_class() class Admin(BasePlugins): """ 有关BOT ADMIN处理 """ + @staticmethod + def create_handlers(service: BaseService) -> list: + admin = Admin(service) + return [ + CommandHandler("add_admin", admin.add_admin, block=False), + CommandHandler("del_admin", admin.del_admin, block=False), + CommandHandler("leave_chat", admin.leave_chat, block=False), + ] + @bot_admins_only async def add_admin(self, update: Update, _: CallbackContext): message = update.message diff --git a/plugins/artifact_rate.py b/plugins/artifact_rate.py index 9dc9b052..ffb7b8a8 100644 --- a/plugins/artifact_rate.py +++ b/plugins/artifact_rate.py @@ -1,3 +1,5 @@ +from typing import List + from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup from telegram.constants import ChatAction, ParseMode from telegram.ext import CallbackContext, ConversationHandler, CommandHandler, CallbackQueryHandler, MessageHandler, \ @@ -5,12 +7,14 @@ from telegram.ext import CallbackContext, ConversationHandler, CommandHandler, C from telegram.helpers import escape_markdown from logger import Log +from manager import listener_plugins_class from model.apihelper.artifact import ArtifactOcrRate, get_comment, get_format_sub_item from plugins.base import BasePlugins, restricts from plugins.errorhandler import conversation_error_handler from service import BaseService +@listener_plugins_class() class ArtifactRate(BasePlugins): COMMAND_RESULT = 1 @@ -32,17 +36,19 @@ class ArtifactRate(BasePlugins): self.artifact_rate = ArtifactOcrRate() @staticmethod - def create_conversation_handler(service: BaseService): + def create_handlers(service: BaseService) -> list: artifact_rate = ArtifactRate(service) - return ConversationHandler( - entry_points=[CommandHandler('artifact_rate', artifact_rate.command_start), - MessageHandler(filters.Regex(r"^圣遗物评分(.*)"), artifact_rate.command_start), - MessageHandler(filters.CaptionRegex(r"^圣遗物评分(.*)"), artifact_rate.command_start)], - states={ - artifact_rate.COMMAND_RESULT: [CallbackQueryHandler(artifact_rate.command_result)] - }, - fallbacks=[CommandHandler('cancel', artifact_rate.cancel)] - ) + return [ + ConversationHandler( + entry_points=[CommandHandler('artifact_rate', artifact_rate.command_start), + MessageHandler(filters.Regex(r"^圣遗物评分(.*)"), artifact_rate.command_start), + MessageHandler(filters.CaptionRegex(r"^圣遗物评分(.*)"), artifact_rate.command_start)], + states={ + artifact_rate.COMMAND_RESULT: [CallbackQueryHandler(artifact_rate.command_result)] + }, + fallbacks=[CommandHandler('cancel', artifact_rate.cancel)] + ) + ] async def get_rate(self, artifact_attr: dict) -> str: rate_result_req = await self.artifact_rate.rate_artifact(artifact_attr) diff --git a/plugins/cookies.py b/plugins/cookies.py index 86cfd81e..ee01c75c 100644 --- a/plugins/cookies.py +++ b/plugins/cookies.py @@ -1,4 +1,6 @@ from http.cookies import SimpleCookie, CookieError +from typing import List +from urllib.request import BaseHandler import genshin import ujson @@ -8,6 +10,7 @@ from telegram.ext import CallbackContext, CommandHandler, MessageHandler, filter from telegram.helpers import escape_markdown from logger import Log +from manager import listener_plugins_class from model.base import ServiceEnum from plugins.base import BasePlugins, restricts from plugins.errorhandler import conversation_error_handler @@ -22,6 +25,7 @@ class CookiesCommandData: user_info: UserInfoData = UserInfoData() +@listener_plugins_class() class Cookies(BasePlugins): """ Cookie绑定 @@ -30,7 +34,7 @@ class Cookies(BasePlugins): CHECK_SERVER, CHECK_COOKIES, COMMAND_RESULT = range(10100, 10103) @staticmethod - def create_conversation_handler(service: BaseService): + def create_handlers(service: BaseService): cookies = Cookies(service) cookies_handler = ConversationHandler( entry_points=[CommandHandler('adduser', cookies.command_start, filters.ChatType.PRIVATE, block=True), @@ -46,7 +50,7 @@ class Cookies(BasePlugins): }, fallbacks=[CommandHandler('cancel', cookies.cancel, block=True)], ) - return cookies_handler + return [cookies_handler] @conversation_error_handler async def command_start(self, update: Update, context: CallbackContext) -> int: diff --git a/plugins/daily_note.py b/plugins/daily_note.py index 1496d2df..057522db 100644 --- a/plugins/daily_note.py +++ b/plugins/daily_note.py @@ -9,6 +9,7 @@ from telegram.ext import CallbackContext, CommandHandler, MessageHandler, Conver CallbackQueryHandler from logger import Log +from manager import listener_plugins_class from model.base import ServiceEnum from plugins.base import BasePlugins, restricts from plugins.errorhandler import conversation_error_handler @@ -20,6 +21,7 @@ class UidCommandData: user_info: UserInfoData = UserInfoData() +@listener_plugins_class() class DailyNote(BasePlugins): """ 每日便签 @@ -32,7 +34,7 @@ class DailyNote(BasePlugins): self.current_dir = os.getcwd() @staticmethod - def create_conversation_handler(service: BaseService): + def create_handlers(service: BaseService) -> list: daily_note = DailyNote(service) daily_note_handler = ConversationHandler( entry_points=[CommandHandler('dailynote', daily_note.command_start, block=True), @@ -42,7 +44,7 @@ class DailyNote(BasePlugins): }, fallbacks=[CommandHandler('cancel', daily_note.cancel, block=True)] ) - return daily_note_handler + return [daily_note_handler] async def _start_get_daily_note(self, user_info_data: UserInfoData, service: ServiceEnum) -> bytes: if service == ServiceEnum.HYPERION: diff --git a/plugins/gacha.py b/plugins/gacha.py index a72aee32..c98922df 100644 --- a/plugins/gacha.py +++ b/plugins/gacha.py @@ -3,20 +3,31 @@ import os from pyppeteer import launch from telegram import Update from telegram.constants import ChatAction -from telegram.ext import CallbackContext, ConversationHandler, filters +from telegram.ext import CallbackContext, ConversationHandler, filters, CommandHandler, MessageHandler from logger import Log +from manager import listener_plugins_class from plugins.base import BasePlugins, restricts from plugins.errorhandler import conversation_error_handler from service import BaseService from service.wish import WishCountInfo, get_one +@listener_plugins_class() class Gacha(BasePlugins): """ 抽卡模拟器(非首模拟器/减寿模拟器) """ + @staticmethod + def create_handlers(service: BaseService) -> list: + gacha = Gacha(service) + return [ + CommandHandler("gacha", gacha.command_start, block=False), + MessageHandler(filters.Regex("^抽卡模拟器(.*)"), gacha.command_start, block=False), + MessageHandler(filters.Regex("^非首模拟器(.*)"), gacha.command_start, block=False), + ] + def __init__(self, service: BaseService): super().__init__(service) self.browser: launch = None diff --git a/plugins/ledger.py b/plugins/ledger.py index 275d4063..447e4a32 100644 --- a/plugins/ledger.py +++ b/plugins/ledger.py @@ -11,6 +11,7 @@ from telegram.ext import CallbackContext, CommandHandler, MessageHandler, Conver CallbackQueryHandler from logger import Log +from manager import listener_plugins_class from model.base import ServiceEnum from plugins.base import BasePlugins, restricts from plugins.errorhandler import conversation_error_handler @@ -58,6 +59,7 @@ def process_ledger_month(context: CallbackContext) -> int: return now_time.month +@listener_plugins_class() class Ledger(BasePlugins): """ 旅行札记 @@ -70,16 +72,16 @@ class Ledger(BasePlugins): self.current_dir = os.getcwd() @staticmethod - def create_conversation_handler(service: BaseService): + def create_handlers(service: BaseService): ledger = Ledger(service) - return ConversationHandler( + return [ConversationHandler( entry_points=[CommandHandler("ledger", ledger.command_start, block=True), MessageHandler(filters.Regex(r"^旅行扎记(.*)"), ledger.command_start, block=True)], states={ ledger.COMMAND_RESULT: [CallbackQueryHandler(ledger.command_result, block=True)] }, fallbacks=[CommandHandler("cancel", ledger.cancel, block=True)] - ) + )] async def _start_get_ledger(self, user_info_data: UserInfoData, service: ServiceEnum, month=None) -> bytes: if service == ServiceEnum.HYPERION: diff --git a/plugins/post.py b/plugins/post.py index d21af14a..03bc6442 100644 --- a/plugins/post.py +++ b/plugins/post.py @@ -9,6 +9,7 @@ from telegram.helpers import escape_markdown from config import config from logger import Log +from manager import listener_plugins_class from model.apihelper import Hyperion, ArtworkImage from plugins.base import BasePlugins from plugins.errorhandler import conversation_error_handler @@ -25,6 +26,7 @@ class PostHandlerData: self.tags: Optional[List[str]] = [] +@listener_plugins_class() class Post(BasePlugins): """ 文章推送 @@ -40,7 +42,7 @@ class Post(BasePlugins): self.bbs = Hyperion() @staticmethod - def create_conversation_handler(service: BaseService): + def create_handlers(service: BaseService): _post = Post(service) post_handler = ConversationHandler( entry_points=[CommandHandler('post', _post.command_start, block=True)], @@ -57,7 +59,7 @@ class Post(BasePlugins): }, fallbacks=[CommandHandler('cancel', _post.cancel, block=True)] ) - return post_handler + return [post_handler] @conversation_error_handler async def command_start(self, update: Update, context: CallbackContext) -> int: diff --git a/plugins/quiz.py b/plugins/quiz.py index 0f2c97bf..6b6d9a5f 100644 --- a/plugins/quiz.py +++ b/plugins/quiz.py @@ -10,6 +10,7 @@ from telegram.ext import CallbackContext, ConversationHandler, CommandHandler, M from telegram.helpers import escape_markdown from logger import Log +from manager import listener_plugins_class from utils.random import MT19937_Random from plugins.base import BasePlugins, restricts from service import BaseService @@ -24,6 +25,7 @@ class QuizCommandData: status: int = 0 +@listener_plugins_class() class Quiz(BasePlugins): """ 派蒙的十万个为什么 @@ -42,7 +44,7 @@ class Quiz(BasePlugins): self.random = MT19937_Random() @staticmethod - def create_conversation_handler(service: BaseService): + def create_handlers(service: BaseService): quiz = Quiz(service) quiz_handler = ConversationHandler( entry_points=[CommandHandler('quiz', quiz.command_start, block=True)], @@ -63,7 +65,7 @@ class Quiz(BasePlugins): }, fallbacks=[CommandHandler('cancel', quiz.cancel, block=True)] ) - return quiz_handler + return [quiz_handler] async def send_poll(self, update: Update) -> Optional[Message]: chat = update.message.chat diff --git a/plugins/sign.py b/plugins/sign.py index 9ab06256..ab7d4fbe 100644 --- a/plugins/sign.py +++ b/plugins/sign.py @@ -9,6 +9,7 @@ from telegram.ext import CallbackContext, CommandHandler, MessageHandler, Conver CallbackQueryHandler from logger import Log +from manager import listener_plugins_class from model.base import ServiceEnum from plugins.base import BasePlugins, restricts from plugins.errorhandler import conversation_error_handler @@ -22,6 +23,7 @@ class SignCommandData: reply_to_message_id: int = 0 +@listener_plugins_class() class Sign(BasePlugins): """ 每日签到 @@ -30,7 +32,7 @@ class Sign(BasePlugins): CHECK_SERVER, COMMAND_RESULT = range(10400, 10402) @staticmethod - def create_conversation_handler(service: BaseService): + def create_handlers(service: BaseService): sign = Sign(service) sign_handler = ConversationHandler( entry_points=[CommandHandler('sign', sign.command_start, block=True), @@ -40,7 +42,7 @@ class Sign(BasePlugins): }, fallbacks=[CommandHandler('cancel', sign.cancel, block=True)] ) - return sign_handler + return [sign_handler] @staticmethod async def _start_sign(user_info: UserInfoData, service: ServiceEnum) -> str: diff --git a/plugins/strategy.py b/plugins/strategy.py index dddf0ec9..cd4e4fe1 100644 --- a/plugins/strategy.py +++ b/plugins/strategy.py @@ -1,14 +1,17 @@ from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup from telegram.constants import ChatAction, ParseMode -from telegram.ext import CallbackContext, filters, ConversationHandler +from telegram.ext import CallbackContext, filters, ConversationHandler, CommandHandler, MessageHandler from logger import Log +from manager import listener_plugins_class from metadata.shortname import roleToName from model.helpers import url_to_file from plugins.base import BasePlugins, restricts from plugins.errorhandler import conversation_error_handler +from service import BaseService +@listener_plugins_class() class Strategy(BasePlugins): """ 角色攻略查询 @@ -16,6 +19,14 @@ class Strategy(BasePlugins): KEYBOARD = [[InlineKeyboardButton(text="查看角色攻略列表并查询", switch_inline_query_current_chat="查看角色攻略列表并查询")]] + @staticmethod + def create_handlers(service: BaseService) -> list: + strategy = Strategy(service) + return [ + CommandHandler("strategy", strategy.command_start, block=False), + MessageHandler(filters.Regex("^角色攻略查询(.*)"), strategy.command_start, block=False), + ] + @conversation_error_handler @restricts(return_data=ConversationHandler.END) async def command_start(self, update: Update, context: CallbackContext) -> None: diff --git a/plugins/uid.py b/plugins/uid.py index 152fb1be..cfc445f7 100644 --- a/plugins/uid.py +++ b/plugins/uid.py @@ -9,6 +9,7 @@ from telegram.ext import CallbackContext, CommandHandler, MessageHandler, Conver CallbackQueryHandler from logger import Log +from manager import listener_plugins_class from model.base import ServiceEnum from model.helpers import url_to_file from plugins.base import BasePlugins, restricts @@ -21,6 +22,7 @@ class UidCommandData: user_info: UserInfoData = UserInfoData() +@listener_plugins_class() class Uid(BasePlugins): """ 玩家查询 @@ -33,7 +35,7 @@ class Uid(BasePlugins): self.current_dir = os.getcwd() @staticmethod - def create_conversation_handler(service: BaseService): + def create_handlers(service: BaseService): uid = Uid(service) uid_handler = ConversationHandler( entry_points=[CommandHandler('uid', uid.command_start, block=True), @@ -43,7 +45,7 @@ class Uid(BasePlugins): }, fallbacks=[CommandHandler('cancel', uid.cancel, block=True)] ) - return uid_handler + return [uid_handler] async def _start_get_user_info(self, user_info_data: UserInfoData, service: ServiceEnum, uid: int = -1) -> bytes: if service == ServiceEnum.HYPERION: diff --git a/plugins/weapon.py b/plugins/weapon.py index 1b730460..05389d79 100644 --- a/plugins/weapon.py +++ b/plugins/weapon.py @@ -1,14 +1,17 @@ from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup from telegram.constants import ChatAction -from telegram.ext import CallbackContext, filters +from telegram.ext import CallbackContext, filters, CommandHandler, MessageHandler from logger import Log +from manager import listener_plugins_class from metadata.shortname import weaponToName from model.helpers import url_to_file from plugins.base import BasePlugins, restricts from plugins.errorhandler import conversation_error_handler +from service import BaseService +@listener_plugins_class() class Weapon(BasePlugins): """ 武器查询 @@ -16,6 +19,14 @@ class Weapon(BasePlugins): KEYBOARD = [[InlineKeyboardButton(text="查看武器列表并查询", switch_inline_query_current_chat="查看武器列表并查询")]] + @staticmethod + def create_handlers(service: BaseService) -> list: + weapon = Weapon(service) + return [ + CommandHandler("weapon", weapon.command_start, block=False), + MessageHandler(filters.Regex("^武器查询(.*)"), weapon.command_start, block=False) + ] + @conversation_error_handler @restricts() async def command_start(self, update: Update, context: CallbackContext) -> None: diff --git a/plugins/wiki.py b/plugins/wiki.py index 9bdff512..6b2344ca 100644 --- a/plugins/wiki.py +++ b/plugins/wiki.py @@ -1,14 +1,25 @@ from telegram import Update -from telegram.ext import CallbackContext +from telegram.ext import CallbackContext, CommandHandler +from manager import listener_plugins_class from plugins.admin import bot_admins_only from plugins.base import BasePlugins +from service import BaseService +@listener_plugins_class() class Wiki(BasePlugins): """ 有关WIKI """ + + @staticmethod + def create_handlers(service: BaseService) -> list: + wiki = Wiki(service) + return [ + CommandHandler("refresh_wiki", wiki.refresh_wiki, block=False), + ] + @bot_admins_only async def refresh_wiki(self, update: Update, _: CallbackContext): message = update.message