atomicshop 2.18.7__py3-none-any.whl → 2.18.9__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.18.7'
4
+ __version__ = '2.18.9'
@@ -1,6 +1,7 @@
1
1
  from datetime import datetime
2
2
  import threading
3
3
  import queue
4
+ import copy
4
5
 
5
6
  from ..wrappers.socketw import receiver, sender, socket_client, base
6
7
  from .. import websocket_parse
@@ -292,12 +293,17 @@ def thread_worker_main(
292
293
  try:
293
294
  while True:
294
295
  client_message = responder_queue.get()
296
+ print_api(f"Got message from queue, action: [{client_message.action}]", logger=network_logger, logger_method='info')
295
297
 
296
298
  # If the message is not a ClientMessage object, then we'll break the loop, since it is the exit signal.
297
299
  if not isinstance(client_message, ClientMessage):
298
300
  return
299
301
 
300
- raw_responses: list[bytes] = create_responder_response(client_message)
302
+ if client_message.action == 'service_connect':
303
+ raw_responses: list[bytes] = responder.create_connect_response(client_message)
304
+ else:
305
+ raw_responses: list[bytes] = create_responder_response(client_message)
306
+ print_api(f"Got responses from responder, count: [{len(raw_responses)}]", logger=network_logger, logger_method='info')
301
307
 
302
308
  is_socket_closed: bool = False
303
309
  for response_raw_bytes in raw_responses:
@@ -383,14 +389,14 @@ def thread_worker_main(
383
389
  # the close on the opposite socket.
384
390
  record_and_statistics_write(client_message)
385
391
 
386
- # if is_socket_closed:
387
- # exception_or_close_in_receiving_thread = True
388
- # finish_thread()
389
- # return
392
+ if is_socket_closed:
393
+ exception_or_close_in_receiving_thread = True
394
+ finish_thread()
395
+ return
390
396
 
391
397
  # If we're in response mode, execute responder.
392
398
  if config_static.TCPServer.server_response_mode:
393
- responder_queue.put(client_message)
399
+ responder_queue.put(copy.deepcopy(client_message))
394
400
  else:
395
401
  # if side == 'Client':
396
402
  # raise NotImplementedError
@@ -543,7 +549,7 @@ def thread_worker_main(
543
549
  client_message_connection.timestamp = datetime.now()
544
550
  client_message_connection.action = 'service_connect'
545
551
  client_message_connection.info = 'Server Response Mode'
546
- responder_queue.put(client_message_connection)
552
+ responder_queue.put(copy.deepcopy(client_message_connection))
547
553
 
548
554
  if connection_error:
549
555
  client_message_connection.timestamp = datetime.now()
@@ -552,30 +558,32 @@ def thread_worker_main(
552
558
  record_and_statistics_write(client_message_connection)
553
559
  else:
554
560
  client_exception_queue: queue.Queue = queue.Queue()
555
- service_exception_queue: queue.Queue = queue.Queue()
556
-
557
561
  client_thread = threading.Thread(
558
562
  target=receive_send_start, args=(client_socket, service_socket_instance, client_exception_queue),
559
563
  name=f"Thread-{thread_id}-Client")
560
564
  client_thread.daemon = True
561
565
  client_thread.start()
562
566
 
563
- service_thread = threading.Thread(
564
- target=receive_send_start, args=(service_socket_instance, client_socket, service_exception_queue),
565
- name=f"Thread-{thread_id}-Service")
566
- service_thread.daemon = True
567
- service_thread.start()
567
+ if not config_static.TCPServer.server_response_mode:
568
+ service_exception_queue: queue.Queue = queue.Queue()
569
+ service_thread = threading.Thread(
570
+ target=receive_send_start, args=(service_socket_instance, client_socket, service_exception_queue),
571
+ name=f"Thread-{thread_id}-Service")
572
+ service_thread.daemon = True
573
+ service_thread.start()
568
574
 
569
575
  client_thread.join()
570
- service_thread.join()
571
576
  if config_static.TCPServer.server_response_mode:
572
577
  responder_thread.join()
578
+ else:
579
+ service_thread.join()
573
580
 
574
581
  # If there was an exception in any of the threads, then we'll raise it here.
575
582
  if not client_exception_queue.empty():
576
583
  raise client_exception_queue.get()
577
- if not service_exception_queue.empty():
578
- raise service_exception_queue.get()
584
+ if not config_static.TCPServer.server_response_mode:
585
+ if not service_exception_queue.empty():
586
+ raise service_exception_queue.get()
579
587
 
580
588
  finish_thread()
581
589
  except Exception as e:
@@ -103,8 +103,13 @@ class ResponderParent:
103
103
 
104
104
  return parameter_value
105
105
 
106
- def build_byte_response_and_fill_lists(
107
- self, http_version: str, status_code: int, headers: dict, body: bytes, client_message: ClientMessage):
106
+ def build_byte_response(
107
+ self,
108
+ http_version: str,
109
+ status_code: int,
110
+ headers: dict,
111
+ body: bytes
112
+ ) -> bytes:
108
113
  """
109
114
  Create genuine response from input parameters.
110
115
  ---------------
@@ -145,8 +150,7 @@ class ResponderParent:
145
150
  :param status_code: HTTP Status Code of Response in HTTP Status line.
146
151
  :param headers: HTTP Headers of Response.
147
152
  :param body: HTTP body data of Response, bytes.
148
- :param client_message: client message class.
149
- :return:
153
+ :return: bytes of the response.
150
154
  """
151
155
 
152
156
  try:
@@ -174,7 +178,6 @@ class ResponderParent:
174
178
  print_api(message, error_type=True, logger=self.logger, logger_method='error', color='red')
175
179
 
176
180
  response_raw_bytes = b''
177
- pass
178
181
 
179
182
  # Parsing the response we created.
180
183
  response_parse_test = HTTPResponseParse(response_raw_bytes)
@@ -182,73 +185,15 @@ class ResponderParent:
182
185
  if response_parse_test.error:
183
186
  self.logger.error(response_parse_test.error)
184
187
  response_raw_bytes = b''
185
- response_decoded = None
186
188
  else:
187
189
  self.logger.info("Created Valid Byte Response.")
188
- response_decoded = response_parse_test.response_raw_decoded
189
-
190
- # Add 'response_raw_bytes' and 'response_decoded' to appropriate response lists in 'class_message'.
191
- self.add_response_elements_to_lists(client_message, response_raw_bytes, response_decoded)
192
190
 
193
- @staticmethod
194
- def add_response_elements_to_lists(class_client_message: ClientMessage, byte_response, decoded_response):
195
- """
196
- Function just adds the byte response to the 'response_list_of_raw_bytes'.
197
- :param class_client_message:
198
- :param byte_response:
199
- :param decoded_response:
200
- :return:
201
- """
191
+ return response_raw_bytes
202
192
 
203
- class_client_message.response_list_of_raw_bytes.append(byte_response)
204
- class_client_message.response_list_of_raw_decoded.append(decoded_response)
193
+ def create_connect_response(self, class_client_message: ClientMessage):
194
+ """ This function should be overridden in the child class. """
195
+ pass
205
196
 
206
197
  def create_response(self, class_client_message: ClientMessage):
207
- # noinspection GrazieInspection
208
- """
209
- Function to create Response based on ClientMessage and its Request.
210
-
211
- :param class_client_message: contains request and other parameters to help creating response.
212
- :return: "class_client_message.response_list_of_raw_bytes" is populated with list of responses in bytes.
213
- -----------------------------------
214
- # Remember that 'response_list_of_raw_bytes' is a list object that will contain byte response/s.
215
-
216
- # Example of creating 'response_list_of_raw_bytes' using 'build_byte_response' function:
217
- class_client_message.response_list_of_raw_bytes.append(
218
- self.build_byte_response(
219
- http_version=class_client_message.request_raw_decoded.request_version,
220
- status_code=200,
221
- headers=response_headers,
222
- body=b''
223
- )
224
- )
225
-
226
- # Or you can use the 'add_byte_response_to_response_list' function that will do it for you:
227
- byte_response = self.build_byte_response(
228
- http_version=class_client_message.request_raw_decoded.request_version,
229
- status_code=200,
230
- headers=response_headers,
231
- body=b''
232
- )
233
- self.add_byte_response_to_response_list(class_client_message, byte_response)
234
- -----------------------------------
235
- # Example of extracting variables from URL PATH based on custom PATH TEMPLATE:
236
- # (more examples in 'self.extract_variables_from_path_template' function description)
237
- template_path: str = "/hithere/<variable1>/else/<variable2>/tested/"
238
- path_variables: dict = extract_variables_from_path_template(
239
- path=class_client_message.request_raw_decoded.path,
240
- template_path=template_path
241
- )
242
- -----------------------------------
243
- # Example of extracting value from URL PATH parameters after question mark:
244
- parameter_value = extract_value_from_path_parameter(
245
- path=class_client_message.request_raw_decoded.path,
246
- parameter='test_id'
247
- )
248
- """
249
-
250
- byte_response = None
251
- decoded_response = None
252
- # class_client_message.response_list_of_raw_bytes.append(byte_response)
253
- self.add_response_elements_to_lists(class_client_message, byte_response, decoded_response)
254
- self.logger.info(f"Response: {class_client_message.response_list_of_raw_bytes}")
198
+ """ This function should be overridden in the child class. """
199
+ pass
@@ -1,6 +1,7 @@
1
1
  # These are specified with hardcoded paths instead of relative, because 'create_module_template.py' copies the content.
2
2
  from atomicshop.mitm.engines.__parent.responder___parent import ResponderParent
3
3
  from atomicshop.mitm.shared_functions import create_custom_logger
4
+ from atomicshop.mitm.message import ClientMessage
4
5
 
5
6
  """
6
7
  import time
@@ -22,6 +23,63 @@ class ResponderGeneral(ResponderParent):
22
23
 
23
24
  self.logger = create_custom_logger()
24
25
 
26
+ def create_response(self, class_client_message: ClientMessage):
27
+ # noinspection GrazieInspection
28
+ """
29
+ Function to create Response based on ClientMessage and its Request.
30
+
31
+ :param class_client_message: contains request and other parameters to help creating response.
32
+ :return: list of responses in bytes.
33
+ -----------------------------------
34
+
35
+ # Example of creating list of bytes using 'build_byte_response' function:
36
+ result_list: list[bytes] = list()
37
+ result_list.append(
38
+ self.build_byte_response(
39
+ http_version=class_client_message.request_raw_decoded.request_version,
40
+ status_code=200,
41
+ headers=response_headers,
42
+ body=b''
43
+ )
44
+ )
45
+
46
+ return result_list
47
+ -----------------------------------
48
+ # Example of extracting variables from URL PATH based on custom PATH TEMPLATE:
49
+ # (more examples in 'self.extract_variables_from_path_template' function description)
50
+ template_path: str = "/hithere/<variable1>/else/<variable2>/tested/"
51
+ path_variables: dict = extract_variables_from_path_template(
52
+ path=class_client_message.request_raw_decoded.path,
53
+ template_path=template_path
54
+ )
55
+ -----------------------------------
56
+ # Example of extracting value from URL PATH parameters after question mark:
57
+ parameter_value = extract_value_from_path_parameter(
58
+ path=class_client_message.request_raw_decoded.path,
59
+ parameter='test_id'
60
+ )
61
+ """
62
+
63
+ # byte_response: bytes = b''
64
+ # self.logger.info(f"Response: {byte_response}")
65
+
66
+ response_bytes_list: list[bytes] = list()
67
+ # response_bytes_list.append(byte_response)
68
+ return response_bytes_list
69
+
70
+ def create_connect_response(self, class_client_message: ClientMessage):
71
+ """
72
+ This is almost the same as 'create_response' function, but it's used only when the client connects and before
73
+ sending any data.
74
+ """
75
+
76
+ # byte_response: bytes = b''
77
+ # self.logger.info(f"Response: {byte_response}")
78
+
79
+ response_bytes_list: list[bytes] = list()
80
+ # response_bytes_list.append(byte_response)
81
+ return response_bytes_list
82
+
25
83
  # ==================================================================================================================
26
84
  # Uncomment this section in order to begin building custom responder.
27
85
  # @staticmethod
@@ -89,7 +147,7 @@ class ResponderGeneral(ResponderParent):
89
147
  # # === Building Headers. ===========================
90
148
  # # Response Date example: 'Tue, 08 Nov 2022 14:23: 00 GMT'
91
149
  # resp_headers = {
92
- # 'Date': self.get_current_formatted_time(),
150
+ # 'Date': self.get_current_formatted_time_http(),
93
151
  # 'Content-Length': str(len(resp_body)),
94
152
  # }
95
153
  #
@@ -109,7 +167,7 @@ class ResponderGeneral(ResponderParent):
109
167
  # # === Building Headers. ===========================
110
168
  # # Response Date example: 'Tue, 08 Nov 2022 14:23: 00 GMT'
111
169
  # resp_headers = {
112
- # 'Date': self.get_current_formatted_time(),
170
+ # 'Date': self.get_current_formatted_time_http(),
113
171
  # 'Content-Length': str(len(resp_body)),
114
172
  # 'Connection': 'keep-alive'
115
173
  # }
@@ -118,10 +176,10 @@ class ResponderGeneral(ResponderParent):
118
176
  #
119
177
  # def create_response(self, class_client_message: ClientMessage):
120
178
  # # Arranging important request entries to appropriate variables.
121
- # req_path = class_client_message.request_raw_decoded.path
122
- # req_command = class_client_message.request_raw_decoded.command
123
- # req_headers = class_client_message.request_raw_decoded.headers
124
- # req_body = class_client_message.request_raw_decoded.body
179
+ # req_path = class_client_message.request_auto_parsed.path
180
+ # req_command = class_client_message.request_auto_parsed.command
181
+ # req_headers = class_client_message.request_auto_parsed.headers
182
+ # req_body = class_client_message.request_auto_parsed.body
125
183
  #
126
184
  # # ====================================
127
185
  # # Case specific.
@@ -144,10 +202,12 @@ class ResponderGeneral(ResponderParent):
144
202
  #
145
203
  # # ==============================================================================
146
204
  # # === Building byte response. ==================================================
147
- # self.build_byte_response(
148
- # http_version=class_client_message.request_raw_decoded.request_version,
205
+ # byte_response = self.build_byte_response(
206
+ # http_version=class_client_message.request_auto_parsed.request_version,
149
207
  # status_code=resp_status_code,
150
208
  # headers=resp_headers,
151
- # body=resp_body_bytes,
152
- # client_message=class_client_message
209
+ # body=resp_body_bytes
153
210
  # )
211
+ #
212
+ # result_response_list: list[bytes] = [byte_response]
213
+ # return result_response_list
@@ -170,10 +170,24 @@ def fetch_urls_content_in_threads(
170
170
  return contents
171
171
 
172
172
 
173
- def _fetch_content(url, number_of_characters_per_link):
173
+ def fetch_urls_content(
174
+ urls: list[str],
175
+ number_of_characters_per_link: int
176
+ ) -> list[str]:
177
+ """ The function to fetch all URLs not concurrently without using threads """
178
+ contents = []
179
+
180
+ for url in urls:
181
+ data = _fetch_content(url, number_of_characters_per_link)
182
+ contents.append(data)
183
+
184
+ return contents
185
+
186
+
187
+ def _fetch_content(url, number_of_characters_per_link, headless: bool = True):
174
188
  """ Function to fetch content from a single URL using the synchronous Playwright API """
175
189
  with sync_playwright() as p:
176
- browser = p.chromium.launch(headless=True)
190
+ browser = p.chromium.launch(headless=headless)
177
191
  page = browser.new_page()
178
192
  page.goto(url)
179
193
 
@@ -67,6 +67,8 @@ def get_wmi_network_configuration(
67
67
  current_adapter = None
68
68
  if use_default_interface:
69
69
  default_connection_name_dict: dict = networks.get_default_connection_name()
70
+ if not default_connection_name_dict:
71
+ raise NetworkAdapterNotFoundError("Default network adapter not found.")
70
72
  # Get the first key from the dictionary.
71
73
  connection_name: str = list(default_connection_name_dict.keys())[0]
72
74
 
@@ -142,6 +142,7 @@ def get_default_dns_gateway() -> tuple[bool, list[str]]:
142
142
  Get the default DNS gateway from the Windows registry.
143
143
 
144
144
  :return: tuple(is dynamic boolean, list of DNS server IPv4s).
145
+ If nothing found will return (None, None).
145
146
  """
146
147
 
147
148
  def get_current_interface_status(current_interface_settings: dict) -> tuple[bool, list[str]]:
@@ -199,5 +200,8 @@ def get_default_dns_gateway() -> tuple[bool, list[str]]:
199
200
 
200
201
  break
201
202
 
203
+ if not function_result:
204
+ function_result = (None, None)
205
+
202
206
  # noinspection PyTypeChecker
203
207
  return function_result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.18.7
3
+ Version: 2.18.9
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=jd26BqEZL3LhjWeES224RKWQeZ2nlDuEDvDkj1P9FCg,123
1
+ atomicshop/__init__.py,sha256=9q2Mv782fS2rPEx31KLLEgXZwkYGkRCBCQ-ZrA0tyd4,123
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
@@ -127,7 +127,7 @@ atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,21
127
127
  atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
128
  atomicshop/mitm/config_static.py,sha256=HIzxyMEj7DZksYvJsN5VuKpB-_HSVvuR6U59ztS9gi0,7871
129
129
  atomicshop/mitm/config_toml_editor.py,sha256=2p1CMcktWRR_NW-SmyDwylu63ad5e0-w1QPMa8ZLDBw,1635
130
- atomicshop/mitm/connection_thread_worker.py,sha256=Of-QmuIbUO8Qd1N_BXdGQk2TnPpZd2z-Pxrj0wyq9S8,26758
130
+ atomicshop/mitm/connection_thread_worker.py,sha256=hCtaaXIPIbawPFaKXumxlmtiEXPakw_PQtZ3qSxuXVo,27439
131
131
  atomicshop/mitm/import_config.py,sha256=0Ij14aISTllTOiWYJpIUMOWobQqGofD6uafui5uWllE,9272
132
132
  atomicshop/mitm/initialize_engines.py,sha256=NWz0yBErSrYBn0xWkJDBcHStBJ-kcsv9VtorcSP9x5M,8258
133
133
  atomicshop/mitm/message.py,sha256=mNo4Lphr_Jo6IlNX5mPJzABpogWGkjOhwI4meAivwHw,2987
@@ -141,11 +141,11 @@ atomicshop/mitm/engines/create_module_template_example.py,sha256=X5xhvbV6-g9jU_b
141
141
  atomicshop/mitm/engines/__parent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
142
142
  atomicshop/mitm/engines/__parent/parser___parent.py,sha256=HHaCXhScl3OlPjz6eUxsDpJaZyk6BNuDMc9xCkeo2Ws,661
143
143
  atomicshop/mitm/engines/__parent/recorder___parent.py,sha256=exfElkgOU57hupV6opRCeYPHw91GIkIZL6UY3f2OClM,5635
144
- atomicshop/mitm/engines/__parent/responder___parent.py,sha256=7WQeR3UmMnN74bDwn-0nz2OfhXJ3-ClXpNGUFZ7wJUE,12004
144
+ atomicshop/mitm/engines/__parent/responder___parent.py,sha256=qIxfPiVZs4ZDDFYYeJJAiBWYg0cSfNDC-ibpGYnB2tA,8926
145
145
  atomicshop/mitm/engines/__reference_general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
146
  atomicshop/mitm/engines/__reference_general/parser___reference_general.py,sha256=57MEPZMAjTO6xBDZ-yt6lgGJyqRrP0Do5Gk_cgCiPns,2998
147
147
  atomicshop/mitm/engines/__reference_general/recorder___reference_general.py,sha256=El2_YHLoHUCiKfkAmGlXxtFpmSjsUFdsb8I1MvSAFaM,653
148
- atomicshop/mitm/engines/__reference_general/responder___reference_general.py,sha256=IUyQYMPeEhIARfALWiKPFeXagSQD6lRzAxUdi4ZIT88,7010
148
+ atomicshop/mitm/engines/__reference_general/responder___reference_general.py,sha256=r7WMv59xlVNttz15ppUvQbH2j5eKHAI-yIy1SCCu2lw,9523
149
149
  atomicshop/mitm/statistic_analyzer_helper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
150
150
  atomicshop/mitm/statistic_analyzer_helper/analyzer_helper.py,sha256=pk6L1t1ea1kvlBoR9QEJptOmaX-mumhwLsP2GCKukbk,5920
151
151
  atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py,sha256=UnnY_FSTiXEfZ8SkDKU2s2qpgPYu1oOT99ghmY-zzas,19992
@@ -275,7 +275,7 @@ atomicshop/wrappers/playwrightw/javascript.py,sha256=_bW7CAtm0Y8IHYrAalg5HpPFnk6
275
275
  atomicshop/wrappers/playwrightw/keyboard.py,sha256=zN3YddGO-qUkn6C0CRVFejP4cTuaUwXLDNFhFREjERY,422
276
276
  atomicshop/wrappers/playwrightw/locators.py,sha256=6wsLywZxDuii7mwv-zQsRbqQC8r7j96Bma5b5_7ZoVo,2411
277
277
  atomicshop/wrappers/playwrightw/mouse.py,sha256=-2FZbQtjgH7tdXWld6ZPGqlKFUdf5in0ujN0hewxa50,656
278
- atomicshop/wrappers/playwrightw/scenarios.py,sha256=RY56hH7UKvDoBr5j1JwP5xRoQtaz0AnCAkA602MurPk,8396
278
+ atomicshop/wrappers/playwrightw/scenarios.py,sha256=HopJJ-caAHuXxH8kiJHtlcFSI-89Zx7Fc6caGPOHC2A,8786
279
279
  atomicshop/wrappers/playwrightw/waits.py,sha256=PBFdz_PoM7Fo7O8hLqMrxNPzBEYgPoXwZceFFCGGeu8,7182
280
280
  atomicshop/wrappers/psutilw/cpus.py,sha256=w6LPBMINqS-T_X8vzdYkLS2Wzuve28Ydp_GafTCngrc,236
281
281
  atomicshop/wrappers/psutilw/disks.py,sha256=3ZSVoommKH1TWo37j_83frB-NqXF4Nf5q5mBCX8G4jE,9221
@@ -299,7 +299,7 @@ atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py,sha25
299
299
  atomicshop/wrappers/pywin32w/win_event_log/subscribes/schannel_logging.py,sha256=8nxIcNcbeEuvoBwhujgh7-oIpL9A6J-gg1NM8hOGAVA,3442
300
300
  atomicshop/wrappers/pywin32w/wmis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
301
301
  atomicshop/wrappers/pywin32w/wmis/helpers.py,sha256=uMXa27UfBpqXInvnmk7CZlqwRI2pg_I_HXelxO9nLLg,5020
302
- atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py,sha256=9H9MdS__GDBMm8H-xINEPFrJ8j-ErIb1ZqzkulTwLTo,5443
302
+ atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py,sha256=Jzl95viXZExrrlDTGHR0-wiXJo3jQRztmLXkigahFww,5574
303
303
  atomicshop/wrappers/pywin32w/wmis/win32process.py,sha256=qMzXtJ5hBZ5ydAyqpDbSx0nO2RJQL95HdmV5SzNKMhk,6826
304
304
  atomicshop/wrappers/socketw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
305
305
  atomicshop/wrappers/socketw/accepter.py,sha256=hZZKVYlF3LOHQJsSIEKXZUf6QXXWm-AtqXZevvaYigE,1732
@@ -318,9 +318,9 @@ atomicshop/wrappers/socketw/socket_wrapper.py,sha256=WtylpezgIIBuz-A6PfM0hO1sm9E
318
318
  atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
319
319
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=fgMzDXI0cybwUEqAxprRmY3lqbh30KAV-jOpoFKT-m8,3395
320
320
  atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
321
- atomicshop/wrappers/winregw/winreg_network.py,sha256=zZQfps-CdODQaTUADbHAwKHr5RUg7BLafnKWBbKaLN4,8728
322
- atomicshop-2.18.7.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
323
- atomicshop-2.18.7.dist-info/METADATA,sha256=QmsAiLi64OzjBDhhrVaF2nlUNIXoKfHiJ0KVmxfHtG8,10576
324
- atomicshop-2.18.7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
325
- atomicshop-2.18.7.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
326
- atomicshop-2.18.7.dist-info/RECORD,,
321
+ atomicshop/wrappers/winregw/winreg_network.py,sha256=AENV88H1qDidrcpyM9OwEZxX5svfi-Jb4N6FkS1xtqA,8851
322
+ atomicshop-2.18.9.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
323
+ atomicshop-2.18.9.dist-info/METADATA,sha256=Lrb80nXPqfa3g30GaTMVeYoROo39tuhNMbDdkxlJT4g,10576
324
+ atomicshop-2.18.9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
325
+ atomicshop-2.18.9.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
326
+ atomicshop-2.18.9.dist-info/RECORD,,