ascript 1.3.27__py3-none-win_amd64.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.
Files changed (177) hide show
  1. ascript/__init__.py +8 -0
  2. ascript/hooks/__init__.py +0 -0
  3. ascript/hooks/hook-ascript.py +2 -0
  4. ascript/windows/__init__.py +29 -0
  5. ascript/windows/daos/__init__.py +0 -0
  6. ascript/windows/daos/screen.py +143 -0
  7. ascript/windows/hardware/__init__.py +5 -0
  8. ascript/windows/hardware/keyboard.py +279 -0
  9. ascript/windows/hardware/logitech_driver.py +179 -0
  10. ascript/windows/hardware/mouse.py +308 -0
  11. ascript/windows/license/__init__.py +16 -0
  12. ascript/windows/license/achttp.cp310-win_amd64.pyd +0 -0
  13. ascript/windows/license/achttp.cp311-win_amd64.pyd +0 -0
  14. ascript/windows/license/achttp.cp312-win_amd64.pyd +0 -0
  15. ascript/windows/license/achttp.cp313-win_amd64.pyd +0 -0
  16. ascript/windows/license/achttp.cp314-win_amd64.pyd +0 -0
  17. ascript/windows/license/achttp.cp38-win_amd64.pyd +0 -0
  18. ascript/windows/license/achttp.cp39-win_amd64.pyd +0 -0
  19. ascript/windows/media/__init__.py +0 -0
  20. ascript/windows/resources/__init__.py +0 -0
  21. ascript/windows/resources/libs/logitech/x64/LogitechGkeyEnginesWrapper.dll +0 -0
  22. ascript/windows/resources/libs/logitech/x86/LogitechGkeyEnginesWrapper.dll +0 -0
  23. ascript/windows/resources/templates/__init__.py +0 -0
  24. ascript/windows/resources/templates/__init__py.win.template +51 -0
  25. ascript/windows/resources/templates/build.as.win.template +14 -0
  26. ascript/windows/resources/templates/build.py +71 -0
  27. ascript/windows/resources/templates/logo_windows.ico +0 -0
  28. ascript/windows/resources/templates/windows/main.py +50 -0
  29. ascript/windows/resources/templates/windows/pyproject.toml +44 -0
  30. ascript/windows/resources/templates/windows/res/img/logo.ico +0 -0
  31. ascript/windows/screen/__init__.py +13 -0
  32. ascript/windows/screen/as_cv.py +382 -0
  33. ascript/windows/screen/canny.py +128 -0
  34. ascript/windows/screen/code_scanner.py +72 -0
  35. ascript/windows/screen/color_algorithms.py +277 -0
  36. ascript/windows/screen/find_colors.py +251 -0
  37. ascript/windows/screen/find_images.py +217 -0
  38. ascript/windows/screen/ocr/__init__.py +4 -0
  39. ascript/windows/screen/ocr/ocr.py +223 -0
  40. ascript/windows/screen/ocr/rapidocr_hook.py +301 -0
  41. ascript/windows/screen/ocrx.py +169 -0
  42. ascript/windows/screen/screen_core.py +139 -0
  43. ascript/windows/store/__init__.py +21 -0
  44. ascript/windows/system/__init__.py +8 -0
  45. ascript/windows/system/device.py +355 -0
  46. ascript/windows/system/easy_print.py +115 -0
  47. ascript/windows/system/env.py +492 -0
  48. ascript/windows/system/exception/__init__.py +1 -0
  49. ascript/windows/system/key_value.py +145 -0
  50. ascript/windows/system/pip.py +175 -0
  51. ascript/windows/system/r.py +165 -0
  52. ascript/windows/system/runtime.py +62 -0
  53. ascript/windows/tools/__init__.py +27 -0
  54. ascript/windows/tools/__main__.py +21 -0
  55. ascript/windows/tools/action.json +33 -0
  56. ascript/windows/tools/action.py +168 -0
  57. ascript/windows/tools/colors_tool.py +391 -0
  58. ascript/windows/tools/config.py +26 -0
  59. ascript/windows/tools/dumptool.py +18 -0
  60. ascript/windows/tools/eel_api.py +495 -0
  61. ascript/windows/tools/gpplug/__init__.py +0 -0
  62. ascript/windows/tools/gpplug/plug.py +70 -0
  63. ascript/windows/tools/mouse_catch.py +168 -0
  64. ascript/windows/tools/plug_manager.py +38 -0
  65. ascript/windows/tools/tool_api.py +906 -0
  66. ascript/windows/tools/tool_window.py +56 -0
  67. ascript/windows/tools/uia_worker.py +365 -0
  68. ascript/windows/tools/web/app_store_window.html +481 -0
  69. ascript/windows/tools/web/colors.html +532 -0
  70. ascript/windows/tools/web/css/screen.css +1342 -0
  71. ascript/windows/tools/web/css/viewtree.css +357 -0
  72. ascript/windows/tools/web/flot_control.html +195 -0
  73. ascript/windows/tools/web/img/ico/favicon.png +0 -0
  74. ascript/windows/tools/web/img/ico/paintpalette.png +0 -0
  75. ascript/windows/tools/web/img/svg/find_colors.svg +1 -0
  76. ascript/windows/tools/web/img/svg/find_images.svg +1 -0
  77. ascript/windows/tools/web/img/svg/illustration-6.svg +89 -0
  78. ascript/windows/tools/web/img/svg/img_default.svg +1 -0
  79. ascript/windows/tools/web/img/svg/ocr.svg +1 -0
  80. ascript/windows/tools/web/js/screen/colors.js +466 -0
  81. ascript/windows/tools/web/js/screen/gp_plug.js +108 -0
  82. ascript/windows/tools/web/js/screen/image_mouse.js +464 -0
  83. ascript/windows/tools/web/js/screen/img_view.js +558 -0
  84. ascript/windows/tools/web/js/screen/plug.js +246 -0
  85. ascript/windows/tools/web/js/screen/screen.js +690 -0
  86. ascript/windows/tools/web/js/screen/screen_api.js +778 -0
  87. ascript/windows/tools/web/js/screen/screen_maker.js +10 -0
  88. ascript/windows/tools/web/js/utils/map.js +73 -0
  89. ascript/windows/tools/web/js/utils/upload.js +157 -0
  90. ascript/windows/tools/web/js/viewtree/niv_js.js +27 -0
  91. ascript/windows/tools/web/js/viewtree/vtree.js +1510 -0
  92. ascript/windows/tools/web/libs/bootstrap/css/bootstrap.min.css +6 -0
  93. ascript/windows/tools/web/libs/bootstrap/js/bootstrap.bundle.min.js +7 -0
  94. ascript/windows/tools/web/libs/bootstrap-icons/0-circle.svg +4 -0
  95. ascript/windows/tools/web/libs/bootstrap-icons/0-square.svg +4 -0
  96. ascript/windows/tools/web/libs/bootstrap-icons/font/bootstrap-icons.css +2078 -0
  97. ascript/windows/tools/web/libs/bootstrap-icons/font/bootstrap-icons.json +2052 -0
  98. ascript/windows/tools/web/libs/bootstrap-icons/font/bootstrap-icons.min.css +5 -0
  99. ascript/windows/tools/web/libs/bootstrap-icons/font/bootstrap-icons.scss +2090 -0
  100. ascript/windows/tools/web/libs/bootstrap-icons/font/fonts/bootstrap-icons.woff +0 -0
  101. ascript/windows/tools/web/libs/bootstrap-icons/font/fonts/bootstrap-icons.woff2 +0 -0
  102. ascript/windows/tools/web/libs/feather-icons/dist/feather.min.js +13 -0
  103. ascript/windows/tools/web/libs/feather-icons/dist/icons.json +1 -0
  104. ascript/windows/tools/web/libs/jquery/core.js +399 -0
  105. ascript/windows/tools/web/libs/jquery/jquery.js +10598 -0
  106. ascript/windows/tools/web/libs/jquery/jquery.min.js +4 -0
  107. ascript/windows/tools/web/libs/jquery/jquery.min.js.zip +0 -0
  108. ascript/windows/tools/web/libs/jquery/jquery.slim.js +8495 -0
  109. ascript/windows/tools/web/libs/jquery/jquery.slim.min.js +2 -0
  110. ascript/windows/tools/web/libs/jquery-menu/jquery.contextMenu.js +2134 -0
  111. ascript/windows/tools/web/libs/jquery-menu/jquery.contextMenu.min.css +16 -0
  112. ascript/windows/tools/web/libs/jquery-zTree/css/zTreeStyle.css +97 -0
  113. ascript/windows/tools/web/libs/jquery-zTree/img/diy/1_close.png +0 -0
  114. ascript/windows/tools/web/libs/jquery-zTree/img/diy/1_open.png +0 -0
  115. ascript/windows/tools/web/libs/jquery-zTree/img/diy/2.png +0 -0
  116. ascript/windows/tools/web/libs/jquery-zTree/img/diy/3.png +0 -0
  117. ascript/windows/tools/web/libs/jquery-zTree/img/diy/4.png +0 -0
  118. ascript/windows/tools/web/libs/jquery-zTree/img/diy/5.png +0 -0
  119. ascript/windows/tools/web/libs/jquery-zTree/img/diy/6.png +0 -0
  120. ascript/windows/tools/web/libs/jquery-zTree/img/diy/7.png +0 -0
  121. ascript/windows/tools/web/libs/jquery-zTree/img/diy/8.png +0 -0
  122. ascript/windows/tools/web/libs/jquery-zTree/img/diy/9.png +0 -0
  123. ascript/windows/tools/web/libs/jquery-zTree/img/line_conn.gif +0 -0
  124. ascript/windows/tools/web/libs/jquery-zTree/img/loading.gif +0 -0
  125. ascript/windows/tools/web/libs/jquery-zTree/img/tree-node-btn.png +0 -0
  126. ascript/windows/tools/web/libs/jquery-zTree/img/zTreeStandard.gif +0 -0
  127. ascript/windows/tools/web/libs/jquery-zTree/img/zTreeStandard.png +0 -0
  128. ascript/windows/tools/web/libs/jquery-zTree/js/jquery.ztree.all.min.js +3 -0
  129. ascript/windows/tools/web/libs/treeview/css/jquery.treeview.css +79 -0
  130. ascript/windows/tools/web/libs/treeview/img/file.png +0 -0
  131. ascript/windows/tools/web/libs/treeview/img/ico_loading.png +0 -0
  132. ascript/windows/tools/web/libs/treeview/img/icon4.png +0 -0
  133. ascript/windows/tools/web/libs/treeview/img/icon5.png +0 -0
  134. ascript/windows/tools/web/libs/treeview/img/icon6.png +0 -0
  135. ascript/windows/tools/web/libs/treeview/img/py.png +0 -0
  136. ascript/windows/tools/web/libs/treeview/img/treeview-black-line.gif +0 -0
  137. ascript/windows/tools/web/libs/treeview/img/treeview-black.gif +0 -0
  138. ascript/windows/tools/web/libs/treeview/img/treeview-default-line.gif +0 -0
  139. ascript/windows/tools/web/libs/treeview/img/treeview-default.gif +0 -0
  140. ascript/windows/tools/web/libs/treeview/img/treeview-famfamfam-line.gif +0 -0
  141. ascript/windows/tools/web/libs/treeview/img/treeview-famfamfam.gif +0 -0
  142. ascript/windows/tools/web/libs/treeview/img/treeview-gray-line.gif +0 -0
  143. ascript/windows/tools/web/libs/treeview/img/treeview-gray.gif +0 -0
  144. ascript/windows/tools/web/libs/treeview/img/treeview-red-line.gif +0 -0
  145. ascript/windows/tools/web/libs/treeview/img/treeview-red.gif +0 -0
  146. ascript/windows/tools/web/libs/treeview/js/jquery.treeview.edit.js +37 -0
  147. ascript/windows/tools/web/libs/treeview/js/jquery.treeview.js +250 -0
  148. ascript/windows/tools/web/license_window.html +255 -0
  149. ascript/windows/tools/web/plugs/a.html +653 -0
  150. ascript/windows/tools/web/plugs/demo.html +52 -0
  151. ascript/windows/tools/web/plugs/find_colors.html +629 -0
  152. ascript/windows/tools/web/plugs/find_images.html +699 -0
  153. ascript/windows/tools/web/plugs/rapidocr.html +954 -0
  154. ascript/windows/tools/web/vtree.html +496 -0
  155. ascript/windows/tools/webview/assets/index-HymBPl-I.css +1 -0
  156. ascript/windows/tools/webview/assets/index-PqA_m8tL.js +17 -0
  157. ascript/windows/tools/webview/index.html +13 -0
  158. ascript/windows/ui/__init__.py +6 -0
  159. ascript/windows/ui/app_store_window.py +272 -0
  160. ascript/windows/ui/draw_window.py +231 -0
  161. ascript/windows/ui/flot_test.py +297 -0
  162. ascript/windows/ui/flot_window.py +488 -0
  163. ascript/windows/ui/license_window.py +111 -0
  164. ascript/windows/ui/web_window.py +466 -0
  165. ascript/windows/utils/__init__.py +0 -0
  166. ascript/windows/utils/node_utils.py +20 -0
  167. ascript/windows/utils/screen_utils.py +280 -0
  168. ascript/windows/window/Selector.py +1015 -0
  169. ascript/windows/window/Window.py +747 -0
  170. ascript/windows/window/__init__.py +5 -0
  171. ascript/windows/window/launcher.py +213 -0
  172. ascript/windows/window/uia_runtime.py +26 -0
  173. ascript-1.3.27.dist-info/METADATA +41 -0
  174. ascript-1.3.27.dist-info/RECORD +177 -0
  175. ascript-1.3.27.dist-info/WHEEL +5 -0
  176. ascript-1.3.27.dist-info/entry_points.txt +2 -0
  177. ascript-1.3.27.dist-info/top_level.txt +1 -0
@@ -0,0 +1,355 @@
1
+ import psutil
2
+ import platform
3
+ import socket
4
+ import uuid
5
+ import ctypes
6
+ import os
7
+ import sys
8
+ import time
9
+ from datetime import datetime
10
+ from typing import Dict, Any, List
11
+
12
+
13
+ # --- 工具类:实现类属性的静态访问 ---
14
+ class classproperty(object):
15
+ """类属性描述符,支持将方法作为类级别的只读属性访问。
16
+
17
+ 通过该描述符,可以像访问普通属性一样访问类方法,无需实例化。
18
+
19
+ Args:
20
+ fget: 被装饰的 getter 函数,接收类对象作为参数。
21
+ """
22
+
23
+ def __init__(self, fget):
24
+ """初始化类属性描述符。
25
+
26
+ Args:
27
+ fget: 被装饰的 getter 函数。
28
+ """
29
+ self.fget = fget
30
+
31
+ def __get__(self, owner_self, owner_cls):
32
+ """获取属性值时调用 getter 函数。
33
+
34
+ Args:
35
+ owner_self: 实例对象(可能为 None)。
36
+ owner_cls: 拥有该描述符的类对象。
37
+
38
+ Returns:
39
+ getter 函数的返回值。
40
+ """
41
+ return self.fget(owner_cls)
42
+
43
+
44
+ class Device:
45
+ """AScript 设备环境全感知中心。
46
+
47
+ 提供对当前 Windows 设备各维度信息的静态访问能力,包括:
48
+ 身份识别、操作系统、运行环境、屏幕与缩放、核心硬件(CPU/内存/GPU)、
49
+ 磁盘管理、电源与外设、网络信息等。所有属性均可通过类直接访问,无需实例化。
50
+ """
51
+
52
+ # ================= 1. 身份识别 (ID) =================
53
+ @classproperty
54
+ def id(cls) -> str:
55
+ """获取设备唯一标识符(基于硬件指纹,重装系统不变)。
56
+
57
+ Returns:
58
+ str: 大写的 UUID5 字符串,由网卡 MAC、处理器型号和主机名生成。
59
+ """
60
+ raw = f"{uuid.getnode()}-{platform.processor()}-{platform.node()}"
61
+ return str(uuid.uuid5(uuid.NAMESPACE_DNS, raw)).upper()
62
+
63
+ # ================= 2. 操作系统 (OS) =================
64
+ class os:
65
+ """操作系统信息。
66
+
67
+ Attributes:
68
+ type: 操作系统类型,如 "Windows"。
69
+ release: 系统版本号,如 "10" 或 "11"。
70
+ version: 内核版本号。
71
+ hostname: 计算机主机名。
72
+ """
73
+ type = platform.system() # Windows
74
+ release = platform.release() # 10 / 11
75
+ version = platform.version() # 内核版本
76
+ hostname = socket.gethostname() # 计算机名
77
+
78
+ @classproperty
79
+ def boot_time(cls) -> str:
80
+ """获取系统启动时间。
81
+
82
+ Returns:
83
+ str: 格式为 "YYYY-MM-DD HH:MM:SS" 的启动时间字符串。
84
+ """
85
+ return datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
86
+
87
+ @classproperty
88
+ def uptime_seconds(cls) -> int:
89
+ """获取系统已运行的秒数。
90
+
91
+ Returns:
92
+ int: 从系统启动到当前时刻的秒数。
93
+ """
94
+ return int(time.time() - psutil.boot_time())
95
+
96
+ # ================= 3. 运行环境 (Env) =================
97
+ class env:
98
+ """运行环境信息,包括权限、Python 版本和工作目录。"""
99
+
100
+ @classproperty
101
+ def is_admin(cls) -> bool:
102
+ """判断当前进程是否拥有管理员权限。
103
+
104
+ Returns:
105
+ bool: 拥有管理员权限返回 True,否则返回 False。
106
+ """
107
+ try:
108
+ return ctypes.windll.shell32.IsUserAnAdmin() != 0
109
+ except:
110
+ return False
111
+
112
+ @classproperty
113
+ def python_ver(cls) -> str:
114
+ """获取当前 Python 版本号。
115
+
116
+ Returns:
117
+ str: Python 版本字符串,如 "3.10.12"。
118
+ """
119
+ return platform.python_version()
120
+
121
+ @classproperty
122
+ def cwd(cls) -> str:
123
+ """获取当前工作目录。
124
+
125
+ Returns:
126
+ str: 当前工作目录的绝对路径。
127
+ """
128
+ return os.getcwd()
129
+
130
+ # ================= 4. 屏幕与缩放 (Screen) =================
131
+ class screen:
132
+ """屏幕与缩放信息,包括 DPI 缩放比例、逻辑分辨率和物理分辨率。"""
133
+
134
+ @classproperty
135
+ def scale(cls) -> float:
136
+ """获取屏幕 DPI 缩放倍数。
137
+
138
+ Returns:
139
+ float: 缩放倍数,如 1.0、1.25、1.5 等。
140
+ """
141
+ try:
142
+ hdc = ctypes.windll.user32.GetDC(0)
143
+ dpi = ctypes.windll.gdi32.GetDeviceCaps(hdc, 88)
144
+ ctypes.windll.user32.ReleaseDC(0, hdc)
145
+ return round(dpi / 96.0, 2)
146
+ except:
147
+ return 1.0
148
+
149
+ @classproperty
150
+ def percent(cls) -> str:
151
+ """获取屏幕缩放百分比字符串。
152
+
153
+ Returns:
154
+ str: 缩放百分比,如 "100%"、"125%"。
155
+ """
156
+ return f"{int(cls.scale * 100)}%"
157
+
158
+ @classproperty
159
+ def logical(cls) -> str:
160
+ """获取逻辑分辨率(受 DPI 缩放影响)。
161
+
162
+ Returns:
163
+ str: 格式为 "宽x高" 的分辨率字符串,如 "1920x1080"。
164
+ """
165
+ u32 = ctypes.windll.user32
166
+ return f"{u32.GetSystemMetrics(0)}x{u32.GetSystemMetrics(1)}"
167
+
168
+ @classproperty
169
+ def physical(cls) -> str:
170
+ """获取物理真实分辨率。
171
+
172
+ Returns:
173
+ str: 格式为 "宽x高" 的物理分辨率字符串,如 "2560x1440"。
174
+ """
175
+ u32 = ctypes.windll.user32
176
+ w = int(u32.GetSystemMetrics(0) * cls.scale)
177
+ h = int(u32.GetSystemMetrics(1) * cls.scale)
178
+ return f"{w}x{h}"
179
+
180
+ # ================= 5. 核心硬件 (CPU/Mem/GPU) =================
181
+ class cpu:
182
+ """CPU 硬件信息。
183
+
184
+ Attributes:
185
+ brand: CPU 型号名称。
186
+ cores: 物理核心数。
187
+ threads: 逻辑线程数。
188
+ """
189
+ brand = platform.processor()
190
+ cores = psutil.cpu_count(logical=False)
191
+ threads = psutil.cpu_count(logical=True)
192
+
193
+ @classproperty
194
+ def usage(cls):
195
+ """获取当前 CPU 使用率。
196
+
197
+ Returns:
198
+ float: CPU 使用百分比,如 23.5。
199
+ """
200
+ return psutil.cpu_percent(interval=0.1)
201
+
202
+ class memory:
203
+ """内存信息。
204
+
205
+ Attributes:
206
+ total_gb: 总内存大小(GB)。
207
+ """
208
+ total_gb = round(psutil.virtual_memory().total / (1024 ** 3), 2)
209
+
210
+ @classproperty
211
+ def free_gb(cls):
212
+ """获取当前可用内存大小。
213
+
214
+ Returns:
215
+ float: 可用内存(GB),保留两位小数。
216
+ """
217
+ return round(psutil.virtual_memory().available / (1024 ** 3), 2)
218
+
219
+ @classproperty
220
+ def percent(cls):
221
+ """获取当前内存使用率。
222
+
223
+ Returns:
224
+ float: 内存使用百分比,如 65.3。
225
+ """
226
+ return psutil.virtual_memory().percent
227
+
228
+ class gpu:
229
+ """GPU 显卡信息。"""
230
+
231
+ @classproperty
232
+ def list(cls) -> List[str]:
233
+ """获取显卡型号列表。
234
+
235
+ Returns:
236
+ List[str]: 显卡名称列表,如 ["NVIDIA GeForce RTX 3080"]。
237
+ """
238
+ names = []
239
+ try:
240
+ import wmi
241
+ for v in wmi.WMI().Win32_VideoController():
242
+ names.append(v.Name)
243
+ except:
244
+ names = ["Standard Display Adapter"]
245
+ return names
246
+
247
+ # ================= 6. 磁盘管理 (Disks) =================
248
+ class disks:
249
+ """磁盘管理信息,提供盘符列表、数量及详情查询。"""
250
+
251
+ @classproperty
252
+ def list(cls) -> List[str]:
253
+ """获取所有有效磁盘盘符。
254
+
255
+ Returns:
256
+ List[str]: 排序后的盘符列表,如 ['C', 'D', 'E']。
257
+ """
258
+ d = []
259
+ for p in psutil.disk_partitions():
260
+ if 'cdrom' in p.opts or p.fstype == '': continue
261
+ d.append(p.mountpoint.split(":")[0].upper())
262
+ return sorted(list(set(d)))
263
+
264
+ @classproperty
265
+ def count(cls) -> int:
266
+ """获取有效磁盘数量。
267
+
268
+ Returns:
269
+ int: 有效磁盘分区的数量。
270
+ """
271
+ return len(cls.list)
272
+
273
+ @staticmethod
274
+ def get_detail(drive: str) -> Dict[str, Any]:
275
+ """获取指定盘符的磁盘详情。
276
+
277
+ Args:
278
+ drive: 盘符字母,如 'C' 或 'D'。
279
+
280
+ Returns:
281
+ Dict[str, Any]: 包含 total(总容量)、free(可用空间)、percent(使用率)的字典。
282
+ 访问失败时返回 {"error": "Access Denied"}。
283
+ """
284
+ try:
285
+ u = psutil.disk_usage(f"{drive.upper()}:\\")
286
+ return {
287
+ "total": f"{u.total / (1024 ** 3):.1f}GB",
288
+ "free": f"{u.free / (1024 ** 3):.1f}GB",
289
+ "percent": f"{u.percent}%"
290
+ }
291
+ except:
292
+ return {"error": "Access Denied"}
293
+
294
+ # ================= 7. 电源与外设 (Power/Audio) =================
295
+ class power:
296
+ """电源与电池信息。"""
297
+
298
+ @classproperty
299
+ def is_plugged(cls) -> bool:
300
+ """判断是否接通外部电源。
301
+
302
+ Returns:
303
+ bool: 已接通电源返回 True,使用电池供电返回 False。
304
+ 无电池设备(台式机)始终返回 True。
305
+ """
306
+ batt = psutil.sensors_battery()
307
+ return batt.power_plugged if batt else True
308
+
309
+ @classproperty
310
+ def percent(cls) -> int:
311
+ """获取当前电池电量百分比。
312
+
313
+ Returns:
314
+ int: 电池电量百分比(0-100),无电池设备返回 100。
315
+ """
316
+ batt = psutil.sensors_battery()
317
+ return batt.percent if batt else 100
318
+
319
+ class audio:
320
+ """音频设备信息。"""
321
+
322
+ @classproperty
323
+ def list(cls) -> List[str]:
324
+ """获取音频输出设备名称列表。
325
+
326
+ Returns:
327
+ List[str]: 音频设备名称列表,获取失败时返回空列表。
328
+ """
329
+ try:
330
+ import wmi
331
+ return [s.Name for s in wmi.WMI().Win32_SoundDevice()]
332
+ except:
333
+ return []
334
+
335
+ # ================= 8. 网络信息 (Network) =================
336
+ class network:
337
+ """网络信息,包括本机 IP 和 MAC 地址。"""
338
+
339
+ @classproperty
340
+ def ip(cls):
341
+ """获取本机局域网 IP 地址。
342
+
343
+ Returns:
344
+ str: 本机 IPv4 地址,如 "192.168.1.100"。
345
+ """
346
+ return socket.gethostbyname(socket.gethostname())
347
+
348
+ @classproperty
349
+ def mac(cls):
350
+ """获取本机 MAC 地址。
351
+
352
+ Returns:
353
+ str: 格式为 "xx:xx:xx:xx:xx:xx" 的 MAC 地址字符串。
354
+ """
355
+ return ':'.join(['{:02x}'.format((uuid.getnode() >> e) & 0xff) for e in range(0, 48, 8)][::-1])
@@ -0,0 +1,115 @@
1
+ # sub_print_capture.py
2
+ from multiprocessing import Queue, current_process
3
+ import sys
4
+ import threading
5
+ import os
6
+
7
+ # 全局队列,用于进程间传递打印内容
8
+ _print_queue = None
9
+ # 标记是否为主进程
10
+ _is_main = False
11
+
12
+ class QueueStream:
13
+ """重定向 stdout/stderr 的流对象,将输出内容写入进程间队列。
14
+
15
+ 用于子进程中替代标准输出/错误流,使子进程的 print 输出能够
16
+ 通过队列传递到主进程统一处理。
17
+
18
+ Args:
19
+ queue: multiprocessing.Queue 实例,用于进程间传递打印内容。
20
+ stream_type: 流类型标识,可选 "stdout" 或 "stderr",默认 "stdout"。
21
+ """
22
+
23
+ def __init__(self, queue, stream_type="stdout"):
24
+ """初始化队列流对象。
25
+
26
+ Args:
27
+ queue: multiprocessing.Queue 实例,用于进程间传递打印内容。
28
+ stream_type: 流类型标识,可选 "stdout" 或 "stderr",默认 "stdout"。
29
+ """
30
+ self.queue = queue
31
+ self.stream_type = stream_type
32
+ self.origin_stream = sys.stdout if stream_type == "stdout" else sys.stderr
33
+
34
+ def write(self, msg):
35
+ """将非空消息写入队列。
36
+
37
+ Args:
38
+ msg: 要写入的消息字符串。
39
+ """
40
+ if msg.strip(): # 过滤空行
41
+ # 传递:进程ID+进程名+输出类型+内容
42
+ self.queue.put({
43
+ "pid": os.getpid(),
44
+ "pname": current_process().name,
45
+ "type": self.stream_type,
46
+ "msg": msg
47
+ })
48
+
49
+ def flush(self):
50
+ """刷新流缓冲区(兼容 print 的 flush=True,无实际操作)。"""
51
+ # 兼容print的flush=True,无实际操作
52
+ pass
53
+
54
+ def isatty(self):
55
+ """判断是否为终端设备。
56
+
57
+ Returns:
58
+ bool: 返回原始流的 isatty() 结果,兼容终端判断。
59
+ """
60
+ # 兼容终端判断,避免部分库报错
61
+ return self.origin_stream.isatty()
62
+
63
+ def init_main(listen_callback=None):
64
+ """主进程初始化:创建进程间共享队列并启动监听线程。
65
+
66
+ 在主进程中调用一次即可。创建用于接收子进程输出的队列,
67
+ 并启动后台线程持续监听子进程的打印内容。
68
+
69
+ Args:
70
+ listen_callback: 自定义监听回调函数,默认为 None。
71
+ 若为 None,则使用内置的默认监听函数将子进程输出打印到主进程终端。
72
+ """
73
+ global _print_queue, _is_main
74
+ if _is_main:
75
+ return
76
+ _print_queue = Queue()
77
+ _is_main = True
78
+
79
+ # 自定义监听回调,默认打印到主进程终端
80
+ def default_listen():
81
+ while True:
82
+ try:
83
+ data = _print_queue.get()
84
+ if data is None: # 结束标记
85
+ break
86
+ # 格式化输出,可自定义
87
+ prefix = f"[子进程{data['pid']}-{data['pname']}][{data['type']}]"
88
+ print(f"{prefix} {data['msg']}", end="")
89
+ except Exception:
90
+ break
91
+
92
+ # 启动监听线程
93
+ listen_fun = listen_callback or default_listen
94
+ t = threading.Thread(target=listen_fun, daemon=True)
95
+ t.start()
96
+
97
+ def init_sub():
98
+ """子进程初始化:将 stdout/stderr 重定向到共享队列。
99
+
100
+ 在子进程中自动执行(模块导入时触发),将标准输出和标准错误
101
+ 重定向为 QueueStream 对象,使子进程的所有 print 输出
102
+ 通过队列传递到主进程。主进程中调用无效。
103
+ """
104
+ global _print_queue
105
+ if _print_queue is None:
106
+ return # 主进程未初始化,不处理
107
+ if current_process().name == "MainProcess":
108
+ return # 跳过主进程
109
+
110
+ # 重定向标准输出/错误
111
+ sys.stdout = QueueStream(_print_queue, "stdout")
112
+ sys.stderr = QueueStream(_print_queue, "stderr")
113
+
114
+ # 子进程引入模块时,自动执行重定向
115
+ init_sub()