ezKit 1.7.7__py3-none-any.whl → 1.8.0__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.
- ezKit/__init__.py +0 -1
- ezKit/bottle.py +7 -2
- ezKit/bottle_extensions.py +14 -18
- ezKit/cipher.py +11 -10
- ezKit/database.py +109 -73
- ezKit/http.py +21 -22
- ezKit/mongo.py +24 -21
- ezKit/redis.py +19 -16
- ezKit/sendemail.py +1 -10
- ezKit/token.py +11 -12
- ezKit/utils.py +8 -6
- ezKit/xftp.py +2 -2
- {ezKit-1.7.7.dist-info → ezKit-1.8.0.dist-info}/METADATA +1 -1
- ezKit-1.8.0.dist-info/RECORD +17 -0
- ezKit/files.py +0 -348
- ezKit/plots.py +0 -155
- ezKit/qywx.py +0 -173
- ezKit/reports.py +0 -274
- ezKit/zabbix.py +0 -737
- ezKit-1.7.7.dist-info/RECORD +0 -22
- {ezKit-1.7.7.dist-info → ezKit-1.8.0.dist-info}/LICENSE +0 -0
- {ezKit-1.7.7.dist-info → ezKit-1.8.0.dist-info}/WHEEL +0 -0
- {ezKit-1.7.7.dist-info → ezKit-1.8.0.dist-info}/top_level.txt +0 -0
ezKit/__init__.py
CHANGED
@@ -1 +0,0 @@
|
|
1
|
-
# from . import bottle, database, files, plots, utils, weixin, zabbix
|
ezKit/bottle.py
CHANGED
@@ -17,7 +17,7 @@ from __future__ import print_function
|
|
17
17
|
import sys
|
18
18
|
|
19
19
|
__author__ = 'Marcel Hellkamp'
|
20
|
-
__version__ = '0.13.
|
20
|
+
__version__ = '0.13.2'
|
21
21
|
__license__ = 'MIT'
|
22
22
|
|
23
23
|
###############################################################################
|
@@ -185,6 +185,7 @@ def depr(major, minor, cause, fix, stacklevel=3):
|
|
185
185
|
if DEBUG == 'strict':
|
186
186
|
raise DeprecationWarning(text)
|
187
187
|
warnings.warn(text, DeprecationWarning, stacklevel=stacklevel)
|
188
|
+
return DeprecationWarning(text)
|
188
189
|
|
189
190
|
|
190
191
|
def makelist(data): # This is just too handy
|
@@ -4671,5 +4672,9 @@ def _main(argv): # pragma: no coverage
|
|
4671
4672
|
config=config)
|
4672
4673
|
|
4673
4674
|
|
4674
|
-
|
4675
|
+
def main():
|
4675
4676
|
_main(sys.argv)
|
4677
|
+
|
4678
|
+
|
4679
|
+
if __name__ == '__main__': # pragma: no coverage
|
4680
|
+
main()
|
ezKit/bottle_extensions.py
CHANGED
@@ -1,36 +1,32 @@
|
|
1
|
+
"""Bottle Extensions"""
|
1
2
|
from typing import Callable
|
2
3
|
|
3
4
|
from . import bottle, utils
|
4
5
|
|
5
6
|
|
6
7
|
def enable_cors(fn: Callable) -> Callable:
|
7
|
-
"""
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
- https://
|
13
|
-
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
|
14
|
-
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
|
15
|
-
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
|
16
|
-
"""
|
8
|
+
"""Bottle CORS"""
|
9
|
+
# 参考文档:
|
10
|
+
# - https://stackoverflow.com/a/17262900
|
11
|
+
# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
|
12
|
+
# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
|
13
|
+
# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
|
17
14
|
def cors(*args, **kwargs):
|
18
15
|
bottle.response.headers['Access-Control-Allow-Headers'] = '*'
|
19
16
|
bottle.response.headers['Access-Control-Allow-Methods'] = '*'
|
20
17
|
bottle.response.headers['Access-Control-Allow-Origin'] = '*'
|
21
18
|
if bottle.request.method != 'OPTIONS':
|
22
19
|
return fn(*args, **kwargs)
|
20
|
+
return None
|
23
21
|
return cors
|
24
22
|
|
25
|
-
def request_json() ->
|
26
|
-
"""
|
27
|
-
Bottle Request JSON
|
28
|
-
"""
|
23
|
+
def request_json() -> bottle.DictProperty | None:
|
24
|
+
"""Bottle Request JSON"""
|
29
25
|
try:
|
30
|
-
data
|
26
|
+
data = bottle.request.json
|
31
27
|
if utils.v_true(data, dict):
|
32
28
|
return data
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
return None
|
30
|
+
except Exception as e:
|
31
|
+
print(e)
|
36
32
|
return None
|
ezKit/cipher.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
|
1
|
+
"""
|
2
2
|
https://docs.python.org/3.10/library/hashlib.html
|
3
3
|
https://www.pycrypto.org/
|
4
4
|
https://stackoverflow.com/a/21928790
|
5
5
|
pip install pycryptodome
|
6
|
-
|
6
|
+
"""
|
7
7
|
import base64
|
8
8
|
import hashlib
|
9
9
|
|
@@ -12,7 +12,8 @@ from Crypto.Cipher import AES
|
|
12
12
|
from loguru import logger
|
13
13
|
|
14
14
|
|
15
|
-
class AESCipher
|
15
|
+
class AESCipher:
|
16
|
+
"""AESCipher"""
|
16
17
|
|
17
18
|
def __init__(self, key: str = 'vB7DoRm9C2Kd', algorithm: str = 'sha256'):
|
18
19
|
|
@@ -40,10 +41,10 @@ class AESCipher(object):
|
|
40
41
|
self.key = hashlib.sha3_384(key.encode()).digest()
|
41
42
|
case True if algorithm == 'sha3_512':
|
42
43
|
self.key = hashlib.sha3_512(key.encode()).digest()
|
43
|
-
case True if algorithm == 'shake_128':
|
44
|
-
|
45
|
-
case True if algorithm == 'shake_256':
|
46
|
-
|
44
|
+
# case True if algorithm == 'shake_128':
|
45
|
+
# self.key = hashlib.shake_128(key.encode()).digest()
|
46
|
+
# case True if algorithm == 'shake_256':
|
47
|
+
# self.key = hashlib.shake_256(key.encode()).digest()
|
47
48
|
case _:
|
48
49
|
self.key = hashlib.sha256(key.encode()).digest()
|
49
50
|
|
@@ -59,10 +60,10 @@ class AESCipher(object):
|
|
59
60
|
|
60
61
|
def decrypt(self, enc: str) -> str | None:
|
61
62
|
try:
|
62
|
-
|
63
|
-
iv =
|
63
|
+
enc_bytes = base64.b64decode(enc)
|
64
|
+
iv = enc_bytes[:AES.block_size]
|
64
65
|
cipher = AES.new(self.key, AES.MODE_CBC, iv)
|
65
|
-
return self._unpad(cipher.decrypt(
|
66
|
+
return self._unpad(cipher.decrypt(enc_bytes[AES.block_size:])).decode('utf-8')
|
66
67
|
except Exception as e:
|
67
68
|
logger.exception(e)
|
68
69
|
return None
|
ezKit/database.py
CHANGED
@@ -1,168 +1,204 @@
|
|
1
|
-
|
1
|
+
"""
|
2
2
|
Column, Table, MetaData API
|
3
3
|
https://docs.sqlalchemy.org/en/14/core/metadata.html#column-table-metadata-api
|
4
4
|
CursorResult
|
5
5
|
https://docs.sqlalchemy.org/en/20/core/connections.html#sqlalchemy.engine.CursorResult
|
6
6
|
PostgreSQL 14 Data Types
|
7
7
|
https://www.postgresql.org/docs/14/datatype.html
|
8
|
-
|
8
|
+
"""
|
9
9
|
import csv
|
10
|
+
from typing import Any
|
10
11
|
|
11
12
|
from loguru import logger
|
12
|
-
from sqlalchemy import Index, create_engine, text
|
13
|
+
from sqlalchemy import CursorResult, Index, create_engine, text
|
13
14
|
|
14
15
|
from . import utils
|
15
16
|
|
16
17
|
|
17
|
-
class Database(
|
18
|
+
class Database():
|
19
|
+
"""Database"""
|
18
20
|
|
19
21
|
engine = create_engine('sqlite://')
|
20
22
|
|
21
|
-
def __init__(self, engine_url
|
22
|
-
|
23
|
-
if engine_url
|
23
|
+
def __init__(self, engine_url, **engine_options):
|
24
|
+
"""Initiation"""
|
25
|
+
if engine_url is not None and utils.v_true(engine_url, str):
|
24
26
|
if utils.v_true(engine_options, dict):
|
25
27
|
self.engine = create_engine(engine_url, **engine_options)
|
26
28
|
else:
|
27
29
|
self.engine = create_engine(engine_url)
|
30
|
+
else:
|
31
|
+
pass
|
28
32
|
|
29
33
|
def initializer(self):
|
30
|
-
|
34
|
+
"""ensure the parent proc's database connections are not touched in the new connection pool"""
|
31
35
|
self.engine.dispose(close=False)
|
32
36
|
|
33
|
-
def connect_test(self):
|
34
|
-
info =
|
37
|
+
def connect_test(self) -> bool:
|
38
|
+
info = "Database connect test"
|
35
39
|
try:
|
36
|
-
logger.info(f
|
40
|
+
logger.info(f"{info} ......")
|
37
41
|
self.engine.connect()
|
38
|
-
logger.success(f
|
42
|
+
logger.success(f"{info} [success]")
|
39
43
|
return True
|
40
44
|
except Exception as e:
|
41
|
-
logger.error(f
|
45
|
+
logger.error(f"{info} [failure]")
|
42
46
|
logger.exception(e)
|
43
47
|
return False
|
44
48
|
|
45
|
-
def metadata_init(self, base, **kwargs):
|
49
|
+
def metadata_init(self, base, **kwargs) -> bool:
|
46
50
|
# https://stackoverflow.com/questions/19175311/how-to-create-only-one-table-with-sqlalchemy
|
47
|
-
info =
|
51
|
+
info = "Database init table"
|
48
52
|
try:
|
49
|
-
logger.info(f
|
53
|
+
logger.info(f"{info} ......")
|
50
54
|
base.metadata.drop_all(self.engine, **kwargs)
|
51
55
|
base.metadata.create_all(self.engine, **kwargs)
|
52
|
-
logger.success(f
|
56
|
+
logger.success(f"{info} [success]")
|
53
57
|
return True
|
54
58
|
except Exception as e:
|
55
|
-
logger.error(f
|
59
|
+
logger.error(f"{info} [failure]")
|
56
60
|
logger.exception(e)
|
57
61
|
return False
|
58
62
|
|
59
|
-
def create_index(self, index_name, table_field):
|
63
|
+
def create_index(self, index_name, table_field) -> bool:
|
60
64
|
# 创建索引
|
61
65
|
# https://stackoverflow.com/a/41254430
|
62
66
|
# 示例:
|
63
67
|
# index_name: a_share_list_code_idx1
|
64
68
|
# table_field: Table_a_share_list.code
|
65
|
-
info =
|
69
|
+
info = "Database create index"
|
66
70
|
try:
|
67
|
-
logger.info(f
|
71
|
+
logger.info(f"{info} ......")
|
68
72
|
idx = Index(index_name, table_field)
|
69
73
|
try:
|
70
74
|
idx.drop(bind=self.engine)
|
71
|
-
except:
|
72
|
-
|
75
|
+
except Exception as e:
|
76
|
+
logger.exception(e)
|
73
77
|
idx.create(bind=self.engine)
|
74
|
-
logger.success(f'{info}[
|
78
|
+
logger.success(f'{info} [success]')
|
75
79
|
return True
|
76
80
|
except Exception as e:
|
77
|
-
logger.error(f'{info}[
|
81
|
+
logger.error(f'{info} [failure]')
|
78
82
|
logger.error(e)
|
79
83
|
return False
|
80
84
|
|
81
85
|
# 私有函数, 保存 execute 的结果到 CSV 文件
|
82
|
-
def _result_save(self, file, data
|
86
|
+
def _result_save(self, file, data) -> bool:
|
83
87
|
try:
|
84
88
|
outcsv = csv.writer(file)
|
85
89
|
outcsv.writerow(data.keys())
|
86
90
|
outcsv.writerows(data)
|
87
91
|
return True
|
88
92
|
except Exception as e:
|
89
|
-
logger.exception(e)
|
93
|
+
logger.exception(e)
|
90
94
|
return False
|
91
95
|
|
92
|
-
def execute(
|
93
|
-
|
96
|
+
def execute(
|
97
|
+
self,
|
98
|
+
sql: str | None = None,
|
99
|
+
sql_file: str | None = None,
|
100
|
+
sql_file_kwargs: dict | None = None,
|
101
|
+
csv_file: str | None = None,
|
102
|
+
csv_file_kwargs: dict | None = None
|
103
|
+
) -> CursorResult[Any] | bool:
|
104
|
+
"""
|
94
105
|
echo 是否打印日志
|
95
106
|
某些情况下只需要结果, 不需要日志, 将 echo 设置为 False 即可
|
96
|
-
|
107
|
+
"""
|
97
108
|
|
98
|
-
info_prefix = '[
|
109
|
+
# info_prefix = '[Execute SQL]'
|
99
110
|
|
100
111
|
# ------------------------------------------------------------
|
101
112
|
|
102
113
|
# 提取 SQL
|
103
114
|
# 如果 sql 和 sql_file 同时存在, 优先执行 sql
|
104
115
|
sql_object = None
|
105
|
-
info =
|
116
|
+
info: str = "Extract SQL"
|
106
117
|
try:
|
107
|
-
|
118
|
+
|
119
|
+
logger.info(f"{info} ......")
|
120
|
+
|
108
121
|
if utils.v_true(sql, str):
|
122
|
+
|
109
123
|
sql_object = sql
|
110
|
-
|
124
|
+
|
125
|
+
elif sql_file is not None and utils.v_true(sql_file, str):
|
126
|
+
|
111
127
|
# 判断文件是否存在
|
112
|
-
if utils.check_file_type(sql_file,
|
113
|
-
|
128
|
+
if isinstance(sql_file, str) and utils.check_file_type(sql_file, "file") is False:
|
129
|
+
|
130
|
+
logger.error(f"No such file: {sql_file}")
|
114
131
|
return False
|
115
|
-
|
116
|
-
if utils.v_true(
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
132
|
+
|
133
|
+
if isinstance(sql_file, str) and utils.v_true(sql_file, str):
|
134
|
+
|
135
|
+
# 读取文件内容
|
136
|
+
if sql_file_kwargs is not None and utils.v_true(sql_file_kwargs, dict):
|
137
|
+
with open(sql_file, "r", encoding="utf-8", **sql_file_kwargs) as _file:
|
138
|
+
sql_object = _file.read()
|
139
|
+
else:
|
140
|
+
with open(sql_file, "r", encoding="utf-8") as _file:
|
141
|
+
sql_object = _file.read()
|
142
|
+
|
122
143
|
else:
|
123
|
-
|
124
|
-
logger.error(
|
144
|
+
|
145
|
+
logger.error("SQL or SQL file error")
|
146
|
+
logger.error(f"{info} [failure]")
|
125
147
|
return False
|
126
|
-
|
148
|
+
|
149
|
+
logger.success(f'{info} [success]')
|
150
|
+
|
127
151
|
except Exception as e:
|
128
|
-
|
129
|
-
logger.
|
152
|
+
|
153
|
+
logger.error(f"{info} [failure]")
|
154
|
+
logger.exception(e)
|
130
155
|
return False
|
131
156
|
|
132
157
|
# ------------------------------------------------------------
|
133
158
|
|
134
159
|
# 执行 SQL
|
135
|
-
info =
|
160
|
+
info: str = "Execute SQL"
|
136
161
|
try:
|
137
|
-
|
162
|
+
|
163
|
+
logger.info(f"{info} ......")
|
164
|
+
|
138
165
|
with self.engine.connect() as connect:
|
166
|
+
|
139
167
|
# 执行SQL
|
168
|
+
if sql_object is None:
|
169
|
+
return False
|
170
|
+
|
140
171
|
result = connect.execute(text(sql_object))
|
141
|
-
|
172
|
+
|
173
|
+
if csv_file is None:
|
142
174
|
# 如果 csv_file 没有定义, 则直接返回结果
|
143
|
-
logger.success(f'{info}[
|
175
|
+
logger.success(f'{info} [success]')
|
144
176
|
return result
|
177
|
+
|
178
|
+
# 如果 csv_file 有定义, 则保存结果到 csv_file
|
179
|
+
info_of_save = f"Save result to file: {csv_file}"
|
180
|
+
logger.info(f"{info_of_save} .......")
|
181
|
+
|
182
|
+
# 保存结果
|
183
|
+
if isinstance(csv_file_kwargs, dict) and utils.v_true(csv_file_kwargs, dict):
|
184
|
+
with open(csv_file, "w", encoding="utf-8", **csv_file_kwargs) as _file:
|
185
|
+
result_of_save = self._result_save(_file, result)
|
145
186
|
else:
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
logger.success(f'{info}[成功]') if echo == True else next
|
160
|
-
return True
|
161
|
-
else:
|
162
|
-
logger.error(f'{info_of_save} [失败]') if echo == True else next
|
163
|
-
logger.error(f'{info}[失败]') if echo == True else next
|
164
|
-
return False
|
187
|
+
with open(csv_file, "w", encoding="utf-8") as _file:
|
188
|
+
result_of_save = self._result_save(_file, result)
|
189
|
+
|
190
|
+
# 检查保存结果
|
191
|
+
if result_of_save is True:
|
192
|
+
logger.success(f'{info_of_save} [success]')
|
193
|
+
logger.success(f'{info} [success]')
|
194
|
+
return True
|
195
|
+
|
196
|
+
logger.error(f"{info_of_save} [failure]")
|
197
|
+
logger.error(f"{info} [failure]")
|
198
|
+
return False
|
199
|
+
|
165
200
|
except Exception as e:
|
166
|
-
|
167
|
-
logger.
|
201
|
+
|
202
|
+
logger.error(f'{info} [failure]')
|
203
|
+
logger.exception(e)
|
168
204
|
return False
|
ezKit/http.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import json
|
2
|
+
from typing import Any
|
2
3
|
|
3
4
|
import requests
|
4
5
|
from loguru import logger
|
@@ -11,61 +12,59 @@ def download(
|
|
11
12
|
file: dict,
|
12
13
|
chunks: bool = False,
|
13
14
|
iter_content: dict | None = None,
|
14
|
-
|
15
|
-
info: str = None,
|
16
|
-
debug: bool = False
|
15
|
+
info: str | None = None
|
17
16
|
) -> bool:
|
18
|
-
"下载文件"
|
17
|
+
"""下载文件"""
|
19
18
|
|
20
19
|
if utils.v_true(request, dict):
|
21
|
-
request_arguments = {
|
20
|
+
request_arguments = {"method": "GET", "stream": True, **request}
|
22
21
|
else:
|
23
22
|
return False
|
24
23
|
|
25
24
|
if utils.v_true(file, dict):
|
26
|
-
file_arguments = {
|
25
|
+
file_arguments = {"mode": "wb", **file}
|
27
26
|
else:
|
28
27
|
return False
|
29
28
|
|
30
|
-
if utils.v_true(iter_content, dict):
|
31
|
-
iter_content_arguments = {
|
29
|
+
if iter_content is not None and utils.v_true(iter_content, dict):
|
30
|
+
iter_content_arguments = {"chunk_size": 1024, **iter_content}
|
32
31
|
else:
|
33
|
-
iter_content_arguments = {
|
32
|
+
iter_content_arguments = {"chunk_size": 1024}
|
34
33
|
|
35
|
-
|
34
|
+
info_prefix: str = "Download"
|
35
|
+
if utils.v_true(info, str):
|
36
|
+
info_prefix = f"Download {info}"
|
36
37
|
|
37
38
|
try:
|
38
39
|
|
39
|
-
logger.info(f'{
|
40
|
+
logger.info(f'{info_prefix} ......')
|
40
41
|
|
41
42
|
response = requests.request(**request_arguments)
|
42
43
|
|
43
|
-
|
44
|
+
# # pylint: disable=W1514
|
45
|
+
with open(**file_arguments) as _file: # type: ignore
|
44
46
|
|
45
47
|
if utils.v_true(chunks, bool):
|
46
|
-
for _chunk in response.iter_content(**iter_content_arguments):
|
48
|
+
for _chunk in response.iter_content(**iter_content_arguments): # type: ignore
|
47
49
|
_file.write(_chunk)
|
48
50
|
else:
|
49
51
|
_file.write(response.content)
|
50
52
|
|
51
|
-
logger.success(f'{
|
53
|
+
logger.success(f'{info_prefix} [success]')
|
52
54
|
|
53
55
|
return True
|
54
56
|
|
55
57
|
except Exception as e:
|
56
|
-
|
57
|
-
logger.error(f'{
|
58
|
+
|
59
|
+
logger.error(f'{info_prefix} [failure]')
|
60
|
+
logger.exception(e)
|
58
61
|
return False
|
59
62
|
|
60
63
|
|
61
|
-
def response_json(
|
62
|
-
data: any = None,
|
63
|
-
debug: bool = False,
|
64
|
-
**kwargs
|
65
|
-
) -> str:
|
64
|
+
def response_json(data: Any = None, **kwargs) -> str | None:
|
66
65
|
"""解决字符编码问题: ensure_ascii=False"""
|
67
66
|
try:
|
68
67
|
return json.dumps(data, default=str, ensure_ascii=False, sort_keys=True, **kwargs)
|
69
68
|
except Exception as e:
|
70
|
-
logger.exception(e)
|
69
|
+
logger.exception(e)
|
71
70
|
return None
|
ezKit/mongo.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"""MongoDB"""
|
2
2
|
from loguru import logger
|
3
3
|
from pymongo import MongoClient
|
4
|
+
from pymongo.collection import Collection
|
4
5
|
|
5
6
|
from . import utils
|
6
7
|
|
@@ -10,39 +11,41 @@ class Mongo():
|
|
10
11
|
|
11
12
|
client = MongoClient()
|
12
13
|
|
13
|
-
def close(self):
|
14
|
+
def close(self) -> bool:
|
14
15
|
"""client close"""
|
15
16
|
try:
|
16
17
|
self.client.close()
|
18
|
+
return True
|
17
19
|
except Exception as e:
|
18
20
|
logger.exception(e)
|
21
|
+
return False
|
19
22
|
|
20
|
-
def connect_test(self
|
21
|
-
"
|
22
|
-
info = 'MongoDB连接测试'
|
23
|
+
def connect_test(self) -> bool:
|
24
|
+
info = "MongoDB connect test"
|
23
25
|
try:
|
24
|
-
logger.info(f
|
26
|
+
logger.info(f"{info} ......")
|
25
27
|
self.client.server_info()
|
26
|
-
logger.success(f
|
28
|
+
logger.success(f"{info} [success]")
|
27
29
|
return True
|
28
30
|
except Exception as e:
|
29
|
-
logger.error(f
|
30
|
-
|
31
|
-
logger.exception(e)
|
31
|
+
logger.error(f"{info} [failure]")
|
32
|
+
logger.exception(e)
|
32
33
|
return False
|
33
34
|
|
34
|
-
def collection(self, database, name):
|
35
|
-
|
36
|
-
|
35
|
+
def collection(self, database: str, name: str) -> Collection | None:
|
36
|
+
try:
|
37
|
+
return self.client[database][name]
|
38
|
+
except Exception as e:
|
39
|
+
logger.exception(e)
|
40
|
+
return None
|
37
41
|
|
38
|
-
def collection_insert(self, database, collection, data, drop=
|
39
|
-
"""client collection insert"""
|
42
|
+
def collection_insert(self, database, collection, data, drop: bool = False):
|
40
43
|
db_collection = self.client[database][collection]
|
41
|
-
info =
|
44
|
+
info = "MongoDB collection insert"
|
42
45
|
try:
|
43
|
-
logger.info(f
|
46
|
+
logger.info(f"{info} ......")
|
44
47
|
# 是否删除 collection
|
45
|
-
if drop
|
48
|
+
if utils.v_true(drop, bool):
|
46
49
|
# 删除 collection
|
47
50
|
db_collection.drop()
|
48
51
|
# 插入数据
|
@@ -53,12 +56,12 @@ class Mongo():
|
|
53
56
|
# 插入多条数据
|
54
57
|
result = db_collection.insert_many(data)
|
55
58
|
else:
|
56
|
-
logger.error(f
|
57
|
-
logger.error(
|
59
|
+
logger.error(f"{info} [failure]")
|
60
|
+
logger.error("Data type error")
|
58
61
|
return False
|
59
|
-
logger.success(f
|
62
|
+
logger.success(f"{info} [success]")
|
60
63
|
return result
|
61
64
|
except Exception as e:
|
62
|
-
logger.error(f
|
65
|
+
logger.error(f"{info} [failure]")
|
63
66
|
logger.exception(e)
|
64
67
|
return False
|
ezKit/redis.py
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
"""Redis"""
|
1
2
|
import redis as RedisClient
|
2
3
|
from loguru import logger
|
3
4
|
|
4
5
|
from . import utils
|
5
6
|
|
6
7
|
|
7
|
-
class Redis
|
8
|
+
class Redis:
|
9
|
+
"""Redis"""
|
8
10
|
|
9
11
|
# https://redis.readthedocs.io/en/stable/_modules/redis/client.html#Redis
|
10
12
|
# https://github.com/redis/redis-py#client-classes-redis-and-strictredis
|
@@ -14,38 +16,39 @@ class Redis(object):
|
|
14
16
|
# 这里修改以下参数: host, port, socket_timeout, socket_connect_timeout, charset
|
15
17
|
redis = RedisClient.Redis()
|
16
18
|
|
17
|
-
def __init__(self, arguments
|
18
|
-
|
19
|
-
if utils.v_true(arguments, str):
|
19
|
+
def __init__(self, arguments: str | dict):
|
20
|
+
"""Initiation"""
|
21
|
+
if isinstance(arguments, str) and utils.v_true(arguments, str):
|
20
22
|
self.redis = RedisClient.from_url(arguments)
|
21
|
-
elif utils.v_true(arguments, dict):
|
23
|
+
elif isinstance(arguments, dict) and utils.v_true(arguments, dict):
|
22
24
|
self.redis = RedisClient.Redis(**arguments)
|
23
25
|
else:
|
24
26
|
pass
|
25
27
|
|
26
|
-
def connect_test(self):
|
27
|
-
info =
|
28
|
+
def connect_test(self) -> bool:
|
29
|
+
info = "Redis connect test"
|
28
30
|
try:
|
29
|
-
logger.info(f
|
31
|
+
logger.info(f"{info} ......")
|
30
32
|
self.redis.ping()
|
31
|
-
logger.success(f
|
33
|
+
logger.success(f"{info} [success]")
|
32
34
|
return True
|
33
35
|
except Exception as e:
|
34
|
-
logger.error(f
|
36
|
+
logger.error(f"{info} [failure]")
|
35
37
|
logger.exception(e)
|
36
38
|
return False
|
37
39
|
|
38
|
-
def flush(self,
|
39
|
-
info =
|
40
|
+
def flush(self, flushall: bool = False) -> bool:
|
41
|
+
info = "Redis flush"
|
40
42
|
try:
|
41
|
-
|
42
|
-
|
43
|
+
if utils.v_true(flushall, bool):
|
44
|
+
logger.info(f"{info} all ......")
|
43
45
|
self.redis.flushall()
|
44
46
|
else:
|
47
|
+
logger.info(f"{info} db ......")
|
45
48
|
self.redis.flushdb()
|
46
|
-
logger.success(f
|
49
|
+
logger.success(f"{info} [success]")
|
47
50
|
return True
|
48
51
|
except Exception as e:
|
49
|
-
logger.error(f
|
52
|
+
logger.error(f"{info} [failure]")
|
50
53
|
logger.exception(e)
|
51
54
|
return False
|