Merge branch 'master' of https://github.com/teahouse-studios/akari-bot
This commit is contained in:
commit
edeb9b1b7d
54 changed files with 799 additions and 318 deletions
2
bot.py
2
bot.py
|
@ -124,7 +124,7 @@ if __name__ == '__main__':
|
|||
logger.add(sys.stderr, format='{message}', level="INFO")
|
||||
query_dbver = session.query(DBVersion).first()
|
||||
if query_dbver is None:
|
||||
session.add_all([DBVersion(value='3')])
|
||||
session.add_all([DBVersion(value=str(BotDBUtil.database_version))])
|
||||
session.commit()
|
||||
query_dbver = session.query(DBVersion).first()
|
||||
if (current_ver := int(query_dbver.value)) < (target_ver := BotDBUtil.database_version):
|
||||
|
|
|
@ -273,8 +273,8 @@ class FetchTarget(FT):
|
|||
_tsk = []
|
||||
fetch_base_superuser = await FetchTarget.fetch_target(base_superuser)
|
||||
if fetch_base_superuser:
|
||||
await fetch_base_superuser.sendDirectMessage(
|
||||
'群消息发送被服务器拦截,已暂停群消息发送,使用~resume命令恢复推送。')
|
||||
await fetch_base_superuser.\
|
||||
sendDirectMessage(fetch_base_superuser.parent.locale.t("error.message.paused"))
|
||||
except Exception:
|
||||
Logger.error(traceback.format_exc())
|
||||
|
||||
|
|
|
@ -30,5 +30,5 @@ class CFG:
|
|||
|
||||
|
||||
Config = CFG().config
|
||||
CachePath = abspath(Config('cache_path'))
|
||||
CachePath = Config('cache_path')
|
||||
DBPath = Config('db_path')
|
||||
|
|
|
@ -9,7 +9,7 @@ dc_token =
|
|||
tg_token =
|
||||
openai_api_key =
|
||||
nl2c_model =
|
||||
|
||||
curseforge_api_key =
|
||||
|
||||
[cfg]
|
||||
debug = False
|
||||
|
|
|
@ -7,7 +7,7 @@ from core.builtins.message import MessageSession as MS
|
|||
from core.builtins.message.chain import MessageChain
|
||||
from core.logger import Logger
|
||||
from core.types import Session, MsgInfo, FetchTarget as FT, \
|
||||
FetchedSession as FS, FinishedSession as FinS, AutoSession as AS
|
||||
FetchedSession as FS, FinishedSession as FinS, AutoSession as AS, AutoSession
|
||||
|
||||
|
||||
class FinishedSession(FinS):
|
||||
|
@ -79,6 +79,21 @@ class Template(MS):
|
|||
self.session.message = c
|
||||
return self
|
||||
|
||||
async def waitReply(self, msgchain, quote=True, all_=False, append_instruction=True):
|
||||
msgchain = MessageChain(msgchain)
|
||||
if append_instruction:
|
||||
msgchain.append(Plain(self.locale.t("message.reply.prompt")))
|
||||
send = await self.sendMessage(msgchain, quote)
|
||||
c = input('Reply: ')
|
||||
return Template(target=MsgInfo(targetId='TEST|Console|0',
|
||||
senderId='TEST|0',
|
||||
senderName='',
|
||||
targetFrom='TEST|Console',
|
||||
senderFrom='TEST', clientName='TEST', messageId=0,
|
||||
replyId=None),
|
||||
session=AutoSession(message=c, target='TEST|Console|0', sender='TEST|0',
|
||||
auto_interactions=None))
|
||||
|
||||
def asDisplay(self, text_only=False):
|
||||
return self.session.message
|
||||
|
||||
|
@ -151,4 +166,3 @@ class FetchTarget(FT):
|
|||
|
||||
Bot.MessageSession = Template
|
||||
Bot.FetchTarget = FetchTarget
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ from typing import Dict, Union
|
|||
from core.builtins import PrivateAssets
|
||||
from core.logger import Logger
|
||||
from core.types import Module
|
||||
from core.utils.i18n import load_locale_file
|
||||
from core.types.module.component_meta import CommandMeta, RegexMeta, ScheduleMeta
|
||||
|
||||
load_dir_path = os.path.abspath('./modules/')
|
||||
|
@ -15,6 +16,10 @@ load_dir_path = os.path.abspath('./modules/')
|
|||
|
||||
def load_modules():
|
||||
err_prompt = []
|
||||
locale_err = load_locale_file()
|
||||
if locale_err:
|
||||
locale_err.append('i18n:')
|
||||
err_prompt.append('\n'.join(locale_err))
|
||||
fun_file = None
|
||||
dir_list = os.listdir(load_dir_path)
|
||||
for file_name in dir_list:
|
||||
|
|
|
@ -40,7 +40,7 @@ async def msg_counter(msg: MessageSession, command: str):
|
|||
else:
|
||||
same['count'] += 1
|
||||
if same['count'] > 10:
|
||||
raise AbuseWarning('一段时间内使用相同命令的次数过多')
|
||||
raise AbuseWarning(msg.locale.t("tos.reason.cooldown"))
|
||||
all_ = counter_all.get(msg.target.senderId)
|
||||
if all_ is None or datetime.now().timestamp() - all_['ts'] > 300: # 检查是否滥用(重复使用同一命令)
|
||||
counter_all[msg.target.senderId] = {'count': 1,
|
||||
|
@ -48,7 +48,7 @@ async def msg_counter(msg: MessageSession, command: str):
|
|||
else:
|
||||
all_['count'] += 1
|
||||
if all_['count'] > 20:
|
||||
raise AbuseWarning('一段时间内使用命令的次数过多')
|
||||
raise AbuseWarning(msg.locale.t("tos.reason.abuse"))
|
||||
|
||||
|
||||
async def temp_ban_check(msg: MessageSession):
|
||||
|
@ -58,15 +58,12 @@ async def temp_ban_check(msg: MessageSession):
|
|||
if ban_time < 300:
|
||||
if is_temp_banned['count'] < 2:
|
||||
is_temp_banned['count'] += 1
|
||||
return await msg.finish('提示:\n'
|
||||
'由于你的行为触发了警告,我们已对你进行临时限制。\n'
|
||||
f'距离解封时间还有{str(int(300 - ban_time))}秒。')
|
||||
return await msg.finish(msg.locale.t("tos.tempbanned", ban_time=str(int(300 - ban_time))))
|
||||
elif is_temp_banned['count'] <= 5:
|
||||
is_temp_banned['count'] += 1
|
||||
return await msg.finish('即使是触发了临时限制,继续使用命令还是可能会导致你被再次警告。\n'
|
||||
f'距离解封时间还有{str(int(300 - ban_time))}秒。')
|
||||
return await msg.finish(msg.locale.t("tos.tempbanned.warning", ban_time=str(int(300 - ban_time))))
|
||||
else:
|
||||
raise AbuseWarning('无视临时限制警告')
|
||||
raise AbuseWarning(msg.locale.t("tos.reason.bypass"))
|
||||
|
||||
|
||||
async def parser(msg: MessageSession, require_enable_modules: bool = True, prefix: list = None,
|
||||
|
@ -176,7 +173,12 @@ async def parser(msg: MessageSession, require_enable_modules: bool = True, prefi
|
|||
module: Module = modules[command_first_word]
|
||||
if not module.command_list.set: # 如果没有可用的命令,则展示模块简介
|
||||
if module.desc is not None:
|
||||
desc = msg.locale.t("parser.module.desc", desc=module.desc)
|
||||
desc_ = module.desc
|
||||
if locale_str := re.findall(r'\{(.*)}', desc_):
|
||||
for l in locale_str:
|
||||
desc_ = desc_.replace(f'{{{l}}}', msg.locale.t(l, fallback_failed_prompt=False))
|
||||
desc = msg.locale.t("parser.module.desc", desc=desc_)
|
||||
|
||||
if command_first_word not in msg.enabled_modules:
|
||||
desc += '\n' + msg.locale.t("parser.module.disabled.prompt", module=command_first_word,
|
||||
prefix=msg.prefixes[0])
|
||||
|
@ -240,7 +242,7 @@ async def parser(msg: MessageSession, require_enable_modules: bool = True, prefi
|
|||
raise FinishedException(msg.sent) # if not using msg.finish
|
||||
except InvalidCommandFormatError:
|
||||
await msg.sendMessage(msg.locale.t("parser.command.format.invalid",
|
||||
module=command_first_word))
|
||||
module=command_first_word, prefix=msg.prefixes[0]))
|
||||
"""if msg.options.get('typo_check', True): # 判断是否开启错字检查
|
||||
nmsg, command_first_word, command_split = await typo_check(msg,
|
||||
display_prefix,
|
||||
|
@ -271,7 +273,7 @@ async def parser(msg: MessageSession, require_enable_modules: bool = True, prefi
|
|||
await func.function(msg)
|
||||
raise FinishedException(msg.sent) # if not using msg.finish
|
||||
except ActionFailed:
|
||||
await msg.sendMessage('消息发送失败,可能被风控,请稍后再试。')
|
||||
await msg.sendMessage(msg.locale.t("error.message.limited"))
|
||||
|
||||
except FinishedException as e:
|
||||
time_used = datetime.now() - time_start
|
||||
|
@ -284,6 +286,12 @@ async def parser(msg: MessageSession, require_enable_modules: bool = True, prefi
|
|||
if enable_analytics:
|
||||
BotDBUtil.Analytics(msg).add(msg.trigger_msg, command_first_word, 'normal')
|
||||
|
||||
except AbuseWarning as e:
|
||||
if enable_tos:
|
||||
await warn_target(msg, str(e))
|
||||
temp_ban_counter[msg.target.senderId] = {'count': 1,
|
||||
'ts': datetime.now().timestamp()}
|
||||
|
||||
except NoReportException as e:
|
||||
Logger.error(traceback.format_exc())
|
||||
err_msg = str(e)
|
||||
|
@ -380,18 +388,24 @@ async def parser(msg: MessageSession, require_enable_modules: bool = True, prefi
|
|||
for l in locale_str:
|
||||
err_msg = err_msg.replace(f'{{{l}}}', msg.locale.t(l, fallback_failed_prompt=False))
|
||||
await msg.sendMessage(msg.locale.t("error.prompt.noreport", err_msg=err_msg))
|
||||
|
||||
except AbuseWarning as e:
|
||||
if enable_tos:
|
||||
await warn_target(msg, str(e))
|
||||
temp_ban_counter[msg.target.senderId] = {'count': 1,
|
||||
'ts': datetime.now().timestamp()}
|
||||
|
||||
except Exception as e:
|
||||
Logger.error(traceback.format_exc())
|
||||
await msg.sendMessage(msg.locale.t('error.prompt.report', err_msg=str(e)) +
|
||||
str(Url(Config('bug_report_url'))))
|
||||
finally:
|
||||
ExecutionLockList.remove(msg)
|
||||
|
||||
except ActionFailed:
|
||||
await msg.sendMessage('消息发送失败,可能被风控,请稍后再试。')
|
||||
await msg.sendMessage((msg.locale.t("error.message.limited")))
|
||||
continue
|
||||
return msg
|
||||
except AbuseWarning as e:
|
||||
if enable_tos:
|
||||
await warn_target(msg, str(e))
|
||||
temp_ban_counter[msg.target.senderId] = {'count': 1,
|
||||
'ts': datetime.now().timestamp()}
|
||||
|
||||
except WaitCancelException: # 出现于等待被取消的情况
|
||||
Logger.warn('Waiting task cancelled by user.')
|
||||
|
|
|
@ -34,13 +34,14 @@ def private_ip_check(url: str):
|
|||
f'Attempt of requesting private IP addresses is not allowed, requesting {hostname}.')
|
||||
|
||||
|
||||
async def get_url(url: str, status_code: int = False, headers: dict = None, fmt=None, timeout=20, attempt=3,
|
||||
async def get_url(url: str, status_code: int = False, headers: dict = None, params: dict = None, fmt=None, timeout=20, attempt=3,
|
||||
request_private_ip=False, logging_err_resp=True):
|
||||
"""利用AioHttp获取指定url的内容。
|
||||
|
||||
:param url: 需要获取的url。
|
||||
:param status_code: 指定请求到的状态码,若不符则抛出ValueError。
|
||||
:param headers: 请求时使用的http头。
|
||||
:param params: 请求时使用的参数。
|
||||
:param fmt: 指定返回的格式。
|
||||
:param timeout: 超时时间。
|
||||
:param attempt: 指定请求尝试次数。
|
||||
|
@ -60,7 +61,7 @@ async def get_url(url: str, status_code: int = False, headers: dict = None, fmt=
|
|||
connector=TCPConnector(verify_ssl=False) if debug else None, ) as session:
|
||||
try:
|
||||
async with session.get(url, timeout=aiohttp.ClientTimeout(total=timeout), headers=headers,
|
||||
proxy=proxy) as req:
|
||||
proxy=proxy, params=params) as req:
|
||||
Logger.debug(f'[{req.status}] {url}')
|
||||
if logging_resp:
|
||||
Logger.debug(await req.read())
|
||||
|
|
|
@ -30,6 +30,7 @@ def flatten(d, parent_key='', sep='.'):
|
|||
|
||||
|
||||
def load_locale_file():
|
||||
err_prompt = []
|
||||
locales_path = os.path.abspath('./locales')
|
||||
locales = os.listdir(locales_path)
|
||||
for l in locales:
|
||||
|
@ -41,14 +42,18 @@ def load_locale_file():
|
|||
if os.path.exists(f'{modules_path}/{m}/locales'):
|
||||
locales_m = os.listdir(f'{modules_path}/{m}/locales')
|
||||
for lm in locales_m:
|
||||
with open(f'{modules_path}/{m}/locales/{lm}', 'r', encoding='utf-8') as f:
|
||||
if remove_suffix(lm, '.json') in locale_cache:
|
||||
locale_cache[remove_suffix(lm, '.json')].update(flatten(json.load(f)))
|
||||
else:
|
||||
locale_cache[remove_suffix(lm, '.json')] = flatten(json.load(f))
|
||||
ml = f'{modules_path}/{m}/locales/{lm}'
|
||||
with open(ml, 'r', encoding='utf-8') as f:
|
||||
try:
|
||||
if remove_suffix(lm, '.json') in locale_cache:
|
||||
locale_cache[remove_suffix(lm, '.json')].update(flatten(json.load(f)))
|
||||
else:
|
||||
locale_cache[remove_suffix(lm, '.json')] = flatten(json.load(f))
|
||||
except Exception as e:
|
||||
err_prompt.append(f'Failed to load {ml}: {e}')
|
||||
|
||||
return err_prompt
|
||||
|
||||
load_locale_file()
|
||||
|
||||
|
||||
class LocaleFile(TypedDict):
|
||||
|
|
|
@ -1,8 +1,26 @@
|
|||
from typing import List
|
||||
import traceback
|
||||
import base64
|
||||
from os.path import abspath
|
||||
from typing import List, Union
|
||||
|
||||
import aiohttp
|
||||
|
||||
from config import Config
|
||||
from core.logger import Logger
|
||||
from core.types.message.chain import MessageChain
|
||||
|
||||
from PIL import Image as PImage
|
||||
import ujson as json
|
||||
import filetype as ft
|
||||
|
||||
from core.builtins import Image
|
||||
from core.builtins import Plain, Image, Voice, Embed
|
||||
from core.utils.cache import random_cache_path
|
||||
from core.utils.http import download_to_cache
|
||||
|
||||
from aiofile import async_open
|
||||
|
||||
web_render = Config('web_render')
|
||||
web_render_local = Config('web_render_local')
|
||||
|
||||
|
||||
async def image_split(i: Image) -> List[Image]:
|
||||
|
@ -20,3 +38,75 @@ async def image_split(i: Image) -> List[Image]:
|
|||
i_list.append(Image(i.crop((0, _h, iw, crop_h))))
|
||||
_h = crop_h
|
||||
return i_list
|
||||
|
||||
|
||||
save_source = True
|
||||
|
||||
|
||||
async def msgchain2image(msgchain: Union[List, MessageChain], use_local=True):
|
||||
if not web_render_local:
|
||||
if not web_render:
|
||||
Logger.warn('[Webrender] Webrender is not configured.')
|
||||
return False
|
||||
use_local = False
|
||||
if isinstance(msgchain, List):
|
||||
msgchain = MessageChain(msgchain)
|
||||
lst = []
|
||||
html_template = """<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="botbox"'>
|
||||
${content}
|
||||
</div>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
for m in msgchain.elements:
|
||||
if isinstance(m, Plain):
|
||||
lst.append('<div>' + m.text.replace('\n', '<br>') + '</div>')
|
||||
if isinstance(m, Image):
|
||||
async with async_open(await m.get(), 'rb') as fi:
|
||||
data = await fi.read()
|
||||
try:
|
||||
ftt = ft.match(data)
|
||||
lst.append(f'<img src="data:{ftt.mime};base64,{(base64.encodebytes(data)).decode("utf-8")}" width="720" />')
|
||||
except TypeError:
|
||||
traceback.print_exc()
|
||||
if isinstance(m, Voice):
|
||||
lst.append('<div>[Voice]</div>')
|
||||
if isinstance(m, Embed):
|
||||
lst.append('<div>[Embed]</div>')
|
||||
|
||||
pic = False
|
||||
|
||||
d = {'content': html_template.replace('${content}', '\n'.join(lst)), 'element': '.botbox'}
|
||||
|
||||
html_ = json.dumps(d)
|
||||
|
||||
fname = random_cache_path() + '.html'
|
||||
with open(fname, 'w', encoding='utf-8') as fi:
|
||||
fi.write(d['content'])
|
||||
|
||||
try:
|
||||
pic = await download_to_cache((web_render_local if use_local else web_render) + 'element_screenshot',
|
||||
status_code=200,
|
||||
headers={'Content-Type': 'application/json'},
|
||||
method="POST",
|
||||
post_data=html_,
|
||||
attempt=1,
|
||||
timeout=30,
|
||||
request_private_ip=True
|
||||
)
|
||||
except aiohttp.ClientConnectorError:
|
||||
if use_local:
|
||||
pic = await download_to_cache(web_render, method='POST', headers={
|
||||
'Content-Type': 'application/json',
|
||||
}, post_data=html_, request_private_ip=True)
|
||||
else:
|
||||
return False
|
||||
return pic
|
||||
|
|
|
@ -25,13 +25,24 @@ async def _(session: MessageSession):
|
|||
@test.command('reply')
|
||||
async def _(session: MessageSession):
|
||||
# >>> ~test reply
|
||||
# <<< Send a word
|
||||
# >>> Hello World!
|
||||
# <<< Reply me!
|
||||
# >>> Hello World! >> [Reply me!]
|
||||
# <<< Hello World!
|
||||
s = await session.waitReply('Send a word')
|
||||
await s.sendMessage(s.asDisplay())
|
||||
|
||||
|
||||
@test.command('confirm')
|
||||
async def _(session: MessageSession):
|
||||
# >>> ~test confirm
|
||||
# <<< Are you sure?
|
||||
# >>> Yes
|
||||
# <<< OK!
|
||||
s = await session.waitConfirm('Are you sure?')
|
||||
if s:
|
||||
await s.sendMessage('OK!')
|
||||
|
||||
|
||||
@test.command('image')
|
||||
async def _(session: MessageSession):
|
||||
# >>> ~test image
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
"error.prompt": "An error occurred: ${error_msg}\nReport this issue: ",
|
||||
"error.prompt.report": "An error occurred while executing the command. Please report the following to developers:\n${err_msg}\nReport this issue: ",
|
||||
"error.prompt.noreport": "An error occurred while executing the command:\n${err_msg}\nThis error is not caused by the bot (e.g. the API request went wrong) and thus should not be reported to developers.",
|
||||
"error.message.limited": "Message sending failed, possibly restricted by server. Please try again later.",
|
||||
"error.message.paused": "群消息发送被服务器拦截,已暂停群消息发送,使用 ${prefix}resume 命令恢复推送。",
|
||||
"error.message.chain.invalid": "The bot attempted to send an invalid message chain. Please get in touch with the developers to solve this issue.",
|
||||
"error.message.chain.empty": "The bot attempted to send an empty message chain. Please get in touch with the developers to solve this issue.",
|
||||
"error.message.chain.plain.empty": "The bot attempted to send an empty text message. Please get in touch with the developers to solve this issue.",
|
||||
|
@ -14,17 +16,23 @@
|
|||
"error.request.api.timeout": "API request timeout.",
|
||||
"tos.warning": "Warning:\nYou have violated our Code of Conduct according to our Terms of Service.",
|
||||
"tos.reason": "Reason: ",
|
||||
"tos.reason.cooldown": "一段时间内使用相同命令的次数过多。",
|
||||
"tos.reason.abuse": "一段时间内使用命令的次数过多。",
|
||||
"tos.reason.bypass": "无视临时封禁警告。",
|
||||
"tos.warning.count": "You have received ${current_warns} warnings. Your account will be blacklisted if you receive more than 5 warnings.",
|
||||
"tos.warning.appeal": "If you have any objections, please go to ${issue_url} and create an issue.",
|
||||
"tos.warning.last": "This is your last warning.",
|
||||
"tos.tempbanned": "提示:\n由于你的行为触发了警告,我们已对你进行临时封禁。\n距离解封时间还有 ${ban_time} 秒。",
|
||||
"tos.tempbanned.warning": "提示:\n即使是触发了临时封禁,继续使用命令还是可能会导致你被再次警告。\n距离解封时间还有 ${ban_time} 秒。",
|
||||
"parser.command.running.prompt": "There are currently commands running. Please try again later.",
|
||||
"parser.command.running.prompt2": "The previous command is being executed.",
|
||||
"parser.command.format.invalid": "Syntax Error.\nUse \"~help ${module}\" for help.",
|
||||
"parser.command.format.invalid": "Syntax Error.\nUse \"${prefix}help ${module}\" for help.",
|
||||
"parser.sudo.permission.denied": "You are not a superuser and cannot use the sudo command.",
|
||||
"parser.superuser.permission.denied": "You do not have permission to use this command.",
|
||||
"parser.admin.module.permission.denied": "Commands under the \"${module}\" module can only be used by the admins of the group. Please contact the admins to execute the command.",
|
||||
"parser.admin.submodule.permission.denied": "This command can only be used by the admins of the group. Please contact the admins to execute the command.",
|
||||
"parser.module.disabled.prompt": "\"${module}\" module is not enabled, please send ${prefix}enable ${module} to enable the module.",
|
||||
"error": "An error occurred: ",
|
||||
"example": "Hello world!",
|
||||
"success": "Success.",
|
||||
"yes": "Yes",
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
"error.prompt": "发生错误:${error_msg}\n错误汇报地址:",
|
||||
"error.prompt.report": "执行命令时发生错误,请报告机器人开发者:\n${err_msg}\n错误汇报地址:",
|
||||
"error.prompt.noreport": "执行命令时发生错误:\n${err_msg}\n此问题并非机器人程序错误(API 请求出错等),请勿将此消息报告给机器人开发者。",
|
||||
"error.message.limited": "消息发送失败,可能被风控,请稍后再试。",
|
||||
"error.message.paused": "群消息发送被服务器拦截,已暂停群消息发送,使用 ${prefix}resume 命令恢复推送。",
|
||||
"error.message.chain.invalid": "机器人尝试发送非法消息链,请联系机器人开发者解决问题。",
|
||||
"error.message.chain.empty": "机器人尝试发送空消息链,请联系机器人开发者解决问题。",
|
||||
"error.message.chain.plain.empty": "机器人尝试发送空文本消息,请联系机器人开发者解决问题。",
|
||||
|
@ -14,17 +16,23 @@
|
|||
"error.request.api.timeout": "请求 API 超时。",
|
||||
"tos.warning": "警告:\n根据服务条款,你已违反我们的行为准则。",
|
||||
"tos.reason": "具体原因:",
|
||||
"tos.reason.cooldown": "一段时间内使用相同命令的次数过多。",
|
||||
"tos.reason.abuse": "一段时间内使用命令的次数过多。",
|
||||
"tos.reason.bypass": "无视临时封禁警告。",
|
||||
"tos.warning.count": "这是对你的第 ${current_warns} 次警告。如超过 5 次警告,我们将会把你的账户加入黑名单。",
|
||||
"tos.warning.appeal": "如果你有任何异议,请至 ${issue_url} 发起问题。",
|
||||
"tos.warning.last": "这是对你的最后一次警告。",
|
||||
"tos.tempbanned": "提示:\n由于你的行为触发了警告,我们已对你进行临时封禁。\n距离解封时间还有 ${ban_time} 秒。",
|
||||
"tos.tempbanned.warning": "提示:\n即使是触发了临时封禁,继续使用命令还是可能会导致你被再次警告。\n距离解封时间还有 ${ban_time} 秒。",
|
||||
"parser.command.running.prompt": "当前有命令正在执行,请稍后再试。",
|
||||
"parser.command.running.prompt2": "先前的命令正在执行中。",
|
||||
"parser.command.format.invalid": "语法错误。\n使用 ~help ${module} 查看帮助。",
|
||||
"parser.command.format.invalid": "语法错误。\n使用 ${prefix}help ${module} 查看帮助。",
|
||||
"parser.sudo.permission.denied": "你不是本机器人的超级用户,无法使用 sudo 命令。",
|
||||
"parser.superuser.permission.denied": "你没有使用该命令的权限。",
|
||||
"parser.admin.module.permission.denied": "${module} 模块下的命令仅能被该群组的管理员所使用,请联系管理员执行此命令。",
|
||||
"parser.admin.submodule.permission.denied": "此命令仅能被该群组的管理员所使用,请联系管理员执行此命令。",
|
||||
"parser.module.disabled.prompt": "${module} 模块未启用,请发送 ${prefix}enable ${module} 启用本模块。",
|
||||
"error": "发生错误:",
|
||||
"example": "你好世界!",
|
||||
"success": "成功。",
|
||||
"yes": "是",
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
"error.prompt": "發生錯誤:${error_msg}\n錯誤回報網址:",
|
||||
"error.prompt.report": "執行指令時發生錯誤,請回報機器人開發人員:\n${err_msg}\n錯誤回報網址:",
|
||||
"error.prompt.noreport": "執行指令時發生錯誤:\n${err_msg}\n此問題並非機器人程式錯誤(API 請求錯誤等),請勿將此訊息回報給機器人開發人員。",
|
||||
"error.message.limited": "訊息傳送失敗,可能被風控,請稍後再試。",
|
||||
"error.message.paused": "群消息发送被服务器拦截,已暂停群消息发送,使用 ${prefix}resume 命令恢复推送。",
|
||||
"error.message.chain.invalid": "機器人嘗試傳送無效訊息鏈,請聯絡機器人開發人員解決問題。",
|
||||
"error.message.chain.empty": "機器人嘗試傳送空白訊息鏈,請聯絡機器人開發人員解決問題。",
|
||||
"error.message.chain.plain.empty": "機器人嘗試傳送空白文字訊息,請聯絡機器人開發人員解決問題。",
|
||||
|
@ -14,23 +16,29 @@
|
|||
"error.request.api.timeout": "請求 API 逾時。",
|
||||
"tos.warning": "警告:\n依據使用條款,你已違反我們的行為準則。",
|
||||
"tos.reason": "原因:",
|
||||
"tos.reason.cooldown": "一段时间内使用相同命令的次数过多。",
|
||||
"tos.reason.abuse": "一段时间内使用命令的次数过多。",
|
||||
"tos.reason.bypass": "无视临时封禁警告。",
|
||||
"tos.warning.count": "這是第 ${current_warns} 次警告。如超過 5 次警告,我們將會把你的帳戶加入黑名單。",
|
||||
"tos.warning.appeal": "如果你有任何異義,請至 ${issue_url} 發起問題。",
|
||||
"tos.warning.last": "這是最後警告。",
|
||||
"tos.tempbanned": "提示:\n由于你的行为触发了警告,我们已对你进行临时封禁。\n距离解封时间还有 ${ban_time} 秒。",
|
||||
"tos.tempbanned.warning": "提示:\n即使是触发了临时封禁,继续使用命令还是可能会导致你被再次警告。\n距离解封时间还有 ${ban_time} 秒。",
|
||||
"parser.command.running.prompt": "目前有指令正在執行,請稍後再試。",
|
||||
"parser.command.running.prompt2": "先前的指令正在執行中。",
|
||||
"parser.command.format.invalid": "語法錯誤。\n使用 ~help ${module} 檢視說明。",
|
||||
"parser.command.format.invalid": "語法錯誤。\n使用 ${prefix}help ${module} 檢視說明。",
|
||||
"parser.sudo.permission.denied": "你不是本機器人的超級使用者,無法使用 sudo 指令。",
|
||||
"parser.superuser.permission.denied": "你沒有使用此指令的權限。",
|
||||
"parser.admin.module.permission.denied": "${module} 模組下的指令僅能由該群組的管理員所使用,請聯絡管理員執行此指令。",
|
||||
"parser.admin.submodule.permission.denied": "此指令僅能由該群組的管理員所使用,請聯絡管理員執行此指令。",
|
||||
"parser.module.disabled.prompt": "${module} 模組未啟用,請發送 ${prefix}enable ${module} 啟用此模組。",
|
||||
"parser.module.disabled.prompt": "${module} 模組未啟用,請傳送 ${prefix}enable ${module} 啟用此模組。",
|
||||
"error": "發生錯誤:",
|
||||
"example": "你好世界!",
|
||||
"success": "成功。",
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
"message.wait.confirm.prompt.type1": "(發送「是」或符合確認條件的詞語確認)",
|
||||
"message.wait.confirm.prompt.type2": "(發送符合條件的詞語確認)",
|
||||
"message.wait.confirm.prompt.type1": "(傳送「是」或符合確認條件的詞語確認)",
|
||||
"message.wait.confirm.prompt.type2": "(傳送符合條件的詞語確認)",
|
||||
"message.reply.prompt": "(請使用指定的詞語回覆此訊息)",
|
||||
"core.help.none": "(此模組沒有說明資訊)",
|
||||
"core.help.options": "參數:",
|
||||
|
|
|
@ -30,7 +30,7 @@ class WithErrCode(Exception):
|
|||
'b30 unofficial [<friendcode>] {{arcaea.message.unofficial}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
if not os.path.exists(assets_path):
|
||||
await msg.finish(msg.locale.t("arcaea.message.assets.not_found"))
|
||||
await msg.finish(msg.locale.t("arcaea.message.assets.not_found", prefix=msg.prefixes[0]))
|
||||
query_code = None
|
||||
prefer_uses = msg.options.get('arc_api', None)
|
||||
official = msg.parsed_msg.get('official', False)
|
||||
|
@ -97,7 +97,7 @@ async def _(msg: Bot.MessageSession):
|
|||
traceback.print_exc()
|
||||
await msg.finish(msg.locale.t("arcaea.message.unofficial.fetch.failed"))
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.user.unbound"))
|
||||
await msg.finish(msg.locale.t("arcaea.message.user.unbound", prefix=msg.prefixes[0]))
|
||||
|
||||
|
||||
@arc.command('info [<friendcode>] {{arcaea.info.help}}',
|
||||
|
@ -105,7 +105,7 @@ async def _(msg: Bot.MessageSession):
|
|||
'info unofficial [<friendcode>] {{arcaea.message.unofficial}}', )
|
||||
async def _(msg: Bot.MessageSession):
|
||||
if not os.path.exists(assets_path):
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.assets.not_found"))
|
||||
await msg.sendMessage(msg.locale.t("arcaea.message.assets.not_found", prefix=msg.prefixes[0]))
|
||||
return
|
||||
query_code = None
|
||||
prefer_uses = msg.options.get('arc_api', None)
|
||||
|
@ -152,7 +152,7 @@ async def _(msg: Bot.MessageSession):
|
|||
traceback.print_exc()
|
||||
await msg.finish(msg.locale.t("arcaea.message.unofficial.fetch.failed"))
|
||||
else:
|
||||
await msg.finish(msg.locale.t("arcaea.message.user.unbound"))
|
||||
await msg.finish(msg.locale.t("arcaea.message.user.unbound", prefix=msg.prefixes[0]))
|
||||
|
||||
|
||||
@arc.command('song <songname+prs/pst/byd> {{arcaea.song.help}}')
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
"arcaea.errcode.-20": "File does not exist",
|
||||
"arcaea.errcode.-23": "Internal error occurred",
|
||||
"arcaea.errcode.-233": "Unknown error occurred",
|
||||
"arcaea.message.assets.not_found": "No resource files found! Please place the apk files of Arcaea to the robot's assets directory and rename them to \"arc.apk\", use \"~arcaea\" to initialize resources.",
|
||||
"arcaea.message.assets.not_found": "No resource files found! Please place the apk files of Arcaea to the robot's assets directory and rename them to \"arc.apk\", use \"${prefix}arcaea initialize\" to initialize resources.",
|
||||
"arcaea.message.failed": "Failed to query.",
|
||||
"arcaea.message.failed.errcode": "Failed to query: ",
|
||||
"arcaea.message.failed.fetch": "Failed to fetch.",
|
||||
|
@ -32,7 +32,7 @@
|
|||
"arcaea.message.official.fetch.failed.fallback": "Failed to fetch using the official API. Trying to use unofficial API.",
|
||||
"arcaea.message.unofficial": "Use Unofficial API",
|
||||
"arcaea.message.unofficial.fetch.failed": "Failed to query using the unofficial API.",
|
||||
"arcaea.message.user.unbound": "Unbound user. Please bind user by \"~arcaea bind <friendcode>\".",
|
||||
"arcaea.message.user.unbound": "Unbound user. Please bind user by \"${prefix}arcaea bind <friendcode>\".",
|
||||
"arcaea.message.no_webrender": "No webrender configured, this command cannot be used.",
|
||||
"arcaea.b30.help": "Query the best 30 list of Arcaea user. (Automatically select to use API)",
|
||||
"arcaea.b30.message.success": "Result\nBest 30:${b30} | Recent 10:${r10}\nBest 30 last 5 list: \n${last5list}",
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
"arcaea.errcode.-20": "文件不存在",
|
||||
"arcaea.errcode.-23": "发生了内部错误",
|
||||
"arcaea.errcode.-233": "发生了未知错误",
|
||||
"arcaea.message.assets.not_found": "未找到资源文件!请放置一份 Arcaea 的 apk 文件到机器人的 assets 目录并重命名为 arc.apk 后,使用 ~arcaea initialize 初始化资源。",
|
||||
"arcaea.message.assets.not_found": "未找到资源文件!请放置一份 Arcaea 的 apk 文件到机器人的 assets 目录并重命名为 arc.apk 后,使用 ${prefix}arcaea initialize 初始化资源。",
|
||||
"arcaea.message.failed": "查询失败。",
|
||||
"arcaea.message.failed.errcode": "查询失败:",
|
||||
"arcaea.message.failed.fetch": "获取失败。",
|
||||
|
@ -32,7 +32,7 @@
|
|||
"arcaea.message.official.fetch.failed.fallback": "使用官方 API 获取失败,尝试使用非官方接口。",
|
||||
"arcaea.message.unofficial": "使用非官方 API",
|
||||
"arcaea.message.unofficial.fetch.failed": "使用非官方 API 查询失败!",
|
||||
"arcaea.message.user.unbound": "未绑定用户,请使用 ~arcaea bind <friendcode> 绑定一个用户。",
|
||||
"arcaea.message.user.unbound": "未绑定用户,请使用 ${prefix}arcaea bind <friendcode> 绑定一个用户。",
|
||||
"arcaea.message.no_webrender": "未配置 webrender,无法使用此命令。",
|
||||
"arcaea.b30.help": "查询 Arcaea 用户的 b30 列表。(自动选择使用 API)",
|
||||
"arcaea.b30.message.success": "获取结果\nB30:${b30} | R10:${r10}\nB30 倒 5 列表:\n${last5list}",
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
"arcaea.errcode.-20": "檔案不存在",
|
||||
"arcaea.errcode.-23": "發生了內部錯誤",
|
||||
"arcaea.errcode.-233": "發生了不明錯誤",
|
||||
"arcaea.message.assets.not_found": "找不到資源檔案! 請放置一份 Arcaea 的 apk 檔案到機器人的 assets 目錄並重命名為 arc.apk 後,使用 ~arcaea initialize 初始化資源。",
|
||||
"arcaea.message.assets.not_found": "找不到資源檔案! 請放置一份 Arcaea 的 apk 檔案到機器人的 assets 目錄並重命名為 arc.apk 後,使用 ${prefix}arcaea initialize 初始化資源。",
|
||||
"arcaea.message.failed": "查詢失敗。",
|
||||
"arcaea.message.failed.errcode": "查詢失敗:",
|
||||
"arcaea.message.failed.fetch": "取得失敗。",
|
||||
|
@ -32,7 +32,7 @@
|
|||
"arcaea.message.official.fetch.failed.fallback": "使用官方 API 取得失敗,嘗試使用非官方介面。",
|
||||
"arcaea.message.unofficial": "使用非官方 API",
|
||||
"arcaea.message.unofficial.fetch.failed": "使用非官方 API 查詢失敗!",
|
||||
"arcaea.message.user.unbound": "未綁定使用者,請使用 ~arcaea bind <friendcode> 綁定一個使用者。",
|
||||
"arcaea.message.user.unbound": "未綁定使用者,請使用 ${prefix}arcaea bind <friendcode> 綁定一個使用者。",
|
||||
"arcaea.message.no_webrender": "未配置 webrender,無法使用此指令。",
|
||||
"arcaea.b30.help": "查詢 Arcaea 使用者的 b30 列表。(自動選擇使用 API)",
|
||||
"arcaea.b30.message.success": "取得結果\nB30:${b30} | R10:${r10}\nB30 倒 5 列表:\n${last5list}",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"coin.begin": "You toss ${count} coin(s),",
|
||||
"coin.help": "Toss any number of coins.",
|
||||
"coin.error": "An error occurred: ",
|
||||
"coin.error.amount": "An error occurred: Invalid number of coins: ",
|
||||
"coin.error.max": "An error occurred: You can only toss at most ${max} coins at one time.",
|
||||
"coin.error.nocoin": "An error occurred: You toss no coin, and nothing happened...",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"coin.begin": "你抛了${count} 枚硬币,",
|
||||
"coin.help": "抛n枚硬币",
|
||||
"coin.error": "发生错误:",
|
||||
"coin.error.amount": "发生错误:无效的硬币个数:",
|
||||
"coin.error.max": "发生错误:你最多只能抛 ${max} 个硬币",
|
||||
"coin.error.nocoin": "发生错误:你抛了个空气,什么也没发生...",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"coin.begin": "你拋了 ${count} 枚硬幣,",
|
||||
"coin.help": "拋任意枚硬幣。",
|
||||
"coin.error": "發生錯誤:",
|
||||
"coin.error.amount": "發生錯誤:無效的硬幣數量:",
|
||||
"coin.error.max": "發生錯誤:你最多只能拋 ${max} 枚硬幣。",
|
||||
"coin.error.nocoin": "發生錯誤:你拋了 0 枚硬幣,什麼也沒有發生...",
|
||||
|
@ -22,7 +21,7 @@
|
|||
"coin.mix.tail": "${tail} 枚是反面",
|
||||
"coin.mix.stand": "…還有 ${stand} 枚立起來了!",
|
||||
"coin.mix.end": "。",
|
||||
"coin_regex.help": "啟用後將在發送的聊天內容尋找到以下相符的訊息時執行對應指令:\n",
|
||||
"coin_regex.help": "啟用後將在傳送的聊天內容尋找到以下相符的訊息時執行對應指令:\n",
|
||||
"coin.stand": "…它立起来了!",
|
||||
"coin.stand.all": "它們…\n…全都立起来了?!"
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
"core.alias.help.reset": "重設自訂指令別名。",
|
||||
"core.alias.help.list": "列出自訂指令別名列表。",
|
||||
"core.alias.message.add.invalid_prefix": "新增的別名對應的指令必須以指令前綴開頭,請檢查。",
|
||||
"core.alias.message.add.success": "已添加自訂指令別名:${arg1} -> ${arg2}",
|
||||
"core.alias.message.add.success": "已新增自訂指令別名:${arg1} -> ${arg2}",
|
||||
"core.alias.message.add.already_in": "[${arg1}]別名已存在於自訂別名列表。",
|
||||
"core.alias.message.remove.success": "已移除自訂指令別名:${arg1}",
|
||||
"core.alias.message.remove.not_found": "[${arg1}]別名不存在於自訂別名列表。",
|
||||
|
@ -40,7 +40,7 @@
|
|||
"core.module.message.reload.confirm": "此操作將額外同時重新載入以下模組:\n${modules}\n是否繼續?",
|
||||
"core.module.message.reload.permission.denied": "失敗:你沒有重新載入模組的權限。",
|
||||
"core.module.message.recommends": "建議同時啟用以下模組:\n${msgs}\n是否一同啟用?",
|
||||
"core.module.message.help.support_regex": "此模組支援正規表示式,訊息發送時將會尋找相符的以下內容:",
|
||||
"core.module.message.help.support_regex": "此模組支援正規表示式,訊息傳送時將會尋找相符的以下內容:",
|
||||
"core.module.message.help.regex.detail": "(${msg})",
|
||||
"core.module.message.help.regex.no_information": "無描述",
|
||||
"core.module.message.help.author.type1": "模組作者:",
|
||||
|
@ -115,7 +115,7 @@
|
|||
"core.locale.help": "用於設定機器人使用的語言。",
|
||||
"core.locale.help.locale": "設定機器人使用的語言。",
|
||||
"core.locale.message.invalid": "語言格式錯誤,已支援的語言有:${lang}。",
|
||||
"core.whoami.help": "取得發送指令的帳戶在機器人內部的 ID。",
|
||||
"core.whoami.help": "取得傳送指令的帳戶在機器人內部的 ID。",
|
||||
"core.whoami.message.admin": "(你擁有此對話的管理員權限)",
|
||||
"core.whoami.message.botadmin": "(你擁有此對話的機器人管理員權限)",
|
||||
"core.whoami.message.superuser": "(你擁有此機器人的超級使用者權限)",
|
||||
|
|
|
@ -405,7 +405,7 @@ async def modules_help(msg: Bot.MessageSession):
|
|||
appends = [module_.bind_prefix]
|
||||
doc_ = []
|
||||
help_ = CommandParser(
|
||||
module_, bind_prefix=module_.bind_prefix, command_prefixes=msg.prefixes)
|
||||
module_, bind_prefix=module_.bind_prefix, command_prefixes=msg.prefixes, msg=msg)
|
||||
if module_.desc is not None:
|
||||
doc_.append(module_.desc)
|
||||
if help_.args:
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"github.user.message.not_found": "The given user cannot be found; please check your input.",
|
||||
"github.search.help": "Searching repositories on GitHub.",
|
||||
"github.search.message": "Successfully to search for ${result} results:",
|
||||
"github.search.message.more": "Truncated due to chat limits; ${more_result} more results may not be shown.",
|
||||
"github.search.message.not_found": "The given repository cannot be found; please check your input.",
|
||||
"github.message.error": "An error occurred: The given repository cannot be found; please check your spelling."
|
||||
"github.message.error": "An error occurred: The given repository cannot be found; please check your spelling.",
|
||||
"github.search.message.more_information": "Truncated due to chat limits; ${more_result} more results may not be shown."
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"github.help": "尝试自动识别并区分 repo/user。",
|
||||
"github.repo.help": "获取 GitHub 仓库信息。",
|
||||
"github.repo.message.not_found": "此仓库不存在,请检查输入。",
|
||||
"github.repo.help": "获取 GitHub 存储库信息。",
|
||||
"github.repo.message.not_found": "此存储库不存在,请检查输入。",
|
||||
"github.user.help": "获取 GitHub 用户或组织信息。",
|
||||
"github.user.message.not_found": "查无此人,请检查输入。",
|
||||
"github.search.help": "搜索 GitHub 上的仓库。",
|
||||
"github.search.help": "搜索 GitHub 上的存储库。",
|
||||
"github.search.message": "搜索成功,共 ${result} 条结果:",
|
||||
"github.search.message.more": "另有 ${more_result} 条结果未显示。",
|
||||
"github.search.message.not_found": "找不到仓库,请检查输入。",
|
||||
"github.message.error": "发生错误:找不到仓库,请检查拼写是否正确。"
|
||||
"github.search.message.not_found": "找不到存储库,请检查输入。",
|
||||
"github.message.error": "发生错误:找不到存储库,请检查拼写是否正确。",
|
||||
"github.search.message.more_information": "另有 ${more_result} 条结果未显示。"
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"github.help": "尝试自动识别并区分 repo/user。",
|
||||
"github.repo.help": "获取 GitHub 仓库信息。",
|
||||
"github.repo.message.not_found": "此仓库不存在,请检查输入。",
|
||||
"github.user.help": "获取 GitHub 用户或组织信息。",
|
||||
"github.user.message.not_found": "查无此人,请检查输入。",
|
||||
"github.search.help": "搜索 GitHub 上的仓库。",
|
||||
"github.search.message": "搜索成功,共 ${result} 条结果:",
|
||||
"github.search.message.more": "另有 ${more_result} 条结果未显示。",
|
||||
"github.help": "嘗試自動識別並區分 repo/user。",
|
||||
"github.repo.help": "取得 Github 儲存庫資訊。",
|
||||
"github.repo.message.not_found": "此儲存庫不存在,請檢查輸入。",
|
||||
"github.user.help": "取得 Github 使用者或組織資訊。",
|
||||
"github.user.message.not_found": "找不到使用者,請檢查輸入。",
|
||||
"github.search.help": "搜尋 Github 上的儲存庫。",
|
||||
"github.search.message": "搜尋成功,共 ${result} 條結果:",
|
||||
"github.search.message.not_found": "找不到仓库,请检查输入。",
|
||||
"github.message.error": "发生错误:找不到仓库,请检查拼写是否正确。"
|
||||
"github.message.error": "发生错误:找不到仓库,请检查拼写是否正确。",
|
||||
"github.search.message.more_information": "另有 ${more_result} 條結果未顯示。"
|
||||
}
|
|
@ -21,7 +21,7 @@ async def search(msg: Bot.MessageSession):
|
|||
items_out.append(str(item['full_name'] + ': ' + str(Url(item['html_url']))))
|
||||
except TypeError:
|
||||
continue
|
||||
footnotes = msg.locale.t("github.search.message.more", more_result=result['total_count'] - 5) if item_count_expected == 5 else ''
|
||||
footnotes = msg.locale.t("github.search.message.more_information", more_result=result['total_count'] - 5) if item_count_expected == 5 else ''
|
||||
message = msg.locale.t("github.search.message", result=result['total_count']) + '\n' + '\n'.join(
|
||||
items_out[0:item_count_expected]) + f'\n{footnotes}'
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ mcmod = module(
|
|||
bind_prefix='mcmod',
|
||||
desc='{mcmod.help.desc}',
|
||||
developers=['Dianliang233', 'HornCopper', 'DrLee_lihr'],
|
||||
alias={'moddetails': 'mcmod details'}
|
||||
alias={'moddetails': 'mcmod details'},
|
||||
support_languages=['zh_cn']
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"mcmod.help.details": "通过模组内容的名称获取模组简介及链接,可使用物品/方块/实体的 ID 或准确名称。",
|
||||
"mcmod.help.mod_name": "通过模组名称获取模组简介及链接,可使用无歧义缩写和准确名称。",
|
||||
"mcmod.message.not_found": "未找到结果。",
|
||||
"mcmod.message.not_found": "找不到结果。",
|
||||
"mcmod.help.desc": "从 MC 百科获取 Minecraft 模组信息。"
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"mcmod.help.details": "透過模組內容的名稱取得模組簡介及連結,可使用物品/方塊/實體的 ID 或準確名稱。",
|
||||
"mcmod.help.mod_name": "透過模組名稱獲取模組簡介及連結,可使用無歧義簡稱或準確名稱。",
|
||||
"mcmod.help.mod_name": "透過模組名稱取得模組簡介及連結,可使用無歧義簡稱或準確名稱。",
|
||||
"mcmod.message.not_found": "找不到結果。",
|
||||
"mcmod.help.desc": "從 MC 百科取得 Minecraft 模組訊息。"
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"mcplayer.help": "Get player information about Minecraft: Java Edition from the Mojang API.",
|
||||
"mcplayer.help": "Get player information about Minecraft: Java Edition from Mojang API.",
|
||||
"mcplayer.help.player": "Get player information from player name or UUID.",
|
||||
"mcplayer.message.not_found": "${player}'s information not found."
|
||||
}
|
|
@ -18,7 +18,7 @@ meme = module(
|
|||
async def _(msg: Bot.MessageSession):
|
||||
# res_jiki = await jiki(msg.parsed_msg['<term>'])
|
||||
# R.I.P. jikipedia
|
||||
res_moegirl = await moegirl(msg.parsed_msg['<term>'])
|
||||
res_moegirl = await moegirl(msg.parsed_msg['<term>'], msg.locale.locale)
|
||||
res_nbnhhsh = await nbnhhsh(msg.parsed_msg['<term>'])
|
||||
res_urban = await urban(msg.parsed_msg['<term>'])
|
||||
chk = await check(res_moegirl, res_nbnhhsh, res_urban)
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import re
|
||||
|
||||
from core.builtins import Bot
|
||||
from core.logger import Logger
|
||||
from modules.wiki import query_pages
|
||||
from modules.wiki.utils.wikilib import QueryInfo
|
||||
|
||||
|
||||
async def moegirl(term: str):
|
||||
async def moegirl(term: str, locale: str = 'zh_cn'):
|
||||
result = await query_pages(QueryInfo('https://zh.moegirl.org.cn/api.php', headers={'accept': '*/*',
|
||||
'accept-encoding': 'gzip, deflate',
|
||||
'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6',
|
||||
'content-type': 'application/json',
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'}),
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'},
|
||||
locale=locale),
|
||||
term)
|
||||
msg = ''
|
||||
if result['msg_list']:
|
||||
|
@ -28,7 +30,7 @@ async def moegirl(term: str):
|
|||
'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,en-GB;q=0.6',
|
||||
'content-type': 'application/json',
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'
|
||||
}), redirect)
|
||||
}, locale=locale), redirect)
|
||||
msg += wait['msg_list'][0].text
|
||||
|
||||
return '[萌娘百科] ' + msg
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
import re
|
||||
import urllib.parse
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
import asyncio
|
||||
import traceback
|
||||
|
||||
from core.builtins import Bot
|
||||
from core.component import module
|
||||
from core.utils.http import get_url
|
||||
from config import Config
|
||||
|
||||
mod_dl = module(
|
||||
bind_prefix='mod_dl',
|
||||
desc='下载CurseForge上的Mod。',
|
||||
developers=['HornCopper', 'OasisAkari'],
|
||||
desc='下载 CurseForge 和 Modrinth 上的 Mod。',
|
||||
developers=['HornCopper', 'OasisAkari', 'z0z0r4'],
|
||||
recommend_modules=['mcmod'],
|
||||
alias='moddl')
|
||||
|
||||
x_api_key = Config("curseforge_api_key")
|
||||
|
||||
def cn_chk(string: str):
|
||||
for word in string:
|
||||
|
@ -21,97 +22,153 @@ def cn_chk(string: str):
|
|||
return True
|
||||
return False
|
||||
|
||||
|
||||
source_url = 'https://files.xmdhs.com/curseforge/'
|
||||
|
||||
|
||||
@mod_dl.handle('<mod_name> [<version>] {通过模组名获取模组下载链接,CloudFlare CDN支持。}')
|
||||
@mod_dl.handle('<mod_name> [<version>] {通过模组名获取模组下载链接}')
|
||||
async def main(msg: Bot.MessageSession):
|
||||
mod_name = msg.parsed_msg['<mod_name>']
|
||||
ver = msg.parsed_msg.get('<version>', False)
|
||||
ver = msg.parsed_msg.get('<version>', None)
|
||||
if ver:
|
||||
match_ver = re.match(r'^\d+\.\d+\.\d+$|^\d+\.\d+$|\d+w\d+[abcd]', ver)
|
||||
if match_ver is None:
|
||||
mod_name += ' ' + ver
|
||||
ver = False
|
||||
if cn_chk(mod_name):
|
||||
return {'msg': 'CurseForge暂不支持中文搜索。', 'success': False}
|
||||
full_url = f'{source_url}s?q={urllib.parse.quote(mod_name)}&type=1'
|
||||
try:
|
||||
html = await get_url(full_url, status_code=200)
|
||||
bs = BeautifulSoup(html, 'html.parser')
|
||||
information = bs.body.div.div
|
||||
infos = {}
|
||||
for x in information.find_all('a'):
|
||||
infos[x.find('h3').text] = x.get('href')
|
||||
if len(infos) > 1:
|
||||
reply_text = []
|
||||
i = 0
|
||||
for info in infos:
|
||||
i += 1
|
||||
reply_text.append(f'{i}. {info}')
|
||||
reply = await msg.waitReply('搜索结果如下:\n' + '\n'.join(reply_text) + '\n请回复编号来选择mod。')
|
||||
replied = reply.asDisplay(text_only=True)
|
||||
if replied.isdigit():
|
||||
replied = int(replied)
|
||||
if replied > len(infos):
|
||||
return await msg.finish('编号超出范围。')
|
||||
else:
|
||||
mod_url = infos[list(infos.keys())[replied - 1]]
|
||||
else:
|
||||
return await msg.finish('无效的编号,必须为纯数字。')
|
||||
else:
|
||||
mod_url = infos[list(infos.keys())[0]]
|
||||
html_2 = await get_url(f'{source_url}{mod_url[1:]}', status_code=200)
|
||||
bs_2 = BeautifulSoup(html_2, 'html.parser')
|
||||
information_2 = bs_2.body.div.div
|
||||
infos_2 = {}
|
||||
for x in information_2.find_all('a'):
|
||||
infos_2[x.find('h3').text] = x.get('href')
|
||||
return {'msg': '暂不支持中文搜索。', 'success': False}
|
||||
|
||||
async def search_modrinth(name: str, ver: str):
|
||||
url = f'https://api.modrinth.com/v2/search?query={name}&limit=10'
|
||||
if ver:
|
||||
if ver in infos_2:
|
||||
mod_url_2 = infos_2[ver]
|
||||
else:
|
||||
return await msg.finish('没有找到指定版本的模组。')
|
||||
url += f'&facets=[["versions:{ver}"],["project_type:mod"]]'
|
||||
else:
|
||||
reply_text = []
|
||||
for info2 in infos_2:
|
||||
reply_text.append(f'{info2}')
|
||||
reply2 = await msg.waitReply('此mod拥有如下版本:\n' + '\n'.join(reply_text) + '\n请回复版本号来选择版本。')
|
||||
replied2 = reply2.asDisplay(text_only=True)
|
||||
if replied2 in infos_2:
|
||||
mod_url_2 = infos_2[replied2]
|
||||
ver = replied2
|
||||
else:
|
||||
return await msg.finish('无效的版本号。')
|
||||
url_3 = source_url + mod_url_2[1:]
|
||||
html_3 = await get_url(url_3, status_code=200)
|
||||
bs_3 = BeautifulSoup(html_3, 'html.parser')
|
||||
infos = {'normal': {}, 'fabric': {}, 'forge': {}}
|
||||
information_3 = bs_3.find_all('tr')
|
||||
for x in information_3[1:]:
|
||||
tbs = x.find_all('td')
|
||||
mod = tbs[0].find('a')
|
||||
status = tbs[1].text
|
||||
name = mod.text
|
||||
depends = tbs[3].find_all('a')
|
||||
mod_type = 'normal'
|
||||
if name.lower().find('fabric') != -1:
|
||||
mod_type = 'fabric'
|
||||
elif name.lower().find('forge') != -1:
|
||||
mod_type = 'forge'
|
||||
if status not in infos[mod_type]:
|
||||
infos[mod_type][status] = {'url': mod.get('href'), 'depends': len(depends), 'name': name}
|
||||
send_ = []
|
||||
for x in infos:
|
||||
for y in infos[x]:
|
||||
send_.append((f'{x.title()} ({y}):\n' if x != 'normal' else f'{y}:\n') +
|
||||
f'下载链接:{infos[x][y]["url"]}\n'
|
||||
f'文件名:{infos[x][y]["name"]}\n' +
|
||||
(f'此mod共有{str(infos[x][y]["depends"])}个依赖,请确认是否已经下载:\n{url_3}' if
|
||||
infos[x][y][
|
||||
"depends"] > 0 else ''))
|
||||
await msg.finish('\n'.join(send_))
|
||||
url += f'&facets=[["project_type:mod"]]'
|
||||
resp = await get_url(url, 200, fmt="json", timeout=5, attempt=3)
|
||||
if resp is not None:
|
||||
results = []
|
||||
if len(resp["hits"]) == 0:
|
||||
return None
|
||||
for project in resp['hits']:
|
||||
results.append(("modrinth", project["title"], project["project_id"], project["versions"]))
|
||||
return results
|
||||
|
||||
async def search_curseforge(name: str, ver: str):
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
'x-api-key': x_api_key
|
||||
}
|
||||
url = f'https://api.curseforge.com/v1/mods/search?gameId=432&searchFilter={name}&sortField=2&sortOrder=desc&pageSize=10&classId=6'
|
||||
if ver:
|
||||
url += f'&gameVersion={ver}'
|
||||
results = []
|
||||
try:
|
||||
resp = await get_url(url, 200, fmt="json", timeout=5, attempt=3, headers=headers)
|
||||
if resp is not None:
|
||||
if resp["pagination"]["resultCount"] == 0:
|
||||
return None
|
||||
for mod in resp["data"]:
|
||||
results.append(("curseforge", mod["name"], mod["id"], None))
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
return results
|
||||
|
||||
async def get_modrinth_project_version(project_id: str, ver: str):
|
||||
url = f'https://api.modrinth.com/v2/project/{project_id}/version?game_versions=["{ver}"]&featured=true'
|
||||
resp = (await get_url(url, 200, fmt="json", timeout=5, attempt=3))[0]
|
||||
if resp is not None:
|
||||
return resp
|
||||
|
||||
except ValueError: # 404 ...
|
||||
await msg.finish('未找到该Mod。')
|
||||
async def get_curseforge_mod_version_index(modid: str):
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
'x-api-key': x_api_key
|
||||
}
|
||||
url = f'https://api.curseforge.com/v1/mods/{modid}'
|
||||
resp = await get_url(url, 200, fmt="json", timeout=5, attempt=3, headers=headers)
|
||||
if resp is not None:
|
||||
return resp["data"]['latestFilesIndexes']
|
||||
|
||||
async def get_curseforge_mod_file(modid: str, ver: str):
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
'x-api-key': x_api_key
|
||||
}
|
||||
url = f'https://api.curseforge.com/v1/mods/{modid}/files?gameVersion={ver}'
|
||||
try:
|
||||
resp = await get_url(url, 200, fmt="json", timeout=5, attempt=3, headers=headers)
|
||||
if resp is not None:
|
||||
return resp["data"][0]
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
# 搜索 Mod
|
||||
result = await asyncio.gather(*(search_modrinth(mod_name, ver), search_curseforge(mod_name, ver)))
|
||||
cache_result = []
|
||||
if result[0] is None and result[1] is None:
|
||||
await msg.finish("搜索失败,无结果。")
|
||||
else:
|
||||
# 合并搜索结果
|
||||
reply_text, count = [], 0
|
||||
if result[0] is None:
|
||||
reply_text.append("Modrinth 结果:无")
|
||||
reply_text.append("Modrinth 结果:")
|
||||
for mod in result[0]:
|
||||
count += 1
|
||||
reply_text.append(f"{count}. {mod[1]}")
|
||||
cache_result.append(mod)
|
||||
|
||||
if result[1] is None:
|
||||
reply_text.append("CurseForge 结果:无")
|
||||
else:
|
||||
reply_text.append("CurseForge 结果:")
|
||||
for mod in result[1]:
|
||||
count += 1
|
||||
reply_text.append(f"{count}. {mod[1]}")
|
||||
cache_result.append(mod)
|
||||
|
||||
reply = await msg.waitReply('\n'.join(reply_text) + '\n请回复编号来选择mod。')
|
||||
replied = reply.asDisplay(text_only=True)
|
||||
|
||||
# 查找 Mod
|
||||
if replied.isdigit():
|
||||
replied = int(replied)
|
||||
if replied > len(cache_result):
|
||||
return await msg.finish('编号超出范围。')
|
||||
else:
|
||||
mod_info = cache_result[replied - 1]
|
||||
else:
|
||||
return await msg.finish('无效的编号,必须为纯数字。')
|
||||
|
||||
if mod_info[0] == "modrinth": # modrinth mod
|
||||
if ver is None:
|
||||
reply2 = await msg.waitReply('此mod拥有如下版本:\n' + '\n'.join(mod_info[3]) + '\n请回复版本号来选择版本。')
|
||||
replied2 = reply2.asDisplay(text_only=True)
|
||||
if replied2 in mod_info[3]:
|
||||
version_info = await get_modrinth_project_version(mod_info[2], replied2)
|
||||
if version_info is not None:
|
||||
await msg.finish(f'{" ".join(version_info["loaders"])}\n下载链接:{version_info["files"][0]["url"]}\n文件名:{version_info["files"][0]["filename"]}')
|
||||
elif ver not in mod_info[3]:
|
||||
await msg.finish("未找到指定版本。")
|
||||
elif ver in mod_info[3]:
|
||||
version_info = await get_modrinth_project_version(mod_info[2], ver)
|
||||
if version_info is not None:
|
||||
await msg.finish(f'{" ".join(version_info["loaders"])}\n下载链接:{version_info["files"][0]["url"]}\n文件名:{version_info["files"][0]["filename"]}')
|
||||
else: # curseforge mod
|
||||
version_index = await get_curseforge_mod_version_index(mod_info[2])
|
||||
if version_index is not None:
|
||||
if ver is None:
|
||||
reply_text = []
|
||||
for version in version_index:
|
||||
reply_text.append(version["gameVersion"])
|
||||
reply2 = await msg.waitReply('此mod拥有如下版本:\n' +
|
||||
'\n'.join(reply_text) +
|
||||
'\n请回复版本号来选择版本。')
|
||||
ver = reply2.asDisplay(text_only=True)
|
||||
elif ver not in version_index:
|
||||
await msg.finish("未找到指定版本。")
|
||||
|
||||
if ver in version_index:
|
||||
file_info = await get_curseforge_mod_file(mod_info[2], ver)
|
||||
if file_info is not None:
|
||||
await msg.finish(f'{" ".join(file_info["gameVersions"])} \
|
||||
\n下载链接:{file_info["downloadUrl"]} \
|
||||
\n文件名:{file_info["fileName"]}')
|
||||
else:
|
||||
await msg.finish("未找到指定版本。")
|
||||
|
|
|
@ -26,24 +26,21 @@ async def main(msg: Bot.MessageSession):
|
|||
is_local_ip = True
|
||||
matchserip = re.match(r'(.*?)\.(.*?)\.(.*?)\.(.*?)', server_address)
|
||||
if matchserip:
|
||||
try:
|
||||
if matchserip.group(1) == '192':
|
||||
if matchserip.group(2) == '168':
|
||||
is_local_ip = True
|
||||
if matchserip.group(1) == '172':
|
||||
if 16 <= int(matchserip.group(2)) <= 31:
|
||||
is_local_ip = True
|
||||
if matchserip.group(1) == '10':
|
||||
if 0 <= int(matchserip.group(2)) <= 255:
|
||||
is_local_ip = True
|
||||
if matchserip.group(1) == '127':
|
||||
if matchserip.group(1) == '192':
|
||||
if matchserip.group(2) == '168':
|
||||
is_local_ip = True
|
||||
if matchserip.group(1) == '0':
|
||||
if matchserip.group(2) == '0':
|
||||
if matchserip.group(3) == '0':
|
||||
is_local_ip = True
|
||||
except:
|
||||
traceback.print_exc()
|
||||
if matchserip.group(1) == '172':
|
||||
if 16 <= int(matchserip.group(2)) <= 31:
|
||||
is_local_ip = True
|
||||
if matchserip.group(1) == '10':
|
||||
if 0 <= int(matchserip.group(2)) <= 255:
|
||||
is_local_ip = True
|
||||
if matchserip.group(1) == '127':
|
||||
is_local_ip = True
|
||||
if matchserip.group(1) == '0':
|
||||
if matchserip.group(2) == '0':
|
||||
if matchserip.group(3) == '0':
|
||||
is_local_ip = True
|
||||
if is_local_ip:
|
||||
return await msg.sendMessage(msg.locale.t('server.message.local_ip'))
|
||||
sm = ['j', 'b']
|
||||
|
|
|
@ -40,10 +40,9 @@ async def server(msg, address, raw=False, showplayer=False, mode='j'):
|
|||
elif 'extra' in description:
|
||||
extra = description['extra']
|
||||
text = []
|
||||
qwq = ''
|
||||
for item in extra[:]:
|
||||
text.append(str(item['text']))
|
||||
servers.append(qwq.join(text))
|
||||
servers.append(''.join(text))
|
||||
else:
|
||||
servers.append(str(description))
|
||||
|
||||
|
@ -83,12 +82,12 @@ async def server(msg, address, raw=False, showplayer=False, mode='j'):
|
|||
bemotd = await req.text()
|
||||
bejson = json.loads(bemotd)
|
||||
unpack_data = bejson['data'].split(';')
|
||||
edition = unpack_data[0]
|
||||
motd_1 = unpack_data[1]
|
||||
motd_2 = unpack_data[7]
|
||||
version_name = unpack_data[3]
|
||||
player_count = unpack_data[4]
|
||||
max_players = unpack_data[5]
|
||||
edition = unpack_data[0]
|
||||
version_name = unpack_data[3]
|
||||
motd_2 = unpack_data[7]
|
||||
game_mode = unpack_data[8]
|
||||
bemsg = '[BE]\n' + \
|
||||
motd_1 + ' - ' + motd_2 + \
|
||||
|
|
|
@ -8,6 +8,7 @@ from core.component import module
|
|||
from core.utils.http import get_url
|
||||
from core.utils.i18n import Locale
|
||||
from .teahouse import get_rss as get_teahouse_rss
|
||||
from core.utils.image import msgchain2image
|
||||
|
||||
|
||||
async def get_weekly(with_img=False, zh_tw=False):
|
||||
|
@ -42,12 +43,25 @@ wky = module('weekly', developers=['Dianliang233'], support_languages=['zh_cn',
|
|||
|
||||
@wky.handle('{{weekly.help}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
weekly = await get_weekly(True if msg.target.clientName == 'QQ' else False,
|
||||
weekly = await get_weekly(True if msg.target.clientName in ['QQ', 'TEST'] else False,
|
||||
zh_tw=True if msg.locale.locale == 'zh_tw' else False)
|
||||
await msg.finish(weekly)
|
||||
|
||||
|
||||
@wky.handle('image {{weekly.image.help}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
weekly = await get_weekly(True if msg.target.clientName in ['QQ', 'TEST'] else False,
|
||||
zh_tw=True if msg.locale.locale == 'zh_tw' else False)
|
||||
await msg.finish(Image((await msgchain2image([Plain(msg.locale.t('weekly_rss.prompt'))] + weekly))))
|
||||
|
||||
|
||||
@wky.handle('teahouse {{weekly.teahouse.help}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
weekly = await get_teahouse_rss()
|
||||
await msg.finish(weekly)
|
||||
|
||||
|
||||
@wky.handle('teahouse image {{weekly.teahouse.help}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
weekly = await get_teahouse_rss()
|
||||
await msg.finish(Image(await msgchain2image([Plain(weekly)])))
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"weekly.help": "Get the weekly page of Chinese Minecraft Wiki.",
|
||||
"weekly.image.help": "获取中文 Minecraft Wiki 的每周页面(图片版)。",
|
||||
"weekly.message": "Weekly page:\n\n${text}",
|
||||
"weekly.message.link": "\nImage: ${img}\n\nArticle Link: ${article}\nWeekly Pages: ${link}",
|
||||
"weekly.message.expired": "An error occurred: The weekly page has expired. Please contact Chinese Minecraft Wiki to update.",
|
||||
"weekly.teahouse.help": "Get Teahouse Weekly."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"weekly.help": "获取中文 Minecraft Wiki 的每周页面。",
|
||||
"weekly.image.help": "获取中文 Minecraft Wiki 的每周页面(图片版)。",
|
||||
"weekly.message": "本周页面:\n\n${text}",
|
||||
"weekly.message.link": "\n图片:${img}\n\n页面链接:${article}\n每周页面:${link}",
|
||||
"weekly.message.expired": "发生错误:本周页面已过期,请联系中文 Minecraft Wiki 更新。",
|
||||
"weekly.teahouse.help": "获取茶馆周报。"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"weekly.help": "取得中文 Minecraft Wiki 的每週頁面。",
|
||||
"weekly.image.help": "取得中文 Minecraft Wiki 的每週頁面(圖片版)。",
|
||||
"weekly.message": "本週頁面:\n\n${text}",
|
||||
"weekly.message.link": "\n圖片:${img}\n\n頁面連結:${article}\n每週頁面:${link}",
|
||||
"weekly.message.expired": "發生錯誤:本週頁面已過期,請聯絡中文 Minecraft Wiki 更新。",
|
||||
"weekly.teahouse.help": "取得茶館週報。"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
from core.builtins import Bot
|
||||
from core.builtins import Bot, Image, Plain
|
||||
from core.component import module
|
||||
from core.logger import Logger
|
||||
from core.scheduler import CronTrigger
|
||||
from core.utils.image import msgchain2image
|
||||
from core.utils.i18n import Locale
|
||||
from modules.weekly import get_weekly
|
||||
from modules.weekly.teahouse import get_rss as get_teahouse_rss
|
||||
|
||||
|
@ -16,6 +18,11 @@ async def weekly_rss():
|
|||
|
||||
weekly_cn = await get_weekly(True if Bot.FetchTarget.name == 'QQ' else False)
|
||||
weekly_tw = await get_weekly(True if Bot.FetchTarget.name == 'QQ' else False, zh_tw=True)
|
||||
if Bot.FetchTarget.name == 'QQ':
|
||||
weekly_cn = [Plain(Locale('zh_cn').t('weekly_rss.prompt'))] + weekly_cn
|
||||
weekly_tw = [Plain(Locale('zh_tw').t('weekly_rss.prompt'))] + weekly_tw
|
||||
weekly_cn = Image(await msgchain2image(weekly_cn))
|
||||
weekly_tw = Image(await msgchain2image(weekly_tw))
|
||||
post_msg = {'zh_cn': weekly_cn, 'zh_tw': weekly_tw, 'fallback': weekly_cn}
|
||||
await Bot.FetchTarget.post_message('weekly_rss', post_msg, i18n=True)
|
||||
Logger.info('Weekly checked.')
|
||||
|
@ -32,5 +39,12 @@ async def weekly_rss():
|
|||
Logger.info('Checking teahouse weekly...')
|
||||
|
||||
weekly = await get_teahouse_rss()
|
||||
await Bot.FetchTarget.post_message('teahouse_weekly_rss', weekly)
|
||||
if Bot.FetchTarget.name == 'QQ':
|
||||
weekly_cn = [Plain(Locale('zh_cn').t('weekly_rss.teahouse.prompt'))] + weekly
|
||||
weekly_tw = [Plain(Locale('zh_tw').t('weekly_rss.teahouse.prompt'))] + weekly
|
||||
weekly_en = [Plain(Locale('en_us').t('weekly_rss.teahouse.prompt'))] + weekly
|
||||
post_msg = {'zh_cn': weekly_cn, 'zh_tw': weekly_tw, 'en_us': weekly_en, 'fallback': weekly_cn}
|
||||
await Bot.FetchTarget.post_message('teahouse_weekly_rss', post_msg, i18n=True)
|
||||
else:
|
||||
await Bot.FetchTarget.post_message('teahouse_weekly_rss', weekly)
|
||||
Logger.info('Teahouse Weekly checked.')
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"weekly_rss.help.desc": "When enabled, you will subscribe to the weekly page of Chinese Minecraft Wiki. (updated every Monday at 8:30)",
|
||||
"teahouse_weekly_rss.help.desc": "When enabled, you will subscribe to the weekly page of Teahouse Weekly. (Updated every Monday at 8:30)"
|
||||
}
|
||||
"teahouse_weekly_rss.help.desc": "When enabled, you will subscribe to the weekly page of Teahouse Weekly. (Updated every Monday at 8:30)",
|
||||
"weekly_rss.prompt": "如需获取每周页面的文字版本及链接,请使用 ~weekly 命令。"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
{
|
||||
"weekly_rss.help.desc": "开启后将订阅中文 Minecraft Wiki 的每周页面。(每周一 8:30 更新)",
|
||||
"teahouse_weekly_rss.help.desc": "开启后将订阅茶馆周报的每周页面。(每周一 8:30 更新)"
|
||||
}
|
||||
"teahouse_weekly_rss.help.desc": "开启后将订阅茶馆周报的每周页面。(每周一 8:30 更新)",
|
||||
"weekly_rss.prompt": "如需获取每周页面的文字版本及链接,请使用 ~weekly 命令。",
|
||||
"weekly_rss.teahouse.prompt": "如需获取每周页面的文字版本及链接,请使用 ~weekly teahouse 命令。"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"weekly_rss.help.desc": "啟用後將訂閱中文 Minecraft Wiki 的每週頁面。(每週一 8:30 更新)",
|
||||
"teahouse_weekly_rss.help.desc": "啟用後將訂閱茶館週報的每週頁面。(每週一 8:30 更新)"
|
||||
}
|
||||
"teahouse_weekly_rss.help.desc": "啟用後將訂閱茶館週報的每週頁面。(每週一 8:30 更新)",
|
||||
"weekly_rss.prompt": "如需获取每周页面的文字版本及链接,请使用 ~weekly 命令。"
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"whois.message.type": "類型:",
|
||||
"whois.message.postal_code": "郵編:",
|
||||
"whois.message.location": "位置:",
|
||||
"whois.message.organization": "機構:",
|
||||
"whois.message.organization": "組織:",
|
||||
"whois.message.asn": "ASN:",
|
||||
"whois.message.utc": "時區:",
|
||||
"whois.message.reverse": "反向解析:",
|
||||
|
|
|
@ -18,17 +18,17 @@ async def _(msg: Bot.MessageSession):
|
|||
api = check.value.api
|
||||
if req.get('trust', False):
|
||||
res = Audit(api).add_to_AllowList(op)
|
||||
list_name = '白'
|
||||
list_name = msg.locale.t('wiki.wiki_audit.list_name.allowlist')
|
||||
else:
|
||||
res = Audit(api).add_to_BlockList(op)
|
||||
list_name = '黑'
|
||||
list_name = msg.locale.t('wiki.wiki_audit.list_name.blocklist')
|
||||
if not res:
|
||||
await msg.finish(f'失败,此wiki已经存在于{list_name}名单中:' + api)
|
||||
await msg.finish(msg.locale.t('wiki.wiki_audit.add.message.failed', list_name=list_name) + api)
|
||||
else:
|
||||
await msg.finish(f'成功加入{list_name}名单:' + api)
|
||||
await msg.finish(msg.locale.t('wiki.wiki_audit.add.message.success', list_name=list_name) + api)
|
||||
else:
|
||||
result = '错误:无法添加此Wiki。' + \
|
||||
('\n详细信息:' + check.message if check.message != '' else '')
|
||||
result = msg.locale.t('wiki.message.error.add') + \
|
||||
('\n' + msg.locale.t('wiki.message.error.info') + check.message if check.message != '' else '')
|
||||
await msg.finish(result)
|
||||
|
||||
|
||||
|
@ -42,18 +42,18 @@ async def _(msg: Bot.MessageSession):
|
|||
if req.get('distrust', False):
|
||||
res = Audit(api).remove_from_AllowList()
|
||||
if res is None:
|
||||
await msg.finish(f'失败,此wiki不存在于白名单中,此wiki的白名单可能来自其它同一域名的Wiki:' + api)
|
||||
list_name = '白'
|
||||
await msg.finish(msg.locale.t('wiki.wiki_audit.remove.message.failed.other') + api)
|
||||
list_name = msg.locale.t('wiki.wiki_audit.list_name.allowlist')
|
||||
else:
|
||||
res = Audit(api).remove_from_BlockList()
|
||||
list_name = '黑'
|
||||
list_name = msg.locale.t('wiki.wiki_audit.list_name.blocklist')
|
||||
if not res:
|
||||
await msg.finish(f'失败,此wiki不存在于{list_name}名单中:' + api)
|
||||
await msg.finish(msg.locale.t('wiki.wiki_audit.remove.message.failed', list_name=list_name) + api)
|
||||
else:
|
||||
await msg.finish(f'成功从{list_name}名单删除:' + api)
|
||||
await msg.finish(msg.locale.t('wiki.wiki_audit.remove.message.success', list_name=list_name) + api)
|
||||
else:
|
||||
result = '错误:无法查询此Wiki。' + \
|
||||
('\n详细信息:' + check.message if check.message != '' else '')
|
||||
result = msg.locale.t('wiki.message.error.query') + \
|
||||
('\n' + msg.locale.t('wiki.message.error.info') + check.message if check.message != '' else '')
|
||||
await msg.finish(result)
|
||||
|
||||
|
||||
|
@ -69,17 +69,17 @@ async def _(msg: Bot.MessageSession):
|
|||
block = audit.inBlockList
|
||||
msg_list = []
|
||||
if allow:
|
||||
msg_list.append(api + '已存在于白名单。')
|
||||
msg_list.append(api + msg.locale.t('wiki.wiki_audit.query.message.allowlist'))
|
||||
if block:
|
||||
msg_list.append(api + '已存在于黑名单。')
|
||||
msg_list.append(api + msg.locale.t('wiki.wiki_audit.query.message.blocklist'))
|
||||
if msg_list:
|
||||
msg_list.append('优先级:白名单 > 黑名单')
|
||||
msg_list.append(msg.locale.t('wiki.wiki_audit.query.message.conflict'))
|
||||
await msg.finish('\n'.join(msg_list))
|
||||
else:
|
||||
await msg.finish(api + '不存在于任何名单。')
|
||||
await msg.finish(api + msg.locale.t('wiki.wiki_audit.query.message.none'))
|
||||
else:
|
||||
result = '错误:无法查询此Wiki。' + \
|
||||
('\n详细信息:' + check.message if check.message != '' else '')
|
||||
result = msg.locale.t('wiki.message.error.query') + \
|
||||
('\n' + msg.locale.t('wiki.message.error.info') + check.message if check.message != '' else '')
|
||||
await msg.finish(result)
|
||||
|
||||
|
||||
|
@ -93,29 +93,33 @@ async def _(msg: Bot.MessageSession):
|
|||
allow_columns = [[x[0], x[1]] for x in allow_list]
|
||||
if allow_columns:
|
||||
allow_table = ImageTable(data=allow_columns, headers=[
|
||||
'APILink', 'Operator'])
|
||||
msg.locale.t('wiki.wiki_audit.list.message.table.header.apilink'),
|
||||
msg.locale.t('wiki.wiki_audit.list.message.table.header.operator')
|
||||
])
|
||||
if allow_table:
|
||||
allow_image = await image_table_render(allow_table)
|
||||
if allow_image:
|
||||
send_msgs.append(Plain('现有白名单:'))
|
||||
send_msgs.append(Plain(msg.locale.t('wiki.wiki_audit.list.message.allowlist')))
|
||||
send_msgs.append(Image(allow_image))
|
||||
block_columns = [[x[0], x[1]] for x in block_list]
|
||||
if block_columns:
|
||||
block_table = ImageTable(data=block_columns, headers=[
|
||||
'APILink', 'Operator'])
|
||||
msg.locale.t('wiki.wiki_audit.list.message.table.header.apilink'),
|
||||
msg.locale.t('wiki.wiki_audit.list.message.table.header.operator')
|
||||
])
|
||||
if block_table:
|
||||
block_image = await image_table_render(block_table)
|
||||
if block_image:
|
||||
send_msgs.append(Plain('现有黑名单:'))
|
||||
send_msgs.append(Plain(msg.locale.t('wiki.wiki_audit.list.message.blocklist')))
|
||||
send_msgs.append(Image(block_image))
|
||||
if send_msgs:
|
||||
await msg.finish(send_msgs)
|
||||
legacy = False
|
||||
if legacy:
|
||||
wikis = ['现有白名单:']
|
||||
wikis = [msg.locale.t('wiki.wiki_audit.list.message.allowlist')]
|
||||
for al in allow_list:
|
||||
wikis.append(f'{al[0]}(by {al[1]})')
|
||||
wikis.append('现有黑名单:')
|
||||
wikis.append(msg.locale.t('wiki.wiki_audit.list.message.blocklist'))
|
||||
for bl in block_list:
|
||||
wikis.append(f'{bl[0]}(by {bl[1]})')
|
||||
await msg.finish('\n'.join(wikis))
|
||||
|
|
|
@ -14,8 +14,9 @@ from modules.wiki.utils.screenshot_image import generate_screenshot_v1, generate
|
|||
from modules.wiki.utils.wikilib import WikiLib
|
||||
from .wiki import query_pages, generate_screenshot_v2_blocklist
|
||||
|
||||
|
||||
wiki_inline = module('wiki_inline',
|
||||
desc='开启后将自动解析消息中带有的[[]]或{{}}字符串并自动查询Wiki,如[[海晶石]]',
|
||||
desc='{wiki.wiki_inline.help.desc}',
|
||||
alias='wiki_regex', developers=['OasisAkari'])
|
||||
|
||||
|
||||
|
@ -97,12 +98,12 @@ async def _(msg: Bot.MessageSession):
|
|||
if guess_type is not None:
|
||||
if guess_type.extension in ["png", "gif", "jpg", "jpeg", "webp", "bmp", "ico"]:
|
||||
if msg.Feature.image:
|
||||
await msg.sendMessage([Plain(f'此页面包括以下文件:{get_page.file}'), Image(dl)],
|
||||
await msg.sendMessage([Plain(msg.locale.t('wiki.wiki_inline.message.flies', file=get_page.file)), Image(dl)],
|
||||
quote=False)
|
||||
img_send = True
|
||||
elif guess_type.extension in ["oga", "ogg", "flac", "mp3", "wav"]:
|
||||
if msg.Feature.voice:
|
||||
await msg.sendMessage([Plain(f'此页面包括以下文件:{get_page.file}'), Voice(dl)],
|
||||
await msg.sendMessage([Plain(msg.locale.t('wiki.wiki_inline.message.flies', file=get_page.file)), Voice(dl)],
|
||||
quote=False)
|
||||
if msg.Feature.image:
|
||||
if get_page.status and wiki_.wiki_info.in_allowlist:
|
||||
|
|
77
modules/wiki/locales/en_us.json
Normal file
77
modules/wiki/locales/en_us.json
Normal file
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"wiki.wiki_audit.list_name.blocklist": "黑名单",
|
||||
"wiki.wiki_audit.list_name.allowlist": "白名单",
|
||||
"wiki.wiki_audit.add.message.success": "成功加入${list_name}:",
|
||||
"wiki.wiki_audit.add.message.failed": "失败,此 Wiki 已存在于${list_name}中:",
|
||||
"wiki.wiki_audit.remove.message.success": "成功从${list_name}删除:",
|
||||
"wiki.wiki_audit.remove.message.failed": "失败,此 Wiki 不存在于${list_name}中:",
|
||||
"wiki.wiki_audit.remove.message.failed.other": "失败,此 Wiki 不存在于白名单中,此 Wiki 的白名单可能来自其他同一域名的 Wiki:",
|
||||
"wiki.wiki_audit.query.message.allowlist": "已存在于白名单。",
|
||||
"wiki.wiki_audit.query.message.blocklist": "已存在于黑名单。",
|
||||
"wiki.wiki_audit.query.message.conflict": "优先级:白名单 > 黑名单",
|
||||
"wiki.wiki_audit.query.message.none": "不存在于任何名单。",
|
||||
"wiki.wiki_audit.list.message.allowlist": "现有白名单:",
|
||||
"wiki.wiki_audit.list.message.blocklist": "现有黑名单:",
|
||||
"wiki.wiki_audit.list.message.table.header.apilink": "API 链接",
|
||||
"wiki.wiki_audit.list.message.table.header.operator": "操作者",
|
||||
"wiki.wiki_inline.help.desc": "开启后将自动解析消息中带有 [[ ]] 或 {{ }} 的字符串并自动查询 Wiki,例如 [[海晶石]]。",
|
||||
"wiki.wiki_inline.message.flies": "此页面包括以下文件:${file}",
|
||||
"wiki.search.help": "搜索一个 Wiki 页面。",
|
||||
"wiki.search.message": "搜索到以下结果:",
|
||||
"wiki.search.message.prompt": "回复编号以查询对应的页面。",
|
||||
"wiki.set.help": "设置起始查询 Wiki。",
|
||||
"wiki.set.message.success": "成功设置起始 Wiki:${name}",
|
||||
"wiki.set.message.default": "没有设置起始 Wiki,已默认为中文 Minecraft Wiki,发送 ${prefix}wiki set <域名> 设置自定义起始 Wiki。\n示例:${prefix}wiki set https://minecraft.fandom.com/zh/wiki/",
|
||||
"wiki.iw.message.none": "当前没有设置任何 Interwiki,可使用 ${prefix}wiki iw add <interwiki> <api_endpoint_link> 添加。",
|
||||
"wiki.iw.set.help": "添加自定义 Interwiki。",
|
||||
"wiki.iw.set.message.success": "成功:已添加自定义 Interwiki:\n${iw} -> ${name}",
|
||||
"wiki.iw.remove.help": "删除自定义 Interwiki。",
|
||||
"wiki.iw.remove.message.success": "成功:已删除自定义 Interwiki:${iw}",
|
||||
"wiki.iw.list.help": "展示当前设置的 Interwiki。",
|
||||
"wiki.iw.list.help.legacy": "展示当前设置的 Interwiki。(旧版)",
|
||||
"wiki.iw.list.message": "使用 ${prefix}wiki iw get <Interwiki> 可以获取 Interwiki 对应的链接。",
|
||||
"wiki.iw.list.message.legacy": "当前设置了以下 Interwiki:",
|
||||
"wiki.iw.list.message.prompt": "此处展示的是为机器人设置的自定义 Interwiki,如需查看起始 Wiki 的 Interwiki,请见:${url}",
|
||||
"wiki.iw.get.help": "获取设置的 Interwiki 对应的 API 地址。",
|
||||
"wiki.iw.get.message.not_found": "未找到 Interwiki:${iw}",
|
||||
"wiki.headers.list.help": "展示当前设置的请求标头。",
|
||||
"wiki.headers.list.message": "当前设置了以下请求标头:\n${headers}\n如需自定义,请使用 ${prefix}wiki headers set <headers>。\n示例:\n${prefix}wiki headers set {{\"accept-language\": \"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\"}}",
|
||||
"wiki.headers.set.help": "添加自定义请求标头。",
|
||||
"wiki.headers.remove.help": "删除自定义请求标头。",
|
||||
"wiki.headers.reset.help": "重置自定义请求标头。",
|
||||
"wiki.headers.set.message.success": "成功:已更新请求时所使用的请求标头:${headers}",
|
||||
"wiki.headers.reset.message.success": "成功:已重置请求时所使用的请求标头。",
|
||||
"wiki.prefix.set.help": "设置自定义前缀。",
|
||||
"wiki.prefix.reset.help": "重置自定义前缀。",
|
||||
"wiki.prefix.set.message.success": "成功:已更新请求时所使用的前缀:${wiki_prefix}",
|
||||
"wiki.fandom.enable.help": "开启 Fandom 全局 Interwiki 查询。",
|
||||
"wiki.fandom.disable.help": "关闭 Fandom 全局 Interwiki 查询。",
|
||||
"wiki.fandom.enable.message": "已开启 Fandom 全局 Interwiki 查询。",
|
||||
"wiki.fandom.disable.message": "已关闭 Fandom 全局 Interwiki 查询。",
|
||||
"wiki.redlink.enable.help": "开启页面不存在时返回编辑链接。",
|
||||
"wiki.redlink.disable.help": "关闭页面不存在时返回编辑链接。",
|
||||
"wiki.redlink.enable.message": "已开启页面不存在时返回编辑链接。",
|
||||
"wiki.redlink.disable.message": "已关闭页面不存在时返回编辑链接。",
|
||||
"wiki.redlink.message.not_found": "(页面不存在)",
|
||||
"wiki.redlink.message.not_found.uneditable": "[${title}] 页面不存在。",
|
||||
"wiki.prefix.reset.message.success": "成功:已重置请求时所使用的前缀。",
|
||||
"wiki.help": "查询一个 Wiki 页面,若查询“随机页面”则随机一个页面。",
|
||||
"wiki.help.l": "查找本页面的对应语言版本,若无结果则返回当前语言。",
|
||||
"wiki.id.help": "根据页面 ID 查询一个 Wiki 页面。",
|
||||
"wiki.id.message.error": "发生错误:页面 ID 必须为数字。",
|
||||
"wiki.id.message.not_found": "找不到页面 ID 为 ${id} 的页面。",
|
||||
"wiki.message.redirect": "(重定向[${title}] -> [${redirected_title}])",
|
||||
"wiki.message.redirect.autofix": "(已指定 [${title}] 更正为 [${redirected_title}]。)",
|
||||
"wiki.message.redirect.template_to_page": "([${title}] 不存在,已自动重定向至 [${redirected_title}])",
|
||||
"wiki.message.invalid_namespace": "此 Wiki 上没有名为 ${namespace} 的命名空间,请检查拼写后重试。",
|
||||
"wiki.message.not_found": "找不到 [${title}]。",
|
||||
"wiki.message.magic_word": "机器人暂不支持魔术字。",
|
||||
"tos.reason.too_many_redirects": "使机器人重定向页面的次数过多。",
|
||||
"tos.reason.wiki_abuse": "一次性查询的页面超过 15 个。",
|
||||
"wiki.message.untrust": "注意:此 Wiki 当前没有加入机器人的白名单列表中,查询此 Wiki 时将会对返回内容进行限制。\n若需取消限制,请在此处申请白名单:\n",
|
||||
"wiki.message.error.add": "发生错误:无法添加此 Wiki。",
|
||||
"wiki.message.error.blocked": "发生错误:${name} 处于黑名单中。",
|
||||
"wiki.message.error.query": "发生错误:无法查询此 Wiki。",
|
||||
"wiki.message.error.set": "发生错误:无法设置此 Wiki。",
|
||||
"wiki.message.error.info": "详细信息:"
|
||||
}
|
77
modules/wiki/locales/zh_cn.json
Normal file
77
modules/wiki/locales/zh_cn.json
Normal file
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"wiki.wiki_audit.list_name.blocklist": "黑名单",
|
||||
"wiki.wiki_audit.list_name.allowlist": "白名单",
|
||||
"wiki.wiki_audit.add.message.success": "成功加入${list_name}:",
|
||||
"wiki.wiki_audit.add.message.failed": "失败,此 Wiki 已存在于${list_name}中:",
|
||||
"wiki.wiki_audit.remove.message.success": "成功从${list_name}删除:",
|
||||
"wiki.wiki_audit.remove.message.failed": "失败,此 Wiki 不存在于${list_name}中:",
|
||||
"wiki.wiki_audit.remove.message.failed.other": "失败,此 Wiki 不存在于白名单中,此 Wiki 的白名单可能来自其他同一域名的 Wiki:",
|
||||
"wiki.wiki_audit.query.message.allowlist": "已存在于白名单。",
|
||||
"wiki.wiki_audit.query.message.blocklist": "已存在于黑名单。",
|
||||
"wiki.wiki_audit.query.message.conflict": "优先级:白名单 > 黑名单",
|
||||
"wiki.wiki_audit.query.message.none": "不存在于任何名单。",
|
||||
"wiki.wiki_audit.list.message.allowlist": "现有白名单:",
|
||||
"wiki.wiki_audit.list.message.blocklist": "现有黑名单:",
|
||||
"wiki.wiki_audit.list.message.table.header.apilink": "API 链接",
|
||||
"wiki.wiki_audit.list.message.table.header.operator": "操作者",
|
||||
"wiki.wiki_inline.help.desc": "开启后将自动解析消息中带有 [[ ]] 或 {{ }} 的字符串并自动查询 Wiki,例如 [[海晶石]]。",
|
||||
"wiki.wiki_inline.message.flies": "此页面包括以下文件:${file}",
|
||||
"wiki.search.help": "搜索一个 Wiki 页面。",
|
||||
"wiki.search.message": "搜索到以下结果:",
|
||||
"wiki.search.message.prompt": "回复编号以查询对应的页面。",
|
||||
"wiki.set.help": "设置起始查询 Wiki。",
|
||||
"wiki.set.message.success": "成功设置起始 Wiki:${name}",
|
||||
"wiki.set.message.default": "没有设置起始 Wiki,已默认为中文 Minecraft Wiki,发送 ${prefix}wiki set <域名> 设置自定义起始 Wiki。\n示例:${prefix}wiki set https://minecraft.fandom.com/zh/wiki/",
|
||||
"wiki.iw.message.none": "当前没有设置任何 Interwiki,可使用 ${prefix}wiki iw add <interwiki> <api_endpoint_link> 添加。",
|
||||
"wiki.iw.set.help": "添加自定义 Interwiki。",
|
||||
"wiki.iw.set.message.success": "成功:已添加自定义 Interwiki:\n${iw} -> ${name}",
|
||||
"wiki.iw.remove.help": "删除自定义 Interwiki。",
|
||||
"wiki.iw.remove.message.success": "成功:已删除自定义 Interwiki:${iw}",
|
||||
"wiki.iw.list.help": "展示当前设置的 Interwiki。",
|
||||
"wiki.iw.list.help.legacy": "展示当前设置的 Interwiki。(旧版)",
|
||||
"wiki.iw.list.message": "使用 ${prefix}wiki iw get <Interwiki> 可以获取 Interwiki 对应的链接。",
|
||||
"wiki.iw.list.message.legacy": "当前设置了以下 Interwiki:",
|
||||
"wiki.iw.list.message.prompt": "此处展示的是为机器人设置的自定义 Interwiki,如需查看起始 Wiki 的 Interwiki,请见:${url}",
|
||||
"wiki.iw.get.help": "获取设置的 Interwiki 对应的 API 地址。",
|
||||
"wiki.iw.get.message.not_found": "未找到 Interwiki:${iw}",
|
||||
"wiki.headers.list.help": "展示当前设置的请求标头。",
|
||||
"wiki.headers.list.message": "当前设置了以下请求标头:\n${headers}\n如需自定义,请使用 ${prefix}wiki headers set <headers>。\n示例:\n${prefix}wiki headers set {{\"accept-language\": \"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\"}}",
|
||||
"wiki.headers.set.help": "添加自定义请求标头。",
|
||||
"wiki.headers.remove.help": "删除自定义请求标头。",
|
||||
"wiki.headers.reset.help": "重置自定义请求标头。",
|
||||
"wiki.headers.set.message.success": "成功:已更新请求时所使用的请求标头:${headers}",
|
||||
"wiki.headers.reset.message.success": "成功:已重置请求时所使用的请求标头。",
|
||||
"wiki.prefix.set.help": "设置自定义前缀。",
|
||||
"wiki.prefix.reset.help": "重置自定义前缀。",
|
||||
"wiki.prefix.set.message.success": "成功:已更新请求时所使用的前缀:${wiki_prefix}",
|
||||
"wiki.fandom.enable.help": "开启 Fandom 全局 Interwiki 查询。",
|
||||
"wiki.fandom.disable.help": "关闭 Fandom 全局 Interwiki 查询。",
|
||||
"wiki.fandom.enable.message": "已开启 Fandom 全局 Interwiki 查询。",
|
||||
"wiki.fandom.disable.message": "已关闭 Fandom 全局 Interwiki 查询。",
|
||||
"wiki.redlink.enable.help": "开启页面不存在时返回编辑链接。",
|
||||
"wiki.redlink.disable.help": "关闭页面不存在时返回编辑链接。",
|
||||
"wiki.redlink.enable.message": "已开启页面不存在时返回编辑链接。",
|
||||
"wiki.redlink.disable.message": "已关闭页面不存在时返回编辑链接。",
|
||||
"wiki.redlink.message.not_found": "(页面不存在)",
|
||||
"wiki.redlink.message.not_found.uneditable": "[${title}] 页面不存在。",
|
||||
"wiki.prefix.reset.message.success": "成功:已重置请求时所使用的前缀。",
|
||||
"wiki.help": "查询一个 Wiki 页面,若查询“随机页面”则随机一个页面。",
|
||||
"wiki.help.l": "查找本页面的对应语言版本,若无结果则返回当前语言。",
|
||||
"wiki.id.help": "根据页面 ID 查询一个 Wiki 页面。",
|
||||
"wiki.id.message.error": "发生错误:页面 ID 必须为数字。",
|
||||
"wiki.id.message.not_found": "找不到页面 ID 为 ${id} 的页面。",
|
||||
"wiki.message.redirect": "(重定向[${title}] -> [${redirected_title}])",
|
||||
"wiki.message.redirect.autofix": "(已指定 [${title}] 更正为 [${redirected_title}]。)",
|
||||
"wiki.message.redirect.template_to_page": "([${title}] 不存在,已自动重定向至 [${redirected_title}])",
|
||||
"wiki.message.invalid_namespace": "此 Wiki 上没有名为 ${namespace} 的命名空间,请检查拼写后重试。",
|
||||
"wiki.message.not_found": "找不到 [${title}]。",
|
||||
"wiki.message.magic_word": "机器人暂不支持魔术字。",
|
||||
"tos.reason.too_many_redirects": "使机器人重定向页面的次数过多。",
|
||||
"tos.reason.wiki_abuse": "一次性查询的页面超过 15 个。",
|
||||
"wiki.message.untrust": "注意:此 Wiki 当前没有加入机器人的白名单列表中,查询此 Wiki 时将会对返回内容进行限制。\n若需取消限制,请在此处申请白名单:\n",
|
||||
"wiki.message.error.add": "发生错误:无法添加此 Wiki。",
|
||||
"wiki.message.error.blocked": "发生错误:${name} 处于黑名单中。",
|
||||
"wiki.message.error.query": "发生错误:无法查询此 Wiki。",
|
||||
"wiki.message.error.set": "发生错误:无法设置此 Wiki。",
|
||||
"wiki.message.error.info": "详细信息:"
|
||||
}
|
77
modules/wiki/locales/zh_tw.json
Normal file
77
modules/wiki/locales/zh_tw.json
Normal file
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"wiki.wiki_audit.list_name.blocklist": "黑名單",
|
||||
"wiki.wiki_audit.list_name.allowlist": "白名單",
|
||||
"wiki.wiki_audit.add.message.success": "成功加入${list_name}:",
|
||||
"wiki.wiki_audit.add.message.failed": "失敗,此 Wiki 已存在於${list_name}中:",
|
||||
"wiki.wiki_audit.remove.message.success": "成功從${list_name}刪除:",
|
||||
"wiki.wiki_audit.remove.message.failed": "失敗,此 Wiki 不存在於${list_name}中:",
|
||||
"wiki.wiki_audit.remove.message.failed.other": "失敗,此 Wiki 不存在於白名單中,此 Wiki 的白名單可能來自其他同一域名的 Wiki:",
|
||||
"wiki.wiki_audit.query.message.allowlist": "已存在於白名單。",
|
||||
"wiki.wiki_audit.query.message.blocklist": "已存在於黑名單。",
|
||||
"wiki.wiki_audit.query.message.conflict": "優先順序:白名單 > 黑名單",
|
||||
"wiki.wiki_audit.query.message.none": "不存在於任何名單。",
|
||||
"wiki.wiki_audit.list.message.allowlist": "現有白名單:",
|
||||
"wiki.wiki_audit.list.message.blocklist": "現有黑名單:",
|
||||
"wiki.wiki_audit.list.message.table.header.apilink": "API 連結",
|
||||
"wiki.wiki_audit.list.message.table.header.operator": "操作員",
|
||||
"wiki.wiki_inline.help.desc": "啟用後將自動解析訊息中帶有 [[ ]] 或 {{ }} 的字串並自動查詢 Wiki,例如 [[海晶石]]。",
|
||||
"wiki.wiki_inline.message.flies": "此頁面含有以下檔案:${file}",
|
||||
"wiki.search.help": "搜尋一個 Wiki 頁面。",
|
||||
"wiki.search.message": "搜尋到以下結果:",
|
||||
"wiki.search.message.prompt": "回覆編號以查詢對應的頁面。",
|
||||
"wiki.set.help": "設定起始查詢 Wiki。",
|
||||
"wiki.set.message.success": "成功設定起始 Wiki:${name}",
|
||||
"wiki.set.message.default": "沒有設定起始 Wiki,已預設為中文 Minecraft Wiki,傳送 ${prefix}wiki set <域名> 設定自訂起始 Wiki。\n示例:${prefix}wiki set https://minecraft.fandom.com/zh/wiki/",
|
||||
"wiki.iw.message.none": "目前沒有設定任何 Interwiki,可使用 ${prefix}wiki iw add <interwiki> <api_endpoint_link> 新增。",
|
||||
"wiki.iw.set.help": "新增自訂 Interwiki。",
|
||||
"wiki.iw.set.message.success": "成功:已新增自訂 Interwiki:\n${iw} -> ${name}",
|
||||
"wiki.iw.remove.help": "刪除自訂 Interwiki。",
|
||||
"wiki.iw.remove.message.success": "成功:已刪除自訂 Interwiki:${iw}",
|
||||
"wiki.iw.list.help": "展示目前設定的 Interwiki。",
|
||||
"wiki.iw.list.help.legacy": "展示目前設定的 Interwiki。(舊版)",
|
||||
"wiki.iw.list.message": "使用 ${prefix}wiki iw get <Interwiki> 可以取得 Interwiki 對應的連結。",
|
||||
"wiki.iw.list.message.legacy": "目前設定了以下 Interwiki:",
|
||||
"wiki.iw.list.message.prompt": "此處展示的是機器人設定的自訂 Interwiki,如需查看起始 Wiki 的 Interwiki,請見:${url}",
|
||||
"wiki.iw.get.help": "取得設定的 Interwiki 對應的 API 地址。",
|
||||
"wiki.iw.get.message.not_found": "未找到 Interwiki:${iw}",
|
||||
"wiki.headers.list.help": "展示目前設定的請求標頭。",
|
||||
"wiki.headers.list.message": "目前設定了以下請求標頭:\n${headers}\n如需自訂,請使用 ${prefix}wiki headers set <headers>。\n示例:\n${prefix}wiki headers set {{\"accept-language\": \"zh-TW,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\"}}",
|
||||
"wiki.headers.set.help": "新增自訂請求標頭。",
|
||||
"wiki.headers.remove.help": "刪除自訂請求標頭。",
|
||||
"wiki.headers.reset.help": "重設自訂請求標頭。",
|
||||
"wiki.headers.set.message.success": "成功:已更新請求時所使用的請求標頭:${headers}",
|
||||
"wiki.headers.reset.message.success": "成功:已重設請求時所使用的請求標頭:",
|
||||
"wiki.prefix.set.help": "設定自訂前綴。",
|
||||
"wiki.prefix.reset.help": "重設自訂前綴。",
|
||||
"wiki.prefix.set.message.success": "成功:已更新請求時所使用的前綴:${wiki_prefix}",
|
||||
"wiki.fandom.enable.help": "啟用 Fandom 全域 Interwiki 查詢。",
|
||||
"wiki.fandom.disable.help": "禁用 Fandom 全域 Interwiki 查詢。",
|
||||
"wiki.fandom.enable.message": "已啟用 Fandom 全域 Interwiki 查詢。",
|
||||
"wiki.fandom.disable.message": "已禁用 Fandom 全域 Interwiki 查詢。",
|
||||
"wiki.redlink.enable.help": "啟用頁面不存在時返回編輯連結。",
|
||||
"wiki.redlink.disable.help": "禁用頁面不存在時返回編輯連結。",
|
||||
"wiki.redlink.enable.message": "已啟用頁面不存在時返回編輯連結。",
|
||||
"wiki.redlink.disable.message": "已禁用頁面不存在時返回編輯連結。",
|
||||
"wiki.redlink.message.not_found": "(頁面不存在)",
|
||||
"wiki.redlink.message.not_found.uneditable": "[${title}] 頁面不存在。",
|
||||
"wiki.prefix.reset.message.success": "成功:已重設請求時所使用的前綴:",
|
||||
"wiki.help": "查詢一個 Wiki 頁面,若查詢「隨機頁面」則隨機一個頁面。",
|
||||
"wiki.help.l": "查找本頁面的對應語言版本,若無結果則返回目前語言。",
|
||||
"wiki.id.help": "根據頁面 ID 查詢一個 Wiki 頁面。",
|
||||
"wiki.id.message.error": "發生錯誤:頁面 ID 必須為數字。",
|
||||
"wiki.id.message.not_found": "找不到頁面 ID 為 ${id} 的頁面。",
|
||||
"wiki.message.redirect": "(重新導向[${title}] -> [${redirected_title}])",
|
||||
"wiki.message.redirect.autofix": "(已指定 [${title}] 更正為 [${redirected_title}]。)",
|
||||
"wiki.message.redirect.template_to_page": "([${title}] 不存在,已自動重新導向至 [${redirected_title}])",
|
||||
"wiki.message.invalid_namespace": "此 Wiki 上沒有名為 ${namespace} 的命名空間,请檢查拼字後重試。",
|
||||
"wiki.message.not_found": "找不到 [${title}]。",
|
||||
"wiki.message.magic_word": "機器人暫不支援魔術字。",
|
||||
"tos.reason.too_many_redirects": "使機器人重新導向頁面的次數過多。",
|
||||
"tos.reason.wiki_abuse": "一次性查詢的頁面超過 15 個。",
|
||||
"wiki.message.untrust": "注意:此 Wiki 目前沒有加入機器人的白名單列表中,查詢此 Wiki 時將會對返回內容進行限制。\n若需取消限制,請在此處申請白名單:",
|
||||
"wiki.message.error.add": "發生錯誤:無法新增此 Wiki。",
|
||||
"wiki.message.error.blocked": "發生錯誤:${name} 處於黑名單中。",
|
||||
"wiki.message.error.query": "發生錯誤:無法查詢此 Wiki。",
|
||||
"wiki.message.error.set": "發生錯誤:無法設定此 Wiki。",
|
||||
"wiki.message.error.info": "詳細資訊:"
|
||||
}
|
|
@ -9,7 +9,7 @@ from modules.wiki.utils.wikilib import WikiLib
|
|||
from .wiki import wiki, query_pages
|
||||
|
||||
|
||||
@wiki.handle('search <PageName> {搜索一个Wiki页面。}')
|
||||
@wiki.handle('search <PageName> {{wiki.search.help}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
await search_pages(msg, msg.parsed_msg['<PageName>'])
|
||||
|
||||
|
@ -22,9 +22,7 @@ async def search_pages(session: Bot.MessageSession, title: Union[str, list, tupl
|
|||
prefix = target.get_prefix()
|
||||
enabled_fandom_addon = session.options.get('wiki_fandom_addon')
|
||||
if start_wiki is None:
|
||||
await session.sendMessage(
|
||||
f'没有指定起始Wiki,已默认指定为中文Minecraft Wiki,发送{session.prefixes[0]}wiki set <域名>来设定自定义起始Wiki。'
|
||||
f'\n例子:{session.prefixes[0]}wiki set https://minecraft.fandom.com/zh/wiki/')
|
||||
await session.sendMessage(session.locale.t('wiki.set.message.default', prefix=session.prefixes[0]))
|
||||
start_wiki = 'https://minecraft.fandom.com/zh/api.php'
|
||||
if isinstance(title, str):
|
||||
title = [title]
|
||||
|
@ -87,13 +85,13 @@ async def search_pages(session: Bot.MessageSession, title: Union[str, list, tupl
|
|||
for r in result:
|
||||
wait_msg_list.append(iw_prefix + r)
|
||||
if len(wait_msg_list) != 0:
|
||||
msg_list.append('查询到以下结果:')
|
||||
msg_list.append(session.locale.t('wiki.search.message'))
|
||||
i = 0
|
||||
for w in wait_msg_list:
|
||||
i += 1
|
||||
w = f'{i}. {w}'
|
||||
msg_list.append(w)
|
||||
msg_list.append('回复编号以查询对应的页面。')
|
||||
msg_list.append(session.locale.t('wiki.search.message.prompt'))
|
||||
reply = await session.waitReply(Plain('\n'.join(msg_list)))
|
||||
if reply.asDisplay(text_only=True).isdigit():
|
||||
reply_number = int(reply.asDisplay(text_only=True)) - 1
|
||||
|
|
|
@ -9,7 +9,7 @@ from .wiki import wiki
|
|||
from config import Config
|
||||
|
||||
|
||||
@wiki.handle('set <WikiUrl> {设置起始查询Wiki}', required_admin=True)
|
||||
@wiki.handle('set <WikiUrl> {{wiki.set.help}}', required_admin=True)
|
||||
async def set_start_wiki(msg: Bot.MessageSession):
|
||||
target = WikiTargetInfo(msg)
|
||||
check = await WikiLib(msg.parsed_msg['<WikiUrl>'], headers=target.get_headers()).check_wiki_available()
|
||||
|
@ -18,19 +18,18 @@ async def set_start_wiki(msg: Bot.MessageSession):
|
|||
result = WikiTargetInfo(msg).add_start_wiki(check.value.api)
|
||||
if result:
|
||||
await msg.finish(
|
||||
f'成功添加起始Wiki:{check.value.name}' + ('\n' + check.message if check.message != '' else '') +
|
||||
(('\n注意:此Wiki当前没有加入本机器人的白名单列表中,查询此Wiki时将会对返回内容进行一些限制。\n'
|
||||
'如需取消限制,请在此处申请白名单:\n' + Config("wiki_whitelist_url"))
|
||||
msg.locale.t("wiki.set.message.success", name=check.value.name) + ('\n' + check.message if check.message != '' else '') +
|
||||
(('\n' + msg.locale.t("wiki.message.untrust") + Config("wiki_whitelist_url"))
|
||||
if not check.value.in_allowlist else ''))
|
||||
else:
|
||||
await msg.finish(f'错误:{check.value.name}处于黑名单中。')
|
||||
await msg.finish(msg.locale.t("wiki.message.error.blocked", name=check.value.name))
|
||||
else:
|
||||
result = '错误:无法添加此Wiki。' + \
|
||||
('\n详细信息:' + check.message if check.message != '' else '')
|
||||
result = msg.locale.t('wiki.message.error.add') + \
|
||||
('\n' + msg.locale.t('wiki.message.error.info') + check.message if check.message != '' else '')
|
||||
await msg.finish(result)
|
||||
|
||||
|
||||
@wiki.handle('iw (add|set) <Interwiki> <WikiUrl> {添加自定义Interwiki}', required_admin=True)
|
||||
@wiki.handle('iw (add|set) <Interwiki> <WikiUrl> {{wiki.iw.set.help}}', required_admin=True)
|
||||
async def _(msg: Bot.MessageSession):
|
||||
iw = msg.parsed_msg['<Interwiki>']
|
||||
url = msg.parsed_msg['<WikiUrl>']
|
||||
|
@ -40,29 +39,28 @@ async def _(msg: Bot.MessageSession):
|
|||
if not check.value.in_blocklist or check.value.in_allowlist:
|
||||
result = target.config_interwikis(iw, check.value.api, let_it=True)
|
||||
if result:
|
||||
await msg.finish(f'成功:添加自定义Interwiki\n{iw} -> {check.value.name}' +
|
||||
(('\n注意:此Wiki当前没有加入本机器人的白名单列表中,查询此Wiki时将会对返回内容进行一些限制。\n'
|
||||
'如需取消限制,请在此处申请白名单:\n' + Config("wiki_whitelist_url"))
|
||||
await msg.finish(msg.locale.t("wiki.iw.set.message.success", iw=iw, name=check.value.name) +
|
||||
(('\n' + msg.locale.t("wiki.message.untrust") + Config("wiki_whitelist_url"))
|
||||
if not check.value.in_allowlist else ''))
|
||||
else:
|
||||
await msg.finish(f'错误:{check.value.name}处于黑名单中。')
|
||||
await msg.finish(msg.locale.t("wiki.message.error.blocked", name=check.value.name))
|
||||
else:
|
||||
result = '错误:无法添加此Wiki。' + \
|
||||
('\n详细信息:' + check.message if check.message != '' else '')
|
||||
result = msg.locale.t('wiki.message.error.add') + \
|
||||
('\n' + msg.locale.t('wiki.message.error.info') + check.message if check.message != '' else '')
|
||||
await msg.finish(result)
|
||||
|
||||
|
||||
@wiki.handle('iw (del|delete|remove|rm) <Interwiki> {删除自定义Interwiki}', required_admin=True)
|
||||
@wiki.handle('iw (del|delete|remove|rm) <Interwiki> {{wiki.iw.remove.help}}', required_admin=True)
|
||||
async def _(msg: Bot.MessageSession):
|
||||
iw = msg.parsed_msg['<Interwiki>']
|
||||
target = WikiTargetInfo(msg)
|
||||
result = target.config_interwikis(iw, let_it=False)
|
||||
if result:
|
||||
await msg.finish(f'成功:删除自定义Interwiki“{msg.parsed_msg["<Interwiki>"]}”')
|
||||
await msg.finish(msg.locale.t("wiki.iw.remove.message.success", iw=iw))
|
||||
|
||||
|
||||
@wiki.handle(['iw list {展示当前设置的Interwiki}', 'iw show {iw list的别名}',
|
||||
'iw (list|show) legacy {展示当前设置的Interwiki(旧版)}'])
|
||||
@wiki.handle(['iw (list|show) {{wiki.iw.list.help}}',
|
||||
'iw (list|show) legacy {{wiki.iw.list.help.legacy}}'])
|
||||
async def _(msg: Bot.MessageSession):
|
||||
target = WikiTargetInfo(msg)
|
||||
query = target.get_interwikis()
|
||||
|
@ -79,21 +77,21 @@ async def _(msg: Bot.MessageSession):
|
|||
else:
|
||||
img = False
|
||||
if img:
|
||||
mt = f'使用{msg.prefixes[0]}wiki iw get <Interwiki> 可以获取interwiki对应的链接。'
|
||||
mt = msg.locale.t("wiki.iw.list.message", prefix=msg.prefixes[0])
|
||||
if base_interwiki_link is not None:
|
||||
mt += f'\n此处展示的是为机器人设定的自定义Interwiki,如需查看起始wiki的Interwiki,请见:{str(Url(base_interwiki_link))}'
|
||||
mt += '\n' + msg.locale.t("wiki.iw.list.message.prompt", url=str(Url(base_interwiki_link)))
|
||||
await msg.finish([Image(img), Plain(mt)])
|
||||
else:
|
||||
result = '当前设置了以下Interwiki:\n' + \
|
||||
result = msg.locale.t("wiki.iw.list.message.legacy") + '\n' + \
|
||||
'\n'.join([f'{x}: {query[x]}' for x in query])
|
||||
if base_interwiki_link is not None:
|
||||
result += f'\n此处展示的是为机器人设定的自定义Interwiki,如需查看起始wiki的Interwiki,请见:{str(Url(base_interwiki_link))}'
|
||||
result += '\n' + msg.locale.t("wiki.iw.list.message.prompt", url=str(Url(base_interwiki_link)))
|
||||
await msg.finish(result)
|
||||
else:
|
||||
await msg.finish('当前没有设置任何Interwiki,使用~wiki iw add <interwiki> <api_endpoint_link>添加一个。')
|
||||
await msg.finish(msg.locale.t("wiki.iw.message.none", prefix=msg.prefixes[0]))
|
||||
|
||||
|
||||
@wiki.handle('iw get <Interwiki> {获取设置的Interwiki对应的api地址}')
|
||||
@wiki.handle('iw get <Interwiki> {{wiki.iw.get.help}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
target = WikiTargetInfo(msg)
|
||||
query = target.get_interwikis()
|
||||
|
@ -101,81 +99,79 @@ async def _(msg: Bot.MessageSession):
|
|||
if msg.parsed_msg['<Interwiki>'] in query:
|
||||
await msg.finish(Url(query[msg.parsed_msg['<Interwiki>']]))
|
||||
else:
|
||||
await msg.finish(f'未找到Interwiki:{msg.parsed_msg["<Interwiki>"]}')
|
||||
await msg.finish(msg.locale.t("wiki.iw.get.message.not_found", iw=iw))
|
||||
else:
|
||||
await msg.finish('当前没有设置任何Interwiki,使用~wiki iw add <interwiki> <api_endpoint_link>添加一个。')
|
||||
await msg.finish(msg.locale.t("wiki.iw.message.none", prefix=msg.prefixes[0]))
|
||||
|
||||
|
||||
@wiki.handle(['headers show {展示当前设置的headers}', 'headers list {headers show 的别名}'])
|
||||
@wiki.handle(['headers (list|show) {{wiki.headers.list.help}}'])
|
||||
async def _(msg: Bot.MessageSession):
|
||||
target = WikiTargetInfo(msg)
|
||||
headers = target.get_headers()
|
||||
prompt = f'当前设置了以下标头:\n{json.dumps(headers)}\n如需自定义,请使用~wiki headers set <headers>。\n' \
|
||||
f'格式:\n' \
|
||||
f'~wiki headers set {{"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"}}'
|
||||
prompt = msg.locale.t("wiki.headers.list.message")
|
||||
await msg.finish(prompt)
|
||||
|
||||
|
||||
@wiki.handle('headers (add|set) <Headers> {添加自定义headers}', required_admin=True)
|
||||
@wiki.handle('headers (add|set) <Headers> {{wiki.headers.set.help}}', required_admin=True)
|
||||
async def _(msg: Bot.MessageSession):
|
||||
target = WikiTargetInfo(msg)
|
||||
add = target.config_headers(
|
||||
" ".join(msg.trigger_msg.split(" ")[3:]), let_it=True)
|
||||
if add:
|
||||
await msg.finish(f'成功更新请求时所使用的Headers:\n{json.dumps(target.get_headers())}')
|
||||
await msg.finish(msg.locale.t("wiki.headers.set.message.success", headers=json.dumps(target.get_headers())))
|
||||
|
||||
|
||||
@wiki.handle('headers (del|delete|remove|rm) <HeaderKey> {删除一个headers}', required_admin=True)
|
||||
@wiki.handle('headers (del|delete|remove|rm) <HeaderKey> {{wiki.headers.remove.help}}', required_admin=True)
|
||||
async def _(msg: Bot.MessageSession):
|
||||
target = WikiTargetInfo(msg)
|
||||
delete = target.config_headers(
|
||||
[msg.parsed_msg['<HeaderHey>']], let_it=False)
|
||||
if delete:
|
||||
await msg.finish(f'成功更新请求时所使用的Headers:\n{json.dumps(target.get_headers())}')
|
||||
await msg.finish(msg.locale.t("wiki.headers.set.message.success", headers=json.dumps(target.get_headers())))
|
||||
|
||||
|
||||
@wiki.handle('headers reset {重置headers}', required_admin=True)
|
||||
@wiki.handle('headers reset {{wiki.headers.reset.help}}', required_admin=True)
|
||||
async def _(msg: Bot.MessageSession):
|
||||
target = WikiTargetInfo(msg)
|
||||
reset = target.config_headers('{}', let_it=None)
|
||||
if reset:
|
||||
await msg.finish(f'成功更新请求时所使用的Headers:\n{json.dumps(target.get_headers())}')
|
||||
await msg.finish(msg.locale.t("wiki.headers.reset.message.success"))
|
||||
|
||||
|
||||
@wiki.handle('prefix set <prefix> {设置查询自动添加前缀}', required_admin=True)
|
||||
@wiki.handle('prefix set <prefix> {{wiki.prefix.set.help}}', required_admin=True)
|
||||
async def _(msg: Bot.MessageSession):
|
||||
target = WikiTargetInfo(msg)
|
||||
prefix = msg.parsed_msg['<prefix>']
|
||||
set_prefix = target.set_prefix(prefix)
|
||||
if set_prefix:
|
||||
await msg.finish(f'成功更新请求时所使用的前缀:{prefix}')
|
||||
await msg.finish(msg.locale.t("wiki.prefix.set.message.success", wiki_prefix=prefix))
|
||||
|
||||
|
||||
@wiki.handle('prefix reset {重置查询自动添加的前缀}', required_admin=True)
|
||||
@wiki.handle('prefix reset {{wiki.prefix.reset.help}}', required_admin=True)
|
||||
async def _(msg: Bot.MessageSession):
|
||||
target = WikiTargetInfo(msg)
|
||||
set_prefix = target.del_prefix()
|
||||
if set_prefix:
|
||||
await msg.finish(f'成功重置请求时所使用的前缀。')
|
||||
await msg.finish(msg.locale.t("wiki.prefix.reset.message.success"))
|
||||
|
||||
|
||||
@wiki.handle('fandom enable {启用Fandom全局Interwiki查询}', 'fandom disable {禁用Fandom全局Interwiki查询}',
|
||||
@wiki.handle('fandom enable {{wiki.fandom.enable.help}}', 'fandom disable {{wiki.fandom.disable.help}}',
|
||||
required_admin=True)
|
||||
async def _(msg: Bot.MessageSession):
|
||||
if msg.parsed_msg.get('enable', False):
|
||||
msg.data.edit_option('wiki_fandom_addon', True)
|
||||
await msg.finish('已启用Fandom全局Interwiki查询。')
|
||||
await msg.finish(msg.locale.t("wiki.fandom.enable.message"))
|
||||
else:
|
||||
msg.data.edit_option('wiki_fandom_addon', False)
|
||||
await msg.finish('已禁用Fandom全局Interwiki查询。')
|
||||
await msg.finish(msg.locale.t("wiki.fandom.disable.message"))
|
||||
|
||||
|
||||
@wiki.handle('redlink enable {启用不存在页面时返回编辑链接}', 'redlink disable {禁用不存在页面时返回编辑链接}',
|
||||
@wiki.handle('redlink enable {{wiki.redlink.enable.help}}', 'redlink disable {{wiki.redlink.disable.help}}',
|
||||
required_admin=True)
|
||||
async def _(msg: Bot.MessageSession):
|
||||
if msg.parsed_msg.get('enable', False):
|
||||
msg.data.edit_option('wiki_redlink', True)
|
||||
await msg.finish('已启用不存在页面时返回编辑链接。')
|
||||
await msg.finish(msg.locale.t("wiki.redlink.enable.message"))
|
||||
else:
|
||||
msg.data.edit_option('wiki_redlink', False)
|
||||
await msg.finish('已禁用不存在页面时返回编辑链接。')
|
||||
await msg.finish(msg.locale.t("wiki.redlink.disable.message"))
|
||||
|
|
|
@ -13,6 +13,7 @@ from core.builtins import Url
|
|||
from core.dirty_check import check
|
||||
from core.logger import Logger
|
||||
from core.utils.http import get_url
|
||||
from core.utils.i18n import Locale
|
||||
from modules.wiki.utils.dbutils import WikiSiteInfo as DBSiteInfo, Audit
|
||||
|
||||
|
||||
|
@ -37,11 +38,12 @@ class WhatAreUDoingError(Exception):
|
|||
|
||||
|
||||
class QueryInfo:
|
||||
def __init__(self, api, headers=None, prefix=None):
|
||||
def __init__(self, api, headers=None, prefix=None, locale=None):
|
||||
self.api = api
|
||||
self.headers = headers if headers is not None else {
|
||||
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6'}
|
||||
self.prefix = prefix
|
||||
self.locale = Locale(locale if locale is not None else 'zh_cn')
|
||||
|
||||
|
||||
class WikiInfo:
|
||||
|
|
|
@ -22,8 +22,8 @@ wiki = module('wiki',
|
|||
developers=['OasisAkari'])
|
||||
|
||||
|
||||
@wiki.handle('<PageName> [-l <lang>] {查询一个Wiki页面,若查询“随机页面”则随机一个页面。}',
|
||||
options_desc={'-l': '查找本页面的对应语言版本,若无结果则返回当前语言。'})
|
||||
@wiki.handle('<PageName> [-l <lang>] {{wiki.help}}',
|
||||
options_desc={'-l': '{wiki.help.l}'})
|
||||
async def _(msg: Bot.MessageSession):
|
||||
get_lang: dict = msg.parsed_msg.get('-l', False)
|
||||
if get_lang:
|
||||
|
@ -33,7 +33,7 @@ async def _(msg: Bot.MessageSession):
|
|||
await query_pages(msg, msg.parsed_msg['<PageName>'], lang=lang)
|
||||
|
||||
|
||||
@wiki.handle('-p <PageID> [-i <CustomIW>] {根据页面ID查询一个Wiki页面。}')
|
||||
@wiki.handle('id <PageID> [-i <CustomIW>] {{wiki.id.help}}')
|
||||
async def _(msg: Bot.MessageSession):
|
||||
if msg.parsed_msg.get('-i', False):
|
||||
iw: str = msg.parsed_msg['-i'].get('<CustomIW>', '')
|
||||
|
@ -41,7 +41,7 @@ async def _(msg: Bot.MessageSession):
|
|||
iw = ''
|
||||
page_id: str = msg.parsed_msg['<PageID>']
|
||||
if not page_id.isdigit():
|
||||
await msg.finish('错误:页面ID必须是数字。')
|
||||
await msg.finish(msg.locale.t('wiki.id.message.error'))
|
||||
Logger.debug(msg.parsed_msg)
|
||||
await query_pages(msg, pageid=page_id, iw=iw)
|
||||
|
||||
|
@ -69,15 +69,13 @@ async def query_pages(session: Union[Bot.MessageSession, QueryInfo], title: Unio
|
|||
|
||||
if start_wiki is None:
|
||||
if isinstance(session, Bot.MessageSession):
|
||||
await session.sendMessage(
|
||||
f'没有指定起始Wiki,已默认指定为中文Minecraft Wiki,发送{session.prefixes[0]}wiki set <域名>来设定自定义起始Wiki。'
|
||||
f'\n例子:{session.prefixes[0]}wiki set https://minecraft.fandom.com/zh/wiki/')
|
||||
await session.sendMessage(session.locale.t('wiki.set.message.default', prefix=session.prefixes[0]))
|
||||
start_wiki = 'https://minecraft.fandom.com/zh/api.php'
|
||||
if title is not None:
|
||||
if isinstance(title, str):
|
||||
title = [title]
|
||||
if len(title) > 15:
|
||||
raise AbuseWarning('一次性查询的页面超出15个。')
|
||||
raise AbuseWarning(session.locale.t('tos.reason.wiki_abuse'))
|
||||
query_task = {start_wiki: {'query': [], 'iw_prefix': ''}}
|
||||
for t in title:
|
||||
if prefix is not None and use_prefix:
|
||||
|
@ -147,7 +145,7 @@ async def query_pages(session: Union[Bot.MessageSession, QueryInfo], title: Unio
|
|||
try:
|
||||
tasks = []
|
||||
for rd in ready_for_query_pages:
|
||||
if rd == '随机页面':
|
||||
if rd in ['随机页面', '隨機頁面', 'Random']:
|
||||
tasks.append(asyncio.create_task(
|
||||
WikiLib(q, headers).random_page()))
|
||||
else:
|
||||
|
@ -179,11 +177,11 @@ async def query_pages(session: Union[Bot.MessageSession, QueryInfo], title: Unio
|
|||
plain_slice = []
|
||||
if display_before_title is not None and display_before_title != display_title:
|
||||
if r.before_page_property == 'template' and r.page_property == 'page':
|
||||
plain_slice.append(
|
||||
f'([{display_before_title}]不存在,已自动重定向至[{display_title}])')
|
||||
plain_slice.append(session.locale.t('wiki.message.redirect.template_to_page',
|
||||
title=display_before_title, redirected_title=display_title))
|
||||
else:
|
||||
plain_slice.append(
|
||||
f'(重定向[{display_before_title}] -> [{display_title}])')
|
||||
plain_slice.append(session.locale.t('wiki.message.redirect', title=display_before_title,
|
||||
redirected_title=display_title))
|
||||
if r.desc is not None and r.desc != '':
|
||||
plain_slice.append(r.desc)
|
||||
if r.link is not None:
|
||||
|
@ -198,7 +196,8 @@ async def query_pages(session: Union[Bot.MessageSession, QueryInfo], title: Unio
|
|||
render_infobox_list.append(
|
||||
{r.link: {'url': r.info.realurl, 'in_allowlist': r.info.in_allowlist,
|
||||
'content_mode': r.has_template_doc or r.title.split(':')[0] in ['User'] or
|
||||
'Template:Disambiguation' in r.templates}})
|
||||
(r.templates is not None and
|
||||
'Template:Disambiguation' in r.templates)}})
|
||||
elif r.link is not None and r.section is not None and r.info.in_allowlist:
|
||||
render_section_list.append(
|
||||
{r.link: {'url': r.info.realurl, 'section': r.section,
|
||||
|
@ -231,39 +230,37 @@ async def query_pages(session: Union[Bot.MessageSession, QueryInfo], title: Unio
|
|||
f'(请直接发送“是”字来确认,发送其他内容则代表取消获取。)')
|
||||
else:
|
||||
if r.edit_link is not None:
|
||||
plain_slice.append(r.edit_link + '(页面不存在)')
|
||||
plain_slice.append(r.edit_link + session.locale.t('wiki.redlink.message.not_found'))
|
||||
else:
|
||||
plain_slice.append(f'{display_before_title}页面不存在。')
|
||||
plain_slice.append(session.locale.t('wiki.redlink.message.not_found.uneditable', title=display_before_title))
|
||||
else:
|
||||
wait_plain_slice.append(
|
||||
f'提示:[{display_before_title}]不存在,您可能要找的是:[{display_title}]。')
|
||||
if len(r.possible_research_title) == 1:
|
||||
wait_list.append({display_title: display_before_title})
|
||||
elif r.before_title is not None:
|
||||
plain_slice.append(f'提示:找不到[{display_before_title}]。')
|
||||
plain_slice.append(session.locale.t('wiki.message.not_found', title=display_before_title))
|
||||
elif r.id != -1:
|
||||
plain_slice.append(f'提示:找不到ID为{str(r.id)}的页面。')
|
||||
plain_slice.append(session.locale.t('wiki.id.message.not_found', id=str(r.id)))
|
||||
if r.desc is not None and r.desc != '':
|
||||
plain_slice.append(r.desc)
|
||||
if r.invalid_namespace and r.before_title is not None:
|
||||
plain_slice.append(
|
||||
f'此Wiki上没有名为{r.invalid_namespace}的命名空间,请检查拼写后再试。')
|
||||
plain_slice.append(session.locale.t('wiki.message.invalid_namespace', namespace=r.invalid_namespace))
|
||||
if r.before_page_property == 'template':
|
||||
if r.before_title.split(':')[1].isupper():
|
||||
plain_slice.append(
|
||||
f'提示:机器人暂不支持魔术字。')
|
||||
plain_slice.append(session.locale.t('wiki.message.magic_word'))
|
||||
if plain_slice:
|
||||
msg_list.append(Plain('\n'.join(plain_slice)))
|
||||
if wait_plain_slice:
|
||||
wait_msg_list.append(
|
||||
Plain('\n'.join(wait_plain_slice)))
|
||||
except WhatAreUDoingError:
|
||||
raise AbuseWarning('使机器人重定向页面的次数过多。')
|
||||
raise AbuseWarning(session.locale.t('tos.reason.too_many_redirects'))
|
||||
except InvalidWikiError as e:
|
||||
if isinstance(session, Bot.MessageSession):
|
||||
await session.sendMessage(f'发生错误:' + str(e))
|
||||
await session.sendMessage(session.locale.t('error') + str(e))
|
||||
else:
|
||||
msg_list.append(Plain(f'发生错误:' + str(e)))
|
||||
msg_list.append(Plain(session.locale.t('error') + str(e)))
|
||||
if isinstance(session, Bot.MessageSession):
|
||||
if msg_list:
|
||||
if all([not render_infobox_list, not render_section_list,
|
||||
|
@ -338,20 +335,20 @@ async def query_pages(session: Union[Bot.MessageSession, QueryInfo], title: Unio
|
|||
wait_list_ = []
|
||||
for w in wait_list:
|
||||
for wd in w:
|
||||
preset_message.append(f'(已指定[{w[wd]}]更正为[{wd}]。)')
|
||||
preset_message.append(session.locale.t('wiki.message.redirect.autofix', title=w[wd], redirected_title=wd))
|
||||
wait_list_.append(wd)
|
||||
if auto_index:
|
||||
for wp in wait_possible_list:
|
||||
for wpk in wp:
|
||||
keys = list(wp[wpk].keys())
|
||||
preset_message.append(f'(已指定[{wpk}]更正为[{keys[0]}]。)')
|
||||
preset_message.append(session.locale.t('wiki.message.redirect.autofix', title=wpk, redirected_title=keys[0]))
|
||||
wait_list_.append(keys[0])
|
||||
else:
|
||||
for wp in wait_possible_list:
|
||||
for wpk in wp:
|
||||
keys = list(wp[wpk].keys())
|
||||
if len(wp[wpk][keys[0]]) > index:
|
||||
preset_message.append(f'(已指定[{wpk}]更正为[{wp[wpk][keys[0]][index]}]。)')
|
||||
preset_message.append(session.locale.t('wiki.message.redirect.autofix', title=wpk, redirected_title=wp[wpk][keys[0]][index]))
|
||||
wait_list_.append(wp[wpk][keys[0]][index])
|
||||
|
||||
if wait_list_:
|
||||
|
|
Reference in a new issue