模块 nonebot_plugin_marshoai.deal_latex
此文件援引并改编自 nonebot-plugin-latex 数据类 源项目地址: https://github.com/EillesWan/nonebot-plugin-latex
Copyright (c) 2024 金羿Eilles nonebot-plugin-latex is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2 THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details.
class ConvertChannel
async func get_to_convert(self, latex_code: str, dpi: int = 600, fgcolour: str = '000000', timeout: int = 5, retry: int = 3) -> Tuple[Literal[True], bytes] | Tuple[Literal[False], bytes | str]
源代码 或 在GitHub上查看
python
async def get_to_convert(self, latex_code: str, dpi: int=600, fgcolour: str='000000', timeout: int=5, retry: int=3) -> Tuple[Literal[True], bytes] | Tuple[Literal[False], bytes | str]:
return (False, '请勿直接调用母类')
async func channel_test() -> int
源代码 或 在GitHub上查看
python
@staticmethod
async def channel_test() -> int:
return -1
attr URL: str = NO_DEFAULT
class L2PChannel(ConvertChannel)
async func get_to_convert(self, latex_code: str, dpi: int = 600, fgcolour: str = '000000', timeout: int = 5, retry: int = 3) -> Tuple[Literal[True], bytes] | Tuple[Literal[False], bytes | str]
源代码 或 在GitHub上查看
python
async def get_to_convert(self, latex_code: str, dpi: int=600, fgcolour: str='000000', timeout: int=5, retry: int=3) -> Tuple[Literal[True], bytes] | Tuple[Literal[False], bytes | str]:
async with httpx.AsyncClient(timeout=timeout, verify=False) as client:
while retry > 0:
try:
post_response = await client.post(self.URL + '/api/convert', json={'auth': {'user': 'guest', 'password': 'guest'}, 'latex': latex_code, 'resolution': dpi, 'color': fgcolour})
if post_response.status_code == 200:
if (json_response := post_response.json())['result-message'] == 'success':
if (get_response := (await client.get(self.URL + json_response['url']))).status_code == 200:
return (True, get_response.content)
else:
return (False, json_response['result-message'])
retry -= 1
except httpx.TimeoutException:
retry -= 1
raise ConnectionError('服务不可用')
return (False, '未知错误')
async func channel_test() -> int
源代码 或 在GitHub上查看
python
@staticmethod
async def channel_test() -> int:
async with httpx.AsyncClient(timeout=5, verify=False) as client:
try:
start_time = time.time_ns()
latex2png = (await client.get('http://www.latex2png.com{}' + (await client.post('http://www.latex2png.com/api/convert', json={'auth': {'user': 'guest', 'password': 'guest'}, 'latex': '\\\\int_{a}^{b} x^2 \\\\, dx = \\\\frac{b^3}{3} - \\\\frac{a^3}{5}\n', 'resolution': 600, 'color': '000000'})).json()['url']), time.time_ns() - start_time)
except:
return 99999
if latex2png[0].status_code == 200:
return latex2png[1]
else:
return 99999
attr URL = 'http://www.latex2png.com'
class CDCChannel(ConvertChannel)
async func get_to_convert(self, latex_code: str, dpi: int = 600, fgcolour: str = '000000', timeout: int = 5, retry: int = 3) -> Tuple[Literal[True], bytes] | Tuple[Literal[False], bytes | str]
源代码 或 在GitHub上查看
python
async def get_to_convert(self, latex_code: str, dpi: int=600, fgcolour: str='000000', timeout: int=5, retry: int=3) -> Tuple[Literal[True], bytes] | Tuple[Literal[False], bytes | str]:
async with httpx.AsyncClient(timeout=timeout, verify=False) as client:
while retry > 0:
try:
response = await client.get(self.URL + '/png.image?\\huge&space;\\dpi{' + str(dpi) + '}\\fg{' + fgcolour + '}' + latex_code)
if response.status_code == 200:
return (True, response.content)
else:
return (False, response.content)
retry -= 1
except httpx.TimeoutException:
retry -= 1
return (False, '未知错误')
async func channel_test() -> int
源代码 或 在GitHub上查看
python
@staticmethod
async def channel_test() -> int:
async with httpx.AsyncClient(timeout=5, verify=False) as client:
try:
start_time = time.time_ns()
codecogs = (await client.get('https://latex.codecogs.com/png.image?\\huge%20\\dpi{600}\\\\int_{a}^{b}x^2\\\\,dx=\\\\frac{b^3}{3}-\\\\frac{a^3}{5}'), time.time_ns() - start_time)
except:
return 99999
if codecogs[0].status_code == 200:
return codecogs[1]
else:
return 99999
attr URL = 'https://latex.codecogs.com'
class JRTChannel(ConvertChannel)
async func get_to_convert(self, latex_code: str, dpi: int = 600, fgcolour: str = '000000', timeout: int = 5, retry: int = 3) -> Tuple[Literal[True], bytes] | Tuple[Literal[False], bytes | str]
源代码 或 在GitHub上查看
python
async def get_to_convert(self, latex_code: str, dpi: int=600, fgcolour: str='000000', timeout: int=5, retry: int=3) -> Tuple[Literal[True], bytes] | Tuple[Literal[False], bytes | str]:
async with httpx.AsyncClient(timeout=timeout, verify=False) as client:
while retry > 0:
try:
post_response = await client.post(self.URL + '/default/latex2image', json={'latexInput': latex_code, 'outputFormat': 'PNG', 'outputScale': '{}%'.format(dpi / 3 * 5)})
if post_response.status_code == 200:
if not (json_response := post_response.json())['error']:
if (get_response := (await client.get(json_response['imageUrl']))).status_code == 200:
return (True, get_response.content)
else:
return (False, json_response['error'])
retry -= 1
except httpx.TimeoutException:
retry -= 1
raise ConnectionError('服务不可用')
return (False, '未知错误')
async func channel_test() -> int
源代码 或 在GitHub上查看
python
@staticmethod
async def channel_test() -> int:
async with httpx.AsyncClient(timeout=5, verify=False) as client:
try:
start_time = time.time_ns()
joeraut = (await client.get((await client.post('http://www.latex2png.com/api/convert', json={'latexInput': '\\\\int_{a}^{b} x^2 \\\\, dx = \\\\frac{b^3}{3} - \\\\frac{a^3}{5}', 'outputFormat': 'PNG', 'outputScale': '1000%'})).json()['imageUrl']), time.time_ns() - start_time)
except:
return 99999
if joeraut[0].status_code == 200:
return joeraut[1]
else:
return 99999
attr URL = 'https://latex2image.joeraut.com'
class ConvertLatex
func __init__(self, channel: Optional[ConvertChannel] = None)
源代码 或 在GitHub上查看
python
def __init__(self, channel: Optional[ConvertChannel]=None):
logger.info('LaTeX 转换服务将在 Bot 连接时异步加载')
async func load_channel(self, channel: ConvertChannel | None = None) -> None
源代码 或 在GitHub上查看
python
async def load_channel(self, channel: ConvertChannel | None=None) -> None:
if channel is None:
logger.info('正在选择 LaTeX 转换服务频道,请稍等...')
self.channel = await self.auto_choose_channel()
logger.info(f'已选择 {self.channel.__class__.__name__} 服务频道')
else:
self.channel = channel
async func generate_png(self, latex: str, dpi: int = 600, foreground_colour: str = '000000', timeout_: int = 5, retry_: int = 3) -> Tuple[Literal[True], bytes] | Tuple[Literal[False], bytes | str]
说明: LaTeX 在线渲染
源代码 或 在GitHub上查看
python
async def generate_png(self, latex: str, dpi: int=600, foreground_colour: str='000000', timeout_: int=5, retry_: int=3) -> Tuple[Literal[True], bytes] | Tuple[Literal[False], bytes | str]:
return await self.channel.get_to_convert(latex, dpi, foreground_colour, timeout_, retry_)
async func auto_choose_channel() -> ConvertChannel
源代码 或 在GitHub上查看
python
@staticmethod
async def auto_choose_channel() -> ConvertChannel:
async def channel_test_wrapper(channel: type[ConvertChannel]) -> Tuple[int, type[ConvertChannel]]:
score = await channel.channel_test()
return (score, channel)
results = await asyncio.gather(*(channel_test_wrapper(channel) for channel in channel_list))
best_channel = min(results, key=lambda x: x[0])[1]
return best_channel()