ezKit 1.7.8__tar.gz → 1.8.1__tar.gz

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.
Files changed (33) hide show
  1. {ezkit-1.7.8/ezKit.egg-info → ezkit-1.8.1}/PKG-INFO +2 -2
  2. ezkit-1.8.1/README.md +1 -0
  3. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit/bottle.py +7 -2
  4. ezkit-1.8.1/ezKit/bottle_extensions.py +32 -0
  5. ezkit-1.8.1/ezKit/database.py +204 -0
  6. ezkit-1.8.1/ezKit/http.py +70 -0
  7. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit/mongo.py +3 -3
  8. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit/qywx.py +48 -34
  9. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit/redis.py +5 -4
  10. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit/sendemail.py +0 -7
  11. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit/utils.py +2 -2
  12. {ezkit-1.7.8 → ezkit-1.8.1/ezKit.egg-info}/PKG-INFO +2 -2
  13. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit.egg-info/SOURCES.txt +0 -4
  14. ezkit-1.8.1/ezKit.egg-info/requires.txt +1 -0
  15. {ezkit-1.7.8 → ezkit-1.8.1}/setup.py +2 -2
  16. ezkit-1.7.8/README.md +0 -60
  17. ezkit-1.7.8/ezKit/bottle_extensions.py +0 -36
  18. ezkit-1.7.8/ezKit/database.py +0 -171
  19. ezkit-1.7.8/ezKit/files.py +0 -348
  20. ezkit-1.7.8/ezKit/http.py +0 -71
  21. ezkit-1.7.8/ezKit/plots.py +0 -155
  22. ezkit-1.7.8/ezKit/reports.py +0 -274
  23. ezkit-1.7.8/ezKit/zabbix.py +0 -737
  24. ezkit-1.7.8/ezKit.egg-info/requires.txt +0 -1
  25. {ezkit-1.7.8 → ezkit-1.8.1}/LICENSE +0 -0
  26. {ezkit-1.7.8 → ezkit-1.8.1}/MANIFEST.in +0 -0
  27. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit/__init__.py +0 -0
  28. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit/cipher.py +0 -0
  29. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit/token.py +0 -0
  30. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit/xftp.py +0 -0
  31. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit.egg-info/dependency_links.txt +0 -0
  32. {ezkit-1.7.8 → ezkit-1.8.1}/ezKit.egg-info/top_level.txt +0 -0
  33. {ezkit-1.7.8 → ezkit-1.8.1}/setup.cfg +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ezKit
3
- Version: 1.7.8
3
+ Version: 1.8.1
4
4
  Summary: Easy Kit
5
5
  Author: septvean
6
6
  Author-email: septvean@gmail.com
7
7
  Requires-Python: >=3.11
8
8
  License-File: LICENSE
9
- Requires-Dist: loguru>=0.7.0
9
+ Requires-Dist: loguru>=0.7
ezkit-1.8.1/README.md ADDED
@@ -0,0 +1 @@
1
+ # Python Easy Kit
@@ -17,7 +17,7 @@ from __future__ import print_function
17
17
  import sys
18
18
 
19
19
  __author__ = 'Marcel Hellkamp'
20
- __version__ = '0.13.1'
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
- if __name__ == '__main__': # pragma: no coverage
4675
+ def main():
4675
4676
  _main(sys.argv)
4677
+
4678
+
4679
+ if __name__ == '__main__': # pragma: no coverage
4680
+ main()
@@ -0,0 +1,32 @@
1
+ """Bottle Extensions"""
2
+ from typing import Callable
3
+
4
+ from . import bottle, utils
5
+
6
+
7
+ def enable_cors(fn: Callable) -> Callable:
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
14
+ def cors(*args, **kwargs):
15
+ bottle.response.headers['Access-Control-Allow-Headers'] = '*'
16
+ bottle.response.headers['Access-Control-Allow-Methods'] = '*'
17
+ bottle.response.headers['Access-Control-Allow-Origin'] = '*'
18
+ if bottle.request.method != 'OPTIONS':
19
+ return fn(*args, **kwargs)
20
+ return None
21
+ return cors
22
+
23
+ def request_json() -> bottle.DictProperty | None:
24
+ """Bottle Request JSON"""
25
+ try:
26
+ data = bottle.request.json
27
+ if utils.v_true(data, dict):
28
+ return data
29
+ return None
30
+ except Exception as e:
31
+ print(e)
32
+ return None
@@ -0,0 +1,204 @@
1
+ """
2
+ Column, Table, MetaData API
3
+ https://docs.sqlalchemy.org/en/14/core/metadata.html#column-table-metadata-api
4
+ CursorResult
5
+ https://docs.sqlalchemy.org/en/20/core/connections.html#sqlalchemy.engine.CursorResult
6
+ PostgreSQL 14 Data Types
7
+ https://www.postgresql.org/docs/14/datatype.html
8
+ """
9
+ import csv
10
+ from typing import Any
11
+
12
+ from loguru import logger
13
+ from sqlalchemy import CursorResult, Index, create_engine, text
14
+
15
+ from . import utils
16
+
17
+
18
+ class Database():
19
+ """Database"""
20
+
21
+ engine = create_engine('sqlite://')
22
+
23
+ def __init__(self, engine_url, **engine_options):
24
+ """Initiation"""
25
+ if engine_url is not None and utils.v_true(engine_url, str):
26
+ if utils.v_true(engine_options, dict):
27
+ self.engine = create_engine(engine_url, **engine_options)
28
+ else:
29
+ self.engine = create_engine(engine_url)
30
+ else:
31
+ pass
32
+
33
+ def initializer(self):
34
+ """ensure the parent proc's database connections are not touched in the new connection pool"""
35
+ self.engine.dispose(close=False)
36
+
37
+ def connect_test(self) -> bool:
38
+ info = "Database connect test"
39
+ try:
40
+ logger.info(f"{info} ......")
41
+ self.engine.connect()
42
+ logger.success(f"{info} [success]")
43
+ return True
44
+ except Exception as e:
45
+ logger.error(f"{info} [failure]")
46
+ logger.exception(e)
47
+ return False
48
+
49
+ def metadata_init(self, base, **kwargs) -> bool:
50
+ # https://stackoverflow.com/questions/19175311/how-to-create-only-one-table-with-sqlalchemy
51
+ info = "Database init table"
52
+ try:
53
+ logger.info(f"{info} ......")
54
+ base.metadata.drop_all(self.engine, **kwargs)
55
+ base.metadata.create_all(self.engine, **kwargs)
56
+ logger.success(f"{info} [success]")
57
+ return True
58
+ except Exception as e:
59
+ logger.error(f"{info} [failure]")
60
+ logger.exception(e)
61
+ return False
62
+
63
+ def create_index(self, index_name, table_field) -> bool:
64
+ # 创建索引
65
+ # https://stackoverflow.com/a/41254430
66
+ # 示例:
67
+ # index_name: a_share_list_code_idx1
68
+ # table_field: Table_a_share_list.code
69
+ info = "Database create index"
70
+ try:
71
+ logger.info(f"{info} ......")
72
+ idx = Index(index_name, table_field)
73
+ try:
74
+ idx.drop(bind=self.engine)
75
+ except Exception as e:
76
+ logger.exception(e)
77
+ idx.create(bind=self.engine)
78
+ logger.success(f'{info} [success]')
79
+ return True
80
+ except Exception as e:
81
+ logger.error(f'{info} [failure]')
82
+ logger.error(e)
83
+ return False
84
+
85
+ # 私有函数, 保存 execute 的结果到 CSV 文件
86
+ def _result_save(self, file, data) -> bool:
87
+ try:
88
+ outcsv = csv.writer(file)
89
+ outcsv.writerow(data.keys())
90
+ outcsv.writerows(data)
91
+ return True
92
+ except Exception as e:
93
+ logger.exception(e)
94
+ return False
95
+
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
+ """
105
+ echo 是否打印日志
106
+ 某些情况下只需要结果, 不需要日志, 将 echo 设置为 False 即可
107
+ """
108
+
109
+ # info_prefix = '[Execute SQL]'
110
+
111
+ # ------------------------------------------------------------
112
+
113
+ # 提取 SQL
114
+ # 如果 sql 和 sql_file 同时存在, 优先执行 sql
115
+ sql_object = None
116
+ info: str = "Extract SQL"
117
+ try:
118
+
119
+ logger.info(f"{info} ......")
120
+
121
+ if utils.v_true(sql, str):
122
+
123
+ sql_object = sql
124
+
125
+ elif sql_file is not None and utils.v_true(sql_file, str):
126
+
127
+ # 判断文件是否存在
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}")
131
+ return False
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
+
143
+ else:
144
+
145
+ logger.error("SQL or SQL file error")
146
+ logger.error(f"{info} [failure]")
147
+ return False
148
+
149
+ logger.success(f'{info} [success]')
150
+
151
+ except Exception as e:
152
+
153
+ logger.error(f"{info} [failure]")
154
+ logger.exception(e)
155
+ return False
156
+
157
+ # ------------------------------------------------------------
158
+
159
+ # 执行 SQL
160
+ info: str = "Execute SQL"
161
+ try:
162
+
163
+ logger.info(f"{info} ......")
164
+
165
+ with self.engine.connect() as connect:
166
+
167
+ # 执行SQL
168
+ if sql_object is None:
169
+ return False
170
+
171
+ result = connect.execute(text(sql_object))
172
+
173
+ if csv_file is None:
174
+ # 如果 csv_file 没有定义, 则直接返回结果
175
+ logger.success(f'{info} [success]')
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)
186
+ else:
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
+
200
+ except Exception as e:
201
+
202
+ logger.error(f'{info} [failure]')
203
+ logger.exception(e)
204
+ return False
@@ -0,0 +1,70 @@
1
+ import json
2
+ from typing import Any
3
+
4
+ import requests
5
+ from loguru import logger
6
+
7
+ from . import utils
8
+
9
+
10
+ def download(
11
+ request: dict,
12
+ file: dict,
13
+ chunks: bool = False,
14
+ iter_content: dict | None = None,
15
+ info: str | None = None
16
+ ) -> bool:
17
+ """下载文件"""
18
+
19
+ if utils.v_true(request, dict):
20
+ request_arguments = {"method": "GET", "stream": True, **request}
21
+ else:
22
+ return False
23
+
24
+ if utils.v_true(file, dict):
25
+ file_arguments = {"mode": "wb", **file}
26
+ else:
27
+ return False
28
+
29
+ if iter_content is not None and utils.v_true(iter_content, dict):
30
+ iter_content_arguments = {"chunk_size": 1024, **iter_content}
31
+ else:
32
+ iter_content_arguments = {"chunk_size": 1024}
33
+
34
+ info_prefix: str = "Download"
35
+ if utils.v_true(info, str):
36
+ info_prefix = f"Download {info}"
37
+
38
+ try:
39
+
40
+ logger.info(f'{info_prefix} ......')
41
+
42
+ response = requests.request(**request_arguments)
43
+
44
+ # # pylint: disable=W1514
45
+ with open(**file_arguments) as _file: # type: ignore
46
+
47
+ if utils.v_true(chunks, bool):
48
+ for _chunk in response.iter_content(**iter_content_arguments): # type: ignore
49
+ _file.write(_chunk)
50
+ else:
51
+ _file.write(response.content)
52
+
53
+ logger.success(f'{info_prefix} [success]')
54
+
55
+ return True
56
+
57
+ except Exception as e:
58
+
59
+ logger.error(f'{info_prefix} [failure]')
60
+ logger.exception(e)
61
+ return False
62
+
63
+
64
+ def response_json(data: Any = None, **kwargs) -> str | None:
65
+ """解决字符编码问题: ensure_ascii=False"""
66
+ try:
67
+ return json.dumps(data, default=str, ensure_ascii=False, sort_keys=True, **kwargs)
68
+ except Exception as e:
69
+ logger.exception(e)
70
+ return None
@@ -28,7 +28,7 @@ class Mongo():
28
28
  logger.success(f"{info} [success]")
29
29
  return True
30
30
  except Exception as e:
31
- logger.error(f"{info} [failed]")
31
+ logger.error(f"{info} [failure]")
32
32
  logger.exception(e)
33
33
  return False
34
34
 
@@ -56,12 +56,12 @@ class Mongo():
56
56
  # 插入多条数据
57
57
  result = db_collection.insert_many(data)
58
58
  else:
59
- logger.error(f"{info} [failed]")
59
+ logger.error(f"{info} [failure]")
60
60
  logger.error("Data type error")
61
61
  return False
62
62
  logger.success(f"{info} [success]")
63
63
  return result
64
64
  except Exception as e:
65
- logger.error(f"{info} [failed]")
65
+ logger.error(f"{info} [failure]")
66
66
  logger.exception(e)
67
67
  return False
@@ -21,7 +21,7 @@ from . import utils
21
21
  class QYWX:
22
22
  """企业微信"""
23
23
 
24
- url_prefix = 'https://qyapi.weixin.qq.com'
24
+ url_prefix = "https://qyapi.weixin.qq.com"
25
25
  work_id: str | None = None
26
26
  agent_id: str | None = None
27
27
  agent_secret: str | None = None
@@ -38,20 +38,22 @@ class QYWX:
38
38
 
39
39
  def getaccess_token(self) -> str | None:
40
40
  try:
41
- response = requests.get(f'{self.url_prefix}/cgi-bin/gettoken?corpid={self.work_id}&corpsecret={self.agent_secret}')
41
+ response = requests.get(f"{self.url_prefix}/cgi-bin/gettoken?corpid={self.work_id}&corpsecret={self.agent_secret}", timeout=10)
42
42
  if response.status_code == 200:
43
43
  result: dict = response.json()
44
44
  self.access_token = result.get('access_token')
45
45
  else:
46
46
  self.access_token = None
47
47
  return result.get('access_token')
48
- except:
48
+ except Exception as e:
49
+ logger.exception(e)
49
50
  return None
50
51
 
51
52
  def get_agent_list(self) -> dict | str | None:
52
53
  try:
53
- self.getaccess_token() if self.access_token == None else next
54
- response = requests.get(f'{self.url_prefix}/cgi-bin/agent/list?access_token={self.access_token}')
54
+ if self.access_token is None:
55
+ self.getaccess_token()
56
+ response = requests.get(f"{self.url_prefix}/cgi-bin/agent/list?access_token={self.access_token}", timeout=10)
55
57
  if response.status_code == 200:
56
58
  response_data: dict = response.json()
57
59
  if response_data.get('errcode') == 42001:
@@ -60,79 +62,91 @@ class QYWX:
60
62
  self.get_agent_list()
61
63
  return response_data
62
64
  return response.text
63
- except:
65
+ except Exception as e:
66
+ logger.exception(e)
64
67
  return None
65
68
 
66
- def get_department_list(self, id) -> dict | str | None:
69
+ def get_department_list(self, eid: str | None = None) -> dict | str | None:
70
+ """eid: Enterprise ID"""
67
71
  try:
68
- self.getaccess_token() if self.access_token == None else next
69
- response = requests.get(f'{self.url_prefix}/cgi-bin/department/list?access_token={self.access_token}&id={id}')
72
+ if self.access_token is None:
73
+ self.getaccess_token()
74
+ response = requests.get(f"{self.url_prefix}/cgi-bin/department/list?access_token={self.access_token}&id={eid}", timeout=10)
70
75
  if response.status_code == 200:
71
76
  response_data: dict = response.json()
72
77
  if response_data.get('errcode') == 42001:
73
78
  self.getaccess_token()
74
79
  time.sleep(1)
75
- self.get_department_list(id)
80
+ self.get_department_list(eid)
76
81
  return response_data
77
82
  return response.text
78
- except:
83
+ except Exception as e:
84
+ logger.exception(e)
79
85
  return None
80
86
 
81
- def get_user_list(self, id) -> dict | str | None:
87
+ def get_user_list(self, eid: str | None = None) -> dict | str | None:
88
+ """eid: Enterprise ID"""
82
89
  try:
83
- self.getaccess_token() if self.access_token == None else next
84
- response = requests.get(f'{self.url_prefix}/cgi-bin/user/list?access_token={self.access_token}&department_id={id}')
90
+ if self.access_token is None:
91
+ self.getaccess_token()
92
+ response = requests.get(f"{self.url_prefix}/cgi-bin/user/list?access_token={self.access_token}&department_id={eid}", timeout=10)
85
93
  if response.status_code == 200:
86
94
  response_data: dict = response.json()
87
95
  if response_data.get('errcode') == 42001:
88
96
  self.getaccess_token()
89
97
  time.sleep(1)
90
- self.get_user_list(id)
98
+ self.get_user_list(eid)
91
99
  return response_data
92
100
  return response.text
93
- except:
101
+ except Exception as e:
102
+ logger.exception(e)
94
103
  return None
95
104
 
96
- def get_user_id_by_mobile(self, mobile) -> dict | str | None:
105
+ def get_user_id_by_mobile(self, mobile: str | None = None) -> dict | str | None:
97
106
  try:
98
- self.getaccess_token() if self.access_token == None else next
107
+ if self.access_token is None:
108
+ self.getaccess_token()
99
109
  json_string = json.dumps({'mobile': mobile})
100
- response = requests.post(f'{self.url_prefix}/cgi-bin/user/getuserid?access_token={self.access_token}', data=json_string)
110
+ response = requests.post(f"{self.url_prefix}/cgi-bin/user/getuserid?access_token={self.access_token}", data=json_string, timeout=10)
101
111
  if response.status_code == 200:
102
112
  response_data: dict = response.json()
103
113
  if response_data.get('errcode') == 42001:
104
114
  self.getaccess_token()
105
115
  time.sleep(1)
106
- self.get_user_id_by_mobile(id)
116
+ self.get_user_id_by_mobile(mobile)
107
117
  return response_data
108
118
  return response.text
109
- except:
119
+ except Exception as e:
120
+ logger.exception(e)
110
121
  return None
111
122
 
112
- def get_user_info(self, id) -> dict | str | None:
123
+ def get_user_info(self, eid: str | None = None) -> dict | str | None:
124
+ """eid: Enterprise ID"""
113
125
  try:
114
- self.getaccess_token() if self.access_token == None else next
115
- response = requests.get(f'{self.url_prefix}/cgi-bin/user/get?access_token={self.access_token}&userid={id}')
126
+ if self.access_token is None:
127
+ self.getaccess_token()
128
+ response = requests.get(f"{self.url_prefix}/cgi-bin/user/get?access_token={self.access_token}&userid={eid}", timeout=10)
116
129
  if response.status_code == 200:
117
130
  response_data: dict = response.json()
118
131
  if response_data.get('errcode') == 42001:
119
132
  self.getaccess_token()
120
133
  time.sleep(1)
121
- self.get_user_info(id)
134
+ self.get_user_info(eid)
122
135
  return response_data
123
136
  return response.text
124
- except:
137
+ except Exception as e:
138
+ logger.exception(e)
125
139
  return None
126
140
 
127
- def send_message_by_mobile(self, mobile: str | list, message: str, debug: bool = False) -> bool:
141
+ def send_message_by_mobile(self, mobile: str | list, message: str) -> bool:
128
142
  """发送消息"""
129
- """
130
- 参考文档:
131
143
 
132
- https://developer.work.weixin.qq.com/document/path/90235
133
- """
144
+ # 参考文档:
145
+ # https://developer.work.weixin.qq.com/document/path/90235
146
+
134
147
  try:
135
- self.getaccess_token() if self.access_token == None else next
148
+ if self.access_token is None:
149
+ self.getaccess_token()
136
150
 
137
151
  users: list = []
138
152
 
@@ -157,7 +171,7 @@ class QYWX:
157
171
  'duplicate_check_interval': 1800
158
172
  }
159
173
  json_string = json.dumps(json_dict)
160
- response = requests.post(f'{self.url_prefix}/cgi-bin/message/send?access_token={self.access_token}', data=json_string)
174
+ response = requests.post(f"{self.url_prefix}/cgi-bin/message/send?access_token={self.access_token}", data=json_string, timeout=10)
161
175
  if response.status_code == 200:
162
176
  response_data: dict = response.json()
163
177
  if response_data.get('errcode') == 42001:
@@ -168,5 +182,5 @@ class QYWX:
168
182
  return True
169
183
 
170
184
  except Exception as e:
171
- logger.exception(e) if utils.v_true(debug, bool) else next
185
+ logger.exception(e)
172
186
  return False
@@ -20,9 +20,10 @@ class Redis:
20
20
  """Initiation"""
21
21
  if isinstance(arguments, str) and utils.v_true(arguments, str):
22
22
  self.redis = RedisClient.from_url(arguments)
23
-
24
- if isinstance(arguments, dict) and utils.v_true(arguments, dict):
23
+ elif isinstance(arguments, dict) and utils.v_true(arguments, dict):
25
24
  self.redis = RedisClient.Redis(**arguments)
25
+ else:
26
+ pass
26
27
 
27
28
  def connect_test(self) -> bool:
28
29
  info = "Redis connect test"
@@ -32,7 +33,7 @@ class Redis:
32
33
  logger.success(f"{info} [success]")
33
34
  return True
34
35
  except Exception as e:
35
- logger.error(f"{info} [failed]")
36
+ logger.error(f"{info} [failure]")
36
37
  logger.exception(e)
37
38
  return False
38
39
 
@@ -48,6 +49,6 @@ class Redis:
48
49
  logger.success(f"{info} [success]")
49
50
  return True
50
51
  except Exception as e:
51
- logger.error(f"{info} [failed]")
52
+ logger.error(f"{info} [failure]")
52
53
  logger.exception(e)
53
54
  return False
@@ -1,12 +1,5 @@
1
1
  """发送邮件"""
2
2
  # https://stackoverflow.com/questions/882712/sending-html-email-using-python
3
- # pylint: disable=E0611
4
- # pylint: disable=R0911
5
- # pylint: disable=R0912
6
- # pylint: disable=R0913
7
- # pylint: disable=R0914
8
- # pylint: disable=R0915
9
- # pylint: disable=R1710
10
3
  import smtplib
11
4
  from email.header import Header
12
5
  from email.mime.image import MIMEImage
@@ -1468,8 +1468,8 @@ def create_empty_file(
1468
1468
  # 创建一个空文件
1469
1469
  if v_true(debug, bool):
1470
1470
  logger.info(f"file: {file}")
1471
- # pylint: disable=R1732,disable=W1514
1472
- open(file, 'w').close()
1471
+ # pylint: disable=R1732
1472
+ open(file, "w", encoding="utf-8").close()
1473
1473
  # 返回文件路径
1474
1474
  return file
1475
1475
  except Exception as e:
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ezKit
3
- Version: 1.7.8
3
+ Version: 1.8.1
4
4
  Summary: Easy Kit
5
5
  Author: septvean
6
6
  Author-email: septvean@gmail.com
7
7
  Requires-Python: >=3.11
8
8
  License-File: LICENSE
9
- Requires-Dist: loguru>=0.7.0
9
+ Requires-Dist: loguru>=0.7
@@ -7,18 +7,14 @@ ezKit/bottle.py
7
7
  ezKit/bottle_extensions.py
8
8
  ezKit/cipher.py
9
9
  ezKit/database.py
10
- ezKit/files.py
11
10
  ezKit/http.py
12
11
  ezKit/mongo.py
13
- ezKit/plots.py
14
12
  ezKit/qywx.py
15
13
  ezKit/redis.py
16
- ezKit/reports.py
17
14
  ezKit/sendemail.py
18
15
  ezKit/token.py
19
16
  ezKit/utils.py
20
17
  ezKit/xftp.py
21
- ezKit/zabbix.py
22
18
  ezKit.egg-info/PKG-INFO
23
19
  ezKit.egg-info/SOURCES.txt
24
20
  ezKit.egg-info/dependency_links.txt
@@ -0,0 +1 @@
1
+ loguru>=0.7
@@ -3,7 +3,7 @@ from setuptools import find_packages, setup
3
3
 
4
4
  setup(
5
5
  name='ezKit',
6
- version='1.7.8',
6
+ version='1.8.1',
7
7
  author='septvean',
8
8
  author_email='septvean@gmail.com',
9
9
  description='Easy Kit',
@@ -11,6 +11,6 @@ setup(
11
11
  include_package_data=True,
12
12
  python_requires='>=3.11',
13
13
  install_requires=[
14
- "loguru>=0.7.0"
14
+ "loguru>=0.7"
15
15
  ]
16
16
  )