2023-01-28 05:53:11 +00:00
|
|
|
|
import asyncio
|
2023-01-19 15:10:08 +00:00
|
|
|
|
import os
|
2023-01-28 05:53:11 +00:00
|
|
|
|
import subprocess
|
2023-01-20 07:43:52 +00:00
|
|
|
|
import sys
|
2023-01-19 15:10:08 +00:00
|
|
|
|
|
2023-02-05 14:33:33 +00:00
|
|
|
|
from core.builtins import Bot
|
2023-01-17 02:59:22 +00:00
|
|
|
|
from core.component import on_command
|
2023-01-28 05:53:11 +00:00
|
|
|
|
from core.exceptions import NoReportException
|
2023-01-19 17:21:08 +00:00
|
|
|
|
from core.logger import Logger
|
|
|
|
|
|
2023-01-17 02:59:22 +00:00
|
|
|
|
c = on_command('calc', developers=[
|
2023-01-19 15:10:08 +00:00
|
|
|
|
'Dianliang233'], desc='安全地计算 Python ast 表达式。')
|
2023-01-17 02:59:22 +00:00
|
|
|
|
|
|
|
|
|
|
2023-01-19 08:55:12 +00:00
|
|
|
|
@c.handle('<math_expression>', options_desc={'+': '和/正数:1 + 2 -> 3',
|
|
|
|
|
'-': '差/负数:3 - 1 -> 2',
|
2023-01-17 02:59:22 +00:00
|
|
|
|
'/': '商:6 / 3 -> 2',
|
|
|
|
|
'*': '积:2 * 3 -> 6',
|
2023-01-20 14:47:39 +00:00
|
|
|
|
'**': 'x 的 y 次幂(由于性能问题,指数不得超过 4e+6):2 ** 3 -> 8',
|
2023-01-17 02:59:22 +00:00
|
|
|
|
'%': '取模:5 % 2 -> 1',
|
|
|
|
|
'==': '等于:1 == 1 -> True',
|
|
|
|
|
'<=': '小于等于:1 <= 2 -> True',
|
2023-01-20 14:47:39 +00:00
|
|
|
|
'>=': '大于等于:1 >= 2 -> False',
|
2023-01-17 02:59:22 +00:00
|
|
|
|
'>>': 'x 右移 y 位(相当于 x / (2 ** y),y < 10000):32 >> 5 -> 1',
|
|
|
|
|
'<<': 'x 左移 y 位(相当于 x * (2 ** y),y < 10000):1 << 5 -> 32',
|
2023-01-20 08:37:18 +00:00
|
|
|
|
'^': '按位异或:1 ^ 1 -> 0',
|
2023-01-19 08:55:12 +00:00
|
|
|
|
'not': '非:not True -> False',
|
|
|
|
|
'is': 'x 与 y 是同一个对象:1 is 1 -> True',
|
2023-01-17 02:59:22 +00:00
|
|
|
|
'randint(x)': '小于 x 的随机整数:randint(6) -> 5',
|
|
|
|
|
'rand()': '0 与 1 之间的随机浮点数:rand() -> 0.5789015836448923',
|
|
|
|
|
'int()': '转换为整数:int(1.5) -> 1',
|
|
|
|
|
'float()': '转换为浮点数:float(1) -> 1.0',
|
|
|
|
|
'str()': '转换为字符串:str(1) -> "1"',
|
2023-01-20 08:45:13 +00:00
|
|
|
|
'complex()': '转换为复数:complex(1) -> (1 + 0j)',
|
2023-01-20 14:47:39 +00:00
|
|
|
|
'bool()': '转换为布尔值:bool(1) -> True',
|
2023-01-21 07:11:13 +00:00
|
|
|
|
'bin()': '转换为二进制:bin(268) -> 0b100001100',
|
|
|
|
|
'oct()': '转换为八进制:oct(268) -> 0o414',
|
|
|
|
|
'hex()': '转换为十六进制:hex(268) -> 0x10c',
|
2023-01-20 14:47:39 +00:00
|
|
|
|
'更多可用运算符和函数': 'https://bot.teahouse.team/-/340',
|
2023-01-17 02:59:22 +00:00
|
|
|
|
})
|
2023-02-05 14:33:33 +00:00
|
|
|
|
async def _(msg: Bot.MessageSession):
|
2023-01-22 12:28:09 +00:00
|
|
|
|
expr = msg.asDisplay().split(' ', 1)[1]
|
2023-01-20 08:01:07 +00:00
|
|
|
|
if sys.platform == 'win32' and sys.version_info.minor < 10:
|
2023-01-19 17:13:11 +00:00
|
|
|
|
try:
|
2023-01-20 07:43:52 +00:00
|
|
|
|
res = subprocess.check_output(
|
2023-01-22 12:28:09 +00:00
|
|
|
|
['python', os.path.abspath("./modules/calc/calc.py"), expr], timeout=10, shell=False).decode('utf-8')
|
2023-01-20 07:43:52 +00:00
|
|
|
|
if res[0:6] == 'Result':
|
2023-01-22 12:28:09 +00:00
|
|
|
|
await msg.finish(f'{(expr)} = {res[7:]}')
|
2023-01-20 07:43:52 +00:00
|
|
|
|
else:
|
2023-01-20 07:46:05 +00:00
|
|
|
|
await msg.finish(f'表达式无效:{res[7:]}')
|
2023-01-20 07:43:52 +00:00
|
|
|
|
except subprocess.TimeoutExpired:
|
2023-01-19 17:13:11 +00:00
|
|
|
|
raise NoReportException('计算超时。')
|
2023-01-20 07:43:52 +00:00
|
|
|
|
else:
|
|
|
|
|
try:
|
2023-01-22 12:28:09 +00:00
|
|
|
|
p = await asyncio.create_subprocess_exec('python', os.path.abspath("./modules/calc/calc.py"), expr,
|
2023-01-21 09:01:10 +00:00
|
|
|
|
stdout=asyncio.subprocess.PIPE,
|
|
|
|
|
stderr=asyncio.subprocess.PIPE
|
|
|
|
|
)
|
2023-01-20 07:43:52 +00:00
|
|
|
|
try:
|
|
|
|
|
await asyncio.wait_for(p.wait(), timeout=10)
|
|
|
|
|
except asyncio.TimeoutError:
|
|
|
|
|
p.kill()
|
|
|
|
|
raise NoReportException('计算超时。')
|
|
|
|
|
stdout_data, stderr_data = await p.communicate()
|
|
|
|
|
if p.returncode == 0:
|
|
|
|
|
res = stdout_data.decode('utf-8')
|
2023-01-19 17:13:11 +00:00
|
|
|
|
|
2023-01-20 07:43:52 +00:00
|
|
|
|
if res[0:6] == 'Result':
|
2023-01-22 12:28:09 +00:00
|
|
|
|
await msg.finish(f'{(expr)} = {res[7:]}')
|
2023-01-20 07:43:52 +00:00
|
|
|
|
else:
|
2023-01-20 07:46:05 +00:00
|
|
|
|
await msg.finish(f'表达式无效:{res[7:]}')
|
2023-01-19 17:13:11 +00:00
|
|
|
|
else:
|
2023-01-20 07:43:52 +00:00
|
|
|
|
Logger.error(f'calc.py exited with code {p.returncode}')
|
2023-01-21 09:08:04 +00:00
|
|
|
|
try:
|
|
|
|
|
Logger.error(
|
|
|
|
|
f'calc.py stderr: {stderr_data.decode("utf-8")}')
|
|
|
|
|
except UnicodeDecodeError:
|
|
|
|
|
Logger.error(
|
|
|
|
|
f'calc.py stderr: {stderr_data.decode("gbk")}')
|
2023-01-20 07:43:52 +00:00
|
|
|
|
except Exception as e:
|
|
|
|
|
raise NoReportException(e)
|