gomyck-tools 1.1.3__tar.gz → 1.1.5__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.
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/PKG-INFO +5 -1
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/bottle_web_base.py +1 -6
- gomyck-tools-1.1.5/ctools/ckafka.py +159 -0
- gomyck-tools-1.1.5/ctools/dict_wrapper.py +11 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/http_utils.py +4 -4
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/id_worker_tools.py +3 -15
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/images_tools.py +0 -1
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/imgDialog.py +0 -1
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/mqtt_utils.py +6 -2
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/pty_tools.py +2 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/string_tools.py +2 -1
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/gomyck_tools.egg-info/PKG-INFO +5 -1
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/gomyck_tools.egg-info/SOURCES.txt +1 -1
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/gomyck_tools.egg-info/requires.txt +4 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/setup.py +2 -2
- gomyck-tools-1.1.3/ctools/ckafka.py +0 -150
- gomyck-tools-1.1.3/ctools/ssh.py +0 -11
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/README.md +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/__init__.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/aes_tools.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/api_result.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/application.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/b64.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/bashPath.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/bottle_webserver.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/bottle_websocket.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/browser_element_tools.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/call.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/cjson.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/compile_tools.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/console.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/cron_lite.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/database.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/date_utils.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/douglas_rarefy.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/download_tools.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/enums.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/ex.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/excelOpt.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/html_soup.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/license.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/metrics.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/obj.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/pacth.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/plan_area_tools.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/process_pool.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/resource_bundle_tools.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/screenshot_tools.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/sign.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/sm_tools.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/strDiff.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/sys_info.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/sys_log.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/thread_pool.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/upload_tools.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/win_canvas.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/win_control.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/wordFill.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/word_fill.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/word_fill_entity.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/ctools/work_path.py +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/gomyck_tools.egg-info/dependency_links.txt +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/gomyck_tools.egg-info/top_level.txt +0 -0
- {gomyck-tools-1.1.3 → gomyck-tools-1.1.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: gomyck-tools
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.5
|
4
4
|
Summary: A ctools for python development by hao474798383
|
5
5
|
Home-page: https://blog.gomyck.com
|
6
6
|
Author: gomyck
|
@@ -20,6 +20,10 @@ Requires-Dist: psutil>=6.0.0
|
|
20
20
|
Requires-Dist: jsonpath_ng>=1.6.1
|
21
21
|
Requires-Dist: bottle==0.13.1
|
22
22
|
Requires-Dist: requests==2.32.3
|
23
|
+
Requires-Dist: urllib3==1.26.18
|
23
24
|
Requires-Dist: kafka-python==2.0.2
|
25
|
+
Requires-Dist: bs4==0.0.2
|
26
|
+
Requires-Dist: paho-mqtt==2.1.0
|
27
|
+
Requires-Dist: fuzzywuzzy==0.18.0
|
24
28
|
|
25
29
|
this package is for python development
|
@@ -4,7 +4,7 @@ from functools import wraps
|
|
4
4
|
|
5
5
|
import bottle
|
6
6
|
from bottle import response, Bottle, request
|
7
|
-
|
7
|
+
from ctools.dict_wrapper import DictWrapper
|
8
8
|
from ctools.api_result import R
|
9
9
|
from ctools.sys_log import flog as log
|
10
10
|
|
@@ -142,9 +142,4 @@ class FormDataParams:
|
|
142
142
|
except Exception:
|
143
143
|
return self.files[key]
|
144
144
|
|
145
|
-
class DictWrapper(dict):
|
146
|
-
def __getattr__(self, key):
|
147
|
-
return self.get(key)
|
148
145
|
|
149
|
-
def __setattr__(self, key, value):
|
150
|
-
self[key] = value
|
@@ -0,0 +1,159 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
__author__ = 'haoyang'
|
4
|
+
__date__ = '2024/9/5 10:39'
|
5
|
+
|
6
|
+
import time
|
7
|
+
from threading import Thread, Lock
|
8
|
+
|
9
|
+
from kafka import KafkaProducer, errors, KafkaConsumer
|
10
|
+
from kafka.producer.future import FutureRecordMetadata
|
11
|
+
|
12
|
+
from ctools import thread_pool
|
13
|
+
from ctools.cjson import dumps
|
14
|
+
|
15
|
+
"""
|
16
|
+
import time
|
17
|
+
from datetime import datetime
|
18
|
+
|
19
|
+
from ctools import thread_pool, string_tools
|
20
|
+
from ctools.ckafka import CKafka
|
21
|
+
|
22
|
+
c = CKafka(kafka_url='192.168.3.160:9094', secure=True)
|
23
|
+
|
24
|
+
producer = c.init_producer()
|
25
|
+
consumer = c.init_consumer(enable_auto_commit=False)
|
26
|
+
|
27
|
+
def send_msg():
|
28
|
+
while True:
|
29
|
+
command = input('发送消息: Y/n \n')
|
30
|
+
if command.strip() not in ['N', 'n']:
|
31
|
+
producer.send_msg('jqxx-lib', '{{"jqid": "{}", "xxxx": "{}=={}"}}'.format(string_tools.get_snowflake_id(), command.strip(), datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S')))
|
32
|
+
else:
|
33
|
+
break
|
34
|
+
|
35
|
+
thread_pool.submit(send_msg)
|
36
|
+
|
37
|
+
def consumer_callback(msg):
|
38
|
+
print(msg)
|
39
|
+
return True
|
40
|
+
|
41
|
+
consumer.receive_msg('jqxx-lib', callBack=consumer_callback)
|
42
|
+
|
43
|
+
time.sleep(10000)
|
44
|
+
"""
|
45
|
+
class KafkaInstance:
|
46
|
+
def __init__(self, producer: KafkaProducer, consumer: KafkaConsumer):
|
47
|
+
self.start_consumer = False
|
48
|
+
self.quited = False
|
49
|
+
self.producer = producer
|
50
|
+
self.consumer = consumer
|
51
|
+
self.consumer_callback = {"topic_key": []}
|
52
|
+
|
53
|
+
# FutureRecordMetadata 可以添加回调, 来监听是否发送成功
|
54
|
+
# r.add_callback(lambda x: print(x))
|
55
|
+
# r.get() 可以同步获取结果
|
56
|
+
def send_msg(self, topic, msg, key: str=None, partition:int=None) -> FutureRecordMetadata:
|
57
|
+
if self.producer is None: raise RuntimeError("Producer is not initialized")
|
58
|
+
if self.quited: return
|
59
|
+
return self.producer.send(topic=topic, value=msg, key=None if key is None else key.encode('utf-8'), partition=partition)
|
60
|
+
|
61
|
+
def receive_msg(self, topics: str, callBack=print):
|
62
|
+
if self.consumer is None: raise RuntimeError("Consumer is not initialized")
|
63
|
+
for topic in topics.split(','):
|
64
|
+
if topic not in self.consumer_callback.keys():
|
65
|
+
self.consumer_callback[topic] = []
|
66
|
+
self.consumer.subscribe(self.consumer_callback.keys())
|
67
|
+
self.consumer_callback[topic].append(callBack)
|
68
|
+
if not self.start_consumer:
|
69
|
+
t = Thread(target=self._start_consumer_poll, daemon=False)
|
70
|
+
t.start()
|
71
|
+
|
72
|
+
def _start_consumer_poll(self):
|
73
|
+
self.start_consumer = True
|
74
|
+
for msg in self.consumer:
|
75
|
+
if self.quited: break
|
76
|
+
funcList = []
|
77
|
+
begin_time = time.time()
|
78
|
+
for func in self.consumer_callback[msg.topic]:
|
79
|
+
if self.quited: break
|
80
|
+
res = func(msg)
|
81
|
+
if not self.consumer.config['enable_auto_commit'] and res: self.consumer.commit()
|
82
|
+
funcList.append(func.__name__)
|
83
|
+
end_time = time.time()
|
84
|
+
if end_time - begin_time > 1: print(f"kafka consume too slow!!! {funcList} time cost: ", f'{round(end_time - begin_time, 2)}s')
|
85
|
+
funcList.clear()
|
86
|
+
|
87
|
+
def shutdown(self):
|
88
|
+
self.quited = True
|
89
|
+
try: self.consumer.close()
|
90
|
+
except Exception: pass
|
91
|
+
try: self.producer.close()
|
92
|
+
except Exception: pass
|
93
|
+
|
94
|
+
|
95
|
+
class CKafka:
|
96
|
+
|
97
|
+
def __init__(self, kafka_url: str = '127.0.0.1:9092', secure: bool = False, username: str = 'client', password: str = 'hylink_user_password'):
|
98
|
+
self.kafka_url = kafka_url
|
99
|
+
self.secure = secure
|
100
|
+
self.username = username
|
101
|
+
self.password = password
|
102
|
+
|
103
|
+
def init_producer(self, acks=1) -> KafkaInstance:
|
104
|
+
print("[ Producer ] Connecting to Kafka [{}]".format(self.kafka_url))
|
105
|
+
for i in range(0, 6):
|
106
|
+
try:
|
107
|
+
if self.secure:
|
108
|
+
producer = KafkaProducer(
|
109
|
+
acks=acks,
|
110
|
+
bootstrap_servers=self.kafka_url,
|
111
|
+
value_serializer=lambda x: dumps(x).encode('utf-8'),
|
112
|
+
sasl_plain_username=self.username,
|
113
|
+
sasl_plain_password=self.password,
|
114
|
+
security_protocol='SASL_PLAINTEXT',
|
115
|
+
sasl_mechanism='PLAIN'
|
116
|
+
)
|
117
|
+
else:
|
118
|
+
producer = KafkaProducer(
|
119
|
+
acks=acks,
|
120
|
+
bootstrap_servers=self.kafka_url,
|
121
|
+
value_serializer=lambda x: dumps(x).encode('utf-8')
|
122
|
+
)
|
123
|
+
print("[ Producer ] Success Connected to Kafka [{}]".format(self.kafka_url))
|
124
|
+
return KafkaInstance(producer=producer, consumer=None)
|
125
|
+
except errors.NoBrokersAvailable:
|
126
|
+
print("[ Producer ] Waiting for Kafka [{}] to become available...".format(self.kafka_url))
|
127
|
+
time.sleep(3)
|
128
|
+
raise RuntimeError("[ Producer ] Failed to connect to Kafka [{}] within 60 seconds".format(self.kafka_url))
|
129
|
+
|
130
|
+
def init_consumer(self, client_id: str = 'ck-py-kafka-consumer', consumer_group: str = 'ck-py-kafka-consumer', enable_auto_commit: bool = True) -> KafkaInstance:
|
131
|
+
print("[ Consumer ] Connecting to Kafka [{}]".format(self.kafka_url))
|
132
|
+
for i in range(0, 6):
|
133
|
+
try:
|
134
|
+
if self.secure:
|
135
|
+
consumer = KafkaConsumer(
|
136
|
+
client_id=client_id,
|
137
|
+
group_id=consumer_group,
|
138
|
+
enable_auto_commit=enable_auto_commit,
|
139
|
+
bootstrap_servers=self.kafka_url,
|
140
|
+
value_deserializer=lambda x: x.decode('utf-8'),
|
141
|
+
sasl_plain_username=self.username,
|
142
|
+
sasl_plain_password=self.password,
|
143
|
+
security_protocol='SASL_PLAINTEXT',
|
144
|
+
sasl_mechanism='PLAIN'
|
145
|
+
)
|
146
|
+
else:
|
147
|
+
consumer = KafkaProducer(
|
148
|
+
client_id=client_id,
|
149
|
+
group_id=consumer_group,
|
150
|
+
enable_auto_commit=enable_auto_commit,
|
151
|
+
bootstrap_servers=self.kafka_url,
|
152
|
+
value_deserializer=lambda x: x.decode('utf-8')
|
153
|
+
)
|
154
|
+
print("[ Consumer ] Success Connected to Kafka [{}]".format(self.kafka_url))
|
155
|
+
return KafkaInstance(producer=None, consumer=consumer)
|
156
|
+
except errors.NoBrokersAvailable:
|
157
|
+
print("[ Consumer ] Waiting for Kafka [{}] to become available...".format(self.kafka_url))
|
158
|
+
time.sleep(3)
|
159
|
+
raise RuntimeError("[ Consumer ] Failed to connect to Kafka [{}] within 60 seconds".format(self.kafka_url))
|
@@ -4,19 +4,19 @@ import requests
|
|
4
4
|
def get(url, params=None, headers=None):
|
5
5
|
result = ""
|
6
6
|
try:
|
7
|
-
response = requests.get(url, params=params, headers=headers, timeout=60)
|
7
|
+
response = requests.get(url, params=params, headers=headers, timeout=60, verify=False)
|
8
8
|
response.raise_for_status()
|
9
9
|
if response.status_code == 200:
|
10
10
|
result = response.content
|
11
11
|
except Exception as e:
|
12
12
|
print("GET请求异常:", e)
|
13
|
-
return result
|
13
|
+
return result.decode('utf-8')
|
14
14
|
|
15
15
|
|
16
16
|
def post(url, data=None, json=None, headers=None, files=None):
|
17
17
|
result = ""
|
18
|
-
response = requests.post(url, data=data, json=json, files=files, headers=headers, timeout=60)
|
18
|
+
response = requests.post(url, data=data, json=json, files=files, headers=headers, timeout=60, verify=False)
|
19
19
|
response.raise_for_status()
|
20
20
|
if response.status_code == 200:
|
21
21
|
result = response.content
|
22
|
-
return result
|
22
|
+
return result.decode('utf-8')
|
@@ -4,49 +4,41 @@ import time
|
|
4
4
|
WORKER_ID_BITS = 5
|
5
5
|
DATACENTER_ID_BITS = 5
|
6
6
|
SEQUENCE_BITS = 12
|
7
|
-
|
8
7
|
# 最大取值计算
|
9
8
|
MAX_WORKER_ID = -1 ^ (-1 << WORKER_ID_BITS) # 2**5-1 0b11111
|
10
9
|
MAX_DATACENTER_ID = -1 ^ (-1 << DATACENTER_ID_BITS)
|
11
|
-
|
12
10
|
# 移位偏移计算
|
13
11
|
WOKER_ID_SHIFT = SEQUENCE_BITS
|
14
12
|
DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS
|
15
13
|
TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS
|
16
|
-
|
17
14
|
# 序号循环掩码
|
18
15
|
SEQUENCE_MASK = -1 ^ (-1 << SEQUENCE_BITS)
|
19
|
-
|
20
16
|
# Twitter元年时间戳
|
21
17
|
TWEPOCH = 1288834974657
|
22
18
|
|
23
|
-
|
24
19
|
class IdWorker(object):
|
25
20
|
"""
|
26
21
|
用于生成IDs
|
27
22
|
"""
|
28
|
-
|
29
23
|
def __init__(self, datacenter_id, worker_id, sequence=0):
|
30
24
|
"""
|
31
25
|
初始化
|
32
26
|
:param datacenter_id: 数据中心(机器区域)ID
|
33
27
|
:param worker_id: 机器ID
|
34
|
-
:param sequence:
|
28
|
+
:param sequence: 起始序号
|
35
29
|
"""
|
36
30
|
# sanity check
|
37
31
|
if worker_id > MAX_WORKER_ID or worker_id < 0:
|
38
32
|
raise ValueError('worker_id值越界')
|
39
|
-
|
40
33
|
if datacenter_id > MAX_DATACENTER_ID or datacenter_id < 0:
|
41
34
|
raise ValueError('datacenter_id值越界')
|
42
|
-
|
43
35
|
self.worker_id = worker_id
|
44
36
|
self.datacenter_id = datacenter_id
|
45
37
|
self.sequence = sequence
|
46
|
-
|
47
38
|
self.last_timestamp = -1 # 上次计算的时间戳
|
48
39
|
|
49
|
-
|
40
|
+
@staticmethod
|
41
|
+
def _gen_timestamp():
|
50
42
|
"""
|
51
43
|
生成整数时间戳
|
52
44
|
:return:int timestamp
|
@@ -59,21 +51,17 @@ class IdWorker(object):
|
|
59
51
|
:return:
|
60
52
|
"""
|
61
53
|
timestamp = self._gen_timestamp()
|
62
|
-
|
63
54
|
# 时钟回拨
|
64
55
|
if timestamp < self.last_timestamp:
|
65
56
|
print('clock is moving backwards. Rejecting requests until {}'.format(self.last_timestamp))
|
66
57
|
raise
|
67
|
-
|
68
58
|
if timestamp == self.last_timestamp:
|
69
59
|
self.sequence = (self.sequence + 1) & SEQUENCE_MASK
|
70
60
|
if self.sequence == 0:
|
71
61
|
timestamp = self._til_next_millis(self.last_timestamp)
|
72
62
|
else:
|
73
63
|
self.sequence = 0
|
74
|
-
|
75
64
|
self.last_timestamp = timestamp
|
76
|
-
|
77
65
|
new_id = ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) | (self.datacenter_id << DATACENTER_ID_SHIFT) | \
|
78
66
|
(self.worker_id << WOKER_ID_SHIFT) | self.sequence
|
79
67
|
return new_id
|
@@ -1,13 +1,17 @@
|
|
1
1
|
import time
|
2
|
+
from enum import Enum
|
2
3
|
from typing import Dict
|
3
4
|
|
4
|
-
from
|
5
|
-
from business.common.constant import MQTTEvent
|
5
|
+
from ctools.dict_wrapper import DictWrapper as DictToObj
|
6
6
|
from paho.mqtt import client as mqtt
|
7
7
|
from paho.mqtt.enums import CallbackAPIVersion
|
8
8
|
|
9
9
|
from ctools import sys_log, cjson, string_tools, sys_info, date_utils, sm_tools, thread_pool
|
10
10
|
|
11
|
+
class MQTTEvent(Enum):
|
12
|
+
|
13
|
+
pass
|
14
|
+
|
11
15
|
'''
|
12
16
|
MQTT服务使用示例:
|
13
17
|
|
@@ -7,6 +7,7 @@ import chardet
|
|
7
7
|
|
8
8
|
from ctools.id_worker_tools import IdWorker
|
9
9
|
|
10
|
+
idWorker = IdWorker(1, 2, 0)
|
10
11
|
|
11
12
|
def get_random_str(size: int = 10):
|
12
13
|
"""
|
@@ -22,7 +23,7 @@ def get_uuid():
|
|
22
23
|
|
23
24
|
|
24
25
|
def get_snowflake_id():
|
25
|
-
return
|
26
|
+
return idWorker.get_id()
|
26
27
|
|
27
28
|
|
28
29
|
def decode_bytes(bytes_str: Union[bytes, bytearray]):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: gomyck-tools
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.5
|
4
4
|
Summary: A ctools for python development by hao474798383
|
5
5
|
Home-page: https://blog.gomyck.com
|
6
6
|
Author: gomyck
|
@@ -20,6 +20,10 @@ Requires-Dist: psutil>=6.0.0
|
|
20
20
|
Requires-Dist: jsonpath_ng>=1.6.1
|
21
21
|
Requires-Dist: bottle==0.13.1
|
22
22
|
Requires-Dist: requests==2.32.3
|
23
|
+
Requires-Dist: urllib3==1.26.18
|
23
24
|
Requires-Dist: kafka-python==2.0.2
|
25
|
+
Requires-Dist: bs4==0.0.2
|
26
|
+
Requires-Dist: paho-mqtt==2.1.0
|
27
|
+
Requires-Dist: fuzzywuzzy==0.18.0
|
24
28
|
|
25
29
|
this package is for python development
|
@@ -18,6 +18,7 @@ ctools/console.py
|
|
18
18
|
ctools/cron_lite.py
|
19
19
|
ctools/database.py
|
20
20
|
ctools/date_utils.py
|
21
|
+
ctools/dict_wrapper.py
|
21
22
|
ctools/douglas_rarefy.py
|
22
23
|
ctools/download_tools.py
|
23
24
|
ctools/enums.py
|
@@ -40,7 +41,6 @@ ctools/resource_bundle_tools.py
|
|
40
41
|
ctools/screenshot_tools.py
|
41
42
|
ctools/sign.py
|
42
43
|
ctools/sm_tools.py
|
43
|
-
ctools/ssh.py
|
44
44
|
ctools/strDiff.py
|
45
45
|
ctools/string_tools.py
|
46
46
|
ctools/sys_info.py
|
@@ -11,7 +11,7 @@ requirements = parse_requirements(os.path.join(os.path.dirname(__file__), 'requi
|
|
11
11
|
|
12
12
|
setup(
|
13
13
|
name="gomyck-tools",
|
14
|
-
version="1.1.
|
14
|
+
version="1.1.5",
|
15
15
|
author="gomyck",
|
16
16
|
author_email="hao474798383@163.com",
|
17
17
|
description="A ctools for python development by hao474798383",
|
@@ -30,5 +30,5 @@ setup(
|
|
30
30
|
|
31
31
|
# 安装依赖, 并生成构建包
|
32
32
|
# pip install setuptools wheel twine
|
33
|
-
# rm -rf gomyck_tools.egg-info dist build && python setup.py sdist bdist_wheel && twine upload dist/*
|
33
|
+
# rm -rf gomyck_tools.egg-info dist build && python setup.py sdist bdist_wheel && twine upload dist/* && rm -rf gomyck_tools.egg-info dist build
|
34
34
|
|
@@ -1,150 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
# -*- coding: UTF-8 -*-
|
3
|
-
__author__ = 'haoyang'
|
4
|
-
__date__ = '2024/9/5 10:39'
|
5
|
-
|
6
|
-
import time
|
7
|
-
from threading import Thread, Lock
|
8
|
-
|
9
|
-
from kafka import KafkaProducer, errors, KafkaConsumer
|
10
|
-
from kafka.producer.future import FutureRecordMetadata
|
11
|
-
|
12
|
-
from ctools import thread_pool
|
13
|
-
from ctools.cjson import dumps
|
14
|
-
|
15
|
-
"""
|
16
|
-
import time
|
17
|
-
|
18
|
-
from ctools import thread_pool
|
19
|
-
from ctools.ckafka import CKafka
|
20
|
-
|
21
|
-
c = CKafka(kafka_url='192.168.3.160:9094', secure=True)
|
22
|
-
|
23
|
-
def send_msg():
|
24
|
-
while True:
|
25
|
-
time.sleep(3)
|
26
|
-
c.send_msg('test', 'test')
|
27
|
-
|
28
|
-
thread_pool.submit(send_msg)
|
29
|
-
c.get_msg('test')
|
30
|
-
"""
|
31
|
-
|
32
|
-
class CKafka:
|
33
|
-
|
34
|
-
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'):
|
35
|
-
self.consumer: KafkaConsumer = None
|
36
|
-
self.producer: KafkaProducer = None
|
37
|
-
self.start_consumer = False
|
38
|
-
self.consumer_callback = {"topic_key": []}
|
39
|
-
self.consumer_group = consumer_group
|
40
|
-
self.kafka_url = kafka_url
|
41
|
-
self.init_producer = False
|
42
|
-
self.init_consumer = False
|
43
|
-
self.secure = secure
|
44
|
-
self.username = username
|
45
|
-
self.password = password
|
46
|
-
self.locker = Lock()
|
47
|
-
self.quited = False
|
48
|
-
|
49
|
-
def _create_producer(self) -> KafkaProducer:
|
50
|
-
print("[ Producer ] Connecting to Kafka brokers")
|
51
|
-
for i in range(0, 6):
|
52
|
-
try:
|
53
|
-
if self.secure:
|
54
|
-
self.producer = KafkaProducer(
|
55
|
-
bootstrap_servers=self.kafka_url,
|
56
|
-
sasl_plain_username=self.username,
|
57
|
-
sasl_plain_password=self.password,
|
58
|
-
security_protocol='SASL_PLAINTEXT',
|
59
|
-
sasl_mechanism='PLAIN',
|
60
|
-
value_serializer=lambda x: dumps(x).encode('utf-8'))
|
61
|
-
else:
|
62
|
-
self.producer = KafkaProducer(
|
63
|
-
bootstrap_servers=self.kafka_url,
|
64
|
-
value_serializer=lambda x: dumps(x).encode('utf-8'))
|
65
|
-
print("[ Producer ] Connected to Kafka...")
|
66
|
-
self.init_producer = True
|
67
|
-
return self.producer
|
68
|
-
except errors.NoBrokersAvailable:
|
69
|
-
print("[ Producer ] Waiting for brokers to become available...")
|
70
|
-
time.sleep(3)
|
71
|
-
raise RuntimeError("[ Producer ] Failed to connect to brokers within 60 seconds")
|
72
|
-
|
73
|
-
def _create_consumer(self) -> KafkaProducer:
|
74
|
-
print("[ Consumer ] Connecting to Kafka brokers")
|
75
|
-
for i in range(0, 6):
|
76
|
-
try:
|
77
|
-
if self.secure:
|
78
|
-
self.consumer = KafkaConsumer(
|
79
|
-
group_id=self.consumer_group,
|
80
|
-
bootstrap_servers=self.kafka_url,
|
81
|
-
sasl_plain_username=self.username,
|
82
|
-
sasl_plain_password=self.password,
|
83
|
-
security_protocol='SASL_PLAINTEXT',
|
84
|
-
sasl_mechanism='PLAIN',
|
85
|
-
value_deserializer=lambda x: x.decode('utf-8'))
|
86
|
-
else:
|
87
|
-
self.consumer = KafkaProducer(
|
88
|
-
bootstrap_servers=self.kafka_url,
|
89
|
-
value_deserializer=lambda x: x.decode('utf-8'))
|
90
|
-
print("[ Consumer ] Connected to Kafka...")
|
91
|
-
self.init_consumer = True
|
92
|
-
return self.consumer
|
93
|
-
except errors.NoBrokersAvailable:
|
94
|
-
print("[ Consumer ] Waiting for brokers to become available...")
|
95
|
-
time.sleep(3)
|
96
|
-
raise RuntimeError("[ Consumer ] Failed to connect to brokers within 60 seconds")
|
97
|
-
|
98
|
-
# FutureRecordMetadata 可以添加回调, 来监听是否发送成功
|
99
|
-
# r.add_callback(lambda x: print(x))
|
100
|
-
# r.get() 可以同步获取结果
|
101
|
-
def send_msg(self, topic, msg, key: str=None, partition:int=None) -> FutureRecordMetadata:
|
102
|
-
if self.quited: return None
|
103
|
-
if not self.init_producer:
|
104
|
-
with self.locker:
|
105
|
-
if not self.init_producer:
|
106
|
-
self._create_producer()
|
107
|
-
return self.producer.send(topic=topic, value=msg, key=None if key is None else key.encode('utf-8'), partition=partition)
|
108
|
-
|
109
|
-
def get_msg(self, topics: str, callBack=print):
|
110
|
-
if not self.init_consumer:
|
111
|
-
with self.locker:
|
112
|
-
if not self.init_consumer:
|
113
|
-
self._create_consumer()
|
114
|
-
for topic in topics.split(','):
|
115
|
-
if topic not in self.consumer_callback.keys():
|
116
|
-
self.consumer_callback[topic] = []
|
117
|
-
self.consumer.subscribe(self.consumer_callback.keys())
|
118
|
-
self.consumer_callback[topic].append(callBack)
|
119
|
-
if not self.start_consumer:
|
120
|
-
t = Thread(target=self._start_consumer_poll)
|
121
|
-
t.start()
|
122
|
-
|
123
|
-
def _start_consumer_poll(self):
|
124
|
-
self.start_consumer = True
|
125
|
-
for msg in self.consumer:
|
126
|
-
if self.quited: break
|
127
|
-
taskList = []
|
128
|
-
funcList = []
|
129
|
-
begin_time = time.time()
|
130
|
-
for func in self.consumer_callback[msg.topic]:
|
131
|
-
if self.quited: break
|
132
|
-
f = thread_pool.submit(func, (msg, ))
|
133
|
-
taskList.append(f)
|
134
|
-
funcList.append(func.__name__)
|
135
|
-
for f in taskList:
|
136
|
-
if self.quited: break
|
137
|
-
f.result()
|
138
|
-
end_time = time.time()
|
139
|
-
if end_time - begin_time > 1: print(f"kafka consume too slow!!! {funcList} time cost: ", f'{round(end_time - begin_time, 2)}s')
|
140
|
-
taskList.clear()
|
141
|
-
funcList.clear()
|
142
|
-
|
143
|
-
def shutdown(self):
|
144
|
-
self.quited = True
|
145
|
-
try: self.consumer.close()
|
146
|
-
except Exception: pass
|
147
|
-
try: self.producer.close()
|
148
|
-
except Exception: pass
|
149
|
-
thread_pool.shutdown(wait=True)
|
150
|
-
|
gomyck-tools-1.1.3/ctools/ssh.py
DELETED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|