重构插件传入 service 方式

* 重构插件传入 `service` 方式

重构插件传入 `service` 方式
将 `create_handlers`函数的修饰符改为 `classmethod`
This commit is contained in:
洛水.山岭居室 2022-07-07 09:36:34 +08:00 committed by GitHub
parent f21ebc51a1
commit 693cd774d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 202 additions and 179 deletions

View File

@ -7,7 +7,6 @@ from manager import PluginsManager
from plugins.auth import Auth
from plugins.base import NewChatMembersHandler
from plugins.errorhandler import error_handler
from plugins.help import Help
from plugins.inline import Inline
from plugins.start import start, ping, reply_keyboard_remove, unknown_command
from service import BaseService
@ -39,20 +38,18 @@ def register_handlers(application: Application, service: BaseService):
plugins_manager.refresh_list("./plugins/*")
# 忽略内置模块
plugins_manager.add_exclude(["help", "start", "base", "auth", "inline", "errorhandler"])
plugins_manager.add_exclude(["start", "base", "auth", "inline", "errorhandler"])
Log.info("加载插件管理器正在加载插件")
plugins_manager.import_module()
plugins_manager.add_handler(application, (service,))
plugins_manager.add_handler(application, service)
Log.info("正在加载内置插件")
plugins_help = Help()
inline = Inline(service)
auth = Auth(service)
add_handler(start, command="start")
add_handler(plugins_help.command_start, command="help")
add_handler(ping, command="ping")
add_handler(auth.query, query=r"^auth_challenge\|")
add_handler(auth.admin, query=r"^auth_admin\|")

View File

@ -2,20 +2,29 @@ import os
from glob import glob
from importlib import import_module
from os import path
from typing import List, Union
from typing import List, Union, Tuple, Callable
from telegram.ext import Application
from logger import Log
from plugins.base import BasePlugins
from service import BaseService
PluginsClass: List[BasePlugins] = []
PluginsClass: List[Tuple[any, dict]] = []
def listener_plugins_class():
def decorator(func: BasePlugins):
def listener_plugins_class(need_service: bool = False):
"""监听插件
:param need_service: 插件类中 create_handlers 函数是否传入 service
:return: None
"""
plugin_info = {
"need_service": need_service
}
def decorator(func: Callable):
PluginsClass.append(
func
(func, plugin_info)
)
return func
@ -61,12 +70,17 @@ class PluginsManager:
Log.debug(f"插件 {plugin_name} 加载成功")
@staticmethod
def add_handler(application: Application, args=None):
def add_handler(application: Application, service: BaseService):
for pc in PluginsClass:
if callable(pc):
func = pc[0]
plugin_info = pc[1]
# 构建 kwargs
kwargs = {}
if plugin_info.get("need_service", False):
kwargs["service"] = service
if callable(func):
try:
ist: BasePlugins = pc(*args)
handlers_list = ist.create_handlers(*args)
handlers_list = func.create_handlers(**kwargs)
for handler in handlers_list:
application.add_handler(handler)
except AttributeError as exc:

View File

@ -12,23 +12,23 @@
``` python
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
from utils.base import PaimonContext
@listener_plugins_class()
class Example(BasePlugins):
@staticmethod
def create_handlers(service: BaseService):
example = Example(service)
@classmethod
def create_handlers(cls):
example = cls()
return [CommandHandler('example', example.command_start)]
@conversation_error_handler
@restricts()
async def command_start(self, update: Update, context: CallbackContext) -> None:
async def command_start(self, update: Update, context: PaimonContext) -> None:
await message.reply_text("Example")
```
@ -51,3 +51,4 @@ plugins 模块下的类必须提供 `create_handlers` 静态函数作为构建
**注意:`@restricts()` 修饰器带参,必须带括号,否则会出现调用错误**
如果 `service` 需要全局共用,可以参考 `daily_note.py` 代码

View File

@ -13,14 +13,9 @@ from utils.base import PaimonContext
@listener_plugins_class()
class Abyss(BasePlugins):
def __init__(self, *args):
"""Abyss插件入口"""
pass
@staticmethod
def create_handlers(*args) -> list:
_ = args
abyss = Abyss()
@classmethod
def create_handlers(cls) -> list:
abyss = cls()
return [
CommandHandler("abyss", abyss.command_start, block=False),
MessageHandler(filters.Regex(r"^深渊数据查询(.*)"), abyss.command_start, block=True)

View File

@ -6,13 +6,13 @@ 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
from utils.base import PaimonContext
def bot_admins_only(func: Callable) -> Callable: # noqa
async def decorator(self, update: Update, context: CallbackContext):
admin_list = await self.service.admin.get_admin_list()
async def decorator(self, update: Update, context: PaimonContext):
service = context.service
admin_list = await service.admin.get_admin_list()
if update.message.from_user.id in admin_list:
return await func(self, update, context)
else:
@ -23,14 +23,13 @@ def bot_admins_only(func: Callable) -> Callable: # noqa
@listener_plugins_class()
class Admin(BasePlugins):
"""
有关BOT ADMIN处理
class Admin:
"""有关BOT ADMIN处理
"""
@staticmethod
def create_handlers(service: BaseService) -> list:
admin = Admin(service)
@classmethod
def create_handlers(cls) -> list:
admin = cls()
return [
CommandHandler("add_admin", admin.add_admin, block=False),
CommandHandler("del_admin", admin.del_admin, block=False),
@ -38,29 +37,31 @@ class Admin(BasePlugins):
]
@bot_admins_only
async def add_admin(self, update: Update, _: CallbackContext):
async def add_admin(self, update: Update, context: PaimonContext):
message = update.message
reply_to_message = message.reply_to_message
admin_list = await self.service.admin.get_admin_list()
service = context.service
admin_list = await service.admin.get_admin_list()
if reply_to_message is None:
await message.reply_text("请回复对应消息")
else:
if reply_to_message.from_user.id in admin_list:
await message.reply_text("该用户已经存在管理员列表")
else:
await self.service.admin.add_admin(reply_to_message.from_user.id)
await service.admin.add_admin(reply_to_message.from_user.id)
await message.reply_text("添加成功")
@bot_admins_only
async def del_admin(self, update: Update, _: CallbackContext):
async def del_admin(self, update: Update, context: PaimonContext):
message = update.message
reply_to_message = message.reply_to_message
admin_list = await self.service.admin.get_admin_list()
service = context.service
admin_list = await service.admin.get_admin_list()
if reply_to_message is None:
await message.reply_text("请回复对应消息")
else:
if reply_to_message.from_user.id in admin_list:
await self.service.admin.delete_admin(reply_to_message.from_user.id)
await service.admin.delete_admin(reply_to_message.from_user.id)
await message.reply_text("删除成功")
else:
await message.reply_text("该用户不存在管理员列表")

View File

@ -9,9 +9,8 @@ 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.base import restricts, BasePlugins
from plugins.errorhandler import conversation_error_handler
from service import BaseService
@listener_plugins_class()
@ -31,13 +30,12 @@ class ArtifactRate(BasePlugins):
f"{i * 5 + j}", callback_data=f"artifact_ocr_rate_data|level|{i * 5 + j}") for j in range(1, 6)
] for i in range(0, 4)]
def __init__(self, service: BaseService):
super().__init__(service)
def __init__(self):
self.artifact_rate = ArtifactOcrRate()
@staticmethod
def create_handlers(service: BaseService) -> list:
artifact_rate = ArtifactRate(service)
@classmethod
def create_handlers(cls) -> list:
artifact_rate = cls()
return [
ConversationHandler(
entry_points=[CommandHandler('artifact_rate', artifact_rate.command_start),

View File

@ -11,8 +11,8 @@ from telegram.helpers import escape_markdown
from logger import Log
from model.helpers import get_admin_list
from utils.random import MT19937_Random
from service import BaseService
from utils.random import MT19937_Random
FullChatPermissions = ChatPermissions(
can_send_messages=True,

View File

@ -4,7 +4,6 @@ from functools import wraps
from typing import Callable, Optional
from telegram import Update, ReplyKeyboardRemove
from telegram.constants import ChatType
from telegram.error import BadRequest
from telegram.ext import CallbackContext, ConversationHandler, filters
@ -37,8 +36,6 @@ def add_delete_message_job(context: CallbackContext, chat_id: int, message_id: i
class BasePlugins:
def __init__(self, service: BaseService):
self.service = service
@staticmethod
async def cancel(update: Update, _: CallbackContext) -> int:
@ -88,22 +85,28 @@ class NewChatMembersHandler:
def restricts(filters_chat: filters = filters.ALL, return_data=None, try_delete_message: bool = False,
restricts_time: int = 5):
"""
用于装饰在指定函数防止洪水调用的装饰器
"""用于装饰在指定函数防止洪水调用的装饰器
被修饰的函数传入参数必须为
async def command_func(update, context)
async def command_func(self, update, context)
被修饰的函数生声明必须为
如果修饰的函数属于
ConversationHandler
参数
return_data
必须传入
ConversationHandler.END
async def command_func(update, context)
async def command_func(self, update, context
我真是服了某些闲着没事干的群友了
如果修饰的函数属于
ConversationHandler
参数
return_data
必须传入
ConversationHandler.END
我真是服了某些闲着没事干的群友了
:param filters_chat: 要限制的群
:param return_data:
:param try_delete_message:
:param restricts_time:
:return: return_data
"""
def decorator(func: Callable):

View File

@ -1,6 +1,4 @@
from http.cookies import SimpleCookie, CookieError
from typing import List
from urllib.request import BaseHandler
import genshin
import ujson
@ -12,10 +10,10 @@ 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.base import restricts, BasePlugins
from plugins.errorhandler import conversation_error_handler
from service import BaseService
from service.base import UserInfoData
from utils.base import PaimonContext
class CookiesCommandData:
@ -33,9 +31,9 @@ class Cookies(BasePlugins):
CHECK_SERVER, CHECK_COOKIES, COMMAND_RESULT = range(10100, 10103)
@staticmethod
def create_handlers(service: BaseService):
cookies = Cookies(service)
@classmethod
def create_handlers(cls):
cookies = cls()
cookies_handler = ConversationHandler(
entry_points=[CommandHandler('adduser', cookies.command_start, filters.ChatType.PRIVATE, block=True),
MessageHandler(filters.Regex(r"^绑定账号(.*)") & filters.ChatType.PRIVATE,
@ -70,10 +68,11 @@ class Cookies(BasePlugins):
@conversation_error_handler
@restricts(return_data=ConversationHandler.END)
async def check_server(self, update: Update, context: CallbackContext) -> int:
async def check_server(self, update: Update, context: PaimonContext) -> int:
user = update.effective_user
service = context.service
cookies_command_data: CookiesCommandData = context.chat_data.get("cookies_command_data")
user_info = await self.service.user_service_db.get_user_info(user.id)
user_info = await service.user_service_db.get_user_info(user.id)
cookies_command_data.user_info = user_info
if update.message.text == "退出":
await update.message.reply_text("退出任务", reply_markup=ReplyKeyboardRemove())
@ -175,8 +174,9 @@ class Cookies(BasePlugins):
return self.COMMAND_RESULT
@conversation_error_handler
async def command_result(self, update: Update, context: CallbackContext) -> int:
async def command_result(self, update: Update, context: PaimonContext) -> int:
user = update.effective_user
service = context.service
cookies_command_data: CookiesCommandData = context.chat_data.get("cookies_command_data")
if update.message.text == "退出":
await update.message.reply_text("退出任务", reply_markup=ReplyKeyboardRemove())
@ -184,17 +184,17 @@ class Cookies(BasePlugins):
elif update.message.text == "确认":
data = ujson.dumps(cookies_command_data.cookies)
user_info = cookies_command_data.user_info
service = ServiceEnum.NULL.value
game_service = ServiceEnum.NULL.value
if cookies_command_data.service == ServiceEnum.HYPERION:
user_info.mihoyo_game_uid = cookies_command_data.game_uid
service = ServiceEnum.HYPERION.value
game_service = ServiceEnum.HYPERION.value
elif cookies_command_data.service == ServiceEnum.HOYOLAB:
user_info.hoyoverse_game_uid = cookies_command_data.game_uid
service = ServiceEnum.HOYOLAB.value
await self.service.user_service_db.set_user_info(user.id, user_info.mihoyo_game_uid,
user_info.hoyoverse_game_uid,
service)
await self.service.user_service_db.set_cookie(user.id, data, cookies_command_data.service)
game_service = ServiceEnum.HOYOLAB.value
await service.user_service_db.set_user_info(user.id, user_info.mihoyo_game_uid,
user_info.hoyoverse_game_uid,
game_service)
await service.user_service_db.set_cookie(user.id, data, cookies_command_data.service)
Log.info(f"用户 {user.full_name}[{user.id}] 绑定账号成功")
await update.message.reply_text("保存成功", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END

View File

@ -5,8 +5,8 @@ import genshin
from genshin import GenshinException, DataNotPublic
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.constants import ChatAction
from telegram.ext import CallbackContext, CommandHandler, MessageHandler, ConversationHandler, filters, \
CallbackQueryHandler
from telegram.ext import CommandHandler, MessageHandler, ConversationHandler, filters, \
CallbackQueryHandler, CallbackContext
from logger import Log
from manager import listener_plugins_class
@ -21,7 +21,7 @@ class UidCommandData:
user_info: UserInfoData = UserInfoData()
@listener_plugins_class()
@listener_plugins_class(need_service=True)
class DailyNote(BasePlugins):
"""
每日便签
@ -30,12 +30,12 @@ class DailyNote(BasePlugins):
COMMAND_RESULT, = range(10200, 10201)
def __init__(self, service: BaseService):
super().__init__(service)
self.service = service
self.current_dir = os.getcwd()
@staticmethod
def create_handlers(service: BaseService) -> list:
daily_note = DailyNote(service)
@classmethod
def create_handlers(cls, service: BaseService) -> list:
daily_note = cls(service)
daily_note_handler = ConversationHandler(
entry_points=[CommandHandler('dailynote', daily_note.command_start, block=True),
MessageHandler(filters.Regex(r"^当前状态(.*)"), daily_note.command_start, block=True)],
@ -46,8 +46,8 @@ class DailyNote(BasePlugins):
)
return [daily_note_handler]
async def _start_get_daily_note(self, user_info_data: UserInfoData, service: ServiceEnum) -> bytes:
if service == ServiceEnum.HYPERION:
async def _get_daily_note_data(self, user_info_data: UserInfoData, game_service: ServiceEnum) -> bytes:
if game_service == ServiceEnum.HYPERION:
client = genshin.ChineseClient(cookies=user_info_data.mihoyo_cookie)
uid = user_info_data.mihoyo_game_uid
else:

View File

@ -3,14 +3,14 @@ import os
from pyppeteer import launch
from telegram import Update
from telegram.constants import ChatAction
from telegram.ext import CallbackContext, ConversationHandler, filters, CommandHandler, MessageHandler
from telegram.ext import 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
from utils.base import PaimonContext
@listener_plugins_class()
@ -19,17 +19,16 @@ class Gacha(BasePlugins):
抽卡模拟器非首模拟器/减寿模拟器
"""
@staticmethod
def create_handlers(service: BaseService) -> list:
gacha = Gacha(service)
@classmethod
def create_handlers(cls) -> list:
gacha = cls()
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)
def __init__(self):
self.browser: launch = None
self.current_dir = os.getcwd()
self.resources_dir = os.path.join(self.current_dir, "resources")
@ -41,11 +40,12 @@ class Gacha(BasePlugins):
@conversation_error_handler
@restricts(filters.ChatType.GROUPS, restricts_time=20, try_delete_message=True)
@restricts(filters.ChatType.PRIVATE)
async def command_start(self, update: Update, context: CallbackContext) -> None:
async def command_start(self, update: Update, context: PaimonContext) -> None:
message = update.message
user = update.effective_user
args = context.args
match = context.match
service = context.service
gacha_name = "角色活动"
if args is None:
if match is not None:
@ -64,7 +64,7 @@ class Gacha(BasePlugins):
await message.reply_text(f"没有找到名为 {gacha_name} 的卡池")
return ConversationHandler.END
Log.info(f"用户 {user.full_name}[{user.id}] 抽卡模拟器命令请求 || 参数 {gacha_name}")
gacha_info = await self.service.gacha.gacha_info(gacha_name)
gacha_info = await service.gacha.gacha_info(gacha_name)
# 用户数据储存和处理
if gacha_info.get("gacha_id") is None:
await message.reply_text(f"没有找到名为 {gacha_name} 的卡池")
@ -104,8 +104,8 @@ class Gacha(BasePlugins):
data["items"].sort(key=take_rang, reverse=True)
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
# 因为 gacha_info["title"] 返回的是 HTML 标签 尝试关闭自动转义
png_data = await self.service.template.render('genshin/gacha', "gacha.html", data,
{"width": 1157, "height": 603}, False, False)
png_data = await service.template.render('genshin/gacha', "gacha.html", data,
{"width": 1157, "height": 603}, False, False)
reply_message = await message.reply_photo(png_data)
if filters.ChatType.GROUPS.filter(message):

View File

@ -1,13 +1,16 @@
from telegram import Update
from telegram.constants import ChatAction
from telegram.error import BadRequest
from telegram.ext import CommandHandler
from config import config
from logger import Log
from manager import listener_plugins_class
from plugins.base import restricts
from utils.base import PaimonContext
@listener_plugins_class()
class Help:
"""
帮助
@ -17,6 +20,13 @@ class Help:
self.help_png = None
self.file_id = None
@classmethod
def create_handlers(cls) -> list:
_help = cls()
return [
CommandHandler("help", _help.command_start, block=False),
]
@restricts()
async def command_start(self, update: Update, context: PaimonContext) -> None:
message = update.message

View File

@ -1,9 +1,9 @@
import os
import json
import genshin
import os
import re
from datetime import datetime, timedelta
import genshin
from genshin import GenshinException, DataNotPublic
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.constants import ChatAction
@ -59,7 +59,7 @@ def process_ledger_month(context: CallbackContext) -> int:
return now_time.month
@listener_plugins_class()
@listener_plugins_class(need_service=True)
class Ledger(BasePlugins):
"""
旅行札记
@ -68,12 +68,12 @@ class Ledger(BasePlugins):
COMMAND_RESULT, = range(10200, 10201)
def __init__(self, service: BaseService):
super().__init__(service)
self.service = service
self.current_dir = os.getcwd()
@staticmethod
def create_handlers(service: BaseService):
ledger = Ledger(service)
@classmethod
def create_handlers(cls, service: BaseService):
ledger = cls(service)
return [ConversationHandler(
entry_points=[CommandHandler("ledger", ledger.command_start, block=True),
MessageHandler(filters.Regex(r"^旅行扎记(.*)"), ledger.command_start, block=True)],
@ -83,8 +83,8 @@ class Ledger(BasePlugins):
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:
async def _start_get_ledger(self, user_info_data: UserInfoData, game_service: ServiceEnum, month=None) -> bytes:
if game_service == ServiceEnum.HYPERION:
client = genshin.ChineseClient(cookies=user_info_data.mihoyo_cookie)
uid = user_info_data.mihoyo_game_uid
else:

View File

@ -27,7 +27,7 @@ class PostHandlerData:
self.tags: Optional[List[str]] = []
@listener_plugins_class()
@listener_plugins_class(need_service=True)
class Post(BasePlugins):
"""
文章推送
@ -39,26 +39,26 @@ class Post(BasePlugins):
MENU_KEYBOARD = ReplyKeyboardMarkup([["推送频道", "添加TAG"], ["编辑文字", "删除图片"], ["退出"]], True, True)
def __init__(self, service: BaseService):
super().__init__(service)
self.service = service
self.bbs = Hyperion()
@staticmethod
def create_handlers(service: BaseService):
_post = Post(service)
@classmethod
def create_handlers(cls, service: BaseService):
post = cls(service)
post_handler = ConversationHandler(
entry_points=[CommandHandler('post', _post.command_start, block=True)],
entry_points=[CommandHandler('post', post.command_start, block=True)],
states={
_post.CHECK_POST: [MessageHandler(filters.TEXT & ~filters.COMMAND, _post.check_post, block=True)],
_post.SEND_POST: [MessageHandler(filters.TEXT & ~filters.COMMAND, _post.send_post, block=True)],
_post.CHECK_COMMAND: [MessageHandler(filters.TEXT & ~filters.COMMAND, _post.check_command, block=True)],
_post.GTE_DELETE_PHOTO: [
MessageHandler(filters.TEXT & ~filters.COMMAND, _post.get_delete_photo, block=True)],
_post.GET_POST_CHANNEL: [
MessageHandler(filters.TEXT & ~filters.COMMAND, _post.get_post_channel, block=True)],
_post.GET_TAGS: [MessageHandler(filters.TEXT & ~filters.COMMAND, _post.get_tags, block=True)],
_post.GET_TEXT: [MessageHandler(filters.TEXT & ~filters.COMMAND, _post.get_edit_text, block=True)]
post.CHECK_POST: [MessageHandler(filters.TEXT & ~filters.COMMAND, post.check_post, block=True)],
post.SEND_POST: [MessageHandler(filters.TEXT & ~filters.COMMAND, post.send_post, block=True)],
post.CHECK_COMMAND: [MessageHandler(filters.TEXT & ~filters.COMMAND, post.check_command, block=True)],
post.GTE_DELETE_PHOTO: [
MessageHandler(filters.TEXT & ~filters.COMMAND, post.get_delete_photo, block=True)],
post.GET_POST_CHANNEL: [
MessageHandler(filters.TEXT & ~filters.COMMAND, post.get_post_channel, block=True)],
post.GET_TAGS: [MessageHandler(filters.TEXT & ~filters.COMMAND, post.get_tags, block=True)],
post.GET_TEXT: [MessageHandler(filters.TEXT & ~filters.COMMAND, post.get_edit_text, block=True)]
},
fallbacks=[CommandHandler('cancel', _post.cancel, block=True)]
fallbacks=[CommandHandler('cancel', post.cancel, block=True)]
)
return [post_handler]

View File

@ -11,10 +11,10 @@ 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
from service.base import QuestionData, AnswerData
from utils.random import MT19937_Random
class QuizCommandData:
@ -25,7 +25,7 @@ class QuizCommandData:
status: int = 0
@listener_plugins_class()
@listener_plugins_class(need_service=True)
class Quiz(BasePlugins):
"""
派蒙的十万个为什么
@ -37,15 +37,14 @@ class Quiz(BasePlugins):
QUESTION_EDIT, SAVE_QUESTION = range(10300, 10308)
def __init__(self, service: BaseService):
super().__init__(service)
self.user_time = {}
self.service = service
self.time_out = 120
self.random = MT19937_Random()
@staticmethod
def create_handlers(service: BaseService):
quiz = Quiz(service)
@classmethod
def create_handlers(cls, service: BaseService):
quiz = cls(service)
quiz_handler = ConversationHandler(
entry_points=[CommandHandler('quiz', quiz.command_start, block=True)],
states={

View File

@ -13,8 +13,8 @@ from manager import listener_plugins_class
from model.base import ServiceEnum
from plugins.base import BasePlugins, restricts
from plugins.errorhandler import conversation_error_handler
from service import BaseService
from service.base import UserInfoData
from utils.base import PaimonContext
class SignCommandData:
@ -31,9 +31,9 @@ class Sign(BasePlugins):
CHECK_SERVER, COMMAND_RESULT = range(10400, 10402)
@staticmethod
def create_handlers(service: BaseService):
sign = Sign(service)
@classmethod
def create_handlers(cls):
sign = cls()
sign_handler = ConversationHandler(
entry_points=[CommandHandler('sign', sign.command_start, block=True),
MessageHandler(filters.Regex(r"^每日签到(.*)"), sign.command_start, block=True)],
@ -45,8 +45,8 @@ class Sign(BasePlugins):
return [sign_handler]
@staticmethod
async def _start_sign(user_info: UserInfoData, service: ServiceEnum) -> str:
if service == ServiceEnum.HYPERION:
async def _start_sign(user_info: UserInfoData, game_service: ServiceEnum) -> str:
if game_service == ServiceEnum.HYPERION:
client = genshin.ChineseClient(cookies=user_info.mihoyo_cookie)
uid = user_info.mihoyo_game_uid
else:
@ -93,9 +93,10 @@ class Sign(BasePlugins):
@conversation_error_handler
@restricts(return_data=ConversationHandler.END)
async def command_start(self, update: Update, context: CallbackContext) -> int:
async def command_start(self, update: Update, context: PaimonContext) -> int:
user = update.effective_user
message = update.message
service = context.service
Log.info(f"用户 {user.full_name}[{user.id}] 每日签到命令请求")
if filters.ChatType.GROUPS.filter(message):
self._add_delete_message_job(context, message.chat_id, message.message_id)
@ -103,7 +104,7 @@ class Sign(BasePlugins):
if sign_command_data is None:
sign_command_data = SignCommandData()
context.chat_data["sign_command_data"] = sign_command_data
user_info = await self.service.user_service_db.get_user_info(user.id)
user_info = await service.user_service_db.get_user_info(user.id)
if user_info.user_id == 0:
await update.message.reply_text("未查询到账号信息,请先私聊派蒙绑定账号")
return ConversationHandler.END

View File

@ -2,12 +2,11 @@ from telegram import Update, ReplyKeyboardRemove
from telegram.ext import CallbackContext
from telegram.helpers import escape_markdown
from utils.base import PaimonContext
from plugins.base import restricts
@restricts()
async def start(update: Update, context: PaimonContext) -> None:
async def start(update: Update, context: CallbackContext) -> None:
user = update.effective_user
message = update.message
args = context.args

View File

@ -1,6 +1,6 @@
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.constants import ChatAction, ParseMode
from telegram.ext import CallbackContext, filters, ConversationHandler, CommandHandler, MessageHandler
from telegram.ext import filters, ConversationHandler, CommandHandler, MessageHandler
from logger import Log
from manager import listener_plugins_class
@ -8,7 +8,7 @@ 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
from utils.base import PaimonContext
@listener_plugins_class()
@ -19,9 +19,9 @@ class Strategy(BasePlugins):
KEYBOARD = [[InlineKeyboardButton(text="查看角色攻略列表并查询", switch_inline_query_current_chat="查看角色攻略列表并查询")]]
@staticmethod
def create_handlers(service: BaseService) -> list:
strategy = Strategy(service)
@classmethod
def create_handlers(cls) -> list:
strategy = cls()
return [
CommandHandler("strategy", strategy.command_start, block=False),
MessageHandler(filters.Regex("^角色攻略查询(.*)"), strategy.command_start, block=False),
@ -29,11 +29,12 @@ class Strategy(BasePlugins):
@conversation_error_handler
@restricts(return_data=ConversationHandler.END)
async def command_start(self, update: Update, context: CallbackContext) -> None:
async def command_start(self, update: Update, context: PaimonContext) -> None:
message = update.message
user = update.effective_user
args = context.args
match = context.match
service = context.service
role_name: str = ""
if args is None:
if match is not None:
@ -52,7 +53,7 @@ class Strategy(BasePlugins):
self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id)
return
role_name = roleToName(role_name)
url = await self.service.get_game_info.get_characters_cultivation_atlas(role_name)
url = await service.get_game_info.get_characters_cultivation_atlas(role_name)
if url == "":
reply_message = await message.reply_text(f"没有找到 {role_name} 的攻略",
reply_markup=InlineKeyboardMarkup(self.KEYBOARD))

View File

@ -22,7 +22,7 @@ class UidCommandData:
user_info: UserInfoData = UserInfoData()
@listener_plugins_class()
@listener_plugins_class(need_service=True)
class Uid(BasePlugins):
"""
玩家查询
@ -31,12 +31,12 @@ class Uid(BasePlugins):
COMMAND_RESULT, = range(10200, 10201)
def __init__(self, service: BaseService):
super().__init__(service)
self.service = service
self.current_dir = os.getcwd()
@staticmethod
def create_handlers(service: BaseService):
uid = Uid(service)
@classmethod
def create_handlers(cls, service: BaseService):
uid = cls(service)
uid_handler = ConversationHandler(
entry_points=[CommandHandler('uid', uid.command_start, block=True),
MessageHandler(filters.Regex(r"^玩家查询(.*)"), uid.command_start, block=True)],

View File

@ -1,6 +1,6 @@
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.constants import ChatAction
from telegram.ext import CallbackContext, filters, CommandHandler, MessageHandler
from telegram.ext import filters, CommandHandler, MessageHandler
from logger import Log
from manager import listener_plugins_class
@ -8,7 +8,7 @@ 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
from utils.base import PaimonContext
@listener_plugins_class()
@ -19,9 +19,9 @@ class Weapon(BasePlugins):
KEYBOARD = [[InlineKeyboardButton(text="查看武器列表并查询", switch_inline_query_current_chat="查看武器列表并查询")]]
@staticmethod
def create_handlers(service: BaseService) -> list:
weapon = Weapon(service)
@classmethod
def create_handlers(cls) -> list:
weapon = cls()
return [
CommandHandler("weapon", weapon.command_start, block=False),
MessageHandler(filters.Regex("^武器查询(.*)"), weapon.command_start, block=False)
@ -29,11 +29,12 @@ class Weapon(BasePlugins):
@conversation_error_handler
@restricts()
async def command_start(self, update: Update, context: CallbackContext) -> None:
async def command_start(self, update: Update, context: PaimonContext) -> None:
message = update.message
user = update.effective_user
args = context.args
match = context.match
service = context.service
weapon_name: str = ""
if args is None:
if match is not None:
@ -90,8 +91,8 @@ class Weapon(BasePlugins):
return _template_data
template_data = await input_template_data(weapon_data)
png_data = await self.service.template.render('genshin/weapon', "weapon.html", template_data,
{"width": 540, "height": 540})
png_data = await service.template.render('genshin/weapon', "weapon.html", template_data,
{"width": 540, "height": 540})
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
await message.reply_photo(png_data, filename=f"{template_data['weapon_name']}.png",
allow_sending_without_reply=True)

View File

@ -1,10 +1,10 @@
from telegram import Update
from telegram.ext import CallbackContext, CommandHandler
from telegram.ext import CommandHandler
from manager import listener_plugins_class
from plugins.admin import bot_admins_only
from plugins.base import BasePlugins
from service import BaseService
from utils.base import PaimonContext
@listener_plugins_class()
@ -13,16 +13,17 @@ class Wiki(BasePlugins):
有关WIKI
"""
@staticmethod
def create_handlers(service: BaseService) -> list:
wiki = Wiki(service)
@classmethod
def create_handlers(cls) -> list:
wiki = cls()
return [
CommandHandler("refresh_wiki", wiki.refresh_wiki, block=False),
]
@bot_admins_only
async def refresh_wiki(self, update: Update, _: CallbackContext):
async def refresh_wiki(self, update: Update, context: PaimonContext):
message = update.message
service = context.service
await message.reply_text("正在刷新Wiki缓存请稍等")
await self.service.wiki.refresh_wiki()
await service.wiki.refresh_wiki()
await message.reply_text("刷新Wiki缓存成功")

View File

@ -4,13 +4,15 @@ from service import BaseService
class PaimonContext(CallbackContext[ExtBot, dict, dict, dict]):
"""
PaimoeContext
"""
"""自定义的PaimoeContext"""
@property
def service(self) -> BaseService:
value = self.bot_data.get("service")
"""在回调中从 bot_data 获取 service 实例
:return: BaseService 实例
"""
value = self.application.bot_data.get("service")
if value is None:
raise RuntimeError("没有与此上下文对象关联的实例化服务")
raise RuntimeError("没有找到与此上下文对象关联的实例化服务")
return value