abstract-utilities 0.2.2.486__py3-none-any.whl → 0.2.2.540__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 +6 -10
- abstract_utilities/circular_import_finder.py +222 -0
- abstract_utilities/circular_import_finder2.py +118 -0
- abstract_utilities/class_utils/__init__.py +7 -0
- abstract_utilities/class_utils/abstract_classes.py +74 -0
- abstract_utilities/class_utils/caller_utils.py +35 -0
- abstract_utilities/class_utils/class_utils.py +109 -0
- abstract_utilities/class_utils/function_utils.py +153 -0
- abstract_utilities/class_utils/global_utils.py +56 -0
- abstract_utilities/class_utils/imports/__init__.py +2 -0
- abstract_utilities/class_utils/imports/imports.py +2 -0
- abstract_utilities/class_utils/imports/utils.py +40 -0
- abstract_utilities/class_utils/module_utils.py +63 -0
- abstract_utilities/directory_utils/__init__.py +2 -0
- abstract_utilities/directory_utils/directory_utils.py +94 -0
- abstract_utilities/directory_utils/imports/__init__.py +2 -0
- abstract_utilities/directory_utils/imports/imports.py +1 -0
- abstract_utilities/directory_utils/imports/module_imports.py +2 -0
- abstract_utilities/directory_utils/name_utils.py +43 -0
- abstract_utilities/directory_utils/size_utils.py +57 -0
- abstract_utilities/directory_utils/src/__init__.py +4 -0
- abstract_utilities/directory_utils/src/directory_utils.py +92 -0
- abstract_utilities/directory_utils/src/name_utils.py +43 -0
- abstract_utilities/directory_utils/src/size_utils.py +57 -0
- abstract_utilities/directory_utils/src/utils.py +116 -0
- abstract_utilities/directory_utils/utils.py +116 -0
- abstract_utilities/env_utils/imports/imports.py +5 -3
- abstract_utilities/error_utils/__init__.py +2 -0
- abstract_utilities/error_utils/error_utils.py +25 -0
- abstract_utilities/error_utils/imports/__init__.py +2 -0
- abstract_utilities/error_utils/imports/imports.py +1 -0
- abstract_utilities/error_utils/imports/module_imports.py +1 -0
- abstract_utilities/file_utils/__init__.py +1 -2
- abstract_utilities/file_utils/file_utils/type_checks.py +2 -1
- abstract_utilities/file_utils/imports/constants.py +84 -4
- abstract_utilities/file_utils/imports/imports.py +3 -18
- abstract_utilities/file_utils/imports/module_imports.py +2 -7
- abstract_utilities/file_utils/module_imports.py +12 -0
- abstract_utilities/file_utils/src/__init__.py +8 -0
- abstract_utilities/file_utils/src/file_filters.py +177 -0
- abstract_utilities/file_utils/src/file_reader.py +544 -0
- abstract_utilities/file_utils/src/file_utils.py +156 -0
- abstract_utilities/file_utils/src/filter_params.py +197 -0
- abstract_utilities/file_utils/src/find_collect.py +266 -0
- abstract_utilities/file_utils/src/initFunctionsGen.py +280 -0
- abstract_utilities/file_utils/src/map_utils.py +29 -0
- abstract_utilities/file_utils/src/pdf_utils.py +300 -0
- abstract_utilities/file_utils/src/type_checks.py +91 -0
- abstract_utilities/file_utils (2)/__init__.py +2 -0
- abstract_utilities/file_utils (2)/imports/__init__.py +2 -0
- abstract_utilities/file_utils (2)/imports/constants.py +118 -0
- abstract_utilities/file_utils (2)/imports/imports/__init__.py +3 -0
- abstract_utilities/file_utils (2)/imports/imports/constants.py +119 -0
- abstract_utilities/file_utils (2)/imports/imports/imports.py +46 -0
- abstract_utilities/file_utils (2)/imports/imports/module_imports.py +8 -0
- abstract_utilities/file_utils (2)/imports/utils/__init__.py +3 -0
- abstract_utilities/file_utils (2)/imports/utils/classes.py +379 -0
- abstract_utilities/file_utils (2)/imports/utils/clean_imps.py +155 -0
- abstract_utilities/file_utils (2)/imports/utils/filter_utils.py +341 -0
- abstract_utilities/file_utils (2)/src/__init__.py +8 -0
- abstract_utilities/file_utils (2)/src/file_filters.py +155 -0
- abstract_utilities/file_utils (2)/src/file_reader.py +604 -0
- abstract_utilities/file_utils (2)/src/find_collect.py +258 -0
- abstract_utilities/file_utils (2)/src/initFunctionsGen.py +286 -0
- abstract_utilities/file_utils (2)/src/map_utils.py +28 -0
- abstract_utilities/file_utils (2)/src/pdf_utils.py +300 -0
- abstract_utilities/hash_utils/__init__.py +2 -0
- abstract_utilities/hash_utils/hash_utils.py +5 -0
- abstract_utilities/hash_utils/imports/__init__.py +2 -0
- abstract_utilities/hash_utils/imports/imports.py +1 -0
- abstract_utilities/hash_utils/imports/module_imports.py +0 -0
- abstract_utilities/history_utils/__init__.py +2 -0
- abstract_utilities/history_utils/history_utils.py +37 -0
- abstract_utilities/history_utils/imports/__init__.py +2 -0
- abstract_utilities/history_utils/imports/imports.py +1 -0
- abstract_utilities/history_utils/imports/module_imports.py +0 -0
- abstract_utilities/import_utils/__init__.py +2 -0
- abstract_utilities/import_utils/imports/__init__.py +4 -0
- abstract_utilities/import_utils/imports/constants.py +2 -0
- abstract_utilities/import_utils/imports/imports.py +4 -0
- abstract_utilities/import_utils/imports/module_imports.py +6 -0
- abstract_utilities/import_utils/imports/utils.py +30 -0
- abstract_utilities/import_utils/src/__init__.py +7 -0
- abstract_utilities/import_utils/src/clean_imports.py +147 -0
- abstract_utilities/import_utils/src/dot_utils.py +69 -0
- abstract_utilities/import_utils/src/extract_utils.py +42 -0
- abstract_utilities/import_utils/src/import_functions.py +46 -0
- abstract_utilities/import_utils/src/import_utils.py +299 -0
- abstract_utilities/import_utils/src/package_utils/__init__.py +139 -0
- abstract_utilities/import_utils/src/package_utils/context_utils.py +27 -0
- abstract_utilities/import_utils/src/package_utils/import_collectors.py +53 -0
- abstract_utilities/import_utils/src/package_utils/path_utils.py +28 -0
- abstract_utilities/import_utils/src/package_utils/safe_import.py +27 -0
- abstract_utilities/import_utils/src/package_utils.py +140 -0
- abstract_utilities/import_utils/src/package_utilss/__init__.py +139 -0
- abstract_utilities/import_utils/src/package_utilss/context_utils.py +27 -0
- abstract_utilities/import_utils/src/package_utilss/import_collectors.py +53 -0
- abstract_utilities/import_utils/src/package_utilss/path_utils.py +28 -0
- abstract_utilities/import_utils/src/package_utilss/safe_import.py +27 -0
- abstract_utilities/import_utils/src/pkg_utils.py +140 -0
- abstract_utilities/import_utils/src/sysroot_utils.py +57 -0
- abstract_utilities/imports.py +18 -0
- abstract_utilities/json_utils/__init__.py +2 -0
- abstract_utilities/json_utils/imports/__init__.py +2 -0
- abstract_utilities/json_utils/imports/imports.py +2 -0
- abstract_utilities/json_utils/imports/module_imports.py +5 -0
- abstract_utilities/json_utils/json_utils.py +743 -0
- abstract_utilities/list_utils/__init__.py +2 -0
- abstract_utilities/list_utils/imports/__init__.py +2 -0
- abstract_utilities/list_utils/imports/imports.py +1 -0
- abstract_utilities/list_utils/imports/module_imports.py +0 -0
- abstract_utilities/list_utils/list_utils.py +199 -0
- abstract_utilities/log_utils/__init__.py +5 -0
- abstract_utilities/log_utils/abstractLogManager.py +64 -0
- abstract_utilities/log_utils/call_response.py +68 -0
- abstract_utilities/log_utils/imports/__init__.py +2 -0
- abstract_utilities/log_utils/imports/imports.py +7 -0
- abstract_utilities/log_utils/imports/module_imports.py +2 -0
- abstract_utilities/log_utils/log_file.py +58 -0
- abstract_utilities/log_utils/logger_callable.py +49 -0
- abstract_utilities/math_utils/__init__.py +2 -0
- abstract_utilities/math_utils/imports/__init__.py +2 -0
- abstract_utilities/math_utils/imports/imports.py +2 -0
- abstract_utilities/math_utils/imports/module_imports.py +1 -0
- abstract_utilities/math_utils/math_utils.py +208 -0
- abstract_utilities/parse_utils/__init__.py +2 -0
- abstract_utilities/parse_utils/imports/__init__.py +3 -0
- abstract_utilities/parse_utils/imports/constants.py +10 -0
- abstract_utilities/parse_utils/imports/imports.py +2 -0
- abstract_utilities/parse_utils/imports/module_imports.py +4 -0
- abstract_utilities/parse_utils/parse_utils.py +516 -0
- abstract_utilities/path_utils/__init__.py +2 -0
- abstract_utilities/path_utils/imports/__init__.py +3 -0
- abstract_utilities/path_utils/imports/imports.py +1 -0
- abstract_utilities/path_utils/imports/module_imports.py +8 -0
- abstract_utilities/path_utils/path_utils.py +251 -0
- abstract_utilities/path_utils.py +95 -14
- abstract_utilities/read_write_utils/__init__.py +1 -0
- abstract_utilities/read_write_utils/imports/__init__.py +2 -0
- abstract_utilities/read_write_utils/imports/imports.py +2 -0
- abstract_utilities/read_write_utils/imports/module_imports.py +5 -0
- abstract_utilities/read_write_utils/read_write_utils.py +338 -0
- abstract_utilities/read_write_utils.py +110 -60
- abstract_utilities/safe_utils/__init__.py +2 -0
- abstract_utilities/safe_utils/imports/__init__.py +3 -0
- abstract_utilities/safe_utils/imports/imports.py +2 -0
- abstract_utilities/safe_utils/imports/module_imports.py +2 -0
- abstract_utilities/safe_utils/safe_utils.py +136 -0
- abstract_utilities/ssh_utils/__init__.py +3 -1
- abstract_utilities/ssh_utils/classes.py +0 -1
- abstract_utilities/ssh_utils/cmd_utils.py +207 -0
- abstract_utilities/ssh_utils/imports/__init__.py +3 -0
- abstract_utilities/ssh_utils/imports/imports.py +5 -0
- abstract_utilities/ssh_utils/imports/module_imports.py +6 -0
- abstract_utilities/ssh_utils/imports/utils.py +189 -0
- abstract_utilities/ssh_utils/pexpect_utils.py +11 -18
- abstract_utilities/ssh_utils/type_checks.py +92 -0
- abstract_utilities/string_utils/__init__.py +4 -0
- abstract_utilities/string_utils/clean_utils.py +28 -0
- abstract_utilities/string_utils/eat_utils.py +103 -0
- abstract_utilities/string_utils/imports/__init__.py +3 -0
- abstract_utilities/string_utils/imports/imports.py +2 -0
- abstract_utilities/string_utils/imports/module_imports.py +2 -0
- abstract_utilities/string_utils/imports/utils.py +81 -0
- abstract_utilities/string_utils/replace_utils.py +27 -0
- abstract_utilities/thread_utils/__init__.py +2 -0
- abstract_utilities/thread_utils/imports/__init__.py +2 -0
- abstract_utilities/thread_utils/imports/imports.py +2 -0
- abstract_utilities/thread_utils/imports/module_imports.py +2 -0
- abstract_utilities/thread_utils/thread_utils.py +140 -0
- abstract_utilities/time_utils/__init__.py +2 -0
- abstract_utilities/time_utils/imports/__init__.py +2 -0
- abstract_utilities/time_utils/imports/imports.py +3 -0
- abstract_utilities/time_utils/imports/module_imports.py +1 -0
- abstract_utilities/time_utils/time_utils.py +392 -0
- abstract_utilities/type_utils/__init__.py +3 -0
- abstract_utilities/type_utils/alpha_utils.py +59 -0
- abstract_utilities/type_utils/imports/__init__.py +2 -0
- abstract_utilities/type_utils/imports/imports.py +4 -0
- abstract_utilities/type_utils/imports/module_imports.py +1 -0
- abstract_utilities/type_utils/num_utils.py +19 -0
- abstract_utilities/type_utils/type_utils.py +981 -0
- {abstract_utilities-0.2.2.486.dist-info → abstract_utilities-0.2.2.540.dist-info}/METADATA +1 -1
- abstract_utilities-0.2.2.540.dist-info/RECORD +263 -0
- imports/__init__.py +36 -0
- abstract_utilities-0.2.2.486.dist-info/RECORD +0 -92
- {abstract_utilities-0.2.2.486.dist-info → abstract_utilities-0.2.2.540.dist-info}/WHEEL +0 -0
- {abstract_utilities-0.2.2.486.dist-info → abstract_utilities-0.2.2.540.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
from ..imports import *
|
|
2
|
+
def if_none_return(obj: object, obj_2: object) -> object:
|
|
3
|
+
"""
|
|
4
|
+
Return obj if obj_2 is None, otherwise return obj_2.
|
|
5
|
+
|
|
6
|
+
Args:
|
|
7
|
+
obj (Any): Primary object to return.
|
|
8
|
+
obj_2 (Any): Secondary object to check.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
Any: obj if obj_2 is None, else obj_2.
|
|
12
|
+
"""
|
|
13
|
+
return obj if obj_2 is None else obj_2
|
|
14
|
+
|
|
15
|
+
def write_pdf() -> PyPDF2.PdfWriter:
|
|
16
|
+
"""
|
|
17
|
+
Return a new PDF writer object.
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
PyPDF2.PdfWriter: New PDF writer object.
|
|
21
|
+
"""
|
|
22
|
+
return PyPDF2.PdfWriter()
|
|
23
|
+
def read_pdf(file: str):
|
|
24
|
+
"""
|
|
25
|
+
Read and return a PDF reader object from the provided file path.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
file (str): Path to the PDF file.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
PyPDF2.PdfReader: PDF reader object.
|
|
32
|
+
"""
|
|
33
|
+
return PyPDF2.PdfReader(file)
|
|
34
|
+
def is_pdf_path(file: str):
|
|
35
|
+
"""
|
|
36
|
+
Checks if a given file path corresponds to a PDF file.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
file (str): A string representing the file path.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
bool: True if the file has a '.pdf' extension, False otherwise.
|
|
43
|
+
"""
|
|
44
|
+
if is_file(file):
|
|
45
|
+
if get_ext(file) == '.pdf':
|
|
46
|
+
return True
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
def read_pdf(file: str):
|
|
50
|
+
"""Read and return a PDF reader object from the provided file path."""
|
|
51
|
+
return PyPDF2.PdfReader(file)
|
|
52
|
+
def get_pdf_obj(pdf_obj: Union[str, object]) -> object:
|
|
53
|
+
"""
|
|
54
|
+
Processes and returns a PDF object. If provided with a file path to a PDF,
|
|
55
|
+
it reads and returns the PDF content as an object.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
pdf_obj: Either a PDF file path or an existing PDF object.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
object: The PDF content as an object.
|
|
62
|
+
"""
|
|
63
|
+
if is_str(pdf_obj):
|
|
64
|
+
if is_pdf_path(pdf_obj):
|
|
65
|
+
pdf_obj = read_pdf(pdf_obj) # Assuming there's a function read_pdf() to read PDF content
|
|
66
|
+
return pdf_obj
|
|
67
|
+
def get_separate_pages(pdf_reader, start_page:int=1, end_page:int=None):
|
|
68
|
+
"""
|
|
69
|
+
Get specific pages from a PDF and return them as a new PDF object.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
pdf_reader (object): The PDF reader object.
|
|
73
|
+
start_page (int, optional): The starting page number. Defaults to 1.
|
|
74
|
+
end_page (int, optional): The ending page number. Defaults to the last page.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
object: A new PDF writer object with the specified pages.
|
|
78
|
+
"""
|
|
79
|
+
num_pages = get_pdf_pages(pdf_reader)
|
|
80
|
+
|
|
81
|
+
# Handling default or out-of-bounds page values
|
|
82
|
+
if end_page is None or num_pages < end_page:
|
|
83
|
+
end_page = num_pages
|
|
84
|
+
elif num_pages < start_page:
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
pdf_writer = write_pdf()
|
|
88
|
+
|
|
89
|
+
for page_num in range(num_pages):
|
|
90
|
+
if start_page <= page_num <= end_page:
|
|
91
|
+
pdf_writer.add_page(pdf_reader.pages[page_num])
|
|
92
|
+
return pdf_writer
|
|
93
|
+
def is_pdf_path(file):
|
|
94
|
+
"""
|
|
95
|
+
Check if the provided file path corresponds to a valid PDF file.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
file (str): File path.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
bool: True if it's a valid PDF path, False otherwise.
|
|
102
|
+
"""
|
|
103
|
+
if is_file(file) and get_ext(file).lower() == '.pdf':
|
|
104
|
+
return True
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
def get_pdf_pages(pdf_file):
|
|
108
|
+
"""
|
|
109
|
+
Get the total number of pages in the PDF.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
pdf_file (object/str): PDF reader object or path to a PDF file.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
int: Number of pages in the PDF.
|
|
116
|
+
"""
|
|
117
|
+
pdf_file = get_pdf_obj(pdf_file)
|
|
118
|
+
try:
|
|
119
|
+
return len(pdf_file.pages)
|
|
120
|
+
except:
|
|
121
|
+
return False
|
|
122
|
+
def save_pdf(output_file_path, pdf_writer):
|
|
123
|
+
"""
|
|
124
|
+
Save a PDF writer object to a file.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
output_file_path (str): Path to save the PDF.
|
|
128
|
+
pdf_writer (object): PDF writer object to save.
|
|
129
|
+
"""
|
|
130
|
+
with open(output_file_path, 'wb') as output_file:
|
|
131
|
+
pdf_writer.write(output_file)
|
|
132
|
+
def split_pdf(input_path: str, output_folder: Optional[str] = None, file_name: Optional[str] = None) -> List[str]:
|
|
133
|
+
"""
|
|
134
|
+
Split a PDF file into separate files for each page.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
input_path (str): Path to the input PDF file.
|
|
138
|
+
output_folder (str, optional): Directory to save the split PDF files. Defaults to the directory of input_path.
|
|
139
|
+
file_name (str, optional): Base name for the output files. Defaults to the base name of input_path.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
list: List of paths to the created split PDF files.
|
|
143
|
+
"""
|
|
144
|
+
pdf_pages = []
|
|
145
|
+
file_name = get_file_name(input_path) if file_name is None else file_name
|
|
146
|
+
output_folder = if_none_return(get_directory(input_path), output_folder)
|
|
147
|
+
|
|
148
|
+
print(f"Splitting PDF: {input_path}")
|
|
149
|
+
print(f"Output Folder: {output_folder}")
|
|
150
|
+
print(f"Using Filename: {file_name}")
|
|
151
|
+
|
|
152
|
+
with open(input_path, 'rb') as pdf_file:
|
|
153
|
+
pdf_reader = PyPDF2.PdfReader(pdf_file)
|
|
154
|
+
num_pages = len(pdf_reader.pages) # Replace getNumPages() with len(pdf_reader.pages)
|
|
155
|
+
|
|
156
|
+
print(f"Number of pages in PDF: {num_pages}")
|
|
157
|
+
|
|
158
|
+
for page_num in range(num_pages):
|
|
159
|
+
pdf_writer = PyPDF2.PdfWriter()
|
|
160
|
+
pdf_writer.add_page(pdf_reader.pages[page_num]) # Use the pdf_writer instance you created
|
|
161
|
+
|
|
162
|
+
output_file_path = os.path.join(output_folder, f'{file_name}_page_{page_num + 1}.pdf')
|
|
163
|
+
output_img_path = os.path.join(output_folder, f'{file_name}_page_{page_num + 1}.png')
|
|
164
|
+
print(f"Writing to: {output_file_path}")
|
|
165
|
+
pdf_pages.append(output_file_path)
|
|
166
|
+
save_pdf(output_file_path,pdf_writer)
|
|
167
|
+
|
|
168
|
+
return pdf_pages
|
|
169
|
+
def pdf_to_img_list(pdf_list: List[str], output_folder: Optional[str] = None, file_name: Optional[str] = None,
|
|
170
|
+
paginate: bool = False, extension: str = "png") -> List[str]:
|
|
171
|
+
"""
|
|
172
|
+
Convert a list of PDF files to images.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
pdf_list (List[str]): List of paths to PDF files.
|
|
176
|
+
output_folder (str, optional): Directory to save the images. Defaults to PDF's directory.
|
|
177
|
+
file_name (str, optional): Base name for the images. Defaults to PDF's name.
|
|
178
|
+
paginate (bool): Whether to paginate the image names. Defaults to False.
|
|
179
|
+
extension (str): Extension for the image files. Defaults to "png".
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
List[str]: List of paths to the created image files.
|
|
183
|
+
"""
|
|
184
|
+
image_list=[]
|
|
185
|
+
file_name_start = file_name
|
|
186
|
+
for i, each in enumerate(pdf_list):
|
|
187
|
+
try:
|
|
188
|
+
images = convert_from_path(each)
|
|
189
|
+
except Exception as e:
|
|
190
|
+
print("An error occurred while converting the PDF:", e)
|
|
191
|
+
|
|
192
|
+
if output_folder is None:
|
|
193
|
+
output_folder = get_directory(each)
|
|
194
|
+
if file_name_start is None:
|
|
195
|
+
file_name = get_file_name(each)
|
|
196
|
+
if paginate:
|
|
197
|
+
file_name=f"{file_name}_Page_{i}"
|
|
198
|
+
|
|
199
|
+
for i, image in enumerate(images):
|
|
200
|
+
image_output_path = os.path.join(output_folder, f"{file_name}.{extension}")
|
|
201
|
+
image_list.append(image_output_path)
|
|
202
|
+
save_image(image=image, image_path=image_output_path, format=extension.upper())
|
|
203
|
+
return image_list
|
|
204
|
+
def img_to_txt_list(img_list: List[str], output_folder: Optional[str] = None, file_name: Optional[str] = None,
|
|
205
|
+
paginate: bool = False, extension: str = "txt") -> List[str]:
|
|
206
|
+
"""
|
|
207
|
+
Convert a list of image files to text.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
img_list (List[str]): List of paths to image files.
|
|
211
|
+
output_folder (str, optional): Directory to save the text files. Defaults to image's directory.
|
|
212
|
+
file_name (str, optional): Base name for the text files. Defaults to image's name.
|
|
213
|
+
paginate (bool): Whether to paginate the text filenames. Defaults to False.
|
|
214
|
+
extension (str): Extension for the text files. Defaults to "txt".
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
List[str]: List of paths to the created text files.
|
|
218
|
+
"""
|
|
219
|
+
text_list = []
|
|
220
|
+
file_name_start = file_name
|
|
221
|
+
for i, each in enumerate(img_list):
|
|
222
|
+
if output_folder is None:
|
|
223
|
+
output_folder = get_directory(each)
|
|
224
|
+
if file_name_start is None:
|
|
225
|
+
file_name = get_file_name(each)
|
|
226
|
+
if paginate:
|
|
227
|
+
file_name=f"{file_name}_Page_{i}"
|
|
228
|
+
|
|
229
|
+
text_output = image_to_text(each)
|
|
230
|
+
text_output_path = os.path.join(output_folder, f"{get_file_name(each)}.{extension}")
|
|
231
|
+
text_list.append(text_output_path)
|
|
232
|
+
write_to_file(filepath=text_output_path, contents=text_output)
|
|
233
|
+
return text_list
|
|
234
|
+
def open_pdf_file(pdf_file_path: str) -> None:
|
|
235
|
+
"""
|
|
236
|
+
Open a PDF file using the default associated program.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
pdf_file_path (str): Path to the PDF file to open.
|
|
240
|
+
"""
|
|
241
|
+
try:
|
|
242
|
+
# Open the PDF file using the default associated program
|
|
243
|
+
cmd_input("open "+pdf_file_path)
|
|
244
|
+
except FileNotFoundError:
|
|
245
|
+
print("Error: The specified file does not exist.")
|
|
246
|
+
except Exception as e:
|
|
247
|
+
print("Error:", e)
|
|
248
|
+
# use it before writing to a file
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def get_pdfs_in_directory(directory: str) -> List[str]:
|
|
252
|
+
"""
|
|
253
|
+
Get a list of PDF filenames in a given directory.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
directory (str): Path to the directory.
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
list: List of PDF filenames in the directory.
|
|
260
|
+
"""
|
|
261
|
+
pdfs = []
|
|
262
|
+
for filename in os.listdir(directory):
|
|
263
|
+
if is_pdf_path(filename):
|
|
264
|
+
pdfs.append(filename)
|
|
265
|
+
return pdfs
|
|
266
|
+
|
|
267
|
+
def get_all_pdf_in_directory(file_directory: Optional[str] = None) -> List[str]:
|
|
268
|
+
"""
|
|
269
|
+
Get a list of complete paths to PDF files in a given directory.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
file_directory (str, optional): Path to the directory.
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
list: List of paths to PDF files in the directory.
|
|
276
|
+
"""
|
|
277
|
+
pdfs=[]
|
|
278
|
+
for filename in sorted(os.listdir(file_directory)):
|
|
279
|
+
if is_pdf_path(filename):
|
|
280
|
+
pdf_path = os.path.join(file_directory, filename)
|
|
281
|
+
if is_file(pdf_path):
|
|
282
|
+
pdfs.append(pdf_path)
|
|
283
|
+
return pdfs
|
|
284
|
+
|
|
285
|
+
def collate_pdfs(pdf_list: List[str], output_pdf_path: str) -> None:
|
|
286
|
+
"""
|
|
287
|
+
Merge multiple PDF files into a single PDF.
|
|
288
|
+
|
|
289
|
+
Args:
|
|
290
|
+
pdf_list (list): List of paths to PDF files to be merged.
|
|
291
|
+
output_pdf_path (str): Path to save the merged PDF.
|
|
292
|
+
"""
|
|
293
|
+
pdf_writer = PyPDF2.PdfWriter()
|
|
294
|
+
for file_path in pdf_list:
|
|
295
|
+
with open(file_path, 'rb') as pdf_file:
|
|
296
|
+
pdf_reader = PyPDF2.PdfReader(pdf_file)
|
|
297
|
+
for page_num in range(len(pdf_reader.pages)):
|
|
298
|
+
pdf_writer.add_page(pdf_reader.pages[page_num])
|
|
299
|
+
save_pdf(output_file_path, pdf_writer)
|
|
300
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from ...imports import hashlib
|
|
File without changes
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
class HistoryManager:
|
|
2
|
+
def __init__(self):
|
|
3
|
+
self.history_names = {}
|
|
4
|
+
|
|
5
|
+
def add_history_name(self, name, initial_data=''):
|
|
6
|
+
self.history_names[name] = {"history": [initial_data], "history_redo": []}
|
|
7
|
+
return name
|
|
8
|
+
|
|
9
|
+
def transfer_state(self, primary_data, secondary_data):
|
|
10
|
+
"""
|
|
11
|
+
Transfer the latest state from primary_data to secondary_data
|
|
12
|
+
Returns the modified primary and secondary data lists
|
|
13
|
+
"""
|
|
14
|
+
self.last_data = None
|
|
15
|
+
# If there's data in primary, transfer the latest to secondary
|
|
16
|
+
if primary_data:
|
|
17
|
+
self.last_data = primary_data.pop()
|
|
18
|
+
secondary_data.append(self.last_data)
|
|
19
|
+
|
|
20
|
+
return primary_data, secondary_data
|
|
21
|
+
|
|
22
|
+
def add_to_history(self, name, data):
|
|
23
|
+
# Clear the redo history when a new state is added
|
|
24
|
+
self.history_names[name]['history_redo'] = []
|
|
25
|
+
self.history_names[name]['history'].append(data)
|
|
26
|
+
|
|
27
|
+
def redo(self, name):
|
|
28
|
+
# Redo by transferring state from redo history to actual history
|
|
29
|
+
self.history_names[name]["history_redo"], self.history_names[name]["history"] = self.transfer_state(
|
|
30
|
+
self.history_names[name]["history_redo"], self.history_names[name]["history"])
|
|
31
|
+
return self.last_data
|
|
32
|
+
|
|
33
|
+
def undo(self, name):
|
|
34
|
+
# Undo by transferring state from actual history to redo history
|
|
35
|
+
self.history_names[name]["history"], self.history_names[name]["history_redo"] = self.transfer_state(
|
|
36
|
+
self.history_names[name]["history"], self.history_names[name]["history_redo"])
|
|
37
|
+
return self.last_data
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
from ...read_write_utils import read_from_file,write_to_file,get_text_or_read
|
|
2
|
+
from ...string_utils import eatAll,eatInner,eatElse,clean_line
|
|
3
|
+
from ...class_utils import get_caller_path
|
|
4
|
+
from ...list_utils import make_list
|
|
5
|
+
from ...path_utils import get_file_parts
|
|
6
|
+
from ...type_utils import is_number,make_list
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from .constants import *
|
|
3
|
+
|
|
4
|
+
def is_line_import(line):
|
|
5
|
+
if line and (line.startswith(FROM_TAG) or line.startswith(IMPORT_TAG)):
|
|
6
|
+
return True
|
|
7
|
+
return False
|
|
8
|
+
def is_line_group_import(line):
|
|
9
|
+
if line and (line.startswith(FROM_TAG) and IMPORT_TAG in line):
|
|
10
|
+
return True
|
|
11
|
+
return False
|
|
12
|
+
|
|
13
|
+
def is_from_line_group(line):
|
|
14
|
+
if line and line.startswith(FROM_TAG) and IMPORT_TAG in line and '(' in line:
|
|
15
|
+
import_spl = line.split(IMPORT_TAG)[-1]
|
|
16
|
+
import_spl_clean = clean_line(line)
|
|
17
|
+
if not import_spl_clean.endswith(')'):
|
|
18
|
+
return True
|
|
19
|
+
return False
|
|
20
|
+
def get_unique_name(string,list_obj):
|
|
21
|
+
if isinstance(list_obj,dict):
|
|
22
|
+
list_obj = list(list_obj.keys())
|
|
23
|
+
if string in list_obj:
|
|
24
|
+
nustring = f"{string}"
|
|
25
|
+
for i in range(len(list_obj)):
|
|
26
|
+
nustring = f"{string}_{i}"
|
|
27
|
+
if nustring not in list_obj:
|
|
28
|
+
break
|
|
29
|
+
string = nustring
|
|
30
|
+
return string
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
from ..imports import *
|
|
2
|
+
from .pkg_utils import *
|
|
3
|
+
|
|
4
|
+
def get_text_or_read(text=None,file_path=None):
|
|
5
|
+
text = text or ''
|
|
6
|
+
imports_js = {}
|
|
7
|
+
if not text and file_path and os.path.isfile(file_path):
|
|
8
|
+
text=read_from_file(file_path)
|
|
9
|
+
return text
|
|
10
|
+
def is_line_import(line):
|
|
11
|
+
if line and (line.startswith(FROM_TAG) or line.startswith(IMPORT_TAG)):
|
|
12
|
+
return True
|
|
13
|
+
return False
|
|
14
|
+
def is_line_group_import(line):
|
|
15
|
+
if line and (line.startswith(FROM_TAG) and IMPORT_TAG in line):
|
|
16
|
+
return True
|
|
17
|
+
return False
|
|
18
|
+
|
|
19
|
+
def is_from_line_group(line):
|
|
20
|
+
if line and line.startswith(FROM_TAG) and IMPORT_TAG in line and '(' in line:
|
|
21
|
+
import_spl = line.split(IMPORT_TAG)[-1]
|
|
22
|
+
import_spl_clean = clean_line(line)
|
|
23
|
+
if not import_spl_clean.endswith(')'):
|
|
24
|
+
return True
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
def get_all_imports(text=None,file_path=None,import_pkg_js=None):
|
|
28
|
+
if text and os.path.isfile(text):
|
|
29
|
+
file_path = text
|
|
30
|
+
text = read_from_file(text)
|
|
31
|
+
text = get_text_or_read(text=text,file_path=file_path)
|
|
32
|
+
lines = text.split('\n')
|
|
33
|
+
cleaned_import_list=[]
|
|
34
|
+
nu_lines = []
|
|
35
|
+
is_from_group = False
|
|
36
|
+
import_pkg_js = ensure_import_pkg_js(import_pkg_js,file_path=file_path)
|
|
37
|
+
for line in lines:
|
|
38
|
+
if line.startswith(IMPORT_TAG) and ' from ' not in line:
|
|
39
|
+
cleaned_import_list = get_cleaned_import_list(line)
|
|
40
|
+
import_pkg_js = add_imports_to_import_pkg_js("import",cleaned_import_list,import_pkg_js=import_pkg_js)
|
|
41
|
+
else:
|
|
42
|
+
if is_from_group:
|
|
43
|
+
import_pkg=is_from_group
|
|
44
|
+
line = clean_line(line)
|
|
45
|
+
if line.endswith(')'):
|
|
46
|
+
is_from_group=False
|
|
47
|
+
line=line[:-1]
|
|
48
|
+
imports_from_import_pkg = clean_imports(line)
|
|
49
|
+
import_pkg_js = add_imports_to_import_pkg_js(import_pkg,imports_from_import_pkg,import_pkg_js=import_pkg_js)
|
|
50
|
+
|
|
51
|
+
else:
|
|
52
|
+
import_pkg_js=update_import_pkg_js(line,import_pkg_js=import_pkg_js)
|
|
53
|
+
if is_from_line_group(line) and is_from_group == False:
|
|
54
|
+
is_from_group=get_import_pkg(line)
|
|
55
|
+
return import_pkg_js
|
|
56
|
+
|
|
57
|
+
def clean_imports(text=None,file_path=None,import_pkg_js=None,fill_nulines=False):
|
|
58
|
+
if text and os.path.isfile(text):
|
|
59
|
+
file_path = text
|
|
60
|
+
text = read_from_file(text)
|
|
61
|
+
if not import_pkg_js:
|
|
62
|
+
import_pkg_js = get_all_imports(text=text,file_path=file_path)
|
|
63
|
+
import_pkg_js = ensure_import_pkg_js(import_pkg_js,file_path=file_path)
|
|
64
|
+
nu_lines = import_pkg_js["context"]["nulines"]
|
|
65
|
+
for pkg,values in import_pkg_js.items():
|
|
66
|
+
comments = []
|
|
67
|
+
if pkg not in ["context"]:
|
|
68
|
+
|
|
69
|
+
imports = values.get('imports')
|
|
70
|
+
for i,imp in enumerate(imports):
|
|
71
|
+
if '#' in imp:
|
|
72
|
+
imp_spl = imp.split('#')
|
|
73
|
+
comments.append(imp_spl[-1])
|
|
74
|
+
imports[i] = clean_line(imp_spl[0])
|
|
75
|
+
imports = list(set(imports))
|
|
76
|
+
if '*' in imports:
|
|
77
|
+
imports="*"
|
|
78
|
+
else:
|
|
79
|
+
imports=','.join(imports)
|
|
80
|
+
if comments:
|
|
81
|
+
comments=','.join(comments)
|
|
82
|
+
imports+=f" #{comments}"
|
|
83
|
+
import_pkg_js[pkg]["imports"]=imports
|
|
84
|
+
if fill_nulines:
|
|
85
|
+
line = values.get('line')
|
|
86
|
+
if len(nu_lines) >= line:
|
|
87
|
+
nu_lines[line] += imports
|
|
88
|
+
return import_pkg_js
|
|
89
|
+
def clean_all_imports(text=None,file_path=None,import_pkg_js=None,fill_nulines=False):
|
|
90
|
+
clean_imports(text=text,file_path=file_path,import_pkg_js=import_pkg_js,fill_nulines=import_pkg_js)
|
|
91
|
+
import_pkg_js["context"]["nulines"]=nu_lines
|
|
92
|
+
return import_pkg_js
|
|
93
|
+
def get_clean_import_string(import_pkg_js,fill_nulines=False,get_locals=False):
|
|
94
|
+
import_pkg_js = clean_imports(import_pkg_js=import_pkg_js,fill_nulines=fill_nulines)
|
|
95
|
+
import_ls = []
|
|
96
|
+
for key,values in import_pkg_js.items():
|
|
97
|
+
if key not in ['context','nulines']:
|
|
98
|
+
imports = None
|
|
99
|
+
imp_values= values.get('imports')
|
|
100
|
+
if key == 'import':
|
|
101
|
+
imports = f'import {imp_values}'
|
|
102
|
+
elif get_locals or not key.startswith('.'):
|
|
103
|
+
imports = f'from {key} import {imp_values}'
|
|
104
|
+
if imports:
|
|
105
|
+
import_ls.append(imports)
|
|
106
|
+
return '\n'.join(import_ls)
|
|
107
|
+
def get_clean_imports_from_files(files):
|
|
108
|
+
import_pkg_js={}
|
|
109
|
+
for file in files:
|
|
110
|
+
import_pkg_js = get_all_imports(file,import_pkg_js=import_pkg_js)
|
|
111
|
+
return get_clean_import_string(import_pkg_js)
|
|
112
|
+
def get_dot_fro_line(line,dirname):
|
|
113
|
+
from_line = line.split(FROM_TAG)[-1]
|
|
114
|
+
dot_fro = ""
|
|
115
|
+
for char in from_line:
|
|
116
|
+
if char != '.':
|
|
117
|
+
line = f"from {dot_fro}{eatAll(from_line,'.')}"
|
|
118
|
+
break
|
|
119
|
+
dirname = os.path.dirname(dirname)
|
|
120
|
+
dirbase = os.path.basename(dirname)
|
|
121
|
+
dot_fro = f"{dirbase}.{dot_fro}"
|
|
122
|
+
return line
|
|
123
|
+
def get_dot_fro_lines(lines,file_path,all_imps):
|
|
124
|
+
for line in lines:
|
|
125
|
+
if line.startswith(FROM_TAG):
|
|
126
|
+
line = get_dot_fro_line(line,file_path)
|
|
127
|
+
if line in all_imps:
|
|
128
|
+
line = ""
|
|
129
|
+
if line:
|
|
130
|
+
all_imps.append(line)
|
|
131
|
+
return all_imps
|
|
132
|
+
def get_all_real_imps(text=None,file_path=None,all_imps=None):
|
|
133
|
+
if text and os.path.isfile(text):
|
|
134
|
+
file_path = text
|
|
135
|
+
text = read_from_file(text)
|
|
136
|
+
all_imps = all_imps or []
|
|
137
|
+
contents = get_text_or_read(text=text,file_path=file_path)
|
|
138
|
+
lines = contents.split('\n')
|
|
139
|
+
all_imps = get_dot_fro_lines(lines,file_path,all_imps)
|
|
140
|
+
return '\n'.join(all_imps)
|
|
141
|
+
def save_cleaned_imports(text=None,file_path=None,write=False,import_pkg_js=None):
|
|
142
|
+
import_pkg_js=get_all_imports(text=text,file_path=file_path,import_pkg_js=import_pkg_js)
|
|
143
|
+
import_pkg_js = clean_all_imports(text=text,file_path=file_path,import_pkg_js=import_pkg_js)
|
|
144
|
+
contents = '\n'.join(import_pkg_js["context"]["nulines"])
|
|
145
|
+
if file_path and write:
|
|
146
|
+
write_to_file(contents=contents,file_path=file_path)
|
|
147
|
+
return contents
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from ..imports import *
|
|
2
|
+
def get_Path(path):
|
|
3
|
+
if isinstance(path,str):
|
|
4
|
+
path = Path(str(path))
|
|
5
|
+
return path
|
|
6
|
+
def get_dot_range(filepath=None,list_obj=None):
|
|
7
|
+
imports = make_list(list_obj) or extract_imports(filepath)
|
|
8
|
+
highest=0
|
|
9
|
+
dots = [get_imp(fro) for fro in imports if fro]
|
|
10
|
+
|
|
11
|
+
if dots:
|
|
12
|
+
dots.sort()
|
|
13
|
+
highest = dots[0]
|
|
14
|
+
return highest
|
|
15
|
+
def dotted_from(file: Path, sysroot: Path) -> str:
|
|
16
|
+
"""
|
|
17
|
+
Build dotted name from sysroot (directory *above* top package)
|
|
18
|
+
e.g. /repo/abstract_ide/consoles/launcherWindowTab/functions/core_utils.py
|
|
19
|
+
sysroot=/repo -> abstract_ide.consoles.launcherWindowTab.functions.core_utils
|
|
20
|
+
"""
|
|
21
|
+
file = get_Path(file)
|
|
22
|
+
sysroot = get_Path(sysroot)
|
|
23
|
+
file = file.resolve()
|
|
24
|
+
stem = file.with_suffix("") # drop .py
|
|
25
|
+
return ".".join(stem.relative_to(sysroot).parts)
|
|
26
|
+
def to_dotted_name(file_path: Path, top_package: str) -> str:
|
|
27
|
+
"""
|
|
28
|
+
Convert .../abstract_ide/consoles/launcherWindowTab/functions/core_utils.py
|
|
29
|
+
-> abstract_ide.consoles.launcherWindowTab.functions.core_utils
|
|
30
|
+
"""
|
|
31
|
+
# find the index of the top_package in the path parts
|
|
32
|
+
file_path = get_Path(file_path)
|
|
33
|
+
top_package = get_Path(top_package)
|
|
34
|
+
parts = file_path.resolve().parts
|
|
35
|
+
i = None
|
|
36
|
+
if is_number(top_package):
|
|
37
|
+
i= int(top_package)
|
|
38
|
+
if i is None:
|
|
39
|
+
try:
|
|
40
|
+
i = parts.index(top_package)
|
|
41
|
+
except ValueError:
|
|
42
|
+
raise RuntimeError(f"Cannot locate package '{top_package}' in {file_path}")
|
|
43
|
+
rel_parts = parts[i:] # from top_package onward
|
|
44
|
+
if rel_parts[-1].endswith(".py"):
|
|
45
|
+
rel_parts = list(rel_parts)
|
|
46
|
+
rel_parts[-1] = rel_parts[-1][:-3] # strip .py
|
|
47
|
+
return ".".join(rel_parts)
|
|
48
|
+
def compute_dotted_and_sysroot(file_path: Path) -> Tuple[str, Path]:
|
|
49
|
+
"""
|
|
50
|
+
If inside packages, build dotted name from the top package down.
|
|
51
|
+
sysroot will be the directory *above* the top package.
|
|
52
|
+
If not a package, we fall back to a repo-ish root guess (2 parents up).
|
|
53
|
+
"""
|
|
54
|
+
file_path = get_Path(file_path)
|
|
55
|
+
file_path = file_path.resolve()
|
|
56
|
+
stem = file_path.with_suffix("") # drop .py
|
|
57
|
+
|
|
58
|
+
top_pkg_dir = find_top_package_dir(file_path)
|
|
59
|
+
if top_pkg_dir:
|
|
60
|
+
sysroot = top_pkg_dir.parent
|
|
61
|
+
dotted = ".".join(stem.relative_to(sysroot).parts)
|
|
62
|
+
return dotted, sysroot
|
|
63
|
+
|
|
64
|
+
# Fallback: not in a package tree — guess a root a couple levels up
|
|
65
|
+
sysroot = file_path.parents[2]
|
|
66
|
+
dotted = ".".join(stem.relative_to(sysroot).parts)
|
|
67
|
+
return dotted, sysroot
|
|
68
|
+
|
|
69
|
+
|