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
pyxllib/prog/ipyexec.py
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# @Author : 陈坤泽
|
4
|
+
# @Email : 877362867@qq.com
|
5
|
+
# @Date : 2023/08/26
|
6
|
+
|
7
|
+
# from pyxllib.prog.pupil import check_install_package
|
8
|
+
|
9
|
+
# check_install_package('IPython', 'ipython')
|
10
|
+
|
11
|
+
import os
|
12
|
+
import sys
|
13
|
+
from multiprocessing import Process, Pipe
|
14
|
+
from io import StringIO
|
15
|
+
import threading
|
16
|
+
|
17
|
+
# from IPython.core.interactiveshell import InteractiveShell
|
18
|
+
|
19
|
+
from pyxllib.prog.pupil import format_exception
|
20
|
+
from pyxllib.file.specialist import XlPath
|
21
|
+
|
22
|
+
if sys.platform == 'win32':
|
23
|
+
def timeout(seconds):
|
24
|
+
def decorator(func):
|
25
|
+
def wrapper(*args, **kwargs):
|
26
|
+
result = None
|
27
|
+
exception = None
|
28
|
+
|
29
|
+
# 定义一个内部函数来运行目标函数
|
30
|
+
def worker():
|
31
|
+
nonlocal result, exception
|
32
|
+
try:
|
33
|
+
result = func(*args, **kwargs)
|
34
|
+
except Exception as e:
|
35
|
+
exception = e
|
36
|
+
|
37
|
+
thread = threading.Thread(target=worker)
|
38
|
+
thread.start()
|
39
|
+
thread.join(timeout=seconds)
|
40
|
+
|
41
|
+
if thread.is_alive():
|
42
|
+
thread.join() # 确保线程结束
|
43
|
+
raise TimeoutError(f"Function '{func.__name__}' exceeded {seconds} seconds of execution time.")
|
44
|
+
if exception:
|
45
|
+
raise exception
|
46
|
+
return result
|
47
|
+
|
48
|
+
return wrapper
|
49
|
+
|
50
|
+
return decorator
|
51
|
+
|
52
|
+
|
53
|
+
class InProcessExecutor:
|
54
|
+
def __init__(self, base_dir=None):
|
55
|
+
""" 注意为了应急,这里暂时是很不工程化的写法,一旦初始化这个类,工作目录、stdout、stderr 就被改变了 """
|
56
|
+
self.base_dir = XlPath(base_dir) if base_dir else None
|
57
|
+
self.user_ns = {}
|
58
|
+
|
59
|
+
# 保存原始的工作目录、stdout 和 stderr
|
60
|
+
self._original_cwd = os.getcwd()
|
61
|
+
self._original_stdout = sys.stdout
|
62
|
+
self._original_stderr = sys.stderr
|
63
|
+
|
64
|
+
if self.base_dir:
|
65
|
+
self.base_dir.mkdir(parents=True, exist_ok=True)
|
66
|
+
os.chdir(self.base_dir)
|
67
|
+
|
68
|
+
def _execute_code(self, code):
|
69
|
+
response = {}
|
70
|
+
try:
|
71
|
+
# 捕获输出
|
72
|
+
old_stdout, old_stderr = sys.stdout, sys.stderr
|
73
|
+
redirected_output = StringIO()
|
74
|
+
sys.stdout, sys.stderr = redirected_output, redirected_output
|
75
|
+
|
76
|
+
# 使用 exec 执行代码
|
77
|
+
exec(code, self.user_ns)
|
78
|
+
|
79
|
+
# 恢复原始的 stdout 和 stderr
|
80
|
+
sys.stdout, sys.stderr = old_stdout, old_stderr
|
81
|
+
|
82
|
+
response['output'] = redirected_output.getvalue().strip()
|
83
|
+
|
84
|
+
except Exception as e:
|
85
|
+
response['error'] = format_exception(e)
|
86
|
+
|
87
|
+
return response
|
88
|
+
|
89
|
+
# @timeout(10) # 先把超时写死了,以后有空再研究怎么加到函数的timeout参数里
|
90
|
+
def execute(self, code: str, silent=False):
|
91
|
+
""" 在主进程中执行代码 """
|
92
|
+
response = self._execute_code(code)
|
93
|
+
|
94
|
+
if not silent and response.get('output'):
|
95
|
+
print(response['output'])
|
96
|
+
|
97
|
+
if response.get('error'):
|
98
|
+
print(f"执行错误: {response['error']}")
|
99
|
+
|
100
|
+
return response
|
101
|
+
|
102
|
+
def get_var(self, var_name: str):
|
103
|
+
""" 获取指定的变量值 """
|
104
|
+
return self.user_ns.get(var_name, None)
|
105
|
+
|
106
|
+
def set_var(self, var_name: str, value):
|
107
|
+
""" 设置变量的值 """
|
108
|
+
self.user_ns[var_name] = value
|
109
|
+
|
110
|
+
def close(self):
|
111
|
+
""" 恢复原始的工作目录、stdout 和 stderr """
|
112
|
+
os.chdir(self._original_cwd)
|
113
|
+
sys.stdout = self._original_stdout
|
114
|
+
sys.stderr = self._original_stderr
|
115
|
+
|
116
|
+
|
117
|
+
class SubprocessExecutor:
|
118
|
+
""" 子进程版本 """
|
119
|
+
|
120
|
+
def __init__(self, base_dir=None):
|
121
|
+
""" 初始化执行器并启动子进程 """
|
122
|
+
self.parent_conn, self.child_conn = Pipe()
|
123
|
+
self.base_dir = XlPath(base_dir)
|
124
|
+
self.process = Process(target=self._child_process, args=(self.child_conn, base_dir))
|
125
|
+
self.process.start()
|
126
|
+
|
127
|
+
def _child_process(self, conn, base_dir):
|
128
|
+
""" 子进程主循环 """
|
129
|
+
if base_dir:
|
130
|
+
os.chdir(base_dir)
|
131
|
+
|
132
|
+
user_ns = {} # 初始化一个空的用户命名空间来替代 InteractiveShell 的 user_ns
|
133
|
+
|
134
|
+
while True:
|
135
|
+
message = conn.recv() # 从父进程接收消息
|
136
|
+
if message.get('action') == 'exit':
|
137
|
+
break
|
138
|
+
elif message.get('action') == 'execute':
|
139
|
+
code = message.get('code')
|
140
|
+
response = self._execute_code(code, user_ns) # 传递user_ns为参数
|
141
|
+
conn.send(response)
|
142
|
+
elif message.get('action') == 'get_var':
|
143
|
+
var_name = message.get('name')
|
144
|
+
response = {'output': str(user_ns.get(var_name, None))}
|
145
|
+
conn.send(response)
|
146
|
+
elif message.get('action') == 'set_var':
|
147
|
+
var_name = message.get('name')
|
148
|
+
value = message.get('value')
|
149
|
+
user_ns[var_name] = value
|
150
|
+
|
151
|
+
def _execute_code(self, code, user_ns):
|
152
|
+
response = {}
|
153
|
+
try:
|
154
|
+
# Capture output
|
155
|
+
old_stdout, old_stderr = sys.stdout, sys.stderr
|
156
|
+
redirected_output = StringIO()
|
157
|
+
sys.stdout, sys.stderr = redirected_output, redirected_output
|
158
|
+
|
159
|
+
# 使用 exec 来执行代码
|
160
|
+
exec(code, user_ns) # 使用传入的用户命名空间来执行代码
|
161
|
+
|
162
|
+
# Restore original stdout and stderr
|
163
|
+
sys.stdout, sys.stderr = old_stdout, old_stderr
|
164
|
+
|
165
|
+
response['output'] = redirected_output.getvalue().strip()
|
166
|
+
|
167
|
+
except Exception as e:
|
168
|
+
response['error'] = format_exception(e)
|
169
|
+
|
170
|
+
return response
|
171
|
+
|
172
|
+
# @timeout(10)
|
173
|
+
def execute(self, code: str, silent=False):
|
174
|
+
""" 在子进程中执行代码 """
|
175
|
+
self.parent_conn.send({'action': 'execute', 'code': code})
|
176
|
+
response = self.parent_conn.recv()
|
177
|
+
|
178
|
+
# 如果不处于静默模式,则处理响应
|
179
|
+
if not silent:
|
180
|
+
if response.get('output'):
|
181
|
+
print(response['output'], end='')
|
182
|
+
if response.get('error'):
|
183
|
+
print(f"Error: {response['error']}")
|
184
|
+
|
185
|
+
return response
|
186
|
+
|
187
|
+
def get_var(self, var_name: str):
|
188
|
+
""" 获取指定的环境变量值 """
|
189
|
+
self.parent_conn.send({'action': 'get_var', 'name': var_name})
|
190
|
+
response = self.parent_conn.recv()
|
191
|
+
return response['output']
|
192
|
+
|
193
|
+
def set_var(self, var_name: str, value):
|
194
|
+
""" 设置环境变量的值 """
|
195
|
+
self.parent_conn.send({'action': 'set_var', 'name': var_name, 'value': value})
|
196
|
+
|
197
|
+
def close(self):
|
198
|
+
""" 关闭子进程 """
|
199
|
+
self.parent_conn.send({'action': 'exit'})
|
200
|
+
self.process.join()
|
201
|
+
|
202
|
+
|
203
|
+
if os.getppid() == os.getpid(): # 主进程的时候,另外建立子进程运行更好,也便于调试
|
204
|
+
AutoProcessExecutor = SubprocessExecutor
|
205
|
+
else: # 并发跑的时候,只能在每个进程里,不能另外再套进程
|
206
|
+
AutoProcessExecutor = InProcessExecutor
|
207
|
+
|
208
|
+
|
209
|
+
class InteractiveExecutor(SubprocessExecutor):
|
210
|
+
""" 这个类是比较定制化的,还不算通用工具类
|
211
|
+
|
212
|
+
但对我来说,暂时会经常用到,所以就写到这里来了
|
213
|
+
"""
|
214
|
+
|
215
|
+
def execute(self, code: str, silent=False):
|
216
|
+
""" 在子进程中执行代码
|
217
|
+
|
218
|
+
相比父类,运行前会先记录当前文件清单,运行后会记录新的文件清单,然后对比两个文件清单,找出新的文件
|
219
|
+
1. 为了简化问题,暂时只考虑工作目录下的直接文件,不考虑子目录,也不考虑对同名文件可能进行的修改
|
220
|
+
2. 假设操作都只会在工作目录里,不会对工作目录外的文件使用绝对路径等手动操作
|
221
|
+
"""
|
222
|
+
# 1 记录运行前的文件清单
|
223
|
+
files1 = {f.name for f in self.base_dir.glob_files()}
|
224
|
+
|
225
|
+
# 2 执行代码
|
226
|
+
self.parent_conn.send({'action': 'execute', 'code': code})
|
227
|
+
response = self.parent_conn.recv()
|
228
|
+
|
229
|
+
# 3 记录运行后的文件清单
|
230
|
+
files2 = {f.name for f in self.base_dir.glob_files()}
|
231
|
+
out_files = list(files2 - files1) # 相减后视为新增的文件
|
232
|
+
if out_files:
|
233
|
+
response['out_files'] = out_files
|
234
|
+
|
235
|
+
# 如果不处于静默模式,则处理响应
|
236
|
+
if not silent:
|
237
|
+
if response['output']:
|
238
|
+
print(response['output'])
|
239
|
+
if 'error' in response:
|
240
|
+
print(f"Error: {response['error']}")
|
241
|
+
|
242
|
+
return response
|
243
|
+
|
244
|
+
|
245
|
+
if __name__ == '__main__':
|
246
|
+
# 读取指定工作目录里的文件;只在指定工作目录里创建文件
|
247
|
+
ie = SubprocessExecutor(XlPath.desktop())
|
248
|
+
ie.execute('with open("a.txt", "r", encoding="utf8") as f: print(f.read())')
|
249
|
+
# Hello
|
250
|
+
r = ie.execute('with open("b.txt", "w", encoding="utf8") as f: f.write ("hello123")')
|
251
|
+
print(r) # {'output': '', 'files': {'b.txt'}}
|
252
|
+
|
253
|
+
print(ie.get_var('test')) # 索引不存在时返回None
|