diff --git a/alembic/env.py b/alembic/env.py
index dc1a58e..3769242 100644
--- a/alembic/env.py
+++ b/alembic/env.py
@@ -42,9 +42,7 @@ def import_models():
try:
import_module(pkg) # 导入 models
except Exception as e: # pylint: disable=W0703
- logger.error(
- f'在导入文件 "{pkg}" 的过程中遇到了错误: \n[red bold]{type(e).__name__}: {e}[/]'
- )
+ logger.error(f'在导入文件 "{pkg}" 的过程中遇到了错误: \n[red bold]{type(e).__name__}: {e}[/]')
# register our models for alembic to auto-generate migrations
diff --git a/core/admin/models.py b/core/admin/models.py
index c9a3fdd..e4bf7c1 100644
--- a/core/admin/models.py
+++ b/core/admin/models.py
@@ -1,9 +1,8 @@
-
from sqlmodel import SQLModel, Field
class Admin(SQLModel, table=True):
- __table_args__ = dict(mysql_charset='utf8mb4', mysql_collate="utf8mb4_general_ci")
+ __table_args__ = dict(mysql_charset="utf8mb4", mysql_collate="utf8mb4_general_ci")
id: int = Field(primary_key=True)
user_id: int = Field(foreign_key="user.user_id")
diff --git a/core/base/aiobrowser.py b/core/base/aiobrowser.py
index 39210c8..ff7b5f5 100644
--- a/core/base/aiobrowser.py
+++ b/core/base/aiobrowser.py
@@ -7,7 +7,6 @@ from utils.log import logger
class AioBrowser(Service):
-
def __init__(self, loop=None):
self.browser: Optional[Browser] = None
self._playwright: Optional[Playwright] = None
@@ -15,16 +14,16 @@ class AioBrowser(Service):
async def start(self):
if self._playwright is None:
- logger.info("正在尝试启动 [blue]Playwright[/]", extra={'markup': True})
+ logger.info("正在尝试启动 [blue]Playwright[/]", extra={"markup": True})
self._playwright = await async_playwright().start()
- logger.success("[blue]Playwright[/] 启动成功", extra={'markup': True})
+ logger.success("[blue]Playwright[/] 启动成功", extra={"markup": True})
if self.browser is None:
- logger.info("正在尝试启动 [blue]Browser[/]", extra={'markup': True})
+ logger.info("正在尝试启动 [blue]Browser[/]", extra={"markup": True})
try:
self.browser = await self._playwright.chromium.launch(timeout=5000)
- logger.success("[blue]Browser[/] 启动成功", extra={'markup': True})
+ logger.success("[blue]Browser[/] 启动成功", extra={"markup": True})
except TimeoutError as err:
- logger.warning("[blue]Browser[/] 启动失败", extra={'markup': True})
+ logger.warning("[blue]Browser[/] 启动失败", extra={"markup": True})
raise err
return self.browser
diff --git a/core/base/mtproto.py b/core/base/mtproto.py
index 4f4d77f..d491aac 100644
--- a/core/base/mtproto.py
+++ b/core/base/mtproto.py
@@ -20,13 +20,12 @@ from core.service import Service
class MTProto(Service):
-
async def get_session(self):
- async with aiofiles.open(self.session_path, mode='r') as f:
+ async with aiofiles.open(self.session_path, mode="r") as f:
return await f.read()
async def set_session(self, b: str):
- async with aiofiles.open(self.session_path, mode='w+') as f:
+ async with aiofiles.open(self.session_path, mode="w+") as f:
await f.write(b)
def session_exists(self):
@@ -53,8 +52,13 @@ class MTProto(Service):
if bot.config.mtproto.api_hash is None:
logger.info("MTProto 服务需要的 api_hash 未配置 本次服务 client 为 None")
return
- self.client = Client(api_id=bot.config.mtproto.api_id, api_hash=bot.config.mtproto.api_hash, name=self.name,
- bot_token=bot.config.bot_token, proxy=self.proxy)
+ self.client = Client(
+ api_id=bot.config.mtproto.api_id,
+ api_hash=bot.config.mtproto.api_hash,
+ name=self.name,
+ bot_token=bot.config.bot_token,
+ proxy=self.proxy,
+ )
await self.client.start()
async def stop(self): # pylint: disable=W0221
diff --git a/core/base/mysql.py b/core/base/mysql.py
index 1b89813..64952e4 100644
--- a/core/base/mysql.py
+++ b/core/base/mysql.py
@@ -12,8 +12,7 @@ class MySQL(Service):
def from_config(cls, config: BotConfig) -> Self:
return cls(**config.mysql.dict())
- def __init__(self, host: str = "127.0.0.1", port: int = 3306, username: str = "root", # nosec B107
- password: str = "", database: str = ""): # nosec B107
+ def __init__(self, host: str, port: int, username: str, password: str, database: str):
self.database = database
self.password = password
self.user = username
diff --git a/core/base/redisdb.py b/core/base/redisdb.py
index aa9f866..ddd4303 100644
--- a/core/base/redisdb.py
+++ b/core/base/redisdb.py
@@ -22,21 +22,21 @@ class RedisDB(Service):
async def ping(self):
if await self.client.ping():
- logger.info("连接 [red]Redis[/] 成功", extra={'markup': True})
+ logger.info("连接 [red]Redis[/] 成功", extra={"markup": True})
else:
- logger.info("连接 [red]Redis[/] 失败", extra={'markup': True})
+ logger.info("连接 [red]Redis[/] 失败", extra={"markup": True})
raise RuntimeError("连接 Redis 失败")
async def start(self): # pylint: disable=W0221
if self._loop is None:
self._loop = asyncio.get_running_loop()
- logger.info("正在尝试建立与 [red]Redis[/] 连接", extra={'markup': True})
+ logger.info("正在尝试建立与 [red]Redis[/] 连接", extra={"markup": True})
try:
await self.ping()
except (KeyboardInterrupt, SystemExit):
pass
except Exception as exc:
- logger.exception("尝试连接 [red]Redis[/] 失败,使用 [red]fakeredis[/] 模拟", exc_info=exc, extra={'markup': True})
+ logger.exception("尝试连接 [red]Redis[/] 失败,使用 [red]fakeredis[/] 模拟", exc_info=exc, extra={"markup": True})
self.client = fakeredis.aioredis.FakeRedis()
await self.ping()
diff --git a/core/baseplugin.py b/core/baseplugin.py
index 73b853f..2eeb645 100644
--- a/core/baseplugin.py
+++ b/core/baseplugin.py
@@ -16,8 +16,7 @@ async def clean_message(context: CallbackContext):
if "not found" in str(exc):
logger.warning(f"删除消息 chat_id[{job.chat_id}] message_id[{job.data}]失败 消息不存在")
elif "Message can't be deleted" in str(exc):
- logger.warning(
- f"删除消息 chat_id[{job.chat_id}] message_id[{job.data}]失败 消息无法删除 可能是没有授权")
+ logger.warning(f"删除消息 chat_id[{job.chat_id}] message_id[{job.data}]失败 消息无法删除 可能是没有授权")
else:
logger.error(f"删除消息 chat_id[{job.chat_id}] message_id[{job.data}]失败")
logger.exception(exc)
@@ -30,10 +29,14 @@ async def clean_message(context: CallbackContext):
def add_delete_message_job(context: CallbackContext, chat_id: int, message_id: int, delete_seconds: int):
- context.job_queue.run_once(callback=clean_message, when=delete_seconds, data=message_id,
- name=f"{chat_id}|{message_id}|clean_message", chat_id=chat_id,
- job_kwargs={"replace_existing": True,
- "id": f"{chat_id}|{message_id}|clean_message"})
+ context.job_queue.run_once(
+ callback=clean_message,
+ when=delete_seconds,
+ data=message_id,
+ name=f"{chat_id}|{message_id}|clean_message",
+ chat_id=chat_id,
+ job_kwargs={"replace_existing": True, "id": f"{chat_id}|{message_id}|clean_message"},
+ )
class _BasePlugin:
@@ -43,9 +46,8 @@ class _BasePlugin:
class _Conversation(_BasePlugin):
-
@conversation.fallback
- @handler.command(command='cancel', block=True)
+ @handler.command(command="cancel", block=True)
async def cancel(self, update: Update, _: CallbackContext) -> int:
await update.effective_message.reply_text("退出命令", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
diff --git a/core/bot.py b/core/bot.py
index 0275263..3245aae 100644
--- a/core/bot.py
+++ b/core/bot.py
@@ -23,6 +23,7 @@ from telegram.ext.filters import StatusUpdate
from core.config import BotConfig, config # pylint: disable=W0611
from core.error import ServiceNotFoundError
+
# noinspection PyProtectedMember
from core.plugin import Plugin, _Plugin
from core.service import Service
@@ -32,10 +33,10 @@ from utils.log import logger
if TYPE_CHECKING:
from telegram import Update
-__all__ = ['bot']
+__all__ = ["bot"]
-T = TypeVar('T')
-PluginType = TypeVar('PluginType', bound=_Plugin)
+T = TypeVar("T")
+PluginType = TypeVar("PluginType", bound=_Plugin)
class Bot:
@@ -57,7 +58,7 @@ class Bot:
def _inject(self, signature: inspect.Signature, target: Callable[..., T]) -> T:
kwargs = {}
for name, parameter in signature.parameters.items():
- if name != 'self' and parameter.annotation != inspect.Parameter.empty:
+ if name != "self" and parameter.annotation != inspect.Parameter.empty:
if value := self._services.get(parameter.annotation):
kwargs[name] = value
return target(**kwargs)
@@ -76,11 +77,11 @@ class Bot:
def _gen_pkg(self, root: Path) -> Iterator[str]:
"""生成可以用于 import_module 导入的字符串"""
for path in root.iterdir():
- if not path.name.startswith('_'):
+ if not path.name.startswith("_"):
if path.is_dir():
yield from self._gen_pkg(path)
- elif path.suffix == '.py':
- yield str(path.relative_to(PROJECT_ROOT).with_suffix('')).replace(os.sep, '.')
+ elif path.suffix == ".py":
+ yield str(path.relative_to(PROJECT_ROOT).with_suffix("")).replace(os.sep, ".")
async def install_plugins(self):
"""安装插件"""
@@ -89,8 +90,7 @@ class Bot:
import_module(pkg) # 导入插件
except Exception as e: # pylint: disable=W0703
logger.exception(
- f'在导入文件 "{pkg}" 的过程中遇到了错误: \n[red bold]{type(e).__name__}: {e}[/]',
- extra={'markup': True}
+ f'在导入文件 "{pkg}" 的过程中遇到了错误: \n[red bold]{type(e).__name__}: {e}[/]', extra={"markup": True}
)
continue # 如有错误则继续
callback_dict: Dict[int, List[Callable]] = {}
@@ -98,7 +98,7 @@ class Bot:
path = f"{plugin_cls.__module__}.{plugin_cls.__name__}"
try:
plugin: PluginType = self.init_inject(plugin_cls)
- if hasattr(plugin, '__async_init__'):
+ if hasattr(plugin, "__async_init__"):
await self.async_inject(plugin.__async_init__)
handlers = plugin.handlers
self.app.add_handlers(handlers)
@@ -115,46 +115,44 @@ class Bot:
for callback, block in error_handlers.items():
self.app.add_error_handler(callback, block)
if error_handlers:
- logger.debug(f"插件 \"{path}\" 添加了 {len(error_handlers)} 个 error handler")
+ logger.debug(f'插件 "{path}" 添加了 {len(error_handlers)} 个 error handler')
if jobs := plugin.jobs:
logger.debug(f'插件 "{path}" 添加了 {len(jobs)} 个任务')
logger.success(f'插件 "{path}" 载入成功')
except Exception as e: # pylint: disable=W0703
logger.exception(
- f'在安装插件 \"{path}\" 的过程中遇到了错误: \n[red bold]{type(e).__name__}: {e}[/]',
- extra={'markup': True}
+ f'在安装插件 "{path}" 的过程中遇到了错误: \n[red bold]{type(e).__name__}: {e}[/]', extra={"markup": True}
)
if callback_dict:
num = sum(len(callback_dict[i]) for i in callback_dict)
- async def _new_chat_member_callback(update: 'Update', context: 'CallbackContext'):
+ async def _new_chat_member_callback(update: "Update", context: "CallbackContext"):
nonlocal callback
for _, value in callback_dict.items():
for callback in value:
await callback(update, context)
- self.app.add_handler(MessageHandler(
- callback=_new_chat_member_callback, filters=StatusUpdate.NEW_CHAT_MEMBERS, block=False
- ))
+ self.app.add_handler(
+ MessageHandler(callback=_new_chat_member_callback, filters=StatusUpdate.NEW_CHAT_MEMBERS, block=False)
+ )
logger.success(
- f'成功添加了 {num} 个针对 [blue]{StatusUpdate.NEW_CHAT_MEMBERS}[/] 的 [blue]MessageHandler[/]',
- extra={'markup': True}
+ f"成功添加了 {num} 个针对 [blue]{StatusUpdate.NEW_CHAT_MEMBERS}[/] 的 [blue]MessageHandler[/]",
+ extra={"markup": True},
)
async def _start_base_services(self):
- for pkg in self._gen_pkg(PROJECT_ROOT / 'core/base'):
+ for pkg in self._gen_pkg(PROJECT_ROOT / "core/base"):
try:
import_module(pkg)
except Exception as e: # pylint: disable=W0703
logger.exception(
- f'在导入文件 "{pkg}" 的过程中遇到了错误: \n[red bold]{type(e).__name__}: {e}[/]',
- extra={'markup': True}
+ f'在导入文件 "{pkg}" 的过程中遇到了错误: \n[red bold]{type(e).__name__}: {e}[/]', extra={"markup": True}
)
continue
for base_service_cls in Service.__subclasses__():
try:
- if hasattr(base_service_cls, 'from_config'):
+ if hasattr(base_service_cls, "from_config"):
instance = base_service_cls.from_config(self._config)
else:
instance = self.init_inject(base_service_cls)
@@ -168,15 +166,14 @@ class Bot:
async def start_services(self):
"""启动服务"""
await self._start_base_services()
- for path in (PROJECT_ROOT / 'core').iterdir():
- if not path.name.startswith('_') and path.is_dir() and path.name != 'base':
- pkg = str(path.relative_to(PROJECT_ROOT).with_suffix('')).replace(os.sep, '.')
+ for path in (PROJECT_ROOT / "core").iterdir():
+ if not path.name.startswith("_") and path.is_dir() and path.name != "base":
+ pkg = str(path.relative_to(PROJECT_ROOT).with_suffix("")).replace(os.sep, ".")
try:
import_module(pkg)
except Exception as e: # pylint: disable=W0703
logger.exception(
- f'在导入文件 "{pkg}" 的过程中遇到了错误: \n[red bold]{type(e).__name__}: {e}[/]',
- extra={'markup': True}
+ f'在导入文件 "{pkg}" 的过程中遇到了错误: \n[red bold]{type(e).__name__}: {e}[/]', extra={"markup": True}
)
continue
@@ -184,11 +181,11 @@ class Bot:
"""关闭服务"""
if not self._services:
return
- logger.info('正在关闭服务')
+ logger.info("正在关闭服务")
for _, service in filter(lambda x: not isinstance(x[1], TgApplication), self._services.items()):
async with timeout(5):
try:
- if hasattr(service, 'stop'):
+ if hasattr(service, "stop"):
if inspect.iscoroutinefunction(service.stop):
await service.stop()
else:
@@ -197,16 +194,19 @@ class Bot:
except CancelledError:
logger.warning(f'服务 "{service.__class__.__name__}" 关闭超时')
except Exception as e: # pylint: disable=W0703
- logger.exception(f"服务 \"{service.__class__.__name__}\" 关闭失败: \n{type(e).__name__}: {e}")
+ logger.exception(f'服务 "{service.__class__.__name__}" 关闭失败: \n{type(e).__name__}: {e}')
async def _post_init(self, context: CallbackContext) -> NoReturn:
- logger.info('开始初始化 genshin.py 相关资源')
+ logger.info("开始初始化 genshin.py 相关资源")
try:
# 替换为 fastgit 镜像源
for i in dir(genshin.utility.extdb):
if "_URL" in i:
- setattr(genshin.utility.extdb, i,
- getattr(genshin.utility.extdb, i).replace("githubusercontent.com", "fastgit.org"))
+ setattr(
+ genshin.utility.extdb,
+ i,
+ getattr(genshin.utility.extdb, i).replace("githubusercontent.com", "fastgit.org"),
+ )
await genshin.utility.update_characters_enka()
except Exception as exc:
logger.error("初始化 genshin.py 相关资源失败")
@@ -214,16 +214,16 @@ class Bot:
else:
logger.success("初始化 genshin.py 相关资源成功")
self._services.update({CallbackContext: context})
- logger.info('开始初始化服务')
+ logger.info("开始初始化服务")
await self.start_services()
- logger.info('开始安装插件')
+ logger.info("开始安装插件")
await self.install_plugins()
- logger.info('BOT 初始化成功')
+ logger.info("BOT 初始化成功")
def launch(self) -> NoReturn:
"""启动机器人"""
self._running = True
- logger.info('正在初始化BOT')
+ logger.info("正在初始化BOT")
self.app = (
TgApplication.builder()
.rate_limiter(AIORateLimiter())
@@ -238,11 +238,11 @@ class Bot:
self.app.run_polling(close_loop=False)
break
except TimedOut:
- logger.warning("连接至 [blue]telegram[/] 服务器失败,正在重试", extra={'markup': True})
+ logger.warning("连接至 [blue]telegram[/] 服务器失败,正在重试", extra={"markup": True})
continue
except NetworkError as e:
logger.exception()
- if 'SSLZeroReturnError' in str(e):
+ if "SSLZeroReturnError" in str(e):
logger.error("代理服务出现异常, 请检查您的代理服务是否配置成功.")
else:
logger.error("网络连接出现问题, 请检查您的网络状况.")
@@ -267,7 +267,7 @@ class Bot:
def add_service(self, service: T) -> NoReturn:
"""添加服务。若已经有同类型的服务,则会抛出异常"""
if type(service) in self._services:
- raise ValueError(f"Service \"{type(service)}\" is already existed.")
+ raise ValueError(f'Service "{type(service)}" is already existed.')
self.update_service(service)
def update_service(self, service: T):
diff --git a/core/cookies/models.py b/core/cookies/models.py
index 0a55b78..93010da 100644
--- a/core/cookies/models.py
+++ b/core/cookies/models.py
@@ -11,7 +11,7 @@ class CookiesStatusEnum(int, enum.Enum):
class Cookies(SQLModel):
- __table_args__ = dict(mysql_charset='utf8mb4', mysql_collate="utf8mb4_general_ci")
+ __table_args__ = dict(mysql_charset="utf8mb4", mysql_collate="utf8mb4_general_ci")
id: int = Field(primary_key=True)
user_id: Optional[int] = Field(foreign_key="user.user_id")
@@ -20,8 +20,8 @@ class Cookies(SQLModel):
class HyperionCookie(Cookies, table=True):
- __tablename__ = 'mihoyo_cookies'
+ __tablename__ = "mihoyo_cookies"
class HoyolabCookie(Cookies, table=True):
- __tablename__ = 'hoyoverse_cookies'
+ __tablename__ = "hoyoverse_cookies"
diff --git a/core/error.py b/core/error.py
index 8b2f25d..344b684 100644
--- a/core/error.py
+++ b/core/error.py
@@ -3,6 +3,5 @@ from typing import Union
class ServiceNotFoundError(Exception):
-
def __init__(self, name: Union[str, type]):
super().__init__(f"No service named '{name if isinstance(name, str) else name.__name__}'")
diff --git a/core/game/services.py b/core/game/services.py
index 535ac05..b17b9c1 100644
--- a/core/game/services.py
+++ b/core/game/services.py
@@ -48,7 +48,7 @@ class GameMaterialService:
self._cache = cache
self._hyperion = Hyperion()
self._collections = [428421, 1164644] if collections is None else collections
- self._special = ['雷电将军', '珊瑚宫心海', '菲谢尔', '托马', '八重神子', '九条裟罗', '辛焱', '神里绫华']
+ self._special = ["雷电将军", "珊瑚宫心海", "菲谢尔", "托马", "八重神子", "九条裟罗", "辛焱", "神里绫华"]
async def _get_material_from_hyperion(self, collection_id: int, character_name: str) -> int:
post_id: int = -1
diff --git a/core/plugin.py b/core/plugin.py
index 31e2d65..599cb71 100644
--- a/core/plugin.py
+++ b/core/plugin.py
@@ -7,43 +7,42 @@ from typing import Any, Callable, Dict, List, Optional, Tuple, Type, TypeVar, Un
# noinspection PyProtectedMember
from telegram._utils.defaultvalue import DEFAULT_TRUE
+
# noinspection PyProtectedMember
from telegram._utils.types import DVInput, JSONDict
from telegram.ext import BaseHandler, ConversationHandler, Job
+
# noinspection PyProtectedMember
from telegram.ext._utils.types import JobCallback
from telegram.ext.filters import BaseFilter
from typing_extensions import ParamSpec
-__all__ = [
- 'Plugin', 'handler', 'conversation', 'job', 'error_handler'
-]
+__all__ = ["Plugin", "handler", "conversation", "job", "error_handler"]
-P = ParamSpec('P')
-T = TypeVar('T')
-HandlerType = TypeVar('HandlerType', bound=BaseHandler)
+P = ParamSpec("P")
+T = TypeVar("T")
+HandlerType = TypeVar("HandlerType", bound=BaseHandler)
TimeType = Union[float, datetime.timedelta, datetime.datetime, datetime.time]
-_Module = import_module('telegram.ext')
+_Module = import_module("telegram.ext")
_NORMAL_HANDLER_ATTR_NAME = "_handler_data"
_CONVERSATION_HANDLER_ATTR_NAME = "_conversation_data"
_JOB_ATTR_NAME = "_job_data"
-_EXCLUDE_ATTRS = ['handlers', 'jobs', 'error_handlers']
+_EXCLUDE_ATTRS = ["handlers", "jobs", "error_handlers"]
class _Plugin:
-
def _make_handler(self, datas: Union[List[Dict], Dict]) -> List[HandlerType]:
result = []
if isinstance(datas, list):
for data in filter(lambda x: x, datas):
- func = getattr(self, data.pop('func'))
- result.append(data.pop('type')(callback=func, **data.pop('kwargs')))
+ func = getattr(self, data.pop("func"))
+ result.append(data.pop("type")(callback=func, **data.pop("kwargs")))
else:
- func = getattr(self, datas.pop('func'))
- result.append(datas.pop('type')(callback=func, **datas.pop('kwargs')))
+ func = getattr(self, datas.pop("func"))
+ result.append(datas.pop("type")(callback=func, **datas.pop("kwargs")))
return result
@property
@@ -52,14 +51,12 @@ class _Plugin:
for attr in dir(self):
# noinspection PyUnboundLocalVariable
if (
- not (attr.startswith('_') or attr in _EXCLUDE_ATTRS)
- and
- isinstance(func := getattr(self, attr), MethodType)
- and
- (datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
+ not (attr.startswith("_") or attr in _EXCLUDE_ATTRS)
+ and isinstance(func := getattr(self, attr), MethodType)
+ and (datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
):
for data in datas:
- if data['type'] not in ['error', 'new_chat_member']:
+ if data["type"] not in ["error", "new_chat_member"]:
result.extend(self._make_handler(data))
return result
@@ -69,15 +66,13 @@ class _Plugin:
for attr in dir(self):
# noinspection PyUnboundLocalVariable
if (
- not (attr.startswith('_') or attr in _EXCLUDE_ATTRS)
- and
- isinstance(func := getattr(self, attr), MethodType)
- and
- (datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
+ not (attr.startswith("_") or attr in _EXCLUDE_ATTRS)
+ and isinstance(func := getattr(self, attr), MethodType)
+ and (datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
):
for data in datas:
- if data and data['type'] == 'new_chat_member':
- result.append((data['priority'], func))
+ if data and data["type"] == "new_chat_member":
+ result.append((data["priority"], func))
return result
@@ -87,34 +82,30 @@ class _Plugin:
for attr in dir(self):
# noinspection PyUnboundLocalVariable
if (
- not (attr.startswith('_') or attr in _EXCLUDE_ATTRS)
- and
- isinstance(func := getattr(self, attr), MethodType)
- and
- (datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
+ not (attr.startswith("_") or attr in _EXCLUDE_ATTRS)
+ and isinstance(func := getattr(self, attr), MethodType)
+ and (datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
):
for data in datas:
- if data and data['type'] == 'error':
- result.update({func: data['block']})
+ if data and data["type"] == "error":
+ result.update({func: data["block"]})
return result
@property
def jobs(self) -> List[Job]:
from core.bot import bot
+
result = []
for attr in dir(self):
# noinspection PyUnboundLocalVariable
if (
- not (attr.startswith('_') or attr in _EXCLUDE_ATTRS)
- and
- isinstance(func := getattr(self, attr), MethodType)
- and
- (datas := getattr(func, _JOB_ATTR_NAME, None))
+ not (attr.startswith("_") or attr in _EXCLUDE_ATTRS)
+ and isinstance(func := getattr(self, attr), MethodType)
+ and (datas := getattr(func, _JOB_ATTR_NAME, None))
):
for data in datas:
- _job = getattr(bot.job_queue, data.pop('type'))(
- callback=func, **data.pop('kwargs'),
- **{key: data.pop(key) for key in list(data.keys())}
+ _job = getattr(bot.job_queue, data.pop("type"))(
+ callback=func, **data.pop("kwargs"), **{key: data.pop(key) for key in list(data.keys())}
)
result.append(_job)
return result
@@ -138,30 +129,27 @@ class _Conversation(_Plugin):
for attr in dir(self):
# noinspection PyUnboundLocalVariable
if (
- not (attr.startswith('_') or attr == 'handlers')
- and
- isinstance(func := getattr(self, attr), Callable)
- and
- (handler_datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
+ not (attr.startswith("_") or attr == "handlers")
+ and isinstance(func := getattr(self, attr), Callable)
+ and (handler_datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
):
_handlers = self._make_handler(handler_datas)
if conversation_data := getattr(func, _CONVERSATION_HANDLER_ATTR_NAME, None):
- if (_type := conversation_data.pop('type')) == 'entry':
+ if (_type := conversation_data.pop("type")) == "entry":
entry_points.extend(_handlers)
- elif _type == 'state':
- if (key := conversation_data.pop('state')) in states:
+ elif _type == "state":
+ if (key := conversation_data.pop("state")) in states:
states[key].extend(_handlers)
else:
states[key] = _handlers
- elif _type == 'fallback':
+ elif _type == "fallback":
fallbacks.extend(_handlers)
else:
result.extend(_handlers)
if entry_points or states or fallbacks:
result.append(
ConversationHandler(
- entry_points, states, fallbacks,
- **self.__class__._conversation_kwargs # pylint: disable=W0212
+ entry_points, states, fallbacks, **self.__class__._conversation_kwargs # pylint: disable=W0212
)
)
return result
@@ -180,7 +168,7 @@ class _Handler:
return getattr(_Module, f"{self.__class__.__name__.strip('_')}Handler")
def __call__(self, func: Callable[P, T]) -> Callable[P, T]:
- data = {'type': self._type, 'func': func.__name__, 'kwargs': self.kwargs}
+ data = {"type": self._type, "func": func.__name__, "kwargs": self.kwargs}
if hasattr(func, _NORMAL_HANDLER_ATTR_NAME):
handler_datas = getattr(func, _NORMAL_HANDLER_ATTR_NAME)
handler_datas.append(data)
@@ -192,9 +180,9 @@ class _Handler:
class _CallbackQuery(_Handler):
def __init__(
- self,
- pattern: Union[str, Pattern, type, Callable[[object], Optional[bool]]] = None,
- block: DVInput[bool] = DEFAULT_TRUE,
+ self,
+ pattern: Union[str, Pattern, type, Callable[[object], Optional[bool]]] = None,
+ block: DVInput[bool] = DEFAULT_TRUE,
):
super(_CallbackQuery, self).__init__(pattern=pattern, block=block)
@@ -221,10 +209,7 @@ class _Command(_Handler):
class _InlineQuery(_Handler):
def __init__(
- self,
- pattern: Union[str, Pattern] = None,
- block: DVInput[bool] = DEFAULT_TRUE,
- chat_types: List[str] = None
+ self, pattern: Union[str, Pattern] = None, block: DVInput[bool] = DEFAULT_TRUE, chat_types: List[str] = None
):
super().__init__(pattern=pattern, block=block, chat_types=chat_types)
@@ -237,7 +222,7 @@ class _MessageNewChatMembers(_Handler):
def __call__(self, func: Callable[P, T] = None) -> Callable[P, T]:
self.func = self.func or func
- data = {'type': 'new_chat_member', 'priority': self.priority}
+ data = {"type": "new_chat_member", "priority": self.priority}
if hasattr(func, _NORMAL_HANDLER_ATTR_NAME):
handler_datas = getattr(func, _NORMAL_HANDLER_ATTR_NAME)
handler_datas.append(data)
@@ -248,7 +233,11 @@ class _MessageNewChatMembers(_Handler):
class _Message(_Handler):
- def __init__(self, filters: "BaseFilter", block: DVInput[bool] = DEFAULT_TRUE, ):
+ def __init__(
+ self,
+ filters: "BaseFilter",
+ block: DVInput[bool] = DEFAULT_TRUE,
+ ):
super(_Message, self).__init__(filters=filters, block=block)
new_chat_members = _MessageNewChatMembers
@@ -271,11 +260,11 @@ class _PreCheckoutQuery(_Handler):
class _Prefix(_Handler):
def __init__(
- self,
- prefix: str,
- command: str,
- filters: BaseFilter = None,
- block: DVInput[bool] = DEFAULT_TRUE,
+ self,
+ prefix: str,
+ command: str,
+ filters: BaseFilter = None,
+ block: DVInput[bool] = DEFAULT_TRUE,
):
super(_Prefix, self).__init__(prefix=prefix, command=command, filters=filters, block=block)
@@ -298,10 +287,7 @@ class _StringRegex(_Handler):
class _Type(_Handler):
# noinspection PyShadowingBuiltins
def __init__(
- self,
- type: Type, # pylint: disable=redefined-builtin
- strict: bool = False,
- block: DVInput[bool] = DEFAULT_TRUE
+ self, type: Type, strict: bool = False, block: DVInput[bool] = DEFAULT_TRUE # pylint: disable=redefined-builtin
):
super(_Type, self).__init__(type=type, strict=strict, block=block)
@@ -342,7 +328,7 @@ class error_handler:
def __call__(self, func: Callable[P, T] = None) -> Callable[P, T]:
self._func = func or self._func
- data = {'type': 'error', 'block': self._block}
+ data = {"type": "error", "block": self._block}
if hasattr(func, _NORMAL_HANDLER_ATTR_NAME):
handler_datas = getattr(func, _NORMAL_HANDLER_ATTR_NAME)
handler_datas.append(data)
@@ -353,7 +339,7 @@ class error_handler:
def _entry(func: Callable[P, T]) -> Callable[P, T]:
- setattr(func, _CONVERSATION_HANDLER_ATTR_NAME, {'type': 'entry'})
+ setattr(func, _CONVERSATION_HANDLER_ATTR_NAME, {"type": "entry"})
return func
@@ -362,12 +348,12 @@ class _State:
self.state = state
def __call__(self, func: Callable[P, T] = None) -> Callable[P, T]:
- setattr(func, _CONVERSATION_HANDLER_ATTR_NAME, {'type': 'state', 'state': self.state})
+ setattr(func, _CONVERSATION_HANDLER_ATTR_NAME, {"type": "state", "state": self.state})
return func
def _fallback(func: Callable[P, T]) -> Callable[P, T]:
- setattr(func, _CONVERSATION_HANDLER_ATTR_NAME, {'type': 'fallback'})
+ setattr(func, _CONVERSATION_HANDLER_ATTR_NAME, {"type": "fallback"})
return func
@@ -382,8 +368,13 @@ class _Job:
kwargs: Dict = {}
def __init__(
- self, name: str = None, data: object = None, chat_id: int = None,
- user_id: int = None, job_kwargs: JSONDict = None, **kwargs
+ self,
+ name: str = None,
+ data: object = None,
+ chat_id: int = None,
+ user_id: int = None,
+ job_kwargs: JSONDict = None,
+ **kwargs,
):
self.name = name
self.data = data
@@ -394,9 +385,13 @@ class _Job:
def __call__(self, func: JobCallback) -> JobCallback:
data = {
- 'name': self.name, 'data': self.data, 'chat_id': self.chat_id, 'user_id': self.user_id,
- 'job_kwargs': self.job_kwargs, 'kwargs': self.kwargs,
- 'type': re.sub(r'([A-Z])', lambda x: '_' + x.group().lower(), self.__class__.__name__).lstrip('_')
+ "name": self.name,
+ "data": self.data,
+ "chat_id": self.chat_id,
+ "user_id": self.user_id,
+ "job_kwargs": self.job_kwargs,
+ "kwargs": self.kwargs,
+ "type": re.sub(r"([A-Z])", lambda x: "_" + x.group().lower(), self.__class__.__name__).lstrip("_"),
}
if hasattr(func, _JOB_ATTR_NAME):
job_datas = getattr(func, _JOB_ATTR_NAME)
@@ -409,39 +404,69 @@ class _Job:
class _RunOnce(_Job):
def __init__(
- self, when: TimeType,
- data: object = None, name: str = None, chat_id: int = None, user_id: int = None, job_kwargs: JSONDict = None
+ self,
+ when: TimeType,
+ data: object = None,
+ name: str = None,
+ chat_id: int = None,
+ user_id: int = None,
+ job_kwargs: JSONDict = None,
):
super().__init__(name, data, chat_id, user_id, job_kwargs, when=when)
class _RunRepeating(_Job):
def __init__(
- self, interval: Union[float, datetime.timedelta], first: TimeType = None, last: TimeType = None,
- data: object = None, name: str = None, chat_id: int = None, user_id: int = None, job_kwargs: JSONDict = None
+ self,
+ interval: Union[float, datetime.timedelta],
+ first: TimeType = None,
+ last: TimeType = None,
+ data: object = None,
+ name: str = None,
+ chat_id: int = None,
+ user_id: int = None,
+ job_kwargs: JSONDict = None,
):
super().__init__(name, data, chat_id, user_id, job_kwargs, interval=interval, first=first, last=last)
class _RunMonthly(_Job):
def __init__(
- self, when: datetime.time, day: int,
- data: object = None, name: str = None, chat_id: int = None, user_id: int = None, job_kwargs: JSONDict = None
+ self,
+ when: datetime.time,
+ day: int,
+ data: object = None,
+ name: str = None,
+ chat_id: int = None,
+ user_id: int = None,
+ job_kwargs: JSONDict = None,
):
super().__init__(name, data, chat_id, user_id, job_kwargs, when=when, day=day)
class _RunDaily(_Job):
def __init__(
- self, time: datetime.time, days: Tuple[int, ...] = tuple(range(7)),
- data: object = None, name: str = None, chat_id: int = None, user_id: int = None, job_kwargs: JSONDict = None
+ self,
+ time: datetime.time,
+ days: Tuple[int, ...] = tuple(range(7)),
+ data: object = None,
+ name: str = None,
+ chat_id: int = None,
+ user_id: int = None,
+ job_kwargs: JSONDict = None,
):
super().__init__(name, data, chat_id, user_id, job_kwargs, time=time, days=days)
class _RunCustom(_Job):
- def __init__(self, data: object = None, name: str = None, chat_id: int = None, user_id: int = None,
- job_kwargs: JSONDict = None):
+ def __init__(
+ self,
+ data: object = None,
+ name: str = None,
+ chat_id: int = None,
+ user_id: int = None,
+ job_kwargs: JSONDict = None,
+ ):
super().__init__(name, data, chat_id, user_id, job_kwargs)
diff --git a/core/quiz/cache.py b/core/quiz/cache.py
index 61cd209..867d87c 100644
--- a/core/quiz/cache.py
+++ b/core/quiz/cache.py
@@ -7,7 +7,6 @@ from .models import Answer, Question
class QuizCache:
-
def __init__(self, redis: RedisDB):
self.client = redis.client
self.question_qname = "quiz:question"
@@ -16,8 +15,7 @@ class QuizCache:
async def get_all_question(self) -> List[Question]:
temp_list = []
qname = self.question_qname + "id_list"
- data_list = [self.question_qname + f":{question_id}" for question_id in
- await self.client.lrange(qname, 0, -1)]
+ data_list = [self.question_qname + f":{question_id}" for question_id in await self.client.lrange(qname, 0, -1)]
data = await self.client.mget(data_list)
for i in data:
temp_list.append(Question.de_json(ujson.loads(i)))
diff --git a/core/quiz/models.py b/core/quiz/models.py
index 982f7a4..ad41a38 100644
--- a/core/quiz/models.py
+++ b/core/quiz/models.py
@@ -7,23 +7,20 @@ from utils.typedefs import JSONDict
class AnswerDB(SQLModel, table=True):
- __tablename__ = 'answer'
- __table_args__ = dict(mysql_charset='utf8mb4', mysql_collate="utf8mb4_general_ci")
+ __tablename__ = "answer"
+ __table_args__ = dict(mysql_charset="utf8mb4", mysql_collate="utf8mb4_general_ci")
id: int = Field(primary_key=True)
question_id: Optional[int] = Field(
- sa_column=Column(
- Integer,
- ForeignKey("question.id", ondelete="RESTRICT", onupdate="RESTRICT")
- )
+ sa_column=Column(Integer, ForeignKey("question.id", ondelete="RESTRICT", onupdate="RESTRICT"))
)
is_correct: Optional[bool] = Field()
text: Optional[str] = Field()
class QuestionDB(SQLModel, table=True):
- __tablename__ = 'question'
- __table_args__ = dict(mysql_charset='utf8mb4', mysql_collate="utf8mb4_general_ci")
+ __tablename__ = "question"
+ __table_args__ = dict(mysql_charset="utf8mb4", mysql_collate="utf8mb4_general_ci")
id: int = Field(primary_key=True)
text: Optional[str] = Field()
diff --git a/core/service.py b/core/service.py
index 1085a9f..a7e02a4 100644
--- a/core/service.py
+++ b/core/service.py
@@ -3,7 +3,7 @@ from types import FunctionType
from utils.log import logger
-__all__ = ['Service', 'init_service']
+__all__ = ["Service", "init_service"]
class Service(ABC):
@@ -20,11 +20,12 @@ class Service(ABC):
def init_service(func: FunctionType):
from core.bot import bot
+
if bot.is_running:
try:
service = bot.init_inject(func)
logger.success(f'服务 "{service.__class__.__name__}" 初始化成功')
bot.add_service(service)
except Exception as e: # pylint: disable=W0703
- logger.exception(f'来自{func.__module__}的服务初始化失败:{e}')
+ logger.exception(f"来自{func.__module__}的服务初始化失败:{e}")
return func
diff --git a/core/sign/models.py b/core/sign/models.py
index 6f9d8c6..4a46aec 100644
--- a/core/sign/models.py
+++ b/core/sign/models.py
@@ -18,7 +18,7 @@ class SignStatusEnum(int, enum.Enum):
class Sign(SQLModel, table=True):
- __table_args__ = dict(mysql_charset='utf8mb4', mysql_collate="utf8mb4_general_ci")
+ __table_args__ = dict(mysql_charset="utf8mb4", mysql_collate="utf8mb4_general_ci")
id: int = Field(primary_key=True)
user_id: int = Field(foreign_key="user.user_id")
diff --git a/core/template/services.py b/core/template/services.py
index 119910e..a9f459d 100644
--- a/core/template/services.py
+++ b/core/template/services.py
@@ -53,9 +53,16 @@ class TemplateService:
logger.debug(f"{template_name} 模板渲染使用了 {str(time.time() - start_time)}")
return html
- async def render(self, template_path: str, template_name: str, template_data: dict,
- viewport: ViewportSize = None, full_page: bool = True, evaluate: Optional[str] = None,
- query_selector: str = None) -> bytes:
+ async def render(
+ self,
+ template_path: str,
+ template_name: str,
+ template_data: dict,
+ viewport: ViewportSize = None,
+ full_page: bool = True,
+ evaluate: Optional[str] = None,
+ query_selector: str = None,
+ ) -> bytes:
"""模板渲染成图片
:param template_path: 模板目录
:param template_name: 模板文件名
diff --git a/core/user/models.py b/core/user/models.py
index 94d8157..f796b9d 100644
--- a/core/user/models.py
+++ b/core/user/models.py
@@ -6,7 +6,7 @@ from utils.models.base import RegionEnum
class User(SQLModel, table=True):
- __table_args__ = dict(mysql_charset='utf8mb4', mysql_collate="utf8mb4_general_ci")
+ __table_args__ = dict(mysql_charset="utf8mb4", mysql_collate="utf8mb4_general_ci")
id: int = Field(primary_key=True)
user_id: int = Field(unique=True)
diff --git a/core/user/repositories.py b/core/user/repositories.py
index 694775c..8b149d2 100644
--- a/core/user/repositories.py
+++ b/core/user/repositories.py
@@ -33,4 +33,4 @@ class UserRepository:
async with self.mysql.Session() as session:
session = cast(AsyncSession, session)
session.add(user)
- await session.commit()
\ No newline at end of file
+ await session.commit()
diff --git a/core/user/services.py b/core/user/services.py
index f7a5ca8..6e89d05 100644
--- a/core/user/services.py
+++ b/core/user/services.py
@@ -3,7 +3,6 @@ from .repositories import UserRepository
class UserService:
-
def __init__(self, user_repository: UserRepository) -> None:
self._repository: UserRepository = user_repository
diff --git a/core/wiki/services.py b/core/wiki/services.py
index 31c953d..891fc08 100644
--- a/core/wiki/services.py
+++ b/core/wiki/services.py
@@ -7,7 +7,6 @@ from utils.log import logger
class WikiService:
-
def __init__(self, cache: WikiCache):
self._cache = cache
"""Redis 在这里的作用是作为持久化"""
diff --git a/metadata/pool/pool_200.py b/metadata/pool/pool_200.py
index 004e4a1..3bc8339 100644
--- a/metadata/pool/pool_200.py
+++ b/metadata/pool/pool_200.py
@@ -1,11 +1 @@
-POOL_200 = [
- {
- "five": [
- "常驻池"
- ],
- "four": [],
- "from": "2020-09-15 06:00:00",
- "name": "常驻池",
- "to": "2050-09-15 17:59:59"
- }
-]
\ No newline at end of file
+POOL_200 = [{"five": ["常驻池"], "four": [], "from": "2020-09-15 06:00:00", "name": "常驻池", "to": "2050-09-15 17:59:59"}]
diff --git a/metadata/pool/pool_301.py b/metadata/pool/pool_301.py
index d975790..c1ee55f 100644
--- a/metadata/pool/pool_301.py
+++ b/metadata/pool/pool_301.py
@@ -1,480 +1,254 @@
POOL_301 = [
{
- "five": [
- "赛诺",
- "温迪"
- ],
- "four": [
- "久岐忍",
- "早柚",
- "坎蒂丝"
- ],
+ "five": ["赛诺", "温迪"],
+ "four": ["久岐忍", "早柚", "坎蒂丝"],
"from": "2022-09-28 06:00:00",
"name": "劈裁冥昭|杯装之诗",
- "to": "2022-10-14 17:59:59"
+ "to": "2022-10-14 17:59:59",
},
{
- "five": [
- "甘雨",
- "心海"
- ],
- "four": [
- "行秋",
- "砂糖",
- "多莉"
- ],
+ "five": ["甘雨", "心海"],
+ "four": ["行秋", "砂糖", "多莉"],
"from": "2022-09-09 18:00:00",
"name": "浮生孰来|浮岳虹珠",
- "to": "2022-09-27 14:59:59"
+ "to": "2022-09-27 14:59:59",
},
{
- "five": [
- "提纳里",
- "钟离"
- ],
- "four": [
- "云堇",
- "辛焱",
- "班尼特"
- ],
+ "five": ["提纳里", "钟离"],
+ "four": ["云堇", "辛焱", "班尼特"],
"from": "2022-08-24 06:00:00",
"name": "巡御蘙荟|陵薮市朝",
- "to": "2022-09-09 17:59:59"
+ "to": "2022-09-09 17:59:59",
},
{
- "five": [
- "宵宫"
- ],
- "four": [
- "云堇",
- "辛焱",
- "班尼特"
- ],
+ "five": ["宵宫"],
+ "four": ["云堇", "辛焱", "班尼特"],
"from": "2022-08-02 18:00:00",
"name": "焰色天河",
- "to": "2022-08-23 14:59:59"
+ "to": "2022-08-23 14:59:59",
},
{
- "five": [
- "枫原万叶",
- "可莉"
- ],
- "four": [
- "凝光",
- "鹿野院平藏",
- "托马"
- ],
+ "five": ["枫原万叶", "可莉"],
+ "four": ["凝光", "鹿野院平藏", "托马"],
"from": "2022-07-13 06:00:00",
"name": "红叶逐荒波",
- "to": "2022-08-02 17:59:59"
+ "to": "2022-08-02 17:59:59",
},
{
- "five": [
- "荒泷一斗"
- ],
- "four": [
- "烟绯",
- "芭芭拉",
- "诺艾尔"
- ],
+ "five": ["荒泷一斗"],
+ "four": ["烟绯", "芭芭拉", "诺艾尔"],
"from": "2022-06-21 18:00:00",
"name": "鬼门斗宴",
- "to": "2022-07-12 14:59:59"
+ "to": "2022-07-12 14:59:59",
},
{
- "five": [
- "夜兰",
- "魈"
- ],
- "four": [
- "烟绯",
- "芭芭拉",
- "诺艾尔"
- ],
+ "five": ["夜兰", "魈"],
+ "four": ["烟绯", "芭芭拉", "诺艾尔"],
"from": "2022-05-31 06:00:00",
"name": "素霓伣天|烟火之邀",
- "to": "2022-06-21 17:59:59"
+ "to": "2022-06-21 17:59:59",
},
{
- "five": [
- "神里绫华"
- ],
- "four": [
- "罗莎莉亚",
- "早柚",
- "雷泽"
- ],
+ "five": ["神里绫华"],
+ "four": ["罗莎莉亚", "早柚", "雷泽"],
"from": "2022-04-19 17:59:59",
"name": "白鹭之庭",
- "to": "2022-05-31 05:59:59"
+ "to": "2022-05-31 05:59:59",
},
{
- "five": [
- "神里绫人",
- "温迪"
- ],
- "four": [
- "香菱",
- "砂糖",
- "云堇"
- ],
+ "five": ["神里绫人", "温迪"],
+ "four": ["香菱", "砂糖", "云堇"],
"from": "2022-03-30 06:00:00",
"name": "苍流踏花|杯装之诗",
- "to": "2022-04-19 17:59:59"
+ "to": "2022-04-19 17:59:59",
},
{
- "five": [
- "雷电将军",
- "珊瑚宫心海"
- ],
- "four": [
- "辛焱",
- "九条裟罗",
- "班尼特"
- ],
+ "five": ["雷电将军", "珊瑚宫心海"],
+ "four": ["辛焱", "九条裟罗", "班尼特"],
"from": "2022-03-08 18:00:00",
"name": "影寂天下人|浮岳虹珠",
- "to": "2022-03-29 14:59:59"
+ "to": "2022-03-29 14:59:59",
},
{
- "five": [
- "八重神子"
- ],
- "four": [
- "菲谢尔",
- "迪奥娜",
- "托马"
- ],
+ "five": ["八重神子"],
+ "four": ["菲谢尔", "迪奥娜", "托马"],
"from": "2022-02-16 06:00:00",
"name": "华紫樱绯",
- "to": "2022-03-08 17:59:59"
+ "to": "2022-03-08 17:59:59",
},
{
- "five": [
- "甘雨",
- "钟离"
- ],
- "four": [
- "行秋",
- "北斗",
- "烟绯"
- ],
+ "five": ["甘雨", "钟离"],
+ "four": ["行秋", "北斗", "烟绯"],
"from": "2022-01-25 18:00:00",
"name": "浮生孰来|陵薮市朝",
- "to": "2022-02-15 14:59:59"
+ "to": "2022-02-15 14:59:59",
},
{
- "five": [
- "申鹤",
- "魈"
- ],
- "four": [
- "云堇",
- "凝光",
- "重云"
- ],
+ "five": ["申鹤", "魈"],
+ "four": ["云堇", "凝光", "重云"],
"from": "2022-01-05 06:00:00",
"name": "出尘入世|烟火之邀",
- "to": "2022-01-25 17:59:59"
+ "to": "2022-01-25 17:59:59",
},
{
- "five": [
- "荒泷一斗"
- ],
- "four": [
- "五郎",
- "芭芭拉",
- "香菱"
- ],
+ "five": ["荒泷一斗"],
+ "four": ["五郎", "芭芭拉", "香菱"],
"from": "2021-12-14 18:00:00",
"name": "鬼门斗宴",
- "to": "2022-01-04 14:59:59"
+ "to": "2022-01-04 14:59:59",
},
{
- "five": [
- "阿贝多",
- "优菈"
- ],
- "four": [
- "班尼特",
- "诺艾尔",
- "罗莎莉亚"
- ],
+ "five": ["阿贝多", "优菈"],
+ "four": ["班尼特", "诺艾尔", "罗莎莉亚"],
"from": "2021-11-24 06:00:00",
"name": "深秘之息|浪涌之瞬",
- "to": "2021-12-14 17:59:59"
+ "to": "2021-12-14 17:59:59",
},
{
- "five": [
- "胡桃"
- ],
- "four": [
- "托马",
- "迪奥娜",
- "早柚"
- ],
+ "five": ["胡桃"],
+ "four": ["托马", "迪奥娜", "早柚"],
"from": "2021-11-02 18:00:00",
"name": "赤团开时",
- "to": "2021-11-23 14:59:59"
+ "to": "2021-11-23 14:59:59",
},
{
- "five": [
- "达达利亚"
- ],
- "four": [
- "凝光",
- "重云",
- "烟绯"
- ],
+ "five": ["达达利亚"],
+ "four": ["凝光", "重云", "烟绯"],
"from": "2021-10-13 06:00:00",
"name": "暂别冬都",
- "to": "2021-11-02 17:59:59"
+ "to": "2021-11-02 17:59:59",
},
{
- "five": [
- "珊瑚宫心海"
- ],
- "four": [
- "罗莎莉亚",
- "北斗",
- "行秋"
- ],
+ "five": ["珊瑚宫心海"],
+ "four": ["罗莎莉亚", "北斗", "行秋"],
"from": "2021-09-21 18:00:00",
"name": "浮岳虹珠",
- "to": "2021-10-12 14:59:59"
+ "to": "2021-10-12 14:59:59",
},
{
- "five": [
- "雷电将军"
- ],
- "four": [
- "九条裟罗",
- "香菱",
- "砂糖"
- ],
+ "five": ["雷电将军"],
+ "four": ["九条裟罗", "香菱", "砂糖"],
"from": "2021-09-01 06:00:00",
"name": "影寂天下人",
- "to": "2021-09-21 17:59:59"
+ "to": "2021-09-21 17:59:59",
},
{
- "five": [
- "宵宫"
- ],
- "four": [
- "早柚",
- "迪奥娜",
- "辛焱"
- ],
+ "five": ["宵宫"],
+ "four": ["早柚", "迪奥娜", "辛焱"],
"from": "2021-08-10 18:00:00",
"name": "焰色天河",
- "to": "2021-08-31 14:59:59"
+ "to": "2021-08-31 14:59:59",
},
{
- "five": [
- "神里绫华"
- ],
- "four": [
- "凝光",
- "重云",
- "烟绯"
- ],
+ "five": ["神里绫华"],
+ "four": ["凝光", "重云", "烟绯"],
"from": "2021-07-21 06:00:00",
"name": "白鹭之庭",
- "to": "2021-08-10 17:59:59"
+ "to": "2021-08-10 17:59:59",
},
{
- "five": [
- "枫原万叶"
- ],
- "four": [
- "罗莎莉亚",
- "班尼特",
- "雷泽"
- ],
+ "five": ["枫原万叶"],
+ "four": ["罗莎莉亚", "班尼特", "雷泽"],
"from": "2021-06-29 18:00:00",
"name": "红叶逐荒波",
- "to": "2021-07-20 14:59:59"
+ "to": "2021-07-20 14:59:59",
},
{
- "five": [
- "可莉"
- ],
- "four": [
- "芭芭拉",
- "砂糖",
- "菲谢尔"
- ],
+ "five": ["可莉"],
+ "four": ["芭芭拉", "砂糖", "菲谢尔"],
"from": "2021-06-09 06:00:00",
"name": "逃跑的太阳",
- "to": "2021-06-29 17:59:59"
+ "to": "2021-06-29 17:59:59",
},
{
- "five": [
- "优菈"
- ],
- "four": [
- "辛焱",
- "行秋",
- "北斗"
- ],
+ "five": ["优菈"],
+ "four": ["辛焱", "行秋", "北斗"],
"from": "2021-05-18 18:00:00",
"name": "浪沫的旋舞",
- "to": "2021-06-08 14:59:59"
+ "to": "2021-06-08 14:59:59",
},
{
- "five": [
- "钟离"
- ],
- "four": [
- "烟绯",
- "诺艾尔",
- "迪奥娜"
- ],
+ "five": ["钟离"],
+ "four": ["烟绯", "诺艾尔", "迪奥娜"],
"from": "2021-04-28 06:00:00",
"name": "陵薮市朝",
- "to": "2021-05-18 17:59:59"
+ "to": "2021-05-18 17:59:59",
},
{
- "five": [
- "达达利亚"
- ],
- "four": [
- "罗莎莉亚",
- "芭芭拉",
- "菲谢尔"
- ],
+ "five": ["达达利亚"],
+ "four": ["罗莎莉亚", "芭芭拉", "菲谢尔"],
"from": "2021-04-06 18:00:00",
"name": "暂别冬都",
- "to": "2021-04-27 14:59:59"
+ "to": "2021-04-27 14:59:59",
},
{
- "five": [
- "温迪"
- ],
- "four": [
- "砂糖",
- "雷泽",
- "诺艾尔"
- ],
+ "five": ["温迪"],
+ "four": ["砂糖", "雷泽", "诺艾尔"],
"from": "2021-03-17 06:00:00",
"name": "杯装之诗",
- "to": "2021-04-06 15:59:59"
+ "to": "2021-04-06 15:59:59",
},
{
- "five": [
- "胡桃"
- ],
- "four": [
- "行秋",
- "香菱",
- "重云"
- ],
+ "five": ["胡桃"],
+ "four": ["行秋", "香菱", "重云"],
"from": "2021-03-02 18:00:00",
"name": "赤团开时",
- "to": "2021-03-16 14:59:59"
+ "to": "2021-03-16 14:59:59",
},
{
- "five": [
- "刻晴"
- ],
- "four": [
- "凝光",
- "班尼特",
- "芭芭拉"
- ],
+ "five": ["刻晴"],
+ "four": ["凝光", "班尼特", "芭芭拉"],
"from": "2021-02-17 18:00:00",
"name": "鱼龙灯昼",
- "to": "2021-03-02 15:59:59"
+ "to": "2021-03-02 15:59:59",
},
{
- "five": [
- "魈"
- ],
- "four": [
- "迪奥娜",
- "北斗",
- "辛焱"
- ],
+ "five": ["魈"],
+ "four": ["迪奥娜", "北斗", "辛焱"],
"from": "2021-02-03 06:00:00",
"name": "烟火之邀",
- "to": "2021-02-17 15:59:59"
+ "to": "2021-02-17 15:59:59",
},
{
- "five": [
- "甘雨"
- ],
- "four": [
- "香菱",
- "行秋",
- "诺艾尔"
- ],
+ "five": ["甘雨"],
+ "four": ["香菱", "行秋", "诺艾尔"],
"from": "2021-01-12 18:00:00",
"name": "浮生孰来",
- "to": "2021-02-02 14:59:59"
+ "to": "2021-02-02 14:59:59",
},
{
- "five": [
- "阿贝多"
- ],
- "four": [
- "菲谢尔",
- "砂糖",
- "班尼特"
- ],
+ "five": ["阿贝多"],
+ "four": ["菲谢尔", "砂糖", "班尼特"],
"from": "2020-12-23 06:00:00",
"name": "深秘之息",
- "to": "2021-01-12 15:59:59"
+ "to": "2021-01-12 15:59:59",
},
{
- "five": [
- "钟离"
- ],
- "four": [
- "辛焱",
- "雷泽",
- "重云"
- ],
+ "five": ["钟离"],
+ "four": ["辛焱", "雷泽", "重云"],
"from": "2020-12-01 18:00:00",
"name": "陵薮市朝",
- "to": "2020-12-22 14:59:59"
+ "to": "2020-12-22 14:59:59",
},
{
- "five": [
- "达达利亚"
- ],
- "four": [
- "迪奥娜",
- "北斗",
- "凝光"
- ],
+ "five": ["达达利亚"],
+ "four": ["迪奥娜", "北斗", "凝光"],
"from": "2020-11-11 06:00:00",
"name": "暂别冬都",
- "to": "2020-12-01 15:59:59"
+ "to": "2020-12-01 15:59:59",
},
{
- "five": [
- "可莉"
- ],
- "four": [
- "行秋",
- "诺艾尔",
- "砂糖"
- ],
+ "five": ["可莉"],
+ "four": ["行秋", "诺艾尔", "砂糖"],
"from": "2020-10-20 18:00:00",
"name": "闪焰的驻足",
- "to": "2020-11-10 14:59:59"
+ "to": "2020-11-10 14:59:59",
},
{
- "five": [
- "温迪"
- ],
- "four": [
- "芭芭拉",
- "菲谢尔",
- "香菱"
- ],
+ "five": ["温迪"],
+ "four": ["芭芭拉", "菲谢尔", "香菱"],
"from": "2020-9-28 06:00:00",
"name": "杯装之诗",
- "to": "2020-10-18 17:59:59"
- }
-]
\ No newline at end of file
+ "to": "2020-10-18 17:59:59",
+ },
+]
diff --git a/metadata/pool/pool_302.py b/metadata/pool/pool_302.py
index 4653e89..5c04b2c 100644
--- a/metadata/pool/pool_302.py
+++ b/metadata/pool/pool_302.py
@@ -1,562 +1,247 @@
POOL_302 = [
{
- "five": [
- "赤沙之杖",
- "终末嗟叹之诗"
- ],
- "four": [
- "匣里龙吟",
- "玛海菈的水色",
- "西风长枪",
- "祭礼残章",
- "西风猎弓"
- ],
+ "five": ["赤沙之杖", "终末嗟叹之诗"],
+ "four": ["匣里龙吟", "玛海菈的水色", "西风长枪", "祭礼残章", "西风猎弓"],
"from": "2022-09-28 06:00:00",
"name": "神铸赋形",
- "to": "2022-10-14 17:59:59"
+ "to": "2022-10-14 17:59:59",
},
{
- "five": [
- "阿莫斯之弓",
- "不灭月华"
- ],
- "four": [
- "祭礼剑",
- "西风大剑",
- "匣里灭辰",
- "昭心",
- "弓藏"
- ],
+ "five": ["阿莫斯之弓", "不灭月华"],
+ "four": ["祭礼剑", "西风大剑", "匣里灭辰", "昭心", "弓藏"],
"from": "2022-09-09 18:00:00",
"name": "神铸赋形",
- "to": "2022-09-27 14:59:59"
+ "to": "2022-09-27 14:59:59",
},
{
- "five": [
- "猎人之径",
- "贯虹之槊"
- ],
- "four": [
- "西风剑",
- "钟剑",
- "西风长枪",
- "西风秘典",
- "绝弦"
- ],
+ "five": ["猎人之径", "贯虹之槊"],
+ "four": ["西风剑", "钟剑", "西风长枪", "西风秘典", "绝弦"],
"from": "2022-08-24 06:00:00",
"name": "神铸赋形",
- "to": "2022-09-09 17:59:59"
+ "to": "2022-09-09 17:59:59",
},
{
- "five": [
- "飞雷之弦振",
- "斫峰之刃"
- ],
- "four": [
- "暗巷的酒与诗",
- "暗巷猎手",
- "笛剑",
- "祭礼大剑",
- "匣里灭辰"
- ],
+ "five": ["飞雷之弦振", "斫峰之刃"],
+ "four": ["暗巷的酒与诗", "暗巷猎手", "笛剑", "祭礼大剑", "匣里灭辰"],
"from": "2022-08-02 18:00:00",
"name": "神铸赋形",
- "to": "2022-08-23 14:59:59"
+ "to": "2022-08-23 14:59:59",
},
{
- "five": [
- "苍古自由之誓",
- "四风原典"
- ],
- "four": [
- "千岩古剑",
- "匣里龙吟",
- "匣里灭辰",
- "祭礼残章",
- "绝弦"
- ],
+ "five": ["苍古自由之誓", "四风原典"],
+ "four": ["千岩古剑", "匣里龙吟", "匣里灭辰", "祭礼残章", "绝弦"],
"from": "2022-07-13 06:00:00",
"name": "神铸赋形",
- "to": "2022-08-02 17:59:59"
+ "to": "2022-08-02 17:59:59",
},
{
- "five": [
- "赤角石溃杵",
- "尘世之锁"
- ],
- "four": [
- "千岩古剑",
- "匣里龙吟",
- "匣里灭辰",
- "祭礼残章",
- "绝弦"
- ],
+ "five": ["赤角石溃杵", "尘世之锁"],
+ "four": ["千岩古剑", "匣里龙吟", "匣里灭辰", "祭礼残章", "绝弦"],
"from": "2022-06-21 18:00:00",
"name": "神铸赋形",
- "to": "2022-07-12 14:59:59"
+ "to": "2022-07-12 14:59:59",
},
{
- "five": [
- "若水",
- "和璞鸢"
- ],
- "four": [
- "千岩长枪",
- "祭礼剑",
- "西风大剑",
- "昭心",
- "祭礼弓"
- ],
+ "five": ["若水", "和璞鸢"],
+ "four": ["千岩长枪", "祭礼剑", "西风大剑", "昭心", "祭礼弓"],
"from": "2022-05-31 06:00:00",
"name": "神铸赋形",
- "to": "2022-06-21 17:59:59"
+ "to": "2022-06-21 17:59:59",
},
{
- "five": [
- "雾切之回光",
- "无工之剑"
- ],
- "four": [
- "西风剑",
- "钟剑",
- "西风长枪",
- "西风秘典",
- "西风猎弓"
- ],
+ "five": ["雾切之回光", "无工之剑"],
+ "four": ["西风剑", "钟剑", "西风长枪", "西风秘典", "西风猎弓"],
"from": "2022-04-19 17:59:59",
"name": "神铸赋形",
- "to": "2022-05-31 05:59:59"
+ "to": "2022-05-31 05:59:59",
},
{
- "five": [
- "波乱月白经津",
- "终末嗟叹之诗"
- ],
- "four": [
- "弓藏",
- "笛剑",
- "流浪乐章",
- "匣里灭辰",
- "祭礼大剑"
- ],
+ "five": ["波乱月白经津", "终末嗟叹之诗"],
+ "four": ["弓藏", "笛剑", "流浪乐章", "匣里灭辰", "祭礼大剑"],
"from": "2022-03-30 06:00:00",
"name": "神铸赋形",
- "to": "2022-04-19 17:59:59"
+ "to": "2022-04-19 17:59:59",
},
{
- "five": [
- "薙草之稻光",
- "不灭月华"
- ],
- "four": [
- "恶王丸",
- "曚云之月",
- "匣里龙吟",
- "西风长枪",
- "祭礼残章"
- ],
+ "five": ["薙草之稻光", "不灭月华"],
+ "four": ["恶王丸", "曚云之月", "匣里龙吟", "西风长枪", "祭礼残章"],
"from": "2022-03-08 18:00:00",
"name": "神铸赋形",
- "to": "2022-03-29 14:59:59"
+ "to": "2022-03-29 14:59:59",
},
{
- "five": [
- "神乐之真意",
- "磐岩结绿"
- ],
- "four": [
- "祭礼剑",
- "雨裁",
- "断浪长鳍",
- "昭心",
- "绝弦"
- ],
+ "five": ["神乐之真意", "磐岩结绿"],
+ "four": ["祭礼剑", "雨裁", "断浪长鳍", "昭心", "绝弦"],
"from": "2022-02-16 06:00:00",
"name": "神铸赋形",
- "to": "2022-03-08 17:59:59"
+ "to": "2022-03-08 17:59:59",
},
{
- "five": [
- "贯虹之槊",
- "阿莫斯之弓"
- ],
- "four": [
- "西风剑",
- "千岩古剑",
- "匣里灭辰",
- "西风秘典",
- "祭礼弓"
- ],
+ "five": ["贯虹之槊", "阿莫斯之弓"],
+ "four": ["西风剑", "千岩古剑", "匣里灭辰", "西风秘典", "祭礼弓"],
"from": "2022-01-25 18:00:00",
"name": "神铸赋形",
- "to": "2022-02-15 14:59:59"
+ "to": "2022-02-15 14:59:59",
},
{
- "five": [
- "息灾",
- "和璞鸢"
- ],
- "four": [
- "笛剑",
- "西风大剑",
- "千岩长枪",
- "流浪乐章",
- "西风猎弓"
- ],
+ "five": ["息灾", "和璞鸢"],
+ "four": ["笛剑", "西风大剑", "千岩长枪", "流浪乐章", "西风猎弓"],
"from": "2022-01-05 06:00:00",
"name": "神铸赋形",
- "to": "2022-01-25 17:59:59"
+ "to": "2022-01-25 17:59:59",
},
{
- "five": [
- "赤角石溃杵",
- "天空之翼"
- ],
- "four": [
- "暗巷闪光",
- "钟剑",
- "西风长枪",
- "祭礼残章",
- "幽夜华尔兹"
- ],
+ "five": ["赤角石溃杵", "天空之翼"],
+ "four": ["暗巷闪光", "钟剑", "西风长枪", "祭礼残章", "幽夜华尔兹"],
"from": "2021-12-14 18:00:00",
"name": "神铸赋形",
- "to": "2022-01-04 14:59:59"
+ "to": "2022-01-04 14:59:59",
},
{
- "five": [
- "苍古自由之誓",
- "松籁响起之时"
- ],
- "four": [
- "匣里龙吟",
- "祭礼大剑",
- "匣里灭辰",
- "暗巷的酒与诗",
- "暗巷猎手"
- ],
+ "five": ["苍古自由之誓", "松籁响起之时"],
+ "four": ["匣里龙吟", "祭礼大剑", "匣里灭辰", "暗巷的酒与诗", "暗巷猎手"],
"from": "2021-11-24 06:00:00",
"name": "神铸赋形",
- "to": "2021-12-14 17:59:59"
+ "to": "2021-12-14 17:59:59",
},
{
- "five": [
- "护摩之杖",
- "终末嗟叹之诗"
- ],
- "four": [
- "祭礼剑",
- "雨裁",
- "断浪长鳍",
- "流浪乐章",
- "曚云之月"
- ],
+ "five": ["护摩之杖", "终末嗟叹之诗"],
+ "four": ["祭礼剑", "雨裁", "断浪长鳍", "流浪乐章", "曚云之月"],
"from": "2021-11-02 18:00:00",
"name": "神铸赋形",
- "to": "2021-11-23 14:59:59"
+ "to": "2021-11-23 14:59:59",
},
{
- "five": [
- "冬极白星",
- "尘世之锁"
- ],
- "four": [
- "西风剑",
- "恶王丸",
- "西风长枪",
- "昭心",
- "弓藏"
- ],
+ "five": ["冬极白星", "尘世之锁"],
+ "four": ["西风剑", "恶王丸", "西风长枪", "昭心", "弓藏"],
"from": "2021-10-13 06:00:00",
"name": "神铸赋形",
- "to": "2021-11-02 17:59:59"
+ "to": "2021-11-02 17:59:59",
},
{
- "five": [
- "不灭月华",
- "磐岩结绿"
- ],
- "four": [
- "笛剑",
- "西风大剑",
- "匣里灭辰",
- "西风秘典",
- "绝弦"
- ],
+ "five": ["不灭月华", "磐岩结绿"],
+ "four": ["笛剑", "西风大剑", "匣里灭辰", "西风秘典", "绝弦"],
"from": "2021-09-21 18:00:00",
"name": "神铸赋形",
- "to": "2021-10-12 14:59:59"
+ "to": "2021-10-12 14:59:59",
},
{
- "five": [
- "薙草之稻光",
- "无工之剑"
- ],
- "four": [
- "匣里龙吟",
- "钟剑",
- "西风长枪",
- "流浪乐章",
- "祭礼弓"
- ],
+ "five": ["薙草之稻光", "无工之剑"],
+ "four": ["匣里龙吟", "钟剑", "西风长枪", "流浪乐章", "祭礼弓"],
"from": "2021-09-01 06:00:00",
"name": "神铸赋形",
- "to": "2021-09-21 17:59:59"
+ "to": "2021-09-21 17:59:59",
},
{
- "five": [
- "飞雷之弦振",
- "天空之刃"
- ],
- "four": [
- "祭礼剑",
- "雨裁",
- "匣里灭辰",
- "祭礼残章",
- "西风猎弓"
- ],
+ "five": ["飞雷之弦振", "天空之刃"],
+ "four": ["祭礼剑", "雨裁", "匣里灭辰", "祭礼残章", "西风猎弓"],
"from": "2021-08-10 18:00:00",
"name": "神铸赋形",
- "to": "2021-08-31 14:59:59"
+ "to": "2021-08-31 14:59:59",
},
{
- "five": [
- "雾切之回光",
- "天空之脊"
- ],
- "four": [
- "西风剑",
- "祭礼大剑",
- "西风长枪",
- "西风秘典",
- "绝弦"
- ],
+ "five": ["雾切之回光", "天空之脊"],
+ "four": ["西风剑", "祭礼大剑", "西风长枪", "西风秘典", "绝弦"],
"from": "2021-07-21 06:00:00",
"name": "神铸赋形",
- "to": "2021-08-10 17:59:59"
+ "to": "2021-08-10 17:59:59",
},
{
- "five": [
- "苍古自由之誓",
- "天空之卷"
- ],
- "four": [
- "暗巷闪光",
- "西风大剑",
- "匣里灭辰",
- "暗巷的酒与诗",
- "暗巷猎手"
- ],
+ "five": ["苍古自由之誓", "天空之卷"],
+ "four": ["暗巷闪光", "西风大剑", "匣里灭辰", "暗巷的酒与诗", "暗巷猎手"],
"from": "2021-06-29 18:00:00",
"name": "神铸赋形",
- "to": "2021-07-20 14:59:59"
+ "to": "2021-07-20 14:59:59",
},
{
- "five": [
- "天空之傲",
- "四风原典"
- ],
- "four": [
- "匣里龙吟",
- "钟剑",
- "西风长枪",
- "流浪乐章",
- "幽夜华尔兹"
- ],
+ "five": ["天空之傲", "四风原典"],
+ "four": ["匣里龙吟", "钟剑", "西风长枪", "流浪乐章", "幽夜华尔兹"],
"from": "2021-06-09 06:00:00",
"name": "神铸赋形",
- "to": "2021-06-29 17:59:59"
+ "to": "2021-06-29 17:59:59",
},
{
- "five": [
- "松籁响起之时",
- "风鹰剑"
- ],
- "four": [
- "祭礼剑",
- "雨裁",
- "匣里灭辰",
- "祭礼残章",
- "弓藏"
- ],
+ "five": ["松籁响起之时", "风鹰剑"],
+ "four": ["祭礼剑", "雨裁", "匣里灭辰", "祭礼残章", "弓藏"],
"from": "2021-05-18 18:00:00",
"name": "神铸赋形",
- "to": "2021-06-08 14:59:59"
+ "to": "2021-06-08 14:59:59",
},
{
- "five": [
- "斫峰之刃",
- "尘世之锁"
- ],
- "four": [
- "笛剑",
- "千岩古剑",
- "祭礼弓",
- "昭心",
- "千岩长枪"
- ],
+ "five": ["斫峰之刃", "尘世之锁"],
+ "four": ["笛剑", "千岩古剑", "祭礼弓", "昭心", "千岩长枪"],
"from": "2021-04-28 06:00:00",
"name": "神铸赋形",
- "to": "2021-05-18 17:59:59"
+ "to": "2021-05-18 17:59:59",
},
{
- "five": [
- "天空之翼",
- "四风原典"
- ],
- "four": [
- "西风剑",
- "祭礼大剑",
- "暗巷猎手",
- "西风秘典",
- "西风长枪"
- ],
+ "five": ["天空之翼", "四风原典"],
+ "four": ["西风剑", "祭礼大剑", "暗巷猎手", "西风秘典", "西风长枪"],
"from": "2021-04-06 18:00:00",
"name": "神铸赋形",
- "to": "2021-04-27 14:59:59"
+ "to": "2021-04-27 14:59:59",
},
{
- "five": [
- "终末嗟叹之诗",
- "天空之刃"
- ],
- "four": [
- "暗巷闪光",
- "西风大剑",
- "西风猎弓",
- "暗巷的酒与诗",
- "匣里灭辰"
- ],
+ "five": ["终末嗟叹之诗", "天空之刃"],
+ "four": ["暗巷闪光", "西风大剑", "西风猎弓", "暗巷的酒与诗", "匣里灭辰"],
"from": "2021-03-17 06:00:00",
"name": "神铸赋形",
- "to": "2021-04-06 15:59:59"
+ "to": "2021-04-06 15:59:59",
},
{
- "five": [
- "护摩之杖",
- "狼的末路"
- ],
- "four": [
- "匣里龙吟",
- "千岩古剑",
- "祭礼弓",
- "流浪乐章",
- "千岩长枪"
- ],
+ "five": ["护摩之杖", "狼的末路"],
+ "four": ["匣里龙吟", "千岩古剑", "祭礼弓", "流浪乐章", "千岩长枪"],
"from": "2021-02-23 18:00:00",
"name": "神铸赋形",
- "to": "2021-03-16 14:59:59"
+ "to": "2021-03-16 14:59:59",
},
{
- "five": [
- "磐岩结绿",
- "和璞鸢"
- ],
- "four": [
- "笛剑",
- "祭礼大剑",
- "弓藏",
- "昭心",
- "西风长枪"
- ],
+ "five": ["磐岩结绿", "和璞鸢"],
+ "four": ["笛剑", "祭礼大剑", "弓藏", "昭心", "西风长枪"],
"from": "2021-02-03 06:00:00",
"name": "神铸赋形",
- "to": "2021-02-23 15:59:59"
+ "to": "2021-02-23 15:59:59",
},
{
- "five": [
- "阿莫斯之弓",
- "天空之傲"
- ],
- "four": [
- "祭礼剑",
- "钟剑",
- "匣里灭辰",
- "昭心",
- "西风猎弓"
- ],
+ "five": ["阿莫斯之弓", "天空之傲"],
+ "four": ["祭礼剑", "钟剑", "匣里灭辰", "昭心", "西风猎弓"],
"from": "2021-01-12 18:00:00",
"name": "神铸赋形",
- "to": "2021-02-02 14:59:59"
+ "to": "2021-02-02 14:59:59",
},
{
- "five": [
- "斫峰之刃",
- "天空之卷"
- ],
- "four": [
- "西风剑",
- "西风大剑",
- "西风长枪",
- "祭礼残章",
- "绝弦"
- ],
+ "five": ["斫峰之刃", "天空之卷"],
+ "four": ["西风剑", "西风大剑", "西风长枪", "祭礼残章", "绝弦"],
"from": "2020-12-23 06:00:00",
"name": "神铸赋形",
- "to": "2021-01-12 15:59:59"
+ "to": "2021-01-12 15:59:59",
},
{
- "five": [
- "贯虹之槊",
- "无工之剑"
- ],
- "four": [
- "匣里龙吟",
- "钟剑",
- "西风秘典",
- "西风猎弓",
- "匣里灭辰"
- ],
+ "five": ["贯虹之槊", "无工之剑"],
+ "four": ["匣里龙吟", "钟剑", "西风秘典", "西风猎弓", "匣里灭辰"],
"from": "2020-12-01 18:00:00",
"name": "神铸赋形",
- "to": "2020-12-22 14:59:59"
+ "to": "2020-12-22 14:59:59",
},
{
- "five": [
- "天空之翼",
- "尘世之锁"
- ],
- "four": [
- "笛剑",
- "雨裁",
- "昭心",
- "弓藏",
- "西风长枪"
- ],
+ "five": ["天空之翼", "尘世之锁"],
+ "four": ["笛剑", "雨裁", "昭心", "弓藏", "西风长枪"],
"from": "2020-11-11 06:00:00",
"name": "神铸赋形",
- "to": "2020-12-01 15:59:59"
+ "to": "2020-12-01 15:59:59",
},
{
- "five": [
- "四风原典",
- "狼的末路"
- ],
- "four": [
- "祭礼剑",
- "祭礼大剑",
- "祭礼残章",
- "祭礼弓",
- "匣里灭辰"
- ],
+ "five": ["四风原典", "狼的末路"],
+ "four": ["祭礼剑", "祭礼大剑", "祭礼残章", "祭礼弓", "匣里灭辰"],
"from": "2020-10-20 18:00:00",
"name": "神铸赋形",
- "to": "2020-11-10 14:59:59"
+ "to": "2020-11-10 14:59:59",
},
{
- "five": [
- "风鹰剑",
- "阿莫斯之弓"
- ],
- "four": [
- "祭礼剑",
- "祭礼大剑",
- "祭礼残章",
- "祭礼弓",
- "匣里灭辰"
- ],
+ "five": ["风鹰剑", "阿莫斯之弓"],
+ "four": ["祭礼剑", "祭礼大剑", "祭礼残章", "祭礼弓", "匣里灭辰"],
"from": "2020-09-28 06:00:00",
"name": "神铸赋形",
- "to": "2020-10-18 17:59:59"
- }
-]
\ No newline at end of file
+ "to": "2020-10-18 17:59:59",
+ },
+]
diff --git a/metadata/scripts/honey.py b/metadata/scripts/honey.py
index b632854..478f565 100644
--- a/metadata/scripts/honey.py
+++ b/metadata/scripts/honey.py
@@ -14,8 +14,12 @@ from utils.log import logger
from utils.typedefs import StrOrInt
__all__ = [
- 'get_avatar_data', 'get_artifact_data', 'get_material_data', 'get_namecard_data', 'get_weapon_data',
- 'update_honey_metadata',
+ "get_avatar_data",
+ "get_artifact_data",
+ "get_material_data",
+ "get_namecard_data",
+ "get_weapon_data",
+ "update_honey_metadata",
]
DATA_TYPE = Dict[StrOrInt, List[str]]
@@ -41,12 +45,12 @@ async def get_avatar_data() -> DATA_TYPE:
result = {}
url = "https://genshin.honeyhunterworld.com/fam_chars/?lang=CHS"
response = await request(url)
- chaos_data = re.findall(r'sortable_data\.push\((.*)\);\s*sortable_cur_page', response.text)[0]
+ chaos_data = re.findall(r"sortable_data\.push\((.*)\);\s*sortable_cur_page", response.text)[0]
json_data = json.loads(chaos_data) # 转为 json
for data in json_data:
- cid = int("10000" + re.findall(r'\d+', data[1])[0])
+ cid = int("10000" + re.findall(r"\d+", data[1])[0])
honey_id = re.findall(r"/(.*?)/", data[1])[0]
- name = re.findall(r'>(.*)<', data[1])[0]
+ name = re.findall(r">(.*)<", data[1])[0]
rarity = int(re.findall(r">(\d)<", data[2])[0])
result[cid] = [honey_id, name, rarity]
return result
@@ -59,13 +63,13 @@ async def get_weapon_data() -> DATA_TYPE:
urls = [HONEY_HOST.join(f"fam_{i.lower()}/?lang=CHS") for i in WeaponType.__members__]
for url in urls:
response = await request(url)
- chaos_data = re.findall(r'sortable_data\.push\((.*)\);\s*sortable_cur_page', response.text)[0]
+ chaos_data = re.findall(r"sortable_data\.push\((.*)\);\s*sortable_cur_page", response.text)[0]
json_data = json.loads(chaos_data) # 转为 json
for data in json_data:
- name = re.findall(r'>(.*)<', data[1])[0]
- if name in ['「一心传」名刀', '石英大剑', '琥珀玥', '黑檀弓']: # 跳过特殊的武器
+ name = re.findall(r">(.*)<", data[1])[0]
+ if name in ["「一心传」名刀", "石英大剑", "琥珀玥", "黑檀弓"]: # 跳过特殊的武器
continue
- wid = int(re.findall(r'\d+', data[1])[0])
+ wid = int(re.findall(r"\d+", data[1])[0])
honey_id = re.findall(r"/(.*?)/", data[1])[0]
rarity = int(re.findall(r">(\d)<", data[2])[0])
result[wid] = [honey_id, name, rarity]
@@ -75,27 +79,27 @@ async def get_weapon_data() -> DATA_TYPE:
async def get_material_data() -> DATA_TYPE:
result = {}
- weapon = [HONEY_HOST.join(f'fam_wep_{i}/?lang=CHS') for i in ['primary', 'secondary', 'common']]
- talent = [HONEY_HOST.join(f'fam_talent_{i}/?lang=CHS') for i in ['book', 'boss', 'common', 'reward']]
+ weapon = [HONEY_HOST.join(f"fam_wep_{i}/?lang=CHS") for i in ["primary", "secondary", "common"]]
+ talent = [HONEY_HOST.join(f"fam_talent_{i}/?lang=CHS") for i in ["book", "boss", "common", "reward"]]
namecard = [HONEY_HOST.join("fam_nameplate/?lang=CHS")]
urls = weapon + talent + namecard
response = await request("https://api.ambr.top/v2/chs/material")
- ambr_data = json.loads(response.text)['data']['items']
+ ambr_data = json.loads(response.text)["data"]["items"]
for url in urls:
response = await request(url)
- chaos_data = re.findall(r'sortable_data\.push\((.*)\);\s*sortable_cur_page', response.text)[0]
+ chaos_data = re.findall(r"sortable_data\.push\((.*)\);\s*sortable_cur_page", response.text)[0]
json_data = json.loads(chaos_data) # 转为 json
for data in json_data:
- honey_id = re.findall(r'/(.*?)/', data[1])[0]
- name = re.findall(r'>(.*)<', data[1])[0]
+ honey_id = re.findall(r"/(.*?)/", data[1])[0]
+ name = re.findall(r">(.*)<", data[1])[0]
rarity = int(re.findall(r">(\d)<", data[2])[0])
mid = None
for mid, item in ambr_data.items():
- if name == item['name']:
+ if name == item["name"]:
break
- mid = int(mid) or int(re.findall(r'\d+', data[1])[0])
+ mid = int(mid) or int(re.findall(r"\d+", data[1])[0])
result[mid] = [honey_id, name, rarity]
return result
@@ -103,7 +107,7 @@ async def get_material_data() -> DATA_TYPE:
async def get_artifact_data() -> DATA_TYPE:
async def get_first_id(_link) -> str:
_response = await request(_link)
- _chaos_data = re.findall(r'sortable_data\.push\((.*)\);\s*sortable_cur_page', _response.text)[0]
+ _chaos_data = re.findall(r"sortable_data\.push\((.*)\);\s*sortable_cur_page", _response.text)[0]
_json_data = json.loads(_chaos_data)
return re.findall(r"/(.*?)/", _json_data[-1][1])[0]
@@ -111,21 +115,21 @@ async def get_artifact_data() -> DATA_TYPE:
url = "https://genshin.honeyhunterworld.com/fam_art_set/?lang=CHS"
response = await request("https://api.ambr.top/v2/chs/reliquary")
- ambr_data = json.loads(response.text)['data']['items']
+ ambr_data = json.loads(response.text)["data"]["items"]
response = await request(url)
- chaos_data = re.findall(r'sortable_data\.push\((.*)\);\s*sortable_cur_page', response.text)[0]
+ chaos_data = re.findall(r"sortable_data\.push\((.*)\);\s*sortable_cur_page", response.text)[0]
json_data = json.loads(chaos_data) # 转为 json
for data in json_data:
- honey_id = re.findall(r'/(.*?)/', data[1])[0]
+ honey_id = re.findall(r"/(.*?)/", data[1])[0]
name = re.findall(r"alt=\"(.*?)\"", data[0])[0]
link = HONEY_HOST.join(re.findall(r'href="(.*?)"', data[0])[0])
first_id = await get_first_id(link)
aid = None
for aid, item in ambr_data.items():
- if name == item['name']:
+ if name == item["name"]:
break
- aid = aid or re.findall(r'\d+', data[1])[0]
+ aid = aid or re.findall(r"\d+", data[1])[0]
result[aid] = [honey_id, name, first_id]
return result
@@ -138,20 +142,21 @@ async def get_namecard_data() -> DATA_TYPE:
# noinspection PyProtectedMember
from metadata.genshin import Data
from metadata.scripts.metadatas import update_metadata_from_github
+
await update_metadata_from_github()
# noinspection PyPep8Naming
- NAMECARD_DATA = Data('namecard')
+ NAMECARD_DATA = Data("namecard")
url = HONEY_HOST.join("fam_nameplate/?lang=CHS")
result = {}
response = await request(url)
- chaos_data = re.findall(r'sortable_data\.push\((.*)\);\s*sortable_cur_page', response.text)[0]
+ chaos_data = re.findall(r"sortable_data\.push\((.*)\);\s*sortable_cur_page", response.text)[0]
json_data = json.loads(chaos_data)
for data in json_data:
- honey_id = re.findall(r'/(.*?)/', data[1])[0]
+ honey_id = re.findall(r"/(.*?)/", data[1])[0]
name = re.findall(r"alt=\"(.*?)\"", data[0])[0]
try:
- nid = [key for key, value in NAMECARD_DATA.items() if value['name'] == name][0]
+ nid = [key for key, value in NAMECARD_DATA.items() if value["name"] == name][0]
except IndexError: # 暂不支持 beta 的名片
continue
rarity = int(re.findall(r">(\d)<", data[2])[0])
@@ -161,7 +166,7 @@ async def get_namecard_data() -> DATA_TYPE:
async def update_honey_metadata(overwrite: bool = True) -> FULL_DATA_TYPE | None:
- path = PROJECT_ROOT.joinpath('metadata/data/honey.json')
+ path = PROJECT_ROOT.joinpath("metadata/data/honey.json")
if not overwrite and path.exists():
return
avatar_data = await get_avatar_data()
@@ -176,13 +181,13 @@ async def update_honey_metadata(overwrite: bool = True) -> FULL_DATA_TYPE | None
logger.success("Namecard data is done.")
result = {
- 'avatar': avatar_data,
- 'weapon': weapon_data,
- 'material': material_data,
- 'artifact': artifact_data,
- 'namecard': namecard_data,
+ "avatar": avatar_data,
+ "weapon": weapon_data,
+ "material": material_data,
+ "artifact": artifact_data,
+ "namecard": namecard_data,
}
path.parent.mkdir(parents=True, exist_ok=True)
- async with async_open(path, mode='w', encoding='utf-8') as file:
+ async with async_open(path, mode="w", encoding="utf-8") as file:
await file.write(json.dumps(result, ensure_ascii=False))
return result
diff --git a/metadata/scripts/metadatas.py b/metadata/scripts/metadatas.py
index cdea1ce..9f06d73 100644
--- a/metadata/scripts/metadatas.py
+++ b/metadata/scripts/metadatas.py
@@ -4,23 +4,23 @@ from httpx import AsyncClient, URL
from utils.const import AMBR_HOST, PROJECT_ROOT
-__all__ = ['update_metadata_from_ambr', 'update_metadata_from_github']
+__all__ = ["update_metadata_from_ambr", "update_metadata_from_github"]
client = AsyncClient()
async def update_metadata_from_ambr(overwrite: bool = True):
result = []
- targets = ['material', 'weapon', 'avatar', 'reliquary']
+ targets = ["material", "weapon", "avatar", "reliquary"]
for target in targets:
- path = PROJECT_ROOT.joinpath(f'metadata/data/{target}.json')
+ path = PROJECT_ROOT.joinpath(f"metadata/data/{target}.json")
if not overwrite and path.exists():
continue
url = AMBR_HOST.join(f"v2/chs/{target}")
path.parent.mkdir(parents=True, exist_ok=True)
response = await client.get(url)
- json_data = json.loads(response.text)['data']['items']
- async with async_open(path, mode='w', encoding='utf-8') as file:
+ json_data = json.loads(response.text)["data"]["items"]
+ async with async_open(path, mode="w", encoding="utf-8") as file:
data = json.dumps(json_data, ensure_ascii=False)
await file.write(data)
result.append(json_data)
@@ -28,7 +28,7 @@ async def update_metadata_from_ambr(overwrite: bool = True):
async def update_metadata_from_github(overwrite: bool = True):
- path = PROJECT_ROOT.joinpath('metadata/data/namecard.json')
+ path = PROJECT_ROOT.joinpath("metadata/data/namecard.json")
if not overwrite and path.exists():
return
@@ -41,25 +41,27 @@ async def update_metadata_from_github(overwrite: bool = True):
material_json_data = json.loads((await client.get(material_url)).text)
data = {}
- for namecard_data in filter(lambda x: x.get('materialType', None) == 'MATERIAL_NAMECARD', material_json_data):
- name = text_map_json_data[str(namecard_data['nameTextMapHash'])]
- icon = namecard_data['icon']
- navbar = namecard_data['picPath'][0]
- banner = namecard_data['picPath'][1]
- rank = namecard_data['rankLevel']
- description = text_map_json_data[str(namecard_data['descTextMapHash'])].replace('\\n', '\n')
- data.update({
- str(namecard_data['id']): {
- "id": namecard_data['id'],
- "name": name,
- "rank": rank,
- "icon": icon,
- "navbar": navbar,
- "profile": banner,
- "description": description,
+ for namecard_data in filter(lambda x: x.get("materialType", None) == "MATERIAL_NAMECARD", material_json_data):
+ name = text_map_json_data[str(namecard_data["nameTextMapHash"])]
+ icon = namecard_data["icon"]
+ navbar = namecard_data["picPath"][0]
+ banner = namecard_data["picPath"][1]
+ rank = namecard_data["rankLevel"]
+ description = text_map_json_data[str(namecard_data["descTextMapHash"])].replace("\\n", "\n")
+ data.update(
+ {
+ str(namecard_data["id"]): {
+ "id": namecard_data["id"],
+ "name": name,
+ "rank": rank,
+ "icon": icon,
+ "navbar": navbar,
+ "profile": banner,
+ "description": description,
+ }
}
- })
- async with async_open(path, mode='w', encoding='utf-8') as file:
+ )
+ async with async_open(path, mode="w", encoding="utf-8") as file:
data = json.dumps(data, ensure_ascii=False)
await file.write(data)
return data
diff --git a/metadata/shortname.py b/metadata/shortname.py
index bcf8e41..f5a84d0 100644
--- a/metadata/shortname.py
+++ b/metadata/shortname.py
@@ -4,103 +4,274 @@ import functools
from metadata.genshin import WEAPON_DATA
-__all__ = [
- 'roles', 'weapons',
- 'roleToId', 'roleToName', 'weaponToName', 'weaponToId'
-]
+__all__ = ["roles", "weapons", "roleToId", "roleToName", "weaponToName", "weaponToId"]
# noinspection SpellCheckingInspection
roles = {
- 20000000: [
- '主角', '旅行者', '卑鄙的外乡人', '荣誉骑士', '爷', '风主', '岩主', '雷主', '草主', '履刑者', '抽卡不歪真君'
+ 20000000: ["主角", "旅行者", "卑鄙的外乡人", "荣誉骑士", "爷", "风主", "岩主", "雷主", "草主", "履刑者", "抽卡不歪真君"],
+ 10000002: ["神里绫华", "Ayaka", "ayaka", "Kamisato Ayaka", "神里", "绫华", "神里凌华", "凌华", "白鹭公主", "神里大小 姐"],
+ 10000003: ["琴", "Jean", "jean", "团长", "代理团长", "琴团长", "蒲公英骑士"],
+ 10000005: ["空", "Aether", "aether", "男主", "男主角", "龙哥", "空哥"],
+ 10000006: ["丽莎", "Lisa", "lisa", "图书管理员", "图书馆管理员", "蔷薇魔女"],
+ 10000007: ["荧", "Lumine", "lumine", "女主", "女主角", "莹", "萤", "黄毛阿姨", "荧妹"],
+ 10000014: ["芭芭拉", "Barbara", "barbara", "巴巴拉", "拉粑粑", "拉巴巴", "内鬼", "加湿器", "闪耀偶像", "偶像"],
+ 10000015: ["凯亚", "Kaeya", "kaeya", "盖亚", "凯子哥", "凯鸭", "矿工", "矿工头子", "骑兵队长", "凯子", "凝冰渡海真君"],
+ 10000016: [
+ "迪卢克",
+ "Diluc",
+ "diluc",
+ "卢姥爷",
+ "姥爷",
+ "卢老爷",
+ "卢锅巴",
+ "正义人",
+ "正e人",
+ "正E人",
+ "卢本伟",
+ "暗夜英雄",
+ "卢卢伯爵",
+ "落魄了",
+ "落魄了家人们",
],
- 10000002: ['神里绫华', 'Ayaka', 'ayaka', 'Kamisato Ayaka', '神里', '绫华', '神里凌华', '凌华', '白鹭公主',
- '神里大小 姐'],
- 10000003: ['琴', 'Jean', 'jean', '团长', '代理团长', '琴团长', '蒲公英骑士'],
- 10000005: ['空', 'Aether', 'aether', '男主', '男主角', '龙哥', '空哥'],
- 10000006: ['丽莎', 'Lisa', 'lisa', '图书管理员', '图书馆管理员', '蔷薇魔女'],
- 10000007: ['荧', 'Lumine', 'lumine', '女主', '女主角', '莹', '萤', '黄毛阿姨', '荧妹'],
- 10000014: ['芭芭拉', 'Barbara', 'barbara', '巴巴拉', '拉粑粑', '拉巴巴', '内鬼', '加湿器', '闪耀偶像', '偶像'],
- 10000015: ['凯亚', 'Kaeya', 'kaeya', '盖亚', '凯子哥', '凯鸭', '矿工', '矿工头子', '骑兵队长', '凯子',
- '凝冰渡海真君'],
- 10000016: ['迪卢克', 'Diluc', 'diluc', '卢姥爷', '姥爷', '卢老爷', '卢锅巴', '正义人', '正e人', '正E人', '卢本伟',
- '暗夜英雄', '卢卢伯爵', '落魄了', '落魄了家人们'],
- 10000020: ['雷泽', 'Razor', 'razor', '狼少年', '狼崽子', '狼崽', '卢皮卡', '小狼', '小狼狗'],
- 10000021: ['安柏', 'Amber', 'amber', '安伯', '兔兔伯爵', '飞行冠军', '侦查骑士', '点火姬', '点火机', '打火机',
- '打火姬'],
- 10000022: ['温迪', 'Venti', 'venti', '温蒂', '风神', '卖唱的', '巴巴托斯', '巴巴脱丝', '芭芭托斯', '芭芭脱丝',
- '干点正事', '不干正事', '吟游诗人', '诶嘿', '唉嘿', '摸鱼'],
- 10000023: ['香菱', 'Xiangling', 'xiangling', '香玲', '锅巴', '厨师', '万民堂厨师', '香师傅'],
- 10000024: ['北斗', 'Beidou', 'beidou', '大姐头', '大姐', '无冕的龙王', '龙王'],
- 10000025: ['行秋', 'Xingqiu', 'xingqiu', '秋秋人', '秋妹妹', '书呆子', '水神', '飞云商会二少爷'],
- 10000026: ['魈', 'Xiao', 'xiao', '杏仁豆腐', '打桩机', '插秧', '三眼五显仙人', '三眼五显真人', '降魔大圣',
- '护法夜叉', '快乐风男', '无聊', '靖妖傩舞', '矮子仙人', '三点五尺仙人', '跳跳虎'],
- 10000027: ['凝光', 'Ningguang', 'ningguang', '富婆', '天权星'],
- 10000029: ['可莉', 'Klee', 'klee', '嘟嘟可', '火花骑士', '蹦蹦炸弹', '炸鱼', '放火烧山', '放火烧山真君',
- '蒙德最强战力', '逃跑的太阳', '啦啦啦', '哒哒哒', '炸弹人', '禁闭室'],
- 10000030: ['钟离', 'Zhongli', 'zhongli', '摩拉克斯', '岩王爷', '岩神', '钟师傅', '天动万象', '岩王帝君', '未来可期',
- '帝君', '拒收病婿'],
- 10000031: ['菲谢尔', 'Fischl', 'fischl', '皇女', '小艾米', '小艾咪', '奥兹', '断罪皇女', '中二病', '中二少女',
- '中二皇女', '奥兹发射器'],
- 10000032: ['班尼特', 'Bennett', 'bennett', '点赞哥', '点赞', '倒霉少年', '倒霉蛋', '霹雳闪雷真君', '班神', '班爷',
- '倒霉', '火神', '六星真神'],
- 10000033: ['达达利亚', 'Tartaglia', 'tartaglia', 'Childe', 'childe', 'Ajax', 'ajax', '达达鸭', '达达利鸭', '公子',
- '玩具销售员', '玩具推销员', '钱包', '鸭鸭', '愚人众末席'],
- 10000034: ['诺艾尔', 'Noelle', 'noelle', '女仆', '高达', '岩王帝姬'],
- 10000035: ['七七', 'Qiqi', 'qiqi', '僵尸', '肚饿真君', '度厄真君', '77'],
- 10000036: ['重云', 'Chongyun', 'chongyun', '纯阳之体', '冰棍'],
- 10000037: ['甘雨', 'Ganyu', 'ganyu', '椰羊', '椰奶', '王小美'],
- 10000038: ['阿贝多', 'Albedo', 'albedo', '可莉哥哥', '升降机', '升降台', '电梯', '白垩之子', '贝爷', '白垩',
- '阿贝少', '花呗多', '阿贝夕', 'abd', '阿师傅'],
- 10000039: ['迪奥娜', 'Diona', 'diona', '迪欧娜', 'dio', 'dio娜', '冰猫', '猫猫', '猫娘', '喵喵', '调酒师'],
- 10000041: ['莫娜', 'Mona', 'mona', '穷鬼', '穷光蛋', '穷', '莫纳', '占星术士', '占星师', '讨龙真君', '半部讨龙真君',
- '阿斯托洛吉斯·莫娜·梅姬斯图斯', '梅姬斯图斯', '梅姬斯图斯卿'],
- 10000042: ['刻晴', 'Keqing', 'keqing', '刻情', '氪晴', '刻师傅', '刻师父', '牛杂', '牛杂师傅', '斩尽牛杂', '免疫',
- '免疫免疫', '屁斜剑法', '玉衡星', '阿晴', ' 啊晴'],
- 10000043: ['砂糖', 'Sucrose', 'sucrose', '雷莹术士', '雷萤术士', '雷荧术士'],
- 10000044: ['辛焱', 'Xinyan', 'xinyan', '辛炎', '黑妹', '摇滚'],
- 10000045: ['罗莎莉亚', 'Rosaria', 'rosaria', '罗莎莉娅', '白色史莱姆', '白史莱姆', '修女', '罗莎利亚', '罗莎利娅',
- '罗沙莉亚', '罗沙莉娅', '罗沙利亚', '罗沙利娅', '萝莎莉亚', '萝莎莉娅', '萝莎利亚', '萝莎利娅',
- '萝沙莉亚', '萝沙莉娅', '萝沙利亚', '萝沙利娅'],
- 10000046: ['胡桃', 'HuTao', 'hutao', 'Hu Tao', 'hu tao', 'Hutao', '胡 淘', '往生堂堂主', '火化', '抬棺的', '蝴蝶',
- '核桃', '堂主', '胡堂主', '雪霁梅香'],
- 10000047: ['枫原万叶', 'Kazuha', 'kazuha', 'Kaedehara Kazuha', '万叶', '叶天帝', '天帝', '叶师傅'],
- 10000048: ['烟绯', 'Yanfei', 'yanfei', '烟老师', '律师', '罗翔'],
- 10000049: ['宵宫', 'Yoimiya', 'yoimiya', '霄宫', '烟花', '肖宫', '肖工', '绷带女孩'],
- 10000050: ['托马', 'Thoma', 'thoma', '家政官', '太郎丸', '地头蛇', '男仆', '拖马'],
- 10000051: ['优菈', 'Eula', 'eula', '优拉', '尤拉', '尤菈', '浪花骑士', '记仇', '劳伦斯'],
- 10000052: ['雷电将军', 'Raiden Shogun', 'Raiden', 'raiden', '雷神', '将军', '雷军', '巴尔', '阿影', '影',
- '巴尔泽布', '煮饭婆', '奶香一刀', '无想一刀', '宅女'],
- 10000053: ['早柚', 'Sayu', 'sayu', '小狸猫', '狸 猫', '忍者'],
- 10000054: ['珊瑚宫心海', 'Kokomi', 'kokomi', 'Sangonomiya Kokomi', '心海', '军师', '珊瑚宫', '书记', '观赏鱼',
- '水母', '鱼', '美人鱼'],
- 10000055: ['五郎', 'Gorou', 'gorou', '柴犬', '土狗', '希娜', '希娜小姐'],
- 10000056: ['九条裟罗', 'Sara', 'sara', 'Kujou Sara', '九条', '九条沙罗', '裟罗', '沙罗', '天狗'],
- 10000057: ['荒泷一斗', 'Itto', 'itto', 'Arataki Itto', '荒龙一斗', '荒泷天下第一斗', '一斗', '一抖', '荒泷', '1斗',
- '牛牛', '斗子哥', '牛子哥', '牛子', '孩子 王', '斗虫', '巧乐兹', '放牛的'],
- 10000058: ['八重神子', 'Miko', 'miko', 'Yae Miko', '八重', '神子', '狐狸', '想得美哦', '巫女', '屑狐狸', '骚狐狸',
- '八重宫司', '婶子', '小八'],
- 10000059: ['鹿野院平藏', 'Heizou', 'heizou', 'shikanoin heizou', 'heizo', '鹿野苑', '鹿野院', '平藏', '鹿野苑平藏',
- '鹿野', '小鹿'],
- 10000060: ['夜兰', 'Yelan', 'yelan', '夜阑', '叶 澜', '腋兰', '夜天后'],
- 10000062: ['埃洛伊', 'Aloy', 'aloy'],
- 10000063: ['申鹤', 'Shenhe', 'shenhe', '神鹤', '小姨', '小姨子', '审鹤'],
- 10000064: ['云堇', 'YunJin', 'yunjin', 'Yun Jin', 'yun jin', '云瑾', '云先生', '云锦', '神女劈观'],
- 10000065: ['久岐忍', 'Kuki', 'kuki', 'Kuki Shinobu', 'Shinobu', 'shinobu', '97忍', '小忍', '久歧忍', '97', '茄忍',
- '阿忍', '忍姐'],
- 10000066: ['神里绫人', 'Ayato', 'ayato', 'Kamisato Ayato', '绫人', '神里凌人', '凌人', '0人', '神人', '零人',
- '大舅哥'],
- 10000067: ['柯莱', 'Collei', 'collei', '柯来', '科莱', '科来', '小天使', '须弥安柏', '须弥飞行冠军', '见习巡林员',
- '克莱', '草安伯'],
- 10000068: ['多莉', 'Dori', 'dori', '多利', '多力', '多丽', '奸商'],
- 10000069: ['提纳里', 'Tighnari', 'tighnari', '小提', '提那里', '缇娜里', '提哪里', '驴', '柯莱老师', '柯莱师傅',
- '巡林官',
- '提那里'],
- 10000070: ['妮露', 'Nilou', 'nilou', '尼露', '尼禄'],
- 10000071: ['赛诺', 'Cyno', 'cyno', '赛洛'],
- 10000072: ['坎蒂丝', 'Candace', 'candace', '坎迪斯'],
- 10000073: ['纳西妲', 'Nahida', 'nahida', '草王', '草神', '小吉祥草王', '草萝莉', '纳西坦'],
- 10000074: ['莱依拉', 'Layla', 'layla', '拉一拉'],
+ 10000020: ["雷泽", "Razor", "razor", "狼少年", "狼崽子", "狼崽", "卢皮卡", "小狼", "小狼狗"],
+ 10000021: ["安柏", "Amber", "amber", "安伯", "兔兔伯爵", "飞行冠军", "侦查骑士", "点火姬", "点火机", "打火机", "打火姬"],
+ 10000022: [
+ "温迪",
+ "Venti",
+ "venti",
+ "温蒂",
+ "风神",
+ "卖唱的",
+ "巴巴托斯",
+ "巴巴脱丝",
+ "芭芭托斯",
+ "芭芭脱丝",
+ "干点正事",
+ "不干正事",
+ "吟游诗人",
+ "诶嘿",
+ "唉嘿",
+ "摸鱼",
+ ],
+ 10000023: ["香菱", "Xiangling", "xiangling", "香玲", "锅巴", "厨师", "万民堂厨师", "香师傅"],
+ 10000024: ["北斗", "Beidou", "beidou", "大姐头", "大姐", "无冕的龙王", "龙王"],
+ 10000025: ["行秋", "Xingqiu", "xingqiu", "秋秋人", "秋妹妹", "书呆子", "水神", "飞云商会二少爷"],
+ 10000026: [
+ "魈",
+ "Xiao",
+ "xiao",
+ "杏仁豆腐",
+ "打桩机",
+ "插秧",
+ "三眼五显仙人",
+ "三眼五显真人",
+ "降魔大圣",
+ "护法夜叉",
+ "快乐风男",
+ "无聊",
+ "靖妖傩舞",
+ "矮子仙人",
+ "三点五尺仙人",
+ "跳跳虎",
+ ],
+ 10000027: ["凝光", "Ningguang", "ningguang", "富婆", "天权星"],
+ 10000029: [
+ "可莉",
+ "Klee",
+ "klee",
+ "嘟嘟可",
+ "火花骑士",
+ "蹦蹦炸弹",
+ "炸鱼",
+ "放火烧山",
+ "放火烧山真君",
+ "蒙德最强战力",
+ "逃跑的太阳",
+ "啦啦啦",
+ "哒哒哒",
+ "炸弹人",
+ "禁闭室",
+ ],
+ 10000030: ["钟离", "Zhongli", "zhongli", "摩拉克斯", "岩王爷", "岩神", "钟师傅", "天动万象", "岩王帝君", "未来可期", "帝君", "拒收病婿"],
+ 10000031: ["菲谢尔", "Fischl", "fischl", "皇女", "小艾米", "小艾咪", "奥兹", "断罪皇女", "中二病", "中二少女", "中二皇女", "奥兹发射器"],
+ 10000032: ["班尼特", "Bennett", "bennett", "点赞哥", "点赞", "倒霉少年", "倒霉蛋", "霹雳闪雷真君", "班神", "班爷", "倒霉", "火神", "六星真神"],
+ 10000033: [
+ "达达利亚",
+ "Tartaglia",
+ "tartaglia",
+ "Childe",
+ "childe",
+ "Ajax",
+ "ajax",
+ "达达鸭",
+ "达达利鸭",
+ "公子",
+ "玩具销售员",
+ "玩具推销员",
+ "钱包",
+ "鸭鸭",
+ "愚人众末席",
+ ],
+ 10000034: ["诺艾尔", "Noelle", "noelle", "女仆", "高达", "岩王帝姬"],
+ 10000035: ["七七", "Qiqi", "qiqi", "僵尸", "肚饿真君", "度厄真君", "77"],
+ 10000036: ["重云", "Chongyun", "chongyun", "纯阳之体", "冰棍"],
+ 10000037: ["甘雨", "Ganyu", "ganyu", "椰羊", "椰奶", "王小美"],
+ 10000038: [
+ "阿贝多",
+ "Albedo",
+ "albedo",
+ "可莉哥哥",
+ "升降机",
+ "升降台",
+ "电梯",
+ "白垩之子",
+ "贝爷",
+ "白垩",
+ "阿贝少",
+ "花呗多",
+ "阿贝夕",
+ "abd",
+ "阿师傅",
+ ],
+ 10000039: ["迪奥娜", "Diona", "diona", "迪欧娜", "dio", "dio娜", "冰猫", "猫猫", "猫娘", "喵喵", "调酒师"],
+ 10000041: [
+ "莫娜",
+ "Mona",
+ "mona",
+ "穷鬼",
+ "穷光蛋",
+ "穷",
+ "莫纳",
+ "占星术士",
+ "占星师",
+ "讨龙真君",
+ "半部讨龙真君",
+ "阿斯托洛吉斯·莫娜·梅姬斯图斯",
+ "梅姬斯图斯",
+ "梅姬斯图斯卿",
+ ],
+ 10000042: [
+ "刻晴",
+ "Keqing",
+ "keqing",
+ "刻情",
+ "氪晴",
+ "刻师傅",
+ "刻师父",
+ "牛杂",
+ "牛杂师傅",
+ "斩尽牛杂",
+ "免疫",
+ "免疫免疫",
+ "屁斜剑法",
+ "玉衡星",
+ "阿晴",
+ " 啊晴",
+ ],
+ 10000043: ["砂糖", "Sucrose", "sucrose", "雷莹术士", "雷萤术士", "雷荧术士"],
+ 10000044: ["辛焱", "Xinyan", "xinyan", "辛炎", "黑妹", "摇滚"],
+ 10000045: [
+ "罗莎莉亚",
+ "Rosaria",
+ "rosaria",
+ "罗莎莉娅",
+ "白色史莱姆",
+ "白史莱姆",
+ "修女",
+ "罗莎利亚",
+ "罗莎利娅",
+ "罗沙莉亚",
+ "罗沙莉娅",
+ "罗沙利亚",
+ "罗沙利娅",
+ "萝莎莉亚",
+ "萝莎莉娅",
+ "萝莎利亚",
+ "萝莎利娅",
+ "萝沙莉亚",
+ "萝沙莉娅",
+ "萝沙利亚",
+ "萝沙利娅",
+ ],
+ 10000046: [
+ "胡桃",
+ "HuTao",
+ "hutao",
+ "Hu Tao",
+ "hu tao",
+ "Hutao",
+ "胡 淘",
+ "往生堂堂主",
+ "火化",
+ "抬棺的",
+ "蝴蝶",
+ "核桃",
+ "堂主",
+ "胡堂主",
+ "雪霁梅香",
+ ],
+ 10000047: ["枫原万叶", "Kazuha", "kazuha", "Kaedehara Kazuha", "万叶", "叶天帝", "天帝", "叶师傅"],
+ 10000048: ["烟绯", "Yanfei", "yanfei", "烟老师", "律师", "罗翔"],
+ 10000049: ["宵宫", "Yoimiya", "yoimiya", "霄宫", "烟花", "肖宫", "肖工", "绷带女孩"],
+ 10000050: ["托马", "Thoma", "thoma", "家政官", "太郎丸", "地头蛇", "男仆", "拖马"],
+ 10000051: ["优菈", "Eula", "eula", "优拉", "尤拉", "尤菈", "浪花骑士", "记仇", "劳伦斯"],
+ 10000052: [
+ "雷电将军",
+ "Raiden Shogun",
+ "Raiden",
+ "raiden",
+ "雷神",
+ "将军",
+ "雷军",
+ "巴尔",
+ "阿影",
+ "影",
+ "巴尔泽布",
+ "煮饭婆",
+ "奶香一刀",
+ "无想一刀",
+ "宅女",
+ ],
+ 10000053: ["早柚", "Sayu", "sayu", "小狸猫", "狸 猫", "忍者"],
+ 10000054: ["珊瑚宫心海", "Kokomi", "kokomi", "Sangonomiya Kokomi", "心海", "军师", "珊瑚宫", "书记", "观赏鱼", "水母", "鱼", "美人鱼"],
+ 10000055: ["五郎", "Gorou", "gorou", "柴犬", "土狗", "希娜", "希娜小姐"],
+ 10000056: ["九条裟罗", "Sara", "sara", "Kujou Sara", "九条", "九条沙罗", "裟罗", "沙罗", "天狗"],
+ 10000057: [
+ "荒泷一斗",
+ "Itto",
+ "itto",
+ "Arataki Itto",
+ "荒龙一斗",
+ "荒泷天下第一斗",
+ "一斗",
+ "一抖",
+ "荒泷",
+ "1斗",
+ "牛牛",
+ "斗子哥",
+ "牛子哥",
+ "牛子",
+ "孩子 王",
+ "斗虫",
+ "巧乐兹",
+ "放牛的",
+ ],
+ 10000058: ["八重神子", "Miko", "miko", "Yae Miko", "八重", "神子", "狐狸", "想得美哦", "巫女", "屑狐狸", "骚狐狸", "八重宫司", "婶子", "小八"],
+ 10000059: ["鹿野院平藏", "Heizou", "heizou", "shikanoin heizou", "heizo", "鹿野苑", "鹿野院", "平藏", "鹿野苑平藏", "鹿野", "小鹿"],
+ 10000060: ["夜兰", "Yelan", "yelan", "夜阑", "叶 澜", "腋兰", "夜天后"],
+ 10000062: ["埃洛伊", "Aloy", "aloy"],
+ 10000063: ["申鹤", "Shenhe", "shenhe", "神鹤", "小姨", "小姨子", "审鹤"],
+ 10000064: ["云堇", "YunJin", "yunjin", "Yun Jin", "yun jin", "云瑾", "云先生", "云锦", "神女劈观"],
+ 10000065: ["久岐忍", "Kuki", "kuki", "Kuki Shinobu", "Shinobu", "shinobu", "97忍", "小忍", "久歧忍", "97", "茄忍", "阿忍", "忍姐"],
+ 10000066: ["神里绫人", "Ayato", "ayato", "Kamisato Ayato", "绫人", "神里凌人", "凌人", "0人", "神人", "零人", "大舅哥"],
+ 10000067: ["柯莱", "Collei", "collei", "柯来", "科莱", "科来", "小天使", "须弥安柏", "须弥飞行冠军", "见习巡林员", "克莱", "草安伯"],
+ 10000068: ["多莉", "Dori", "dori", "多利", "多力", "多丽", "奸商"],
+ 10000069: ["提纳里", "Tighnari", "tighnari", "小提", "提那里", "缇娜里", "提哪里", "驴", "柯莱老师", "柯莱师傅", "巡林官", "提那里"],
+ 10000070: ["妮露", "Nilou", "nilou", "尼露", "尼禄"],
+ 10000071: ["赛诺", "Cyno", "cyno", "赛洛"],
+ 10000072: ["坎蒂丝", "Candace", "candace", "坎迪斯"],
+ 10000073: ["纳西妲", "Nahida", "nahida", "草王", "草神", "小吉祥草王", "草萝莉", "纳西坦"],
+ 10000074: ["莱依拉", "Layla", "layla", "拉一拉"],
}
not_real_roles = [10000073, 10000074]
weapons = {
@@ -110,37 +281,29 @@ weapons = {
"贯虹之槊": ["贯虹", "岩枪", "盾枪"],
"赤角石溃杵": ["赤角", "石溃杵"],
"尘世之锁": ["尘世锁", "尘世", "盾书", "锁"],
-
"终末嗟叹之诗": ["终末", "终末弓", "叹气弓", "乐团弓"],
"松籁响起之时": ["松籁", "乐团大剑", "松剑"],
"苍古自由之誓": ["苍古", "乐团剑"],
-
"「渔获」": ["鱼叉", "渔叉"],
"衔珠海皇": ["海皇", "咸鱼剑", "咸鱼大剑"],
-
"匣里日月": ["日月"],
"匣里灭辰": ["灭辰"],
"匣里龙吟": ["龙吟"],
-
"天空之翼": ["天空弓"],
"天空之刃": ["天空剑"],
"天空之卷": ["天空书", "厕纸"],
"天空之脊": ["天空枪", "薄荷枪"],
"天空之傲": ["天空大剑"],
"四风原典": ["四风"],
-
"试作斩岩": ["斩岩"],
"试作星镰": ["星镰"],
"试作金珀": ["金珀"],
"试作古华": ["古华"],
"试作澹月": ["澹月"],
-
"千岩长枪": ["千岩枪"],
"千岩古剑": ["千岩剑", "千岩大剑"],
-
"暗巷闪光": ["暗巷剑"],
"暗巷猎手": ["暗巷弓"],
-
"阿莫斯之弓": ["阿莫斯", "ams", "痛苦弓"],
"雾切之回光": ["雾切"],
"飞雷之弦振": ["飞雷", "飞雷弓"],
@@ -154,7 +317,6 @@ weapons = {
"不灭月华": ["月华"],
"波乱月白经津": ["波乱", "月白", "波乱月白", "经津", "波波津"],
"若水": ["麒麟弓", "Aqua", "aqua"],
-
"昭心": ["糟心"],
"幽夜华尔兹": ["幽夜", "幽夜弓", "华尔兹", "皇女弓"],
"雪葬的星银": ["雪葬", "星银", "雪葬星银", "雪山大剑"],
@@ -172,15 +334,13 @@ weapons = {
"嘟嘟可故事集": ["嘟嘟可"],
"辰砂之纺锤": ["辰砂", "辰砂纺锤", "纺锤"],
"白辰之环": ["白辰", "白辰环"],
-
"决斗之枪": ["决斗枪", "决斗", "月卡枪"],
"螭骨剑": ["螭骨", "丈育剑", "离骨剑", "月卡大剑"],
"黑剑": ["月卡剑"],
"苍翠猎弓": ["绿弓", "月卡弓"],
-
"讨龙英杰谭": ["讨龙"],
"神射手之誓": ["脚气弓", "神射手"],
- "黑缨枪": ["史莱姆枪"]
+ "黑缨枪": ["史莱姆枪"],
}
@@ -209,4 +369,4 @@ def weaponToName(shortname: str) -> str:
@functools.lru_cache()
def weaponToId(name: str) -> int | None:
"""获取武器ID"""
- return next((int(key) for key, value in WEAPON_DATA.items() if weaponToName(name) in value['name']), None)
+ return next((int(key) for key, value in WEAPON_DATA.items() if weaponToName(name) in value["name"]), None)
diff --git a/modules/apihelper/artifact.py b/modules/apihelper/artifact.py
index b3949b2..6656439 100644
--- a/modules/apihelper/artifact.py
+++ b/modules/apihelper/artifact.py
@@ -9,20 +9,54 @@ def get_format_sub_item(artifact_attr: dict):
def get_comment(get_rate_num):
- data = {"1": ["破玩意谁能用啊,谁都用不了吧", "喂了吧,这东西做狗粮还能有点用", "抽卡有保底,圣遗物没有下限",
- "未来可期呢(笑)", "你出门一定很安全", "你是不是得罪米哈游了?", "……宁就是班尼特本特?",
- "丢人!你给我退出提瓦特(", "不能说很糟糕,只能说特别不好"],
- "2": ["淡如清泉镇的圣水,莫得提升", "你怎么不强化啊?", "嗯嗯嗯好好好可以可以可以挺好挺好(敷衍)",
- "这就是日常,下一个", "洗洗还能吃(bushi)", "下次一定行……?", "派蒙平静地点了个赞",
- "不知道该说什么,就当留个纪念吧"],
- "3": ["不能说有质变,只能说有提升", "过渡用的话没啥问题,大概", "再努努力吧", "嗯,差不多能用",
- "这很合理", "达成成就“合格圣遗物”", "嗯,及格了,过渡用挺好的", "中规中矩,有待提升"],
- "4": ["以普遍理性而论,很好", "算是个很不戳的圣遗物了!", "很好,很有精神!", "再努努力,超越一下自己",
- "感觉可以戴着它大杀四方了", "这就是大佬背包里的平均水平吧", "先锁上呗,这波不亏", "达成成就“高分圣遗物”",
- "这波对输出有很大提升啊(认真)", "我也想拥有这种分数的圣遗物(切实)"],
- "5": ["多吃点好的,出门注意安全", "晒吧,欧不可耻,只是可恨", "没啥好说的,让我自闭一会", "达成成就“高分圣遗物”",
- "怕不是以后开宝箱只能开出卷心菜", "吃了吗?没吃的话,吃我一拳", "我觉得这个游戏有问题", "这合理吗",
- "这东西没啥用,给我吧(柠檬)", "??? ????"]}
+ data = {
+ "1": [
+ "破玩意谁能用啊,谁都用不了吧",
+ "喂了吧,这东西做狗粮还能有点用",
+ "抽卡有保底,圣遗物没有下限",
+ "未来可期呢(笑)",
+ "你出门一定很安全",
+ "你是不是得罪米哈游了?",
+ "……宁就是班尼特本特?",
+ "丢人!你给我退出提瓦特(",
+ "不能说很糟糕,只能说特别不好",
+ ],
+ "2": [
+ "淡如清泉镇的圣水,莫得提升",
+ "你怎么不强化啊?",
+ "嗯嗯嗯好好好可以可以可以挺好挺好(敷衍)",
+ "这就是日常,下一个",
+ "洗洗还能吃(bushi)",
+ "下次一定行……?",
+ "派蒙平静地点了个赞",
+ "不知道该说什么,就当留个纪念吧",
+ ],
+ "3": ["不能说有质变,只能说有提升", "过渡用的话没啥问题,大概", "再努努力吧", "嗯,差不多能用", "这很合理", "达成成就“合格圣遗物”", "嗯,及格了,过渡用挺好的", "中规中矩,有待提升"],
+ "4": [
+ "以普遍理性而论,很好",
+ "算是个很不戳的圣遗物了!",
+ "很好,很有精神!",
+ "再努努力,超越一下自己",
+ "感觉可以戴着它大杀四方了",
+ "这就是大佬背包里的平均水平吧",
+ "先锁上呗,这波不亏",
+ "达成成就“高分圣遗物”",
+ "这波对输出有很大提升啊(认真)",
+ "我也想拥有这种分数的圣遗物(切实)",
+ ],
+ "5": [
+ "多吃点好的,出门注意安全",
+ "晒吧,欧不可耻,只是可恨",
+ "没啥好说的,让我自闭一会",
+ "达成成就“高分圣遗物”",
+ "怕不是以后开宝箱只能开出卷心菜",
+ "吃了吗?没吃的话,吃我一拳",
+ "我觉得这个游戏有问题",
+ "这合理吗",
+ "这东西没啥用,给我吧(柠檬)",
+ "??? ????",
+ ],
+ }
try:
data_ = int(float(get_rate_num))
except ValueError:
@@ -36,22 +70,22 @@ class ArtifactOcrRate:
OCR_URL = "https://api.genshin.pub/api/v1/app/ocr"
RATE_URL = "https://api.genshin.pub/api/v1/relic/rate"
HEADERS = {
- 'authority': 'api.genshin.pub',
- 'accept': 'application/json, text/plain, */*',
- 'accept-language': 'zh-CN,zh;q=0.9,zh-Hans;q=0.8,und;q=0.7,en;q=0.6,zh-Hant;q=0.5,ja;q=0.4',
- 'content-type': 'application/json;charset=UTF-8',
- 'dnt': '1',
- 'origin': 'https://genshin.pub',
- 'referer': 'https://genshin.pub/',
- 'sec-ch-ua': '"Chromium";v="104", " Not A;Brand";v="99"',
- 'sec-ch-ua-mobile': '?0',
- 'sec-ch-ua-platform': '"Windows"',
- 'sec-fetch-dest': 'empty',
- 'sec-fetch-mode': 'cors',
- 'sec-fetch-site': 'same-site',
- 'sec-gpc': '1',
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
- 'Chrome/104.0.5112.115 Safari/537.36',
+ "authority": "api.genshin.pub",
+ "accept": "application/json, text/plain, */*",
+ "accept-language": "zh-CN,zh;q=0.9,zh-Hans;q=0.8,und;q=0.7,en;q=0.6,zh-Hant;q=0.5,ja;q=0.4",
+ "content-type": "application/json;charset=UTF-8",
+ "dnt": "1",
+ "origin": "https://genshin.pub",
+ "referer": "https://genshin.pub/",
+ "sec-ch-ua": '"Chromium";v="104", " Not A;Brand";v="99"',
+ "sec-ch-ua-mobile": "?0",
+ "sec-ch-ua-platform": '"Windows"',
+ "sec-fetch-dest": "empty",
+ "sec-fetch-mode": "cors",
+ "sec-fetch-site": "same-site",
+ "sec-gpc": "1",
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
+ "Chrome/104.0.5112.115 Safari/537.36",
}
def __init__(self):
diff --git a/modules/apihelper/base.py b/modules/apihelper/base.py
index 63930c1..e3ef79e 100644
--- a/modules/apihelper/base.py
+++ b/modules/apihelper/base.py
@@ -43,8 +43,14 @@ class PostInfo(BaseModel):
created_at = post["created_at"]
user = _data_post["user"] # 用户数据
user_uid = user["uid"] # 用户ID
- return PostInfo(_data=data, post_id=post_id, user_uid=user_uid, subject=subject, image_urls=image_urls,
- created_at=created_at)
+ return PostInfo(
+ _data=data,
+ post_id=post_id,
+ user_uid=user_uid,
+ subject=subject,
+ image_urls=image_urls,
+ created_at=created_at,
+ )
def __getitem__(self, item):
return self._data[item]
diff --git a/modules/apihelper/helpers.py b/modules/apihelper/helpers.py
index 97bf71b..90f9a4c 100644
--- a/modules/apihelper/helpers.py
+++ b/modules/apihelper/helpers.py
@@ -16,7 +16,7 @@ RECOGNIZE_SERVER = {
def get_device_id(name: str) -> str:
- return str(uuid.uuid3(uuid.NAMESPACE_URL, name)).replace('-', '').upper()
+ return str(uuid.uuid3(uuid.NAMESPACE_URL, name)).replace("-", "").upper()
def md5(text: str) -> str:
@@ -26,7 +26,7 @@ def md5(text: str) -> str:
def random_text(num: int) -> str:
- return ''.join(random.sample(string.ascii_lowercase + string.digits, num))
+ return "".join(random.sample(string.ascii_lowercase + string.digits, num))
def timestamp() -> int:
@@ -58,6 +58,6 @@ def get_recognize_server(uid: int) -> str:
def get_headers():
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
- "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36",
+ "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36",
}
return headers
diff --git a/modules/apihelper/hyperion.py b/modules/apihelper/hyperion.py
index 9300490..4e8d095 100644
--- a/modules/apihelper/hyperion.py
+++ b/modules/apihelper/hyperion.py
@@ -20,8 +20,10 @@ class Hyperion:
POST_FULL_URL = "https://bbs-api.mihoyo.com/post/wapi/getPostFull"
POST_FULL_IN_COLLECTION_URL = "https://bbs-api.mihoyo.com/post/wapi/getPostFullInCollection"
GET_NEW_LIST_URL = "https://bbs-api.mihoyo.com/post/wapi/getNewsList"
- USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " \
- "Chrome/90.0.4430.72 Safari/537.36"
+ USER_AGENT = (
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
+ "Chrome/90.0.4430.72 Safari/537.36"
+ )
def __init__(self):
self.client = HOYORequest(headers=self.get_headers())
@@ -42,34 +44,31 @@ class Hyperion:
if entries is None:
return -1
try:
- art_id = int(entries.get('article_id'))
+ art_id = int(entries.get("article_id"))
except (IndexError, ValueError, TypeError):
return -1
return art_id
def get_headers(self, referer: str = "https://bbs.mihoyo.com/"):
- return {
- "User-Agent": self.USER_AGENT,
- "Referer": referer
- }
+ return {"User-Agent": self.USER_AGENT, "Referer": referer}
@staticmethod
- def get_list_url_params(forum_id: int, is_good: bool = False, is_hot: bool = False,
- page_size: int = 20) -> dict:
+ def get_list_url_params(forum_id: int, is_good: bool = False, is_hot: bool = False, page_size: int = 20) -> dict:
params = {
"forum_id": forum_id,
"gids": 2,
"is_good": is_good,
"is_hot": is_hot,
"page_size": page_size,
- "sort_type": 1
+ "sort_type": 1,
}
return params
@staticmethod
- def get_images_params(resize: int = 600, quality: int = 80, auto_orient: int = 0, interlace: int = 1,
- images_format: str = "jpg"):
+ def get_images_params(
+ resize: int = 600, quality: int = 80, auto_orient: int = 0, interlace: int = 1, images_format: str = "jpg"
+ ):
"""
image/resize,s_600/quality,q_80/auto-orient,0/interlace,1/format,jpg
:param resize: 图片大小
@@ -79,25 +78,19 @@ class Hyperion:
:param images_format: 图片格式
:return:
"""
- params = f"image/resize,s_{resize}/quality,q_{quality}/auto-orient," \
- f"{auto_orient}/interlace,{interlace}/format,{images_format}"
+ params = (
+ f"image/resize,s_{resize}/quality,q_{quality}/auto-orient,"
+ f"{auto_orient}/interlace,{interlace}/format,{images_format}"
+ )
return {"x-oss-process": params}
async def get_post_full_in_collection(self, collection_id: int, gids: int = 2, order_type=1) -> JSONDict:
- params = {
- "collection_id": collection_id,
- "gids": gids,
- "order_type": order_type
- }
+ params = {"collection_id": collection_id, "gids": gids, "order_type": order_type}
response = await self.client.get(url=self.POST_FULL_IN_COLLECTION_URL, params=params)
return response
async def get_post_info(self, gids: int, post_id: int, read: int = 1) -> PostInfo:
- params = {
- "gids": gids,
- "post_id": post_id,
- "read": read
- }
+ params = {"gids": gids, "post_id": post_id, "read": read}
response = await self.client.get(self.POST_FULL_URL, params=params)
return PostInfo.paste_data(response)
@@ -128,11 +121,7 @@ class Hyperion:
?gids=2&page_size=20&type=3
:return:
"""
- params = {
- "gids": gids,
- "page_size": page_size,
- "type": type_id
- }
+ params = {"gids": gids, "page_size": page_size, "type": type_id}
response = await self.client.get(url=self.GET_NEW_LIST_URL, params=params)
return response
@@ -144,12 +133,14 @@ class GachaInfo:
GACHA_LIST_URL = "https://webstatic.mihoyo.com/hk4e/gacha_info/cn_gf01/gacha/list.json"
GACHA_INFO_URL = "https://webstatic.mihoyo.com/hk4e/gacha_info/cn_gf01/%s/zh-cn.json"
- USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " \
- "Chrome/90.0.4430.72 Safari/537.36"
+ USER_AGENT = (
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
+ "Chrome/90.0.4430.72 Safari/537.36"
+ )
def __init__(self):
self.headers = {
- 'User-Agent': self.USER_AGENT,
+ "User-Agent": self.USER_AGENT,
}
self.client = HOYORequest(headers=self.headers)
self.cache = {}
@@ -177,32 +168,35 @@ class GachaInfo:
class SignIn:
LOGIN_URL = "https://webapi.account.mihoyo.com/Api/login_by_mobilecaptcha"
- S_TOKEN_URL = "https://api-takumi.mihoyo.com/auth/api/getMultiTokenByLoginTicket?" \
- "login_ticket={0}&token_types=3&uid={1}"
+ S_TOKEN_URL = (
+ "https://api-takumi.mihoyo.com/auth/api/getMultiTokenByLoginTicket?" "login_ticket={0}&token_types=3&uid={1}"
+ )
BBS_URL = "https://api-takumi.mihoyo.com/account/auth/api/webLoginByMobile"
- USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " \
- "AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15"
+ USER_AGENT = (
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
+ "AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15"
+ )
HEADERS = {
"Host": "webapi.account.mihoyo.com",
"Connection": "keep-alive",
- "sec-ch-ua": "\".Not/A)Brand\";v=\"99\", \"Microsoft Edge\";v=\"103\", \"Chromium\";v=\"103\"",
+ "sec-ch-ua": '".Not/A)Brand";v="99", "Microsoft Edge";v="103", "Chromium";v="103"',
"DNT": "1",
"x-rpc-device_model": "OS X 10.15.7",
"sec-ch-ua-mobile": "?0",
"User-Agent": USER_AGENT,
- 'x-rpc-device_id': get_device_id(USER_AGENT),
+ "x-rpc-device_id": get_device_id(USER_AGENT),
"Accept": "application/json, text/plain, */*",
"x-rpc-device_name": "Microsoft Edge 103.0.1264.62",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"x-rpc-client_type": "4",
- "sec-ch-ua-platform": "\"macOS\"",
+ "sec-ch-ua-platform": '"macOS"',
"Origin": "https://user.mihoyo.com",
"Sec-Fetch-Site": "same-site",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"Referer": "https://user.mihoyo.com/",
"Accept-Encoding": "gzip, deflate, br",
- "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"
+ "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
}
BBS_HEADERS = {
"Host": "api-takumi.mihoyo.com",
@@ -213,7 +207,7 @@ class SignIn:
"Accept": "application/json, text/plain, */*",
"User-Agent": USER_AGENT,
"Referer": "https://bbs.mihoyo.com/",
- "Accept-Language": "zh-CN,zh-Hans;q=0.9"
+ "Accept-Language": "zh-CN,zh-Hans;q=0.9",
}
def __init__(self, phone: int):
@@ -251,7 +245,7 @@ class SignIn:
data = await self.client.post(
self.LOGIN_URL,
data={"mobile": str(self.phone), "mobile_captcha": str(captcha), "source": "user.mihoyo.com"},
- headers=self.HEADERS
+ headers=self.HEADERS,
)
res_json = data.json()
if self.check_error(res_json):
@@ -265,8 +259,7 @@ class SignIn:
async def get_s_token(self):
data = await self.client.get(
- self.S_TOKEN_URL.format(self.cookie["login_ticket"], self.uid),
- headers={"User-Agent": self.USER_AGENT}
+ self.S_TOKEN_URL.format(self.cookie["login_ticket"], self.uid), headers={"User-Agent": self.USER_AGENT}
)
res_json = data.json()
res_data = res_json.get("data", {}).get("list", [])
@@ -283,8 +276,8 @@ class SignIn:
"mobile": str(self.phone),
"captcha": str(captcha),
"action_type": "login",
- "token_type": 6
- }
+ "token_type": 6,
+ },
)
res_json = data.json()
if self.check_error(res_json):
diff --git a/modules/apihelper/request/hoyorequest.py b/modules/apihelper/request/hoyorequest.py
index 17125f1..d0178ad 100644
--- a/modules/apihelper/request/hoyorequest.py
+++ b/modules/apihelper/request/hoyorequest.py
@@ -8,9 +8,9 @@ from modules.apihelper.typedefs import POST_DATA, JSON_DATA
class HOYORequest(HTTPXRequest):
-
- async def get(self, url: str, *args, de_json: bool = True, re_json_data: bool = False, **kwargs) \
- -> Union[POST_DATA, JSON_DATA, bytes]:
+ async def get(
+ self, url: str, *args, de_json: bool = True, re_json_data: bool = False, **kwargs
+ ) -> Union[POST_DATA, JSON_DATA, bytes]:
try:
response = await self._client.get(url=url, *args, **kwargs)
except httpx.TimeoutException as err:
diff --git a/modules/apihelper/request/httpxrequest.py b/modules/apihelper/request/httpxrequest.py
index e61a2a7..052dc5c 100644
--- a/modules/apihelper/request/httpxrequest.py
+++ b/modules/apihelper/request/httpxrequest.py
@@ -6,7 +6,6 @@ import httpx
class HTTPXRequest(AbstractAsyncContextManager):
-
def __init__(self, *args, headers=None, **kwargs):
self._client = httpx.AsyncClient(headers=headers, *args, **kwargs)
@@ -18,8 +17,9 @@ class HTTPXRequest(AbstractAsyncContextManager):
await self.shutdown()
raise exc
- async def __aexit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException],
- exc_tb: Optional[TracebackType]) -> None:
+ async def __aexit__(
+ self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType]
+ ) -> None:
await self.initialize()
diff --git a/modules/playercards/helpers.py b/modules/playercards/helpers.py
index 3ee0622..a4a1a31 100644
--- a/modules/playercards/helpers.py
+++ b/modules/playercards/helpers.py
@@ -15,29 +15,33 @@ with open(_fix_skills_level_file, "r", encoding="utf-8") as f:
class ArtifactStatsTheory:
-
def __init__(self, character_name: str):
self.character_name = character_name
fight_prop_rule_list = fight_prop_rule_data.get(self.character_name, [])
self.main_prop = [FightProp(fight_prop_rule) for fight_prop_rule in fight_prop_rule_list]
if not self.main_prop:
- self.main_prop = [FightProp.FIGHT_PROP_CRITICAL, FightProp.FIGHT_PROP_CRITICAL_HURT,
- FightProp.FIGHT_PROP_ATTACK_PERCENT]
+ self.main_prop = [
+ FightProp.FIGHT_PROP_CRITICAL,
+ FightProp.FIGHT_PROP_CRITICAL_HURT,
+ FightProp.FIGHT_PROP_ATTACK_PERCENT,
+ ]
# 修正要评分的数值词条
if FightProp.FIGHT_PROP_ATTACK_PERCENT in self.main_prop and FightProp.FIGHT_PROP_ATTACK not in self.main_prop:
self.main_prop.append(FightProp.FIGHT_PROP_ATTACK)
if FightProp.FIGHT_PROP_HP_PERCENT in self.main_prop and FightProp.FIGHT_PROP_HP not in self.main_prop:
self.main_prop.append(FightProp.FIGHT_PROP_HP)
- if FightProp.FIGHT_PROP_DEFENSE_PERCENT in self.main_prop and \
- FightProp.FIGHT_PROP_DEFENSE not in self.main_prop:
+ if (
+ FightProp.FIGHT_PROP_DEFENSE_PERCENT in self.main_prop
+ and FightProp.FIGHT_PROP_DEFENSE not in self.main_prop
+ ):
self.main_prop.append(FightProp.FIGHT_PROP_DEFENSE)
def theory(self, sub_stats: EquipmentsStats) -> float:
"""圣遗物副词条评分
- Args:
- sub_stats: 圣遗物对象
- Returns:
- 返回得分
+ Args:
+ sub_stats: 圣遗物对象
+ Returns:
+ 返回得分
"""
score: float = 0
if sub_stats.prop_id in map(lambda x: x.name, self.main_prop):
diff --git a/modules/wiki/base.py b/modules/wiki/base.py
index cf5dc36..d05da0b 100644
--- a/modules/wiki/base.py
+++ b/modules/wiki/base.py
@@ -16,7 +16,7 @@ from pydantic import (
)
from typing_extensions import Self
-__all__ = ['Model', 'WikiModel', 'HONEY_HOST']
+__all__ = ["Model", "WikiModel", "HONEY_HOST"]
HONEY_HOST = URL("https://genshin.honeyhunterworld.com/")
@@ -39,13 +39,13 @@ class WikiModel(Model):
# noinspection PyUnresolvedReferences
"""wiki所用到的基类
- Attributes:
- id (:obj:`int`): ID
- name (:obj:`str`): 名称
- rarity (:obj:`int`): 星级
+ Attributes:
+ id (:obj:`int`): ID
+ name (:obj:`str`): 名称
+ rarity (:obj:`int`): 星级
- _client (:class:`httpx.AsyncClient`): 发起 http 请求的 client
- """
+ _client (:class:`httpx.AsyncClient`): 发起 http 请求的 client
+ """
_client: ClassVar[AsyncClient] = AsyncClient()
id: str
@@ -107,7 +107,7 @@ class WikiModel(Model):
返回对应的 WikiModel
"""
response = await cls._client_get(url)
- return await cls._parse_soup(BeautifulSoup(response.text, 'lxml'))
+ return await cls._parse_soup(BeautifulSoup(response.text, "lxml"))
@classmethod
async def get_by_id(cls, id_: str) -> Self:
@@ -152,7 +152,7 @@ class WikiModel(Model):
返回能爬到的所有的 WikiModel 所组成的 List
"""
queue: Queue[Self] = Queue() # 存放 Model 的队列
- signal = Value('i', 0) # 一个用于异步任务同步的信号
+ signal = Value("i", 0) # 一个用于异步任务同步的信号
async def task(u):
# 包装的爬虫任务
@@ -196,18 +196,18 @@ class WikiModel(Model):
"""
urls = cls.scrape_urls()
queue: Queue[Union[str, Tuple[str, URL]]] = Queue() # 存放 Model 的队列
- signal = Value('i', len(urls)) # 一个用于异步任务同步的信号,初始值为存放所需要爬取的页面数
+ signal = Value("i", len(urls)) # 一个用于异步任务同步的信号,初始值为存放所需要爬取的页面数
async def task(page: URL):
"""包装的爬虫任务"""
response = await cls._client_get(page)
# 从页面中获取对应的 chaos data (未处理的json格式字符串)
- chaos_data = re.findall(r'sortable_data\.push\((.*)\);\s*sortable_cur_page', response.text)[0]
+ chaos_data = re.findall(r"sortable_data\.push\((.*)\);\s*sortable_cur_page", response.text)[0]
json_data = json.loads(chaos_data) # 转为 json
for data in json_data: # 遍历 json
- data_name = re.findall(r'>(.*)<', data[1])[0] # 获取 Model 的名称
+ data_name = re.findall(r">(.*)<", data[1])[0] # 获取 Model 的名称
if with_url: # 如果需要返回对应的 url
- data_url = HONEY_HOST.join(re.findall(r'\"(.*?)\"', data[0])[0])
+ data_url = HONEY_HOST.join(re.findall(r"\"(.*?)\"", data[0])[0])
await queue.put((data_name, data_url))
else:
await queue.put(data_name)
diff --git a/modules/wiki/character.py b/modules/wiki/character.py
index e380301..e38dc00 100644
--- a/modules/wiki/character.py
+++ b/modules/wiki/character.py
@@ -15,6 +15,7 @@ class Birth(Model):
day: 天
month: 月
"""
+
day: int
month: int
@@ -26,6 +27,7 @@ class CharacterAscension(Model):
level: 等级突破材料
skill: 技能/天赋培养材料
"""
+
level: List[str] = []
skill: List[str] = []
@@ -42,6 +44,7 @@ class CharacterState(Model):
CD: 暴击伤害
bonus: 突破属性
"""
+
level: str
HP: int
ATK: float
@@ -97,23 +100,23 @@ class Character(WikiModel):
return [HONEY_HOST.join("fam_chars/?lang=CHS")]
@classmethod
- async def _parse_soup(cls, soup: BeautifulSoup) -> 'Character':
+ async def _parse_soup(cls, soup: BeautifulSoup) -> "Character":
"""解析角色页"""
- soup = soup.select('.wp-block-post-content')[0]
- tables = soup.find_all('table')
- table_rows = tables[0].find_all('tr')
+ soup = soup.select(".wp-block-post-content")[0]
+ tables = soup.find_all("table")
+ table_rows = tables[0].find_all("tr")
def get_table_text(row_num: int) -> str:
"""一个快捷函数,用于返回表格对应行的最后一个单元格中的文本"""
- return table_rows[row_num].find_all('td')[-1].text.replace('\xa0', '')
+ return table_rows[row_num].find_all("td")[-1].text.replace("\xa0", "")
- id_ = re.findall(r'img/(.*?_\d+)_.*', table_rows[0].find('img').attrs['src'])[0]
+ id_ = re.findall(r"img/(.*?_\d+)_.*", table_rows[0].find("img").attrs["src"])[0]
name = get_table_text(0)
- if name != '旅行者': # 如果角色名不是 旅行者
+ if name != "旅行者": # 如果角色名不是 旅行者
title = get_table_text(1)
occupation = get_table_text(2)
association = Association.convert(get_table_text(3).lower().title())
- rarity = len(table_rows[4].find_all('img'))
+ rarity = len(table_rows[4].find_all("img"))
weapon_type = WeaponType[get_table_text(5)]
element = Element[get_table_text(6)]
birth = Birth(day=int(get_table_text(7)), month=int(get_table_text(8)))
@@ -123,11 +126,11 @@ class Character(WikiModel):
en_cv = get_table_text(13)
kr_cv = get_table_text(14)
else:
- name = '空' if id_.endswith('5') else '荧'
+ name = "空" if id_.endswith("5") else "荧"
title = get_table_text(0)
occupation = get_table_text(1)
association = Association.convert(get_table_text(2).lower().title())
- rarity = len(table_rows[3].find_all('img'))
+ rarity = len(table_rows[3].find_all("img"))
weapon_type = WeaponType[get_table_text(4)]
element = Element[get_table_text(5)]
birth = None
@@ -139,30 +142,50 @@ class Character(WikiModel):
description = get_table_text(-3)
ascension = CharacterAscension(
level=[
- target[0] for i in table_rows[-2].find_all('a')
- if (target := re.findall(r'/(.*)/', i.attrs['href'])) # 过滤掉错误的材料(honey网页的bug)
+ target[0]
+ for i in table_rows[-2].find_all("a")
+ if (target := re.findall(r"/(.*)/", i.attrs["href"])) # 过滤掉错误的材料(honey网页的bug)
],
- skill=[re.findall(r'/(.*)/', i.attrs['href'])[0] for i in table_rows[-1].find_all('a')]
+ skill=[re.findall(r"/(.*)/", i.attrs["href"])[0] for i in table_rows[-1].find_all("a")],
)
stats = []
- for row in tables[2].find_all('tr')[1:]:
- cells = row.find_all('td')
+ for row in tables[2].find_all("tr")[1:]:
+ cells = row.find_all("td")
stats.append(
CharacterState(
- level=cells[0].text, HP=cells[1].text, ATK=cells[2].text, DEF=cells[3].text,
- CR=cells[4].text, CD=cells[5].text, bonus=cells[6].text
+ level=cells[0].text,
+ HP=cells[1].text,
+ ATK=cells[2].text,
+ DEF=cells[3].text,
+ CR=cells[4].text,
+ CD=cells[5].text,
+ bonus=cells[6].text,
)
)
return Character(
- id=id_, name=name, title=title, occupation=occupation, association=association, weapon_type=weapon_type,
- element=element, birth=birth, constellation=constellation, cn_cv=cn_cv, jp_cv=jp_cv, rarity=rarity,
- en_cv=en_cv, kr_cv=kr_cv, description=description, ascension=ascension, stats=stats
+ id=id_,
+ name=name,
+ title=title,
+ occupation=occupation,
+ association=association,
+ weapon_type=weapon_type,
+ element=element,
+ birth=birth,
+ constellation=constellation,
+ cn_cv=cn_cv,
+ jp_cv=jp_cv,
+ rarity=rarity,
+ en_cv=en_cv,
+ kr_cv=kr_cv,
+ description=description,
+ ascension=ascension,
+ stats=stats,
)
@classmethod
async def get_url_by_name(cls, name: str) -> Optional[URL]:
# 重写此函数的目的是处理主角名字的 ID
- _map = {'荧': "playergirl_007", '空': "playerboy_005"}
+ _map = {"荧": "playergirl_007", "空": "playerboy_005"}
if (id_ := _map.get(name)) is not None:
return await cls.get_url_by_id(id_)
return await super(Character, cls).get_url_by_name(name)
@@ -170,8 +193,8 @@ class Character(WikiModel):
@property
def icon(self) -> CharacterIcon:
return CharacterIcon(
- icon=str(HONEY_HOST.join(f'/img/{self.id}_icon.webp')),
- side=str(HONEY_HOST.join(f'/img/{self.id}_side_icon.webp')),
- gacha=str(HONEY_HOST.join(f'/img/{self.id}_gacha_card.webp')),
- splash=str(HONEY_HOST.join(f'/img/{self.id}_gacha_splash.webp'))
+ icon=str(HONEY_HOST.join(f"/img/{self.id}_icon.webp")),
+ side=str(HONEY_HOST.join(f"/img/{self.id}_side_icon.webp")),
+ gacha=str(HONEY_HOST.join(f"/img/{self.id}_gacha_card.webp")),
+ splash=str(HONEY_HOST.join(f"/img/{self.id}_gacha_splash.webp")),
)
diff --git a/modules/wiki/material.py b/modules/wiki/material.py
index 44294f0..cfdbdcd 100644
--- a/modules/wiki/material.py
+++ b/modules/wiki/material.py
@@ -6,21 +6,21 @@ from httpx import URL
from modules.wiki.base import HONEY_HOST, WikiModel
-__all__ = ['Material']
+__all__ = ["Material"]
-WEEKDAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
+WEEKDAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
class Material(WikiModel):
# noinspection PyUnresolvedReferences
"""武器、角色培养素材
- Attributes:
- type: 类型
- weekdays: 每周开放的时间
- source: 获取方式
- description: 描述
- """
+ Attributes:
+ type: 类型
+ weekdays: 每周开放的时间
+ source: 获取方式
+ description: 描述
+ """
type: str
source: Optional[List[str]] = None
weekdays: Optional[List[int]] = None
@@ -28,8 +28,8 @@ class Material(WikiModel):
@staticmethod
def scrape_urls() -> List[URL]:
- weapon = [HONEY_HOST.join(f'fam_wep_{i}/?lang=CHS') for i in ['primary', 'secondary', 'common']]
- talent = [HONEY_HOST.join(f'fam_talent_{i}/?lang=CHS') for i in ['book', 'boss', 'common', 'reward']]
+ weapon = [HONEY_HOST.join(f"fam_wep_{i}/?lang=CHS") for i in ["primary", "secondary", "common"]]
+ talent = [HONEY_HOST.join(f"fam_talent_{i}/?lang=CHS") for i in ["book", "boss", "common", "reward"]]
return weapon + talent
@classmethod
@@ -39,37 +39,37 @@ class Material(WikiModel):
@classmethod
async def _parse_soup(cls, soup: BeautifulSoup) -> "Material":
"""解析突破素材页"""
- soup = soup.select('.wp-block-post-content')[0]
- tables = soup.find_all('table')
- table_rows = tables[0].find_all('tr')
+ soup = soup.select(".wp-block-post-content")[0]
+ tables = soup.find_all("table")
+ table_rows = tables[0].find_all("tr")
def get_table_row(target: str):
"""一个便捷函数,用于返回对应表格头的对应行的最后一个单元格中的文本"""
for row in table_rows:
- if target in row.find('td').text:
- return row.find_all('td')[-1]
+ if target in row.find("td").text:
+ return row.find_all("td")[-1]
def get_table_text(row_num: int) -> str:
"""一个便捷函数,用于返回表格对应行的最后一个单元格中的文本"""
- return table_rows[row_num].find_all('td')[-1].text.replace('\xa0', '')
+ return table_rows[row_num].find_all("td")[-1].text.replace("\xa0", "")
- id_ = re.findall(r'/img/(.*?)\.webp', str(table_rows[0]))[0]
+ id_ = re.findall(r"/img/(.*?)\.webp", str(table_rows[0]))[0]
name = get_table_text(0)
- rarity = len(table_rows[3].find_all('img'))
+ rarity = len(table_rows[3].find_all("img"))
type_ = get_table_text(1)
- if (item_source := get_table_row('Item Source')) is not None:
+ if (item_source := get_table_row("Item Source")) is not None:
item_source = list(
# filter 在这里的作用是过滤掉为空的数据
- filter(lambda x: x, item_source.encode_contents().decode().split('
'))
+ filter(lambda x: x, item_source.encode_contents().decode().split("
"))
)
- if (alter_source := get_table_row('Alternative Item')) is not None:
+ if (alter_source := get_table_row("Alternative Item")) is not None:
alter_source = list(
# filter 在这里的作用是过滤掉为空的数据
- filter(lambda x: x, alter_source.encode_contents().decode().split('
'))
+ filter(lambda x: x, alter_source.encode_contents().decode().split("
"))
)
source = list(sorted(set((item_source or []) + (alter_source or []))))
- if (weekdays := get_table_row('Weekday')) is not None:
- weekdays = [*(WEEKDAYS.index(weekdays.text.replace('\xa0', '').split(',')[0]) + 3 * i for i in range(2)), 6]
+ if (weekdays := get_table_row("Weekday")) is not None:
+ weekdays = [*(WEEKDAYS.index(weekdays.text.replace("\xa0", "").split(",")[0]) + 3 * i for i in range(2)), 6]
description = get_table_text(-1)
return Material(
id=id_, name=name, rarity=rarity, type=type_, description=description, source=source, weekdays=weekdays
@@ -77,4 +77,4 @@ class Material(WikiModel):
@property
def icon(self) -> str:
- return str(HONEY_HOST.join(f'/img/{self.id}.webp'))
+ return str(HONEY_HOST.join(f"/img/{self.id}.webp"))
diff --git a/modules/wiki/other.py b/modules/wiki/other.py
index 41357fd..4677f04 100644
--- a/modules/wiki/other.py
+++ b/modules/wiki/other.py
@@ -6,41 +6,43 @@ from typing_extensions import Self
from modules.wiki.base import HONEY_HOST
__all__ = [
- 'Element',
- 'WeaponType',
- 'AttributeType',
- 'Association',
+ "Element",
+ "WeaponType",
+ "AttributeType",
+ "Association",
]
class Element(Enum):
"""元素"""
- Pyro = '火'
- Hydro = '水'
- Electro = '雷'
- Cryo = '冰'
- Dendro = '草'
- Anemo = '风'
- Geo = '岩'
- Multi = '无' # 主角
+
+ Pyro = "火"
+ Hydro = "水"
+ Electro = "雷"
+ Cryo = "冰"
+ Dendro = "草"
+ Anemo = "风"
+ Geo = "岩"
+ Multi = "无" # 主角
_WEAPON_ICON_MAP = {
- 'Sword': HONEY_HOST.join('img/s_23101.png'),
- 'Claymore': HONEY_HOST.join('img/s_163101.png'),
- 'Polearm': HONEY_HOST.join('img/s_233101.png'),
- 'Catalyst': HONEY_HOST.join('img/s_43101.png'),
- 'Bow': HONEY_HOST.join('img/s_213101.png'),
+ "Sword": HONEY_HOST.join("img/s_23101.png"),
+ "Claymore": HONEY_HOST.join("img/s_163101.png"),
+ "Polearm": HONEY_HOST.join("img/s_233101.png"),
+ "Catalyst": HONEY_HOST.join("img/s_43101.png"),
+ "Bow": HONEY_HOST.join("img/s_213101.png"),
}
class WeaponType(Enum):
"""武器类型"""
- Sword = '单手剑'
- Claymore = '双手剑'
- Polearm = '长柄武器'
- Catalyst = '法器'
- Bow = '弓'
+
+ Sword = "单手剑"
+ Claymore = "双手剑"
+ Polearm = "长柄武器"
+ Catalyst = "法器"
+ Bow = "弓"
def icon_url(self) -> str:
return str(_WEAPON_ICON_MAP.get(self.name))
@@ -49,17 +51,17 @@ class WeaponType(Enum):
_ATTR_TYPE_MAP = {
# 这个字典用于将 Honey 页面中遇到的 属性的缩写的字符 转为 AttributeType 的字符
# 例如 Honey 页面上写的 HP% 则对应 HP_p
- "HP": ['Health'],
- "HP_p": ['HP%', 'Health %'],
- "ATK": ['Attack'],
- "ATK_p": ['Atk%', 'Attack %'],
- "DEF": ['Defense'],
- "DEF_p": ['Def%', 'Defense %'],
- "EM": ['Elemental Mastery'],
- "ER": ['ER%', 'Energy Recharge %'],
- "CR": ['CrR%', 'Critical Rate %', 'CritRate%'],
- "CD": ['Crd%', 'Critical Damage %', 'CritDMG%'],
- "PD": ['Phys%', 'Physical Damage %'],
+ "HP": ["Health"],
+ "HP_p": ["HP%", "Health %"],
+ "ATK": ["Attack"],
+ "ATK_p": ["Atk%", "Attack %"],
+ "DEF": ["Defense"],
+ "DEF_p": ["Def%", "Defense %"],
+ "EM": ["Elemental Mastery"],
+ "ER": ["ER%", "Energy Recharge %"],
+ "CR": ["CrR%", "Critical Rate %", "CritRate%"],
+ "CD": ["Crd%", "Critical Damage %", "CritDMG%"],
+ "PD": ["Phys%", "Physical Damage %"],
"HB": [],
"Pyro": [],
"Hydro": [],
@@ -73,6 +75,7 @@ _ATTR_TYPE_MAP = {
class AttributeType(Enum):
"""属性枚举类。包含了武器和圣遗物的属性。"""
+
HP = "生命"
HP_p = "生命%"
ATK = "攻击力"
@@ -85,13 +88,13 @@ class AttributeType(Enum):
CD = "暴击伤害"
PD = "物理伤害加成"
HB = "治疗加成"
- Pyro = '火元素伤害加成'
- Hydro = '水元素伤害加成'
- Electro = '雷元素伤害加成'
- Cryo = '冰元素伤害加成'
- Dendro = '草元素伤害加成'
- Anemo = '风元素伤害加成'
- Geo = '岩元素伤害加成'
+ Pyro = "火元素伤害加成"
+ Hydro = "水元素伤害加成"
+ Electro = "雷元素伤害加成"
+ Cryo = "冰元素伤害加成"
+ Dendro = "草元素伤害加成"
+ Anemo = "风元素伤害加成"
+ Geo = "岩元素伤害加成"
@classmethod
def convert(cls, string: str) -> Optional[Self]:
@@ -102,23 +105,24 @@ class AttributeType(Enum):
_ASSOCIATION_MAP = {
- 'Other': ['Mainactor', 'Ranger', 'Fatui'],
- 'Snezhnaya': [],
- 'Sumeru': [],
- 'Inazuma': [],
- 'Liyue': [],
- 'Mondstadt': [],
+ "Other": ["Mainactor", "Ranger", "Fatui"],
+ "Snezhnaya": [],
+ "Sumeru": [],
+ "Inazuma": [],
+ "Liyue": [],
+ "Mondstadt": [],
}
class Association(Enum):
"""角色所属地区"""
- Other = '其它'
- Snezhnaya = '至冬'
- Sumeru = '须弥'
- Inazuma = '稻妻'
- Liyue = '璃月'
- Mondstadt = '蒙德'
+
+ Other = "其它"
+ Snezhnaya = "至冬"
+ Sumeru = "须弥"
+ Inazuma = "稻妻"
+ Liyue = "璃月"
+ Mondstadt = "蒙德"
@classmethod
def convert(cls, string: str) -> Optional[Self]:
diff --git a/modules/wiki/weapon.py b/modules/wiki/weapon.py
index ff4afa3..65d6fea 100644
--- a/modules/wiki/weapon.py
+++ b/modules/wiki/weapon.py
@@ -8,11 +8,12 @@ from httpx import URL
from modules.wiki.base import Model, HONEY_HOST, WikiModel
from modules.wiki.other import AttributeType, WeaponType
-__all__ = ['Weapon', 'WeaponAffix', 'WeaponAttribute']
+__all__ = ["Weapon", "WeaponAffix", "WeaponAttribute"]
class WeaponAttribute(Model):
"""武器词条"""
+
type: AttributeType
value: str
@@ -25,6 +26,7 @@ class WeaponAffix(Model):
description: 技能描述
"""
+
name: str
description: List[str]
@@ -69,38 +71,36 @@ class Weapon(WikiModel):
return [HONEY_HOST.join(f"fam_{i.lower()}/?lang=CHS") for i in WeaponType.__members__]
@classmethod
- async def _parse_soup(cls, soup: BeautifulSoup) -> 'Weapon':
+ async def _parse_soup(cls, soup: BeautifulSoup) -> "Weapon":
"""解析武器页"""
- soup = soup.select('.wp-block-post-content')[0]
- tables = soup.find_all('table')
- table_rows = tables[0].find_all('tr')
+ soup = soup.select(".wp-block-post-content")[0]
+ tables = soup.find_all("table")
+ table_rows = tables[0].find_all("tr")
def get_table_text(row_num: int) -> str:
"""一个快捷函数,用于返回表格对应行的最后一个单元格中的文本"""
- return table_rows[row_num].find_all('td')[-1].text.replace('\xa0', '')
+ return table_rows[row_num].find_all("td")[-1].text.replace("\xa0", "")
def find_table(select: str):
"""一个快捷函数,用于寻找对应表格头的表格"""
- return list(filter(lambda x: select in ' '.join(x.attrs['class']), tables))
+ return list(filter(lambda x: select in " ".join(x.attrs["class"]), tables))
- id_ = re.findall(r'/img/(.*?)_gacha', str(table_rows[0]))[0]
- weapon_type = WeaponType[get_table_text(1).split(',')[-1].strip()]
+ id_ = re.findall(r"/img/(.*?)_gacha", str(table_rows[0]))[0]
+ weapon_type = WeaponType[get_table_text(1).split(",")[-1].strip()]
name = get_table_text(0)
- rarity = len(table_rows[2].find_all('img'))
+ rarity = len(table_rows[2].find_all("img"))
attack = float(get_table_text(4))
- ascension = [re.findall(r'/(.*)/', tag.attrs['href'])[0] for tag in table_rows[-1].find_all('a')]
+ ascension = [re.findall(r"/(.*)/", tag.attrs["href"])[0] for tag in table_rows[-1].find_all("a")]
if rarity > 2: # 如果是 3 星及其以上的武器
attribute = WeaponAttribute(
- type=AttributeType.convert(
- tables[2].find('thead').find('tr').find_all('td')[2].text.split(' ')[1]
- ),
- value=get_table_text(6)
+ type=AttributeType.convert(tables[2].find("thead").find("tr").find_all("td")[2].text.split(" ")[1]),
+ value=get_table_text(6),
+ )
+ affix = WeaponAffix(
+ name=get_table_text(7), description=[i.find_all("td")[1].text for i in tables[3].find_all("tr")[1:]]
)
- affix = WeaponAffix(name=get_table_text(7), description=[
- i.find_all('td')[1].text for i in tables[3].find_all('tr')[1:]
- ])
description = get_table_text(-1) if len(tables) < 11 else get_table_text(9)
- if story_table := find_table('quotes'):
+ if story_table := find_table("quotes"):
story = story_table[0].text.strip()
else:
story = None
@@ -109,15 +109,24 @@ class Weapon(WikiModel):
description = get_table_text(5)
story = tables[-1].text.strip()
stats = []
- for row in tables[2].find_all('tr')[1:]:
- cells = row.find_all('td')
+ for row in tables[2].find_all("tr")[1:]:
+ cells = row.find_all("td")
if rarity > 2:
stats.append(WeaponState(level=cells[0].text, ATK=cells[1].text, bonus=cells[2].text))
else:
stats.append(WeaponState(level=cells[0].text, ATK=cells[1].text))
return Weapon(
- id=id_, name=name, rarity=rarity, attack=attack, attribute=attribute, affix=affix, weapon_type=weapon_type,
- story=story, stats=stats, description=description, ascension=ascension
+ id=id_,
+ name=name,
+ rarity=rarity,
+ attack=attack,
+ attribute=attribute,
+ affix=affix,
+ weapon_type=weapon_type,
+ story=story,
+ stats=stats,
+ description=description,
+ ascension=ascension,
)
@classmethod
@@ -125,16 +134,14 @@ class Weapon(WikiModel):
# 重写此函数的目的是名字去重,例如单手剑页面中有三个 “「一心传」名刀”
name_list = [i async for i in cls._name_list_generator(with_url=with_url)]
if with_url:
- return [
- (i[0], list(i[1])[0][1]) for i in itertools.groupby(name_list, lambda x: x[0])
- ]
+ return [(i[0], list(i[1])[0][1]) for i in itertools.groupby(name_list, lambda x: x[0])]
else:
return [i[0] for i in itertools.groupby(name_list, lambda x: x)]
@property
def icon(self) -> WeaponIcon:
return WeaponIcon(
- icon=str(HONEY_HOST.join(f'/img/{self.id}.webp')),
- awakened=str(HONEY_HOST.join(f'/img/{self.id}_awaken_icon.webp')),
- gacha=str(HONEY_HOST.join(f'/img/{self.id}_gacha_icon.webp')),
+ icon=str(HONEY_HOST.join(f"/img/{self.id}.webp")),
+ awakened=str(HONEY_HOST.join(f"/img/{self.id}_awaken_icon.webp")),
+ gacha=str(HONEY_HOST.join(f"/img/{self.id}_gacha_icon.webp")),
)
diff --git a/plugins/genshin/abyss.py b/plugins/genshin/abyss.py
index cbbf767..3963ab5 100644
--- a/plugins/genshin/abyss.py
+++ b/plugins/genshin/abyss.py
@@ -21,11 +21,13 @@ from utils.log import logger
class AbyssUnlocked(Exception):
"""根本没动"""
+
pass
class NoMostKills(Exception):
"""挑战了但是数据没刷新"""
+
pass
@@ -33,11 +35,11 @@ class Abyss(Plugin, BasePlugin):
"""深渊数据查询"""
def __init__(
- self,
- user_service: UserService = None,
- cookies_service: CookiesService = None,
- template_service: TemplateService = None,
- assets_service: AssetsService = None
+ self,
+ user_service: UserService = None,
+ cookies_service: CookiesService = None,
+ template_service: TemplateService = None,
+ assets_service: AssetsService = None,
):
self.template_service = template_service
self.cookies_service = cookies_service
@@ -77,20 +79,20 @@ class Abyss(Plugin, BasePlugin):
},
"strongest_strike": {
"icon": await self.assets_service.avatar(ranks.strongest_strike[0].id).side(),
- "value": ranks.strongest_strike[0].value
+ "value": ranks.strongest_strike[0].value,
},
"most_damage_taken": {
"icon": await self.assets_service.avatar(ranks.most_damage_taken[0].id).side(),
- "value": ranks.most_damage_taken[0].value
+ "value": ranks.most_damage_taken[0].value,
},
"most_bursts_used": {
"icon": await self.assets_service.avatar(ranks.most_bursts_used[0].id).side(),
- "value": ranks.most_bursts_used[0].value
+ "value": ranks.most_bursts_used[0].value,
},
"most_skills_used": {
"icon": await self.assets_service.avatar(ranks.most_skills_used[0].id).side(),
- "value": ranks.most_skills_used[0].value
- }
+ "value": ranks.most_skills_used[0].value,
+ },
}
# most_kills
most_played_list = ranks.most_played
@@ -98,7 +100,7 @@ class Abyss(Plugin, BasePlugin):
temp = {
"icon": await self.assets_service.avatar(most_played.id).icon(),
"value": most_played.value,
- "background": self._get_role_star_bg(most_played.rarity)
+ "background": self._get_role_star_bg(most_played.rarity),
}
abyss_data["most_played_list"].append(temp)
return abyss_data
@@ -132,7 +134,7 @@ class Abyss(Plugin, BasePlugin):
await message.reply_text("本次深渊旅行者还没挑战呢,咕咕咕~~~")
return
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
- png_data = await self.template_service.render('genshin/abyss', "abyss.html", abyss_data,
- {"width": 865, "height": 504}, full_page=False)
- await message.reply_photo(png_data, filename=f"abyss_{user.id}.png",
- allow_sending_without_reply=True)
+ png_data = await self.template_service.render(
+ "genshin/abyss", "abyss.html", abyss_data, {"width": 865, "height": 504}, full_page=False
+ )
+ await message.reply_photo(png_data, filename=f"abyss_{user.id}.png", allow_sending_without_reply=True)
diff --git a/plugins/genshin/artifact_rate.py b/plugins/genshin/artifact_rate.py
index 77d63e0..37c4360 100644
--- a/plugins/genshin/artifact_rate.py
+++ b/plugins/genshin/artifact_rate.py
@@ -18,15 +18,17 @@ COMMAND_RESULT = 1
class ArtifactRate(Plugin.Conversation, BasePlugin.Conversation):
"""圣遗物评分"""
- STAR_KEYBOARD = [[
- InlineKeyboardButton(
- f"{i}", callback_data=f"artifact_ocr_rate_data|star|{i}") for i in range(1, 6)
- ]]
+ STAR_KEYBOARD = [
+ [InlineKeyboardButton(f"{i}", callback_data=f"artifact_ocr_rate_data|star|{i}") for i in range(1, 6)]
+ ]
- LEVEL_KEYBOARD = [[
- InlineKeyboardButton(
- 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)]
+ LEVEL_KEYBOARD = [
+ [
+ InlineKeyboardButton(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):
self.artifact_rate = ArtifactOcrRate()
@@ -39,19 +41,21 @@ class ArtifactRate(Plugin.Conversation, BasePlugin.Conversation):
return artifact_attr.get("message", "API请求错误")
return "API请求错误"
rate_result = rate_result_req.json()
- return "*圣遗物评分结果*\n" \
- f"主属性:{escape_markdown(artifact_attr['main_item']['name'], version=2)}\n" \
- f"{escape_markdown(get_format_sub_item(artifact_attr), version=2)}" \
- f'`--------------------`\n' \
- f"总分:{escape_markdown(rate_result['total_percent'], version=2)}\n" \
- f"主词条:{escape_markdown(rate_result['main_percent'], version=2)}\n" \
- f"副词条:{escape_markdown(rate_result['sub_percent'], version=2)}\n" \
- f'`--------------------`\n' \
- f"{escape_markdown(get_comment(rate_result['total_percent']), version=2)}\n" \
- "_评分、识图均来自 genshin\\.pub_"
+ return (
+ "*圣遗物评分结果*\n"
+ f"主属性:{escape_markdown(artifact_attr['main_item']['name'], version=2)}\n"
+ f"{escape_markdown(get_format_sub_item(artifact_attr), version=2)}"
+ f"`--------------------`\n"
+ f"总分:{escape_markdown(rate_result['total_percent'], version=2)}\n"
+ f"主词条:{escape_markdown(rate_result['main_percent'], version=2)}\n"
+ f"副词条:{escape_markdown(rate_result['sub_percent'], version=2)}\n"
+ f"`--------------------`\n"
+ f"{escape_markdown(get_comment(rate_result['total_percent']), version=2)}\n"
+ "_评分、识图均来自 genshin\\.pub_"
+ )
@conversation.entry_point
- @handler.command(command='artifact_rate', filters=filters.ChatType.PRIVATE, block=True)
+ @handler.command(command="artifact_rate", filters=filters.ChatType.PRIVATE, block=True)
@handler.message(filters=filters.Regex(r"^圣遗物评分(.*)"), block=True)
@handler.message(filters=filters.CaptionRegex(r"^圣遗物评分(.*)"), block=True)
@error_callable
@@ -95,15 +99,12 @@ class ArtifactRate(Plugin.Conversation, BasePlugin.Conversation):
artifact_attr = artifact_attr_req.json()
context.user_data["artifact_attr"] = artifact_attr
if artifact_attr.get("star") is None:
- await message.reply_text("无法识别圣遗物星级,请选择圣遗物星级",
- reply_markup=InlineKeyboardMarkup(self.STAR_KEYBOARD))
+ await message.reply_text("无法识别圣遗物星级,请选择圣遗物星级", reply_markup=InlineKeyboardMarkup(self.STAR_KEYBOARD))
return COMMAND_RESULT
if artifact_attr.get("level") is None:
- await message.reply_text("无法识别圣遗物等级,请选择圣遗物等级",
- reply_markup=InlineKeyboardMarkup(self.LEVEL_KEYBOARD))
+ await message.reply_text("无法识别圣遗物等级,请选择圣遗物等级", reply_markup=InlineKeyboardMarkup(self.LEVEL_KEYBOARD))
return COMMAND_RESULT
- reply_message = await message.reply_text("识图成功!\n"
- "正在评分中...")
+ reply_message = await message.reply_text("识图成功!\n" "正在评分中...")
rate_text = await self.get_rate(artifact_attr)
await reply_message.edit_text(rate_text, parse_mode=ParseMode.MARKDOWN_V2)
return ConversationHandler.END
@@ -138,12 +139,10 @@ class ArtifactRate(Plugin.Conversation, BasePlugin.Conversation):
await query.edit_message_text("数据错误")
return ConversationHandler.END
if artifact_attr.get("level") is None:
- await query.edit_message_text("无法识别圣遗物等级,请选择圣遗物等级",
- reply_markup=InlineKeyboardMarkup(self.LEVEL_KEYBOARD))
+ await query.edit_message_text("无法识别圣遗物等级,请选择圣遗物等级", reply_markup=InlineKeyboardMarkup(self.LEVEL_KEYBOARD))
return COMMAND_RESULT
if artifact_attr.get("star") is None:
- await query.edit_message_text("无法识别圣遗物星级,请选择圣遗物星级",
- reply_markup=InlineKeyboardMarkup(self.STAR_KEYBOARD))
+ await query.edit_message_text("无法识别圣遗物星级,请选择圣遗物星级", reply_markup=InlineKeyboardMarkup(self.STAR_KEYBOARD))
return COMMAND_RESULT
await query.edit_message_text("正在评分中...")
rate_text = await self.get_rate(artifact_attr)
diff --git a/plugins/genshin/cookies.py b/plugins/genshin/cookies.py
index 4bf27dd..97ecc9a 100644
--- a/plugins/genshin/cookies.py
+++ b/plugins/genshin/cookies.py
@@ -43,7 +43,7 @@ class SetUserCookies(Plugin.Conversation, BasePlugin.Conversation):
self.user_service = user_service
@conversation.entry_point
- @handler.command(command='setcookies', filters=filters.ChatType.PRIVATE, block=True)
+ @handler.command(command="setcookies", filters=filters.ChatType.PRIVATE, block=True)
@restricts()
@error_callable
async def command_start(self, update: Update, context: CallbackContext) -> int:
@@ -56,12 +56,12 @@ class SetUserCookies(Plugin.Conversation, BasePlugin.Conversation):
context.chat_data["add_user_command_data"] = cookies_command_data
text = f'你好 {user.mention_markdown_v2()} {escape_markdown("!请选择要绑定的服务器!或回复退出取消操作")}'
- reply_keyboard = [['米游社', 'HoYoLab'], ["退出"]]
+ reply_keyboard = [["米游社", "HoYoLab"], ["退出"]]
await message.reply_markdown_v2(text, reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
return CHECK_SERVER
@conversation.entry_point
- @handler.command(command='mlogin', filters=filters.ChatType.PRIVATE, block=True)
+ @handler.command(command="mlogin", filters=filters.ChatType.PRIVATE, block=True)
@error_callable
async def choose_method(self, update: Update, context: CallbackContext) -> int:
user = update.effective_user
@@ -112,21 +112,25 @@ class SetUserCookies(Plugin.Conversation, BasePlugin.Conversation):
add_user_command_data.user = user_info
add_user_command_data.region = region
await message.reply_text(f"请输入{bbs_name}的Cookies!或回复退出取消操作", reply_markup=ReplyKeyboardRemove())
- javascript = "javascript:(()=>{_=(n)=>{for(i in(r=document.cookie.split(';'))){var a=r[i].split('=');if(a[" \
- "0].trim()==n)return a[1]}};c=_('account_id')||alert('无效的Cookie,请重新登录!');c&&confirm(" \
- "'将Cookie复制到剪贴板?')&©(document.cookie)})(); "
+ javascript = (
+ "javascript:(()=>{_=(n)=>{for(i in(r=document.cookie.split(';'))){var a=r[i].split('=');if(a["
+ "0].trim()==n)return a[1]}};c=_('account_id')||alert('无效的Cookie,请重新登录!');c&&confirm("
+ "'将Cookie复制到剪贴板?')&©(document.cookie)})(); "
+ )
javascript_android = "javascript:(()=>{prompt('',document.cookie)})();"
- help_message = f"*关于如何获取Cookies*\n\n" \
- f"PC:\n" \
- f"[1、打开{bbs_name}并登录]({bbs_url})\n" \
- f"2、按F12打开开发者工具\n" \
- f"3、{escape_markdown('将开发者工具切换至控制台(Console)页签', version=2)}\n" \
- f"4、复制下方的代码,并将其粘贴在控制台中,按下回车\n" \
- f"`{escape_markdown(javascript, version=2, entity_type='code')}`\n\n" \
- f"Android:\n" \
- f"[1、通过 Via 浏览器打开{bbs_name}并登录]({bbs_url})\n" \
- f"2、复制下方的代码,并将其粘贴在地址栏中,点击右侧箭头\n" \
- f"`{escape_markdown(javascript_android, version=2, entity_type='code')}`"
+ help_message = (
+ f"*关于如何获取Cookies*\n\n"
+ f"PC:\n"
+ f"[1、打开{bbs_name}并登录]({bbs_url})\n"
+ f"2、按F12打开开发者工具\n"
+ f"3、{escape_markdown('将开发者工具切换至控制台(Console)页签', version=2)}\n"
+ f"4、复制下方的代码,并将其粘贴在控制台中,按下回车\n"
+ f"`{escape_markdown(javascript, version=2, entity_type='code')}`\n\n"
+ f"Android:\n"
+ f"[1、通过 Via 浏览器打开{bbs_name}并登录]({bbs_url})\n"
+ f"2、复制下方的代码,并将其粘贴在地址栏中,点击右侧箭头\n"
+ f"`{escape_markdown(javascript_android, version=2, entity_type='code')}`"
+ )
await message.reply_markdown_v2(help_message, disable_web_page_preview=True)
return INPUT_COOKIES
@@ -149,8 +153,9 @@ class SetUserCookies(Plugin.Conversation, BasePlugin.Conversation):
return CHECK_PHONE
add_user_command_data: AddUserCommandData = context.chat_data.get("add_user_command_data")
add_user_command_data.phone = phone
- await message.reply_text("请打开 https://user.mihoyo.com/#/login/captcha ,输入手机号并获取验证码,"
- "然后将收到的验证码发送给我(请不要在网页上进行登录)")
+ await message.reply_text(
+ "请打开 https://user.mihoyo.com/#/login/captcha ,输入手机号并获取验证码," "然后将收到的验证码发送给我(请不要在网页上进行登录)"
+ )
return CHECK_CAPTCHA
@conversation.state(state=CHECK_CAPTCHA)
@@ -175,8 +180,7 @@ class SetUserCookies(Plugin.Conversation, BasePlugin.Conversation):
try:
success = await client.login(captcha)
if not success:
- await message.reply_text(
- "登录失败:可能是验证码错误,注意不要在登录页面使用掉验证码,如果验证码已经使用,请重新获取验证码!")
+ await message.reply_text("登录失败:可能是验证码错误,注意不要在登录页面使用掉验证码,如果验证码已经使用,请重新获取验证码!")
return ConversationHandler.END
await client.get_s_token()
except Exception:
@@ -184,16 +188,15 @@ class SetUserCookies(Plugin.Conversation, BasePlugin.Conversation):
return ConversationHandler.END
add_user_command_data.sign_in_client = client
await message.reply_text(
- "请再次打开 https://user.mihoyo.com/#/login/captcha ,输入手机号并获取验证码(需要等待一分钟),"
- "然后将收到的验证码发送给我(请不要在网页上进行登录)")
+ "请再次打开 https://user.mihoyo.com/#/login/captcha ,输入手机号并获取验证码(需要等待一分钟)," "然后将收到的验证码发送给我(请不要在网页上进行登录)"
+ )
return CHECK_CAPTCHA
else:
client = add_user_command_data.sign_in_client
try:
success = await client.get_token(captcha)
if not success:
- await message.reply_text(
- "登录失败:可能是验证码错误,注意不要在登录页面使用掉验证码,如果验证码已经使用,请重新获取验证码!")
+ await message.reply_text("登录失败:可能是验证码错误,注意不要在登录页面使用掉验证码,如果验证码已经使用,请重新获取验证码!")
return ConversationHandler.END
except Exception:
await message.reply_text("登录失败:米游社返回了错误的数据,请稍后再试!")
@@ -249,21 +252,24 @@ class SetUserCookies(Plugin.Conversation, BasePlugin.Conversation):
await message.reply_text("Cookies已经过期,请检查是否正确", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
except GenshinException as exc:
- await message.reply_text(f"获取账号信息发生错误,错误信息为 {str(exc)},请检查Cookie或者账号是否正常",
- reply_markup=ReplyKeyboardRemove())
+ await message.reply_text(
+ f"获取账号信息发生错误,错误信息为 {str(exc)},请检查Cookie或者账号是否正常", reply_markup=ReplyKeyboardRemove()
+ )
return ConversationHandler.END
except (AttributeError, ValueError):
await message.reply_text("Cookies错误,请检查是否正确", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
add_user_command_data.game_uid = user_info.uid
- reply_keyboard = [['确认', '退出']]
+ reply_keyboard = [["确认", "退出"]]
await message.reply_text("获取角色基础信息成功,请检查是否正确!")
logger.info(f"用户 {user.full_name}[{user.id}] 获取账号 {user_info.nickname}[{user_info.uid}] 信息成功")
- text = f"*角色信息*\n" \
- f"角色名称:{escape_markdown(user_info.nickname, version=2)}\n" \
- f"角色等级:{user_info.level}\n" \
- f"UID:`{user_info.uid}`\n" \
- f"服务器名称:`{user_info.server_name}`\n"
+ text = (
+ f"*角色信息*\n"
+ f"角色名称:{escape_markdown(user_info.nickname, version=2)}\n"
+ f"角色等级:{user_info.level}\n"
+ f"UID:`{user_info.uid}`\n"
+ f"服务器名称:`{user_info.server_name}`\n"
+ )
await message.reply_markdown_v2(text, reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
return COMMAND_RESULT
@@ -280,11 +286,15 @@ class SetUserCookies(Plugin.Conversation, BasePlugin.Conversation):
elif message.text == "确认":
if add_user_command_data.user is None:
if add_user_command_data.region == RegionEnum.HYPERION:
- user_db = User(user_id=user.id, yuanshen_uid=add_user_command_data.game_uid,
- region=add_user_command_data.region)
+ user_db = User(
+ user_id=user.id,
+ yuanshen_uid=add_user_command_data.game_uid,
+ region=add_user_command_data.region,
+ )
elif add_user_command_data.region == RegionEnum.HOYOLAB:
- user_db = User(user_id=user.id, genshin_uid=add_user_command_data.game_uid,
- region=add_user_command_data.region)
+ user_db = User(
+ user_id=user.id, genshin_uid=add_user_command_data.game_uid, region=add_user_command_data.region
+ )
else:
await message.reply_text("数据错误")
return ConversationHandler.END
@@ -301,11 +311,13 @@ class SetUserCookies(Plugin.Conversation, BasePlugin.Conversation):
return ConversationHandler.END
await self.user_service.update_user(user_db)
if add_user_command_data.cookies_database_data is None:
- await self.cookies_service.add_cookies(user.id, add_user_command_data.cookies,
- add_user_command_data.region)
+ await self.cookies_service.add_cookies(
+ user.id, add_user_command_data.cookies, add_user_command_data.region
+ )
else:
- await self.cookies_service.update_cookies(user.id, add_user_command_data.cookies,
- add_user_command_data.region)
+ await self.cookies_service.update_cookies(
+ user.id, add_user_command_data.cookies, add_user_command_data.region
+ )
logger.info(f"用户 {user.full_name}[{user.id}] 绑定账号成功")
await message.reply_text("保存成功", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
diff --git a/plugins/genshin/daily/material.py b/plugins/genshin/daily/material.py
index 6dc0eb0..31c2544 100644
--- a/plugins/genshin/daily/material.py
+++ b/plugins/genshin/daily/material.py
@@ -39,14 +39,14 @@ from utils.log import logger
INTERVAL = 1
DATA_TYPE = Dict[str, List[List[str]]]
-DATA_FILE_PATH = Path(__file__).joinpath('../daily.json').resolve()
-DOMAINS = ['忘却之峡', '太山府', '菫色之庭', '昏识塔', '塞西莉亚苗圃', '震雷连山密宫', '砂流之庭', '有顶塔']
-DOMAIN_AREA_MAP = dict(zip(DOMAINS, ['蒙德', '璃月', '稻妻', '须弥'] * 2))
+DATA_FILE_PATH = Path(__file__).joinpath("../daily.json").resolve()
+DOMAINS = ["忘却之峡", "太山府", "菫色之庭", "昏识塔", "塞西莉亚苗圃", "震雷连山密宫", "砂流之庭", "有顶塔"]
+DOMAIN_AREA_MAP = dict(zip(DOMAINS, ["蒙德", "璃月", "稻妻", "须弥"] * 2))
-WEEK_MAP = ['一', '二', '三', '四', '五', '六', '日']
+WEEK_MAP = ["一", "二", "三", "四", "五", "六", "日"]
-def sort_item(items: List['ItemData']) -> Iterable['ItemData']:
+def sort_item(items: List["ItemData"]) -> Iterable["ItemData"]:
"""对武器和角色进行排序
排序规则:持有(星级 > 等级 > 命座/精炼) > 未持有(星级 > 等级 > 命座/精炼)
@@ -60,14 +60,17 @@ def sort_item(items: List['ItemData']) -> Iterable['ItemData']:
ArkoWrapper(x[1])
.sort(lambda y: y.rarity, reverse=True)
.groupby(lambda y: y.rarity) # 根据星级分组并排序
- .map(lambda y: (
- ArkoWrapper(y[1])
- .sort(lambda z: z.refinement or z.constellation or -1, reverse=True)
- .groupby(lambda z: z.refinement or z.constellation or -1) # 根据命座/精炼进行分组并排序
- .map(lambda i: ArkoWrapper(i[1]).sort(lambda j: j.id))
- ))
+ .map(
+ lambda y: (
+ ArkoWrapper(y[1])
+ .sort(lambda z: z.refinement or z.constellation or -1, reverse=True)
+ .groupby(lambda z: z.refinement or z.constellation or -1) # 根据命座/精炼进行分组并排序
+ .map(lambda i: ArkoWrapper(i[1]).sort(lambda j: j.id))
+ )
+ )
)
- ).flat(3)
+ )
+ .flat(3)
)
@@ -87,7 +90,7 @@ def get_material_serial_name(names: Iterable[str]) -> str:
if sub_string in ArkoWrapper(all_substrings(name_b)):
result.append(sub_string)
result = ArkoWrapper(result).sort(len, reverse=True)[0]
- chars = {'的': 0, '之': 0}
+ chars = {"的": 0, "之": 0}
for char, k in chars.items():
result = result.split(char)[k]
return result
@@ -95,6 +98,7 @@ def get_material_serial_name(names: Iterable[str]) -> str:
class DailyMaterial(Plugin, BasePlugin):
"""每日素材表"""
+
data: DATA_TYPE
locks: Tuple[Lock] = (Lock(), Lock())
@@ -122,39 +126,47 @@ class DailyMaterial(Plugin, BasePlugin):
async def _get_data_from_user(self, user: User) -> Tuple[Optional[Client], Dict[str, List[Any]]]:
"""获取已经绑定的账号的角色、武器信息"""
client = None
- user_data = {'avatar': [], 'weapon': []}
+ user_data = {"avatar": [], "weapon": []}
try:
logger.debug("尝试获取已绑定的原神账号")
client = await get_genshin_client(user.id)
logger.debug(f"获取账号数据成功: UID={client.uid}")
characters = await client.get_genshin_characters(client.uid)
for character in characters:
- if character.name == '旅行者': # 跳过主角
+ if character.name == "旅行者": # 跳过主角
continue
- cid = AVATAR_DATA[str(character.id)]['id']
+ cid = AVATAR_DATA[str(character.id)]["id"]
weapon = character.weapon
- user_data['avatar'].append(
+ user_data["avatar"].append(
ItemData(
- id=cid, name=character.name, rarity=character.rarity, level=character.level,
+ id=cid,
+ name=character.name,
+ rarity=character.rarity,
+ level=character.level,
constellation=character.constellation,
- icon=(await self.assets_service.avatar(cid).icon()).as_uri()
+ icon=(await self.assets_service.avatar(cid).icon()).as_uri(),
)
)
- user_data['weapon'].append(
+ user_data["weapon"].append(
ItemData(
- id=str(weapon.id), name=weapon.name, level=weapon.level, rarity=weapon.rarity,
+ id=str(weapon.id),
+ name=weapon.name,
+ level=weapon.level,
+ rarity=weapon.rarity,
refinement=weapon.refinement,
- icon=(await getattr( # 判定武器的突破次数是否大于 2 ;若是, 则将图标替换为 awakened (觉醒) 的图标
- self.assets_service.weapon(weapon.id), 'icon' if weapon.ascension < 2 else 'awaken'
- )()).as_uri(),
- c_path=(await self.assets_service.avatar(cid).side()).as_uri()
+ icon=(
+ await getattr( # 判定武器的突破次数是否大于 2 ;若是, 则将图标替换为 awakened (觉醒) 的图标
+ self.assets_service.weapon(weapon.id), "icon" if weapon.ascension < 2 else "awaken"
+ )()
+ ).as_uri(),
+ c_path=(await self.assets_service.avatar(cid).side()).as_uri(),
)
)
except (UserNotFoundError, CookiesNotFoundError):
logger.info(f"未查询到用户({user.full_name} {user.id}) 所绑定的账号信息")
return client, user_data
- @handler.command('daily_material', block=False)
+ @handler.command("daily_material", block=False)
@restricts(restricts_time_of_groups=20, without_overlapping=True)
@error_callable
async def daily_material(self, update: Update, context: CallbackContext):
@@ -171,15 +183,13 @@ class DailyMaterial(Plugin, BasePlugin):
weekday = now.weekday() - (1 if now.hour < 4 else 0)
weekday = 6 if weekday < 0 else weekday
time = now.strftime("%m-%d %H:%M") + " 星期" + WEEK_MAP[weekday]
- full = bool(args and args[-1] == 'full') # 判定最后一个参数是不是 full
+ full = bool(args and args[-1] == "full") # 判定最后一个参数是不是 full
- logger.info(
- f"用户 {user.full_name}[{user.id}] 每日素材命令请求 || 参数 weekday=\"{WEEK_MAP[weekday]}\" full={full}")
+ logger.info(f'用户 {user.full_name}[{user.id}] 每日素材命令请求 || 参数 weekday="{WEEK_MAP[weekday]}" full={full}')
if weekday == 6:
await update.message.reply_text(
- ("今天" if title == '今日' else '这天') + "是星期天, 全部素材都可以刷哦~",
- parse_mode=ParseMode.HTML
+ ("今天" if title == "今日" else "这天") + "是星期天, 全部素材都可以刷哦~", parse_mode=ParseMode.HTML
)
return
@@ -196,26 +206,26 @@ class DailyMaterial(Plugin, BasePlugin):
await update.message.reply_chat_action(ChatAction.TYPING)
# 获取已经缓存的秘境素材信息
- local_data = {'avatar': [], 'weapon': []}
+ local_data = {"avatar": [], "weapon": []}
if not self.data: # 若没有缓存每日素材表的数据
logger.info("正在获取每日素材缓存")
self.data = await self._refresh_data()
for domain, sche in self.data.items():
area = DOMAIN_AREA_MAP[domain] # 获取秘境所在的区域
- type_ = 'avatar' if DOMAINS.index(domain) < 4 else 'weapon' # 获取秘境的培养素材的类型:是天赋书还是武器突破材料
+ type_ = "avatar" if DOMAINS.index(domain) < 4 else "weapon" # 获取秘境的培养素材的类型:是天赋书还是武器突破材料
# 将读取到的数据存入 local_data 中
- local_data[type_].append({'name': area, 'materials': sche[weekday][0], 'items': sche[weekday][1]})
+ local_data[type_].append({"name": area, "materials": sche[weekday][0], "items": sche[weekday][1]})
# 尝试获取用户已绑定的原神账号信息
client, user_data = await self._get_data_from_user(user)
await update.message.reply_chat_action(ChatAction.TYPING)
render_data = RenderData(title=title, time=time, uid=client.uid if client else client)
- for type_ in ['avatar', 'weapon']:
+ for type_ in ["avatar", "weapon"]:
areas = []
for area_data in local_data[type_]: # 遍历每个区域的信息:蒙德、璃月、稻妻、须弥
items = []
- for id_ in area_data['items']: # 遍历所有该区域下,当天(weekday)可以培养的角色、武器
+ for id_ in area_data["items"]: # 遍历所有该区域下,当天(weekday)可以培养的角色、武器
added = False
for i in user_data[type_]: # 从已经获取的角色数据中查找对应角色、武器
if id_ == str(i.id):
@@ -231,33 +241,42 @@ class DailyMaterial(Plugin, BasePlugin):
continue
if item[2] < 4: # 跳过 3 星及以下的武器
continue
- items.append(ItemData( # 添加角色数据中未找到的
- id=id_, name=item[1], rarity=item[2],
- icon=(await getattr(self.assets_service, type_)(id_).icon()).as_uri()
- ))
+ items.append(
+ ItemData( # 添加角色数据中未找到的
+ id=id_,
+ name=item[1],
+ rarity=item[2],
+ icon=(await getattr(self.assets_service, type_)(id_).icon()).as_uri(),
+ )
+ )
materials = []
- for mid in area_data['materials']: # 添加这个区域当天(weekday)的培养素材
+ for mid in area_data["materials"]: # 添加这个区域当天(weekday)的培养素材
path = (await self.assets_service.material(mid).icon()).as_uri()
- material = HONEY_DATA['material'][mid]
+ material = HONEY_DATA["material"][mid]
materials.append(ItemData(id=mid, icon=path, name=material[1], rarity=material[2]))
- areas.append(AreaData(
- name=area_data['name'], materials=materials, items=sort_item(items),
- material_name=get_material_serial_name(map(lambda x: x.name, materials))
- ))
- setattr(render_data, {'avatar': 'character'}.get(type_, type_), areas)
+ areas.append(
+ AreaData(
+ name=area_data["name"],
+ materials=materials,
+ items=sort_item(items),
+ material_name=get_material_serial_name(map(lambda x: x.name, materials)),
+ )
+ )
+ setattr(render_data, {"avatar": "character"}.get(type_, type_), areas)
await update.message.reply_chat_action(ChatAction.TYPING)
render_tasks = [
asyncio.create_task(
self.template_service.render( # 渲染角色素材页
- 'genshin/daily_material', 'character.html', {'data': render_data}, {'width': 1164, 'height': 500}
+ "genshin/daily_material", "character.html", {"data": render_data}, {"width": 1164, "height": 500}
)
),
asyncio.create_task(
self.template_service.render( # 渲染武器素材页
- 'genshin/daily_material', 'weapon.html', {'data': render_data}, {'width': 1164, 'height': 500}
+ "genshin/daily_material", "weapon.html", {"data": render_data}, {"width": 1164, "height": 500}
)
- )]
+ ),
+ ]
while not all(map(lambda x: x.done(), render_tasks)):
await asyncio.sleep(0)
@@ -267,25 +286,25 @@ class DailyMaterial(Plugin, BasePlugin):
self._add_delete_message_job(context, notice.chat_id, notice.message_id, 5)
await update.message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
if full: # 是否发送原图
- await update.message.reply_media_group([
- InputMediaDocument(character_img_data, filename="可培养角色.png"),
- InputMediaDocument(weapon_img_data, filename="可培养武器.png")
- ])
+ await update.message.reply_media_group(
+ [
+ InputMediaDocument(character_img_data, filename="可培养角色.png"),
+ InputMediaDocument(weapon_img_data, filename="可培养武器.png"),
+ ]
+ )
else:
await update.message.reply_media_group(
[InputMediaPhoto(character_img_data), InputMediaPhoto(weapon_img_data)]
)
logger.debug("角色、武器培养素材图发送成功")
- @handler.command('refresh_daily_material', block=False)
+ @handler.command("refresh_daily_material", block=False)
@bot_admins_rights_check
async def refresh(self, update: Update, context: CallbackContext):
user = update.effective_user
message = update.effective_message
- logger.info(
- f"用户 {user.full_name}[{user.id}] 刷新[bold]每日素材[/]缓存命令", extra={'markup': True}
- )
+ logger.info(f"用户 {user.full_name}[{user.id}] 刷新[bold]每日素材[/]缓存命令", extra={"markup": True})
if self.locks[0].locked():
notice = await message.reply_text("派蒙还在抄每日素材表呢,我有在好好工作哦~")
self._add_delete_message_job(context, notice.chat_id, notice.message_id, 10)
@@ -299,68 +318,61 @@ class DailyMaterial(Plugin, BasePlugin):
async with self.locks[0]: # 锁住第一把锁
data = await self._refresh_data()
notice = await notice.edit_text(
- "每日素材表" +
- ("摘抄完成!" if data else "坏掉了!等会它再长好了之后我再抄。。。") +
- '\n正搬运每日素材的图标中。。。',
- parse_mode=ParseMode.HTML
+ "每日素材表" + ("摘抄完成!" if data else "坏掉了!等会它再长好了之后我再抄。。。") + "\n正搬运每日素材的图标中。。。",
+ parse_mode=ParseMode.HTML,
)
self.data = data or self.data
time = await self._download_icon(notice)
async def job(_, n):
- await n.edit_text(
- n.text_html.split('\n')[0] + "\n每日素材图标搬运完成!",
- parse_mode=ParseMode.HTML
- )
+ await n.edit_text(n.text_html.split("\n")[0] + "\n每日素材图标搬运完成!", parse_mode=ParseMode.HTML)
await asyncio.sleep(INTERVAL)
await notice.delete()
context.application.job_queue.run_once(
- partial(job, n=notice), when=time + INTERVAL, name='notice_msg_final_job'
+ partial(job, n=notice), when=time + INTERVAL, name="notice_msg_final_job"
)
async def _refresh_data(self, retry: int = 5) -> DATA_TYPE:
"""刷新来自 honey impact 的每日素材表"""
from bs4 import Tag
+
result = {}
for i in range(retry): # 重复尝试 retry 次
try:
response = await self.client.get("https://genshin.honeyhunterworld.com/?lang=CHS")
- soup = BeautifulSoup(response.text, 'lxml')
+ soup = BeautifulSoup(response.text, "lxml")
calendar = soup.select(".calendar_day_wrap")[0]
- key: str = ''
+ key: str = ""
for tag in calendar:
tag: Tag
- if tag.name == 'span': # 如果是秘境
- key = tag.find('a').text
+ if tag.name == "span": # 如果是秘境
+ key = tag.find("a").text
result[key] = [[[], []] for _ in range(7)]
- for day, div in enumerate(tag.find_all('div')):
+ for day, div in enumerate(tag.find_all("div")):
result[key][day][0] = []
- for a in div.find_all('a'):
- honey_id = re.findall(r"/(.*)?/", a['href'])[0]
- mid: str = [
- i[0]
- for i in HONEY_DATA['material'].items()
- if i[1][0] == honey_id
- ][0]
+ for a in div.find_all("a"):
+ honey_id = re.findall(r"/(.*)?/", a["href"])[0]
+ mid: str = [i[0] for i in HONEY_DATA["material"].items() if i[1][0] == honey_id][0]
result[key][day][0].append(mid)
else: # 如果是角色或武器
- id_ = re.findall(r"/(.*)?/", tag['href'])[0]
- if tag.text.strip() == '旅行者': # 忽略主角
+ id_ = re.findall(r"/(.*)?/", tag["href"])[0]
+ if tag.text.strip() == "旅行者": # 忽略主角
continue
- id_ = ("" if id_.startswith('i_n') else "10000") + re.findall(r'\d+', id_)[0]
- for day in map(int, tag.find('div')['data-days']): # 获取该角色/武器的可培养天
+ id_ = ("" if id_.startswith("i_n") else "10000") + re.findall(r"\d+", id_)[0]
+ for day in map(int, tag.find("div")["data-days"]): # 获取该角色/武器的可培养天
result[key][day][1].append(id_)
for stage, schedules in result.items():
for day, _ in enumerate(schedules):
# noinspection PyUnresolvedReferences
result[stage][day][1] = list(set(result[stage][day][1])) # 去重
- async with async_open(DATA_FILE_PATH, 'w', encoding='utf-8') as file:
+ async with async_open(DATA_FILE_PATH, "w", encoding="utf-8") as file:
await file.write(json.dumps(result)) # pylint: disable=PY-W0079
logger.info("每日素材刷新成功")
break
except (HTTPError, SSLZeroReturnError):
from asyncio import sleep
+
await sleep(1)
if i <= retry - 1:
logger.warning("每日素材刷新失败, 正在重试")
@@ -375,6 +387,7 @@ class DailyMaterial(Plugin, BasePlugin):
asset_list = []
from time import time as time_
+
lock = asyncio.Lock()
the_time = Value(c_double, time_() - INTERVAL)
@@ -382,20 +395,15 @@ class DailyMaterial(Plugin, BasePlugin):
async def edit_message(text):
"""修改提示消息"""
async with lock:
- if (
- message is not None
- and
- time_() >= (the_time.value + INTERVAL)
- ):
+ if message is not None and time_() >= (the_time.value + INTERVAL):
with contextlib.suppress(TimedOut, RetryAfter):
await message.edit_text(
- '\n'.join(message.text_html.split('\n')[:2] + [text]),
- parse_mode=ParseMode.HTML
+ "\n".join(message.text_html.split("\n")[:2] + [text]), parse_mode=ParseMode.HTML
)
the_time.value = time_()
async def task(item_id, name, item_type):
- logger.debug(f"正在开始下载 \"{name}\" 的图标素材")
+ logger.debug(f'正在开始下载 "{name}" 的图标素材')
await edit_message(f"正在搬运 {name} 的图标素材。。。")
asset: AssetsServiceType = getattr(self.assets_service, item_type)(item_id) # 获取素材对象
asset_list.append(asset.honey_id)
@@ -403,7 +411,7 @@ class DailyMaterial(Plugin, BasePlugin):
# 并根据图标类型找到下载对应图标的函数
for icon_type in asset.icon_types:
await getattr(asset, icon_type)(True) # 执行下载函数
- logger.debug(f"\"{name}\" 的图标素材下载成功")
+ logger.debug(f'"{name}" 的图标素材下载成功')
await edit_message(f"正在搬运 {name} 的图标素材。。。成功!")
for TYPE, ITEMS in HONEY_DATA.items(): # 遍历每个对象
@@ -431,7 +439,7 @@ class ItemData(BaseModel):
class AreaData(BaseModel):
- name: Literal['蒙德', '璃月', '稻妻', '须弥'] # 区域名
+ name: Literal["蒙德", "璃月", "稻妻", "须弥"] # 区域名
material_name: str # 区域的材料系列名
materials: List[ItemData] = [] # 区域材料
items: Iterable[ItemData] = [] # 可培养的角色或武器
diff --git a/plugins/genshin/daily_note.py b/plugins/genshin/daily_note.py
index eabb1c7..f458d24 100644
--- a/plugins/genshin/daily_note.py
+++ b/plugins/genshin/daily_note.py
@@ -5,8 +5,7 @@ from typing import Optional
from genshin import DataNotPublic
from telegram import Update
from telegram.constants import ChatAction
-from telegram.ext import CommandHandler, MessageHandler, ConversationHandler, filters, \
- CallbackContext
+from telegram.ext import CommandHandler, MessageHandler, ConversationHandler, filters, CallbackContext
from core.baseplugin import BasePlugin
from core.cookies.error import CookiesNotFoundError
@@ -24,8 +23,12 @@ from utils.log import logger
class DailyNote(Plugin, BasePlugin):
"""每日便签"""
- def __init__(self, user_service: UserService = None, cookies_service: CookiesService = None,
- template_service: TemplateService = None):
+ def __init__(
+ self,
+ user_service: UserService = None,
+ cookies_service: CookiesService = None,
+ template_service: TemplateService = None,
+ ):
self.template_service = template_service
self.cookies_service = cookies_service
self.user_service = user_service
@@ -34,11 +37,18 @@ class DailyNote(Plugin, BasePlugin):
async def _get_daily_note(self, client) -> bytes:
daily_info = await client.get_genshin_notes(client.uid)
day = datetime.datetime.now().strftime("%m-%d %H:%M") + " 星期" + "一二三四五六日"[datetime.datetime.now().weekday()]
- resin_recovery_time = daily_info.resin_recovery_time.strftime("%m-%d %H:%M") if \
- daily_info.max_resin - daily_info.current_resin else None
- realm_recovery_time = (datetime.datetime.now().astimezone() +
- daily_info.remaining_realm_currency_recovery_time).strftime("%m-%d %H:%M") if \
- daily_info.max_realm_currency - daily_info.current_realm_currency else None
+ resin_recovery_time = (
+ daily_info.resin_recovery_time.strftime("%m-%d %H:%M")
+ if daily_info.max_resin - daily_info.current_resin
+ else None
+ )
+ realm_recovery_time = (
+ (datetime.datetime.now().astimezone() + daily_info.remaining_realm_currency_recovery_time).strftime(
+ "%m-%d %H:%M"
+ )
+ if daily_info.max_realm_currency - daily_info.current_realm_currency
+ else None
+ )
remained_time = None
for i in daily_info.expeditions:
if remained_time:
@@ -73,10 +83,11 @@ class DailyNote(Plugin, BasePlugin):
"max_resin_discounts": daily_info.max_resin_discounts,
"transformer": transformer,
"transformer_ready": transformer_ready,
- "transformer_recovery_time": transformer_recovery_time
+ "transformer_recovery_time": transformer_recovery_time,
}
- png_data = await self.template_service.render('genshin/daily_note', "daily_note.html", daily_data,
- {"width": 600, "height": 548}, full_page=False)
+ png_data = await self.template_service.render(
+ "genshin/daily_note", "daily_note.html", daily_data, {"width": 600, "height": 548}, full_page=False
+ )
return png_data
@handler(CommandHandler, command="dailynote", block=False)
diff --git a/plugins/genshin/gacha/gacha.py b/plugins/genshin/gacha/gacha.py
index 4e112b8..42d18b9 100644
--- a/plugins/genshin/gacha/gacha.py
+++ b/plugins/genshin/gacha/gacha.py
@@ -125,8 +125,9 @@ class Gacha(Plugin, BasePlugin):
data["items"].sort(key=take_rang, reverse=True)
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
# 因为 gacha_info["title"] 返回的是 HTML 标签 尝试关闭自动转义
- png_data = await self.template_service.render('genshin/gacha', "gacha.html", data,
- {"width": 1157, "height": 603}, False)
+ png_data = await self.template_service.render(
+ "genshin/gacha", "gacha.html", data, {"width": 1157, "height": 603}, False
+ )
reply_message = await message.reply_photo(png_data)
if filters.ChatType.GROUPS.filter(message):
diff --git a/plugins/genshin/ledger.py b/plugins/genshin/ledger.py
index 8c613b3..9786c50 100644
--- a/plugins/genshin/ledger.py
+++ b/plugins/genshin/ledger.py
@@ -38,8 +38,7 @@ def check_ledger_month(context: CallbackContext) -> int:
elif re_data := re.findall(r"\d+", str(month)):
month = int(re_data[0])
else:
- num_dict = {"一": 1, "二": 2, "三": 3, "四": 4, "五": 5,
- "六": 6, "七": 7, "八": 8, "九": 9, "十": 10}
+ num_dict = {"一": 1, "二": 2, "三": 3, "四": 4, "五": 5, "六": 6, "七": 7, "八": 8, "九": 9, "十": 10}
month = sum(num_dict.get(i, 0) for i in str(month))
# check right
allow_month = [now_time.month]
@@ -58,8 +57,12 @@ def check_ledger_month(context: CallbackContext) -> int:
class Ledger(Plugin, BasePlugin):
"""旅行札记"""
- def __init__(self, user_service: UserService = None, cookies_service: CookiesService = None,
- template_service: TemplateService = None):
+ def __init__(
+ self,
+ user_service: UserService = None,
+ cookies_service: CookiesService = None,
+ template_service: TemplateService = None,
+ ):
self.template_service = template_service
self.cookies_service = cookies_service
self.user_service = user_service
@@ -71,18 +74,26 @@ class Ledger(Plugin, BasePlugin):
except GenshinException as error:
raise error
color = ["#73a9c6", "#d56565", "#70b2b4", "#bd9a5a", "#739970", "#7a6da7", "#597ea0"]
- categories = [{"id": i.id,
- "name": i.name,
- "color": color[i.id % len(color)],
- "amount": i.amount,
- "percentage": i.percentage} for i in diary_info.month_data.categories]
+ categories = [
+ {
+ "id": i.id,
+ "name": i.name,
+ "color": color[i.id % len(color)],
+ "amount": i.amount,
+ "percentage": i.percentage,
+ }
+ for i in diary_info.month_data.categories
+ ]
color = [i["color"] for i in categories]
def format_amount(amount: int) -> str:
return f"{round(amount / 10000, 2)}w" if amount >= 10000 else amount
- evaluate = """const { Pie } = G2Plot;
- const data = JSON.parse(`""" + json.dumps(categories) + """`);
+ evaluate = (
+ """const { Pie } = G2Plot;
+ const data = JSON.parse(`"""
+ + json.dumps(categories)
+ + """`);
const piePlot = new Pie("chartContainer", {
renderer: "svg",
animation: false,
@@ -92,7 +103,9 @@ class Ledger(Plugin, BasePlugin):
colorField: "name",
radius: 1,
innerRadius: 0.7,
- color: JSON.parse(`""" + json.dumps(color) + """`),
+ color: JSON.parse(`"""
+ + json.dumps(color)
+ + """`),
meta: {},
label: {
type: "inner",
@@ -121,6 +134,7 @@ class Ledger(Plugin, BasePlugin):
legend:false,
});
piePlot.render();"""
+ )
ledger_data = {
"uid": client.uid,
"day": diary_info.month,
@@ -132,9 +146,9 @@ class Ledger(Plugin, BasePlugin):
"last_mora": format_amount(diary_info.month_data.last_mora),
"categories": categories,
}
- png_data = await self.template_service.render('genshin/ledger', "ledger.html", ledger_data,
- {"width": 580, "height": 610},
- evaluate=evaluate)
+ png_data = await self.template_service.render(
+ "genshin/ledger", "ledger.html", ledger_data, {"width": 580, "height": 610}, evaluate=evaluate
+ )
return png_data
@handler(CommandHandler, command="ledger", block=False)
diff --git a/plugins/genshin/map/map.py b/plugins/genshin/map/map.py
index 2c0f81b..f15e009 100644
--- a/plugins/genshin/map/map.py
+++ b/plugins/genshin/map/map.py
@@ -60,6 +60,6 @@ class Map(Plugin, BasePlugin):
return
img = Image.open(f"cache{sep}map.jpg")
if img.size[0] > 2048 or img.size[1] > 2048:
- await message.reply_document(open(f"cache{sep}map.jpg", mode='rb+'), caption=text)
+ await message.reply_document(open(f"cache{sep}map.jpg", mode="rb+"), caption=text)
else:
- await message.reply_photo(open(f"cache{sep}map.jpg", mode='rb+'), caption=text)
+ await message.reply_photo(open(f"cache{sep}map.jpg", mode="rb+"), caption=text)
diff --git a/plugins/genshin/map/model.py b/plugins/genshin/map/model.py
index db714b2..02f4844 100644
--- a/plugins/genshin/map/model.py
+++ b/plugins/genshin/map/model.py
@@ -16,9 +16,9 @@ RESOURCE_ICON_OFFSET = (-int(150 * 0.5 * ZOOM), -int(150 * ZOOM))
class MapHelper:
- LABEL_URL = 'https://api-static.mihoyo.com/common/blackboard/ys_obc/v1/map/label/tree?app_sn=ys_obc'
- POINT_LIST_URL = 'https://api-static.mihoyo.com/common/blackboard/ys_obc/v1/map/point/list?map_id=2&app_sn=ys_obc'
- MAP_URL = 'https://api-static.mihoyo.com/common/map_user/ys_obc/v1/map/info?map_id=2&app_sn=ys_obc&lang=zh-cn'
+ LABEL_URL = "https://api-static.mihoyo.com/common/blackboard/ys_obc/v1/map/label/tree?app_sn=ys_obc"
+ POINT_LIST_URL = "https://api-static.mihoyo.com/common/blackboard/ys_obc/v1/map/point/list?map_id=2&app_sn=ys_obc"
+ MAP_URL = "https://api-static.mihoyo.com/common/map_user/ys_obc/v1/map/info?map_id=2&app_sn=ys_obc&lang=zh-cn"
def __init__(self, cache_dir_name: str = "cache"):
self._current_dir = os.getcwd()
@@ -109,11 +109,11 @@ class MapHelper:
map_info = map_info["data"]["info"]["detail"]
map_info = ujson.loads(map_info)
- map_url_list = map_info['slices'][0]
+ map_url_list = map_info["slices"][0]
origin = map_info["origin"]
- x_start = map_info['total_size'][1]
- y_start = map_info['total_size'][1]
+ x_start = map_info["total_size"][1]
+ y_start = map_info["total_size"][1]
x_end = 0
y_end = 0
for resource_point in self.all_resource_point_list:
@@ -223,7 +223,6 @@ class MapHelper:
class ResourceMap:
-
def __init__(self, all_resource_point_list: List[dict], map_icon: Image, center: List[float], resource_id: int):
self.all_resource_point_list = all_resource_point_list
self.resource_id = resource_id
@@ -263,8 +262,9 @@ class ResourceMap:
# 这时地图已经裁切过了,要以裁切后的地图左上角为中心再转换一次坐标
x -= self.x_start
y -= self.y_start
- self.map_image.paste(self.resource_icon, (x + RESOURCE_ICON_OFFSET[0], y + RESOURCE_ICON_OFFSET[1]),
- self.resource_icon)
+ self.map_image.paste(
+ self.resource_icon, (x + RESOURCE_ICON_OFFSET[0], y + RESOURCE_ICON_OFFSET[1]), self.resource_icon
+ )
def crop(self):
# 把大地图裁切到只保留资源图标位置
@@ -291,8 +291,7 @@ class ResourceMap:
self.y_start = center - 500
self.y_end = center + 500
- self.map_image = self.map_image.crop((self.x_start, self.y_start,
- self.x_end, self.y_end))
+ self.map_image = self.map_image.crop((self.x_start, self.y_start, self.x_end, self.y_end))
def gen_jpg(self):
if not self.resource_xy_list:
@@ -301,7 +300,7 @@ class ResourceMap:
os.mkdir("cache") # 查找 cache 目录 (缓存目录) 是否存在,如果不存在则创建
self.crop()
self.paste()
- self.map_image.save(f'cache{os.sep}map.jpg', format='JPEG')
+ self.map_image.save(f"cache{os.sep}map.jpg", format="JPEG")
def get_resource_count(self):
return len(self.resource_xy_list)
diff --git a/plugins/genshin/material.py b/plugins/genshin/material.py
index b605e07..f534e67 100644
--- a/plugins/genshin/material.py
+++ b/plugins/genshin/material.py
@@ -16,9 +16,7 @@ from utils.log import logger
class Material(Plugin, BasePlugin):
"""角色培养素材查询"""
- KEYBOARD = [[InlineKeyboardButton(
- text="查看角色培养素材列表并查询",
- switch_inline_query_current_chat="查看角色培养素材列表并查询")]]
+ KEYBOARD = [[InlineKeyboardButton(text="查看角色培养素材列表并查询", switch_inline_query_current_chat="查看角色培养素材列表并查询")]]
def __init__(self, game_material_service: GameMaterialService = None):
self.game_material_service = game_material_service
@@ -34,8 +32,9 @@ class Material(Plugin, BasePlugin):
if len(args) >= 1:
character_name = args[0]
else:
- reply_message = await message.reply_text("请回复你要查询的培养素材的角色名",
- reply_markup=InlineKeyboardMarkup(self.KEYBOARD))
+ reply_message = await message.reply_text(
+ "请回复你要查询的培养素材的角色名", reply_markup=InlineKeyboardMarkup(self.KEYBOARD)
+ )
if filters.ChatType.GROUPS.filter(reply_message):
self._add_delete_message_job(context, message.chat_id, message.message_id)
self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id)
@@ -43,8 +42,9 @@ class Material(Plugin, BasePlugin):
character_name = roleToName(character_name)
url = await self.game_material_service.get_material(character_name)
if not url:
- reply_message = await message.reply_text(f"没有找到 {character_name} 的培养素材",
- reply_markup=InlineKeyboardMarkup(self.KEYBOARD))
+ reply_message = await message.reply_text(
+ f"没有找到 {character_name} 的培养素材", reply_markup=InlineKeyboardMarkup(self.KEYBOARD)
+ )
if filters.ChatType.GROUPS.filter(reply_message):
self._add_delete_message_job(context, message.chat_id, message.message_id)
self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id)
@@ -52,7 +52,11 @@ class Material(Plugin, BasePlugin):
logger.info(f"用户 {user.full_name}[{user.id}] 查询角色培养素材命令请求 || 参数 {character_name}")
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
file_path = await url_to_file(url, return_path=True)
- caption = "From 米游社 " \
- f"查看 [原图]({url})"
- await message.reply_photo(photo=open(file_path, "rb"), caption=caption, filename=f"{character_name}.png",
- allow_sending_without_reply=True, parse_mode=ParseMode.MARKDOWN_V2)
+ caption = "From 米游社 " f"查看 [原图]({url})"
+ await message.reply_photo(
+ photo=open(file_path, "rb"),
+ caption=caption,
+ filename=f"{character_name}.png",
+ allow_sending_without_reply=True,
+ parse_mode=ParseMode.MARKDOWN_V2,
+ )
diff --git a/plugins/genshin/quiz.py b/plugins/genshin/quiz.py
index 05ba1f0..6e4694c 100644
--- a/plugins/genshin/quiz.py
+++ b/plugins/genshin/quiz.py
@@ -50,8 +50,13 @@ class QuizPlugin(Plugin, BasePlugin):
return None
random.shuffle(_options)
index = _options.index(correct_option)
- poll_message = await update.effective_message.reply_poll(question.text, _options,
- correct_option_id=index, is_anonymous=False,
- open_period=self.time_out, type=Poll.QUIZ)
+ poll_message = await update.effective_message.reply_poll(
+ question.text,
+ _options,
+ correct_option_id=index,
+ is_anonymous=False,
+ open_period=self.time_out,
+ type=Poll.QUIZ,
+ )
self._add_delete_message_job(context, update.message.chat_id, update.message.message_id, 300)
self._add_delete_message_job(context, poll_message.chat_id, poll_message.message_id, 300)
diff --git a/plugins/genshin/strategy.py b/plugins/genshin/strategy.py
index 57732e9..c88c48f 100644
--- a/plugins/genshin/strategy.py
+++ b/plugins/genshin/strategy.py
@@ -35,8 +35,7 @@ class StrategyPlugin(Plugin, BasePlugin):
if len(args) >= 1:
character_name = args[0]
else:
- reply_message = await message.reply_text("请回复你要查询的攻略的角色名",
- reply_markup=InlineKeyboardMarkup(self.KEYBOARD))
+ reply_message = await message.reply_text("请回复你要查询的攻略的角色名", reply_markup=InlineKeyboardMarkup(self.KEYBOARD))
if filters.ChatType.GROUPS.filter(reply_message):
self._add_delete_message_job(context, message.chat_id, message.message_id)
self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id)
@@ -44,8 +43,9 @@ class StrategyPlugin(Plugin, BasePlugin):
character_name = roleToName(character_name)
url = await self.game_strategy_service.get_strategy(character_name)
if url == "":
- reply_message = await message.reply_text(f"没有找到 {character_name} 的攻略",
- reply_markup=InlineKeyboardMarkup(self.KEYBOARD))
+ reply_message = await message.reply_text(
+ f"没有找到 {character_name} 的攻略", reply_markup=InlineKeyboardMarkup(self.KEYBOARD)
+ )
if filters.ChatType.GROUPS.filter(reply_message):
self._add_delete_message_job(context, message.chat_id, message.message_id)
self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id)
@@ -53,7 +53,11 @@ class StrategyPlugin(Plugin, BasePlugin):
logger.info(f"用户 {user.full_name}[{user.id}] 查询角色攻略命令请求 || 参数 {character_name}")
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
file_path = await url_to_file(url, return_path=True)
- caption = "From 米游社 西风驿站 " \
- f"查看 [原图]({url})"
- await message.reply_photo(photo=open(file_path, "rb"), caption=caption, filename=f"{character_name}.png",
- allow_sending_without_reply=True, parse_mode=ParseMode.MARKDOWN_V2)
+ caption = "From 米游社 西风驿站 " f"查看 [原图]({url})"
+ await message.reply_photo(
+ photo=open(file_path, "rb"),
+ caption=caption,
+ filename=f"{character_name}.png",
+ allow_sending_without_reply=True,
+ parse_mode=ParseMode.MARKDOWN_V2,
+ )
diff --git a/plugins/genshin/uid.py b/plugins/genshin/uid.py
index ea16fe5..03dbf4f 100644
--- a/plugins/genshin/uid.py
+++ b/plugins/genshin/uid.py
@@ -31,14 +31,18 @@ CHECK_SERVER, CHECK_UID, COMMAND_RESULT = range(10100, 10103)
class SetUserUid(Plugin.Conversation, BasePlugin.Conversation):
"""UID用户绑定"""
- def __init__(self, user_service: UserService = None, cookies_service: CookiesService = None,
- public_cookies_service: PublicCookiesService = None):
+ def __init__(
+ self,
+ user_service: UserService = None,
+ cookies_service: CookiesService = None,
+ public_cookies_service: PublicCookiesService = None,
+ ):
self.public_cookies_service = public_cookies_service
self.cookies_service = cookies_service
self.user_service = user_service
@conversation.entry_point
- @handler.command(command='setuid', filters=filters.ChatType.PRIVATE, block=True)
+ @handler.command(command="setuid", filters=filters.ChatType.PRIVATE, block=True)
@restricts()
@error_callable
async def command_start(self, update: Update, context: CallbackContext) -> int:
@@ -49,9 +53,11 @@ class SetUserUid(Plugin.Conversation, BasePlugin.Conversation):
if add_user_command_data is None:
cookies_command_data = AddUserCommandData()
context.chat_data["add_uid_command_data"] = cookies_command_data
- text = f'你好 {user.mention_markdown_v2()} ' \
- f'{escape_markdown("!请输入通行证UID(非游戏UID),BOT将会通过通行证UID查找游戏UID。请选择要绑定的服务器!或回复退出取消操作")}'
- reply_keyboard = [['米游社', 'HoYoLab'], ["退出"]]
+ text = (
+ f"你好 {user.mention_markdown_v2()} "
+ f'{escape_markdown("!请输入通行证UID(非游戏UID),BOT将会通过通行证UID查找游戏UID。请选择要绑定的服务器!或回复退出取消操作")}'
+ )
+ reply_keyboard = [["米游社", "HoYoLab"], ["退出"]]
await message.reply_markdown_v2(text, reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
return CHECK_SERVER
@@ -112,8 +118,9 @@ class SetUserUid(Plugin.Conversation, BasePlugin.Conversation):
if region == RegionEnum.HYPERION:
client = genshin.Client(cookies=cookies.cookies, game=types.Game.GENSHIN, region=types.Region.CHINESE)
elif region == RegionEnum.HOYOLAB:
- client = genshin.Client(cookies=cookies.cookies, game=types.Game.GENSHIN, region=types.Region.OVERSEAS,
- lang="zh-cn")
+ client = genshin.Client(
+ cookies=cookies.cookies, game=types.Game.GENSHIN, region=types.Region.OVERSEAS, lang="zh-cn"
+ )
else:
return ConversationHandler.END
try:
@@ -128,22 +135,20 @@ class SetUserUid(Plugin.Conversation, BasePlugin.Conversation):
logger.exception(exc)
return ConversationHandler.END
if user_info.game != types.Game.GENSHIN:
- await message.reply_text("角色信息查询返回非原神游戏信息,"
- "请设置展示主界面为原神", reply_markup=ReplyKeyboardRemove())
+ await message.reply_text("角色信息查询返回非原神游戏信息," "请设置展示主界面为原神", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
- reply_keyboard = [['确认', '退出']]
+ reply_keyboard = [["确认", "退出"]]
await message.reply_text("获取角色基础信息成功,请检查是否正确!")
logger.info(f"用户 {user.full_name}[{user.id}] 获取账号 {user_info.nickname}[{user_info.uid}] 信息成功")
- text = f"*角色信息*\n" \
- f"角色名称:{escape_markdown(user_info.nickname, version=2)}\n" \
- f"角色等级:{user_info.level}\n" \
- f"UID:`{user_info.uid}`\n" \
- f"服务器名称:`{user_info.server_name}`\n"
- add_user_command_data.game_uid = user_info.uid
- await message.reply_markdown_v2(
- text,
- reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
+ text = (
+ f"*角色信息*\n"
+ f"角色名称:{escape_markdown(user_info.nickname, version=2)}\n"
+ f"角色等级:{user_info.level}\n"
+ f"UID:`{user_info.uid}`\n"
+ f"服务器名称:`{user_info.server_name}`\n"
)
+ add_user_command_data.game_uid = user_info.uid
+ await message.reply_markdown_v2(text, reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
return COMMAND_RESULT
@conversation.state(state=COMMAND_RESULT)
@@ -159,11 +164,15 @@ class SetUserUid(Plugin.Conversation, BasePlugin.Conversation):
elif message.text == "确认":
if add_user_command_data.user is None:
if add_user_command_data.region == RegionEnum.HYPERION:
- user_db = User(user_id=user.id, yuanshen_uid=add_user_command_data.game_uid,
- region=add_user_command_data.region)
+ user_db = User(
+ user_id=user.id,
+ yuanshen_uid=add_user_command_data.game_uid,
+ region=add_user_command_data.region,
+ )
elif add_user_command_data.region == RegionEnum.HOYOLAB:
- user_db = User(user_id=user.id, genshin_uid=add_user_command_data.game_uid,
- region=add_user_command_data.region)
+ user_db = User(
+ user_id=user.id, genshin_uid=add_user_command_data.game_uid, region=add_user_command_data.region
+ )
else:
await message.reply_text("数据错误")
return ConversationHandler.END
diff --git a/plugins/genshin/userstats.py b/plugins/genshin/userstats.py
index 5eb571f..3c7d6ff 100644
--- a/plugins/genshin/userstats.py
+++ b/plugins/genshin/userstats.py
@@ -55,13 +55,9 @@ class UserStatsPlugins(Plugin, BasePlugin):
except UserNotFoundError:
reply_message = await message.reply_text("未查询到账号信息,请先私聊派蒙绑定账号")
if filters.ChatType.GROUPS.filter(message):
- self._add_delete_message_job(
- context, reply_message.chat_id, reply_message.message_id, 30
- )
+ self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id, 30)
- self._add_delete_message_job(
- context, message.chat_id, message.message_id, 30
- )
+ self._add_delete_message_job(context, message.chat_id, message.message_id, 30)
return
except TooManyRequestPublicCookies:
await message.reply_text("用户查询次数过多 请稍后重试")
@@ -72,9 +68,7 @@ class UserStatsPlugins(Plugin, BasePlugin):
await message.reply_text("角色数据有误 估计是派蒙晕了")
return
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
- await message.reply_photo(
- png_data, filename=f"{client.uid}.png", allow_sending_without_reply=True
- )
+ await message.reply_photo(png_data, filename=f"{client.uid}.png", allow_sending_without_reply=True)
async def render(self, client: Client, uid: Optional[int] = None) -> bytes:
if uid is None:
@@ -109,7 +103,7 @@ class UserStatsPlugins(Plugin, BasePlugin):
("雷神瞳", "electroculi"),
("草神瞳", "dendroculi"),
],
- "style": secrets.choice(["mondstadt", "liyue"])
+ "style": secrets.choice(["mondstadt", "liyue"]),
}
# html = await self.template_service.render_async(
diff --git a/plugins/genshin/weapon.py b/plugins/genshin/weapon.py
index b6e8d64..7a846bd 100644
--- a/plugins/genshin/weapon.py
+++ b/plugins/genshin/weapon.py
@@ -20,15 +20,13 @@ from utils.log import logger
class WeaponPlugin(Plugin, BasePlugin):
"""武器查询"""
- KEYBOARD = [[
- InlineKeyboardButton(text="查看武器列表并查询", switch_inline_query_current_chat="查看武器列表并查询")
- ]]
+ KEYBOARD = [[InlineKeyboardButton(text="查看武器列表并查询", switch_inline_query_current_chat="查看武器列表并查询")]]
def __init__(
- self,
- template_service: TemplateService = None,
- wiki_service: WikiService = None,
- assets_service: AssetsService = None
+ self,
+ template_service: TemplateService = None,
+ wiki_service: WikiService = None,
+ assets_service: AssetsService = None,
):
self.wiki_service = wiki_service
self.template_service = template_service
@@ -45,8 +43,7 @@ class WeaponPlugin(Plugin, BasePlugin):
if len(args) >= 1:
weapon_name = args[0]
else:
- reply_message = await message.reply_text("请回复你要查询的武器",
- reply_markup=InlineKeyboardMarkup(self.KEYBOARD))
+ reply_message = await message.reply_text("请回复你要查询的武器", reply_markup=InlineKeyboardMarkup(self.KEYBOARD))
if filters.ChatType.GROUPS.filter(reply_message):
self._add_delete_message_job(context, message.chat_id, message.message_id)
self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id)
@@ -59,8 +56,9 @@ class WeaponPlugin(Plugin, BasePlugin):
weapon_data = weapon
break
else:
- reply_message = await message.reply_text(f"没有找到 {weapon_name}",
- reply_markup=InlineKeyboardMarkup(self.KEYBOARD))
+ reply_message = await message.reply_text(
+ f"没有找到 {weapon_name}", reply_markup=InlineKeyboardMarkup(self.KEYBOARD)
+ )
if filters.ChatType.GROUPS.filter(reply_message):
self._add_delete_message_job(context, message.chat_id, message.message_id)
self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id)
@@ -70,8 +68,8 @@ class WeaponPlugin(Plugin, BasePlugin):
async def input_template_data(_weapon_data: Weapon):
if weapon.rarity > 2:
bonus = _weapon_data.stats[-1].bonus
- if '%' in bonus:
- bonus = str(round(float(bonus.rstrip('%')))) + '%'
+ if "%" in bonus:
+ bonus = str(round(float(bonus.rstrip("%")))) + "%"
else:
bonus = str(round(float(bonus)))
_template_data = {
@@ -80,12 +78,12 @@ class WeaponPlugin(Plugin, BasePlugin):
"progression_secondary_stat_value": bonus,
"progression_secondary_stat_name": _weapon_data.attribute.type.value,
"weapon_info_source_img": (
- await self.assets_service.weapon(honey_id_to_game_id(_weapon_data.id, 'weapon')).icon()
+ await self.assets_service.weapon(honey_id_to_game_id(_weapon_data.id, "weapon")).icon()
).as_uri(),
"weapon_info_max_level": _weapon_data.stats[-1].level,
"progression_base_atk": round(_weapon_data.stats[-1].ATK),
"weapon_info_source_list": [
- (await self.assets_service.material(honey_id_to_game_id(mid, 'material')).icon()).as_uri()
+ (await self.assets_service.material(honey_id_to_game_id(mid, "material")).icon()).as_uri()
for mid in _weapon_data.ascension[-3:]
],
"special_ability_name": _weapon_data.affix.name,
@@ -95,25 +93,27 @@ class WeaponPlugin(Plugin, BasePlugin):
_template_data = {
"weapon_name": _weapon_data.name,
"weapon_info_type_img": await url_to_file(_weapon_data.weapon_type.icon_url()),
- "progression_secondary_stat_value": ' ',
- "progression_secondary_stat_name": '无其它属性加成',
+ "progression_secondary_stat_value": " ",
+ "progression_secondary_stat_name": "无其它属性加成",
"weapon_info_source_img": (
- await self.assets_service.weapon(honey_id_to_game_id(_weapon_data.id, 'weapon')).icon()
+ await self.assets_service.weapon(honey_id_to_game_id(_weapon_data.id, "weapon")).icon()
).as_uri(),
"weapon_info_max_level": _weapon_data.stats[-1].level,
"progression_base_atk": round(_weapon_data.stats[-1].ATK),
"weapon_info_source_list": [
- (await self.assets_service.material(honey_id_to_game_id(mid, 'material')).icon()).as_uri()
+ (await self.assets_service.material(honey_id_to_game_id(mid, "material")).icon()).as_uri()
for mid in _weapon_data.ascension[-3:]
],
- "special_ability_name": '',
+ "special_ability_name": "",
"special_ability_info": _weapon_data.description,
}
return _template_data
template_data = await input_template_data(weapon_data)
- png_data = await self.template_service.render('genshin/weapon', "weapon.html", template_data,
- {"width": 540, "height": 540})
+ png_data = await self.template_service.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)
+ await message.reply_photo(
+ png_data, filename=f"{template_data['weapon_name']}.png", allow_sending_without_reply=True
+ )
diff --git a/plugins/jobs/public_cookies.py b/plugins/jobs/public_cookies.py
index 8326434..df223e7 100644
--- a/plugins/jobs/public_cookies.py
+++ b/plugins/jobs/public_cookies.py
@@ -8,7 +8,6 @@ from utils.log import logger
class PublicCookies(Plugin):
-
def __init__(self, public_cookies_service: PublicCookiesService = None):
self.public_cookies_service = public_cookies_service
diff --git a/plugins/other/post.py b/plugins/other/post.py
index 2ebe10a..9667d21 100644
--- a/plugins/other/post.py
+++ b/plugins/other/post.py
@@ -19,7 +19,6 @@ from utils.log import logger
class PostHandlerData:
-
def __init__(self):
self.post_text: str = ""
self.post_images: Optional[List[ArtworkImage]] = None
@@ -41,7 +40,7 @@ class Post(Plugin.Conversation, BasePlugin):
self.bbs = Hyperion()
@conversation.entry_point
- @handler.command(command='post', filters=filters.ChatType.PRIVATE, block=True)
+ @handler.command(command="post", filters=filters.ChatType.PRIVATE, block=True)
@restricts()
@bot_admins_rights_check
@error_callable
@@ -53,10 +52,8 @@ class Post(Plugin.Conversation, BasePlugin):
if post_handler_data is None:
post_handler_data = PostHandlerData()
context.chat_data["post_handler_data"] = post_handler_data
- text = f"✿✿ヽ(°▽°)ノ✿ 你好! {user.username} ,\n" \
- "只需复制URL回复即可 \n" \
- "退出投稿只需回复退出"
- reply_keyboard = [['退出']]
+ text = f"✿✿ヽ(°▽°)ノ✿ 你好! {user.username} ,\n" "只需复制URL回复即可 \n" "退出投稿只需回复退出"
+ reply_keyboard = [["退出"]]
await message.reply_text(text, reply_markup=ReplyKeyboardMarkup(reply_keyboard, True, True))
return CHECK_POST
@@ -77,17 +74,16 @@ class Post(Plugin.Conversation, BasePlugin):
post_info = await self.bbs.get_post_info(2, post_id)
post_images = await self.bbs.get_images_by_post_id(2, post_id)
post_data = post_info["post"]["post"]
- post_subject = post_data['subject']
+ post_subject = post_data["subject"]
post_soup = BeautifulSoup(post_data["content"], features="html.parser")
- post_p = post_soup.find_all('p')
- post_text = f"*{escape_markdown(post_subject, version=2)}*\n" \
- f"\n"
+ post_p = post_soup.find_all("p")
+ post_text = f"*{escape_markdown(post_subject, version=2)}*\n" f"\n"
for p in post_p:
post_text += f"{escape_markdown(p.get_text(), version=2)}\n"
post_text += f"[source](https://bbs.mihoyo.com/ys/article/{post_id})"
if len(post_text) >= MessageLimit.CAPTION_LENGTH:
await message.reply_markdown_v2(post_text)
- post_text = post_text[0:MessageLimit.CAPTION_LENGTH]
+ post_text = post_text[0 : MessageLimit.CAPTION_LENGTH]
await message.reply_text(f"警告!图片字符描述已经超过 {MessageLimit.CAPTION_LENGTH} 个字,已经切割并发送原文本")
try:
if len(post_images) > 1:
@@ -138,8 +134,7 @@ class Post(Plugin.Conversation, BasePlugin):
post_handler_data: PostHandlerData = context.chat_data.get("post_handler_data")
photo_len = len(post_handler_data.post_images)
message = update.effective_message
- await message.reply_text("请回复你要删除的图片的序列,从1开始,如果删除多张图片回复的序列请以空格作为分隔符,"
- f"当前一共有 {photo_len} 张图片")
+ await message.reply_text("请回复你要删除的图片的序列,从1开始,如果删除多张图片回复的序列请以空格作为分隔符," f"当前一共有 {photo_len} 张图片")
return GTE_DELETE_PHOTO
@conversation.state(state=GTE_DELETE_PHOTO)
@@ -175,8 +170,7 @@ class Post(Plugin.Conversation, BasePlugin):
logger.error("从配置文件获取频道信息发生错误,退出任务", error)
await message.reply_text("从配置文件获取频道信息发生错误,退出任务", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
- await message.reply_text("请选择你要推送的频道",
- reply_markup=ReplyKeyboardMarkup(reply_keyboard, True, True))
+ await message.reply_text("请选择你要推送的频道", reply_markup=ReplyKeyboardMarkup(reply_keyboard, True, True))
return GET_POST_CHANNEL
@conversation.state(state=GET_POST_CHANNEL)
@@ -200,8 +194,7 @@ class Post(Plugin.Conversation, BasePlugin):
return ConversationHandler.END
post_handler_data.channel_id = channel_id
reply_keyboard = [["确认", "退出"]]
- await message.reply_text("请核对你修改的信息",
- reply_markup=ReplyKeyboardMarkup(reply_keyboard, True, True))
+ await message.reply_text("请核对你修改的信息", reply_markup=ReplyKeyboardMarkup(reply_keyboard, True, True))
return SEND_POST
async def add_tags(self, update: Update, _: CallbackContext) -> int:
@@ -273,8 +266,9 @@ class Post(Plugin.Conversation, BasePlugin):
await context.bot.send_media_group(channel_id, media=media)
elif len(post_images) == 1:
image = post_images[0]
- await context.bot.send_photo(channel_id, photo=image.data, caption=post_text,
- parse_mode=ParseMode.MARKDOWN_V2)
+ await context.bot.send_photo(
+ channel_id, photo=image.data, caption=post_text, parse_mode=ParseMode.MARKDOWN_V2
+ )
elif len(post_images) == 0:
await context.bot.send_message(channel_id, post_text, parse_mode=ParseMode.MARKDOWN_V2)
else:
@@ -287,4 +281,3 @@ class Post(Plugin.Conversation, BasePlugin):
return ConversationHandler.END
await message.reply_text("推送成功", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
-
diff --git a/plugins/system/auth.py b/plugins/system/auth.py
index db6d8a7..6d472f3 100644
--- a/plugins/system/auth.py
+++ b/plugins/system/auth.py
@@ -72,8 +72,9 @@ class GroupJoiningVerification(Plugin):
job = context.job
logger.info(f"踢出用户 user_id[{job.user_id}] 在 chat_id[{job.chat_id}]")
try:
- await context.bot.ban_chat_member(chat_id=job.chat_id, user_id=job.user_id,
- until_date=int(time.time()) + self.kick_time)
+ await context.bot.ban_chat_member(
+ chat_id=job.chat_id, user_id=job.user_id, until_date=int(time.time()) + self.kick_time
+ )
except BadRequest as exc:
logger.error(f"Auth模块在 chat_id[{job.chat_id}] user_id[{job.user_id}] 执行kick失败")
logger.exception(exc)
@@ -88,8 +89,7 @@ class GroupJoiningVerification(Plugin):
if "not found" in str(exc):
logger.warning(f"Auth模块删除消息 chat_id[{job.chat_id}] message_id[{job.data}]失败 消息不存在")
elif "Message can't be deleted" in str(exc):
- logger.warning(
- f"Auth模块删除消息 chat_id[{job.chat_id}] message_id[{job.data}]失败 消息无法删除 可能是没有授权")
+ logger.warning(f"Auth模块删除消息 chat_id[{job.chat_id}] message_id[{job.data}]失败 消息无法删除 可能是没有授权")
else:
logger.error(f"Auth模块删除消息 chat_id[{job.chat_id}] message_id[{job.data}]失败")
logger.exception(exc)
@@ -106,7 +106,6 @@ class GroupJoiningVerification(Plugin):
@handler(CallbackQueryHandler, pattern=r"^auth_admin\|", block=False)
@restricts(without_overlapping=True)
async def admin(self, update: Update, context: CallbackContext) -> None:
-
async def admin_callback(callback_query_data: str) -> Tuple[str, int]:
_data = callback_query_data.split("|")
_result = _data[1]
@@ -122,8 +121,7 @@ class GroupJoiningVerification(Plugin):
chat_administrators = await self.get_chat_administrators(context, chat_id=chat.id)
if not self.is_admin(chat_administrators, user.id):
logger.debug(f"用户 {user.full_name}[{user.id}] 在群 {chat.title}[{chat.id}] 非群管理")
- await callback_query.answer(text="你不是管理!\n"
- "再乱点我叫西风骑士团、千岩军和天领奉行了!", show_alert=True)
+ await callback_query.answer(text="你不是管理!\n" "再乱点我叫西风骑士团、千岩军和天领奉行了!", show_alert=True)
return
result, user_id = await admin_callback(callback_query.data)
try:
@@ -139,22 +137,21 @@ class GroupJoiningVerification(Plugin):
await self.restore_member(context, chat.id, user_id)
if schedule := context.job_queue.scheduler.get_job(f"{chat.id}|{user_id}|auth_kick"):
schedule.remove()
- await message.edit_text(f"{user_info} 被 {user.mention_markdown_v2()} 放行",
- parse_mode=ParseMode.MARKDOWN_V2)
+ await message.edit_text(f"{user_info} 被 {user.mention_markdown_v2()} 放行", parse_mode=ParseMode.MARKDOWN_V2)
logger.info(f"用户 user_id[{user_id}] 在群 {chat.title}[{chat.id}] 被管理放行")
elif result == "kick":
await callback_query.answer(text="驱离", show_alert=False)
await context.bot.ban_chat_member(chat.id, user_id)
- await message.edit_text(f"{user_info} 被 {user.mention_markdown_v2()} 驱离",
- parse_mode=ParseMode.MARKDOWN_V2)
+ await message.edit_text(f"{user_info} 被 {user.mention_markdown_v2()} 驱离", parse_mode=ParseMode.MARKDOWN_V2)
logger.info(f"用户 user_id[{user_id}] 在群 {chat.title}[{chat.id}] 被管理踢出")
elif result == "unban":
await callback_query.answer(text="解除驱离", show_alert=False)
await self.restore_member(context, chat.id, user_id)
if schedule := context.job_queue.scheduler.get_job(f"{chat.id}|{user_id}|auth_kick"):
schedule.remove()
- await message.edit_text(f"{user_info} 被 {user.mention_markdown_v2()} 解除驱离",
- parse_mode=ParseMode.MARKDOWN_V2)
+ await message.edit_text(
+ f"{user_info} 被 {user.mention_markdown_v2()} 解除驱离", parse_mode=ParseMode.MARKDOWN_V2
+ )
logger.info(f"用户 user_id[{user_id}] 在群 {chat.title}[{chat.id}] 被管理解除封禁")
else:
logger.warning(f"auth 模块 admin 函数 发现未知命令 result[{result}]")
@@ -165,7 +162,6 @@ class GroupJoiningVerification(Plugin):
@handler(CallbackQueryHandler, pattern=r"^auth_challenge\|", block=False)
@restricts(without_overlapping=True)
async def query(self, update: Update, context: CallbackContext) -> None:
-
async def query_callback(callback_query_data: str) -> Tuple[int, bool, str, str]:
_data = callback_query_data.split("|")
_user_id = int(_data[1])
@@ -176,8 +172,10 @@ class GroupJoiningVerification(Plugin):
_result = _answer.is_correct
_answer_encode = _answer.text
_question_encode = _question.text
- logger.debug(f"query_callback函数返回 user_id[{_user_id}] result[{_result}] \n"
- f"question_encode[{_question_encode}] answer_encode[{_answer_encode}]")
+ logger.debug(
+ f"query_callback函数返回 user_id[{_user_id}] result[{_result}] \n"
+ f"question_encode[{_question_encode}] answer_encode[{_answer_encode}]"
+ )
return _user_id, _result, _question_encode, _answer_encode
callback_query = update.callback_query
@@ -187,36 +185,43 @@ class GroupJoiningVerification(Plugin):
user_id, result, question, answer = await query_callback(callback_query.data)
logger.info(f"用户 {user.full_name}[{user.id}] 在群 {chat.title}[{chat.id}] 点击Auth认证命令 ")
if user.id != user_id:
- await callback_query.answer(text="这不是你的验证!\n"
- "再乱点再按我叫西风骑士团、千岩军和天领奉行了!", show_alert=True)
+ await callback_query.answer(text="这不是你的验证!\n" "再乱点再按我叫西风骑士团、千岩军和天领奉行了!", show_alert=True)
return
- logger.info(
- f"用户 {user.full_name}[{user.id}] 在群 {chat.title}[{chat.id}] 认证结果为 {'通过' if result else '失败'}")
+ logger.info(f"用户 {user.full_name}[{user.id}] 在群 {chat.title}[{chat.id}] 认证结果为 {'通过' if result else '失败'}")
if result:
buttons = [[InlineKeyboardButton("驱离", callback_data=f"auth_admin|kick|{user.id}")]]
await callback_query.answer(text="验证成功", show_alert=False)
await self.restore_member(context, chat.id, user_id)
if schedule := context.job_queue.scheduler.get_job(f"{chat.id}|{user.id}|auth_kick"):
schedule.remove()
- text = f"{user.mention_markdown_v2()} 验证成功,向着星辰与深渊!\n" \
- f"问题:{escape_markdown(question, version=2)} \n" \
- f"回答:{escape_markdown(answer, version=2)}"
+ text = (
+ f"{user.mention_markdown_v2()} 验证成功,向着星辰与深渊!\n"
+ f"问题:{escape_markdown(question, version=2)} \n"
+ f"回答:{escape_markdown(answer, version=2)}"
+ )
logger.info(f"用户 user_id[{user_id}] 在群 {chat.title}[{chat.id}] 验证成功")
else:
- buttons = [[InlineKeyboardButton("驱离", callback_data=f"auth_admin|kick|{user.id}"),
- InlineKeyboardButton("撤回驱离", callback_data=f"auth_admin|unban|{user.id}")]]
+ buttons = [
+ [
+ InlineKeyboardButton("驱离", callback_data=f"auth_admin|kick|{user.id}"),
+ InlineKeyboardButton("撤回驱离", callback_data=f"auth_admin|unban|{user.id}"),
+ ]
+ ]
await callback_query.answer(text=f"验证失败,请在 {self.time_out} 秒后重试", show_alert=True)
await asyncio.sleep(3)
- await context.bot.ban_chat_member(chat_id=chat.id, user_id=user_id,
- until_date=int(time.time()) + self.kick_time)
- text = f"{user.mention_markdown_v2()} 验证失败,已经赶出提瓦特大陆!\n" \
- f"问题:{escape_markdown(question, version=2)} \n" \
- f"回答:{escape_markdown(answer, version=2)}"
+ await context.bot.ban_chat_member(
+ chat_id=chat.id, user_id=user_id, until_date=int(time.time()) + self.kick_time
+ )
+ text = (
+ f"{user.mention_markdown_v2()} 验证失败,已经赶出提瓦特大陆!\n"
+ f"问题:{escape_markdown(question, version=2)} \n"
+ f"回答:{escape_markdown(answer, version=2)}"
+ )
logger.info(f"用户 user_id[{user_id}] 在群 {chat.title}[{chat.id}] 验证失败")
try:
await message.edit_text(text, reply_markup=InlineKeyboardMarkup(buttons), parse_mode=ParseMode.MARKDOWN_V2)
except BadRequest as exc:
- if 'are exactly the same as ' in str(exc):
+ if "are exactly the same as " in str(exc):
logger.warning("编辑消息发生异常,可能为用户点按多次键盘导致")
else:
raise exc
@@ -254,8 +259,9 @@ class GroupJoiningVerification(Plugin):
await message.reply_text("旅行者!!!派蒙的问题清单你还没给我!!快去私聊我给我问题!")
return
try:
- await context.bot.restrict_chat_member(chat_id=message.chat.id, user_id=user.id,
- permissions=ChatPermissions(can_send_messages=False))
+ await context.bot.restrict_chat_member(
+ chat_id=message.chat.id, user_id=user.id, permissions=ChatPermissions(can_send_messages=False)
+ )
except BadRequest as err:
if "Not enough rights" in str(err):
logger.warning(f"权限不够 chat_id[{message.chat_id}]")
@@ -290,45 +296,59 @@ class GroupJoiningVerification(Plugin):
),
]
)
- reply_message = f"*欢迎来到「提瓦特」世界!* \n" \
- f"问题: {escape_markdown(question.text, version=2)} \n" \
- f"请在 {self.time_out}S 内回答问题"
- logger.debug(f"发送入群验证问题 question_id[{question.question_id}] question[{question.text}] \n"
- f"给{user.full_name}[{user.id}] 在 {chat.title}[{chat.id}]")
+ reply_message = (
+ f"*欢迎来到「提瓦特」世界!* \n" f"问题: {escape_markdown(question.text, version=2)} \n" f"请在 {self.time_out}S 内回答问题"
+ )
+ logger.debug(
+ f"发送入群验证问题 question_id[{question.question_id}] question[{question.text}] \n"
+ f"给{user.full_name}[{user.id}] 在 {chat.title}[{chat.id}]"
+ )
try:
- question_message = await message.reply_markdown_v2(reply_message,
- reply_markup=InlineKeyboardMarkup(buttons))
+ question_message = await message.reply_markdown_v2(
+ reply_message, reply_markup=InlineKeyboardMarkup(buttons)
+ )
except BadRequest as exc:
await message.reply_text("派蒙分心了一下,不小心忘记你了,你只能先退出群再重新进来吧。")
raise exc
- context.job_queue.run_once(callback=self.kick_member_job, when=self.time_out,
- name=f"{chat.id}|{user.id}|auth_kick", chat_id=chat.id, user_id=user.id,
- job_kwargs={"replace_existing": True, "id": f"{chat.id}|{user.id}|auth_kick"})
- context.job_queue.run_once(callback=self.clean_message_job, when=self.time_out, data=message.message_id,
- name=f"{chat.id}|{user.id}|auth_clean_join_message",
- chat_id=chat.id, user_id=user.id,
- job_kwargs={"replace_existing": True,
- "id": f"{chat.id}|{user.id}|auth_clean_join_message"})
- context.job_queue.run_once(callback=self.clean_message_job, when=self.time_out,
- data=question_message.message_id,
- name=f"{chat.id}|{user.id}|auth_clean_question_message",
- chat_id=chat.id, user_id=user.id,
- job_kwargs={"replace_existing": True,
- "id": f"{chat.id}|{user.id}|auth_clean_question_message"})
+ context.job_queue.run_once(
+ callback=self.kick_member_job,
+ when=self.time_out,
+ name=f"{chat.id}|{user.id}|auth_kick",
+ chat_id=chat.id,
+ user_id=user.id,
+ job_kwargs={"replace_existing": True, "id": f"{chat.id}|{user.id}|auth_kick"},
+ )
+ context.job_queue.run_once(
+ callback=self.clean_message_job,
+ when=self.time_out,
+ data=message.message_id,
+ name=f"{chat.id}|{user.id}|auth_clean_join_message",
+ chat_id=chat.id,
+ user_id=user.id,
+ job_kwargs={"replace_existing": True, "id": f"{chat.id}|{user.id}|auth_clean_join_message"},
+ )
+ context.job_queue.run_once(
+ callback=self.clean_message_job,
+ when=self.time_out,
+ data=question_message.message_id,
+ name=f"{chat.id}|{user.id}|auth_clean_question_message",
+ chat_id=chat.id,
+ user_id=user.id,
+ job_kwargs={"replace_existing": True, "id": f"{chat.id}|{user.id}|auth_clean_question_message"},
+ )
if self.mtp and (question_message.id - message.id - 1):
from pyrogram.errors import BadRequest as MTPBadRequest, FloodWait as MTPFloodWait
+
try:
messages_list = await self.mtp.get_messages(
- chat.id,
- message_ids=list(range(message.id + 1, question_message.id))
+ chat.id, message_ids=list(range(message.id + 1, question_message.id))
)
for find_message in messages_list:
if find_message.empty:
continue
if find_message.from_user and find_message.from_user.id == user.id:
await self.mtp.delete_messages(chat_id=chat.id, message_ids=find_message.id)
- logger.info(f"用户 {user.full_name}[{user.id}] 在群 {chat.title}[{chat.id}] 验证缝隙间发送消息"
- "现已删除")
+ logger.info(f"用户 {user.full_name}[{user.id}] 在群 {chat.title}[{chat.id}] 验证缝隙间发送消息" "现已删除")
except MTPFloodWait:
logger.warning("调用 mtp 触发洪水限制")
continue
diff --git a/plugins/system/errorhandler.py b/plugins/system/errorhandler.py
index 3c143a3..7046753 100644
--- a/plugins/system/errorhandler.py
+++ b/plugins/system/errorhandler.py
@@ -24,7 +24,6 @@ if not os.path.exists(report_dir):
class ErrorHandler(Plugin):
-
@error_handler(block=False) # pylint: disable=E1123, E1120
async def error_handler(self, update: object, context: CallbackContext) -> None:
"""记录错误并发送消息通知开发人员。 logger the error and send a telegram message to notify the developer."""
@@ -52,20 +51,23 @@ class ErrorHandler(Plugin):
file_name = f"error_{update.update_id if isinstance(update, Update) else int(time.time())}.txt"
log_file = os.path.join(report_dir, file_name)
try:
- async with aiofiles.open(log_file, mode='w+', encoding='utf-8') as f:
+ async with aiofiles.open(log_file, mode="w+", encoding="utf-8") as f:
await f.write(error_text)
except Exception as exc:
logger.error("保存日记失败")
logger.exception(exc)
try:
- if 'make sure that only one bot instance is running' in tb_string:
+ if "make sure that only one bot instance is running" in tb_string:
logger.error("其他机器人在运行,请停止!")
return
- if 'Message is not modified' in tb_string:
+ if "Message is not modified" in tb_string:
logger.error("消息未修改")
return
- await context.bot.send_document(chat_id=notice_chat_id, document=open(log_file, "rb"),
- caption=f"Error: \"{context.error.__class__.__name__}\"")
+ await context.bot.send_document(
+ chat_id=notice_chat_id,
+ document=open(log_file, "rb"),
+ caption=f'Error: "{context.error.__class__.__name__}"',
+ )
except (BadRequest, Forbidden) as exc:
logger.error("发送日记失败")
logger.exception(exc)
@@ -76,12 +78,15 @@ class ErrorHandler(Plugin):
try:
if effective_message is not None:
chat = effective_message.chat
- logger.info(f"尝试通知用户 {effective_user.full_name}[{effective_user.id}] "
- f"在 {chat.full_name}[{chat.id}]"
- f"的 update_id[{update.update_id}] 错误信息")
+ logger.info(
+ f"尝试通知用户 {effective_user.full_name}[{effective_user.id}] "
+ f"在 {chat.full_name}[{chat.id}]"
+ f"的 update_id[{update.update_id}] 错误信息"
+ )
text = "出错了呜呜呜 ~ 派蒙这边发生了点问题无法处理!"
- await context.bot.send_message(effective_message.chat_id, text, reply_markup=ReplyKeyboardRemove(),
- parse_mode=ParseMode.HTML)
+ await context.bot.send_message(
+ effective_message.chat_id, text, reply_markup=ReplyKeyboardRemove(), parse_mode=ParseMode.HTML
+ )
except (BadRequest, Forbidden) as exc:
logger.error(f"发送 update_id[{update.update_id}] 错误信息失败 错误信息为")
logger.exception(exc)
diff --git a/plugins/system/get_chat.py b/plugins/system/get_chat.py
index ecd9497..6b83f23 100644
--- a/plugins/system/get_chat.py
+++ b/plugins/system/get_chat.py
@@ -25,15 +25,14 @@ class GetChat(Plugin):
@staticmethod
def parse_group_chat(chat: Chat, admins: List[ChatMember]) -> str:
- text = f"群 ID:{chat.id}
\n" \
- f"群名称:{chat.title}
\n"
+ text = f"群 ID:{chat.id}
\n" f"群名称:{chat.title}
\n"
if chat.username:
text += f"群用户名:{chat.username}
\n"
if chat.description:
text += f"群简介:{chat.description}
\n"
if admins:
for admin in admins:
- text += f"{admin.user.full_name} "
+ text += f'{admin.user.full_name} '
if isinstance(admin, ChatMemberAdministrator):
text += "C" if admin.can_change_info else "_"
text += "D" if admin.can_delete_messages else "_"
@@ -49,9 +48,11 @@ class GetChat(Plugin):
return text
async def parse_private_chat(self, chat: Chat) -> str:
- text = f"MENTION\n" \
- f"用户 ID:{chat.id}
\n" \
- f"用户名称:{chat.full_name}
\n"
+ text = (
+ f'MENTION\n'
+ f"用户 ID:{chat.id}
\n"
+ f"用户名称:{chat.full_name}
\n"
+ )
if chat.username:
text += f"用户名:@{chat.username}\n"
try:
@@ -70,8 +71,7 @@ class GetChat(Plugin):
await get_genshin_client(chat.id)
except CookiesNotFoundError:
temp = "UID 绑定"
- text += f"{temp}
\n" \
- f"游戏 ID:{uid}
"
+ text += f"{temp}
\n" f"游戏 ID:{uid}
"
with contextlib.suppress(Exception):
gacha_log, status = await GachaLog.load_history_info(str(chat.id), str(uid))
if status:
diff --git a/plugins/system/inline.py b/plugins/system/inline.py
index 504a242..df7e88c 100644
--- a/plugins/system/inline.py
+++ b/plugins/system/inline.py
@@ -36,9 +36,11 @@ class Inline(Plugin):
id=str(uuid4()),
title=weapons_name,
description=f"查看武器列表并查询 {weapons_name}",
- input_message_content=InputTextMessageContent(f"武器查询{weapons_name}",
- parse_mode=ParseMode.MARKDOWN_V2)
- ))
+ input_message_content=InputTextMessageContent(
+ f"武器查询{weapons_name}", parse_mode=ParseMode.MARKDOWN_V2
+ ),
+ )
+ )
elif "查看角色攻略列表并查询" == args[0]:
characters_list = await self.wiki_service.get_characters_name_list()
for role_name in characters_list:
@@ -47,9 +49,11 @@ class Inline(Plugin):
id=str(uuid4()),
title=role_name,
description=f"查看角色攻略列表并查询 {role_name}",
- input_message_content=InputTextMessageContent(f"角色攻略查询{role_name}",
- parse_mode=ParseMode.MARKDOWN_V2)
- ))
+ input_message_content=InputTextMessageContent(
+ f"角色攻略查询{role_name}", parse_mode=ParseMode.MARKDOWN_V2
+ ),
+ )
+ )
elif "查看角色培养素材列表并查询" == args[0]:
characters_list = await self.wiki_service.get_characters_name_list()
for role_name in characters_list:
@@ -58,9 +62,11 @@ class Inline(Plugin):
id=str(uuid4()),
title=role_name,
description=f"查看角色培养素材列表并查询 {role_name}",
- input_message_content=InputTextMessageContent(f"角色培养素材查询{role_name}",
- parse_mode=ParseMode.MARKDOWN_V2)
- ))
+ input_message_content=InputTextMessageContent(
+ f"角色培养素材查询{role_name}", parse_mode=ParseMode.MARKDOWN_V2
+ ),
+ )
+ )
if not results_list:
results_list.append(
@@ -69,7 +75,8 @@ class Inline(Plugin):
title="好像找不到问题呢",
description="这个问题我也不知道,因为我就是个应急食品。",
input_message_content=InputTextMessageContent("这个问题我也不知道,因为我就是个应急食品。"),
- ))
+ )
+ )
try:
await ilq.answer(
results=results_list,
diff --git a/plugins/system/log.py b/plugins/system/log.py
index 22c0a2d..2dcc0b0 100644
--- a/plugins/system/log.py
+++ b/plugins/system/log.py
@@ -13,7 +13,6 @@ debug_log = os.path.join(current_dir, "logs", "debug", "debug.log")
class Log(Plugin):
-
@handler(CommandHandler, command="send_log", block=False)
@bot_admins_rights_check
async def send_log(self, update: Update, _: CallbackContext):
@@ -21,10 +20,10 @@ class Log(Plugin):
logger.info(f"用户 {user.full_name}[{user.id}] send_log 命令请求")
message = update.effective_message
if os.path.exists(error_log) and os.path.getsize(error_log) > 0:
- await message.reply_document(open(error_log, mode='rb+'), caption="Error Log")
+ await message.reply_document(open(error_log, mode="rb+"), caption="Error Log")
else:
await message.reply_text("错误日记未找到")
if os.path.exists(debug_log) and os.path.getsize(debug_log) > 0:
- await message.reply_document(open(debug_log, mode='rb+'), caption="Debug Log")
+ await message.reply_document(open(debug_log, mode="rb+"), caption="Debug Log")
else:
await message.reply_text("调试日记未找到")
diff --git a/plugins/system/new_member.py b/plugins/system/new_member.py
index 5caa37c..49f4b7c 100644
--- a/plugins/system/new_member.py
+++ b/plugins/system/new_member.py
@@ -7,7 +7,6 @@ from utils.log import logger
class BotJoiningGroupsVerification(Plugin):
-
def __init__(self, bot_admin_service: BotAdminService = None):
self.bot_admin_service = bot_admin_service
@@ -25,8 +24,7 @@ class BotJoiningGroupsVerification(Plugin):
logger.info(f"用户 {from_user.full_name}[{from_user.id}] 在群 {chat.title}[{chat.id}] 邀请BOT")
admin_list = await self.bot_admin_service.get_admin_list()
if from_user.id in admin_list:
- await context.bot.send_message(message.chat_id,
- '感谢邀请小派蒙到本群!请使用 /help 查看咱已经学会的功能。')
+ await context.bot.send_message(message.chat_id, "感谢邀请小派蒙到本群!请使用 /help 查看咱已经学会的功能。")
quit_status = False
else:
logger.info(f"未知用户 在群 {chat.title}[{chat.id}] 邀请BOT")
diff --git a/plugins/system/refresh_metadata.py b/plugins/system/refresh_metadata.py
index 978d61c..eaf0270 100644
--- a/plugins/system/refresh_metadata.py
+++ b/plugins/system/refresh_metadata.py
@@ -8,16 +8,13 @@ from utils.log import logger
class MetadataPlugin(Plugin):
-
- @handler.command('refresh_metadata')
+ @handler.command("refresh_metadata")
@bot_admins_rights_check
async def refresh(self, update: Update, _) -> None:
user = update.effective_user
message = update.effective_message
- logger.info(
- f"用户 {user.full_name}[{user.id}] 刷新[bold]metadata[/]缓存命令", extra={'markup': True}
- )
+ logger.info(f"用户 {user.full_name}[{user.id}] 刷新[bold]metadata[/]缓存命令", extra={"markup": True})
msg = await message.reply_text("正在刷新元数据,请耐心等待...")
logger.info("正在从 github 上获取元数据")
diff --git a/plugins/system/set_quiz.py b/plugins/system/set_quiz.py
index 40cfd77..6bb073b 100644
--- a/plugins/system/set_quiz.py
+++ b/plugins/system/set_quiz.py
@@ -23,7 +23,7 @@ from utils.log import logger
GET_NEW_CORRECT_ANSWER,
GET_NEW_WRONG_ANSWER,
QUESTION_EDIT,
- SAVE_QUESTION
+ SAVE_QUESTION,
) = range(10300, 10308)
@@ -43,7 +43,7 @@ class SetQuizPlugin(Plugin.Conversation, BasePlugin.Conversation):
self.time_out = 120
@conversation.entry_point
- @handler.command(command='set_quiz', filters=filters.ChatType.PRIVATE, block=True)
+ @handler.command(command="set_quiz", filters=filters.ChatType.PRIVATE, block=True)
@restricts()
@bot_admins_rights_check
@error_callable
@@ -56,32 +56,20 @@ class SetQuizPlugin(Plugin.Conversation, BasePlugin.Conversation):
quiz_command_data = QuizCommandData()
context.chat_data["quiz_command_data"] = quiz_command_data
text = f'你好 {user.mention_markdown_v2()} {escape_markdown("!请选择你的操作!")}'
- reply_keyboard = [
- ["查看问题", "添加问题"],
- ["重载问题"],
- ["退出"]
- ]
+ reply_keyboard = [["查看问题", "添加问题"], ["重载问题"], ["退出"]]
await message.reply_markdown_v2(text, reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
return CHECK_COMMAND
async def view_command(self, update: Update, _: CallbackContext) -> int:
_ = self
- keyboard = [
- [
- InlineKeyboardButton(text="选择问题", switch_inline_query_current_chat="查看问题 ")
- ]
- ]
- await update.message.reply_text("请回复你要查看的问题",
- reply_markup=InlineKeyboardMarkup(keyboard))
+ keyboard = [[InlineKeyboardButton(text="选择问题", switch_inline_query_current_chat="查看问题 ")]]
+ await update.message.reply_text("请回复你要查看的问题", reply_markup=InlineKeyboardMarkup(keyboard))
return CHECK_COMMAND
@conversation.state(state=CHECK_QUESTION)
@handler.message(filters=filters.TEXT & ~filters.COMMAND, block=True)
async def check_question(self, update: Update, _: CallbackContext) -> int:
- reply_keyboard = [
- ["删除问题"],
- ["退出"]
- ]
+ reply_keyboard = [["删除问题"], ["退出"]]
await update.message.reply_text("请选择你的操作", reply_markup=ReplyKeyboardMarkup(reply_keyboard))
return CHECK_COMMAND
@@ -124,8 +112,7 @@ class SetQuizPlugin(Plugin.Conversation, BasePlugin.Conversation):
return ConversationHandler.END
except ResponseError as error:
logger.error("重载问题失败", error)
- await update.message.reply_text("重载问题失败,异常抛出Redis请求错误异常,详情错误请看日记",
- reply_markup=ReplyKeyboardRemove())
+ await update.message.reply_text("重载问题失败,异常抛出Redis请求错误异常,详情错误请看日记", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
await update.message.reply_text("重载成功", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
@@ -137,8 +124,7 @@ class SetQuizPlugin(Plugin.Conversation, BasePlugin.Conversation):
quiz_command_data.new_question = ""
quiz_command_data.new_correct_answer = ""
quiz_command_data.status = 1
- await update.message.reply_text("请回复你要添加的问题,或发送 /cancel 取消操作",
- reply_markup=ReplyKeyboardRemove())
+ await update.message.reply_text("请回复你要添加的问题,或发送 /cancel 取消操作", reply_markup=ReplyKeyboardRemove())
return GET_NEW_QUESTION
@conversation.state(state=GET_NEW_QUESTION)
@@ -146,8 +132,7 @@ class SetQuizPlugin(Plugin.Conversation, BasePlugin.Conversation):
async def get_new_question(self, update: Update, context: CallbackContext) -> int:
message = update.effective_message
quiz_command_data: QuizCommandData = context.chat_data.get("quiz_command_data")
- reply_text = f"问题:`{escape_markdown(update.message.text, version=2)}`\n" \
- f"请填写正确答案:"
+ reply_text = f"问题:`{escape_markdown(update.message.text, version=2)}`\n" f"请填写正确答案:"
quiz_command_data.new_question = message.text
await update.message.reply_markdown_v2(reply_text)
return GET_NEW_CORRECT_ANSWER
@@ -156,19 +141,20 @@ class SetQuizPlugin(Plugin.Conversation, BasePlugin.Conversation):
@handler.message(filters=filters.TEXT & ~filters.COMMAND, block=True)
async def get_new_correct_answer(self, update: Update, context: CallbackContext) -> int:
quiz_command_data: QuizCommandData = context.chat_data.get("quiz_command_data")
- reply_text = f"正确答案:`{escape_markdown(update.message.text, version=2)}`\n" \
- f"请填写错误答案:"
+ reply_text = f"正确答案:`{escape_markdown(update.message.text, version=2)}`\n" f"请填写错误答案:"
await update.message.reply_markdown_v2(reply_text)
quiz_command_data.new_correct_answer = update.message.text
return GET_NEW_WRONG_ANSWER
@conversation.state(state=GET_NEW_WRONG_ANSWER)
@handler.message(filters=filters.TEXT & ~filters.COMMAND, block=True)
- @handler.command(command='finish_edit', block=True)
+ @handler.command(command="finish_edit", block=True)
async def get_new_wrong_answer(self, update: Update, context: CallbackContext) -> int:
quiz_command_data: QuizCommandData = context.chat_data.get("quiz_command_data")
- reply_text = f"错误答案:`{escape_markdown(update.message.text, version=2)}`\n" \
- f"可继续填写,并使用 {escape_markdown('/finish', version=2)} 结束。"
+ reply_text = (
+ f"错误答案:`{escape_markdown(update.message.text, version=2)}`\n"
+ f"可继续填写,并使用 {escape_markdown('/finish', version=2)} 结束。"
+ )
await update.message.reply_markdown_v2(reply_text)
quiz_command_data.new_wrong_answer.append(update.message.text)
return GET_NEW_WRONG_ANSWER
@@ -176,13 +162,14 @@ class SetQuizPlugin(Plugin.Conversation, BasePlugin.Conversation):
async def finish_edit(self, update: Update, context: CallbackContext):
_ = self
quiz_command_data: QuizCommandData = context.chat_data.get("quiz_command_data")
- reply_text = f"问题:`{escape_markdown(quiz_command_data.new_question, version=2)}`\n" \
- f"正确答案:`{escape_markdown(quiz_command_data.new_correct_answer, version=2)}`\n" \
- f"错误答案:`{escape_markdown(' '.join(quiz_command_data.new_wrong_answer), version=2)}`"
+ reply_text = (
+ f"问题:`{escape_markdown(quiz_command_data.new_question, version=2)}`\n"
+ f"正确答案:`{escape_markdown(quiz_command_data.new_correct_answer, version=2)}`\n"
+ f"错误答案:`{escape_markdown(' '.join(quiz_command_data.new_wrong_answer), version=2)}`"
+ )
await update.message.reply_markdown_v2(reply_text)
reply_keyboard = [["保存并重载配置", "抛弃修改并退出"]]
- await update.message.reply_text("请核对问题,并选择下一步操作。",
- reply_markup=ReplyKeyboardMarkup(reply_keyboard))
+ await update.message.reply_text("请核对问题,并选择下一步操作。", reply_markup=ReplyKeyboardMarkup(reply_keyboard))
return SAVE_QUESTION
@conversation.state(state=SAVE_QUESTION)
@@ -195,19 +182,18 @@ class SetQuizPlugin(Plugin.Conversation, BasePlugin.Conversation):
elif update.message.text == "保存并重载配置":
if quiz_command_data.status == 1:
answer = [
- Answer(text=wrong_answer, is_correct=False) for wrong_answer in
- quiz_command_data.new_wrong_answer
+ Answer(text=wrong_answer, is_correct=False) for wrong_answer in quiz_command_data.new_wrong_answer
]
answer.append(Answer(text=quiz_command_data.new_correct_answer, is_correct=True))
- await self.quiz_service.save_quiz(
- Question(text=quiz_command_data.new_question))
+ await self.quiz_service.save_quiz(Question(text=quiz_command_data.new_question))
await update.message.reply_text("保存成功", reply_markup=ReplyKeyboardRemove())
try:
await self.quiz_service.refresh_quiz()
except ResponseError as error:
logger.error("重载问题失败", error)
- await update.message.reply_text("重载问题失败,异常抛出Redis请求错误异常,详情错误请看日记",
- reply_markup=ReplyKeyboardRemove())
+ await update.message.reply_text(
+ "重载问题失败,异常抛出Redis请求错误异常,详情错误请看日记", reply_markup=ReplyKeyboardRemove()
+ )
return ConversationHandler.END
await update.message.reply_text("重载配置成功", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
@@ -239,8 +225,7 @@ class SetQuizPlugin(Plugin.Conversation, BasePlugin.Conversation):
await self.quiz_service.refresh_quiz()
except ResponseError as error:
logger.error("重载问题失败", error)
- await update.message.reply_text("重载问题失败,异常抛出Redis请求错误异常,详情错误请看日记",
- reply_markup=ReplyKeyboardRemove())
+ await update.message.reply_text("重载问题失败,异常抛出Redis请求错误异常,详情错误请看日记", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
await update.message.reply_text("重载配置成功", reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
diff --git a/plugins/system/start.py b/plugins/system/start.py
index 1fe08b9..f04db48 100644
--- a/plugins/system/start.py
+++ b/plugins/system/start.py
@@ -7,7 +7,6 @@ from utils.decorators.restricts import restricts
class StartPlugin(Plugin):
-
@handler(CommandHandler, command="start", block=False)
@restricts()
async def start(self, update: Update, context: CallbackContext) -> None:
@@ -15,8 +14,10 @@ class StartPlugin(Plugin):
message = update.effective_message
args = context.args
if args is not None and len(args) >= 1 and args[0] == "inline_message":
- await message.reply_markdown_v2(f"你好 {user.mention_markdown_v2()} {escape_markdown('!我是派蒙 !')}\n"
- f"{escape_markdown('发送 /help 命令即可查看命令帮助')}")
+ await message.reply_markdown_v2(
+ f"你好 {user.mention_markdown_v2()} {escape_markdown('!我是派蒙 !')}\n"
+ f"{escape_markdown('发送 /help 命令即可查看命令帮助')}"
+ )
return
await message.reply_markdown_v2(f"你好 {user.mention_markdown_v2()} {escape_markdown('!我是派蒙 !')}")
diff --git a/plugins/system/update.py b/plugins/system/update.py
index f5c4fa9..40ff430 100644
--- a/plugins/system/update.py
+++ b/plugins/system/update.py
@@ -21,7 +21,6 @@ UPDATE_DATA = os.path.join(current_dir, "data", "update.json")
class UpdatePlugin(Plugin):
-
def __init__(self):
self._lock = asyncio.Lock()
@@ -59,6 +58,6 @@ class UpdatePlugin(Plugin):
await execute(f"{executable} -m poetry install --extras all")
logger.info(f"更新成功 正在重启")
await reply_text.edit_text("更新成功 正在重启")
- async with async_open(UPDATE_DATA, mode='w', encoding='utf-8') as file:
+ async with async_open(UPDATE_DATA, mode="w", encoding="utf-8") as file:
await file.write(reply_text.to_json())
raise SystemExit
diff --git a/resources/genshin/abyss_team/example2.html b/resources/genshin/abyss_team/example2.html
new file mode 100644
index 0000000..9e0e5cc
--- /dev/null
+++ b/resources/genshin/abyss_team/example2.html
@@ -0,0 +1,477 @@
+
+
+