pyxllib 0.3.197__py3-none-any.whl → 3.201.1__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 +14 -21
- pyxllib/algo/__init__.py +8 -8
- pyxllib/algo/disjoint.py +54 -54
- pyxllib/algo/geo.py +537 -541
- pyxllib/algo/intervals.py +964 -964
- pyxllib/algo/matcher.py +389 -389
- pyxllib/algo/newbie.py +166 -166
- pyxllib/algo/pupil.py +629 -629
- pyxllib/algo/shapelylib.py +67 -67
- pyxllib/algo/specialist.py +241 -241
- pyxllib/algo/stat.py +494 -494
- pyxllib/algo/treelib.py +145 -149
- pyxllib/algo/unitlib.py +62 -66
- pyxllib/autogui/__init__.py +5 -5
- pyxllib/autogui/activewin.py +246 -246
- pyxllib/autogui/all.py +9 -9
- pyxllib/autogui/autogui.py +846 -852
- pyxllib/autogui/uiautolib.py +362 -362
- pyxllib/autogui/virtualkey.py +102 -102
- pyxllib/autogui/wechat.py +827 -827
- pyxllib/autogui/wechat_msg.py +421 -421
- pyxllib/autogui/wxautolib.py +84 -84
- pyxllib/cv/__init__.py +5 -5
- pyxllib/cv/expert.py +267 -267
- pyxllib/cv/imfile.py +159 -159
- pyxllib/cv/imhash.py +39 -39
- pyxllib/cv/pupil.py +9 -9
- pyxllib/cv/rgbfmt.py +1525 -1525
- pyxllib/cv/slidercaptcha.py +137 -137
- pyxllib/cv/trackbartools.py +251 -251
- pyxllib/cv/xlcvlib.py +1040 -1040
- pyxllib/cv/xlpillib.py +423 -423
- pyxllib/data/echarts.py +236 -240
- pyxllib/data/jsonlib.py +85 -89
- pyxllib/data/oss.py +72 -72
- pyxllib/data/pglib.py +1111 -1127
- pyxllib/data/sqlite.py +568 -568
- pyxllib/data/sqllib.py +297 -297
- pyxllib/ext/JLineViewer.py +505 -505
- pyxllib/ext/__init__.py +6 -6
- pyxllib/ext/demolib.py +251 -246
- pyxllib/ext/drissionlib.py +277 -277
- pyxllib/ext/kq5034lib.py +12 -12
- pyxllib/ext/qt.py +449 -449
- pyxllib/ext/robustprocfile.py +493 -497
- pyxllib/ext/seleniumlib.py +76 -76
- pyxllib/ext/tk.py +173 -173
- pyxllib/ext/unixlib.py +821 -827
- pyxllib/ext/utools.py +345 -351
- pyxllib/ext/webhook.py +124 -119
- pyxllib/ext/win32lib.py +40 -40
- pyxllib/ext/wjxlib.py +91 -88
- pyxllib/ext/wpsapi.py +124 -124
- pyxllib/ext/xlwork.py +9 -9
- pyxllib/ext/yuquelib.py +1110 -1105
- pyxllib/file/__init__.py +17 -17
- pyxllib/file/docxlib.py +757 -761
- pyxllib/file/gitlib.py +309 -309
- pyxllib/file/libreoffice.py +165 -165
- pyxllib/file/movielib.py +144 -148
- pyxllib/file/newbie.py +10 -10
- pyxllib/file/onenotelib.py +1469 -1469
- pyxllib/file/packlib/__init__.py +330 -330
- pyxllib/file/packlib/zipfile.py +2441 -2441
- pyxllib/file/pdflib.py +422 -426
- pyxllib/file/pupil.py +185 -185
- pyxllib/file/specialist/__init__.py +681 -685
- pyxllib/file/specialist/dirlib.py +799 -799
- pyxllib/file/specialist/download.py +193 -193
- pyxllib/file/specialist/filelib.py +2825 -2829
- pyxllib/file/xlsxlib.py +3122 -3131
- pyxllib/file/xlsyncfile.py +341 -341
- pyxllib/prog/__init__.py +5 -5
- pyxllib/prog/cachetools.py +58 -64
- pyxllib/prog/deprecatedlib.py +233 -233
- pyxllib/prog/filelock.py +42 -42
- pyxllib/prog/ipyexec.py +253 -253
- pyxllib/prog/multiprogs.py +940 -940
- pyxllib/prog/newbie.py +451 -451
- pyxllib/prog/pupil.py +1208 -1197
- pyxllib/prog/sitepackages.py +33 -33
- pyxllib/prog/specialist/__init__.py +348 -391
- pyxllib/prog/specialist/bc.py +203 -203
- pyxllib/prog/specialist/browser.py +497 -497
- pyxllib/prog/specialist/common.py +347 -347
- pyxllib/prog/specialist/datetime.py +198 -198
- pyxllib/prog/specialist/tictoc.py +240 -240
- pyxllib/prog/specialist/xllog.py +180 -180
- pyxllib/prog/xlosenv.py +110 -108
- pyxllib/stdlib/__init__.py +17 -17
- pyxllib/stdlib/tablepyxl/__init__.py +10 -10
- pyxllib/stdlib/tablepyxl/style.py +303 -303
- pyxllib/stdlib/tablepyxl/tablepyxl.py +130 -130
- pyxllib/text/__init__.py +8 -8
- pyxllib/text/ahocorasick.py +36 -39
- pyxllib/text/airscript.js +754 -744
- pyxllib/text/charclasslib.py +121 -121
- pyxllib/text/jiebalib.py +267 -267
- pyxllib/text/jinjalib.py +27 -32
- pyxllib/text/jsa_ai_prompt.md +271 -271
- pyxllib/text/jscode.py +922 -922
- pyxllib/text/latex/__init__.py +158 -158
- pyxllib/text/levenshtein.py +303 -303
- pyxllib/text/nestenv.py +1215 -1215
- pyxllib/text/newbie.py +300 -300
- pyxllib/text/pupil/__init__.py +8 -8
- pyxllib/text/pupil/common.py +1121 -1121
- pyxllib/text/pupil/xlalign.py +326 -326
- pyxllib/text/pycode.py +47 -47
- pyxllib/text/specialist/__init__.py +8 -8
- pyxllib/text/specialist/common.py +112 -112
- pyxllib/text/specialist/ptag.py +186 -186
- pyxllib/text/spellchecker.py +172 -172
- pyxllib/text/templates/echart_base.html +10 -10
- pyxllib/text/templates/highlight_code.html +16 -16
- pyxllib/text/templates/latex_editor.html +102 -102
- pyxllib/text/vbacode.py +17 -17
- pyxllib/text/xmllib.py +741 -747
- pyxllib/xl.py +42 -39
- pyxllib/xlcv.py +17 -17
- pyxllib-3.201.1.dist-info/METADATA +296 -0
- pyxllib-3.201.1.dist-info/RECORD +125 -0
- {pyxllib-0.3.197.dist-info → pyxllib-3.201.1.dist-info}/licenses/LICENSE +190 -190
- pyxllib/ext/old.py +0 -663
- pyxllib-0.3.197.dist-info/METADATA +0 -48
- pyxllib-0.3.197.dist-info/RECORD +0 -126
- {pyxllib-0.3.197.dist-info → pyxllib-3.201.1.dist-info}/WHEEL +0 -0
@@ -1,193 +1,193 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
# -*- coding: utf-8 -*-
|
3
|
-
# @Author : 陈坤泽
|
4
|
-
# @Email : 877362867@qq.com
|
5
|
-
# @Date : 2021/06/09 11:02
|
6
|
-
|
7
|
-
import logging
|
8
|
-
import os
|
9
|
-
import shutil
|
10
|
-
from typing import Callable, List, Optional
|
11
|
-
from urllib import request
|
12
|
-
|
13
|
-
import requests
|
14
|
-
from bs4 import BeautifulSoup
|
15
|
-
|
16
|
-
from pyxllib.file.specialist import File, Dir, refinepath
|
17
|
-
|
18
|
-
|
19
|
-
def download_file(url, fn=None, *, encoding=None, if_exists=None, ext=None, temp=False):
|
20
|
-
r""" 类似writefile,只是源数据是从url里下载
|
21
|
-
|
22
|
-
:param url: 数据下载链接
|
23
|
-
:param fn: 保存位置,会从url智能提取文件名
|
24
|
-
:param if_exists: 详见 File.write 参数解释
|
25
|
-
:para temp: 将文件写到临时文件夹
|
26
|
-
:return:
|
27
|
-
|
28
|
-
>> download_file(image_url) # 保存在当前工作目录下
|
29
|
-
D:/home/chenkunze/slns/xlproject/xlsln/ckz2024/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg
|
30
|
-
>> download_file(image_url, fn=r"D:/home/chenkunze/slns/xlproject/xlsln/ckz2024/a.png") # 指定路径
|
31
|
-
D:/home/chenkunze/slns/xlproject/xlsln/ckz2024/a.png
|
32
|
-
>> download_file(image_url, fn=r"D:/home/chenkunze/slns/xlproject/xlsln/ckz2024") # 暂不支持目录
|
33
|
-
ValueError: 不能用目录初始化一个File对象 D:\home\chenkunze\slns\xlproject\xlsln\ckz2023
|
34
|
-
"""
|
35
|
-
if not fn: fn = refinepath(url.split('/')[-1])[-80:] # 这里故意截断文件名最长80个字符
|
36
|
-
root = Dir.TEMP if temp else None
|
37
|
-
fn = File(fn, root, suffix=ext).write(requests.get(url).content,
|
38
|
-
encoding=encoding, if_exists=if_exists, etag=(not fn))
|
39
|
-
return fn.to_str()
|
40
|
-
|
41
|
-
|
42
|
-
def read_from_ubuntu(url):
|
43
|
-
"""从paste.ubuntu.com获取数据"""
|
44
|
-
if isinstance(url, int): # 允许输入一个数字ID来获取网页内容
|
45
|
-
url = 'https://paste.ubuntu.com/' + str(url) + '/'
|
46
|
-
r = requests.get(url)
|
47
|
-
soup = BeautifulSoup(r.text, 'lxml')
|
48
|
-
content = soup.find_all(name='div', attrs={'class': 'paste'})[2]
|
49
|
-
return content.get_text()
|
50
|
-
|
51
|
-
|
52
|
-
def download(
|
53
|
-
url: str, dir: str, *, filename: Optional[str] = None, progress: bool = True
|
54
|
-
) -> str:
|
55
|
-
""" 取自fvcore:Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
56
|
-
|
57
|
-
Download a file from a given URL to a directory. If file exists, will not
|
58
|
-
overwrite the existing file.
|
59
|
-
|
60
|
-
Args:
|
61
|
-
url (str):
|
62
|
-
dir (str): the directory to download the file
|
63
|
-
filename (str or None): the basename to save the file.
|
64
|
-
Will use the name in the URL if not given.
|
65
|
-
progress (bool): whether to use tqdm to draw a progress bar.
|
66
|
-
|
67
|
-
Returns:
|
68
|
-
str: the path to the downloaded file or the existing one.
|
69
|
-
"""
|
70
|
-
os.makedirs(dir, exist_ok=True)
|
71
|
-
if filename is None:
|
72
|
-
filename = url.split("/")[-1]
|
73
|
-
assert len(filename), "Cannot obtain filename from url {}".format(url)
|
74
|
-
fpath = os.path.join(dir, filename)
|
75
|
-
logger = logging.getLogger(__name__)
|
76
|
-
|
77
|
-
if os.path.isfile(fpath):
|
78
|
-
logger.info("File {} exists! Skipping download.".format(filename))
|
79
|
-
return fpath
|
80
|
-
|
81
|
-
tmp = fpath + ".tmp" # download to a tmp file first, to be more atomic.
|
82
|
-
try:
|
83
|
-
logger.info("Downloading from {} ...".format(url))
|
84
|
-
if progress:
|
85
|
-
import tqdm
|
86
|
-
|
87
|
-
def hook(t: tqdm.tqdm) -> Callable[[int, int, Optional[int]], None]:
|
88
|
-
last_b: List[int] = [0]
|
89
|
-
|
90
|
-
def inner(b: int, bsize: int, tsize: Optional[int] = None) -> None:
|
91
|
-
if tsize is not None:
|
92
|
-
t.total = tsize
|
93
|
-
t.update((b - last_b[0]) * bsize) # type: ignore
|
94
|
-
last_b[0] = b
|
95
|
-
|
96
|
-
return inner
|
97
|
-
|
98
|
-
with tqdm.tqdm( # type: ignore
|
99
|
-
unit="B", unit_scale=True, miniters=1, desc=filename, leave=True
|
100
|
-
) as t:
|
101
|
-
tmp, _ = request.urlretrieve(url, filename=tmp, reporthook=hook(t))
|
102
|
-
|
103
|
-
else:
|
104
|
-
tmp, _ = request.urlretrieve(url, filename=tmp)
|
105
|
-
statinfo = os.stat(tmp)
|
106
|
-
size = statinfo.st_size
|
107
|
-
if size == 0:
|
108
|
-
raise IOError("Downloaded an empty file from {}!".format(url))
|
109
|
-
# download to tmp first and move to fpath, to make this function more
|
110
|
-
# atomic.
|
111
|
-
shutil.move(tmp, fpath)
|
112
|
-
except IOError:
|
113
|
-
logger.error("Failed to download {}".format(url))
|
114
|
-
raise
|
115
|
-
finally:
|
116
|
-
try:
|
117
|
-
os.unlink(tmp)
|
118
|
-
except IOError:
|
119
|
-
pass
|
120
|
-
|
121
|
-
logger.info("Successfully downloaded " + fpath + ". " + str(size) + " bytes.")
|
122
|
-
return fpath
|
123
|
-
|
124
|
-
|
125
|
-
def ensure_localfile(localfile, from_url, *, if_exists=None, progress=True):
|
126
|
-
""" 判断本地文件 localfile 是否存在,如果不存在,自动从指定的 from_url 下载下来
|
127
|
-
|
128
|
-
TODO 增加 md5校验、自动解压 等功能
|
129
|
-
|
130
|
-
:param if_exists: 参数含义见 file.exist_preprcs
|
131
|
-
使用 'replace' 可以强制下载重置文件
|
132
|
-
:param progress: 是否显示下载进度
|
133
|
-
|
134
|
-
>> ensure_localfile('ufo.csv', r'https://gitee.com/code4101/TestData/raw/master/ufo.csv')
|
135
|
-
"""
|
136
|
-
path, file = str(localfile), File(localfile)
|
137
|
-
|
138
|
-
if file.exist_preprcs(if_exists):
|
139
|
-
dirname, name = os.path.split(path)
|
140
|
-
download(from_url, dirname, filename=name, progress=progress)
|
141
|
-
return localfile
|
142
|
-
|
143
|
-
|
144
|
-
def ensure_localdir(localdir, from_url, *, if_exists=None, progress=True, wrap=0):
|
145
|
-
""" 判断本地目录 localdir 是否存在,如果不存在,自动从指定的 from_url 下载下来
|
146
|
-
|
147
|
-
:param from_url: 相比 ensure_localfile,这个链接一般是一个压缩包,下载到本地后要解压到目标目录
|
148
|
-
:param wrap:
|
149
|
-
wrap=1,如果压缩包里的文件有多个,可以多加一层目录包装起来
|
150
|
-
wrap<0,有的从url下载的压缩包,还会自带一层目录,为了避免冗余,要去掉
|
151
|
-
"""
|
152
|
-
from pyxllib.file.packlib import unpack_archive
|
153
|
-
d = Dir(localdir)
|
154
|
-
if not d.is_dir():
|
155
|
-
if d.exist_preprcs(if_exists):
|
156
|
-
pack_file = download(from_url, d.parent, progress=progress)
|
157
|
-
unpack_archive(pack_file, localdir, wrap=wrap)
|
158
|
-
os.remove(pack_file)
|
159
|
-
|
160
|
-
return localdir
|
161
|
-
|
162
|
-
|
163
|
-
def get_font_file(name):
|
164
|
-
""" 获得指定名称的字体文件
|
165
|
-
|
166
|
-
:param name: 记得要写后缀,例如 "simfang.ttf"
|
167
|
-
simfang.ttf,仿宋
|
168
|
-
msyh.ttf,微软雅黑
|
169
|
-
"""
|
170
|
-
from pyxllib.file.specialist import ensure_localfile, XlPath
|
171
|
-
|
172
|
-
# 0 当前目录有,则优先返回当前目录的文件
|
173
|
-
p = XlPath(name)
|
174
|
-
if p.is_file():
|
175
|
-
return p
|
176
|
-
|
177
|
-
# 1 windows直接找系统的字体目录
|
178
|
-
font_file = XlPath(f'C:/Windows/Fonts/{name}')
|
179
|
-
if font_file.is_file():
|
180
|
-
return font_file
|
181
|
-
|
182
|
-
# 2 否则下载到.xlpr/fonts
|
183
|
-
# 注意不能下载到C:/Windows/Fonts,会遇到权限问题,报错
|
184
|
-
font_file = XlPath.userdir() / f'.xlpr/fonts/{name}'
|
185
|
-
# 去github上paddleocr项目下载
|
186
|
-
# from_url = f'https://raw.githubusercontent.com/code4101/data1/main/fonts/{name}'
|
187
|
-
from_url = f'https://xmutpriu.com/download/fonts/{name}'
|
188
|
-
try:
|
189
|
-
ensure_localfile(font_file, from_url)
|
190
|
-
except TimeoutError as e:
|
191
|
-
raise TimeoutError(f'{font_file} 下载失败:{from_url}')
|
192
|
-
|
193
|
-
return font_file
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# @Author : 陈坤泽
|
4
|
+
# @Email : 877362867@qq.com
|
5
|
+
# @Date : 2021/06/09 11:02
|
6
|
+
|
7
|
+
import logging
|
8
|
+
import os
|
9
|
+
import shutil
|
10
|
+
from typing import Callable, List, Optional
|
11
|
+
from urllib import request
|
12
|
+
|
13
|
+
import requests
|
14
|
+
from bs4 import BeautifulSoup
|
15
|
+
|
16
|
+
from pyxllib.file.specialist import File, Dir, refinepath
|
17
|
+
|
18
|
+
|
19
|
+
def download_file(url, fn=None, *, encoding=None, if_exists=None, ext=None, temp=False):
|
20
|
+
r""" 类似writefile,只是源数据是从url里下载
|
21
|
+
|
22
|
+
:param url: 数据下载链接
|
23
|
+
:param fn: 保存位置,会从url智能提取文件名
|
24
|
+
:param if_exists: 详见 File.write 参数解释
|
25
|
+
:para temp: 将文件写到临时文件夹
|
26
|
+
:return:
|
27
|
+
|
28
|
+
>> download_file(image_url) # 保存在当前工作目录下
|
29
|
+
D:/home/chenkunze/slns/xlproject/xlsln/ckz2024/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg
|
30
|
+
>> download_file(image_url, fn=r"D:/home/chenkunze/slns/xlproject/xlsln/ckz2024/a.png") # 指定路径
|
31
|
+
D:/home/chenkunze/slns/xlproject/xlsln/ckz2024/a.png
|
32
|
+
>> download_file(image_url, fn=r"D:/home/chenkunze/slns/xlproject/xlsln/ckz2024") # 暂不支持目录
|
33
|
+
ValueError: 不能用目录初始化一个File对象 D:\home\chenkunze\slns\xlproject\xlsln\ckz2023
|
34
|
+
"""
|
35
|
+
if not fn: fn = refinepath(url.split('/')[-1])[-80:] # 这里故意截断文件名最长80个字符
|
36
|
+
root = Dir.TEMP if temp else None
|
37
|
+
fn = File(fn, root, suffix=ext).write(requests.get(url).content,
|
38
|
+
encoding=encoding, if_exists=if_exists, etag=(not fn))
|
39
|
+
return fn.to_str()
|
40
|
+
|
41
|
+
|
42
|
+
def read_from_ubuntu(url):
|
43
|
+
"""从paste.ubuntu.com获取数据"""
|
44
|
+
if isinstance(url, int): # 允许输入一个数字ID来获取网页内容
|
45
|
+
url = 'https://paste.ubuntu.com/' + str(url) + '/'
|
46
|
+
r = requests.get(url)
|
47
|
+
soup = BeautifulSoup(r.text, 'lxml')
|
48
|
+
content = soup.find_all(name='div', attrs={'class': 'paste'})[2]
|
49
|
+
return content.get_text()
|
50
|
+
|
51
|
+
|
52
|
+
def download(
|
53
|
+
url: str, dir: str, *, filename: Optional[str] = None, progress: bool = True
|
54
|
+
) -> str:
|
55
|
+
""" 取自fvcore:Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
56
|
+
|
57
|
+
Download a file from a given URL to a directory. If file exists, will not
|
58
|
+
overwrite the existing file.
|
59
|
+
|
60
|
+
Args:
|
61
|
+
url (str):
|
62
|
+
dir (str): the directory to download the file
|
63
|
+
filename (str or None): the basename to save the file.
|
64
|
+
Will use the name in the URL if not given.
|
65
|
+
progress (bool): whether to use tqdm to draw a progress bar.
|
66
|
+
|
67
|
+
Returns:
|
68
|
+
str: the path to the downloaded file or the existing one.
|
69
|
+
"""
|
70
|
+
os.makedirs(dir, exist_ok=True)
|
71
|
+
if filename is None:
|
72
|
+
filename = url.split("/")[-1]
|
73
|
+
assert len(filename), "Cannot obtain filename from url {}".format(url)
|
74
|
+
fpath = os.path.join(dir, filename)
|
75
|
+
logger = logging.getLogger(__name__)
|
76
|
+
|
77
|
+
if os.path.isfile(fpath):
|
78
|
+
logger.info("File {} exists! Skipping download.".format(filename))
|
79
|
+
return fpath
|
80
|
+
|
81
|
+
tmp = fpath + ".tmp" # download to a tmp file first, to be more atomic.
|
82
|
+
try:
|
83
|
+
logger.info("Downloading from {} ...".format(url))
|
84
|
+
if progress:
|
85
|
+
import tqdm
|
86
|
+
|
87
|
+
def hook(t: tqdm.tqdm) -> Callable[[int, int, Optional[int]], None]:
|
88
|
+
last_b: List[int] = [0]
|
89
|
+
|
90
|
+
def inner(b: int, bsize: int, tsize: Optional[int] = None) -> None:
|
91
|
+
if tsize is not None:
|
92
|
+
t.total = tsize
|
93
|
+
t.update((b - last_b[0]) * bsize) # type: ignore
|
94
|
+
last_b[0] = b
|
95
|
+
|
96
|
+
return inner
|
97
|
+
|
98
|
+
with tqdm.tqdm( # type: ignore
|
99
|
+
unit="B", unit_scale=True, miniters=1, desc=filename, leave=True
|
100
|
+
) as t:
|
101
|
+
tmp, _ = request.urlretrieve(url, filename=tmp, reporthook=hook(t))
|
102
|
+
|
103
|
+
else:
|
104
|
+
tmp, _ = request.urlretrieve(url, filename=tmp)
|
105
|
+
statinfo = os.stat(tmp)
|
106
|
+
size = statinfo.st_size
|
107
|
+
if size == 0:
|
108
|
+
raise IOError("Downloaded an empty file from {}!".format(url))
|
109
|
+
# download to tmp first and move to fpath, to make this function more
|
110
|
+
# atomic.
|
111
|
+
shutil.move(tmp, fpath)
|
112
|
+
except IOError:
|
113
|
+
logger.error("Failed to download {}".format(url))
|
114
|
+
raise
|
115
|
+
finally:
|
116
|
+
try:
|
117
|
+
os.unlink(tmp)
|
118
|
+
except IOError:
|
119
|
+
pass
|
120
|
+
|
121
|
+
logger.info("Successfully downloaded " + fpath + ". " + str(size) + " bytes.")
|
122
|
+
return fpath
|
123
|
+
|
124
|
+
|
125
|
+
def ensure_localfile(localfile, from_url, *, if_exists=None, progress=True):
|
126
|
+
""" 判断本地文件 localfile 是否存在,如果不存在,自动从指定的 from_url 下载下来
|
127
|
+
|
128
|
+
TODO 增加 md5校验、自动解压 等功能
|
129
|
+
|
130
|
+
:param if_exists: 参数含义见 file.exist_preprcs
|
131
|
+
使用 'replace' 可以强制下载重置文件
|
132
|
+
:param progress: 是否显示下载进度
|
133
|
+
|
134
|
+
>> ensure_localfile('ufo.csv', r'https://gitee.com/code4101/TestData/raw/master/ufo.csv')
|
135
|
+
"""
|
136
|
+
path, file = str(localfile), File(localfile)
|
137
|
+
|
138
|
+
if file.exist_preprcs(if_exists):
|
139
|
+
dirname, name = os.path.split(path)
|
140
|
+
download(from_url, dirname, filename=name, progress=progress)
|
141
|
+
return localfile
|
142
|
+
|
143
|
+
|
144
|
+
def ensure_localdir(localdir, from_url, *, if_exists=None, progress=True, wrap=0):
|
145
|
+
""" 判断本地目录 localdir 是否存在,如果不存在,自动从指定的 from_url 下载下来
|
146
|
+
|
147
|
+
:param from_url: 相比 ensure_localfile,这个链接一般是一个压缩包,下载到本地后要解压到目标目录
|
148
|
+
:param wrap:
|
149
|
+
wrap=1,如果压缩包里的文件有多个,可以多加一层目录包装起来
|
150
|
+
wrap<0,有的从url下载的压缩包,还会自带一层目录,为了避免冗余,要去掉
|
151
|
+
"""
|
152
|
+
from pyxllib.file.packlib import unpack_archive
|
153
|
+
d = Dir(localdir)
|
154
|
+
if not d.is_dir():
|
155
|
+
if d.exist_preprcs(if_exists):
|
156
|
+
pack_file = download(from_url, d.parent, progress=progress)
|
157
|
+
unpack_archive(pack_file, localdir, wrap=wrap)
|
158
|
+
os.remove(pack_file)
|
159
|
+
|
160
|
+
return localdir
|
161
|
+
|
162
|
+
|
163
|
+
def get_font_file(name):
|
164
|
+
""" 获得指定名称的字体文件
|
165
|
+
|
166
|
+
:param name: 记得要写后缀,例如 "simfang.ttf"
|
167
|
+
simfang.ttf,仿宋
|
168
|
+
msyh.ttf,微软雅黑
|
169
|
+
"""
|
170
|
+
from pyxllib.file.specialist import ensure_localfile, XlPath
|
171
|
+
|
172
|
+
# 0 当前目录有,则优先返回当前目录的文件
|
173
|
+
p = XlPath(name)
|
174
|
+
if p.is_file():
|
175
|
+
return p
|
176
|
+
|
177
|
+
# 1 windows直接找系统的字体目录
|
178
|
+
font_file = XlPath(f'C:/Windows/Fonts/{name}')
|
179
|
+
if font_file.is_file():
|
180
|
+
return font_file
|
181
|
+
|
182
|
+
# 2 否则下载到.xlpr/fonts
|
183
|
+
# 注意不能下载到C:/Windows/Fonts,会遇到权限问题,报错
|
184
|
+
font_file = XlPath.userdir() / f'.xlpr/fonts/{name}'
|
185
|
+
# 去github上paddleocr项目下载
|
186
|
+
# from_url = f'https://raw.githubusercontent.com/code4101/data1/main/fonts/{name}'
|
187
|
+
from_url = f'https://xmutpriu.com/download/fonts/{name}'
|
188
|
+
try:
|
189
|
+
ensure_localfile(font_file, from_url)
|
190
|
+
except TimeoutError as e:
|
191
|
+
raise TimeoutError(f'{font_file} 下载失败:{from_url}')
|
192
|
+
|
193
|
+
return font_file
|