atomicshop 2.16.38__py3-none-any.whl → 2.16.39__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.38'
4
+ __version__ = '2.16.39'
@@ -42,7 +42,18 @@ def thread_worker_main(
42
42
  except AttributeError:
43
43
  http_command: str = str()
44
44
 
45
- response_size_bytes = ','.join([str(len(x)) for x in client_message.response_list_of_raw_bytes])
45
+ response_size_bytes: str = str()
46
+ for response_index, response in enumerate(client_message.response_list_of_raw_bytes):
47
+ if response is None:
48
+ response_size_bytes += ''
49
+ else:
50
+ response_size_bytes += str(len(response))
51
+
52
+ # If it is not the last entry, add the comma.
53
+ if response_index + 1 != len(client_message.response_list_of_raw_bytes):
54
+ response_size_bytes += ','
55
+
56
+ # response_size_bytes = ','.join([str(len(x)) for x in client_message.response_list_of_raw_bytes])
46
57
 
47
58
  if statistics_error_list and len(statistics_error_list) > 1:
48
59
  error_string = '||'.join(statistics_error_list)
@@ -258,7 +269,16 @@ def thread_worker_main(
258
269
  # Since we need a list for raw bytes, we'll add the 'response_raw_bytes' to our list object.
259
270
  # But we need to re-initiate it first.
260
271
  client_message.response_list_of_raw_bytes = list()
261
- client_message.response_list_of_raw_bytes.append(response_raw_bytes)
272
+ # If there was error during send or receive from the service and response was None,
273
+ # It means that there was no response at all because of the error.
274
+ if client_message.error and response_raw_bytes is None:
275
+ client_message.response_list_of_raw_bytes.append(None)
276
+ # If there was no error, but response came empty, it means that the service has closed the
277
+ # socket after it received the request, without sending any data.
278
+ elif client_message.error is None and response_raw_bytes is None:
279
+ client_message.response_list_of_raw_bytes.append("")
280
+ else:
281
+ client_message.response_list_of_raw_bytes.append(response_raw_bytes)
262
282
 
263
283
  client_message.response_list_of_raw_decoded = list()
264
284
  # Make HTTP Response parsing only if there was response at all.
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  from pathlib import Path
3
+ import socket
3
4
 
4
5
  from ..print_api import print_api
5
6
  from .. import config_init, filesystem, dns
@@ -111,12 +112,29 @@ def check_configurations() -> int:
111
112
  if (config_static.DNSServer.set_default_dns_gateway or
112
113
  config_static.DNSServer.set_default_dns_gateway_to_localhost or
113
114
  config_static.DNSServer.set_default_dns_gateway_to_default_interface_ipv4):
115
+ # Get current settings of the DNS gateway.
114
116
  is_dns_dynamic, current_dns_gateway = dns.get_default_dns_gateway()
115
- if is_dns_dynamic and not is_admin:
116
- message: str = \
117
- "Need to run the script with administrative rights to set the default DNS gateway.\nExiting..."
118
- print_api(message, color='red')
119
- return 1
117
+
118
+ if not is_admin:
119
+ if config_static.DNSServer.set_default_dns_gateway:
120
+ ipv4_address_list = config_static.DNSServer.set_default_dns_gateway
121
+ elif config_static.DNSServer.set_default_dns_gateway_to_localhost:
122
+ ipv4_address_list = ['127.0.0.1']
123
+ elif config_static.DNSServer.set_default_dns_gateway_to_default_interface_ipv4:
124
+ ipv4_address_list = [socket.gethostbyname(socket.gethostname())]
125
+ else:
126
+ raise ValueError("Error: DNS gateway configuration is not set.")
127
+
128
+ # If the setting is dynamic or static, but the needed target address is not in the current DNS gateway.
129
+ if (is_dns_dynamic or
130
+ (not is_dns_dynamic and current_dns_gateway != ipv4_address_list)):
131
+ status_string = 'Dynamic' if is_dns_dynamic else 'Static'
132
+ message: str = (
133
+ "Need to run the script with administrative rights to set the default DNS gateway.\n"
134
+ f"Current DNS gateway: {status_string}, {current_dns_gateway}\n"
135
+ f"Target DNS gateway: Static, {ipv4_address_list}")
136
+ print_api(message, color='red')
137
+ return 1
120
138
 
121
139
  # This is checked directly in the SocketWrapper.
122
140
  # if (config_static.Certificates.install_ca_certificate_to_root_store and not is_admin) or \
@@ -38,11 +38,17 @@ except win_console.NotWindowsConsoleError:
38
38
  def exit_cleanup():
39
39
  if permissions.is_admin():
40
40
  is_dns_dynamic, current_dns_gateway = dns.get_default_dns_gateway()
41
- print_api.print_api(f'Current DNS Gateway: {current_dns_gateway}')
41
+ status_string = 'Dynamic' if is_dns_dynamic else 'Static'
42
+ print_api.print_api(f'Current DNS Gateway: {status_string}, {current_dns_gateway}')
42
43
 
43
44
  if is_dns_dynamic != NETWORK_INTERFACE_IS_DYNAMIC or \
44
45
  (not is_dns_dynamic and current_dns_gateway != NETWORK_INTERFACE_IPV4_ADDRESS_LIST):
45
- dns.set_connection_dns_gateway_dynamic(use_default_connection=True)
46
+ if NETWORK_INTERFACE_IS_DYNAMIC:
47
+ dns.set_connection_dns_gateway_dynamic(use_default_connection=True)
48
+ else:
49
+ dns.set_connection_dns_gateway_static(
50
+ dns_servers=NETWORK_INTERFACE_IPV4_ADDRESS_LIST, use_default_connection=True)
51
+
46
52
  print_api.print_api("Returned default DNS gateway...", color='blue')
47
53
 
48
54
  # The process will not be executed if there was an exception in the beginning.
@@ -349,10 +355,16 @@ def mitm_server(config_file_path: str):
349
355
  # from the one specified in the configuration file.
350
356
  if (NETWORK_INTERFACE_IS_DYNAMIC or (not NETWORK_INTERFACE_IS_DYNAMIC and
351
357
  NETWORK_INTERFACE_IPV4_ADDRESS_LIST != dns_gateway_server_list)):
352
- dns.set_connection_dns_gateway_static(
353
- dns_servers=dns_gateway_server_list,
354
- use_default_connection=True
355
- )
358
+ try:
359
+ dns.set_connection_dns_gateway_static(
360
+ dns_servers=dns_gateway_server_list,
361
+ use_default_connection=True
362
+ )
363
+ except PermissionError as e:
364
+ print_api.print_api(e, error_type=True, color="red", logger=system_logger)
365
+ # Wait for the message to be printed and saved to file.
366
+ time.sleep(1)
367
+ return 1
356
368
 
357
369
  socket_thread = threading.Thread(
358
370
  target=socket_wrapper_instance.loop_for_incoming_sockets,
@@ -5,14 +5,16 @@ import random
5
5
  import getpass
6
6
  from tempfile import gettempdir
7
7
 
8
- from ...keyboard_press import send_alt_tab
9
- from ... import filesystem, print_api
10
-
11
8
  # noinspection PyPackageRequirements
12
- from playwright.sync_api import sync_playwright
9
+ from playwright.sync_api import sync_playwright, Error
13
10
  # Stealth options for playwright. External.
14
11
  from playwright_stealth import stealth_sync
15
12
 
13
+ from ...keyboard_press import send_alt_tab
14
+ from ... import filesystem, print_api
15
+
16
+ from . import infra
17
+
16
18
 
17
19
  class PlaywrightEngine:
18
20
  """
@@ -21,8 +23,11 @@ class PlaywrightEngine:
21
23
 
22
24
  def __init__(
23
25
  self,
24
- browser: str = 'chromium', headless: bool = False, incognito_mode: bool = True,
25
- browser_content_working_directory: str = None):
26
+ browser: str = 'chromium',
27
+ headless: bool = False,
28
+ incognito_mode: bool = True,
29
+ browser_content_working_directory: str = None
30
+ ):
26
31
  """
27
32
  :param browser: string, specifies which browser will be executed. Playwright default is 'chromium'.
28
33
  :param headless: boolean, specifies if browser will be executed in headless mode. Default is 'False'.
@@ -69,7 +74,15 @@ class PlaywrightEngine:
69
74
  # Also, 'sync_playwright()' has 'start()' function that executes the '__enter__()' function.
70
75
  # So, we can execute only that.
71
76
  self.playwright = sync_playwright().start()
72
- self.execute_browser()
77
+
78
+ try:
79
+ self.execute_browser()
80
+ except Error as e:
81
+ if "BrowserType.launch: Executable doesn't exist" in e.message:
82
+ infra.install_playwright()
83
+ self.execute_browser()
84
+ else:
85
+ raise e
73
86
 
74
87
  def stop(self):
75
88
  # Close browser objects. You can only close browser without stopping playwright.
@@ -79,8 +92,7 @@ class PlaywrightEngine:
79
92
  # creates '.stop' attribute for 'playwright' object, which gets the '__exit__' function reference name.
80
93
  # playwright.stop = self.__exit__
81
94
  # So, we can call 'playwright.stop()' in order to close the object without 'with' statement.
82
- # noinspection PyStatementEffect,PyUnresolvedReferences
83
- self.playwright.stop
95
+ self.playwright.stop()
84
96
 
85
97
  def execute_browser(self) -> None:
86
98
  """ Execute browser based on mode """
@@ -169,9 +181,13 @@ class PlaywrightEngine:
169
181
  self.page.wait_for_selector(f'{element}[{attribute}="{value}"]')
170
182
 
171
183
  def login(
172
- self, url_login: str,
173
- user_box_text: str = str(), pass_box_text: str = str(), submit_button_text: str = str(),
174
- username: str = str(), password: str = str(),
184
+ self,
185
+ url_login: str,
186
+ user_box_text: str = str(),
187
+ pass_box_text: str = str(),
188
+ submit_button_text: str = str(),
189
+ username: str = str(),
190
+ password: str = str(),
175
191
  credential_single_usage: bool = False
176
192
  ) -> None:
177
193
  """
@@ -0,0 +1,5 @@
1
+ import subprocess
2
+
3
+
4
+ def install_playwright():
5
+ subprocess.run(["playwright", "install"])
@@ -0,0 +1,14 @@
1
+ def type_text(page, text):
2
+ # Directly type into the focused field (if the cursor is already there)
3
+ page.keyboard.type(text)
4
+
5
+
6
+ def press_key(page, key: str):
7
+ """
8
+ Press a key on the keyboard.
9
+ :param page: playwright page
10
+ :param key: str, the key to press. Example: 'Enter'.
11
+ :return:
12
+ """
13
+ # Optionally, you can press Enter or other keys as needed
14
+ page.keyboard.press(key)
@@ -126,7 +126,7 @@ def network_fully_idle(page, timeout: int = 2000, print_kwargs: dict = None) ->
126
126
  # 'page.expect_response' will wait for the response to be received, and then return the response object.
127
127
  # When timeout is reached, it will raise a TimeoutError, which will break the while loop.
128
128
  with page.expect_response("**/*", timeout=timeout) as response_info:
129
- print_api.print_api(response_info.value, **print_kwargs)
129
+ print_api.print_api(response_info.value, **(print_kwargs or {}))
130
130
  except PlaywrightTimeoutError:
131
131
  break
132
132
 
@@ -153,13 +153,13 @@ def maximum_idle(page, print_kwargs: dict = None) -> None:
153
153
  :return: None
154
154
  """
155
155
 
156
- print_api.print_api('Before wait_for_load', **print_kwargs)
156
+ print_api.print_api('Before wait_for_load', **(print_kwargs or {}))
157
157
  load(page)
158
- print_api.print_api('After wait_for_load, Before wait_for_domcontentloaded', **print_kwargs)
158
+ print_api.print_api('After wait_for_load, Before wait_for_domcontentloaded', **(print_kwargs or {}))
159
159
  domcontentloaded(page)
160
- print_api.print_api('After wait_for_domcontentloaded', **print_kwargs)
160
+ print_api.print_api('After wait_for_domcontentloaded', **(print_kwargs or {}))
161
161
  # For some reason 'networkidle' can result in timeout errors, so currently this is disabled.
162
162
  # networkidle(page)
163
- print_api.print_api('Before wait_for_network_fully_idle', **print_kwargs)
163
+ print_api.print_api('Before wait_for_network_fully_idle', **(print_kwargs or {}))
164
164
  network_fully_idle(page, print_kwargs=print_kwargs)
165
- print_api.print_api('After wait_for_network_fully_idle', **print_kwargs)
165
+ print_api.print_api('After wait_for_network_fully_idle', **(print_kwargs or {}))
@@ -66,7 +66,7 @@ def set_socket_timeout(socket_object, seconds: int = 1):
66
66
 
67
67
  def get_default_ip_address() -> str:
68
68
  """
69
- Get the default IP address of the system.
69
+ Get the default IP address of the system (in other words the interface IPv4 that is used for internet connection).
70
70
  :return: string.
71
71
  """
72
72
  return socket.gethostbyname(socket.gethostname())
@@ -21,6 +21,33 @@ def install_packages(package_list: list[str]):
21
21
  subprocess.check_call(command)
22
22
 
23
23
 
24
+ def remove_packages(
25
+ package_list: list[str],
26
+ remove_config_files: bool = False,
27
+ remove_dependencies: bool = False,
28
+ ):
29
+ """
30
+ Function removes a list of packages.
31
+ :param package_list: list of strings, package names to remove. Regular removal is through 'apt remove'.
32
+ :param remove_config_files: bool, if True, the config files will be removed also through 'apt purge'.
33
+ :param remove_dependencies: bool, if True, the dependencies will be removed also through 'apt autoremove'.
34
+ :return:
35
+ """
36
+
37
+ # Construct the command with the package list
38
+ command = ["sudo", "apt", "remove", "-y"] + package_list
39
+
40
+ # If remove_config_files is True, add 'purge' to the command
41
+ if remove_config_files:
42
+ command.insert(2, "purge")
43
+
44
+ subprocess.check_call(command)
45
+
46
+ # If remove_dependencies is True, remove the dependencies
47
+ if remove_dependencies:
48
+ subprocess.check_call(["sudo", "apt", "autoremove", "-y"])
49
+
50
+
24
51
  def is_package_installed(package: str) -> bool:
25
52
  """
26
53
  Function checks if a package is installed.
@@ -164,9 +164,9 @@ def get_default_dns_gateway() -> tuple[bool, list[str]]:
164
164
  current_interface_dynamic_ipv4_address == default_ipv4_address)
165
165
  if static_and_ip_match or dynamic_and_ip_match:
166
166
  if interface_settings['NameServer']:
167
- function_result = (False, interface_settings['NameServer'].split(' '))
167
+ function_result = (False, interface_settings['NameServer'].split(','))
168
168
  else:
169
- function_result = (True, interface_settings['DhcpNameServer'].split(' '))
169
+ function_result = (True, interface_settings['DhcpNameServer'].split(','))
170
170
 
171
171
  break
172
172
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.16.38
3
+ Version: 2.16.39
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=UzoPJvYSWkcgbb6utU10RMAyutqGcdktQwV8ManJJD4,124
1
+ atomicshop/__init__.py,sha256=bIjUt8YtOUluRMl05Fh2mdwS0716FvRSvSe1Y-OEDjI,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
@@ -125,11 +125,11 @@ 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=YdPL2E2ZYV5nnuaXXtyBZssT4qDalVb05BVO62MwW0k,16627
129
- atomicshop/mitm/import_config.py,sha256=ZKQXxbtjVqzN9fpRrMwPNQREecH06RG8F_nXZAKTUJM,8182
128
+ atomicshop/mitm/connection_thread_worker.py,sha256=q_h4rRHupuUMwGsHEyKUhOLCtIAEHDB4loLrxApzQvQ,17859
129
+ atomicshop/mitm/import_config.py,sha256=0Ij14aISTllTOiWYJpIUMOWobQqGofD6uafui5uWllE,9272
130
130
  atomicshop/mitm/initialize_engines.py,sha256=VyJE8QnzlgD3QbX5inz5o6rC3zQ3is9CeTL7-B10g1w,8292
131
131
  atomicshop/mitm/message.py,sha256=URR5JKSuAT8XmGIkyprEjlPW2GW4ef_gfUz_GgcFseE,2184
132
- atomicshop/mitm/mitm_main.py,sha256=ICQS8-4-owDhPUIQohymLShzgCZwgq7jUocZHX1J3Zo,22592
132
+ atomicshop/mitm/mitm_main.py,sha256=tT6U4UuJ1PgNs__gDkExSR_qIbCjdBPkOQl8RPMMC5c,23224
133
133
  atomicshop/mitm/recs_files.py,sha256=mMyO1kPB-VkS_pbWCDhZHKdbWzlPbYSout61QuzHOao,3077
134
134
  atomicshop/mitm/shared_functions.py,sha256=l6oEyv4ug5D_03V3QLADYoocbcL2Ml_dYVW2WKM21l4,1818
135
135
  atomicshop/mitm/statistic_analyzer.py,sha256=5_sAYGX2Xunzo_pS2W5WijNCwr_BlGJbbOO462y_wN4,27533
@@ -189,7 +189,7 @@ atomicshop/wrappers/pipw.py,sha256=mu4jnHkSaYNfpBiLZKMZxEX_E2LqW5BVthMZkblPB_c,1
189
189
  atomicshop/wrappers/process_wrapper_pbtk.py,sha256=ycPmBRnv627RWks6N8OhxJQe8Gu3h3Vwj-4HswPOw0k,599
190
190
  atomicshop/wrappers/pyopensslw.py,sha256=OBWxA6EJ2vU_Qlf4M8m6ilcG3hyYB4yB0EsXUf7NhEU,6804
191
191
  atomicshop/wrappers/sysmonw.py,sha256=MFF8ts0gHbXn2_QeH196UncOUtm4MnM2cQBzTOnfrnk,5351
192
- atomicshop/wrappers/ubuntu_terminal.py,sha256=8BgL8EtIashrYnBxrV5R4ZLtL0mosfNHyWfV0ZjoN8w,10963
192
+ atomicshop/wrappers/ubuntu_terminal.py,sha256=3UJaje_Ke5G9xEyj3b37XZ_KjR_FSSnb4gupdCyI-jE,11965
193
193
  atomicshop/wrappers/wslw.py,sha256=2Z7X0j5M2hoRZjbHfm_vqwNXZeptsdkNCdhdcM_S9vo,6998
194
194
  atomicshop/wrappers/certauthw/certauth.py,sha256=hKedW0DOWlEigSNm8wu4SqHkCQsGJ1tJfH7s4nr3Bk0,12223
195
195
  atomicshop/wrappers/certauthw/certauthw.py,sha256=4WvhjANI7Kzqrr_nKmtA8Kf7B6rute_5wfP65gwQrjw,8082
@@ -264,12 +264,14 @@ atomicshop/wrappers/playwrightw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
264
264
  atomicshop/wrappers/playwrightw/_tryouts.py,sha256=l1BLkFsiIMNlgv7nfZd1XGEvXQkIQkIcg48__9OaC00,4920
265
265
  atomicshop/wrappers/playwrightw/base.py,sha256=WeRpx8otdXuKSr-BjY-uCJTze21kbPpfitoOjKQz5-g,9818
266
266
  atomicshop/wrappers/playwrightw/combos.py,sha256=215y7wugyyBrFK9_0WutnMXsF1jqJ2PLm9eHEa2PMz0,7145
267
- atomicshop/wrappers/playwrightw/engine.py,sha256=0kzlt9lDcFiMFCGUUndYftt3OMCvzxmaSTqGy9XEDLM,14887
267
+ atomicshop/wrappers/playwrightw/engine.py,sha256=fapOeaqSMNoxJucTvhzp30cKfKNSVe45drhZJcJ-fOk,15191
268
+ atomicshop/wrappers/playwrightw/infra.py,sha256=ncp62l6CgAgLz4lqBtKEWZO_6ES8cqnbzJBov-tlpBo,97
268
269
  atomicshop/wrappers/playwrightw/javascript.py,sha256=CL3tVE9C4SVvy76FEgGCl77B-xziCG6JZR5Ed8IfcSo,1112
270
+ atomicshop/wrappers/playwrightw/keyboard.py,sha256=zN3YddGO-qUkn6C0CRVFejP4cTuaUwXLDNFhFREjERY,422
269
271
  atomicshop/wrappers/playwrightw/locators.py,sha256=6wsLywZxDuii7mwv-zQsRbqQC8r7j96Bma5b5_7ZoVo,2411
270
272
  atomicshop/wrappers/playwrightw/mouse.py,sha256=-2FZbQtjgH7tdXWld6ZPGqlKFUdf5in0ujN0hewxa50,656
271
273
  atomicshop/wrappers/playwrightw/scenarios.py,sha256=Wz7aVYfG7K4fuSe_TUAc1jhFXVq5jYvZKbDtvqUiONc,5236
272
- atomicshop/wrappers/playwrightw/waits.py,sha256=3yTyC-AlCU-WfUI5kgwrDON4S3O8YMbMBDSlbqImBoQ,7134
274
+ atomicshop/wrappers/playwrightw/waits.py,sha256=PBFdz_PoM7Fo7O8hLqMrxNPzBEYgPoXwZceFFCGGeu8,7182
273
275
  atomicshop/wrappers/psutilw/cpus.py,sha256=w6LPBMINqS-T_X8vzdYkLS2Wzuve28Ydp_GafTCngrc,236
274
276
  atomicshop/wrappers/psutilw/disks.py,sha256=3ZSVoommKH1TWo37j_83frB-NqXF4Nf5q5mBCX8G4jE,9221
275
277
  atomicshop/wrappers/psutilw/memories.py,sha256=_S0aL8iaoIHebd1vOFrY_T9aROM5Jx2D5CvDh_4j0Vc,528
@@ -296,7 +298,7 @@ atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py,sha256=9H9MdS__GDBMm8H-
296
298
  atomicshop/wrappers/pywin32w/wmis/win32process.py,sha256=qMzXtJ5hBZ5ydAyqpDbSx0nO2RJQL95HdmV5SzNKMhk,6826
297
299
  atomicshop/wrappers/socketw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
298
300
  atomicshop/wrappers/socketw/accepter.py,sha256=hZZKVYlF3LOHQJsSIEKXZUf6QXXWm-AtqXZevvaYigE,1732
299
- atomicshop/wrappers/socketw/base.py,sha256=evoOIxg5Xff3THJnrVX00D5HobaOpDp6_e_gso7TJmA,2191
301
+ atomicshop/wrappers/socketw/base.py,sha256=DV6BWao9kiLAWimhVDKGEi3ISVaWk5iPHXtBHrO3uwc,2264
300
302
  atomicshop/wrappers/socketw/certificator.py,sha256=3CpQKtcW68FSbH6LVSEZTqWBS6Yg_-3K0x4nFkId4UY,12236
301
303
  atomicshop/wrappers/socketw/creator.py,sha256=3_OraDkw2DAWZfoSdY3svCGMOIxpjLEEY7NxWd7M5P4,9873
302
304
  atomicshop/wrappers/socketw/dns_server.py,sha256=RklzINNuoMQn4PGGQEI5hiAldprbVwwvikY6u9X-jTY,49067
@@ -311,9 +313,9 @@ atomicshop/wrappers/socketw/socket_wrapper.py,sha256=WtylpezgIIBuz-A6PfM0hO1sm9E
311
313
  atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
312
314
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=w1AH-zf4mBuT4euf28UKij9ihM-b1BRU9Qfby0QDdqI,2957
313
315
  atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
314
- atomicshop/wrappers/winregw/winreg_network.py,sha256=bQ8Jql8bVGBJ0dt3VQ56lga_1LBOMLI3Km_otvvbU6c,7138
315
- atomicshop-2.16.38.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
316
- atomicshop-2.16.38.dist-info/METADATA,sha256=9X8gvogTkh8eb7rNY2gJgWalFHxpMdPmNxkDkSBv6SM,10473
317
- atomicshop-2.16.38.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
318
- atomicshop-2.16.38.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
319
- atomicshop-2.16.38.dist-info/RECORD,,
316
+ atomicshop/wrappers/winregw/winreg_network.py,sha256=4tIBitgT4X_y76k3T1ychRu85KNRflLfjFumSmoj7es,7138
317
+ atomicshop-2.16.39.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
318
+ atomicshop-2.16.39.dist-info/METADATA,sha256=CWPz7RJ4Ri2Jd_hddn8Z3-ZSm66UJN0m2kQDXHZby9E,10473
319
+ atomicshop-2.16.39.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
320
+ atomicshop-2.16.39.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
321
+ atomicshop-2.16.39.dist-info/RECORD,,