abstract-utilities 0.2.2.447__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.

Files changed (57) hide show
  1. abstract_utilities/__init__.py +43 -17
  2. abstract_utilities/abstract_classes.py +0 -49
  3. abstract_utilities/class_utils.py +3 -39
  4. abstract_utilities/cmd_utils/user_utils.py +1 -1
  5. abstract_utilities/{compare_utils/compare_utils.py → compare_utils.py} +1 -1
  6. abstract_utilities/dynimport.py +15 -7
  7. abstract_utilities/json_utils.py +0 -35
  8. abstract_utilities/log_utils.py +3 -14
  9. abstract_utilities/path_utils.py +6 -90
  10. abstract_utilities/read_write_utils.py +156 -99
  11. abstract_utilities/robust_reader/__init__.py +1 -1
  12. abstract_utilities/{file_utils/file_utils → robust_reader}/file_reader.py +19 -5
  13. abstract_utilities/{file_utils/file_utils → robust_reader}/pdf_utils.py +9 -1
  14. abstract_utilities/robust_readers/__init__.py +1 -0
  15. abstract_utilities/{file_utils/file_utils/file_utils.py → robust_readers/file_filters.py} +1 -2
  16. abstract_utilities/{file_utils/file_utils → robust_readers}/filter_params.py +38 -1
  17. abstract_utilities/robust_readers/initFuncGen.py +74 -82
  18. abstract_utilities/type_utils.py +1 -0
  19. {abstract_utilities-0.2.2.447.dist-info → abstract_utilities-0.2.2.449.dist-info}/METADATA +4 -15
  20. abstract_utilities-0.2.2.449.dist-info/RECORD +49 -0
  21. {abstract_utilities-0.2.2.447.dist-info → abstract_utilities-0.2.2.449.dist-info}/WHEEL +1 -1
  22. abstract_utilities/cmd_utils/imports/__init__.py +0 -1
  23. abstract_utilities/cmd_utils/imports/imports.py +0 -10
  24. abstract_utilities/cmd_utils/pexpect_utils.py +0 -310
  25. abstract_utilities/compare_utils/__init__.py +0 -3
  26. abstract_utilities/compare_utils/best_match.py +0 -150
  27. abstract_utilities/compare_utils/find_value.py +0 -105
  28. abstract_utilities/env_utils/__init__.py +0 -3
  29. abstract_utilities/env_utils/abstractEnv.py +0 -129
  30. abstract_utilities/env_utils/envy_it.py +0 -33
  31. abstract_utilities/env_utils/imports/__init__.py +0 -2
  32. abstract_utilities/env_utils/imports/imports.py +0 -8
  33. abstract_utilities/env_utils/imports/utils.py +0 -122
  34. abstract_utilities/file_utils/__init__.py +0 -3
  35. abstract_utilities/file_utils/file_utils/__init__.py +0 -6
  36. abstract_utilities/file_utils/file_utils/file_filters.py +0 -104
  37. abstract_utilities/file_utils/file_utils/imports.py +0 -1
  38. abstract_utilities/file_utils/file_utils/map_utils.py +0 -29
  39. abstract_utilities/file_utils/imports/__init__.py +0 -5
  40. abstract_utilities/file_utils/imports/classes.py +0 -381
  41. abstract_utilities/file_utils/imports/constants.py +0 -39
  42. abstract_utilities/file_utils/imports/file_functions.py +0 -10
  43. abstract_utilities/file_utils/imports/imports.py +0 -14
  44. abstract_utilities/file_utils/imports/module_imports.py +0 -9
  45. abstract_utilities/file_utils/req.py +0 -329
  46. abstract_utilities/robust_reader/imports/__init__.py +0 -1
  47. abstract_utilities/robust_reader/imports/imports.py +0 -12
  48. abstract_utilities/robust_readers/imports.py +0 -8
  49. abstract_utilities/safe_utils.py +0 -133
  50. abstract_utilities/ssh_utils/__init__.py +0 -3
  51. abstract_utilities/ssh_utils/classes.py +0 -127
  52. abstract_utilities/ssh_utils/imports.py +0 -10
  53. abstract_utilities/ssh_utils/pexpect_utils.py +0 -315
  54. abstract_utilities/ssh_utils/utils.py +0 -188
  55. abstract_utilities/string_utils.py +0 -5
  56. abstract_utilities-0.2.2.447.dist-info/RECORD +0 -83
  57. {abstract_utilities-0.2.2.447.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
- Unified read/write utility for safe file operations.
5
- Supports:
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
- from abstract_utilities.read_write_utils import *
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
- # --- Helper utilities --------------------------------------------------------
23
- def string_in_keys(strings, kwargs):
24
- """Find a matching keyword in kwargs that contains any of the given substrings."""
25
- for key in kwargs:
26
- for s in strings:
27
- if s.lower() in key.lower():
28
- return key
29
- return None
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, str):
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
- Determine file_path and contents from arguments.
58
- Returns a tuple: (file_path, contents)
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 args (fallback)
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("Missing file_path argument.")
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
- # --- Core functionality -------------------------------------------------------
78
- def write_to_file(*args, **kwargs):
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
- Write contents to a file (create if missing).
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
- Returns the file_path written.
157
+ def read_from_file(file_path) -> str:
83
158
  """
84
- file_path, contents = check_read_write_params(*args, **kwargs)
85
- if contents is None:
86
- raise ValueError("Missing contents to write.")
87
-
88
- os.makedirs(os.path.dirname(file_path) or ".", exist_ok=True)
89
- with open(file_path, "w", encoding="utf-8") as f:
90
- f.write(str(contents))
91
- return file_path
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 the file (if missing) and read contents from it.
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(file_path, contents or "")
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
- """Return True if obj looks like a filename with extension."""
118
- if not isinstance(obj, str):
119
- return False
120
- root, ext = os.path.splitext(obj)
121
- return bool(root and ext)
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 ..file_utils import *
1
+ from .file_reader import *
2
2
 
@@ -1,15 +1,29 @@
1
1
  # file_reader.py
2
- from .imports import *
3
- # -------- Public API drop-ins that mirror your originals --------
4
- from .filter_params import *
5
- from .file_filters import *
6
- from .file_utils import *
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
- from .imports import *
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.
@@ -1,2 +1,3 @@
1
+ from .file_filters import *
1
2
  from .initFuncGen import *
2
3
  from .import_utils import *
@@ -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
- items = [item for item in make_list(items) if item]
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 .imports import *
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 .imports import *
5
- def call_for_all_tabs(root = None,tab_control=True):
6
- root = root or get_caller_dir()
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,tab_control=True):
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
- if tab_control:
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 write_init_functions(import_lines,functions_dir):
62
- functions_init = "\n".join(import_lines) + ("\n" if import_lines else "")
63
- init_file_path = os.path.join(functions_dir, "__init__.py")
64
- write_to_file(contents=functions_init, file_path=init_file_path)
65
- return {"functions_init":functions_init,"init_file_path":init_file_path}
66
- def extract_funcs(filepaths):
67
- funcs = []
68
- for line in read_from_file(path).splitlines():
69
- m = re.match(r"^def\s+([A-Za-z_]\w*)\s*\(self", line)
70
- if m:
71
- funcs.append(m.group(1))
72
- return funcs
73
- def get_all_funcs(
74
- filepaths,
75
- all_funcs=None,
76
- import_lines=None
77
- ):
78
- import_lines = import_lines or []
79
- all_funcs = all_funcs or []
80
- for fp in filepaths:
81
- basename = os.path.basename(fp)
82
- module = os.path.splitext(basename)[0]
83
- funcs = extract_funcs(fp)
84
- if funcs:
85
- import_lines.append(f"from .{module} import ({', '.join(funcs)})")
86
- all_funcs.extend(funcs)
87
- uniq_funcs = sorted(set(all_funcs))
88
- func_tuple=", ".join(uniq_funcs) + ("," if len(uniq_funcs) == 1 else "")
89
- all_funcs_js = {"import_lines":import_lines,"all_funcs":all_funcs,"uniq_funcs":uniq_funcs,"func_tuple":func_tuple}
90
- return all_funcs_js
91
- def get_init_funcs_str(func_tuple):
92
- init_funcs_str = textwrap.dedent(f"""\
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
- return init_funcs_str
106
- def get_function_file_paths(functions_dir):
107
- filepaths=[]
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
 
@@ -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.4
1
+ Metadata-Version: 2.1
2
2
  Name: abstract_utilities
3
- Version: 0.2.2.447
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.11
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
- Dynamic: author
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