pyxllib 0.0.43__py3-none-any.whl → 0.3.197__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.
Files changed (186) hide show
  1. pyxllib/__init__.py +9 -2
  2. pyxllib/algo/__init__.py +8 -0
  3. pyxllib/algo/disjoint.py +54 -0
  4. pyxllib/algo/geo.py +541 -0
  5. pyxllib/{util/mathlib.py → algo/intervals.py} +172 -36
  6. pyxllib/algo/matcher.py +389 -0
  7. pyxllib/algo/newbie.py +166 -0
  8. pyxllib/algo/pupil.py +629 -0
  9. pyxllib/algo/shapelylib.py +67 -0
  10. pyxllib/algo/specialist.py +241 -0
  11. pyxllib/algo/stat.py +494 -0
  12. pyxllib/algo/treelib.py +149 -0
  13. pyxllib/algo/unitlib.py +66 -0
  14. pyxllib/autogui/__init__.py +5 -0
  15. pyxllib/autogui/activewin.py +246 -0
  16. pyxllib/autogui/all.py +9 -0
  17. pyxllib/autogui/autogui.py +852 -0
  18. pyxllib/autogui/uiautolib.py +362 -0
  19. pyxllib/autogui/virtualkey.py +102 -0
  20. pyxllib/autogui/wechat.py +827 -0
  21. pyxllib/autogui/wechat_msg.py +421 -0
  22. pyxllib/autogui/wxautolib.py +84 -0
  23. pyxllib/cv/__init__.py +1 -11
  24. pyxllib/cv/expert.py +267 -0
  25. pyxllib/cv/{imlib.py → imfile.py} +18 -83
  26. pyxllib/cv/imhash.py +39 -0
  27. pyxllib/cv/pupil.py +9 -0
  28. pyxllib/cv/rgbfmt.py +1525 -0
  29. pyxllib/cv/slidercaptcha.py +137 -0
  30. pyxllib/cv/trackbartools.py +163 -49
  31. pyxllib/cv/xlcvlib.py +1040 -0
  32. pyxllib/cv/xlpillib.py +423 -0
  33. pyxllib/data/__init__.py +0 -0
  34. pyxllib/data/echarts.py +240 -0
  35. pyxllib/data/jsonlib.py +89 -0
  36. pyxllib/{util/oss2_.py → data/oss.py} +11 -9
  37. pyxllib/data/pglib.py +1127 -0
  38. pyxllib/data/sqlite.py +568 -0
  39. pyxllib/{util → data}/sqllib.py +13 -31
  40. pyxllib/ext/JLineViewer.py +505 -0
  41. pyxllib/ext/__init__.py +6 -0
  42. pyxllib/{util → ext}/demolib.py +119 -35
  43. pyxllib/ext/drissionlib.py +277 -0
  44. pyxllib/ext/kq5034lib.py +12 -0
  45. pyxllib/{util/main.py → ext/old.py} +122 -284
  46. pyxllib/ext/qt.py +449 -0
  47. pyxllib/ext/robustprocfile.py +497 -0
  48. pyxllib/ext/seleniumlib.py +76 -0
  49. pyxllib/{util/tklib.py → ext/tk.py} +10 -11
  50. pyxllib/ext/unixlib.py +827 -0
  51. pyxllib/ext/utools.py +351 -0
  52. pyxllib/{util/webhooklib.py → ext/webhook.py} +45 -17
  53. pyxllib/ext/win32lib.py +40 -0
  54. pyxllib/ext/wjxlib.py +88 -0
  55. pyxllib/ext/wpsapi.py +124 -0
  56. pyxllib/ext/xlwork.py +9 -0
  57. pyxllib/ext/yuquelib.py +1105 -0
  58. pyxllib/file/__init__.py +17 -0
  59. pyxllib/file/docxlib.py +761 -0
  60. pyxllib/{util → file}/gitlib.py +40 -27
  61. pyxllib/file/libreoffice.py +165 -0
  62. pyxllib/file/movielib.py +148 -0
  63. pyxllib/file/newbie.py +10 -0
  64. pyxllib/file/onenotelib.py +1469 -0
  65. pyxllib/file/packlib/__init__.py +330 -0
  66. pyxllib/{util → file/packlib}/zipfile.py +598 -195
  67. pyxllib/file/pdflib.py +426 -0
  68. pyxllib/file/pupil.py +185 -0
  69. pyxllib/file/specialist/__init__.py +685 -0
  70. pyxllib/{basic/_5_dirlib.py → file/specialist/dirlib.py} +364 -93
  71. pyxllib/file/specialist/download.py +193 -0
  72. pyxllib/file/specialist/filelib.py +2829 -0
  73. pyxllib/file/xlsxlib.py +3131 -0
  74. pyxllib/file/xlsyncfile.py +341 -0
  75. pyxllib/prog/__init__.py +5 -0
  76. pyxllib/prog/cachetools.py +64 -0
  77. pyxllib/prog/deprecatedlib.py +233 -0
  78. pyxllib/prog/filelock.py +42 -0
  79. pyxllib/prog/ipyexec.py +253 -0
  80. pyxllib/prog/multiprogs.py +940 -0
  81. pyxllib/prog/newbie.py +451 -0
  82. pyxllib/prog/pupil.py +1197 -0
  83. pyxllib/{sitepackages.py → prog/sitepackages.py} +5 -3
  84. pyxllib/prog/specialist/__init__.py +391 -0
  85. pyxllib/prog/specialist/bc.py +203 -0
  86. pyxllib/prog/specialist/browser.py +497 -0
  87. pyxllib/prog/specialist/common.py +347 -0
  88. pyxllib/prog/specialist/datetime.py +199 -0
  89. pyxllib/prog/specialist/tictoc.py +240 -0
  90. pyxllib/prog/specialist/xllog.py +180 -0
  91. pyxllib/prog/xlosenv.py +108 -0
  92. pyxllib/stdlib/__init__.py +17 -0
  93. pyxllib/{util → stdlib}/tablepyxl/__init__.py +1 -3
  94. pyxllib/{util → stdlib}/tablepyxl/style.py +1 -1
  95. pyxllib/{util → stdlib}/tablepyxl/tablepyxl.py +2 -4
  96. pyxllib/text/__init__.py +8 -0
  97. pyxllib/text/ahocorasick.py +39 -0
  98. pyxllib/text/airscript.js +744 -0
  99. pyxllib/text/charclasslib.py +121 -0
  100. pyxllib/text/jiebalib.py +267 -0
  101. pyxllib/text/jinjalib.py +32 -0
  102. pyxllib/text/jsa_ai_prompt.md +271 -0
  103. pyxllib/text/jscode.py +922 -0
  104. pyxllib/text/latex/__init__.py +158 -0
  105. pyxllib/text/levenshtein.py +303 -0
  106. pyxllib/text/nestenv.py +1215 -0
  107. pyxllib/text/newbie.py +300 -0
  108. pyxllib/text/pupil/__init__.py +8 -0
  109. pyxllib/text/pupil/common.py +1121 -0
  110. pyxllib/text/pupil/xlalign.py +326 -0
  111. pyxllib/text/pycode.py +47 -0
  112. pyxllib/text/specialist/__init__.py +8 -0
  113. pyxllib/text/specialist/common.py +112 -0
  114. pyxllib/text/specialist/ptag.py +186 -0
  115. pyxllib/text/spellchecker.py +172 -0
  116. pyxllib/text/templates/echart_base.html +11 -0
  117. pyxllib/text/templates/highlight_code.html +17 -0
  118. pyxllib/text/templates/latex_editor.html +103 -0
  119. pyxllib/text/vbacode.py +17 -0
  120. pyxllib/text/xmllib.py +747 -0
  121. pyxllib/xl.py +39 -0
  122. pyxllib/xlcv.py +17 -0
  123. pyxllib-0.3.197.dist-info/METADATA +48 -0
  124. pyxllib-0.3.197.dist-info/RECORD +126 -0
  125. {pyxllib-0.0.43.dist-info → pyxllib-0.3.197.dist-info}/WHEEL +4 -5
  126. pyxllib/basic/_1_strlib.py +0 -945
  127. pyxllib/basic/_2_timelib.py +0 -488
  128. pyxllib/basic/_3_pathlib.py +0 -916
  129. pyxllib/basic/_4_loglib.py +0 -419
  130. pyxllib/basic/__init__.py +0 -54
  131. pyxllib/basic/arrow_.py +0 -250
  132. pyxllib/basic/chardet_.py +0 -66
  133. pyxllib/basic/dirlib.py +0 -529
  134. pyxllib/basic/dprint.py +0 -202
  135. pyxllib/basic/extension.py +0 -12
  136. pyxllib/basic/judge.py +0 -31
  137. pyxllib/basic/log.py +0 -204
  138. pyxllib/basic/pathlib_.py +0 -705
  139. pyxllib/basic/pytictoc.py +0 -102
  140. pyxllib/basic/qiniu_.py +0 -61
  141. pyxllib/basic/strlib.py +0 -761
  142. pyxllib/basic/timer.py +0 -132
  143. pyxllib/cv/cv.py +0 -834
  144. pyxllib/cv/cvlib/_1_geo.py +0 -543
  145. pyxllib/cv/cvlib/_2_cvprcs.py +0 -309
  146. pyxllib/cv/cvlib/_2_imgproc.py +0 -594
  147. pyxllib/cv/cvlib/_3_pilprcs.py +0 -80
  148. pyxllib/cv/cvlib/_4_cvimg.py +0 -211
  149. pyxllib/cv/cvlib/__init__.py +0 -10
  150. pyxllib/cv/debugtools.py +0 -82
  151. pyxllib/cv/fitz_.py +0 -300
  152. pyxllib/cv/installer.py +0 -42
  153. pyxllib/debug/_0_installer.py +0 -38
  154. pyxllib/debug/_1_typelib.py +0 -277
  155. pyxllib/debug/_2_chrome.py +0 -198
  156. pyxllib/debug/_3_showdir.py +0 -161
  157. pyxllib/debug/_4_bcompare.py +0 -140
  158. pyxllib/debug/__init__.py +0 -49
  159. pyxllib/debug/bcompare.py +0 -132
  160. pyxllib/debug/chrome.py +0 -198
  161. pyxllib/debug/installer.py +0 -38
  162. pyxllib/debug/showdir.py +0 -158
  163. pyxllib/debug/typelib.py +0 -278
  164. pyxllib/image/__init__.py +0 -12
  165. pyxllib/torch/__init__.py +0 -20
  166. pyxllib/torch/modellib.py +0 -37
  167. pyxllib/torch/trainlib.py +0 -344
  168. pyxllib/util/__init__.py +0 -20
  169. pyxllib/util/aip_.py +0 -141
  170. pyxllib/util/casiadb.py +0 -59
  171. pyxllib/util/excellib.py +0 -495
  172. pyxllib/util/filelib.py +0 -612
  173. pyxllib/util/jsondata.py +0 -27
  174. pyxllib/util/jsondata2.py +0 -92
  175. pyxllib/util/labelmelib.py +0 -139
  176. pyxllib/util/onepy/__init__.py +0 -29
  177. pyxllib/util/onepy/onepy.py +0 -574
  178. pyxllib/util/onepy/onmanager.py +0 -170
  179. pyxllib/util/pyautogui_.py +0 -219
  180. pyxllib/util/textlib.py +0 -1305
  181. pyxllib/util/unorder.py +0 -22
  182. pyxllib/util/xmllib.py +0 -639
  183. pyxllib-0.0.43.dist-info/METADATA +0 -39
  184. pyxllib-0.0.43.dist-info/RECORD +0 -80
  185. pyxllib-0.0.43.dist-info/top_level.txt +0 -1
  186. {pyxllib-0.0.43.dist-info → pyxllib-0.3.197.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,421 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # @Author : 陈坤泽
4
+ # @Email : 877362867@qq.com
5
+ # @Date : 2024/11/05
6
+
7
+ """
8
+ 微信 消息框中不同消息结构的解析器 工具
9
+
10
+ todo 这个文件很多值可以写成枚举类型更规范?
11
+ """
12
+
13
+ import re
14
+ import json
15
+
16
+ # 定义全局字典
17
+ msg_parsers = {}
18
+
19
+
20
+ # 定义装饰器
21
+ def register_tool(key):
22
+ def decorator(func):
23
+ # 将函数添加到全局字典中,键为传入的key参数
24
+ msg_parsers[key] = func
25
+ return func
26
+
27
+ return decorator
28
+
29
+
30
+ def fmt_text(text):
31
+ return text.replace('\n', ' ')
32
+
33
+
34
+ def parse_time_string(time_str):
35
+ """
36
+ 解析不同格式的时间字符串为标准的 Python datetime 类型。
37
+
38
+ 支持以下格式:
39
+ 1. 完整的日期和时间,如 "2024年10月31日 22:03",解析为对应的 datetime 对象。
40
+ 2. 仅包含时间的字符串,如 "19:18",会被解析为当天的时间点,日期部分设为当前日期。
41
+ 3. 特殊字符串 "以下为新消息",解析为当前时间的 datetime 对象。
42
+
43
+ 示例输入:
44
+ - "2024年10月31日 22:03"
45
+ - "2024年11月1日 20:09"
46
+ - "2024年11月1日 21:08"
47
+ - "19:18"
48
+ - "20:16"
49
+ - "以下为新消息"
50
+ """
51
+ from datetime import datetime
52
+
53
+ # 定义当前日期
54
+ now = datetime.now()
55
+
56
+ # 定义不同的正则表达式模式
57
+ full_date_pattern = r"(\d{4})年(\d{1,2})月(\d{1,2})日\s+(\d{1,2}):(\d{2})"
58
+ partial_time_pattern = r"^(\d{1,2}):(\d{2})$"
59
+ new_message_pattern = r"^以下为新消息$"
60
+
61
+ # 解析完整的日期时间
62
+ match = re.match(full_date_pattern, time_str)
63
+ if match:
64
+ year, month, day, hour, minute = map(int, match.groups())
65
+ return datetime(year, month, day, hour, minute)
66
+
67
+ # 解析只有时间(小时:分钟),默认当天的日期
68
+ match = re.match(partial_time_pattern, time_str)
69
+ if match:
70
+ hour, minute = map(int, match.groups())
71
+ return datetime(now.year, now.month, now.day, hour, minute)
72
+
73
+ # 解析 "以下为新消息" 为当前时间
74
+ if re.match(new_message_pattern, time_str):
75
+ return now
76
+
77
+ # 如果未匹配到任何模式,返回 None 表示无法解析
78
+ return None
79
+
80
+
81
+ @register_tool("1b2p3p3b3p")
82
+ def 系统_查看更多消息(node):
83
+ node.msg_type = 'system'
84
+ node.content_type = 'button_more'
85
+ node.render_text = f'⚙️: 点击此处可 {node.text}'
86
+
87
+
88
+ @register_tool("1l2t")
89
+ def 系统_时间标签(node):
90
+ node.msg_type = 'system'
91
+ node.content_type = 'time'
92
+ node.time = parse_time_string(node.text)
93
+ node.render_text = f'⚙️: {node.text}'
94
+
95
+
96
+ # 刚刚发送的特殊时间标签
97
+ @register_tool("1l2p3p3p3t3p3p")
98
+ def 系统_时间标签2(node):
99
+ node.msg_type = 'system'
100
+ node.content_type = 'time'
101
+ node.time = parse_time_string(node.text)
102
+ node.render_text = f'⚙️: {node.text}'
103
+
104
+
105
+ @register_tool("1l2p3p3t3p")
106
+ def 系统_撤回消息(node):
107
+ node.msg_type = 'system'
108
+
109
+ if node.text.endswith('撤回了一条消息'):
110
+ node.content_type = 'recall'
111
+ if node.text == '你撤回了一条消息':
112
+ node.user = node.user2 = '你'
113
+ else:
114
+ node.user = re.search(r'"(.+)"', node.text).group(1)
115
+ node.user2 = node.user
116
+ node.render_text = f'⚙️: {node.text}'
117
+ elif node.text.endswith('现在可以开始聊天了。'):
118
+ node.content_type = 'add_friend'
119
+ node.user = re.search(r'你已添加了(.+?),现在可以开始聊天了。', node.text).group(1)
120
+ node.user2 = node.user
121
+ node.render_text = f'⚙️: {node.text}'
122
+ else:
123
+ raise ValueError
124
+
125
+
126
+ @register_tool("1l2p3p3p4p5p6p7t3b")
127
+ def 发送_文本(node):
128
+ node.msg_type = 'send'
129
+ node.content_type = 'text'
130
+ node.user = node[0][2].text
131
+ node.render_text = f'↑{node.user}: {fmt_text(node.text)}'
132
+
133
+
134
+ @register_tool("1l2p3p3p4p5p6p7p7p8p8b3b")
135
+ def 发送_图片(node):
136
+ node.msg_type = 'send'
137
+ node.content_type = 'image'
138
+ node.user = node[0][2].text
139
+
140
+
141
+ @register_tool("1l2p3p3p4p5p6p7p7p8p9t9p9b8b3b")
142
+ def 发送_视频(node):
143
+ node.msg_type = 'send'
144
+ node.content_type = 'video'
145
+ node.user = node[0][2].text
146
+
147
+
148
+ @register_tool("1l2p3p3p4p5p6p7p7p8p9p10p11t6p7p8p9p10p11t7b3b")
149
+ def 发送_文本_引用文本(node):
150
+ node.msg_type = 'send'
151
+ node.content_type = 'text'
152
+ node.user = node[0][2].text
153
+ quoted_node = node[0][1][0][0] # 引用的层级结构
154
+ node.text = quoted_node[0][1][0][0][0][0].text
155
+ node.cite_text = quoted_node[1][0][0][0][0][0].text
156
+
157
+
158
+ @register_tool("1l2p3p3p4p5p6p7p7p8p9p10p11t6p7p8p9p10p11t11t11p12b7b3b")
159
+ def 发送_文本_引用图片(node):
160
+ node.msg_type = 'send'
161
+ node.content_type = 'text'
162
+ node.user = node[0][2].text
163
+ quoted_node = node[0][1][0][0]
164
+ node.text = quoted_node[0][1][0][0][0][0].text
165
+ node.cite_text = f'{quoted_node[1][0][0][0][0][0].text} : [图片]'
166
+
167
+
168
+ # 引用文件
169
+ @register_tool("1l2p3p3p4p5p6p7p7p8p9p10p11t6p7p8p9p10p11p12t11p12b7b3b")
170
+ def 发送_文本_引用文件(node):
171
+ node.msg_type = 'send'
172
+ node.content_type = 'text'
173
+ node.user = node[0][2].text
174
+ quoted_node = node[0][1][0][0]
175
+ node.text = quoted_node[0][1][0][0][0][0].text
176
+ node.cite_text = f'[文件] {quoted_node[1][0][0][0][0][0][0].text}'
177
+
178
+
179
+ # 发送文件
180
+ @register_tool("1l2p3p3p4p5p6p7p8p9p10t10p11t11t9p10p10p8p9t7b7b3b")
181
+ def 发送_文本_引用文件(node):
182
+ node.msg_type = 'send'
183
+ node.content_type = 'file'
184
+ node.user = node[0][2].text
185
+ file_node = node[0][1][0][0][0][0]
186
+ desc = {
187
+ 'name': file_node[0][0][0].text,
188
+ 'size': file_node[0][0][1][0].text,
189
+ 'platform': file_node[1][0].text
190
+ }
191
+ node.text = json.dumps(desc, ensure_ascii=False)
192
+
193
+
194
+ # 发送链接
195
+ @register_tool("1l2p3p3p4p5p6p7p8t8p9t9p9b8p9b9t7b3b")
196
+ def 发送_链接(node):
197
+ node.msg_type = 'send'
198
+ node.content_type = 'link'
199
+ node.user = node[0][2].text
200
+ link_node = node[0][1][0][0]
201
+ desc = {
202
+ 'title': link_node[0][0][0].text,
203
+ 'head': link_node[0][0][1][0].text,
204
+ 'author': link_node[0][0][2][1].text
205
+ }
206
+ node.text = json.dumps(desc, ensure_ascii=False)
207
+
208
+
209
+ # 转发消息
210
+ @register_tool("1l2p3p3p4p5p6p7p8t8p9t9t9t8p9p9t7b3b")
211
+ def 发送_转发消息(node):
212
+ node.msg_type = 'send'
213
+ node.content_type = 'messages'
214
+ node.user = node[0][2].text
215
+
216
+
217
+ @register_tool("1l2p3b3p4p5p6p7t3p")
218
+ def 接收_文本(node):
219
+ node.msg_type = 'receive'
220
+ node.content_type = 'text'
221
+ node.user = node[0][0].text
222
+ node.render_text = f'↓{node.user}: {fmt_text(node.text)}'
223
+
224
+
225
+ @register_tool("1l2p3b3p4p5p6p7p7b3p")
226
+ def 接收_图片(node):
227
+ node.msg_type = 'receive'
228
+ node.content_type = 'image'
229
+ node.user = node[0][0].text
230
+ node.render_text = f'↓{node.user}: [图片]'
231
+
232
+
233
+ @register_tool("1l2p3b3p4p5p6p7p8p9p10t10p11t11t9p10p10p8p9t7b7b3p")
234
+ def 接收_文件(node):
235
+ node.msg_type = 'receive'
236
+ node.content_type = 'file'
237
+ node.user = node[0][0].text
238
+ node.render_text = f'↓{node.user}: {fmt_text(node.text)}'
239
+
240
+
241
+ @register_tool("1l2p3b3p4p5p6p7p8b8p8t7b3p")
242
+ def 接收_语音(node):
243
+ node.msg_type = 'receive'
244
+ node.content_type = 'voice'
245
+ node.user = node[0][0].text
246
+
247
+
248
+ @register_tool("1l2p3b3p4p5p6p7p8t8p9t9p9b8p9b9t7b3p")
249
+ def 接收_链接(node):
250
+ node.msg_type = 'receive'
251
+ node.content_type = 'link'
252
+ node.user = node[0][0].text
253
+ link_node = node[0][1][0][0][0][0] # 链接内容的层级结构
254
+ desc = {
255
+ 'title': link_node[0].text,
256
+ 'head': link_node[1][0].text, # 文章开头部分
257
+ 'author': link_node[2][1].text
258
+ }
259
+ node.text = json.dumps(desc, ensure_ascii=False)
260
+
261
+
262
+ @register_tool("1l2p3b3p4p5t4p5p6p7t3p")
263
+ def 群接收_文本(node):
264
+ node.msg_type = 'receive'
265
+ node.content_type = 'text'
266
+ node.user = node[0][0].text
267
+ node.user2 = node[0][1][0][0].text
268
+
269
+
270
+ @register_tool("1l2p3b3p4p5t4p5p6p7p7b3p")
271
+ def 群接收_图片(node):
272
+ node.msg_type = 'receive'
273
+ node.content_type = 'image'
274
+ node.user = node[0][0].text
275
+ node.user2 = node[0][1][0][0].text
276
+
277
+
278
+ @register_tool("1l2p3b3p4p5t4p5p6p7p8p9p10t10p11t11t9p10p10p7b7b3p")
279
+ def 群接收_文件(node):
280
+ node.msg_type = 'receive'
281
+ node.content_type = 'file'
282
+ node.user = node[0][0].text
283
+ file_node = node[0][1] # 文件信息的节点
284
+ node.user2 = file_node[0][0].text
285
+ file_info_node = file_node[1][0][0][0][0]
286
+ desc = {
287
+ 'name': file_info_node[0][0].text,
288
+ 'size': file_info_node[0][1][0].text
289
+ }
290
+ node.text = json.dumps(desc, ensure_ascii=False)
291
+
292
+
293
+ @register_tool("1l2p3b3p4p5t4p5p6p7p8p9p10t10p11t11t9p10p10p8p9t7b7b3p")
294
+ def 群接收_文件2(node):
295
+ node.msg_type = 'receive'
296
+ node.content_type = 'file'
297
+ node.user = node[0][0].text
298
+ node.user2 = node[0][1][0][0].text
299
+ file_info_node = node[0][1][1][0][0][0]
300
+ desc = {
301
+ 'name': file_info_node[0][0][0].text,
302
+ 'size': file_info_node[0][0][1][0].text,
303
+ 'platform': file_info_node[1][0].text
304
+ }
305
+ node.text = json.dumps(desc, ensure_ascii=False)
306
+
307
+
308
+ @register_tool("1l2p3b3p4p5t4p5p6p7b3p")
309
+ def 群接收_动画表情(node):
310
+ node.msg_type = 'receive'
311
+ node.content_type = 'emoji'
312
+ node.user = node[0][0].text
313
+ node.user2 = node[0][1][0][0].text
314
+
315
+
316
+ @register_tool("1l2p3b3p4p5t4p5p6p7p8t8p9t9p9b8p9b9t7b3p")
317
+ def 群接收_链接_有公众号作者名(node):
318
+ node.msg_type = 'receive'
319
+ node.content_type = 'link'
320
+ node.user = node[0][0].text
321
+ link_node = node[0][1]
322
+ node.user2 = link_node[0][0].text
323
+ link_info_node = link_node[1][0][0][0]
324
+ desc = {
325
+ 'title': link_info_node[0].text,
326
+ 'head': link_info_node[1][0].text, # 文章开头的一小部分
327
+ 'author': link_info_node[2][0].text
328
+ }
329
+ node.text = json.dumps(desc, ensure_ascii=False)
330
+
331
+
332
+ @register_tool("1l2p3b3p4p5t4p5p6p7p8t8p9t9p9b7b3p")
333
+ def 群接收_链接_无公众号作者名(node):
334
+ node.msg_type = 'receive'
335
+ node.content_type = 'link'
336
+ node.user = node[0][0].text
337
+ link_node = node[0][1]
338
+ node.user2 = link_node[0][0].text
339
+ link_info_node = link_node[1][0][0][0]
340
+ desc = {
341
+ 'title': link_info_node[0].text,
342
+ 'head': link_info_node[1][0].text # 文章开头的一小部分
343
+ }
344
+ node.text = json.dumps(desc, ensure_ascii=False)
345
+
346
+
347
+ @register_tool("1l2p3b3p4p5t4p5p6p7p8b8p9p8p9p10p10t8p9p7b3p")
348
+ def 群接收_视频(node):
349
+ node.msg_type = 'receive'
350
+ node.content_type = 'video'
351
+ node.user = node[0][0].text
352
+ video_node = node[0][1]
353
+ node.user2 = video_node[0][0].text
354
+ video_info_node = video_node[1][0][0][0]
355
+ desc = {
356
+ 'author': video_info_node[2][0][1].text
357
+ }
358
+ node.text = json.dumps(desc, ensure_ascii=False)
359
+
360
+
361
+ @register_tool("1l2p3b3p4p5t4p5p6p7p8t8p9t8t7b3p")
362
+ def 群接收_视频2(node):
363
+ node.msg_type = 'receive'
364
+ node.content_type = 'video'
365
+ node.user = node[0][0].text
366
+ video_node = node[0][1]
367
+ node.user2 = video_node[0][0].text
368
+ video_info_node = video_node[1][0][0][0]
369
+ desc = {
370
+ 'title': video_info_node[0].text,
371
+ 'head': video_info_node[1][0].text,
372
+ 'duration': video_info_node[2].text
373
+ }
374
+ node.text = json.dumps(desc, ensure_ascii=False)
375
+
376
+
377
+ @register_tool("1l2p3b3p4p5t4p5p6p7p8p9b9t8t8b8p9t9t7b3p")
378
+ def 群接收_小程序(node):
379
+ node.msg_type = 'receive'
380
+ node.content_type = 'applet'
381
+ node.user = node[0][0].text
382
+ applet_node = node[0][1]
383
+ node.user2 = applet_node[0][0].text
384
+ applet_info_node = applet_node[1][0][0][0]
385
+ desc = {
386
+ 'name': applet_info_node[0][1].text,
387
+ 'title': applet_info_node[1].text,
388
+ 'footnote': applet_info_node[3][1].text
389
+ }
390
+ node.text = json.dumps(desc, ensure_ascii=False)
391
+
392
+
393
+ @register_tool("1l2p3p3p4p5l6p7p7t7p3p")
394
+ def 群接收_拍一拍(node):
395
+ node.msg_type = 'receive'
396
+ node.content_type = 'shake'
397
+ node.text = node[0][1][0][0].text
398
+ node.user = re.search(r'"(.+?)" 拍了拍 "', node.text).group(1)
399
+
400
+
401
+ @register_tool("1l2p3b3p4p5t4p5p6p7p8t4p5p6p7p8p9t5b3p")
402
+ def 群接收_引用消息(node):
403
+ node.msg_type = 'receive'
404
+ node.content_type = 'text'
405
+ node.user = node[0][0].text
406
+ quoted_node = node[0][1]
407
+ node.user2 = quoted_node[0][0].text
408
+ node.text = quoted_node[1][0][0][0][0].text
409
+ node.cite_text = quoted_node[2][0][0][0][0][0].text
410
+
411
+
412
+ @register_tool("1l2p3b3p4p5t4p5p6p7p8t4p5p6p7p8p9p10t9p10b5b3p")
413
+ def 群接收_引用文件(node):
414
+ node.msg_type = 'receive'
415
+ node.content_type = 'text'
416
+ node.user = node[0][0].text
417
+ quoted_node = node[0][1]
418
+ node.user2 = quoted_node[0][0].text
419
+ node.text = quoted_node[1][0][0][0][0].text
420
+ file_node = quoted_node[2][0][0][0][0][0][0]
421
+ node.cite_text = f'[文件] {file_node.text}'
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # @Author : 陈坤泽
4
+ # @Email : 877362867@qq.com
5
+ # @Date : 2024/12/16
6
+
7
+ import sys
8
+
9
+ from loguru import logger
10
+
11
+ if sys.platform == 'win32':
12
+ try: # 尝试加载VIP版
13
+ from wxautox import WeChat
14
+ from wxautox.elements import WxParam # WxParam.DEFALUT_SAVEPATH 可以用来配置数据自动保存位置
15
+ except ModuleNotFoundError: # 否则用贫民版
16
+ from wxauto import WeChat
17
+ from wxauto.elements import WxParam
18
+
19
+ from pyxllib.prog.filelock import get_autoui_lock
20
+
21
+
22
+ class WeChatSingletonLock:
23
+ """ 基于 get_autoui_lock 的微信全局唯一单例控制器,确保同一时间仅有一个微信自动化程序在操作 """
24
+
25
+ def __init__(self, lock_timeout=-1, *, init=True):
26
+ # 初始化全局锁
27
+ self.lock = get_autoui_lock(timeout=lock_timeout)
28
+ self.wx = WeChat() if init else None
29
+
30
+ def __enter__(self):
31
+ # 获取锁并激活微信窗口
32
+ self.lock.acquire()
33
+ if self.wx:
34
+ self.wx._show()
35
+ return self.wx
36
+
37
+ def __exit__(self, exc_type, exc_value, traceback):
38
+ # 释放锁
39
+ self.lock.release()
40
+
41
+
42
+ def wechat_lock_send(user, text=None, files=None, *, timeout=-1):
43
+ """ 使用全局唯一单例锁,确保同一时间仅有一个微信自动化程序在操作 """
44
+ with WeChatSingletonLock(timeout) as we:
45
+ # 241223周一12:27,今天可被这个默认2秒坑惨了,往错误群一直发骚扰消息
46
+ # 22:07,但我复测,感觉不可能找不到啊,为什么会找到禅宗考勤管理群呢,太离谱了
47
+ status = we.ChatWith(user, timeout=5)
48
+
49
+ if status != user:
50
+ raise ValueError(f'无法找到用户:{user}')
51
+
52
+ if text:
53
+ we.SendMsg(text, user)
54
+ if files:
55
+ we.SendFiles(files, user)
56
+
57
+
58
+ def wechat_handler(message):
59
+ # 获取群名,如果没有指定,不使用此微信发送功能
60
+ user = message.record["extra"].get("wechat_user")
61
+ if user:
62
+ wechat_lock_send(user, message)
63
+
64
+
65
+ if sys.platform == 'win32':
66
+ # 创建专用的微信日志记录器,不绑定默认群名
67
+ wechat_logger = logger.bind(wechat_user='文件传输助手')
68
+
69
+ # 添加专用的微信处理器
70
+ wechat_logger.add(wechat_handler,
71
+ format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {name}:{function}:{line} - {message}")
72
+
73
+ """ 往微信发送特殊的日志格式报告
74
+ 用法:wechat_logger.bind(wechat_user='文件传输助手').info(message)
75
+
76
+ 或者:
77
+ # 先做好默认群名绑定
78
+ wechat_logger = wechat_logger.bind(wechat_user='考勤管理')
79
+ # 然后就能普通logger用法发送了
80
+ wechat_logger.info('测试')
81
+ """
82
+ else:
83
+ # 降级为普通logger
84
+ wechat_logger = logger
pyxllib/cv/__init__.py CHANGED
@@ -2,14 +2,4 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  # @Author : 陈坤泽
4
4
  # @Email : 877362867@qq.com
5
- # @Data : 2020/08/14 22:59
6
-
7
- # 确保安装了前置包
8
- # image部分需要依赖的第三方库
9
- from .installer import *
10
- # pdf相关解析功能
11
- from .fitz_ import *
12
- # 非算法层面的一些简单的图像格式转换功能
13
- from .imlib import *
14
- # 几何运算功能,也有相关的透视变换等图像处理
15
- from pyxllib.cv.cvlib import *
5
+ # @Date : 2020/11/15 10:04