gomyck-tools 1.0.0__py3-none-any.whl → 1.4.7__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.
Files changed (107) hide show
  1. ctools/__init__.py +21 -0
  2. ctools/ai/__init__.py +4 -0
  3. ctools/ai/llm_chat.py +184 -0
  4. ctools/ai/llm_client.py +163 -0
  5. ctools/ai/llm_exception.py +17 -0
  6. ctools/ai/mcp/__init__.py +4 -0
  7. ctools/ai/mcp/mcp_client.py +326 -0
  8. ctools/ai/tools/__init__.py +4 -0
  9. ctools/ai/tools/json_extract.py +202 -0
  10. ctools/ai/tools/quick_tools.py +149 -0
  11. ctools/ai/tools/think_process.py +11 -0
  12. ctools/ai/tools/tool_use_xml_parse.py +40 -0
  13. ctools/ai/tools/xml_extract.py +15 -0
  14. ctools/application.py +50 -47
  15. ctools/aspect.py +65 -0
  16. ctools/auto/__init__.py +4 -0
  17. ctools/{browser_element_tools.py → auto/browser_element.py} +18 -8
  18. ctools/{plan_area_tools.py → auto/plan_area.py} +5 -7
  19. ctools/{pty_tools.py → auto/pty_process.py} +6 -3
  20. ctools/{resource_bundle_tools.py → auto/resource_bundle.py} +4 -4
  21. ctools/{screenshot_tools.py → auto/screenshot.py} +7 -6
  22. ctools/{win_canvas.py → auto/win_canvas.py} +10 -4
  23. ctools/{win_control.py → auto/win_control.py} +14 -5
  24. ctools/call.py +34 -49
  25. ctools/cdate.py +84 -0
  26. ctools/cdebug.py +146 -0
  27. ctools/cid.py +20 -0
  28. ctools/cipher/__init__.py +4 -0
  29. ctools/{aes_tools.py → cipher/aes_util.py} +10 -0
  30. ctools/{b64.py → cipher/b64.py} +2 -0
  31. ctools/cipher/czip.py +133 -0
  32. ctools/cipher/rsa.py +75 -0
  33. ctools/{sign.py → cipher/sign.py} +2 -1
  34. ctools/{sm_tools.py → cipher/sm_util.py} +20 -4
  35. ctools/cjson.py +10 -10
  36. ctools/cron_lite.py +109 -97
  37. ctools/database/__init__.py +4 -0
  38. ctools/{database.py → database/database.py} +93 -26
  39. ctools/dict_wrapper.py +21 -0
  40. ctools/ex.py +4 -0
  41. ctools/geo/__init__.py +4 -0
  42. ctools/geo/coord_trans.py +127 -0
  43. ctools/geo/douglas_rarefy.py +139 -0
  44. ctools/metrics.py +56 -63
  45. ctools/office/__init__.py +4 -0
  46. ctools/office/cword.py +30 -0
  47. ctools/{word_fill.py → office/word_fill.py} +3 -6
  48. ctools/patch.py +88 -0
  49. ctools/{work_path.py → path_info.py} +34 -2
  50. ctools/pkg/__init__.py +4 -0
  51. ctools/pkg/dynamic_imp.py +38 -0
  52. ctools/pools/__init__.py +4 -0
  53. ctools/pools/process_pool.py +41 -0
  54. ctools/{thread_pool.py → pools/thread_pool.py} +13 -4
  55. ctools/similar.py +25 -0
  56. ctools/stream/__init__.py +4 -0
  57. ctools/stream/ckafka.py +164 -0
  58. ctools/stream/credis.py +127 -0
  59. ctools/{mqtt_utils.py → stream/mqtt_utils.py} +20 -12
  60. ctools/sys_info.py +36 -13
  61. ctools/sys_log.py +46 -27
  62. ctools/util/__init__.py +4 -0
  63. ctools/util/cftp.py +76 -0
  64. ctools/util/cklock.py +118 -0
  65. ctools/util/config_util.py +52 -0
  66. ctools/util/env_config.py +63 -0
  67. ctools/{html_soup.py → util/html_soup.py} +0 -7
  68. ctools/{http_utils.py → util/http_util.py} +4 -2
  69. ctools/{images_tools.py → util/image_process.py} +10 -1
  70. ctools/util/jb_cut.py +54 -0
  71. ctools/{id_worker_tools.py → util/snow_id.py} +8 -23
  72. ctools/web/__init__.py +4 -0
  73. ctools/web/aio_web_server.py +186 -0
  74. ctools/web/api_result.py +56 -0
  75. ctools/web/bottle_web_base.py +239 -0
  76. ctools/web/bottle_webserver.py +191 -0
  77. ctools/web/bottle_websocket.py +79 -0
  78. ctools/web/ctoken.py +103 -0
  79. ctools/{download_tools.py → web/download_util.py} +14 -12
  80. ctools/web/params_util.py +46 -0
  81. ctools/{upload_tools.py → web/upload_util.py} +3 -2
  82. gomyck_tools-1.4.7.dist-info/METADATA +70 -0
  83. gomyck_tools-1.4.7.dist-info/RECORD +88 -0
  84. {gomyck_tools-1.0.0.dist-info → gomyck_tools-1.4.7.dist-info}/WHEEL +1 -1
  85. gomyck_tools-1.4.7.dist-info/licenses/LICENSE +13 -0
  86. ctools/bashPath.py +0 -13
  87. ctools/bottle_server.py +0 -49
  88. ctools/console.py +0 -55
  89. ctools/date_utils.py +0 -44
  90. ctools/enums.py +0 -4
  91. ctools/excelOpt.py +0 -36
  92. ctools/imgDialog.py +0 -44
  93. ctools/license.py +0 -37
  94. ctools/log.py +0 -28
  95. ctools/mvc.py +0 -56
  96. ctools/obj.py +0 -20
  97. ctools/pacth.py +0 -73
  98. ctools/ssh.py +0 -9
  99. ctools/strDiff.py +0 -20
  100. ctools/string_tools.py +0 -101
  101. ctools/token_tools.py +0 -13
  102. ctools/wordFill.py +0 -24
  103. gomyck_tools-1.0.0.dist-info/METADATA +0 -20
  104. gomyck_tools-1.0.0.dist-info/RECORD +0 -54
  105. /ctools/{word_fill_entity.py → office/word_fill_entity.py} +0 -0
  106. /ctools/{compile_tools.py → util/compile_util.py} +0 -0
  107. {gomyck_tools-1.0.0.dist-info → gomyck_tools-1.4.7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,79 @@
1
+ from bottle import ServerAdapter, Bottle
2
+ from geventwebsocket.handler import WebSocketHandler
3
+
4
+ from ctools import sys_log
5
+
6
+ """
7
+ module_names = list(globals().keys())
8
+ def get_modules():
9
+ mods = []
10
+ for modname in module_names:
11
+ if modname == 'base' or modname == 'online' or modname.startswith('__') or modname == 'importlib': continue
12
+ module = globals()[modname]
13
+ mods.append(module)
14
+ return mods
15
+
16
+ def get_ws_modules():
17
+ from . import websocket
18
+ return [websocket]
19
+ """
20
+
21
+ """
22
+ ws_app = bottle_web_base.init_app('/websocket_demo')
23
+
24
+ @ws_app.route('/script_debug', apply=[websocket])
25
+ @bottle_web_base.rule('DOC:DOWNLOAD')
26
+ def script_debug(ws: WebSocket):
27
+ print(123)
28
+
29
+ socket_app = bottle_websocket.init_bottle()
30
+ socket_app.mount(app.context_path, ws_app)
31
+ socket_app.run()
32
+ """
33
+
34
+ _default_port = 8887
35
+
36
+
37
+ class CBottle:
38
+
39
+ def __init__(self, bottle: Bottle, port=_default_port, quiet=False):
40
+ self.port = port
41
+ self.quiet = quiet
42
+ self.bottle = bottle
43
+
44
+ def run(self):
45
+ socket_server = WebSocketServer(port=self.port)
46
+ self.bottle.run(server=socket_server, quiet=self.quiet)
47
+
48
+ def mount(self, context_path, app):
49
+ self.bottle.mount(context_path, app)
50
+
51
+
52
+ def init_bottle(port=_default_port, quiet=False) -> CBottle:
53
+ bottle = Bottle()
54
+ return CBottle(bottle, port, quiet)
55
+
56
+
57
+ class CustomWebSocketHandler(WebSocketHandler):
58
+ def log_request(self):
59
+ if '101' not in str(self.status):
60
+ log_msg = self.format_request()
61
+ for nk in sys_log.neglect_keywords:
62
+ if nk in log_msg:
63
+ return
64
+ self.logger.info(log_msg)
65
+
66
+
67
+ class WebSocketServer(ServerAdapter):
68
+
69
+ def __init__(self, host='0.0.0.0', port=_default_port):
70
+ super().__init__(host, port)
71
+ self.server = None
72
+
73
+ def run(self, handler):
74
+ from gevent import pywsgi
75
+ self.server = pywsgi.WSGIServer((self.host, self.port), handler, handler_class=CustomWebSocketHandler)
76
+ self.server.serve_forever()
77
+
78
+ def stop(self):
79
+ self.server.stop()
ctools/web/ctoken.py ADDED
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: UTF-8 -*-
3
+ __author__ = 'haoyang'
4
+ __date__ = '2025/1/21 16:01'
5
+
6
+ import time
7
+
8
+ import jwt
9
+ from bottle import request
10
+
11
+ from ctools import cid
12
+ from ctools.dict_wrapper import DictWrapper
13
+
14
+
15
+ class CToken:
16
+ token_audience = ["gomyck"]
17
+ token_secret_key = 'gomyck123'
18
+ token_header = 'Authorization'
19
+
20
+ def gen_token(userid, username, payload={}, expired: int = 3600, rules= []) -> str:
21
+ if expired and expired > 0: payload.update({'exp': time.time() + expired})
22
+ payload.update({'iss': "gomyck", 'jti': cid.get_snowflake_id_str(), 'nbf': time.time(), 'iat': time.time()})
23
+ payload.update({'rules': rules})
24
+ payload.update({'uid': userid})
25
+ payload.update({'sub': username})
26
+ payload.update({'aud': CToken.token_audience})
27
+ payload.update({'rules': rules})
28
+ return jwt.encode(payload, CToken.token_secret_key, algorithm='HS256')
29
+
30
+ def get_payload(token=None):
31
+ try:
32
+ if token is None: token = get_token()
33
+ payload = jwt.decode(token, options={"verify_signature": False}, algorithms=['HS256'])
34
+ return DictWrapper(payload)
35
+ except Exception as e:
36
+ return None
37
+
38
+ def get_token_payload(token=None):
39
+ if token is None: token = get_token()
40
+ return get_payload(token)
41
+
42
+ def is_valid(token=None):
43
+ """
44
+ 判断token是否有效
45
+ :param token: token 信息
46
+ :return: 是否有效
47
+ """
48
+ if token is None: token = get_token()
49
+ if token is None: return False
50
+ try:
51
+ jwt.decode(token, CToken.token_secret_key, algorithms=['HS256'], audience=CToken.token_audience)
52
+ except Exception as e:
53
+ print(e)
54
+ return False
55
+ return True
56
+
57
+ def get_user_name():
58
+ """
59
+ 获取用户名称
60
+ :return: 用户ID
61
+ """
62
+ token_obj = get_token_attr("sub")
63
+ return token_obj
64
+
65
+ def get_user_id():
66
+ """
67
+ 获取用户ID
68
+ :return: 用户ID
69
+ """
70
+ token_obj = get_token_attr("uid")
71
+ return token_obj
72
+
73
+ def get_token_id():
74
+ """
75
+ 获取token id
76
+ :return: token id
77
+ """
78
+ token_obj = get_token_attr("jti")
79
+ return token_obj
80
+
81
+ def get_app_flag() -> []:
82
+ """
83
+ 获取服务标识
84
+ :return: 服务标识 []
85
+ """
86
+ token_obj = get_token_attr("aud")
87
+ return token_obj
88
+
89
+ def get_token_attr(attr):
90
+ token_obj = get_token_payload()
91
+ return getattr(token_obj, attr, None)
92
+
93
+ def get_token():
94
+ auth_token = request.get_header(CToken.token_header)
95
+ if auth_token is None:
96
+ auth_token = request.get_cookie(CToken.token_header)
97
+ return auth_token
98
+
99
+ # if __name__ == '__main__':
100
+ # token = gen_token(123, username='xxx', expired=0)
101
+ # print(token)
102
+ # print(get_payload(token))
103
+ # print(is_valid(token))
@@ -3,7 +3,8 @@ from urllib.parse import urlencode
3
3
 
4
4
  from bottle import static_file, HTTPResponse
5
5
 
6
- from ctools import sys_log, http_utils
6
+ from ctools import sys_log
7
+ from ctools.util import http_util
7
8
 
8
9
  log = sys_log.flog
9
10
 
@@ -12,44 +13,45 @@ log = sys_log.flog
12
13
  """
13
14
 
14
15
 
15
- def download(file_path: str):
16
+ def download(file_path: str, download_name: str = None):
16
17
  """
17
18
  文件下载
18
19
  :param file_path: 静态文件路径
20
+ :param download_name: 下载文件名
19
21
  :return:
20
22
  """
21
23
  if os.path.exists(file_path):
22
24
  root_path = os.path.split(file_path)[0]
23
25
  file_name = os.path.split(file_path)[1]
24
- encoded_filename = urlencode({'filename': file_name}).split("=")[-1] # 对文件名进行URL编码
25
- response = static_file(file_path, root=root_path, download=True)
26
+ download_filename = urlencode({'filename': download_name or file_name}).split("=")[-1] # 对文件名进行URL编码
27
+ response = static_file(file_name, root=root_path, download=True)
26
28
  # 设置响应头,告诉浏览器这是一个文件下载
27
29
  response.headers['Content-Type'] = 'application/octet-stream;charset=utf-8'
28
- response.headers['Content-Disposition'] = f'attachment; filename={encoded_filename}'
29
- log.debug("下载文件成功, file_path: %s" % file_path)
30
+ response.headers['Content-Disposition'] = f'attachment; filename={download_filename}'
31
+ log.debug(f"下载文件成功, file_path: {file_path}, file_name: {file_name}, download_name: {download_name}")
30
32
  else:
31
33
  response = None
32
34
  log.info("下载文件失败, 此文件不存在, file_path: %s" % file_path)
33
35
  return response
34
36
 
35
37
 
36
- def download_bytes(file_name: str, file_bytes: bytes):
38
+ def download_bytes(file_bytes: bytes, download_name: str):
37
39
  """
38
40
  文件下载
39
- :param file_name:
40
- :param file_bytes:
41
+ :param file_bytes: file_bytes
42
+ :param download_name: download_name
41
43
  :return:
42
44
  """
43
- encoded_filename = urlencode({'filename': file_name}).split("=")[-1] # 对文件名进行URL编码
45
+ download_filename = urlencode({'filename': download_name}).split("=")[-1] # 对文件名进行URL编码
44
46
  # 设置响应头,告诉浏览器这是一个文件下载
45
47
  headers = {"Accept-Ranges": "bytes", "Content-Length": len(file_bytes),
46
48
  'Content-Type': 'application/octet-stream;charset=utf-8',
47
- 'Content-Disposition': f'attachment; filename={encoded_filename}'}
49
+ 'Content-Disposition': f'attachment; filename={download_filename}'}
48
50
  return HTTPResponse(file_bytes, **headers)
49
51
 
50
52
 
51
53
  def download_url(url: str, save_path: str):
52
- content = http_utils.get(url)
54
+ content = http_util.get(url)
53
55
  if content:
54
56
  with open(save_path, "wb") as f:
55
57
  f.write(content)
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: UTF-8 -*-
3
+ __author__ = 'haoyang'
4
+ __date__ = '2025/6/11 09:35'
5
+
6
+
7
+ def is_list(v: str):
8
+ try:
9
+ list(v)
10
+ if v[0] == "[" and v[-1] == "]":
11
+ return True
12
+ else:
13
+ return False
14
+ except Exception:
15
+ return False
16
+
17
+
18
+ def is_digit(v: str):
19
+ try:
20
+ float(v)
21
+ return True
22
+ except Exception:
23
+ return False
24
+
25
+
26
+ def is_bool(v: str):
27
+ if v in ["False", "True"]:
28
+ return True
29
+ else:
30
+ return False
31
+
32
+
33
+ def dict_to_params(obj: dict):
34
+ params = ""
35
+ for k, v in obj.items():
36
+ if k == 'varname':
37
+ continue
38
+ v = str(v)
39
+ if not is_list(v) and not is_digit(v) and not is_bool(v):
40
+ if k == "path" and v[:4] != "http":
41
+ v = "r'%s'" % v
42
+ else:
43
+ v = "'%s'" % v
44
+ params += "%s=%s, " % (k, v)
45
+ params = params[:params.rfind(',')]
46
+ return params
@@ -1,6 +1,7 @@
1
1
  import os
2
2
 
3
- from ctools import sys_log, date_utils
3
+ from ctools import cdate
4
+ from ctools import sys_log
4
5
 
5
6
  log = sys_log.flog
6
7
 
@@ -25,7 +26,7 @@ def save(upload, output_dir: str, file_name: str = None):
25
26
  if not unique_filename:
26
27
  # 生成不重复的文件名,加上时间戳
27
28
  file_name, ext = os.path.splitext(upload.raw_filename)
28
- timestamp = date_utils.get_time()
29
+ timestamp = cdate.get_time()
29
30
  unique_filename = f'{file_name}_{timestamp}{ext}'
30
31
  else:
31
32
  dot_index = unique_filename.find(".")
@@ -0,0 +1,70 @@
1
+ Metadata-Version: 2.4
2
+ Name: gomyck-tools
3
+ Version: 1.4.7
4
+ Summary: A tools collection for python development by hao474798383
5
+ Author-email: gomyck <hao474798383@163.com>
6
+ License-Expression: Apache-2.0
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: jsonpickle~=3.4.2
11
+ Requires-Dist: SQLAlchemy~=2.0.36
12
+ Requires-Dist: chardet~=5.2.0
13
+ Requires-Dist: psycopg2-binary~=2.9.10
14
+ Requires-Dist: croniter~=5.0.1
15
+ Requires-Dist: gmssl~=3.2.2
16
+ Requires-Dist: psutil~=6.1.0
17
+ Requires-Dist: jsonpath_ng~=1.7.0
18
+ Requires-Dist: bottle~=0.13.4
19
+ Requires-Dist: requests~=2.32.3
20
+ Requires-Dist: urllib3~=1.26.20
21
+ Requires-Dist: kafka-python~=2.0.2
22
+ Requires-Dist: bs4~=0.0.2
23
+ Requires-Dist: paho-mqtt~=2.1.0
24
+ Requires-Dist: fuzzywuzzy~=0.18.0
25
+ Requires-Dist: pymysql~=1.1.1
26
+ Requires-Dist: pyzipper==0.3.6
27
+ Requires-Dist: prometheus_client==0.21.1
28
+ Requires-Dist: paramiko==3.5.0
29
+ Requires-Dist: pyjwt==2.10.1
30
+ Requires-Dist: cryptography==44.0.2
31
+ Requires-Dist: redis==5.2.1
32
+ Requires-Dist: uvloop>=0.21.0
33
+ Requires-Dist: pyyaml>=6.0.2
34
+ Provides-Extra: kwc
35
+ Requires-Dist: imageio>=2.37.0; extra == "kwc"
36
+ Requires-Dist: wordcloud>=1.9.4; extra == "kwc"
37
+ Requires-Dist: jieba==0.42.1; extra == "kwc"
38
+ Requires-Dist: paddlepaddle==2.6.1; extra == "kwc"
39
+ Provides-Extra: cut
40
+ Requires-Dist: jieba==0.42.1; extra == "cut"
41
+ Requires-Dist: paddlepaddle==2.6.1; extra == "cut"
42
+ Provides-Extra: ml
43
+ Requires-Dist: scikit-learn>=1.7.1; extra == "ml"
44
+ Requires-Dist: pandas>=2.3.2; extra == "ml"
45
+ Requires-Dist: lxml>=6.0.1; extra == "ml"
46
+ Requires-Dist: xlrd>=2.0.2; extra == "ml"
47
+ Dynamic: license-file
48
+
49
+ # Gomyck-Tools
50
+
51
+ ## project
52
+
53
+ https://github.com/mzxc
54
+
55
+ ## install
56
+
57
+ This package need python version >= 3.9
58
+
59
+ ```shell
60
+ pip install gomyck-tools
61
+ ```
62
+
63
+ ## usage
64
+
65
+ ```python
66
+ from ctools import sys_log
67
+ sys_log.clog.info('hello world')
68
+ ```
69
+
70
+
@@ -0,0 +1,88 @@
1
+ ctools/__init__.py,sha256=7EtnbO7mi1iYQeyU4CLusYrwO96_dC7eR7jboyWAqvg,1089
2
+ ctools/application.py,sha256=QFLbwmjznz2HAwVyph9PhzMpJUU5R82eMaVcw5UDSMk,15899
3
+ ctools/aspect.py,sha256=lXrpeu_F3w6v2Hu2yOwQIRGqfDN25_H-1YyW6fPt_mw,1667
4
+ ctools/call.py,sha256=TFFC8PqvCu0PS0XelmV4QXdXezQiUsEacxg3RgKvdwE,1572
5
+ ctools/cdate.py,sha256=OhKAaQfo2Rxd3Jx3g9AfPsaISRoLkstqZdaGT4ZZr_I,3096
6
+ ctools/cdebug.py,sha256=_mihZRCEx_bi7Kv_QPjP4MPLNFrl-GR1Y_irTgOP7OU,4021
7
+ ctools/cid.py,sha256=utxK9u6Df1HuMaiQztqnJ5EENYaJHzZ0pCIuXpveckA,401
8
+ ctools/cjson.py,sha256=XloZIRnc8Wd8OsTAqDRvhmkqbj97KtyzXTDWJm-unZk,1370
9
+ ctools/cron_lite.py,sha256=rVu9S2oouaw_XZ5RMDJidCNepg5yoEJwLcfcaGTuJRA,8235
10
+ ctools/dict_wrapper.py,sha256=0NRtHUX7MVjfIyms_gJiofGcD-x4lBCnaSpkk5yDdjE,461
11
+ ctools/ex.py,sha256=9npepunW0G1obXqjnvUEiNAjQ5XDazZvEtlF5ceFRCM,869
12
+ ctools/metrics.py,sha256=8d0ymwyHF5vDnVmjVqny5puLljX_mSsqAH8BI3tiMYg,5254
13
+ ctools/patch.py,sha256=2eIle4uVTIcy1QMB1LbApo47cQTJ8GnXMihp-Mkgse0,3128
14
+ ctools/path_info.py,sha256=JoEGPeeSu1jMGTIquq2CZFMe7Ergg8gL4DPt3_Q4q0U,2688
15
+ ctools/similar.py,sha256=ByOFaJ2AHZBe3ekoEco5miXcZP1XW7vGecH1i3dES5g,698
16
+ ctools/sys_info.py,sha256=QynB_2nQeGUuUdqJQldtEq916gDfPBsei1OWx9GYKSI,4278
17
+ ctools/sys_log.py,sha256=Sud91NQEVIiqiW6zffv-LrdmVKqva9ijUpdhTxrQhDA,2782
18
+ ctools/ai/__init__.py,sha256=gTYAICILq48icnFbg0HCbsQO8PbU02EDOQ0JeMvfqTY,98
19
+ ctools/ai/llm_chat.py,sha256=vgv1C72fv7YEGj_203L6JY_PyDszxvhrlLjLYbxuvZk,9133
20
+ ctools/ai/llm_client.py,sha256=0xHvSQoAd4PAnunyH2a-cJ9RKTkWO1cFyrnqmA1j3g0,6178
21
+ ctools/ai/llm_exception.py,sha256=wsCVl0m53Mk7Xfug1obocAthlX0oEo4dytg1eOhWHPg,389
22
+ ctools/ai/mcp/__init__.py,sha256=gTYAICILq48icnFbg0HCbsQO8PbU02EDOQ0JeMvfqTY,98
23
+ ctools/ai/mcp/mcp_client.py,sha256=UU7TSMreWcSmbOVoyH02YSVzxE3peg89Z5Hifyg3RlQ,11946
24
+ ctools/ai/tools/__init__.py,sha256=gPc-ViRgtFlfX7JUbk5wQZ3wkJ5Ylh14CIqPwa83VPs,98
25
+ ctools/ai/tools/json_extract.py,sha256=FLrwrpYxAYQ0nvUok9OhmVQUaWhOpftDS4-uJIV3j0o,4839
26
+ ctools/ai/tools/quick_tools.py,sha256=Z0eJGEdQbEq7rNQtIO0WwEE94mbtu-JTtyehyJOwtMQ,3028
27
+ ctools/ai/tools/think_process.py,sha256=RGU9j3_O328Byw05ILek-aMfFBczbly2RA-QRouqUjM,257
28
+ ctools/ai/tools/tool_use_xml_parse.py,sha256=xZkxbXoOR5o_mEaUgKfD6oMGsc0BVxNJk5FO4_uvQ_4,1430
29
+ ctools/ai/tools/xml_extract.py,sha256=u1HZFCbMDwmNAvSPBia6-7H3WoRHN6oUQ8wGG5A2WHw,234
30
+ ctools/auto/__init__.py,sha256=zERjXFeDwOnR6GW77qJfpxTFv-otJK2HvI241-214N4,98
31
+ ctools/auto/browser_element.py,sha256=pbcAS8V6KaEflIaV4BEQxIcFapW9ZtMvv_RsaraP1Cc,9969
32
+ ctools/auto/plan_area.py,sha256=kPCOGxHG8KIdE1wjm62u-5MWqmlbaoW8ZIjVj5kpims,3370
33
+ ctools/auto/pty_process.py,sha256=0lHow3na3M3f7EFx7IPM9petdSZC9iTEF7a246pv0GQ,1622
34
+ ctools/auto/resource_bundle.py,sha256=FA0p_yLp6dxVwCqUgorVUq495J-RDhmCMe5P5f4F_oc,3796
35
+ ctools/auto/screenshot.py,sha256=Uu8rHG2jKQh6Dj39c3oNujU6O_5qnvnwXhVJ88WtLbI,4558
36
+ ctools/auto/win_canvas.py,sha256=zr4ND0wjKlbP_YM9jJBbl4GEr_I5UvJ8CPS_JJhrRaE,2531
37
+ ctools/auto/win_control.py,sha256=r7OUc9YsQsU6bIpJPnBFvfVks5flmjOpAzT-v47fCJk,3543
38
+ ctools/cipher/__init__.py,sha256=OkUaZv5ckkXJFNbRyFZqkX5m3GxTueEGEBU99_jJQNE,98
39
+ ctools/cipher/aes_util.py,sha256=IOkvo89jOOqpjvFDehS2jgy-q7QD8_Vxcjgt-vqmyLE,699
40
+ ctools/cipher/b64.py,sha256=TLVYRCZc4BowPGk-RoSz89o9mqpDmFW8IlceP_KNZcI,196
41
+ ctools/cipher/czip.py,sha256=7zNaafiG-O6NkaSv4cBP8jxUBqCTmCmPsd6efX0bu9Y,4679
42
+ ctools/cipher/rsa.py,sha256=7TPwlt-JQxDVHwvL_Am9ZKI70B2CfJDqQDf473edHSQ,2264
43
+ ctools/cipher/sign.py,sha256=i__5PVevvR2-VjJyInmyH1QJOpmuxcA9ZIM0oxxFWVo,567
44
+ ctools/cipher/sm_util.py,sha256=cC58wZ9IL08SvUfWUNjX5139fal2SnXGaFQ0R9WA3SE,1675
45
+ ctools/database/__init__.py,sha256=fB36UC93Pya_1YyWGMzDy3D4tMDTBQoYK20E4wgNqec,98
46
+ ctools/database/database.py,sha256=yfW8nw6_rONYz6F1343hmwy_es6eh3WEtKt9jIrStHk,7220
47
+ ctools/geo/__init__.py,sha256=OkUaZv5ckkXJFNbRyFZqkX5m3GxTueEGEBU99_jJQNE,98
48
+ ctools/geo/coord_trans.py,sha256=UWCU1wnrTDU1aLSVAwmiHOeH7Pu-Dp8lDLAngDG48NM,3761
49
+ ctools/geo/douglas_rarefy.py,sha256=bJo6TwNxPa-7-8MOi8MULxeqnz4cvIJN-oXqBDWNAVM,4883
50
+ ctools/office/__init__.py,sha256=wum34b8YJg0qD7uKdDEbozSE8RIxWqTVa44CCIZyqPU,98
51
+ ctools/office/cword.py,sha256=bIthKmf0oBqjcdkrU5hFDAPp66ZrjeMNzjIxOlMPeCc,837
52
+ ctools/office/word_fill.py,sha256=ZoTxz0-agEy5atIRWqYmQZz82nVr2zz9JebSTMkulIo,18214
53
+ ctools/office/word_fill_entity.py,sha256=eX3G0Gy16hfGpavQSEkCIoKDdTnNgRRJrFvKliETZK8,985
54
+ ctools/pkg/__init__.py,sha256=MVdmAIChV2Jx9OaBGq639vNGsshVvKVAc3lf7hN90Yg,98
55
+ ctools/pkg/dynamic_imp.py,sha256=rHPPq5gHCOxSgKv4kuU3xOUI0tc_oU5CJd9rourSQbA,1256
56
+ ctools/pools/__init__.py,sha256=3_W3mvEs6pInRTvK7TqOPu9dC2z8rCHvHZFXO4KNYT8,98
57
+ ctools/pools/process_pool.py,sha256=p6Mrh59gXrL9wpQ1dS72-GKtX_lEoAFc4_PLrXjukPk,957
58
+ ctools/pools/thread_pool.py,sha256=ekfoxowyaKWUgevUgRbwee27IFJpqNoz-w27urlX_q8,948
59
+ ctools/stream/__init__.py,sha256=mf8vkbcJdYpvDslgXkkHOz6rKBzU1qfxi8xQGQ1A90w,98
60
+ ctools/stream/ckafka.py,sha256=_vTMIVQBjjsW1iH29BXNQrvEWGgdacDBm3ZrjBjBUGk,5938
61
+ ctools/stream/credis.py,sha256=qxfkhtwHCvGN2eUAr9lpS42um02IXkcZTmiMXs0_Yfg,4551
62
+ ctools/stream/mqtt_utils.py,sha256=HOT8uFOXmgPFRvxcmBPXlOJuhekupleaYwB47lGVSpk,10718
63
+ ctools/util/__init__.py,sha256=jJLxgj-rdTVIo_czMcN83-HQI9yyBYy1L5gw8ZAbmyc,98
64
+ ctools/util/cftp.py,sha256=ESLFNW7yfRYD4e_c777Gmm4jf9Vks4waGe_TKncgxMQ,2485
65
+ ctools/util/cklock.py,sha256=uS1g8H7jtQ5dINKe-k23osQ1sjvZSZrkXGwH6qKcgNo,3234
66
+ ctools/util/compile_util.py,sha256=Nybh3vnkurIKnPnubdYzigjnzFu4GaTMKPvqFdibxmE,510
67
+ ctools/util/config_util.py,sha256=FBacCqQ1kPtRl1VEz0IsAuxI0zdpqUiuBv11G8kiDLE,1230
68
+ ctools/util/env_config.py,sha256=L98G9LPdpD7Yl5XbA_-KfkcA4mDunQoKiYtK5w7QR-s,1790
69
+ ctools/util/html_soup.py,sha256=rnr8M3gn3gQGo-wNaNFXDjdzp8AAkv9o4yqfIIfO-zw,1567
70
+ ctools/util/http_util.py,sha256=cx0FRnPLFdJ0mF9UYphl40SZj68fqG30Q0udku9hZIE,769
71
+ ctools/util/image_process.py,sha256=nqJOi2p8wLe8wRsfkH99MyEYSjE9i4fthxBJwrrZVB8,835
72
+ ctools/util/jb_cut.py,sha256=h8Ey-LbpHtbAHskITn5GXEO7-DHJ_ZLODmE8Lc_dgSc,1664
73
+ ctools/util/snow_id.py,sha256=KCuQ0zOTlmus8gZetmRA5y0jBSd8J0KXcJ33EzgCKjE,2225
74
+ ctools/web/__init__.py,sha256=koSNYeKF5Z_xbp4Q2qbZ4ZP-3--1phbOYN9e4SJy_gk,98
75
+ ctools/web/aio_web_server.py,sha256=p46BOU3_m4Jb57yAACeedKjhlFc1YC0QJSUe2selBgA,5693
76
+ ctools/web/api_result.py,sha256=i1MjTnnlgkWl_q07xr-TLQeLYlXEh4DEclUFE414nSk,1568
77
+ ctools/web/bottle_web_base.py,sha256=ezifwvLGakHViVhILgCL6E89VQB_6pL62ZTUapNQpg0,8661
78
+ ctools/web/bottle_webserver.py,sha256=0xHLnuGIShxrEHc2mLnyx43NDVkCqM5QnlkY-Ndzrk4,6650
79
+ ctools/web/bottle_websocket.py,sha256=xsu9fAtTuR5DsSsQjiBfaYxLjOWFyfr1sYM6cktTovI,1957
80
+ ctools/web/ctoken.py,sha256=WaB29kqGlKAh21aUw5avl2h8AgLD1aESw8KCpqaN5nM,2539
81
+ ctools/web/download_util.py,sha256=v0JTXiED1bvoWFfwfd-LD5s7_aoRQ0lCkaGwSnSp7WI,1954
82
+ ctools/web/params_util.py,sha256=eJDV3PSq-ZHb8UZf6xqs8kOhbyZzits1H9yPoUBIDXg,828
83
+ ctools/web/upload_util.py,sha256=z1QQCi4SFx08jrAQH5-Y_ShiM4MghuD_5Qz6V9KK_4U,1076
84
+ gomyck_tools-1.4.7.dist-info/licenses/LICENSE,sha256=X25ypfH9E6VTht2hcO8k7LCSdHUcoG_ALQt80jdYZfY,547
85
+ gomyck_tools-1.4.7.dist-info/METADATA,sha256=hHtf1YheL3SCsl0LbLWKzErlHDUncUMEBMozNXXZxII,1826
86
+ gomyck_tools-1.4.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
87
+ gomyck_tools-1.4.7.dist-info/top_level.txt,sha256=-MiIH9FYRVKp1i5_SVRkaI-71WmF1sZSRrNWFU9ls3s,7
88
+ gomyck_tools-1.4.7.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.2)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,13 @@
1
+ Copyright 2025 gomyck
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
ctools/bashPath.py DELETED
@@ -1,13 +0,0 @@
1
- import inspect
2
- import os
3
- import sys
4
-
5
-
6
- def path(subPath: str = '') -> str:
7
- if getattr(sys, 'frozen', False):
8
- base_path = sys._MEIPASS
9
- else:
10
- caller_frame = inspect.currentframe().f_back
11
- caller_path = caller_frame.f_globals["__file__"]
12
- base_path = os.path.dirname(caller_path)
13
- return base_path + os.path.sep + subPath
ctools/bottle_server.py DELETED
@@ -1,49 +0,0 @@
1
- from bottle import ServerAdapter
2
- from socketserver import ThreadingMixIn
3
- from wsgiref.simple_server import WSGIServer, WSGIRequestHandler, make_server
4
- from geventwebsocket.handler import WebSocketHandler
5
- from ctools import sys_log
6
-
7
- class ThreadedWSGIServer(ThreadingMixIn, WSGIServer): pass
8
-
9
- class CustomWSGIHandler(WSGIRequestHandler):
10
- def log_request(*args, **kw): pass
11
-
12
- class CustomWebSocketHandler(WebSocketHandler):
13
- def log_request(self):
14
- if '101' not in str(self.status):
15
- log_msg = self.format_request()
16
- for nk in sys_log.neglect_keywords:
17
- if nk in log_msg:
18
- return
19
- self.logger.info(log_msg)
20
-
21
- class WSGIRefServer(ServerAdapter):
22
-
23
- def __init__(self, host='0.0.0.0', port=8010):
24
- super().__init__(host, port)
25
- self.server = None
26
-
27
- def run(self, handler):
28
- req_handler = WSGIRequestHandler
29
- if self.quiet: req_handler = CustomWSGIHandler
30
- self.server = make_server(self.host, self.port, handler, server_class=ThreadedWSGIServer, handler_class=req_handler)
31
- self.server.serve_forever()
32
-
33
- def stop(self):
34
- self.server.shutdown()
35
-
36
-
37
- class WebSocketServer(ServerAdapter):
38
-
39
- def __init__(self, host='0.0.0.0', port=8012):
40
- super().__init__(host, port)
41
- self.server = None
42
-
43
- def run(self, handler):
44
- from gevent import pywsgi
45
- self.server = pywsgi.WSGIServer((self.host, self.port), handler, handler_class=CustomWebSocketHandler)
46
- self.server.serve_forever()
47
-
48
- def stop(self):
49
- self.server.stop()
ctools/console.py DELETED
@@ -1,55 +0,0 @@
1
- import sys
2
- import tkinter as tk
3
- import logging
4
-
5
-
6
- class Console:
7
-
8
- def __init__(self, master):
9
- self.master = master
10
-
11
- # 创建文本框和滚动条
12
- self.textbox = tk.Text(self.master, wrap=tk.NONE)
13
-
14
- self.vertical_scrollbar = tk.Scrollbar(self.textbox, command=self.textbox.yview)
15
- self.horizontal_scrollbar = tk.Scrollbar(self.textbox, command=self.textbox.xview, orient=tk.HORIZONTAL)
16
-
17
- self.textbox.configure(yscrollcommand=self.vertical_scrollbar.set, xscrollcommand=self.horizontal_scrollbar.set)
18
- self.textbox.pack(side=tk.LEFT, pady=10, padx=10, ipadx=10, ipady=10, fill=tk.BOTH, expand=True)
19
-
20
- self.vertical_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
21
- self.horizontal_scrollbar.pack(side=tk.BOTTOM, fill=tk.X)
22
-
23
- # 将标准输出和标准错误输出重定向到文本框中
24
- sys.stdout = self
25
- sys.stderr = self
26
-
27
- # # 创建输入框和按钮
28
- # self.entry = tk.Entry(self.master)
29
- # self.entry.pack(side=tk.BOTTOM, fill=tk.X, expand=True)
30
- # self.button = tk.Button(self.master, text="Send", command=self.send)
31
- # self.button.pack(side=tk.BOTTOM)
32
-
33
- # 将日志输出到文本框中
34
- self.log_handler = logging.StreamHandler(self)
35
- self.log_handler.setFormatter(logging.Formatter('%(asctime)s - %(message)s'))
36
- logging.getLogger().addHandler(self.log_handler)
37
- # logging.getLogger().setLevel(logging.INFO)
38
-
39
- def write(self, message):
40
- # 在文本框中输出消息
41
- self.textbox.insert(tk.END, message + '\n')
42
- self.textbox.see(tk.END)
43
-
44
- def flush(self):
45
- pass
46
-
47
- def send(self):
48
- # 获取输入框中的文本并打印到控制台
49
- text = self.entry.get()
50
- print(text)
51
- self.entry.delete(0, tk.END)
52
-
53
- def __del__(self):
54
- # 关闭日志处理器
55
- logging.getLogger().removeHandler(self.log_handler)
ctools/date_utils.py DELETED
@@ -1,44 +0,0 @@
1
- import time
2
-
3
-
4
- def get_date():
5
- """
6
- 获取 %Y-%m-%d格式时间
7
- :return:
8
- """
9
- return time.strftime('%Y-%m-%d', time.localtime(time.time()))
10
-
11
-
12
- def get_time():
13
- """
14
- 获取 %H-%M-%S格式时间
15
- :return:
16
- """
17
- return time.strftime('%H-%M-%S', time.localtime(time.time()))
18
-
19
-
20
- def get_date_time(offset=0):
21
- """
22
- 获取 %Y-%m-%d %H:%M:%S格式时间
23
- :return:
24
- """
25
- return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time() + offset))
26
-
27
-
28
- def get_file_time():
29
- """
30
- 获取 %Y-%m-%d %H:%M:%S 文件格式时间
31
- :return:
32
- """
33
- return time.strftime('%Y-%m-%d_%H-%M-%S', time.localtime(time.time()))
34
-
35
- def get_timestamp(offset=0):
36
- return int(time.time() + offset)
37
-
38
- def str_to_timestamp(val: str):
39
- return time.mktime(time.strptime(val, "%Y-%m-%d %H:%M:%S"))
40
-
41
- def str_to_datetime(val: str):
42
- return time.strptime(val, "%Y-%m-%d %H:%M:%S")
43
-
44
-
ctools/enums.py DELETED
@@ -1,4 +0,0 @@
1
- def value_of(e, v):
2
- for member_name, member in e.__members__.items():
3
- if member.value == v:
4
- return member