265 lines
8.4 KiB
Python
265 lines
8.4 KiB
Python
import random
|
||
from typing import Optional
|
||
import opencc
|
||
|
||
from nonebot.adapters import Event as BaseEvent
|
||
from nonebot.adapters.discord.event import MessageEvent as DiscordMessageEvent
|
||
from nonebot_plugin_alconna import (
|
||
Alconna,
|
||
Args,
|
||
UniMessage,
|
||
UniMsg,
|
||
on_alconna,
|
||
)
|
||
|
||
from konabot.common.web_render import konaweb
|
||
from konabot.common.web_render.core import WebRenderer
|
||
from konabot.plugins.hanzi.er_data import ErFontData
|
||
|
||
convert_type = ["简","簡","繁","正","港","日"]
|
||
|
||
compiled_str = "|".join([f"{a}{mid}{b}" for mid in ["转","轉","転"] for a in convert_type for b in convert_type if a != b])
|
||
|
||
def hanzi_to_abbr(hanzi: str) -> str:
|
||
mapping = {
|
||
"简": "s",
|
||
"簡": "s",
|
||
"繁": "t",
|
||
"正": "t",
|
||
"港": "hk",
|
||
"日": "jp",
|
||
"二": "er",
|
||
}
|
||
return mapping.get(hanzi, "")
|
||
|
||
def check_valid_convert_type(convert_type: str) -> bool:
|
||
avaliable_set = ["s2t","t2s","s2tw","tw2s","s2hk","hk2s","s2twp","tw2sp","t2tw","hk2t","t2hk","t2jp","jp2t","tw2t"]
|
||
if convert_type in avaliable_set:
|
||
return True
|
||
return False
|
||
|
||
def convert(source, src_abbr, dst_abbr):
|
||
if dst_abbr == "er":
|
||
# 直接转换为二简
|
||
return ErFontData.convert_text(source)
|
||
convert_type_key = f"{src_abbr}2{dst_abbr}"
|
||
if not check_valid_convert_type(convert_type_key):
|
||
# 先转为繁体,再转为目标
|
||
converter = opencc.OpenCC(f"{src_abbr}2t.json")
|
||
source = converter.convert(source)
|
||
src_abbr = "t"
|
||
converter = opencc.OpenCC(f"{src_abbr}2{dst_abbr}.json")
|
||
converted = converter.convert(source)
|
||
return converted
|
||
|
||
evt = on_alconna(
|
||
Alconna(
|
||
f"re:({compiled_str})",
|
||
Args["source?", str],
|
||
),
|
||
use_cmd_start=True,
|
||
use_cmd_sep=False,
|
||
skip_for_unmatch=True,
|
||
)
|
||
|
||
@evt.handle()
|
||
async def _(msg: UniMsg, event: BaseEvent, source: Optional[str] = None):
|
||
if isinstance(event, DiscordMessageEvent):
|
||
content = event.get_message().extract_plain_text()
|
||
else:
|
||
content = event.get_message().extract_plain_text()
|
||
|
||
prefix = content.split()[0]
|
||
to_convert = ""
|
||
# 如果回复了消息,则转换回复的内容
|
||
if(source is None):
|
||
if event.reply:
|
||
to_convert = event.reply.message.extract_plain_text()
|
||
if not to_convert:
|
||
return
|
||
else:
|
||
return
|
||
else:
|
||
to_convert = source
|
||
parts = []
|
||
if "转" in prefix:
|
||
parts = prefix.split("转")
|
||
elif "轉" in prefix:
|
||
parts = prefix.split("轉")
|
||
elif "転" in prefix:
|
||
parts = prefix.split("転")
|
||
if len(parts) != 2:
|
||
notice = "转换格式错误,请使用“简转繁”、“繁转简”等格式。"
|
||
await evt.send(await UniMessage().text(notice).export())
|
||
return
|
||
src, dst = parts
|
||
src_abbr = hanzi_to_abbr(src)
|
||
dst_abbr = hanzi_to_abbr(dst)
|
||
if not src_abbr or not dst_abbr:
|
||
notice = "不支持的转换类型,请使用“简”、“繁”、“正”、“港”、“日”等。"
|
||
if src_abbr:
|
||
notice = convert(notice, "s", src_abbr)
|
||
await evt.send(await UniMessage().text(notice).export())
|
||
return
|
||
|
||
converted = convert(to_convert, src_abbr, dst_abbr)
|
||
|
||
converted_prefix = convert("转换结果", "s", dst_abbr)
|
||
await evt.send(await UniMessage().text(f"{converted_prefix}:{converted}").export())
|
||
|
||
shuo = ["说","說"]
|
||
|
||
full_name_type = ["简体","簡體","繁體","繁体","正體","正体","港話","港话","日文","二简","二簡"]
|
||
|
||
combined_list = [f"{a}{b}" for a in shuo for b in full_name_type]
|
||
|
||
compiled_str_2 = "|".join(combined_list)
|
||
|
||
evt = on_alconna(
|
||
Alconna(
|
||
f"re:({compiled_str_2})",
|
||
Args["source?", str]
|
||
),
|
||
use_cmd_start=True,
|
||
use_cmd_sep=False,
|
||
skip_for_unmatch=True,
|
||
)
|
||
|
||
@evt.handle()
|
||
async def _(msg: UniMsg, event: BaseEvent, source: Optional[str] = None):
|
||
if isinstance(event, DiscordMessageEvent):
|
||
content = event.get_message().extract_plain_text()
|
||
else:
|
||
content = event.get_message().extract_plain_text()
|
||
|
||
prefix = content.split()[0]
|
||
to_convert = ""
|
||
# 如果回复了消息,则转换回复的内容
|
||
if(source is None):
|
||
if event.reply:
|
||
to_convert = event.reply.message.extract_plain_text()
|
||
if not to_convert:
|
||
return
|
||
else:
|
||
return
|
||
else:
|
||
to_convert = source
|
||
# 获取目标转换类型
|
||
dst = ""
|
||
match prefix:
|
||
case "说简体" | "說簡體" | "说簡體" | "說简体":
|
||
dst = "简"
|
||
case "說繁體" | "说繁体" | "說繁体" | "说繁體":
|
||
dst = "繁"
|
||
case "說正體" | "说正体" | "說正体" | "说正體":
|
||
dst = "正"
|
||
case "說港話" | "说港话" | "說港话" | "说港話":
|
||
dst = "港"
|
||
case "說日文" | "说日文":
|
||
dst = "日"
|
||
case "說二簡" | "说二简" | "說二簡" | "说二簡":
|
||
dst = "二"
|
||
dst_abbr = hanzi_to_abbr(dst)
|
||
if not dst_abbr:
|
||
notice = "不支持的转换类型,请使用“简体”、“繁體”、“正體”、“港話”、“日文”、“二简”等。"
|
||
await evt.send(await UniMessage().text(notice).export())
|
||
return
|
||
# 如果是二简,直接转换
|
||
if dst_abbr == "er":
|
||
current_text = ErFontData.convert_text(to_convert)
|
||
else:
|
||
# 循环,将源语言一次次转换为目标语言
|
||
current_text = to_convert
|
||
for src_abbr in ["s","hk","jp","tw","t"]:
|
||
if src_abbr != dst_abbr:
|
||
current_text = convert(current_text, src_abbr, dst_abbr)
|
||
|
||
converted_prefix = convert("转换结果", "s", dst_abbr)
|
||
|
||
if "span" in current_text:
|
||
# 改为网页渲染
|
||
render_result = await render_with_web_renderer(current_text)
|
||
await evt.send(await UniMessage().image(raw=render_result).export())
|
||
else:
|
||
await evt.send(await UniMessage().text(f"{converted_prefix}:{current_text}").export())
|
||
|
||
async def render_with_web_renderer(text: str) -> bytes:
|
||
async def page_function(page):
|
||
# 找到id为content的文本框
|
||
await page.wait_for_selector('textarea[name=content]')
|
||
# 填入文本
|
||
await page.locator('textarea[name=content]').fill(text)
|
||
|
||
out = await WebRenderer.render_with_persistent_page(
|
||
"markdown_renderer",
|
||
konaweb('old_font'),
|
||
target='#main',
|
||
other_function=page_function,
|
||
)
|
||
|
||
return out
|
||
|
||
def random_char(char: str) -> str:
|
||
dst_abbr = random.choice(["s","t","hk","jp","tw"])
|
||
for src_abbr in ["s","hk","jp","tw","t"]:
|
||
if src_abbr != dst_abbr:
|
||
char = convert(char, src_abbr, dst_abbr)
|
||
return char
|
||
|
||
def random_string(text: str) -> str:
|
||
final_text = ""
|
||
for char in text:
|
||
final_text += random_char(char)
|
||
return final_text
|
||
|
||
random_match = ["混乱字形","混亂字形","乱数字形","亂數字形","ランダム字形"]
|
||
|
||
evt = on_alconna(
|
||
Alconna(
|
||
f"re:({'|'.join(random_match)})",
|
||
Args["source?", str]
|
||
),
|
||
use_cmd_start=True,
|
||
use_cmd_sep=False,
|
||
skip_for_unmatch=True,
|
||
)
|
||
@evt.handle()
|
||
async def _(msg: UniMsg, event: BaseEvent, source: Optional[str] = None):
|
||
if isinstance(event, DiscordMessageEvent):
|
||
content = event.get_message().extract_plain_text()
|
||
else:
|
||
content = event.get_message().extract_plain_text()
|
||
|
||
prefix = content.split()[0]
|
||
to_convert = ""
|
||
# 如果回复了消息,则转换回复的内容
|
||
if(source is None):
|
||
if event.reply:
|
||
to_convert = event.reply.message.extract_plain_text()
|
||
if not to_convert:
|
||
return
|
||
else:
|
||
return
|
||
else:
|
||
to_convert = source
|
||
|
||
final_text = ""
|
||
final_text = random_string(to_convert)
|
||
converted_prefix = convert(random_string("转换结果"), "s", "s")
|
||
|
||
await evt.send(await UniMessage().text(f"{converted_prefix}:{final_text}").export())
|
||
|
||
def get_char(char: str, abbr: str) -> str:
|
||
output = ""
|
||
for src_abbr in ["s","hk","jp","tw","t"]:
|
||
if src_abbr != abbr:
|
||
output += convert(char, src_abbr, abbr)
|
||
return output
|
||
|
||
def get_all_variants(char: str) -> str:
|
||
output = ""
|
||
for abbr in ["s","hk","jp","tw","t"]:
|
||
for src_abbr in ["s","hk","jp","tw","t"]:
|
||
if src_abbr != abbr:
|
||
output += convert(char, src_abbr, abbr)
|
||
return output |