2023-05-10 15:26:04 +00:00
|
|
|
import asyncio
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import time
|
2023-05-28 09:38:21 +00:00
|
|
|
|
2023-05-11 15:19:55 +00:00
|
|
|
import ujson as json
|
2023-05-10 15:26:04 +00:00
|
|
|
|
|
|
|
from core.builtins import Bot
|
|
|
|
from core.component import module
|
|
|
|
from core.exceptions import NoReportException
|
|
|
|
from core.logger import Logger
|
|
|
|
|
2023-05-10 15:48:59 +00:00
|
|
|
calc_dir = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
2023-05-10 15:26:04 +00:00
|
|
|
c = module('calc', developers=[
|
2023-05-21 03:48:33 +00:00
|
|
|
'Dianliang233'], desc='{calc.help.calc.desc}')
|
2023-05-10 15:26:04 +00:00
|
|
|
|
|
|
|
|
2023-05-21 03:48:33 +00:00
|
|
|
@c.command('<math_expression>', options_desc={'+': '{calc.help.calc.plus}',
|
|
|
|
'-': '{calc.help.calc.minus}',
|
|
|
|
'/': '{calc.help.calc.multiply}',
|
|
|
|
'*': '{calc.help.calc.divide}',
|
|
|
|
'**': '{calc.help.calc.power}',
|
|
|
|
'%': '{calc.help.calc.modulo}',
|
|
|
|
'==': '{calc.help.calc.equal}',
|
|
|
|
'<=': '{calc.help.calc.less_equal}',
|
|
|
|
'>=': '{calc.help.calc.greater_equal}',
|
|
|
|
'>>': '{calc.help.calc.move_right}',
|
|
|
|
'<<': '{calc.help.calc.move_left}',
|
|
|
|
'^': '{calc.help.calc.xor}',
|
|
|
|
'not': '{calc.help.calc.not}',
|
|
|
|
'is': '{calc.help.calc.is}',
|
|
|
|
'randint(x)': '{calc.help.calc.randint}',
|
|
|
|
'rand()': '{calc.help.calc.rand}',
|
|
|
|
'int()': '{calc.help.calc.int}',
|
|
|
|
'float()': '{calc.help.calc.float}',
|
|
|
|
'str()': '{calc.help.calc.str}',
|
|
|
|
'complex()': '{calc.help.calc.complex}',
|
|
|
|
'bool()': '{calc.help.calc.bool}',
|
|
|
|
'bin()': '{calc.help.calc.bin}',
|
|
|
|
'oct()': '{calc.help.calc.oct}',
|
|
|
|
'hex()': '{calc.help.calc.hex}',
|
|
|
|
'{calc.help.calc.more}': 'https://bot.teahouse.team/-/340',
|
2023-05-10 15:26:04 +00:00
|
|
|
})
|
|
|
|
async def _(msg: Bot.MessageSession):
|
|
|
|
expr = msg.asDisplay().split(' ', 1)[1]
|
2023-05-11 15:19:55 +00:00
|
|
|
start = time.perf_counter_ns()
|
|
|
|
res = await spawn_subprocess('/calc.py', expr, msg)
|
|
|
|
stop = time.perf_counter_ns()
|
|
|
|
delta = (stop - start) / 1000000
|
|
|
|
if res[:6] == 'Result':
|
|
|
|
if msg.target.senderFrom == "Discord|Client":
|
|
|
|
m = f'`{(expr)}` = {res[7:]}'
|
|
|
|
else:
|
|
|
|
m = f'{(expr)} = {res[7:]}'
|
|
|
|
if msg.checkSuperUser():
|
|
|
|
m += '\n' + msg.locale.t("calc.message.running_time", time=delta)
|
|
|
|
await msg.finish(m)
|
|
|
|
else:
|
2023-05-21 03:48:33 +00:00
|
|
|
await msg.finish(msg.locale.t("calc.message.calc.invalid", expr={res[7:]}))
|
2023-05-11 15:19:55 +00:00
|
|
|
|
|
|
|
|
2023-05-31 15:00:22 +00:00
|
|
|
factor = module('factor', developers=['DoroWolf', 'Light-Beacon', 'Dianliang233'])
|
2023-05-11 15:19:55 +00:00
|
|
|
|
|
|
|
|
2023-05-21 03:48:33 +00:00
|
|
|
@factor.handle('prime <number> {{calc.help.factor.prime}}')
|
2023-05-11 15:19:55 +00:00
|
|
|
async def prime(msg: Bot.MessageSession):
|
|
|
|
try:
|
2023-05-17 10:43:25 +00:00
|
|
|
num = int(msg.parsed_msg.get('<number>'))
|
2023-05-11 15:19:55 +00:00
|
|
|
if num <= 1:
|
2023-05-17 10:43:25 +00:00
|
|
|
raise ValueError
|
2023-05-11 15:19:55 +00:00
|
|
|
except ValueError:
|
2023-05-21 03:48:33 +00:00
|
|
|
return await msg.finish(msg.locale.t('calc.message.factor.prime.error'))
|
2023-05-11 15:19:55 +00:00
|
|
|
start = time.perf_counter_ns()
|
|
|
|
res = await spawn_subprocess('/factor.py', str(num), msg)
|
|
|
|
stop = time.perf_counter_ns()
|
|
|
|
delta = (stop - start) / 1000000
|
2023-05-11 15:31:12 +00:00
|
|
|
if res[:6] != 'Result':
|
2023-05-11 15:19:55 +00:00
|
|
|
raise ValueError(res)
|
2023-05-11 15:31:12 +00:00
|
|
|
primes = json.loads(res[7:])
|
|
|
|
prime = "*".join(primes)
|
|
|
|
if len(primes) == 1:
|
2023-05-21 03:48:33 +00:00
|
|
|
m = msg.locale.t("calc.message.factor.prime.is_prime", num=num)
|
2023-05-12 10:58:03 +00:00
|
|
|
else:
|
|
|
|
m = (
|
|
|
|
f'{num} = `{prime}`'
|
|
|
|
if msg.target.senderFrom == "Discord|Client"
|
|
|
|
else f'{num} = {prime}'
|
|
|
|
)
|
2023-05-11 15:31:12 +00:00
|
|
|
if msg.checkSuperUser():
|
|
|
|
m += '\n' + msg.locale.t("calc.message.running_time", time=delta)
|
|
|
|
await msg.finish(m)
|
2023-05-11 15:19:55 +00:00
|
|
|
|
|
|
|
|
2023-05-12 10:58:03 +00:00
|
|
|
async def spawn_subprocess(file: str, arg: str, msg: Bot.MessageSession) -> str:
|
2023-05-11 17:18:00 +00:00
|
|
|
envs = os.environ.copy()
|
2023-05-10 15:26:04 +00:00
|
|
|
if sys.platform == 'win32' and sys.version_info.minor < 10:
|
|
|
|
try:
|
2023-05-11 15:19:55 +00:00
|
|
|
return subprocess.check_output(
|
2023-05-12 10:58:03 +00:00
|
|
|
[sys.executable, calc_dir + file, arg], timeout=10, shell=False,
|
2023-05-11 17:18:00 +00:00
|
|
|
cwd=os.path.abspath('.'), env=envs) \
|
2023-05-10 15:26:04 +00:00
|
|
|
.decode('utf-8')
|
2023-05-11 15:31:12 +00:00
|
|
|
except subprocess.TimeoutExpired as e:
|
2023-05-14 01:18:23 +00:00
|
|
|
raise NoReportException(msg.locale.t("calc.message.time_out")) from e
|
2023-05-10 15:26:04 +00:00
|
|
|
else:
|
|
|
|
try:
|
2023-05-11 15:19:55 +00:00
|
|
|
p = await asyncio.create_subprocess_exec(sys.executable, calc_dir + file,
|
2023-05-12 10:58:03 +00:00
|
|
|
arg,
|
2023-05-10 15:26:04 +00:00
|
|
|
stdout=asyncio.subprocess.PIPE,
|
2023-05-11 17:18:00 +00:00
|
|
|
stderr=asyncio.subprocess.PIPE,
|
|
|
|
cwd=os.path.abspath('.'), env=envs
|
2023-05-10 15:26:04 +00:00
|
|
|
)
|
|
|
|
try:
|
|
|
|
await asyncio.wait_for(p.wait(), timeout=10)
|
2023-05-11 15:31:12 +00:00
|
|
|
except asyncio.TimeoutError as e:
|
2023-05-10 15:26:04 +00:00
|
|
|
p.kill()
|
2023-05-11 15:31:12 +00:00
|
|
|
raise NoReportException(msg.locale.t("calc.message.time_out")) from e
|
2023-05-10 15:26:04 +00:00
|
|
|
stdout_data, stderr_data = await p.communicate()
|
2023-05-11 15:19:55 +00:00
|
|
|
if p.returncode != 0:
|
2023-05-11 15:31:12 +00:00
|
|
|
Logger.error(f'{file} exited with code {p.returncode}')
|
2023-05-10 15:26:04 +00:00
|
|
|
try:
|
|
|
|
Logger.error(
|
2023-05-11 15:31:12 +00:00
|
|
|
f'{file} stderr: {stderr_data.decode("utf-8")}')
|
2023-05-10 15:26:04 +00:00
|
|
|
except UnicodeDecodeError:
|
|
|
|
Logger.error(
|
2023-05-11 15:31:12 +00:00
|
|
|
f'{file} stderr: {stderr_data.decode("gbk")}')
|
2023-05-11 15:19:55 +00:00
|
|
|
return stdout_data.decode('utf-8')
|
2023-05-10 15:26:04 +00:00
|
|
|
except Exception as e:
|
2023-05-11 15:31:12 +00:00
|
|
|
raise NoReportException(e) from e
|