gomyck-tools 0.1.0__py3-none-any.whl → 1.0.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.
- {tools → ctools}/application.py +4 -4
- {tools → ctools}/bottle_server.py +1 -1
- {tools → ctools}/browser_element_tools.py +1 -1
- {tools → ctools}/cjson.py +1 -0
- ctools/ckafka.py +152 -0
- {tools → ctools}/cron_lite.py +111 -99
- {tools → ctools}/database.py +7 -7
- {tools → ctools}/download_tools.py +1 -1
- {tools → ctools}/html_soup.py +1 -1
- {tools → ctools}/license.py +1 -1
- {tools → ctools}/metrics.py +2 -21
- {tools → ctools}/mqtt_utils.py +1 -1
- {tools → ctools}/pacth.py +1 -1
- {tools → ctools}/plan_area_tools.py +1 -1
- {tools → ctools}/resource_bundle_tools.py +1 -1
- {tools → ctools}/screenshot_tools.py +1 -1
- {tools → ctools}/string_tools.py +1 -1
- {tools → ctools}/sys_info.py +1 -1
- {tools → ctools}/sys_log.py +2 -4
- {tools → ctools}/thread_pool.py +5 -1
- {tools → ctools}/upload_tools.py +1 -1
- {tools → ctools}/win_control.py +1 -1
- {tools → ctools}/word_fill.py +2 -2
- {gomyck_tools-0.1.0.dist-info → gomyck_tools-1.0.1.dist-info}/METADATA +10 -8
- gomyck_tools-1.0.1.dist-info/RECORD +54 -0
- gomyck_tools-1.0.1.dist-info/top_level.txt +1 -0
- gomyck_tools-0.1.0.dist-info/RECORD +0 -54
- gomyck_tools-0.1.0.dist-info/top_level.txt +0 -1
- tools/token_tools.py +0 -13
- {tools → ctools}/__init__.py +0 -0
- {tools → ctools}/aes_tools.py +0 -0
- {tools → ctools}/b64.py +0 -0
- {tools → ctools}/bashPath.py +0 -0
- {tools → ctools}/call.py +0 -0
- {tools → ctools}/compile_tools.py +0 -0
- {tools → ctools}/console.py +0 -0
- {tools → ctools}/date_utils.py +0 -0
- {tools → ctools}/enums.py +0 -0
- {tools → ctools}/ex.py +0 -0
- {tools → ctools}/excelOpt.py +0 -0
- {tools → ctools}/http_utils.py +0 -0
- {tools → ctools}/id_worker_tools.py +0 -0
- {tools → ctools}/images_tools.py +0 -0
- {tools → ctools}/imgDialog.py +0 -0
- {tools → ctools}/log.py +0 -0
- {tools → ctools}/mvc.py +0 -0
- {tools → ctools}/obj.py +0 -0
- {tools → ctools}/pty_tools.py +0 -0
- {tools → ctools}/sign.py +0 -0
- {tools → ctools}/sm_tools.py +0 -0
- {tools → ctools}/ssh.py +0 -0
- {tools → ctools}/strDiff.py +0 -0
- {tools → ctools}/win_canvas.py +0 -0
- {tools → ctools}/wordFill.py +0 -0
- {tools → ctools}/word_fill_entity.py +0 -0
- {tools → ctools}/work_path.py +0 -0
- {gomyck_tools-0.1.0.dist-info → gomyck_tools-1.0.1.dist-info}/WHEEL +0 -0
{tools → ctools}/application.py
RENAMED
@@ -8,8 +8,8 @@ from configparser import ConfigParser
|
|
8
8
|
|
9
9
|
from PIL import Image
|
10
10
|
|
11
|
-
from
|
12
|
-
from
|
11
|
+
from ctools import work_path, call, sign, thread_pool
|
12
|
+
from ctools.sys_info import get_os_architecture, get_os_architecture4x
|
13
13
|
|
14
14
|
"""
|
15
15
|
本模块引用的依赖, 不允许引用sys_log模块, 否则将报错: 循环引用
|
@@ -157,7 +157,7 @@ def sync_version(callFunc):
|
|
157
157
|
shutil.rmtree(taguiPath)
|
158
158
|
except Exception:
|
159
159
|
pass
|
160
|
-
from
|
160
|
+
from ctools.pacth import Patch
|
161
161
|
patch = Patch(oldVersion='V1.0.0', newVersion=Server.version, pythonPath=pythonPath, playwrightPath=msPlayPath, driverPath=driverPath)
|
162
162
|
patch.apply_patch()
|
163
163
|
if callFunc: callFunc()
|
@@ -172,7 +172,7 @@ def sync_version(callFunc):
|
|
172
172
|
oldVersion.close()
|
173
173
|
if oldV == Server.version and '-snapshot' not in oldV: return
|
174
174
|
print('开始升级本地程序..')
|
175
|
-
from
|
175
|
+
from ctools.pacth import Patch
|
176
176
|
patch = Patch(oldVersion=oldV, newVersion=Server.version, pythonPath=pythonPath, playwrightPath=msPlayPath, driverPath=driverPath)
|
177
177
|
patch.apply_patch()
|
178
178
|
if callFunc: callFunc()
|
@@ -2,7 +2,7 @@ from bottle import ServerAdapter
|
|
2
2
|
from socketserver import ThreadingMixIn
|
3
3
|
from wsgiref.simple_server import WSGIServer, WSGIRequestHandler, make_server
|
4
4
|
from geventwebsocket.handler import WebSocketHandler
|
5
|
-
from
|
5
|
+
from ctools import sys_log
|
6
6
|
|
7
7
|
class ThreadedWSGIServer(ThreadingMixIn, WSGIServer): pass
|
8
8
|
|
@@ -10,7 +10,7 @@ from selenium.webdriver.chrome.service import Service
|
|
10
10
|
from urllib3.exceptions import MaxRetryError
|
11
11
|
from lxml import etree
|
12
12
|
from business.common.constant import Scheduler
|
13
|
-
from
|
13
|
+
from ctools import application, string_tools
|
14
14
|
|
15
15
|
|
16
16
|
keyboard_listener = None
|
{tools → ctools}/cjson.py
RENAMED
ctools/ckafka.py
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
__author__ = 'haoyang'
|
4
|
+
__date__ = '2024/9/5 10:39'
|
5
|
+
|
6
|
+
import signal
|
7
|
+
import sys
|
8
|
+
import time
|
9
|
+
from threading import Thread, Lock
|
10
|
+
|
11
|
+
from kafka import KafkaProducer, errors, KafkaConsumer
|
12
|
+
from kafka.producer.future import FutureRecordMetadata
|
13
|
+
|
14
|
+
from ctools import thread_pool
|
15
|
+
from ctools.cjson import dumps
|
16
|
+
|
17
|
+
"""
|
18
|
+
import time
|
19
|
+
|
20
|
+
from ctools import thread_pool
|
21
|
+
from ctools.ckafka import CKafka
|
22
|
+
|
23
|
+
c = CKafka(kafka_url='192.168.3.160:9094', secure=True)
|
24
|
+
|
25
|
+
def send_msg():
|
26
|
+
while True:
|
27
|
+
time.sleep(3)
|
28
|
+
c.send_msg('test', 'test')
|
29
|
+
|
30
|
+
thread_pool.submit(send_msg)
|
31
|
+
c.get_msg('test')
|
32
|
+
"""
|
33
|
+
|
34
|
+
class CKafka:
|
35
|
+
|
36
|
+
def __init__(self, kafka_url: str = '127.0.0.1:9092', secure: bool = False, username: str = 'client', password: str = 'hylink_user_password', consumer_group: str = 'ck-py-kafka-consumer'):
|
37
|
+
self.consumer: KafkaConsumer = None
|
38
|
+
self.producer: KafkaProducer = None
|
39
|
+
self.start_consumer = False
|
40
|
+
self.consumer_callback = {"topic_key": []}
|
41
|
+
self.consumer_group = consumer_group
|
42
|
+
self.kafka_url = kafka_url
|
43
|
+
self.init_producer = False
|
44
|
+
self.init_consumer = False
|
45
|
+
self.secure = secure
|
46
|
+
self.username = username
|
47
|
+
self.password = password
|
48
|
+
self.locker = Lock()
|
49
|
+
self.quited = False
|
50
|
+
|
51
|
+
def _create_producer(self) -> KafkaProducer:
|
52
|
+
print("[ Producer ] Connecting to Kafka brokers")
|
53
|
+
for i in range(0, 6):
|
54
|
+
try:
|
55
|
+
if self.secure:
|
56
|
+
self.producer = KafkaProducer(
|
57
|
+
bootstrap_servers=self.kafka_url,
|
58
|
+
sasl_plain_username=self.username,
|
59
|
+
sasl_plain_password=self.password,
|
60
|
+
security_protocol='SASL_PLAINTEXT',
|
61
|
+
sasl_mechanism='PLAIN',
|
62
|
+
value_serializer=lambda x: dumps(x).encode('utf-8'))
|
63
|
+
else:
|
64
|
+
self.producer = KafkaProducer(
|
65
|
+
bootstrap_servers=self.kafka_url,
|
66
|
+
value_serializer=lambda x: dumps(x).encode('utf-8'))
|
67
|
+
print("[ Producer ] Connected to Kafka...")
|
68
|
+
self.init_producer = True
|
69
|
+
return self.producer
|
70
|
+
except errors.NoBrokersAvailable:
|
71
|
+
print("[ Producer ] Waiting for brokers to become available...")
|
72
|
+
time.sleep(3)
|
73
|
+
raise RuntimeError("[ Producer ] Failed to connect to brokers within 60 seconds")
|
74
|
+
|
75
|
+
def _create_consumer(self) -> KafkaProducer:
|
76
|
+
print("[ Consumer ] Connecting to Kafka brokers")
|
77
|
+
for i in range(0, 6):
|
78
|
+
try:
|
79
|
+
if self.secure:
|
80
|
+
self.consumer = KafkaConsumer(
|
81
|
+
group_id=self.consumer_group,
|
82
|
+
bootstrap_servers=self.kafka_url,
|
83
|
+
sasl_plain_username=self.username,
|
84
|
+
sasl_plain_password=self.password,
|
85
|
+
security_protocol='SASL_PLAINTEXT',
|
86
|
+
sasl_mechanism='PLAIN',
|
87
|
+
value_deserializer=lambda x: x.decode('utf-8'))
|
88
|
+
else:
|
89
|
+
self.consumer = KafkaProducer(
|
90
|
+
bootstrap_servers=self.kafka_url,
|
91
|
+
value_deserializer=lambda x: x.decode('utf-8'))
|
92
|
+
print("[ Consumer ] Connected to Kafka...")
|
93
|
+
self.init_consumer = True
|
94
|
+
return self.consumer
|
95
|
+
except errors.NoBrokersAvailable:
|
96
|
+
print("[ Consumer ] Waiting for brokers to become available...")
|
97
|
+
time.sleep(3)
|
98
|
+
raise RuntimeError("[ Consumer ] Failed to connect to brokers within 60 seconds")
|
99
|
+
|
100
|
+
# FutureRecordMetadata 可以添加回调, 来监听是否发送成功
|
101
|
+
# r.add_callback(lambda x: print(x))
|
102
|
+
# r.get() 可以同步获取结果
|
103
|
+
def send_msg(self, topic, msg, key: str=None, partition:int=None) -> FutureRecordMetadata:
|
104
|
+
if self.quited: return None
|
105
|
+
if not self.init_producer:
|
106
|
+
with self.locker:
|
107
|
+
if not self.init_producer:
|
108
|
+
self._create_producer()
|
109
|
+
return self.producer.send(topic=topic, value=msg, key=None if key is None else key.encode('utf-8'), partition=partition)
|
110
|
+
|
111
|
+
def get_msg(self, topics: str, callBack=print):
|
112
|
+
if not self.init_consumer:
|
113
|
+
with self.locker:
|
114
|
+
if not self.init_consumer:
|
115
|
+
self._create_consumer()
|
116
|
+
for topic in topics.split(','):
|
117
|
+
if topic not in self.consumer_callback.keys():
|
118
|
+
self.consumer_callback[topic] = []
|
119
|
+
self.consumer.subscribe(self.consumer_callback.keys())
|
120
|
+
self.consumer_callback[topic].append(callBack)
|
121
|
+
if not self.start_consumer:
|
122
|
+
t = Thread(target=self._start_consumer_poll)
|
123
|
+
t.start()
|
124
|
+
|
125
|
+
def _start_consumer_poll(self):
|
126
|
+
self.start_consumer = True
|
127
|
+
for msg in self.consumer:
|
128
|
+
if self.quited: break
|
129
|
+
taskList = []
|
130
|
+
funcList = []
|
131
|
+
begin_time = time.time()
|
132
|
+
for func in self.consumer_callback[msg.topic]:
|
133
|
+
if self.quited: break
|
134
|
+
f = thread_pool.submit(func, (msg, ))
|
135
|
+
taskList.append(f)
|
136
|
+
funcList.append(func.__name__)
|
137
|
+
for f in taskList:
|
138
|
+
if self.quited: break
|
139
|
+
f.result()
|
140
|
+
end_time = time.time()
|
141
|
+
if end_time - begin_time > 1: print(f"kafka consume too slow!!! {funcList} time cost: ", f'{round(end_time - begin_time, 2)}s')
|
142
|
+
taskList.clear()
|
143
|
+
funcList.clear()
|
144
|
+
|
145
|
+
def shutdown(self):
|
146
|
+
self.quited = True
|
147
|
+
try: self.consumer.close()
|
148
|
+
except Exception: pass
|
149
|
+
try: self.producer.close()
|
150
|
+
except Exception: pass
|
151
|
+
thread_pool.shutdown(wait=True)
|
152
|
+
|
{tools → ctools}/cron_lite.py
RENAMED
@@ -7,10 +7,26 @@ import traceback
|
|
7
7
|
from datetime import datetime
|
8
8
|
from functools import wraps
|
9
9
|
from typing import Optional, Dict
|
10
|
-
|
11
10
|
import pytz
|
12
11
|
from croniter import croniter
|
13
12
|
|
13
|
+
"""
|
14
|
+
@cron_lite.cron_task('0/1 * * * * ? *')
|
15
|
+
def demo():
|
16
|
+
print('hello world')
|
17
|
+
|
18
|
+
@cron_lite.cron_task('0/1 * * * * ? *')
|
19
|
+
def demo1():
|
20
|
+
print('hello world111')
|
21
|
+
|
22
|
+
def demo2(xx, fff):
|
23
|
+
print('hello world222', xx, fff)
|
24
|
+
|
25
|
+
cron_lite.apply_cron_task('0/1 * * * * ? *', demo2, (123123123, 34534534))
|
26
|
+
print(123123)
|
27
|
+
|
28
|
+
cron_lite.start_all()
|
29
|
+
"""
|
14
30
|
|
15
31
|
class SchedulerMeta:
|
16
32
|
timer_task_name: str = None
|
@@ -22,8 +38,8 @@ class SchedulerMeta:
|
|
22
38
|
|
23
39
|
scheduler_map: Dict[str, SchedulerMeta] = {} # {timer_task_name: SchedulerMeta}
|
24
40
|
_switch = False
|
41
|
+
_info_handler = print
|
25
42
|
_error_handler = print
|
26
|
-
_info_handler = print
|
27
43
|
_time_zone: Optional[pytz.BaseTzInfo] = None
|
28
44
|
|
29
45
|
|
@@ -31,75 +47,8 @@ def set_time_zone(time_zone_name: str):
|
|
31
47
|
global _time_zone
|
32
48
|
_time_zone = pytz.timezone(time_zone_name)
|
33
49
|
|
34
|
-
|
35
|
-
def
|
36
|
-
cron_obj = croniter(cron_expr)
|
37
|
-
if _time_zone:
|
38
|
-
cron_obj.set_current(datetime.now(tz=_time_zone))
|
39
|
-
next_time = int(cron_obj.get_next())
|
40
|
-
if scheduler_map.get(timer_task_name) is None:
|
41
|
-
scheduler_meta = SchedulerMeta()
|
42
|
-
scheduler_meta.timer_task_name = timer_task_name
|
43
|
-
scheduler_meta.switch = True
|
44
|
-
scheduler_meta.scheduler = sched.scheduler(time.time, time.sleep)
|
45
|
-
scheduler_map[timer_task_name] = scheduler_meta
|
46
|
-
if till_time_stamp is None or next_time <= till_time_stamp:
|
47
|
-
scheduler_map[timer_task_name].event = scheduler_map[timer_task_name].scheduler.enterabs(next_time, 0, base_func)
|
48
|
-
|
49
|
-
|
50
|
-
def _run_sched(scheduler_meta: SchedulerMeta):
|
51
|
-
active(scheduler_meta.timer_task_name)
|
52
|
-
while True:
|
53
|
-
scheduler = scheduler_meta.scheduler
|
54
|
-
if not _switch or not scheduler_meta.switch:
|
55
|
-
scheduler.empty()
|
56
|
-
inactive(scheduler_meta.timer_task_name)
|
57
|
-
return
|
58
|
-
t = scheduler.run(False)
|
59
|
-
if t is None:
|
60
|
-
inactive(scheduler_meta.timer_task_name)
|
61
|
-
return
|
62
|
-
st = time.time()
|
63
|
-
while time.time() - st < t:
|
64
|
-
if not _switch or not scheduler_meta.switch:
|
65
|
-
scheduler.empty()
|
66
|
-
inactive(scheduler_meta.timer_task_name)
|
67
|
-
return
|
68
|
-
time.sleep(0.5)
|
69
|
-
|
70
|
-
|
71
|
-
def _start():
|
72
|
-
global _switch
|
73
|
-
_info_handler("cron started")
|
74
|
-
tl = []
|
75
|
-
for timer_task_name, scheduler_meta in scheduler_map.items():
|
76
|
-
print("Registering Job:", timer_task_name)
|
77
|
-
t = threading.Thread(target=_run_sched, args=(scheduler_meta,), daemon=True)
|
78
|
-
# 有些task非常耗时,会影响退出。目前设计改为退出时不保证task完成
|
79
|
-
t.start()
|
80
|
-
tl.append(t)
|
81
|
-
|
82
|
-
for t in tl:
|
83
|
-
t.join()
|
84
|
-
_info_handler("cron finished")
|
85
|
-
_switch = False # ensure close when there are no more tasks with switch open
|
86
|
-
scheduler_map.clear()
|
87
|
-
|
88
|
-
|
89
|
-
def convert_cron(cron_expr):
|
90
|
-
res_cron = ""
|
91
|
-
cron_list = cron_expr.split(" ")
|
92
|
-
if len(cron_list) > 6:
|
93
|
-
for cron in cron_list[1:]:
|
94
|
-
if cron != "?":
|
95
|
-
res_cron += "%s " % cron
|
96
|
-
res_cron += "%s" % cron_list[0]
|
97
|
-
else:
|
98
|
-
res_cron = cron_expr
|
99
|
-
return res_cron
|
100
|
-
|
101
|
-
|
102
|
-
def cron_task(cron_expr: str, till_time_stamp: int = None):
|
50
|
+
# @annotation
|
51
|
+
def cron_task(cron_expr: str, task_name: str = None, till_time_stamp: int = None):
|
103
52
|
"""
|
104
53
|
cron_task decorator to register a function as crontab task
|
105
54
|
:param cron_expr: the croniter accepted cron_expression. NOTICE: the default timezone is UTC and can be changed by
|
@@ -107,7 +56,7 @@ def cron_task(cron_expr: str, till_time_stamp: int = None):
|
|
107
56
|
:param till_time_stamp: run this jog till when. None means forever
|
108
57
|
:return: the real decorator
|
109
58
|
"""
|
110
|
-
cron_expr =
|
59
|
+
cron_expr = _convert_cron(cron_expr)
|
111
60
|
assert len(cron_expr.split(" ")) in (5, 6), \
|
112
61
|
"only supported <min hour day month weekday> and <min hour day month weekday sec>"
|
113
62
|
|
@@ -121,15 +70,15 @@ def cron_task(cron_expr: str, till_time_stamp: int = None):
|
|
121
70
|
_error_handler(f"run {func.__name__} failed\n" + traceback.format_exc())
|
122
71
|
except Exception:
|
123
72
|
_error_handler(f"run {func.__name__} failed\n")
|
124
|
-
_register_next(inner, inner, cron_expr, till_time_stamp)
|
73
|
+
_register_next(inner.__name__ if task_name is None else task_name, inner, cron_expr, till_time_stamp)
|
125
74
|
|
126
|
-
_register_next(inner, inner, cron_expr, till_time_stamp)
|
75
|
+
_register_next(inner.__name__ if task_name is None else task_name, inner, cron_expr, till_time_stamp, init=True)
|
127
76
|
return inner
|
128
77
|
|
129
78
|
return deco
|
130
79
|
|
131
80
|
|
132
|
-
def apply_cron_task(
|
81
|
+
def apply_cron_task(cron_expr, func, params, timer_task_name=None, till_time_stamp=None):
|
133
82
|
"""
|
134
83
|
cron_task decorator to register a function as crontab task
|
135
84
|
:param func: task callback function
|
@@ -140,37 +89,32 @@ def apply_cron_task(timer_task_name, func, params, cron_expr, till_time_stamp=No
|
|
140
89
|
:param till_time_stamp: run this jog till when. None means forever
|
141
90
|
:return: the real decorator
|
142
91
|
"""
|
143
|
-
cron_expr =
|
144
|
-
assert len(cron_expr.split(" ")) in (5, 6),
|
145
|
-
|
146
|
-
|
92
|
+
cron_expr = _convert_cron(cron_expr)
|
93
|
+
assert len(cron_expr.split(" ")) in (5, 6), "Only supported <minute hour day month weekday> and <minute hour day month weekday second>"
|
94
|
+
task_name = func.__name__ if timer_task_name is None else timer_task_name
|
147
95
|
@wraps(func)
|
148
96
|
def wrapper(*args, **kwargs):
|
149
97
|
try:
|
150
|
-
|
98
|
+
nonlocal params
|
99
|
+
func.__taskName__ = task_name
|
100
|
+
func(*params, *args, **kwargs)
|
151
101
|
except Exception as exc:
|
152
102
|
_error_handler(f"Run {func.__name__} failed with error: {str(exc)}")
|
153
103
|
finally:
|
154
|
-
_register_next(
|
104
|
+
_register_next(task_name, wrapper, cron_expr, till_time_stamp)
|
155
105
|
|
156
|
-
_register_next(
|
106
|
+
_register_next(task_name, wrapper, cron_expr, till_time_stamp, init=True)
|
107
|
+
# 不使用 submit, 因为提交的任务, 不是 daemon 线程
|
108
|
+
t = threading.Thread(target=_start, args=(timer_task_name, ))
|
109
|
+
t.setDaemon(True)
|
110
|
+
t.start()
|
111
|
+
return t
|
157
112
|
|
158
|
-
|
159
|
-
_switch = True
|
160
|
-
|
161
|
-
scheduler = scheduler_map.get(timer_task_name)
|
162
|
-
if scheduler:
|
163
|
-
scheduler.switch = True
|
164
|
-
t = threading.Thread(target=_run_sched, name=timer_task_name, args=(scheduler,), daemon=True)
|
165
|
-
# 有些task非常耗时,会影响退出。目前设计改为退出时不保证task完成
|
166
|
-
t.start()
|
167
|
-
return wrapper
|
168
|
-
|
169
|
-
|
170
|
-
def start_all(spawn: bool = True, info_handler=None, error_handler=None) -> Optional[threading.Thread]:
|
113
|
+
def start_all(spawn: bool = True, daemon: bool = True, info_handler=None, error_handler=None) -> Optional[threading.Thread]:
|
171
114
|
"""
|
172
115
|
start_all starts all cron tasks registered before.
|
173
116
|
:param spawn: whether to start a new thread for scheduler. If not, the action will block the current thread
|
117
|
+
:param daemon: the new thread is daemon if True
|
174
118
|
:param info_handler: handle info output (scheduler start / stop), default = print, can use logging.info
|
175
119
|
:param error_handler: handle error output (task execute exception), default = print, can use logging.error
|
176
120
|
:raise RuntimeError: if the tasks are already started and still running we cannot start again. The feature is not
|
@@ -179,16 +123,14 @@ def start_all(spawn: bool = True, info_handler=None, error_handler=None) -> Opti
|
|
179
123
|
"""
|
180
124
|
global _switch, _info_handler, _error_handler
|
181
125
|
if _switch:
|
182
|
-
raise RuntimeError("the crontab was already started")
|
126
|
+
raise RuntimeError("the crontab was already started...")
|
183
127
|
if info_handler:
|
184
128
|
_info_handler = info_handler
|
185
129
|
if error_handler:
|
186
130
|
_error_handler = error_handler
|
187
|
-
|
188
|
-
_switch = True
|
189
131
|
if spawn:
|
190
132
|
t = threading.Thread(target=_start)
|
191
|
-
t.setDaemon(
|
133
|
+
t.setDaemon(daemon)
|
192
134
|
t.start()
|
193
135
|
return t
|
194
136
|
else:
|
@@ -237,3 +179,73 @@ def stop_all(wait_thread: Optional[threading.Thread] = None):
|
|
237
179
|
scheduler_map.get(timer_task_name).switch = False
|
238
180
|
if wait_thread:
|
239
181
|
wait_thread.join()
|
182
|
+
|
183
|
+
|
184
|
+
def _register_next(timer_task_name, base_func, cron_expr, till_time_stamp, init: bool = False):
|
185
|
+
cron_obj = croniter(cron_expr)
|
186
|
+
if _time_zone:
|
187
|
+
cron_obj.set_current(datetime.now(tz=_time_zone))
|
188
|
+
next_time = int(cron_obj.get_next())
|
189
|
+
if scheduler_map.get(timer_task_name) is None:
|
190
|
+
scheduler_meta = SchedulerMeta()
|
191
|
+
scheduler_meta.timer_task_name = timer_task_name
|
192
|
+
scheduler_meta.switch = True
|
193
|
+
scheduler_meta.scheduler = sched.scheduler(time.time, time.sleep)
|
194
|
+
scheduler_map[timer_task_name] = scheduler_meta
|
195
|
+
elif init:
|
196
|
+
raise ValueError(f"task name: {timer_task_name} already exists!!!!!")
|
197
|
+
if till_time_stamp is None or next_time <= till_time_stamp:
|
198
|
+
scheduler_map[timer_task_name].event = scheduler_map[timer_task_name].scheduler.enterabs(next_time, 0, base_func)
|
199
|
+
|
200
|
+
|
201
|
+
def _run_sched(scheduler_meta: SchedulerMeta):
|
202
|
+
active(scheduler_meta.timer_task_name)
|
203
|
+
while True:
|
204
|
+
scheduler = scheduler_meta.scheduler
|
205
|
+
if not _switch or not scheduler_meta.switch:
|
206
|
+
scheduler.empty()
|
207
|
+
inactive(scheduler_meta.timer_task_name)
|
208
|
+
return
|
209
|
+
t = scheduler.run(False)
|
210
|
+
if t is None:
|
211
|
+
inactive(scheduler_meta.timer_task_name)
|
212
|
+
return
|
213
|
+
st = time.time()
|
214
|
+
while time.time() - st < t:
|
215
|
+
if not _switch or not scheduler_meta.switch:
|
216
|
+
scheduler.empty()
|
217
|
+
inactive(scheduler_meta.timer_task_name)
|
218
|
+
return
|
219
|
+
time.sleep(0.5)
|
220
|
+
|
221
|
+
|
222
|
+
def _start(taskName: str = None):
|
223
|
+
global _switch
|
224
|
+
_switch = True
|
225
|
+
_info_handler("cron job begin start...")
|
226
|
+
taskList = []
|
227
|
+
for timer_task_name, scheduler_meta in scheduler_map.items():
|
228
|
+
if taskName is not None and timer_task_name != taskName: continue
|
229
|
+
print("register job: ", timer_task_name)
|
230
|
+
thread = threading.Thread(target=_run_sched, args=(scheduler_meta, ))
|
231
|
+
thread.setDaemon(True)
|
232
|
+
thread.start()
|
233
|
+
taskList.append(thread)
|
234
|
+
for task in taskList: task.join()
|
235
|
+
_info_handler("cron job execute finished...")
|
236
|
+
_switch = False
|
237
|
+
scheduler_map.clear()
|
238
|
+
|
239
|
+
|
240
|
+
def _convert_cron(cron_expr):
|
241
|
+
res_cron = ""
|
242
|
+
cron_list = cron_expr.split(" ")
|
243
|
+
if len(cron_list) > 6:
|
244
|
+
for cron in cron_list[1:]:
|
245
|
+
if cron != "?":
|
246
|
+
res_cron += "%s " % cron
|
247
|
+
res_cron += "%s" % cron_list[0]
|
248
|
+
else:
|
249
|
+
res_cron = cron_expr
|
250
|
+
return res_cron
|
251
|
+
|
{tools → ctools}/database.py
RENAMED
@@ -5,8 +5,8 @@ from sqlalchemy import create_engine, Integer, Column, event
|
|
5
5
|
from sqlalchemy.ext.declarative import declarative_base
|
6
6
|
from sqlalchemy.orm import sessionmaker, Session
|
7
7
|
from sqlalchemy.sql import text
|
8
|
-
from
|
9
|
-
from
|
8
|
+
from ctools import call, string_tools
|
9
|
+
from ctools.thread_pool import thread_local
|
10
10
|
|
11
11
|
Base = None
|
12
12
|
inited_db = {}
|
@@ -21,10 +21,6 @@ def _init():
|
|
21
21
|
global Base
|
22
22
|
Base = declarative_base()
|
23
23
|
|
24
|
-
def set_search_path(dbapi_connection, default_schema):
|
25
|
-
with dbapi_connection.cursor() as cursor:
|
26
|
-
cursor.execute(f'SET search_path TO {default_schema}')
|
27
|
-
|
28
24
|
# 密码里的@ 要替换成 %40
|
29
25
|
def init_db(db_url: str, db_key: str='default', connect_args: dict={}, default_schema: str=None, pool_size: int=5, max_overflow: int=25, echo: bool=False):
|
30
26
|
if inited_db.get(db_key): raise Exception('db {} already init!!!'.format(db_key))
|
@@ -33,7 +29,11 @@ def init_db(db_url: str, db_key: str='default', connect_args: dict={}, default_s
|
|
33
29
|
engines[db_key] = engine
|
34
30
|
sessionMakers[db_key] = sessionMaker
|
35
31
|
inited_db[db_key] = True
|
36
|
-
if default_schema: event.listen(engine, 'connect', lambda dbapi_connection, connection_record:
|
32
|
+
if default_schema: event.listen(engine, 'connect', lambda dbapi_connection, connection_record: _set_search_path(dbapi_connection, default_schema))
|
33
|
+
|
34
|
+
def _set_search_path(dbapi_connection, default_schema):
|
35
|
+
with dbapi_connection.cursor() as cursor:
|
36
|
+
cursor.execute(f'SET search_path TO {default_schema}')
|
37
37
|
|
38
38
|
def _create_connection(db_url: str, pool_size: int=5, max_overflow: int=25, connect_args={}, echo: bool=False):
|
39
39
|
engine = create_engine('{}'.format(db_url),
|
{tools → ctools}/html_soup.py
RENAMED
{tools → ctools}/license.py
RENAMED
{tools → ctools}/metrics.py
RENAMED
@@ -4,9 +4,8 @@ from enum import Enum
|
|
4
4
|
|
5
5
|
from prometheus_client import Counter, Gauge, Summary, Histogram
|
6
6
|
|
7
|
-
from
|
8
|
-
from
|
9
|
-
from tools.application import Server
|
7
|
+
from ctools import call, cjson, sys_log
|
8
|
+
from ctools.application import Server
|
10
9
|
|
11
10
|
log = sys_log.flog
|
12
11
|
|
@@ -123,23 +122,5 @@ def opt(metric_key: str, label_values: [], metric_value: int):
|
|
123
122
|
log.error("添加指标信息异常: %s" % e)
|
124
123
|
_lock.release()
|
125
124
|
|
126
|
-
|
127
125
|
def _init_all_metrics():
|
128
126
|
Metric(MetricType.COUNTER, 'demo123123', ['asdasd', 'sdfsdf'], persistent=True)
|
129
|
-
Metric(MetricType.GAUGE, MetricKey.ASSETS_TPL_COUNT.value, [], persistent=True, desc="模版数量")
|
130
|
-
Metric(MetricType.GAUGE, MetricKey.ASSETS_FLOW_COUNT.value, [], persistent=True, desc="流程数量")
|
131
|
-
Metric(MetricType.GAUGE, MetricKey.ASSETS_SCHEDULE_COUNT.value, [], persistent=True, desc="调度任务数量")
|
132
|
-
|
133
|
-
Metric(MetricType.COUNTER, MetricKey.CLIENT_STATUS_RUNNING_STATE.value, [], reset=True, desc="运行状态")
|
134
|
-
Metric(MetricType.COUNTER, MetricKey.CLIENT_STATUS_AUTHORIZED_DAYS.value, [], reset=True, desc="已授权天数")
|
135
|
-
Metric(MetricType.COUNTER, MetricKey.CLIENT_STATUS_PROGRESS.value, ['process_id'], reset=True, desc="流程运行进度[0-100]")
|
136
|
-
|
137
|
-
Metric(MetricType.COUNTER, MetricKey.WORKLOAD_PROCESS_EXEC_COUNT.value, ['process_id'], persistent=True, desc="流程执行次数")
|
138
|
-
Metric(MetricType.COUNTER, MetricKey.WORKLOAD_PROCESS_HOURS.value, ['process_id'], persistent=True, desc="全部流程工作时长")
|
139
|
-
Metric(MetricType.COUNTER, MetricKey.WORKLOAD_PROCESS_HOURS_SINGLE.value, ['process_id'], reset=True, desc="单次流程工作时长")
|
140
|
-
Metric(MetricType.COUNTER, MetricKey.WORKLOAD_PROCESS_COLLECT_DATA_TOTAL.value, ['process_id'], persistent=True, desc="全部流程采集数据总量")
|
141
|
-
Metric(MetricType.COUNTER, MetricKey.WORKLOAD_PROCESS_COLLECT_DATA_TOTAL_SINGLE.value, ['process_id'], reset=True, desc="单次流程采集数据总量")
|
142
|
-
Metric(MetricType.COUNTER, MetricKey.WORKLOAD_PROCESS_SEND_DATA_TOTAL.value, ['process_id'], persistent=True, desc="全部流程发送数据总量")
|
143
|
-
Metric(MetricType.COUNTER, MetricKey.WORKLOAD_PROCESS_SEND_DATA_TOTAL_SINGLE.value, ['process_id'], reset=True, desc="单次流程发送数据总量")
|
144
|
-
|
145
|
-
Metric(MetricType.COUNTER, MetricKey.ERROR_SCHEDULE_COUNT.value, ['process_id'], persistent=True, desc="出错任务数")
|
{tools → ctools}/mqtt_utils.py
RENAMED
@@ -6,7 +6,7 @@ from paho.mqtt.enums import CallbackAPIVersion
|
|
6
6
|
|
7
7
|
from business.common import DictToObj
|
8
8
|
from business.common.constant import MQTTEvent
|
9
|
-
from
|
9
|
+
from ctools import sys_log, cjson, string_tools, sys_info, date_utils, sm_tools, thread_pool
|
10
10
|
|
11
11
|
'''
|
12
12
|
MQTT服务使用示例:
|
{tools → ctools}/pacth.py
RENAMED
{tools → ctools}/string_tools.py
RENAMED
{tools → ctools}/sys_info.py
RENAMED
{tools → ctools}/sys_log.py
RENAMED
@@ -3,9 +3,7 @@ import os
|
|
3
3
|
import sys
|
4
4
|
import time
|
5
5
|
|
6
|
-
from
|
7
|
-
|
8
|
-
application.sync_config()
|
6
|
+
from ctools import call
|
9
7
|
|
10
8
|
clog, flog = None, None
|
11
9
|
|
@@ -72,6 +70,6 @@ class GlobalLogger(object):
|
|
72
70
|
@call.init
|
73
71
|
def _init_log() -> None:
|
74
72
|
global flog, clog
|
75
|
-
flog = _file_log(sys_log_path=
|
73
|
+
flog = _file_log(sys_log_path='~/ck-py-log/', mixin=True, log_level=logging.INFO)
|
76
74
|
clog = _console_log()
|
77
75
|
GlobalLogger(flog)
|
{tools → ctools}/thread_pool.py
RENAMED
@@ -2,7 +2,7 @@ import os
|
|
2
2
|
import time
|
3
3
|
from concurrent.futures import ThreadPoolExecutor
|
4
4
|
import threading
|
5
|
-
from
|
5
|
+
from ctools import call
|
6
6
|
|
7
7
|
thread_local = threading.local()
|
8
8
|
|
@@ -28,3 +28,7 @@ def submit(func, *args, callback=None, **kwargs):
|
|
28
28
|
future.add_done_callback(lambda f: cb(f, callback))
|
29
29
|
time.sleep(0.01)
|
30
30
|
return future
|
31
|
+
|
32
|
+
def shutdown(wait=True):
|
33
|
+
if _threadPool is None: raise Exception('thread pool is not init')
|
34
|
+
_threadPool.shutdown(wait=wait)
|
{tools → ctools}/upload_tools.py
RENAMED
{tools → ctools}/win_control.py
RENAMED
@@ -3,7 +3,7 @@ import time
|
|
3
3
|
import pyautogui
|
4
4
|
import uiautomation as auto
|
5
5
|
from pynput import keyboard
|
6
|
-
from
|
6
|
+
from ctools import thread_pool, win_canvas, application, string_tools
|
7
7
|
|
8
8
|
current_control = None
|
9
9
|
ctrl_pressed = False
|
{tools → ctools}/word_fill.py
RENAMED
@@ -15,8 +15,8 @@ from xlstpl import writer as xls_writer
|
|
15
15
|
from xlsxtpl import writerx as xlsx_writerx
|
16
16
|
from xlutils.copy import copy
|
17
17
|
|
18
|
-
from
|
19
|
-
from
|
18
|
+
from ctools import cjson
|
19
|
+
from ctools.word_fill_entity import WordTable, WordCell, Style, Font, Alignment
|
20
20
|
|
21
21
|
EXCEL_WORD_ALIGNMENT = {"left": WD_TABLE_ALIGNMENT.LEFT,
|
22
22
|
"center": WD_TABLE_ALIGNMENT.CENTER,
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: gomyck-tools
|
3
|
-
Version: 0.1
|
4
|
-
Summary: A
|
3
|
+
Version: 1.0.1
|
4
|
+
Summary: A ctools for python development by hao474798383
|
5
5
|
Home-page: https://blog.gomyck.com
|
6
6
|
Author: gomyck
|
7
7
|
Author-email: hao474798383@163.com
|
@@ -10,11 +10,13 @@ Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
11
11
|
Requires-Python: >=3.8
|
12
12
|
Description-Content-Type: text/markdown
|
13
|
-
Requires-Dist:
|
14
|
-
Requires-Dist:
|
15
|
-
Requires-Dist:
|
16
|
-
Requires-Dist:
|
17
|
-
Requires-Dist:
|
18
|
-
Requires-Dist:
|
13
|
+
Requires-Dist: jsonpickle >=3.2.2
|
14
|
+
Requires-Dist: SQLAlchemy >=2.0.32
|
15
|
+
Requires-Dist: chardet >=5.2.0
|
16
|
+
Requires-Dist: psycopg2-binary >=2.9.9
|
17
|
+
Requires-Dist: croniter >=3.0.3
|
18
|
+
Requires-Dist: pyautogui >=0.9.54
|
19
|
+
Requires-Dist: gmssl >=3.2.2
|
20
|
+
Requires-Dist: psutil >=6.0.0
|
19
21
|
|
20
22
|
this package is for python development
|
@@ -0,0 +1,54 @@
|
|
1
|
+
ctools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
ctools/aes_tools.py,sha256=ylUgyhlx7bNCTGrbWEZVwCObzYdJTQtwEc4ZMidL2Fo,563
|
3
|
+
ctools/application.py,sha256=WviU7p9GOqducbGW3XGkP7jCNKmraCh6JGSYBC33CQk,16008
|
4
|
+
ctools/b64.py,sha256=_BdhX3p3-MaSSlU2wivN5qPxQfacR3VRBr1WC456tU0,194
|
5
|
+
ctools/bashPath.py,sha256=BCN_EhYzqvwsxYso81omMNd3SbEociwSOyb9kLvu8V4,337
|
6
|
+
ctools/bottle_server.py,sha256=1FngczUlovRpS8HGx7_q2-jrnGmS0g2UUxbILaMmsR8,1482
|
7
|
+
ctools/browser_element_tools.py,sha256=tWNxUJ9m-hNTYtS0NRvmH9r5I-Qw55uKekwDYgt49bc,9951
|
8
|
+
ctools/call.py,sha256=v1QGKo8UeWDs1zASJSHUUuFkYZ5zb8Pzd0vEYzAi4d8,1545
|
9
|
+
ctools/cjson.py,sha256=tS_K_NzXYQjMq-_kKnKSsqkCMY491IblPg3E7Y1LIfk,1270
|
10
|
+
ctools/ckafka.py,sha256=win6iV9-7FJDzcmqwQ5httN_NWjrBlWHc5b7N9E5tCQ,5187
|
11
|
+
ctools/compile_tools.py,sha256=Nybh3vnkurIKnPnubdYzigjnzFu4GaTMKPvqFdibxmE,510
|
12
|
+
ctools/console.py,sha256=1VAq_-fSGgHKYv6Qe53kHaJL0-3NpFRUZljahbJPcfk,1807
|
13
|
+
ctools/cron_lite.py,sha256=L3Le_ScIuKiLAfzdaCf8qoPUbFIMT9ASallQkmwJTfc,8307
|
14
|
+
ctools/database.py,sha256=gyNAqAqMQ-Iq9qtXt-qI3TVSebuIooFuriKQO8WtNt0,4985
|
15
|
+
ctools/date_utils.py,sha256=-xI2anEzAonOvYwVmM1hCnkuLKodZ8pb33dS3dRxEIc,865
|
16
|
+
ctools/download_tools.py,sha256=h12HGr2IaVvl8IDAvpDftHycSACI5V7HF0Yk9kV4bVY,1750
|
17
|
+
ctools/enums.py,sha256=QbHa3j7j4-BDdwaga5Y0nYfA2uNSVJDHumYdIZdKVkM,118
|
18
|
+
ctools/ex.py,sha256=vIkSWzHuNFslDFeBZCzCmbOefgLTEeScJp0vKeNm_P8,783
|
19
|
+
ctools/excelOpt.py,sha256=q3HLAb1JScTrMCvx_x-4WWnqKhyTEzQ-m5vtqFy8NZU,1138
|
20
|
+
ctools/html_soup.py,sha256=LabCo4yWI58fbFBPhunk3THWBf0BbHEWLgwyvSpTGR4,1903
|
21
|
+
ctools/http_utils.py,sha256=5tW_MV8JUfA4hMLh4cup0kyBsiiTK1l6sgdHVdc8p5g,614
|
22
|
+
ctools/id_worker_tools.py,sha256=xtfxpL8q4hHLT02JFx2jVXEXpasHq44ZFsOhO580JmE,2357
|
23
|
+
ctools/images_tools.py,sha256=hjYu-3tpjZ96yMqAM3XrFSUEOiUcyGk4DbAsz2_OeIs,669
|
24
|
+
ctools/imgDialog.py,sha256=DSq5cFofyP_el80AFConht_ZYRqxZhIz4CWjqBlJ0cw,1385
|
25
|
+
ctools/license.py,sha256=0Kh7lXL7LD1PQqyijHajFL0GbmZGNB88PA2WskbQn_s,1066
|
26
|
+
ctools/log.py,sha256=kLlT67by9kTV6UlFXuYPg5AkNnqFRZknoUqLGGIKj14,1097
|
27
|
+
ctools/metrics.py,sha256=vq9Fnq2fhmhS4yoHS4gO7ArKS033Eou8vpA779Uue0I,4414
|
28
|
+
ctools/mqtt_utils.py,sha256=9q_5CGvEhhvy8fZxaioguPSz8mvkdpCxnZ86GxjwTE0,10676
|
29
|
+
ctools/mvc.py,sha256=MgOaM7Jg_tUwVoBSzTgr12E3bX4-IQnIqBwDC-1BO08,1792
|
30
|
+
ctools/obj.py,sha256=GYS1B8NyjtUIh0HlK9r8avC2eGbK2SJac4C1CGnfGhI,479
|
31
|
+
ctools/pacth.py,sha256=4TNWbgNqFSY_BBXKF4KzKauxL8W937wDkoqt84rU-Qg,2603
|
32
|
+
ctools/plan_area_tools.py,sha256=yyFWIAvVe_p1e8HugR_h7r_W7dW9dQ-CGtgMz_Hz5QQ,3396
|
33
|
+
ctools/pty_tools.py,sha256=H-j2xlZ5A0Q75NMop1ghCs2C0BZPKOPjilRujnh5Ngg,1602
|
34
|
+
ctools/resource_bundle_tools.py,sha256=8zW1-aj6jAYFBCoyslz5bL-5916G6Aif1RUy_ObbiVU,3793
|
35
|
+
ctools/screenshot_tools.py,sha256=-DzWgguxTOTolzQXdZfUIHTOU3HNhp74fdomeSTBxKs,4538
|
36
|
+
ctools/sign.py,sha256=YOrON1SeLRPavPWtE3GonvWFVv1SGFjfjrEVJ3k4x6s,566
|
37
|
+
ctools/sm_tools.py,sha256=RwhTjuKw_TjaAJAui39wctzFFpbt79MQ3hjF0fhL638,1113
|
38
|
+
ctools/ssh.py,sha256=3Oo4Lf6UyX-F_u_c1icHHDNzvVDHMKiWIO1u7E22QkM,217
|
39
|
+
ctools/strDiff.py,sha256=QUtXOfsRLTFozH_zByqsC39JeuG3eZtrwGVeLyaHYUI,429
|
40
|
+
ctools/string_tools.py,sha256=qjFn47lM27ISAa2Q4OKO7WOBdhyWC5lLHbME-uSeICE,2142
|
41
|
+
ctools/sys_info.py,sha256=podW43pcn7z2f6FW2w1L9bU1HfeVjC3D34BdN_H6rf4,3625
|
42
|
+
ctools/sys_log.py,sha256=vjsIQiME5l8ajffh2o0Zfs-5zrchGHTMxDMhEh0mUhQ,2081
|
43
|
+
ctools/thread_pool.py,sha256=pPtKCE1BjagbhqtWjKo5HA2LktcSQ5KQUJz9Fn2Jl0w,924
|
44
|
+
ctools/upload_tools.py,sha256=sqe6K3ZWiyY58pFE5IO5mNaS1znnS7U4c4UqY8noED4,1068
|
45
|
+
ctools/win_canvas.py,sha256=PAxI4i1jalfree9d1YG4damjc2EzaHZrgHZCTgk2GiM,2530
|
46
|
+
ctools/win_control.py,sha256=zNu06wNCtOnfIg12LIMMy2hBb1rskVQ8QIZu9qx4CNY,3487
|
47
|
+
ctools/wordFill.py,sha256=dB1OLt6GLmWdkDV8H20VWbJmY4ggNNI8iHD1ocae2iM,875
|
48
|
+
ctools/word_fill.py,sha256=aIkzjAF2soSW6w2dO2CRZlveDcuIdr6v9DtyyyB8uxM,18216
|
49
|
+
ctools/word_fill_entity.py,sha256=eX3G0Gy16hfGpavQSEkCIoKDdTnNgRRJrFvKliETZK8,985
|
50
|
+
ctools/work_path.py,sha256=i4MTUobqNW2WMrT3mwEC_XYQ0_IhFmKoNpTX2W6A8Tc,1680
|
51
|
+
gomyck_tools-1.0.1.dist-info/METADATA,sha256=h24LRZHemvSBALvDO13vYZTbWF6rvmL8Muj9PPKmKTo,711
|
52
|
+
gomyck_tools-1.0.1.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
53
|
+
gomyck_tools-1.0.1.dist-info/top_level.txt,sha256=-MiIH9FYRVKp1i5_SVRkaI-71WmF1sZSRrNWFU9ls3s,7
|
54
|
+
gomyck_tools-1.0.1.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
ctools
|
@@ -1,54 +0,0 @@
|
|
1
|
-
tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
tools/aes_tools.py,sha256=ylUgyhlx7bNCTGrbWEZVwCObzYdJTQtwEc4ZMidL2Fo,563
|
3
|
-
tools/application.py,sha256=kchrmTRXaYn7wfdXZ2zE8ix6J5BDmndatKD8650I1SY,16004
|
4
|
-
tools/b64.py,sha256=_BdhX3p3-MaSSlU2wivN5qPxQfacR3VRBr1WC456tU0,194
|
5
|
-
tools/bashPath.py,sha256=BCN_EhYzqvwsxYso81omMNd3SbEociwSOyb9kLvu8V4,337
|
6
|
-
tools/bottle_server.py,sha256=CRkJ7_YMuZfn-kbiU_8JJlAXBXP9-dieIy49kyUvX50,1481
|
7
|
-
tools/browser_element_tools.py,sha256=v5yiDrxbZG9kowjsEo0Nw_FjSj651qHmEK-C3b3s_g0,9950
|
8
|
-
tools/call.py,sha256=v1QGKo8UeWDs1zASJSHUUuFkYZ5zb8Pzd0vEYzAi4d8,1545
|
9
|
-
tools/cjson.py,sha256=n7Q3k5-1F30uIKRsRoizXdDTsIC-wAyt338B_FzktdE,1236
|
10
|
-
tools/compile_tools.py,sha256=Nybh3vnkurIKnPnubdYzigjnzFu4GaTMKPvqFdibxmE,510
|
11
|
-
tools/console.py,sha256=1VAq_-fSGgHKYv6Qe53kHaJL0-3NpFRUZljahbJPcfk,1807
|
12
|
-
tools/cron_lite.py,sha256=ehayjzS9HHNc9ub9BY4aBJglXS01PJCGYvOrQyr3X8Y,7713
|
13
|
-
tools/database.py,sha256=_WrzjTRIjNAtQ1cx4JHDwgn-neBkVxrCf2Z-eLOKac4,4981
|
14
|
-
tools/date_utils.py,sha256=-xI2anEzAonOvYwVmM1hCnkuLKodZ8pb33dS3dRxEIc,865
|
15
|
-
tools/download_tools.py,sha256=WK-7w9hgxqoBzl5qexEgDZC60LOLAUu7-lznFK7bbWw,1749
|
16
|
-
tools/enums.py,sha256=QbHa3j7j4-BDdwaga5Y0nYfA2uNSVJDHumYdIZdKVkM,118
|
17
|
-
tools/ex.py,sha256=vIkSWzHuNFslDFeBZCzCmbOefgLTEeScJp0vKeNm_P8,783
|
18
|
-
tools/excelOpt.py,sha256=q3HLAb1JScTrMCvx_x-4WWnqKhyTEzQ-m5vtqFy8NZU,1138
|
19
|
-
tools/html_soup.py,sha256=jqz2-9sAutXcZXcID4UwP1-hpG6lj_rs9oMDqWtSpnQ,1902
|
20
|
-
tools/http_utils.py,sha256=5tW_MV8JUfA4hMLh4cup0kyBsiiTK1l6sgdHVdc8p5g,614
|
21
|
-
tools/id_worker_tools.py,sha256=xtfxpL8q4hHLT02JFx2jVXEXpasHq44ZFsOhO580JmE,2357
|
22
|
-
tools/images_tools.py,sha256=hjYu-3tpjZ96yMqAM3XrFSUEOiUcyGk4DbAsz2_OeIs,669
|
23
|
-
tools/imgDialog.py,sha256=DSq5cFofyP_el80AFConht_ZYRqxZhIz4CWjqBlJ0cw,1385
|
24
|
-
tools/license.py,sha256=rQacenrLN8MQe8BRGne2C0NGydwnv5DDcgWjGuXoobE,1065
|
25
|
-
tools/log.py,sha256=kLlT67by9kTV6UlFXuYPg5AkNnqFRZknoUqLGGIKj14,1097
|
26
|
-
tools/metrics.py,sha256=V33cnyN1BhTi6y8buFF7GxWzsx7uKTYzw_0Mx5oUwRM,6286
|
27
|
-
tools/mqtt_utils.py,sha256=QqQ2rGdVzVaGVKQ1ZhbSxsVom1bUqWwIIBlv-szyjyQ,10675
|
28
|
-
tools/mvc.py,sha256=MgOaM7Jg_tUwVoBSzTgr12E3bX4-IQnIqBwDC-1BO08,1792
|
29
|
-
tools/obj.py,sha256=GYS1B8NyjtUIh0HlK9r8avC2eGbK2SJac4C1CGnfGhI,479
|
30
|
-
tools/pacth.py,sha256=D2bTpYZ05MvLJ9aPwsRPo3ze2jV-siKQ6s0zDUCg82E,2616
|
31
|
-
tools/plan_area_tools.py,sha256=Hdk0zslU_XVl58oGur_5Mb-qjU8gI0nTn2szVTHVnEE,3395
|
32
|
-
tools/pty_tools.py,sha256=H-j2xlZ5A0Q75NMop1ghCs2C0BZPKOPjilRujnh5Ngg,1602
|
33
|
-
tools/resource_bundle_tools.py,sha256=9gePzxobL7uq39mI_S9QXohMggjyH4AiH1BIvF-fnds,3792
|
34
|
-
tools/screenshot_tools.py,sha256=Hu1-9AIaYdlPp-zTeXkObGlBpSnEo_QOYwV8TZmdUZM,4537
|
35
|
-
tools/sign.py,sha256=YOrON1SeLRPavPWtE3GonvWFVv1SGFjfjrEVJ3k4x6s,566
|
36
|
-
tools/sm_tools.py,sha256=RwhTjuKw_TjaAJAui39wctzFFpbt79MQ3hjF0fhL638,1113
|
37
|
-
tools/ssh.py,sha256=3Oo4Lf6UyX-F_u_c1icHHDNzvVDHMKiWIO1u7E22QkM,217
|
38
|
-
tools/strDiff.py,sha256=QUtXOfsRLTFozH_zByqsC39JeuG3eZtrwGVeLyaHYUI,429
|
39
|
-
tools/string_tools.py,sha256=Oe-33SJ3sG50lvtH-n7pedQ0qMUUBr0oCIv9w1_LJGQ,2141
|
40
|
-
tools/sys_info.py,sha256=G0tGMk9-HMcyk9SmsihInNodIZ1UPv_Y-IH4wD3Dqvg,3624
|
41
|
-
tools/sys_log.py,sha256=tRXZ9SNE44ZkavL1ErFP9t2AduwnNNvBeZytW6qTGxw,2191
|
42
|
-
tools/thread_pool.py,sha256=N46HQaWUqCIfRAuDIg7O7b_RXSM3z4ttGEWoN837rg4,794
|
43
|
-
tools/token_tools.py,sha256=8ir4C1fzcofWCTYrQXME2zqwCSSREF0ZUGmLH0IDP_Q,315
|
44
|
-
tools/upload_tools.py,sha256=W7Dys5QAz4mjDrRsFXg7QBfVxkriJvw9dyUl1CTDzVY,1067
|
45
|
-
tools/win_canvas.py,sha256=PAxI4i1jalfree9d1YG4damjc2EzaHZrgHZCTgk2GiM,2530
|
46
|
-
tools/win_control.py,sha256=pEW2EpiTFLorSYWq1V7oLJkQanaap104t7Fl2B7x37U,3486
|
47
|
-
tools/wordFill.py,sha256=dB1OLt6GLmWdkDV8H20VWbJmY4ggNNI8iHD1ocae2iM,875
|
48
|
-
tools/word_fill.py,sha256=H0LMx5kL6F00-8AA8r0LYz0PXIDs24f2-UbrxlEDrsQ,18214
|
49
|
-
tools/word_fill_entity.py,sha256=eX3G0Gy16hfGpavQSEkCIoKDdTnNgRRJrFvKliETZK8,985
|
50
|
-
tools/work_path.py,sha256=i4MTUobqNW2WMrT3mwEC_XYQ0_IhFmKoNpTX2W6A8Tc,1680
|
51
|
-
gomyck_tools-0.1.0.dist-info/METADATA,sha256=I7_MRLyQtP2T_Bagg3wQDJUerjCADjOtofLbWdsgR1s,635
|
52
|
-
gomyck_tools-0.1.0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
53
|
-
gomyck_tools-0.1.0.dist-info/top_level.txt,sha256=Ib4ZA2MPBpiT0tC-0qt5RcP9g42gLddRbx9PiYGa-Fc,6
|
54
|
-
gomyck_tools-0.1.0.dist-info/RECORD,,
|
@@ -1 +0,0 @@
|
|
1
|
-
tools
|
tools/token_tools.py
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
from business.controller.base import GlobalState
|
2
|
-
from tools import string_tools
|
3
|
-
|
4
|
-
|
5
|
-
def get_tmp_token():
|
6
|
-
tmp_token = string_tools.get_uuid()
|
7
|
-
GlobalState.tmp_token.append(tmp_token)
|
8
|
-
return tmp_token
|
9
|
-
|
10
|
-
|
11
|
-
def remove_tmp_token(token: str):
|
12
|
-
if token in GlobalState.tmp_token:
|
13
|
-
GlobalState.tmp_token.remove(token)
|
{tools → ctools}/__init__.py
RENAMED
File without changes
|
{tools → ctools}/aes_tools.py
RENAMED
File without changes
|
{tools → ctools}/b64.py
RENAMED
File without changes
|
{tools → ctools}/bashPath.py
RENAMED
File without changes
|
{tools → ctools}/call.py
RENAMED
File without changes
|
File without changes
|
{tools → ctools}/console.py
RENAMED
File without changes
|
{tools → ctools}/date_utils.py
RENAMED
File without changes
|
{tools → ctools}/enums.py
RENAMED
File without changes
|
{tools → ctools}/ex.py
RENAMED
File without changes
|
{tools → ctools}/excelOpt.py
RENAMED
File without changes
|
{tools → ctools}/http_utils.py
RENAMED
File without changes
|
File without changes
|
{tools → ctools}/images_tools.py
RENAMED
File without changes
|
{tools → ctools}/imgDialog.py
RENAMED
File without changes
|
{tools → ctools}/log.py
RENAMED
File without changes
|
{tools → ctools}/mvc.py
RENAMED
File without changes
|
{tools → ctools}/obj.py
RENAMED
File without changes
|
{tools → ctools}/pty_tools.py
RENAMED
File without changes
|
{tools → ctools}/sign.py
RENAMED
File without changes
|
{tools → ctools}/sm_tools.py
RENAMED
File without changes
|
{tools → ctools}/ssh.py
RENAMED
File without changes
|
{tools → ctools}/strDiff.py
RENAMED
File without changes
|
{tools → ctools}/win_canvas.py
RENAMED
File without changes
|
{tools → ctools}/wordFill.py
RENAMED
File without changes
|
File without changes
|
{tools → ctools}/work_path.py
RENAMED
File without changes
|
File without changes
|