abstract-utilities 0.2.2.540__py3-none-any.whl → 0.2.2.593__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/class_utils/caller_utils.py +18 -0
- abstract_utilities/class_utils/global_utils.py +3 -2
- abstract_utilities/class_utils/imports/imports.py +1 -1
- abstract_utilities/directory_utils/src/directory_utils.py +17 -1
- abstract_utilities/file_utils/imports/imports.py +0 -4
- abstract_utilities/file_utils/imports/module_imports.py +1 -1
- abstract_utilities/file_utils/src/__init__.py +2 -3
- abstract_utilities/file_utils/src/file_filters/__init__.py +4 -0
- abstract_utilities/file_utils/src/file_filters/ensure_utils.py +118 -0
- abstract_utilities/file_utils/src/file_filters/filter_params.py +86 -0
- abstract_utilities/file_utils/src/file_filters/filter_utils.py +78 -0
- abstract_utilities/file_utils/src/file_filters/predicate_utils.py +114 -0
- abstract_utilities/file_utils/src/file_reader.py +0 -1
- abstract_utilities/file_utils/src/find_collect.py +10 -86
- abstract_utilities/file_utils/src/find_content.py +210 -0
- abstract_utilities/file_utils/src/reader_utils/__init__.py +4 -0
- abstract_utilities/file_utils/src/reader_utils/directory_reader.py +53 -0
- abstract_utilities/file_utils/src/reader_utils/file_reader.py +543 -0
- abstract_utilities/file_utils/src/reader_utils/file_readers.py +376 -0
- abstract_utilities/file_utils/src/reader_utils/imports.py +18 -0
- abstract_utilities/file_utils/src/reader_utils/pdf_utils.py +300 -0
- abstract_utilities/import_utils/circular_import_finder.py +222 -0
- abstract_utilities/import_utils/circular_import_finder2.py +118 -0
- abstract_utilities/import_utils/imports/module_imports.py +3 -1
- abstract_utilities/import_utils/src/clean_imports.py +156 -25
- abstract_utilities/import_utils/src/dot_utils.py +11 -0
- abstract_utilities/import_utils/src/extract_utils.py +4 -0
- abstract_utilities/import_utils/src/import_functions.py +46 -2
- abstract_utilities/import_utils/src/pkg_utils.py +58 -4
- abstract_utilities/import_utils/src/sysroot_utils.py +56 -1
- abstract_utilities/log_utils/log_file.py +3 -2
- abstract_utilities/path_utils/path_utils.py +25 -23
- abstract_utilities/safe_utils/safe_utils.py +30 -0
- {abstract_utilities-0.2.2.540.dist-info → abstract_utilities-0.2.2.593.dist-info}/METADATA +1 -1
- {abstract_utilities-0.2.2.540.dist-info → abstract_utilities-0.2.2.593.dist-info}/RECORD +37 -23
- {abstract_utilities-0.2.2.540.dist-info → abstract_utilities-0.2.2.593.dist-info}/WHEEL +0 -0
- {abstract_utilities-0.2.2.540.dist-info → abstract_utilities-0.2.2.593.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
from .file_filters import *
|
|
2
|
+
from .reader_utils import *
|
|
3
|
+
from .find_collect import *
|
|
4
|
+
STOP_SEARCH = False
|
|
5
|
+
|
|
6
|
+
def request_find_console_stop():
|
|
7
|
+
global STOP_SEARCH
|
|
8
|
+
STOP_SEARCH = True
|
|
9
|
+
|
|
10
|
+
def reset_find_console_stop():
|
|
11
|
+
global STOP_SEARCH
|
|
12
|
+
STOP_SEARCH = False
|
|
13
|
+
|
|
14
|
+
def get_contents(
|
|
15
|
+
full_path=None,
|
|
16
|
+
parse_lines=False,
|
|
17
|
+
content=None
|
|
18
|
+
):
|
|
19
|
+
if full_path:
|
|
20
|
+
content = content or read_any_file(full_path)
|
|
21
|
+
if content:
|
|
22
|
+
if parse_lines:
|
|
23
|
+
content = str(content).split('\n')
|
|
24
|
+
return make_list(content)
|
|
25
|
+
return []
|
|
26
|
+
|
|
27
|
+
def _normalize(s: str, strip_comments=True, collapse_ws=True, lower=True):
|
|
28
|
+
if s is None:
|
|
29
|
+
return ""
|
|
30
|
+
if strip_comments:
|
|
31
|
+
s = s.split('//', 1)[0]
|
|
32
|
+
if collapse_ws:
|
|
33
|
+
s = re.sub(r'\s+', ' ', s)
|
|
34
|
+
if lower:
|
|
35
|
+
s = s.lower()
|
|
36
|
+
return s.strip()
|
|
37
|
+
|
|
38
|
+
def stringInContent(content, strings, total_strings=False, normalize=False):
|
|
39
|
+
if not content:
|
|
40
|
+
return False
|
|
41
|
+
if normalize:
|
|
42
|
+
c = _normalize(str(content))
|
|
43
|
+
|
|
44
|
+
found = [s for s in strings if _normalize(s) and _normalize(s) in c]
|
|
45
|
+
else:
|
|
46
|
+
c = str(content)
|
|
47
|
+
found = [s for s in strings if s and s in c]
|
|
48
|
+
if not found:
|
|
49
|
+
return False
|
|
50
|
+
return len(found) == len(strings) if total_strings else True
|
|
51
|
+
def find_file(content, spec_line, strings, total_strings=False):
|
|
52
|
+
lines = content.split('\n')
|
|
53
|
+
if 1 <= spec_line <= len(lines):
|
|
54
|
+
return stringInContent(lines[spec_line - 1], strings, total_strings=total_strings)
|
|
55
|
+
return False
|
|
56
|
+
def find_lines(content, strings, total_strings=False, normalize=True, any_per_line=True):
|
|
57
|
+
lines = content.split('\n')
|
|
58
|
+
hits = []
|
|
59
|
+
for i, line in enumerate(lines):
|
|
60
|
+
# match one line either if ANY string matches or if ALL match (configurable)
|
|
61
|
+
if any_per_line:
|
|
62
|
+
match = stringInContent(line, strings, total_strings=False, normalize=normalize)
|
|
63
|
+
else:
|
|
64
|
+
match = stringInContent(line, strings, total_strings=True, normalize=normalize)
|
|
65
|
+
if match:
|
|
66
|
+
hits.append({"line": i+1, "content": line})
|
|
67
|
+
return hits
|
|
68
|
+
def getPaths(files, strings):
|
|
69
|
+
tot_strings = strings
|
|
70
|
+
nu_files, found_paths = [], []
|
|
71
|
+
if isinstance(strings,list):
|
|
72
|
+
if len(strings) >1:
|
|
73
|
+
tot_strings = '\n'.join(strings)
|
|
74
|
+
else:
|
|
75
|
+
if len(strings) == 0:
|
|
76
|
+
return nu_files, found_paths
|
|
77
|
+
tot_strings = strings[0]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
for file_path in files:
|
|
81
|
+
try:
|
|
82
|
+
og_content = read_any_file(file_path)
|
|
83
|
+
if tot_strings not in og_content:
|
|
84
|
+
continue
|
|
85
|
+
if file_path not in nu_files:
|
|
86
|
+
nu_files.append(file_path)
|
|
87
|
+
ogLines = og_content.split('\n')
|
|
88
|
+
# find all occurrences of the block
|
|
89
|
+
for m in re.finditer(re.escape(tot_strings), og_content):
|
|
90
|
+
start_line = og_content[:m.start()].count('\n') + 1 # 1-based
|
|
91
|
+
curr = {'file_path': file_path, 'lines': []}
|
|
92
|
+
for j in range(len(strings)):
|
|
93
|
+
ln = start_line + j
|
|
94
|
+
curr['lines'].append({'line': ln, 'content': ogLines[ln - 1]})
|
|
95
|
+
found_paths.append(curr)
|
|
96
|
+
except Exception as e:
|
|
97
|
+
print(f"{e}")
|
|
98
|
+
return nu_files, found_paths
|
|
99
|
+
|
|
100
|
+
def findContent(
|
|
101
|
+
*args,
|
|
102
|
+
strings: list=[],
|
|
103
|
+
total_strings=True,
|
|
104
|
+
parse_lines=False,
|
|
105
|
+
spec_line=False,
|
|
106
|
+
get_lines=True,
|
|
107
|
+
diffs=False,
|
|
108
|
+
**kwargs
|
|
109
|
+
):
|
|
110
|
+
global STOP_SEARCH
|
|
111
|
+
kwargs["directories"] = ensure_directories(*args,**kwargs)
|
|
112
|
+
|
|
113
|
+
found_paths = []
|
|
114
|
+
|
|
115
|
+
dirs, files = get_files_and_dirs(
|
|
116
|
+
**kwargs
|
|
117
|
+
)
|
|
118
|
+
nu_files, found_paths = getPaths(files, strings)
|
|
119
|
+
|
|
120
|
+
if diffs and found_paths:
|
|
121
|
+
return found_paths
|
|
122
|
+
|
|
123
|
+
for file_path in nu_files:
|
|
124
|
+
if STOP_SEARCH:
|
|
125
|
+
return found_paths # early exit
|
|
126
|
+
|
|
127
|
+
if file_path:
|
|
128
|
+
og_content = read_any_file(file_path)
|
|
129
|
+
contents = get_contents(
|
|
130
|
+
file_path,
|
|
131
|
+
parse_lines=parse_lines,
|
|
132
|
+
content=og_content
|
|
133
|
+
)
|
|
134
|
+
found = False
|
|
135
|
+
for content in contents:
|
|
136
|
+
if STOP_SEARCH:
|
|
137
|
+
return found_paths # bail out cleanly
|
|
138
|
+
|
|
139
|
+
if stringInContent(content, strings, total_strings=True, normalize=True):
|
|
140
|
+
found = True
|
|
141
|
+
if spec_line:
|
|
142
|
+
found = find_file(og_content, spec_line, strings, total_strings=True)
|
|
143
|
+
if found:
|
|
144
|
+
if get_lines:
|
|
145
|
+
lines = find_lines(
|
|
146
|
+
og_content,
|
|
147
|
+
strings=strings,
|
|
148
|
+
total_strings=False,
|
|
149
|
+
normalize=True,
|
|
150
|
+
any_per_line=True
|
|
151
|
+
)
|
|
152
|
+
if lines:
|
|
153
|
+
file_path = {"file_path": file_path, "lines": lines}
|
|
154
|
+
found_paths.append(file_path)
|
|
155
|
+
break
|
|
156
|
+
return found_paths
|
|
157
|
+
def return_function(start_dir=None,preferred_dir=None,basenames=None,functionName=None):
|
|
158
|
+
if basenames:
|
|
159
|
+
basenames = make_list(basenames)
|
|
160
|
+
abstract_file_finder = AbstractFileFinderImporter(start_dir=start_dir,preferred_dir=preferred_dir)
|
|
161
|
+
paths = abstract_file_finder.find_paths(basenames)
|
|
162
|
+
func = abstract_file_finder.import_function_from_path(paths[0], functionName)
|
|
163
|
+
return func
|
|
164
|
+
def getLineNums(file_path):
|
|
165
|
+
lines=[]
|
|
166
|
+
if file_path and isinstance(file_path,dict):
|
|
167
|
+
lines = file_path.get('lines')
|
|
168
|
+
file_path = file_path.get('file_path')
|
|
169
|
+
return file_path,lines
|
|
170
|
+
def get_line_content(obj):
|
|
171
|
+
line,content=None,None
|
|
172
|
+
if obj and isinstance(obj,dict):
|
|
173
|
+
line=obj.get('line')
|
|
174
|
+
content = obj.get('content')
|
|
175
|
+
#print(f"line: {line}\ncontent: {content}")
|
|
176
|
+
return line,content
|
|
177
|
+
def get_edit(file_path):
|
|
178
|
+
if file_path and os.path.isfile(file_path):
|
|
179
|
+
os.system(f"code {file_path}")
|
|
180
|
+
input()
|
|
181
|
+
def editLines(file_paths):
|
|
182
|
+
for file_path in file_paths:
|
|
183
|
+
file_path,lines = getLineNums(file_path)
|
|
184
|
+
for obj in lines:
|
|
185
|
+
line,content = get_line_content(obj)
|
|
186
|
+
get_edit(file_path)
|
|
187
|
+
def findContentAndEdit(*args,
|
|
188
|
+
strings: list=[],
|
|
189
|
+
total_strings=True,
|
|
190
|
+
parse_lines=False,
|
|
191
|
+
spec_line=False,
|
|
192
|
+
get_lines=True,
|
|
193
|
+
edit_lines=False,
|
|
194
|
+
diffs=False,
|
|
195
|
+
**kwargs
|
|
196
|
+
):
|
|
197
|
+
file_paths = findContent(
|
|
198
|
+
*args,
|
|
199
|
+
strings=strings,
|
|
200
|
+
total_strings=total_strings,
|
|
201
|
+
parse_lines=parse_lines,
|
|
202
|
+
spec_line=spec_line,
|
|
203
|
+
get_lines=get_lines,
|
|
204
|
+
diffs=diffs,
|
|
205
|
+
**kwargs
|
|
206
|
+
)
|
|
207
|
+
if edit_lines:
|
|
208
|
+
editLines(file_paths)
|
|
209
|
+
return file_paths
|
|
210
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from .imports import *
|
|
2
|
+
from .file_readers import *
|
|
3
|
+
# ─── Example walker ──────────────────────────────────────────────────────────
|
|
4
|
+
_logger = get_logFile(__name__)
|
|
5
|
+
|
|
6
|
+
def read_files(files=None,allowed=None):
|
|
7
|
+
allowed = allowed or make_allowed_predicate()
|
|
8
|
+
files = get_all_files(make_list(files or []),allowed)
|
|
9
|
+
collected = {}
|
|
10
|
+
for full_path in files:
|
|
11
|
+
ext = Path(full_path).suffix.lower()
|
|
12
|
+
|
|
13
|
+
# ——— 1) Pure-text quick reads —————————————
|
|
14
|
+
if ext in {'.txt', '.md', '.csv', '.tsv', '.log'}:
|
|
15
|
+
try:
|
|
16
|
+
with open(full_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
17
|
+
collected[full_path] = f.read()
|
|
18
|
+
except Exception as e:
|
|
19
|
+
#_logger.warning(f"Failed to read {full_path} as text: {e}")
|
|
20
|
+
pass
|
|
21
|
+
continue
|
|
22
|
+
|
|
23
|
+
# ——— 2) Try your DataFrame loader ——————————
|
|
24
|
+
try:
|
|
25
|
+
df_or_map = get_df(full_path)
|
|
26
|
+
if isinstance(df_or_map, (pd.DataFrame, gpd.GeoDataFrame)):
|
|
27
|
+
collected[full_path] = df_or_map
|
|
28
|
+
#_logger.info(f"Loaded DataFrame: {full_path}")
|
|
29
|
+
continue
|
|
30
|
+
|
|
31
|
+
if isinstance(df_or_map, dict):
|
|
32
|
+
for sheet, df in df_or_map.items():
|
|
33
|
+
key = f"{full_path}::[{sheet}]"
|
|
34
|
+
collected[key] = df
|
|
35
|
+
#_logger.info(f"Loaded sheet DataFrame: {key}")
|
|
36
|
+
continue
|
|
37
|
+
except Exception as e:
|
|
38
|
+
#_logger.debug(f"get_df failed for {full_path}: {e}")
|
|
39
|
+
pass
|
|
40
|
+
# ——— 3) Fallback to generic text extractor ————
|
|
41
|
+
try:
|
|
42
|
+
parts = read_file_as_text(full_path) # List[str]
|
|
43
|
+
combined = "\n\n".join(parts)
|
|
44
|
+
collected[full_path] = combined
|
|
45
|
+
#_logger.info(f"Read fallback text for: {full_path}")
|
|
46
|
+
except Exception as e:
|
|
47
|
+
_logger.warning(f"Could not read {full_path} at all: {e}")
|
|
48
|
+
|
|
49
|
+
return collected
|
|
50
|
+
def read_directory(*args,**kwargs) -> Dict[str, Union[pd.DataFrame, str]]:
|
|
51
|
+
directories,cfg,allowed,include_files,recursive = get_file_filters(*args,**kwargs)
|
|
52
|
+
|
|
53
|
+
return read_files(files=directories[0],allowed=allowed)
|