atomicshop 2.19.3__py3-none-any.whl → 2.19.5__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.19.3'
4
+ __version__ = '2.19.5'
@@ -0,0 +1,12 @@
1
+ #! /usr/bin/env python3
2
+ import sys
3
+
4
+ from atomicshop.wrappers.nodejsw import install_nodejs_ubuntu
5
+
6
+
7
+ def main():
8
+ install_nodejs_ubuntu.install_nodejs_main()
9
+
10
+
11
+ if __name__ == "__main__":
12
+ sys.exit(main())
@@ -0,0 +1,11 @@
1
+ import sys
2
+
3
+ from atomicshop.wrappers.nodejsw import install_nodejs_windows
4
+
5
+
6
+ def main():
7
+ install_nodejs_windows.install_nodejs_windows()
8
+
9
+
10
+ if __name__ == "__main__":
11
+ sys.exit(main())
@@ -5,6 +5,7 @@ import tempfile
5
5
  from atomicshop.print_api import print_api
6
6
  from atomicshop.wrappers import githubw
7
7
  from atomicshop.permissions import permissions
8
+ from atomicshop.wrappers.nodejsw import install_nodejs_windows
8
9
 
9
10
 
10
11
  WINDOWS_TESSERACT_DEFAULT_INSTALLATION_DIRECTORY: str = r"C:\Program Files\Tesseract-OCR"
@@ -14,7 +15,9 @@ def main():
14
15
  if not permissions.is_admin():
15
16
  print_api("Please run this script as an Administrator.", color="red")
16
17
  return 1
17
- """
18
+
19
+ install_nodejs_windows.install_nodejs_windows()
20
+
18
21
  print_api("PIP Installing Robocorp.")
19
22
  subprocess.check_call(["pip", "install", "--upgrade", "rpaframework"])
20
23
 
@@ -43,7 +46,7 @@ def main():
43
46
 
44
47
  # The Admin needed to install Tesseract.
45
48
  subprocess.check_call([tesseract_installer, "/S"])
46
- """
49
+
47
50
  # Add Tesseract to the PATH.
48
51
  subprocess.check_call(["setx", "PATH", f"%PATH%;{WINDOWS_TESSERACT_DEFAULT_INSTALLATION_DIRECTORY}"])
49
52
 
@@ -420,6 +420,7 @@ def mitm_server_main(config_file_path: str, script_version: str):
420
420
  exit_cleanup()
421
421
  return 0
422
422
  except Exception as e:
423
+ print_api.print_api('', error_type=True, color='red', traceback_string=True)
423
424
  # The error logger will not be initiated if there will be a problem with configuration file or checks.
424
425
  if MITM_ERROR_LOGGER is not None:
425
426
  MITM_ERROR_LOGGER.write(e)
@@ -1,5 +1,6 @@
1
1
  import subprocess
2
2
  import requests
3
+ import argparse
3
4
 
4
5
  from ...basics import booleans
5
6
  from .. import githubw, ubuntu_terminal
@@ -121,6 +122,46 @@ def install_nodejs_ubuntu(
121
122
  is_nodejs_installed()
122
123
 
123
124
 
125
+ def install_nodejs_main():
126
+ """
127
+ The function will install Node.js on Ubuntu.
128
+ :return:
129
+ """
130
+
131
+ # Create the parser.
132
+ parser = argparse.ArgumentParser(description="Install Node.js on Ubuntu.")
133
+ parser.add_argument(
134
+ '--latest',
135
+ action='store_true',
136
+ help="Install the latest version of Node.js."
137
+ )
138
+ parser.add_argument(
139
+ '--lts',
140
+ action='store_true',
141
+ help="Install the LTS version of Node.js."
142
+ )
143
+ parser.add_argument(
144
+ '--version',
145
+ type=str,
146
+ help="Install a specific version of Node.js."
147
+ )
148
+ parser.add_argument(
149
+ '--force',
150
+ action='store_true',
151
+ help="Force the installation of Node.js."
152
+ )
153
+
154
+ # Parse the arguments.
155
+ args = parser.parse_args()
156
+
157
+ install_nodejs_ubuntu(
158
+ install_latest_version=args.latest,
159
+ install_lts=args.lts,
160
+ install_by_version_number=args.version,
161
+ force_install=args.force
162
+ )
163
+
164
+
124
165
  def install_npm_package_ubuntu(package_name: str, sudo: bool = True):
125
166
  """
126
167
  The function will install a npm package on Ubuntu.
@@ -0,0 +1,115 @@
1
+ import os
2
+ import requests
3
+ import time
4
+ import tempfile
5
+
6
+ from ... import web
7
+ from ...permissions import permissions
8
+ from .. import msiw
9
+ from ...print_api import print_api
10
+
11
+
12
+ WINDOWS_X64_SUFFIX: str = "x64.msi"
13
+
14
+
15
+ class NodeJSWindowsInstallerNoVersionsFound(Exception):
16
+ pass
17
+
18
+
19
+ class NodeJSWindowsInstallerMoreThanOneVersionFound(Exception):
20
+ pass
21
+
22
+
23
+ class NodeJSWindowsInstallerFailedToExtractFileNameFromString(Exception):
24
+ pass
25
+
26
+
27
+ class NodeJSWindowsInstallerFailedToExtractVersionInString(Exception):
28
+ pass
29
+
30
+
31
+ def get_latest_nodejs_version():
32
+ """
33
+ Fetch the latest Node.js version from the official Node.js website.
34
+ """
35
+ print_api("Fetching the latest Node.js version...")
36
+ url = "https://nodejs.org/dist/latest/SHASUMS256.txt"
37
+
38
+ response = requests.get(url, timeout=10)
39
+ response.raise_for_status()
40
+ # Parse the file for the Node.js version
41
+ found_versions: list = []
42
+ for line in response.text.splitlines():
43
+ if line.endswith(WINDOWS_X64_SUFFIX):
44
+ found_versions.append(line)
45
+
46
+ if not found_versions:
47
+ raise NodeJSWindowsInstallerNoVersionsFound("No Node.js versions found in [https://nodejs.org/dist/latest/SHASUMS256.txt]")
48
+ elif len(found_versions) > 1:
49
+ raise NodeJSWindowsInstallerMoreThanOneVersionFound(f"More than one Node.js version found:\n"
50
+ f"{'\n'.join(found_versions)}")
51
+
52
+ try:
53
+ file_name = found_versions[0].split(" ")[-1]
54
+ except IndexError:
55
+ raise NodeJSWindowsInstallerFailedToExtractFileNameFromString("Failed to extract the file name from the string.")
56
+
57
+ try:
58
+ version = file_name.replace("node-v", "").replace(f"-{WINDOWS_X64_SUFFIX}", "")
59
+ except Exception:
60
+ raise NodeJSWindowsInstallerFailedToExtractVersionInString("Failed to extract the version from the string.")
61
+
62
+ print_api(f"Latest Node.js version: {version}")
63
+ return version
64
+
65
+
66
+ def download_nodejs_installer(version):
67
+ """
68
+ Download the Node.js MSI installer for Windows.
69
+ """
70
+
71
+ version = f"v{version}"
72
+ nodejs_base_url = f"https://nodejs.org/dist/{version}/"
73
+ file_name = f"node-{version}-x64.msi"
74
+ download_url = nodejs_base_url + file_name
75
+ print_api(f"Downloading Node.js installer from: {download_url}")
76
+
77
+ # Make temporary directory to store the installer
78
+ temp_dir = tempfile.gettempdir()
79
+ temp_file_path = web.download(download_url, temp_dir)
80
+ return temp_file_path
81
+
82
+
83
+ def clean_up(installer_path):
84
+ """
85
+ Remove the installer file after installation.
86
+ """
87
+ try:
88
+ if os.path.exists(installer_path):
89
+ os.remove(installer_path)
90
+ print_api(f"Removed installer: {installer_path}")
91
+ except Exception as e:
92
+ print_api(f"Failed to clean up the installer: {e}")
93
+
94
+
95
+ def install_nodejs_windows() -> int:
96
+ if not permissions.is_admin():
97
+ print_api("This script requires administrative privileges to install Node.js.")
98
+ return 1
99
+
100
+ print_api("Starting Node.js installation process...")
101
+ version = get_latest_nodejs_version()
102
+ if not version:
103
+ print_api("Exiting: Could not fetch the latest Node.js version.")
104
+ return 1
105
+
106
+ installer_path = download_nodejs_installer(version)
107
+ if not installer_path:
108
+ print_api("Exiting: Failed to download the Node.js installer.")
109
+ return 1
110
+
111
+ msiw.install_msi(installer_path, silent_progress_bar=True)
112
+ time.sleep(5) # Wait a few seconds for the installation to complete
113
+ clean_up(installer_path)
114
+ print_api("Installation process finished.")
115
+ return 0
@@ -41,17 +41,44 @@ def delete_certificate_by_issuer_name(
41
41
  :param print_kwargs: dict, print_api kwargs.
42
42
  """
43
43
 
44
- store = wcrypt.CertOpenStore(
45
- CERT_STORE_PROV_SYSTEM, 0, None, STORE_LOCATION_TO_CERT_SYSTEM_STORE[store_location], store_location)
44
+ """
45
+ WinAPI doesn't like to do 2 actions in one iteration. So, first we will collect all certificates to remove,
46
+ and in the second iteration remove them.
47
+
48
+ Full Explanation:
49
+ When you iterate with for cert in store.CertEnumCertificatesInStore(): and call
50
+ cert.CertDeleteCertificateFromStore() inside that loop, you’re modifying the underlying certificate store
51
+ while its internal enumeration is still active. This can lead to a segmentation fault (access violation 0xC0000005).
52
+ By collecting the certificates in the first pass, you freeze the iteration so the store
53
+ doesn’t get mutated mid-enumeration.
54
+ In the second pass, when you actually remove them, you’re no longer in the middle of enumerating.
55
+ This prevents the store’s pointer from becoming invalid.
56
+
57
+ This approach should stop the Process finished with exit code -1073741819 (0xC0000005) issue.
58
+ """
46
59
 
60
+ store = wcrypt.CertOpenStore(
61
+ CERT_STORE_PROV_SYSTEM,
62
+ 0,
63
+ None,
64
+ STORE_LOCATION_TO_CERT_SYSTEM_STORE[store_location],
65
+ store_location
66
+ )
67
+
68
+ # Collect all matching certificates in a list
69
+ certs_to_remove = []
47
70
  for cert in store.CertEnumCertificatesInStore():
48
71
  # Certificate properties.
49
72
  # cert.CertEnumCertificateContextProperties()
50
73
  subject_string: str = wcrypt.CertNameToStr(cert.Subject)
51
74
  if subject_string == issuer_name:
52
75
  # Remove the certificate.
53
- cert.CertDeleteCertificateFromStore()
54
- print_api(f"Removed the Certificate with issuer: {issuer_name}", **(print_kwargs or {}))
76
+ certs_to_remove.append(cert)
77
+
78
+ # Remove all certificates from the list.
79
+ for cert in certs_to_remove:
80
+ cert.CertDeleteCertificateFromStore()
81
+ print_api(f"Removed the Certificate from store [{store_location}] with issuer [{issuer_name}]", **(print_kwargs or {}))
55
82
 
56
83
  # There is an exception about store close.
57
84
  # store.CertCloseStore()
@@ -298,7 +298,7 @@ class SocketWrapper:
298
298
  # Check file existence.
299
299
  if not filesystem.is_file_exists(file_path=self.custom_server_certificate_path):
300
300
  message = f"File not found: {self.custom_server_certificate_path}"
301
- print_api(message, color='red')
301
+ print_api(message, color='red', logger=self.logger)
302
302
  return 1
303
303
 
304
304
  # And if 'custom_private_key_path' field was populated in [advanced] section, we'll check its existence.
@@ -306,7 +306,7 @@ class SocketWrapper:
306
306
  # Check private key file existence.
307
307
  if not filesystem.is_file_exists(file_path=self.custom_private_key_path):
308
308
  message = f"File not found: {self.custom_private_key_path}"
309
- print_api(message, color='red')
309
+ print_api(message, color='red', logger=self.logger)
310
310
  return 1
311
311
 
312
312
  port_in_use = networks.get_processes_using_port_list(self.listening_port_list)
@@ -345,6 +345,8 @@ class SocketWrapper:
345
345
  issuer_name=self.ca_certificate_name)
346
346
  # If there is more than one certificate with the same name, delete them all.
347
347
  if is_installed_by_name and len(certificate_list_by_name) > 1:
348
+ message = f"More than one certificate with the same issuer name is installed. Removing all..."
349
+ print_api(message, color='yellow', logger=self.logger)
348
350
  certificates.delete_certificate_by_issuer_name(self.ca_certificate_name)
349
351
  # If there is only one certificate with the same name, check if it is the same certificate.
350
352
  elif is_installed_by_name and len(certificate_list_by_name) == 1:
@@ -355,6 +357,10 @@ class SocketWrapper:
355
357
  if not permissions.is_admin():
356
358
  raise SocketWrapperConfigurationValuesError(
357
359
  "You need to run the script with admin rights to uninstall the unused certificates.")
360
+ message = (
361
+ f"Certificate with the same issuer name is installed, but it is not the same certificate. "
362
+ f"Removing...")
363
+ print_api(message, color='yellow', logger=self.logger)
358
364
  certificates.delete_certificate_by_issuer_name(
359
365
  self.ca_certificate_name, store_location="ROOT", print_kwargs={'logger': self.logger})
360
366
 
@@ -367,7 +373,8 @@ class SocketWrapper:
367
373
  raise SocketWrapperConfigurationValuesError(
368
374
  "You need to run the script with admin rights to install the CA certificate.")
369
375
  certificates.install_certificate_file(
370
- self.ca_certificate_filepath, store_location="ROOT", print_kwargs={'logger': self.logger})
376
+ self.ca_certificate_filepath, store_location="ROOT",
377
+ print_kwargs={'logger': self.logger, 'color': 'blue'})
371
378
 
372
379
  # Creating listening sockets.
373
380
  def create_socket_ipv4_tcp(self, ip_address: str, port: int):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.19.3
3
+ Version: 2.19.5
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=gyk6mrX1OBCCtPgfOJ948fDBI1E_d4N4iQTn8PeeKhc,123
1
+ atomicshop/__init__.py,sha256=HqJjN2U9eg60cXrH3gI048pmphyRdHtu6prGubLOP9Q,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
@@ -51,11 +51,13 @@ atomicshop/a_installs/ubuntu/docker_rootless.py,sha256=9IPNtGZYjfy1_n6ZRt7gWz9KZ
51
51
  atomicshop/a_installs/ubuntu/docker_sudo.py,sha256=JzayxeyKDtiuT4Icp2L2LyFRbx4wvpyN_bHLfZ-yX5E,281
52
52
  atomicshop/a_installs/ubuntu/elastic_search_and_kibana.py,sha256=yRB-l1zBxdiN6av-FwNkhcBlaeu4zrDPjQ0uPGgpK2I,244
53
53
  atomicshop/a_installs/ubuntu/mongodb.py,sha256=xuRJS1qqOZ0EZp7of5R3tTjSu6CwBIxYg8-NaM7othE,230
54
+ atomicshop/a_installs/ubuntu/nodejs.py,sha256=Iax55VJpT2HZsdRv-JvxkLg6JPYpJ-M8_r-wI5ES_yQ,222
54
55
  atomicshop/a_installs/ubuntu/pycharm.py,sha256=Ld7YQBwPxrjuZcTG1K4kZqjbBdt8aooCVRa15u5FOmE,157
55
56
  atomicshop/a_installs/win/fibratus.py,sha256=TU4e9gdZ_zI73C40uueJ59pD3qmN-UFGdX5GFoVf6cM,179
56
57
  atomicshop/a_installs/win/mongodb.py,sha256=AqyItXu19aaoe49pppDxtEkXey6PMy0PoT2Y_RmPpPE,179
58
+ atomicshop/a_installs/win/nodejs.py,sha256=U519Dyt4bsQPbEg_PwnZL5tsbfqDr1BbhxwoQFZsSKo,200
57
59
  atomicshop/a_installs/win/pycharm.py,sha256=j_RSd7aDOyC3yDd-_GUTMLlQTmDrqtVFG--oUfGLiZk,140
58
- atomicshop/a_installs/win/robocorp.py,sha256=sxSqncQIXr4rA8lCr_SwDU18IxWZlNznDE2WY3vPEMM,1789
60
+ atomicshop/a_installs/win/robocorp.py,sha256=K5Y6Irniq_f56Lzacztna-348iJBpXwufMpds3gFaXk,1894
59
61
  atomicshop/a_installs/win/wsl_ubuntu_lts.py,sha256=dZbPRLNKFeMd6MotjkE6UDY9cOiIaaclIdR1kGYWI50,139
60
62
  atomicshop/a_mains/dns_gateway_setting.py,sha256=ncc2rFQCChxlNP59UshwmTonLqC6MWblrVAzbbz-13M,149
61
63
  atomicshop/a_mains/msi_unpacker.py,sha256=5hrkqETYt9HIqR_3PMf32_q06kCrIcsdm_RJV9oY438,188
@@ -132,7 +134,7 @@ atomicshop/mitm/connection_thread_worker.py,sha256=TzC-wTdCT7NIkO-x0myvGbDItbFPm
132
134
  atomicshop/mitm/import_config.py,sha256=0Ij14aISTllTOiWYJpIUMOWobQqGofD6uafui5uWllE,9272
133
135
  atomicshop/mitm/initialize_engines.py,sha256=-3B8xkXyPOwrC_mDJm_uaW9s56VeV-f6VTu4-8dou2s,8258
134
136
  atomicshop/mitm/message.py,sha256=mNo4Lphr_Jo6IlNX5mPJzABpogWGkjOhwI4meAivwHw,2987
135
- atomicshop/mitm/mitm_main.py,sha256=RqRlh5YIY2u817n_L1IUnki6JYXSmr7fTi3bjY5ygRA,23498
137
+ atomicshop/mitm/mitm_main.py,sha256=hLFg5ATozqY8S-4PgHXojy-gDYsj_J9cUFE33RXyyhQ,23584
136
138
  atomicshop/mitm/recs_files.py,sha256=ZAAD0twun-FtmbSniXe3XQhIlawvANNB_HxwbHj7kwI,3151
137
139
  atomicshop/mitm/shared_functions.py,sha256=0lzeyINd44sVEfFbahJxQmz6KAMWbYrW5ou3UYfItvw,1777
138
140
  atomicshop/mitm/statistic_analyzer.py,sha256=5_sAYGX2Xunzo_pS2W5WijNCwr_BlGJbbOO462y_wN4,27533
@@ -266,7 +268,8 @@ atomicshop/wrappers/mongodbw/install_mongodb_win.py,sha256=64EUQYx7VuMC3ndO2x3nS
266
268
  atomicshop/wrappers/mongodbw/mongo_infra.py,sha256=IjEF0jPzQz866MpTm7rnksnyyWQeUT_B2h2DA9ryAio,2034
267
269
  atomicshop/wrappers/mongodbw/mongodbw.py,sha256=ih3Gd45rg_70y4sGeu0eEJ3sJd9tEN4I5IqHZelRZJw,52854
268
270
  atomicshop/wrappers/nodejsw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
269
- atomicshop/wrappers/nodejsw/install_nodejs.py,sha256=TKGa3jSlSqZTL2NA0nMkWDFtlkz7rxGGn44ywCg7MN8,5228
271
+ atomicshop/wrappers/nodejsw/install_nodejs_ubuntu.py,sha256=wjpJdfAaY92RYl_L9esDIWuBMGeYH35RHJ5BVgMof8Y,6260
272
+ atomicshop/wrappers/nodejsw/install_nodejs_windows.py,sha256=wZBlhEyg-iYCDir0ces6RXPQTihp96VzTN3OApcd4c8,3716
270
273
  atomicshop/wrappers/playwrightw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
271
274
  atomicshop/wrappers/playwrightw/_tryouts.py,sha256=l1BLkFsiIMNlgv7nfZd1XGEvXQkIQkIcg48__9OaC00,4920
272
275
  atomicshop/wrappers/playwrightw/base.py,sha256=WeRpx8otdXuKSr-BjY-uCJTze21kbPpfitoOjKQz5-g,9818
@@ -290,7 +293,7 @@ atomicshop/wrappers/pycharmw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
290
293
  atomicshop/wrappers/pycharmw/ubuntu.py,sha256=m9MpgqvIYygulhPxo9g2zlGGXrihBpiY3GNLNyT-B7U,1290
291
294
  atomicshop/wrappers/pycharmw/win.py,sha256=jdnTkUqZX_BrMW8AmW-xGtxdV-wmmNr_NMA2jB6JHsQ,2725
292
295
  atomicshop/wrappers/pywin32w/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
293
- atomicshop/wrappers/pywin32w/cert_store.py,sha256=bpFm5nH9j6I9eJdLjPnSvo-g4OyJO7Sb5VddzVE9-UM,3156
296
+ atomicshop/wrappers/pywin32w/cert_store.py,sha256=dV1XyoKTFKZ-HCIVqU2Nd6CTZ8HANqjAXv26rsNzO6s,4365
294
297
  atomicshop/wrappers/pywin32w/console.py,sha256=LstHajPLgXp9qQxFNR44QfH10nOnNp3bCJquxaTquns,1175
295
298
  atomicshop/wrappers/pywin32w/winshell.py,sha256=i2bKiMldPU7_azsD5xGQDdMwjaM7suKJd3k0Szmcs6c,723
296
299
  atomicshop/wrappers/pywin32w/win_event_log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -316,14 +319,14 @@ atomicshop/wrappers/socketw/sender.py,sha256=aX_K8l_rHjd5AWb8bi5mt8-YTkMYVRDB6Dn
316
319
  atomicshop/wrappers/socketw/sni.py,sha256=T9PXROiTYYxrd_7X4Hoj9hoNPXXTQpa2HdvmBJJIoeA,17607
317
320
  atomicshop/wrappers/socketw/socket_client.py,sha256=oa3GwS4OPgokrJE5_Oc4-5_wlXHxSH9J5f2DKebms8k,22035
318
321
  atomicshop/wrappers/socketw/socket_server_tester.py,sha256=Qobmh4XV8ZxLUaw-eW4ESKAbeSLecCKn2OWFzMhadk0,6420
319
- atomicshop/wrappers/socketw/socket_wrapper.py,sha256=WtylpezgIIBuz-A6PfM0hO1sm9Exd4j3qhDXcFc74-E,35567
322
+ atomicshop/wrappers/socketw/socket_wrapper.py,sha256=S03micuzwD06BSz5YU8DsKfAs_toppgQsndpczj60s4,36124
320
323
  atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
321
324
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=fgMzDXI0cybwUEqAxprRmY3lqbh30KAV-jOpoFKT-m8,3395
322
325
  atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
323
326
  atomicshop/wrappers/winregw/winreg_installed_software.py,sha256=Qzmyktvob1qp6Tjk2DjLfAqr_yXV0sgWzdMW_9kwNjY,2345
324
327
  atomicshop/wrappers/winregw/winreg_network.py,sha256=AENV88H1qDidrcpyM9OwEZxX5svfi-Jb4N6FkS1xtqA,8851
325
- atomicshop-2.19.3.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
326
- atomicshop-2.19.3.dist-info/METADATA,sha256=Rh6fT-9IvY-K1PhKUFnKe3ow4asjkGDycu6faIOkurU,10630
327
- atomicshop-2.19.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
328
- atomicshop-2.19.3.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
329
- atomicshop-2.19.3.dist-info/RECORD,,
328
+ atomicshop-2.19.5.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
329
+ atomicshop-2.19.5.dist-info/METADATA,sha256=vkTvJ6-xa2PnBQvbzlWF2u7Hk_NBhPKermW9W9izX9A,10630
330
+ atomicshop-2.19.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
331
+ atomicshop-2.19.5.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
332
+ atomicshop-2.19.5.dist-info/RECORD,,