Archived
1
0
Fork 0
This repository has been archived on 2024-04-26. You can view files and clone it, but cannot push or open issues or pull requests.
akari-bot/modules/wiki/__init__.py

874 lines
40 KiB
Python
Raw Normal View History

2021-10-31 15:59:18 +00:00
import asyncio
2021-07-28 18:51:24 +00:00
import re
2021-11-12 14:25:53 +00:00
import traceback
import urllib.parse
2021-10-31 15:59:18 +00:00
from typing import Union
2021-11-12 14:25:53 +00:00
import filetype
2021-09-10 18:05:27 +00:00
import ujson as json
2022-07-31 08:27:58 +00:00
from core.builtins.message import MessageSession
2022-07-01 14:12:26 +00:00
from core.component import on_command, on_regex
from core.dirty_check import check
2022-08-04 15:52:53 +00:00
from core.elements import Plain, Image, Voice, Url, confirm_command
2021-11-12 14:25:53 +00:00
from core.exceptions import AbuseWarning
2022-08-04 07:52:42 +00:00
from core.logger import Logger
2021-08-18 13:11:14 +00:00
from core.utils import download_to_cache
2021-11-08 16:09:06 +00:00
from core.utils.image_table import image_table_render, ImageTable
from .dbutils import WikiTargetInfo, Audit
2022-04-13 15:36:55 +00:00
from .getinfobox import get_pic
2021-11-12 14:25:53 +00:00
from .utils.ab import ab
from .utils.ab_qq import ab_qq
from .utils.newbie import newbie
from .utils.rc import rc
from .utils.rc_qq import rc_qq
2022-04-08 07:17:39 +00:00
from .wikilib import WikiLib, WhatAreUDoingError, PageInfo, InvalidWikiError, QueryInfo
2021-07-28 18:51:24 +00:00
2021-10-24 10:55:45 +00:00
wiki = on_command('wiki',
2022-04-08 07:17:39 +00:00
alias={'wiki_start_site': 'wiki set',
'interwiki': 'wiki iw'},
2021-10-24 10:55:45 +00:00
recommend_modules='wiki_inline',
developers=['OasisAkari'])
2021-07-28 18:51:24 +00:00
@wiki.handle('<PageName> [-l <lang>] {查询一个Wiki页面若查询“随机页面”则随机一个页面。}',
options_desc={'-l': '查找本页面的对应语言版本,若无结果则返回当前语言。'})
2021-10-24 10:55:45 +00:00
async def _(msg: MessageSession):
2022-08-30 12:49:01 +00:00
get_lang: dict = msg.parsed_msg.get('-l', False)
if get_lang:
lang = get_lang['<lang>']
else:
lang = None
await query_pages(msg, msg.parsed_msg['<PageName>'], lang=lang)
2021-07-28 18:51:24 +00:00
2022-06-28 06:59:25 +00:00
@wiki.handle('-p <PageID> [-i <CustomIW>] {根据页面ID查询一个Wiki页面。}')
2022-01-27 13:16:53 +00:00
async def _(msg: MessageSession):
2022-08-15 06:04:07 +00:00
if msg.parsed_msg.get('-i', False):
2022-08-30 12:49:01 +00:00
iw: str = msg.parsed_msg['-i'].get('<CustomIW>', '')
2022-08-15 06:04:07 +00:00
else:
2022-08-30 12:49:01 +00:00
iw = ''
2022-02-09 12:42:13 +00:00
page_id: str = msg.parsed_msg['<PageID>']
if not page_id.isdigit():
2022-05-21 16:04:29 +00:00
await msg.finish('错误页面ID必须是数字。')
2022-08-04 07:52:42 +00:00
Logger.debug(msg.parsed_msg)
2022-02-09 12:42:13 +00:00
await query_pages(msg, pageid=page_id, iw=iw)
2022-01-27 13:16:53 +00:00
2022-06-28 06:59:25 +00:00
@wiki.handle('search <PageName> {搜索一个Wiki页面。}')
async def _(msg: MessageSession):
await search_pages(msg, msg.parsed_msg['<PageName>'])
2021-10-24 10:55:45 +00:00
@wiki.handle('set <WikiUrl> {设置起始查询Wiki}', required_admin=True)
2021-07-28 18:51:24 +00:00
async def set_start_wiki(msg: MessageSession):
2021-10-31 15:59:18 +00:00
target = WikiTargetInfo(msg)
check = await WikiLib(msg.parsed_msg['<WikiUrl>'], headers=target.get_headers()).check_wiki_available()
if check.available:
2021-11-17 13:17:13 +00:00
if not check.value.in_blocklist or check.value.in_allowlist:
result = WikiTargetInfo(msg).add_start_wiki(check.value.api)
if result:
2022-05-21 16:04:29 +00:00
await msg.finish(
2021-11-17 13:17:13 +00:00
f'成功添加起始Wiki{check.value.name}' + ('\n' + check.message if check.message != '' else ''))
else:
2022-05-21 16:04:29 +00:00
await msg.finish(f'错误:{check.value.name}处于黑名单中。')
2021-07-28 18:51:24 +00:00
else:
2022-04-08 07:17:39 +00:00
result = '错误无法添加此Wiki。' + \
('\n详细信息:' + check.message if check.message != '' else '')
2022-05-21 16:04:29 +00:00
await msg.finish(result)
2021-07-28 18:51:24 +00:00
2021-11-07 15:16:21 +00:00
@wiki.handle('iw (add|set) <Interwiki> <WikiUrl> {添加自定义Interwiki}', required_admin=True)
2021-10-31 15:59:18 +00:00
async def _(msg: MessageSession):
2021-07-28 18:51:24 +00:00
iw = msg.parsed_msg['<Interwiki>']
url = msg.parsed_msg['<WikiUrl>']
target = WikiTargetInfo(msg)
2021-11-07 15:16:21 +00:00
check = await WikiLib(url, headers=target.get_headers()).check_wiki_available()
if check.available:
2021-11-17 13:17:13 +00:00
if not check.value.in_blocklist or check.value.in_allowlist:
result = target.config_interwikis(iw, check.value.api, let_it=True)
if result:
2022-05-21 16:04:29 +00:00
await msg.finish(f'成功添加自定义Interwiki\n{iw} -> {check.value.name}')
2021-11-17 13:17:13 +00:00
else:
2022-05-21 16:04:29 +00:00
await msg.finish(f'错误:{check.value.name}处于黑名单中。')
2021-11-07 15:16:21 +00:00
else:
2022-04-08 07:17:39 +00:00
result = '错误无法添加此Wiki。' + \
('\n详细信息:' + check.message if check.message != '' else '')
2022-05-21 16:04:29 +00:00
await msg.finish(result)
2021-11-07 15:16:21 +00:00
@wiki.handle('iw (del|delete|remove|rm) <Interwiki> {删除自定义Interwiki}', required_admin=True)
async def _(msg: MessageSession):
iw = msg.parsed_msg['<Interwiki>']
target = WikiTargetInfo(msg)
result = target.config_interwikis(iw, let_it=False)
if result:
2022-05-21 16:04:29 +00:00
await msg.finish(f'成功删除自定义Interwiki“{msg.parsed_msg["<Interwiki>"]}')
2021-11-07 15:16:21 +00:00
2021-11-08 16:09:06 +00:00
@wiki.handle(['iw list {展示当前设置的Interwiki}', 'iw show {iw list的别名}',
'iw (list|show) legacy {展示当前设置的Interwiki旧版}'])
2021-11-07 15:16:21 +00:00
async def _(msg: MessageSession):
target = WikiTargetInfo(msg)
query = target.get_interwikis()
2022-01-20 10:37:27 +00:00
start_wiki = target.get_start_wiki()
base_interwiki_link = None
if start_wiki is not None:
base_interwiki_link = await WikiLib(start_wiki, target.get_headers()).parse_page_info('Special:Interwiki')
if base_interwiki_link.status:
base_interwiki_link = base_interwiki_link.link
2022-01-20 10:41:43 +00:00
base_interwiki_link_msg = f'\n此处展示的是为机器人设定的自定义Interwiki如需查看起始wiki的Interwiki请见{str(Url(base_interwiki_link))}'
2021-11-07 15:16:21 +00:00
if query != {}:
if 'legacy' not in msg.parsed_msg and msg.Feature.image:
2021-11-08 16:09:06 +00:00
columns = [[x, query[x]] for x in query]
img = await image_table_render(ImageTable(columns, ['Interwiki', 'Url']))
else:
img = False
2021-11-07 15:16:21 +00:00
if img:
mt = f'使用{msg.prefixes[0]}wiki iw get <Interwiki> 可以获取interwiki对应的链接。'
2022-01-20 10:37:27 +00:00
if base_interwiki_link is not None:
mt += base_interwiki_link_msg
2022-05-21 16:04:29 +00:00
await msg.finish([Image(img), Plain(mt)])
2021-11-07 15:16:21 +00:00
else:
2022-04-08 07:17:39 +00:00
result = '当前设置了以下Interwiki\n' + \
'\n'.join([f'{x}: {query[x]}' for x in query])
2022-01-20 10:37:27 +00:00
if base_interwiki_link is not None:
result += base_interwiki_link_msg
2022-05-21 16:04:29 +00:00
await msg.finish(result)
2021-11-07 15:16:21 +00:00
else:
2022-05-21 16:04:29 +00:00
await msg.finish('当前没有设置任何Interwiki使用~wiki iw add <interwiki> <api_endpoint_link>添加一个。')
2021-11-07 15:16:21 +00:00
@wiki.handle('iw get <Interwiki> {获取设置的Interwiki对应的api地址}')
async def _(msg: MessageSession):
target = WikiTargetInfo(msg)
query = target.get_interwikis()
if query != {}:
if msg.parsed_msg['<Interwiki>'] in query:
2022-05-21 16:04:29 +00:00
await msg.finish(Url(query[msg.parsed_msg['<Interwiki>']]))
2021-07-28 18:51:24 +00:00
else:
2022-05-21 16:04:29 +00:00
await msg.finish(f'未找到Interwiki{msg.parsed_msg["<Interwiki>"]}')
2021-11-07 15:16:21 +00:00
else:
2022-05-21 16:04:29 +00:00
await msg.finish('当前没有设置任何Interwiki使用~wiki iw add <interwiki> <api_endpoint_link>添加一个。')
2021-11-07 15:16:21 +00:00
@wiki.handle(['headers show {展示当前设置的headers}', 'headers list {headers show 的别名}'])
async def _(msg: 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"}}'
2022-05-21 16:04:29 +00:00
await msg.finish(prompt)
2021-11-07 15:16:21 +00:00
@wiki.handle('headers (add|set) <Headers> {添加自定义headers}', required_admin=True)
async def _(msg: MessageSession):
target = WikiTargetInfo(msg)
2022-04-08 07:17:39 +00:00
add = target.config_headers(
" ".join(msg.trigger_msg.split(" ")[3:]), let_it=True)
2021-11-07 15:16:21 +00:00
if add:
2022-05-21 16:04:29 +00:00
await msg.finish(f'成功更新请求时所使用的Headers\n{json.dumps(target.get_headers())}')
2021-07-28 18:51:24 +00:00
2021-11-07 15:16:21 +00:00
@wiki.handle('headers (del|delete|remove|rm) <HeaderKey> {删除一个headers}', required_admin=True)
async def _(msg: MessageSession):
2021-07-28 18:51:24 +00:00
target = WikiTargetInfo(msg)
2022-04-08 07:17:39 +00:00
delete = target.config_headers(
[msg.parsed_msg['<HeaderHey>']], let_it=False)
2021-11-07 15:16:21 +00:00
if delete:
2022-05-21 16:04:29 +00:00
await msg.finish(f'成功更新请求时所使用的Headers\n{json.dumps(target.get_headers())}')
2021-11-07 15:16:21 +00:00
@wiki.handle('headers reset {重置headers}', required_admin=True)
async def _(msg: MessageSession):
target = WikiTargetInfo(msg)
2022-06-18 11:54:27 +00:00
reset = target.config_headers('{}', let_it=None)
2021-11-07 15:16:21 +00:00
if reset:
2022-05-21 16:04:29 +00:00
await msg.finish(f'成功更新请求时所使用的Headers\n{json.dumps(target.get_headers())}')
2021-11-07 15:16:21 +00:00
2021-07-28 18:51:24 +00:00
2021-12-19 08:29:28 +00:00
@wiki.handle('prefix set <prefix> {设置查询自动添加前缀}', required_admin=True)
2021-12-19 08:23:24 +00:00
async def _(msg: MessageSession):
target = WikiTargetInfo(msg)
prefix = msg.parsed_msg['<prefix>']
set_prefix = target.set_prefix(prefix)
if set_prefix:
2022-05-21 16:04:29 +00:00
await msg.finish(f'成功更新请求时所使用的前缀:{prefix}')
2021-12-19 08:23:24 +00:00
2021-12-19 08:29:28 +00:00
@wiki.handle('prefix reset {重置查询自动添加的前缀}', required_admin=True)
2021-12-19 08:23:24 +00:00
async def _(msg: MessageSession):
target = WikiTargetInfo(msg)
set_prefix = target.del_prefix()
if set_prefix:
2022-05-21 16:04:29 +00:00
await msg.finish(f'成功重置请求时所使用的前缀。')
2021-12-19 08:23:24 +00:00
2022-08-16 18:52:40 +00:00
@wiki.handle('fandom enable {禁用Fandom全局Interwiki查询}', 'fandom disable {禁用Fandom全局Interwiki查询}', required_admin=True)
2022-07-01 14:12:26 +00:00
async def _(msg: MessageSession):
2022-08-16 18:52:40 +00:00
if msg.parsed_msg.get('enable', False):
2022-08-26 18:51:56 +00:00
msg.data.edit_option('wiki_fandom_addon', True)
2022-07-01 14:12:26 +00:00
await msg.finish('已启用Fandom全局Interwiki查询。')
else:
2022-08-26 18:51:56 +00:00
msg.data.edit_option('wiki_fandom_addon', False)
2022-07-01 14:12:26 +00:00
await msg.finish('已禁用Fandom全局Interwiki查询。')
aud = on_command('wiki_audit', alias='wa',
2021-11-17 13:17:13 +00:00
developers=['Dianliang233', 'OasisAkari'], required_superuser=True)
2021-11-27 12:18:02 +00:00
@aud.handle(['trust <apiLink>', 'block <apiLink>'])
async def _(msg: MessageSession):
2021-09-21 08:22:29 +00:00
req = msg.parsed_msg
op = msg.session.sender
2021-11-15 16:34:36 +00:00
api = req['<apiLink>']
2021-11-17 13:17:13 +00:00
check = await WikiLib(api).check_wiki_available()
if check.available:
api = check.value.api
2022-08-16 18:52:40 +00:00
if req.get('trust', False):
2021-11-17 13:17:13 +00:00
res = Audit(api).add_to_AllowList(op)
list_name = ''
else:
2021-11-17 13:17:13 +00:00
res = Audit(api).add_to_BlockList(op)
list_name = ''
if not res:
2022-05-21 16:04:29 +00:00
await msg.finish(f'失败此wiki已经存在于{list_name}名单中:' + api)
2021-11-17 13:17:13 +00:00
else:
2022-05-21 16:04:29 +00:00
await msg.finish(f'成功加入{list_name}名单:' + api)
2021-11-17 13:17:13 +00:00
else:
2022-04-08 07:17:39 +00:00
result = '错误无法添加此Wiki。' + \
('\n详细信息:' + check.message if check.message != '' else '')
2022-05-21 16:04:29 +00:00
await msg.finish(result)
2021-11-27 12:18:02 +00:00
@aud.handle(['distrust <apiLink>', 'unblock <apiLink>'])
async def _(msg: MessageSession):
req = msg.parsed_msg
2021-11-15 16:34:36 +00:00
api = req['<apiLink>']
2021-11-17 13:17:13 +00:00
check = await WikiLib(api).check_wiki_available()
if check.available:
2021-11-17 13:17:13 +00:00
api = check.value.api
2022-08-16 18:52:40 +00:00
if req.get('distrust', False):
2021-11-17 13:17:13 +00:00
res = Audit(api).remove_from_AllowList()
list_name = ''
else:
res = Audit(api).remove_from_BlockList()
list_name = ''
if not res:
2022-05-21 16:04:29 +00:00
await msg.finish(f'失败此wiki不存在于{list_name}名单中:' + api)
2021-11-17 13:17:13 +00:00
else:
2022-05-21 16:04:29 +00:00
await msg.finish(f'成功从{list_name}名单删除:' + api)
else:
2022-04-08 07:17:39 +00:00
result = '错误无法查询此Wiki。' + \
('\n详细信息:' + check.message if check.message != '' else '')
2022-05-21 16:04:29 +00:00
await msg.finish(result)
2021-11-15 16:34:36 +00:00
@aud.handle('query <apiLink>')
async def _(msg: MessageSession):
req = msg.parsed_msg
2021-11-15 16:34:36 +00:00
api = req['<apiLink>']
2021-11-17 13:17:13 +00:00
check = await WikiLib(api).check_wiki_available()
if check.available:
2021-11-17 13:17:13 +00:00
api = check.value.api
audit = Audit(api)
allow = audit.inAllowList
block = audit.inBlockList
msg_list = []
if allow:
msg_list.append(api + '已存在于白名单。')
if block:
msg_list.append(api + '已存在于黑名单。')
if msg_list:
msg_list.append('优先级:白名单 > 黑名单')
2022-05-21 16:04:29 +00:00
await msg.finish('\n'.join(msg_list))
2021-11-17 13:17:13 +00:00
else:
2022-05-21 16:04:29 +00:00
await msg.finish(api + '不存在于任何名单。')
else:
2022-04-08 07:17:39 +00:00
result = '错误无法查询此Wiki。' + \
('\n详细信息:' + check.message if check.message != '' else '')
2022-05-21 16:04:29 +00:00
await msg.finish(result)
@aud.handle('list')
async def _(msg: MessageSession):
2021-11-17 13:17:13 +00:00
allow_list = Audit.get_allow_list()
block_list = Audit.get_block_list()
legacy = True
if msg.Feature.image:
send_msgs = []
allow_columns = [[x[0], x[1]] for x in allow_list]
if allow_columns:
2022-04-08 07:17:39 +00:00
allow_table = ImageTable(data=allow_columns, headers=[
'APILink', 'Operator'])
2021-11-17 13:17:13 +00:00
if allow_table:
allow_image = await image_table_render(allow_table)
if allow_image:
send_msgs.append(Plain('现有白名单:'))
send_msgs.append(Image(allow_image))
block_columns = [[x[0], x[1]] for x in block_list]
if block_columns:
2022-04-08 07:17:39 +00:00
block_table = ImageTable(data=block_columns, headers=[
'APILink', 'Operator'])
2021-11-17 13:17:13 +00:00
if block_table:
block_image = await image_table_render(block_table)
if block_image:
send_msgs.append(Plain('现有黑名单:'))
send_msgs.append(Image(block_image))
if send_msgs:
2022-05-21 16:04:29 +00:00
await msg.finish(send_msgs)
2021-11-17 13:17:13 +00:00
legacy = False
if legacy:
wikis = ['现有白名单:']
2021-11-17 13:17:13 +00:00
for al in allow_list:
wikis.append(f'{al[0]}by {al[1]}')
wikis.append('现有黑名单:')
for bl in block_list:
wikis.append(f'{bl[0]}by {bl[1]}')
2022-05-21 16:04:29 +00:00
await msg.finish('\n'.join(wikis))
2021-07-28 18:51:24 +00:00
2022-07-31 08:33:20 +00:00
2021-10-31 15:59:18 +00:00
wiki_inline = on_regex('wiki_inline',
2022-01-20 10:37:27 +00:00
desc='开启后将自动解析消息中带有的[[]]或{{}}字符串并自动查询Wiki如[[海晶石]]',
2021-10-31 15:59:18 +00:00
alias='wiki_regex', developers=['OasisAkari'])
2021-10-24 10:55:45 +00:00
2021-07-28 18:51:24 +00:00
@wiki_inline.handle(re.compile(r'\[\[(.*?)]]', flags=re.I), mode='A')
2021-10-31 15:59:18 +00:00
async def _(msg: MessageSession):
query_list = []
for x in msg.matched_msg:
if x != '' and x not in query_list and x[0] != '#':
2021-11-14 05:27:20 +00:00
query_list.append(x.split("|")[0])
2021-10-31 15:59:18 +00:00
if query_list:
2022-04-29 16:49:30 +00:00
await query_pages(msg, query_list, inline_mode=True)
2021-07-28 18:51:24 +00:00
@wiki_inline.handle(re.compile(r'\{\{(.*?)}}', flags=re.I), mode='A')
2021-10-31 15:59:18 +00:00
async def _(msg: MessageSession):
query_list = []
for x in msg.matched_msg:
if x != '' and x not in query_list and x[0] != '#' and x.find("{") == -1:
2021-11-14 05:27:20 +00:00
query_list.append(x.split("|")[0])
2021-10-31 15:59:18 +00:00
if query_list:
2022-04-29 16:49:30 +00:00
await query_pages(msg, query_list, template=True, inline_mode=True)
2021-07-28 18:51:24 +00:00
2021-10-31 15:59:18 +00:00
@wiki_inline.handle(re.compile(r'≺(.*?)≻|⧼(.*?)⧽', flags=re.I), mode='A', show_typing=False)
async def _(msg: MessageSession):
query_list = []
for x in msg.matched_msg:
2021-11-06 13:44:33 +00:00
for y in x:
if y != '' and y not in query_list and y[0] != '#':
query_list.append(y)
if query_list:
2022-04-29 16:49:30 +00:00
await query_pages(msg, query_list, mediawiki=True, inline_mode=True)
2022-08-31 15:02:11 +00:00
@wiki_inline.handle(re.compile(
r'(https?://[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,4}\b[-a-zA-Z0-9@:%_+.~#?&/=]*)', flags=re.I),
2022-08-31 15:02:11 +00:00
mode='A', show_typing=False)
async def _(msg: MessageSession):
2022-08-31 16:00:45 +00:00
match_msg = msg.matched_msg
2022-08-31 15:35:00 +00:00
async def bgtask():
query_list = []
target = WikiTargetInfo(msg)
headers = target.get_headers()
iws = target.get_interwikis()
wikis = [target.get_start_wiki()] + [iws[w] for w in iws]
2022-08-31 15:45:49 +00:00
for x in match_msg:
2022-09-02 10:00:22 +00:00
wiki_ = WikiLib(x)
if check_from_database := await wiki_.check_wiki_info_from_database_cache():
if check_from_database.available:
2022-09-02 10:01:19 +00:00
check_from_api = await wiki_.check_wiki_available()
if check_from_api.available:
2022-09-02 10:00:22 +00:00
query_list.append({x: check_from_api.value})
if query_list:
for q in query_list:
2022-08-31 16:40:06 +00:00
img_send = False
for qq in q:
articlepath = q[qq].articlepath.replace('$1', '(.*)')
get_title = re.sub(r'' + articlepath, '\\1', qq)
if get_title != '':
title = urllib.parse.unquote(get_title)
if not q[qq].in_allowlist:
for result in await check(title):
if not result['status']:
return
wiki_ = WikiLib(qq)
get_page = await wiki_.parse_page_info(title)
if get_page.status and get_page.file is not None:
dl = await download_to_cache(get_page.file)
guess_type = filetype.guess(dl)
if guess_type is not None:
if guess_type.extension in ["png", "gif", "jpg", "jpeg", "webp", "bmp", "ico"]:
if msg.Feature.image:
2022-09-03 13:42:48 +00:00
await msg.sendMessage([Plain(f'此页面包括以下文件:{get_page.file}'), Image(dl)],
quote=False)
2022-08-31 16:40:06 +00:00
img_send = True
elif guess_type.extension in ["oga", "ogg", "flac", "mp3", "wav"]:
if msg.Feature.voice:
2022-09-03 13:42:48 +00:00
await msg.sendMessage([Plain(f'此页面包括以下文件:{get_page.file}'), Voice(dl)],
quote=False)
2022-08-31 16:40:06 +00:00
if len(query_list) == 1 and img_send:
return
if msg.Feature.image:
for qq in q:
2022-08-31 16:40:06 +00:00
get_infobox = await get_pic(q[qq].realurl, qq, headers, allow_special_page=q[qq].in_allowlist)
if get_infobox:
await msg.sendMessage(Image(get_infobox), quote=False)
for qq in q:
section_ = []
quote_code = False
for qs in qq:
if qs == '#':
quote_code = True
if qs == '?':
quote_code = False
if quote_code:
section_.append(qs)
if section_:
s = urllib.parse.unquote(''.join(section_)[1:])
if q[qq].realurl:
get_section = await get_pic(q[qq].realurl, qq, headers, section=s)
if get_section:
await msg.sendMessage(Image(get_section))
2022-08-31 15:35:00 +00:00
asyncio.create_task(bgtask())
2022-06-28 06:59:25 +00:00
async def search_pages(session: MessageSession, title: Union[str, list, tuple], use_prefix=True):
target = WikiTargetInfo(session)
start_wiki = target.get_start_wiki()
interwiki_list = target.get_interwikis()
headers = target.get_headers()
prefix = target.get_prefix()
enabled_fandom_addon = session.options.get('wiki_fandom_addon')
2022-06-28 06:59:25 +00:00
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/')
2022-06-28 06:59:25 +00:00
start_wiki = 'https://minecraft.fandom.com/zh/api.php'
if isinstance(title, str):
title = [title]
query_task = {start_wiki: {'query': [], 'iw_prefix': ''}}
for t in title:
if prefix is not None and use_prefix:
t = prefix + t
if t[0] == ':':
if len(t) > 1:
query_task[start_wiki]['query'].append(t[1:])
else:
matched = False
match_interwiki = re.match(r'^(.*?):(.*)', t)
if match_interwiki:
g1 = match_interwiki.group(1)
g2 = match_interwiki.group(2)
if g1 in interwiki_list:
interwiki_url = interwiki_list[g1]
if interwiki_url not in query_task:
query_task[interwiki_url] = {
'query': [], 'iw_prefix': g1}
query_task[interwiki_url]['query'].append(g2)
matched = True
elif g1 == 'w' and enabled_fandom_addon:
if match_interwiki := re.match(r'(.*?):(.*)', match_interwiki.group(2)):
if match_interwiki.group(1) == 'c':
if match_interwiki := re.match(r'(.*?):(.*)', match_interwiki.group(2)):
interwiki_split = match_interwiki.group(
1).split('.')
if len(interwiki_split) == 2:
get_link = f'https://{interwiki_split[1]}.fandom.com/api.php'
find = interwiki_split[0] + \
':' + match_interwiki.group(2)
iw = 'w:c:' + interwiki_split[0]
else:
get_link = f'https://{match_interwiki.group(1)}.fandom.com/api.php'
find = match_interwiki.group(2)
iw = 'w:c:' + match_interwiki.group(1)
if get_link not in query_task:
query_task[get_link] = {
'query': [], 'iw_prefix': iw}
query_task[get_link]['query'].append(find)
matched = True
if not matched:
query_task[start_wiki]['query'].append(t)
2022-08-04 07:52:42 +00:00
Logger.debug(query_task)
2022-06-28 06:59:25 +00:00
msg_list = []
wait_msg_list = []
for q in query_task:
current_task = query_task[q]
ready_for_query_pages = current_task['query'] if 'query' in current_task else []
iw_prefix = (current_task['iw_prefix'] +
':') if current_task['iw_prefix'] != '' else ''
tasks = []
for rd in ready_for_query_pages:
tasks.append(asyncio.ensure_future(
WikiLib(q, headers).search_page(rd)))
query = await asyncio.gather(*tasks)
for result in query:
for r in result:
wait_msg_list.append(iw_prefix + r)
if len(wait_msg_list) != 0:
msg_list.append('查询到以下结果:')
i = 0
for w in wait_msg_list:
i += 1
w = f'{i}. {w}'
msg_list.append(w)
msg_list.append('回复编号以查询对应的页面。')
reply = await session.waitReply(Plain('\n'.join(msg_list)))
if reply.asDisplay().isdigit():
reply_number = int(reply.asDisplay()) - 1
await query_pages(reply, wait_msg_list[reply_number])
2022-01-27 13:16:53 +00:00
async def query_pages(session: Union[MessageSession, QueryInfo], title: Union[str, list, tuple] = None,
pageid: str = None, iw: str = None, lang: str = None,
2022-07-18 14:34:31 +00:00
template=False, mediawiki=False, use_prefix=True, inline_mode=False, preset_message=None):
if isinstance(session, MessageSession):
target = WikiTargetInfo(session)
start_wiki = target.get_start_wiki()
interwiki_list = target.get_interwikis()
headers = target.get_headers()
prefix = target.get_prefix()
enabled_fandom_addon = session.options.get('wiki_fandom_addon')
2022-07-01 14:12:26 +00:00
if enabled_fandom_addon is None:
enabled_fandom_addon = False
elif isinstance(session, QueryInfo):
start_wiki = session.api
interwiki_list = []
headers = session.headers
prefix = session.prefix
enabled_fandom_addon = False
else:
raise TypeError('session must be MessageSession or QueryInfo.')
2021-10-31 15:59:18 +00:00
if start_wiki is None:
if isinstance(session, MessageSession):
2022-07-31 08:33:20 +00:00
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/')
2021-10-31 15:59:18 +00:00
start_wiki = 'https://minecraft.fandom.com/zh/api.php'
2022-01-27 13:16:53 +00:00
if title is not None:
if isinstance(title, str):
title = [title]
if len(title) > 15:
raise AbuseWarning('一次性查询的页面超出15个。')
query_task = {start_wiki: {'query': [], 'iw_prefix': ''}}
for t in title:
if prefix is not None and use_prefix:
t = prefix + t
if t[0] == ':':
if len(t) > 1:
query_task[start_wiki]['query'].append(t[1:])
else:
match_interwiki = re.match(r'^(.*?):(.*)', t)
2022-06-28 06:59:25 +00:00
matched = False
2022-01-27 13:16:53 +00:00
if match_interwiki:
g1 = match_interwiki.group(1)
g2 = match_interwiki.group(2)
if g1 in interwiki_list:
interwiki_url = interwiki_list[g1]
if interwiki_url not in query_task:
2022-04-08 07:17:39 +00:00
query_task[interwiki_url] = {
'query': [], 'iw_prefix': g1}
2022-01-27 13:16:53 +00:00
query_task[interwiki_url]['query'].append(g2)
2022-06-28 06:59:25 +00:00
matched = True
2022-01-27 13:16:53 +00:00
elif g1 == 'w' and enabled_fandom_addon:
if match_interwiki := re.match(r'(.*?):(.*)', match_interwiki.group(2)):
if match_interwiki.group(1) == 'c':
if match_interwiki := re.match(r'(.*?):(.*)', match_interwiki.group(2)):
2022-04-08 07:17:39 +00:00
interwiki_split = match_interwiki.group(
1).split('.')
2022-01-27 13:16:53 +00:00
if len(interwiki_split) == 2:
get_link = f'https://{interwiki_split[1]}.fandom.com/api.php'
2022-04-08 07:17:39 +00:00
find = interwiki_split[0] + \
':' + match_interwiki.group(2)
2022-01-27 13:16:53 +00:00
iw = 'w:c:' + interwiki_split[0]
else:
get_link = f'https://{match_interwiki.group(1)}.fandom.com/api.php'
find = match_interwiki.group(2)
iw = 'w:c:' + match_interwiki.group(1)
if get_link not in query_task:
2022-04-08 07:17:39 +00:00
query_task[get_link] = {
'query': [], 'iw_prefix': iw}
2022-01-27 13:16:53 +00:00
query_task[get_link]['query'].append(find)
2022-06-28 06:59:25 +00:00
matched = True
if not matched:
2021-10-31 15:59:18 +00:00
query_task[start_wiki]['query'].append(t)
2022-01-27 13:16:53 +00:00
elif pageid is not None:
2022-06-18 16:21:59 +00:00
if iw == '':
2022-01-27 13:16:53 +00:00
query_task = {start_wiki: {'queryid': [pageid], 'iw_prefix': ''}}
else:
2022-04-08 07:17:39 +00:00
query_task = {interwiki_list[iw]: {
'queryid': [pageid], 'iw_prefix': iw}}
2022-01-27 13:16:53 +00:00
else:
raise ValueError('title or pageid must be specified.')
2022-08-04 07:52:42 +00:00
Logger.debug(query_task)
2021-10-31 15:59:18 +00:00
msg_list = []
wait_msg_list = []
wait_list = []
2022-08-04 15:52:53 +00:00
wait_possible_list = []
2022-01-29 11:25:23 +00:00
render_infobox_list = []
render_section_list = []
2021-12-31 14:44:34 +00:00
dl_list = []
2022-07-18 14:34:31 +00:00
if preset_message is not None:
msg_list.append(Plain(preset_message))
2021-10-31 15:59:18 +00:00
for q in query_task:
current_task = query_task[q]
2022-04-29 16:49:30 +00:00
ready_for_query_pages = current_task['query'] if 'query' in current_task else []
ready_for_query_ids = current_task['queryid'] if 'queryid' in current_task else []
2022-04-08 07:17:39 +00:00
iw_prefix = (current_task['iw_prefix'] +
':') if current_task['iw_prefix'] != '' else ''
2021-10-31 15:59:18 +00:00
try:
tasks = []
for rd in ready_for_query_pages:
2021-11-10 15:05:21 +00:00
if rd == '随机页面':
2022-04-08 07:17:39 +00:00
tasks.append(asyncio.create_task(
WikiLib(q, headers).random_page()))
2021-11-10 15:05:21 +00:00
else:
if template:
rd = f'Template:{rd}'
if mediawiki:
rd = f'MediaWiki:{rd}'
2022-04-08 07:17:39 +00:00
tasks.append(asyncio.ensure_future(
WikiLib(q, headers).parse_page_info(title=rd, inline=inline_mode, lang=lang)))
2022-01-27 13:16:53 +00:00
for rdp in ready_for_query_ids:
2022-04-08 07:17:39 +00:00
tasks.append(asyncio.ensure_future(
WikiLib(q, headers).parse_page_info(pageid=rdp, inline=inline_mode, lang=lang)))
2021-10-31 15:59:18 +00:00
query = await asyncio.gather(*tasks)
for result in query:
2022-08-04 07:52:42 +00:00
Logger.debug(result.__dict__)
2021-10-31 15:59:18 +00:00
r: PageInfo = result
display_title = None
display_before_title = None
if r.title is not None:
display_title = iw_prefix + r.title
if r.before_title is not None:
display_before_title = iw_prefix + r.before_title
2022-08-04 15:52:53 +00:00
new_possible_title_list = []
if r.possible_research_title is not None:
for possible in r.possible_research_title:
new_possible_title_list.append(iw_prefix + possible)
r.possible_research_title = new_possible_title_list
2021-10-31 15:59:18 +00:00
if r.status:
plain_slice = []
2021-11-19 12:50:13 +00:00
if display_before_title is not None and display_before_title != display_title:
2021-10-31 15:59:18 +00:00
if r.before_page_property == 'template' and r.page_property == 'page':
2022-04-08 07:17:39 +00:00
plain_slice.append(
f'[{display_before_title}]不存在,已自动重定向至[{display_title}]')
2021-10-31 15:59:18 +00:00
else:
2022-04-08 07:17:39 +00:00
plain_slice.append(
f'(重定向[{display_before_title}] -> [{display_title}]')
2022-05-12 15:26:11 +00:00
if r.desc is not None and r.desc != '':
plain_slice.append(r.desc)
2021-10-31 15:59:18 +00:00
if r.link is not None:
2022-04-08 07:17:39 +00:00
plain_slice.append(
str(Url(r.link, use_mm=not r.info.in_allowlist)))
2022-09-01 15:34:38 +00:00
2021-10-31 15:59:18 +00:00
if r.file is not None:
2021-12-31 14:44:34 +00:00
dl_list.append(r.file)
2022-09-01 15:34:38 +00:00
plain_slice.append('此页面包含以下文件:\n' + r.file)
2021-10-31 15:59:18 +00:00
else:
2022-01-29 11:25:23 +00:00
if r.link is not None and r.section is None:
2022-04-08 07:17:39 +00:00
render_infobox_list.append(
2022-04-13 15:36:55 +00:00
{r.link: {'url': r.info.realurl, 'in_allowlist': r.info.in_allowlist}})
2022-01-29 11:25:23 +00:00
elif r.link is not None and r.section is not None and r.info.in_allowlist:
2022-04-08 07:17:39 +00:00
render_section_list.append(
{r.link: {'url': r.info.realurl, 'section': r.section}})
2022-09-01 15:34:38 +00:00
if plain_slice:
msg_list.append(Plain('\n'.join(plain_slice)))
2021-10-31 15:59:18 +00:00
else:
plain_slice = []
wait_plain_slice = []
2021-11-06 13:27:11 +00:00
if display_title is not None and display_before_title is not None:
2022-01-16 13:24:15 +00:00
if isinstance(session, MessageSession) and session.Feature.wait:
2022-08-04 15:52:53 +00:00
if len(r.possible_research_title) > 1:
wait_plain_slice.append(
f'提示:[{display_before_title}]不存在,您是否想要找的是:')
pi = 0
for p in r.possible_research_title:
pi += 1
wait_plain_slice.append(
f'{pi}. {p}')
wait_plain_slice.append(f'请回复指定序号获取对应内容,若回复“是”,'
f'则默认选择{str(r.possible_research_title.index(display_title) + 1)}号内容。')
wait_possible_list.append({display_before_title: {display_title: r.possible_research_title}})
else:
wait_plain_slice.append(
f'提示:[{display_before_title}]不存在,您是否想要找的是[{display_title}]')
2022-01-16 13:24:15 +00:00
else:
2022-04-08 07:17:39 +00:00
wait_plain_slice.append(
f'提示:[{display_before_title}]不存在,您可能要找的是:[{display_title}]。')
2022-08-04 15:52:53 +00:00
if len(r.possible_research_title) == 1:
wait_list.append({display_title: display_before_title})
2021-11-06 13:27:11 +00:00
elif r.before_title is not None:
plain_slice.append(f'提示:找不到[{display_before_title}]。')
2022-01-27 13:16:53 +00:00
elif r.id != -1:
plain_slice.append(f'提示找不到ID为{str(r.id)}的页面。')
2021-11-17 13:17:13 +00:00
if r.desc is not None and r.desc != '':
2021-11-10 15:05:21 +00:00
plain_slice.append(r.desc)
2021-11-06 13:27:11 +00:00
if r.invalid_namespace and r.before_title is not None:
2022-04-08 07:17:39 +00:00
plain_slice.append(
f'此Wiki上没有名为{r.invalid_namespace}的命名空间,请检查拼写后再试。')
2022-05-17 16:05:19 +00:00
if r.before_page_property == 'template':
if r.before_title.split(':')[1].isupper():
plain_slice.append(
f'提示:机器人暂不支持魔术字。')
2021-11-06 13:27:11 +00:00
if plain_slice:
msg_list.append(Plain('\n'.join(plain_slice)))
if wait_plain_slice:
2022-04-08 07:17:39 +00:00
wait_msg_list.append(
Plain('\n'.join(wait_plain_slice)))
2021-10-31 15:59:18 +00:00
except WhatAreUDoingError:
raise AbuseWarning('使机器人重定向页面的次数过多。')
2021-11-12 14:25:53 +00:00
except InvalidWikiError as e:
2022-06-18 11:19:54 +00:00
if isinstance(session, MessageSession):
await session.sendMessage(f'发生错误:' + str(e))
else:
2022-06-18 11:23:37 +00:00
msg_list.append(Plain(f'发生错误:' + str(e)))
if isinstance(session, MessageSession):
if msg_list:
2022-08-04 15:52:53 +00:00
if all([not render_infobox_list, not render_section_list, not dl_list, not wait_list, not wait_possible_list]):
2022-05-22 13:57:39 +00:00
await session.finish(msg_list)
else:
await session.sendMessage(msg_list)
2022-08-30 13:05:03 +00:00
async def infobox():
if render_infobox_list and session.Feature.image:
infobox_msg_list = []
for i in render_infobox_list:
for ii in i:
get_infobox = await get_pic(i[ii]['url'], ii, headers, allow_special_page=i[ii]['in_allowlist'])
if get_infobox:
infobox_msg_list.append(Image(get_infobox))
if infobox_msg_list:
await session.sendMessage(infobox_msg_list, quote=False)
2022-08-30 13:05:03 +00:00
async def section():
if render_section_list and session.Feature.image:
section_msg_list = []
for i in render_section_list:
for ii in i:
if i[ii]['in_allowlist']:
get_section = await get_pic(i[ii]['url'], ii, headers, section=i[ii]['section'])
if get_section:
section_msg_list.append(Image(get_section))
if section_msg_list:
await session.sendMessage(section_msg_list, quote=False)
2022-08-30 13:05:03 +00:00
async def image_and_voice():
if dl_list:
for f in dl_list:
dl = await download_to_cache(f)
guess_type = filetype.guess(dl)
if guess_type is not None:
if guess_type.extension in ["png", "gif", "jpg", "jpeg", "webp", "bmp", "ico"]:
if session.Feature.image:
await session.sendMessage(Image(dl), quote=False)
elif guess_type.extension in ["oga", "ogg", "flac", "mp3", "wav"]:
if session.Feature.voice:
await session.sendMessage(Voice(dl), quote=False)
2022-08-30 13:05:03 +00:00
async def wait_confirm():
if wait_msg_list and session.Feature.wait:
confirm = await session.waitNextMessage(wait_msg_list, delete=True)
auto_index = False
index = 0
if confirm.asDisplay() in confirm_command:
auto_index = True
elif confirm.asDisplay().isdigit():
index = int(confirm.asDisplay()) - 1
else:
return
preset_message = []
wait_list_ = []
for w in wait_list:
for wd in w:
preset_message.append(f'(已指定[{w[wd]}]更正为[{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]}]。)')
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]}]。)')
wait_list_.append(wp[wpk][keys[0]][index])
if wait_list_:
await query_pages(session, wait_list_, use_prefix=False, preset_message='\n'.join(preset_message),
lang=lang)
2022-08-30 13:05:03 +00:00
asyncio.create_task(infobox())
asyncio.create_task(section())
asyncio.create_task(image_and_voice())
asyncio.create_task(wait_confirm())
else:
2022-01-29 11:25:23 +00:00
return {'msg_list': msg_list, 'web_render_list': render_infobox_list, 'dl_list': dl_list,
'wait_list': wait_list, 'wait_msg_list': wait_msg_list}
2021-11-12 14:25:53 +00:00
rc_ = on_command('rc', desc='获取默认wiki的最近更改', developers=['OasisAkari'])
@rc_.handle()
async def rc_loader(msg: MessageSession):
start_wiki = WikiTargetInfo(msg).get_start_wiki()
if start_wiki is None:
2022-05-21 16:04:29 +00:00
return await msg.finish('未设置起始wiki。')
2021-11-17 16:17:41 +00:00
legacy = True
2021-11-12 14:25:53 +00:00
if msg.Feature.forward and msg.target.targetFrom == 'QQ|Group':
2021-11-17 16:17:41 +00:00
try:
nodelist = await rc_qq(start_wiki)
await msg.fake_forward_msg(nodelist)
legacy = False
except Exception:
traceback.print_exc()
2022-05-21 16:04:29 +00:00
await msg.finish('无法发送转发消息,已自动回滚至传统样式。')
2021-11-17 16:17:41 +00:00
legacy = True
if legacy:
2021-11-12 14:25:53 +00:00
res = await rc(start_wiki)
2022-05-21 16:04:29 +00:00
await msg.finish(res)
2021-11-12 14:25:53 +00:00
a = on_command('ab', desc='获取默认wiki的最近滥用日志', developers=['OasisAkari'])
@a.handle()
async def ab_loader(msg: MessageSession):
start_wiki = WikiTargetInfo(msg).get_start_wiki()
if start_wiki is None:
2022-05-21 16:04:29 +00:00
return await msg.finish('未设置起始wiki。')
2021-11-17 16:17:41 +00:00
legacy = True
2021-11-12 14:25:53 +00:00
if msg.Feature.forward and msg.target.targetFrom == 'QQ|Group':
2021-11-17 16:17:41 +00:00
try:
nodelist = await ab_qq(start_wiki)
await msg.fake_forward_msg(nodelist)
legacy = False
except Exception:
traceback.print_exc()
2022-05-21 16:04:29 +00:00
await msg.finish('无法发送转发消息,已自动回滚至传统样式。')
2021-11-17 16:17:41 +00:00
legacy = True
if legacy:
2021-11-12 14:25:53 +00:00
res = await ab(start_wiki)
2022-05-21 16:04:29 +00:00
await msg.finish(res)
2021-11-12 14:25:53 +00:00
n = on_command('newbie', desc='获取默认wiki的新用户', developers=['OasisAkari'])
@n.handle()
async def newbie_loader(msg: MessageSession):
start_wiki = WikiTargetInfo(msg).get_start_wiki()
if start_wiki is None:
2022-05-21 16:04:29 +00:00
return await msg.finish('未设置起始wiki。')
2021-11-12 14:25:53 +00:00
res = await newbie(start_wiki)
2022-05-21 16:04:29 +00:00
await msg.finish(res)