nonebot-plugin-latex 0.0.2.2__py3-none-any.whl → 0.0.3__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,13 +13,13 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13
13
  See the Mulan PSL v2 for more details.
14
14
  """
15
15
 
16
- from nonebot import get_plugin_config
16
+ from nonebot import get_plugin_config, get_driver
17
17
  from nonebot.plugin import PluginMetadata
18
18
 
19
19
  from .config import Config
20
- from .converter import converter
20
+ from .converter import _converter, get_converter
21
21
 
22
- __version__ = "0.0.2.2"
22
+ __version__ = "0.0.3"
23
23
 
24
24
  __author__ = "Eilles"
25
25
 
@@ -27,11 +27,22 @@ __plugin_meta__ = PluginMetadata(
27
27
  name="LaTeX图形渲染插件",
28
28
  description="从互联网服务渲染LaTeX公式并发送",
29
29
  usage="发送 latex 或 公式,后接内容或回复公式信息。",
30
- type="application",
31
- homepage="https://github.com/LiteyukiStudio/nonebot-plugin-marshoai",
30
+ type="library",
31
+ homepage="https://github.com/EillesWan/nonebot-plugin-latex",
32
+ config=Config,
33
+ supported_adapters={
34
+ "~onebot.v11",
35
+ },
32
36
  extra={"License": "Mulan PSL v2", "Author": __author__},
33
37
  )
34
38
 
39
+ __all__ = ["get_converter"]
40
+
41
+
42
+ @get_driver().on_startup
43
+ async def init():
44
+ await _converter.load_channel()
45
+
35
46
 
36
47
  config = get_plugin_config(Config)
37
48
 
@@ -1,6 +1,13 @@
1
1
  from .data import ConvertLatex
2
2
 
3
- converter = ConvertLatex()
3
+ _converter = ConvertLatex()
4
4
  """
5
5
  Latex 渲染器
6
6
  """
7
+
8
+
9
+ def get_converter() -> ConvertLatex:
10
+ """
11
+ 获取渲染器
12
+ """
13
+ return _converter
@@ -13,10 +13,23 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13
13
  See the Mulan PSL v2 for more details.
14
14
  """
15
15
 
16
- from typing import Optional, Literal, Tuple
17
- import httpx
18
- import time
19
16
  import re
17
+ import time
18
+ import asyncio
19
+ from typing import Literal, Optional, Tuple
20
+
21
+ import httpx
22
+ from nonebot import logger
23
+
24
+
25
+ # 正则匹配 LaTeX 公式内容
26
+ LATEX_PATTERN = re.compile(
27
+ r"\\begin\{equation\}(.*?)\\end\{equation\}|(?<!\$)(\$(.*?)\$|\$\$(.*?)\$\$|\\\[(.*?)\\\]|\\\[.*?\\\]|\\\((.*?)\\\))",
28
+ re.DOTALL,
29
+ )
30
+
31
+
32
+ MAX_TIME = 0xFFFFFF
20
33
 
21
34
 
22
35
  class ConvertChannel:
@@ -33,8 +46,8 @@ class ConvertChannel:
33
46
  return False, "请勿直接调用母类"
34
47
 
35
48
  @staticmethod
36
- def channel_test() -> int:
37
- return -1
49
+ async def channel_test() -> int:
50
+ return MAX_TIME
38
51
 
39
52
 
40
53
  class L2PChannel(ConvertChannel):
@@ -52,6 +65,7 @@ class L2PChannel(ConvertChannel):
52
65
 
53
66
  async with httpx.AsyncClient(
54
67
  timeout=timeout,
68
+ verify=False,
55
69
  ) as client:
56
70
  while retry > 0:
57
71
  try:
@@ -87,36 +101,38 @@ class L2PChannel(ConvertChannel):
87
101
  return False, "未知错误"
88
102
 
89
103
  @staticmethod
90
- def channel_test() -> int:
91
- with httpx.Client(timeout=5) as client:
104
+ async def channel_test() -> int:
105
+ async with httpx.AsyncClient(timeout=5, verify=False) as client:
92
106
  try:
93
107
  start_time = time.time_ns()
94
108
  latex2png = (
95
- client.get(
109
+ await client.get(
96
110
  "http://www.latex2png.com{}"
97
- + client.post(
98
- "http://www.latex2png.com/api/convert",
99
- json={
100
- "auth": {"user": "guest", "password": "guest"},
101
- "latex": "\\\\int_{a}^{b} x^2 \\\\, dx = \\\\frac{b^3}{3} - \\\\frac{a^3}{5}\n",
102
- "resolution": 600,
103
- "color": "000000",
104
- },
111
+ + (
112
+ await client.post(
113
+ "http://www.latex2png.com/api/convert",
114
+ json={
115
+ "auth": {"user": "guest", "password": "guest"},
116
+ "latex": "\\\\int_{a}^{b} x^2 \\\\, dx = \\\\frac{b^3}{3} - \\\\frac{a^3}{5}\n",
117
+ "resolution": 600,
118
+ "color": "000000",
119
+ },
120
+ )
105
121
  ).json()["url"]
106
122
  ),
107
123
  time.time_ns() - start_time,
108
124
  )
109
125
  except:
110
- return 99999
126
+ return MAX_TIME
111
127
  if latex2png[0].status_code == 200:
112
128
  return latex2png[1]
113
129
  else:
114
- return 99999
130
+ return MAX_TIME
115
131
 
116
132
 
117
133
  class CDCChannel(ConvertChannel):
118
134
 
119
- URL = "http://latex.codecogs.com"
135
+ URL = "https://latex.codecogs.com"
120
136
 
121
137
  async def get_to_convert(
122
138
  self,
@@ -128,6 +144,7 @@ class CDCChannel(ConvertChannel):
128
144
  ) -> Tuple[Literal[True], bytes] | Tuple[Literal[False], bytes | str]:
129
145
  async with httpx.AsyncClient(
130
146
  timeout=timeout,
147
+ verify=False,
131
148
  ) as client:
132
149
 
133
150
  while retry > 0:
@@ -152,27 +169,27 @@ class CDCChannel(ConvertChannel):
152
169
  return False, "未知错误"
153
170
 
154
171
  @staticmethod
155
- def channel_test() -> int:
156
- with httpx.Client(timeout=5) as client:
172
+ async def channel_test() -> int:
173
+ async with httpx.AsyncClient(timeout=5, verify=False) as client:
157
174
  try:
158
175
  start_time = time.time_ns()
159
176
  codecogs = (
160
- client.get(
161
- r"http://latex.codecogs.com/png.image?\huge%20\dpi{600}\\int_{a}^{b}x^2\\,dx=\\frac{b^3}{3}-\\frac{a^3}{5}"
177
+ await client.get(
178
+ r"https://latex.codecogs.com/png.image?\huge%20\dpi{600}\\int_{a}^{b}x^2\\,dx=\\frac{b^3}{3}-\\frac{a^3}{5}"
162
179
  ),
163
180
  time.time_ns() - start_time,
164
181
  )
165
182
  except:
166
- return 99999
183
+ return MAX_TIME
167
184
  if codecogs[0].status_code == 200:
168
185
  return codecogs[1]
169
186
  else:
170
- return 99999
187
+ return MAX_TIME
171
188
 
172
189
 
173
190
  class JRTChannel(ConvertChannel):
174
191
 
175
- URL = "http://latex2image.joeraut.com"
192
+ URL = "https://latex2image.joeraut.com"
176
193
 
177
194
  async def get_to_convert(
178
195
  self,
@@ -185,6 +202,7 @@ class JRTChannel(ConvertChannel):
185
202
 
186
203
  async with httpx.AsyncClient(
187
204
  timeout=timeout,
205
+ verify=False,
188
206
  ) as client:
189
207
  while retry > 0:
190
208
  try:
@@ -196,7 +214,6 @@ class JRTChannel(ConvertChannel):
196
214
  "outputScale": "{}%".format(dpi / 3 * 5),
197
215
  },
198
216
  )
199
- print(post_response)
200
217
  if post_response.status_code == 200:
201
218
 
202
219
  if not (json_response := post_response.json())["error"]:
@@ -218,29 +235,31 @@ class JRTChannel(ConvertChannel):
218
235
  return False, "未知错误"
219
236
 
220
237
  @staticmethod
221
- def channel_test() -> int:
222
- with httpx.Client(timeout=5) as client:
238
+ async def channel_test() -> int:
239
+ async with httpx.AsyncClient(timeout=5, verify=False) as client:
223
240
  try:
224
241
  start_time = time.time_ns()
225
242
  joeraut = (
226
- client.get(
227
- client.post(
228
- "http://www.latex2png.com/api/convert",
229
- json={
230
- "latexInput": "\\\\int_{a}^{b} x^2 \\\\, dx = \\\\frac{b^3}{3} - \\\\frac{a^3}{5}",
231
- "outputFormat": "PNG",
232
- "outputScale": "1000%",
233
- },
243
+ await client.get(
244
+ (
245
+ await client.post(
246
+ "http://www.latex2png.com/api/convert",
247
+ json={
248
+ "latexInput": "\\\\int_{a}^{b} x^2 \\\\, dx = \\\\frac{b^3}{3} - \\\\frac{a^3}{5}",
249
+ "outputFormat": "PNG",
250
+ "outputScale": "1000%",
251
+ },
252
+ )
234
253
  ).json()["imageUrl"]
235
254
  ),
236
255
  time.time_ns() - start_time,
237
256
  )
238
257
  except:
239
- return 99999
258
+ return MAX_TIME
240
259
  if joeraut[0].status_code == 200:
241
260
  return joeraut[1]
242
261
  else:
243
- return 99999
262
+ return MAX_TIME
244
263
 
245
264
 
246
265
  CHANNEL_LIST: list[type[ConvertChannel]] = [L2PChannel, CDCChannel, JRTChannel]
@@ -248,20 +267,17 @@ CHANNEL_LIST: list[type[ConvertChannel]] = [L2PChannel, CDCChannel, JRTChannel]
248
267
 
249
268
  class ConvertLatex:
250
269
 
251
- channel: ConvertChannel
252
-
253
- def __init__(self, channel: Optional[ConvertChannel] = None) -> None:
254
- """
255
- LaTeX在线渲染类
270
+ channel: Optional[ConvertChannel]
256
271
 
257
- Args:
258
- channel (Optional[ConvertChannel], optional):
259
- 选择何种在线转换通道,若为空,则自动选择延迟最低的通道。默认为空。
260
- [WARNING] 请注意!选择通道时采取的是同步函数,因此可能造成阻塞。
261
- """
272
+ def __init__(self, channel: Optional[ConvertChannel] = None):
273
+ self.channel = channel
274
+ logger.info("LaTeX 转换服务将在 Bot 连接时异步加载")
262
275
 
276
+ async def load_channel(self, channel: ConvertChannel | None = None) -> None:
263
277
  if channel is None:
264
- self.channel = self.auto_choose_channel()
278
+ logger.info("正在选择 LaTeX 转换服务频道,请稍等...")
279
+ self.channel = await self.auto_choose_channel()
280
+ logger.info(f"已选择 {self.channel.__class__.__name__} 服务频道")
265
281
  else:
266
282
  self.channel = channel
267
283
 
@@ -276,8 +292,7 @@ class ConvertLatex:
276
292
  """
277
293
  LaTeX 在线渲染
278
294
 
279
- 参数
280
- ====
295
+ 参数:
281
296
 
282
297
  latex: str
283
298
  LaTeX 代码
@@ -289,26 +304,37 @@ class ConvertLatex:
289
304
  超时时间
290
305
  retry_: int
291
306
  重试次数
292
- 返回
293
- ====
307
+ 返回:
294
308
  bytes
295
309
  图片
296
310
  """
297
- return await self.channel.get_to_convert(
311
+ if self.channel is None:
312
+ await self.load_channel()
313
+
314
+ return await self.channel.get_to_convert( # type: ignore
298
315
  latex, dpi, foreground_colour, timeout_, retry_
299
316
  )
300
317
 
301
318
  @staticmethod
302
- def auto_choose_channel() -> ConvertChannel:
319
+ async def auto_choose_channel() -> ConvertChannel:
320
+ """
321
+ 依据访问延迟,自动选择 LaTeX 转换服务频道
303
322
 
304
- return min(
305
- CHANNEL_LIST,
306
- key=lambda channel: channel.channel_test(),
307
- )()
323
+ 返回
324
+ ====
325
+ ConvertChannel
326
+ LaTeX 转换服务实例
327
+ """
308
328
 
329
+ async def channel_test_wrapper(
330
+ channel: type[ConvertChannel],
331
+ ) -> Tuple[int, type[ConvertChannel]]:
332
+ score = await channel.channel_test()
333
+ return score, channel
309
334
 
310
- # 正则匹配 LaTeX 公式内容
311
- LATEX_PATTERN = re.compile(
312
- r"\\begin\{equation\}(.*?)\\end\{equation\}|(?<!\$)(\$(.*?)\$|\$\$(.*?)\$\$|\\\[(.*?)\\\]|\\\[.*?\\\]|\\\((.*?)\\\))",
313
- re.DOTALL,
314
- )
335
+ return min(
336
+ await asyncio.gather(
337
+ *(channel_test_wrapper(channel) for channel in CHANNEL_LIST)
338
+ ),
339
+ key=lambda x: x[0],
340
+ )[1]()
@@ -14,8 +14,8 @@ See the Mulan PSL v2 for more details.
14
14
  """
15
15
 
16
16
  import nonebot
17
- from nonebot.adapters.onebot.v11 import MessageEvent
18
17
 
18
+ from nonebot.adapters.onebot.v11 import MessageEvent
19
19
 
20
20
  # from nonebot.matcher import Matcher
21
21
 
@@ -29,7 +29,7 @@ from nonebot_plugin_alconna import (
29
29
  )
30
30
 
31
31
  from .data import LATEX_PATTERN
32
- from .converter import converter
32
+ from .converter import _converter
33
33
 
34
34
  command_heads = (
35
35
  "latex",
@@ -69,6 +69,7 @@ async def check_for_scan(
69
69
  # print("判断:这不是指令")
70
70
  return False
71
71
  return False
72
+ return False
72
73
 
73
74
 
74
75
  latexg = nonebot.on_message(
@@ -103,7 +104,7 @@ async def handle_pic(
103
104
 
104
105
  for tex_macher in latexes:
105
106
  tex = tex_macher.group().replace("$", "")
106
- if (result := await converter.generate_png(tex))[0]:
107
+ if (result := await _converter.generate_png(tex))[0]:
107
108
  result_msg.append(
108
109
  Alconna_Image(raw=result[1], mimetype="image/png", name="latex.png") # type: ignore
109
110
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nonebot-plugin-latex
3
- Version: 0.0.2.2
3
+ Version: 0.0.3
4
4
  Summary: 通过互联网公共服务渲染LaTeX公式
5
5
  Author-email: Eilles <EillesWan@outlook.com>
6
6
  License: 木兰宽松许可证, 第2版
@@ -136,14 +136,10 @@ Project-URL: Bug Tracker, https://github.com/EillesWan/nonebot-plugin-latex/issu
136
136
  Requires-Python: <4.0,>=3.9
137
137
  Description-Content-Type: text/markdown
138
138
  License-File: LICENSE
139
- Requires-Dist: playwright>=1.17.2
140
- Requires-Dist: nonebot2>=2.2.0
141
- Requires-Dist: jinja2>=3.0.3
142
- Requires-Dist: markdown>=3.3.6
143
- Requires-Dist: Pygments>=2.10.0
144
- Requires-Dist: python-markdown-math>=0.8
145
- Requires-Dist: pymdown-extensions>=9.1
146
- Requires-Dist: aiofiles>=0.8.0
139
+ Requires-Dist: nonebot2
140
+ Requires-Dist: httpx<0.28.0,>=0.27.0
141
+ Requires-Dist: nonebot-adapter-onebot
142
+ Requires-Dist: nonebot-plugin-alconna
147
143
 
148
144
  # nonebot-plugin-latex
149
145
 
@@ -168,3 +164,8 @@ latex_enable_as_application = true
168
164
  ```
169
165
 
170
166
  这样就可以使用 `latex` 命令进行渲染了,例如 `latex $E=mc^2$` 就会返回这个方程式的渲染图片。
167
+
168
+ ## 提交
169
+
170
+ 各位可以搭建自己的 LaTeX 在线渲染服务,或者直接本地渲染,如果提交到本仓库,在下不胜感激。\
171
+ 对于本地渲染服务,请不要使用 nonebot-plugin-htmlrender
@@ -0,0 +1,10 @@
1
+ nonebot_plugin_latex/__init__.py,sha256=fIXI5w5E0KYMTqIVYWAMoogjzMHLE9V2wEFzNYUY40A,1476
2
+ nonebot_plugin_latex/config.py,sha256=5WOJF-vsuLqGTDGgklpMm-xLd_qdwVb0VCq-n8EwoJQ,198
3
+ nonebot_plugin_latex/converter.py,sha256=rTyeJoZOhXciLcfZ6FWOe0mHczmd2E_sTrqEbJRZ6d8,194
4
+ nonebot_plugin_latex/data.py,sha256=ygcJClUUM4lNR9PotPC1E0rtrRq1swanPWIBnwAvcWM,11443
5
+ nonebot_plugin_latex/main.py,sha256=mMbng0Eo1J3gnztTKbJe_PH63qMgJFZ6Ooj4EY8QKx4,3538
6
+ nonebot_plugin_latex-0.0.3.dist-info/LICENSE,sha256=ISc-fUbtRp39lxd4MpdVr2Saz7XF2yik0RTSRNuhlaM,9375
7
+ nonebot_plugin_latex-0.0.3.dist-info/METADATA,sha256=OWrGenR2OJ2mSyU-C2-kNAWt4XCaU_YZGEdBfE1QX2k,11737
8
+ nonebot_plugin_latex-0.0.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
9
+ nonebot_plugin_latex-0.0.3.dist-info/top_level.txt,sha256=AEtxXrscUdkhTvgg--hAE9WRsW0QVttzK2H-fI9xbGs,21
10
+ nonebot_plugin_latex-0.0.3.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- nonebot_plugin_latex/__init__.py,sha256=sX4NN2jsnbkd4RqLiT0INoRAi0vGgxuSmh40U-6iCZ8,1267
2
- nonebot_plugin_latex/config.py,sha256=5WOJF-vsuLqGTDGgklpMm-xLd_qdwVb0VCq-n8EwoJQ,198
3
- nonebot_plugin_latex/converter.py,sha256=08RmFCBrUda8PlnqazX71aHjntBzlSOJc_ZeUHfMQ_M,89
4
- nonebot_plugin_latex/data.py,sha256=S_KjGkOBGdJMUeKYRfhJ8yllJgbhg1XjPXyypJQ3CFA,10427
5
- nonebot_plugin_latex/main.py,sha256=uBN1bQm-i55RimDfwpOPMOx3bkCuPe-vli2NTzuoXRg,3518
6
- nonebot_plugin_latex-0.0.2.2.dist-info/LICENSE,sha256=ISc-fUbtRp39lxd4MpdVr2Saz7XF2yik0RTSRNuhlaM,9375
7
- nonebot_plugin_latex-0.0.2.2.dist-info/METADATA,sha256=SGjgpPfQFtnqKJ0RU-trNf_18pBT4-kZr0Xygqm10P4,11656
8
- nonebot_plugin_latex-0.0.2.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
9
- nonebot_plugin_latex-0.0.2.2.dist-info/top_level.txt,sha256=AEtxXrscUdkhTvgg--hAE9WRsW0QVttzK2H-fI9xbGs,21
10
- nonebot_plugin_latex-0.0.2.2.dist-info/RECORD,,