xulbux 1.5.5__py3-none-any.whl → 1.5.8__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 xulbux might be problematic. Click here for more details.
- xulbux/__init__.py +28 -18
- xulbux/{__help__.py → _cli_.py} +23 -45
- xulbux/_consts_.py +108 -111
- xulbux/xx_code.py +31 -28
- xulbux/xx_color.py +364 -205
- xulbux/xx_console.py +381 -0
- xulbux/xx_data.py +358 -261
- xulbux/xx_env_path.py +113 -0
- xulbux/xx_file.py +22 -16
- xulbux/xx_format_codes.py +156 -91
- xulbux/xx_json.py +38 -18
- xulbux/xx_path.py +38 -23
- xulbux/xx_regex.py +64 -29
- xulbux/xx_string.py +104 -47
- xulbux/xx_system.py +37 -26
- {xulbux-1.5.5.dist-info → xulbux-1.5.8.dist-info}/METADATA +23 -19
- xulbux-1.5.8.dist-info/RECORD +20 -0
- {xulbux-1.5.5.dist-info → xulbux-1.5.8.dist-info}/WHEEL +1 -1
- xulbux-1.5.8.dist-info/entry_points.txt +3 -0
- xulbux/xx_cmd.py +0 -240
- xulbux/xx_env_vars.py +0 -60
- xulbux-1.5.5.dist-info/RECORD +0 -20
- xulbux-1.5.5.dist-info/entry_points.txt +0 -2
- {xulbux-1.5.5.dist-info → xulbux-1.5.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
|
-
Name:
|
|
3
|
-
Version: 1.5.
|
|
2
|
+
Name: xulbux
|
|
3
|
+
Version: 1.5.8
|
|
4
4
|
Summary: A library which includes a lot of really helpful functions.
|
|
5
|
-
Project-URL: Homepage, https://github.com/XulbuX-dev/
|
|
6
|
-
Project-URL: Bug Reports, https://github.com/XulbuX-dev/
|
|
7
|
-
Project-URL: Documentation, https://github.com/XulbuX-dev/
|
|
8
|
-
Project-URL: Source Code, https://github.com/XulbuX-dev/
|
|
9
|
-
Project-URL: Changelog, https://github.com/XulbuX-dev/
|
|
5
|
+
Project-URL: Homepage, https://github.com/XulbuX-dev/PythonLibraryXulbuX
|
|
6
|
+
Project-URL: Bug Reports, https://github.com/XulbuX-dev/PythonLibraryXulbuX/issues
|
|
7
|
+
Project-URL: Documentation, https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki
|
|
8
|
+
Project-URL: Source Code, https://github.com/XulbuX-dev/PythonLibraryXulbuX/tree/main/src
|
|
9
|
+
Project-URL: Changelog, https://github.com/XulbuX-dev/PythonLibraryXulbuX/blob/main/CHANGELOG.md
|
|
10
10
|
Author-email: XulbuX <xulbux.real@gmail.com>
|
|
11
11
|
License: MIT License
|
|
12
12
|
|
|
@@ -29,7 +29,7 @@ License: MIT License
|
|
|
29
29
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
30
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
31
|
SOFTWARE.
|
|
32
|
-
Keywords: classes,cmd,code,color,data,env,environment,file,format,functions,helper,
|
|
32
|
+
Keywords: classes,cmd,code,color,data,env,environment,file,format,functions,helper,json,library,methods,operations,path,presets,python,regex,string,structures,system,tools,types,utility,xulbux
|
|
33
33
|
Classifier: Intended Audience :: Developers
|
|
34
34
|
Classifier: License :: OSI Approved :: MIT License
|
|
35
35
|
Classifier: Operating System :: OS Independent
|
|
@@ -41,24 +41,28 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
41
41
|
Requires-Python: >=3.10.0
|
|
42
42
|
Requires-Dist: keyboard>=0.13.5
|
|
43
43
|
Requires-Dist: mouse>=0.7.1
|
|
44
|
+
Requires-Dist: pyperclip>=1.9.0
|
|
44
45
|
Requires-Dist: regex>=2023.10.3
|
|
45
46
|
Provides-Extra: dev
|
|
46
|
-
Requires-Dist:
|
|
47
|
+
Requires-Dist: black>=23.7.0; extra == 'dev'
|
|
48
|
+
Requires-Dist: flake8>=6.1.0; extra == 'dev'
|
|
49
|
+
Requires-Dist: isort>=5.12.0; extra == 'dev'
|
|
50
|
+
Requires-Dist: pytest>=7.4.2; extra == 'dev'
|
|
47
51
|
Description-Content-Type: text/markdown
|
|
48
52
|
|
|
49
53
|
# **$\color{#8085FF}\Huge\textsf{XulbuX}$**
|
|
50
54
|
|
|
51
55
|
**$\color{#8085FF}\textsf{XulbuX}$** is a library which includes a lot of really helpful classes, types and functions.
|
|
52
56
|
|
|
53
|
-
For the libraries latest changes, see the [change log](https://github.com/XulbuX-dev/
|
|
54
|
-
For precise information about the library, see the library's [Wiki page](https://github.com/XulbuX-dev/
|
|
57
|
+
For the libraries latest changes, see the [change log](https://github.com/XulbuX-dev/PythonLibraryXulbuX/blob/main/CHANGELOG.md).<br>
|
|
58
|
+
For precise information about the library, see the library's [Wiki page](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki).
|
|
55
59
|
|
|
56
60
|
|
|
57
61
|
## Installation
|
|
58
62
|
|
|
59
63
|
On all operating systems, run the following command:
|
|
60
64
|
```bash
|
|
61
|
-
pip install
|
|
65
|
+
pip install xulbux
|
|
62
66
|
```
|
|
63
67
|
|
|
64
68
|
|
|
@@ -66,9 +70,9 @@ pip install XulbuX
|
|
|
66
70
|
|
|
67
71
|
```python
|
|
68
72
|
# GENERAL LIBRARY
|
|
69
|
-
import
|
|
73
|
+
import xulbux as xx
|
|
70
74
|
# CUSTOM TYPES
|
|
71
|
-
from
|
|
75
|
+
from xulbux import rgba, hsla, hexa
|
|
72
76
|
```
|
|
73
77
|
The library **$\color{#8085FF}\textsf{XulbuX}$** (*below used as* `xx` *with above imported types*) contains the following modules:
|
|
74
78
|
```python
|
|
@@ -80,12 +84,12 @@ The library **$\color{#8085FF}\textsf{XulbuX}$** (*below used as* `xx` *with abo
|
|
|
80
84
|
• FILE OPERATIONS xx.File
|
|
81
85
|
• JSON FILE OPERATIONS xx.Json
|
|
82
86
|
• SYSTEM ACTIONS xx.System
|
|
83
|
-
• MANAGE
|
|
84
|
-
•
|
|
85
|
-
• PRETTY PRINTING
|
|
86
|
-
•
|
|
87
|
+
• MANAGE THE ENV PATH VAR xx.EnvPath
|
|
88
|
+
• CONSOLE LOG AND ACTIONS xx.Console
|
|
89
|
+
• EASY PRETTY PRINTING xx.FormatCodes
|
|
90
|
+
• WORKING WITH COLORS xx.Color
|
|
87
91
|
• DATA OPERATIONS xx.Data
|
|
88
|
-
•
|
|
92
|
+
• STRING OPERATIONS xx.String
|
|
89
93
|
• CODE STRING OPERATIONS xx.Code
|
|
90
94
|
• REGEX PATTERN TEMPLATES xx.Regex
|
|
91
95
|
```
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
xulbux/__init__.py,sha256=yhdvShCcbcLeBfKckjurNcrkCHIj1wWEezgtQPbytGI,1672
|
|
2
|
+
xulbux/_cli_.py,sha256=zCa4dROOwJ3TPIH8ed1gezRj309ljGOAapICRqq4OKs,3464
|
|
3
|
+
xulbux/_consts_.py,sha256=HqBCzFYSk9LS2TrxPCQBQcEjEB8McLodH4ZGZ8yP3Ec,4858
|
|
4
|
+
xulbux/xx_code.py,sha256=v3fhHelqxFXtp2RI7sY7mXusRKdiyOEzy_rmrC3N-Os,5158
|
|
5
|
+
xulbux/xx_color.py,sha256=Ib_jVAYHl3uVUvWUv1jE_QHScNvIPgm9KxEl2xSJfQo,45019
|
|
6
|
+
xulbux/xx_console.py,sha256=Xzl73_LTyt9AW09KAV9tsGdEdiltxPJwJq9nZChWrUQ,15482
|
|
7
|
+
xulbux/xx_data.py,sha256=cwjJeQHwf-b9yE6UTI0DO7US-hWtgTmIdvwKH5KKtmI,25969
|
|
8
|
+
xulbux/xx_env_path.py,sha256=ITdJ4DKh1zAvZrV5kph1z0jUDBhwEtOP4u1OKW0hMts,4309
|
|
9
|
+
xulbux/xx_file.py,sha256=Zhlx7TZ0u2wcl_7khgpMCoqlrcfsbiOh03sj4nsuPaQ,2616
|
|
10
|
+
xulbux/xx_format_codes.py,sha256=hRQ4Vecw2TTa-g5pKshLP-pep_Da7iy38o879McCrOc,13547
|
|
11
|
+
xulbux/xx_json.py,sha256=Sz-UicwU2vdTud4itMV-ljqePzpNByu5WgnX4lEUVRc,5056
|
|
12
|
+
xulbux/xx_path.py,sha256=KB1HGYCxFB3_T97RVACajy3-QiksbviZVIW9-iQcr4s,4558
|
|
13
|
+
xulbux/xx_regex.py,sha256=ce-K62uk1nvayOvLAtMQSD-IwKiVu2IATj0s1C1u6pM,7956
|
|
14
|
+
xulbux/xx_string.py,sha256=cQOvektdBKKe4CuBw6VOoxTElayghk0SQPuLdMILn9A,7650
|
|
15
|
+
xulbux/xx_system.py,sha256=yehO57ggWDRJbeFoTE1VisW4QrbkqZzAyjKoL3xHx9k,3935
|
|
16
|
+
xulbux-1.5.8.dist-info/METADATA,sha256=B95tctbGYaeyy-_nvGssLk08OJNWaFUF1JeTD5_wi2A,4340
|
|
17
|
+
xulbux-1.5.8.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
18
|
+
xulbux-1.5.8.dist-info/entry_points.txt,sha256=a3womfLIMZKnOFiyy-xnVb4g2qkZsHR5FbKKkljcGns,94
|
|
19
|
+
xulbux-1.5.8.dist-info/licenses/LICENSE,sha256=6NflEcvzFEe8_JFVNCPVwZBwBhlLLd4vqQi8WiX_Xk4,1084
|
|
20
|
+
xulbux-1.5.8.dist-info/RECORD,,
|
xulbux/xx_cmd.py
DELETED
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Functions for logging and other small actions within the console:
|
|
3
|
-
- `Cmd.get_args()`
|
|
4
|
-
- `Cmd.user()`
|
|
5
|
-
- `Cmd.is_admin()`
|
|
6
|
-
- `Cmd.pause_exit()`
|
|
7
|
-
- `Cmd.cls()`
|
|
8
|
-
- `Cmd.log()`
|
|
9
|
-
- `Cmd.debug()`
|
|
10
|
-
- `Cmd.info()`
|
|
11
|
-
- `Cmd.done()`
|
|
12
|
-
- `Cmd.warn()`
|
|
13
|
-
- `Cmd.fail()`
|
|
14
|
-
- `Cmd.exit()`
|
|
15
|
-
- `Cmd.confirm()`
|
|
16
|
-
- `Cmd.restricted_input()`
|
|
17
|
-
- `Cmd.pwd_input()`\n
|
|
18
|
-
----------------------------------------------------------------------------------------------------------
|
|
19
|
-
You can also use special formatting codes directly inside the log message to change their appearance.<br>
|
|
20
|
-
For more detailed information about formatting codes, see the the `xx_format_codes` description.
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
from ._consts_ import DEFAULT, CHARS
|
|
25
|
-
from .xx_format_codes import *
|
|
26
|
-
from .xx_string import *
|
|
27
|
-
from .xx_color import *
|
|
28
|
-
|
|
29
|
-
from contextlib import suppress
|
|
30
|
-
import subprocess as _subprocess
|
|
31
|
-
import pyperclip as _pyperclip
|
|
32
|
-
import keyboard as _keyboard
|
|
33
|
-
import getpass as _getpass
|
|
34
|
-
import ctypes as _ctypes
|
|
35
|
-
import shutil as _shutil
|
|
36
|
-
import mouse as _mouse
|
|
37
|
-
import sys as _sys
|
|
38
|
-
import os as _os
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class Cmd:
|
|
44
|
-
|
|
45
|
-
@staticmethod
|
|
46
|
-
def get_args(find_args:dict) -> dict:
|
|
47
|
-
args = _sys.argv[1:]
|
|
48
|
-
results = {}
|
|
49
|
-
for arg_key, arg_group in find_args.items():
|
|
50
|
-
value = None
|
|
51
|
-
exists = False
|
|
52
|
-
for arg in arg_group:
|
|
53
|
-
if arg in args:
|
|
54
|
-
exists = True
|
|
55
|
-
arg_index = args.index(arg)
|
|
56
|
-
if arg_index + 1 < len(args) and not args[arg_index + 1].startswith('-'):
|
|
57
|
-
value = String.to_type(args[arg_index + 1])
|
|
58
|
-
break
|
|
59
|
-
results[arg_key] = {'exists': exists, 'value': value}
|
|
60
|
-
return results
|
|
61
|
-
|
|
62
|
-
def w() -> int: return getattr(_shutil.get_terminal_size(), 'columns', 80)
|
|
63
|
-
def h() -> int: return getattr(_shutil.get_terminal_size(), 'lines', 24)
|
|
64
|
-
def wh() -> tuple[int,int]: return Cmd.w(), Cmd.h()
|
|
65
|
-
def user() -> str: return _os.getenv('USER') or _os.getenv('USERNAME') or _getpass.getuser()
|
|
66
|
-
|
|
67
|
-
@staticmethod
|
|
68
|
-
def is_admin() -> bool:
|
|
69
|
-
try:
|
|
70
|
-
if _os.name == 'nt':
|
|
71
|
-
return _ctypes.windll.shell32.IsUserAnAdmin() != 0
|
|
72
|
-
elif _os.name == 'posix':
|
|
73
|
-
return _os.geteuid() == 0
|
|
74
|
-
else:
|
|
75
|
-
return False
|
|
76
|
-
except:
|
|
77
|
-
return False
|
|
78
|
-
|
|
79
|
-
@staticmethod
|
|
80
|
-
def pause_exit(pause:bool = False, exit:bool = False, last_prompt:object = '', exit_code:int = 0, reset_ansi:bool = False) -> None:
|
|
81
|
-
"""Will print the `last_prompt` and then pause the program if `pause` is set<br>
|
|
82
|
-
to `True` and after the pause, exit the program if `exit` is set to `True`."""
|
|
83
|
-
print(last_prompt, end='', flush=True)
|
|
84
|
-
if reset_ansi: FormatCodes.print('[_]', end='')
|
|
85
|
-
if pause: _keyboard.read_event()
|
|
86
|
-
if exit: _sys.exit(exit_code)
|
|
87
|
-
|
|
88
|
-
@staticmethod
|
|
89
|
-
def cls() -> None:
|
|
90
|
-
"""Will clear the console in addition to completely resetting the ANSI formats."""
|
|
91
|
-
if _shutil.which('cls'): _os.system('cls')
|
|
92
|
-
elif _shutil.which('clear'): _os.system('clear')
|
|
93
|
-
print('\033[0m', end='', flush=True)
|
|
94
|
-
|
|
95
|
-
@staticmethod
|
|
96
|
-
def log(title:str, prompt:object, start:str = '', end:str = '\n', title_bg_color:hexa|rgba = None, default_color:hexa|rgba = None) -> None:
|
|
97
|
-
"""Will print a formatted log message:<br>
|
|
98
|
-
`title` -⠀the title of the log message (e.g. `DEBUG`, `WARN`, `FAIL`, etc.)<br>
|
|
99
|
-
`prompt` -⠀the log message<br>
|
|
100
|
-
`start` -⠀something to print before the log is printed<br>
|
|
101
|
-
`end` -⠀something to print after the log is printed (e.g. `\\n\\n`)<br>
|
|
102
|
-
`title_bg_color` -⠀the background color of the `title`<br>
|
|
103
|
-
`default_color` -⠀the default text color of the `prompt`\n
|
|
104
|
-
--------------------------------------------------------------------------------
|
|
105
|
-
The log message supports special formatting codes. For more detailed<br>
|
|
106
|
-
information about formatting codes, see `xx_format_codes` class description."""
|
|
107
|
-
title_color = '_color' if not title_bg_color else Color.text_color_for_on_bg(title_bg_color)
|
|
108
|
-
if title: FormatCodes.print(f'{start} [bold][{title_color}]{f"[BG:{title_bg_color}]" if title_bg_color else ""} {title.upper()}: [_]\t{f"[{default_color}]" if default_color else ""}{str(prompt)}[_]', default_color, end=end)
|
|
109
|
-
else: FormatCodes.print(f'{start} {f"[{default_color}]" if default_color else ""}{str(prompt)}[_]', default_color, end=end)
|
|
110
|
-
|
|
111
|
-
@staticmethod
|
|
112
|
-
def debug(prompt:object = 'Point in program reached.', active:bool = True, start:str = '\n', end:str = '\n\n', title_bg_color:hexa|rgba = DEFAULT.color['yellow'], default_color:hexa|rgba = DEFAULT.text_color, pause:bool = False, exit:bool = False) -> None:
|
|
113
|
-
"""A preset for `log()`: `DEBUG` log message with the options to pause<br>
|
|
114
|
-
at the message and exit the program after the message was printed."""
|
|
115
|
-
if active:
|
|
116
|
-
Cmd.log('DEBUG', prompt, start, end, title_bg_color, default_color)
|
|
117
|
-
Cmd.pause_exit(pause, exit)
|
|
118
|
-
|
|
119
|
-
@staticmethod
|
|
120
|
-
def info(prompt:object = 'Program running.', start:str = '\n', end:str = '\n\n', title_bg_color:hexa|rgba = DEFAULT.color['blue'], default_color:hexa|rgba = DEFAULT.text_color, pause:bool = False, exit:bool = False) -> None:
|
|
121
|
-
"""A preset for `log()`: `INFO` log message with the options to pause<br>
|
|
122
|
-
at the message and exit the program after the message was printed."""
|
|
123
|
-
Cmd.log('INFO', prompt, start, end, title_bg_color, default_color)
|
|
124
|
-
Cmd.pause_exit(pause, exit)
|
|
125
|
-
|
|
126
|
-
@staticmethod
|
|
127
|
-
def done(prompt:object = 'Program finished.', start:str = '\n', end:str = '\n\n', title_bg_color:hexa|rgba = DEFAULT.color['teal'], default_color:hexa|rgba = DEFAULT.text_color, pause:bool = False, exit:bool = False) -> None:
|
|
128
|
-
"""A preset for `log()`: `DONE` log message with the options to pause<br>
|
|
129
|
-
at the message and exit the program after the message was printed."""
|
|
130
|
-
Cmd.log('DONE', prompt, start, end, title_bg_color, default_color)
|
|
131
|
-
Cmd.pause_exit(pause, exit)
|
|
132
|
-
|
|
133
|
-
@staticmethod
|
|
134
|
-
def warn(prompt:object = 'Important message.', start:str = '\n', end:str = '\n\n', title_bg_color:hexa|rgba = DEFAULT.color['orange'], default_color:hexa|rgba = DEFAULT.text_color, pause:bool = False, exit:bool = False) -> None:
|
|
135
|
-
"""A preset for `log()`: `WARN` log message with the options to pause<br>
|
|
136
|
-
at the message and exit the program after the message was printed."""
|
|
137
|
-
Cmd.log('WARN', prompt, start, end, title_bg_color, default_color)
|
|
138
|
-
Cmd.pause_exit(pause, exit)
|
|
139
|
-
|
|
140
|
-
@staticmethod
|
|
141
|
-
def fail(prompt:object = 'Program error.', start:str = '\n', end:str = '\n\n', title_bg_color:hexa|rgba = DEFAULT.color['red'], default_color:hexa|rgba = DEFAULT.text_color, pause:bool = False, exit:bool = True, reset_ansi=True) -> None:
|
|
142
|
-
"""A preset for `log()`: `FAIL` log message with the options to pause<br>
|
|
143
|
-
at the message and exit the program after the message was printed."""
|
|
144
|
-
Cmd.log('FAIL', prompt, start, end, title_bg_color, default_color)
|
|
145
|
-
Cmd.pause_exit(pause, exit, reset_ansi=reset_ansi)
|
|
146
|
-
|
|
147
|
-
@staticmethod
|
|
148
|
-
def exit(prompt:object = 'Program ended.', start:str = '\n', end:str = '\n\n', title_bg_color:hexa|rgba = DEFAULT.color['magenta'], default_color:hexa|rgba = DEFAULT.text_color, pause:bool = False, exit:bool = True, reset_ansi=True) -> None:
|
|
149
|
-
"""A preset for `log()`: `EXIT` log message with the options to pause<br>
|
|
150
|
-
at the message and exit the program after the message was printed."""
|
|
151
|
-
Cmd.log('EXIT', prompt, start, end, title_bg_color, default_color)
|
|
152
|
-
Cmd.pause_exit(pause, exit, reset_ansi=reset_ansi)
|
|
153
|
-
|
|
154
|
-
@staticmethod
|
|
155
|
-
def input(prompt:object = '', default_color:hexa|rgba = DEFAULT.color['cyan']) -> None:
|
|
156
|
-
"""Acts like a standard Python `input()` but the prompt can be formatted with special formatting codes.<br>
|
|
157
|
-
For more detailed information about formatting codes, see the `xx_format_codes` description."""
|
|
158
|
-
return input(FormatCodes.to_ansi(str(prompt), default_color))
|
|
159
|
-
|
|
160
|
-
@staticmethod
|
|
161
|
-
def confirm(prompt:object = 'Do you want to continue?', start = '\n', end = '\n', default_color:hexa|rgba = DEFAULT.color['cyan'], default_is_yes:bool = True) -> None:
|
|
162
|
-
"""Ask a yes/no question.\n
|
|
163
|
-
-----------------------------------------------------------------------------------
|
|
164
|
-
The question can be formatted with special formatting codes. For more detailed<br>
|
|
165
|
-
information about formatting codes, see the `xx_format_codes` description."""
|
|
166
|
-
confirmed = input(FormatCodes.to_ansi(f'{start} {str(prompt)} [_|dim](({"Y" if default_is_yes else "y"}/{"n" if default_is_yes else "N"}): )', default_color)).strip().lower() in (('', 'y', 'yes') if default_is_yes else ('y', 'yes'))
|
|
167
|
-
if end: Cmd.log('', '') if end == '\n' else Cmd.log('', end[1:]) if end.startswith('\n') else Cmd.log('', end)
|
|
168
|
-
return confirmed
|
|
169
|
-
|
|
170
|
-
@staticmethod
|
|
171
|
-
def restricted_input(prompt:object = '', allowed_chars:str = CHARS.all, min_length:int = None, max_length:int = None, mask_char:str = None) -> str|None:
|
|
172
|
-
"""Acts like a standard Python `input()` with the advantage, that you can specify:
|
|
173
|
-
- what text characters the user is allowed to type and
|
|
174
|
-
- the minimum and/or maximum length of the users input
|
|
175
|
-
- optional mask character (hide user input, e.g. for passwords)\n
|
|
176
|
-
-----------------------------------------------------------------------------------
|
|
177
|
-
The input can be formatted with special formatting codes. For more detailed<br>
|
|
178
|
-
information about formatting codes, see the `xx_format_codes` description."""
|
|
179
|
-
print(prompt, end='', flush=True)
|
|
180
|
-
result, select_all, last_line_count, last_console_width = '', False, 1, 0
|
|
181
|
-
def filter_pasted_text(text:str) -> str:
|
|
182
|
-
if allowed_chars == CHARS.all: return text
|
|
183
|
-
return ''.join(char for char in text if char in allowed_chars)
|
|
184
|
-
def update_display(console_width:int) -> None:
|
|
185
|
-
nonlocal select_all, last_line_count, last_console_width
|
|
186
|
-
lines = String.split_every_chars(str(prompt) + (mask_char * len(result) if mask_char else result), console_width)
|
|
187
|
-
line_count = len(lines)
|
|
188
|
-
if (line_count > 1 or line_count < last_line_count) and not last_line_count == 1:
|
|
189
|
-
if last_console_width > console_width: line_count *= 2
|
|
190
|
-
for _ in range(line_count if line_count < last_line_count and not line_count > last_line_count else line_count - 2 if line_count > last_line_count else line_count - 1):
|
|
191
|
-
_sys.stdout.write('\033[2K\r\033[A')
|
|
192
|
-
prompt_len = len(str(prompt)) if prompt else 0
|
|
193
|
-
prompt_str, input_str = lines[0][:prompt_len], lines[0][prompt_len:] if len(lines) == 1 else '\n'.join([lines[0][prompt_len:]] + lines[1:]) # SEPARATE THE PROMPT AND THE INPUT
|
|
194
|
-
_sys.stdout.write('\033[2K\r' + prompt_str + ('\033[7m' if select_all else '') + input_str + '\033[0m')
|
|
195
|
-
last_line_count, last_console_width = line_count, console_width
|
|
196
|
-
while True:
|
|
197
|
-
event = _keyboard.read_event()
|
|
198
|
-
if event.event_type == 'down':
|
|
199
|
-
if event.name == 'enter':
|
|
200
|
-
if min_length is not None and len(result) < min_length:
|
|
201
|
-
continue
|
|
202
|
-
print()
|
|
203
|
-
return result.rstrip('\n')
|
|
204
|
-
elif event.name in ('backspace', 'delete', 'entf'):
|
|
205
|
-
if select_all: result, select_all = '', False
|
|
206
|
-
elif result and event.name == 'backspace':
|
|
207
|
-
result = result[:-1]
|
|
208
|
-
update_display(Cmd.w())
|
|
209
|
-
elif (event.name == 'v' and _keyboard.is_pressed('ctrl')) or _mouse.is_pressed('right'):
|
|
210
|
-
if select_all: result, select_all = '', False
|
|
211
|
-
filtered_text = filter_pasted_text(_pyperclip.paste())
|
|
212
|
-
if max_length is None or len(result) + len(filtered_text) <= max_length:
|
|
213
|
-
result += filtered_text
|
|
214
|
-
update_display(Cmd.w())
|
|
215
|
-
elif event.name == 'a' and _keyboard.is_pressed('ctrl'):
|
|
216
|
-
select_all = True
|
|
217
|
-
update_display(Cmd.w())
|
|
218
|
-
elif event.name == 'c' and _keyboard.is_pressed('ctrl') and select_all:
|
|
219
|
-
with suppress(KeyboardInterrupt): # PREVENT CTRL+C FROM RAISING A `KeyboardInterrupt` EXCEPTION
|
|
220
|
-
select_all = False
|
|
221
|
-
update_display(Cmd.w())
|
|
222
|
-
_pyperclip.copy(result)
|
|
223
|
-
elif event.name == 'esc':
|
|
224
|
-
return
|
|
225
|
-
elif event.name == 'space':
|
|
226
|
-
if (allowed_chars == CHARS.all or ' ' in allowed_chars) and (max_length is None or len(result) < max_length):
|
|
227
|
-
result += ' '
|
|
228
|
-
update_display(Cmd.w())
|
|
229
|
-
elif len(event.name) == 1:
|
|
230
|
-
if (allowed_chars == CHARS.all or event.name in allowed_chars) and (max_length is None or len(result) < max_length):
|
|
231
|
-
result += event.name
|
|
232
|
-
update_display(Cmd.w())
|
|
233
|
-
else: # ANY DISALLOWED OR NON-DEFINED KEY PRESSED
|
|
234
|
-
select_all = False
|
|
235
|
-
update_display(Cmd.w())
|
|
236
|
-
|
|
237
|
-
@staticmethod
|
|
238
|
-
def pwd_input(prompt:object = 'Password: ', allowed_chars:str = CHARS.standard_ascii, min_length:int = None, max_length:int = None) -> str:
|
|
239
|
-
"""Password input that masks the entered characters with asterisks."""
|
|
240
|
-
return Cmd.restricted_input(prompt, allowed_chars, min_length, max_length, mask_char='*')
|
xulbux/xx_env_vars.py
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Functions for modifying and checking the systems environment-variables:
|
|
3
|
-
- `EnvVars.get_paths()`
|
|
4
|
-
- `EnvVars.has_path()`
|
|
5
|
-
- `EnvVars.add_path()`
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
from .xx_data import *
|
|
10
|
-
from .xx_path import *
|
|
11
|
-
|
|
12
|
-
import os as _os
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class EnvVars:
|
|
18
|
-
|
|
19
|
-
@staticmethod
|
|
20
|
-
def get_paths(as_list:bool = False) -> str|list:
|
|
21
|
-
paths = _os.environ.get('PATH')
|
|
22
|
-
return paths.split(_os.pathsep) if as_list else paths
|
|
23
|
-
|
|
24
|
-
@staticmethod
|
|
25
|
-
def has_path(path:str = None, cwd:bool = False, base_dir:bool = False) -> bool:
|
|
26
|
-
if cwd: path = _os.getcwd()
|
|
27
|
-
if base_dir: path = Path.get(base_dir=True)
|
|
28
|
-
paths = EnvVars.get_paths()
|
|
29
|
-
return path in paths
|
|
30
|
-
|
|
31
|
-
@staticmethod
|
|
32
|
-
def __add_sort_paths(add_path:str, current_paths:str) -> str:
|
|
33
|
-
final_paths = Data.remove_empty_items(Data.remove_duplicates(f'{add_path};{current_paths}'.split(_os.pathsep)))
|
|
34
|
-
final_paths.sort()
|
|
35
|
-
return f'{_os.pathsep.join(final_paths)};'
|
|
36
|
-
|
|
37
|
-
@staticmethod
|
|
38
|
-
def add_path(add_path:str = None, cwd:bool = False, base_dir:bool = False, persistent:bool = True) -> None:
|
|
39
|
-
if cwd:
|
|
40
|
-
add_path = _os.getcwd()
|
|
41
|
-
if base_dir:
|
|
42
|
-
add_path = Path.get(base_dir=True)
|
|
43
|
-
if not EnvVars.has_path(add_path):
|
|
44
|
-
final_paths = EnvVars.__add_sort_paths(add_path, EnvVars.get_paths())
|
|
45
|
-
_os.environ['PATH'] = final_paths
|
|
46
|
-
if persistent:
|
|
47
|
-
if _os.name == 'nt': # Windows
|
|
48
|
-
try:
|
|
49
|
-
import winreg
|
|
50
|
-
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Environment', 0, winreg.KEY_ALL_ACCESS)
|
|
51
|
-
winreg.SetValueEx(key, 'PATH', 0, winreg.REG_EXPAND_SZ, final_paths)
|
|
52
|
-
winreg.CloseKey(key)
|
|
53
|
-
except ImportError: raise ImportError('Unable to make persistent changes on Windows.')
|
|
54
|
-
else: # UNIX-LIKE (Linux/macOS)
|
|
55
|
-
shell_rc_file = _os.path.expanduser('~/.bashrc' if _os.path.exists(_os.path.expanduser('~/.bashrc')) else '~/.zshrc')
|
|
56
|
-
with open(shell_rc_file, 'a') as f:
|
|
57
|
-
f.write(f'\n# Added by XulbuX\nexport PATH="$PATH:{add_path}"\n')
|
|
58
|
-
_os.system(f'source {shell_rc_file}')
|
|
59
|
-
else:
|
|
60
|
-
raise ValueError(f'{add_path} is already in PATH.')
|
xulbux-1.5.5.dist-info/RECORD
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
xulbux/__help__.py,sha256=2p_CLFMoEu4Coqs2d3dFuoZ16NQTI6aZkctVjSmq7mE,4098
|
|
2
|
-
xulbux/__init__.py,sha256=8I7GLhkT_P3-KIDDZmAlbIgxmQfoh3ujgv5_aPzQt8g,1644
|
|
3
|
-
xulbux/_consts_.py,sha256=vquutpFVjJsGqRi78EboXbyMczqMdAPZVnAyqcwzJ6k,5313
|
|
4
|
-
xulbux/xx_cmd.py,sha256=9rmnq7YkgfzBoCpcyai0FKZTcBPpMjw3L15-FORUdnI,14070
|
|
5
|
-
xulbux/xx_code.py,sha256=wnQuA0gfxd-Q_sCW-R3Sqw4Ld6u4TQMRAJGzMgTDiqk,5520
|
|
6
|
-
xulbux/xx_color.py,sha256=TqsY5akT9vzHMWJZQ0Ggev5DIzfHaCcq0Tgd-sp15TM,42106
|
|
7
|
-
xulbux/xx_data.py,sha256=U9qzEZFVV_I6CgjbENfz2SuhvIN31Y9t_EtOhccF-6c,26127
|
|
8
|
-
xulbux/xx_env_vars.py,sha256=zN0xFtqukQO9TdR-Ci7sky4s5m2wjQQUfhrhdcNaS1Y,2394
|
|
9
|
-
xulbux/xx_file.py,sha256=CEv5n-ZG_l7HK2ClVQWRiqlERaHhHeGvy0W4rr8OrMI,2513
|
|
10
|
-
xulbux/xx_format_codes.py,sha256=O7DnVnzwa1riiHP9DbRtpMD1LNrOKMT4xpwngt49iPo,12939
|
|
11
|
-
xulbux/xx_json.py,sha256=Z4617tA2VJIdHxQIGCbx99ubLTYj1Dky75C7qiORkWg,4827
|
|
12
|
-
xulbux/xx_path.py,sha256=P_r8WzJygtDCFuQxcEONlkW_exkHxRaqJoUxnPBetyo,4338
|
|
13
|
-
xulbux/xx_regex.py,sha256=s3AsnlMrwblz57BjygV-fjgFn0AguopvZLCKWHVd3ZA,6921
|
|
14
|
-
xulbux/xx_string.py,sha256=gwwY8pTB7d6gJgp8lo8pUftnyJBna0VQ4oFFc_AmOjo,5297
|
|
15
|
-
xulbux/xx_system.py,sha256=2zqqT_oqCPDPzaUBSNMC8awRhSUHQtwIwju9pIQQQQ4,3797
|
|
16
|
-
xulbux-1.5.5.dist-info/METADATA,sha256=PorHfyAoYZ3R8blKx0TAlsqqT9qcZ5auVdlVBJ97L5Y,4162
|
|
17
|
-
xulbux-1.5.5.dist-info/WHEEL,sha256=3U_NnUcV_1B1kPkYaPzN-irRckL5VW_lytn0ytO_kRY,87
|
|
18
|
-
xulbux-1.5.5.dist-info/entry_points.txt,sha256=hfQ1MjdOLVbINRpbJVzNcqRbAouwYF4a-5kzO69zcHE,46
|
|
19
|
-
xulbux-1.5.5.dist-info/licenses/LICENSE,sha256=6NflEcvzFEe8_JFVNCPVwZBwBhlLLd4vqQi8WiX_Xk4,1084
|
|
20
|
-
xulbux-1.5.5.dist-info/RECORD,,
|
|
File without changes
|