abstract-utilities 0.2.2.496__py3-none-any.whl → 0.2.2.504__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.
- abstract_utilities/__init__.py +5 -9
- abstract_utilities/class_utils/__init__.py +7 -0
- abstract_utilities/class_utils/abstract_classes.py +74 -0
- abstract_utilities/class_utils/caller_utils.py +35 -0
- abstract_utilities/class_utils/class_utils.py +109 -0
- abstract_utilities/class_utils/function_utils.py +153 -0
- abstract_utilities/class_utils/global_utils.py +56 -0
- abstract_utilities/class_utils/imports/__init__.py +2 -0
- abstract_utilities/class_utils/imports/imports.py +2 -0
- abstract_utilities/class_utils/imports/utils.py +40 -0
- abstract_utilities/class_utils/module_utils.py +63 -0
- abstract_utilities/env_utils/imports/imports.py +3 -2
- abstract_utilities/error_utils/__init__.py +2 -0
- abstract_utilities/error_utils/error_utils.py +25 -0
- abstract_utilities/error_utils/imports/__init__.py +2 -0
- abstract_utilities/error_utils/imports/imports.py +1 -0
- abstract_utilities/error_utils/imports/module_imports.py +1 -0
- abstract_utilities/file_utils/imports/imports.py +3 -18
- abstract_utilities/file_utils/imports/module_imports.py +3 -6
- abstract_utilities/file_utils/src/type_checks.py +0 -1
- abstract_utilities/hash_utils/__init__.py +2 -0
- abstract_utilities/hash_utils/hash_utils.py +5 -0
- abstract_utilities/hash_utils/imports/__init__.py +2 -0
- abstract_utilities/hash_utils/imports/imports.py +1 -0
- abstract_utilities/hash_utils/imports/module_imports.py +0 -0
- abstract_utilities/history_utils/__init__.py +2 -0
- abstract_utilities/history_utils/history_utils.py +37 -0
- abstract_utilities/history_utils/imports/__init__.py +2 -0
- abstract_utilities/history_utils/imports/imports.py +1 -0
- abstract_utilities/history_utils/imports/module_imports.py +0 -0
- abstract_utilities/import_utils/imports/imports.py +1 -1
- abstract_utilities/import_utils/imports/module_imports.py +1 -1
- abstract_utilities/import_utils/src/__init__.py +1 -1
- abstract_utilities/import_utils/src/clean_imports.py +31 -5
- abstract_utilities/import_utils/src/dot_utils.py +9 -0
- abstract_utilities/import_utils/src/package_utilss/__init__.py +139 -0
- abstract_utilities/import_utils/src/package_utilss/context_utils.py +27 -0
- abstract_utilities/import_utils/src/package_utilss/import_collectors.py +53 -0
- abstract_utilities/import_utils/src/package_utilss/path_utils.py +28 -0
- abstract_utilities/import_utils/src/package_utilss/safe_import.py +27 -0
- abstract_utilities/import_utils/src/pkg_utils.py +140 -0
- abstract_utilities/imports.py +18 -0
- abstract_utilities/json_utils/__init__.py +2 -0
- abstract_utilities/json_utils/imports/__init__.py +2 -0
- abstract_utilities/json_utils/imports/imports.py +2 -0
- abstract_utilities/json_utils/imports/module_imports.py +5 -0
- abstract_utilities/json_utils/json_utils.py +743 -0
- abstract_utilities/list_utils/__init__.py +2 -0
- abstract_utilities/list_utils/imports/__init__.py +2 -0
- abstract_utilities/list_utils/imports/imports.py +1 -0
- abstract_utilities/list_utils/imports/module_imports.py +0 -0
- abstract_utilities/list_utils/list_utils.py +199 -0
- abstract_utilities/log_utils/__init__.py +5 -0
- abstract_utilities/log_utils/abstractLogManager.py +64 -0
- abstract_utilities/log_utils/call_response.py +68 -0
- abstract_utilities/log_utils/imports/__init__.py +2 -0
- abstract_utilities/log_utils/imports/imports.py +7 -0
- abstract_utilities/log_utils/imports/module_imports.py +2 -0
- abstract_utilities/log_utils/log_file.py +56 -0
- abstract_utilities/log_utils/logger_callable.py +49 -0
- abstract_utilities/math_utils/__init__.py +2 -0
- abstract_utilities/math_utils/imports/__init__.py +2 -0
- abstract_utilities/math_utils/imports/imports.py +2 -0
- abstract_utilities/math_utils/imports/module_imports.py +1 -0
- abstract_utilities/math_utils/math_utils.py +208 -0
- abstract_utilities/parse_utils/__init__.py +2 -0
- abstract_utilities/parse_utils/imports/__init__.py +3 -0
- abstract_utilities/parse_utils/imports/constants.py +10 -0
- abstract_utilities/parse_utils/imports/imports.py +2 -0
- abstract_utilities/parse_utils/imports/module_imports.py +4 -0
- abstract_utilities/parse_utils/parse_utils.py +516 -0
- abstract_utilities/path_utils/__init__.py +2 -0
- abstract_utilities/path_utils/imports/__init__.py +2 -0
- abstract_utilities/path_utils/imports/imports.py +1 -0
- abstract_utilities/path_utils/imports/module_imports.py +6 -0
- abstract_utilities/path_utils/path_utils.py +715 -0
- abstract_utilities/path_utils.py +94 -2
- abstract_utilities/read_write_utils/__init__.py +1 -0
- abstract_utilities/read_write_utils/imports/__init__.py +2 -0
- abstract_utilities/read_write_utils/imports/imports.py +2 -0
- abstract_utilities/read_write_utils/imports/module_imports.py +5 -0
- abstract_utilities/read_write_utils/read_write_utils.py +338 -0
- abstract_utilities/read_write_utils.py +2 -4
- abstract_utilities/safe_utils/__init__.py +2 -0
- abstract_utilities/safe_utils/imports/__init__.py +3 -0
- abstract_utilities/safe_utils/imports/imports.py +1 -0
- abstract_utilities/safe_utils/imports/module_imports.py +2 -0
- abstract_utilities/safe_utils/safe_utils.py +130 -0
- abstract_utilities/ssh_utils/__init__.py +2 -1
- abstract_utilities/ssh_utils/classes.py +0 -1
- abstract_utilities/ssh_utils/cmd_utils.py +207 -0
- abstract_utilities/ssh_utils/imports/__init__.py +3 -0
- abstract_utilities/ssh_utils/imports/imports.py +5 -0
- abstract_utilities/ssh_utils/imports/module_imports.py +5 -0
- abstract_utilities/ssh_utils/imports/utils.py +189 -0
- abstract_utilities/ssh_utils/pexpect_utils.py +11 -18
- abstract_utilities/string_utils/__init__.py +4 -0
- abstract_utilities/string_utils/clean_utils.py +28 -0
- abstract_utilities/string_utils/eat_utils.py +103 -0
- abstract_utilities/string_utils/imports/__init__.py +3 -0
- abstract_utilities/string_utils/imports/imports.py +2 -0
- abstract_utilities/string_utils/imports/module_imports.py +2 -0
- abstract_utilities/string_utils/imports/utils.py +81 -0
- abstract_utilities/string_utils/replace_utils.py +27 -0
- abstract_utilities/thread_utils/__init__.py +2 -0
- abstract_utilities/thread_utils/imports/__init__.py +2 -0
- abstract_utilities/thread_utils/imports/imports.py +2 -0
- abstract_utilities/thread_utils/imports/module_imports.py +2 -0
- abstract_utilities/thread_utils/thread_utils.py +140 -0
- abstract_utilities/time_utils/__init__.py +2 -0
- abstract_utilities/time_utils/imports/__init__.py +2 -0
- abstract_utilities/time_utils/imports/imports.py +3 -0
- abstract_utilities/time_utils/imports/module_imports.py +1 -0
- abstract_utilities/time_utils/time_utils.py +392 -0
- abstract_utilities/type_utils/__init__.py +3 -0
- abstract_utilities/type_utils/alpha_utils.py +59 -0
- abstract_utilities/type_utils/imports/__init__.py +2 -0
- abstract_utilities/type_utils/imports/imports.py +4 -0
- abstract_utilities/type_utils/imports/module_imports.py +1 -0
- abstract_utilities/type_utils/num_utils.py +19 -0
- abstract_utilities/type_utils/type_utils.py +981 -0
- {abstract_utilities-0.2.2.496.dist-info → abstract_utilities-0.2.2.504.dist-info}/METADATA +1 -1
- abstract_utilities-0.2.2.504.dist-info/RECORD +229 -0
- abstract_utilities-0.2.2.496.dist-info/RECORD +0 -123
- {abstract_utilities-0.2.2.496.dist-info → abstract_utilities-0.2.2.504.dist-info}/WHEEL +0 -0
- {abstract_utilities-0.2.2.496.dist-info → abstract_utilities-0.2.2.504.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
from .imports import *
|
|
2
|
+
def get_output(p):
|
|
3
|
+
"""
|
|
4
|
+
Get the output of a subprocess command.
|
|
5
|
+
|
|
6
|
+
This function takes a subprocess Popen object as an argument and returns
|
|
7
|
+
the output generated by the command's execution.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
p (subprocess.Popen): A Popen object representing a subprocess command.
|
|
11
|
+
|
|
12
|
+
Returns:
|
|
13
|
+
tuple: A tuple containing the standard output and standard error streams
|
|
14
|
+
of the executed command.
|
|
15
|
+
"""
|
|
16
|
+
return p.communicate()
|
|
17
|
+
|
|
18
|
+
def get_cmd_out(st):
|
|
19
|
+
"""
|
|
20
|
+
Get the output of a shell command.
|
|
21
|
+
|
|
22
|
+
This function executes a shell command using the 'cmd_input' function and
|
|
23
|
+
retrieves the output generated by the command's execution.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
st (str): The shell command to execute.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
tuple: A tuple containing the standard output and standard error streams
|
|
30
|
+
of the executed shell command.
|
|
31
|
+
"""
|
|
32
|
+
return get_output(cmd_input(st))
|
|
33
|
+
def cmd_input(st):
|
|
34
|
+
"""
|
|
35
|
+
Execute a shell command using subprocess.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
- st (str): Command to be executed.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
- subprocess.Popen: A Popen object for communication.
|
|
42
|
+
"""
|
|
43
|
+
return subprocess.Popen(st, stdout=subprocess.PIPE, shell=True)
|
|
44
|
+
def get_output_text(parent_dir: str = os.getcwd()) -> str:
|
|
45
|
+
"""
|
|
46
|
+
Get the path to the 'output.txt' file in the given directory.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
parent_dir (str, optional): Directory path. Defaults to the current working directory.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
str: Path to the 'output.txt' file.
|
|
53
|
+
"""
|
|
54
|
+
return os.path.join(parent_dir,'output.txt')
|
|
55
|
+
def get_env_value(key: str = None, env_path: str = None) -> str:
|
|
56
|
+
"""
|
|
57
|
+
Retrieve environment value based on a key from a specified .env file.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
key (str, optional): Environment key to search for. Defaults to None.
|
|
61
|
+
env_path (str, optional): Path to start searching for the .env file. Defaults to None.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
str: Value corresponding to the given environment key.
|
|
65
|
+
"""
|
|
66
|
+
args={}
|
|
67
|
+
if key != None:
|
|
68
|
+
args["key"]=key
|
|
69
|
+
if env_path != None:
|
|
70
|
+
args["start_path"]=env_path
|
|
71
|
+
return find_and_read_env_file(**args)
|
|
72
|
+
def print_cmd(input: str, output: str) -> None:
|
|
73
|
+
"""
|
|
74
|
+
Print the input command and its corresponding output.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
input (str): The command that was run.
|
|
78
|
+
output (str): Output produced by the command.
|
|
79
|
+
"""
|
|
80
|
+
print(f"Command Line Arguments: {input}")
|
|
81
|
+
print(f"Output:\n{output}")
|
|
82
|
+
def get_sudo_password(key: str = "SUDO_PASSWORD") -> str:
|
|
83
|
+
"""
|
|
84
|
+
Retrieve the sudo password from an environment file.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
key (str, optional): Environment key for the sudo password. Defaults to "SUDO_PASSWORD".
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
str: The sudo password.
|
|
91
|
+
"""
|
|
92
|
+
return find_and_read_env_file(key=key)
|
|
93
|
+
def cmd_run_sudo(cmd: str, password: str = None, key: str = None, output_text: str = None) -> None:
|
|
94
|
+
"""
|
|
95
|
+
Execute a command with sudo privileges using either provided password or retrieving it from an environment file.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
cmd (str): Command to be executed.
|
|
99
|
+
password (str, optional): Password for sudo. Defaults to None.
|
|
100
|
+
key (str, optional): Environment key to retrieve sudo password. Defaults to None.
|
|
101
|
+
output_text (str, optional): Path to store the command output. Defaults to None.
|
|
102
|
+
"""
|
|
103
|
+
if password !=None:
|
|
104
|
+
cmd_run(f'echo "{password}" | sudo -S -k {cmd}',output_text)
|
|
105
|
+
elif key != None:
|
|
106
|
+
cmd_run(f'echo "{get_env_value(key)}" | sudo -S -k {cmd}',output_text)
|
|
107
|
+
else:
|
|
108
|
+
cmd_run(f'echo "{get_sudo_password()}" | sudo -S -k {cmd}',output_text)
|
|
109
|
+
def cmd_run(cmd: str, output_text: str = None, print_output: bool = False) -> None:
|
|
110
|
+
if output_text is None:
|
|
111
|
+
output_text = get_output_text()
|
|
112
|
+
|
|
113
|
+
# Clear output file
|
|
114
|
+
with open(output_text, 'w') as f:
|
|
115
|
+
pass
|
|
116
|
+
|
|
117
|
+
# Append output redirection
|
|
118
|
+
full_cmd = f'{cmd} >> {output_text}; echo END_OF_CMD >> {output_text}'
|
|
119
|
+
|
|
120
|
+
if print_output:
|
|
121
|
+
print(full_cmd)
|
|
122
|
+
|
|
123
|
+
subprocess.call(full_cmd, shell=True)
|
|
124
|
+
|
|
125
|
+
# Wait until END_OF_CMD appears
|
|
126
|
+
while True:
|
|
127
|
+
get_sleep(sleep_timer=0.5)
|
|
128
|
+
with open(output_text, 'r') as f:
|
|
129
|
+
lines = f.readlines()
|
|
130
|
+
if lines and lines[-1].strip() == 'END_OF_CMD':
|
|
131
|
+
break
|
|
132
|
+
|
|
133
|
+
if print_output:
|
|
134
|
+
with open(output_text, 'r') as f:
|
|
135
|
+
print_cmd(full_cmd, f.read().strip())
|
|
136
|
+
|
|
137
|
+
os.remove(output_text)
|
|
138
|
+
|
|
139
|
+
def pexpect_cmd_with_args(command: str, child_runs: list, output_text: str = os.getcwd(),print_output:bool=False) -> int:
|
|
140
|
+
"""
|
|
141
|
+
Run a command using pexpect and handle its prompts with specified responses.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
command (str): Command to be executed.
|
|
145
|
+
child_runs (list): List of prompts and their respective responses.
|
|
146
|
+
output_text (str, optional): Path to store the command output. Defaults to the current working directory.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
int: Exit status of the command.
|
|
150
|
+
"""
|
|
151
|
+
child = pexpect.spawn(command)
|
|
152
|
+
|
|
153
|
+
for each in child_runs:
|
|
154
|
+
# Wait for the process to prompt for the input and respond with it
|
|
155
|
+
child.expect(each["prompt"])
|
|
156
|
+
|
|
157
|
+
# Respond with the corresponding input
|
|
158
|
+
if each["pass"] is not None:
|
|
159
|
+
pass_phrase = each["pass"]
|
|
160
|
+
else:
|
|
161
|
+
args = {}
|
|
162
|
+
if "key" in each:
|
|
163
|
+
if each["key"] is not None:
|
|
164
|
+
args["key"] = each["key"]
|
|
165
|
+
if "env_path" in each:
|
|
166
|
+
if each["env_path"] is not None:
|
|
167
|
+
args["start_path"] = each["env_path"]
|
|
168
|
+
|
|
169
|
+
pass_phrase = get_env_value(**args)
|
|
170
|
+
|
|
171
|
+
child.sendline(pass_phrase)
|
|
172
|
+
if print_output:
|
|
173
|
+
print("Output after handling prompt:")
|
|
174
|
+
print(each["prompt"])
|
|
175
|
+
|
|
176
|
+
# Wait for the process to finish
|
|
177
|
+
child.expect(pexpect.EOF)
|
|
178
|
+
output = child.before.decode("utf-8")
|
|
179
|
+
|
|
180
|
+
# Write output to the output file
|
|
181
|
+
with open(get_output_text(), "w") as f:
|
|
182
|
+
f.write(output)
|
|
183
|
+
if print_output:
|
|
184
|
+
print_cmd(command, output)
|
|
185
|
+
|
|
186
|
+
return child.exitstatus
|
|
187
|
+
def get_user_pass_host_key(**kwargs):
|
|
188
|
+
args = ['password','user_at_host','host','key','user']
|
|
189
|
+
kwargs['del_kwarg']=kwargs.get('del_kwarg',False)
|
|
190
|
+
values,kwargs = get_from_kwargs(*args,**kwargs)
|
|
191
|
+
return values
|
|
192
|
+
|
|
193
|
+
# --- Base remote checker -----------------------------------------------------
|
|
194
|
+
def _remote_test(path: str, test_flag: str, timeout: int = 5,*args, **kwargs) -> bool:
|
|
195
|
+
"""
|
|
196
|
+
Run a remote shell test (e.g. -f, -d) via SSH.
|
|
197
|
+
Returns True if test succeeds, False otherwise.
|
|
198
|
+
"""
|
|
199
|
+
try:
|
|
200
|
+
kwargs['cmd']=f"[ {test_flag} {shlex.quote(path)} ] && echo 1 || echo 0"
|
|
201
|
+
kwargs['text']=True
|
|
202
|
+
kwargs['timeout']=timeout
|
|
203
|
+
kwargs['stderr']=subprocess.DEVNULL
|
|
204
|
+
result = run_pruned_func(run_cmd,**kwargs)
|
|
205
|
+
return result.strip() == "1"
|
|
206
|
+
except Exception:
|
|
207
|
+
return False
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
from .imports import *
|
|
2
|
+
from .module_imports import *
|
|
3
|
+
def get_pass_from_key(key=None,env_path=None):
|
|
4
|
+
if key:
|
|
5
|
+
return get_env_value(key=key,path=env_path)
|
|
6
|
+
def get_password(password=None,key=None,env_path=None):
|
|
7
|
+
password = password or get_pass_from_key(key=key,env_path=env_path)
|
|
8
|
+
return password
|
|
9
|
+
|
|
10
|
+
def get_print_sudo_cmd(
|
|
11
|
+
cmd: str,
|
|
12
|
+
password=None,
|
|
13
|
+
key=None,
|
|
14
|
+
env_path=None
|
|
15
|
+
):
|
|
16
|
+
password = get_password(password=password,key=key,env_path=env_path)
|
|
17
|
+
if password != None:
|
|
18
|
+
|
|
19
|
+
cmd = get_password_cmd(password=password,cmd=cmd)
|
|
20
|
+
return cmd
|
|
21
|
+
def get_password_cmd(password:str,cmd:str):
|
|
22
|
+
sudo_cmd = get_sudo_cmd(cmd)
|
|
23
|
+
password_sudo_cmd = get_raw_password_sudo_cmd(password=password,sudo_cmd=sudo_cmd)
|
|
24
|
+
return password_sudo_cmd
|
|
25
|
+
def get_sudo_cmd(cmd: str):
|
|
26
|
+
return f"sudo -S -k {cmd}"
|
|
27
|
+
def get_raw_password_sudo_cmd(password:str,sudo_cmd:str):
|
|
28
|
+
return f"printf %s {shlex.quote(password)} | {sudo_cmd}"
|
|
29
|
+
def get_remote_bash(
|
|
30
|
+
cmd: str,
|
|
31
|
+
cwd: str | None = None
|
|
32
|
+
):
|
|
33
|
+
return f"bash -lc {shlex.quote((f'cd {shlex.quote(cwd)} && {cmd}') if cwd else cmd)}"
|
|
34
|
+
def get_remote_ssh(
|
|
35
|
+
user_at_host: str=None,
|
|
36
|
+
remote:str=None
|
|
37
|
+
):
|
|
38
|
+
return f"ssh {shlex.quote(user_at_host)} {shlex.quote(remote)}"
|
|
39
|
+
def get_remote_cmd(
|
|
40
|
+
cmd: str,
|
|
41
|
+
user_at_host: str,
|
|
42
|
+
cwd: str | None = None,
|
|
43
|
+
password=None,
|
|
44
|
+
key=None,
|
|
45
|
+
env_path=None
|
|
46
|
+
|
|
47
|
+
):
|
|
48
|
+
cmd = get_print_sudo_cmd(
|
|
49
|
+
cmd=cmd,
|
|
50
|
+
password=password,
|
|
51
|
+
key=key,
|
|
52
|
+
env_path=env_path
|
|
53
|
+
)
|
|
54
|
+
remote = get_remote_bash(
|
|
55
|
+
cmd=cmd,
|
|
56
|
+
cwd=cwd
|
|
57
|
+
)
|
|
58
|
+
full = get_remote_ssh(
|
|
59
|
+
user_at_host=user_at_host,
|
|
60
|
+
remote=remote
|
|
61
|
+
)
|
|
62
|
+
return full
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def execute_cmd(
|
|
66
|
+
*args,
|
|
67
|
+
outfile=None,
|
|
68
|
+
**kwargs
|
|
69
|
+
) -> str:
|
|
70
|
+
proc = subprocess.run(*args, **kwargs)
|
|
71
|
+
output = (proc.stdout or "") + (proc.stderr or "")
|
|
72
|
+
if outfile:
|
|
73
|
+
try:
|
|
74
|
+
with open(outfile, "w", encoding="utf-8", errors="ignore") as f:
|
|
75
|
+
f.write(output)
|
|
76
|
+
except Exception:
|
|
77
|
+
pass
|
|
78
|
+
return output
|
|
79
|
+
|
|
80
|
+
def run_local_cmd(
|
|
81
|
+
cmd: str,
|
|
82
|
+
cwd: str | None = None,
|
|
83
|
+
outfile: Optional[str] = None,
|
|
84
|
+
shell=True,
|
|
85
|
+
text=True,
|
|
86
|
+
capture_output=True,
|
|
87
|
+
user_at_host: str=None,
|
|
88
|
+
password=None,
|
|
89
|
+
key=None,
|
|
90
|
+
env_path=None
|
|
91
|
+
) -> str:
|
|
92
|
+
cmd = get_print_sudo_cmd(
|
|
93
|
+
cmd=cmd,
|
|
94
|
+
password=password,
|
|
95
|
+
key=key,
|
|
96
|
+
env_path=env_path
|
|
97
|
+
)
|
|
98
|
+
return execute_cmd(
|
|
99
|
+
cmd,
|
|
100
|
+
outfile=outfile,
|
|
101
|
+
shell=shell,
|
|
102
|
+
cwd=cwd,
|
|
103
|
+
text=text,
|
|
104
|
+
capture_output=capture_output
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
def run_remote_cmd(
|
|
108
|
+
user_at_host: str,
|
|
109
|
+
cmd: str,
|
|
110
|
+
cwd: str | None = None,
|
|
111
|
+
outfile: Optional[str] = None,
|
|
112
|
+
shell=True,
|
|
113
|
+
text=True,
|
|
114
|
+
capture_output=True,
|
|
115
|
+
password=None,
|
|
116
|
+
key=None,
|
|
117
|
+
env_path=None
|
|
118
|
+
) -> str:
|
|
119
|
+
"""
|
|
120
|
+
Run on remote via SSH; capture stdout+stderr locally; write to local outfile.
|
|
121
|
+
NOTE: we do *not* try to write the file on the remote to avoid later scp.
|
|
122
|
+
"""
|
|
123
|
+
cmd = get_print_sudo_cmd(
|
|
124
|
+
cmd=cmd,
|
|
125
|
+
password=password,
|
|
126
|
+
key=key,
|
|
127
|
+
env_path=env_path
|
|
128
|
+
)
|
|
129
|
+
# wrap in bash -lc for PATH/profile + allow 'cd && ...'
|
|
130
|
+
cmd = get_remote_cmd(
|
|
131
|
+
cmd=cmd,
|
|
132
|
+
user_at_host=user_at_host,
|
|
133
|
+
cwd=cwd
|
|
134
|
+
)
|
|
135
|
+
return execute_cmd(
|
|
136
|
+
cmd,
|
|
137
|
+
outfile=outfile,
|
|
138
|
+
shell=shell,
|
|
139
|
+
text=text,
|
|
140
|
+
capture_output=capture_output
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
def run_cmd(
|
|
144
|
+
cmd: str=None,
|
|
145
|
+
cwd: str | None = None,
|
|
146
|
+
outfile: Optional[str] = None,
|
|
147
|
+
shell=True,
|
|
148
|
+
text=True,
|
|
149
|
+
capture_output=True,
|
|
150
|
+
user_at_host: str=None,
|
|
151
|
+
password=None,
|
|
152
|
+
key=None,
|
|
153
|
+
env_path=None
|
|
154
|
+
) -> str:
|
|
155
|
+
|
|
156
|
+
if user_at_host:
|
|
157
|
+
return run_ssh_cmd(
|
|
158
|
+
user_at_host=user_at_host,
|
|
159
|
+
cmd=cmd,
|
|
160
|
+
cwd=cwd,
|
|
161
|
+
outfile=outfile,
|
|
162
|
+
shell=shell,
|
|
163
|
+
text=text,
|
|
164
|
+
capture_output=capture_output,
|
|
165
|
+
password=password,
|
|
166
|
+
key=key,
|
|
167
|
+
env_path=env_path
|
|
168
|
+
)
|
|
169
|
+
return run_local_cmd(
|
|
170
|
+
cmd=cmd,
|
|
171
|
+
cwd=cwd,
|
|
172
|
+
outfile=outfile,
|
|
173
|
+
shell=shell,
|
|
174
|
+
text=text,
|
|
175
|
+
capture_output=capture_output,
|
|
176
|
+
password=password,
|
|
177
|
+
key=key,
|
|
178
|
+
env_path=env_path
|
|
179
|
+
)
|
|
180
|
+
run_ssh_cmd = run_remote_cmd
|
|
181
|
+
remote_cmd = run_remote_cmd
|
|
182
|
+
ssh_cmd = run_remote_cmd
|
|
183
|
+
|
|
184
|
+
local_cmd = run_local_cmd
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
run_any_cmd = run_cmd
|
|
188
|
+
any_cmd = run_cmd
|
|
189
|
+
cmd_run = run_cmd
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
from .
|
|
2
|
-
from .utils import *
|
|
3
|
-
from ..env_utils import *
|
|
1
|
+
from .imports import *
|
|
4
2
|
# pexpect is optional; import lazily if you prefer
|
|
5
3
|
|
|
6
4
|
# keep your execute_cmd; add a thin wrapper that supports stdin text cleanly
|
|
@@ -36,17 +34,17 @@ def exec_sudo_capture(
|
|
|
36
34
|
"""
|
|
37
35
|
if password is None:
|
|
38
36
|
password = get_env_value(key=key) if key else get_sudo_password()
|
|
39
|
-
|
|
37
|
+
|
|
40
38
|
sudo_cmd = f"sudo -S -k {cmd}"
|
|
41
39
|
|
|
42
40
|
if user_at_host:
|
|
43
41
|
# build the remote command (bash -lc + optional cd)
|
|
44
42
|
remote = get_remote_cmd(cmd=sudo_cmd, user_at_host=user_at_host, cwd=cwd)
|
|
45
43
|
# feed password to remote's stdin (ssh forwards stdin)
|
|
46
|
-
out = execute_cmd_input(remote, input_text=password,
|
|
44
|
+
out = execute_cmd_input(remote, input_text=password + "\n",
|
|
47
45
|
shell=True, text=True, capture_output=True)
|
|
48
46
|
else:
|
|
49
|
-
out = execute_cmd_input(sudo_cmd, input_text=password,
|
|
47
|
+
out = execute_cmd_input(sudo_cmd, input_text=password + "\n",
|
|
50
48
|
shell=True, text=True, capture_output=True, cwd=cwd)
|
|
51
49
|
|
|
52
50
|
if print_output:
|
|
@@ -123,8 +121,8 @@ def cmd_run(
|
|
|
123
121
|
out = execute_cmd(remote, shell=True, text=True, capture_output=True)
|
|
124
122
|
else:
|
|
125
123
|
out = execute_cmd(cmd, shell=True, text=True, capture_output=True, cwd=cwd)
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
if print_output:
|
|
125
|
+
print_cmd(cmd, out or "")
|
|
128
126
|
return out or ""
|
|
129
127
|
|
|
130
128
|
# ---- legacy file-backed path (unchanged in spirit) ----
|
|
@@ -150,10 +148,9 @@ def cmd_run(
|
|
|
150
148
|
if lines and lines[-1].strip() == 'END_OF_CMD':
|
|
151
149
|
break
|
|
152
150
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
## print_cmd(full_cmd, f.read().strip())
|
|
151
|
+
if print_output:
|
|
152
|
+
with open(output_text, 'r') as f:
|
|
153
|
+
print_cmd(full_cmd, f.read().strip())
|
|
157
154
|
|
|
158
155
|
try:
|
|
159
156
|
os.remove(output_text)
|
|
@@ -212,8 +209,8 @@ def exec_expect(
|
|
|
212
209
|
|
|
213
210
|
child.expect(pexpect.EOF)
|
|
214
211
|
out = child.before.decode("utf-8", errors="ignore")
|
|
215
|
-
|
|
216
|
-
|
|
212
|
+
if print_output:
|
|
213
|
+
print_cmd(command, out)
|
|
217
214
|
|
|
218
215
|
return child.exitstatus if child.exitstatus is not None else 0
|
|
219
216
|
|
|
@@ -261,7 +258,6 @@ def cmd_run_sudo(
|
|
|
261
258
|
remote_sudo_line = f'printf %s {shlex.quote(pw)} | {sudo_cmd}'
|
|
262
259
|
remote_full = get_remote_cmd(cmd=remote_sudo_line, user_at_host=user_at_host, cwd=cwd)
|
|
263
260
|
return cmd_run(remote_full, output_text=output_text, print_output=print_output)
|
|
264
|
-
|
|
265
261
|
def pexpect_cmd_with_args(
|
|
266
262
|
command: str,
|
|
267
263
|
child_runs: list,
|
|
@@ -310,6 +306,3 @@ def pexpect_cmd_with_args(
|
|
|
310
306
|
else:
|
|
311
307
|
if print_output:
|
|
312
308
|
print_cmd(command, out)
|
|
313
|
-
|
|
314
|
-
return child.exitstatus if child.exitstatus is not None else 0
|
|
315
|
-
cmd_input = execute_cmd_input
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from .eat_utils import eatAll
|
|
2
|
+
def clean_spaces(obj: str) -> str:
|
|
3
|
+
"""
|
|
4
|
+
Removes leading spaces and tabs from a string.
|
|
5
|
+
|
|
6
|
+
Args:
|
|
7
|
+
obj (str): The input string.
|
|
8
|
+
|
|
9
|
+
Returns:
|
|
10
|
+
str: The string with leading spaces and tabs removed.
|
|
11
|
+
"""
|
|
12
|
+
if len(obj) == 0:
|
|
13
|
+
return obj
|
|
14
|
+
while obj[0] in [' ', '\t']:
|
|
15
|
+
obj = obj[1:]
|
|
16
|
+
return obj
|
|
17
|
+
def clean_line(line):
|
|
18
|
+
return eatAll(line,[' ','','\t','\n'])
|
|
19
|
+
def url_join(*paths):
|
|
20
|
+
final_url = os.path.join(*paths)
|
|
21
|
+
for i,path in enumerate(paths):
|
|
22
|
+
if i == 0:
|
|
23
|
+
final_path = path # Note: Fixed bug; original code had `final_path = paths`
|
|
24
|
+
else:
|
|
25
|
+
final_path = eatOuter(final_path, '/')
|
|
26
|
+
path = eatInner(path, '/')
|
|
27
|
+
final_path = f"{final_path}/{path}"
|
|
28
|
+
return final_path
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from .imports import *
|
|
2
|
+
def eatInner(string: str, list_objects:(str or list)) -> any:
|
|
3
|
+
"""
|
|
4
|
+
Removes characters from the inner part of a string or list.
|
|
5
|
+
|
|
6
|
+
Args:
|
|
7
|
+
x (str or list): The input string or list.
|
|
8
|
+
ls (list): The list of characters to remove.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
any: The modified string or list.
|
|
12
|
+
"""
|
|
13
|
+
if not isinstance(list_objects,list):
|
|
14
|
+
list_objects = [list_objects]
|
|
15
|
+
if not isinstance(string,str):
|
|
16
|
+
string = str(string)
|
|
17
|
+
if string and list_objects:
|
|
18
|
+
for char in string:
|
|
19
|
+
if string:
|
|
20
|
+
if char not in list_objects:
|
|
21
|
+
return string
|
|
22
|
+
string = string[1:]
|
|
23
|
+
return string
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def eatOuter(string: str, list_objects:(str or list)) -> any:
|
|
27
|
+
"""
|
|
28
|
+
Removes characters from the outer part of a string or list.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
x (str or list): The input string or list.
|
|
32
|
+
ls (list): The list of characters to remove.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
any: The modified string or list.
|
|
36
|
+
"""
|
|
37
|
+
if not isinstance(list_objects,list):
|
|
38
|
+
list_objects = [list_objects]
|
|
39
|
+
if not isinstance(string,str):
|
|
40
|
+
string = str(string)
|
|
41
|
+
if string and list_objects:
|
|
42
|
+
for i in range(len(string)):
|
|
43
|
+
if string:
|
|
44
|
+
if string[-1] not in list_objects:
|
|
45
|
+
return string
|
|
46
|
+
string = string[:-1]
|
|
47
|
+
return string
|
|
48
|
+
def eatAll(string: str, list_objects:(str or list)) -> any:
|
|
49
|
+
"""
|
|
50
|
+
Removes characters from both the inner and outer parts of a string or list.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
x (str or list): The input string or list.
|
|
54
|
+
ls (list): The list of characters to remove.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
any: The modified string or list.
|
|
58
|
+
"""
|
|
59
|
+
if not isinstance(list_objects,list):
|
|
60
|
+
list_objects = [list_objects]
|
|
61
|
+
if not isinstance(string,str):
|
|
62
|
+
string = str(string)
|
|
63
|
+
if string and list_objects:
|
|
64
|
+
string = eatInner(string, list_objects)
|
|
65
|
+
if string and list_objects:
|
|
66
|
+
string = eatOuter(string, list_objects)
|
|
67
|
+
return string
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def eatElse(
|
|
72
|
+
stringObj,
|
|
73
|
+
chars=None,
|
|
74
|
+
ints=True,
|
|
75
|
+
alpha=True,
|
|
76
|
+
lower=True,
|
|
77
|
+
capitalize=True,
|
|
78
|
+
string=True,
|
|
79
|
+
listObj=True
|
|
80
|
+
):
|
|
81
|
+
alpha_ints = get_alpha_ints(
|
|
82
|
+
ints=True,
|
|
83
|
+
alpha=True,
|
|
84
|
+
lower=True,
|
|
85
|
+
capitalize=True,
|
|
86
|
+
string=True,
|
|
87
|
+
listObj=True
|
|
88
|
+
)
|
|
89
|
+
chars = make_list(chars or [])+alpha_ints
|
|
90
|
+
|
|
91
|
+
while True:
|
|
92
|
+
if stringObj:
|
|
93
|
+
str_0 = stringObj[0] not in chars
|
|
94
|
+
str_1 = stringObj[-1] not in chars
|
|
95
|
+
str_eat = str_0 or str_1
|
|
96
|
+
if not str_eat:
|
|
97
|
+
return stringObj
|
|
98
|
+
if stringObj and str_0:
|
|
99
|
+
stringObj = stringObj[1:] if len(stringObj) !=1 else ""
|
|
100
|
+
if stringObj and str_1:
|
|
101
|
+
stringObj = stringObj[:-1] if len(stringObj) !=1 else ""
|
|
102
|
+
else:
|
|
103
|
+
return stringObj
|