词库插件
Project description
nonebot-plugin-ciku
✨ NoneBot 插件描述 ✨
这是一个 onebot.v11的词库语言插件
📖 介绍
词库插件方面:
面向小白的词库语言插件,目的是减少编写代码的时间和难度 特点:语言精简(应该) 无需重启nb和reload即可实 现功能热重载 缺点:目前仅能实现一些简单的逻辑运行,但随着更新肯定会慢慢削减
支持导入自定义解析规则(自定义的优先级较低,请注意是否与默认规则冲突)
💿 安装
使用 nb-cli 安装
在 nonebot2 项目的根目录下打开命令行, 输入以下指令即可安装nb plugin install nonebot_plugin_ciku
使用包管理器安装
在 nonebot2 项目的插件目录下, 打开命令行, 根据你使用的包管理器, 输入相应的安装命令pip
pip install nonebot_plugin_ciku
打开 nonebot2 项目根目录下的 pyproject.toml 文件, 在 [tool.nonebot] 部分追加写入
plugins = ["nonebot_plugin_ciku"]
⚙️ 说明
词库文件(dicpro.ck)和自定义拓展文件夹都会在初次使用时自动创建
项目还在持续优化,暂时不开放env配置相关
⚙️ webui
为方便用户使用,本插件自带webui 具体路径为 你nonebot的ws链接地址:端口/ck_webui 例如:http://127.0.0.1:8090/ck_webui 后续会将变量大全等教程转移到webui里面
变量大全
目前支持的变量(\是md转译问题,忽略就行):| 变量 | 说明 |
|---|---|
| %QQ% | 用户id |
| %群号% | 群号 |
| %BotQQ% | 机器人自己的QQ |
| %括号0% | 从0开始匹配正则,提取对应字段 |
| %AT0% | 从0开始,提取艾特对应的对象QQ号 |
| [[1150]/6+5[50+6-7*8]] | 如果被包裹的不是数组,优先被识别为计算式,如果不符合计算式,才是正常字符串 |
| \$读 路径 键 默认值\$ | 读文件 |
| \$写 路径 键 值\$ | 写文件 |
| \$调用 名称\$ | 调用对应语块,若有消息字符串单独发出(例子见下,调用的语块前必须有[内部]) |
| \$回调 名称\$ | 调用对应语块,若有消息字符串则合并到对应位置一起发出(例子见下,调用的语块前必须有[内部]) |
| ±at QQ号± | 艾特用户 |
| ±img 路径/链接± | 发送图片 |
| ±reply 0± | 回复指令消息 |
| @%a%['data'] | 比如你前面写了a:{'data':1},那么为1 |
🎉 使用
词库格式
测试
路径:/词库项目/qrbot/src/plugins/词库v2/
name:['123']
a:$读 %路径%send.txt a 0$
b:$读 %路径%send.txt b 0$
c:$读 %路径%send.txt c 123$
d:±img bug.png±
$写 %路径%send.txt c 哈哈哈$
±reply 0±
%a%《隔断》%b%%c%\n±at %QQ%±\n456789
±img https://homdgcat.wiki/images/emote/Yunli/1.png±
%d%
如果:1 > 2
$读 %路径%send.txt c wdnmd$
如果:%a% == %a%
变量测试成功@%name%[0]
如果尾
如果尾
如果:%a% == %a%
缩进测试成功
测试访问
a:$访问 https://api.tangdouz.com/a/steam.php?return=json$ //默认get方法
$访问 url 请求头$
$访问 get url 请求头$
$访问 post url 请求头 json$ //请求头和json没有就填None
@%a%['store']
测试json
name:['123']
data:{'a':'123','b':'456'}
test:{'a':['123']}
@%name%[0]\n
@%data%['b']\n
@%test%['a'][0]
循环测试
测试:1
循环:%i% in 5
测试:[%测试% + %i%]
%测试%\n
循环尾
%测试%\n[1+5*%测试%]
(.*)测试正则(.*)
测试成功\n%括号0%
.*测试艾特
%AT1%\n%BotQQ%
$回调 测试调用$
$调用 测试调用$
[内部]测试调用
测试成功
自定义拓展
webui里找到拓展编辑,新建py文件,这里是示例
# example.py
from abc import ABC, abstractmethod
from nonebot.adapters.onebot.v11 import Event
class ParseRule(ABC):
@abstractmethod
async def process(self, line: str, event: Event,arg_list:list,async_def_list:list) -> str:
pass
class example_rule(ParseRule):
async def process(self, def_list, event, arg_list, async_def_list):
##一系列文本替换操作
##def_list是主指令文本
##async_def_list是响应函数文本([内部]xxx)
##下面是部分逻辑的实现过程
return def_list,async_def_list
"""
class 冒号_rule(ParseRule):
async def process(self, def_list, event, arg_list, async_def_list):
def process_line(lines,self_line):
for i, line in enumerate(lines):
if re.search(r'^.*:.*$', line) is not None:
parts = line.split(':', 1)
stripped_part = parts[1].strip().replace("'", '"')
if f'%{parts[0]}%' in self_line:
try:
json.loads(stripped_part)
lines[i] = f'ck_bianliang_{parts[0]} = {stripped_part}'
except json.JSONDecodeError:
if re.match(r'^.*:\$访问[^$]*\$$', line):
lines[i] = f'ck_bianliang_{parts[0]} = {stripped_part}'
elif re.match(r'^.*:\[.*\]$', line):
if '%' in stripped_part:
variables = re.findall(r'%([^%]*)%', stripped_part)
for var in variables:
stripped_part = stripped_part.replace(f'%{var}%', "ck_bianliang_"+str(var))
stripped_part = list_to_number(stripped_part)
if stripped_part is not False:
lines[i] = f'ck_bianliang_{parts[0]} = {stripped_part}'
else:
lines[i] = f'ck_bianliang_{parts[0]} = f"{stripped_part}"'
else:
lines[i] = f'ck_bianliang_{parts[0]} = f"{stripped_part}"'
else:
lines[i] = line
return lines
if re.search(r'.*:.*', def_list) is not None:
def_list_lines = def_list.split('\n')
def_list_lines = process_line(def_list_lines,def_list)
def_list = '\n'.join(def_list_lines)
else:
pass
for a, async_def_list_line in enumerate(async_def_list):
if re.search(r'\n.*:.*\n', async_def_list_line) is not None:
async_list = async_def_list_line.split('\n')
async_def_list_lines = async_list[1:]
async_def_list_lines = process_line(async_def_list_lines,async_def_list_line)
async_def_list_line = async_list[0]+'\n' + '\n'.join(async_def_list_lines)
else:
pass
async_def_list[a] = async_def_list_line
return def_list,async_def_list
class 变量_rule(ParseRule):
async def process(self, def_list, event, arg_list, async_def_list):
def process_line(lines):
if '%' in lines:
variables = re.findall(r'%([^%]*)%', lines)
for var in variables:
if var == '群号':
lines = lines.replace(f'%{var}%', f'{event.group_id}')
elif var == 'QQ':
lines = lines.replace(f'%{var}%', f'{event.user_id}')
elif var == 'BotQQ':
lines = lines.replace(f'%{var}%', f'{event.self_id}')
elif var == 'TargetQQ':
lines = lines.replace(f'%{var}%', f'{event.target_id}')
elif match := re.match(r'^括号(\d+)$', var):
lines = lines.replace(f'%{var}%', f'{arg_list[int(match.group(1))]}')
elif match := re.match(r'^AT(\d+)$', var):
if len(at := event.original_message.include("at")) > 0:
id = at[int(match.group(1))].data["qq"]
lines = lines.replace(f'%{var}%', f'{id}')
elif f'ck_bianliang_{var}' in lines:
lines = lines.replace(f'%{var}%', f'{{{"ck_bianliang_"+str(var)}}}')
else:
pass
return lines
def_list = process_line(def_list)
for i, line in enumerate(async_def_list):
async_def_list[i] = process_line(line)
return def_list,async_def_list
class 读_Rule(ParseRule):
'''有返回值的可以这样写————写法1'''
async def process(self, def_list, event, arg_list, async_def_list):
def process_line(lines):
matches_3 = re.findall(r'\$读 ([^\$]*) ([^\$]*) ([^\$]*)\$', lines)
matches_2 = re.findall(r'\$读 ([^\$]*) ([^\$]*)\$', lines)
if matches_3:
for match in matches_3:
data = "{read_txt(f'" + match[0] + "', f'" + match[2] + "', f'" + match[1] + "')}"
lines = lines.replace(f'$读 {match[0]} {match[1]} {match[2]}$', data)
elif matches_2:
for match in matches_2:
data = "{read_txt(f'" + match[0] + "', f'" + match[1] + "')}"
lines = lines.replace(f'$读 {match[0]} {match[1]}$', data)
return lines
if re.search(r'\$读 (.*?) (.*?) (.*?)\$', def_list) is not None or \
re.search(r'\$读 (.*?) (.*?)\$', def_list) is not None:
def_list = process_line(def_list)
for i, line in enumerate(async_def_list):
if re.search(r'\$读 (.*?) (.*?) (.*?)\$', line) is not None or \
re.search(r'\$读 (.*?) (.*?)\$', line) is not None:
async_def_list[i] = process_line(line)
return def_list, async_def_list
class 调用_Rlue(ParseRule):
'''有返回值的———写法2'''
async def process(self, def_list, event, arg_list, async_def_list):
def process_line(lines):
matches_retrun = re.findall(r'\$回调 ([^\$]*)\$', lines)
matches_await = re.findall(r'\$调用 ([^\$]*)\$', lines)
if matches_retrun:
for match in matches_retrun:
data = f"ck_res_finall_data += await ck_call_{match}(event)"
return_type = False
for i,line in enumerate(async_def_list):
if f"[内部]{match}" in line:
return_type = True
if return_type == True:
lines = lines.replace(f'$回调 {match}$', data)
else:
lines = lines.replace(f'$回调 {match}$', "")
if matches_await:
for match in matches_await:
data = f"await bot.send(event, Message(await ck_call_{match}(event)))"
await_type = False
for i,line in enumerate(async_def_list):
if f"[内部]{match}" in line:
await_type = True
if await_type == True:
lines = lines.replace(f'$调用 {match}$', data)
else:
lines = lines.replace(f'$调用 {match}$', "")
return lines
def_list = process_line(def_list)
for i,line in enumerate(async_def_list):
async_def_list[i] = process_line(line)
return def_list,async_def_list
class 循环_Rule(ParseRule):
'''如果需要缩进的你就这样写'''
async def process(self, def_list, event, arg_list, async_def_list):
def process_line(lines):
tab_time=0
for i,line in enumerate(lines):
parts = re.match(r'^循环:(.*) in (.*)$',line)
parts_match = re.match(r'^循环尾$',line)
parts_break = re.match(r'^阻断$',line)
if parts:
parts_bianliang = re.match(r'^{.*}$',parts.group(1))
if parts_bianliang:
line = '\t' * tab_time + 'for ' + parts.group(1).replace('{','').replace('}','') + ' in ' + f'range({parts.group(2)})' + ':'
tab_time += 1
else:
line = '\t' * tab_time + 'for ' + parts.group(1) + ' in ' + parts.group(2) + ':'
tab_time += 1
elif parts_match:
line = ''
tab_time -= 1
elif parts_break:
line = '\t' * tab_time + 'break'
tab_time -= 1
else:
line = '\t' * tab_time + line
lines[i] = line
lines = '\n'.join(lines)
return lines
def_list = process_line(def_list.split('\n'))
for i,line in enumerate(async_def_list):
async_def_list[i] = process_line(line.split('\n'))
return def_list,async_def_list
"""
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nonebot_plugin_ciku-0.2.0.tar.gz.
File metadata
- Download URL: nonebot_plugin_ciku-0.2.0.tar.gz
- Upload date:
- Size: 26.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9f30f2ee7a6610b5239f7b224ded65d956398cc466dcd20aa9a70e7b79f8cfa
|
|
| MD5 |
3f7916c06280d90c5286451f11c58d08
|
|
| BLAKE2b-256 |
5ca0e9c5afb5948e57864ce5abd72b1a6219fb47df3df77821989a4faa3e0994
|
File details
Details for the file nonebot_plugin_ciku-0.2.0-py3-none-any.whl.
File metadata
- Download URL: nonebot_plugin_ciku-0.2.0-py3-none-any.whl
- Upload date:
- Size: 27.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81565b514ca320224a191eff3964cc9a3c3daea4ab204978af9038b9c4757d9e
|
|
| MD5 |
12556182d49c2b81e677471fbbc3fbcb
|
|
| BLAKE2b-256 |
baf026a9232edefc274b2db916076d929353526693662d9747e93ab311842b25
|