Compare commits
No commits in common. 'main' and 'master' have entirely different histories.
@ -1,162 +0,0 @@
|
||||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
@ -0,0 +1,22 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredErrors">
|
||||
<list>
|
||||
<option value="N813" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredIdentifiers">
|
||||
<list>
|
||||
<option value="object.transform" />
|
||||
<option value="object.cluster_centers_" />
|
||||
<option value="object.labels_" />
|
||||
<option value="nodes" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (py-xltpl-lyFnwNVB)" project-jdk-type="Python SDK" />
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/py-xltpl.iml" filepath="$PROJECT_DIR$/.idea/py-xltpl.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -1,9 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -0,0 +1,11 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.8"
|
@ -0,0 +1,20 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "7f7606f08e0544d8d012ef4d097dabdd6df6843a28793eb6551245d4b2db4242"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.8"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {},
|
||||
"develop": {}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2023/4/27 6:21
|
||||
# @Author : old tom
|
||||
# @File : __init__.py.py
|
||||
# @Project : py-xltpl
|
||||
# @Desc :
|
Binary file not shown.
@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2023/4/27 10:01
|
||||
# @Author : old tom
|
||||
# @File : excel_writer.py
|
||||
# @Project : py-xltpl
|
||||
# @Desc : 写入excel模板
|
||||
from xltpl.writerx import BookWriter
|
||||
from exceltpl.pdman.pdman_reader import PDmanReader
|
||||
from futool.core.fh_file_path import exist
|
||||
|
||||
|
||||
class ATiDeDBDocWriter(object):
|
||||
class TemplateNotExistError(Exception):
|
||||
def __init__(self, msg):
|
||||
Exception.__init__(self, msg)
|
||||
|
||||
def __init__(self, data, tpl_path, out_path):
|
||||
"""
|
||||
:param data: 数据 使用PDmanReader 读取
|
||||
:param tpl_path: 模板路径
|
||||
:param out_path: 输出路径
|
||||
"""
|
||||
if not exist(tpl_path):
|
||||
raise self.TemplateNotExistError(f'[{tpl_path}]模板不存在,请检查路径')
|
||||
self.writer = BookWriter(tpl_path)
|
||||
self.writer.set_jinja_globals(dir=dir, getattr=getattr)
|
||||
self.data = data
|
||||
self.out_path = out_path
|
||||
|
||||
def fill(self):
|
||||
payloads = []
|
||||
for i, t in enumerate(self.data):
|
||||
table = self.data[t]
|
||||
table['sheet_name'] = str(i + 1) + '.' + table['table_name']
|
||||
table['tpl_idx'] = i
|
||||
payloads.append(table)
|
||||
self.writer.render_sheets(payloads=payloads)
|
||||
self.writer.save(self.out_path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
reader = PDmanReader(r'D:\文档\工作\ATD\2023上半年\项目\昭通OA\表结构\昭通OA.pdma.json')
|
||||
writer = ATiDeDBDocWriter(reader.read_by_module('OA_CAR'), r'C:\Users\89295\Desktop\atide_db_tpl.xlsx',
|
||||
r'C:\Users\89295\Desktop\车辆管理.xlsx')
|
||||
writer.fill()
|
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2023/4/27 6:21
|
||||
# @Author : old tom
|
||||
# @File : __init__.py.py
|
||||
# @Project : py-xltpl
|
||||
# @Desc :
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2023/4/27 6:21
|
||||
# @Author : old tom
|
||||
# @File : pdman_reader.py
|
||||
# @Project : py-xltpl
|
||||
# @Desc : 读取pdman 文件
|
||||
|
||||
from futool.core.fh_file_path import exist
|
||||
import json
|
||||
|
||||
|
||||
class PDmanReader(object):
|
||||
DATA_TYPE_MAPPING = {
|
||||
'oracle': {
|
||||
'DefaultString': 'VARCHAR2(255)',
|
||||
'IdOrKey': 'VARCHAR2(32)',
|
||||
'Name': 'VARCHAR2(90)',
|
||||
'Int': 'NUMBER(38,0)',
|
||||
'Double': 'NUMBER(24,6)',
|
||||
'Money': 'NUMBER(24,6)',
|
||||
'DateTime': 'DATE',
|
||||
'YesNo': 'VARCHAR2(1)',
|
||||
'Dict': 'VARCHAR2(32)',
|
||||
'DescText': 'VARCHAR2(900)'
|
||||
}
|
||||
}
|
||||
|
||||
class PDfileNotExistError(Exception):
|
||||
"""
|
||||
PDMAN 文件不存在
|
||||
"""
|
||||
|
||||
def __init__(self, msg):
|
||||
Exception.__init__(self, msg)
|
||||
|
||||
class ModuleNotExistError(Exception):
|
||||
"""
|
||||
模块不存在
|
||||
"""
|
||||
|
||||
def __init__(self, msg):
|
||||
Exception.__init__(self, msg)
|
||||
|
||||
def __init__(self, pdman_file):
|
||||
if not exist(pdman_file):
|
||||
raise self.PDfileNotExistError(msg=f'{pdman_file}文件不存在')
|
||||
with open(pdman_file, 'r', encoding='utf-8') as f:
|
||||
self.json_reader = json.loads(f.read())
|
||||
self.modules = self._load_all_module()
|
||||
self.domains = self._load_data_domains()
|
||||
|
||||
def read_by_module(self, module_name):
|
||||
"""
|
||||
根据模块读取
|
||||
:param module_name: 模块名称
|
||||
:return:
|
||||
"""
|
||||
if module_name not in self.modules.keys():
|
||||
raise self.ModuleNotExistError(f'{module_name}模块不存在')
|
||||
# 获取模块与表关联关系
|
||||
entry_ids = self.modules[module_name]
|
||||
tables = {}
|
||||
for entry in self.json_reader['entities']:
|
||||
if entry['id'] in entry_ids:
|
||||
# 读取表名,字段
|
||||
tables[entry['defKey']] = {
|
||||
'table_name': entry['defName'],
|
||||
'table_en_name': entry['defKey'],
|
||||
'rows': self._fields_convert(entry['fields'])
|
||||
}
|
||||
return tables
|
||||
|
||||
def _load_all_module(self):
|
||||
"""
|
||||
加载模块索引
|
||||
:return:
|
||||
"""
|
||||
modules = self.json_reader['viewGroups']
|
||||
module_dict = {}
|
||||
for m in modules:
|
||||
module_dict[m['defKey']] = m['refEntities']
|
||||
return module_dict
|
||||
|
||||
def _load_data_domains(self, db_type='oracle'):
|
||||
"""
|
||||
加载数据域
|
||||
:return:
|
||||
"""
|
||||
domains_dict = {}
|
||||
domains = self.json_reader['domains']
|
||||
for d in domains:
|
||||
domains_dict[d['id']] = self.DATA_TYPE_MAPPING[db_type][d['defKey']]
|
||||
return domains_dict
|
||||
|
||||
#
|
||||
def _fields_convert(self, fields):
|
||||
rt = []
|
||||
for f in fields:
|
||||
if 'domain' in f.keys() and len(f['domain']) > 0:
|
||||
f['type'] = self.domains[f['domain']]
|
||||
elif len(str(f['len'])) > 0 and len(str(f['scale'])) == 0:
|
||||
f['type'] = f['type'] + '(' + str(f['len']) + ')'
|
||||
elif len(str(f['len'])) > 0 and len(str(f['scale'])) > 0:
|
||||
f['type'] = f['type'] + '(' + str(f['len']) + ',' + str(f['scale']) + ')'
|
||||
rt.append({'enName': f['defKey'],
|
||||
'chName': f['defName'] + ';' + f['comment'] if len(f['comment']) > 0 else f['defName'],
|
||||
'type': f['type'], 'nullable': 'Y' if f['notNull'] else 'N'})
|
||||
return rt
|
||||
|
||||
|
||||
#
|
||||
if __name__ == '__main__':
|
||||
pdfile = r'C:\Users\89295\Desktop\昭通OA.pdma.json'
|
||||
reader = PDmanReader(pdfile)
|
||||
all_table = reader.read_by_module('OA_CAR')
|
||||
print(all_table)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2022/9/10 10:15
|
||||
# @Author : old tom
|
||||
# @File : fu_lang.py
|
||||
# @Project : Futool
|
||||
# @Desc : 字符串相关
|
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2022/9/10 10:17
|
||||
# @Author : old tom
|
||||
# @File : fu_math.py
|
||||
# @Project : Futool
|
||||
# @Desc : 数学计算
|
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2022/9/10 10:46
|
||||
# @Author : old tom
|
||||
# @File : fu_parser.py
|
||||
# @Project : Futool
|
||||
# @Desc : 解析器(CSV,JSON,NB文件)
|
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2023/4/3 21:46
|
||||
# @Author : old tom
|
||||
# @File : fh_db.py
|
||||
# @Project : futool
|
||||
# @Desc : 数据库通用类
|
||||
|
@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2022/8/31 23:34
|
||||
# @Author : old tom
|
||||
# @File : http_downloader.py
|
||||
# @Project : Futool
|
||||
# @Desc : 文件下载器
|
||||
import time
|
||||
|
||||
from futool.http.http_request import head
|
||||
from multiprocessing import Pool
|
||||
import urllib.request as req
|
||||
|
||||
|
||||
class HttpDownloader(object):
|
||||
"""
|
||||
HTTP 下载器
|
||||
"""
|
||||
|
||||
def __init__(self, pool=None):
|
||||
self.pool = Pool(16) if not pool else pool
|
||||
|
||||
def download(self, url, dst, chunk_size=1000):
|
||||
"""
|
||||
文件下,自动开启多线程
|
||||
:param url: 下载链接
|
||||
:param dst: 保存路径
|
||||
:param chunk_size: 文件块
|
||||
:return:
|
||||
"""
|
||||
is_support, content_length = HttpDownloader.is_support_range(url)
|
||||
if is_support:
|
||||
# 每个线程下载字节偏移量
|
||||
offset = self.fork(int(content_length), chunk_size)
|
||||
self.__join(offset, url, dst)
|
||||
else:
|
||||
print('无法获取Content-Length,使用单线程下载')
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def is_support_range(url):
|
||||
"""
|
||||
判断是否支持range请求
|
||||
:return:
|
||||
"""
|
||||
wrapper = head(url)
|
||||
header = wrapper.header()
|
||||
h_keys = header.keys()
|
||||
if 'Accept-Ranges' in h_keys and 'Content-Length' in h_keys and header['Accept-Ranges'] != 'none':
|
||||
return True, header['Content-Length']
|
||||
else:
|
||||
return False, 0
|
||||
|
||||
@staticmethod
|
||||
def fork(content_length: int, chunk_size):
|
||||
"""
|
||||
拆分线程
|
||||
:param chunk_size: 文件块大小
|
||||
:param content_length:
|
||||
:return:
|
||||
"""
|
||||
offset = []
|
||||
if content_length <= chunk_size:
|
||||
offset.append((0, content_length))
|
||||
else:
|
||||
for i in range(content_length // chunk_size):
|
||||
start_offset = chunk_size * i + 1
|
||||
end_offset = start_offset - 1 + chunk_size
|
||||
offset.append((0 if i == 0 else start_offset, end_offset))
|
||||
offset.append((chunk_size * (content_length // chunk_size), content_length))
|
||||
return offset
|
||||
|
||||
def __join(self, offset, url, dst):
|
||||
"""
|
||||
多线程下载
|
||||
:param offset:
|
||||
:param url:
|
||||
:param dst:
|
||||
:return:
|
||||
"""
|
||||
|
||||
def download_by_thread(part):
|
||||
_request = req.Request(url=url, headers={
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.70",
|
||||
'Range': f'bytes:{part[0]}-{part[1]}'
|
||||
}, method='GET')
|
||||
response = req.urlopen(_request)
|
||||
with open(dst + f'.{time.time_ns()}', 'wb') as f:
|
||||
f.write(response.read())
|
||||
|
||||
self.pool.map(download_by_thread, offset)
|
||||
self.pool.close()
|
||||
self.pool.join()
|
@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2022/8/29 23:14
|
||||
# @Author : old tom
|
||||
# @File : http_response.py
|
||||
# @Project : Futool
|
||||
# @Desc : 响应解析
|
||||
|
||||
from http.client import HTTPResponse
|
||||
from http.cookiejar import CookieJar
|
||||
import json
|
||||
|
||||
DEFAULT_ENCODING = 'UTF-8'
|
||||
|
||||
# 响应类型编码
|
||||
RESPONSE_CONTENT_ENCODING = "Content-Encoding"
|
||||
|
||||
# 压缩类型
|
||||
COMPRESS_TYPE = ('gzip', 'deflate', 'br')
|
||||
|
||||
|
||||
class ResponseWrapper(object):
|
||||
|
||||
def __init__(self, response: HTTPResponse, cookie: CookieJar = None):
|
||||
self.resp = response
|
||||
if cookie and len(cookie) > 0:
|
||||
self.cookie = cookie
|
||||
|
||||
def body(self, encoding=DEFAULT_ENCODING):
|
||||
return self.resp.read().decode(encoding)
|
||||
|
||||
def json_body(self, encoding=DEFAULT_ENCODING):
|
||||
return json.loads(self.body(encoding))
|
||||
|
||||
def status(self):
|
||||
return self.resp.status
|
||||
|
||||
def is_ok(self):
|
||||
st_code = self.resp.status
|
||||
return 200 <= st_code <= 300
|
||||
|
||||
def header(self, name=None):
|
||||
return self.resp.getheader(name) if name else self._parse_header_dict()
|
||||
|
||||
def _parse_header_dict(self):
|
||||
headers = self.resp.getheaders()
|
||||
header_dict = {}
|
||||
if headers:
|
||||
for h in headers:
|
||||
header_dict[h[0]] = h[1]
|
||||
return header_dict
|
||||
|
||||
def is_compress(self):
|
||||
"""
|
||||
是否压缩
|
||||
:return:
|
||||
"""
|
||||
return self.compress_type() in COMPRESS_TYPE
|
||||
|
||||
def compress_type(self):
|
||||
"""
|
||||
压缩格式
|
||||
:return:
|
||||
"""
|
||||
header = self.header()
|
||||
if RESPONSE_CONTENT_ENCODING in header.keys():
|
||||
res_content_encoding = header[RESPONSE_CONTENT_ENCODING]
|
||||
return res_content_encoding
|
||||
|
||||
def cookies(self):
|
||||
"""
|
||||
获取cookie
|
||||
:return:
|
||||
"""
|
||||
ck = {}
|
||||
if self.cookie:
|
||||
for item in self.cookie:
|
||||
ck[item.name] = item.value
|
||||
return ck
|
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2023/4/2 9:07
|
||||
# @Author : old tom
|
||||
# @File : __init__.py.py
|
||||
# @Project : futool
|
||||
# @Desc : excel、word操作相关
|
@ -0,0 +1 @@
|
||||
xltpl~=0.18
|
Binary file not shown.
Loading…
Reference in new issue