abstract-paths 0.0.0.14__tar.gz
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_paths-0.0.0.14/PKG-INFO +49 -0
- abstract_paths-0.0.0.14/README.md +28 -0
- abstract_paths-0.0.0.14/pyproject.toml +3 -0
- abstract_paths-0.0.0.14/setup.cfg +4 -0
- abstract_paths-0.0.0.14/setup.py +30 -0
- abstract_paths-0.0.0.14/src/abstract_paths/__init__.py +7 -0
- abstract_paths-0.0.0.14/src/abstract_paths/abstractFileImporter.py +88 -0
- abstract_paths-0.0.0.14/src/abstract_paths/content_utils/__init__.py +1 -0
- abstract_paths-0.0.0.14/src/abstract_paths/content_utils/imports.py +1 -0
- abstract_paths-0.0.0.14/src/abstract_paths/content_utils/src/__init__.py +6 -0
- abstract_paths-0.0.0.14/src/abstract_paths/content_utils/src/file_utils.py +233 -0
- abstract_paths-0.0.0.14/src/abstract_paths/content_utils/src/find_content.py +69 -0
- abstract_paths-0.0.0.14/src/abstract_paths/directory_reader/__init__.py +1 -0
- abstract_paths-0.0.0.14/src/abstract_paths/directory_reader/directory_reader.py +67 -0
- abstract_paths-0.0.0.14/src/abstract_paths/file_filtering/__init__.py +1 -0
- abstract_paths-0.0.0.14/src/abstract_paths/file_filtering/file_filters.py +143 -0
- abstract_paths-0.0.0.14/src/abstract_paths/file_filtering/test read.py +2 -0
- abstract_paths-0.0.0.14/src/abstract_paths/file_handlers/__init__.py +2 -0
- abstract_paths-0.0.0.14/src/abstract_paths/file_handlers/file_readers.py +389 -0
- abstract_paths-0.0.0.14/src/abstract_paths/file_handlers/pdf_utils.py +305 -0
- abstract_paths-0.0.0.14/src/abstract_paths/getnu.py +38 -0
- abstract_paths-0.0.0.14/src/abstract_paths.egg-info/PKG-INFO +49 -0
- abstract_paths-0.0.0.14/src/abstract_paths.egg-info/SOURCES.txt +24 -0
- abstract_paths-0.0.0.14/src/abstract_paths.egg-info/dependency_links.txt +1 -0
- abstract_paths-0.0.0.14/src/abstract_paths.egg-info/requires.txt +1 -0
- abstract_paths-0.0.0.14/src/abstract_paths.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: abstract_paths
|
|
3
|
+
Version: 0.0.0.14
|
|
4
|
+
Author: putkoff
|
|
5
|
+
Author-email: partners@abstractendeavors.com
|
|
6
|
+
Classifier: Development Status :: 3 - Alpha
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: flask
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: requires-dist
|
|
20
|
+
Dynamic: requires-python
|
|
21
|
+
|
|
22
|
+
# Unknown Package (vUnknown Version)
|
|
23
|
+
|
|
24
|
+
No description available
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install Unknown Package
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Dependencies
|
|
33
|
+
|
|
34
|
+
None
|
|
35
|
+
|
|
36
|
+
## Modules
|
|
37
|
+
|
|
38
|
+
### src/abstract_paths/abstractFileImporter.py
|
|
39
|
+
|
|
40
|
+
Description of script based on prompt: You are analyzing a Python script 'abstractFileImp (mock response)
|
|
41
|
+
|
|
42
|
+
### src/abstract_paths/__init__.py
|
|
43
|
+
|
|
44
|
+
Description of script based on prompt: You are analyzing a Python script '__init__.py' lo (mock response)
|
|
45
|
+
|
|
46
|
+
### src/abstract_paths/getnu.py
|
|
47
|
+
|
|
48
|
+
Description of script based on prompt: You are analyzing a Python script 'getnu.py' locat (mock response)
|
|
49
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Unknown Package (vUnknown Version)
|
|
2
|
+
|
|
3
|
+
No description available
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install Unknown Package
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Dependencies
|
|
12
|
+
|
|
13
|
+
None
|
|
14
|
+
|
|
15
|
+
## Modules
|
|
16
|
+
|
|
17
|
+
### src/abstract_paths/abstractFileImporter.py
|
|
18
|
+
|
|
19
|
+
Description of script based on prompt: You are analyzing a Python script 'abstractFileImp (mock response)
|
|
20
|
+
|
|
21
|
+
### src/abstract_paths/__init__.py
|
|
22
|
+
|
|
23
|
+
Description of script based on prompt: You are analyzing a Python script '__init__.py' lo (mock response)
|
|
24
|
+
|
|
25
|
+
### src/abstract_paths/getnu.py
|
|
26
|
+
|
|
27
|
+
Description of script based on prompt: You are analyzing a Python script 'getnu.py' locat (mock response)
|
|
28
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import setuptools
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
5
|
+
long_description = fh.read()
|
|
6
|
+
|
|
7
|
+
setuptools.setup(
|
|
8
|
+
name='abstract_paths',
|
|
9
|
+
version='0.0.0.14',
|
|
10
|
+
author='putkoff',
|
|
11
|
+
author_email='partners@abstractendeavors.com',
|
|
12
|
+
description="",
|
|
13
|
+
long_description=long_description,
|
|
14
|
+
long_description_content_type='text/markdown',
|
|
15
|
+
classifiers=[
|
|
16
|
+
'Development Status :: 3 - Alpha',
|
|
17
|
+
'Intended Audience :: Developers',
|
|
18
|
+
'License :: OSI Approved :: MIT License',
|
|
19
|
+
'Programming Language :: Python :: 3',
|
|
20
|
+
'Programming Language :: Python :: 3.11',
|
|
21
|
+
],
|
|
22
|
+
install_requires=['flask'],
|
|
23
|
+
package_dir={"": "src"},
|
|
24
|
+
packages=setuptools.find_packages(where="src"),
|
|
25
|
+
python_requires=">=3.6",
|
|
26
|
+
# Add this line to include wheel format in your distribution
|
|
27
|
+
setup_requires=['wheel'],
|
|
28
|
+
include_package_data=True, # Include package data specified in MANIFEST.in
|
|
29
|
+
|
|
30
|
+
)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import importlib.util
|
|
4
|
+
from abstract_utilities import *
|
|
5
|
+
class AbstractFileFinderImporter:
|
|
6
|
+
def __init__(self, start_dir=None, preferred_dir=None):
|
|
7
|
+
start_dir = start_dir or '.'
|
|
8
|
+
self.start_dir = os.path.abspath(start_dir)
|
|
9
|
+
self.preferred_dir = os.path.abspath(preferred_dir) if preferred_dir else None
|
|
10
|
+
|
|
11
|
+
def find_paths(self, basenames):
|
|
12
|
+
"""
|
|
13
|
+
Finds all paths to files with the given basename(s) starting from start_dir.
|
|
14
|
+
"""
|
|
15
|
+
if isinstance(basenames, str):
|
|
16
|
+
basenames = [basenames]
|
|
17
|
+
|
|
18
|
+
matching_paths = []
|
|
19
|
+
|
|
20
|
+
for root, dirs, files in os.walk(self.start_dir):
|
|
21
|
+
found_files = set(basenames).intersection(files)
|
|
22
|
+
for basename in found_files:
|
|
23
|
+
full_path = os.path.join(root, basename)
|
|
24
|
+
matching_paths.append(full_path)
|
|
25
|
+
|
|
26
|
+
# Remove duplicates and sort paths by distance from start_dir
|
|
27
|
+
matching_paths = list(set(matching_paths))
|
|
28
|
+
matching_paths.sort(key=lambda path: self._compute_distance(path))
|
|
29
|
+
|
|
30
|
+
return matching_paths
|
|
31
|
+
|
|
32
|
+
def _compute_distance(self, path):
|
|
33
|
+
path = os.path.abspath(path)
|
|
34
|
+
if self.preferred_dir and os.path.commonpath([self.preferred_dir, path]) == self.preferred_dir:
|
|
35
|
+
return -1000 + self._path_length(path)
|
|
36
|
+
|
|
37
|
+
relative_path = os.path.relpath(path, self.start_dir)
|
|
38
|
+
distance = len(relative_path.split(os.sep))
|
|
39
|
+
|
|
40
|
+
return distance
|
|
41
|
+
|
|
42
|
+
def _path_length(self, path):
|
|
43
|
+
return len(path.split(os.sep))
|
|
44
|
+
|
|
45
|
+
def import_module_from_path(self, module_path):
|
|
46
|
+
"""
|
|
47
|
+
Dynamically imports a module from a given file path, handling relative imports within the module.
|
|
48
|
+
"""
|
|
49
|
+
module_name = os.path.splitext(os.path.basename(module_path))[0]
|
|
50
|
+
spec = importlib.util.spec_from_file_location(module_name, module_path)
|
|
51
|
+
module = importlib.util.module_from_spec(spec)
|
|
52
|
+
|
|
53
|
+
# Add the module's directory and any necessary subdirectories to sys.path temporarily
|
|
54
|
+
module_dir = os.path.dirname(module_path)
|
|
55
|
+
original_sys_path = list(sys.path)
|
|
56
|
+
sys.path.insert(0, module_dir)
|
|
57
|
+
|
|
58
|
+
# If `scripts` exists in the module directory, add it to sys.path
|
|
59
|
+
scripts_dir = os.path.join(module_dir, 'scripts')
|
|
60
|
+
if os.path.isdir(scripts_dir):
|
|
61
|
+
sys.path.insert(0, scripts_dir)
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
spec.loader.exec_module(module)
|
|
65
|
+
except Exception as e:
|
|
66
|
+
raise ImportError(f"Failed to import module {module_name}: {e}")
|
|
67
|
+
finally:
|
|
68
|
+
sys.path = original_sys_path # Restore original sys.path
|
|
69
|
+
|
|
70
|
+
return module
|
|
71
|
+
|
|
72
|
+
def import_function_from_path(self, module_path, function_name):
|
|
73
|
+
"""
|
|
74
|
+
Imports a specific function from a module file path.
|
|
75
|
+
"""
|
|
76
|
+
module = self.import_module_from_path(module_path)
|
|
77
|
+
if not hasattr(module, function_name):
|
|
78
|
+
raise AttributeError(f"Function {function_name} not found in module {module.__name__}")
|
|
79
|
+
|
|
80
|
+
return getattr(module, function_name)
|
|
81
|
+
|
|
82
|
+
def return_function(start_dir=None,preferred_dir=None,basenames=None,functionName=None):
|
|
83
|
+
if basenames:
|
|
84
|
+
basenames = make_list(basenames)
|
|
85
|
+
abstract_file_finder = AbstractFileFinderImporter(start_dir=start_dir,preferred_dir=preferred_dir)
|
|
86
|
+
paths = abstract_file_finder.find_paths(basenames)
|
|
87
|
+
func = abstract_file_finder.import_function_from_path(paths[0], functionName)
|
|
88
|
+
return func
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .src import *
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from ..file_handlers.file_readers import read_any_file
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import glob
|
|
3
|
+
from typing import Optional, Union, List, Dict
|
|
4
|
+
from collections import defaultdict
|
|
5
|
+
|
|
6
|
+
def normalize_paths(paths: Optional[Union[bool, str]] = True) -> str:
|
|
7
|
+
"""
|
|
8
|
+
Normalize the paths parameter for glob pattern.
|
|
9
|
+
|
|
10
|
+
- If True, returns '**' for recursive search.
|
|
11
|
+
- If False or None, returns '_' (non-recursive placeholder).
|
|
12
|
+
- If str, returns the provided string.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
paths: The paths specification.
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
Normalized paths string.
|
|
19
|
+
"""
|
|
20
|
+
if paths is True:
|
|
21
|
+
return '**'
|
|
22
|
+
elif paths in (False, None):
|
|
23
|
+
return '_'
|
|
24
|
+
elif isinstance(paths, str):
|
|
25
|
+
return paths
|
|
26
|
+
raise ValueError(f"Invalid paths value: {paths}")
|
|
27
|
+
|
|
28
|
+
def normalize_extensions(exts: Optional[Union[bool, str, List[str]]] = True) -> str:
|
|
29
|
+
"""
|
|
30
|
+
Normalize the extensions parameter for glob pattern.
|
|
31
|
+
|
|
32
|
+
- If True, returns '*' for all files.
|
|
33
|
+
- If False or None, returns '_' (no extension filter).
|
|
34
|
+
- If str starting with '.', returns '*{exts}'.
|
|
35
|
+
- If str without '.', assumes it's the extension and adds '.'.
|
|
36
|
+
- If list of str, returns '*.' + '{ext1,ext2,...}' for multiple extensions.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
exts: The extensions specification.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
Normalized extensions string.
|
|
43
|
+
"""
|
|
44
|
+
if exts is True:
|
|
45
|
+
return '*'
|
|
46
|
+
elif exts in (False, None):
|
|
47
|
+
return '_'
|
|
48
|
+
elif isinstance(exts, str):
|
|
49
|
+
if exts.startswith('.'):
|
|
50
|
+
return f"*{exts}"
|
|
51
|
+
else:
|
|
52
|
+
return f"*.{exts}"
|
|
53
|
+
elif isinstance(exts, list):
|
|
54
|
+
if not exts:
|
|
55
|
+
return '*'
|
|
56
|
+
normalized = [e.lstrip('.') for e in exts]
|
|
57
|
+
return "*." + "{" + ",".join(normalized) + "}"
|
|
58
|
+
raise ValueError(f"Invalid exts value: {exts}")
|
|
59
|
+
|
|
60
|
+
def build_glob_pattern(
|
|
61
|
+
directory: str,
|
|
62
|
+
paths: Optional[Union[bool, str]] = True,
|
|
63
|
+
exts: Optional[Union[bool, str, List[str]]] = True
|
|
64
|
+
) -> str:
|
|
65
|
+
"""
|
|
66
|
+
Build the full glob search pattern by joining directory, paths, and extensions.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
directory: The base directory to search in.
|
|
70
|
+
paths: The paths specification (see normalize_paths).
|
|
71
|
+
exts: The extensions specification (see normalize_extensions).
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
The complete glob pattern string.
|
|
75
|
+
"""
|
|
76
|
+
norm_paths = normalize_paths(paths)
|
|
77
|
+
norm_exts = normalize_extensions(exts)
|
|
78
|
+
return os.path.join(directory, norm_paths, norm_exts)
|
|
79
|
+
|
|
80
|
+
def findGlobFiles(
|
|
81
|
+
directory: str,
|
|
82
|
+
paths: Optional[Union[bool, str]] = True,
|
|
83
|
+
exts: Optional[Union[bool, str, List[str]]] = True,
|
|
84
|
+
recursive: bool = True
|
|
85
|
+
) -> List[str]:
|
|
86
|
+
"""
|
|
87
|
+
Find files in the directory using glob based on the provided patterns.
|
|
88
|
+
|
|
89
|
+
This is the main entry point for file searching. It builds the glob pattern
|
|
90
|
+
and performs the search.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
directory: The base directory to search in.
|
|
94
|
+
paths: The paths specification (see normalize_paths).
|
|
95
|
+
exts: The extensions specification (see normalize_extensions).
|
|
96
|
+
recursive: Whether to search recursively (affects glob behavior).
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
List of matching file paths.
|
|
100
|
+
"""
|
|
101
|
+
search_pattern = build_glob_pattern(directory, paths, exts)
|
|
102
|
+
return glob.glob(search_pattern, recursive=recursive)
|
|
103
|
+
def get_e_normalized(f,exts):
|
|
104
|
+
norm_exts = normalize_extensions(exts)
|
|
105
|
+
if norm_exts == '_':
|
|
106
|
+
return True
|
|
107
|
+
norm_exts_spl = norm_exts.lstrip('*').split(',')
|
|
108
|
+
lstrip_exts = [norm_exts.lstrip('*.')]
|
|
109
|
+
brak_in_exts = '{' in norm_exts
|
|
110
|
+
def get_strip(f,e,norm_exts_spl,lstrip_exts,brak_in_exts):
|
|
111
|
+
if brak_in_exts:
|
|
112
|
+
f.endswith(e.lstrip('*.'))
|
|
113
|
+
return lstrip_exts
|
|
114
|
+
if any(get_strip(f,e,norm_exts_spl,lstrip_exts,brak_in_exts) for e in norm_exts_spl):
|
|
115
|
+
return True
|
|
116
|
+
return False
|
|
117
|
+
def build_directory_tree(
|
|
118
|
+
directory: str,
|
|
119
|
+
paths: Optional[Union[bool, str]] = True,
|
|
120
|
+
exts: Optional[Union[bool, str, List[str]]] = True,
|
|
121
|
+
recursive: bool = True,
|
|
122
|
+
include_files: bool = True,
|
|
123
|
+
prefix: str = ""
|
|
124
|
+
) -> str:
|
|
125
|
+
"""
|
|
126
|
+
Generate a text-based tree map of the directory structure.
|
|
127
|
+
|
|
128
|
+
This function uses os.walk to traverse the directory and builds a
|
|
129
|
+
printable tree string that represents the hierarchy. It can filter
|
|
130
|
+
files based on extensions if provided. The output is designed to be
|
|
131
|
+
easily copied to the clipboard for quick inspection of the dir structure.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
directory: The base directory to map.
|
|
135
|
+
paths: The paths specification (influences recursion if not True).
|
|
136
|
+
exts: The extensions to include (if include_files=True).
|
|
137
|
+
recursive: Whether to traverse recursively.
|
|
138
|
+
include_files: Whether to include files in the tree (True) or just dirs (False).
|
|
139
|
+
prefix: Internal prefix for indentation in recursive calls.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
A string representation of the directory tree.
|
|
143
|
+
"""
|
|
144
|
+
tree_str = []
|
|
145
|
+
directory = os.path.abspath(directory)
|
|
146
|
+
base_name = os.path.basename(directory)
|
|
147
|
+
tree_str.append(f"{prefix}{base_name}/")
|
|
148
|
+
|
|
149
|
+
if not recursive:
|
|
150
|
+
# Non-recursive: just list immediate contents
|
|
151
|
+
contents = os.listdir(directory)
|
|
152
|
+
dirs = [d for d in contents if os.path.isdir(os.path.join(directory, d))]
|
|
153
|
+
files = [f for f in contents if os.path.isfile(os.path.join(directory, f))]
|
|
154
|
+
|
|
155
|
+
for i, d in enumerate(sorted(dirs)):
|
|
156
|
+
is_last = (i == len(dirs) - 1) and not files
|
|
157
|
+
tree_str.append(f"{prefix}{'└── ' if is_last else '├── '}{d}/")
|
|
158
|
+
|
|
159
|
+
if include_files:
|
|
160
|
+
norm_exts = normalize_extensions(exts).lstrip('*') # For simple filtering
|
|
161
|
+
for i, f in enumerate(sorted(files)):
|
|
162
|
+
if norm_exts != '_' and not f.endswith(tuple(norm_exts.split(',')) if '{' in norm_exts else (norm_exts,)):
|
|
163
|
+
continue
|
|
164
|
+
is_last = (i == len(files) - 1)
|
|
165
|
+
tree_str.append(f"{prefix}{'└── ' if is_last else '├── '}{f}")
|
|
166
|
+
else:
|
|
167
|
+
# Recursive: use os.walk
|
|
168
|
+
file_list = findGlobFiles(directory, paths, exts, recursive=True) if include_files else []
|
|
169
|
+
dir_structure: Dict[str, List[str]] = defaultdict(list)
|
|
170
|
+
|
|
171
|
+
# Build dir -> subdirs/files mapping
|
|
172
|
+
for root, dirs, files in os.walk(directory):
|
|
173
|
+
rel_root = os.path.relpath(root, directory)
|
|
174
|
+
if rel_root != '.':
|
|
175
|
+
parent = os.path.dirname(rel_root)
|
|
176
|
+
dir_structure[parent].append(os.path.basename(rel_root) + '/')
|
|
177
|
+
|
|
178
|
+
if include_files:
|
|
179
|
+
filtered_files = [f for f in files if get_e_normalized(f,exts)]
|
|
180
|
+
dir_structure[rel_root].extend(filtered_files)
|
|
181
|
+
if normalize_extensions(exts) == '_':
|
|
182
|
+
return True
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# Recursive tree builder
|
|
186
|
+
def _build_tree(current: str, prefix: str, structure: Dict[str, List[str]]) -> List[str]:
|
|
187
|
+
lines = []
|
|
188
|
+
contents = sorted(structure.get(current, []))
|
|
189
|
+
for i, item in enumerate(contents):
|
|
190
|
+
is_last = (i == len(contents) - 1)
|
|
191
|
+
new_prefix = prefix + (' ' if is_last else '│ ')
|
|
192
|
+
connector = '└── ' if is_last else '├── '
|
|
193
|
+
|
|
194
|
+
lines.append(f"{prefix}{connector}{item}")
|
|
195
|
+
|
|
196
|
+
if item.endswith('/'):
|
|
197
|
+
sub_path = os.path.join(current, item.rstrip('/')) if current != '.' else item.rstrip('/')
|
|
198
|
+
lines.extend(_build_tree(sub_path, new_prefix, structure))
|
|
199
|
+
return lines
|
|
200
|
+
|
|
201
|
+
tree_str.extend(_build_tree('.', prefix + '│ ', dir_structure))
|
|
202
|
+
|
|
203
|
+
return '\n'.join(tree_str)
|
|
204
|
+
|
|
205
|
+
def get_directory_map(
|
|
206
|
+
directory: str,
|
|
207
|
+
paths: Optional[Union[bool, str]] = True,
|
|
208
|
+
exts: Optional[Union[bool, str, List[str]]] = True,
|
|
209
|
+
recursive: bool = True,
|
|
210
|
+
include_files: bool = True
|
|
211
|
+
) -> str:
|
|
212
|
+
"""
|
|
213
|
+
Public entry point to get a copyable directory map string.
|
|
214
|
+
|
|
215
|
+
This wraps build_directory_tree to provide a simple API for generating
|
|
216
|
+
and returning the tree string, which can be printed or copied to clipboard.
|
|
217
|
+
|
|
218
|
+
Example usage:
|
|
219
|
+
map_str = get_directory_map('/path/to/dir')
|
|
220
|
+
print(map_str) # Or copy to clipboard via pyperclip or similar
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
directory: The base directory to map.
|
|
224
|
+
paths: The paths specification.
|
|
225
|
+
exts: The extensions to include.
|
|
226
|
+
recursive: Whether to map recursively.
|
|
227
|
+
include_files: Whether to include files in the map.
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
The directory tree as a string.
|
|
231
|
+
"""
|
|
232
|
+
return build_directory_tree(directory, paths, exts, recursive, include_files)
|
|
233
|
+
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from .file_utils import findGlobFiles
|
|
2
|
+
from ..imports import *
|
|
3
|
+
def stringInContent(
|
|
4
|
+
content,
|
|
5
|
+
strings,
|
|
6
|
+
total_strings=False
|
|
7
|
+
):
|
|
8
|
+
found = [string for string in strings if string in content]
|
|
9
|
+
if found:
|
|
10
|
+
if total_strings:
|
|
11
|
+
if len(strings) == len(found):
|
|
12
|
+
return True
|
|
13
|
+
return False
|
|
14
|
+
return True
|
|
15
|
+
return False
|
|
16
|
+
def get_contents(
|
|
17
|
+
full_path=None,
|
|
18
|
+
parse_lines=False,
|
|
19
|
+
content=None
|
|
20
|
+
):
|
|
21
|
+
if full_path:
|
|
22
|
+
content = content or read_any_file(full_path)
|
|
23
|
+
if content:
|
|
24
|
+
if parse_lines:
|
|
25
|
+
content = str(content).split('\n')
|
|
26
|
+
return make_list(content)
|
|
27
|
+
return content or []
|
|
28
|
+
def find_file(content,spec_line,strings,total_strings=False):
|
|
29
|
+
lines = content.split('\n')
|
|
30
|
+
if len(lines) >= spec_line:
|
|
31
|
+
return stringInContent(
|
|
32
|
+
lines[spec_line],
|
|
33
|
+
strings,
|
|
34
|
+
total_strings=total_strings
|
|
35
|
+
)
|
|
36
|
+
return False
|
|
37
|
+
def findContent(directory: str,
|
|
38
|
+
paths: Optional[Union[bool, str]] = True,
|
|
39
|
+
exts: Optional[Union[bool, str, List[str]]] = True,
|
|
40
|
+
recursive: bool = True,
|
|
41
|
+
strings: list=[]
|
|
42
|
+
total_strings=False,
|
|
43
|
+
parse_lines=False,
|
|
44
|
+
spec_lines=False
|
|
45
|
+
):
|
|
46
|
+
found_paths = []
|
|
47
|
+
globFiles = findGlobFiles(directory,paths,exts,recursive)
|
|
48
|
+
for file_path in globFiles:
|
|
49
|
+
if file_path:
|
|
50
|
+
og_content or read_any_file(full_path)
|
|
51
|
+
contents = get_contents(
|
|
52
|
+
full_path,
|
|
53
|
+
parse_lines=parse_lines,
|
|
54
|
+
content = og_content
|
|
55
|
+
)
|
|
56
|
+
found = False
|
|
57
|
+
for content in contents:
|
|
58
|
+
if stringInContent(content, strings,total_strings):
|
|
59
|
+
found = True
|
|
60
|
+
if spec_line != False and isinstance(spec_line,int):
|
|
61
|
+
found = find_file(og_content,
|
|
62
|
+
spec_line,
|
|
63
|
+
strings,
|
|
64
|
+
total_strings=total_strings)
|
|
65
|
+
if found:
|
|
66
|
+
found_paths.append(file_path)
|
|
67
|
+
break
|
|
68
|
+
|
|
69
|
+
return found_paths
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .directory_reader import *
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import *
|
|
3
|
+
from ..file_filtering import *
|
|
4
|
+
from ..file_handlers import *
|
|
5
|
+
# ─── Example walker ──────────────────────────────────────────────────────────
|
|
6
|
+
_logger = get_logFile(__name__)
|
|
7
|
+
|
|
8
|
+
def read_files(files=None,allowed=None):
|
|
9
|
+
allowed = allowed or make_allowed_predicate()
|
|
10
|
+
files = get_all_files(make_list(files or []),allowed)
|
|
11
|
+
collected = {}
|
|
12
|
+
for full_path in files:
|
|
13
|
+
ext = Path(full_path).suffix.lower()
|
|
14
|
+
|
|
15
|
+
# ——— 1) Pure-text quick reads —————————————
|
|
16
|
+
if ext in {'.txt', '.md', '.csv', '.tsv', '.log'}:
|
|
17
|
+
try:
|
|
18
|
+
with open(full_path, 'r', encoding='utf-8', errors='replace') as f:
|
|
19
|
+
collected[full_path] = f.read()
|
|
20
|
+
except Exception as e:
|
|
21
|
+
_logger.warning(f"Failed to read {full_path} as text: {e}")
|
|
22
|
+
continue
|
|
23
|
+
|
|
24
|
+
# ——— 2) Try your DataFrame loader ——————————
|
|
25
|
+
try:
|
|
26
|
+
df_or_map = get_df(full_path)
|
|
27
|
+
if isinstance(df_or_map, (pd.DataFrame, gpd.GeoDataFrame)):
|
|
28
|
+
collected[full_path] = df_or_map
|
|
29
|
+
#_logger.info(f"Loaded DataFrame: {full_path}")
|
|
30
|
+
continue
|
|
31
|
+
|
|
32
|
+
if isinstance(df_or_map, dict):
|
|
33
|
+
for sheet, df in df_or_map.items():
|
|
34
|
+
key = f"{full_path}::[{sheet}]"
|
|
35
|
+
collected[key] = df
|
|
36
|
+
#_logger.info(f"Loaded sheet DataFrame: {key}")
|
|
37
|
+
continue
|
|
38
|
+
except Exception as e:
|
|
39
|
+
_logger.debug(f"get_df failed for {full_path}: {e}")
|
|
40
|
+
|
|
41
|
+
# ——— 3) Fallback to generic text extractor ————
|
|
42
|
+
try:
|
|
43
|
+
parts = read_file_as_text(full_path) # List[str]
|
|
44
|
+
combined = "\n\n".join(parts)
|
|
45
|
+
collected[full_path] = combined
|
|
46
|
+
#_logger.info(f"Read fallback text for: {full_path}")
|
|
47
|
+
except Exception as e:
|
|
48
|
+
_logger.warning(f"Could not read {full_path} at all: {e}")
|
|
49
|
+
|
|
50
|
+
return collected
|
|
51
|
+
def read_directory(
|
|
52
|
+
root_path: str,
|
|
53
|
+
*,
|
|
54
|
+
allowed_exts: Set[str] = DEFAULT_ALLOWED_EXTS,
|
|
55
|
+
unallowed_exts: Set[str] = DEFAULT_UNALLOWED_EXTS,
|
|
56
|
+
exclude_types: Set[str] = DEFAULT_EXCLUDE_TYPES,
|
|
57
|
+
exclude_dirs: List[str] = DEFAULT_EXCLUDE_DIRS,
|
|
58
|
+
exclude_patterns: List[str] = DEFAULT_EXCLUDE_PATTERNS,
|
|
59
|
+
) -> Dict[str, Union[pd.DataFrame, str]]:
|
|
60
|
+
allowed = make_allowed_predicate(
|
|
61
|
+
allowed_exts = allowed_exts,
|
|
62
|
+
unallowed_exts = unallowed_exts,
|
|
63
|
+
exclude_types = exclude_types,
|
|
64
|
+
extra_dirs = exclude_dirs,
|
|
65
|
+
extra_patterns = exclude_patterns,
|
|
66
|
+
)
|
|
67
|
+
return read_files(files=root_path,allowed=allowed)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .file_filters import *
|