tretool 0.2.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.
- tretool/__init__.py +27 -0
- tretool/config.py +262 -0
- tretool/encoding.py +92 -0
- tretool/jsonlib.py +299 -0
- tretool/markfunc.py +152 -0
- tretool/mathlib.py +620 -0
- tretool/memorizeTools.py +24 -0
- tretool/path.py +1139 -0
- tretool/platformlib.py +332 -0
- tretool/plugin/plu.py +0 -0
- tretool/plugin.py +348 -0
- tretool/timelib.py +518 -0
- tretool/transform/__init__.py +1 -0
- tretool/transform/pdf.py +396 -0
- tretool/writeLog.py +69 -0
- tretool-0.2.1.dist-info/METADATA +28 -0
- tretool-0.2.1.dist-info/RECORD +20 -0
- tretool-0.2.1.dist-info/WHEEL +5 -0
- tretool-0.2.1.dist-info/licenses/LICENSE +19 -0
- tretool-0.2.1.dist-info/top_level.txt +1 -0
tretool/transform/pdf.py
ADDED
@@ -0,0 +1,396 @@
|
|
1
|
+
import os
|
2
|
+
from abc import ABC, abstractmethod
|
3
|
+
from pathlib import Path
|
4
|
+
from typing import Union, List, Optional
|
5
|
+
from pdfminer.high_level import extract_text
|
6
|
+
from pdf2image import convert_from_path
|
7
|
+
from docx import Document
|
8
|
+
import pandas as pd
|
9
|
+
from tabula import read_pdf
|
10
|
+
from PIL import Image
|
11
|
+
import json
|
12
|
+
|
13
|
+
|
14
|
+
class ConversionError(Exception):
|
15
|
+
"""自定义转换异常"""
|
16
|
+
pass
|
17
|
+
|
18
|
+
|
19
|
+
class PDFConverter(ABC):
|
20
|
+
def __init__(self, pdf_path: Union[str, Path]):
|
21
|
+
"""
|
22
|
+
初始化PDF转换器
|
23
|
+
|
24
|
+
参数:
|
25
|
+
pdf_path: PDF文件路径
|
26
|
+
"""
|
27
|
+
self.pdf_path = Path(pdf_path)
|
28
|
+
if not self.pdf_path.exists():
|
29
|
+
raise FileNotFoundError(f"PDF文件不存在: {pdf_path}")
|
30
|
+
if self.pdf_path.suffix.lower() != '.pdf':
|
31
|
+
raise ValueError("输入文件必须是PDF格式")
|
32
|
+
|
33
|
+
@abstractmethod
|
34
|
+
def convert(self, output_path: Union[str, Path], **kwargs):
|
35
|
+
"""
|
36
|
+
将PDF转换为目标格式
|
37
|
+
|
38
|
+
参数:
|
39
|
+
output_path: 输出文件路径
|
40
|
+
**kwargs: 转换选项
|
41
|
+
"""
|
42
|
+
pass
|
43
|
+
|
44
|
+
@classmethod
|
45
|
+
@abstractmethod
|
46
|
+
def supported_formats(cls) -> List[str]:
|
47
|
+
"""返回支持的格式列表"""
|
48
|
+
return []
|
49
|
+
|
50
|
+
def _prepare_output_path(self, output_path: Union[str, Path],
|
51
|
+
default_extension: str) -> Path:
|
52
|
+
"""
|
53
|
+
准备输出路径
|
54
|
+
|
55
|
+
参数:
|
56
|
+
output_path: 输出路径
|
57
|
+
default_extension: 默认文件扩展名
|
58
|
+
|
59
|
+
返回:
|
60
|
+
处理后的Path对象
|
61
|
+
"""
|
62
|
+
output_path = Path(output_path)
|
63
|
+
|
64
|
+
# 如果是目录,自动生成文件名
|
65
|
+
if output_path.is_dir():
|
66
|
+
output_path = output_path / f"{self.pdf_path.stem}.{default_extension}"
|
67
|
+
# 如果没有扩展名,添加默认扩展名
|
68
|
+
elif not output_path.suffix:
|
69
|
+
output_path = output_path.with_suffix(f".{default_extension}")
|
70
|
+
|
71
|
+
# 创建父目录(如果不存在)
|
72
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
73
|
+
|
74
|
+
return output_path
|
75
|
+
|
76
|
+
|
77
|
+
class PDFToDocxConverter(PDFConverter):
|
78
|
+
def convert(self, output_path: Union[str, Path], **kwargs):
|
79
|
+
"""
|
80
|
+
将PDF转换为Word文档(.docx)
|
81
|
+
|
82
|
+
参数:
|
83
|
+
output_path: 输出文件路径
|
84
|
+
**kwargs:
|
85
|
+
- start_page: 开始页(从1开始)
|
86
|
+
- end_page: 结束页
|
87
|
+
- preserve_formatting: 是否保留格式(True/False)
|
88
|
+
"""
|
89
|
+
try:
|
90
|
+
output_path = self._prepare_output_path(output_path, 'docx')
|
91
|
+
|
92
|
+
start_page = kwargs.get('start_page', 1)
|
93
|
+
end_page = kwargs.get('end_page', None)
|
94
|
+
preserve = kwargs.get('preserve_formatting', False)
|
95
|
+
|
96
|
+
doc = Document()
|
97
|
+
text = extract_text(
|
98
|
+
str(self.pdf_path),
|
99
|
+
page_numbers=range(start_page-1, end_page) if end_page else None
|
100
|
+
)
|
101
|
+
|
102
|
+
# 简单的段落处理
|
103
|
+
for paragraph in text.split('\n\n'):
|
104
|
+
if paragraph.strip():
|
105
|
+
para = doc.add_paragraph()
|
106
|
+
if preserve:
|
107
|
+
# 这里可以添加更复杂的格式保留逻辑
|
108
|
+
runs = paragraph.split('\n')
|
109
|
+
for run in runs:
|
110
|
+
if run.strip():
|
111
|
+
para.add_run(run.strip() + ' ')
|
112
|
+
else:
|
113
|
+
para.add_run(paragraph.strip())
|
114
|
+
|
115
|
+
doc.save(output_path)
|
116
|
+
return str(output_path)
|
117
|
+
except Exception as e:
|
118
|
+
raise ConversionError(f"转换为DOCX失败: {str(e)}")
|
119
|
+
|
120
|
+
@classmethod
|
121
|
+
def supported_formats(cls) -> List[str]:
|
122
|
+
return ['docx']
|
123
|
+
|
124
|
+
|
125
|
+
class PDFToImageConverter(PDFConverter):
|
126
|
+
def convert(self, output_path: Union[str, Path], **kwargs):
|
127
|
+
"""
|
128
|
+
将PDF转换为图像
|
129
|
+
|
130
|
+
参数:
|
131
|
+
output_path: 输出文件路径或目录
|
132
|
+
**kwargs:
|
133
|
+
- dpi: 图像DPI(默认200)
|
134
|
+
- fmt: 图像格式(png/jpg/tiff)
|
135
|
+
- merge: 是否合并所有页为一张长图(True/False)
|
136
|
+
- quality: 图像质量(1-100)
|
137
|
+
"""
|
138
|
+
try:
|
139
|
+
dpi = kwargs.get('dpi', 200)
|
140
|
+
fmt = kwargs.get('fmt', 'png').lower()
|
141
|
+
merge = kwargs.get('merge', False)
|
142
|
+
quality = kwargs.get('quality', 90)
|
143
|
+
|
144
|
+
if fmt not in ['png', 'jpg', 'jpeg', 'tiff']:
|
145
|
+
raise ValueError(f"不支持的图像格式: {fmt}")
|
146
|
+
|
147
|
+
images = convert_from_path(
|
148
|
+
str(self.pdf_path),
|
149
|
+
dpi=dpi,
|
150
|
+
fmt=fmt if fmt != 'jpg' else 'jpeg'
|
151
|
+
)
|
152
|
+
|
153
|
+
if merge:
|
154
|
+
# 合并所有页为一张长图
|
155
|
+
output_path = self._prepare_output_path(output_path, fmt)
|
156
|
+
total_height = sum(img.height for img in images)
|
157
|
+
max_width = max(img.width for img in images)
|
158
|
+
|
159
|
+
merged_image = Image.new('RGB', (max_width, total_height))
|
160
|
+
y_offset = 0
|
161
|
+
for img in images:
|
162
|
+
merged_image.paste(img, (0, y_offset))
|
163
|
+
y_offset += img.height
|
164
|
+
|
165
|
+
merged_image.save(output_path, quality=quality)
|
166
|
+
return str(output_path)
|
167
|
+
else:
|
168
|
+
# 每页保存为单独图像
|
169
|
+
output_path = Path(output_path)
|
170
|
+
if len(images) == 1:
|
171
|
+
output_path = self._prepare_output_path(output_path, fmt)
|
172
|
+
images[0].save(output_path, quality=quality)
|
173
|
+
return str(output_path)
|
174
|
+
else:
|
175
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
176
|
+
output_files = []
|
177
|
+
for i, image in enumerate(images):
|
178
|
+
page_path = output_path / f"page_{i+1}.{fmt}"
|
179
|
+
image.save(page_path, quality=quality)
|
180
|
+
output_files.append(str(page_path))
|
181
|
+
return output_files
|
182
|
+
except Exception as e:
|
183
|
+
raise ConversionError(f"转换为图像失败: {str(e)}")
|
184
|
+
|
185
|
+
@classmethod
|
186
|
+
def supported_formats(cls) -> List[str]:
|
187
|
+
return ['png', 'jpg', 'jpeg', 'tiff']
|
188
|
+
|
189
|
+
|
190
|
+
class PDFToTextConverter(PDFConverter):
|
191
|
+
def convert(self, output_path: Union[str, Path], **kwargs):
|
192
|
+
"""
|
193
|
+
将PDF转换为纯文本
|
194
|
+
|
195
|
+
参数:
|
196
|
+
output_path: 输出文件路径
|
197
|
+
**kwargs:
|
198
|
+
- start_page: 开始页(从1开始)
|
199
|
+
- end_page: 结束页
|
200
|
+
- encoding: 文本编码(默认utf-8)
|
201
|
+
"""
|
202
|
+
try:
|
203
|
+
output_path = self._prepare_output_path(output_path, 'txt')
|
204
|
+
|
205
|
+
start_page = kwargs.get('start_page', 1)
|
206
|
+
end_page = kwargs.get('end_page', None)
|
207
|
+
encoding = kwargs.get('encoding', 'utf-8')
|
208
|
+
|
209
|
+
text = extract_text(
|
210
|
+
str(self.pdf_path),
|
211
|
+
page_numbers=range(start_page-1, end_page) if end_page else None
|
212
|
+
)
|
213
|
+
|
214
|
+
with open(output_path, 'w', encoding=encoding) as f:
|
215
|
+
f.write(text)
|
216
|
+
|
217
|
+
return str(output_path)
|
218
|
+
except Exception as e:
|
219
|
+
raise ConversionError(f"转换为文本失败: {str(e)}")
|
220
|
+
|
221
|
+
@classmethod
|
222
|
+
def supported_formats(cls) -> List[str]:
|
223
|
+
return ['txt']
|
224
|
+
|
225
|
+
|
226
|
+
class PDFToCSVConverter(PDFConverter):
|
227
|
+
def convert(self, output_path: Union[str, Path], **kwargs):
|
228
|
+
"""
|
229
|
+
提取PDF中的表格为CSV
|
230
|
+
|
231
|
+
参数:
|
232
|
+
output_path: 输出文件路径或目录
|
233
|
+
**kwargs:
|
234
|
+
- pages: 要提取的页码('all'或数字或列表)
|
235
|
+
- multiple_tables: 如何处理多个表格(separate/merge)
|
236
|
+
- encoding: CSV文件编码(默认utf-8)
|
237
|
+
"""
|
238
|
+
try:
|
239
|
+
pages = kwargs.get('pages', 'all')
|
240
|
+
multiple_tables = kwargs.get('multiple_tables', 'separate')
|
241
|
+
encoding = kwargs.get('encoding', 'utf-8')
|
242
|
+
|
243
|
+
dfs = read_pdf(str(self.pdf_path), pages=pages, multiple_tables=True)
|
244
|
+
|
245
|
+
if not dfs:
|
246
|
+
raise ConversionError("未找到表格数据")
|
247
|
+
|
248
|
+
if multiple_tables == 'merge':
|
249
|
+
# 合并所有表格
|
250
|
+
output_path = self._prepare_output_path(output_path, 'csv')
|
251
|
+
merged_df = pd.concat(dfs, ignore_index=True)
|
252
|
+
merged_df.to_csv(output_path, index=False, encoding=encoding)
|
253
|
+
return str(output_path)
|
254
|
+
else:
|
255
|
+
# 每个表格保存为单独CSV
|
256
|
+
output_path = Path(output_path)
|
257
|
+
if len(dfs) == 1:
|
258
|
+
output_path = self._prepare_output_path(output_path, 'csv')
|
259
|
+
dfs[0].to_csv(output_path, index=False, encoding=encoding)
|
260
|
+
return str(output_path)
|
261
|
+
else:
|
262
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
263
|
+
output_files = []
|
264
|
+
for i, df in enumerate(dfs):
|
265
|
+
table_path = output_path / f"table_{i+1}.csv"
|
266
|
+
df.to_csv(table_path, index=False, encoding=encoding)
|
267
|
+
output_files.append(str(table_path))
|
268
|
+
return output_files
|
269
|
+
except Exception as e:
|
270
|
+
raise ConversionError(f"提取表格失败: {str(e)}")
|
271
|
+
|
272
|
+
@classmethod
|
273
|
+
def supported_formats(cls) -> List[str]:
|
274
|
+
return ['csv']
|
275
|
+
|
276
|
+
|
277
|
+
class PDFToHTMLConverter(PDFConverter):
|
278
|
+
def convert(self, output_path: Union[str, Path], **kwargs):
|
279
|
+
"""
|
280
|
+
将PDF转换为HTML
|
281
|
+
|
282
|
+
参数:
|
283
|
+
output_path: 输出文件路径
|
284
|
+
**kwargs:
|
285
|
+
- css: 自定义CSS样式
|
286
|
+
- images: 是否嵌入图像(True/False)
|
287
|
+
"""
|
288
|
+
try:
|
289
|
+
output_path = self._prepare_output_path(output_path, 'html')
|
290
|
+
|
291
|
+
# 使用pdfminer提取文本
|
292
|
+
text = extract_text(str(self.pdf_path))
|
293
|
+
|
294
|
+
# 简单的HTML转换
|
295
|
+
html_content = f"""<!DOCTYPE html>
|
296
|
+
<html>
|
297
|
+
<head>
|
298
|
+
<meta charset="UTF-8">
|
299
|
+
<title>{self.pdf_path.stem}</title>
|
300
|
+
<style>
|
301
|
+
{kwargs.get('css', 'body { font-family: Arial; margin: 20px; }')}
|
302
|
+
</style>
|
303
|
+
</head>
|
304
|
+
<body>
|
305
|
+
<h1>{self.pdf_path.stem}</h1>
|
306
|
+
<div id="content">
|
307
|
+
{text.replace('\n', '<br>')}
|
308
|
+
</div>
|
309
|
+
</body>
|
310
|
+
</html>"""
|
311
|
+
|
312
|
+
with open(output_path, 'w', encoding='utf-8') as f:
|
313
|
+
f.write(html_content)
|
314
|
+
|
315
|
+
return str(output_path)
|
316
|
+
except Exception as e:
|
317
|
+
raise ConversionError(f"转换为HTML失败: {str(e)}")
|
318
|
+
|
319
|
+
@classmethod
|
320
|
+
def supported_formats(cls) -> List[str]:
|
321
|
+
return ['html']
|
322
|
+
|
323
|
+
|
324
|
+
class PDFConverterFactory:
|
325
|
+
@staticmethod
|
326
|
+
def get_converter(target_format: str, pdf_path: str) -> PDFConverter:
|
327
|
+
"""
|
328
|
+
获取指定格式的转换器
|
329
|
+
|
330
|
+
参数:
|
331
|
+
target_format: 目标格式
|
332
|
+
pdf_path: PDF文件路径
|
333
|
+
|
334
|
+
返回:
|
335
|
+
PDFConverter实例
|
336
|
+
"""
|
337
|
+
format_map = {
|
338
|
+
'docx': PDFToDocxConverter,
|
339
|
+
'txt': PDFToTextConverter,
|
340
|
+
'png': PDFToImageConverter,
|
341
|
+
'jpg': PDFToImageConverter,
|
342
|
+
'jpeg': PDFToImageConverter,
|
343
|
+
'tiff': PDFToImageConverter,
|
344
|
+
'csv': PDFToCSVConverter,
|
345
|
+
'html': PDFToHTMLConverter,
|
346
|
+
}
|
347
|
+
|
348
|
+
target_format = target_format.lower()
|
349
|
+
if target_format not in format_map:
|
350
|
+
raise ValueError(f"不支持的格式: {target_format}")
|
351
|
+
|
352
|
+
return format_map[target_format](pdf_path)
|
353
|
+
|
354
|
+
@staticmethod
|
355
|
+
def get_supported_formats() -> dict:
|
356
|
+
"""获取所有支持的格式"""
|
357
|
+
return {
|
358
|
+
'docx': 'Microsoft Word文档',
|
359
|
+
'txt': '纯文本文件',
|
360
|
+
'png': 'PNG图像',
|
361
|
+
'jpg': 'JPEG图像',
|
362
|
+
'jpeg': 'JPEG图像',
|
363
|
+
'tiff': 'TIFF图像',
|
364
|
+
'csv': 'CSV表格数据',
|
365
|
+
'html': 'HTML网页',
|
366
|
+
}
|
367
|
+
|
368
|
+
|
369
|
+
# 使用示例
|
370
|
+
if __name__ == "__main__":
|
371
|
+
try:
|
372
|
+
# 示例1: PDF转Word
|
373
|
+
print("转换PDF到Word...")
|
374
|
+
docx_converter = PDFConverterFactory.get_converter('docx', 'example.pdf')
|
375
|
+
result = docx_converter.convert('output.docx', preserve_formatting=True)
|
376
|
+
print(f"转换成功: {result}")
|
377
|
+
|
378
|
+
# 示例2: PDF转图像
|
379
|
+
print("\n转换PDF到图像...")
|
380
|
+
img_converter = PDFConverterFactory.get_converter('png', 'example.pdf')
|
381
|
+
result = img_converter.convert('output_images', dpi=300)
|
382
|
+
print(f"转换成功: {result if isinstance(result, str) else len(result)}个文件")
|
383
|
+
|
384
|
+
# 示例3: 提取表格数据
|
385
|
+
print("\n提取PDF中的表格...")
|
386
|
+
csv_converter = PDFConverterFactory.get_converter('csv', 'example.pdf')
|
387
|
+
result = csv_converter.convert('output_tables', pages='all')
|
388
|
+
print(f"提取成功: {result if isinstance(result, str) else len(result)}个表格")
|
389
|
+
|
390
|
+
# 查看所有支持的格式
|
391
|
+
print("\n支持的转换格式:")
|
392
|
+
for fmt, desc in PDFConverterFactory.get_supported_formats().items():
|
393
|
+
print(f"- {fmt}: {desc}")
|
394
|
+
|
395
|
+
except Exception as e:
|
396
|
+
print(f"发生错误: {str(e)}")
|
tretool/writeLog.py
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
import sys
|
2
|
+
import datetime
|
3
|
+
import traceback
|
4
|
+
|
5
|
+
from typing import Tuple
|
6
|
+
|
7
|
+
class LogWriter:
|
8
|
+
def __init__(self) -> None:
|
9
|
+
self.log = []
|
10
|
+
|
11
|
+
|
12
|
+
def save_file(self, filepath:str) -> Tuple[bool, str]:
|
13
|
+
try:
|
14
|
+
with open(filepath, 'w', encoding='utf-8') as file:
|
15
|
+
file.write('\n'.join(self.log))
|
16
|
+
return (True, 'No error')
|
17
|
+
except Exception as e:
|
18
|
+
return (False, str(e))
|
19
|
+
|
20
|
+
|
21
|
+
def write_debug(self, content:str, user:str='root', time:str=None):
|
22
|
+
if time is None:
|
23
|
+
time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
24
|
+
|
25
|
+
self.log.append(f'[{time}] (debug) {user}: {content}')
|
26
|
+
|
27
|
+
|
28
|
+
def write_info(self, content:str, user:str='root', time:str=None):
|
29
|
+
if time is None:
|
30
|
+
time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
31
|
+
|
32
|
+
self.log.append(f'[{time}] (info) {user}: {content}')
|
33
|
+
|
34
|
+
|
35
|
+
def write_warning(self, content:str, user:str='root', time:str=None):
|
36
|
+
if time is None:
|
37
|
+
time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
38
|
+
|
39
|
+
self.log.append(f'[{time}] (warning) {user}: {content}')
|
40
|
+
|
41
|
+
|
42
|
+
def write_error(self, content:str, user:str='root', time:str=None):
|
43
|
+
if time is None:
|
44
|
+
time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
45
|
+
|
46
|
+
self.log.append(f'[{time}] (error) {user}: {content}')
|
47
|
+
|
48
|
+
|
49
|
+
def write_traceback(self, user: str = 'root', time: str = None):
|
50
|
+
"""捕获当前异常信息并写入日志"""
|
51
|
+
if time is None:
|
52
|
+
time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
53
|
+
|
54
|
+
# 获取当前异常信息
|
55
|
+
exc_type, exc_value, exc_traceback = sys.exc_info()
|
56
|
+
if exc_type is None: # 如果没有异常,直接返回
|
57
|
+
return
|
58
|
+
|
59
|
+
# 格式化 traceback 信息
|
60
|
+
tb_lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
|
61
|
+
tb_content = ''.join(tb_lines).strip() # 将 traceback 转为字符串
|
62
|
+
|
63
|
+
# 写入日志
|
64
|
+
self.log.append(f'[{time}] {user}: [EXCEPTION]\n{tb_content}')
|
65
|
+
|
66
|
+
|
67
|
+
@property
|
68
|
+
def log_content(self):
|
69
|
+
return self.log
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: tretool
|
3
|
+
Version: 0.2.1
|
4
|
+
Summary: 一个有着许多功能的Python工具库
|
5
|
+
Author-email: Jemy <sh_ljr_2013@163.com>
|
6
|
+
License-Expression: MIT
|
7
|
+
Project-URL: Homepage, https://github.com/pypa/sampleproject
|
8
|
+
Project-URL: Issues, https://github.com/pypa/sampleproject/issues
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
10
|
+
Classifier: Operating System :: OS Independent
|
11
|
+
Requires-Python: >=3.10
|
12
|
+
Description-Content-Type: text/markdown
|
13
|
+
License-File: LICENSE
|
14
|
+
Dynamic: license-file
|
15
|
+
|
16
|
+
# tretool
|
17
|
+
|
18
|
+
## tretool - Python多功能工具库
|
19
|
+
|
20
|
+
[](https://www.python.org/)
|
21
|
+
|
22
|
+
**tretool** 是一个集成常用功能的Python工具库。
|
23
|
+
|
24
|
+
## 📦 安装
|
25
|
+
|
26
|
+
### 使用pip
|
27
|
+
bash
|
28
|
+
```pip install tretool
|
@@ -0,0 +1,20 @@
|
|
1
|
+
tretool/__init__.py,sha256=g8doPxAxYQEDb6JTP8KVCuvN0eXlNTT2yS7hodLbKOA,498
|
2
|
+
tretool/config.py,sha256=nWGKFfQbpihFCeVejiyhQ1dpxcw4EC0biAJtkvQRILc,8179
|
3
|
+
tretool/encoding.py,sha256=bED_2D1TXcH0Z7AbBqfeVWrlH7ER99-SngaNi-vlMow,2735
|
4
|
+
tretool/jsonlib.py,sha256=tR51UJg9q_pPdmryoPsdjnuAPun6UESDMyD4Uv4lzMg,9808
|
5
|
+
tretool/markfunc.py,sha256=vv9tdfwRX9MosvFdRFkf-oOysyK6HgFE3UzuYnp0Pc8,5298
|
6
|
+
tretool/mathlib.py,sha256=Lz6UkZM5Gf3x_4RWVRtNiIxLAcQ_Y72h_aGYAVref8g,19696
|
7
|
+
tretool/memorizeTools.py,sha256=OBTV4XHdInduA8O1mUGpP4tE4Ze1h5FqZbPOVDm3s3I,466
|
8
|
+
tretool/path.py,sha256=eEmJL33MiYK3X1n74Jc98YqH3SDOJ09KDnlBCFFaVII,31910
|
9
|
+
tretool/platformlib.py,sha256=XDWo7kf9zwGguFK77yG3T_R4tc-unjdM3dbUA6rZ29o,9727
|
10
|
+
tretool/plugin.py,sha256=OcOmXCrzhiyOjSDSx3lqykJqpyLtbRMOBpEZBz3sUXY,13182
|
11
|
+
tretool/timelib.py,sha256=XH1o8WDoj4W41vO-AuRV782d6IuqvmcCuKEkdabHsjg,16559
|
12
|
+
tretool/writeLog.py,sha256=l-7BtOGCFk1DZNyPI5Vw_EdC_NbgfwKGpHWbdL8Pi9c,2251
|
13
|
+
tretool/plugin/plu.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
+
tretool/transform/__init__.py,sha256=-0UKgEwky5AAV_UNGSRdKhYbrkAjUHZIO4Lj0z-ITPE,17
|
15
|
+
tretool/transform/pdf.py,sha256=yP__RWZvZt5FmfKubT7Tw1oDf1dKNLi43mB05w2n9z4,14156
|
16
|
+
tretool-0.2.1.dist-info/licenses/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
17
|
+
tretool-0.2.1.dist-info/METADATA,sha256=48L-GCSmZCvG6VCnSTkkQ1xIy4NScYD-5CiTZ7YlI_0,792
|
18
|
+
tretool-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
19
|
+
tretool-0.2.1.dist-info/top_level.txt,sha256=0kbUVnSHjYxSRD1ziCdpw73ECdl7QysxeNHlRuY9xtc,8
|
20
|
+
tretool-0.2.1.dist-info/RECORD,,
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2018 The Python Packaging Authority
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
@@ -0,0 +1 @@
|
|
1
|
+
tretool
|