-
Notifications
You must be signed in to change notification settings - Fork 27
pdf broken encoding reader #522
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
…takes too much time), changed imports
requirements.txt
Outdated
@@ -40,3 +39,6 @@ wget==3.2 | |||
xgbfir>=0.3.1,<1.0 | |||
xgboost>=1.6.0,<2.0 # lower versions aren't compatible with pandas>2 | |||
xlrd>=1.2.0,<2.0 | |||
nltk==3.9.1 | |||
tensorflow==2.13.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tensorflow
import should be optional similarly to torch
(https://github.com/ispras/dedoc/blob/master/pyproject.toml)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
scripts/get_text_broken_pdf.py
Outdated
|
||
from dedoc.readers.pdf_reader.pdf_txtlayer_reader.pdf_broken_encoding_reader.pdf_broken_encoding_reader import PdfBrokenEncodingReader | ||
|
||
if __name__ == "__main__": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This script can be converted into test (e.g. here https://github.com/ispras/dedoc/blob/master/tests/unit_tests/test_format_pdf_reader.py)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -24,7 +24,7 @@ class QueryParameters: | |||
table_type: str = Form("", description="Pipeline mode for table recognition") | |||
|
|||
# pdf handling | |||
pdf_with_text_layer: str = Form("auto_tabby", enum=["true", "false", "auto", "auto_tabby", "tabby"], | |||
pdf_with_text_layer: str = Form("auto_tabby", enum=["true", "false", "auto", "auto_tabby", "tabby","bad_encoding_reader"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API test should be written for a new parameter: you can create file test_pdf_bad_encoding_reader.py
similarly to test_api_format_pdf_with_text.py
.gitignore
Outdated
@@ -26,6 +26,7 @@ var/ | |||
*.egg-info/ | |||
.installed.cfg | |||
*.egg | |||
dedoc/readers/pdf_reader/pdf_txtlayer_reader/pdf_broken_encoding_reader/data/pdfdata |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the directory should be placed in cache ("resources_path" of dedoc config) and downloaded if needed, as it is done for other data (datasets, models) in download_models.py - this script is used in Docker for downloading data in advance
For PyPI library, readers download their data if needed, e.g. for PdfAutoReader - pdf_auto_reader/txtlayer_classifier.py#L27
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
class PdfBrokenEncodingReader(PdfBaseReader): | ||
""" | ||
This class allows to extract content (text, tables, attachments) from the .pdf documents with a textual layer (copyable documents). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong docstring (it's doc for other reader)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
self.extractor_layer = PdfminerExtractor(config=self.config) | ||
self.__pdf_txtlayer_reader = PdfTxtlayerReader(config=config) | ||
|
||
def can_read(self, file_path: Optional[str] = None, mime: Optional[str] = None, extension: Optional[str] = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong docstring
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
return super().can_read(file_path=file_path, mime=mime, extension=extension) and get_param_pdf_with_txt_layer( | ||
parameters) == "bad_encoding_reader" | ||
|
||
def read(self, file_path: str, parameters: Optional[dict] = None) -> UnstructuredDocument: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docstring is needed
@@ -110,6 +110,7 @@ <h4>PDF handling</h4> | |||
<option value="auto">auto</option> | |||
<option value="auto_tabby" selected>auto_tabby</option> | |||
<option value="tabby">tabby</option> | |||
<option value="bad_encoding_reader">bad_encoding_reader</option> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New parameter should be added into docs:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
WordObj = namedtuple("Word", ["start", "end", "value"]) | ||
|
||
|
||
class PdfBrokenEncodingReader(PdfBaseReader): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New reader should be added to the docs: https://github.com/ispras/dedoc/blob/master/docs/source/modules/readers.rst
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Please look to the logs of test pipelines - they all should pass before merge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All binary files should be downloaded as needed at the reader initialization stage.
all binary files should be downloaded as needed at the reader initialization stage
You can see how it is done in dedoc/readers/pdf_reader/pdf_image_reader/pdf_image_reader.py
in the line:
checkpoint_path=os.path.join(get_config()["resources_path"],
"scan_orientation_efficient_net_b0.pth"),
...
-
Binary files should be downloaded to the "resources_path" directory of config file
-
an example of initialization and downloading of weights
dedoc/readers/pdf_reader/pdf_image_reader/columns_orientation_classifier/columns_orientation_classifier.py (function _load_weights)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
scripts/get_text_broken_pdf.py
Outdated
args = parser.parse_args() | ||
reader = PdfBrokenEncodingReader() | ||
document = reader.read(args.pdf_path) | ||
print(document.get_text()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should add more then one tests:
- add api tests into
tests/api_tests
to check that your reader is working correctly via api - add a unit test to
test/unit_test
to check that your reader is working correctly
|
||
|
||
class PdfBrokenEncodingReader(PdfBaseReader): | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a detailed description of the functionality of your reader
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
except Exception as e: | ||
raise Exception(f"some problem occured: {e}") | ||
pages, layouts = reader.get_correct_layout(file_path) | ||
tables = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'tables' unused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
image_page = cv2.cvtColor(image_page, cv2.COLOR_GRAY2BGR) | ||
return image_page | ||
|
||
def __debug_extract_layout(self, image_src: np.ndarray, layout: LTContainer, page_num: int, k_w: float, k_h: float, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a dublicate code of dedoc/readers/pdf_reader/pdf_txtlayer_reader/pdfminer_reader/pdfminer_extractor.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cv2.imwrite(os.path.join(tmp_dir, f"img_page_{page_num}.png"), image_src) | ||
file_text.close() | ||
|
||
def __extract_image(self, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a dublicate code of dedoc/readers/pdf_reader/pdf_txtlayer_reader/pdfminer_reader/pdfminer_extractor.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
return text_with_bbox | ||
|
||
def __get_line_annotations(self, lobj: LTTextLineHorizontal, height: int, width: int) -> Tuple[ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a dublicate code of dedoc/readers/pdf_reader/pdf_txtlayer_reader/pdfminer_reader/pdfminer_extractor.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
def _get_new_weight(self) -> str: | ||
return binascii.hexlify(os.urandom(8)).decode("ascii") | ||
|
||
def __parse_style_string(self, chars_with_meta: str, begin: int, end: int) -> List[Annotation]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a dublicate code of dedoc/readers/pdf_reader/pdf_txtlayer_reader/pdfminer_reader/pdfminer_extractor.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
call_classifier=False)) | ||
return lines, tables, page.attachments, [] | ||
|
||
def __handle_page(self, page: PDFPage, page_number: int, path: str, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is dublicated code of dedoc/readers/pdf_reader/pdf_txtlayer_reader/pdfminer_reader/pdfminer_extractor.py
with different that you use own layout
(pass own layout ). Try to use code of dedoc/readers/pdf_reader/pdf_txtlayer_reader/pdfminer_reader/pdfminer_extractor.py
with small changes of code of pdfminer_extractor.py.
For example in file dedoc/readers/pdf_reader/pdf_txtlayer_reader/pdfminer_reader/pdfminer_extractor.py
:
- do pubic function
def __handle_page(...)
->def handle_page(...)
- added small changes into code:
def handle_page(self, page: PDFPage, page_number: int, path: str, parameters: ParametersForParseDoc, Layout: Optional[LTPage] = None) -> PageWithBBox:
...
if not layout:
layout = device.get_result()
...
So, by adding these small changes you will get rid of 300 lines of duplicate code!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
onlyRus = ['я', 'й', 'ц', 'б', 'ж', 'з', 'д', 'л', 'ф', 'ш', 'щ', "ч", "ъ", "ь", "э", "ю", 'г'] | ||
onlyEng = ['q', 'w', 'f', 'i', 'j', 'l', 'z', 's', 'v', 'g'] | ||
|
||
from nltk.corpus import words |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from nltk.corpus import words
put inside code of function substitute_chars_by_dict
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
from dedoc.readers.pdf_reader.pdf_txtlayer_reader.pdf_broken_encoding_reader.functions import get_project_root | ||
|
||
|
||
class Model: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docstring is needed
import tensorflow as tf | ||
from keras import layers | ||
from keras.callbacks import TensorBoard | ||
from keras.models import load_model |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move all external imports inside the function codes where they are called
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
import PIL.ImageOps | ||
from PIL import Image | ||
from pdfminer.high_level import extract_text |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move all external imports inside the function codes where they are called
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
import warnings | ||
from pathlib import Path | ||
|
||
import fontforge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move all external imports inside the function codes where they are called
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
import os | ||
from pathlib import Path | ||
|
||
from keras.models import load_model |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move all external imports inside the function codes where they are called
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
…pdfminer_extractor, added function handle_page(...) to pdfminer_extractor to use in my reader
…ction to tempfile
Reader to extract code from PDF with complex background using information from PDF
added my code from project needed to extract text:
added script to scripts dir to extract text using reader
edited index.html, api_args, manager_config, gitignore and requirements