abstract-utilities 0.2.2.448__py3-none-any.whl → 0.2.2.449__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 +43 -17
- abstract_utilities/abstract_classes.py +0 -49
- abstract_utilities/class_utils.py +3 -39
- abstract_utilities/cmd_utils/user_utils.py +1 -1
- abstract_utilities/{compare_utils/compare_utils.py → compare_utils.py} +1 -1
- abstract_utilities/dynimport.py +15 -7
- abstract_utilities/json_utils.py +0 -35
- abstract_utilities/log_utils.py +3 -14
- abstract_utilities/path_utils.py +6 -90
- abstract_utilities/read_write_utils.py +156 -99
- abstract_utilities/robust_reader/__init__.py +1 -1
- abstract_utilities/{file_utils/file_utils → robust_reader}/file_reader.py +19 -5
- abstract_utilities/{file_utils/file_utils → robust_reader}/pdf_utils.py +9 -1
- abstract_utilities/robust_readers/__init__.py +1 -0
- abstract_utilities/{file_utils/file_utils/file_utils.py → robust_readers/file_filters.py} +1 -2
- abstract_utilities/{file_utils/file_utils → robust_readers}/filter_params.py +38 -1
- abstract_utilities/robust_readers/initFuncGen.py +74 -82
- abstract_utilities/type_utils.py +1 -0
- {abstract_utilities-0.2.2.448.dist-info → abstract_utilities-0.2.2.449.dist-info}/METADATA +4 -15
- abstract_utilities-0.2.2.449.dist-info/RECORD +49 -0
- {abstract_utilities-0.2.2.448.dist-info → abstract_utilities-0.2.2.449.dist-info}/WHEEL +1 -1
- abstract_utilities/cmd_utils/imports/__init__.py +0 -1
- abstract_utilities/cmd_utils/imports/imports.py +0 -10
- abstract_utilities/cmd_utils/pexpect_utils.py +0 -310
- abstract_utilities/compare_utils/__init__.py +0 -3
- abstract_utilities/compare_utils/best_match.py +0 -150
- abstract_utilities/compare_utils/find_value.py +0 -105
- abstract_utilities/env_utils/__init__.py +0 -3
- abstract_utilities/env_utils/abstractEnv.py +0 -129
- abstract_utilities/env_utils/envy_it.py +0 -33
- abstract_utilities/env_utils/imports/__init__.py +0 -2
- abstract_utilities/env_utils/imports/imports.py +0 -8
- abstract_utilities/env_utils/imports/utils.py +0 -122
- abstract_utilities/file_utils/__init__.py +0 -3
- abstract_utilities/file_utils/file_utils/__init__.py +0 -6
- abstract_utilities/file_utils/file_utils/file_filters.py +0 -104
- abstract_utilities/file_utils/file_utils/imports.py +0 -1
- abstract_utilities/file_utils/file_utils/map_utils.py +0 -29
- abstract_utilities/file_utils/imports/__init__.py +0 -5
- abstract_utilities/file_utils/imports/classes.py +0 -381
- abstract_utilities/file_utils/imports/constants.py +0 -39
- abstract_utilities/file_utils/imports/file_functions.py +0 -10
- abstract_utilities/file_utils/imports/imports.py +0 -14
- abstract_utilities/file_utils/imports/module_imports.py +0 -9
- abstract_utilities/file_utils/req.py +0 -329
- abstract_utilities/robust_reader/imports/__init__.py +0 -1
- abstract_utilities/robust_reader/imports/imports.py +0 -12
- abstract_utilities/robust_readers/imports.py +0 -8
- abstract_utilities/safe_utils.py +0 -133
- abstract_utilities/ssh_utils/__init__.py +0 -3
- abstract_utilities/ssh_utils/classes.py +0 -127
- abstract_utilities/ssh_utils/imports.py +0 -10
- abstract_utilities/ssh_utils/pexpect_utils.py +0 -315
- abstract_utilities/ssh_utils/utils.py +0 -188
- abstract_utilities/string_utils.py +0 -12
- abstract_utilities-0.2.2.448.dist-info/RECORD +0 -83
- {abstract_utilities-0.2.2.448.dist-info → abstract_utilities-0.2.2.449.dist-info}/top_level.txt +0 -0
|
@@ -1,38 +1,115 @@
|
|
|
1
1
|
"""
|
|
2
2
|
read_write_utils.py
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
- Writing content to a file
|
|
7
|
-
- Reading content from a file
|
|
8
|
-
- Creating and reading if missing
|
|
9
|
-
- Detecting file/content params via positional args or kwargs
|
|
3
|
+
|
|
4
|
+
This module, 'read_write_utils.py', provides utility functions for reading and writing to files.
|
|
5
|
+
These include functions to:
|
|
10
6
|
|
|
11
7
|
Usage:
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
import abstract_utilities.read_write_utils as read_write_utils
|
|
9
|
+
|
|
10
|
+
1. Write content to a file.
|
|
11
|
+
2. Read content from a file.
|
|
12
|
+
3. Check if a string has a file extension.
|
|
13
|
+
4. Read from or write to a file depending on the number of arguments.
|
|
14
|
+
5. Create a file if it does not exist, then read from it.
|
|
14
15
|
|
|
16
|
+
Each function includes a docstring to further explain its purpose, input parameters, and return values.
|
|
15
17
|
import os
|
|
16
|
-
from .ssh_utils.utils import run_cmd
|
|
17
|
-
from .abstract_classes import run_pruned_func
|
|
18
|
-
_FILE_PATH_KEYS = ['file', 'filepath', 'file_path', 'path', 'directory', 'f', 'dst', 'dest']
|
|
19
|
-
_CONTENTS_KEYS = ['cont', 'content', 'contents', 'data', 'datas', 'dat', 'src', 'source']
|
|
20
18
|
|
|
19
|
+
# File and Directory Operations
|
|
20
|
+
os.rename(src, dst) # Rename a file or directory
|
|
21
|
+
os.remove(path) # Remove a file
|
|
22
|
+
os.unlink(path) # Alias for os.remove()
|
|
23
|
+
os.rmdir(path) # Remove an empty directory
|
|
24
|
+
os.makedirs(path) # Create directories recursively
|
|
25
|
+
os.makedirs(path, exist_ok=True) # Create directories, ignore if exists
|
|
26
|
+
os.mkdir(path) # Create a single directory
|
|
27
|
+
os.listdir(path) # List files and directories in a path
|
|
28
|
+
os.chdir(path) # Change current working directory
|
|
29
|
+
os.getcwd() # Get current working directory
|
|
30
|
+
os.stat(path) # Get file/directory information
|
|
31
|
+
os.lstat(path) # Get symbolic link information
|
|
32
|
+
os.symlink(src, dst) # Create a symbolic link
|
|
33
|
+
os.readlink(path) # Read the target of a symbolic link
|
|
34
|
+
os.getcwd() # Get current working directory
|
|
35
|
+
os.chdir(path) # Change current working directory
|
|
36
|
+
|
|
37
|
+
# File and Directory Information
|
|
38
|
+
os.path.exists(path) # Check if a path exists
|
|
39
|
+
os.path.isfile(path) # Check if a path points to a file
|
|
40
|
+
os.path.isdir(path) # Check if a path points to a directory
|
|
41
|
+
os.path.islink(path) # Check if a path points to a symbolic link
|
|
42
|
+
os.path.abspath(path) # Get the absolute path of a file/directory
|
|
43
|
+
os.path.basename(path) # Get the base name of a path
|
|
44
|
+
os.path.dirname(path) # Get the directory name of a path
|
|
45
|
+
os.path.join(path1, path2, ...) # Join path components into a single path
|
|
46
|
+
|
|
47
|
+
# File Permissions
|
|
48
|
+
os.chmod(path, mode) # Change file permissions
|
|
49
|
+
os.access(path, mode) # Check if a file is accessible with given mode
|
|
50
|
+
|
|
51
|
+
# File Times
|
|
52
|
+
os.path.getatime(path) # Get last access time of a file
|
|
53
|
+
os.path.getmtime(path) # Get last modification time of a file
|
|
54
|
+
os.path.getctime(path) # Get creation time of a file
|
|
55
|
+
os.utime(path, times) # Set access and modification times
|
|
56
|
+
|
|
57
|
+
# Working with Paths
|
|
58
|
+
os.path.split(path) # Split a path into (head, tail)
|
|
59
|
+
os.path.splitext(path) # Split a path into (root, ext)
|
|
60
|
+
os.path.normpath(path) # Normalize a path (e.g., convert slashes)
|
|
61
|
+
|
|
62
|
+
# Other
|
|
63
|
+
os.path.samefile(path1, path2) # Check if two paths refer to the same file
|
|
64
|
+
|
|
65
|
+
# Directory Traversal
|
|
66
|
+
for root, dirs, files in os.walk(top, topdown=True):
|
|
67
|
+
# Traverse a directory tree, yielding root, dirs, and files lists
|
|
68
|
+
|
|
69
|
+
# Temporary Files and Directories
|
|
70
|
+
import tempfile
|
|
71
|
+
tempfile.mkstemp() # Create a temporary file
|
|
72
|
+
tempfile.mkdtemp() # Create a temporary directory
|
|
73
|
+
tempfile.TemporaryFile() # Create a temporary file object
|
|
74
|
+
|
|
75
|
+
# Environment Variables
|
|
76
|
+
os.environ # Dictionary of environment variables
|
|
77
|
+
os.environ['VAR_NAME'] # Access an environment variable
|
|
78
|
+
os.environ.get('VAR_NAME') # Access an environment variable (with default)
|
|
79
|
+
|
|
80
|
+
# Path Manipulation
|
|
81
|
+
os.path.abspath(path) # Convert relative path to absolute path
|
|
82
|
+
os.path.join(path1, path2, ...) # Join paths together
|
|
83
|
+
os.path.split(path) # Split a path into directory and filename
|
|
84
|
+
os.path.dirname(path) # Get the directory part of a path
|
|
85
|
+
os.path.basename(path) # Get the filename part of a path
|
|
86
|
+
os.path.exists(path) # Check if a path exists
|
|
87
|
+
os.path.isfile(path) # Check if a path points to a file
|
|
88
|
+
os.path.isdir(path) # Check if a path points to a directory
|
|
89
|
+
|
|
90
|
+
# File Permissions
|
|
91
|
+
os.chmod(path, mode) # Change file permissions
|
|
92
|
+
|
|
93
|
+
# Miscellaneous
|
|
94
|
+
os.getpid() # Get the current process ID
|
|
95
|
+
os.getlogin() # Get the name of the logged-in user
|
|
21
96
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
97
|
+
"""
|
|
98
|
+
import os
|
|
99
|
+
def break_down_find_existing(path):
|
|
100
|
+
test_path = ''
|
|
101
|
+
for part in path.split(os.sep):
|
|
102
|
+
test_path = os.path.join(test_path, part)
|
|
103
|
+
if not os.path.exists(test_path):
|
|
104
|
+
return test_path if test_path else None
|
|
105
|
+
return test_path
|
|
30
106
|
|
|
107
|
+
def string_in_keys(strings, kwargs):
|
|
108
|
+
return next((key for key in kwargs if any(s.lower() in key.lower() for s in strings)), None)
|
|
31
109
|
|
|
32
110
|
def get_path(paths):
|
|
33
|
-
"""Return the first valid path among given paths."""
|
|
34
111
|
for path in paths:
|
|
35
|
-
if isinstance(path,
|
|
112
|
+
if isinstance(path,str):
|
|
36
113
|
if os.path.isfile(path):
|
|
37
114
|
return path
|
|
38
115
|
dirname = os.path.dirname(path)
|
|
@@ -40,103 +117,83 @@ def get_path(paths):
|
|
|
40
117
|
return path
|
|
41
118
|
return None
|
|
42
119
|
|
|
43
|
-
|
|
44
|
-
def break_down_find_existing(path):
|
|
45
|
-
"""Return the first non-existent subpath within a path chain."""
|
|
46
|
-
test_path = ''
|
|
47
|
-
for part in path.split(os.sep):
|
|
48
|
-
test_path = os.path.join(test_path, part)
|
|
49
|
-
if not os.path.exists(test_path):
|
|
50
|
-
return test_path if test_path else None
|
|
51
|
-
return test_path
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
# --- Parameter parsing --------------------------------------------------------
|
|
55
120
|
def check_read_write_params(*args, **kwargs):
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
file_key = string_in_keys(_FILE_PATH_KEYS, kwargs)
|
|
61
|
-
content_key = string_in_keys(_CONTENTS_KEYS, kwargs)
|
|
62
|
-
|
|
63
|
-
file_path = kwargs.get(file_key) if file_key else None
|
|
64
|
-
contents = kwargs.get(content_key) if content_key else None
|
|
121
|
+
file_path = kwargs.get('file_path', None)
|
|
122
|
+
contents = kwargs.get('contents', None)
|
|
123
|
+
if contents is None:
|
|
124
|
+
contents = kwargs.get('data', None)
|
|
65
125
|
|
|
66
|
-
# Handle positional
|
|
126
|
+
# Handle positional arguments
|
|
67
127
|
if file_path is None and len(args) > 0:
|
|
68
128
|
file_path = args[0]
|
|
69
129
|
if contents is None and len(args) > 1:
|
|
70
130
|
contents = args[1]
|
|
131
|
+
elif contents is None and len(args) > 0 and file_path != args[0]:
|
|
132
|
+
contents = args[0]
|
|
71
133
|
|
|
72
|
-
if file_path is None:
|
|
73
|
-
raise ValueError("
|
|
74
|
-
return file_path, contents
|
|
134
|
+
if file_path is None or contents is None:
|
|
135
|
+
raise ValueError("Both 'file_path' and 'contents' (or 'data') are required.")
|
|
75
136
|
|
|
137
|
+
return file_path, contents
|
|
76
138
|
|
|
77
|
-
|
|
78
|
-
|
|
139
|
+
def write_to_file(file_path=None, contents=None,*args, **kwargs):
|
|
140
|
+
"""
|
|
141
|
+
Write contents to a file. If the file does not exist, it is created.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
file_path: The path of the file to write to.
|
|
145
|
+
contents: The content to write to the file.
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
The contents that were written to the file.
|
|
79
149
|
"""
|
|
80
|
-
|
|
150
|
+
params = check_read_write_params(file_path=file_path, contents=contents,*args, **kwargs)
|
|
151
|
+
if params:
|
|
152
|
+
with open(params[0], 'w', encoding='UTF-8') as f:
|
|
153
|
+
f.write(params[1])
|
|
154
|
+
return contents
|
|
155
|
+
|
|
81
156
|
|
|
82
|
-
|
|
157
|
+
def read_from_file(file_path) -> str:
|
|
83
158
|
"""
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def read_from_file(file_path,**kwargs):
|
|
95
|
-
user_at_host = kwargs.get("user_at_host")
|
|
96
|
-
if user_at_host:
|
|
97
|
-
kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
|
|
98
|
-
basename = os.path.basename(file_path)
|
|
99
|
-
kwargs["cmd"] = f'cat {basename}'
|
|
100
|
-
return run_pruned_func(run_cmd,**kwargs)
|
|
101
|
-
"""Read text content from a file."""
|
|
102
|
-
with open(file_path, "r", encoding="utf-8") as f:
|
|
159
|
+
Read the contents of a file.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
file_path: The path of the file to read from.
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
The contents of the file.
|
|
166
|
+
"""
|
|
167
|
+
with open(file_path, 'r', encoding='UTF-8') as f:
|
|
103
168
|
return f.read()
|
|
104
169
|
|
|
105
|
-
|
|
106
|
-
def create_and_read_file(*args, **kwargs):
|
|
170
|
+
def create_and_read_file(file_path=None, contents:str='',*args, **kwargs) -> str:
|
|
107
171
|
"""
|
|
108
|
-
Create
|
|
172
|
+
Create a file if it does not exist, then read from it.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
file_path: The path of the file to create and read from.
|
|
176
|
+
contents: The content to write to the file if it does not exist.
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
The contents of the file.
|
|
109
180
|
"""
|
|
110
|
-
file_path, contents = check_read_write_params(*args, **kwargs)
|
|
111
181
|
if not os.path.isfile(file_path):
|
|
112
|
-
write_to_file(
|
|
182
|
+
write_to_file(contents, file_path)
|
|
113
183
|
return read_from_file(file_path)
|
|
114
|
-
|
|
115
|
-
|
|
116
184
|
def is_file_extension(obj: str) -> bool:
|
|
117
|
-
"""
|
|
118
|
-
if
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
185
|
+
"""
|
|
186
|
+
Check if a string has a file extension.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
obj: The string to check.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
True if the string has a file extension, False otherwise.
|
|
193
|
+
"""
|
|
194
|
+
return len(obj) >= 4 and '.' in obj[-4:-3]
|
|
123
195
|
|
|
124
196
|
def delete_file(file_path: str):
|
|
125
|
-
"""Safely delete a file if it exists."""
|
|
126
197
|
if os.path.isfile(file_path):
|
|
127
198
|
os.remove(file_path)
|
|
128
|
-
return True
|
|
129
|
-
return False
|
|
130
|
-
|
|
131
199
|
|
|
132
|
-
def get_content_lines(*args, **kwargs):
|
|
133
|
-
"""Return a list of lines from string or file path."""
|
|
134
|
-
file_path, contents = check_read_write_params(*args, **kwargs)
|
|
135
|
-
if os.path.isfile(file_path):
|
|
136
|
-
contents = read_from_file(filepath)
|
|
137
|
-
|
|
138
|
-
if isinstance(contents, str):
|
|
139
|
-
return contents.splitlines()
|
|
140
|
-
elif isinstance(contents, list):
|
|
141
|
-
return contents
|
|
142
|
-
return []
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
from
|
|
1
|
+
from .file_reader import *
|
|
2
2
|
|
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
# file_reader.py
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
from
|
|
2
|
+
import os,tempfile,shutil,logging,ezodf,fnmatch
|
|
3
|
+
from typing import Union
|
|
4
|
+
import pandas as pd
|
|
5
|
+
import geopandas as gpd
|
|
6
|
+
from abstract_utilities import *
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from werkzeug.utils import secure_filename
|
|
9
|
+
from werkzeug.datastructures import FileStorage
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
from typing import Dict, Union, List
|
|
7
12
|
from .pdf_utils import *
|
|
13
|
+
import pdfplumber
|
|
14
|
+
from pdf2image import convert_from_path # only used for OCR fallback
|
|
15
|
+
import pytesseract
|
|
16
|
+
from pathlib import Path
|
|
8
17
|
# ---------------------------------------------------------------------------
|
|
9
18
|
# NOTE: The following helper functions must be provided elsewhere:
|
|
10
19
|
# - convert_date_string(s: str) -> datetime
|
|
11
20
|
# - read_from_file(path: str) -> pd.DataFrame
|
|
12
21
|
# ---------------------------------------------------------------------------
|
|
22
|
+
DEFAULT_EXCLUDE_DIRS = {"node_modules", "__pycache__","backups","backup"}
|
|
23
|
+
DEFAULT_EXCLUDE_FILE_PATTERNS = {"__init__*", "*.tmp", "*.log"}
|
|
24
|
+
DEFAULT_EXCLUDE_TYPES = {"image","video","audio","presentation"}
|
|
25
|
+
def get_ext(item):
|
|
26
|
+
return item.split('.')[-1]
|
|
13
27
|
def _should_skip_dir(dir_name: str, exclude_dirs: set[str]) -> bool:
|
|
14
28
|
"""
|
|
15
29
|
Return True if dir_name match=self.exclude_types)es one of the excluded directory names exactly.
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import PyPDF2
|
|
2
|
+
from typing import *
|
|
3
|
+
from pdf2image import convert_from_path
|
|
4
|
+
from abstract_utilities.path_utils import (is_file, mkdirs, get_directory,
|
|
5
|
+
get_base_name, split_text,
|
|
6
|
+
get_ext, get_file_name)
|
|
7
|
+
from abstract_utilities.type_utils import is_str
|
|
8
|
+
from abstract_utilities.cmd_utils import cmd_input
|
|
9
|
+
from abstract_utilities.read_write_utils import write_to_file
|
|
2
10
|
def if_none_return(obj: object, obj_2: object) -> object:
|
|
3
11
|
"""
|
|
4
12
|
Return obj if obj_2 is None, otherwise return obj_2.
|
|
@@ -15,8 +15,7 @@ def get_allowed_predicate(allowed=None):
|
|
|
15
15
|
return allowed
|
|
16
16
|
def get_globs(items,recursive: bool = True,allowed=None):
|
|
17
17
|
glob_paths = []
|
|
18
|
-
|
|
19
|
-
for item in items:
|
|
18
|
+
for item in make_list(items):
|
|
20
19
|
pattern = os.path.join(item, "**/*") # include all files recursively\n
|
|
21
20
|
nuItems = glob.glob(pattern, recursive=recursive)
|
|
22
21
|
if allowed:
|
|
@@ -1,4 +1,41 @@
|
|
|
1
|
-
from
|
|
1
|
+
from typing import *
|
|
2
|
+
from ..type_utils import make_list,get_media_exts, is_media_type
|
|
3
|
+
from ..string_clean import eatAll
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
@dataclass
|
|
6
|
+
class ScanConfig:
|
|
7
|
+
allowed_exts: Set[str]
|
|
8
|
+
unallowed_exts: Set[str]
|
|
9
|
+
exclude_types: Set[str]
|
|
10
|
+
exclude_dirs: List[str] = field(default_factory=list)
|
|
11
|
+
exclude_patterns: List[str] = field(default_factory=list)
|
|
12
|
+
DEFAULT_ALLOWED_EXTS: Set[str] = {
|
|
13
|
+
".py", ".pyw", # python
|
|
14
|
+
".js", ".jsx", ".ts", ".tsx", ".mjs", # JS/TS
|
|
15
|
+
".html", ".htm", ".xml", # markup
|
|
16
|
+
".css", ".scss", ".sass", ".less", # styles
|
|
17
|
+
".json", ".yaml", ".yml", ".toml", ".ini", # configs
|
|
18
|
+
".cfg", ".md", ".markdown", ".rst", # docs
|
|
19
|
+
".sh", ".bash", ".env", # scripts/env
|
|
20
|
+
".txt" # plain text
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
DEFAULT_EXCLUDE_TYPES: Set[str] = {
|
|
24
|
+
"image", "video", "audio", "presentation",
|
|
25
|
+
"spreadsheet", "archive", "executable"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# never want these—even if they sneak into ALLOWED
|
|
29
|
+
_unallowed = set(get_media_exts(DEFAULT_EXCLUDE_TYPES)) | {'.bak', '.shp', '.cpg', '.dbf', '.shx','.geojson',".pyc",'.shx','.geojson','.prj','.sbn','.sbx'}
|
|
30
|
+
DEFAULT_UNALLOWED_EXTS = {e for e in _unallowed if e not in DEFAULT_ALLOWED_EXTS}
|
|
31
|
+
|
|
32
|
+
DEFAULT_EXCLUDE_DIRS: Set[str] = {
|
|
33
|
+
"node_modules", "__pycache__", "backups", "backup", "backs", "trash", "depriciated", "old", "__init__"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
DEFAULT_EXCLUDE_PATTERNS: Set[str] = {
|
|
37
|
+
"__init__*", "*.tmp", "*.log", "*.lock", "*.zip","*~"
|
|
38
|
+
}
|
|
2
39
|
def get_default_modular(obj,default=None,add=False,typ=set):
|
|
3
40
|
if obj in [False,True,None]:
|
|
4
41
|
if obj in [True,None]:
|
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
# attach_functions.py — single helper you can import anywhere
|
|
2
2
|
# attach_dynamic.py
|
|
3
3
|
from __future__ import annotations
|
|
4
|
-
from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
get_for_all_tabs(root,tab_control=tab_control)
|
|
4
|
+
from types import ModuleType
|
|
5
|
+
from typing import Iterable
|
|
6
|
+
from .file_filters import define_defaults,get_files_and_dirs
|
|
8
7
|
|
|
8
|
+
import inspect
|
|
9
|
+
from ..read_write_utils import *
|
|
10
|
+
import textwrap, pkgutil, os, re, textwrap, sys, types, importlib, importlib.util, inspect
|
|
11
|
+
from typing import *
|
|
12
|
+
ABSPATH = os.path.abspath(__file__)
|
|
13
|
+
ABSROOT = os.path.dirname(ABSPATH)
|
|
14
|
+
def get_caller_path():
|
|
15
|
+
frame = inspect.stack()[1]
|
|
16
|
+
return os.path.abspath(frame.filename)
|
|
17
|
+
def get_caller_dir():
|
|
18
|
+
frame = inspect.stack()[1]
|
|
19
|
+
abspath = os.path.abspath(frame.filename)
|
|
20
|
+
return os.path.dirname(abspath)
|
|
21
|
+
def call_for_all_tabs():
|
|
22
|
+
|
|
23
|
+
root = get_caller_dir()
|
|
24
|
+
get_for_all_tabs(root)
|
|
25
|
+
|
|
26
|
+
ABSPATH = os.path.abspath(__file__)
|
|
27
|
+
ABSROOT = os.path.dirname(ABSPATH)
|
|
9
28
|
def clean_imports():
|
|
10
29
|
alls = str(list(set("""os,re,subprocess,sys,re,traceback,pydot, enum, inspect, sys, traceback, threading,json,traceback,logging,requests""".replace('\n','').replace(' ','').replace('\t','').split(','))))[1:-1].replace('"','').replace("'",'')
|
|
11
30
|
input(alls)
|
|
@@ -38,17 +57,11 @@ def ifFunctionsInFile(root):
|
|
|
38
57
|
return item
|
|
39
58
|
|
|
40
59
|
|
|
41
|
-
def get_for_all_tabs(root = None
|
|
60
|
+
def get_for_all_tabs(root = None):
|
|
42
61
|
root = root or caller_path()
|
|
43
62
|
if os.path.isfile(root):
|
|
44
63
|
root = os.path.dirname(root)
|
|
45
|
-
|
|
46
|
-
all_tabs = get_dirs(root = root)
|
|
47
|
-
else:
|
|
48
|
-
dirname = root
|
|
49
|
-
if root and os.path.isfile(root):
|
|
50
|
-
dirname = os.path.dirname(root)
|
|
51
|
-
all_tabs = [dirname]
|
|
64
|
+
all_tabs = get_dirs(root = root)
|
|
52
65
|
for ROOT in all_tabs:
|
|
53
66
|
FUNCS_DIR = ifFunctionsInFile(ROOT)
|
|
54
67
|
if FUNCS_DIR == None:
|
|
@@ -58,38 +71,52 @@ def get_for_all_tabs(root = None,tab_control=True):
|
|
|
58
71
|
apply_inits(ROOT)
|
|
59
72
|
|
|
60
73
|
|
|
61
|
-
def
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
74
|
+
def apply_inits(ROOT):
|
|
75
|
+
FUNCS_DIR = ifFunctionsInFile(ROOT)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if_fun_dir = isDir(FUNCS_DIR)
|
|
79
|
+
if if_fun_dir != None:
|
|
80
|
+
|
|
81
|
+
if if_fun_dir:
|
|
82
|
+
CFG = define_defaults(allowed_exts='.py',
|
|
83
|
+
unallowed_exts = True,
|
|
84
|
+
exclude_types = True,
|
|
85
|
+
exclude_dirs = True,
|
|
86
|
+
exclude_patterns = True)
|
|
87
|
+
_,filepaths = get_files_and_dirs(FUNCS_DIR,cfg=CFG)
|
|
88
|
+
|
|
89
|
+
else:
|
|
90
|
+
filepaths = [FUNCS_DIR]
|
|
91
|
+
|
|
92
|
+
# Parse top-level def names
|
|
93
|
+
def extract_funcs(path: str):
|
|
94
|
+
funcs = []
|
|
95
|
+
for line in read_from_file(path).splitlines():
|
|
96
|
+
m = re.match(r"^def\s+([A-Za-z_]\w*)\s*\(self", line)
|
|
97
|
+
if m:
|
|
98
|
+
funcs.append(m.group(1))
|
|
99
|
+
return funcs
|
|
100
|
+
|
|
101
|
+
# Build functions/__init__.py that re-exports all discovered functions
|
|
102
|
+
import_lines = []
|
|
103
|
+
all_funcs = []
|
|
104
|
+
for fp in filepaths:
|
|
105
|
+
module = os.path.splitext(os.path.basename(fp))[0]
|
|
106
|
+
funcs = extract_funcs(fp)
|
|
107
|
+
if funcs:
|
|
108
|
+
import_lines.append(f"from .{module} import ({', '.join(funcs)})")
|
|
109
|
+
all_funcs.extend(funcs)
|
|
110
|
+
if if_fun_dir:
|
|
111
|
+
functions_init = "\n".join(import_lines) + ("\n" if import_lines else "")
|
|
112
|
+
write_to_file(contents=functions_init, file_path=os.path.join(FUNCS_DIR, "__init__.py"))
|
|
113
|
+
|
|
114
|
+
# Prepare the tuple literal of function names for import + loop
|
|
115
|
+
uniq_funcs = sorted(set(all_funcs))
|
|
116
|
+
func_tuple = ", ".join(uniq_funcs) + ("," if len(uniq_funcs) == 1 else "")
|
|
117
|
+
|
|
118
|
+
# Generate apiConsole/initFuncs.py using the safer setattr-loop
|
|
119
|
+
init_funcs_src = textwrap.dedent(f"""\
|
|
93
120
|
|
|
94
121
|
|
|
95
122
|
from .functions import ({func_tuple})
|
|
@@ -102,42 +129,7 @@ def get_init_funcs_str(func_tuple):
|
|
|
102
129
|
logger.info(f"{{e}}")
|
|
103
130
|
return self
|
|
104
131
|
""")
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if_fun_dir = isDir(functions_dir)
|
|
109
|
-
if if_fun_dir != None:
|
|
110
|
-
input(if_fun_dir)
|
|
111
|
-
if if_fun_dir:
|
|
112
|
-
CFG = define_defaults(allowed_exts='.py',
|
|
113
|
-
unallowed_exts = True,
|
|
114
|
-
exclude_types = True,
|
|
115
|
-
exclude_dirs = True,
|
|
116
|
-
exclude_patterns = True)
|
|
117
|
-
input(CFG)
|
|
118
|
-
_,filepaths = get_files_and_dirs(functions_dir,cfg=CFG)
|
|
119
|
-
else:
|
|
120
|
-
filepaths = [FUNCS_DIR]
|
|
121
|
-
input(filepaths)
|
|
122
|
-
return filepaths
|
|
123
|
-
def apply_inits(root=None,tab_control=True):
|
|
124
|
-
root = root or get_caller_dir()
|
|
125
|
-
FUNCS_DIR = ifFunctionsInFile(root)
|
|
126
|
-
if_fun_dir = isDir(FUNCS_DIR)
|
|
127
|
-
if if_fun_dir != None:
|
|
128
|
-
file_paths = get_function_file_paths(FUNCS_DIR)
|
|
129
|
-
|
|
130
|
-
all_funcs_js = get_all_funcs(
|
|
131
|
-
filepaths=file_paths
|
|
132
|
-
)
|
|
133
|
-
if if_fun_dir:
|
|
134
|
-
init_func_js = write_init_functions(import_lines=all_funcs_js.get('import_lines'),functions_dir=FUNCS_DIR)
|
|
135
|
-
all_funcs_js.update(init_func_js)
|
|
136
|
-
func_tuple = all_funcs_js.get("func_tuple")
|
|
137
|
-
init_funcs_str = get_init_funcs_str(func_tuple)
|
|
138
|
-
init_funcs_file_path = os.path.join(root, "initFuncs.py")
|
|
139
|
-
all_funcs_js["funcs_str"]=init_funcs_str
|
|
140
|
-
all_funcs_js["funcs_file_path"]=init_funcs_file_path
|
|
141
|
-
write_to_file(contents=init_funcs_str, file_path=init_funcs_file_path)
|
|
142
|
-
return all_funcs_js
|
|
132
|
+
|
|
133
|
+
write_to_file(contents=init_funcs_src, file_path=os.path.join(ROOT, "initFuncs.py"))
|
|
134
|
+
|
|
143
135
|
|
abstract_utilities/type_utils.py
CHANGED
|
@@ -59,6 +59,7 @@ Version: 0.1.2
|
|
|
59
59
|
import os
|
|
60
60
|
from pathlib import Path
|
|
61
61
|
from typing import Union
|
|
62
|
+
from .path_utils import get_all_item_paths,get_files
|
|
62
63
|
from .list_utils import make_list
|
|
63
64
|
# A big, but by no means exhaustive, map of extensions to mime‐types by category:
|
|
64
65
|
MIME_TYPES = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: abstract_utilities
|
|
3
|
-
Version: 0.2.2.
|
|
3
|
+
Version: 0.2.2.449
|
|
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
|
|
@@ -10,21 +10,10 @@ Classifier: Intended Audience :: Developers
|
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
-
Requires-Python: >=3.
|
|
13
|
+
Requires-Python: >=3.6
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
|
-
Requires-Dist: pathlib>=1.0.1
|
|
16
|
-
Requires-Dist: abstract_security>=0.0.1
|
|
17
|
-
Requires-Dist: yt_dlp>=2023.10.13
|
|
18
15
|
Requires-Dist: pexpect>=4.8.0
|
|
19
|
-
|
|
20
|
-
Dynamic: author-email
|
|
21
|
-
Dynamic: classifier
|
|
22
|
-
Dynamic: description
|
|
23
|
-
Dynamic: description-content-type
|
|
24
|
-
Dynamic: home-page
|
|
25
|
-
Dynamic: requires-dist
|
|
26
|
-
Dynamic: requires-python
|
|
27
|
-
Dynamic: summary
|
|
16
|
+
Requires-Dist: abstract-security>=0.0.1
|
|
28
17
|
|
|
29
18
|
|
|
30
19
|
# Abstract Utilities
|