nonebot-plugin-ts3-tracker 1.0.0__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.
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.4
2
+ Name: nonebot-plugin-ts3-tracker
3
+ Version: 1.0.0
4
+ Summary: TeamSpeak 3 query and join/leave notification plugin for NoneBot2
5
+ Keywords: nonebot,nonebot2,ts3,teamspeak3,serverquery,onebot
6
+ Author: neri
7
+ License-Expression: MIT
8
+ Requires-Dist: nonebot2>=2.4.4,<3.0.0
9
+ Requires-Dist: nonebot-adapter-onebot>=2.4.0,<3.0.0
10
+ Requires-Dist: nonebot-plugin-localstore>=0.7.4,<1.0.0
11
+ Requires-Dist: pydantic>=2.0.0,<3.0.0
12
+ Requires-Python: >=3.10, <4.0
13
+ Project-URL: Homepage, https://github.com/moeneri/nonebot-plugin-ts3-tracker
14
+ Project-URL: Repository, https://github.com/moeneri/nonebot-plugin-ts3-tracker
15
+ Description-Content-Type: text/markdown
16
+
17
+ # nonebot-plugin-ts3-tracker
18
+
19
+ 基于 NoneBot2 的 TeamSpeak 3 查询与进服/退服通知插件。
20
+
21
+ 本插件提供以下查询命令:
22
+
23
+ - `上号`
24
+ - `ts`
25
+ - `tsinfo`
26
+
27
+ 并补充了适合长期运行的能力:
28
+
29
+ - TS3 进服通知
30
+ - TS3 退服通知
31
+ - 5 秒轮询监控
32
+ - 在线快照持久化
33
+ - 重启后静默同步,避免历史误报
34
+ - 频道内玩家在线时长显示
35
+ - 群聊 / 私聊主动推送
36
+ - 群白名单模式
37
+ - 中文日志输出
38
+
39
+ ## 安装
40
+
41
+ 1. 安装插件:
42
+ `nb plugin install nonebot-plugin-ts3-tracker`
43
+ 2. 确保已安装本插件依赖的 `nonebot-plugin-localstore`
44
+ 3. 在机器人项目中加载插件 `nonebot_plugin_ts3_tracker`
45
+ 4. 配置环境变量
46
+
47
+ ## 基础配置
48
+
49
+ 插件使用以下环境变量:
50
+
51
+ ```env
52
+ TS3_TRACKER__SERVER_HOST=127.0.0.1
53
+ TS3_TRACKER__SERVER_PORT=9987
54
+ TS3_TRACKER__SERVERQUERY_PORT=10011
55
+ TS3_TRACKER__SERVERQUERY_USERNAME=your-serverquery-username
56
+ TS3_TRACKER__SERVERQUERY_PASSWORD=your-password
57
+ TS3_TRACKER__DEBUG=false
58
+ ```
59
+
60
+ ## 配置
61
+
62
+ ```env
63
+ HOST=127.0.0.1
64
+ PORT=8080
65
+
66
+ TS3_TRACKER__SERVER_HOST=127.0.0.1
67
+ TS3_TRACKER__SERVER_PORT=9987
68
+ TS3_TRACKER__SERVERQUERY_PORT=10011
69
+ TS3_TRACKER__SERVERQUERY_USERNAME=your-serverquery-username
70
+ TS3_TRACKER__SERVERQUERY_PASSWORD=your-password
71
+ TS3_TRACKER__DEBUG=false
72
+ TS3_TRACKER__COMMAND_PRIORITY=10
73
+ TS3_TRACKER__QUERY_TIMEOUT_SECONDS=10
74
+
75
+ TS3_TRACKER__NOTIFICATION_ENABLED=true
76
+ TS3_TRACKER__NOTIFY_TARGET_GROUPS=123456789
77
+ TS3_TRACKER__NOTIFY_TARGET_USERS=
78
+ TS3_TRACKER__NOTIFY_BOT_ID=
79
+
80
+ TS3_TRACKER__GROUP_WHITELIST_ENABLED=false
81
+ TS3_TRACKER__GROUP_WHITELIST_GROUPS=
82
+
83
+ TS3_TRACKER__POLL_INTERVAL_SECONDS=5
84
+ TS3_TRACKER__STARTUP_SILENT=true
85
+ TS3_TRACKER__DATA_DIR=data/ts3_tracker
86
+ ```
87
+
88
+ 配置说明:
89
+
90
+ - `TS3_TRACKER__SERVER_HOST`:TS3 服务器地址
91
+ - `TS3_TRACKER__SERVER_PORT`:TS3 语音端口,通常为 `9987`
92
+ - `TS3_TRACKER__SERVERQUERY_PORT`:TS3 ServerQuery 端口,通常为 `10011`
93
+ - `TS3_TRACKER__SERVERQUERY_USERNAME`:ServerQuery 用户名
94
+ - `TS3_TRACKER__SERVERQUERY_PASSWORD`:ServerQuery 密码
95
+ - `TS3_TRACKER__DEBUG`:是否输出调试日志
96
+ - `TS3_TRACKER__COMMAND_PRIORITY`:命令优先级
97
+ - `TS3_TRACKER__QUERY_TIMEOUT_SECONDS`:单次查询超时秒数
98
+ - `TS3_TRACKER__NOTIFICATION_ENABLED`:是否启用进服/退服通知
99
+ - `TS3_TRACKER__NOTIFY_TARGET_GROUPS`:接收通知的群号,支持逗号、分号、换行分隔
100
+ - `TS3_TRACKER__NOTIFY_TARGET_USERS`:接收通知的私聊 QQ,支持逗号、分号、换行分隔
101
+ - `TS3_TRACKER__NOTIFY_BOT_ID`:指定发送主动通知的 OneBot v11 Bot ID
102
+ - `TS3_TRACKER__GROUP_WHITELIST_ENABLED`:是否开启群白名单模式
103
+ - `TS3_TRACKER__GROUP_WHITELIST_GROUPS`:允许使用群命令查询,且允许接收群通知的白名单群号
104
+ - `TS3_TRACKER__POLL_INTERVAL_SECONDS`:轮询间隔,默认 `5`
105
+ - `TS3_TRACKER__STARTUP_SILENT`:启动时只同步快照,不立刻发送历史在线通知
106
+ - `TS3_TRACKER__DATA_DIR`:自定义快照持久化目录;不填写时使用 `nonebot-plugin-localstore` 的插件数据目录
107
+
108
+ ## 群白名单模式
109
+
110
+ 默认情况下:
111
+
112
+ - 所有群聊都可以使用 `上号`、`ts`、`tsinfo`
113
+ - 所有私聊都可以使用查询命令
114
+ - 通知只会发给 `TS3_TRACKER__NOTIFY_TARGET_GROUPS` 和 `TS3_TRACKER__NOTIFY_TARGET_USERS`
115
+
116
+ 当开启白名单模式后:
117
+
118
+ ```env
119
+ TS3_TRACKER__GROUP_WHITELIST_ENABLED=true
120
+ TS3_TRACKER__GROUP_WHITELIST_GROUPS=123456789
121
+ ```
122
+
123
+ 效果如下:
124
+
125
+ - 只有白名单群可以使用群聊查询命令
126
+ - 私聊仍然可以查询
127
+ - 群通知只会发到白名单内,且同时存在于 `TS3_TRACKER__NOTIFY_TARGET_GROUPS` 的群
128
+
129
+ ## 命令
130
+
131
+ 群聊或私聊发送以下任一命令:
132
+
133
+ ```text
134
+ 上号
135
+ ts
136
+ tsinfo
137
+ ```
138
+
139
+ ## 查询返回示例
140
+
141
+ ```text
142
+ 服务器地址:127.0.0.1:9987
143
+ 服务器端口:9987
144
+ 服务器名称:迷你世界高手大会
145
+ 服务器频道:
146
+ APEX: neri(20秒)
147
+ 原神
148
+ 守望先锋-归西
149
+ 穿越火线
150
+ 永雏塔菲
151
+ 高能英雄
152
+ 三国杀
153
+ 迷你世界
154
+ 王者荣耀
155
+ 三角洲行动
156
+ ```
157
+
158
+ ## 通知示例
159
+
160
+ 进服通知:
161
+
162
+ ```text
163
+ 让我看看是谁还没上号 👀
164
+ 🧾 昵称:neri
165
+ 🟢 上线时间:2026-03-16 00:33:19
166
+ 📣 neri 进入了 TS 服务器
167
+ 👥 当前在线人数:3
168
+ 📜 在线列表:neri, koishi
169
+ ```
170
+
171
+ 退服通知:
172
+
173
+ ```text
174
+ 📤 用户下线通知
175
+ 🧾 昵称:neri
176
+ 🟢 上线时间:2026-03-16 00:32:51
177
+ 🔴 下线时间:2026-03-16 01:31:37
178
+ ⏱️ 在线时长:58分46秒
179
+ 👥 当前在线人数:2
180
+ 📜 在线列表:KirA, Cirno
181
+ ```
182
+
183
+ ## 日志示例
184
+
185
+ ```text
186
+ 群号 123456789 查询了服务器信息。
187
+ neri 进入了服务器。
188
+ neri 退出了服务器。
189
+ ```
190
+
191
+ ## 数据持久化
192
+
193
+ 插件当前不是通过数据库持久化。
194
+
195
+ 它使用本地 JSON 快照文件记录在线状态。
196
+
197
+ 默认情况下,文件通过 `nonebot-plugin-localstore` 保存到插件专属数据目录。
198
+
199
+ 如果你手动设置了 `TS3_TRACKER__DATA_DIR`,则会改为保存到你指定目录下的:
200
+
201
+ ```text
202
+ <TS3_TRACKER__DATA_DIR>/snapshot.json
203
+ ```
204
+
205
+ 快照中主要保存:
206
+
207
+ - 用户唯一标识
208
+ - 所在频道
209
+ - 首次上线时间
210
+ - 已连接时长
211
+ - 离开检测所需的对比状态
212
+
213
+ ## 验证
214
+
215
+ 运行单元测试:
216
+
217
+ ```bash
218
+ pytest
219
+ ```
220
+
221
+ 实时验证 TS3 查询:
222
+
223
+ ```bash
224
+ python scripts/verify_live.py
225
+ ```
226
+
227
+ ## NoneBot2 规范确认
228
+
229
+ 已按本地 `nonebot2-master` 文档核对以下要求:
230
+
231
+ - 使用 `PluginMetadata` 声明插件元信息
232
+ - 明确 `config=Config`
233
+ - 明确 `supported_adapters={"nonebot.adapters.onebot.v11"}`
234
+ - 使用标准 `pyproject.toml` 打包结构
235
+ - 根目录包含 `README.md`、`LICENSE`、测试目录与验证脚本
@@ -0,0 +1,219 @@
1
+ # nonebot-plugin-ts3-tracker
2
+
3
+ 基于 NoneBot2 的 TeamSpeak 3 查询与进服/退服通知插件。
4
+
5
+ 本插件提供以下查询命令:
6
+
7
+ - `上号`
8
+ - `ts`
9
+ - `tsinfo`
10
+
11
+ 并补充了适合长期运行的能力:
12
+
13
+ - TS3 进服通知
14
+ - TS3 退服通知
15
+ - 5 秒轮询监控
16
+ - 在线快照持久化
17
+ - 重启后静默同步,避免历史误报
18
+ - 频道内玩家在线时长显示
19
+ - 群聊 / 私聊主动推送
20
+ - 群白名单模式
21
+ - 中文日志输出
22
+
23
+ ## 安装
24
+
25
+ 1. 安装插件:
26
+ `nb plugin install nonebot-plugin-ts3-tracker`
27
+ 2. 确保已安装本插件依赖的 `nonebot-plugin-localstore`
28
+ 3. 在机器人项目中加载插件 `nonebot_plugin_ts3_tracker`
29
+ 4. 配置环境变量
30
+
31
+ ## 基础配置
32
+
33
+ 插件使用以下环境变量:
34
+
35
+ ```env
36
+ TS3_TRACKER__SERVER_HOST=127.0.0.1
37
+ TS3_TRACKER__SERVER_PORT=9987
38
+ TS3_TRACKER__SERVERQUERY_PORT=10011
39
+ TS3_TRACKER__SERVERQUERY_USERNAME=your-serverquery-username
40
+ TS3_TRACKER__SERVERQUERY_PASSWORD=your-password
41
+ TS3_TRACKER__DEBUG=false
42
+ ```
43
+
44
+ ## 配置
45
+
46
+ ```env
47
+ HOST=127.0.0.1
48
+ PORT=8080
49
+
50
+ TS3_TRACKER__SERVER_HOST=127.0.0.1
51
+ TS3_TRACKER__SERVER_PORT=9987
52
+ TS3_TRACKER__SERVERQUERY_PORT=10011
53
+ TS3_TRACKER__SERVERQUERY_USERNAME=your-serverquery-username
54
+ TS3_TRACKER__SERVERQUERY_PASSWORD=your-password
55
+ TS3_TRACKER__DEBUG=false
56
+ TS3_TRACKER__COMMAND_PRIORITY=10
57
+ TS3_TRACKER__QUERY_TIMEOUT_SECONDS=10
58
+
59
+ TS3_TRACKER__NOTIFICATION_ENABLED=true
60
+ TS3_TRACKER__NOTIFY_TARGET_GROUPS=123456789
61
+ TS3_TRACKER__NOTIFY_TARGET_USERS=
62
+ TS3_TRACKER__NOTIFY_BOT_ID=
63
+
64
+ TS3_TRACKER__GROUP_WHITELIST_ENABLED=false
65
+ TS3_TRACKER__GROUP_WHITELIST_GROUPS=
66
+
67
+ TS3_TRACKER__POLL_INTERVAL_SECONDS=5
68
+ TS3_TRACKER__STARTUP_SILENT=true
69
+ TS3_TRACKER__DATA_DIR=data/ts3_tracker
70
+ ```
71
+
72
+ 配置说明:
73
+
74
+ - `TS3_TRACKER__SERVER_HOST`:TS3 服务器地址
75
+ - `TS3_TRACKER__SERVER_PORT`:TS3 语音端口,通常为 `9987`
76
+ - `TS3_TRACKER__SERVERQUERY_PORT`:TS3 ServerQuery 端口,通常为 `10011`
77
+ - `TS3_TRACKER__SERVERQUERY_USERNAME`:ServerQuery 用户名
78
+ - `TS3_TRACKER__SERVERQUERY_PASSWORD`:ServerQuery 密码
79
+ - `TS3_TRACKER__DEBUG`:是否输出调试日志
80
+ - `TS3_TRACKER__COMMAND_PRIORITY`:命令优先级
81
+ - `TS3_TRACKER__QUERY_TIMEOUT_SECONDS`:单次查询超时秒数
82
+ - `TS3_TRACKER__NOTIFICATION_ENABLED`:是否启用进服/退服通知
83
+ - `TS3_TRACKER__NOTIFY_TARGET_GROUPS`:接收通知的群号,支持逗号、分号、换行分隔
84
+ - `TS3_TRACKER__NOTIFY_TARGET_USERS`:接收通知的私聊 QQ,支持逗号、分号、换行分隔
85
+ - `TS3_TRACKER__NOTIFY_BOT_ID`:指定发送主动通知的 OneBot v11 Bot ID
86
+ - `TS3_TRACKER__GROUP_WHITELIST_ENABLED`:是否开启群白名单模式
87
+ - `TS3_TRACKER__GROUP_WHITELIST_GROUPS`:允许使用群命令查询,且允许接收群通知的白名单群号
88
+ - `TS3_TRACKER__POLL_INTERVAL_SECONDS`:轮询间隔,默认 `5`
89
+ - `TS3_TRACKER__STARTUP_SILENT`:启动时只同步快照,不立刻发送历史在线通知
90
+ - `TS3_TRACKER__DATA_DIR`:自定义快照持久化目录;不填写时使用 `nonebot-plugin-localstore` 的插件数据目录
91
+
92
+ ## 群白名单模式
93
+
94
+ 默认情况下:
95
+
96
+ - 所有群聊都可以使用 `上号`、`ts`、`tsinfo`
97
+ - 所有私聊都可以使用查询命令
98
+ - 通知只会发给 `TS3_TRACKER__NOTIFY_TARGET_GROUPS` 和 `TS3_TRACKER__NOTIFY_TARGET_USERS`
99
+
100
+ 当开启白名单模式后:
101
+
102
+ ```env
103
+ TS3_TRACKER__GROUP_WHITELIST_ENABLED=true
104
+ TS3_TRACKER__GROUP_WHITELIST_GROUPS=123456789
105
+ ```
106
+
107
+ 效果如下:
108
+
109
+ - 只有白名单群可以使用群聊查询命令
110
+ - 私聊仍然可以查询
111
+ - 群通知只会发到白名单内,且同时存在于 `TS3_TRACKER__NOTIFY_TARGET_GROUPS` 的群
112
+
113
+ ## 命令
114
+
115
+ 群聊或私聊发送以下任一命令:
116
+
117
+ ```text
118
+ 上号
119
+ ts
120
+ tsinfo
121
+ ```
122
+
123
+ ## 查询返回示例
124
+
125
+ ```text
126
+ 服务器地址:127.0.0.1:9987
127
+ 服务器端口:9987
128
+ 服务器名称:迷你世界高手大会
129
+ 服务器频道:
130
+ APEX: neri(20秒)
131
+ 原神
132
+ 守望先锋-归西
133
+ 穿越火线
134
+ 永雏塔菲
135
+ 高能英雄
136
+ 三国杀
137
+ 迷你世界
138
+ 王者荣耀
139
+ 三角洲行动
140
+ ```
141
+
142
+ ## 通知示例
143
+
144
+ 进服通知:
145
+
146
+ ```text
147
+ 让我看看是谁还没上号 👀
148
+ 🧾 昵称:neri
149
+ 🟢 上线时间:2026-03-16 00:33:19
150
+ 📣 neri 进入了 TS 服务器
151
+ 👥 当前在线人数:3
152
+ 📜 在线列表:neri, koishi
153
+ ```
154
+
155
+ 退服通知:
156
+
157
+ ```text
158
+ 📤 用户下线通知
159
+ 🧾 昵称:neri
160
+ 🟢 上线时间:2026-03-16 00:32:51
161
+ 🔴 下线时间:2026-03-16 01:31:37
162
+ ⏱️ 在线时长:58分46秒
163
+ 👥 当前在线人数:2
164
+ 📜 在线列表:KirA, Cirno
165
+ ```
166
+
167
+ ## 日志示例
168
+
169
+ ```text
170
+ 群号 123456789 查询了服务器信息。
171
+ neri 进入了服务器。
172
+ neri 退出了服务器。
173
+ ```
174
+
175
+ ## 数据持久化
176
+
177
+ 插件当前不是通过数据库持久化。
178
+
179
+ 它使用本地 JSON 快照文件记录在线状态。
180
+
181
+ 默认情况下,文件通过 `nonebot-plugin-localstore` 保存到插件专属数据目录。
182
+
183
+ 如果你手动设置了 `TS3_TRACKER__DATA_DIR`,则会改为保存到你指定目录下的:
184
+
185
+ ```text
186
+ <TS3_TRACKER__DATA_DIR>/snapshot.json
187
+ ```
188
+
189
+ 快照中主要保存:
190
+
191
+ - 用户唯一标识
192
+ - 所在频道
193
+ - 首次上线时间
194
+ - 已连接时长
195
+ - 离开检测所需的对比状态
196
+
197
+ ## 验证
198
+
199
+ 运行单元测试:
200
+
201
+ ```bash
202
+ pytest
203
+ ```
204
+
205
+ 实时验证 TS3 查询:
206
+
207
+ ```bash
208
+ python scripts/verify_live.py
209
+ ```
210
+
211
+ ## NoneBot2 规范确认
212
+
213
+ 已按本地 `nonebot2-master` 文档核对以下要求:
214
+
215
+ - 使用 `PluginMetadata` 声明插件元信息
216
+ - 明确 `config=Config`
217
+ - 明确 `supported_adapters={"nonebot.adapters.onebot.v11"}`
218
+ - 使用标准 `pyproject.toml` 打包结构
219
+ - 根目录包含 `README.md`、`LICENSE`、测试目录与验证脚本
@@ -0,0 +1,87 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+
5
+ from nonebot import get_driver, get_plugin_config, logger, on_command, on_regex
6
+ from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent
7
+ from nonebot.plugin import PluginMetadata
8
+
9
+ from .config import Config
10
+ from .runtime import Ts3TrackerRuntime
11
+ from .service import Ts3TrackerService
12
+
13
+ plugin_config = get_plugin_config(Config).ts3_tracker
14
+ service = Ts3TrackerService(plugin_config)
15
+ runtime = Ts3TrackerRuntime(plugin_config, service)
16
+
17
+ __plugin_meta__ = PluginMetadata(
18
+ name="TS3 Tracker",
19
+ description="查询 TeamSpeak 3 服务器在线状态与频道在线成员。",
20
+ usage=(
21
+ "上号\n"
22
+ "/ts\n"
23
+ "/tsinfo\n\n"
24
+ "可选:开启轮询后发送 TS3 进服/退服通知"
25
+ ),
26
+ type="application",
27
+ homepage="https://github.com/moeneri/nonebot-plugin-ts3-tracker",
28
+ config=Config,
29
+ supported_adapters={"nonebot.adapters.onebot.v11"},
30
+ )
31
+
32
+
33
+ def _ensure_group_allowed(event: MessageEvent) -> str | None:
34
+ if not isinstance(event, GroupMessageEvent):
35
+ return None
36
+ if plugin_config.is_group_allowed(event.group_id):
37
+ return None
38
+ return "当前群未开启 TS3 查询白名单权限。"
39
+
40
+
41
+ ts3_status = on_command(
42
+ "上号",
43
+ aliases={"ts", "tsinfo"},
44
+ priority=plugin_config.command_priority,
45
+ block=True,
46
+ )
47
+ ts3_status_regex = on_regex(
48
+ r"^(?:/)?(?:上号|ts|tsinfo)$",
49
+ flags=re.IGNORECASE,
50
+ priority=plugin_config.command_priority,
51
+ block=True,
52
+ )
53
+
54
+
55
+ @ts3_status.handle()
56
+ async def handle_ts3_status(event: MessageEvent) -> None:
57
+ denied_message = _ensure_group_allowed(event)
58
+ if denied_message is not None:
59
+ await ts3_status.finish(denied_message)
60
+
61
+ group_id = getattr(event, "group_id", None)
62
+ logger.info(
63
+ "群号 {} 查询了服务器信息。",
64
+ group_id if group_id is not None else event.get_session_id(),
65
+ )
66
+ message = await service.build_server_message()
67
+ await ts3_status.finish(message)
68
+
69
+
70
+ @ts3_status_regex.handle()
71
+ async def handle_ts3_status_regex(event: MessageEvent) -> None:
72
+ denied_message = _ensure_group_allowed(event)
73
+ if denied_message is not None:
74
+ await ts3_status_regex.finish(denied_message)
75
+
76
+ group_id = getattr(event, "group_id", None)
77
+ logger.info(
78
+ "群号 {} 查询了服务器信息。",
79
+ group_id if group_id is not None else event.get_session_id(),
80
+ )
81
+ message = await service.build_server_message()
82
+ await ts3_status_regex.finish(message)
83
+
84
+
85
+ driver = get_driver()
86
+ driver.on_startup(runtime.startup)
87
+ driver.on_shutdown(runtime.shutdown)
@@ -0,0 +1,69 @@
1
+ from __future__ import annotations
2
+
3
+ from pydantic import BaseModel, Field, field_validator
4
+
5
+
6
+ class Ts3TrackerSettings(BaseModel):
7
+ server_host: str = ""
8
+ server_port: int = 9987
9
+ serverquery_port: int = 10011
10
+ serverquery_username: str = ""
11
+ serverquery_password: str = ""
12
+ debug: bool = False
13
+ command_priority: int = 10
14
+ query_timeout_seconds: float = 10.0
15
+ notification_enabled: bool = False
16
+ notify_target_groups: str = ""
17
+ notify_target_users: str = ""
18
+ notify_bot_id: str = ""
19
+ group_whitelist_enabled: bool = False
20
+ group_whitelist_groups: str = ""
21
+ poll_interval_seconds: int = 5
22
+ startup_silent: bool = True
23
+ data_dir: str = ""
24
+
25
+ @field_validator(
26
+ "server_host",
27
+ "serverquery_username",
28
+ "serverquery_password",
29
+ "notify_target_groups",
30
+ "notify_target_users",
31
+ "notify_bot_id",
32
+ "group_whitelist_groups",
33
+ "data_dir",
34
+ mode="before",
35
+ )
36
+ @classmethod
37
+ def strip_text(cls, value: object) -> str:
38
+ return str(value).strip()
39
+
40
+ @field_validator("command_priority", "poll_interval_seconds")
41
+ @classmethod
42
+ def validate_positive_int(cls, value: int) -> int:
43
+ return max(1, value)
44
+
45
+ @field_validator("query_timeout_seconds")
46
+ @classmethod
47
+ def validate_timeout(cls, value: float) -> float:
48
+ return max(1.0, value)
49
+
50
+ def parse_targets(self, raw: str) -> list[str]:
51
+ normalized = raw.replace("\r", "\n").replace(";", "\n").replace(",", "\n")
52
+ targets = [item.strip() for item in normalized.split("\n")]
53
+ return [item for item in targets if item]
54
+
55
+ def is_group_allowed(self, group_id: str | int | None) -> bool:
56
+ if group_id is None or not self.group_whitelist_enabled:
57
+ return True
58
+ return str(group_id) in set(self.parse_targets(self.group_whitelist_groups))
59
+
60
+ def get_effective_notify_groups(self) -> list[str]:
61
+ notify_groups = self.parse_targets(self.notify_target_groups)
62
+ if not self.group_whitelist_enabled:
63
+ return notify_groups
64
+ whitelist = set(self.parse_targets(self.group_whitelist_groups))
65
+ return [group_id for group_id in notify_groups if group_id in whitelist]
66
+
67
+
68
+ class Config(BaseModel):
69
+ ts3_tracker: Ts3TrackerSettings = Field(default_factory=Ts3TrackerSettings)
@@ -0,0 +1,26 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+
5
+
6
+ @dataclass(slots=True)
7
+ class Ts3OnlineUser:
8
+ nickname: str
9
+ channel_id: str
10
+ channel_name: str
11
+ client_id: str
12
+ database_id: str
13
+ unique_id: str
14
+ client_ip: str
15
+ connected_duration_seconds: int
16
+ away: bool
17
+
18
+
19
+ @dataclass(slots=True)
20
+ class Ts3ServerStatus:
21
+ server_name: str
22
+ server_host: str
23
+ server_port: int
24
+ online_count: int
25
+ channels: list[tuple[str, str]]
26
+ users: list[Ts3OnlineUser]