Merge branch
This commit is contained in:
commit
b5183a88c0
13 changed files with 254 additions and 130 deletions
|
@ -21,7 +21,7 @@ class ImageTable:
|
|||
self.headers = headers
|
||||
|
||||
|
||||
async def image_table_render(table: Union[ImageTable, List[ImageTable]], save_source=False):
|
||||
async def image_table_render(table: Union[ImageTable, List[ImageTable]], save_source=True):
|
||||
if not web_render:
|
||||
return False
|
||||
try:
|
||||
|
@ -54,7 +54,7 @@ async def image_table_render(table: Union[ImageTable, List[ImageTable]], save_so
|
|||
padding: 15px;
|
||||
text-align: left;
|
||||
}</style>"""
|
||||
html = {'content': tblst + css, 'width': w}
|
||||
html = {'content': tblst + css, 'width': w, 'mw': False}
|
||||
if save_source:
|
||||
fname = random_cache_path() + '.html'
|
||||
with open(fname, 'w') as fi:
|
||||
|
|
|
@ -1,55 +1,31 @@
|
|||
from core.builtins.message import MessageSession
|
||||
from core.component import on_command
|
||||
from simpleeval import InvalidExpression, SimpleEval, DEFAULT_FUNCTIONS, DEFAULT_NAMES, DEFAULT_OPERATORS
|
||||
import ast
|
||||
import operator as op
|
||||
import asyncio
|
||||
import math
|
||||
import os
|
||||
import sys
|
||||
|
||||
from core.exceptions import NoReportException
|
||||
from .constant import consts
|
||||
from core.builtins.message import MessageSession
|
||||
from core.component import on_command
|
||||
|
||||
funcs = {}
|
||||
for name in dir(math):
|
||||
item = getattr(math, name)
|
||||
if not name.startswith('_') and callable(item):
|
||||
funcs[name] = item
|
||||
import asyncio
|
||||
import subprocess
|
||||
|
||||
s_eval = SimpleEval(
|
||||
operators={
|
||||
**DEFAULT_OPERATORS,
|
||||
ast.BitOr: op.or_,
|
||||
ast.BitAnd: op.and_,
|
||||
ast.BitXor: op.xor,
|
||||
ast.Invert: op.invert,
|
||||
},
|
||||
functions={**DEFAULT_FUNCTIONS, **funcs},
|
||||
names={
|
||||
**DEFAULT_NAMES, **consts,
|
||||
'pi': math.pi,
|
||||
'e': math.e,
|
||||
'tau': math.tau,
|
||||
'inf': math.inf, 'nan': math.nan,
|
||||
},)
|
||||
from core.logger import Logger
|
||||
|
||||
c = on_command('calc', developers=[
|
||||
'Dianliang233'], desc='安全地计算 Python ast 表达式。',)
|
||||
'Dianliang233'], desc='安全地计算 Python ast 表达式。')
|
||||
|
||||
|
||||
@c.handle('<math_expression>', options_desc={'+': '和/正数:1 + 2 -> 3',
|
||||
'-': '差/负数:3 - 1 -> 2',
|
||||
'/': '商:6 / 3 -> 2',
|
||||
'//': '整除:7 // 4 -> 1',
|
||||
'*': '积:2 * 3 -> 6',
|
||||
'**': 'x 的 y 次幂(由于性能问题,结果不得超过 4e+6):2 ** 3 -> 8',
|
||||
'**': 'x 的 y 次幂(由于性能问题,指数不得超过 4e+6):2 ** 3 -> 8',
|
||||
'%': '取模:5 % 2 -> 1',
|
||||
'==': '等于:1 == 1 -> True',
|
||||
'<': '小于:1 < 2 -> True',
|
||||
'>': '大于:2 > 1 -> True',
|
||||
'<=': '小于等于:1 <= 2 -> True',
|
||||
'>=': '大于等于:1 >= 2 -> False',
|
||||
'>>': 'x 右移 y 位(相当于 x / (2 ** y),y < 10000):32 >> 5 -> 1',
|
||||
'<<': 'x 左移 y 位(相当于 x * (2 ** y),y < 10000):1 << 5 -> 32',
|
||||
'in': 'x 在 y 中:"hat" in "what" -> True',
|
||||
'^': '按位异或:1 ^ 1 -> 0',
|
||||
'not': '非:not True -> False',
|
||||
'is': 'x 与 y 是同一个对象:1 is 1 -> True',
|
||||
'randint(x)': '小于 x 的随机整数:randint(6) -> 5',
|
||||
|
@ -57,24 +33,51 @@ c = on_command('calc', developers=[
|
|||
'int()': '转换为整数:int(1.5) -> 1',
|
||||
'float()': '转换为浮点数:float(1) -> 1.0',
|
||||
'str()': '转换为字符串:str(1) -> "1"',
|
||||
'更多数学函数': 'https://docs.python.org/zh-cn/3/library/math.html'
|
||||
'complex()': '转换为复数:complex(1) -> (1 + 0j)',
|
||||
'bool()': '转换为布尔值:bool(1) -> True',
|
||||
'bin()': '转换为二进制:bin(268) -> 0b100001100',
|
||||
'oct()': '转换为八进制:oct(268) -> 0o414',
|
||||
'hex()': '转换为十六进制:hex(268) -> 0x10c',
|
||||
'更多可用运算符和函数': 'https://bot.teahouse.team/-/340',
|
||||
})
|
||||
async def _(msg: MessageSession):
|
||||
try:
|
||||
res = await asyncio.wait_for(async_eval(msg.parsed_msg["<math_expression>"]), 15)
|
||||
await msg.finish(f'{(msg.parsed_msg["<math_expression>"])} = {str(res)}')
|
||||
except InvalidExpression as e:
|
||||
await msg.finish(f"表达式无效:{e}")
|
||||
except asyncio.TimeoutError:
|
||||
raise TimeoutException()
|
||||
except Exception as e:
|
||||
raise NoReportException(e)
|
||||
expr = msg.asDisplay().split(' ', 1)[1]
|
||||
if sys.platform == 'win32' and sys.version_info.minor < 10:
|
||||
try:
|
||||
res = subprocess.check_output(
|
||||
['python', os.path.abspath("./modules/calc/calc.py"), expr], timeout=10, shell=False).decode('utf-8')
|
||||
if res[0:6] == 'Result':
|
||||
await msg.finish(f'{(expr)} = {res[7:]}')
|
||||
else:
|
||||
await msg.finish(f'表达式无效:{res[7:]}')
|
||||
except subprocess.TimeoutExpired:
|
||||
raise NoReportException('计算超时。')
|
||||
else:
|
||||
try:
|
||||
p = await asyncio.create_subprocess_exec('python', os.path.abspath("./modules/calc/calc.py"), expr,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
)
|
||||
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')
|
||||
|
||||
|
||||
async def async_eval(expr: str):
|
||||
return s_eval.eval(expr)
|
||||
|
||||
|
||||
class TimeoutException(NoReportException):
|
||||
'''计算超时,最大计算时间为 15 秒。'''
|
||||
pass
|
||||
if res[0:6] == 'Result':
|
||||
await msg.finish(f'{(expr)} = {res[7:]}')
|
||||
else:
|
||||
await msg.finish(f'表达式无效:{res[7:]}')
|
||||
else:
|
||||
Logger.error(f'calc.py exited with code {p.returncode}')
|
||||
try:
|
||||
Logger.error(
|
||||
f'calc.py stderr: {stderr_data.decode("utf-8")}')
|
||||
except UnicodeDecodeError:
|
||||
Logger.error(
|
||||
f'calc.py stderr: {stderr_data.decode("gbk")}')
|
||||
except Exception as e:
|
||||
raise NoReportException(e)
|
||||
|
|
94
modules/calc/calc.py
Normal file
94
modules/calc/calc.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
from constant import consts
|
||||
from simpleeval import EvalWithCompoundTypes, DEFAULT_FUNCTIONS, DEFAULT_NAMES, DEFAULT_OPERATORS
|
||||
import ast
|
||||
import sys
|
||||
import operator as op
|
||||
import math
|
||||
import statistics
|
||||
import cmath
|
||||
import decimal
|
||||
import fractions
|
||||
import os
|
||||
|
||||
if os.name == 'posix':
|
||||
os.nice(15)
|
||||
import resource
|
||||
resource.setrlimit(resource.RLIMIT_AS,
|
||||
(16 * 1024 * 1024, 16 * 1024 * 1024))
|
||||
resource.setrlimit(resource.RLIMIT_DATA,
|
||||
(16 * 1024 * 1024, 16 * 1024 * 1024))
|
||||
resource.setrlimit(resource.RLIMIT_STACK,
|
||||
(16 * 1024 * 1024, 16 * 1024 * 1024))
|
||||
elif os.name == 'nt':
|
||||
import win32process
|
||||
win32process.SetPriorityClass(win32process.GetCurrentProcess(
|
||||
), 16384)
|
||||
win32process.SetProcessWorkingSetSize(
|
||||
win32process.GetCurrentProcess(), 1, 16 * 1024 * 1024)
|
||||
|
||||
funcs = {}
|
||||
named_funcs = {}
|
||||
|
||||
|
||||
def add_func(module):
|
||||
for name in dir(module):
|
||||
item = getattr(module, name)
|
||||
if not name.startswith('_') and callable(item):
|
||||
funcs[name] = item
|
||||
|
||||
|
||||
def add_named_func(module):
|
||||
named_funcs[module.__name__] = {}
|
||||
for name in dir(module):
|
||||
item = getattr(module, name)
|
||||
if not name.startswith('_') and callable(item):
|
||||
named_funcs[module.__name__][name] = item
|
||||
|
||||
|
||||
add_func(math)
|
||||
add_func(statistics)
|
||||
add_named_func(cmath)
|
||||
add_named_func(decimal)
|
||||
add_named_func(fractions)
|
||||
|
||||
s_eval = EvalWithCompoundTypes(
|
||||
operators={
|
||||
**DEFAULT_OPERATORS,
|
||||
ast.BitOr: op.or_,
|
||||
ast.BitAnd: op.and_,
|
||||
ast.BitXor: op.xor,
|
||||
ast.Invert: op.invert,
|
||||
},
|
||||
functions={**funcs, **DEFAULT_FUNCTIONS,
|
||||
'bin': bin,
|
||||
'bool': bool,
|
||||
'complex': complex,
|
||||
'divmod': divmod,
|
||||
'hex': hex,
|
||||
'len': len,
|
||||
'oct': oct,
|
||||
'round': round
|
||||
},
|
||||
names={
|
||||
**DEFAULT_NAMES, **consts, **named_funcs,
|
||||
'pi': math.pi,
|
||||
'e': math.e,
|
||||
'tau': math.tau,
|
||||
'inf': math.inf, 'nan': math.nan,
|
||||
'cmath': {
|
||||
'pi': cmath.pi,
|
||||
'e': cmath.e,
|
||||
'tau': cmath.tau,
|
||||
'inf': cmath.inf,
|
||||
'infj': cmath.infj,
|
||||
'nan': cmath.nan,
|
||||
'nanj': cmath.nanj,
|
||||
**named_funcs['cmath'],
|
||||
},
|
||||
}, )
|
||||
|
||||
try: # rina's rina lazy solution :rina:
|
||||
sys.stdout.write('Result ' + str(s_eval.eval(' '.join(sys.argv[1:]))))
|
||||
except Exception as e:
|
||||
sys.stdout.write('Failed ' + str(e))
|
||||
sys.exit()
|
|
@ -12,7 +12,7 @@ i = on_command('convert', alias=('conv', 'unit'), desc='全能单位转换。',
|
|||
developers=['Dianliang233'])
|
||||
|
||||
|
||||
@i.handle('<from_val> <to_unit> {单位转换。单位原文为英文,由 ChatGPT 翻译生成,欢迎汇报错误。}')
|
||||
@i.handle('<from_val> <to_unit> {单位转换。大小写敏感。单位原文为英文,由 ChatGPT 翻译生成,欢迎汇报错误。}')
|
||||
async def _(msg: MessageSession):
|
||||
from_val = msg.parsed_msg['<from_val>']
|
||||
to_unit = msg.parsed_msg['<to_unit>']
|
||||
|
|
|
@ -132,10 +132,10 @@ count = [] = 个
|
|||
turn = 2 * π * radian = _ = revolution = cycle = circle = 转
|
||||
degree = π / 180 * radian = deg = arcdeg = arcdegree = 度 = 角度
|
||||
arcminute = degree / 60 = arcmin = arc_minute = angular_minute = 弧分 = 角分
|
||||
arcsecond = arcminute / 60 = arcsec = arc_second = angular_second = 角秒 = 角秒
|
||||
arcsecond = arcminute / 60 = arcsec = arc_second = angular_second = 弧秒 = 角秒
|
||||
milliarcsecond = 1e-3 * arcsecond = mas = 毫弧秒 = 毫角秒
|
||||
grade = π / 200 * radian = grad = gon = 百分度 = 梯度
|
||||
mil = π / 32000 * radian = 毫弧度 = 密位
|
||||
milliradian = π / 32000 * radian = mil = 毫弧度 = 密位
|
||||
|
||||
# Solid angle
|
||||
steradian = radian ** 2 = sr = 球面度
|
||||
|
@ -154,13 +154,13 @@ ppm = 1e-6 = 分比
|
|||
|
||||
# Length
|
||||
angstrom = 1e-10 * meter = Å = ångström = Å = 埃格斯特朗 = 埃
|
||||
micron = micrometer = µ = μ = 微米
|
||||
micron = micrometer = µm = μ = 微米
|
||||
fermi = femtometer = fm = 费米
|
||||
light_year = speed_of_light * julian_year = ly = lightyear = 光年
|
||||
astronomical_unit = 149597870700 * meter = au = 天文单位 # since Aug 2012
|
||||
parsec = 1 / tansec * astronomical_unit = pc = 秒差距
|
||||
nautical_mile = 1852 * meter = nmi = 海里
|
||||
bohr = hbar / (alpha * m_e * c) = a_0 = a0 = bohr_radius = atomic_unit_of_length = a_u_length = 波尔
|
||||
nautical_mile = 1852 * meter = nmi = 海里 = 浬
|
||||
bohr = hbar / (alpha * m_e * c) = a_0 = a0 = bohr_radius = atomic_unit_of_length = a_u_length = 玻尔半径 = 原子单位长度
|
||||
x_unit_Cu = K_alpha_Cu_d_220 * d_220 / 1537.4 = Xu_Cu = 铜的X单位 = 铜的X射线波长
|
||||
x_unit_Mo = K_alpha_Mo_d_220 * d_220 / 707.831 = Xu_Mo = 钼的X单位 = 钼的X射线波长
|
||||
angstrom_star = K_alpha_W_d_220 * d_220 / 0.2090100 = Å_star = 埃星
|
||||
|
@ -168,7 +168,7 @@ planck_length = (hbar * gravitational_constant / c ** 3) ** 0.5 = 普朗克长
|
|||
|
||||
|
||||
# Mass
|
||||
metric_ton = 1e3 * kilogram = t = tonne = 公吨
|
||||
metric_ton = 1e3 * kilogram = t = tonne = 吨 = 公吨
|
||||
unified_atomic_mass_unit = atomic_mass_constant = u = amu = 原子质量单位
|
||||
dalton = atomic_mass_constant = Da = 道尔顿
|
||||
grain = 64.79891 * milligram = gr = 格令
|
||||
|
@ -177,22 +177,22 @@ carat = 200 * milligram = ct = karat = 克拉
|
|||
planck_mass = (hbar * c / gravitational_constant) ** 0.5 = 普朗克质量
|
||||
|
||||
# Time
|
||||
minute = 60 * second = min = 分钟
|
||||
minute = 60 * second = min = 分钟 = 分
|
||||
hour = 60 * minute = h = hr = 小时
|
||||
day = 24 * hour = d = 天
|
||||
week = 7 * day = 星期
|
||||
day = 24 * hour = d = 日 = 天
|
||||
week = 7 * day = 星期 = 周 = 礼拜
|
||||
fortnight = 2 * week = 两星期
|
||||
year = 365.25 * day = a = yr = julian_year = 年
|
||||
year = 365.25 * day = a = yr = julian_year = 年 = 儒略年
|
||||
month = year / 12 = 月
|
||||
|
||||
# decade = 10 * year
|
||||
## NOTE: decade [time] can conflict with decade [dimensionless]
|
||||
|
||||
century = 100 * year = _ = centuries = 世纪
|
||||
millennium = 1e3 * year = _ = millennia = 千年
|
||||
millennium = 1e3 * year = _ = millennia = 千年纪 = 千纪 = 千年
|
||||
eon = 1e9 * year = 宙
|
||||
shake = 1e-8 * second = 抖
|
||||
svedberg = 1e-13 * second = 斯维德伯格
|
||||
svedberg = 1e-13 * second = 斯韦德贝里 = 斯维德伯格
|
||||
atomic_unit_of_time = hbar / E_h = a_u_time = 原子单位时间
|
||||
gregorian_year = 365.2425 * day = 公历年
|
||||
sidereal_year = 365.256363004 * day = 恒星年
|
||||
|
@ -202,12 +202,12 @@ leap_year = 366 * day = 闰年
|
|||
sidereal_day = day / 1.00273790935079524 = 恒星日
|
||||
sidereal_month = 27.32166155 * day = 恒星月
|
||||
tropical_month = 27.321582 * day = 回归月
|
||||
synodic_month = 29.530589 * day = _ = lunar_month = 同步月
|
||||
synodic_month = 29.530589 * day = _ = lunar_month = 同步月 = 朔望月
|
||||
planck_time = (hbar * gravitational_constant / c ** 5) ** 0.5 = 普朗克时间
|
||||
|
||||
# Temperature
|
||||
degree_Celsius = kelvin; offset: 273.15 = °C = celsius = degC = degreeC = 摄氏度
|
||||
degree_Rankine = 5 / 9 * kelvin; offset: 0 = °R = rankine = degR = degreeR = 兰氏度
|
||||
degree_Rankine = 5 / 9 * kelvin; offset: 0 = °R = °Ra = rankine = degR = degreeR = 兰氏度
|
||||
degree_Fahrenheit = 5 / 9 * kelvin; offset: 233.15 + 200 / 9 = °F = fahrenheit = degF = degreeF = 华氏度
|
||||
réaumur = 4 / 5 * kelvin; offset: 273.15 = °Re = reaumur = degRe = degreeRe = degree_Réaumur = 列氏度
|
||||
atomic_unit_of_temperature = E_h / k = a_u_temp = 原子单位温度
|
||||
|
@ -215,21 +215,21 @@ planck_temperature = (hbar * c ** 5 / gravitational_constant / k ** 2) ** 0.5 =
|
|||
|
||||
# Area
|
||||
[area] = [length] ** 2
|
||||
are = 100 * meter ** 2
|
||||
b = 1e-28 * meter ** 2 = barn
|
||||
darcy = centipoise * centimeter ** 2 / (second * atmosphere) = 达西
|
||||
ha = 100 * are = hectare
|
||||
|
||||
# Volume
|
||||
[volume] = [length] ** 3
|
||||
are = 100 * meter ** 2 = 公亩
|
||||
barn = 1e-28 * meter ** 2 = b = 贝纳
|
||||
barn = 1e-28 * meter ** 2 = b = 靶恩
|
||||
darcy = centipoise * centimeter ** 2 / (second * atmosphere) = 达西
|
||||
hectare = 100 * are = ha = 公顷
|
||||
|
||||
# Volume
|
||||
[volume] = [length] ** 3
|
||||
liter = decimeter ** 3 = l = L = litre = 升
|
||||
cubic_centimeter = centimeter ** 3 = cc = 立方厘米
|
||||
lambda = microliter = λ
|
||||
stere = meter ** 3
|
||||
|
||||
# Frequency
|
||||
[frequency] = 1 / [time]
|
||||
hertz = 1 / second = Hz = 赫兹
|
||||
hertz = 1 / second = Hz = 赫兹 = 赫
|
||||
revolutions_per_minute = revolution / minute = rpm = 转每分
|
||||
revolutions_per_second = revolution / second = rps = 转每秒
|
||||
counts_per_second = count / second = cps = 次每秒
|
||||
|
@ -242,7 +242,7 @@ reciprocal_centimeter = 1 / cm = cm_1 = kayser = 倒数厘米
|
|||
[velocity] = [length] / [time]
|
||||
[speed] = [velocity]
|
||||
knot = nautical_mile / hour = kt = knot_international = international_knot = 节
|
||||
mile_per_hour = mile / hour = mph = MPH = 英里每小时
|
||||
mile_per_hour = mile / hour = mph = MPH = 英里每小时 = 迈
|
||||
kilometer_per_hour = kilometer / hour = kph = KPH = 千米每小时
|
||||
kilometer_per_second = kilometer / second = kps = 千米每秒
|
||||
meter_per_second = meter / second = mps = 米每秒
|
||||
|
@ -258,11 +258,11 @@ galileo = centimeter / second ** 2 = Gal = 伽利略
|
|||
|
||||
# Force
|
||||
[force] = [mass] * [acceleration]
|
||||
newton = kilogram * meter / second ** 2 = N = 牛顿
|
||||
dyne = gram * centimeter / second ** 2 = dyn = 丁
|
||||
newton = kilogram * meter / second ** 2 = N = 牛顿 = 牛
|
||||
dyne = gram * centimeter / second ** 2 = dyn = 达因
|
||||
force_kilogram = g_0 * kilogram = kgf = kilogram_force = pond = 千克力
|
||||
force_gram = g_0 * gram = gf = gram_force = 克力
|
||||
force_metric_ton = g_0 * metric_ton = tf = metric_ton_force = force_t = t_force = 公吨力
|
||||
force_metric_ton = g_0 * metric_ton = tf = metric_ton_force = force_t = t_force = 公吨力 = 吨力
|
||||
atomic_unit_of_force = E_h / a_0 = a_u_force = 原子单位力
|
||||
|
||||
# Energy
|
||||
|
@ -282,7 +282,7 @@ thermochemical_british_thermal_unit = 1e3 * pound / kilogram * degR / kelvin * c
|
|||
quadrillion_Btu = 1e15 * Btu = quad = 兆英热单位
|
||||
therm = 1e5 * Btu = thm = EC_therm = 热量
|
||||
US_therm = 1.054804e8 * joule = 美国热量
|
||||
ton_TNT = 1e9 * calorie = tTNT = 吨TNT
|
||||
ton_TNT = 1e9 * calorie = tTNT = TNT当量
|
||||
tonne_of_oil_equivalent = 1e10 * international_calorie = toe = 吨油当量
|
||||
atmosphere_liter = atmosphere * liter = atm_l = 气体升
|
||||
|
||||
|
@ -315,18 +315,18 @@ water_60F = 0.999001 * kilogram / liter = 水60华氏度
|
|||
pascal = newton / meter ** 2 = Pa = 帕斯卡
|
||||
barye = dyne / centimeter ** 2 = Ba = barie = barad = barrie = baryd = 微巴
|
||||
bar = 1e5 * pascal = 巴
|
||||
technical_atmosphere = kilogram * g_0 / centimeter ** 2 = at = 技术大气
|
||||
torr = atm / 760 = 托尔
|
||||
pound_force_per_square_inch = force_pound / inch ** 2 = psi = 每平方英寸磅力
|
||||
kip_per_square_inch = kip / inch ** 2 = ksi = 每平方英寸千磅力
|
||||
millimeter_Hg_0C = millimeter * Hg * g_0 = mmHg = mm_Hg = 毫米水银
|
||||
centimeter_Hg_0C = centimeter * Hg * g_0 = cmHg = cm_Hg = 厘米水银
|
||||
inch_Hg_32F = inch * Hg * g_0 = inHg = in_Hg = 英寸水银
|
||||
inch_Hg_60F = inch * Hg_60F * g_0 = 英寸水银60华氏度
|
||||
inch_H2O_39F = inch * water_39F * g_0 = 英寸水39华氏度
|
||||
inch_H2O_60F = inch * water_60F * g_0 = 英寸水60华氏度
|
||||
feet_H2O = foot * water * g_0 = ftH2O = 英尺水
|
||||
cm_H2O = centimeter * water * g_0 = cmH2O = 厘米水
|
||||
technical_atmosphere = kilogram * g_0 / centimeter ** 2 = at = 工程大气压
|
||||
torr = atm / 760 = 托
|
||||
pound_force_per_square_inch = force_pound / inch ** 2 = psi = 磅力每平方英寸
|
||||
kip_per_square_inch = kip / inch ** 2 = ksi = 千磅力每平方英寸
|
||||
millimeter_Hg_0C = millimeter * Hg * g_0 = mmHg = mm_Hg = 毫米汞柱
|
||||
centimeter_Hg_0C = centimeter * Hg * g_0 = cmHg = cm_Hg = 厘米汞柱
|
||||
inch_Hg_32F = inch * Hg * g_0 = inHg = in_Hg = 英寸汞柱
|
||||
inch_Hg_60F = inch * Hg_60F * g_0 = 60华氏度英寸汞柱
|
||||
inch_H2O_39F = inch * water_39F * g_0 = 39华氏度英寸水柱
|
||||
inch_H2O_60F = inch * water_60F * g_0 = 60华氏度英寸水柱
|
||||
feet_H2O = foot * water * g_0 = ftH2O = 英尺水柱
|
||||
centimeter_H2O = cm_H2O = centimeter * water * g_0 = cmH2O = 厘米水柱
|
||||
sound_pressure_level = 20e-6 * pascal = SPL = 声压级
|
||||
|
||||
# Torque
|
||||
|
@ -355,7 +355,7 @@ molar = mole / liter = M = 体积摩尔
|
|||
|
||||
# Catalytic activity
|
||||
[activity] = [substance] / [time]
|
||||
katal = mole / second = kat = 卡塔尔
|
||||
katal = mole / second = kat = 开特
|
||||
enzyme_unit = micromole / minute = U = enzymeunit = 酶单位
|
||||
|
||||
# Entropy
|
||||
|
@ -367,11 +367,11 @@ clausius = calorie / kelvin = Cl = 克劳西斯
|
|||
entropy_unit = calorie / kelvin / mole = eu = 熵单位
|
||||
|
||||
# Radiation
|
||||
becquerel = counts_per_second = Bq = 贝可勒尔
|
||||
becquerel = counts_per_second = Bq = 贝克勒尔 = 贝克
|
||||
curie = 3.7e10 * becquerel = Ci = 居里
|
||||
rutherford = 1e6 * becquerel = Rd = 卢瑟福
|
||||
gray = joule / kilogram = Gy = 格雷
|
||||
sievert = joule / kilogram = Sv = 西弗
|
||||
gray = joule / kilogram = Gy = 戈瑞
|
||||
sievert = joule / kilogram = Sv = 希沃特
|
||||
rads = 0.01 * gray = 拉德斯
|
||||
rem = 0.01 * sievert = 雷质
|
||||
roentgen = 2.58e-4 * coulomb / kilogram = _ = röntgen = 伦琴
|
||||
|
@ -400,7 +400,7 @@ lux = lumen / meter ** 2 = lx = 勒克斯
|
|||
atomic_unit_of_intensity = 0.5 * ε_0 * c * atomic_unit_of_electric_field ** 2 = a_u_intensity = 原子单位光强
|
||||
|
||||
# Current
|
||||
biot = 10 * ampere = Bi = 比奥
|
||||
biot = 10 * ampere = Bi = 毕奥
|
||||
abampere = biot = abA = 绝对安培
|
||||
atomic_unit_of_current = e / atomic_unit_of_time = a_u_current = 原子单位电流
|
||||
mean_international_ampere = mean_international_volt / mean_international_ohm = A_it = 平均国际安培
|
||||
|
@ -418,7 +418,7 @@ ampere_hour = ampere * hour = Ah = 安培时
|
|||
|
||||
# Electric potential
|
||||
[electric_potential] = [energy] / [charge]
|
||||
volt = joule / coulomb = V = 伏特
|
||||
volt = joule / coulomb = V = 伏特 = 伏
|
||||
abvolt = 1e-8 * volt = abV = 绝对伏特
|
||||
mean_international_volt = 1.00034 * volt = V_it = 平均国际伏特 # approximate
|
||||
US_international_volt = 1.00033 * volt = V_US = 美国国际伏特 # approximate
|
||||
|
@ -433,7 +433,7 @@ atomic_unit_of_electric_field = e * k_C / a_0 ** 2 = a_u_electric_field = 原子
|
|||
|
||||
# Resistance
|
||||
[resistance] = [electric_potential] / [current]
|
||||
ohm = volt / ampere = Ω = 欧姆
|
||||
ohm = volt / ampere = Ω = 欧姆 = 欧
|
||||
abohm = 1e-9 * ohm = abΩ = 绝对欧姆
|
||||
mean_international_ohm = 1.00049 * ohm = Ω_it = ohm_it = 平均国际欧姆 # approximate
|
||||
US_international_ohm = 1.000495 * ohm = Ω_US = ohm_US = 美国国际欧姆 # approximate
|
||||
|
@ -444,7 +444,7 @@ conventional_ohm_90 = R_K / R_K90 * ohm = Ω_90 = ohm_90 = 传统欧姆90
|
|||
|
||||
# Conductance
|
||||
[conductance] = [current] / [electric_potential]
|
||||
siemens = ampere / volt = S = mho = 西门子
|
||||
siemens = ampere / volt = S = mho = 西门子 = 西门
|
||||
absiemens = 1e9 * siemens = abS = abmho = 绝对西门子
|
||||
|
||||
# Capacitance
|
||||
|
|
|
@ -11,7 +11,9 @@ from database import BotDBUtil
|
|||
|
||||
module = on_command('module',
|
||||
base=True,
|
||||
alias={'enable': 'module enable', 'disable': 'module disable','reload':'module reload'},
|
||||
alias={'enable': 'module enable',
|
||||
'disable': 'module disable',
|
||||
'reload':'module reload'},
|
||||
developers=['OasisAkari','Light-Beacon'],
|
||||
required_admin=True
|
||||
)
|
||||
|
@ -44,9 +46,11 @@ async def _(msg: MessageSession):
|
|||
|
||||
async def config_modules(msg: MessageSession):
|
||||
alias = ModulesManager.return_modules_alias_map()
|
||||
modules_ = ModulesManager.return_modules_list_as_dict(targetFrom=msg.target.targetFrom)
|
||||
modules_ = ModulesManager.return_modules_list_as_dict(
|
||||
targetFrom=msg.target.targetFrom)
|
||||
enabled_modules_list = BotDBUtil.TargetInfo(msg).enabled_modules
|
||||
wait_config = [msg.parsed_msg.get('<module>')] + msg.parsed_msg.get('...', [])
|
||||
wait_config = [msg.parsed_msg.get(
|
||||
'<module>')] + msg.parsed_msg.get('...', [])
|
||||
wait_config_list = []
|
||||
for module_ in wait_config:
|
||||
if module_ not in wait_config_list:
|
||||
|
@ -64,7 +68,7 @@ async def config_modules(msg: MessageSession):
|
|||
if function[0] == '_':
|
||||
continue
|
||||
if isinstance(modules_[function], Command) and (
|
||||
modules_[function].base or modules_[function].required_superuser):
|
||||
modules_[function].base or modules_[function].required_superuser):
|
||||
continue
|
||||
enable_list.append(function)
|
||||
else:
|
||||
|
@ -103,7 +107,8 @@ async def config_modules(msg: MessageSession):
|
|||
recommend_modules_help_doc_list.append(f'模块{m}的帮助信息:')
|
||||
|
||||
if modules_[m].desc is not None:
|
||||
recommend_modules_help_doc_list.append(modules_[m].desc)
|
||||
recommend_modules_help_doc_list.append(
|
||||
modules_[m].desc)
|
||||
if isinstance(modules_[m], Command):
|
||||
hdoc = CommandParser(modules_[m], msg=msg, bind_prefix=modules_[m].bind_prefix,
|
||||
command_prefixes=msg.prefixes).return_formatted_help_doc()
|
||||
|
@ -117,7 +122,7 @@ async def config_modules(msg: MessageSession):
|
|||
if function[0] == '_':
|
||||
continue
|
||||
if isinstance(modules_[function], Command) and (
|
||||
modules_[function].base or modules_[function].required_superuser):
|
||||
modules_[function].base or modules_[function].required_superuser):
|
||||
continue
|
||||
disable_list.append(function)
|
||||
else:
|
||||
|
@ -178,7 +183,6 @@ async def config_modules(msg: MessageSession):
|
|||
await msg.finish()
|
||||
|
||||
|
||||
|
||||
hlp = on_command('help',
|
||||
base=True,
|
||||
developers=['OasisAkari', 'Dianliang233'],
|
||||
|
@ -187,7 +191,8 @@ hlp = on_command('help',
|
|||
|
||||
@hlp.handle('<module> {查看一个模块的详细信息}')
|
||||
async def bot_help(msg: MessageSession):
|
||||
module_list = ModulesManager.return_modules_list_as_dict(targetFrom=msg.target.targetFrom)
|
||||
module_list = ModulesManager.return_modules_list_as_dict(
|
||||
targetFrom=msg.target.targetFrom)
|
||||
developers = ModulesManager.return_modules_developers_map()
|
||||
alias = ModulesManager.return_modules_alias_map()
|
||||
if msg.parsed_msg is not None:
|
||||
|
@ -215,7 +220,8 @@ async def bot_help(msg: MessageSession):
|
|||
if help_name in developers:
|
||||
dev_list = developers[help_name]
|
||||
if isinstance(dev_list, (list, tuple)):
|
||||
devs = '、'.join(developers[help_name]) if developers[help_name] is not None else ''
|
||||
devs = '、'.join(
|
||||
developers[help_name]) if developers[help_name] is not None else ''
|
||||
elif isinstance(dev_list, str):
|
||||
devs = dev_list
|
||||
else:
|
||||
|
@ -223,6 +229,7 @@ async def bot_help(msg: MessageSession):
|
|||
else:
|
||||
devs = ''
|
||||
devs_msg = '\n模块作者:' + devs if devs != '' else ''
|
||||
wiki_msg = f'\n模块文档:https://bot.teahouse.team/wiki/' + help_name
|
||||
await msg.finish(doc + devs_msg)
|
||||
else:
|
||||
await msg.finish('此模块可能不存在,请检查输入。')
|
||||
|
@ -230,7 +237,8 @@ async def bot_help(msg: MessageSession):
|
|||
|
||||
@hlp.handle('{查看帮助列表}')
|
||||
async def _(msg: MessageSession):
|
||||
module_list = ModulesManager.return_modules_list_as_dict(targetFrom=msg.target.targetFrom)
|
||||
module_list = ModulesManager.return_modules_list_as_dict(
|
||||
targetFrom=msg.target.targetFrom)
|
||||
target_enabled_list = msg.enabled_modules
|
||||
developers = ModulesManager.return_modules_developers_map()
|
||||
legacy_help = True
|
||||
|
@ -256,18 +264,21 @@ async def _(msg: MessageSession):
|
|||
doc_.append(module_.desc)
|
||||
doc = '\n'.join(doc_)
|
||||
appends.append(doc)
|
||||
module_alias = ModulesManager.return_module_alias(module_.bind_prefix)
|
||||
module_alias = ModulesManager.return_module_alias(
|
||||
module_.bind_prefix)
|
||||
malias = []
|
||||
for a in module_alias:
|
||||
malias.append(f'{a} -> {module_alias[a]}')
|
||||
appends.append('\n'.join(malias) if malias else '')
|
||||
appends.append('、'.join(developers[x]) if developers.get(x) is not None else '')
|
||||
appends.append('、'.join(developers[x]) if developers.get(
|
||||
x) is not None else '')
|
||||
if isinstance(module_, Command) and module_.base:
|
||||
essential.append(appends)
|
||||
if x in target_enabled_list:
|
||||
m.append(appends)
|
||||
if essential:
|
||||
tables.append(ImageTable(essential, ['基础模块列表', '帮助信息', '命令别名', '作者']))
|
||||
tables.append(ImageTable(
|
||||
essential, ['基础模块列表', '帮助信息', '命令别名', '作者']))
|
||||
if m:
|
||||
tables.append(ImageTable(m, ['扩展模块列表', '帮助信息', '命令别名', '作者']))
|
||||
if tables:
|
||||
|
@ -306,7 +317,8 @@ async def _(msg: MessageSession):
|
|||
|
||||
|
||||
async def modules_help(msg: MessageSession):
|
||||
module_list = ModulesManager.return_modules_list_as_dict(targetFrom=msg.target.targetFrom)
|
||||
module_list = ModulesManager.return_modules_list_as_dict(
|
||||
targetFrom=msg.target.targetFrom)
|
||||
developers = ModulesManager.return_modules_developers_map()
|
||||
legacy_help = True
|
||||
if web_render and msg.Feature.image:
|
||||
|
@ -322,7 +334,8 @@ async def modules_help(msg: MessageSession):
|
|||
appends = [module_.bind_prefix]
|
||||
doc_ = []
|
||||
if isinstance(module_, Command):
|
||||
help_ = CommandParser(module_, bind_prefix=module_.bind_prefix, command_prefixes=msg.prefixes)
|
||||
help_ = CommandParser(
|
||||
module_, bind_prefix=module_.bind_prefix, command_prefixes=msg.prefixes)
|
||||
if module_.desc is not None:
|
||||
doc_.append(module_.desc)
|
||||
if help_.args is not None:
|
||||
|
@ -332,12 +345,14 @@ async def modules_help(msg: MessageSession):
|
|||
doc_.append(module_.desc)
|
||||
doc = '\n'.join(doc_)
|
||||
appends.append(doc)
|
||||
module_alias = ModulesManager.return_module_alias(module_.bind_prefix)
|
||||
module_alias = ModulesManager.return_module_alias(
|
||||
module_.bind_prefix)
|
||||
malias = []
|
||||
for a in module_alias:
|
||||
malias.append(f'{a} -> {module_alias[a]}')
|
||||
appends.append('\n'.join(malias) if malias else '')
|
||||
appends.append('、'.join(developers[x]) if developers.get(x) is not None else '')
|
||||
appends.append('、'.join(developers[x]) if developers.get(
|
||||
x) is not None else '')
|
||||
m.append(appends)
|
||||
if m:
|
||||
tables.append(ImageTable(m, ['扩展模块列表', '帮助信息', '命令别名', '作者']))
|
||||
|
|
|
@ -46,6 +46,9 @@ async def cytoid_profile(msg: MessageSession):
|
|||
s = grade.get('S')
|
||||
if s is not None:
|
||||
grade_t.append(f'S: {s}')
|
||||
aa = grade.get('AA')
|
||||
if aa is not None:
|
||||
grade_t.append(f'AA: {aa}')
|
||||
a = grade.get('A')
|
||||
if a is not None:
|
||||
grade_t.append(f'A: {a}')
|
||||
|
|
|
@ -14,7 +14,7 @@ async def _(msg: MessageSession):
|
|||
await msg.finish(''+str(random))
|
||||
|
||||
|
||||
@r.handle('choice ... {从选项中选择一个}',)
|
||||
@r.handle('choice ... {从集合中选择元素}',)
|
||||
async def _(msg: MessageSession):
|
||||
choices = msg.parsed_msg['...']
|
||||
await msg.finish(secrets.choice(choices))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Any
|
||||
from typing import Any, Dict
|
||||
import json
|
||||
import socket
|
||||
import ipaddress
|
||||
|
@ -82,7 +82,7 @@ def parse_coordinate(axis: str, value: float):
|
|||
return f'{value}°{"E" if value > 0 else "W"}'
|
||||
|
||||
|
||||
async def format_ip(info: dict[str, Any]):
|
||||
async def format_ip(info: Dict[str, Any]):
|
||||
ip_property = {
|
||||
'global': '全局',
|
||||
'private': '私有',
|
||||
|
|
|
@ -122,7 +122,7 @@ async def _(msg: MessageSession):
|
|||
section_.append(qs)
|
||||
if section_:
|
||||
s = urllib.parse.unquote(''.join(section_)[1:])
|
||||
if q[qq].realurl:
|
||||
if q[qq].realurl and q[qq].in_allowlist:
|
||||
if q[qq].realurl in generate_screenshot_v2_blocklist:
|
||||
get_section = await generate_screenshot_v1(q[qq].realurl, qq, headers, section=s)
|
||||
else:
|
||||
|
|
|
@ -26,6 +26,7 @@ async def generate_screenshot_v2(page_link, section=None, allow_special_page=Fal
|
|||
if allow_special_page and doc_mode:
|
||||
page_link += '/doc'
|
||||
elements_.insert(0, '.mw-parser-output')
|
||||
elements_.insert(0, '.documentation')
|
||||
if allow_special_page and not doc_mode:
|
||||
elements_.insert(0, '.diff')
|
||||
Logger.info('[Webrender] Generating element screenshot...')
|
||||
|
@ -309,7 +310,7 @@ async def generate_screenshot_v1(link, page_link, headers, section=None, allow_s
|
|||
open_file.write('</html>')
|
||||
open_file.close()
|
||||
read_file = open(url, 'r', encoding='utf-8')
|
||||
html = {'content': read_file.read(), 'width': w}
|
||||
html = {'content': read_file.read(), 'width': w, 'mw': True}
|
||||
Logger.info('Start rendering...')
|
||||
picname = os.path.abspath(f'./cache/{pagename}.jpg')
|
||||
if os.path.exists(picname):
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import asyncio
|
||||
import re
|
||||
from datetime import datetime
|
||||
from typing import Union
|
||||
|
||||
import filetype
|
||||
|
@ -274,11 +275,13 @@ async def query_pages(session: Union[MessageSession, QueryInfo], title: Union[st
|
|||
for ii in i:
|
||||
Logger.info(i[ii]['url'])
|
||||
if i[ii]['url'] not in generate_screenshot_v2_blocklist:
|
||||
timer = datetime.now().timestamp()
|
||||
get_infobox = await generate_screenshot_v2(ii, allow_special_page=i[ii]['in_allowlist'],
|
||||
doc_mode=i[ii]['has_doc'])
|
||||
if get_infobox:
|
||||
infobox_msg_list.append(Image(get_infobox))
|
||||
infobox_msg_list.append(Plain('*我们正在测试新的窗口截图方式,如您遇到机器人发送的图片发生错位等情况,请及时报告。报告地址:'
|
||||
infobox_msg_list.append(Plain(f'生成用时:{int(datetime.now().timestamp() - timer)}s' +
|
||||
'*我们正在测试新的窗口截图方式,如您遇到机器人发送的图片发生错位等情况,请及时报告。报告地址:'
|
||||
'https://s.wd-ljt.com/botreportbug'))
|
||||
else:
|
||||
get_infobox = await generate_screenshot_v1(i[ii]['url'], ii, headers,
|
||||
|
@ -295,13 +298,17 @@ async def query_pages(session: Union[MessageSession, QueryInfo], title: Union[st
|
|||
for ii in i:
|
||||
if i[ii]['in_allowlist']:
|
||||
if i[ii]['url'] not in generate_screenshot_v2_blocklist:
|
||||
timer = datetime.now().timestamp()
|
||||
get_section = await generate_screenshot_v2(ii, section=i[ii]['section'])
|
||||
if get_section:
|
||||
section_msg_list.append(Image(get_section))
|
||||
section_msg_list.append(Plain('*我们正在测试新的窗口截图方式,如您遇到机器人发送的图片发生错位等情况,请及时报告。报告地址:'
|
||||
'https://s.wd-ljt.com/botreportbug'))
|
||||
section_msg_list.append(
|
||||
Plain(f'生成用时:{int(datetime.now().timestamp() - timer)}s' +
|
||||
'*我们正在测试新的窗口截图方式,如您遇到机器人发送的图片发生错位等情况,请及时报告。报告地址:'
|
||||
'https://s.wd-ljt.com/botreportbug'))
|
||||
else:
|
||||
get_section = await generate_screenshot_v1(i[ii]['url'], ii, headers, section=i[ii]['section'])
|
||||
get_section = await generate_screenshot_v1(i[ii]['url'], ii, headers,
|
||||
section=i[ii]['section'])
|
||||
if get_section:
|
||||
section_msg_list.append(Image(get_section))
|
||||
if section_msg_list:
|
||||
|
|
|
@ -24,3 +24,4 @@ numpy
|
|||
matplotlib
|
||||
pint
|
||||
simpleeval
|
||||
pywin32; sys_platform == 'win32'
|
||||
|
|
Reference in a new issue