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.
- pyxllib/__init__.py +9 -2
- pyxllib/algo/__init__.py +8 -0
- pyxllib/algo/disjoint.py +54 -0
- pyxllib/algo/geo.py +541 -0
- pyxllib/{util/mathlib.py → algo/intervals.py} +172 -36
- pyxllib/algo/matcher.py +389 -0
- pyxllib/algo/newbie.py +166 -0
- pyxllib/algo/pupil.py +629 -0
- pyxllib/algo/shapelylib.py +67 -0
- pyxllib/algo/specialist.py +241 -0
- pyxllib/algo/stat.py +494 -0
- pyxllib/algo/treelib.py +149 -0
- pyxllib/algo/unitlib.py +66 -0
- pyxllib/autogui/__init__.py +5 -0
- pyxllib/autogui/activewin.py +246 -0
- pyxllib/autogui/all.py +9 -0
- pyxllib/autogui/autogui.py +852 -0
- pyxllib/autogui/uiautolib.py +362 -0
- pyxllib/autogui/virtualkey.py +102 -0
- pyxllib/autogui/wechat.py +827 -0
- pyxllib/autogui/wechat_msg.py +421 -0
- pyxllib/autogui/wxautolib.py +84 -0
- pyxllib/cv/__init__.py +1 -11
- pyxllib/cv/expert.py +267 -0
- pyxllib/cv/{imlib.py → imfile.py} +18 -83
- pyxllib/cv/imhash.py +39 -0
- pyxllib/cv/pupil.py +9 -0
- pyxllib/cv/rgbfmt.py +1525 -0
- pyxllib/cv/slidercaptcha.py +137 -0
- pyxllib/cv/trackbartools.py +163 -49
- pyxllib/cv/xlcvlib.py +1040 -0
- pyxllib/cv/xlpillib.py +423 -0
- pyxllib/data/__init__.py +0 -0
- pyxllib/data/echarts.py +240 -0
- pyxllib/data/jsonlib.py +89 -0
- pyxllib/{util/oss2_.py → data/oss.py} +11 -9
- pyxllib/data/pglib.py +1127 -0
- pyxllib/data/sqlite.py +568 -0
- pyxllib/{util → data}/sqllib.py +13 -31
- pyxllib/ext/JLineViewer.py +505 -0
- pyxllib/ext/__init__.py +6 -0
- pyxllib/{util → ext}/demolib.py +119 -35
- pyxllib/ext/drissionlib.py +277 -0
- pyxllib/ext/kq5034lib.py +12 -0
- pyxllib/{util/main.py → ext/old.py} +122 -284
- pyxllib/ext/qt.py +449 -0
- pyxllib/ext/robustprocfile.py +497 -0
- pyxllib/ext/seleniumlib.py +76 -0
- pyxllib/{util/tklib.py → ext/tk.py} +10 -11
- pyxllib/ext/unixlib.py +827 -0
- pyxllib/ext/utools.py +351 -0
- pyxllib/{util/webhooklib.py → ext/webhook.py} +45 -17
- pyxllib/ext/win32lib.py +40 -0
- pyxllib/ext/wjxlib.py +88 -0
- pyxllib/ext/wpsapi.py +124 -0
- pyxllib/ext/xlwork.py +9 -0
- pyxllib/ext/yuquelib.py +1105 -0
- pyxllib/file/__init__.py +17 -0
- pyxllib/file/docxlib.py +761 -0
- pyxllib/{util → file}/gitlib.py +40 -27
- pyxllib/file/libreoffice.py +165 -0
- pyxllib/file/movielib.py +148 -0
- pyxllib/file/newbie.py +10 -0
- pyxllib/file/onenotelib.py +1469 -0
- pyxllib/file/packlib/__init__.py +330 -0
- pyxllib/{util → file/packlib}/zipfile.py +598 -195
- pyxllib/file/pdflib.py +426 -0
- pyxllib/file/pupil.py +185 -0
- pyxllib/file/specialist/__init__.py +685 -0
- pyxllib/{basic/_5_dirlib.py → file/specialist/dirlib.py} +364 -93
- pyxllib/file/specialist/download.py +193 -0
- pyxllib/file/specialist/filelib.py +2829 -0
- pyxllib/file/xlsxlib.py +3131 -0
- pyxllib/file/xlsyncfile.py +341 -0
- pyxllib/prog/__init__.py +5 -0
- pyxllib/prog/cachetools.py +64 -0
- pyxllib/prog/deprecatedlib.py +233 -0
- pyxllib/prog/filelock.py +42 -0
- pyxllib/prog/ipyexec.py +253 -0
- pyxllib/prog/multiprogs.py +940 -0
- pyxllib/prog/newbie.py +451 -0
- pyxllib/prog/pupil.py +1197 -0
- pyxllib/{sitepackages.py → prog/sitepackages.py} +5 -3
- pyxllib/prog/specialist/__init__.py +391 -0
- pyxllib/prog/specialist/bc.py +203 -0
- pyxllib/prog/specialist/browser.py +497 -0
- pyxllib/prog/specialist/common.py +347 -0
- pyxllib/prog/specialist/datetime.py +199 -0
- pyxllib/prog/specialist/tictoc.py +240 -0
- pyxllib/prog/specialist/xllog.py +180 -0
- pyxllib/prog/xlosenv.py +108 -0
- pyxllib/stdlib/__init__.py +17 -0
- pyxllib/{util → stdlib}/tablepyxl/__init__.py +1 -3
- pyxllib/{util → stdlib}/tablepyxl/style.py +1 -1
- pyxllib/{util → stdlib}/tablepyxl/tablepyxl.py +2 -4
- pyxllib/text/__init__.py +8 -0
- pyxllib/text/ahocorasick.py +39 -0
- pyxllib/text/airscript.js +744 -0
- pyxllib/text/charclasslib.py +121 -0
- pyxllib/text/jiebalib.py +267 -0
- pyxllib/text/jinjalib.py +32 -0
- pyxllib/text/jsa_ai_prompt.md +271 -0
- pyxllib/text/jscode.py +922 -0
- pyxllib/text/latex/__init__.py +158 -0
- pyxllib/text/levenshtein.py +303 -0
- pyxllib/text/nestenv.py +1215 -0
- pyxllib/text/newbie.py +300 -0
- pyxllib/text/pupil/__init__.py +8 -0
- pyxllib/text/pupil/common.py +1121 -0
- pyxllib/text/pupil/xlalign.py +326 -0
- pyxllib/text/pycode.py +47 -0
- pyxllib/text/specialist/__init__.py +8 -0
- pyxllib/text/specialist/common.py +112 -0
- pyxllib/text/specialist/ptag.py +186 -0
- pyxllib/text/spellchecker.py +172 -0
- pyxllib/text/templates/echart_base.html +11 -0
- pyxllib/text/templates/highlight_code.html +17 -0
- pyxllib/text/templates/latex_editor.html +103 -0
- pyxllib/text/vbacode.py +17 -0
- pyxllib/text/xmllib.py +747 -0
- pyxllib/xl.py +39 -0
- pyxllib/xlcv.py +17 -0
- pyxllib-0.3.197.dist-info/METADATA +48 -0
- pyxllib-0.3.197.dist-info/RECORD +126 -0
- {pyxllib-0.0.43.dist-info → pyxllib-0.3.197.dist-info}/WHEEL +4 -5
- pyxllib/basic/_1_strlib.py +0 -945
- pyxllib/basic/_2_timelib.py +0 -488
- pyxllib/basic/_3_pathlib.py +0 -916
- pyxllib/basic/_4_loglib.py +0 -419
- pyxllib/basic/__init__.py +0 -54
- pyxllib/basic/arrow_.py +0 -250
- pyxllib/basic/chardet_.py +0 -66
- pyxllib/basic/dirlib.py +0 -529
- pyxllib/basic/dprint.py +0 -202
- pyxllib/basic/extension.py +0 -12
- pyxllib/basic/judge.py +0 -31
- pyxllib/basic/log.py +0 -204
- pyxllib/basic/pathlib_.py +0 -705
- pyxllib/basic/pytictoc.py +0 -102
- pyxllib/basic/qiniu_.py +0 -61
- pyxllib/basic/strlib.py +0 -761
- pyxllib/basic/timer.py +0 -132
- pyxllib/cv/cv.py +0 -834
- pyxllib/cv/cvlib/_1_geo.py +0 -543
- pyxllib/cv/cvlib/_2_cvprcs.py +0 -309
- pyxllib/cv/cvlib/_2_imgproc.py +0 -594
- pyxllib/cv/cvlib/_3_pilprcs.py +0 -80
- pyxllib/cv/cvlib/_4_cvimg.py +0 -211
- pyxllib/cv/cvlib/__init__.py +0 -10
- pyxllib/cv/debugtools.py +0 -82
- pyxllib/cv/fitz_.py +0 -300
- pyxllib/cv/installer.py +0 -42
- pyxllib/debug/_0_installer.py +0 -38
- pyxllib/debug/_1_typelib.py +0 -277
- pyxllib/debug/_2_chrome.py +0 -198
- pyxllib/debug/_3_showdir.py +0 -161
- pyxllib/debug/_4_bcompare.py +0 -140
- pyxllib/debug/__init__.py +0 -49
- pyxllib/debug/bcompare.py +0 -132
- pyxllib/debug/chrome.py +0 -198
- pyxllib/debug/installer.py +0 -38
- pyxllib/debug/showdir.py +0 -158
- pyxllib/debug/typelib.py +0 -278
- pyxllib/image/__init__.py +0 -12
- pyxllib/torch/__init__.py +0 -20
- pyxllib/torch/modellib.py +0 -37
- pyxllib/torch/trainlib.py +0 -344
- pyxllib/util/__init__.py +0 -20
- pyxllib/util/aip_.py +0 -141
- pyxllib/util/casiadb.py +0 -59
- pyxllib/util/excellib.py +0 -495
- pyxllib/util/filelib.py +0 -612
- pyxllib/util/jsondata.py +0 -27
- pyxllib/util/jsondata2.py +0 -92
- pyxllib/util/labelmelib.py +0 -139
- pyxllib/util/onepy/__init__.py +0 -29
- pyxllib/util/onepy/onepy.py +0 -574
- pyxllib/util/onepy/onmanager.py +0 -170
- pyxllib/util/pyautogui_.py +0 -219
- pyxllib/util/textlib.py +0 -1305
- pyxllib/util/unorder.py +0 -22
- pyxllib/util/xmllib.py +0 -639
- pyxllib-0.0.43.dist-info/METADATA +0 -39
- pyxllib-0.0.43.dist-info/RECORD +0 -80
- pyxllib-0.0.43.dist-info/top_level.txt +0 -1
- {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
|
-
# @
|
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
|