stouputils 1.14.0__py3-none-any.whl → 1.14.2__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.
Files changed (108) hide show
  1. stouputils/__init__.pyi +15 -0
  2. stouputils/_deprecated.pyi +12 -0
  3. stouputils/all_doctests.pyi +46 -0
  4. stouputils/applications/__init__.pyi +2 -0
  5. stouputils/applications/automatic_docs.py +3 -0
  6. stouputils/applications/automatic_docs.pyi +106 -0
  7. stouputils/applications/upscaler/__init__.pyi +3 -0
  8. stouputils/applications/upscaler/config.pyi +18 -0
  9. stouputils/applications/upscaler/image.pyi +109 -0
  10. stouputils/applications/upscaler/video.pyi +60 -0
  11. stouputils/archive.pyi +67 -0
  12. stouputils/backup.pyi +109 -0
  13. stouputils/collections.pyi +86 -0
  14. stouputils/continuous_delivery/__init__.pyi +5 -0
  15. stouputils/continuous_delivery/cd_utils.pyi +129 -0
  16. stouputils/continuous_delivery/github.pyi +162 -0
  17. stouputils/continuous_delivery/pypi.pyi +52 -0
  18. stouputils/continuous_delivery/pyproject.pyi +67 -0
  19. stouputils/continuous_delivery/stubs.pyi +39 -0
  20. stouputils/ctx.pyi +211 -0
  21. stouputils/data_science/config/get.py +51 -51
  22. stouputils/data_science/data_processing/image/__init__.py +66 -66
  23. stouputils/data_science/data_processing/image/auto_contrast.py +79 -79
  24. stouputils/data_science/data_processing/image/axis_flip.py +58 -58
  25. stouputils/data_science/data_processing/image/bias_field_correction.py +74 -74
  26. stouputils/data_science/data_processing/image/binary_threshold.py +73 -73
  27. stouputils/data_science/data_processing/image/blur.py +59 -59
  28. stouputils/data_science/data_processing/image/brightness.py +54 -54
  29. stouputils/data_science/data_processing/image/canny.py +110 -110
  30. stouputils/data_science/data_processing/image/clahe.py +92 -92
  31. stouputils/data_science/data_processing/image/common.py +30 -30
  32. stouputils/data_science/data_processing/image/contrast.py +53 -53
  33. stouputils/data_science/data_processing/image/curvature_flow_filter.py +74 -74
  34. stouputils/data_science/data_processing/image/denoise.py +378 -378
  35. stouputils/data_science/data_processing/image/histogram_equalization.py +123 -123
  36. stouputils/data_science/data_processing/image/invert.py +64 -64
  37. stouputils/data_science/data_processing/image/laplacian.py +60 -60
  38. stouputils/data_science/data_processing/image/median_blur.py +52 -52
  39. stouputils/data_science/data_processing/image/noise.py +59 -59
  40. stouputils/data_science/data_processing/image/normalize.py +65 -65
  41. stouputils/data_science/data_processing/image/random_erase.py +66 -66
  42. stouputils/data_science/data_processing/image/resize.py +69 -69
  43. stouputils/data_science/data_processing/image/rotation.py +80 -80
  44. stouputils/data_science/data_processing/image/salt_pepper.py +68 -68
  45. stouputils/data_science/data_processing/image/sharpening.py +55 -55
  46. stouputils/data_science/data_processing/image/shearing.py +64 -64
  47. stouputils/data_science/data_processing/image/threshold.py +64 -64
  48. stouputils/data_science/data_processing/image/translation.py +71 -71
  49. stouputils/data_science/data_processing/image/zoom.py +83 -83
  50. stouputils/data_science/data_processing/image_augmentation.py +118 -118
  51. stouputils/data_science/data_processing/image_preprocess.py +183 -183
  52. stouputils/data_science/data_processing/prosthesis_detection.py +359 -359
  53. stouputils/data_science/data_processing/technique.py +481 -481
  54. stouputils/data_science/dataset/__init__.py +45 -45
  55. stouputils/data_science/dataset/dataset.py +292 -292
  56. stouputils/data_science/dataset/dataset_loader.py +135 -135
  57. stouputils/data_science/dataset/grouping_strategy.py +296 -296
  58. stouputils/data_science/dataset/image_loader.py +100 -100
  59. stouputils/data_science/dataset/xy_tuple.py +696 -696
  60. stouputils/data_science/metric_dictionnary.py +106 -106
  61. stouputils/data_science/mlflow_utils.py +206 -206
  62. stouputils/data_science/models/abstract_model.py +149 -149
  63. stouputils/data_science/models/all.py +85 -85
  64. stouputils/data_science/models/keras/all.py +38 -38
  65. stouputils/data_science/models/keras/convnext.py +62 -62
  66. stouputils/data_science/models/keras/densenet.py +50 -50
  67. stouputils/data_science/models/keras/efficientnet.py +60 -60
  68. stouputils/data_science/models/keras/mobilenet.py +56 -56
  69. stouputils/data_science/models/keras/resnet.py +52 -52
  70. stouputils/data_science/models/keras/squeezenet.py +233 -233
  71. stouputils/data_science/models/keras/vgg.py +42 -42
  72. stouputils/data_science/models/keras/xception.py +38 -38
  73. stouputils/data_science/models/keras_utils/callbacks/__init__.py +20 -20
  74. stouputils/data_science/models/keras_utils/callbacks/colored_progress_bar.py +219 -219
  75. stouputils/data_science/models/keras_utils/callbacks/learning_rate_finder.py +148 -148
  76. stouputils/data_science/models/keras_utils/callbacks/model_checkpoint_v2.py +31 -31
  77. stouputils/data_science/models/keras_utils/callbacks/progressive_unfreezing.py +249 -249
  78. stouputils/data_science/models/keras_utils/callbacks/warmup_scheduler.py +66 -66
  79. stouputils/data_science/models/keras_utils/losses/__init__.py +12 -12
  80. stouputils/data_science/models/keras_utils/losses/next_generation_loss.py +56 -56
  81. stouputils/data_science/models/keras_utils/visualizations.py +416 -416
  82. stouputils/data_science/models/sandbox.py +116 -116
  83. stouputils/data_science/range_tuple.py +234 -234
  84. stouputils/data_science/utils.py +285 -285
  85. stouputils/decorators.pyi +242 -0
  86. stouputils/image.pyi +172 -0
  87. stouputils/installer/__init__.py +18 -18
  88. stouputils/installer/__init__.pyi +5 -0
  89. stouputils/installer/common.pyi +39 -0
  90. stouputils/installer/downloader.pyi +24 -0
  91. stouputils/installer/linux.py +144 -144
  92. stouputils/installer/linux.pyi +39 -0
  93. stouputils/installer/main.py +223 -223
  94. stouputils/installer/main.pyi +57 -0
  95. stouputils/installer/windows.py +136 -136
  96. stouputils/installer/windows.pyi +31 -0
  97. stouputils/io.pyi +213 -0
  98. stouputils/parallel.py +12 -10
  99. stouputils/parallel.pyi +211 -0
  100. stouputils/print.pyi +136 -0
  101. stouputils/py.typed +1 -1
  102. stouputils/stouputils/parallel.pyi +4 -4
  103. stouputils/version_pkg.pyi +15 -0
  104. {stouputils-1.14.0.dist-info → stouputils-1.14.2.dist-info}/METADATA +1 -1
  105. stouputils-1.14.2.dist-info/RECORD +171 -0
  106. stouputils-1.14.0.dist-info/RECORD +0 -140
  107. {stouputils-1.14.0.dist-info → stouputils-1.14.2.dist-info}/WHEEL +0 -0
  108. {stouputils-1.14.0.dist-info → stouputils-1.14.2.dist-info}/entry_points.txt +0 -0
@@ -1,223 +1,223 @@
1
- """ Main module of the installer subpackage for stouputils.
2
-
3
- Provides functions for installing programs from local zip files or URLs.
4
- It handles downloading, extracting, and setting up programs in a platform-agnostic way.
5
-
6
- This module contains the core installation functions that are used by both the Windows
7
- and Linux/macOS specific modules.
8
- """
9
- # ruff: noqa: F403
10
- # ruff: noqa: F405
11
-
12
- # Imports
13
- import os
14
- import platform
15
- import shutil
16
- import tarfile
17
- import zipfile
18
- from collections.abc import Callable
19
- from tempfile import TemporaryDirectory
20
-
21
- import requests
22
-
23
- from ..decorators import LogLevels, handle_error
24
- from ..print import info, warning
25
- from .common import *
26
- from .linux import *
27
- from .windows import *
28
-
29
-
30
- # Helper functions
31
- def extract_archive(
32
- extraction_path: str,
33
- temp_dir: str,
34
- extract_func: Callable[[str], None],
35
- get_file_list_func: Callable[[], list[str]]
36
- ) -> None:
37
- """ Helper function to extract archive files with consistent handling.
38
-
39
- Args:
40
- extraction_path (str): Path where files should be extracted
41
- temp_dir (str): Temporary directory for intermediate extraction
42
- extract_func (Callable[[str], None]): Function to extract the archive
43
- get_file_list_func (Callable[[], list[str]]): Function to get the list of files in the archive
44
- """
45
- os.makedirs(extraction_path, exist_ok=True)
46
-
47
- # Check if the archive contains a single folder
48
- file_list: list[str] = get_file_list_func()
49
- root_dirs: set[str] = {item.split('/')[0] + '/' for item in file_list if '/' in item}
50
-
51
- # If all files are in a single root directory
52
- if len(root_dirs) == 1 and all(item.startswith(next(iter(root_dirs))) for item in file_list):
53
- # Extract to a temporary location first
54
- temp_extract_path: str = os.path.join(temp_dir, "extracted")
55
- os.makedirs(temp_extract_path, exist_ok=True)
56
- extract_func(temp_extract_path)
57
-
58
- # Move contents from the single folder to the final path
59
- single_folder_path: str = os.path.join(temp_extract_path, next(iter(root_dirs)).rstrip('/'))
60
- for item in os.listdir(single_folder_path):
61
- src_path: str = os.path.join(single_folder_path, item)
62
- dst_path: str = os.path.join(extraction_path, item)
63
- if os.path.isdir(src_path):
64
- shutil.copytree(src_path, dst_path, dirs_exist_ok=True)
65
- else:
66
- shutil.copy2(src_path, dst_path)
67
- debug(f"Extracted program contents from single folder to '{extraction_path}'")
68
- else:
69
- # Normal extraction if not a single folder
70
- extract_func(extraction_path)
71
- debug(f"Extracted program to '{extraction_path}'")
72
-
73
-
74
- # Functions
75
- def get_install_path(
76
- program_name: str,
77
- platform_str: str = platform.system(),
78
- ask_global: int = 0,
79
- add_path: bool = True,
80
- append_to_path: str = "",
81
- ) -> str:
82
- """ Get the installation path for the program on the current platform.
83
-
84
- Args:
85
- program_name (str): The name of the program to install.
86
- platform_str (str): The platform to get the installation path for.
87
- ask_global (int): Whether to ask the user for a path, 0 = ask, 1 = install globally, 2 = install locally.
88
- add_path (bool): Whether to add the program to the PATH environment variable.
89
- append_to_path (str): String to append to the installation path when adding to PATH.
90
- (ex: "bin" if executables are in the bin folder)
91
-
92
- Returns:
93
- str: The installation path for the program.
94
- """
95
- platform_str = str(platform_str).lower()
96
- if platform_str == "windows":
97
- return get_install_path_windows(program_name, ask_global, add_path=add_path, append_to_path=append_to_path)
98
- elif platform_str == "linux":
99
- return get_install_path_linux(program_name, ask_global, add_path=add_path, append_to_path=append_to_path)
100
- else:
101
- warning(f"Unsupported platform for automatic install path: {platform_str}")
102
- return ""
103
-
104
- def add_to_path(install_path: str, platform_str: str = platform.system()) -> bool:
105
- """ Add the program to the PATH environment variable.
106
-
107
- Args:
108
- install_path (str): The path to the program to add to the PATH environment variable.
109
- platform_str (str): The platform you are running on (ex: "Windows", "Linux", "Darwin", ...),
110
- we use this to determine the installation path if not provided.
111
-
112
- Returns:
113
- bool: True if add to PATH was successful, False otherwise.
114
- """
115
- platform_str = str(platform_str).lower()
116
- if platform_str == "windows":
117
- return add_to_path_windows(install_path) is True
118
- elif platform_str == "linux":
119
- return add_to_path_linux(install_path) is True
120
- else:
121
- warning(f"Unsupported platform for automatic add to PATH: {platform_str}")
122
- return False
123
-
124
- @handle_error(message="Failed during program installation", error_log=LogLevels.WARNING_TRACEBACK)
125
- def install_program(
126
- input_path: str,
127
- install_path: str = "",
128
- platform_str: str = platform.system(),
129
- program_name: str = "",
130
- add_path: bool = True,
131
- append_to_path: str = "",
132
- ) -> bool:
133
- """ Install a program to a specific path from a local zip file or URL.
134
-
135
- Args:
136
- input_path (str): Path to a zip file or a download URL.
137
- install_path (str): The directory to extract the program into, we ask user for a path if not provided.
138
- platform_str (str): The platform you are running on (ex: "Windows", "Linux", "Darwin", ...),
139
- we use this to determine the installation path if not provided.
140
- add_path (bool): Whether to add the program to the PATH environment variable.
141
- program_name (str): Override the program name, we get it from the input path if not provided.
142
- append_to_path (str): String to append to the installation path when adding to PATH.
143
- (ex: "bin" if executables are in the bin folder)
144
-
145
- Returns:
146
- bool: True if installation was successful, False otherwise.
147
- """
148
- # Get program name from input path if not provided
149
- # (ex: "https://example.com/program.zip" -> "program", "/var/www/program.exe" -> "program")
150
- if not program_name:
151
- program_name = os.path.splitext(os.path.basename(input_path))[0]
152
-
153
- # If no install path is provided, ask the user for one
154
- final_install_path: str = install_path
155
- if not install_path:
156
- final_install_path = get_install_path(program_name, platform_str, add_path=add_path, append_to_path=append_to_path)
157
- if not final_install_path:
158
- warning("Failed to get installation path, please provide a path to install the program to.")
159
- return False
160
-
161
- # Create a temporary directory
162
- with TemporaryDirectory() as temp_dir:
163
- temp_dir: str
164
- program_path: str = ""
165
-
166
- # Download the program if it's a URL
167
- if input_path.startswith("http"):
168
- info(f"Downloading program from '{input_path}'")
169
- response: requests.Response = requests.get(input_path)
170
- if response.status_code != 200:
171
- warning(f"Failed to download program from '{input_path}', reason: {response.reason}")
172
- return False
173
-
174
- # Save the program to a temporary directory
175
- temp_file: str = os.path.join(temp_dir, "program.zip")
176
- with open(temp_file, "wb") as f:
177
- f.write(response.content)
178
- program_path = temp_file
179
- debug(f"Downloaded program to '{program_path}'")
180
- else:
181
- program_path = input_path
182
- debug(f"Using local program path '{program_path}'")
183
-
184
- # Extract the program if it's a zip file
185
- if program_path.endswith(".zip"):
186
- with zipfile.ZipFile(program_path, "r") as zip_ref:
187
- extract_archive(
188
- final_install_path,
189
- temp_dir,
190
- lambda path: zip_ref.extractall(path),
191
- lambda: zip_ref.namelist()
192
- )
193
-
194
- # Extract the program if it's a tar.xz file
195
- elif program_path.endswith(".tar.xz"):
196
- with tarfile.open(program_path, "r:xz") as tar_ref:
197
- extract_archive(
198
- final_install_path,
199
- temp_dir,
200
- lambda path: tar_ref.extractall(path),
201
- lambda: tar_ref.getnames()
202
- )
203
-
204
- # Else, it's a directory so we just need to copy it
205
- elif os.path.isdir(program_path):
206
- shutil.copytree(program_path, final_install_path)
207
-
208
- else:
209
- warning(f"Failed to install program, input path is not a zip, tar.xz file or directory: '{program_path}'")
210
- return False
211
-
212
- # If add_path is True, and the installation path was provided, we add it to the PATH environment variable
213
- if add_path and install_path:
214
- if not add_to_path(os.path.join(final_install_path, append_to_path), platform_str):
215
- warning(
216
- f"Failed to add program to PATH, please add it manually to your PATH environment variable:\n"
217
- f"{final_install_path}"
218
- )
219
- return False
220
-
221
- # If we get here, the program was installed successfully
222
- return True
223
-
1
+ """ Main module of the installer subpackage for stouputils.
2
+
3
+ Provides functions for installing programs from local zip files or URLs.
4
+ It handles downloading, extracting, and setting up programs in a platform-agnostic way.
5
+
6
+ This module contains the core installation functions that are used by both the Windows
7
+ and Linux/macOS specific modules.
8
+ """
9
+ # ruff: noqa: F403
10
+ # ruff: noqa: F405
11
+
12
+ # Imports
13
+ import os
14
+ import platform
15
+ import shutil
16
+ import tarfile
17
+ import zipfile
18
+ from collections.abc import Callable
19
+ from tempfile import TemporaryDirectory
20
+
21
+ import requests
22
+
23
+ from ..decorators import LogLevels, handle_error
24
+ from ..print import info, warning
25
+ from .common import *
26
+ from .linux import *
27
+ from .windows import *
28
+
29
+
30
+ # Helper functions
31
+ def extract_archive(
32
+ extraction_path: str,
33
+ temp_dir: str,
34
+ extract_func: Callable[[str], None],
35
+ get_file_list_func: Callable[[], list[str]]
36
+ ) -> None:
37
+ """ Helper function to extract archive files with consistent handling.
38
+
39
+ Args:
40
+ extraction_path (str): Path where files should be extracted
41
+ temp_dir (str): Temporary directory for intermediate extraction
42
+ extract_func (Callable[[str], None]): Function to extract the archive
43
+ get_file_list_func (Callable[[], list[str]]): Function to get the list of files in the archive
44
+ """
45
+ os.makedirs(extraction_path, exist_ok=True)
46
+
47
+ # Check if the archive contains a single folder
48
+ file_list: list[str] = get_file_list_func()
49
+ root_dirs: set[str] = {item.split('/')[0] + '/' for item in file_list if '/' in item}
50
+
51
+ # If all files are in a single root directory
52
+ if len(root_dirs) == 1 and all(item.startswith(next(iter(root_dirs))) for item in file_list):
53
+ # Extract to a temporary location first
54
+ temp_extract_path: str = os.path.join(temp_dir, "extracted")
55
+ os.makedirs(temp_extract_path, exist_ok=True)
56
+ extract_func(temp_extract_path)
57
+
58
+ # Move contents from the single folder to the final path
59
+ single_folder_path: str = os.path.join(temp_extract_path, next(iter(root_dirs)).rstrip('/'))
60
+ for item in os.listdir(single_folder_path):
61
+ src_path: str = os.path.join(single_folder_path, item)
62
+ dst_path: str = os.path.join(extraction_path, item)
63
+ if os.path.isdir(src_path):
64
+ shutil.copytree(src_path, dst_path, dirs_exist_ok=True)
65
+ else:
66
+ shutil.copy2(src_path, dst_path)
67
+ debug(f"Extracted program contents from single folder to '{extraction_path}'")
68
+ else:
69
+ # Normal extraction if not a single folder
70
+ extract_func(extraction_path)
71
+ debug(f"Extracted program to '{extraction_path}'")
72
+
73
+
74
+ # Functions
75
+ def get_install_path(
76
+ program_name: str,
77
+ platform_str: str = platform.system(),
78
+ ask_global: int = 0,
79
+ add_path: bool = True,
80
+ append_to_path: str = "",
81
+ ) -> str:
82
+ """ Get the installation path for the program on the current platform.
83
+
84
+ Args:
85
+ program_name (str): The name of the program to install.
86
+ platform_str (str): The platform to get the installation path for.
87
+ ask_global (int): Whether to ask the user for a path, 0 = ask, 1 = install globally, 2 = install locally.
88
+ add_path (bool): Whether to add the program to the PATH environment variable.
89
+ append_to_path (str): String to append to the installation path when adding to PATH.
90
+ (ex: "bin" if executables are in the bin folder)
91
+
92
+ Returns:
93
+ str: The installation path for the program.
94
+ """
95
+ platform_str = str(platform_str).lower()
96
+ if platform_str == "windows":
97
+ return get_install_path_windows(program_name, ask_global, add_path=add_path, append_to_path=append_to_path)
98
+ elif platform_str == "linux":
99
+ return get_install_path_linux(program_name, ask_global, add_path=add_path, append_to_path=append_to_path)
100
+ else:
101
+ warning(f"Unsupported platform for automatic install path: {platform_str}")
102
+ return ""
103
+
104
+ def add_to_path(install_path: str, platform_str: str = platform.system()) -> bool:
105
+ """ Add the program to the PATH environment variable.
106
+
107
+ Args:
108
+ install_path (str): The path to the program to add to the PATH environment variable.
109
+ platform_str (str): The platform you are running on (ex: "Windows", "Linux", "Darwin", ...),
110
+ we use this to determine the installation path if not provided.
111
+
112
+ Returns:
113
+ bool: True if add to PATH was successful, False otherwise.
114
+ """
115
+ platform_str = str(platform_str).lower()
116
+ if platform_str == "windows":
117
+ return add_to_path_windows(install_path) is True
118
+ elif platform_str == "linux":
119
+ return add_to_path_linux(install_path) is True
120
+ else:
121
+ warning(f"Unsupported platform for automatic add to PATH: {platform_str}")
122
+ return False
123
+
124
+ @handle_error(message="Failed during program installation", error_log=LogLevels.WARNING_TRACEBACK)
125
+ def install_program(
126
+ input_path: str,
127
+ install_path: str = "",
128
+ platform_str: str = platform.system(),
129
+ program_name: str = "",
130
+ add_path: bool = True,
131
+ append_to_path: str = "",
132
+ ) -> bool:
133
+ """ Install a program to a specific path from a local zip file or URL.
134
+
135
+ Args:
136
+ input_path (str): Path to a zip file or a download URL.
137
+ install_path (str): The directory to extract the program into, we ask user for a path if not provided.
138
+ platform_str (str): The platform you are running on (ex: "Windows", "Linux", "Darwin", ...),
139
+ we use this to determine the installation path if not provided.
140
+ add_path (bool): Whether to add the program to the PATH environment variable.
141
+ program_name (str): Override the program name, we get it from the input path if not provided.
142
+ append_to_path (str): String to append to the installation path when adding to PATH.
143
+ (ex: "bin" if executables are in the bin folder)
144
+
145
+ Returns:
146
+ bool: True if installation was successful, False otherwise.
147
+ """
148
+ # Get program name from input path if not provided
149
+ # (ex: "https://example.com/program.zip" -> "program", "/var/www/program.exe" -> "program")
150
+ if not program_name:
151
+ program_name = os.path.splitext(os.path.basename(input_path))[0]
152
+
153
+ # If no install path is provided, ask the user for one
154
+ final_install_path: str = install_path
155
+ if not install_path:
156
+ final_install_path = get_install_path(program_name, platform_str, add_path=add_path, append_to_path=append_to_path)
157
+ if not final_install_path:
158
+ warning("Failed to get installation path, please provide a path to install the program to.")
159
+ return False
160
+
161
+ # Create a temporary directory
162
+ with TemporaryDirectory() as temp_dir:
163
+ temp_dir: str
164
+ program_path: str = ""
165
+
166
+ # Download the program if it's a URL
167
+ if input_path.startswith("http"):
168
+ info(f"Downloading program from '{input_path}'")
169
+ response: requests.Response = requests.get(input_path)
170
+ if response.status_code != 200:
171
+ warning(f"Failed to download program from '{input_path}', reason: {response.reason}")
172
+ return False
173
+
174
+ # Save the program to a temporary directory
175
+ temp_file: str = os.path.join(temp_dir, "program.zip")
176
+ with open(temp_file, "wb") as f:
177
+ f.write(response.content)
178
+ program_path = temp_file
179
+ debug(f"Downloaded program to '{program_path}'")
180
+ else:
181
+ program_path = input_path
182
+ debug(f"Using local program path '{program_path}'")
183
+
184
+ # Extract the program if it's a zip file
185
+ if program_path.endswith(".zip"):
186
+ with zipfile.ZipFile(program_path, "r") as zip_ref:
187
+ extract_archive(
188
+ final_install_path,
189
+ temp_dir,
190
+ lambda path: zip_ref.extractall(path),
191
+ lambda: zip_ref.namelist()
192
+ )
193
+
194
+ # Extract the program if it's a tar.xz file
195
+ elif program_path.endswith(".tar.xz"):
196
+ with tarfile.open(program_path, "r:xz") as tar_ref:
197
+ extract_archive(
198
+ final_install_path,
199
+ temp_dir,
200
+ lambda path: tar_ref.extractall(path),
201
+ lambda: tar_ref.getnames()
202
+ )
203
+
204
+ # Else, it's a directory so we just need to copy it
205
+ elif os.path.isdir(program_path):
206
+ shutil.copytree(program_path, final_install_path)
207
+
208
+ else:
209
+ warning(f"Failed to install program, input path is not a zip, tar.xz file or directory: '{program_path}'")
210
+ return False
211
+
212
+ # If add_path is True, and the installation path was provided, we add it to the PATH environment variable
213
+ if add_path and install_path:
214
+ if not add_to_path(os.path.join(final_install_path, append_to_path), platform_str):
215
+ warning(
216
+ f"Failed to add program to PATH, please add it manually to your PATH environment variable:\n"
217
+ f"{final_install_path}"
218
+ )
219
+ return False
220
+
221
+ # If we get here, the program was installed successfully
222
+ return True
223
+
@@ -0,0 +1,57 @@
1
+ from .common import *
2
+ from .linux import *
3
+ from .windows import *
4
+ from ..decorators import LogLevels as LogLevels, handle_error as handle_error
5
+ from ..print import info as info, warning as warning
6
+ from collections.abc import Callable as Callable
7
+
8
+ def extract_archive(extraction_path: str, temp_dir: str, extract_func: Callable[[str], None], get_file_list_func: Callable[[], list[str]]) -> None:
9
+ """ Helper function to extract archive files with consistent handling.
10
+
11
+ \tArgs:
12
+ \t\textraction_path (str): Path where files should be extracted
13
+ \t\ttemp_dir (str): Temporary directory for intermediate extraction
14
+ \t\textract_func (Callable[[str], None]): Function to extract the archive
15
+ \t\tget_file_list_func (Callable[[], list[str]]): Function to get the list of files in the archive
16
+ \t"""
17
+ def get_install_path(program_name: str, platform_str: str = ..., ask_global: int = 0, add_path: bool = True, append_to_path: str = '') -> str:
18
+ ''' Get the installation path for the program on the current platform.
19
+
20
+ \tArgs:
21
+ \t\tprogram_name (str): The name of the program to install.
22
+ \t\tplatform_str (str): The platform to get the installation path for.
23
+ \t\task_global (int): Whether to ask the user for a path, 0 = ask, 1 = install globally, 2 = install locally.
24
+ \t\tadd_path (bool): Whether to add the program to the PATH environment variable.
25
+ \t\tappend_to_path (str): String to append to the installation path when adding to PATH.
26
+ \t\t\t(ex: "bin" if executables are in the bin folder)
27
+
28
+ \tReturns:
29
+ \t\tstr: The installation path for the program.
30
+ \t'''
31
+ def add_to_path(install_path: str, platform_str: str = ...) -> bool:
32
+ ''' Add the program to the PATH environment variable.
33
+
34
+ \tArgs:
35
+ \t\tinstall_path (str): The path to the program to add to the PATH environment variable.
36
+ \t\tplatform_str (str): The platform you are running on (ex: "Windows", "Linux", "Darwin", ...),
37
+ \t\t\twe use this to determine the installation path if not provided.
38
+
39
+ \tReturns:
40
+ \t\tbool: True if add to PATH was successful, False otherwise.
41
+ \t'''
42
+ def install_program(input_path: str, install_path: str = '', platform_str: str = ..., program_name: str = '', add_path: bool = True, append_to_path: str = '') -> bool:
43
+ ''' Install a program to a specific path from a local zip file or URL.
44
+
45
+ \tArgs:
46
+ \t\tinput_path (str): Path to a zip file or a download URL.
47
+ \t\tinstall_path (str): The directory to extract the program into, we ask user for a path if not provided.
48
+ \t\tplatform_str (str): The platform you are running on (ex: "Windows", "Linux", "Darwin", ...),
49
+ \t\t\twe use this to determine the installation path if not provided.
50
+ \t\tadd_path (bool): Whether to add the program to the PATH environment variable.
51
+ \t\tprogram_name (str): Override the program name, we get it from the input path if not provided.
52
+ \t\tappend_to_path (str): String to append to the installation path when adding to PATH.
53
+ \t\t\t(ex: "bin" if executables are in the bin folder)
54
+
55
+ \tReturns:
56
+ \t\tbool: True if installation was successful, False otherwise.
57
+ \t'''