xulbux 1.9.5__cp311-cp311-macosx_11_0_arm64.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.
- 455848faf89d8974b22a__mypyc.cpython-311-darwin.so +0 -0
- xulbux/__init__.cpython-311-darwin.so +0 -0
- xulbux/__init__.py +46 -0
- xulbux/base/consts.cpython-311-darwin.so +0 -0
- xulbux/base/consts.py +172 -0
- xulbux/base/decorators.cpython-311-darwin.so +0 -0
- xulbux/base/decorators.py +28 -0
- xulbux/base/exceptions.cpython-311-darwin.so +0 -0
- xulbux/base/exceptions.py +23 -0
- xulbux/base/types.cpython-311-darwin.so +0 -0
- xulbux/base/types.py +118 -0
- xulbux/cli/help.cpython-311-darwin.so +0 -0
- xulbux/cli/help.py +77 -0
- xulbux/code.cpython-311-darwin.so +0 -0
- xulbux/code.py +137 -0
- xulbux/color.cpython-311-darwin.so +0 -0
- xulbux/color.py +1331 -0
- xulbux/console.cpython-311-darwin.so +0 -0
- xulbux/console.py +2069 -0
- xulbux/data.cpython-311-darwin.so +0 -0
- xulbux/data.py +798 -0
- xulbux/env_path.cpython-311-darwin.so +0 -0
- xulbux/env_path.py +123 -0
- xulbux/file.cpython-311-darwin.so +0 -0
- xulbux/file.py +74 -0
- xulbux/file_sys.cpython-311-darwin.so +0 -0
- xulbux/file_sys.py +266 -0
- xulbux/format_codes.cpython-311-darwin.so +0 -0
- xulbux/format_codes.py +722 -0
- xulbux/json.cpython-311-darwin.so +0 -0
- xulbux/json.py +200 -0
- xulbux/regex.cpython-311-darwin.so +0 -0
- xulbux/regex.py +247 -0
- xulbux/string.cpython-311-darwin.so +0 -0
- xulbux/string.py +161 -0
- xulbux/system.cpython-311-darwin.so +0 -0
- xulbux/system.py +313 -0
- xulbux-1.9.5.dist-info/METADATA +271 -0
- xulbux-1.9.5.dist-info/RECORD +43 -0
- xulbux-1.9.5.dist-info/WHEEL +6 -0
- xulbux-1.9.5.dist-info/entry_points.txt +2 -0
- xulbux-1.9.5.dist-info/licenses/LICENSE +21 -0
- xulbux-1.9.5.dist-info/top_level.txt +2 -0
xulbux/system.py
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides the `System` class, which includes
|
|
3
|
+
methods to interact with the underlying operating system.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .base.types import MissingLibsMsgs
|
|
7
|
+
from .base.decorators import mypyc_attr
|
|
8
|
+
|
|
9
|
+
from .format_codes import FormatCodes
|
|
10
|
+
from .console import Console
|
|
11
|
+
|
|
12
|
+
from typing import Optional
|
|
13
|
+
import subprocess as _subprocess
|
|
14
|
+
import multiprocessing as _multiprocessing
|
|
15
|
+
import platform as _platform
|
|
16
|
+
import ctypes as _ctypes
|
|
17
|
+
import getpass as _getpass
|
|
18
|
+
import socket as _socket
|
|
19
|
+
import time as _time
|
|
20
|
+
import sys as _sys
|
|
21
|
+
import os as _os
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@mypyc_attr(native_class=False)
|
|
25
|
+
class _SystemMeta(type):
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def is_elevated(cls) -> bool:
|
|
29
|
+
"""Whether the current process has elevated privileges or not."""
|
|
30
|
+
try:
|
|
31
|
+
if _os.name == "nt":
|
|
32
|
+
return getattr(_ctypes, "windll").shell32.IsUserAnAdmin() != 0
|
|
33
|
+
elif _os.name == "posix":
|
|
34
|
+
return _os.geteuid() == 0 # type: ignore[attr-defined]
|
|
35
|
+
except Exception:
|
|
36
|
+
pass
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def is_win(cls) -> bool:
|
|
41
|
+
"""Whether the current operating system is Windows or not."""
|
|
42
|
+
return _platform.system() == "Windows"
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def is_linux(cls) -> bool:
|
|
46
|
+
"""Whether the current operating system is Linux or not."""
|
|
47
|
+
return _platform.system() == "Linux"
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def is_mac(cls) -> bool:
|
|
51
|
+
"""Whether the current operating system is macOS or not."""
|
|
52
|
+
return _platform.system() == "Darwin"
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def is_unix(cls) -> bool:
|
|
56
|
+
"""Whether the current operating system is a Unix-like OS (Linux, macOS, BSD, …) or not."""
|
|
57
|
+
return _os.name == "posix"
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def hostname(cls) -> str:
|
|
61
|
+
"""The network hostname of the current machine."""
|
|
62
|
+
try:
|
|
63
|
+
return _socket.gethostname()
|
|
64
|
+
except Exception:
|
|
65
|
+
return "unknown"
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def username(cls) -> str:
|
|
69
|
+
"""The name of the current user."""
|
|
70
|
+
try:
|
|
71
|
+
return _getpass.getuser()
|
|
72
|
+
except Exception:
|
|
73
|
+
try:
|
|
74
|
+
return _os.getlogin()
|
|
75
|
+
except Exception:
|
|
76
|
+
return "unknown"
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def os_name(cls) -> str:
|
|
80
|
+
"""The name of the operating system (e.g. `Windows`, `Linux`, …)."""
|
|
81
|
+
return _platform.system()
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def os_version(cls) -> str:
|
|
85
|
+
"""The version of the operating system."""
|
|
86
|
+
try:
|
|
87
|
+
return _platform.version()
|
|
88
|
+
except Exception:
|
|
89
|
+
return "unknown"
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def architecture(cls) -> str:
|
|
93
|
+
"""The CPU architecture (e.g. `x86_64`, `ARM`, …)."""
|
|
94
|
+
return _platform.machine()
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def cpu_count(cls) -> int:
|
|
98
|
+
"""The number of CPU cores available."""
|
|
99
|
+
try:
|
|
100
|
+
count = _multiprocessing.cpu_count()
|
|
101
|
+
return count if count is not None else 1
|
|
102
|
+
except (NotImplementedError, AttributeError):
|
|
103
|
+
return 1
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def python_version(cls) -> str:
|
|
107
|
+
"""The version string of the currently running Python interpreter (e.g. `3.10.4`)."""
|
|
108
|
+
return _platform.python_version()
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class System(metaclass=_SystemMeta):
|
|
112
|
+
"""This class provides methods to interact with the underlying operating system."""
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def restart(cls, prompt: object = "", wait: int = 0, continue_program: bool = False, force: bool = False) -> None:
|
|
116
|
+
"""Restarts the system with some advanced options\n
|
|
117
|
+
--------------------------------------------------------------------------------------------------
|
|
118
|
+
- `prompt` -⠀the message to be displayed in the systems restart notification
|
|
119
|
+
- `wait` -⠀the time to wait until restarting in seconds
|
|
120
|
+
- `continue_program` -⠀whether to continue the current Python program after calling this function
|
|
121
|
+
- `force` -⠀whether to force a restart even if other processes are still running"""
|
|
122
|
+
if wait < 0:
|
|
123
|
+
raise ValueError(f"The 'wait' parameter must be non-negative, got {wait!r}")
|
|
124
|
+
|
|
125
|
+
_SystemRestartHelper(prompt, wait, continue_program, force)()
|
|
126
|
+
|
|
127
|
+
@classmethod
|
|
128
|
+
def check_libs(
|
|
129
|
+
cls,
|
|
130
|
+
lib_names: list[str],
|
|
131
|
+
install_missing: bool = False,
|
|
132
|
+
missing_libs_msgs: MissingLibsMsgs = {
|
|
133
|
+
"found_missing": "The following required libraries are missing:",
|
|
134
|
+
"should_install": "Do you want to install them now?",
|
|
135
|
+
},
|
|
136
|
+
confirm_install: bool = True,
|
|
137
|
+
) -> Optional[list[str]]:
|
|
138
|
+
"""Checks if the given list of libraries are installed and optionally installs missing libraries.\n
|
|
139
|
+
------------------------------------------------------------------------------------------------------------
|
|
140
|
+
- `lib_names` -⠀a list of library names to check
|
|
141
|
+
- `install_missing` -⠀whether to directly missing libraries will be installed automatically using pip
|
|
142
|
+
- `missing_libs_msgs` -⠀two messages: the first one is displayed when missing libraries are found,
|
|
143
|
+
the second one is the confirmation message before installing missing libraries
|
|
144
|
+
- `confirm_install` -⠀whether the user will be asked for confirmation before installing missing libraries\n
|
|
145
|
+
------------------------------------------------------------------------------------------------------------
|
|
146
|
+
If some libraries are missing or they could not be installed, their names will be returned as a list.
|
|
147
|
+
If all libraries are installed (or were installed successfully), `None` will be returned."""
|
|
148
|
+
return _SystemCheckLibsHelper(lib_names, install_missing, missing_libs_msgs, confirm_install)()
|
|
149
|
+
|
|
150
|
+
@classmethod
|
|
151
|
+
def elevate(cls, win_title: Optional[str] = None, args: Optional[list] = None) -> bool:
|
|
152
|
+
"""Attempts to start a new process with elevated privileges.\n
|
|
153
|
+
---------------------------------------------------------------------------------
|
|
154
|
+
- `win_title` -⠀the window title of the elevated process (only on Windows)
|
|
155
|
+
- `args` -⠀a list of additional arguments to be passed to the elevated process\n
|
|
156
|
+
---------------------------------------------------------------------------------
|
|
157
|
+
After the elevated process started, the original process will exit.<br>
|
|
158
|
+
This means, that this method has to be run at the beginning of the program or
|
|
159
|
+
or else the program has to continue in a new window after elevation.\n
|
|
160
|
+
---------------------------------------------------------------------------------
|
|
161
|
+
Returns `True` if the current process already has elevated privileges and raises
|
|
162
|
+
a `PermissionError` if the user denied the elevation or the elevation failed."""
|
|
163
|
+
if cls.is_elevated:
|
|
164
|
+
return True
|
|
165
|
+
|
|
166
|
+
args_list = args or []
|
|
167
|
+
|
|
168
|
+
if _os.name == "nt": # WINDOWS
|
|
169
|
+
if win_title:
|
|
170
|
+
args_str = f'-c "import ctypes; ctypes.windll.kernel32.SetConsoleTitleW(\\"{win_title}\\"); exec(open(\\"{_sys.argv[0]}\\").read())" {" ".join(args_list)}"'
|
|
171
|
+
else:
|
|
172
|
+
args_str = f'-c "exec(open(\\"{_sys.argv[0]}\\").read())" {" ".join(args_list)}'
|
|
173
|
+
|
|
174
|
+
result = getattr(_ctypes, "windll").shell32.ShellExecuteW(None, "runas", _sys.executable, args_str, None, 1)
|
|
175
|
+
if result <= 32:
|
|
176
|
+
raise PermissionError("Failed to launch elevated process.")
|
|
177
|
+
else:
|
|
178
|
+
_sys.exit(0)
|
|
179
|
+
|
|
180
|
+
else: # POSIX
|
|
181
|
+
cmd = ["pkexec"]
|
|
182
|
+
if win_title:
|
|
183
|
+
cmd.extend(["--description", win_title])
|
|
184
|
+
cmd.extend([_sys.executable] + _sys.argv[1:] + args_list)
|
|
185
|
+
|
|
186
|
+
proc = _subprocess.Popen(cmd)
|
|
187
|
+
proc.wait()
|
|
188
|
+
if proc.returncode != 0:
|
|
189
|
+
raise PermissionError("Process elevation was denied.")
|
|
190
|
+
_sys.exit(0)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class _SystemRestartHelper:
|
|
194
|
+
"""Internal, callable helper class to handle system restart with platform-specific logic."""
|
|
195
|
+
|
|
196
|
+
def __init__(self, prompt: object, wait: int, continue_program: bool, force: bool):
|
|
197
|
+
self.prompt = prompt
|
|
198
|
+
self.wait = wait
|
|
199
|
+
self.continue_program = continue_program
|
|
200
|
+
self.force = force
|
|
201
|
+
|
|
202
|
+
def __call__(self) -> None:
|
|
203
|
+
if (system := _platform.system().lower()) == "windows":
|
|
204
|
+
self.restart_windows()
|
|
205
|
+
elif system in {"linux", "darwin"}:
|
|
206
|
+
self.restart_posix()
|
|
207
|
+
else:
|
|
208
|
+
raise NotImplementedError(f"Restart not implemented for '{system}' systems.")
|
|
209
|
+
|
|
210
|
+
def check_running_processes(self, command: str | list[str], skip_lines: int = 0) -> None:
|
|
211
|
+
"""Check if processes are running and raise error if force is False."""
|
|
212
|
+
if self.force:
|
|
213
|
+
return
|
|
214
|
+
|
|
215
|
+
if isinstance(command, str):
|
|
216
|
+
output = _subprocess.check_output(command, shell=True).decode()
|
|
217
|
+
else:
|
|
218
|
+
output = _subprocess.check_output(command).decode()
|
|
219
|
+
|
|
220
|
+
processes = [line for line in output.splitlines()[skip_lines:] if line.strip()]
|
|
221
|
+
if len(processes) > 2: # EXCLUDING PYTHON AND SHELL PROCESSES
|
|
222
|
+
raise RuntimeError("Processes are still running.\nTo restart anyway set parameter 'force' to True.")
|
|
223
|
+
|
|
224
|
+
def restart_windows(self) -> None:
|
|
225
|
+
"""Handle Windows system restart."""
|
|
226
|
+
self.check_running_processes("tasklist", skip_lines=3)
|
|
227
|
+
|
|
228
|
+
if self.prompt:
|
|
229
|
+
_os.system(f'shutdown /r /t {self.wait} /c "{self.prompt}"')
|
|
230
|
+
else:
|
|
231
|
+
_os.system("shutdown /r /t 0")
|
|
232
|
+
|
|
233
|
+
if self.continue_program:
|
|
234
|
+
self.wait_for_restart()
|
|
235
|
+
|
|
236
|
+
def restart_posix(self) -> None:
|
|
237
|
+
"""Handle Linux/macOS system restart."""
|
|
238
|
+
self.check_running_processes(["ps", "-A"], skip_lines=1)
|
|
239
|
+
|
|
240
|
+
if self.prompt:
|
|
241
|
+
_subprocess.Popen(["notify-send", "System Restart", str(self.prompt)])
|
|
242
|
+
_time.sleep(self.wait)
|
|
243
|
+
|
|
244
|
+
try:
|
|
245
|
+
_subprocess.run(["sudo", "shutdown", "-r", "now"])
|
|
246
|
+
except _subprocess.CalledProcessError:
|
|
247
|
+
raise PermissionError("Failed to restart: insufficient privileges.\nEnsure sudo permissions are granted.")
|
|
248
|
+
|
|
249
|
+
if self.continue_program:
|
|
250
|
+
self.wait_for_restart()
|
|
251
|
+
|
|
252
|
+
def wait_for_restart(self) -> None:
|
|
253
|
+
"""Wait and print message before restart."""
|
|
254
|
+
print(f"Restarting in {self.wait} seconds...")
|
|
255
|
+
_time.sleep(self.wait)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class _SystemCheckLibsHelper:
|
|
259
|
+
"""Internal, callable helper class to check and install missing Python libraries."""
|
|
260
|
+
|
|
261
|
+
def __init__(
|
|
262
|
+
self,
|
|
263
|
+
lib_names: list[str],
|
|
264
|
+
install_missing: bool,
|
|
265
|
+
missing_libs_msgs: MissingLibsMsgs,
|
|
266
|
+
confirm_install: bool,
|
|
267
|
+
):
|
|
268
|
+
self.lib_names = lib_names
|
|
269
|
+
self.install_missing = install_missing
|
|
270
|
+
self.missing_libs_msgs = missing_libs_msgs
|
|
271
|
+
self.confirm_install = confirm_install
|
|
272
|
+
|
|
273
|
+
def __call__(self) -> Optional[list[str]]:
|
|
274
|
+
missing = self.find_missing_libs()
|
|
275
|
+
|
|
276
|
+
if not missing:
|
|
277
|
+
return None
|
|
278
|
+
elif not self.install_missing:
|
|
279
|
+
return missing
|
|
280
|
+
|
|
281
|
+
if self.confirm_install and not self.confirm_installation(missing):
|
|
282
|
+
return missing
|
|
283
|
+
|
|
284
|
+
return self.install_libs(missing)
|
|
285
|
+
|
|
286
|
+
def find_missing_libs(self) -> list[str]:
|
|
287
|
+
"""Find which libraries are missing."""
|
|
288
|
+
missing = []
|
|
289
|
+
for lib in self.lib_names:
|
|
290
|
+
try:
|
|
291
|
+
__import__(lib)
|
|
292
|
+
except ImportError:
|
|
293
|
+
missing.append(lib)
|
|
294
|
+
return missing
|
|
295
|
+
|
|
296
|
+
def confirm_installation(self, missing: list[str]) -> bool:
|
|
297
|
+
"""Ask user for confirmation before installing libraries."""
|
|
298
|
+
FormatCodes.print(f"[b]({self.missing_libs_msgs['found_missing']})")
|
|
299
|
+
for lib in missing:
|
|
300
|
+
FormatCodes.print(f" [dim](•) [i]{lib}[_i]")
|
|
301
|
+
print()
|
|
302
|
+
return Console.confirm(self.missing_libs_msgs["should_install"], end="\n")
|
|
303
|
+
|
|
304
|
+
def install_libs(self, missing: list[str]) -> Optional[list[str]]:
|
|
305
|
+
"""Install missing libraries using pip."""
|
|
306
|
+
for lib in missing[:]:
|
|
307
|
+
try:
|
|
308
|
+
_subprocess.check_call([_sys.executable, "-m", "pip", "install", lib])
|
|
309
|
+
missing.remove(lib)
|
|
310
|
+
except _subprocess.CalledProcessError:
|
|
311
|
+
pass
|
|
312
|
+
|
|
313
|
+
return None if len(missing) == 0 else missing
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: xulbux
|
|
3
|
+
Version: 1.9.5
|
|
4
|
+
Summary: A Python library to simplify common programming tasks.
|
|
5
|
+
Author-email: XulbuX <xulbux.real@gmail.com>
|
|
6
|
+
Maintainer-email: XulbuX <xulbux.real@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/XulbuX/PythonLibraryXulbuX
|
|
9
|
+
Project-URL: Documentation, https://github.com/XulbuX/PythonLibraryXulbuX/wiki
|
|
10
|
+
Project-URL: Source Code, https://github.com/XulbuX/PythonLibraryXulbuX/tree/main/src
|
|
11
|
+
Project-URL: Changelog, https://github.com/XulbuX/PythonLibraryXulbuX/blob/main/CHANGELOG.md
|
|
12
|
+
Project-URL: Bug Reports, https://github.com/XulbuX/PythonLibraryXulbuX/issues
|
|
13
|
+
Project-URL: Stats, https://clickpy.clickhouse.com/dashboard/xulbux
|
|
14
|
+
Project-URL: License, https://github.com/XulbuX/PythonLibraryXulbuX/blob/main/LICENSE
|
|
15
|
+
Keywords: args,arguments,attributes,classes,client,cmd,code,codes,color,commands,console,constants,consts,conversion,convert,data,debug,easier,env,environment,error,file,format,formatting,functions,helper,hex,hexa,hsl,hsla,info,input,json,library,log,logging,methods,nice,operations,path,presets,pretty,printing,properties,python,re,regex,rgb,rgba,string,structures,system,tools,types,utility,warn,warning,xulbux
|
|
16
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Classifier: Intended Audience :: Developers
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
|
+
Requires-Python: >=3.10.0
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: keyboard>=0.13.5
|
|
29
|
+
Requires-Dist: prompt_toolkit>=3.0.41
|
|
30
|
+
Requires-Dist: regex>=2023.10.3
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: flake8-pyproject>=1.2.3; extra == "dev"
|
|
33
|
+
Requires-Dist: flake8>=6.1.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest>=7.4.2; extra == "dev"
|
|
35
|
+
Requires-Dist: toml>=0.10.2; extra == "dev"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
> [!IMPORTANT]<br>
|
|
39
|
+
> This library is compatible with Python 3.14, but **some dependencies may not yet support this version**.
|
|
40
|
+
|
|
41
|
+
# **xulbux**
|
|
42
|
+
|
|
43
|
+
[](https://pypi.org/project/xulbux) [](https://clickpy.clickhouse.com/dashboard/xulbux) [](https://github.com/XulbuX/PythonLibraryXulbuX/blob/main/LICENSE) [](https://github.com/XulbuX/PythonLibraryXulbuX/commits) [](https://github.com/XulbuX/PythonLibraryXulbuX/issues) [](https://github.com/XulbuX/PythonLibraryXulbuX/stargazers)
|
|
44
|
+
|
|
45
|
+
**`xulbux`** is a library that contains many useful classes, types, and functions,
|
|
46
|
+
ranging from console logging and working with colors to file management and system operations.
|
|
47
|
+
The library is designed to simplify common programming tasks and improve code readability through its collection of tools.
|
|
48
|
+
|
|
49
|
+
For precise information about the library, see the library's [**documentation**](https://github.com/XulbuX/PythonLibraryXulbuX/wiki).<br>
|
|
50
|
+
For the libraries latest changes and updates, see the [**change log**](https://github.com/XulbuX/PythonLibraryXulbuX/blob/main/CHANGELOG.md).
|
|
51
|
+
|
|
52
|
+
### The best modules, you have to check out:
|
|
53
|
+
|
|
54
|
+
[](https://github.com/XulbuX/PythonLibraryXulbuX/wiki/format_codes) [](https://github.com/XulbuX/PythonLibraryXulbuX/wiki/console) [](https://github.com/XulbuX/PythonLibraryXulbuX/wiki/color)
|
|
55
|
+
|
|
56
|
+
<br>
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
Run the following commands in a console with administrator privileges, so the actions take effect for all users.
|
|
61
|
+
|
|
62
|
+
Install the library and all its dependencies with the command:
|
|
63
|
+
```console
|
|
64
|
+
pip install xulbux
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Upgrade the library and all its dependencies to their latest available version with the command:
|
|
68
|
+
```console
|
|
69
|
+
pip install --upgrade xulbux
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
<br>
|
|
73
|
+
|
|
74
|
+
## CLI Commands
|
|
75
|
+
|
|
76
|
+
When the library is installed, the following commands are available in the console:
|
|
77
|
+
| Command | Description |
|
|
78
|
+
| :------------ | :--------------------------------------- |
|
|
79
|
+
| `xulbux-help` | shows some information about the library |
|
|
80
|
+
|
|
81
|
+
<br>
|
|
82
|
+
|
|
83
|
+
## Usage
|
|
84
|
+
|
|
85
|
+
Import the full library under the alias `xx`, so its modules and main classes are accessible with `xx.module.Class`, `xx.MainClass.method()`:
|
|
86
|
+
```python
|
|
87
|
+
import xulbux as xx
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
So you don't have to import the full library under an alias, you can also import only certain parts of the library's contents:
|
|
91
|
+
```python
|
|
92
|
+
# LIBRARY SUB MODULES
|
|
93
|
+
from xulbux.base.consts import COLOR, CHARS, ANSI
|
|
94
|
+
# MODULE MAIN CLASSES
|
|
95
|
+
from xulbux import Code, Color, Console, ...
|
|
96
|
+
# MODULE SPECIFIC IMPORTS
|
|
97
|
+
from xulbux.color import rgba, hsla, hexa
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
<br>
|
|
101
|
+
|
|
102
|
+
## Modules
|
|
103
|
+
|
|
104
|
+
<table>
|
|
105
|
+
<thead>
|
|
106
|
+
<tr>
|
|
107
|
+
<th align="left">Main Module</th>
|
|
108
|
+
<th align="left">Contents</th>
|
|
109
|
+
</tr>
|
|
110
|
+
</thead>
|
|
111
|
+
<tbody>
|
|
112
|
+
<tr>
|
|
113
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/base"><img src="https://img.shields.io/badge/base-B272FC?style=for-the-badge" alt="base"></a></td>
|
|
114
|
+
<td>
|
|
115
|
+
<table>
|
|
116
|
+
<thead>
|
|
117
|
+
<tr>
|
|
118
|
+
<th align="left">Sub Module</th>
|
|
119
|
+
<th align="left">Contents</th>
|
|
120
|
+
</tr>
|
|
121
|
+
</thead>
|
|
122
|
+
<tbody>
|
|
123
|
+
<tr>
|
|
124
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/base#consts"><img src="https://img.shields.io/badge/consts-B272FC?style=for-the-badge" alt="consts"></a></td>
|
|
125
|
+
<td>Constant values used throughout the library.</td>
|
|
126
|
+
</tr>
|
|
127
|
+
<tr>
|
|
128
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/base#exceptions"><img src="https://img.shields.io/badge/exceptions-B272FC?style=for-the-badge" alt="exceptions"></a></td>
|
|
129
|
+
<td>Custom exception classes used throughout the library.</td>
|
|
130
|
+
</tr>
|
|
131
|
+
<tr>
|
|
132
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/base#types"><img src="https://img.shields.io/badge/types-B272FC?style=for-the-badge" alt="types"></a></td>
|
|
133
|
+
<td>Custom type definitions used throughout the library.</td>
|
|
134
|
+
</tr>
|
|
135
|
+
</tbody>
|
|
136
|
+
</table>
|
|
137
|
+
</td>
|
|
138
|
+
</tr>
|
|
139
|
+
<tr>
|
|
140
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/code"><img src="https://img.shields.io/badge/code-B272FC?style=for-the-badge" alt="code"></a></td>
|
|
141
|
+
<td><code>Code</code> class, which includes methods to work with code strings.</td>
|
|
142
|
+
</tr>
|
|
143
|
+
<tr>
|
|
144
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/color"><img src="https://img.shields.io/badge/color-B272FC?style=for-the-badge" alt="color"></a></td>
|
|
145
|
+
<td><code>rgba</code> <code>hsla</code> <code>hexa</code> <code>Color</code> classes, which include methods to work with<br>
|
|
146
|
+
colors in various formats.</td>
|
|
147
|
+
</tr>
|
|
148
|
+
<tr>
|
|
149
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/console"><img src="https://img.shields.io/badge/console-B272FC?style=for-the-badge" alt="console"></a></td>
|
|
150
|
+
<td><code>Console</code> <code>ProgressBar</code> classes, which include methods for logging<br>
|
|
151
|
+
and other actions within the console.</td>
|
|
152
|
+
</tr>
|
|
153
|
+
<tr>
|
|
154
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/data"><img src="https://img.shields.io/badge/data-B272FC?style=for-the-badge" alt="data"></a></td>
|
|
155
|
+
<td><code>Data</code> class, which includes methods to work with nested data structures.</td>
|
|
156
|
+
</tr>
|
|
157
|
+
<tr>
|
|
158
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/env_path"><img src="https://img.shields.io/badge/env__path-B272FC?style=for-the-badge" alt="env_path"></a></td>
|
|
159
|
+
<td><code>EnvPath</code> class, which includes methods to work with the PATH environment variable.</td>
|
|
160
|
+
</tr>
|
|
161
|
+
<tr>
|
|
162
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/path"><img src="https://img.shields.io/badge/file__sys-B272FC?style=for-the-badge" alt="path"></a></td>
|
|
163
|
+
<td><code>FileSys</code> class, which includes methods to work with the file system and directories.</td>
|
|
164
|
+
</tr>
|
|
165
|
+
<tr>
|
|
166
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/file"><img src="https://img.shields.io/badge/file-B272FC?style=for-the-badge" alt="file"></a></td>
|
|
167
|
+
<td><code>File</code> class, which includes methods to work with files and file paths.</td>
|
|
168
|
+
</tr>
|
|
169
|
+
<tr>
|
|
170
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/format_codes"><img src="https://img.shields.io/badge/format__codes-B272FC?style=for-the-badge" alt="format_codes"></a></td>
|
|
171
|
+
<td><code>FormatCodes</code> class, which includes methods to print and work with strings that contain<br>
|
|
172
|
+
special formatting codes, which are then converted to ANSI codes for pretty console output.</td>
|
|
173
|
+
</tr>
|
|
174
|
+
<tr>
|
|
175
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/json"><img src="https://img.shields.io/badge/json-B272FC?style=for-the-badge" alt="json"></a></td>
|
|
176
|
+
<td><code>Json</code> class, which includes methods to read, create and update JSON files,<br>
|
|
177
|
+
with support for comments inside the JSON data.</td>
|
|
178
|
+
</tr>
|
|
179
|
+
<tr>
|
|
180
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/regex"><img src="https://img.shields.io/badge/regex-B272FC?style=for-the-badge" alt="regex"></a></td>
|
|
181
|
+
<td><code>Regex</code> class, which includes methods to dynamically generate complex regex patterns<br>
|
|
182
|
+
for common use cases.</td>
|
|
183
|
+
</tr>
|
|
184
|
+
<tr>
|
|
185
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/string"><img src="https://img.shields.io/badge/string-B272FC?style=for-the-badge" alt="string"></a></td>
|
|
186
|
+
<td><code>String</code> class, which includes various utility methods for string manipulation and conversion.</td>
|
|
187
|
+
</tr>
|
|
188
|
+
<tr>
|
|
189
|
+
<td><a href="https://github.com/XulbuX/PythonLibraryXulbuX/wiki/system"><img src="https://img.shields.io/badge/system-B272FC?style=for-the-badge" alt="system"></a></td>
|
|
190
|
+
<td><code>System</code> class, which includes methods to interact with the underlying operating system.</td>
|
|
191
|
+
</tr>
|
|
192
|
+
</tbody>
|
|
193
|
+
</table>
|
|
194
|
+
|
|
195
|
+
<br>
|
|
196
|
+
|
|
197
|
+
## Example Usage
|
|
198
|
+
|
|
199
|
+
This is what it could look like using this library for a simple but ultra good-looking color converter:
|
|
200
|
+
```python
|
|
201
|
+
from xulbux.base.consts import COLOR, CHARS
|
|
202
|
+
from xulbux.color import hexa
|
|
203
|
+
from xulbux import Console
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def main() -> None:
|
|
207
|
+
|
|
208
|
+
# LET THE USER ENTER A HEXA COLOR IN ANY HEXA FORMAT
|
|
209
|
+
input_clr = Console.input(
|
|
210
|
+
"[b](Enter a HEXA color in any format) > ",
|
|
211
|
+
start="\n",
|
|
212
|
+
placeholder="#7075FF",
|
|
213
|
+
max_len=7,
|
|
214
|
+
allowed_chars=CHARS.HEX_DIGITS,
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
# ANNOUNCE INDEXING THE INPUT COLOR
|
|
218
|
+
Console.log(
|
|
219
|
+
"INDEX",
|
|
220
|
+
"Indexing the input HEXA color...",
|
|
221
|
+
start="\n",
|
|
222
|
+
title_bg_color=COLOR.BLUE,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
try:
|
|
226
|
+
# TRY TO CONVERT THE INPUT STRING INTO A hexa() OBJECT
|
|
227
|
+
hexa_color = hexa(input_clr)
|
|
228
|
+
|
|
229
|
+
except ValueError:
|
|
230
|
+
# ANNOUNCE THE INVALID INPUT COLOR AND EXIT THE PROGRAM
|
|
231
|
+
Console.fail(
|
|
232
|
+
"The input HEXA color is invalid.",
|
|
233
|
+
end="\n\n",
|
|
234
|
+
exit=True,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
# ANNOUNCE STARTING THE CONVERSION
|
|
238
|
+
Console.log(
|
|
239
|
+
"CONVERT",
|
|
240
|
+
"Converting the HEXA color into different types...",
|
|
241
|
+
title_bg_color=COLOR.TANGERINE,
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
# CONVERT THE HEXA COLOR INTO THE TWO OTHER COLOR FORMATS
|
|
245
|
+
rgba_color = hexa_color.to_rgba()
|
|
246
|
+
hsla_color = hexa_color.to_hsla()
|
|
247
|
+
|
|
248
|
+
# ANNOUNCE THE SUCCESSFUL CONVERSION
|
|
249
|
+
Console.done(
|
|
250
|
+
"Successfully converted color into different types.",
|
|
251
|
+
end="\n\n",
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
# PRETTY PRINT THE COLOR IN DIFFERENT FORMATS
|
|
255
|
+
Console.log_box_bordered(
|
|
256
|
+
f"[b](HEXA:) [i|white]({hexa_color})",
|
|
257
|
+
f"[b](RGBA:) [i|white]({rgba_color})",
|
|
258
|
+
f"[b](HSLA:) [i|white]({hsla_color})",
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
if __name__ == "__main__":
|
|
263
|
+
main()
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
<br>
|
|
268
|
+
<br>
|
|
269
|
+
|
|
270
|
+
-----------------------------------------------------------------
|
|
271
|
+
[View this library on **PyPI**](https://pypi.org/project/xulbux)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
455848faf89d8974b22a__mypyc.cpython-311-darwin.so,sha256=069yox67z4jhxsxbIiNTej0gGpxwY2sjl8brGA_Q7ZM,3014240
|
|
2
|
+
xulbux/file_sys.cpython-311-darwin.so,sha256=eEj2YbHSlXympHYG1WvdLyo3tqsTcH-ayMuARyWezPw,50656
|
|
3
|
+
xulbux/console.py,sha256=v_u9rsD1Wx1izNhj8jpOMGP-Zys9wOGvL3HgqN-Zoi8,89527
|
|
4
|
+
xulbux/file_sys.py,sha256=rDonTTpCpVIcpEkqGJynyB-uwvqN5G7Ukyq5yWS2Ql8,10848
|
|
5
|
+
xulbux/system.py,sha256=oPC8sKhabrTBXI61cTaLvPp3SL1JZQa6e2ru_spXOL8,12272
|
|
6
|
+
xulbux/color.py,sha256=bFkz5tApLNjhrfgp-4IRApCnO3co9sCs5olVTLTnkes,63549
|
|
7
|
+
xulbux/json.cpython-311-darwin.so,sha256=yXhzNdsUbJQzGZ3WevjuH6F7cWE2_FnpfG18bdKCMSg,50632
|
|
8
|
+
xulbux/console.cpython-311-darwin.so,sha256=W-S83oMjiii7350XrJbsCTQG7mpioYOaamSTxVGA-ic,50656
|
|
9
|
+
xulbux/color.cpython-311-darwin.so,sha256=eVUpt0LvyWths-kqKGYIhF3Ab_VPb6ZRgnvfD7SfszU,50632
|
|
10
|
+
xulbux/string.cpython-311-darwin.so,sha256=FDRhXesidLZIXmWjzxEJz_NYbyULom9VMrgC-v8C0dw,50640
|
|
11
|
+
xulbux/code.cpython-311-darwin.so,sha256=ZzaXOC2S9Eh4-_NShqsGCRA6hPd4zGh48DBEnvci3PQ,50632
|
|
12
|
+
xulbux/code.py,sha256=cuC01ZRcPEDLlZ-5whc27pJKsZ-YiLHQqdvlPxPHD80,6633
|
|
13
|
+
xulbux/__init__.py,sha256=BDCeIoSfeMZNxgwailjuHXSzxURuuNn6448c_bJzX5I,980
|
|
14
|
+
xulbux/system.cpython-311-darwin.so,sha256=Y3FUIM7tfRpZ0Z7fd2uam9xbRdxHUH5JiO3M9tEChYo,50640
|
|
15
|
+
xulbux/file.py,sha256=vDo7LqyJ2gVShc9a45P1yvQ4Ral9GZ8FFkSiYg-FZ_o,3001
|
|
16
|
+
xulbux/env_path.py,sha256=OXdHIriy0Qd7IekKiEzkR6SHFYNrVpmMq0LtIN51GJY,5768
|
|
17
|
+
xulbux/file.cpython-311-darwin.so,sha256=6d52SmMXFYf8cLFLkNZWinzPKVil-BPYWneEnSAl9ts,50632
|
|
18
|
+
xulbux/data.cpython-311-darwin.so,sha256=527ZPc9LJIEC-ARa7CbD0oAWQ-Yr1axoCFlgx74Oc8E,50632
|
|
19
|
+
xulbux/format_codes.cpython-311-darwin.so,sha256=gPOj59JTyuOiCSoyKsvwOkDO1G9fu03ETwGaSKywRho,50672
|
|
20
|
+
xulbux/regex.cpython-311-darwin.so,sha256=MQxEqEESNvZL_2dr16Az5qK9xHZE268cyAQ5-1n9aQ4,50632
|
|
21
|
+
xulbux/string.py,sha256=p9c0f8MQmhNvgYiN4_d8iwMkstMLZ9bXtYE6kqReFVw,8095
|
|
22
|
+
xulbux/__init__.cpython-311-darwin.so,sha256=OgrVBKFwglDLAoy_PNzGvfaaTpur5kViaBV2nJFhA_0,50640
|
|
23
|
+
xulbux/format_codes.py,sha256=D-kw0BHVn-fW8YgpNbeIXDV59yC9VA4KoXtubMYJjFg,33048
|
|
24
|
+
xulbux/json.py,sha256=1NGC6Uo_DtvNUAo_W4Ef5pnYlrWIZz9o1K4y0OjADY8,8816
|
|
25
|
+
xulbux/regex.py,sha256=jxTeV_rHYKOU6wHEpZUqwXsR9Oa9pmrR6I7wQCYzwZ4,11088
|
|
26
|
+
xulbux/data.py,sha256=aG6IqXDqKMzC5pjH-v-ust3_kgwAzbBmQpIMkbAzIuQ,37717
|
|
27
|
+
xulbux/env_path.cpython-311-darwin.so,sha256=NSKDoRmHtpBhrvmtSpPjYlm01N_aMeAjjIqQ4qwO-c8,50656
|
|
28
|
+
xulbux/cli/help.cpython-311-darwin.so,sha256=qoAS2Nqdw_R6u-0ETPV7wzojz5ipHxt9Oy_rQ4JzWyY,50648
|
|
29
|
+
xulbux/cli/help.py,sha256=m8ESGfCC_dZ4K8IvGmB_jRIkQqzANDIAVO5rSEyMbi8,4694
|
|
30
|
+
xulbux/base/consts.cpython-311-darwin.so,sha256=UC0pp974NpWhEvfn1dimL3ctZ8jU3SBe3U8bUgC0jF0,50656
|
|
31
|
+
xulbux/base/exceptions.cpython-311-darwin.so,sha256=9FhSAg9Lh6gXVYCl3Y05byfZLmKjXrlJ3QhPfJqM_QM,50672
|
|
32
|
+
xulbux/base/types.cpython-311-darwin.so,sha256=BJKbHX0W2xTgRsZU1VqzeQuRn-iQpuzcvS-6YIttiNY,50648
|
|
33
|
+
xulbux/base/types.py,sha256=diE4gtfa4ZbHfHcmIupbAHl_brD5aCwYNLMs8opkzCY,4621
|
|
34
|
+
xulbux/base/consts.py,sha256=iHWfXl_HBvN0ijCZZKRHnknkChACGVAqO0UJNW3_90I,6121
|
|
35
|
+
xulbux/base/decorators.cpython-311-darwin.so,sha256=VU11Sh9c6sty5yom3yk4dbpx3BOIZ0GzD2BqMMBMj6U,50672
|
|
36
|
+
xulbux/base/exceptions.py,sha256=vGVBMCz9kIG3uqKLb4wgJzivvRfmyMFN1q9_EgtyBMc,694
|
|
37
|
+
xulbux/base/decorators.py,sha256=eG4jQuTRv6Xjuk8T3G-jBI5jt9JIMqnxlY8ZgqxpFco,1025
|
|
38
|
+
xulbux-1.9.5.dist-info/RECORD,,
|
|
39
|
+
xulbux-1.9.5.dist-info/WHEEL,sha256=kRQSXRktg6-1OW1dEVdlVLDFcaf4B6AUNRZVJD--zs8,137
|
|
40
|
+
xulbux-1.9.5.dist-info/entry_points.txt,sha256=aYh89GfiBOB8vw2VPgC6rhBinhnJoAL1kig-3lq_zkg,58
|
|
41
|
+
xulbux-1.9.5.dist-info/top_level.txt,sha256=0pBrA469P41tUFO2XpUoGuu2NFBXnRgpe0pbojAlxOM,35
|
|
42
|
+
xulbux-1.9.5.dist-info/METADATA,sha256=KRsysgBxA4zqDkw379dEB7QWsUe8JaXZcAa238sIlMA,12819
|
|
43
|
+
xulbux-1.9.5.dist-info/licenses/LICENSE,sha256=LHwUGQKA35mmTlOCvvcg9RAiMQUA3e_n3q0taRMKE5w,1063
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 XulbuX
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|