atomicshop 2.20.4__py3-none-any.whl → 2.20.6__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.20.4'
4
+ __version__ = '2.20.6'
@@ -20,31 +20,31 @@ def main():
20
20
  install_nodejs_windows.install_nodejs_windows()
21
21
  install_nodejs_windows.add_nodejs_to_path()
22
22
  if not install_nodejs_windows.is_nodejs_installed():
23
- print_api("Node.js installation failed.")
23
+ print_api("Node.js installation failed.", color="red")
24
24
  return 1
25
25
 
26
- print_api("PIP Installing Robocorp.")
26
+ print_api("PIP Installing Robocorp.", color="blue")
27
27
  subprocess.check_call(["pip", "install", "--upgrade", "rpaframework"])
28
28
 
29
- print_api("PIP Installing Robocorp-Browser.")
29
+ print_api("PIP Installing Robocorp-Browser.", color="blue")
30
30
  subprocess.check_call(["pip", "install", "--upgrade", "robotframework-browser"])
31
31
 
32
- print_api("PIP Installing Robocorp-Recognition.")
32
+ print_api("PIP Installing Robocorp-Recognition.", color="blue")
33
33
  subprocess.check_call(["pip", "install", "--upgrade", "rpaframework-recognition"])
34
34
 
35
- print_api("PIP Installing pynput.")
35
+ print_api("PIP Installing pynput.", color="blue")
36
36
  subprocess.check_call(["pip", "install", "--upgrade", "pynput"])
37
37
 
38
- print_api("Installing Playwright browsers.")
38
+ print_api("Installing Playwright browsers.", color="blue")
39
39
  subprocess.check_call(["playwright", "install"])
40
40
 
41
- print_api("Initializing Robocorp Browser.")
41
+ print_api("Initializing Robocorp Browser.", color="blue")
42
42
  subprocess.check_call(["rfbrowser", "init"])
43
43
 
44
- print_api("Installing Additional modules.")
44
+ print_api("Installing Additional modules.", color="blue")
45
45
  subprocess.check_call(["pip", "install", "--upgrade", "matplotlib", "imagehash"])
46
46
 
47
- print_api("Installing Tesseract OCR.")
47
+ print_api("Installing Tesseract OCR.", color="blue")
48
48
  github_wrapper = githubw.GitHubWrapper(
49
49
  user_name="tesseract-ocr",
50
50
  repo_name="tesseract",
@@ -61,6 +61,22 @@ def main():
61
61
  # Add Tesseract to the PATH.
62
62
  subprocess.check_call(["setx", "PATH", f"%PATH%;{WINDOWS_TESSERACT_DEFAULT_INSTALLATION_DIRECTORY}"])
63
63
 
64
+ # Patch robocorp: Remove mouse to the center of the screen on control command.
65
+ # Import the library to find its path.
66
+ print_api("Patching: .\RPA\Windows\keywords\window.py", color="blue")
67
+ import RPA.Windows.keywords.window as window
68
+ window_file_path = window.__file__
69
+
70
+ # Patch the file.
71
+ with open(window_file_path, "r") as file:
72
+ file_content = file.read()
73
+ file_content = file_content.replace(
74
+ "window.item.MoveCursorToMyCenter(simulateMove=self.ctx.simulate_move)",
75
+ "# window.item.MoveCursorToMyCenter(simulateMove=self.ctx.simulate_move) # Patched to remove center placement during foreground window control."
76
+ )
77
+ with open(window_file_path, "w") as file:
78
+ file.write(file_content)
79
+
64
80
 
65
81
  if __name__ == '__main__':
66
82
  sys.exit(main())
@@ -99,8 +99,7 @@ class TCPServer:
99
99
  engines_usage: bool
100
100
  server_response_mode: bool
101
101
 
102
- listening_interface: str
103
- listening_port_list: list[int]
102
+ listening_address_list: list[str]
104
103
 
105
104
  forwarding_dns_service_ipv4_list___only_for_localhost: list[str]
106
105
 
@@ -45,9 +45,9 @@ class CreateModuleTemplate:
45
45
  self.responder_general_path: str = reference_folder_path + os.sep + REFERENCE_RESPONDER_FILE_NAME
46
46
  self.recorder_general_path: str = reference_folder_path + os.sep + REFERENCE_RECORDER_FILE_NAME
47
47
 
48
- self.parser_file_name: str = f"parser_{self.engine_name}.py"
49
- self.responder_file_name: str = f"responder_{self.engine_name}.py"
50
- self.recorder_file_name: str = f"recorder_{self.engine_name}.py"
48
+ self.parser_file_name: str = f"parser.py"
49
+ self.responder_file_name: str = f"responder.py"
50
+ self.recorder_file_name: str = f"recorder.py"
51
51
 
52
52
  self.create_template()
53
53
 
@@ -58,7 +58,7 @@ class CreateModuleTemplate:
58
58
  # Create the 'engines' directory if it doesn't exist.
59
59
  filesystem.create_directory(ENGINES_DIRECTORY_PATH)
60
60
 
61
- # Create new engines folder.
61
+ # Create new engines' folder.
62
62
  filesystem.create_directory(self.new_engine_directory)
63
63
 
64
64
  self._create_engine_module_from_reference(file_path=self.parser_general_path, module_type='parser')
@@ -75,10 +75,6 @@ class CreateModuleTemplate:
75
75
  domains_with_quotes: list = [f'"{domain}"' for domain in self.domains]
76
76
  config_lines_list.append(f'"domains" = [{", ".join(domains_with_quotes)}]\n')
77
77
  # config_lines_list.append(f'\n')
78
- config_lines_list.append(f'"parser_file" = "{self.parser_file_name}"')
79
- config_lines_list.append(f'"responder_file" = "{self.responder_file_name}"')
80
- config_lines_list.append(f'"recorder_file" = "{self.recorder_file_name}"\n')
81
- # config_lines_list.append(f'\n')
82
78
  config_lines_list.append(f'[mtls]')
83
79
  config_lines_list.append(f'# "subdomain.domain.com" = "file_name_in_current_dir.pem"')
84
80
 
@@ -52,10 +52,17 @@ class ModuleCategory:
52
52
  if not self.domain_list or self.domain_list[0] == '':
53
53
  raise ValueError(f"Engine Configuration file doesn't contain any domains: {engine_config_file_path}")
54
54
 
55
+ # This is needed for backwards compatibility before glass 1.8.2, atomicshop 2.20.6
56
+ # When the name of each file was following the pattern: parser_<EngineName>.py, responder_<EngineName>.py, recorder_<EngineName>.py
57
+ if os.path.isfile(f"{engine_directory_path}{os.sep}parser.py"):
58
+ file_name_suffix: str = ''
59
+ else:
60
+ file_name_suffix: str = f"_{self.engine_name}"
61
+
55
62
  # Full path to file
56
- self.parser_file_path = f"{engine_directory_path}{os.sep}{configuration_data['parser_file']}"
57
- self.responder_file_path = f"{engine_directory_path}{os.sep}{configuration_data['responder_file']}"
58
- self.recorder_file_path = f"{engine_directory_path}{os.sep}{configuration_data['recorder_file']}"
63
+ self.parser_file_path = f"{engine_directory_path}{os.sep}parser{file_name_suffix}.py"
64
+ self.responder_file_path = f"{engine_directory_path}{os.sep}responder{file_name_suffix}.py"
65
+ self.recorder_file_path = f"{engine_directory_path}{os.sep}recorder{file_name_suffix}.py"
59
66
 
60
67
  for subdomain, file_name in self.mtls.items():
61
68
  self.mtls[subdomain] = f'{engine_directory_path}{os.sep}{file_name}'
@@ -269,6 +269,7 @@ def mitm_server(config_file_path: str, script_version: str):
269
269
  # === Initialize DNS module ====================================================================================
270
270
  if config_static.DNSServer.enable:
271
271
  dns_process = multiprocessing.Process(
272
+ # dns_process = threading.Thread(
272
273
  target=dns_server.start_dns_server_multiprocessing_worker,
273
274
  kwargs={
274
275
  'listening_interface': config_static.DNSServer.listening_interface,
@@ -294,6 +295,7 @@ def mitm_server(config_file_path: str, script_version: str):
294
295
  dns_process.daemon = True
295
296
  dns_process.start()
296
297
 
298
+ # Wait for the DNS server to start and do the port test.
297
299
  is_alive: bool = False
298
300
  max_wait_time: int = 5
299
301
  while not is_alive:
@@ -307,16 +309,31 @@ def mitm_server(config_file_path: str, script_version: str):
307
309
  time.sleep(1)
308
310
  return 1
309
311
 
312
+ # Now we can check if the process wasn't terminated after the check.
313
+ max_wait_time: int = 5
314
+ while max_wait_time > 0:
315
+ is_alive = dns_process.is_alive()
316
+
317
+ if not is_alive:
318
+ message = "DNS Server process terminated."
319
+ print_api.print_api(message, error_type=True, color="red", logger=system_logger)
320
+ # Wait for the message to be printed and saved to file.
321
+ time.sleep(1)
322
+ return 1
323
+
324
+ time.sleep(1)
325
+ max_wait_time -= 1
326
+
310
327
  # === EOF Initialize DNS module ================================================================================
311
328
  # === Initialize TCP Server ====================================================================================
312
329
  if config_static.TCPServer.enable:
313
330
  engines_domains: dict = dict()
314
331
  for engine in engines_list:
315
332
  engines_domains[engine.engine_name] = engine.domain_list
333
+
316
334
  try:
317
335
  socket_wrapper_instance = socket_wrapper.SocketWrapper(
318
- listening_interface=config_static.TCPServer.listening_interface,
319
- listening_port_list=config_static.TCPServer.listening_port_list,
336
+ listening_address_list=config_static.TCPServer.listening_address_list,
320
337
  ca_certificate_name=config_static.MainConfig.ca_certificate_name,
321
338
  ca_certificate_filepath=config_static.MainConfig.ca_certificate_filepath,
322
339
  ca_certificate_crt_filepath=config_static.MainConfig.ca_certificate_crt_filepath,
@@ -245,7 +245,7 @@ def wrap_socket_with_ssl_context_client___default_certs___ignore_verification(
245
245
 
246
246
  :param socket_object: socket.socket object
247
247
  :param server_hostname: string, hostname of the server. Default is None.
248
- :param custom_pem_client_certificate_file_path: string, full file path for the client certificate PWM file.
248
+ :param custom_pem_client_certificate_file_path: string, full file path for the client certificate PEM file.
249
249
  Default is None.
250
250
  :param enable_sslkeylogfile_env_to_client_ssl_context: boolean, enables the SSLKEYLOGFILE environment variable
251
251
  to the SSL context. Default is False.
@@ -309,7 +309,7 @@ class DnsServer:
309
309
  error_messages.append(f"Port [{port}] is already in use by process: {process_info}")
310
310
 
311
311
  message = "\n".join(error_messages)
312
- print_api(f'DnsPortInUseError: {str(e)}', error_type=True, color="red", logger=self.logger)
312
+ print_api(f'DnsPortInUseError: {str(message)}', error_type=True, color="red", logger=self.logger)
313
313
  # Wait for the message to be printed and saved to file.
314
314
  time.sleep(1)
315
315
  raise DnsPortInUseError(message)
@@ -905,8 +905,6 @@ def start_dns_server_multiprocessing_worker(
905
905
  current_process_name = multiprocessing.current_process().name
906
906
  threading.current_thread().name = current_process_name
907
907
 
908
-
909
-
910
908
  try:
911
909
  dns_server_instance = DnsServer(
912
910
  listening_interface=listening_interface,
@@ -928,7 +926,6 @@ def start_dns_server_multiprocessing_worker(
928
926
  logger_name=logger_name
929
927
  )
930
928
  except (DnsPortInUseError, DnsConfigurationValuesError) as e:
931
- print_api(e, error_type=True, color="red", logger=dns_server_instance.logger)
932
929
  # Wait for the message to be printed and saved to file.
933
930
  time.sleep(1)
934
931
  return 1
@@ -261,12 +261,12 @@ class SNIHandler:
261
261
  self.sni_received_parameters.destination_name = self.domain_from_dns_server
262
262
  message = \
263
263
  f"SNI Handler: No SNI was passed, using domain from DNS Server: {self.domain_from_dns_server}"
264
- print_api(message, **(print_kwargs or {}))
264
+ print_api(message, color="yellow", **(print_kwargs or {}))
265
265
  # If DNS server is disabled, the domain from dns server will be empty.
266
266
  else:
267
267
  message = f"SNI Handler: No SNI was passed, No domain passed from DNS Server. " \
268
268
  f"Service name will be 'None'."
269
- print_api(message, **(print_kwargs or {}))
269
+ print_api(message, color="yellow", **(print_kwargs or {}))
270
270
 
271
271
  # Setting "server_hostname" as a domain.
272
272
  self.sni_received_parameters.ssl_socket.server_hostname = self.sni_received_parameters.destination_name
@@ -32,8 +32,7 @@ SNI_QUEUE = queues.NonBlockQueue()
32
32
  class SocketWrapper:
33
33
  def __init__(
34
34
  self,
35
- listening_interface: str,
36
- listening_port_list: list[int],
35
+ listening_address_list: list[str],
37
36
  forwarding_dns_service_ipv4_list___only_for_localhost: list = None,
38
37
  ca_certificate_name: str = None,
39
38
  ca_certificate_filepath: str = None,
@@ -76,9 +75,8 @@ class SocketWrapper:
76
75
  Socket Wrapper class that will be used to create sockets, listen on them, accept connections and send them to
77
76
  new threads.
78
77
 
79
- :param listening_interface: string, interface that will be listened on.
80
- Example: '0.0.0.0'. For all interfaces.
81
- :param listening_port_list: list, of ports that will be listened on.
78
+ :param listening_address_list: list, of ips+ports that will be listened on.
79
+ Example: ['0.0.0.0:443', '0.0.0.0:80']
82
80
  :param ca_certificate_name: CA certificate name.
83
81
  :param ca_certificate_filepath: CA certificate file path with '.pem' extension.
84
82
  :param ca_certificate_crt_filepath: CA certificate file path with '.crt' extension.
@@ -177,8 +175,7 @@ class SocketWrapper:
177
175
  by the domain name from the list in the dictionary.
178
176
  """
179
177
 
180
- self.listening_interface: str = listening_interface
181
- self.listening_port_list: list[int] = listening_port_list
178
+ self.listening_address_list: list[str] = listening_address_list
182
179
  self.ca_certificate_name: str = ca_certificate_name
183
180
  self.ca_certificate_filepath: str = ca_certificate_filepath
184
181
  self.ca_certificate_crt_filepath: str = ca_certificate_crt_filepath
@@ -321,11 +318,7 @@ class SocketWrapper:
321
318
  print_api(message, color='red', logger=self.logger)
322
319
  return 1
323
320
 
324
- ips_ports: list[str] = list()
325
- for port in self.listening_port_list:
326
- ips_ports.append(f"{self.listening_interface}:{port}")
327
-
328
- port_in_use = networks.get_processes_using_port_list(ips_ports)
321
+ port_in_use = networks.get_processes_using_port_list(self.listening_address_list)
329
322
  if port_in_use:
330
323
  error_messages: list = list()
331
324
  for port, process_info in port_in_use.items():
@@ -409,9 +402,11 @@ class SocketWrapper:
409
402
  self.listening_sockets = list()
410
403
 
411
404
  # Creating a socket for each port in the list set in configuration file
412
- for port in self.listening_port_list:
405
+ for address in self.listening_address_list:
406
+ ip_address, port_str = address.split(':')
407
+ port = int(port_str)
413
408
  socket_by_port = self.create_socket_ipv4_tcp(
414
- self.listening_interface, port)
409
+ ip_address, port)
415
410
 
416
411
  self.listening_sockets.append(socket_by_port)
417
412
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.20.4
3
+ Version: 2.20.6
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=db6JGtlhqdS5AI8AP9hTGCkD-0rCHHR2UqDNerpAIQE,123
1
+ atomicshop/__init__.py,sha256=Ze7AVg_bmEuygfC1cWbcsq1Z8ibD2N91Q7kgO8C7_h4,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
@@ -58,7 +58,7 @@ atomicshop/a_installs/win/fibratus.py,sha256=TU4e9gdZ_zI73C40uueJ59pD3qmN-UFGdX5
58
58
  atomicshop/a_installs/win/mongodb.py,sha256=AqyItXu19aaoe49pppDxtEkXey6PMy0PoT2Y_RmPpPE,179
59
59
  atomicshop/a_installs/win/nodejs.py,sha256=U519Dyt4bsQPbEg_PwnZL5tsbfqDr1BbhxwoQFZsSKo,200
60
60
  atomicshop/a_installs/win/pycharm.py,sha256=j_RSd7aDOyC3yDd-_GUTMLlQTmDrqtVFG--oUfGLiZk,140
61
- atomicshop/a_installs/win/robocorp.py,sha256=ExdMR705fW4iyNDZnH9YZMrio4FYEwNH_8nEP1GWkjM,2383
61
+ atomicshop/a_installs/win/robocorp.py,sha256=Ob8X9Czwd-OR3pudFIFft1dcUjDM0Pw0X03yfPaf3yw,3280
62
62
  atomicshop/a_installs/win/wsl_ubuntu_lts.py,sha256=dZbPRLNKFeMd6MotjkE6UDY9cOiIaaclIdR1kGYWI50,139
63
63
  atomicshop/a_mains/dns_gateway_setting.py,sha256=ncc2rFQCChxlNP59UshwmTonLqC6MWblrVAzbbz-13M,149
64
64
  atomicshop/a_mains/github_wrapper.py,sha256=F-PoZknVCxWPN0PTO6l7ZNiaYvo7OVFKFI_zlPt56ps,169
@@ -133,18 +133,18 @@ atomicshop/file_io/tomls.py,sha256=vZ_Wng5alLf8z6HSEZj7PS0XKDA-Iies9ihVWOkTcKo,1
133
133
  atomicshop/file_io/xlsxs.py,sha256=v_dyg9GD4LqgWi6wA1QuWRZ8zG4ZwB6Dz52ytdcmmmI,2184
134
134
  atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,2104
135
135
  atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
136
- atomicshop/mitm/config_static.py,sha256=DjSnDtMU8srdqca8s6Q-oFCWgjjiCjXRhyk-nafRAUk,7788
136
+ atomicshop/mitm/config_static.py,sha256=6naOZiB5dlZ4YlsgXuWhpmst17Bh3WaZbnrtYmjtOV4,7761
137
137
  atomicshop/mitm/config_toml_editor.py,sha256=2p1CMcktWRR_NW-SmyDwylu63ad5e0-w1QPMa8ZLDBw,1635
138
138
  atomicshop/mitm/connection_thread_worker.py,sha256=tn71RotrQOTo6dyAakuLlY4HrM5ia_0FbNKLCY6Xahg,29304
139
139
  atomicshop/mitm/import_config.py,sha256=0Ij14aISTllTOiWYJpIUMOWobQqGofD6uafui5uWllE,9272
140
- atomicshop/mitm/initialize_engines.py,sha256=rijND1jxt3Zs8P0jhcQZc0tgcWD4-nq8ARODiWzhurU,8278
140
+ atomicshop/mitm/initialize_engines.py,sha256=e2f7i7d0F6duZQRO2lOOzFBbmfnyIf_E5bqj0rL2IF8,8677
141
141
  atomicshop/mitm/message.py,sha256=CDhhm4BTuZE7oNZCjvIZ4BuPOW4MuIzQLOg91hJaxDI,3065
142
- atomicshop/mitm/mitm_main.py,sha256=DhkdUhe-l6wtX7eUDoy8lsOFhIZkfgxQhEdcYuZd2cQ,25228
142
+ atomicshop/mitm/mitm_main.py,sha256=hEiJ0N-bA4LMHe3GYZvYGRy2ea46SY7aUxaCidGsDoY,25837
143
143
  atomicshop/mitm/recs_files.py,sha256=ZAAD0twun-FtmbSniXe3XQhIlawvANNB_HxwbHj7kwI,3151
144
144
  atomicshop/mitm/shared_functions.py,sha256=0lzeyINd44sVEfFbahJxQmz6KAMWbYrW5ou3UYfItvw,1777
145
145
  atomicshop/mitm/statistic_analyzer.py,sha256=5_sAYGX2Xunzo_pS2W5WijNCwr_BlGJbbOO462y_wN4,27533
146
146
  atomicshop/mitm/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
147
- atomicshop/mitm/engines/create_module_template.py,sha256=TAzsA4eLD2wYr7auuL4Nf_71iXqn-BOBXlSkNVrnYD4,5336
147
+ atomicshop/mitm/engines/create_module_template.py,sha256=E518bIwztHshciTSGtJxdVhwjKgZ7fGRpAg23bSEmeE,4985
148
148
  atomicshop/mitm/engines/create_module_template_example.py,sha256=X5xhvbV6-g9jU_bQVhf_crZmaH50LRWz3bS-faQ18ds,489
149
149
  atomicshop/mitm/engines/__parent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
150
150
  atomicshop/mitm/engines/__parent/parser___parent.py,sha256=HHaCXhScl3OlPjz6eUxsDpJaZyk6BNuDMc9xCkeo2Ws,661
@@ -315,23 +315,23 @@ atomicshop/wrappers/socketw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
315
315
  atomicshop/wrappers/socketw/accepter.py,sha256=hZZKVYlF3LOHQJsSIEKXZUf6QXXWm-AtqXZevvaYigE,1732
316
316
  atomicshop/wrappers/socketw/base.py,sha256=EcosGkD8VzgBY3GeIHDSG29ThQfXwg3-GQPmBTAqTdw,3048
317
317
  atomicshop/wrappers/socketw/certificator.py,sha256=mtWPJ_ew3OSwt0-1W4jaoco1VIY4NRCrMv3mDUxb_Cc,12418
318
- atomicshop/wrappers/socketw/creator.py,sha256=aSwfN_IwXXf4Hob35vHXUxD_OPeshZcRDZU2hMyfKs0,13243
319
- atomicshop/wrappers/socketw/dns_server.py,sha256=QEHIQ1onGIOpwZ_nLXvGOgFCM5m-jSwh2HZ2eZC30cE,53337
318
+ atomicshop/wrappers/socketw/creator.py,sha256=ePGjde04Jgq1gscTfiIam9u7nx3GfszUz1Oi1_5j5b0,13243
319
+ atomicshop/wrappers/socketw/dns_server.py,sha256=FjdcZV34usfGWsHPpPc6LnO5q6sB0ugyDbfPrK58wiU,53252
320
320
  atomicshop/wrappers/socketw/exception_wrapper.py,sha256=B-X5SHLSUIWToihH2MKnOB1F4A81_X0DpLLfnYKYbEc,7067
321
321
  atomicshop/wrappers/socketw/get_process.py,sha256=aJC-_qFUv3NgWCSUzDI72E4z8_-VTZE9NVZ0CwUoNlM,5698
322
322
  atomicshop/wrappers/socketw/receiver.py,sha256=9B3MvcDqr4C3x2fsnjG5SQognd1wRqsBgikxZa0wXG8,8243
323
323
  atomicshop/wrappers/socketw/sender.py,sha256=aX_K8l_rHjd5AWb8bi5mt8-YTkMYVRDB6DnPqK_XDUE,4754
324
- atomicshop/wrappers/socketw/sni.py,sha256=T9PXROiTYYxrd_7X4Hoj9hoNPXXTQpa2HdvmBJJIoeA,17607
324
+ atomicshop/wrappers/socketw/sni.py,sha256=q-F-R1KtE94g8WGrR3QHgi-otXZJUPBprEwQqnY80_A,17639
325
325
  atomicshop/wrappers/socketw/socket_client.py,sha256=oa3GwS4OPgokrJE5_Oc4-5_wlXHxSH9J5f2DKebms8k,22035
326
326
  atomicshop/wrappers/socketw/socket_server_tester.py,sha256=Qobmh4XV8ZxLUaw-eW4ESKAbeSLecCKn2OWFzMhadk0,6420
327
- atomicshop/wrappers/socketw/socket_wrapper.py,sha256=i2-1asl25n_RAVvI0zJMw9VSlb3Mu0AD43VZZuJe7Bk,38740
327
+ atomicshop/wrappers/socketw/socket_wrapper.py,sha256=4apajkc4fR3V01_VvYtMH60Z7-mt19OeF_fyPj2ZKhs,38517
328
328
  atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
329
329
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=WcNyaqEZ82S5-f3kzqi1nllNT2Nd2P_zg8HqCc7vW4s,4120
330
330
  atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
331
331
  atomicshop/wrappers/winregw/winreg_installed_software.py,sha256=Qzmyktvob1qp6Tjk2DjLfAqr_yXV0sgWzdMW_9kwNjY,2345
332
332
  atomicshop/wrappers/winregw/winreg_network.py,sha256=AENV88H1qDidrcpyM9OwEZxX5svfi-Jb4N6FkS1xtqA,8851
333
- atomicshop-2.20.4.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
334
- atomicshop-2.20.4.dist-info/METADATA,sha256=vj3fQF5hXmJ1WwdtNNC7fJ1_eIebTpjKfAkROwEZuMM,10630
335
- atomicshop-2.20.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
336
- atomicshop-2.20.4.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
337
- atomicshop-2.20.4.dist-info/RECORD,,
333
+ atomicshop-2.20.6.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
334
+ atomicshop-2.20.6.dist-info/METADATA,sha256=68p1ayX03Wp47tjakHcnGkYLe2OUgnbVh6jwtFe-M2s,10630
335
+ atomicshop-2.20.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
336
+ atomicshop-2.20.6.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
337
+ atomicshop-2.20.6.dist-info/RECORD,,