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
@@ -2,10 +2,11 @@
|
|
2
2
|
# -*- coding: utf-8 -*-
|
3
3
|
# @Author : 陈坤泽
|
4
4
|
# @Email : 877362867@qq.com
|
5
|
-
# @
|
5
|
+
# @Date : 2018/07/12 09:32
|
6
6
|
|
7
7
|
|
8
|
-
"""
|
8
|
+
""" 一系列还未整理的旧代码
|
9
|
+
|
9
10
|
任何模块代码的第一个字符串用来写文档注释
|
10
11
|
|
11
12
|
因为util下的debuglib、textlib、filelib的功能拆分并不是特别精确,所以一般不对外开放接口
|
@@ -14,45 +15,20 @@
|
|
14
15
|
|
15
16
|
import filecmp
|
16
17
|
import shutil
|
17
|
-
import sys
|
18
|
+
import sys
|
18
19
|
import textwrap
|
19
|
-
from os.path import getmtime
|
20
20
|
from os.path import join as pathjoin
|
21
|
-
from collections import OrderedDict, Counter
|
21
|
+
from collections import OrderedDict, Counter
|
22
|
+
import base64
|
23
|
+
import requests
|
22
24
|
|
23
25
|
from bs4 import BeautifulSoup
|
24
26
|
|
25
|
-
from pyxllib.debug import *
|
26
|
-
from pyxllib.image import *
|
27
|
-
from pyxllib.util.filelib import *
|
28
|
-
|
29
|
-
|
30
|
-
def ________B_数据结构________():
|
31
|
-
pass
|
32
|
-
|
33
|
-
|
34
|
-
def dict__sub__(d1, d2):
|
35
|
-
"""在d1中删除d2存在Keys的方法"""
|
36
|
-
d = {}
|
37
|
-
for k in [k for k in d1 if k not in d2]:
|
38
|
-
d[k] = d1[k]
|
39
|
-
return d
|
40
|
-
|
41
27
|
|
42
28
|
def ________C_文本处理________():
|
43
29
|
pass
|
44
30
|
|
45
31
|
|
46
|
-
def read_from_ubuntu(url):
|
47
|
-
"""从paste.ubuntu.com获取数据"""
|
48
|
-
if isinstance(url, int): # 允许输入一个数字ID来获取网页内容
|
49
|
-
url = 'https://paste.ubuntu.com/' + str(url) + '/'
|
50
|
-
r = requests.get(url)
|
51
|
-
soup = BeautifulSoup(r.text, 'lxml')
|
52
|
-
content = soup.find_all(name='div', attrs={'class': 'paste'})[2]
|
53
|
-
return content.get_text()
|
54
|
-
|
55
|
-
|
56
32
|
def 从部门Confluence获取数据(url):
|
57
33
|
cookies = getattr(从部门Confluence获取数据, 'cookies', None)
|
58
34
|
if cookies: # 如果存储了cookies,尝试使用
|
@@ -84,107 +60,6 @@ def ReadFromUrl(url):
|
|
84
60
|
return soup.get_text()
|
85
61
|
|
86
62
|
|
87
|
-
class CWord:
|
88
|
-
def __init__(self, arg1=None, *, visible=None):
|
89
|
-
"""visible默认为None,代表不对现有窗口显示情况做更改
|
90
|
-
如果设为bool值true或false,
|
91
|
-
"""
|
92
|
-
self.__dict__['app'] = win32.gencache.EnsureDispatch('Word.Application')
|
93
|
-
if isinstance(visible, bool): self.app.Visible = visible
|
94
|
-
|
95
|
-
if isinstance(arg1, str): # 输入的是一个文件名则打开
|
96
|
-
file = arg1
|
97
|
-
self.app.Documents.Open(file) # 打开文件
|
98
|
-
# self.__dict__ = app.Documents(Path(file).name).__dict__
|
99
|
-
self.__dict__['doc'] = self.app.Documents(Path(file).name) # 存储到doc成员变量
|
100
|
-
else: # 如果输入参数不合法,新建一个空word
|
101
|
-
self.app.Documents.Add()
|
102
|
-
self.__dict__['doc'] = self.app.ActiveDocument
|
103
|
-
|
104
|
-
def CheckAttr(self):
|
105
|
-
""" 输出 self.app.Documents 的成员 """
|
106
|
-
showdir(self.doc)
|
107
|
-
|
108
|
-
def CntPage(self):
|
109
|
-
"""统计word页数"""
|
110
|
-
return self.doc.ActiveWindow.Panes(1).Pages.Count
|
111
|
-
|
112
|
-
def GetParagraphs(self):
|
113
|
-
"""以 yield 形式获得每个段落文本内容"""
|
114
|
-
cntPar = self.doc.Paragraphs.Count
|
115
|
-
for i in range(1, cntPar + 1):
|
116
|
-
yield str(self.doc.Paragraphs(i))
|
117
|
-
|
118
|
-
def Close(self):
|
119
|
-
""" 关闭word文件 """
|
120
|
-
self.doc.Close(False)
|
121
|
-
# self.app.Quit()
|
122
|
-
|
123
|
-
def __getattr__(self, item):
|
124
|
-
""" 智能获取成员 """
|
125
|
-
if item in self.__dict__:
|
126
|
-
return self.__dict__[item]
|
127
|
-
elif self.doc:
|
128
|
-
return getattr(self.doc, item)
|
129
|
-
else:
|
130
|
-
return None
|
131
|
-
|
132
|
-
def __setattr__(self, key, value):
|
133
|
-
""" 智能设置成员 """
|
134
|
-
if key in self.__dict__:
|
135
|
-
self.__dict__[key] = value
|
136
|
-
elif self.doc:
|
137
|
-
setattr(self.doc, key, value)
|
138
|
-
else:
|
139
|
-
pass
|
140
|
-
|
141
|
-
def __str__(self):
|
142
|
-
""" 获得word文件的全文纯文本 """
|
143
|
-
return str(self.doc.Content)
|
144
|
-
|
145
|
-
|
146
|
-
class CExcel:
|
147
|
-
def __init__(self, arg1=None, *, visible=None):
|
148
|
-
"""visible默认为None,代表不对现有窗口显示情况做更改
|
149
|
-
如果设为bool值true或false,
|
150
|
-
"""
|
151
|
-
import win32com.client as win32
|
152
|
-
import win32com
|
153
|
-
|
154
|
-
self.__dict__['app'] = win32.gencache.EnsureDispatch('Excel.Application')
|
155
|
-
if isinstance(visible, bool): self.app.Visible = visible
|
156
|
-
|
157
|
-
if isinstance(arg1, str): # 输入的是一个文件名则打开
|
158
|
-
file = arg1
|
159
|
-
self.app.Workbooks.Open(file) # 打开文件
|
160
|
-
# self.__dict__ = app.Documents(Path(file).name).__dict__
|
161
|
-
self.__dict__['wb'] = self.app.Workbooks(Path(file).name) # 存储到doc成员变量
|
162
|
-
else: # 如果输入参数不合法,新建一个空word
|
163
|
-
# self.app.Workbooks.Add()
|
164
|
-
# self.__dict__['wb'] = self.app.ActiveWorkbook
|
165
|
-
self.__dict__['wb'] = self.app.Workbooks.Add()
|
166
|
-
self.__dict__['st'] = self.wb.ActiveSheet
|
167
|
-
|
168
|
-
def WriteCell(self, row=0, col=0, val='', *, fontColor=None):
|
169
|
-
"""往当前激活的st增加数据
|
170
|
-
|
171
|
-
row可以写0,表示往新的一行加数据
|
172
|
-
col可以列名,智能进行列查找
|
173
|
-
|
174
|
-
color可以设置颜色
|
175
|
-
"""
|
176
|
-
# 空表还有bug
|
177
|
-
if row == 0: row = self.st.UsedRange.Count + 1
|
178
|
-
dprint(row)
|
179
|
-
# if col == 0: row = self.st.UsedRange.Count + 1
|
180
|
-
|
181
|
-
self.st.Cells(row, col).Value = str(val)
|
182
|
-
|
183
|
-
def GetVal(self, row, col):
|
184
|
-
"""获得指定单元格的值"""
|
185
|
-
return self.st.Cells(row, col).Text
|
186
|
-
|
187
|
-
|
188
63
|
def EnsureContent(ob=None, encoding='utf8'):
|
189
64
|
"""
|
190
65
|
未输入ob参数时,自动从控制台获取文本
|
@@ -209,8 +84,10 @@ def EnsureContent(ob=None, encoding='utf8'):
|
|
209
84
|
text = textract.process(ob)
|
210
85
|
return text.decode(encoding, errors='ignore')
|
211
86
|
elif ob.endswith('.doc'):
|
212
|
-
|
213
|
-
|
87
|
+
from pyxllib.ex.win32lib import XlWin32WordApplication
|
88
|
+
app = XlWin32WordApplication.get_app()
|
89
|
+
a = app.open_doc(ob)
|
90
|
+
s = a.content
|
214
91
|
a.Close()
|
215
92
|
return s
|
216
93
|
else: # 其他按文本格式处理
|
@@ -338,8 +215,8 @@ def SetWkDir(wkDir=None, key=None):
|
|
338
215
|
|
339
216
|
def SmartCopyFiles(files, inFolder, outFolder):
|
340
217
|
"""将files里的文件移到folder目录里,如果folder里已经存在对应文件则自动进行备份"""
|
341
|
-
inFd =
|
342
|
-
outFd =
|
218
|
+
inFd = File(inFolder)
|
219
|
+
outFd = File(outFolder)
|
343
220
|
|
344
221
|
for file in files:
|
345
222
|
inFile = inFd / file
|
@@ -350,9 +227,9 @@ def SmartCopyFiles(files, inFolder, outFolder):
|
|
350
227
|
if filecmp.cmp(inFile, outFile):
|
351
228
|
continue # 如果两个文件是相同的,不用操作,可以直接处理下一个
|
352
229
|
else:
|
353
|
-
|
230
|
+
File(outFile).backup() # 如果不相同,则对outFile进行备份
|
354
231
|
shutil.copy2(inFile, outFile)
|
355
|
-
|
232
|
+
File(outFile).backup() # 对拷贝过来的文件也提前做好备份
|
356
233
|
|
357
234
|
|
358
235
|
def MyMove(folder1, folder2):
|
@@ -363,7 +240,7 @@ def MyMove(folder1, folder2):
|
|
363
240
|
def 多规则字符串筛选(列表, glob筛选=None, *, 正则筛选=None, 指定名筛选=None, 去除备份文件=False):
|
364
241
|
"""该函数主要供文件处理使用,其它字符串算法慎用"""
|
365
242
|
if glob筛选:
|
366
|
-
列表 = list(filter(lambda x:
|
243
|
+
列表 = list(filter(lambda x: File(x).match(glob筛选), 列表))
|
367
244
|
|
368
245
|
# 只挑选出满足正则条件的文件名(目录名)
|
369
246
|
if 正则筛选:
|
@@ -373,7 +250,7 @@ def 多规则字符串筛选(列表, glob筛选=None, *, 正则筛选=None, 指
|
|
373
250
|
列表 = list(filter(lambda x: x in 指定名筛选, 列表))
|
374
251
|
|
375
252
|
if 去除备份文件:
|
376
|
-
列表 = list(filter(lambda x: not
|
253
|
+
列表 = list(filter(lambda x: not File(x).backup_time, 列表))
|
377
254
|
|
378
255
|
return 列表
|
379
256
|
|
@@ -443,7 +320,7 @@ class CBaseFolder(object):
|
|
443
320
|
if not 目标目录: # 如果没有设置目标目录,则以该类所在目录为准
|
444
321
|
目标目录 = self.name
|
445
322
|
for fn in files:
|
446
|
-
f =
|
323
|
+
f = File(os.path.join(self.name, fn))
|
447
324
|
目标名称 = re.sub(origin, target, fn, flags=re.IGNORECASE)
|
448
325
|
f.rename(os.path.join(目标目录, 目标名称))
|
449
326
|
|
@@ -462,7 +339,7 @@ class CBaseFolder(object):
|
|
462
339
|
continue
|
463
340
|
|
464
341
|
def 大小(self):
|
465
|
-
return
|
342
|
+
return File(self.name).size
|
466
343
|
|
467
344
|
def 删除(self):
|
468
345
|
shutil.rmtree(self.name, ignore_errors=True)
|
@@ -486,7 +363,7 @@ def 文件搜索匹配(源目录, 自定义正则规则, *, 目标类型=('文
|
|
486
363
|
正则规则 = 自定义正则规则转为标准正则表达式(自定义正则规则)
|
487
364
|
所有目录 = tuple(os.walk(源目录))
|
488
365
|
for 当前目录名, 包含目录, 包含文件 in 所有目录:
|
489
|
-
parts =
|
366
|
+
parts = File(当前目录名).parts
|
490
367
|
if '.git' in parts or '$RECYCLE.BIN' in parts: # 去掉'.git'这个备份目录,'$RECYCLE.BIN'这个不知啥鬼目录
|
491
368
|
continue
|
492
369
|
相对目录 = 当前目录名[源目录前缀长度 + 1:]
|
@@ -523,8 +400,8 @@ def 文件重命名(源目录, 自定义正则规则, 新正则名称, *, 目标
|
|
523
400
|
ls.append([f, f2])
|
524
401
|
if not 调试:
|
525
402
|
targetName = os.path.join(目标目录, f2)
|
526
|
-
f3 =
|
527
|
-
if f3
|
403
|
+
f3 = File(targetName)
|
404
|
+
if f3:
|
528
405
|
print('文件已存在:', f3.name)
|
529
406
|
if 覆盖操作:
|
530
407
|
f3.delete()
|
@@ -565,7 +442,7 @@ def 目录下查找文本(目录, 文件名筛选, 目标文本, *, 模式='表
|
|
565
442
|
行文本模式:显示所有匹配的行文本
|
566
443
|
"""
|
567
444
|
ls = 文件搜索匹配(目录, 文件名筛选, 目标类型=('文件',))
|
568
|
-
ls = list(filter(lambda x:
|
445
|
+
ls = list(filter(lambda x: File(x).backup_time == '', ls)) # 去除备份文件
|
569
446
|
ls = natural_sort(ls)
|
570
447
|
if 模式 == '表格':
|
571
448
|
table = list()
|
@@ -598,8 +475,8 @@ def 目录下统计单词出现频数(目录, 文件名筛选, 目标文本=r'(\
|
|
598
475
|
"""默认会找所有单词,以及tex命令"""
|
599
476
|
ls = 文件搜索匹配(目录, 文件名筛选, 目标类型=('文件',))
|
600
477
|
s = list()
|
601
|
-
for fileName in [f for f in ls if not
|
602
|
-
c =
|
478
|
+
for fileName in [f for f in ls if not File(f).backup_time]: # 去除备份文件
|
479
|
+
c = File(pathjoin(目录, fileName)).read()
|
603
480
|
s.append(c)
|
604
481
|
s = '\n'.join(s)
|
605
482
|
|
@@ -616,70 +493,91 @@ def 目录下统计单词出现频数(目录, 文件名筛选, 目标文本=r'(\
|
|
616
493
|
def GetFullPathClass(s):
|
617
494
|
"""如果输入的是相对路径,会解析为绝对路径"""
|
618
495
|
# p = Path(s).resolve() # 奕本的电脑这句话运行不了
|
619
|
-
p =
|
496
|
+
p = File(s)
|
620
497
|
if not s.startswith('\\') and not p.drive:
|
621
|
-
p =
|
498
|
+
p = File.cwd() / p
|
622
499
|
return p
|
623
500
|
|
624
501
|
|
625
|
-
|
626
|
-
pass
|
502
|
+
____other = """"""
|
627
503
|
|
504
|
+
mydecrypt = base64.b64decode
|
628
505
|
|
629
|
-
################################################################################
|
630
|
-
### 图 像 处 理 操 作
|
631
|
-
################################################################################
|
632
|
-
import PIL
|
633
|
-
import PIL.ExifTags
|
634
|
-
from PIL import Image
|
635
506
|
|
507
|
+
class LengthFormatter:
|
508
|
+
""" 长度换算类,可以在允许浮点小误差的场景使用
|
509
|
+
TODO 需要精确运算也是可以的,那就要用分数类来存储底层值了
|
510
|
+
|
511
|
+
# 默认标准长度是mm,所以初始化一个233数字,就等于用233mm初始化
|
512
|
+
>>> LengthFormatter(233).cm # 然后可以转化为cm,计算厘米单位下的长度值
|
513
|
+
23.3
|
514
|
+
>>> LengthFormatter('233pt') # 可以用带单位的字符串
|
515
|
+
81.78mm
|
516
|
+
>>> LengthFormatter('233.45 pt') # 支持小数、有空格等格式
|
517
|
+
81.94mm
|
636
518
|
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
从而识别出正拍(代号1),顺时针旋转90度拍摄(代号8),顺时针180度拍摄(代号3),顺时针270度拍摄(代号6)。
|
641
|
-
windows上的图片查阅软件能识别方向代号后正确摆放;
|
642
|
-
为了让python处理图片的时候能增加这个属性的考虑,这个函数能修正识别角度返回新的图片。
|
519
|
+
应用举例:把长度超过12cm的hspace都限制在12cm以内
|
520
|
+
>> s = NestEnv(s).latexcmd1('hspace').bracket('{', inner=True).\
|
521
|
+
replace(lambda x: '12cm' if LengthFormatter(x).cm > 12 else x)
|
643
522
|
"""
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
523
|
+
|
524
|
+
# 所有其他单位长度与参照长度mm之间比例关系
|
525
|
+
ratio = {'pt': 0.351, # 点
|
526
|
+
'bp': 0.353, # 大点,≈1pt
|
527
|
+
'dd': 0.376, # 迪多,=1.07pt
|
528
|
+
'pc': 4.218, # 派卡,=12pt
|
529
|
+
'sp': 1 / 65536, # 定标点,65536sp=1pt
|
530
|
+
'cm': 10, # 厘米
|
531
|
+
'cc': 4.513, # 西塞罗
|
532
|
+
'in': 25.4, # 英寸,=72.27pt
|
533
|
+
'em': 18, # 1em≈当前字体中M的宽度,在正文12pt情况下,一般为18pt
|
534
|
+
'ex': 12, # 1ex≈当前字体中x的高度,暂按12pt处理
|
535
|
+
}
|
536
|
+
|
537
|
+
def __init__(self, v=0):
|
538
|
+
if isinstance(v, (int, float)):
|
539
|
+
self.__dict__['mm'] = v
|
540
|
+
elif isinstance(v, str):
|
541
|
+
m = re.match(r'(-?\d+(?:\.\d*)?)\s*(' + '|'.join(list(self.ratio.keys()) + ['mm']) + ')$', v)
|
542
|
+
if not m: raise ValueError(f'不存在的长度单位类型:{v}')
|
543
|
+
self.__dict__['mm'] = 0
|
544
|
+
self.__setitem__(m.group(2), float(m.group(1)))
|
545
|
+
else:
|
546
|
+
raise ValueError(f'不存在的长度单位类型:{v}')
|
547
|
+
|
548
|
+
def __repr__(self):
|
549
|
+
return '{:.2f}mm'.format(self.__dict__['mm'])
|
550
|
+
|
551
|
+
def __getattr__(self, key):
|
552
|
+
if key in self.ratio.keys():
|
553
|
+
return self.__dict__['mm'] / self.ratio[key]
|
554
|
+
else:
|
555
|
+
raise ValueError(f'不存在的长度单位类型:{key}')
|
556
|
+
|
557
|
+
def __setitem__(self, key, value):
|
558
|
+
if key == 'mm':
|
559
|
+
self.__dict__['mm'] = value
|
560
|
+
elif key in self.ratio.keys():
|
561
|
+
self.__dict__['mm'] = value * self.ratio[key]
|
562
|
+
else:
|
563
|
+
raise ValueError(f'不存在的长度单位类型:{key}')
|
564
|
+
|
565
|
+
|
566
|
+
____image = """
|
567
|
+
暂时还没空整理的一些图片功能
|
568
|
+
"""
|
672
569
|
|
673
570
|
|
674
571
|
def 缩放目录下所有png图片(folder, rate=120):
|
675
572
|
"""rate可以控制缩放比例,正常是100
|
676
573
|
再乘120是不想缩放太多,理论上乘100是正常比例
|
574
|
+
|
575
|
+
旧函数名:缩放目录下所有png图片
|
677
576
|
"""
|
678
|
-
fd =
|
679
|
-
for
|
680
|
-
files = pathjoin(fd.name, imgFile)
|
577
|
+
fd = Dir(folder)
|
578
|
+
for f in fd.select_files('*.png'):
|
681
579
|
try:
|
682
|
-
im = Image.open(
|
580
|
+
im = Image.open(str(f))
|
683
581
|
if 'dpi' in im.info:
|
684
582
|
if im.info['dpi'][0] in (305, 610): # 这个是magick转换过来的特殊值,不能缩放
|
685
583
|
continue # 180920周四,610是为欧龙加的,欧龙双师需要设置-density 240
|
@@ -689,137 +587,77 @@ def 缩放目录下所有png图片(folder, rate=120):
|
|
689
587
|
s[0] = int(s[0] / im.info['dpi'][0] * rate)
|
690
588
|
s[1] = int(s[1] / im.info['dpi'][1] * rate)
|
691
589
|
im = im.resize(s, Image.ANTIALIAS)
|
692
|
-
im.save(
|
590
|
+
im.save(str(f))
|
693
591
|
except:
|
694
|
-
print('无法处理图片:',
|
592
|
+
print('无法处理图片:', f)
|
695
593
|
continue
|
696
594
|
|
697
595
|
|
698
596
|
def 缩放目录下所有png图片2(folder, scale=1.0):
|
699
597
|
"""rate可以控制缩放比例,正常是100
|
700
598
|
再乘120是不想缩放太多,理论上乘100是正常比例
|
599
|
+
|
600
|
+
旧函数名:缩放目录下所有png图片2
|
701
601
|
"""
|
702
|
-
fd =
|
703
|
-
for
|
704
|
-
|
705
|
-
im = Image.open(files)
|
602
|
+
fd = Dir(folder)
|
603
|
+
for f in fd.select_files('*.png'):
|
604
|
+
im = Image.open(str(f))
|
706
605
|
s = list(im.size)
|
707
606
|
s[0] = int(s[0] * scale)
|
708
607
|
s[1] = int(s[1] * scale)
|
709
608
|
im = im.resize(s, Image.ANTIALIAS)
|
710
|
-
im.save(
|
609
|
+
im.save(str(f))
|
711
610
|
|
712
611
|
|
713
612
|
def 查看目录下png图片信息(folder):
|
714
|
-
|
613
|
+
"""
|
614
|
+
旧函数名:查看目录下png图片信息
|
615
|
+
"""
|
616
|
+
fd = Dir(folder)
|
715
617
|
ls = list()
|
716
|
-
for
|
717
|
-
|
718
|
-
im = Image.open(file.name)
|
618
|
+
for f in fd.select_files('*.png'):
|
619
|
+
im = Image.open(str(f))
|
719
620
|
d0, d1 = im.info['dpi'] if 'dpi' in im.info else ('', '')
|
720
621
|
# 处理eps格式
|
721
|
-
epsFile =
|
622
|
+
epsFile = f.with_suffix('.eps')
|
722
623
|
if epsFile:
|
723
624
|
epsSize, epsIm = epsFile.大小(), Image.open(epsFile.name)
|
724
625
|
boundingBox = epsIm.info['BoundingBox'].replace(' ', ',') if 'BoundingBox' in epsIm.info else ''
|
725
626
|
else:
|
726
627
|
epsSize, boundingBox = '', ''
|
727
628
|
# 处理pdf格式
|
728
|
-
pdfFile =
|
629
|
+
pdfFile = File(f.name[:-4] + '-eps-converted-to.pdf')
|
729
630
|
pdfSize = pdfFile.size if pdfFile else ''
|
730
631
|
# 存储到列表
|
731
|
-
ls.append((
|
732
|
-
|
632
|
+
ls.append((f, im.size[0], im.size[1], d0, d1,
|
633
|
+
f.size, f.mtime.strftime(' %y%m%d-%H%M%S'),
|
733
634
|
epsSize, boundingBox, pdfSize))
|
734
635
|
df = pd.DataFrame.from_records(ls,
|
735
636
|
columns=('fileName', 'width', 'height', 'dpi_w', 'dpi_h', 'size', 'time', 'epsSize',
|
736
637
|
'boundingBox', 'pdfSize'))
|
737
|
-
|
638
|
+
with pd.option_context('display.max_colwidth', -1, 'display.max_columns', 20,
|
639
|
+
'display.width', 200): # 上下文控制格式
|
640
|
+
print(df)
|
738
641
|
return df
|
739
642
|
|
740
643
|
|
741
|
-
def
|
742
|
-
"""
|
743
|
-
|
644
|
+
def make_color_transparent(image, color, thresh2=0):
|
645
|
+
""" 将指定颜色转为透明
|
646
|
+
https://stackoverflow.com/questions/765736/using-pil-to-make-all-white-pixels-transparent/765829
|
744
647
|
|
745
|
-
|
648
|
+
旧函数名:MakeColorTransparent
|
649
|
+
"""
|
746
650
|
from PIL import ImageMath
|
747
651
|
|
748
|
-
def
|
652
|
+
def distance2(a, b):
|
749
653
|
return (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]) + (a[2] - b[2]) * (a[2] - b[2])
|
750
654
|
|
751
655
|
image = image.convert("RGBA")
|
752
656
|
red, green, blue, alpha = image.split()
|
753
657
|
image.putalpha(ImageMath.eval("""convert(((((t - d(c, (r, g, b))) >> 31) + 1) ^ 1) * a, 'L')""",
|
754
|
-
t=thresh2, d=
|
658
|
+
t=thresh2, d=distance2, c=color, r=red, g=green, b=blue, a=alpha))
|
755
659
|
return image
|
756
660
|
|
757
661
|
|
758
|
-
____other = """"""
|
759
|
-
|
760
|
-
mydecrypt = base64.b64decode
|
761
|
-
|
762
|
-
|
763
|
-
class LengthFormatter:
|
764
|
-
""" 长度换算类,可以在允许浮点小误差的场景使用
|
765
|
-
TODO 需要精确运算也是可以的,那就要用分数类来存储底层值了
|
766
|
-
|
767
|
-
# 默认标准长度是mm,所以初始化一个233数字,就等于用233mm初始化
|
768
|
-
>>> LengthFormatter(233).cm # 然后可以转化为cm,计算厘米单位下的长度值
|
769
|
-
23.3
|
770
|
-
>>> LengthFormatter('233pt') # 可以用带单位的字符串
|
771
|
-
81.78mm
|
772
|
-
>>> LengthFormatter('233.45 pt') # 支持小数、有空格等格式
|
773
|
-
81.94mm
|
774
|
-
|
775
|
-
应用举例:把长度超过12cm的hspace都限制在12cm以内
|
776
|
-
>> s = NestEnv(s).latexcmd1('hspace').bracket('{', inner=True).\
|
777
|
-
replace(lambda x: '12cm' if LengthFormatter(x).cm > 12 else x)
|
778
|
-
"""
|
779
|
-
|
780
|
-
# 所有其他单位长度与参照长度mm之间比例关系
|
781
|
-
ratio = {'pt': 0.351, # 点
|
782
|
-
'bp': 0.353, # 大点,≈1pt
|
783
|
-
'dd': 0.376, # 迪多,=1.07pt
|
784
|
-
'pc': 4.218, # 派卡,=12pt
|
785
|
-
'sp': 1 / 65536, # 定标点,65536sp=1pt
|
786
|
-
'cm': 10, # 厘米
|
787
|
-
'cc': 4.513, # 西塞罗
|
788
|
-
'in': 25.4, # 英寸,=72.27pt
|
789
|
-
'em': 18, # 1em≈当前字体中M的宽度,在正文12pt情况下,一般为18pt
|
790
|
-
'ex': 12, # 1ex≈当前字体中x的高度,暂按12pt处理
|
791
|
-
}
|
792
|
-
|
793
|
-
def __init__(self, v=0):
|
794
|
-
if isinstance(v, (int, float)):
|
795
|
-
self.__dict__['mm'] = v
|
796
|
-
elif isinstance(v, str):
|
797
|
-
m = re.match(r'(-?\d+(?:\.\d*)?)\s*(' + '|'.join(list(self.ratio.keys()) + ['mm']) + ')$', v)
|
798
|
-
if not m: raise ValueError(f'不存在的长度单位类型:{v}')
|
799
|
-
self.__dict__['mm'] = 0
|
800
|
-
self.__setitem__(m.group(2), float(m.group(1)))
|
801
|
-
else:
|
802
|
-
raise ValueError(f'不存在的长度单位类型:{v}')
|
803
|
-
|
804
|
-
def __repr__(self):
|
805
|
-
return '{:.2f}mm'.format(self.__dict__['mm'])
|
806
|
-
|
807
|
-
def __getattr__(self, key):
|
808
|
-
if key == 'mm':
|
809
|
-
return self.__dict__['mm']
|
810
|
-
elif key in self.ratio.keys():
|
811
|
-
return self.__dict__['mm'] / self.ratio[key]
|
812
|
-
else:
|
813
|
-
raise ValueError(f'不存在的长度单位类型:{key}')
|
814
|
-
|
815
|
-
def __setitem__(self, key, value):
|
816
|
-
if key == 'mm':
|
817
|
-
self.__dict__['mm'] = value
|
818
|
-
elif key in self.ratio.keys():
|
819
|
-
self.__dict__['mm'] = value * self.ratio[key]
|
820
|
-
else:
|
821
|
-
raise ValueError(f'不存在的长度单位类型:{key}')
|
822
|
-
|
823
|
-
|
824
662
|
if __name__ == '__main__':
|
825
663
|
print('测试')
|