nonebot-plugin-pErithacus 1.4.2__tar.gz → 1.4.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/PKG-INFO +3 -3
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/pyproject.toml +5 -5
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/__init__.py +1 -1
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/cmd_add.py +5 -5
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/cmd_check.py +1 -1
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/cmd_delete.py +1 -1
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/cmd_detail.py +1 -1
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/cmd_edit.py +1 -1
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/cmd_list.py +1 -1
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/cmd_search.py +15 -21
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/database.py +7 -2
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/lib.py +13 -12
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/trigger.py +1 -1
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/README.md +0 -0
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/apscheduler.py +0 -0
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/command.py +0 -0
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/handle_args.py +0 -0
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/migrations/4184a6a150e9_.py +0 -0
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/migrations/59488f45afb7_.py +0 -0
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/migrations/bd67704f77ad_.py +0 -0
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/migrations/c2cbe27dd921_.py +0 -0
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/migrations/cc658325e0ad_.py +0 -0
- {nonebot_plugin_perithacus-1.4.2 → nonebot_plugin_perithacus-1.4.4}/src/nonebot_plugin_perithacus/upgrade_database.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nonebot-plugin-pErithacus
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.4
|
|
4
4
|
Summary: pErithacus 是一个基于 NoneBot2 框架的聊天插件,可以根据用户设定的关键词自动回复相关内容。该插件提供了完整的词条管理功能,让用户能够轻松创建、编辑和管理自定义回复内容
|
|
5
5
|
Keywords: nonebot2,chatbot,qqbot,nonebot-plugin
|
|
6
6
|
Author: SnowMoonSS
|
|
7
7
|
License-Expression: MIT
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
11
|
Classifier: Framework :: Robot Framework
|
|
12
12
|
Requires-Dist: httpx>=0.24.0
|
|
@@ -18,7 +18,7 @@ Requires-Dist: nonebot-plugin-orm[default]>=0.8.2
|
|
|
18
18
|
Requires-Dist: nonebot-plugin-apscheduler>=0.5.0
|
|
19
19
|
Requires-Dist: pyright[nodejs] ; extra == 'dev'
|
|
20
20
|
Requires-Dist: ruff ; extra == 'dev'
|
|
21
|
-
Requires-Python: >=3.
|
|
21
|
+
Requires-Python: >=3.11, <4.0
|
|
22
22
|
Project-URL: Homepage, https://github.com/SnowMoonSS/nonebot-plugin-pErithacus
|
|
23
23
|
Project-URL: Repository, https://github.com/SnowMoonSS/nonebot-plugin-pErithacus.git
|
|
24
24
|
Project-URL: Documentation, https://github.com/SnowMoonSS/nonebot-plugin-pErithacus/blob/master/README.md
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nonebot-plugin-pErithacus"
|
|
3
|
-
version = "1.4.
|
|
3
|
+
version = "1.4.4"
|
|
4
4
|
description = "pErithacus 是一个基于 NoneBot2 框架的聊天插件,可以根据用户设定的关键词自动回复相关内容。该插件提供了完整的词条管理功能,让用户能够轻松创建、编辑和管理自定义回复内容"
|
|
5
5
|
readme = "README.md"
|
|
6
|
-
requires-python = ">=3.
|
|
6
|
+
requires-python = ">=3.11, <4.0"
|
|
7
7
|
dependencies = [
|
|
8
8
|
"httpx>=0.24.0",
|
|
9
9
|
"filetype>=1.2.0",
|
|
@@ -17,7 +17,7 @@ authors = [{ name = "SnowMoonSS" }]
|
|
|
17
17
|
license = "MIT"
|
|
18
18
|
classifiers = [
|
|
19
19
|
"Programming Language :: Python :: 3",
|
|
20
|
-
"Programming Language :: Python :: 3.
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
21
|
"Operating System :: OS Independent",
|
|
22
22
|
"Framework :: Robot Framework"
|
|
23
23
|
]
|
|
@@ -58,7 +58,7 @@ nonebot-plugin-apscheduler = ["nonebot_plugin_apscheduler"]
|
|
|
58
58
|
|
|
59
59
|
[tool.ruff]
|
|
60
60
|
line-length = 128
|
|
61
|
-
target-version = "
|
|
61
|
+
target-version = "py312"
|
|
62
62
|
|
|
63
63
|
[tool.ruff.format]
|
|
64
64
|
line-ending = "lf"
|
|
@@ -126,6 +126,6 @@ keep-runtime-typing = true
|
|
|
126
126
|
|
|
127
127
|
[tool.pyright]
|
|
128
128
|
# For Pylance/Pyright configurations, see https://microsoft.github.io/pyright/#/configuration.
|
|
129
|
-
pythonVersion = "3.
|
|
129
|
+
pythonVersion = "3.12"
|
|
130
130
|
pythonPlatform = "All"
|
|
131
131
|
typeCheckingMode = "standard"
|
|
@@ -8,7 +8,7 @@ from nonebot_plugin_alconna import (
|
|
|
8
8
|
UniMessage,
|
|
9
9
|
UniMsg,
|
|
10
10
|
)
|
|
11
|
-
from nonebot_plugin_orm import async_scoped_session
|
|
11
|
+
from nonebot_plugin_orm import async_scoped_session
|
|
12
12
|
|
|
13
13
|
from .apscheduler import add_cron_job
|
|
14
14
|
from .command import pe
|
|
@@ -27,7 +27,7 @@ from .handle_args import (
|
|
|
27
27
|
handle_reg,
|
|
28
28
|
handle_scope,
|
|
29
29
|
)
|
|
30
|
-
from .lib import dump_msg, get_cron, get_scope, get_source
|
|
30
|
+
from .lib import dump_msg, get_cron, get_scope, get_source
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
@pe.assign("add")
|
|
@@ -91,13 +91,13 @@ async def _( # noqa: PLR0913
|
|
|
91
91
|
entry_id = existing_entry.id
|
|
92
92
|
await session.commit()
|
|
93
93
|
|
|
94
|
-
uni_keyword =
|
|
94
|
+
uni_keyword = UniMessage.load(keyword_text)
|
|
95
95
|
await pe.finish(
|
|
96
96
|
f"词条 {entry_id} : " + uni_keyword + " 加入了新的内容:"
|
|
97
97
|
f"{add_content_result.content_id}"
|
|
98
98
|
)
|
|
99
99
|
else:
|
|
100
|
-
uni_keyword =
|
|
100
|
+
uni_keyword = UniMessage.load(keyword_text)
|
|
101
101
|
await pe.finish(
|
|
102
102
|
f"词条 {existing_entry.id} : " + uni_keyword + " 已存在该内容:"
|
|
103
103
|
f"{add_content_result.content_id}",
|
|
@@ -128,7 +128,7 @@ async def _( # noqa: PLR0913
|
|
|
128
128
|
entry_id = new_entry.id
|
|
129
129
|
await session.commit()
|
|
130
130
|
|
|
131
|
-
uni_keyword =
|
|
131
|
+
uni_keyword = UniMessage.load(keyword_text)
|
|
132
132
|
await pe.finish(
|
|
133
133
|
f"词条 {entry_id} : " + uni_keyword + " 已创建并加入了新的内容:"
|
|
134
134
|
f"{add_content_result.content_id}"
|
|
@@ -2,7 +2,7 @@ import json
|
|
|
2
2
|
from datetime import UTC, timedelta, timezone
|
|
3
3
|
|
|
4
4
|
from nonebot_plugin_alconna import AlconnaMatch, AlconnaQuery, Match, Query, UniMessage
|
|
5
|
-
from nonebot_plugin_orm import async_scoped_session
|
|
5
|
+
from nonebot_plugin_orm import async_scoped_session
|
|
6
6
|
|
|
7
7
|
from .command import pe
|
|
8
8
|
from .database import get_entry_by_id
|
|
@@ -2,7 +2,7 @@ import json
|
|
|
2
2
|
from datetime import UTC, datetime
|
|
3
3
|
|
|
4
4
|
from nonebot_plugin_alconna import AlconnaMatch, Match, MsgTarget, UniMsg
|
|
5
|
-
from nonebot_plugin_orm import async_scoped_session
|
|
5
|
+
from nonebot_plugin_orm import async_scoped_session
|
|
6
6
|
|
|
7
7
|
from .apscheduler import remove_cron_job
|
|
8
8
|
from .command import pe
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from datetime import UTC, timedelta, timezone
|
|
2
2
|
|
|
3
3
|
from nonebot_plugin_alconna import AlconnaMatch, AlconnaQuery, Match, Query, UniMessage
|
|
4
|
-
from nonebot_plugin_orm import async_scoped_session
|
|
4
|
+
from nonebot_plugin_orm import async_scoped_session
|
|
5
5
|
|
|
6
6
|
from .command import pe
|
|
7
7
|
from .database import get_contents, get_entry_by_id
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from nonebot import logger
|
|
2
2
|
from nonebot_plugin_alconna import AlconnaMatch, Match, MsgTarget, UniMessage, UniMsg
|
|
3
|
-
from nonebot_plugin_orm import async_scoped_session
|
|
3
|
+
from nonebot_plugin_orm import async_scoped_session
|
|
4
4
|
|
|
5
5
|
from .command import pe
|
|
6
6
|
from .database import (
|
|
@@ -12,11 +12,12 @@ from nonebot_plugin_alconna import (
|
|
|
12
12
|
Query,
|
|
13
13
|
UniMessage,
|
|
14
14
|
)
|
|
15
|
+
from nonebot_plugin_alconna.uniseg.segment import At, Media
|
|
15
16
|
from nonebot_plugin_orm import async_scoped_session # noqa: TC002
|
|
16
17
|
|
|
17
18
|
from .command import pe
|
|
18
19
|
from .database import Index, get_all_contents, get_entries, get_entry_by_id
|
|
19
|
-
from .lib import
|
|
20
|
+
from .lib import get_scope, get_source, load_msg, pe_download
|
|
20
21
|
|
|
21
22
|
if TYPE_CHECKING:
|
|
22
23
|
from collections.abc import Sequence
|
|
@@ -82,19 +83,17 @@ async def _( # noqa: PLR0913
|
|
|
82
83
|
await pe.finish(UniMessage("搜索结果:\n无"))
|
|
83
84
|
|
|
84
85
|
async def get_key(keyword: Match) -> str:
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
msg = UniMessage(keyword.result) if not isinstance(keyword.result, UniMessage) else keyword.result
|
|
87
|
+
msg = await pe_download(msg)
|
|
87
88
|
|
|
88
89
|
# 检查pe_message_list中的每个元素
|
|
89
90
|
key = None
|
|
90
|
-
for
|
|
91
|
-
if
|
|
92
|
-
|
|
93
|
-
if item.get("media"):
|
|
94
|
-
key = item["id"]
|
|
91
|
+
for seg in msg:
|
|
92
|
+
if isinstance(seg, Media):
|
|
93
|
+
key = seg.id
|
|
95
94
|
break
|
|
96
|
-
if
|
|
97
|
-
key =
|
|
95
|
+
if isinstance(seg, At):
|
|
96
|
+
key = seg.target
|
|
98
97
|
break
|
|
99
98
|
if not key:
|
|
100
99
|
key = UniMessage(keyword.result).extract_plain_text()
|
|
@@ -110,9 +109,7 @@ async def search_in_entries(
|
|
|
110
109
|
# 检查keyword列和alias列包含key的行
|
|
111
110
|
if key in entry.keyword or (entry.alias and key in entry.alias):
|
|
112
111
|
result_list.append(entry.id)
|
|
113
|
-
logger.info(
|
|
114
|
-
f"在 Index 中找到匹配的词条 {entry.id},关键词 {entry.keyword}"
|
|
115
|
-
)
|
|
112
|
+
logger.info(f"在 Index 中找到匹配的词条 {entry.id},关键词 {entry.keyword}")
|
|
116
113
|
return result_list
|
|
117
114
|
|
|
118
115
|
async def search_in_contents(
|
|
@@ -124,14 +121,11 @@ async def search_in_contents(
|
|
|
124
121
|
) -> list[int]:
|
|
125
122
|
contents = await get_all_contents(session)
|
|
126
123
|
for content in contents:
|
|
127
|
-
if not content.deleted and key in content.content
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
logger.debug(f"跳过词条 {content.entry_id},该词条已存在搜索结果中")
|
|
133
|
-
else:
|
|
134
|
-
logger.debug(f"未在 {content.entry_id} 中找到包含 {key} 的内容")
|
|
124
|
+
if ((not content.deleted and key in content.content)
|
|
125
|
+
and (content.entry_id not in result_list)
|
|
126
|
+
and (not await check_is_deleted(session, content.entry_id, scope_list))):
|
|
127
|
+
result_list.append(content.entry_id)
|
|
128
|
+
logger.debug(f"在 {content.entry_id} 中找到包含 {key} 的内容")
|
|
135
129
|
|
|
136
130
|
return result_list
|
|
137
131
|
|
|
@@ -151,6 +151,8 @@ def _is_fuzzy_match(entry: Index, keyword_msg: UniMessage) -> bool:
|
|
|
151
151
|
return False
|
|
152
152
|
|
|
153
153
|
key = keyword_msg.extract_plain_text()
|
|
154
|
+
if not key: # 空字符串不应匹配任何词条
|
|
155
|
+
return False
|
|
154
156
|
entry_key = load_media(entry.keyword).extract_plain_text()
|
|
155
157
|
if key in entry_key:
|
|
156
158
|
return True
|
|
@@ -174,6 +176,8 @@ def _is_regex_match(entry: Index, keyword_msg: UniMessage) -> bool:
|
|
|
174
176
|
return False
|
|
175
177
|
|
|
176
178
|
key = keyword_msg.extract_plain_text()
|
|
179
|
+
if not key: # 空字符串不应匹配任何词条
|
|
180
|
+
return False
|
|
177
181
|
return bool(re.match(entry.reg, key))
|
|
178
182
|
|
|
179
183
|
async def matching(
|
|
@@ -320,7 +324,8 @@ async def add_entry(
|
|
|
320
324
|
**kwargs
|
|
321
325
|
)
|
|
322
326
|
session.add(new_entry)
|
|
323
|
-
|
|
327
|
+
await session.flush()
|
|
328
|
+
logger.info(f"添加新词条 {new_entry.id}: {new_entry.keyword} 到 Index")
|
|
324
329
|
return new_entry
|
|
325
330
|
|
|
326
331
|
async def get_entry_by_id(
|
|
@@ -535,7 +540,6 @@ async def add_content(
|
|
|
535
540
|
await restore_deleted_content(session, row.id)
|
|
536
541
|
return AddContentResult(success=True, content_id=row.id)
|
|
537
542
|
|
|
538
|
-
logger.debug(f"添加内容 {content} 到 Content")
|
|
539
543
|
new_content = Content(
|
|
540
544
|
entry_id=entry_id,
|
|
541
545
|
content=content,
|
|
@@ -544,6 +548,7 @@ async def add_content(
|
|
|
544
548
|
)
|
|
545
549
|
session.add(new_content)
|
|
546
550
|
await session.flush()
|
|
551
|
+
logger.info(f"添加内容 {new_content.id}: {content} 到 Content")
|
|
547
552
|
return AddContentResult(success=True, content_id=new_content.id)
|
|
548
553
|
|
|
549
554
|
async def delete_content(session: async_scoped_session, content_id: int) -> bool:
|
|
@@ -10,6 +10,7 @@ from json import dumps
|
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
from typing import Any, Literal, overload
|
|
12
12
|
|
|
13
|
+
import anyio
|
|
13
14
|
import filetype
|
|
14
15
|
import httpx
|
|
15
16
|
from apscheduler.triggers.cron import CronTrigger
|
|
@@ -37,11 +38,11 @@ async def download_media(
|
|
|
37
38
|
:return: 最终文件路径 或 None(失败时)
|
|
38
39
|
"""
|
|
39
40
|
save_dir = Path(save_dir)
|
|
40
|
-
save_dir.mkdir(parents=True, exist_ok=True)
|
|
41
|
+
await anyio.Path(save_dir).mkdir(parents=True, exist_ok=True)
|
|
41
42
|
|
|
42
43
|
# 创建临时文件(在 save_dir 中)
|
|
43
44
|
with tempfile.NamedTemporaryFile(delete=False, dir=save_dir) as tmp_file:
|
|
44
|
-
tmp_path = Path(tmp_file.name)
|
|
45
|
+
tmp_path = anyio.Path(tmp_file.name)
|
|
45
46
|
md5_hash = hashlib.md5()
|
|
46
47
|
|
|
47
48
|
try:
|
|
@@ -59,13 +60,13 @@ async def download_media(
|
|
|
59
60
|
os.fsync(tmp_file.fileno())
|
|
60
61
|
except httpx.HTTPError as e:
|
|
61
62
|
# 包括连接错误、超时、4xx/5xx 等
|
|
62
|
-
tmp_path.unlink(missing_ok=True)
|
|
63
|
+
await tmp_path.unlink(missing_ok=True)
|
|
63
64
|
logger.error(f"HTTP 请求失败: {e}")
|
|
64
65
|
return None
|
|
65
66
|
|
|
66
67
|
except OSError as e:
|
|
67
68
|
# 文件写入、fsync、磁盘空间、权限等问题
|
|
68
|
-
tmp_path.unlink(missing_ok=True)
|
|
69
|
+
await tmp_path.unlink(missing_ok=True)
|
|
69
70
|
logger.error(f"文件 I/O 错误: {e}")
|
|
70
71
|
return None
|
|
71
72
|
|
|
@@ -82,20 +83,20 @@ async def download_media(
|
|
|
82
83
|
final_path = save_dir / (md5_hex + extension)
|
|
83
84
|
|
|
84
85
|
if json:
|
|
85
|
-
tmp_path.unlink(missing_ok=True)
|
|
86
|
+
await tmp_path.unlink(missing_ok=True)
|
|
86
87
|
return final_path
|
|
87
|
-
if final_path.exists():
|
|
88
|
+
if await anyio.Path(final_path).exists():
|
|
88
89
|
logger.info(f"文件已存在,跳过: {final_path}")
|
|
89
|
-
tmp_path.unlink(missing_ok=True)
|
|
90
|
+
await tmp_path.unlink(missing_ok=True)
|
|
90
91
|
return final_path
|
|
91
92
|
|
|
92
93
|
# 重命名
|
|
93
94
|
try:
|
|
94
|
-
tmp_path.rename(final_path)
|
|
95
|
+
await tmp_path.rename(anyio.Path(final_path))
|
|
95
96
|
logger.info(f"保存成功: {final_path}")
|
|
96
97
|
except OSError as e:
|
|
97
98
|
logger.info(f"重命名失败: {e}")
|
|
98
|
-
tmp_path.unlink(missing_ok=True)
|
|
99
|
+
await tmp_path.unlink(missing_ok=True)
|
|
99
100
|
return None
|
|
100
101
|
else:
|
|
101
102
|
return final_path
|
|
@@ -247,10 +248,10 @@ async def pe_download(
|
|
|
247
248
|
stream (bool, optional): 是否以流式下载. Defaults to False.
|
|
248
249
|
**kwargs: 传递给下载器的参数
|
|
249
250
|
"""
|
|
250
|
-
logger.debug("开始下载媒体数据")
|
|
251
251
|
for media in self.select(Media):
|
|
252
252
|
if not media.url:
|
|
253
253
|
continue
|
|
254
|
+
logger.debug("开始下载媒体数据")
|
|
254
255
|
raw: bytes = b""
|
|
255
256
|
async with httpx.AsyncClient(**kwargs) as client:
|
|
256
257
|
if stream:
|
|
@@ -363,7 +364,7 @@ def pe_save(
|
|
|
363
364
|
return path.resolve()
|
|
364
365
|
|
|
365
366
|
async def dump_msg(
|
|
366
|
-
msg: UniMessage,
|
|
367
|
+
msg: UniMessage | str | tuple,
|
|
367
368
|
*,
|
|
368
369
|
media_save_dir: str | Path | bool | None = MEDIA_SAVE_DIR
|
|
369
370
|
) -> str:
|
|
@@ -382,7 +383,7 @@ async def dump_msg(
|
|
|
382
383
|
:rtype: str
|
|
383
384
|
"""
|
|
384
385
|
|
|
385
|
-
if isinstance(msg,
|
|
386
|
+
if not isinstance(msg, UniMessage):
|
|
386
387
|
msg = UniMessage(msg)
|
|
387
388
|
|
|
388
389
|
msg = await pe_download(msg)
|
|
@@ -2,7 +2,7 @@ import random
|
|
|
2
2
|
|
|
3
3
|
from nonebot.log import logger
|
|
4
4
|
from nonebot_plugin_alconna import MsgTarget, UniMessage, UniMsg
|
|
5
|
-
from nonebot_plugin_orm import async_scoped_session
|
|
5
|
+
from nonebot_plugin_orm import async_scoped_session
|
|
6
6
|
|
|
7
7
|
from .command import on_every_message
|
|
8
8
|
from .database import get_contents, get_entry
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|