atomicshop 2.15.0__py3-none-any.whl → 2.15.1__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.15.0'
4
+ __version__ = '2.15.1'
atomicshop/filesystem.py CHANGED
@@ -1453,3 +1453,17 @@ def backup_file(file_path: str, backup_directory: str, timestamp_as_prefix: bool
1453
1453
  file_name: str = f"{file_name_no_extension}_{timestamp}{file_extension}"
1454
1454
  backup_file_path: str = str(Path(backup_directory) / file_name)
1455
1455
  move_file(file_path, backup_file_path)
1456
+
1457
+
1458
+ def find_file(file_name: str, directory_path: str):
1459
+ """
1460
+ The function finds the file in the directory recursively.
1461
+ :param file_name: string, The name of the file to find.
1462
+ :param directory_path: string, The directory to search in.
1463
+ :return:
1464
+ """
1465
+ for dirpath, dirnames, filenames in os.walk(directory_path):
1466
+ for filename in filenames:
1467
+ if filename == file_name:
1468
+ return os.path.join(dirpath, filename)
1469
+ return None
@@ -1,12 +1,15 @@
1
1
  import os
2
- import subprocess
3
2
  import requests
3
+ from typing import Union
4
4
 
5
- from ... import urls, web
5
+ from ... import urls, web, permissions, get_process_list, filesystem
6
6
  from ...print_api import print_api
7
+ from .. import msiw
7
8
 
8
9
 
9
10
  MONGODB_DOWNLOAD_PAGE_URL: str = 'https://www.mongodb.com/try/download/community'
11
+ WHERE_TO_SEARCH_FOR_MONGODB_EXE: str = 'C:\\Program Files\\MongoDB\\Server\\'
12
+ MONGODB_EXE_NAME: str = 'mongod.exe'
10
13
 
11
14
 
12
15
  class MongoDBWebPageNoSuccessCodeError(Exception):
@@ -49,6 +52,7 @@ def get_latest_mongodb_download_url(
49
52
  for url in windows_urls:
50
53
  if f'-{major_specific}.' in url:
51
54
  windows_urls = [url]
55
+ break
52
56
 
53
57
  if not windows_urls:
54
58
  raise MongoDBNoDownloadLinkForWindowsError(
@@ -58,32 +62,28 @@ def get_latest_mongodb_download_url(
58
62
  return windows_urls[0]
59
63
 
60
64
 
61
- def install_mongodb(installer_path):
62
- try:
63
- subprocess.run([installer_path, '/install', '/quiet', '/norestart'], check=True)
64
- print_api("MongoDB installation completed successfully.", color='green')
65
- except subprocess.CalledProcessError as e:
66
- raise MongoDBInstallationError(
67
- f"An error occurred during the installation: {e}\n"
68
- f"Try running manually: {installer_path}")
65
+ def is_service_running() -> bool:
66
+ """
67
+ Check if the MongoDB service is running.
68
+ :return: bool, True if the MongoDB service is running, False otherwise.
69
+ """
70
+ current_processes: dict = (
71
+ get_process_list.GetProcessList(get_method='pywin32', connect_on_init=True).get_processes())
72
+
73
+ for pid, process_info in current_processes.items():
74
+ if MONGODB_EXE_NAME in process_info['name']:
75
+ return True
76
+
77
+ return False
69
78
 
70
79
 
71
- def is_installed() -> bool:
80
+ def is_installed() -> Union[str, None]:
72
81
  """
73
82
  Check if MongoDB is installed.
74
- :return: bool, True if MongoDB is installed, False otherwise.
83
+ :return: string if MongoDB executable is found, None otherwise.
75
84
  """
76
- try:
77
- # Run the 'mongo' command to see if MongoDB is installed
78
- result = subprocess.run(['mongo', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
79
85
 
80
- # Check the return code
81
- if result.returncode == 0:
82
- return True
83
- else:
84
- return False
85
- except FileNotFoundError:
86
- return False
86
+ return filesystem.find_file(MONGODB_EXE_NAME, WHERE_TO_SEARCH_FOR_MONGODB_EXE)
87
87
 
88
88
 
89
89
  def download_install_latest_main(
@@ -99,11 +99,26 @@ def download_install_latest_main(
99
99
  :return:
100
100
  """
101
101
 
102
- if is_installed():
103
- print_api("MongoDB is already installed.", color='blue')
102
+ if not permissions.is_admin():
103
+ print_api("This function requires administrator privileges.", color='red')
104
+ return 1
105
+
106
+ if is_service_running():
107
+ print_api("MongoDB service is running - already installed.", color='blue')
104
108
 
105
109
  if not force:
106
110
  return 0
111
+ else:
112
+ print_api("MongoDB is service is not running.")
113
+
114
+ mongo_is_installed: Union[str, None] = is_installed()
115
+ if is_installed():
116
+ message = f"MongoDB is installed in: {mongo_is_installed}\n" \
117
+ f"The service is not running. Fix the service or use the 'force' parameter to reinstall."
118
+ print_api(message, color='yellow')
119
+
120
+ if not force:
121
+ return 0
107
122
 
108
123
  print_api("Fetching the latest MongoDB download URL...")
109
124
  mongo_installer_url = get_latest_mongodb_download_url(no_rc_version=no_rc_version, major_specific=major_specific)
@@ -112,7 +127,37 @@ def download_install_latest_main(
112
127
  installer_file_path: str = web.download(mongo_installer_url)
113
128
 
114
129
  print_api("Installing MongoDB...")
115
- install_mongodb(installer_file_path)
130
+ try:
131
+ msiw.install_msi(
132
+ installer_file_path,
133
+ silent_no_gui=True,
134
+ no_restart=True,
135
+ terminate_required_processes=True,
136
+ create_log_near_msi=True,
137
+ scan_log_for_errors=True,
138
+ additional_args='ADDLOCAL="ServerService"'
139
+ )
140
+ except msiw.MsiInstallationError as e:
141
+ print_api(f'{e} Exiting...', color='red')
142
+ return 1
143
+
144
+ # Check if MongoDB is installed.
145
+ message: str = ''
146
+ mongo_is_installed = is_installed()
147
+ if not mongo_is_installed:
148
+ message += "MongoDB Executable not found.\n"
149
+
150
+ if not is_service_running():
151
+ message += "MongoDB service is not running.\n"
152
+
153
+ if message:
154
+ message += f"MSI Path: {installer_file_path}"
155
+ print_api(message, color='red')
156
+ return 1
157
+ else:
158
+ success_message: str = f"MongoDB installed successfully to: {mongo_is_installed}\n" \
159
+ f"Service is running."
160
+ print_api(success_message, color='green')
116
161
 
117
162
  # Clean up the installer file
118
163
  if os.path.exists(installer_file_path):
@@ -1,7 +1,10 @@
1
1
  import subprocess
2
+ import sys
2
3
 
3
4
  from ..print_api import print_api
4
5
  from .. import permissions
6
+ from ..import get_process_list
7
+ from .psutilw import processes
5
8
 
6
9
 
7
10
  ERROR_CODES = {
@@ -11,29 +14,94 @@ ERROR_CODES = {
11
14
  }
12
15
 
13
16
 
17
+ class MsiInstallationError(Exception):
18
+ pass
19
+
20
+
21
+ def get_current_msiexec_processes(msi_file_path: str = None) -> dict:
22
+ """
23
+ Get the current msiexec processes.
24
+ :param msi_file_path: string, OPTIONAL path to the MSI file to check in the command line.
25
+ :return: list of dicts, each key represents a pid and its values are process name and cmdline.
26
+ """
27
+
28
+ current_processes: dict = (
29
+ get_process_list.GetProcessList(get_method='pywin32', connect_on_init=True).get_processes())
30
+
31
+ current_msiexec_dict: dict = {}
32
+ for pid, process_info in current_processes.items():
33
+ if 'msiexec.exe' in process_info['name']:
34
+ if msi_file_path:
35
+ if msi_file_path in process_info['cmdline']:
36
+ current_msiexec_dict[pid] = process_info
37
+ else:
38
+ current_msiexec_dict[pid] = process_info
39
+
40
+ return current_msiexec_dict
41
+
42
+
43
+ def wait_for_msiexec_processes_to_finish(msi_file_path: str):
44
+ """
45
+ Wait for the msiexec processes to finish.
46
+ :param msi_file_path: string, path to the MSI file.
47
+ :return:
48
+ """
49
+
50
+ current_msiexec: dict = get_current_msiexec_processes(msi_file_path)
51
+ current_pid = list(current_msiexec.keys())[0]
52
+
53
+ result_code = processes.wait_for_process(current_pid)
54
+ if result_code != 0:
55
+ raise Exception(f"MSI Installation failed. Return code: {result_code}")
56
+
57
+
14
58
  def install_msi(
15
59
  msi_path,
16
- silent_no_gui=True,
17
- silent_progress_bar=False,
18
- no_restart=True,
19
- as_admin=False,
20
- exit_on_error=False,
21
- print_kwargs=None):
60
+ silent_no_gui: bool = False,
61
+ silent_progress_bar: bool = False,
62
+ no_restart: bool = False,
63
+ terminate_required_processes: bool = False,
64
+ additional_args: str = None,
65
+ create_log_near_msi: bool = False,
66
+ log_file_path: str = None,
67
+ scan_log_for_errors: bool = False,
68
+ # as_admin=True,
69
+ print_kwargs: dict = None):
22
70
  """
23
71
  Install an MSI file silently.
24
72
  :param msi_path: str, path to the MSI file.
25
73
  :param silent_no_gui: bool, whether to run the installation silently, without showing GUI.
26
74
  :param silent_progress_bar: bool, whether to show a progress bar during silent installation.
27
75
  :param no_restart: bool, whether to restart the computer after installation.
28
- :param as_admin: bool, whether to run the installation as administrator.
29
- :param exit_on_error: bool, whether to exit the script if the installation fails.
76
+ :param terminate_required_processes: bool, whether to terminate processes that are required by the installation.
77
+ :param additional_args: str, additional arguments to pass to the msiexec command.
78
+ :param create_log_near_msi: bool, whether to create a log file near the MSI file.
79
+ If the msi file located in 'c:\\path\\to\\file.msi', the log file will be created in 'c:\\path\\to\\file.log'.
80
+ The log options that will be used: /l*v c:\\path\\to\\file.log
81
+ :param log_file_path: str, path to the log file. Even if 'create_log_near_msi' is False, you can specify a custom
82
+ path for the log file, and it will be created.
83
+ The log options that will be used: /l*v c:\\path\\to\\file.log
84
+ :param scan_log_for_errors: bool, whether to scan the log file for errors in case of failure.
85
+ # :param as_admin: bool, whether to run the installation as administrator.
30
86
  :param print_kwargs: dict, print_api kwargs.
31
87
  :return:
32
88
  """
33
89
 
90
+ if not permissions.is_admin():
91
+ raise PermissionError("This function requires administrator privileges.")
92
+
34
93
  if silent_progress_bar and silent_no_gui:
35
94
  raise ValueError("silent_progress_bar and silent_no_gui cannot be both True.")
36
95
 
96
+ if create_log_near_msi and log_file_path:
97
+ raise ValueError("create_log_near_msi and log_file_path cannot be both set.")
98
+
99
+ if create_log_near_msi:
100
+ log_file_path = msi_path.replace('.msi', '.log')
101
+
102
+ if scan_log_for_errors and not log_file_path:
103
+ raise ValueError("[scan_log_for_errors] is set, but [log_file_path] or [create_log_near_msi] is not set.")
104
+
37
105
  # Define the msiexec command
38
106
  command = f'msiexec /i "{msi_path}"'
39
107
 
@@ -44,17 +112,38 @@ def install_msi(
44
112
  if no_restart:
45
113
  command = f"{command} /norestart"
46
114
 
47
- if as_admin:
48
- command = permissions.get_command_to_run_as_admin_windows(command)
115
+ if log_file_path:
116
+ command = f"{command} /l*v {log_file_path}"
117
+
118
+ if terminate_required_processes:
119
+ command = f"{command} REBOOT=ReallySuppress"
120
+
121
+ if additional_args:
122
+ if additional_args.startswith(' '):
123
+ additional_args = additional_args[1:]
124
+ command = f"{command} {additional_args}"
125
+
126
+ # if as_admin:
127
+ # command = permissions.get_command_to_run_as_admin_windows(command)
49
128
 
50
129
  # Run the command
51
- result = subprocess.run(command, capture_output=True, shell=True, text=True)
130
+ result = subprocess.run(command, capture_output=True, text=True)
52
131
 
53
132
  # Check the result
54
133
  if result.returncode == 0:
55
134
  print_api("MSI Installation completed.", color="green", **(print_kwargs or {}))
56
135
  else:
57
- message = f"Installation failed. Return code: {result.returncode}\n{ERROR_CODES.get(str(result.returncode), '')}"
136
+ message = (f"Installation failed. Return code: {result.returncode}\n{ERROR_CODES.get(str(result.returncode), '')}\n"
137
+ f"MSI path: {msi_path}\nCommand: {command}\nOutput: {result.stdout}\nError: {result.stderr}")
138
+
139
+ if scan_log_for_errors:
140
+ with open(log_file_path, 'r', encoding='utf-16 le') as f:
141
+ log_content = f.read()
142
+ if 'error' in log_content.lower():
143
+ # Get the error text of the lines that contain 'error'.
144
+ error_lines = [line for line in log_content.split('\n') if 'error' in line.lower()]
145
+ for line in error_lines:
146
+ message += f"\n{line}"
147
+
58
148
  print_api(message, color="red", **(print_kwargs or {}))
59
- if exit_on_error:
60
- exit()
149
+ raise MsiInstallationError("MSI Installation Failed.")
@@ -0,0 +1,26 @@
1
+ import psutil
2
+ import time
3
+
4
+
5
+ def wait_for_process(pid: int):
6
+ """
7
+ Wait for the process with the given PID to finish.
8
+ :param pid: int, PID of the process to wait for.
9
+ :return:
10
+ """
11
+ try:
12
+ # Create a process object for the given PID
13
+ process = psutil.Process(pid)
14
+
15
+ # Wait for the process to terminate
16
+ while process.is_running():
17
+ print(f"Process with PID {pid} is still running...")
18
+ time.sleep(1) # Sleep for 1 second before checking again
19
+
20
+ # Refresh process status and get the exit code
21
+ process.wait()
22
+ print(f"Process with PID [{pid}] has finished.")
23
+ except psutil.NoSuchProcess:
24
+ print(f"No process found with PID {pid}")
25
+ except psutil.AccessDenied:
26
+ print(f"Access denied to process with PID {pid}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.15.0
3
+ Version: 2.15.1
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License: MIT License
@@ -50,6 +50,7 @@ Requires-Dist: protobuf
50
50
  Requires-Dist: psutil
51
51
  Requires-Dist: py7zr
52
52
  Requires-Dist: pyautogui
53
+ Requires-Dist: pymongo
53
54
  Requires-Dist: pyopenssl
54
55
  Requires-Dist: python-bidi
55
56
  Requires-Dist: python-docx
@@ -1,4 +1,4 @@
1
- atomicshop/__init__.py,sha256=af2i4LBZ0v9l4xOxfMEIXMsbc6UVm2YVVHFR9u8F6uY,123
1
+ atomicshop/__init__.py,sha256=d6t5Ql0zc3dSUJNAyTjHj6blBObI-unNn2kZw5eOlhs,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
@@ -14,7 +14,7 @@ atomicshop/dns.py,sha256=h4uZKoz4wbBlLOOduL1GtRcTm-YpiPnGOEGxUm7hhOI,2140
14
14
  atomicshop/domains.py,sha256=Rxu6JhhMqFZRcoFs69IoEd1PtYca0lMCG6F1AomP7z4,3197
15
15
  atomicshop/emails.py,sha256=I0KyODQpIMEsNRi9YWSOL8EUPBiWyon3HRdIuSj3AEU,1410
16
16
  atomicshop/file_types.py,sha256=-0jzQMRlmU1AP9DARjk-HJm1tVE22E6ngP2mRblyEjY,763
17
- atomicshop/filesystem.py,sha256=aTnO1bcRiNWwkD787pKPi7ze-H95cV8YTc2WmLxcSk4,54539
17
+ atomicshop/filesystem.py,sha256=GIuRNtqUkUXrqKhvRxC9rRulK8FpgKqPcPXG1bf1fac,55030
18
18
  atomicshop/functions.py,sha256=pK8hoCE9z61PtWCxQJsda7YAphrLH1wxU5x-1QJP-sY,499
19
19
  atomicshop/get_process_list.py,sha256=hi1NOG-i8S6EcyQ6LTfP4pdxqRfjEijz9SZ5nEbcM9Q,6076
20
20
  atomicshop/get_process_name_cmd_dll.py,sha256=CtaSp3mgxxJKCCVW8BLx6BJNx4giCklU_T7USiCEwfc,5162
@@ -46,21 +46,23 @@ atomicshop/urls.py,sha256=yqEn8YJS2Ma-cZidn0NZgIfuzFX0rReJ_L5IDt6iWJA,1414
46
46
  atomicshop/uuids.py,sha256=JSQdm3ZTJiwPQ1gYe6kU0TKS_7suwVrHc8JZDGYlydM,2214
47
47
  atomicshop/virtualization.py,sha256=LPP4vjE0Vr10R6DA4lqhfX_WaNdDGRAZUW0Am6VeGco,494
48
48
  atomicshop/web.py,sha256=J9izvF5LNEVOVkkWon0XUgJmR7nrFln03nIxW7wUZWg,11547
49
+ atomicshop/a_installs/win/fibratus.py,sha256=TU4e9gdZ_zI73C40uueJ59pD3qmN-UFGdX5GFoVf6cM,179
50
+ atomicshop/a_installs/win/mongodb.py,sha256=5k9sFWM_9Zh5ShutH2IhGvAo7nrLkOIeUPzhoKvEsx8,171
51
+ atomicshop/a_installs/win/pycharm.py,sha256=uYTfME7hOeNkAsOZxDDPj2hDqmkxrFqVV6Nv6xnYNVk,141
52
+ atomicshop/a_mains/search_for_hyperlinks_in_docx.py,sha256=HkIdo_Sz9nPbbbJf1mwfwFkyI7vkvpH8qiIkuYopN4w,529
49
53
  atomicshop/addons/PlayWrightCodegen.cmd,sha256=Z5cnllsyXD4F1W2h-WLEnyFkg5nZy0-hTGHRWXVOuW4,173
50
54
  atomicshop/addons/ScriptExecution.cmd,sha256=8iC-uHs9MX9qUD_C2M7n9Xw4MZvwOfxT8H5v3hluVps,93
51
55
  atomicshop/addons/a_setup_scripts/install_psycopg2_ubuntu.sh,sha256=lM7LkXQ2AxfFzDGyzSOfIS_zpg9bAD1k3JJ-qu5CdH8,81
52
56
  atomicshop/addons/a_setup_scripts/install_pywintrace_0.3.cmd,sha256=lEP_o6rWcBFUyup6_c-LTL3Q2LRMqryLuG3mJw080Zc,115
57
+ atomicshop/addons/inits/init_to_import_all_modules.py,sha256=piyFjkqtNbM9PT2p8aGcatI615517XEQHgU9kDFwseY,559
53
58
  atomicshop/addons/mains/install_docker_rootless_ubuntu.py,sha256=9IPNtGZYjfy1_n6ZRt7gWz9KZgR6XCgevjqq02xk-o0,281
54
59
  atomicshop/addons/mains/install_docker_ubuntu_main_sudo.py,sha256=JzayxeyKDtiuT4Icp2L2LyFRbx4wvpyN_bHLfZ-yX5E,281
55
60
  atomicshop/addons/mains/install_elastic_search_and_kibana_ubuntu.py,sha256=yRB-l1zBxdiN6av-FwNkhcBlaeu4zrDPjQ0uPGgpK2I,244
56
- atomicshop/addons/mains/install_fibratus_windows.py,sha256=TU4e9gdZ_zI73C40uueJ59pD3qmN-UFGdX5GFoVf6cM,179
57
61
  atomicshop/addons/mains/install_wsl_ubuntu_lts_admin.py,sha256=PrvZ4hMuadzj2GYKRZSwyNayJUuaSnCF9nV6ORqoPdo,123
58
62
  atomicshop/addons/mains/msi_unpacker.py,sha256=XAJdEqs-3s9JqIgHpGRL-HxLKpFMXdrlXmq2Is2Pyfk,164
59
- atomicshop/addons/mains/search_for_hyperlinks_in_docx.py,sha256=HkIdo_Sz9nPbbbJf1mwfwFkyI7vkvpH8qiIkuYopN4w,529
60
63
  atomicshop/addons/mains/FACT/factw_fact_extractor_docker_image_main_sudo.py,sha256=DDKX3Wp2SmzMCEtCIEOUbEKMob2ZQ7VEQGLEf9uYXrs,320
61
64
  atomicshop/addons/mains/FACT/update_extract.py,sha256=H3VsdhlA7xxK5lI_nyrWUdk8GNZXbEUVR_K9cJ4ECAw,506
62
65
  atomicshop/addons/mains/__pycache__/install_fibratus_windows.cpython-312.pyc,sha256=u92dFjDrTbZBIti9B3ttna33Jg1ZSeMYhTiupdfklt4,549
63
- atomicshop/addons/mains/inits/init_to_import_all_modules.py,sha256=piyFjkqtNbM9PT2p8aGcatI615517XEQHgU9kDFwseY,559
64
66
  atomicshop/addons/package_setup/CreateWheel.cmd,sha256=hq9aWBSH6iffYlZyaCNrFlA0vxMh3j1k8DQE8IARQuA,189
65
67
  atomicshop/addons/package_setup/Setup in Edit mode.cmd,sha256=299RsExjR8Mup6YyC6rW0qF8lnwa3uIzwk_gYg_R_Ss,176
66
68
  atomicshop/addons/package_setup/Setup.cmd,sha256=IMm0PfdARH7CG7h9mbWwmWD9X47l7tddwQ2U4MUxy3A,213
@@ -118,8 +120,6 @@ atomicshop/file_io/jsons.py,sha256=q9ZU8slBKnHLrtn3TnbK1qxrRpj5ZvCm6AlsFzoANjo,5
118
120
  atomicshop/file_io/tomls.py,sha256=oa0Wm8yMkPRXKN9jgBuTnKbioSOee4mABW5IMUFCYyU,3041
119
121
  atomicshop/file_io/xlsxs.py,sha256=v_dyg9GD4LqgWi6wA1QuWRZ8zG4ZwB6Dz52ytdcmmmI,2184
120
122
  atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,2104
121
- atomicshop/mains/installs/win/mongodb.py,sha256=5k9sFWM_9Zh5ShutH2IhGvAo7nrLkOIeUPzhoKvEsx8,171
122
- atomicshop/mains/installs/win/pycharm.py,sha256=uYTfME7hOeNkAsOZxDDPj2hDqmkxrFqVV6Nv6xnYNVk,141
123
123
  atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
124
124
  atomicshop/mitm/config_editor.py,sha256=9ZwD6NGqgsr1f85NyFwWwM7FDut2vGQ4xari3vS9UT0,1130
125
125
  atomicshop/mitm/connection_thread_worker.py,sha256=PQ8bwOgrPudYP5oPnSi_DWaKXOi038M8TMImlLkxuPI,20486
@@ -174,7 +174,7 @@ atomicshop/wrappers/configparserw.py,sha256=JwDTPjZoSrv44YKwIRcjyUnpN-FjgXVfMqMK
174
174
  atomicshop/wrappers/cryptographyw.py,sha256=H5NaHHDkr97QYhUrHFO9vY218u8k3N3Zgh6bQRnicUE,13140
175
175
  atomicshop/wrappers/ffmpegw.py,sha256=wcq0ZnAe0yajBOuTKZCCaKI7CDBjkq7FAgdW5IsKcVE,6031
176
176
  atomicshop/wrappers/githubw.py,sha256=AQcFuT5mvDUNT_cI31MwkJ7srdhMtttF8FyXS8vs5cU,12270
177
- atomicshop/wrappers/msiw.py,sha256=1kEs9T3eJYGzEpEBXaq8OZxlCnV4gnIR4zhmCsQiKvY,2201
177
+ atomicshop/wrappers/msiw.py,sha256=BizivVfz-NAQgBCYUrGjrNiQJdc9gI9G3FYd55GdJn4,6115
178
178
  atomicshop/wrappers/numpyw.py,sha256=sBV4gSKyr23kXTalqAb1oqttzE_2XxBooCui66jbAqc,1025
179
179
  atomicshop/wrappers/olefilew.py,sha256=biD5m58rogifCYmYhJBrAFb9O_Bn_spLek_9HofLeYE,2051
180
180
  atomicshop/wrappers/pipw.py,sha256=mu4jnHkSaYNfpBiLZKMZxEX_E2LqW5BVthMZkblPB_c,1317
@@ -246,7 +246,7 @@ atomicshop/wrappers/loggingw/loggers.py,sha256=DHOOTAtqkwn1xgvLHSkOiBm6yFGNuQy1k
246
246
  atomicshop/wrappers/loggingw/loggingw.py,sha256=lo4OZPXCbYZi3GqpaaJSs9SOGFfqD2EgHzzTK7f5IR4,11275
247
247
  atomicshop/wrappers/loggingw/reading.py,sha256=b4-ibM5WwjEOanvHY3hIsu9-4b2RAdPYiCxvl7745fk,17521
248
248
  atomicshop/wrappers/mongodbw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
249
- atomicshop/wrappers/mongodbw/install_mongodb.py,sha256=5fyIatRm9e_6hmNRnIzhKKLJh6GgObr_0kAR4UAIdis,3846
249
+ atomicshop/wrappers/mongodbw/install_mongodb.py,sha256=cuisakPkuIsMfleyARyuOTgbcXWvfSWKqoYaMdOnPuw,5456
250
250
  atomicshop/wrappers/nodejsw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
251
251
  atomicshop/wrappers/nodejsw/install_nodejs.py,sha256=QZg-R2iTQt7kFb8wNtnTmwraSGwvUs34JIasdbNa7ZU,5154
252
252
  atomicshop/wrappers/playwrightw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -263,6 +263,7 @@ atomicshop/wrappers/psutilw/cpus.py,sha256=w6LPBMINqS-T_X8vzdYkLS2Wzuve28Ydp_Gaf
263
263
  atomicshop/wrappers/psutilw/disks.py,sha256=3ZSVoommKH1TWo37j_83frB-NqXF4Nf5q5mBCX8G4jE,9221
264
264
  atomicshop/wrappers/psutilw/memories.py,sha256=_S0aL8iaoIHebd1vOFrY_T9aROM5Jx2D5CvDh_4j0Vc,528
265
265
  atomicshop/wrappers/psutilw/networks.py,sha256=jC53QXKdZQPCLdy_iNWXeq-CwpW7H6va6bFPRmI_e7A,1507
266
+ atomicshop/wrappers/psutilw/processes.py,sha256=XVqbr7btnT1aJioCFOBnudKGZ5-L9sTpBFWb4DHn2Rw,847
266
267
  atomicshop/wrappers/psutilw/psutilw.py,sha256=q3EwgprqyrR4zLCjl4l5DHFOQoukEvQMIPjNB504oQ0,21262
267
268
  atomicshop/wrappers/psycopgw/psycopgw.py,sha256=XJvVf0oAUjCHkrYfKeFuGCpfn0Oxj3u4SbKMKA1508E,7118
268
269
  atomicshop/wrappers/pywin32w/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -291,8 +292,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=AhpurHJmP2kgzHaUbq5ey
291
292
  atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
292
293
  atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
293
294
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
294
- atomicshop-2.15.0.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
295
- atomicshop-2.15.0.dist-info/METADATA,sha256=nd7pqmFFd9WGeuK9aUT0ADduvInXnHIm6pf0feFpMwM,10478
296
- atomicshop-2.15.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
297
- atomicshop-2.15.0.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
298
- atomicshop-2.15.0.dist-info/RECORD,,
295
+ atomicshop-2.15.1.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
296
+ atomicshop-2.15.1.dist-info/METADATA,sha256=uIXlm-6-iPV6AdPBYI4b8Y9LnSZmj2qU6yKOWK1V13E,10502
297
+ atomicshop-2.15.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
298
+ atomicshop-2.15.1.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
299
+ atomicshop-2.15.1.dist-info/RECORD,,