1313
1414if BERNARD_LEDIT_AVAILABLE :
1515 # pylint: disable=import-error
16- import bernard_ledit .image as bernard_image
1716 import bernard_ledit .pdf as bernard_pdf
1817else :
1918 bernard_pdf = None # type: ignore[assignment] # pylint: disable=invalid-name
20- bernard_image = None # type: ignore[assignment] # pylint: disable=invalid-name
2119
2220
2321class PDFExtractor :
2422 """PDF extraction class."""
2523
26- _source_pdf : BinaryIO
24+ _source : BinaryIO
2725 _filename : str
2826 _page_count : int
2927
3028 @requires_bernard_ledit
3129 def __init__ (self , local_input : LocalInputSource ):
3230 self ._filename = local_input .filename
3331 self ._page_count = local_input .page_count
34- if local_input .is_pdf ():
35- self ._source_pdf = local_input .file_object
36- else :
37- pdf_image = bernard_image .Image (local_input .file_object .read ()) # type: ignore[call-arg]
38- self ._source_pdf = io .BytesIO ()
39- pdf_image .save (self ._source_pdf , format = "PDF" )
32+ self ._source = local_input .file_object
4033
4134 @requires_bernard_ledit
4235 def extract_single_document (self , page_indexes : list [int ]) -> ExtractedPDF :
@@ -46,26 +39,11 @@ def extract_single_document(self, page_indexes: list[int]) -> ExtractedPDF:
4639 :param page_indexes: List of pages number to use for merging in the original PDF.
4740 :return: The buffer containing the new PDF.
4841 """
42+
4943 if not page_indexes or len (page_indexes ) == 0 :
5044 raise MindeeError ("Empty indexes aren't allowed for extraction." )
51- for page_index in page_indexes :
52- if page_index > self ._page_count :
53- raise MindeeError (f"Index { page_index } is out of range." )
54-
55- self ._source_pdf .seek (0 )
56- new_pdf = bernard_pdf .PdfDocument .new ()
57- pdf = bernard_pdf .PdfDocument (self ._source_pdf .read ())
58- new_pdf .import_pages (pdf , page_indexes )
59- bytes_io = io .BytesIO ()
60- new_pdf .save (bytes_io )
61-
62- first_page = page_indexes [0 ]
63- last_page = page_indexes [len (page_indexes ) - 1 ]
64- return ExtractedPDF (
65- pdf_byte_stream = bytes_io ,
66- filename = self ._make_filename (first_page , last_page ),
67- page_indexes = page_indexes ,
68- )
45+ self ._check_indexes (page_indexes )
46+ return self ._extract ([page_indexes ])[0 ]
6947
7048 @requires_bernard_ledit
7149 def extract_multiple_documents (
@@ -79,10 +57,33 @@ def extract_multiple_documents(
7957 """
8058 if len (page_indexes ) < 1 :
8159 raise MindeeError ("No indexes provided." )
82- extracted_pdfs : list [ExtractedPDF ] = []
83- for page_index_elem in page_indexes :
84- extracted_pdfs .append (self .extract_single_document (page_index_elem ))
85- return ExtractedPDFs (extracted_pdfs )
60+ for group in page_indexes :
61+ if not group :
62+ raise MindeeError ("Empty indexes aren't allowed for extraction." )
63+ self ._check_indexes (group )
64+ return ExtractedPDFs (self ._extract (page_indexes ))
65+
66+ def _check_indexes (self , page_indexes : list [int ]) -> None :
67+ for page_index in page_indexes :
68+ if page_index < 0 or page_index >= self ._page_count :
69+ raise MindeeError (f"Index { page_index } is out of range." )
70+
71+ def _extract (self , groups : list [list [int ]]) -> list [ExtractedPDF ]:
72+ self ._source .seek (0 )
73+ docs = bernard_pdf .extract_documents (self ._source , groups ) # type: ignore[attr-defined]
74+ extracted : list [ExtractedPDF ] = []
75+ for doc , indexes in zip (docs , groups , strict = True ):
76+ with doc :
77+ bytes_io = io .BytesIO ()
78+ doc .save (bytes_io )
79+ extracted .append (
80+ ExtractedPDF (
81+ pdf_byte_stream = bytes_io ,
82+ filename = self ._make_filename (indexes [0 ], indexes [- 1 ]),
83+ page_indexes = indexes ,
84+ )
85+ )
86+ return extracted
8687
8788 def _make_filename (self , first_page : int , last_page : int ) -> str :
8889 stem = Path (self ._filename ).stem
0 commit comments