abstract-utilities 0.2.2.419__py3-none-any.whl → 0.2.2.421__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.
- abstract_utilities/__init__.py +1 -2
- abstract_utilities/file_utils/__init__.py +1 -1
- abstract_utilities/file_utils/file_utils/file_utils.py +154 -140
- abstract_utilities/file_utils/imports/classes.py +300 -22
- abstract_utilities/file_utils/imports/module_imports.py +3 -3
- abstract_utilities/ssh_utils/utils.py +72 -6
- {abstract_utilities-0.2.2.419.dist-info → abstract_utilities-0.2.2.421.dist-info}/METADATA +1 -1
- {abstract_utilities-0.2.2.419.dist-info → abstract_utilities-0.2.2.421.dist-info}/RECORD +10 -10
- {abstract_utilities-0.2.2.419.dist-info → abstract_utilities-0.2.2.421.dist-info}/WHEEL +0 -0
- {abstract_utilities-0.2.2.419.dist-info → abstract_utilities-0.2.2.421.dist-info}/top_level.txt +0 -0
abstract_utilities/__init__.py
CHANGED
|
@@ -3,9 +3,8 @@ from datetime import timedelta
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
from typing import *
|
|
5
5
|
from .hash_utils import *
|
|
6
|
-
from .dynimport import get_abstract_import,import_symbols_to_parent,call_for_all_tabs
|
|
6
|
+
##from .dynimport import get_abstract_import,import_symbols_to_parent,call_for_all_tabs
|
|
7
7
|
|
|
8
|
-
from .robust_readers import *
|
|
9
8
|
from .json_utils import (unified_json_loader,
|
|
10
9
|
find_keys,
|
|
11
10
|
get_key_values_from_path,
|
|
@@ -1,194 +1,208 @@
|
|
|
1
1
|
from .imports import *
|
|
2
|
-
# -------- Public API drop-ins that mirror your originals --------
|
|
3
2
|
from .filter_params import *
|
|
4
|
-
from .file_filters import *
|
|
5
|
-
def make_allowed_predicate(cfg: ScanConfig, *, isdir=None, isfile=None) -> Callable[[str], bool]:
|
|
6
|
-
def _isdir(p: str) -> bool: return isdir(p) if isdir else Path(p).is_dir()
|
|
7
|
-
def _isfile(p: str) -> bool: return isfile(p) if isfile else Path(p).is_file()
|
|
8
|
-
def allowed(path: str) -> bool:
|
|
9
|
-
name = os.path.basename(path).lower()
|
|
10
|
-
path_str = path.lower()
|
|
11
3
|
|
|
12
|
-
if cfg.exclude_dirs:
|
|
13
|
-
for dpat in cfg.exclude_dirs:
|
|
14
|
-
d = dpat.lower()
|
|
15
|
-
if d in path_str or fnmatch.fnmatch(name, d):
|
|
16
|
-
if _isdir(path) or d in path_str:
|
|
17
|
-
return False
|
|
18
4
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return False
|
|
5
|
+
# -------------------------------------------------------------
|
|
6
|
+
# Wrapper: respects your original API and naming conventions
|
|
7
|
+
# -------------------------------------------------------------
|
|
23
8
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
9
|
+
def get_allowed_predicate(allowed=None):
|
|
10
|
+
if allowed is not False:
|
|
11
|
+
if allowed is True:
|
|
12
|
+
allowed = None
|
|
13
|
+
allowed = allowed or make_allowed_predicate()
|
|
14
|
+
else:
|
|
15
|
+
def allowed(*args):
|
|
16
|
+
return True
|
|
29
17
|
return allowed
|
|
30
18
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
19
|
+
|
|
20
|
+
# -------------------------------------------------------------
|
|
21
|
+
# Remote-aware globbing
|
|
22
|
+
# -------------------------------------------------------------
|
|
23
|
+
def get_globs(items, recursive: bool = True, allowed=None, **kwargs):
|
|
24
|
+
"""
|
|
25
|
+
Behaves like your original get_globs(), but can traverse both
|
|
26
|
+
local and remote paths transparently via normalize_items().
|
|
27
|
+
"""
|
|
28
|
+
glob_paths = []
|
|
29
|
+
roots = [p for p in make_list(items) if p]
|
|
30
|
+
|
|
31
|
+
kwargs.setdefault("mindepth", 1)
|
|
32
|
+
if not recursive:
|
|
38
33
|
kwargs.setdefault("maxdepth", 1)
|
|
39
|
-
for fs, root in normalize_items(roots, **kwargs):
|
|
40
|
-
gl = fs.glob_recursive(root, **kwargs)
|
|
41
|
-
if allowed:
|
|
42
|
-
gl = [p for p in gl if allowed(p)]
|
|
43
|
-
res.extend(gl)
|
|
44
|
-
return res
|
|
45
34
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if fs.isfile(root): out.append(root)
|
|
35
|
+
for fs, root, _ in normalize_items(roots, **kwargs):
|
|
36
|
+
# use the backend's recursive walker
|
|
37
|
+
nu_items = fs.glob_recursive(root, **kwargs)
|
|
38
|
+
if allowed:
|
|
39
|
+
nu_items = [n for n in nu_items if n and allowed(n)]
|
|
40
|
+
glob_paths += nu_items
|
|
41
|
+
return glob_paths
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# -------------------------------------------------------------
|
|
45
|
+
# Allowed filters
|
|
46
|
+
# -------------------------------------------------------------
|
|
47
|
+
def get_allowed_files(items, allowed=True, **kwargs):
|
|
48
|
+
allowed = get_allowed_predicate(allowed=allowed)
|
|
49
|
+
out = []
|
|
50
|
+
for fs, item, _ in normalize_items(items, **kwargs):
|
|
51
|
+
if fs.isfile(item) and allowed(item):
|
|
52
|
+
out.append(item)
|
|
65
53
|
return out
|
|
66
54
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
roots = [p for p in make_list(paths) if p]
|
|
76
|
-
out: List[str] = []
|
|
77
|
-
kwargs = {**kwargs, "include_files": False, "include_dirs": True}
|
|
78
|
-
for fs, root in normalize_items(roots):
|
|
79
|
-
if fs.isdir(root):
|
|
80
|
-
if (not allowed) or allowed(root):
|
|
81
|
-
out.append(root)
|
|
82
|
-
for p in fs.glob_recursive(root, **kwargs):
|
|
83
|
-
if (not allowed) or allowed(p):
|
|
84
|
-
if fs.isdir(p): out.append(p)
|
|
55
|
+
|
|
56
|
+
def get_allowed_dirs(items, allowed=False, **kwargs):
|
|
57
|
+
allowed = get_allowed_predicate(allowed=allowed)
|
|
58
|
+
out = []
|
|
59
|
+
for fs, item, _ in normalize_items(items, **kwargs):
|
|
60
|
+
if fs.isdir(item) and allowed(item):
|
|
61
|
+
out.append(item)
|
|
85
62
|
return out
|
|
86
63
|
|
|
87
|
-
def get_filtered_files(paths, allowed=None, files: List[str] | None = None, **kwargs) -> List[str]:
|
|
88
|
-
if allowed is not False:
|
|
89
|
-
if allowed is True:
|
|
90
|
-
allowed = None
|
|
91
|
-
allowed = allowed or make_allowed_predicate(ScanConfig())
|
|
92
|
-
else:
|
|
93
|
-
allowed = (lambda *_: True)
|
|
94
64
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
65
|
+
# -------------------------------------------------------------
|
|
66
|
+
# Filtered sets
|
|
67
|
+
# -------------------------------------------------------------
|
|
68
|
+
def get_filtered_files(items, allowed=None, files=None, **kwargs):
|
|
69
|
+
allowed = get_allowed_predicate(allowed=allowed)
|
|
70
|
+
files = set(files or [])
|
|
71
|
+
out = []
|
|
72
|
+
for fs, root, _ in normalize_items(items, **kwargs):
|
|
100
73
|
for p in fs.glob_recursive(root, **kwargs):
|
|
101
|
-
if p in files:
|
|
102
|
-
|
|
103
|
-
if
|
|
74
|
+
if p in files:
|
|
75
|
+
continue
|
|
76
|
+
if allowed(p) and fs.isfile(p):
|
|
77
|
+
out.append(p)
|
|
104
78
|
return out
|
|
105
79
|
|
|
106
|
-
def get_filtered_dirs(paths, allowed=None, dirs: List[str] | None = None, **kwargs) -> List[str]:
|
|
107
|
-
if allowed is not False:
|
|
108
|
-
if allowed is True:
|
|
109
|
-
allowed = None
|
|
110
|
-
allowed = allowed or make_allowed_predicate(ScanConfig())
|
|
111
|
-
else:
|
|
112
|
-
allowed = (lambda *_: True)
|
|
113
80
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
for fs, root in normalize_items(
|
|
81
|
+
def get_filtered_dirs(items, allowed=None, dirs=None, **kwargs):
|
|
82
|
+
allowed = get_allowed_predicate(allowed=allowed)
|
|
83
|
+
dirs = set(dirs or [])
|
|
84
|
+
out = []
|
|
85
|
+
for fs, root, _ in normalize_items(items, **kwargs):
|
|
119
86
|
for p in fs.glob_recursive(root, **kwargs):
|
|
120
|
-
if p in dirs:
|
|
121
|
-
|
|
122
|
-
if
|
|
87
|
+
if p in dirs:
|
|
88
|
+
continue
|
|
89
|
+
if allowed(p) and fs.isdir(p):
|
|
90
|
+
out.append(p)
|
|
123
91
|
return out
|
|
124
92
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
93
|
+
|
|
94
|
+
# -------------------------------------------------------------
|
|
95
|
+
# Recursive expansion
|
|
96
|
+
# -------------------------------------------------------------
|
|
97
|
+
def get_all_allowed_files(items, allowed=None, **kwargs):
|
|
98
|
+
dirs = get_all_allowed_dirs(items, allowed=allowed, **kwargs)
|
|
99
|
+
files = get_allowed_files(items, allowed=allowed, **kwargs)
|
|
128
100
|
seen = set(files)
|
|
129
|
-
for fs, directory in normalize_items(dirs):
|
|
101
|
+
for fs, directory, _ in normalize_items(dirs, **kwargs):
|
|
130
102
|
for p in fs.glob_recursive(directory, **kwargs):
|
|
131
|
-
if p in seen:
|
|
132
|
-
|
|
103
|
+
if p in seen:
|
|
104
|
+
continue
|
|
105
|
+
if allowed and not allowed(p):
|
|
106
|
+
continue
|
|
133
107
|
if fs.isfile(p):
|
|
134
|
-
files.append(p)
|
|
108
|
+
files.append(p)
|
|
109
|
+
seen.add(p)
|
|
135
110
|
return files
|
|
136
111
|
|
|
137
|
-
def get_all_allowed_dirs(paths, allowed=None, **kwargs) -> List[str]:
|
|
138
|
-
if allowed is not False:
|
|
139
|
-
if allowed is True:
|
|
140
|
-
allowed = None
|
|
141
|
-
allowed = allowed or make_allowed_predicate(ScanConfig())
|
|
142
|
-
else:
|
|
143
|
-
allowed = (lambda *_: True)
|
|
144
112
|
|
|
145
|
-
|
|
146
|
-
|
|
113
|
+
def get_all_allowed_dirs(items, allowed=None, **kwargs):
|
|
114
|
+
allowed = get_allowed_predicate(allowed=allowed)
|
|
115
|
+
out = []
|
|
147
116
|
seen = set()
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
117
|
+
for fs, root, _ in normalize_items(items, **kwargs):
|
|
118
|
+
if fs.isdir(root) and allowed(root):
|
|
119
|
+
out.append(root)
|
|
120
|
+
seen.add(root)
|
|
152
121
|
for p in fs.glob_recursive(root, **kwargs):
|
|
153
|
-
if p in seen:
|
|
154
|
-
|
|
155
|
-
if fs.isdir(p):
|
|
156
|
-
out.append(p)
|
|
122
|
+
if p in seen:
|
|
123
|
+
continue
|
|
124
|
+
if allowed(p) and fs.isdir(p):
|
|
125
|
+
out.append(p)
|
|
126
|
+
seen.add(p)
|
|
157
127
|
return out
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# -------------------------------------------------------------
|
|
131
|
+
# Unified directory scan
|
|
132
|
+
# -------------------------------------------------------------
|
|
158
133
|
def get_files_and_dirs(
|
|
159
|
-
directory: str
|
|
134
|
+
directory: str=None,
|
|
160
135
|
cfg: Optional["ScanConfig"] = None,
|
|
161
136
|
allowed_exts: Optional[Set[str]] = False,
|
|
162
137
|
unallowed_exts: Optional[Set[str]] = False,
|
|
163
138
|
exclude_types: Optional[Set[str]] = False,
|
|
164
139
|
exclude_dirs: Optional[List[str]] = False,
|
|
165
140
|
exclude_patterns: Optional[List[str]] = False,
|
|
166
|
-
add
|
|
141
|
+
add=False,
|
|
167
142
|
recursive: bool = True,
|
|
168
143
|
include_files: bool = True,
|
|
169
|
-
|
|
144
|
+
roots=None,
|
|
170
145
|
**kwargs
|
|
171
146
|
):
|
|
147
|
+
"""
|
|
148
|
+
Same public signature as your original get_files_and_dirs(),
|
|
149
|
+
but powered by backend objects (LocalFS or SSHFS).
|
|
150
|
+
"""
|
|
172
151
|
cfg = cfg or define_defaults(
|
|
173
152
|
allowed_exts=allowed_exts,
|
|
174
153
|
unallowed_exts=unallowed_exts,
|
|
175
154
|
exclude_types=exclude_types,
|
|
176
155
|
exclude_dirs=exclude_dirs,
|
|
177
156
|
exclude_patterns=exclude_patterns,
|
|
178
|
-
add=add
|
|
157
|
+
add=add
|
|
179
158
|
)
|
|
180
|
-
# make predicate backend-agnostic here; the per-backend calls below pass strings only
|
|
181
159
|
allowed = make_allowed_predicate(cfg)
|
|
182
|
-
|
|
160
|
+
items = []
|
|
161
|
+
files = []
|
|
162
|
+
roots = make_list(roots)
|
|
163
|
+
directory = make_list(directory)+roots
|
|
183
164
|
if recursive:
|
|
184
|
-
|
|
165
|
+
items = get_globs(directory, recursive=recursive, allowed=allowed, **kwargs)
|
|
185
166
|
else:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
167
|
+
for fs, base, _ in normalize_items(make_list(directory), **kwargs):
|
|
168
|
+
try:
|
|
169
|
+
items += [fs.join(base, name) for name in fs.listdir(base)]
|
|
170
|
+
except Exception:
|
|
171
|
+
pass
|
|
191
172
|
|
|
192
173
|
dirs = get_allowed_dirs(items, allowed=allowed, **kwargs)
|
|
193
|
-
|
|
174
|
+
if include_files:
|
|
175
|
+
files = get_allowed_files(items, allowed=allowed, **kwargs)
|
|
194
176
|
return dirs, files
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
# -------------------------------------------------------------
|
|
180
|
+
# Unchanged predicate builder
|
|
181
|
+
# -------------------------------------------------------------
|
|
182
|
+
def make_allowed_predicate(cfg: ScanConfig) -> Callable[[str], bool]:
|
|
183
|
+
def allowed(path: str) -> bool:
|
|
184
|
+
p = Path(path)
|
|
185
|
+
name = p.name.lower()
|
|
186
|
+
path_str = str(p).lower()
|
|
187
|
+
|
|
188
|
+
# A) directory exclusions
|
|
189
|
+
if cfg.exclude_dirs:
|
|
190
|
+
for dpat in cfg.exclude_dirs:
|
|
191
|
+
if dpat in path_str or fnmatch.fnmatch(name, dpat.lower()):
|
|
192
|
+
if p.is_dir() or dpat in path_str:
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
# B) filename pattern exclusions
|
|
196
|
+
if cfg.exclude_patterns:
|
|
197
|
+
for pat in cfg.exclude_patterns:
|
|
198
|
+
if fnmatch.fnmatch(name, pat.lower()):
|
|
199
|
+
return False
|
|
200
|
+
|
|
201
|
+
# C) extension gates
|
|
202
|
+
if p.is_file():
|
|
203
|
+
ext = p.suffix.lower()
|
|
204
|
+
if (cfg.allowed_exts and ext not in cfg.allowed_exts) or \
|
|
205
|
+
(cfg.unallowed_exts and ext in cfg.unallowed_exts):
|
|
206
|
+
return False
|
|
207
|
+
return True
|
|
208
|
+
return allowed
|
|
@@ -1,6 +1,138 @@
|
|
|
1
1
|
from .imports import *
|
|
2
2
|
from .module_imports import *
|
|
3
3
|
from .constants import *
|
|
4
|
+
def get_item_check_cmd(path, file=True, directory=False, exists=False):
|
|
5
|
+
if (directory and file) or exists:
|
|
6
|
+
typ = "e"
|
|
7
|
+
elif file:
|
|
8
|
+
typ = "f"
|
|
9
|
+
elif directory:
|
|
10
|
+
typ = "d"
|
|
11
|
+
elif isinstance(file, str):
|
|
12
|
+
if "f" in file:
|
|
13
|
+
typ = "f"
|
|
14
|
+
elif "d" in file:
|
|
15
|
+
typ = "d"
|
|
16
|
+
else:
|
|
17
|
+
typ = "e"
|
|
18
|
+
else:
|
|
19
|
+
typ = "e"
|
|
20
|
+
return f"test -{typ} {shlex.quote(path)} && echo __OK__ || true"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_all_item_check_cmd(path, file=True, directory=True, exists=True):
|
|
24
|
+
collects = []
|
|
25
|
+
out_js = {}
|
|
26
|
+
|
|
27
|
+
if file:
|
|
28
|
+
collects.append("file")
|
|
29
|
+
if directory:
|
|
30
|
+
collects.append("dir")
|
|
31
|
+
if exists:
|
|
32
|
+
collects.append("exists")
|
|
33
|
+
|
|
34
|
+
if not collects:
|
|
35
|
+
return out_js
|
|
36
|
+
|
|
37
|
+
path = shlex.quote(path)
|
|
38
|
+
for typ in collects:
|
|
39
|
+
t = typ[0] # f, d, or e
|
|
40
|
+
out_js[typ] = f"test -{t} {path} && echo __OK__ || true"
|
|
41
|
+
|
|
42
|
+
return out_js
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def is_file(
|
|
46
|
+
path,
|
|
47
|
+
user_at_host=None,
|
|
48
|
+
password=None,
|
|
49
|
+
key=None,
|
|
50
|
+
env_path=None,
|
|
51
|
+
**kwargs
|
|
52
|
+
):
|
|
53
|
+
contingencies = list(set([user_at_host,password,key,env_path]))
|
|
54
|
+
len_contingencies = len(contingencies)
|
|
55
|
+
is_potential = (len_contingencies >1 or (None not in contingencies))
|
|
56
|
+
if not is_potential:
|
|
57
|
+
return os.path.isfile(path)
|
|
58
|
+
cmd = get_item_check_cmd(path,file=True)
|
|
59
|
+
return run_cmd(cmd=cmd,
|
|
60
|
+
user_at_host=user_at_host,
|
|
61
|
+
password=password,
|
|
62
|
+
key=key,
|
|
63
|
+
env_path=env_path,
|
|
64
|
+
**kwargs
|
|
65
|
+
)
|
|
66
|
+
def is_dir(
|
|
67
|
+
path,
|
|
68
|
+
user_at_host=None,
|
|
69
|
+
password=None,
|
|
70
|
+
key=None,
|
|
71
|
+
env_path=None,
|
|
72
|
+
**kwargs
|
|
73
|
+
):
|
|
74
|
+
contingencies = list(set([user_at_host,password,key,env_path]))
|
|
75
|
+
len_contingencies = len(contingencies)
|
|
76
|
+
is_potential = (len_contingencies >1 or (None not in contingencies))
|
|
77
|
+
if not is_potential:
|
|
78
|
+
return os.path.isdir(path)
|
|
79
|
+
cmd = get_item_check_cmd(path,file=False,directory=True)
|
|
80
|
+
return run_cmd(cmd=cmd,
|
|
81
|
+
user_at_host=user_at_host,
|
|
82
|
+
password=password,
|
|
83
|
+
key=key,
|
|
84
|
+
env_path=env_path,
|
|
85
|
+
**kwargs
|
|
86
|
+
)
|
|
87
|
+
def is_exists(
|
|
88
|
+
path,
|
|
89
|
+
user_at_host=None,
|
|
90
|
+
password=None,
|
|
91
|
+
key=None,
|
|
92
|
+
env_path=None,
|
|
93
|
+
**kwargs
|
|
94
|
+
):
|
|
95
|
+
contingencies = list(set([user_at_host,password,key,env_path]))
|
|
96
|
+
len_contingencies = len(contingencies)
|
|
97
|
+
is_potential = (len_contingencies >1 or (None not in contingencies))
|
|
98
|
+
if not is_potential:
|
|
99
|
+
return os.path.exists(path)
|
|
100
|
+
if is_potential == True:
|
|
101
|
+
cmd = get_item_check_cmd(path,exists=True)
|
|
102
|
+
return run_cmd(cmd=cmd,
|
|
103
|
+
user_at_host=user_at_host,
|
|
104
|
+
password=password,
|
|
105
|
+
key=key,
|
|
106
|
+
env_path=env_path,
|
|
107
|
+
**kwargs
|
|
108
|
+
)
|
|
109
|
+
def is_any(
|
|
110
|
+
path,
|
|
111
|
+
user_at_host=None,
|
|
112
|
+
password=None,
|
|
113
|
+
key=None,
|
|
114
|
+
env_path=None,
|
|
115
|
+
**kwargs
|
|
116
|
+
):
|
|
117
|
+
contingencies = list(set([user_at_host,password,key,env_path]))
|
|
118
|
+
len_contingencies = len(contingencies)
|
|
119
|
+
is_potential = (len_contingencies >1 or (None not in contingencies))
|
|
120
|
+
if not is_potential:
|
|
121
|
+
return os.path.exists(path)
|
|
122
|
+
if is_potential == True:
|
|
123
|
+
out_js = get_all_item_check_cmd(path,file=True,directory=True,exists=True)
|
|
124
|
+
for typ,cmd in out_js.items():
|
|
125
|
+
response = run_cmd(cmd=cmd,
|
|
126
|
+
user_at_host=user_at_host,
|
|
127
|
+
password=password,
|
|
128
|
+
key=key,
|
|
129
|
+
env_path=env_path,
|
|
130
|
+
**kwargs
|
|
131
|
+
)
|
|
132
|
+
result = "__OK__" in (response or "")
|
|
133
|
+
if result:
|
|
134
|
+
return typ
|
|
135
|
+
return None
|
|
4
136
|
class PathBackend(Protocol):
|
|
5
137
|
def join(self, *parts: str) -> str: ...
|
|
6
138
|
def isfile(self, path: str) -> bool: ...
|
|
@@ -9,12 +141,42 @@ class PathBackend(Protocol):
|
|
|
9
141
|
def listdir(self, base: str) -> List[str]: ...
|
|
10
142
|
|
|
11
143
|
class LocalFS:
|
|
144
|
+
def __init__(self, get_type=False, get_is_dir=False, get_is_file=False, get_is_exists=False, **kwargs):
|
|
145
|
+
self.get_type = get_type
|
|
146
|
+
self.get_is_dir = get_is_dir
|
|
147
|
+
self.get_is_file = get_is_file
|
|
148
|
+
self.get_is_exists = get_is_exists
|
|
149
|
+
|
|
12
150
|
def join(self, *parts: str) -> str:
|
|
13
151
|
return os.path.join(*parts)
|
|
152
|
+
|
|
14
153
|
def isfile(self, path: str) -> bool:
|
|
15
154
|
return os.path.isfile(path)
|
|
155
|
+
|
|
16
156
|
def isdir(self, path: str) -> bool:
|
|
17
157
|
return os.path.isdir(path)
|
|
158
|
+
|
|
159
|
+
def isexists(self, path: str) -> bool:
|
|
160
|
+
return os.path.exists(path)
|
|
161
|
+
|
|
162
|
+
def istype(self, path: str) -> str | None:
|
|
163
|
+
funcs_js = {"file": os.path.isfile, "dir": os.path.isdir, "exists": os.path.exists}
|
|
164
|
+
for key, func in funcs_js.items():
|
|
165
|
+
if func(path):
|
|
166
|
+
return key
|
|
167
|
+
return None
|
|
168
|
+
|
|
169
|
+
def is_included(self, path, **kwargs):
|
|
170
|
+
include_js = {}
|
|
171
|
+
if self.get_type:
|
|
172
|
+
include_js["typ"] = self.istype(path)
|
|
173
|
+
if self.get_is_dir:
|
|
174
|
+
include_js["dir"] = self.isdir(path)
|
|
175
|
+
if self.get_is_file:
|
|
176
|
+
include_js["file"] = self.isfile(path)
|
|
177
|
+
if self.get_is_exists:
|
|
178
|
+
include_js["exists"] = self.isexists(path)
|
|
179
|
+
return include_js
|
|
18
180
|
def glob_recursive(self, base: str, **opts) -> List[str]:
|
|
19
181
|
"""
|
|
20
182
|
opts:
|
|
@@ -55,25 +217,73 @@ class LocalFS:
|
|
|
55
217
|
return [os.path.join(base, name) for name in os.listdir(base)]
|
|
56
218
|
except Exception:
|
|
57
219
|
return []
|
|
58
|
-
|
|
220
|
+
def get_spec_kwargs(
|
|
221
|
+
user_at_host=None,
|
|
222
|
+
password=None,
|
|
223
|
+
key=None,
|
|
224
|
+
env_path=None,
|
|
225
|
+
kwargs=None
|
|
226
|
+
):
|
|
227
|
+
kwargs = kwargs or {}
|
|
228
|
+
kwargs["user_at_host"] = kwargs.get("user_at_host") or user_at_host
|
|
229
|
+
kwargs["password"] = kwargs.get("password") or password
|
|
230
|
+
kwargs["key"] = kwargs.get("key") or key
|
|
231
|
+
kwargs["env_path"] = kwargs.get("env_path") or env_path
|
|
232
|
+
return kwargs
|
|
59
233
|
class SSHFS:
|
|
60
|
-
"""Remote POSIX backend via
|
|
61
|
-
def __init__(self,
|
|
62
|
-
|
|
234
|
+
"""Remote POSIX backend via run_remote_cmd."""
|
|
235
|
+
def __init__(self, password=None, key=None, env_path=None,
|
|
236
|
+
get_type=False, get_is_dir=False, get_is_file=False, get_is_exists=False, **kwargs):
|
|
237
|
+
self.user_at_host = kwargs.get('user_at_host') or kwargs.get('user') or kwargs.get('host')
|
|
238
|
+
self.password = password
|
|
239
|
+
self.key = key
|
|
240
|
+
self.env_path = env_path
|
|
241
|
+
self.get_type = get_type
|
|
242
|
+
self.get_is_dir = get_is_dir
|
|
243
|
+
self.get_is_file = get_is_file
|
|
244
|
+
self.get_is_exists = get_is_exists
|
|
245
|
+
|
|
246
|
+
def cell_spec_kwargs(self, func, path, **kwargs):
|
|
247
|
+
kwargs = get_spec_kwargs(
|
|
248
|
+
user_at_host=self.user_at_host,
|
|
249
|
+
password=self.password,
|
|
250
|
+
key=self.key,
|
|
251
|
+
env_path=self.env_path,
|
|
252
|
+
kwargs=kwargs
|
|
253
|
+
)
|
|
254
|
+
return func(path, **kwargs)
|
|
255
|
+
|
|
256
|
+
def is_included(self, path, **kwargs):
|
|
257
|
+
include_js = {}
|
|
258
|
+
if self.get_type:
|
|
259
|
+
include_js["typ"] = self.istype(path, **kwargs)
|
|
260
|
+
if self.get_is_dir:
|
|
261
|
+
include_js["dir"] = self.isdir(path, **kwargs)
|
|
262
|
+
if self.get_is_file:
|
|
263
|
+
include_js["file"] = self.isfile(path, **kwargs)
|
|
264
|
+
if self.get_is_exists:
|
|
265
|
+
include_js["exists"] = self.isexists(path, **kwargs)
|
|
266
|
+
return include_js
|
|
63
267
|
|
|
64
268
|
def join(self, *parts: str) -> str:
|
|
65
269
|
return posixpath.join(*parts)
|
|
66
270
|
|
|
67
|
-
def isfile(self, path: str) -> bool:
|
|
68
|
-
|
|
69
|
-
out = run_remote_cmd(self.user_at_host, cmd)
|
|
271
|
+
def isfile(self, path: str, **kwargs) -> bool:
|
|
272
|
+
out = self.cell_spec_kwargs(is_file, path, **kwargs)
|
|
70
273
|
return "__OK__" in (out or "")
|
|
71
274
|
|
|
72
|
-
def isdir(self, path: str) -> bool:
|
|
73
|
-
|
|
74
|
-
|
|
275
|
+
def isdir(self, path: str, **kwargs) -> bool:
|
|
276
|
+
out = self.cell_spec_kwargs(is_dir, path, **kwargs)
|
|
277
|
+
return "__OK__" in (out or "")
|
|
278
|
+
|
|
279
|
+
def isexists(self, path: str, **kwargs) -> bool:
|
|
280
|
+
out = self.cell_spec_kwargs(is_exists, path, **kwargs)
|
|
75
281
|
return "__OK__" in (out or "")
|
|
76
282
|
|
|
283
|
+
def istype(self, path: str, **kwargs) -> str | None:
|
|
284
|
+
out = self.cell_spec_kwargs(is_any, path, **kwargs)
|
|
285
|
+
return out
|
|
286
|
+
|
|
77
287
|
def glob_recursive(self, base: str, **opts) -> List[str]:
|
|
78
288
|
maxdepth = opts.get("maxdepth")
|
|
79
289
|
mindepth = opts.get("mindepth", 1)
|
|
@@ -111,18 +321,86 @@ class SSHFS:
|
|
|
111
321
|
return [line.strip() for line in (out or "").splitlines() if line.strip()]
|
|
112
322
|
|
|
113
323
|
|
|
114
|
-
def
|
|
115
|
-
|
|
116
|
-
|
|
324
|
+
def make_allowed_predicate(cfg: ScanConfig,fs=None) -> Callable[[str], bool]:
|
|
325
|
+
fs = fs or LocalFS()
|
|
326
|
+
def allowed(path: str) -> bool:
|
|
327
|
+
|
|
328
|
+
name = p.name.lower()
|
|
329
|
+
path_str = str(p).lower()
|
|
330
|
+
# A) directories
|
|
331
|
+
if cfg.exclude_dirs:
|
|
332
|
+
for dpat in cfg.exclude_dirs:
|
|
333
|
+
if dpat in path_str or fnmatch.fnmatch(name, dpat.lower()):
|
|
334
|
+
if p.is_dir() or dpat in path_str:
|
|
335
|
+
return False
|
|
336
|
+
|
|
337
|
+
if cfg.exclude_patterns:
|
|
338
|
+
# B) filename patterns
|
|
339
|
+
for pat in cfg.exclude_patterns:
|
|
340
|
+
if fnmatch.fnmatch(name, pat.lower()):
|
|
341
|
+
return False
|
|
342
|
+
|
|
343
|
+
# C) extension gates
|
|
344
|
+
if p.is_file():
|
|
345
|
+
ext = p.suffix.lower()
|
|
346
|
+
if (cfg.allowed_exts and ext not in cfg.allowed_exts) or (cfg.unallowed_exts and ext in cfg.unallowed_exts):
|
|
347
|
+
return False
|
|
348
|
+
return True
|
|
349
|
+
return allowed
|
|
350
|
+
def try_group(pre,item,strings):
|
|
351
|
+
|
|
352
|
+
try:
|
|
353
|
+
m = pre.match(item)
|
|
354
|
+
for i,string in enumerate(strings):
|
|
355
|
+
strings[i] = m.group(string)
|
|
356
|
+
|
|
357
|
+
except:
|
|
358
|
+
return None
|
|
359
|
+
return strings
|
|
360
|
+
def normalize_items(
|
|
361
|
+
paths: Iterable[str],
|
|
362
|
+
user_at_host=None,
|
|
363
|
+
get_type=True,
|
|
364
|
+
get_is_dir=False,
|
|
365
|
+
get_is_file=False,
|
|
366
|
+
get_is_exists=False,
|
|
367
|
+
**kwargs
|
|
368
|
+
) -> List[tuple[PathBackend, str, dict]]:
|
|
369
|
+
pairs: List[tuple[PathBackend, str, dict]] = []
|
|
370
|
+
host = user_at_host or kwargs.get("host") or kwargs.get("user")
|
|
371
|
+
|
|
117
372
|
for item in paths:
|
|
118
|
-
if not item:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
373
|
+
if not item:
|
|
374
|
+
continue
|
|
375
|
+
|
|
376
|
+
strings = try_group(REMOTE_RE, item, ["host", "path"])
|
|
377
|
+
fs_host = None
|
|
378
|
+
nuhost = None
|
|
379
|
+
|
|
380
|
+
if (strings and None not in strings) or host:
|
|
381
|
+
if strings and None not in strings:
|
|
382
|
+
nuhost = strings[0]
|
|
383
|
+
item = strings[1] or item
|
|
384
|
+
nuhost = nuhost or host
|
|
385
|
+
fs_host = SSHFS(
|
|
386
|
+
nuhost,
|
|
387
|
+
user_at_host=user_at_host,
|
|
388
|
+
get_type=get_type,
|
|
389
|
+
get_is_dir=get_is_dir,
|
|
390
|
+
get_is_file=get_is_file,
|
|
391
|
+
get_is_exists=get_is_exists,
|
|
392
|
+
**kwargs
|
|
393
|
+
)
|
|
125
394
|
else:
|
|
126
|
-
|
|
127
|
-
|
|
395
|
+
fs_host = LocalFS(
|
|
396
|
+
get_type=get_type,
|
|
397
|
+
get_is_dir=get_is_dir,
|
|
398
|
+
get_is_file=get_is_file,
|
|
399
|
+
get_is_exists=get_is_exists
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
includes = fs_host.is_included(item)
|
|
403
|
+
pairs.append((fs_host, item, includes))
|
|
128
404
|
return pairs
|
|
405
|
+
|
|
406
|
+
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from ...string_clean import eatAll
|
|
2
2
|
from ...list_utils import make_list
|
|
3
3
|
from ...type_utils import get_media_exts, is_media_type,MIME_TYPES,is_str
|
|
4
|
-
from ...ssh_utils import
|
|
4
|
+
from ...ssh_utils import *
|
|
5
5
|
from ...env_utils import *
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
from ...abstract_classes import SingletonMeta
|
|
8
|
-
|
|
8
|
+
|
|
@@ -1,4 +1,30 @@
|
|
|
1
1
|
from .imports import *
|
|
2
|
+
def get_pass_from_key(key=None,env_path=None):
|
|
3
|
+
if key:
|
|
4
|
+
return get_env_value(key=key,path=env_path)
|
|
5
|
+
def get_password(password=None,key=None,env_path=None):
|
|
6
|
+
password = password or get_pass_from_key(key=key,env_path=env_path)
|
|
7
|
+
return password
|
|
8
|
+
|
|
9
|
+
def get_print_sudo_cmd(
|
|
10
|
+
cmd: str,
|
|
11
|
+
password=None,
|
|
12
|
+
key=None,
|
|
13
|
+
env_path=None
|
|
14
|
+
):
|
|
15
|
+
password = get_password(password=password,key=key,env_path=env_path)
|
|
16
|
+
if password != None:
|
|
17
|
+
|
|
18
|
+
cmd = get_password_cmd(password=password,cmd=cmd)
|
|
19
|
+
return cmd
|
|
20
|
+
def get_password_cmd(password:str,cmd:str):
|
|
21
|
+
sudo_cmd = get_sudo_cmd(cmd)
|
|
22
|
+
password_sudo_cmd = get_raw_password_sudo_cmd(password=password,sudo_cmd=sudo_cmd)
|
|
23
|
+
return password_sudo_cmd
|
|
24
|
+
def get_sudo_cmd(cmd: str):
|
|
25
|
+
return f"sudo -S -k {cmd}"
|
|
26
|
+
def get_raw_password_sudo_cmd(password:str,sudo_cmd:str):
|
|
27
|
+
return f"printf %s {shlex.quote(password)} | {sudo_cmd}"
|
|
2
28
|
def get_remote_bash(
|
|
3
29
|
cmd: str,
|
|
4
30
|
cwd: str | None = None
|
|
@@ -9,13 +35,21 @@ def get_remote_ssh(
|
|
|
9
35
|
remote:str=None
|
|
10
36
|
):
|
|
11
37
|
return f"ssh {shlex.quote(user_at_host)} {shlex.quote(remote)}"
|
|
12
|
-
|
|
13
38
|
def get_remote_cmd(
|
|
14
39
|
cmd: str,
|
|
15
40
|
user_at_host: str,
|
|
16
41
|
cwd: str | None = None,
|
|
42
|
+
password=None,
|
|
43
|
+
key=None,
|
|
44
|
+
env_path=None
|
|
17
45
|
|
|
18
46
|
):
|
|
47
|
+
cmd = get_print_sudo_cmd(
|
|
48
|
+
cmd=cmd,
|
|
49
|
+
password=password,
|
|
50
|
+
key=key,
|
|
51
|
+
env_path=env_path
|
|
52
|
+
)
|
|
19
53
|
remote = get_remote_bash(
|
|
20
54
|
cmd=cmd,
|
|
21
55
|
cwd=cwd
|
|
@@ -25,6 +59,8 @@ def get_remote_cmd(
|
|
|
25
59
|
remote=remote
|
|
26
60
|
)
|
|
27
61
|
return full
|
|
62
|
+
|
|
63
|
+
|
|
28
64
|
def execute_cmd(
|
|
29
65
|
*args,
|
|
30
66
|
outfile=None,
|
|
@@ -46,8 +82,18 @@ def run_local_cmd(
|
|
|
46
82
|
outfile: Optional[str] = None,
|
|
47
83
|
shell=True,
|
|
48
84
|
text=True,
|
|
49
|
-
capture_output=True
|
|
85
|
+
capture_output=True,
|
|
86
|
+
user_at_host: str=None,
|
|
87
|
+
password=None,
|
|
88
|
+
key=None,
|
|
89
|
+
env_path=None
|
|
50
90
|
) -> str:
|
|
91
|
+
cmd = get_print_sudo_cmd(
|
|
92
|
+
cmd=cmd,
|
|
93
|
+
password=password,
|
|
94
|
+
key=key,
|
|
95
|
+
env_path=env_path
|
|
96
|
+
)
|
|
51
97
|
return execute_cmd(
|
|
52
98
|
cmd,
|
|
53
99
|
outfile=outfile,
|
|
@@ -64,12 +110,21 @@ def run_remote_cmd(
|
|
|
64
110
|
outfile: Optional[str] = None,
|
|
65
111
|
shell=True,
|
|
66
112
|
text=True,
|
|
67
|
-
capture_output=True
|
|
113
|
+
capture_output=True,
|
|
114
|
+
password=None,
|
|
115
|
+
key=None,
|
|
116
|
+
env_path=None
|
|
68
117
|
) -> str:
|
|
69
118
|
"""
|
|
70
119
|
Run on remote via SSH; capture stdout+stderr locally; write to local outfile.
|
|
71
120
|
NOTE: we do *not* try to write the file on the remote to avoid later scp.
|
|
72
121
|
"""
|
|
122
|
+
cmd = get_print_sudo_cmd(
|
|
123
|
+
cmd=cmd,
|
|
124
|
+
password=password,
|
|
125
|
+
key=key,
|
|
126
|
+
env_path=env_path
|
|
127
|
+
)
|
|
73
128
|
# wrap in bash -lc for PATH/profile + allow 'cd && ...'
|
|
74
129
|
cmd = get_remote_cmd(
|
|
75
130
|
cmd=cmd,
|
|
@@ -83,6 +138,7 @@ def run_remote_cmd(
|
|
|
83
138
|
text=text,
|
|
84
139
|
capture_output=capture_output
|
|
85
140
|
)
|
|
141
|
+
|
|
86
142
|
def run_cmd(
|
|
87
143
|
cmd: str=None,
|
|
88
144
|
cwd: str | None = None,
|
|
@@ -90,8 +146,12 @@ def run_cmd(
|
|
|
90
146
|
shell=True,
|
|
91
147
|
text=True,
|
|
92
148
|
capture_output=True,
|
|
93
|
-
user_at_host: str=None
|
|
149
|
+
user_at_host: str=None,
|
|
150
|
+
password=None,
|
|
151
|
+
key=None,
|
|
152
|
+
env_path=None
|
|
94
153
|
) -> str:
|
|
154
|
+
|
|
95
155
|
if user_at_host:
|
|
96
156
|
return run_ssh_cmd(
|
|
97
157
|
user_at_host=user_at_host,
|
|
@@ -100,7 +160,10 @@ def run_cmd(
|
|
|
100
160
|
outfile=outfile,
|
|
101
161
|
shell=shell,
|
|
102
162
|
text=text,
|
|
103
|
-
capture_output=capture_output
|
|
163
|
+
capture_output=capture_output,
|
|
164
|
+
password=password,
|
|
165
|
+
key=key,
|
|
166
|
+
env_path=env_path
|
|
104
167
|
)
|
|
105
168
|
return run_local_cmd(
|
|
106
169
|
cmd=cmd,
|
|
@@ -108,7 +171,10 @@ def run_cmd(
|
|
|
108
171
|
outfile=outfile,
|
|
109
172
|
shell=shell,
|
|
110
173
|
text=text,
|
|
111
|
-
capture_output=capture_output
|
|
174
|
+
capture_output=capture_output,
|
|
175
|
+
password=password,
|
|
176
|
+
key=key,
|
|
177
|
+
env_path=env_path
|
|
112
178
|
)
|
|
113
179
|
run_ssh_cmd = run_remote_cmd
|
|
114
180
|
remote_cmd = run_remote_cmd
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: abstract_utilities
|
|
3
|
-
Version: 0.2.2.
|
|
3
|
+
Version: 0.2.2.421
|
|
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
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
abstract_utilities/__init__.py,sha256=
|
|
1
|
+
abstract_utilities/__init__.py,sha256=hnDgg4ErEvB4kQ9j1GyN-wex9ba_XqTmz1Etf_i-XC8,6380
|
|
2
2
|
abstract_utilities/abstract_classes.py,sha256=A6-FNDQb2P_jcyt01Kc5SuY2QawLVKNjQ-rDGfsn4rA,2461
|
|
3
3
|
abstract_utilities/class_utils.py,sha256=-YHkdbaChRIz9YLXJlFF4m7VkdwUCts_HOUbKXxkrYA,12735
|
|
4
4
|
abstract_utilities/collator_utils.py,sha256=9exNoZAr9rABGYTwZOn7hdLbpnMtRd2AgfU7yjZrXGw,2348
|
|
@@ -37,21 +37,21 @@ abstract_utilities/env_utils/envy_it.py,sha256=lGkTB3AOY1KTRfQgtJji_yjSVVt0FV9YT
|
|
|
37
37
|
abstract_utilities/env_utils/imports/__init__.py,sha256=LVIEQXKiAmaKKWxPxfSJKe7JGWi4RDt4eatm_VG-WUI,44
|
|
38
38
|
abstract_utilities/env_utils/imports/imports.py,sha256=ZrGEf-J2lyVbb4MrNBX3DwHR0o-frba52RbPkypNvao,355
|
|
39
39
|
abstract_utilities/env_utils/imports/utils.py,sha256=oB7WhIm_-cHLrUHRXypZGCdWUtNRyePaVO5_kq5Cv84,4490
|
|
40
|
-
abstract_utilities/file_utils/__init__.py,sha256=
|
|
40
|
+
abstract_utilities/file_utils/__init__.py,sha256=I4md5xU5nuBuKyxumvKmnrR0-UgBePX9QfY-QNS-Zso,101
|
|
41
41
|
abstract_utilities/file_utils/req.py,sha256=DicCS80V4L8GPWr7lBKDR_gTC1WI9o8lMC2IYLyDUBk,12105
|
|
42
42
|
abstract_utilities/file_utils/file_utils/__init__.py,sha256=fm_uNRnfKfZOIg7e1HXhWbHac5VoUgRD2iTO5cxLkA0,160
|
|
43
43
|
abstract_utilities/file_utils/file_utils/file_filters.py,sha256=khfbonAPEAhW1wxfFo0I4dawYPCrIKEjNc7VKb1RvzA,3437
|
|
44
44
|
abstract_utilities/file_utils/file_utils/file_reader.py,sha256=2MRj2PGKq4C-iKL8dmhHwWnhmA8GPVsNaWkTREOF9vo,24545
|
|
45
|
-
abstract_utilities/file_utils/file_utils/file_utils.py,sha256=
|
|
45
|
+
abstract_utilities/file_utils/file_utils/file_utils.py,sha256=jCZGSE1hD_xHMHH3cJxJNb_hMRzpXH9Puyw5lbxtrks,6964
|
|
46
46
|
abstract_utilities/file_utils/file_utils/filter_params.py,sha256=NF692W0cBhEsbtmaVzb8EKMAasasHDElSRaC9fnzYwE,3382
|
|
47
47
|
abstract_utilities/file_utils/file_utils/imports.py,sha256=SXCMBuHUwqXbfRBk4LjKehsBKZa8-Po5UfEcNTwn4Es,24
|
|
48
48
|
abstract_utilities/file_utils/file_utils/map_utils.py,sha256=B_MlkLP8s-o0yU0R3Y2LcTpBntBzysJO18qq181xz9c,1043
|
|
49
49
|
abstract_utilities/file_utils/file_utils/pdf_utils.py,sha256=D_wg8h-SapCvqinxRIKxMri1jWZNpr5jGvKq9EJePfY,10335
|
|
50
50
|
abstract_utilities/file_utils/imports/__init__.py,sha256=0nezbIo1RqmfZ7pZ0V3kxZDNchNWH8wVATnnvNeILMo,101
|
|
51
|
-
abstract_utilities/file_utils/imports/classes.py,sha256=
|
|
51
|
+
abstract_utilities/file_utils/imports/classes.py,sha256=hNOw48TPAkcDwOY530I7DiYjIfPjVXwEtvb_vN00vdg,13186
|
|
52
52
|
abstract_utilities/file_utils/imports/constants.py,sha256=kSWXjZrbM7MmkytpiCFnsEJcfhPGI5ztUmrvTmT1xpU,1571
|
|
53
53
|
abstract_utilities/file_utils/imports/imports.py,sha256=OjHHuys4ue01PjTIBJuOBAseWUN9pxmAvWsPEj0QcCw,532
|
|
54
|
-
abstract_utilities/file_utils/imports/module_imports.py,sha256=
|
|
54
|
+
abstract_utilities/file_utils/imports/module_imports.py,sha256=jhigHKn-tA98-nKvnp2WBeD9vQrC0xQ10AmKIUOV1r4,247
|
|
55
55
|
abstract_utilities/robust_reader/__init__.py,sha256=7JVGEqZ2VFyFF06cqQ8TFz8EyreOB7Jhisnd69rxL-8,28
|
|
56
56
|
abstract_utilities/robust_reader/file_reader2.py,sha256=U-5opkLu-bct091Eb-5CiNBTf0UFoSITYi8zR-Sz38w,25077
|
|
57
57
|
abstract_utilities/robust_reader/file_readers.py,sha256=U-5opkLu-bct091Eb-5CiNBTf0UFoSITYi8zR-Sz38w,25077
|
|
@@ -73,8 +73,8 @@ abstract_utilities/ssh_utils/__init__.py,sha256=-DxUpOmfMi5zdG3lu93uT9MziZ-I_anw
|
|
|
73
73
|
abstract_utilities/ssh_utils/classes.py,sha256=3Q9BfLpyagNFYyiF4bt-5UCezeUJv9NK9YAFdTsLCV0,4802
|
|
74
74
|
abstract_utilities/ssh_utils/imports.py,sha256=7-pVJK1RfR0KiZsv0mNYGPuNXA4iYqmDvqbAR9h1llU,371
|
|
75
75
|
abstract_utilities/ssh_utils/pexpect_utils.py,sha256=JBdOIXBTXAqE5TrsFjmPWJgwSaWyRJN8rbJ6y3_zKPY,10556
|
|
76
|
-
abstract_utilities/ssh_utils/utils.py,sha256=
|
|
77
|
-
abstract_utilities-0.2.2.
|
|
78
|
-
abstract_utilities-0.2.2.
|
|
79
|
-
abstract_utilities-0.2.2.
|
|
80
|
-
abstract_utilities-0.2.2.
|
|
76
|
+
abstract_utilities/ssh_utils/utils.py,sha256=smUWAx3nW1h0etTndJ_te9bkUX5YzQ8kYd9_gD1TXLk,4882
|
|
77
|
+
abstract_utilities-0.2.2.421.dist-info/METADATA,sha256=gqoBTuNFePTshXPoSCS4eCuZtmvpVNhrpMtGZsnioT4,28108
|
|
78
|
+
abstract_utilities-0.2.2.421.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
79
|
+
abstract_utilities-0.2.2.421.dist-info/top_level.txt,sha256=BF0GZ0xVFfN1K-hFIWPO3viNsOs1sSF86n1vHBg39FM,19
|
|
80
|
+
abstract_utilities-0.2.2.421.dist-info/RECORD,,
|
|
File without changes
|
{abstract_utilities-0.2.2.419.dist-info → abstract_utilities-0.2.2.421.dist-info}/top_level.txt
RENAMED
|
File without changes
|