kotonebot 0.5.0__py3-none-any.whl → 0.7.0__py3-none-any.whl
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.
- kotonebot/__init__.py +39 -39
- kotonebot/backend/bot.py +312 -312
- kotonebot/backend/color.py +525 -525
- kotonebot/backend/context/__init__.py +3 -3
- kotonebot/backend/context/context.py +1002 -1002
- kotonebot/backend/context/task_action.py +183 -183
- kotonebot/backend/core.py +86 -129
- kotonebot/backend/debug/entry.py +89 -89
- kotonebot/backend/debug/mock.py +78 -78
- kotonebot/backend/debug/server.py +222 -222
- kotonebot/backend/debug/vars.py +351 -351
- kotonebot/backend/dispatch.py +227 -227
- kotonebot/backend/flow_controller.py +196 -196
- kotonebot/backend/image.py +36 -5
- kotonebot/backend/loop.py +222 -208
- kotonebot/backend/ocr.py +535 -535
- kotonebot/backend/preprocessor.py +103 -103
- kotonebot/client/__init__.py +9 -9
- kotonebot/client/device.py +369 -529
- kotonebot/client/fast_screenshot.py +377 -377
- kotonebot/client/host/__init__.py +43 -43
- kotonebot/client/host/adb_common.py +101 -107
- kotonebot/client/host/custom.py +118 -118
- kotonebot/client/host/leidian_host.py +196 -196
- kotonebot/client/host/mumu12_host.py +353 -353
- kotonebot/client/host/protocol.py +214 -214
- kotonebot/client/host/windows_common.py +73 -58
- kotonebot/client/implements/__init__.py +65 -70
- kotonebot/client/implements/adb.py +89 -89
- kotonebot/client/implements/nemu_ipc/__init__.py +11 -11
- kotonebot/client/implements/nemu_ipc/external_renderer_ipc.py +284 -284
- kotonebot/client/implements/nemu_ipc/nemu_ipc.py +327 -327
- kotonebot/client/implements/remote_windows.py +188 -188
- kotonebot/client/implements/uiautomator2.py +85 -85
- kotonebot/client/implements/windows/__init__.py +1 -0
- kotonebot/client/implements/windows/print_window.py +133 -0
- kotonebot/client/implements/windows/send_message.py +324 -0
- kotonebot/client/implements/{windows.py → windows/windows.py} +175 -176
- kotonebot/client/protocol.py +69 -69
- kotonebot/client/registration.py +24 -24
- kotonebot/client/scaler.py +467 -0
- kotonebot/config/base_config.py +103 -96
- kotonebot/config/config.py +61 -0
- kotonebot/config/manager.py +36 -36
- kotonebot/core/__init__.py +13 -0
- kotonebot/core/entities/base.py +182 -0
- kotonebot/core/entities/compound.py +75 -0
- kotonebot/core/entities/ocr.py +117 -0
- kotonebot/core/entities/template_match.py +198 -0
- kotonebot/devtools/__init__.py +42 -0
- kotonebot/devtools/cli/__init__.py +6 -0
- kotonebot/devtools/cli/main.py +53 -0
- kotonebot/{tools → devtools}/mirror.py +354 -354
- kotonebot/devtools/project/project.py +41 -0
- kotonebot/devtools/project/scanner.py +202 -0
- kotonebot/devtools/project/schema.py +99 -0
- kotonebot/devtools/resgen/__init__.py +42 -0
- kotonebot/devtools/resgen/codegen.py +331 -0
- kotonebot/devtools/resgen/core.py +94 -0
- kotonebot/devtools/resgen/parsers.py +360 -0
- kotonebot/devtools/resgen/utils.py +158 -0
- kotonebot/devtools/resgen/validation.py +115 -0
- kotonebot/devtools/web/dist/assets/bootstrap-icons-BOrJxbIo.woff +0 -0
- kotonebot/devtools/web/dist/assets/bootstrap-icons-BtvjY1KL.woff2 +0 -0
- kotonebot/devtools/web/dist/assets/ext-language_tools-CD021WJ2.js +2577 -0
- kotonebot/devtools/web/dist/assets/index-B_m5f2LF.js +2836 -0
- kotonebot/devtools/web/dist/assets/index-BlEDyGGa.css +9 -0
- kotonebot/devtools/web/dist/assets/language-client-C9muzqaq.js +128 -0
- kotonebot/devtools/web/dist/assets/mode-python-CtHp76XS.js +476 -0
- kotonebot/devtools/web/dist/icons/symbol-class.svg +3 -0
- kotonebot/devtools/web/dist/icons/symbol-file.svg +3 -0
- kotonebot/devtools/web/dist/icons/symbol-method.svg +3 -0
- kotonebot/devtools/web/dist/index.html +25 -0
- kotonebot/devtools/web/server/__init__.py +0 -0
- kotonebot/devtools/web/server/rest_api.py +217 -0
- kotonebot/devtools/web/server/server.py +85 -0
- kotonebot/errors.py +76 -76
- kotonebot/interop/win/__init__.py +13 -9
- kotonebot/interop/win/_mouse.py +310 -310
- kotonebot/interop/win/message_box.py +313 -313
- kotonebot/interop/win/reg.py +37 -37
- kotonebot/interop/win/shake_mouse.py +224 -0
- kotonebot/interop/win/shortcut.py +43 -43
- kotonebot/interop/win/task_dialog.py +513 -513
- kotonebot/interop/win/window.py +89 -0
- kotonebot/logging/__init__.py +2 -2
- kotonebot/logging/log.py +17 -17
- kotonebot/primitives/__init__.py +19 -17
- kotonebot/primitives/geometry.py +1067 -862
- kotonebot/primitives/visual.py +143 -63
- kotonebot/ui/file_host/sensio.py +36 -36
- kotonebot/ui/file_host/tmp_send.py +54 -54
- kotonebot/ui/pushkit/__init__.py +3 -3
- kotonebot/ui/pushkit/image_host.py +88 -88
- kotonebot/ui/pushkit/protocol.py +13 -13
- kotonebot/ui/pushkit/wxpusher.py +54 -54
- kotonebot/ui/user.py +148 -148
- kotonebot/util.py +436 -436
- {kotonebot-0.5.0.dist-info → kotonebot-0.7.0.dist-info}/METADATA +84 -82
- kotonebot-0.7.0.dist-info/RECORD +109 -0
- {kotonebot-0.5.0.dist-info → kotonebot-0.7.0.dist-info}/WHEEL +1 -1
- kotonebot-0.7.0.dist-info/entry_points.txt +2 -0
- {kotonebot-0.5.0.dist-info → kotonebot-0.7.0.dist-info}/licenses/LICENSE +673 -673
- kotonebot/client/implements/adb_raw.py +0 -163
- kotonebot-0.5.0.dist-info/RECORD +0 -71
- /kotonebot/{tools → devtools/project}/__init__.py +0 -0
- {kotonebot-0.5.0.dist-info → kotonebot-0.7.0.dist-info}/top_level.txt +0 -0
kotonebot/ui/pushkit/wxpusher.py
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import json
|
|
3
|
-
from typing import Sequence
|
|
4
|
-
from cv2.typing import MatLike
|
|
5
|
-
from dotenv import dotenv_values
|
|
6
|
-
|
|
7
|
-
from .image_host import upload
|
|
8
|
-
from .protocol import PushkitProtocol
|
|
9
|
-
|
|
10
|
-
config = dotenv_values(".env")
|
|
11
|
-
|
|
12
|
-
class Wxpusher(PushkitProtocol):
|
|
13
|
-
def __init__(self, app_token: str | None = None, uid: str | None = None):
|
|
14
|
-
self.app_token = app_token or config["WXPUSHER_APP_TOKEN"]
|
|
15
|
-
self.uid = uid or config["WXPUSHER_UID"]
|
|
16
|
-
|
|
17
|
-
def push(self, title: str, message: str, *, images: Sequence[str | MatLike] | None = None) -> None:
|
|
18
|
-
import requests
|
|
19
|
-
|
|
20
|
-
summary = title
|
|
21
|
-
content = message
|
|
22
|
-
|
|
23
|
-
if images:
|
|
24
|
-
image_urls = upload(images)
|
|
25
|
-
img_md = "\n".join([f"" for img_url in image_urls])
|
|
26
|
-
content = content + "\n" + img_md
|
|
27
|
-
|
|
28
|
-
data = {
|
|
29
|
-
"appToken": self.app_token,
|
|
30
|
-
"uid": self.uid,
|
|
31
|
-
"summary": summary,
|
|
32
|
-
"content": content,
|
|
33
|
-
"contentType": 3, # 1: 文本 2: HTML 3: Markdown
|
|
34
|
-
"uids": [self.uid],
|
|
35
|
-
"verifyPay": False,
|
|
36
|
-
"verifyPayType": 0
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
response = requests.post(
|
|
40
|
-
"http://wxpusher.zjiecode.com/api/send/message",
|
|
41
|
-
json=data
|
|
42
|
-
)
|
|
43
|
-
result = response.json()
|
|
44
|
-
|
|
45
|
-
if result["code"] != 1000 or not result["success"]:
|
|
46
|
-
raise RuntimeError(f"推送失败: {result['msg']}")
|
|
47
|
-
|
|
48
|
-
# TODO: 极简推送 https://wxpusher.zjiecode.com/docs/#/?id=spt
|
|
49
|
-
|
|
50
|
-
if __name__ == "__main__":
|
|
51
|
-
import cv2
|
|
52
|
-
wxpusher = Wxpusher()
|
|
53
|
-
wxpusher.push("测试图片", "测试图片", images=[cv2.imread("res/sprites/jp/common/button_close.png")])
|
|
54
|
-
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
from typing import Sequence
|
|
4
|
+
from cv2.typing import MatLike
|
|
5
|
+
from dotenv import dotenv_values
|
|
6
|
+
|
|
7
|
+
from .image_host import upload
|
|
8
|
+
from .protocol import PushkitProtocol
|
|
9
|
+
|
|
10
|
+
config = dotenv_values(".env")
|
|
11
|
+
|
|
12
|
+
class Wxpusher(PushkitProtocol):
|
|
13
|
+
def __init__(self, app_token: str | None = None, uid: str | None = None):
|
|
14
|
+
self.app_token = app_token or config["WXPUSHER_APP_TOKEN"]
|
|
15
|
+
self.uid = uid or config["WXPUSHER_UID"]
|
|
16
|
+
|
|
17
|
+
def push(self, title: str, message: str, *, images: Sequence[str | MatLike] | None = None) -> None:
|
|
18
|
+
import requests
|
|
19
|
+
|
|
20
|
+
summary = title
|
|
21
|
+
content = message
|
|
22
|
+
|
|
23
|
+
if images:
|
|
24
|
+
image_urls = upload(images)
|
|
25
|
+
img_md = "\n".join([f"" for img_url in image_urls])
|
|
26
|
+
content = content + "\n" + img_md
|
|
27
|
+
|
|
28
|
+
data = {
|
|
29
|
+
"appToken": self.app_token,
|
|
30
|
+
"uid": self.uid,
|
|
31
|
+
"summary": summary,
|
|
32
|
+
"content": content,
|
|
33
|
+
"contentType": 3, # 1: 文本 2: HTML 3: Markdown
|
|
34
|
+
"uids": [self.uid],
|
|
35
|
+
"verifyPay": False,
|
|
36
|
+
"verifyPayType": 0
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
response = requests.post(
|
|
40
|
+
"http://wxpusher.zjiecode.com/api/send/message",
|
|
41
|
+
json=data
|
|
42
|
+
)
|
|
43
|
+
result = response.json()
|
|
44
|
+
|
|
45
|
+
if result["code"] != 1000 or not result["success"]:
|
|
46
|
+
raise RuntimeError(f"推送失败: {result['msg']}")
|
|
47
|
+
|
|
48
|
+
# TODO: 极简推送 https://wxpusher.zjiecode.com/docs/#/?id=spt
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
import cv2
|
|
52
|
+
wxpusher = Wxpusher()
|
|
53
|
+
wxpusher.push("测试图片", "测试图片", images=[cv2.imread("res/sprites/jp/common/button_close.png")])
|
|
54
|
+
|
kotonebot/ui/user.py
CHANGED
|
@@ -1,149 +1,149 @@
|
|
|
1
|
-
"""消息框、通知、推送等 UI 相关函数"""
|
|
2
|
-
import os
|
|
3
|
-
import time
|
|
4
|
-
|
|
5
|
-
import cv2
|
|
6
|
-
from cv2.typing import MatLike
|
|
7
|
-
from kotonebot.util import is_windows
|
|
8
|
-
if is_windows():
|
|
9
|
-
from win11toast import toast
|
|
10
|
-
else:
|
|
11
|
-
def toast(title: str, message: str | None = None, buttons: list[str] | None = None):
|
|
12
|
-
raise ImportError('toast notification is only available on Windows')
|
|
13
|
-
|
|
14
|
-
from .pushkit import Wxpusher
|
|
15
|
-
from .. import logging
|
|
16
|
-
|
|
17
|
-
logger = logging.getLogger(__name__)
|
|
18
|
-
|
|
19
|
-
def retry(func):
|
|
20
|
-
"""
|
|
21
|
-
装饰器:当函数发生 ConnectionResetError 时自动重试三次
|
|
22
|
-
"""
|
|
23
|
-
def wrapper(*args, **kwargs):
|
|
24
|
-
for i in range(3):
|
|
25
|
-
try:
|
|
26
|
-
return func(*args, **kwargs)
|
|
27
|
-
except ConnectionResetError:
|
|
28
|
-
if i == 2: # 最后一次重试失败
|
|
29
|
-
raise
|
|
30
|
-
logger.warning(f'ConnectionResetError raised when calling {func}, retrying {i+1}/{3}')
|
|
31
|
-
continue
|
|
32
|
-
return wrapper
|
|
33
|
-
|
|
34
|
-
def _save_local(
|
|
35
|
-
title: str,
|
|
36
|
-
message: str,
|
|
37
|
-
images: list[MatLike] | None = None
|
|
38
|
-
):
|
|
39
|
-
"""
|
|
40
|
-
保存消息到本地
|
|
41
|
-
"""
|
|
42
|
-
if not os.path.exists('messages'):
|
|
43
|
-
os.makedirs('messages')
|
|
44
|
-
file_name = f'messages/{time.strftime("%Y-%m-%d_%H-%M-%S")}'
|
|
45
|
-
with open(file_name + '.txt', 'w', encoding='utf-8') as f:
|
|
46
|
-
logger.verbose('saving message to local: %s', file_name + '.txt')
|
|
47
|
-
f.write(message)
|
|
48
|
-
if images is not None:
|
|
49
|
-
for i, image in enumerate(images):
|
|
50
|
-
logger.verbose('saving image to local: %s', f'{file_name}_{i}.png')
|
|
51
|
-
cv2.imwrite(f'{file_name}_{i}.png', image)
|
|
52
|
-
|
|
53
|
-
@retry
|
|
54
|
-
def push(
|
|
55
|
-
title: str,
|
|
56
|
-
message: str | None = None,
|
|
57
|
-
*,
|
|
58
|
-
images: list[MatLike] | None = None
|
|
59
|
-
):
|
|
60
|
-
"""
|
|
61
|
-
推送消息
|
|
62
|
-
"""
|
|
63
|
-
message = message or ''
|
|
64
|
-
try:
|
|
65
|
-
logger.verbose('pushing to wxpusher: %s', message)
|
|
66
|
-
wxpusher = Wxpusher()
|
|
67
|
-
wxpusher.push(title, message, images=images)
|
|
68
|
-
except Exception as e:
|
|
69
|
-
logger.warning('push remote message failed: %s', e)
|
|
70
|
-
_save_local(title, message, images)
|
|
71
|
-
|
|
72
|
-
def _show_toast(title: str, message: str | None = None, buttons: list[str] | None = None):
|
|
73
|
-
"""
|
|
74
|
-
统一的 Toast 通知函数
|
|
75
|
-
|
|
76
|
-
:param title: 通知标题
|
|
77
|
-
:param message: 通知消息内容
|
|
78
|
-
:param buttons: 按钮列表,如果提供则显示带按钮的通知
|
|
79
|
-
"""
|
|
80
|
-
try:
|
|
81
|
-
if buttons:
|
|
82
|
-
logger.verbose('showing toast notification with buttons: %s - %s', title, message or '')
|
|
83
|
-
toast(title, message or '', buttons=buttons)
|
|
84
|
-
else:
|
|
85
|
-
# 如果没有 message,只显示 title
|
|
86
|
-
if message:
|
|
87
|
-
logger.verbose('showing toast notification: %s - %s', title, message)
|
|
88
|
-
toast(title, message)
|
|
89
|
-
else:
|
|
90
|
-
logger.verbose('showing toast notification: %s', title)
|
|
91
|
-
toast(title)
|
|
92
|
-
except Exception as e:
|
|
93
|
-
logger.warning('toast notification failed: %s', e)
|
|
94
|
-
|
|
95
|
-
def ask(
|
|
96
|
-
question: str,
|
|
97
|
-
options: list[tuple[str, str]],
|
|
98
|
-
*,
|
|
99
|
-
timeout: float = -1,
|
|
100
|
-
) -> str:
|
|
101
|
-
"""
|
|
102
|
-
询问用户
|
|
103
|
-
"""
|
|
104
|
-
# 将选项转换为按钮列表
|
|
105
|
-
buttons = [option[1] for option in options]
|
|
106
|
-
_show_toast("琴音小助手询问", question, buttons=buttons)
|
|
107
|
-
raise NotImplementedError
|
|
108
|
-
|
|
109
|
-
def info(
|
|
110
|
-
title: str,
|
|
111
|
-
message: str | None = None,
|
|
112
|
-
images: list[MatLike] | None = None,
|
|
113
|
-
*,
|
|
114
|
-
once: bool = False
|
|
115
|
-
):
|
|
116
|
-
logger.info('user.info: %s', message)
|
|
117
|
-
push('KAA:' + title, message, images=images)
|
|
118
|
-
_show_toast('KAA:' + title, message)
|
|
119
|
-
|
|
120
|
-
def warning(
|
|
121
|
-
title: str,
|
|
122
|
-
message: str | None = None,
|
|
123
|
-
images: list[MatLike] | None = None,
|
|
124
|
-
*,
|
|
125
|
-
once: bool = False
|
|
126
|
-
):
|
|
127
|
-
"""
|
|
128
|
-
警告信息。
|
|
129
|
-
|
|
130
|
-
:param message: 消息内容
|
|
131
|
-
:param once: 每次运行是否只显示一次。
|
|
132
|
-
"""
|
|
133
|
-
logger.warning('user.warning: %s', message)
|
|
134
|
-
push("琴音小助手警告:" + title, message, images=images)
|
|
135
|
-
_show_toast("琴音小助手警告:" + title, message)
|
|
136
|
-
|
|
137
|
-
def error(
|
|
138
|
-
title: str,
|
|
139
|
-
message: str | None = None,
|
|
140
|
-
images: list[MatLike] | None = None,
|
|
141
|
-
*,
|
|
142
|
-
once: bool = False
|
|
143
|
-
):
|
|
144
|
-
"""
|
|
145
|
-
错误信息。
|
|
146
|
-
"""
|
|
147
|
-
logger.error('user.error: %s', message)
|
|
148
|
-
push("琴音小助手错误:" + title, message, images=images)
|
|
1
|
+
"""消息框、通知、推送等 UI 相关函数"""
|
|
2
|
+
import os
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
import cv2
|
|
6
|
+
from cv2.typing import MatLike
|
|
7
|
+
from kotonebot.util import is_windows
|
|
8
|
+
if is_windows():
|
|
9
|
+
from win11toast import toast
|
|
10
|
+
else:
|
|
11
|
+
def toast(title: str, message: str | None = None, buttons: list[str] | None = None):
|
|
12
|
+
raise ImportError('toast notification is only available on Windows')
|
|
13
|
+
|
|
14
|
+
from .pushkit import Wxpusher
|
|
15
|
+
from .. import logging
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
def retry(func):
|
|
20
|
+
"""
|
|
21
|
+
装饰器:当函数发生 ConnectionResetError 时自动重试三次
|
|
22
|
+
"""
|
|
23
|
+
def wrapper(*args, **kwargs):
|
|
24
|
+
for i in range(3):
|
|
25
|
+
try:
|
|
26
|
+
return func(*args, **kwargs)
|
|
27
|
+
except ConnectionResetError:
|
|
28
|
+
if i == 2: # 最后一次重试失败
|
|
29
|
+
raise
|
|
30
|
+
logger.warning(f'ConnectionResetError raised when calling {func}, retrying {i+1}/{3}')
|
|
31
|
+
continue
|
|
32
|
+
return wrapper
|
|
33
|
+
|
|
34
|
+
def _save_local(
|
|
35
|
+
title: str,
|
|
36
|
+
message: str,
|
|
37
|
+
images: list[MatLike] | None = None
|
|
38
|
+
):
|
|
39
|
+
"""
|
|
40
|
+
保存消息到本地
|
|
41
|
+
"""
|
|
42
|
+
if not os.path.exists('messages'):
|
|
43
|
+
os.makedirs('messages')
|
|
44
|
+
file_name = f'messages/{time.strftime("%Y-%m-%d_%H-%M-%S")}'
|
|
45
|
+
with open(file_name + '.txt', 'w', encoding='utf-8') as f:
|
|
46
|
+
logger.verbose('saving message to local: %s', file_name + '.txt')
|
|
47
|
+
f.write(message)
|
|
48
|
+
if images is not None:
|
|
49
|
+
for i, image in enumerate(images):
|
|
50
|
+
logger.verbose('saving image to local: %s', f'{file_name}_{i}.png')
|
|
51
|
+
cv2.imwrite(f'{file_name}_{i}.png', image)
|
|
52
|
+
|
|
53
|
+
@retry
|
|
54
|
+
def push(
|
|
55
|
+
title: str,
|
|
56
|
+
message: str | None = None,
|
|
57
|
+
*,
|
|
58
|
+
images: list[MatLike] | None = None
|
|
59
|
+
):
|
|
60
|
+
"""
|
|
61
|
+
推送消息
|
|
62
|
+
"""
|
|
63
|
+
message = message or ''
|
|
64
|
+
try:
|
|
65
|
+
logger.verbose('pushing to wxpusher: %s', message)
|
|
66
|
+
wxpusher = Wxpusher()
|
|
67
|
+
wxpusher.push(title, message, images=images)
|
|
68
|
+
except Exception as e:
|
|
69
|
+
logger.warning('push remote message failed: %s', e)
|
|
70
|
+
_save_local(title, message, images)
|
|
71
|
+
|
|
72
|
+
def _show_toast(title: str, message: str | None = None, buttons: list[str] | None = None):
|
|
73
|
+
"""
|
|
74
|
+
统一的 Toast 通知函数
|
|
75
|
+
|
|
76
|
+
:param title: 通知标题
|
|
77
|
+
:param message: 通知消息内容
|
|
78
|
+
:param buttons: 按钮列表,如果提供则显示带按钮的通知
|
|
79
|
+
"""
|
|
80
|
+
try:
|
|
81
|
+
if buttons:
|
|
82
|
+
logger.verbose('showing toast notification with buttons: %s - %s', title, message or '')
|
|
83
|
+
toast(title, message or '', buttons=buttons)
|
|
84
|
+
else:
|
|
85
|
+
# 如果没有 message,只显示 title
|
|
86
|
+
if message:
|
|
87
|
+
logger.verbose('showing toast notification: %s - %s', title, message)
|
|
88
|
+
toast(title, message)
|
|
89
|
+
else:
|
|
90
|
+
logger.verbose('showing toast notification: %s', title)
|
|
91
|
+
toast(title)
|
|
92
|
+
except Exception as e:
|
|
93
|
+
logger.warning('toast notification failed: %s', e)
|
|
94
|
+
|
|
95
|
+
def ask(
|
|
96
|
+
question: str,
|
|
97
|
+
options: list[tuple[str, str]],
|
|
98
|
+
*,
|
|
99
|
+
timeout: float = -1,
|
|
100
|
+
) -> str:
|
|
101
|
+
"""
|
|
102
|
+
询问用户
|
|
103
|
+
"""
|
|
104
|
+
# 将选项转换为按钮列表
|
|
105
|
+
buttons = [option[1] for option in options]
|
|
106
|
+
_show_toast("琴音小助手询问", question, buttons=buttons)
|
|
107
|
+
raise NotImplementedError
|
|
108
|
+
|
|
109
|
+
def info(
|
|
110
|
+
title: str,
|
|
111
|
+
message: str | None = None,
|
|
112
|
+
images: list[MatLike] | None = None,
|
|
113
|
+
*,
|
|
114
|
+
once: bool = False
|
|
115
|
+
):
|
|
116
|
+
logger.info('user.info: %s', message)
|
|
117
|
+
push('KAA:' + title, message, images=images)
|
|
118
|
+
_show_toast('KAA:' + title, message)
|
|
119
|
+
|
|
120
|
+
def warning(
|
|
121
|
+
title: str,
|
|
122
|
+
message: str | None = None,
|
|
123
|
+
images: list[MatLike] | None = None,
|
|
124
|
+
*,
|
|
125
|
+
once: bool = False
|
|
126
|
+
):
|
|
127
|
+
"""
|
|
128
|
+
警告信息。
|
|
129
|
+
|
|
130
|
+
:param message: 消息内容
|
|
131
|
+
:param once: 每次运行是否只显示一次。
|
|
132
|
+
"""
|
|
133
|
+
logger.warning('user.warning: %s', message)
|
|
134
|
+
push("琴音小助手警告:" + title, message, images=images)
|
|
135
|
+
_show_toast("琴音小助手警告:" + title, message)
|
|
136
|
+
|
|
137
|
+
def error(
|
|
138
|
+
title: str,
|
|
139
|
+
message: str | None = None,
|
|
140
|
+
images: list[MatLike] | None = None,
|
|
141
|
+
*,
|
|
142
|
+
once: bool = False
|
|
143
|
+
):
|
|
144
|
+
"""
|
|
145
|
+
错误信息。
|
|
146
|
+
"""
|
|
147
|
+
logger.error('user.error: %s', message)
|
|
148
|
+
push("琴音小助手错误:" + title, message, images=images)
|
|
149
149
|
_show_toast("琴音小助手错误:" + title, message)
|