convert-stream 2.2.1__tar.gz → 2.2.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of convert-stream might be problematic. Click here for more details.

Files changed (32) hide show
  1. {convert_stream-2.2.1 → convert_stream-2.2.5}/PKG-INFO +1 -1
  2. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/pdf/pdf_document.py +238 -93
  3. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/stream.py +12 -8
  4. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/table_files.py +8 -101
  5. convert_stream-2.2.5/convert_stream/text/__init__.py +7 -0
  6. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/text/string.py +0 -25
  7. convert_stream-2.2.5/convert_stream/text/terminal.py +61 -0
  8. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream.egg-info/PKG-INFO +1 -1
  9. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream.egg-info/SOURCES.txt +2 -1
  10. {convert_stream-2.2.1 → convert_stream-2.2.5}/pyproject.toml +1 -1
  11. convert_stream-2.2.1/convert_stream/text/__init__.py +0 -6
  12. {convert_stream-2.2.1 → convert_stream-2.2.5}/README.md +0 -0
  13. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/__init__.py +0 -0
  14. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/__main__.py +0 -0
  15. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/_version.py +0 -0
  16. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/enum_libs/enums.py +0 -0
  17. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/enum_libs/modules.py +0 -0
  18. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/image/__init__.py +0 -0
  19. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/image/img_object.py +0 -0
  20. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/pdf/__init__.py +0 -0
  21. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/pdf/image_to_pdf.py +0 -0
  22. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/pdf/pdf_page.py +0 -0
  23. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/pdf/pdf_to_image.py +0 -0
  24. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/sheets/__init__.py +0 -0
  25. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/sheets/load.py +0 -0
  26. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/sheets/parse.py +0 -0
  27. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/sheets/save.py +0 -0
  28. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream/text/date.py +0 -0
  29. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream.egg-info/dependency_links.txt +0 -0
  30. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream.egg-info/requires.txt +0 -0
  31. {convert_stream-2.2.1 → convert_stream-2.2.5}/convert_stream.egg-info/top_level.txt +0 -0
  32. {convert_stream-2.2.1 → convert_stream-2.2.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: convert_stream
3
- Version: 2.2.1
3
+ Version: 2.2.5
4
4
  Summary: Manipulação de documentos PDF e Imagens. Converter, Ler, rotacionar exportar etc.
5
5
  Author: Bruno Chaves
6
6
  Requires-Python: >=3.11
@@ -6,13 +6,107 @@
6
6
  from __future__ import annotations
7
7
  from abc import ABC, abstractmethod
8
8
  from io import BytesIO
9
- from soup_files import File, Directory, LibraryDocs, InputFiles, ProgressBarAdapter
10
- from convert_stream.enum_libs.enums import LibPDF
9
+
10
+ import pandas as pd
11
+ from soup_files import File, Directory, LibraryDocs, InputFiles, ProgressBarAdapter, JsonConvert
12
+ from convert_stream.enum_libs.enums import LibPDF, ColumnsTable
11
13
  from convert_stream.enum_libs.modules import (
12
14
  DEFAULT_LIB_PDF, ModuleDocPdf, ModulePagePdf, PdfWriter, PdfReader, PageObject, fitz,
13
15
  )
14
16
  from convert_stream.image.img_object import get_hash_from_bytes
15
17
  from convert_stream.pdf.pdf_page import PageDocumentPdf
18
+ from convert_stream.text import show_error, show_info, show_warning, MapText, FindText
19
+ from convert_stream.sheets.save import save_data
20
+
21
+
22
+ class SearchableTextPdf(object):
23
+ """
24
+ Esta classe serve para armazenar textos filtrados em documentos PDF
25
+ guardando o texto buscado e outros elementos como a página em que o texto foi
26
+ encontrado, linha e o nome do arquivo.
27
+ """
28
+ def __init__(self, silent: bool = False):
29
+ self.silent = silent
30
+ self.elements: dict[str, list[str]] = {
31
+ ColumnsTable.NUM_PAGE.value: [],
32
+ ColumnsTable.NUM_LINHA.value: [],
33
+ ColumnsTable.TEXT.value: [],
34
+ ColumnsTable.FILE.value: [],
35
+ }
36
+
37
+ def __repr__(self):
38
+ return f'SearchableTextPdf: {self.elements}'
39
+
40
+ def is_empty(self) -> bool:
41
+ return len(self.elements[ColumnsTable.TEXT.value]) == 0
42
+
43
+ @property
44
+ def first(self) -> dict[str, str]:
45
+ if self.is_empty():
46
+ return {}
47
+ return {
48
+ ColumnsTable.NUM_PAGE.value: self.elements[ColumnsTable.NUM_PAGE.value][0],
49
+ ColumnsTable.NUM_LINHA.value: self.elements[ColumnsTable.NUM_LINHA.value][0],
50
+ ColumnsTable.TEXT.value: self.elements[ColumnsTable.TEXT.value][0],
51
+ ColumnsTable.FILE.value: self.elements[ColumnsTable.FILE.value][0],
52
+ }
53
+
54
+ @property
55
+ def last(self) -> dict[str, str]:
56
+ if self.is_empty():
57
+ return {}
58
+ return {
59
+ ColumnsTable.NUM_PAGE.value: self.elements[ColumnsTable.NUM_PAGE.value][-1],
60
+ ColumnsTable.NUM_LINHA.value: self.elements[ColumnsTable.NUM_LINHA.value][-1],
61
+ ColumnsTable.TEXT.value: self.elements[ColumnsTable.TEXT.value][-1],
62
+ ColumnsTable.FILE.value: self.elements[ColumnsTable.FILE.value][-1],
63
+ }
64
+
65
+ @property
66
+ def length(self) -> int:
67
+ return len(self.elements[ColumnsTable.TEXT.value])
68
+
69
+ def get_item(self, idx: int) -> dict[str, str]:
70
+ try:
71
+ return {
72
+ ColumnsTable.NUM_PAGE.value: self.elements[ColumnsTable.NUM_PAGE.value][idx],
73
+ ColumnsTable.NUM_LINHA.value: self.elements[ColumnsTable.NUM_LINHA.value][idx],
74
+ ColumnsTable.TEXT.value: self.elements[ColumnsTable.TEXT.value][idx],
75
+ ColumnsTable.FILE.value: self.elements[ColumnsTable.FILE.value][idx],
76
+ }
77
+ except Exception as err:
78
+ if not self.silent:
79
+ print(err)
80
+ return {}
81
+
82
+ def add_line(self, text, *, num_page: str, num_line: str, file: str) -> None:
83
+ if not self.silent:
84
+ print(f'{file} => {text}')
85
+ self.elements[ColumnsTable.NUM_PAGE.value].append(num_page)
86
+ self.elements[ColumnsTable.NUM_LINHA.value].append(num_line)
87
+ self.elements[ColumnsTable.TEXT.value].append(text)
88
+ self.elements[ColumnsTable.FILE.value].append(file)
89
+
90
+ def clear(self) -> None:
91
+ for _k in self.elements.keys():
92
+ self.elements[_k].clear()
93
+
94
+ def to_string(self) -> str:
95
+ try:
96
+ return ' '.join(self.elements[ColumnsTable.TEXT.value])
97
+ except Exception as e:
98
+ print(e)
99
+ return 'nas'
100
+
101
+ def to_data_frame(self) -> pd.DataFrame:
102
+ return pd.DataFrame.from_dict(self.elements)
103
+
104
+ def to_file_json(self, file: File):
105
+ dt = JsonConvert.from_dict(self.elements).to_json_data()
106
+ dt.to_file(file)
107
+
108
+ def to_file_excel(self, file: File):
109
+ save_data(self.to_data_frame(), file=file)
16
110
 
17
111
 
18
112
  class ABCDocument(ABC):
@@ -39,11 +133,11 @@ class ABCDocument(ABC):
39
133
  pass
40
134
 
41
135
  @abstractmethod
42
- def add_page(self, page: ModulePagePdf):
136
+ def add_page(self, page: PageDocumentPdf):
43
137
  pass
44
138
 
45
139
  @abstractmethod
46
- def add_pages(self, pages: list[ModulePagePdf]):
140
+ def add_pages(self, pages: list[PageDocumentPdf]):
47
141
  pass
48
142
 
49
143
  @abstractmethod
@@ -58,14 +152,6 @@ class ABCDocument(ABC):
58
152
  def to_pages(self) -> list[PageDocumentPdf]:
59
153
  pass
60
154
 
61
- @abstractmethod
62
- def to_list(self, separator: str = '\n') -> list[str]:
63
- pass
64
-
65
- @abstractmethod
66
- def to_dict(self, separator: str = '\n') -> dict[str, list[str]]:
67
- pass
68
-
69
155
  @classmethod
70
156
  def create_from_file(cls, file: File) -> ABCDocument:
71
157
  pass
@@ -79,7 +165,7 @@ class ImplementDocumentFitz(ABCDocument):
79
165
 
80
166
  def __init__(self, mod_doc_pdf: ModuleDocPdf, name: str):
81
167
  super().__init__(mod_doc_pdf, name)
82
- self.mod_doc_pdf: fitz.Document = mod_doc_pdf
168
+ self.mod_doc_pdf: ModuleDocPdf = mod_doc_pdf
83
169
  self.lib_pdf: LibPDF = LibPDF.FITZ
84
170
 
85
171
  def get_first_page(self) -> PageDocumentPdf:
@@ -94,22 +180,29 @@ class ImplementDocumentFitz(ABCDocument):
94
180
  if 0 <= idx < self.mod_doc_pdf.page_count:
95
181
  pg = self.mod_doc_pdf.load_page(idx) # retorna fitz.Page
96
182
  if pg is not None:
97
- _page_pdf = PageDocumentPdf.create_from_page_fitz(pg, idx)
183
+ _page_pdf = PageDocumentPdf.create_from_page_fitz(pg)
98
184
  return _page_pdf
99
185
 
100
186
  def get_number_pages(self) -> int:
101
187
  return self.mod_doc_pdf.page_count
102
188
 
103
- def add_page(self, page: fitz.Page):
189
+ def add_page(self, page: PageDocumentPdf):
104
190
  # Assume que page.mod_page é fitz.Page
105
- self.mod_doc_pdf.insert_pdf(page, from_page=page.number, to_page=page.number)
191
+ self.mod_doc_pdf.insert_pdf(
192
+ page.implement_page_pdf.mod_page.parent,
193
+ from_page=page.implement_page_pdf.mod_page.number,
194
+ to_page=page.implement_page_pdf.mod_page.number
195
+ )
106
196
 
107
- def add_pages(self, pages: list[fitz.Page]):
197
+ def add_pages(self, pages: list[PageDocumentPdf]):
108
198
  for page in pages:
109
199
  self.add_page(page)
110
200
 
111
201
  def to_file(self, file: File):
112
- self.mod_doc_pdf.save(file.path)
202
+ try:
203
+ self.mod_doc_pdf.save(file.path)
204
+ except Exception as e:
205
+ show_warning(f'{e}')
113
206
 
114
207
  def to_bytes(self) -> BytesIO:
115
208
  buf = BytesIO()
@@ -124,27 +217,10 @@ class ImplementDocumentFitz(ABCDocument):
124
217
  pages.append(page_pdf)
125
218
  return pages
126
219
 
127
- def to_list(self, separator: str = '\n') -> list[str]:
128
- pages: list[PageDocumentPdf] = self.to_pages()
129
- values = []
130
- for pg in pages:
131
- values.extend(pg.to_list(separator))
132
- return values
133
-
134
- def to_dict(self, separator: str = '\n') -> dict[str, list[str]]:
135
- pages_pdf = self.to_pages()
136
- document_dict = PageDocumentPdf.DEFAULT_DICT
137
- for pg in pages_pdf:
138
- page_dict = pg.to_dict(separator)
139
- document_dict['TEXTO'].extend(page_dict['TEXTO'])
140
- document_dict['NUM_PAGE'].extend(page_dict['NUM_PAGE'])
141
- document_dict['NUM_LINHA'].extend(page_dict['NUM_LINHA'])
142
- return document_dict
143
-
144
220
  @classmethod
145
221
  def create_from_bytes(cls, bt: BytesIO) -> ImplementDocumentFitz:
146
222
  # Cria documento a partir de BytesIO
147
- doc = fitz.open(stream=bt.getvalue(), filetype="pdf")
223
+ doc: ModuleDocPdf = fitz.open(stream=bt.getvalue(), filetype="pdf")
148
224
  name = get_hash_from_bytes(bt)
149
225
  return cls(doc, name)
150
226
 
@@ -156,7 +232,6 @@ class ImplementDocumentFitz(ABCDocument):
156
232
 
157
233
  @classmethod
158
234
  def create_from_pages(cls, pages: list[PageDocumentPdf]) -> ImplementDocumentFitz:
159
-
160
235
  pdf_document = fitz.Document() # Criar novo documento PDF.
161
236
  for page in pages:
162
237
  # Verifica se a página é do tipo fitz.Page
@@ -168,13 +243,7 @@ class ImplementDocumentFitz(ABCDocument):
168
243
  from_page=page.implement_page_pdf.mod_page.number,
169
244
  to_page=page.implement_page_pdf.mod_page.number
170
245
  )
171
-
172
246
  bt = BytesIO(pdf_document.write())
173
- #name = get_hash_from_bytes(bt)
174
- #bt.seek(0)
175
- #bt.close()
176
- #del bt
177
- #return cls(pdf_document, name)
178
247
  return cls.create_from_bytes(bt)
179
248
 
180
249
 
@@ -215,10 +284,10 @@ class ImplementDocumentPyPdf(ABCDocument):
215
284
  def get_number_pages(self) -> int:
216
285
  return len(self.mod_doc_pdf.pages)
217
286
 
218
- def add_page(self, page: PageObject):
219
- self.mod_doc_pdf.add_page(page)
287
+ def add_page(self, page: PageDocumentPdf):
288
+ self.mod_doc_pdf.add_page(page.implement_page_pdf.mod_page)
220
289
 
221
- def add_pages(self, pages: list[PageObject]):
290
+ def add_pages(self, pages: list[PageDocumentPdf]):
222
291
  for page in pages:
223
292
  self.add_page(page)
224
293
 
@@ -239,23 +308,6 @@ class ImplementDocumentPyPdf(ABCDocument):
239
308
  pages_pdf.append(pg)
240
309
  return pages_pdf
241
310
 
242
- def to_list(self, separator: str = '\n') -> list[str]:
243
- pages: list[PageDocumentPdf] = self.to_pages()
244
- values = []
245
- for pg in pages:
246
- values.extend(pg.to_list(separator))
247
- return values
248
-
249
- def to_dict(self, separator: str = '\n') -> dict[str, list[str]]:
250
- pages_pdf = self.to_pages()
251
- document_dict = PageDocumentPdf.DEFAULT_DICT
252
- for pg in pages_pdf:
253
- page_dict = pg.to_dict(separator)
254
- document_dict['TEXTO'].extend(page_dict['TEXTO'])
255
- document_dict['NUM_PAGE'].extend(page_dict['NUM_PAGE'])
256
- document_dict['NUM_LINHA'].extend(page_dict['NUM_LINHA'])
257
- return document_dict
258
-
259
311
  @classmethod
260
312
  def create_from_bytes(cls, bt: BytesIO) -> ImplementDocumentPyPdf:
261
313
  # Usa PdfReader diretamente de BytesIO
@@ -266,7 +318,6 @@ class ImplementDocumentPyPdf(ABCDocument):
266
318
  pdf_writer = PdfWriter()
267
319
  for page in reader.pages:
268
320
  pdf_writer.add_page(page)
269
-
270
321
  bt.close()
271
322
  del bt
272
323
  del reader
@@ -327,10 +378,10 @@ class DocumentPdf(object):
327
378
  def get_number_pages(self) -> int:
328
379
  return self.doc_pdf.get_number_pages()
329
380
 
330
- def add_page(self, page: ModulePagePdf):
381
+ def add_page(self, page: PageDocumentPdf):
331
382
  self.doc_pdf.add_page(page)
332
383
 
333
- def add_pages(self, pages: list[ModulePagePdf]):
384
+ def add_pages(self, pages: list[PageDocumentPdf]):
334
385
  self.doc_pdf.add_pages(pages)
335
386
 
336
387
  def to_file(self, file: File):
@@ -343,36 +394,130 @@ class DocumentPdf(object):
343
394
  return self.doc_pdf.to_pages()
344
395
 
345
396
  def to_list(self, separator: str = '\n') -> list[str]:
346
- return self.doc_pdf.to_list(separator)
397
+ _pages = self.to_pages()
398
+ _values = []
399
+ for page in _pages:
400
+ try:
401
+ _values.extend(page.to_string().split(separator))
402
+ except Exception as e:
403
+ show_warning(f'{e}')
404
+ return _values
347
405
 
348
406
  def to_dict(self, separator: str = '\n') -> dict[str, list[str]]:
349
- return self.doc_pdf.to_dict(separator)
350
-
351
- def find(self, text_find: str, *, separator: str = '\n', iqual: bool = False, case: bool = False) -> str | None:
352
- _find_item = None
353
- pages = self.to_pages()
354
- for pg in pages:
355
- page_text_str = pg.find(text_find, separator=separator, iqual=iqual, case=case)
356
- if page_text_str is not None:
357
- _find_item = page_text_str
358
- break
359
- pages.clear()
360
- del pages
361
- return _find_item
362
-
363
- def find_all(self, text: str, *, separator: str = '\n', iqual: bool = False, case: bool = True) -> list[str]:
364
- if text is None:
365
- raise ValueError(f'{__class__.__name__}: o texto de pesquisa {text} é nulo!')
366
- elements = []
407
+ dict_doc = {
408
+ ColumnsTable.NUM_PAGE.value: [],
409
+ ColumnsTable.NUM_LINHA.value: [],
410
+ ColumnsTable.TEXT.value: [],
411
+ ColumnsTable.FILENAME.value: [],
412
+ }
367
413
  pages = self.to_pages()
368
- for pg in pages:
369
- page_text_str = pg.find(text, separator=separator, iqual=iqual, case=case)
370
- if page_text_str is not None:
371
- elements.append(text)
372
- break
373
- pages.clear()
374
- del pages
375
- return elements
414
+ for page in pages:
415
+ try:
416
+ _mp = MapText(page.to_list(separator))
417
+ _mp.add_column(ColumnsTable.NUM_PAGE.value, [f'{page.number_page}'] * _mp.length)
418
+ _mp.add_column(ColumnsTable.NUM_PAGE.value, [self.name] * _mp.length)
419
+ except Exception as e:
420
+ show_warning(f'{e}')
421
+ else:
422
+ dict_doc[ColumnsTable.NUM_PAGE.value].extend(_mp.map_elements[ColumnsTable.NUM_PAGE.value])
423
+ dict_doc[ColumnsTable.NUM_LINHA.value].extend(_mp.map_elements[ColumnsTable.NUM_LINHA.value])
424
+ dict_doc[ColumnsTable.TEXT.value].extend(_mp.map_elements[ColumnsTable.TEXT.value])
425
+ dict_doc[ColumnsTable.FILENAME.value].extend(_mp.map_elements[ColumnsTable.FILENAME.value])
426
+ del _mp
427
+ return dict_doc
428
+
429
+ def find(
430
+ self, text: str,
431
+ separator: str = '\n',
432
+ iqual: bool = False,
433
+ case: bool = False,
434
+ silent: bool = False,
435
+ ) -> SearchableTextPdf:
436
+ """
437
+ Filtrar texto retornando a primeira ocorrência do Documento PDF.
438
+ """
439
+ _searchable = SearchableTextPdf(silent)
440
+ pages_pdf = self.to_pages()
441
+ for page_pdf in pages_pdf:
442
+ text_str_in_page = page_pdf.to_string()
443
+ if (text_str_in_page == 'nas') or (text_str_in_page is None):
444
+ continue
445
+ try:
446
+ fd = FindText(text_str_in_page, separator=separator)
447
+ idx = fd.index(text, iqual=iqual, case=case)
448
+ if idx is None:
449
+ continue
450
+ math_text = fd.get_index(idx)
451
+ except:
452
+ pass
453
+ else:
454
+ _searchable.add_line(
455
+ math_text,
456
+ num_page=str(page_pdf.number_page),
457
+ num_line=str(idx + 1),
458
+ file=self.name,
459
+ )
460
+ return _searchable
461
+ return _searchable
462
+
463
+ def find_all(
464
+ self, text: str,
465
+ separator: str = '\n',
466
+ iqual: bool = False,
467
+ case: bool = False,
468
+ silent: bool = False,
469
+ ) -> SearchableTextPdf:
470
+ """
471
+ Filtrar texto em documento PDF e retorna todas as ocorrências do texto
472
+ encontradas no documento, incluindo o número da linha, página e nome do arquivo
473
+ em cada ocorrência.
474
+ """
475
+ _searchable = SearchableTextPdf(silent)
476
+ _pages_pdf = self.to_pages()
477
+ for page_pdf in _pages_pdf:
478
+ text_str_in_page = page_pdf.to_string()
479
+ if (text_str_in_page == 'nas') or (text_str_in_page is None):
480
+ continue
481
+ try:
482
+ _values = text_str_in_page.split(separator)
483
+ for num, item in enumerate(_values):
484
+ if case:
485
+ if iqual:
486
+ if text == item:
487
+ _searchable.add_line(
488
+ item,
489
+ num_page=str(page_pdf.number_page),
490
+ num_line=str(num + 1),
491
+ file=self.name,
492
+ )
493
+ else:
494
+ if text in item:
495
+ _searchable.add_line(
496
+ item,
497
+ num_page=str(page_pdf.number_page),
498
+ num_line=str(num + 1),
499
+ file=self.name,
500
+ )
501
+ else:
502
+ if iqual:
503
+ if text.lower() == item.lower():
504
+ _searchable.add_line(
505
+ item,
506
+ num_page=str(page_pdf.number_page),
507
+ num_line=str(num + 1),
508
+ file=self.name,
509
+ )
510
+ else:
511
+ if text.lower() in item.lower():
512
+ _searchable.add_line(
513
+ item,
514
+ num_page=str(page_pdf.number_page),
515
+ num_line=str(num + 1),
516
+ file=self.name,
517
+ )
518
+ except Exception as e:
519
+ show_warning(f'{__class__.__name__} {e}')
520
+ return _searchable
376
521
 
377
522
  @classmethod
378
523
  def create_from_bytes(cls, bt: BytesIO, *, lib_pdf: LibPDF = LibPDF.FITZ) -> DocumentPdf:
@@ -42,8 +42,7 @@ class ImageStream(CollectionImages):
42
42
  class PdfStream(object):
43
43
 
44
44
  def __init__(
45
- self,
46
- collection_pages: CollectionPagePdf = CollectionPagePdf(), *,
45
+ self, *,
47
46
  pbar: ProgressBarAdapter = ProgressBarAdapter(),
48
47
  lib_pdf: LibPDF = DEFAULT_LIB_PDF,
49
48
  lib_img: LibImage = DEFAULT_LIB_IMAGE,
@@ -51,7 +50,7 @@ class PdfStream(object):
51
50
  lib_pdf_to_img: LibPdfToImage = DEFAULT_LIB_PDF_TO_IMG,
52
51
  ) -> None:
53
52
  self.progress: ProgressBarAdapter = pbar
54
- self.collection_pages: CollectionPagePdf = collection_pages
53
+ self.collection_pages: CollectionPagePdf = CollectionPagePdf()
55
54
  self.collection_images: CollectionImages = CollectionImages()
56
55
  self.collection_images.set_pbar(pbar)
57
56
  self.collection_pages.set_pbar(pbar)
@@ -59,9 +58,10 @@ class PdfStream(object):
59
58
  self.lib_img: LibImage = lib_img
60
59
  self.lib_img_to_pdf: LibImageToPdf = lib_img_to_pdf
61
60
  self.lib_pdf_to_img: LibPdfToImage = lib_pdf_to_img
61
+ self.clear()
62
62
 
63
63
  @property
64
- def is_null(self) -> bool:
64
+ def is_empty(self) -> bool:
65
65
  return self.collection_pages.is_null
66
66
 
67
67
  def set_land_scape(self):
@@ -79,7 +79,7 @@ class PdfStream(object):
79
79
  self.collection_pages.add_page(page)
80
80
 
81
81
  def add_pages(self, pages: list[PageDocumentPdf]) -> None:
82
- self.add_pages(pages)
82
+ self.collection_pages.add_pages(pages)
83
83
 
84
84
  def add_file_image(self, f: File) -> None:
85
85
  self.collection_images.add_file_image(f)
@@ -111,13 +111,17 @@ class PdfStream(object):
111
111
  def to_document(self) -> DocumentPdf:
112
112
  if self.collection_pages.is_null and self.collection_images.is_empty:
113
113
  raise ValueError('Adicione imagens e/ou documentos para prosseguir!')
114
-
115
- _doc = DocumentPdf.create_from_pages(self.collection_pages.pages)
114
+ _doc = None
115
+ if not self.collection_pages.is_null:
116
+ _doc = DocumentPdf.create_from_pages(self.collection_pages.pages)
116
117
  if not self.collection_images.is_empty:
117
118
  _convert_img_to_pdf = ConvertImageToPdf(self.collection_images)
118
119
  _pages = _convert_img_to_pdf.to_document().to_pages()
119
120
  self.collection_images.clear()
120
- _doc.add_pages(_pages)
121
+ if _doc is None:
122
+ _doc = DocumentPdf.create_from_pages(_pages)
123
+ else:
124
+ _doc.add_pages(_pages)
121
125
  return _doc
122
126
 
123
127
  def to_files_images(
@@ -2,15 +2,14 @@
2
2
 
3
3
  from __future__ import annotations
4
4
  from abc import ABC, abstractmethod
5
- from enum import Enum
6
-
7
5
  from soup_files import (
8
6
  File, Directory, ProgressBarAdapter, CreatePbar,
9
7
  InputFiles, LibraryDocs, JsonConvert, JsonData
10
8
  )
11
9
  from convert_stream.enum_libs.enums import ColumnsTable
12
- from convert_stream import FindText, ArrayString, save_data, MapText
13
- from convert_stream.stream import PdfStream, DocumentPdf, CollectionPagePdf
10
+ from convert_stream.text.string import FindText, ArrayString, MapText
11
+ from convert_stream.pdf.pdf_document import SearchableTextPdf, DocumentPdf
12
+ from convert_stream.stream import PdfStream, CollectionPagePdf
14
13
  import pandas as pd
15
14
 
16
15
 
@@ -209,97 +208,6 @@ class FileToTable(object):
209
208
  return cls(TableFilesPdf())
210
209
 
211
210
 
212
- class SearchableTextPdf(object):
213
- """
214
- Esta classe serve para armazenar textos filtrados em documentos PDF
215
- guardando o texto buscado e outros elementos como a página em que o texto foi
216
- encontrado, linha e o nome do arquivo.
217
-
218
- """
219
- def __init__(self, silent: bool = False):
220
- self.silent = silent
221
- self.elements: dict[str, list[str]] = {
222
- ColumnsTable.NUM_PAGE.value: [],
223
- ColumnsTable.NUM_LINHA.value: [],
224
- ColumnsTable.TEXT.value: [],
225
- ColumnsTable.FILE.value: [],
226
- }
227
-
228
- def __repr__(self):
229
- return f'SearchableTextPdf: {self.elements}'
230
-
231
- def is_empty(self) -> bool:
232
- return len(self.elements[ColumnsTable.TEXT.value]) == 0
233
-
234
- @property
235
- def first(self) -> dict[str, str]:
236
- if self.is_empty():
237
- return {}
238
- return {
239
- ColumnsTable.NUM_PAGE.value: self.elements[ColumnsTable.NUM_PAGE.value][0],
240
- ColumnsTable.NUM_LINHA.value: self.elements[ColumnsTable.NUM_LINHA.value][0],
241
- ColumnsTable.TEXT.value: self.elements[ColumnsTable.TEXT.value][0],
242
- ColumnsTable.FILE.value: self.elements[ColumnsTable.FILE.value][0],
243
- }
244
-
245
- @property
246
- def last(self) -> dict[str, str]:
247
- if self.is_empty():
248
- return {}
249
- return {
250
- ColumnsTable.NUM_PAGE.value: self.elements[ColumnsTable.NUM_PAGE.value][-1],
251
- ColumnsTable.NUM_LINHA.value: self.elements[ColumnsTable.NUM_LINHA.value][-1],
252
- ColumnsTable.TEXT.value: self.elements[ColumnsTable.TEXT.value][-1],
253
- ColumnsTable.FILE.value: self.elements[ColumnsTable.FILE.value][-1],
254
- }
255
-
256
- @property
257
- def length(self) -> int:
258
- return len(self.elements[ColumnsTable.TEXT.value])
259
-
260
- def get_item(self, idx: int) -> dict[str, str]:
261
- try:
262
- return {
263
- ColumnsTable.NUM_PAGE.value: self.elements[ColumnsTable.NUM_PAGE.value][idx],
264
- ColumnsTable.NUM_LINHA.value: self.elements[ColumnsTable.NUM_LINHA.value][idx],
265
- ColumnsTable.TEXT.value: self.elements[ColumnsTable.TEXT.value][idx],
266
- ColumnsTable.FILE.value: self.elements[ColumnsTable.FILE.value][idx],
267
- }
268
- except Exception as err:
269
- if not self.silent:
270
- print(err)
271
- return {}
272
-
273
- def add_line(self, text, *, num_page: str, num_line: str, file: str) -> None:
274
- if not self.silent:
275
- print(f'{file} => {text}')
276
- self.elements[ColumnsTable.NUM_PAGE.value].append(num_page)
277
- self.elements[ColumnsTable.NUM_LINHA.value].append(num_line)
278
- self.elements[ColumnsTable.TEXT.value].append(text)
279
- self.elements[ColumnsTable.FILE.value].append(file)
280
-
281
- def clear(self) -> None:
282
- for _k in self.elements.keys():
283
- self.elements[_k].clear()
284
-
285
- def to_string(self) -> str:
286
- try:
287
- return ' '.join(self.elements[ColumnsTable.TEXT.value])
288
- except Exception as e:
289
- print(e)
290
- return 'nas'
291
-
292
- def to_data_frame(self) -> pd.DataFrame:
293
- return pd.DataFrame.from_dict(self.elements)
294
-
295
- def to_file_json(self, file: File):
296
- dt = JsonConvert.from_dict(self.elements).to_json_data()
297
- dt.to_file(file)
298
-
299
- def to_file_excel(self, file: File):
300
- save_data(self.to_data_frame(), file=file)
301
-
302
-
303
211
  class PdfFinder(object):
304
212
  """
305
213
  Classe para Filtrar texto em documentos PDF,
@@ -328,15 +236,14 @@ class PdfFinder(object):
328
236
  self.add_files_pdf(files)
329
237
 
330
238
  def find(
331
- self, text: str,
332
- separator: str = '\n',
333
- iqual: bool = False,
334
- case: bool = False,
335
- silent: bool = False,
239
+ self, text: str,
240
+ separator: str = '\n',
241
+ iqual: bool = False,
242
+ case: bool = False,
243
+ silent: bool = False,
336
244
  ) -> SearchableTextPdf:
337
245
  """
338
246
  Filtrar texto retornando a primeira ocorrência do Documento PDF.
339
- :param text: texto a ser filtrado no documento
340
247
  """
341
248
  _searchable = SearchableTextPdf(silent)
342
249
  if self.is_empty():
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env python3
2
+ from .date import ConvertStringDate
3
+ from .string import ArrayString, FindText, MapText
4
+ from .terminal import (
5
+ print_line, print_title, show_error, show_warning, show_info, Colors, msg
6
+ )
7
+
@@ -1,33 +1,8 @@
1
1
  #!/usr/bin/env python3
2
2
  from __future__ import annotations
3
- import os
4
3
  import pandas as pd
5
4
 
6
5
 
7
- def print_line(char: str = '='):
8
- """
9
- Imprime uma linha na tela.
10
- """
11
- try:
12
- num_size = os.get_terminal_size().columns
13
- except:
14
- num_size = 80
15
- print(char * num_size)
16
-
17
-
18
- def print_title(title: str, char: str = '='):
19
- """
20
- Imprime um título na tela.
21
- """
22
- try:
23
- num_size = os.get_terminal_size().columns
24
- except:
25
- num_size = 80
26
-
27
- # print_line(char)
28
- print(title.center(num_size, char))
29
-
30
-
31
6
  class MapText(object):
32
7
 
33
8
  def __init__(
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env python3
2
+ import os
3
+ from enum import Enum
4
+
5
+
6
+ class Colors(Enum):
7
+
8
+ GREEN = '\033[92m'
9
+ YELLOW = '\033[93m'
10
+ RED = '\033[91m'
11
+ DARK_RED = '\033[91m'
12
+ DARK_GREEN = '\033[92m'
13
+ DARK_YELLOW = '\033[93m'
14
+ VOID = '\033[0m'
15
+ END = '\033[0m'
16
+
17
+
18
+ def print_line(char: str = '=', *, color: Colors = Colors.VOID):
19
+ """
20
+ Imprime uma linha na tela.
21
+ """
22
+ try:
23
+ num_size = os.get_terminal_size().columns
24
+ except:
25
+ num_size = 80
26
+ print(f'{color.value}{char}{Colors.END.value}' * num_size)
27
+
28
+
29
+ def print_title(title: str, char: str = '='):
30
+ """
31
+ Imprime um título na tela.
32
+ """
33
+ try:
34
+ num_size = os.get_terminal_size().columns
35
+ except:
36
+ num_size = 80
37
+
38
+ # print_line(char)
39
+ print(title.center(num_size, char))
40
+
41
+
42
+ def msg(text: str, *, color: Colors = Colors.VOID):
43
+ print(f'{color.value}{text}{Colors.END.value}')
44
+
45
+
46
+ def show_warning(text: str, *, line: bool = True):
47
+ if line:
48
+ print_line('-')
49
+ print(f'{Colors.DARK_YELLOW}[?] WARNING:{Colors.END.value} {text}')
50
+
51
+
52
+ def show_error(text: str, *, line: bool = True):
53
+ if line:
54
+ print_line('-')
55
+ print(f'{Colors.DARK_YELLOW}[!] ERRO:{Colors.END.value} {text}')
56
+
57
+
58
+ def show_info(text: str, *, line: bool = True):
59
+ if line:
60
+ print_line('-')
61
+ print(f'{Colors.DARK_YELLOW}[+] INFO:{Colors.END.value} {text}')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: convert_stream
3
- Version: 2.2.1
3
+ Version: 2.2.5
4
4
  Summary: Manipulação de documentos PDF e Imagens. Converter, Ler, rotacionar exportar etc.
5
5
  Author: Bruno Chaves
6
6
  Requires-Python: >=3.11
@@ -25,4 +25,5 @@ convert_stream/sheets/parse.py
25
25
  convert_stream/sheets/save.py
26
26
  convert_stream/text/__init__.py
27
27
  convert_stream/text/date.py
28
- convert_stream/text/string.py
28
+ convert_stream/text/string.py
29
+ convert_stream/text/terminal.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "convert_stream"
7
- version = "2.2.1"
7
+ version = "2.2.5"
8
8
  authors = [
9
9
  { name="Bruno Chaves"},
10
10
  ]
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env python3
2
- from .date import ConvertStringDate
3
- from .string import (
4
- ArrayString, FindText, print_line, print_title, MapText
5
- )
6
-
File without changes
File without changes