atomicshop 2.16.35__py3-none-any.whl → 2.16.37__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.

Potentially problematic release.


This version of atomicshop might be problematic. Click here for more details.

atomicshop/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  """Atomic Basic functions and classes to make developer life easier"""
2
2
 
3
3
  __author__ = "Den Kras"
4
- __version__ = '2.16.35'
4
+ __version__ = '2.16.37'
@@ -1,4 +1,3 @@
1
- # v1.0.3 - 28.03.2023 17:20
2
1
  import sys
3
2
 
4
3
  from .threads import current_thread_id
@@ -15,3 +14,8 @@ def print_exception() -> None:
15
14
  exc_type, exc_value, exc_traceback = sys.exc_info()
16
15
 
17
16
  print(f"{error_log_prefix} Thread {thread_id}: * Details: {exc_type}, {exc_value}")
17
+
18
+
19
+ def get_exception_type_string(exception: Exception) -> str:
20
+ """ Get exception type string """
21
+ return type(exception).__name__
@@ -273,6 +273,8 @@ def thread_worker_main(
273
273
 
274
274
  # So if the socket was closed and there was an error we can break the loop
275
275
  if not service_ssl_socket:
276
+ record_and_statistics_write()
277
+ recorded = True
276
278
  break
277
279
 
278
280
  # If there is a response, then send it.
@@ -316,7 +316,7 @@ class DnsServer:
316
316
  print_api(message, logger=self.logger)
317
317
 
318
318
  message = f"Current engine domains: {self.tcp_resolve_domain_list}"
319
- print_api(message, logger=self.logger, color='green')
319
+ print_api(message, logger=self.logger, color='blue')
320
320
 
321
321
  if self.resolve_to_tcp_server_all_domains:
322
322
  message = "Routing all domains to Built-in TCP Server."
@@ -324,7 +324,7 @@ class DnsServer:
324
324
 
325
325
  if self.resolve_regular:
326
326
  message = f"Routing all domains to Live DNS Service: {self.forwarding_dns_service_ipv4}"
327
- print_api(message, logger=self.logger, color='green')
327
+ print_api(message, logger=self.logger, color='blue')
328
328
 
329
329
  # The list that will hold all the threads that can be joined later
330
330
  threads_list: list = list()
@@ -76,7 +76,7 @@ class Sender:
76
76
  destination_address = self.ssl_socket.server_hostname
77
77
  destination: str = f'[{source_address}:{source_port}<->{destination_address}:{destination_port}]'
78
78
 
79
- error_class_type = str(type(e)).replace("<class '", '').replace("'>", '')
79
+ error_class_type = type(e).__name__
80
80
  exception_error = tracebacks.get_as_string(one_line=True)
81
81
 
82
82
  if 'ssl' in error_class_type.lower():
@@ -18,6 +18,7 @@ from .. import cryptographyw
18
18
  from ..loggingw import loggingw
19
19
  from ...print_api import print_api
20
20
  from ...file_io import file_io
21
+ from ...basics import tracebacks
21
22
 
22
23
 
23
24
  class SocketClient:
@@ -55,6 +56,12 @@ class SocketClient:
55
56
  self.connection_ip = connection_ip
56
57
  self.dns_servers_list = dns_servers_list
57
58
 
59
+ if logger:
60
+ # Create child logger for the provided logger with the module's name.
61
+ self.logger: logging.Logger = loggingw.get_logger_with_level(f'{logger.name}.{Path(__file__).stem}')
62
+ else:
63
+ self.logger: logging.Logger = logger
64
+
58
65
  self.socket_instance = None
59
66
 
60
67
  # If 'connection_ip' was specified, but no 'dns_servers_list', then this IP will be used for 'socket.connect()'.
@@ -68,12 +75,6 @@ class SocketClient:
68
75
  elif self.connection_ip and self.dns_servers_list:
69
76
  raise ValueError("Both 'connection_ip' and 'dns_servers_list' were specified.")
70
77
 
71
- if logger:
72
- # Create child logger for the provided logger with the module's name.
73
- self.logger: logging.Logger = loggingw.get_logger_with_level(f'{logger.name}.{Path(__file__).stem}')
74
- else:
75
- self.logger: logging.Logger = logger
76
-
77
78
  # Function to create SSL socket to destination service
78
79
  def create_service_socket(self):
79
80
  # If TLS is enabled.
@@ -86,8 +87,18 @@ class SocketClient:
86
87
  return creator.wrap_socket_with_ssl_context_client___default_certs___ignore_verification(
87
88
  socket_object, self.service_name)
88
89
 
89
- def service_connection(self):
90
- """ Function to establish connection to server """
90
+ def service_connection(
91
+ self
92
+ ) -> tuple[
93
+ Union[socket.socket, ssl.SSLSocket, None],
94
+ Union[str, None]]:
95
+ """
96
+ Function to establish connection to server
97
+
98
+ :return: Tuple with socket object and error string.
99
+ If connection was successful, the error string will be None.
100
+ If connection wasn't successful, the socket object will be None.
101
+ """
91
102
  # Check if socket to service domain exists.
92
103
  # If not
93
104
  if not self.socket_instance:
@@ -106,8 +117,8 @@ class SocketClient:
106
117
  f"Socket already defined to [{self.service_name}:{self.service_port}]. "
107
118
  f"Should be connected - Reusing.")
108
119
  # Since, restart the function each send_receive iteration, and there's still a connection we need to
109
- # set it True, or the socket object will be nullified in the next step.
110
- return True
120
+ # return the socket, or the socket object will be nullified in the next step.
121
+ return self.socket_instance
111
122
 
112
123
  # If 'dns_servers_list' was provided, we will resolve the domain to ip through these servers.
113
124
  if self.dns_servers_list:
@@ -125,11 +136,13 @@ class SocketClient:
125
136
  # Get only the first entry of the list of IPs [0]
126
137
  self.connection_ip = function_server_address[0].to_text()
127
138
  self.logger.info(f"Resolved to [{self.connection_ip}]")
128
- except dns.resolver.NXDOMAIN:
129
- self.logger.error(f"Domain {self.service_name} doesn't exist - Couldn't resolve with "
130
- f"{self.dns_servers_list}.")
131
- pass
132
- return None
139
+ except dns.resolver.NXDOMAIN as e:
140
+ exception_type: str = type(e).__name__
141
+ error_string = (
142
+ f"Socket Client Connect: {exception_type}: "
143
+ f"Domain {self.service_name} doesn't exist - Couldn't resolve with {self.dns_servers_list}.")
144
+ print_api(error_string, logger=self.logger, logger_method='error')
145
+ return None, error_string
133
146
 
134
147
  # If DNS was resolved correctly or DNS servers weren't specified - we can try connecting.
135
148
  # If 'connection_ip' was manually specified or resolved with 'dnspython' - the connection
@@ -144,49 +157,31 @@ class SocketClient:
144
157
  try:
145
158
  # "connect()" to the server using address and port
146
159
  self.socket_instance.connect((destination, self.service_port))
147
- except ConnectionRefusedError:
148
- message = f"Couldn't connect to: {self.service_name}. The server is unreachable - Connection refused."
149
- print_api(message, logger=self.logger, logger_method='error', traceback_string=True, oneline=True)
150
- # Socket close will be handled in the thread_worker_main
151
- pass
152
- return None
153
- except ConnectionAbortedError:
154
- message = f"Connection was aborted (by the software on host) to {self.service_name}."
155
- print_api(message, logger=self.logger, logger_method='error', traceback_string=True, oneline=True)
156
- # Socket close will be handled in the thread_worker_main
157
- pass
158
- return None
159
- except socket.gaierror:
160
- message = f"Couldn't resolve [{self.service_name}] to IP using default methods. " \
161
- f"Domain doesn't exist or there's no IP assigned to it."
162
- print_api(message, logger=self.logger, logger_method='error', traceback_string=True, oneline=True)
163
- # Socket close will be handled in the thread_worker_main
164
- pass
165
- return None
166
- except ssl.SSLError:
167
- message = f"SSLError raised on connection to {self.service_name}."
168
- print_api(message, logger=self.logger, logger_method='error', traceback_string=True, oneline=True)
169
- # Socket close will be handled in the thread_worker_main
170
- pass
171
- return None
172
- except TimeoutError:
173
- message = f"TimeoutError raised on connection to {self.service_name}."
174
- print_api(message, logger=self.logger, logger_method='error', traceback_string=True, oneline=True)
175
- # Socket close will be handled in the thread_worker_main
176
- pass
177
- return None
178
- except ValueError as e:
179
- message = f'{str(e)} | on connect to [{self.service_name}].'
180
- print_api(message, logger=self.logger, logger_method='error')
181
- # Socket close will be handled in the thread_worker_main
182
- pass
183
- return None
160
+ except Exception as e:
161
+ exception_type: str = type(e).__name__
162
+ exception_error: str = tracebacks.get_as_string(one_line=True)
163
+ error_string: str = f"Socket Client Connect: {destination}: {exception_type}"
164
+
165
+ if exception_type in ['ConnectionRefusedError', 'ConnectionAbortedError', 'ConnectionResetError',
166
+ 'ssl.SSLError', 'TimeoutError']:
167
+ error_message: str = f"{error_string}: {exception_error}"
168
+ print_api(error_message, logger=self.logger, logger_method='error')
169
+ return None, error_message
170
+ elif exception_type == 'socket.gaierror':
171
+ custom_error_message: str = (
172
+ f"Couldn't resolve [{self.service_name}] to IP using default methods. "
173
+ f"Domain doesn't exist or there's no IP assigned to it.")
174
+ error_message: str = f"{error_string}: {custom_error_message}"
175
+ print_api(error_message, logger=self.logger, logger_method='error')
176
+ return None, error_message
177
+ else:
178
+ raise e
184
179
 
185
180
  # If everything was fine, we'll log the connection.
186
181
  self.logger.info("Connected...")
187
182
 
188
183
  # Return the connected socket.
189
- return self.socket_instance
184
+ return self.socket_instance, None
190
185
 
191
186
  def get_socket(self):
192
187
  return self.socket_instance
@@ -200,14 +195,12 @@ class SocketClient:
200
195
  def send_receive_to_service(self, request_bytes: bytearray):
201
196
  # Define variables
202
197
  function_service_data = None
203
- error_string = None
198
+ error_message = None
204
199
 
200
+ service_socket, error_message = self.service_connection()
205
201
  # If connection to service server wasn't successful
206
- if not self.service_connection():
207
- error_string = "Wasn't able to connect to service, closing the destination service socket"
208
- print_api(error_string, logger=self.logger, logger_method='error')
209
-
210
- # We'll close the socket and nullify the object
202
+ if error_message:
203
+ # Wasn't able to connect to service, closing the destination service socket and nullify the object.
211
204
  self.close_socket()
212
205
  # If the connection to the service was successful
213
206
  else:
@@ -227,7 +220,7 @@ class SocketClient:
227
220
 
228
221
  # If the socket disconnected on data send
229
222
  if error_on_send:
230
- error_string = f"Service socket closed on data send: {error_on_send}"
223
+ error_message = f"Service socket closed on data send: {error_on_send}"
231
224
 
232
225
  # We'll close the socket and nullify the object
233
226
  self.close_socket()
@@ -238,12 +231,12 @@ class SocketClient:
238
231
 
239
232
  # If data received is empty meaning the socket was closed on the other side
240
233
  if not function_service_data:
241
- error_string = "Service server closed the connection on receive"
234
+ error_message = "Service server closed the connection on receive"
242
235
 
243
236
  # We'll close the socket and nullify the object
244
237
  self.close_socket()
245
238
 
246
- return function_service_data, error_string, self.connection_ip, self.socket_instance
239
+ return function_service_data, error_message, self.connection_ip, self.socket_instance
247
240
 
248
241
  def send_receive_message_list_with_interval(
249
242
  self, requests_bytes_list: list, intervals_list: list, intervals_defaults: int, cycles: int = 1):
@@ -316,15 +309,15 @@ class SocketClient:
316
309
  # be passed.
317
310
  # If there was connection error or socket close, then "ssl_socket" of the "service_client"
318
311
  # will be empty.
319
- response_raw_bytes, error_string, self.connection_ip, service_ssl_socket = \
312
+ response_raw_bytes, error_message, self.connection_ip, service_ssl_socket = \
320
313
  self.send_receive_to_service(request_raw_bytes)
321
314
 
322
315
  # Adding the response to responses list. Same for error.
323
316
  responses_list.append(response_raw_bytes)
324
- errors_list.append(error_string)
317
+ errors_list.append(error_message)
325
318
 
326
319
  self.logger.info(f"Response: {response_raw_bytes}")
327
- self.logger.info(f"Error: {error_string}")
320
+ self.logger.info(f"Error: {error_message}")
328
321
 
329
322
  # So if the socket was closed and there was an error we can break the loop.
330
323
  # This is needed for more complex operations
@@ -359,7 +352,7 @@ class SocketClient:
359
352
  raise ValueError("If 'save_as_file' is True, then 'cert_file_path' must be provided.")
360
353
 
361
354
  # Connect and get the connected socket.
362
- server_socket_for_certificate = self.service_connection()
355
+ server_socket_for_certificate, error_message = self.service_connection()
363
356
  # Get the DER byte certificate from the socket.
364
357
  certificate_from_socket_der_bytes = ssl_base.get_certificate_from_socket(server_socket_for_certificate)
365
358
  print_api('Fetched certificate from socket.', logger=self.logger, **kwargs)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.16.35
3
+ Version: 2.16.37
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- atomicshop/__init__.py,sha256=UtKTcWqPrVHpu6j_BPCWMmIdo2RCZbCRac7Es1CoDwI,124
1
+ atomicshop/__init__.py,sha256=ym3OPl2oH_mHsSJELO-ElUvWSSDSZmEGXFuzBQB5lt8,124
2
2
  atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
3
3
  atomicshop/_create_pdf_demo.py,sha256=Yi-PGZuMg0RKvQmLqVeLIZYadqEZwUm-4A9JxBl_vYA,3713
4
4
  atomicshop/_patch_import.py,sha256=ENp55sKVJ0e6-4lBvZnpz9PQCt3Otbur7F6aXDlyje4,6334
@@ -90,7 +90,7 @@ atomicshop/basics/dicts.py,sha256=DeYHIh940pMMBrFhpXt4dsigFVYzTrlqWymNo4Pq_Js,14
90
90
  atomicshop/basics/dicts_nested.py,sha256=StYxYnYPa0SEJr1lmEwAv5zfERWWqoULeyG8e0zRAwE,4107
91
91
  atomicshop/basics/enumerations.py,sha256=41VVQYh_vnVapggxKg2IRU5e_EiMpZzX1n1mtxvoSzM,1364
92
92
  atomicshop/basics/enums.py,sha256=aAk1jFeQLvrC4NOpk9kgyX1-DCBr2ArPhZ8Ad7cMAVA,3537
93
- atomicshop/basics/exceptions.py,sha256=-1Gu8bHA3hrf11mmeaPuVE73jWV3EOyRgh2vSpWfveg,504
93
+ atomicshop/basics/exceptions.py,sha256=8mhhdQloYVz8D3u16I5O_cMeuIf5pPTXoi1iY94O9zw,616
94
94
  atomicshop/basics/guids.py,sha256=iRx5n18ATZWhpo748BwEjuLWLsu9y3OwF5-Adp-Dtik,403
95
95
  atomicshop/basics/hexs.py,sha256=i8CTG-J0TGGa25yFSbWEvpVyHFnof_qSWUrmXY-ylKM,1054
96
96
  atomicshop/basics/if_else.py,sha256=MakivJChofZCpr0mOVjwCthzpiaBxXVB-zv7GwMOqVo,202
@@ -125,7 +125,7 @@ atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,21
125
125
  atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
126
126
  atomicshop/mitm/config_static.py,sha256=ROAtbibSWSsF3BraUbhu-QO3MPIFqYY5KUKgsQbiSkk,7813
127
127
  atomicshop/mitm/config_toml_editor.py,sha256=2p1CMcktWRR_NW-SmyDwylu63ad5e0-w1QPMa8ZLDBw,1635
128
- atomicshop/mitm/connection_thread_worker.py,sha256=fybUBcZckgF7TC_P1z2yIYGH6ATX7jQEfsQSBuddt2s,16531
128
+ atomicshop/mitm/connection_thread_worker.py,sha256=YdPL2E2ZYV5nnuaXXtyBZssT4qDalVb05BVO62MwW0k,16627
129
129
  atomicshop/mitm/import_config.py,sha256=ZKQXxbtjVqzN9fpRrMwPNQREecH06RG8F_nXZAKTUJM,8182
130
130
  atomicshop/mitm/initialize_engines.py,sha256=VyJE8QnzlgD3QbX5inz5o6rC3zQ3is9CeTL7-B10g1w,8292
131
131
  atomicshop/mitm/message.py,sha256=URR5JKSuAT8XmGIkyprEjlPW2GW4ef_gfUz_GgcFseE,2184
@@ -299,21 +299,21 @@ atomicshop/wrappers/socketw/accepter.py,sha256=hZZKVYlF3LOHQJsSIEKXZUf6QXXWm-Atq
299
299
  atomicshop/wrappers/socketw/base.py,sha256=evoOIxg5Xff3THJnrVX00D5HobaOpDp6_e_gso7TJmA,2191
300
300
  atomicshop/wrappers/socketw/certificator.py,sha256=3CpQKtcW68FSbH6LVSEZTqWBS6Yg_-3K0x4nFkId4UY,12236
301
301
  atomicshop/wrappers/socketw/creator.py,sha256=3_OraDkw2DAWZfoSdY3svCGMOIxpjLEEY7NxWd7M5P4,9873
302
- atomicshop/wrappers/socketw/dns_server.py,sha256=VHV6s7vd0zqqW3dhE6li-260YRzmEB5ZUXqYJ9p0vVA,49069
302
+ atomicshop/wrappers/socketw/dns_server.py,sha256=RklzINNuoMQn4PGGQEI5hiAldprbVwwvikY6u9X-jTY,49067
303
303
  atomicshop/wrappers/socketw/exception_wrapper.py,sha256=B-X5SHLSUIWToihH2MKnOB1F4A81_X0DpLLfnYKYbEc,7067
304
304
  atomicshop/wrappers/socketw/get_process.py,sha256=aJC-_qFUv3NgWCSUzDI72E4z8_-VTZE9NVZ0CwUoNlM,5698
305
305
  atomicshop/wrappers/socketw/receiver.py,sha256=XVvWOoeCo3vA0O5p19ryi-hcDIyx382WNG7WzMNVeYk,9322
306
- atomicshop/wrappers/socketw/sender.py,sha256=5HPrgTS2pA1g-jbG1TUtR7drHT1Z_8UevlRCTwW7dgY,5007
306
+ atomicshop/wrappers/socketw/sender.py,sha256=vjgU1TaADJjaYiZOkLzfxcdCbmkvjhEhVjSV5mmIbw8,4969
307
307
  atomicshop/wrappers/socketw/sni.py,sha256=J1kPnQ77XwKN1pO5aOI1c_VfhuivCm95OOaQxMpPuZ0,17627
308
- atomicshop/wrappers/socketw/socket_client.py,sha256=XC-YaqA1wu0rvWQ9Q99DWLxcycKPkPc72pSnflzalfo,20320
308
+ atomicshop/wrappers/socketw/socket_client.py,sha256=B_4jI0RWorHcO3i9R9KLoX1-4NlTf2pfJfgXiMGH0jM,19861
309
309
  atomicshop/wrappers/socketw/socket_server_tester.py,sha256=Qobmh4XV8ZxLUaw-eW4ESKAbeSLecCKn2OWFzMhadk0,6420
310
310
  atomicshop/wrappers/socketw/socket_wrapper.py,sha256=WtylpezgIIBuz-A6PfM0hO1sm9Exd4j3qhDXcFc74-E,35567
311
311
  atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
312
312
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=w1AH-zf4mBuT4euf28UKij9ihM-b1BRU9Qfby0QDdqI,2957
313
313
  atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
314
314
  atomicshop/wrappers/winregw/winreg_network.py,sha256=bQ8Jql8bVGBJ0dt3VQ56lga_1LBOMLI3Km_otvvbU6c,7138
315
- atomicshop-2.16.35.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
316
- atomicshop-2.16.35.dist-info/METADATA,sha256=Dbczjg5jtonq5G-BaD0Hqj93hiHQhsodw5FN3Ytv6UM,10473
317
- atomicshop-2.16.35.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
318
- atomicshop-2.16.35.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
319
- atomicshop-2.16.35.dist-info/RECORD,,
315
+ atomicshop-2.16.37.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
316
+ atomicshop-2.16.37.dist-info/METADATA,sha256=ZuxU8sOc4ZRnmt_V-mWPB5p-Itv8PYnSrWGloBL_dTU,10473
317
+ atomicshop-2.16.37.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
318
+ atomicshop-2.16.37.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
319
+ atomicshop-2.16.37.dist-info/RECORD,,