ezKit 1.11.3__tar.gz → 1.11.5__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {ezkit-1.11.3/ezKit.egg-info → ezkit-1.11.5}/PKG-INFO +1 -1
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/bottle_extensions.py +3 -2
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/sendemail.py +30 -29
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/utils.py +15 -16
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/xftp.py +9 -1
- {ezkit-1.11.3 → ezkit-1.11.5/ezKit.egg-info}/PKG-INFO +1 -1
- {ezkit-1.11.3 → ezkit-1.11.5}/setup.py +1 -1
- {ezkit-1.11.3 → ezkit-1.11.5}/LICENSE +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/MANIFEST.in +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/README.md +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/__init__.py +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/_file.py +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/bottle.py +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/cipher.py +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/database.py +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/http.py +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/mongo.py +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/qywx.py +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/redis.py +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit/token.py +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit.egg-info/SOURCES.txt +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit.egg-info/dependency_links.txt +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit.egg-info/requires.txt +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/ezKit.egg-info/top_level.txt +0 -0
- {ezkit-1.11.3 → ezkit-1.11.5}/setup.cfg +0 -0
@@ -1,10 +1,11 @@
|
|
1
1
|
"""Bottle Extensions"""
|
2
|
-
from
|
2
|
+
from types import FunctionType
|
3
|
+
from typing import Any
|
3
4
|
|
4
5
|
from . import bottle, utils
|
5
6
|
|
6
7
|
|
7
|
-
def enable_cors(fn:
|
8
|
+
def enable_cors(fn: FunctionType) -> Any | None:
|
8
9
|
"""Bottle CORS"""
|
9
10
|
# 参考文档:
|
10
11
|
# - https://stackoverflow.com/a/17262900
|
@@ -6,7 +6,7 @@ from email.mime.image import MIMEImage
|
|
6
6
|
from email.mime.multipart import MIMEMultipart
|
7
7
|
from email.mime.text import MIMEText
|
8
8
|
from email.utils import formataddr, parseaddr
|
9
|
-
from typing import
|
9
|
+
from typing import TypedDict, cast
|
10
10
|
|
11
11
|
from loguru import logger
|
12
12
|
|
@@ -28,9 +28,10 @@ class TypedSender(TypedDict):
|
|
28
28
|
class TypedBody(TypedDict, total=False):
|
29
29
|
"""body type"""
|
30
30
|
content: str
|
31
|
-
type:
|
31
|
+
type: str | None # "plain", "html", or "file"
|
32
32
|
|
33
33
|
def format_parse(s):
|
34
|
+
"""格式化邮件地址"""
|
34
35
|
_name, _addr = parseaddr(s)
|
35
36
|
return formataddr((Header(_name, "utf-8").encode(), _addr))
|
36
37
|
|
@@ -42,33 +43,33 @@ def sendemail(
|
|
42
43
|
body: TypedBody,
|
43
44
|
images: None | list = None
|
44
45
|
) -> bool:
|
45
|
-
"""
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
46
|
+
"""发送邮件"""
|
47
|
+
|
48
|
+
# smtp SMTP信息
|
49
|
+
#
|
50
|
+
# server SMTP地址
|
51
|
+
# port SMTP端口
|
52
|
+
# tls 是否使用TLS
|
53
|
+
#
|
54
|
+
# sender 发件人信息
|
55
|
+
#
|
56
|
+
# name 发件人名称
|
57
|
+
# address 发件人邮箱地址
|
58
|
+
# password 发件人邮箱密码(SMTP)
|
59
|
+
#
|
60
|
+
# recipients 收件人(或列表)
|
61
|
+
#
|
62
|
+
# subject 邮件主题
|
63
|
+
#
|
64
|
+
# body 邮件主体
|
65
|
+
#
|
66
|
+
# content 内容
|
67
|
+
# type 类型 (默认 plain, 或者 file, 或者 html)
|
68
|
+
#
|
69
|
+
# images 图片列表(可选)
|
70
|
+
#
|
71
|
+
# cid 图片CID
|
72
|
+
# path 图片路径
|
72
73
|
|
73
74
|
logger.success("sendemail start")
|
74
75
|
|
@@ -7,13 +7,12 @@ import os
|
|
7
7
|
import subprocess
|
8
8
|
import time
|
9
9
|
import tomllib
|
10
|
+
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
|
10
11
|
from copy import deepcopy
|
11
12
|
from itertools import islice
|
12
|
-
from multiprocessing import Pool
|
13
|
-
from multiprocessing.pool import ThreadPool
|
14
13
|
from pathlib import Path
|
15
14
|
from shutil import rmtree
|
16
|
-
from typing import Any, Callable
|
15
|
+
from typing import Any, Callable
|
17
16
|
from urllib.parse import ParseResult, urlparse
|
18
17
|
from uuid import uuid4
|
19
18
|
|
@@ -23,7 +22,7 @@ from loguru import logger
|
|
23
22
|
|
24
23
|
|
25
24
|
# None Type
|
26
|
-
|
25
|
+
# from types import NoneType
|
27
26
|
|
28
27
|
|
29
28
|
# --------------------------------------------------------------------------------------------------
|
@@ -741,7 +740,7 @@ def parent_dir(
|
|
741
740
|
# --------------------------------------------------------------------------------------------------
|
742
741
|
|
743
742
|
|
744
|
-
def retry(func: Callable, times: int = 3, **kwargs):
|
743
|
+
def retry(func: Callable, times: int = 3, **kwargs) -> Any:
|
745
744
|
"""重试"""
|
746
745
|
|
747
746
|
# 函数传递参数: https://stackoverflow.com/a/803632
|
@@ -1005,9 +1004,9 @@ def shell(
|
|
1005
1004
|
command: str,
|
1006
1005
|
isfile: bool = False,
|
1007
1006
|
sh_shell: str = "/bin/bash",
|
1008
|
-
sh_option:
|
1007
|
+
sh_option: str | None = None,
|
1009
1008
|
**kwargs
|
1010
|
-
) ->
|
1009
|
+
) -> subprocess.CompletedProcess | None:
|
1011
1010
|
"""执行 Shell 命令 或 脚本"""
|
1012
1011
|
|
1013
1012
|
# :param command: 需要执行的命令
|
@@ -1100,7 +1099,7 @@ def json_sort(
|
|
1100
1099
|
|
1101
1100
|
|
1102
1101
|
def delete_files(
|
1103
|
-
files:
|
1102
|
+
files: str | list
|
1104
1103
|
) -> bool:
|
1105
1104
|
"""删除文件"""
|
1106
1105
|
try:
|
@@ -1132,7 +1131,7 @@ def delete_files(
|
|
1132
1131
|
|
1133
1132
|
|
1134
1133
|
def delete_directory(
|
1135
|
-
directory:
|
1134
|
+
directory: str | list,
|
1136
1135
|
) -> bool:
|
1137
1136
|
"""
|
1138
1137
|
delete directory
|
@@ -1191,11 +1190,11 @@ def delete_directory(
|
|
1191
1190
|
|
1192
1191
|
def processor(
|
1193
1192
|
process_func: Callable,
|
1194
|
-
process_data:
|
1193
|
+
process_data: list,
|
1195
1194
|
process_num: int = 2,
|
1196
1195
|
thread: bool = False,
|
1197
1196
|
**kwargs
|
1198
|
-
) ->
|
1197
|
+
) -> Any:
|
1199
1198
|
"""使用多线程或多进程对数据进行并行处理"""
|
1200
1199
|
|
1201
1200
|
# :param process_func: 处理函数
|
@@ -1225,13 +1224,13 @@ def processor(
|
|
1225
1224
|
|
1226
1225
|
# 确保并行数不超过数据量
|
1227
1226
|
process_num = min(len(process_data), process_num)
|
1228
|
-
|
1227
|
+
data_chunks = (
|
1229
1228
|
list_split(process_data, process_num, equally=True)
|
1230
1229
|
if process_num > 1
|
1231
1230
|
else [process_data]
|
1232
1231
|
)
|
1233
1232
|
|
1234
|
-
if not
|
1233
|
+
if not data_chunks:
|
1235
1234
|
logger.error("data chunks error")
|
1236
1235
|
return False
|
1237
1236
|
|
@@ -1240,9 +1239,9 @@ def processor(
|
|
1240
1239
|
)
|
1241
1240
|
|
1242
1241
|
# 执行多线程或多进程任务
|
1243
|
-
|
1244
|
-
with
|
1245
|
-
return
|
1242
|
+
pool = ThreadPoolExecutor if thread else ProcessPoolExecutor
|
1243
|
+
with pool(process_num, **kwargs) as executor:
|
1244
|
+
return executor.map(process_func, data_chunks)
|
1246
1245
|
|
1247
1246
|
except Exception as e:
|
1248
1247
|
logger.exception(e)
|
@@ -10,7 +10,15 @@ from loguru import logger
|
|
10
10
|
class XFTP:
|
11
11
|
"""XFTP"""
|
12
12
|
|
13
|
-
def __init__(
|
13
|
+
def __init__(
|
14
|
+
self,
|
15
|
+
host: str = "127.0.0.1",
|
16
|
+
port: int = 21,
|
17
|
+
username: str = "anonymous",
|
18
|
+
password: str = "",
|
19
|
+
encoding: str = "UTF-8",
|
20
|
+
debuglevel: int = 0
|
21
|
+
):
|
14
22
|
"""Initiation"""
|
15
23
|
self.ftp = FTP()
|
16
24
|
self.ftp.set_debuglevel(debuglevel)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|