abstract-utilities 0.2.2.476__py3-none-any.whl → 0.2.2.486__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 abstract-utilities might be problematic. Click here for more details.

@@ -6,7 +6,8 @@ from ....ssh_utils import *
6
6
  from ....env_utils import *
7
7
  from ....read_write_utils import *
8
8
  from ....abstract_classes import SingletonMeta
9
-
9
+ from ....string_utils import get_from_kwargs
10
+ from ....abstract_classes import run_pruned_func
10
11
  from ....class_utils import get_caller, get_caller_path, get_caller_dir
11
12
 
12
13
 
@@ -1,34 +1,36 @@
1
1
  from .imports import *
2
2
 
3
+ def get_user_pass_host_key(**kwargs):
4
+ args = ['password','user_at_host','host','key','user']
5
+ values,kwargs = get_from_kwargs(*args,**kwargs,del_kwarg=False)
6
+ return values
3
7
 
4
8
  # --- Base remote checker -----------------------------------------------------
5
- def _remote_test(path: str, test_flag: str, user_at_host: str, timeout: int = 5) -> bool:
9
+ def _remote_test(path: str, test_flag: str, timeout: int = 5,*args, **kwargs) -> bool:
6
10
  """
7
11
  Run a remote shell test (e.g. -f, -d) via SSH.
8
12
  Returns True if test succeeds, False otherwise.
9
13
  """
10
- cmd = f"[ {test_flag} {shlex.quote(path)} ] && echo 1 || echo 0"
11
14
  try:
12
- result = subprocess.check_output(
13
- ["ssh", user_at_host, cmd],
14
- stderr=subprocess.DEVNULL,
15
- text=True,
16
- timeout=timeout
17
- ).strip()
18
- return result == "1"
15
+ kwargs['cmd']=f"[ {test_flag} {shlex.quote(path)} ] && echo 1 || echo 0"
16
+ kwargs['text']=True
17
+ kwargs['timeout']=timeout
18
+ kwargs['stderr']=subprocess.DEVNULL
19
+ result = run_pruned_func(run_cmd,**kwargs)
20
+ return result.strip() == "1"
19
21
  except Exception:
20
22
  return False
21
23
 
22
24
 
23
25
  # --- Individual path checks --------------------------------------------------
24
- def is_remote_file(path: str, user_at_host: str) -> bool:
26
+ def is_remote_file(path: str,*args, **kwargs) -> bool:
25
27
  """True if remote path is a file."""
26
- return _remote_test(path, "-f", user_at_host)
28
+ return _remote_test(path, "-f", **kwargs)
27
29
 
28
30
 
29
- def is_remote_dir(path: str, user_at_host: str) -> bool:
31
+ def is_remote_dir(path: str,*args, **kwargs) -> bool:
30
32
  """True if remote path is a directory."""
31
- return _remote_test(path, "-d", user_at_host)
33
+ return _remote_test(path, "-d", **kwargs)
32
34
 
33
35
 
34
36
  def is_local_file(path: str) -> bool:
@@ -42,33 +44,40 @@ def is_local_dir(path: str) -> bool:
42
44
 
43
45
 
44
46
  # --- Unified interface -------------------------------------------------------
45
- def is_file(path: str,*args, user_at_host: Optional[str] = None,**kwargs) -> bool:
47
+
48
+ def is_file(path: str,*args,**kwargs) -> bool:
46
49
  """Determine if path is a file (works local or remote)."""
47
- if user_at_host:
48
- return is_remote_file(path, user_at_host)
50
+ if get_user_pass_host_key(**kwargs):
51
+ return is_remote_file(path, **kwargs)
49
52
  return is_local_file(path)
50
53
 
51
54
 
52
- def is_dir(path: str, *args,user_at_host: Optional[str] = None,**kwargs) -> bool:
55
+ def is_dir(path: str, *args,**kwargs) -> bool:
53
56
  """Determine if path is a directory (works local or remote)."""
54
- if user_at_host:
55
- return is_remote_dir(path, user_at_host)
57
+ if get_user_pass_host_key(**kwargs):
58
+ return is_remote_dir(path, **kwargs)
56
59
  return is_local_dir(path)
57
60
 
58
-
61
+ def is_exists(path: str, *args,**kwargs) -> bool:
62
+ if is_file(path,**kwargs):
63
+ return True
64
+ if is_dir(path,**kwargs):
65
+ return True
66
+ return False
59
67
  # --- Optional: keep your original all-in-one wrapper ------------------------
60
68
  def check_path_type(
61
69
  path: str,
62
- user_at_host: Optional[str] = None,
70
+ *args,
71
+ **kwargs
63
72
  ) -> str:
64
73
  """
65
74
  Return 'file', 'directory', 'missing', or 'unknown'.
66
75
  Uses isolated is_file/is_dir functions.
67
76
  """
68
- if user_at_host:
69
- if is_remote_file(path, user_at_host):
77
+ if get_user_pass_host_key(**kwargs):
78
+ if is_remote_file(path,**kwargs):
70
79
  return "file"
71
- elif is_remote_dir(path, user_at_host):
80
+ elif is_remote_dir(path,**kwargs):
72
81
  return "directory"
73
82
  else:
74
83
  return "missing"
@@ -15,12 +15,12 @@ Usage:
15
15
  import os
16
16
  import shlex
17
17
  from .ssh_utils.utils import run_cmd,get_print_sudo_cmd,run_local_cmd,run_remote_cmd
18
- from .file_utils.file_utils.type_checks import is_file,is_dir
18
+ from .file_utils.file_utils.type_checks import is_file,is_dir,get_user_pass_host_key,is_exists
19
19
  from .abstract_classes import run_pruned_func
20
20
  _FILE_PATH_KEYS = ['file', 'filepath', 'file_path', 'path', 'directory', 'f', 'dst', 'dest']
21
21
  _CONTENTS_KEYS = ['cont', 'content', 'contents', 'data', 'datas', 'dat', 'src', 'source']
22
22
 
23
-
23
+
24
24
  # --- Helper utilities --------------------------------------------------------
25
25
  def string_in_keys(strings, kwargs):
26
26
  """Find a matching keyword in kwargs that contains any of the given substrings."""
@@ -30,25 +30,60 @@ def string_in_keys(strings, kwargs):
30
30
  return key
31
31
  return None
32
32
 
33
-
34
- def get_path(paths):
33
+ def make_dirs(path,exist_ok=True,**kwargs):
34
+ if exist_ok or (not exist_ok and not is_dir(path,**kwargs)):
35
+ if get_user_pass_host_key(**kwargs):
36
+ kwargs['cmd']=f"mkdir {path}"
37
+ run_pruned_func(run_cmd,**kwargs)
38
+ else:
39
+ os.makedirs(path,exist_ok=exist_ok)
40
+ return path
41
+ def path_join(*args):
42
+ path = None
43
+ for i,arg in enumerate(args):
44
+ if arg:
45
+ if i == 0:
46
+ path = arg
47
+ else:
48
+ path = os.path.join(path,arg)
49
+ return path
50
+ def make_path(path,home_dir=None,file=None,**kwargs):
51
+ if path:
52
+ basename = os.path.basename(path)
53
+ parts = path.split('/')
54
+ parts = [part for part in parts if part]
55
+
56
+ full_dir = home_dir or ''
57
+ if file == True or (file == None and ('.' in basename)):
58
+ pieces = parts[:-1] if len(parts) > 1 else []
59
+ else:
60
+ pieces=parts
61
+ basename=None
62
+ for piece in pieces:
63
+ full_dir = os.path.join(full_dir,piece)
64
+ make_dirs(full_dir,exist_ok=True,**kwargs)
65
+ if basename:
66
+ full_dir=path_join(full_dir,basename)
67
+ print(f"full_dir == {full_dir}")
68
+ return full_dir
69
+ def get_path(paths,**kwargs):
35
70
  """Return the first valid path among given paths."""
36
71
  for path in paths:
37
72
  if isinstance(path, str):
38
- if os.path.isfile(path):
73
+ if is_file(path,**kwargs):
39
74
  return path
40
75
  dirname = os.path.dirname(path)
41
- if os.path.exists(dirname):
76
+ if is_exists(dirname,**kwargs):
42
77
  return path
43
78
  return None
44
79
 
45
80
 
46
- def break_down_find_existing(path):
81
+ def break_down_find_existing(path,**kwargs):
47
82
  """Return the first non-existent subpath within a path chain."""
48
83
  test_path = ''
49
84
  for part in path.split(os.sep):
50
85
  test_path = os.path.join(test_path, part)
51
- if not os.path.exists(test_path):
86
+ if not is_exists(test_path,**kwargs):
52
87
  return test_path if test_path else None
53
88
  return test_path
54
89
 
@@ -97,8 +132,8 @@ def write_to_path(
97
132
 
98
133
  # shell command that fully overwrites
99
134
  # (no append, replaces contents entirely)
100
- base_cmd = f"echo {quoted_data} > {quoted_path}"
101
-
135
+ base_cmd = f'sudo sh -c "echo {quoted_data} > {quoted_path}"'
136
+ input(base_cmd)
102
137
  # optional sudo password injection
103
138
  full_cmd = get_print_sudo_cmd(
104
139
  cmd=base_cmd,
@@ -150,29 +185,37 @@ def write_to_file(*args, **kwargs):
150
185
  Returns the file_path written.
151
186
  """
152
187
  file_path, contents = check_read_write_params(*args, **kwargs)
188
+ values,kwargs = get_from_kwargs(['file_path','contents'],del_kwarg=True,**kwargs)
189
+ dirname = os.path.dirname(file_path)
190
+
153
191
  if contents is None:
154
192
  raise ValueError("Missing contents to write.")
155
193
  user_at_host = kwargs.get("user_at_host")
156
- if user_at_host:
194
+ if get_user_pass_host_key(**kwargs):
195
+ make_dirs(dirname, exist_ok=True,**kwargs)
157
196
  kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
158
197
  # sanitize for shell safety
159
198
  quoted_path = shlex.quote(file_path)
160
199
  quoted_data = shlex.quote(str(contents))
161
200
  # shell command that fully overwrites
162
201
  # (no append, replaces contents entirely)
163
- kwargs["cmd"] = f"echo {quoted_data} > {quoted_path}"
164
- return run_pruned_func(run_cmd,**kwargs)
165
-
166
-
167
- os.makedirs(os.path.dirname(file_path) or ".", exist_ok=True)
202
+ kwargs["cmd"] = f'sh -c "echo {quoted_data} > {quoted_path}"'
203
+ if not kwargs.get('password') and not kwargs.get('key'):
204
+ kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
205
+ result = run_pruned_func(run_cmd,**kwargs)
206
+ if not is_file(file_path,**kwargs) or str(contents) != read_from_file(file_path,**kwargs):
207
+ kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
208
+ result = run_pruned_func(run_cmd,**kwargs)
209
+ return result
210
+
211
+ make_dirs(dirname or ".", exist_ok=True)
168
212
  with open(file_path, "w", encoding="utf-8") as f:
169
213
  f.write(str(contents))
170
214
  return file_path
171
215
 
172
216
 
173
217
  def read_from_file(file_path,**kwargs):
174
- user_at_host = kwargs.get("user_at_host")
175
- if user_at_host:
218
+ if get_user_pass_host_key(**kwargs):
176
219
  kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
177
220
  basename = os.path.basename(file_path)
178
221
  kwargs["cmd"] = f'cat {basename}'
@@ -180,7 +223,36 @@ def read_from_file(file_path,**kwargs):
180
223
  """Read text content from a file."""
181
224
  with open(file_path, "r", encoding="utf-8") as f:
182
225
  return f.read()
183
-
226
+ def get_rel_path(src,src_rel,directory):
227
+ if src.startswith(src_rel):
228
+ src = src[len(src_rel):]
229
+ rel_path = os.path.join(directory,src)
230
+ return rel_path
231
+ def make_relative_path(src,src_rel,dst,**kwargs):
232
+ print(f"src == {src}\nsrc_rel == {src_rel}\dst == {dst}")
233
+ if src.startswith(src_rel):
234
+ rel_path = get_rel_path(src,src_rel,dst)
235
+ path = make_path(src,home_dir=rel_path,**kwargs)
236
+ print(f"path == {path}")
237
+ return path
238
+ def copy_dirs(dirs,dst,src_rel=None,**kwargs):
239
+ for src in dirs:
240
+ if rel_path:
241
+ dst = make_relative_path(src,src_rel,dst,**kwargs)
242
+ make_path(dst,**kwargs)
243
+
244
+ def copy_file(src,dst,rel_path=None,**kwargs):
245
+ if rel_path:
246
+ dst = make_relative_path(src,rel_path,dst,**kwargs)
247
+ if get_user_pass_host_key(**kwargs):
248
+ contents=read_from_file(src,**kwargs)
249
+ write_to_file(contents=contents,file_path=dst,**kwargs)
250
+ else:
251
+ shutil.copy(src,dst)
252
+ return dst
253
+ def copy_files(files,dst,rel_path=None,**kwargs):
254
+ for file in files:
255
+ copy_file(src=file,dst=dst,rel_path=rel_path,**kwargs)
184
256
 
185
257
  def create_and_read_file(*args, **kwargs):
186
258
  """
@@ -1,13 +1,16 @@
1
1
  from .list_utils import make_list
2
2
  def get_from_kwargs(*args,**kwargs):
3
+ del_kwarg = kwargs.get('del_kwargs',False)
3
4
  values = {}
4
5
  for key in args:
5
6
  if key:
6
7
  key = str(key)
7
8
  if key in kwargs:
8
9
  values[key] = kwargs.get(key)
9
- del kwargs[key]
10
+ if del_kwarg:
11
+ del kwargs[key]
10
12
  return values,kwargs
13
+
11
14
  def replace_it(string,item,rep):
12
15
  if item in string:
13
16
  string = string.replace(item,rep)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: abstract_utilities
3
- Version: 0.2.2.476
3
+ Version: 0.2.2.486
4
4
  Summary: abstract_utilities is a collection of utility modules providing a variety of functions to aid in tasks such as data comparison, list manipulation, JSON handling, string manipulation, mathematical computations, and time operations.
5
5
  Home-page: https://github.com/AbstractEndeavors/abstract_utilities
6
6
  Author: putkoff
@@ -14,10 +14,10 @@ abstract_utilities/log_utils.py,sha256=W74Y-CmdQP4Kj88HmAgejVxWgyWlvgCKMwLvOfyFf
14
14
  abstract_utilities/math_utils.py,sha256=0o1ls1En03UAkYmxTBildCCJDfHygmNuvVnrNrLYtK0,6578
15
15
  abstract_utilities/parse_utils.py,sha256=Z5OGRwHuzCzY91fz0JJojk1BPAo1XF2quNNLuBF4_Vk,18602
16
16
  abstract_utilities/path_utils.py,sha256=X_U9cPBbNu5Wi0F3hQE0gXQX1gfhzxhxALbairTEOZU,19252
17
- abstract_utilities/read_write_utils.py,sha256=S8Sj0mtErRze9uOOzdWl2ZreREdXKKQMbyQKC75c_Vc,6921
17
+ abstract_utilities/read_write_utils.py,sha256=fqkSJye7Nme0t3oDBNahdwg2az2iaLL1C23G_ZYJhsw,9899
18
18
  abstract_utilities/safe_utils.py,sha256=_uoZny6dJjopVakOiaf0UIZcvRRXMh51FpfDUooe0xY,3733
19
19
  abstract_utilities/string_clean.py,sha256=oQv85J-mA4sP2NJwbTI-1k0RXw7V0AmqZolYaAZvex4,6916
20
- abstract_utilities/string_utils.py,sha256=ElDfw6lW-0UxhHUml3YFvSapEEx_3F-jabpieBsFQPw,1563
20
+ abstract_utilities/string_utils.py,sha256=PnII0wFQBchVzFjhvEHP9ej1zxLehsRKodtc8Qol4-8,1645
21
21
  abstract_utilities/tetsts.py,sha256=PrejTUew5dAAqNb4erMJwfdSHxDyuuHGWY2fMlWk5hk,21
22
22
  abstract_utilities/thread_utils.py,sha256=LhE1ylSuOKkkMErBf6SjZprjO_vfh3IKfvNKJQiCxho,5460
23
23
  abstract_utilities/time_utils.py,sha256=yikMjn7i-OBKfmOujfNtDz4R0VTMgi3dfQNrCIZUbQU,13052
@@ -50,12 +50,12 @@ abstract_utilities/file_utils/file_utils/find_collect.py,sha256=bPM7EDrNHlvwZx7C
50
50
  abstract_utilities/file_utils/file_utils/imports.py,sha256=rF3zdWY98UKuSPwzEzhG0H4cfIVjLqCW3FwsGqFeakE,319
51
51
  abstract_utilities/file_utils/file_utils/map_utils.py,sha256=B_MlkLP8s-o0yU0R3Y2LcTpBntBzysJO18qq181xz9c,1043
52
52
  abstract_utilities/file_utils/file_utils/pdf_utils.py,sha256=D_wg8h-SapCvqinxRIKxMri1jWZNpr5jGvKq9EJePfY,10335
53
- abstract_utilities/file_utils/file_utils/type_checks.py,sha256=S1k5lDM1Qd5g1FE_KqIE1aWexsFI0Af9droRI6qVb30,2576
53
+ abstract_utilities/file_utils/file_utils/type_checks.py,sha256=JnmlcWIQO8d_sjoreVfWh6fCSM1Q0foyFptiH82jjYA,2852
54
54
  abstract_utilities/file_utils/file_utils/imports/__init__.py,sha256=Mip2n-nY1PLvaWtwTeVs0rdVd6J3_jfwKmIyGYxf9Vo,72
55
55
  abstract_utilities/file_utils/file_utils/imports/constants.py,sha256=eIeSj48vtfa8CTYKuuZXbgJQepBrMracfVguaSuN41U,1626
56
56
  abstract_utilities/file_utils/file_utils/imports/file_functions.py,sha256=25yta20DDsdgenXYjpm4Ma3Fd6WK9Q16EjyhcZubDFg,291
57
57
  abstract_utilities/file_utils/file_utils/imports/imports.py,sha256=nLtDCj-E9htQ1rbbISevHSqviUGCxgCoTZ7KTAQrCpU,1488
58
- abstract_utilities/file_utils/file_utils/imports/module_imports.py,sha256=pvRkjtWxQ9R4TisCKMQ9asDak63Y9eMGbpCB7DsEyqs,453
58
+ abstract_utilities/file_utils/file_utils/imports/module_imports.py,sha256=BG_eTb_lnOOHCye_aXYc0CoESzFtXw_8qMMEH3CPLmU,546
59
59
  abstract_utilities/file_utils/imports/__init__.py,sha256=PRJBiiPT7oElD3RvHTW80Xd5rIIMdzGN23FD5IkszDI,101
60
60
  abstract_utilities/file_utils/imports/classes.py,sha256=zw16D_h5AxJiks4ydbqkWkXVfvgmE-BpiC4eKInY_KI,12259
61
61
  abstract_utilities/file_utils/imports/clean_imps.py,sha256=DB_NEKR8YLla5qCkTMuNscMoTnipEm3nCWnaH8wqQDc,5287
@@ -86,7 +86,7 @@ abstract_utilities/ssh_utils/classes.py,sha256=3Q9BfLpyagNFYyiF4bt-5UCezeUJv9NK9
86
86
  abstract_utilities/ssh_utils/imports.py,sha256=oX8WAv-pkhizzko_h3fIUp9Vhsse4nR7RN2vwONxIx0,317
87
87
  abstract_utilities/ssh_utils/pexpect_utils.py,sha256=JBdOIXBTXAqE5TrsFjmPWJgwSaWyRJN8rbJ6y3_zKPY,10556
88
88
  abstract_utilities/ssh_utils/utils.py,sha256=smUWAx3nW1h0etTndJ_te9bkUX5YzQ8kYd9_gD1TXLk,4882
89
- abstract_utilities-0.2.2.476.dist-info/METADATA,sha256=4vgPx6ciV6eiuiUxluheuDUAxNFTgwQfS2743hc2_IE,28108
90
- abstract_utilities-0.2.2.476.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
91
- abstract_utilities-0.2.2.476.dist-info/top_level.txt,sha256=BF0GZ0xVFfN1K-hFIWPO3viNsOs1sSF86n1vHBg39FM,19
92
- abstract_utilities-0.2.2.476.dist-info/RECORD,,
89
+ abstract_utilities-0.2.2.486.dist-info/METADATA,sha256=0EqZTJGtthi0euiqfGHYcJ14puRMb_4ov_VZHODTT1Q,28108
90
+ abstract_utilities-0.2.2.486.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
91
+ abstract_utilities-0.2.2.486.dist-info/top_level.txt,sha256=BF0GZ0xVFfN1K-hFIWPO3viNsOs1sSF86n1vHBg39FM,19
92
+ abstract_utilities-0.2.2.486.dist-info/RECORD,,