jorisschellekens / borb

borb is a library for reading, creating and manipulating PDF files in python.
https://borbpdf.com/
Other
3.4k stars 147 forks source link

BUG While trying to run a windows isntaller that contains borb library #155

Closed GideonStruts closed 1 year ago

GideonStruts commented 1 year ago

Describe the bug Fails to run an executable created via pyinstaller on windows. The executable gets created, but on running it, the following error is produced;

Traceback (most recent call last): File "main.py", line 3, in File "", line 1178, in _find_and_load File "", line 1149, in _find_and_load_unlocked File "", line 690, in _load_unlocked File "PyInstaller\loader\pyimod02_importers.py", line 352, in exec_module File "borb\toolkit__init__.py", line 49, in File "", line 1178, in _find_and_load File "", line 1149, in _find_and_load_unlocked File "", line 690, in _load_unlocked File "PyInstaller\loader\pyimod02_importers.py", line 352, in exec_module File "borb\toolkit\export\html_to_pdf\html_to_pdf.py", line 42, in File "borb\toolkit\export\html_to_pdf\html_to_pdf.py", line 963, in HTMLToPDF File "borb\pdf\canvas\font\simple_font\font_type_1.py", line 432, in init AssertionError: AFM directory not found [23288] Failed to execute script 'main' due to unhandled exception!

To Reproduce

  1. Create a python script that utilizes borb
  2. Create an executable with pyinstaller;

pyinstaller --noconfirm --onefile --name My_Awesome_app_v$(version).exe \ --exclude-module _bootlocale \ --console main.py

# please enter a concise, complete and self-contained code sample
# that reproduces the bug

from borb.pdf.document.document import Document from borb.pdf.pdf import PDF from borb.toolkit.text.simple_text_extraction import SimpleTextExtraction

def main():

Extract pdf text

d: typing.Optional[Document] = None
l: SimpleTextExtraction = SimpleTextExtraction()
with open("sample.pdf", "rb") as pdf_in_handle:
    d = PDF.loads(pdf_in_handle, [l])

assert d is not None

pdfTextDict = l._text_per_page
pdfText = pdfTextDict[0]

text = pdfText.split("\n")
print(text)

if name == "main":
main()

Expected behaviour The executable should run Ok, like the standalone python script.

Screenshots If applicable, add screenshots to help explain your problem.

image

Desktop (please complete the following information):

Additional context It processes pdf files Ok, just on running from an installer is where the issue is.

jorisschellekens commented 1 year ago

Hi,

I have no experience using pyinstaller.

What I can say from the error though is that this program is not taking into account all files in the borb project (specifically the non-.py files).

The file triggering your error is a .afm file (Adobe font metrics). It contains details such as the width of each character for a particular font.

These .afm files are used whenever one of the standard fonts is used. The PDF specification defines 14 standard fonts which every piece of compliant software ought to be able to write/interpret.

Whenever you don't specify a Font in borb you are using the default (standard 14) Font Helvetica. In order for borb to know how wide/tall each character is, it loads the .afm file.

I recognize the error, because I faced similar problems when trying to package borb into a library. I fixed it by modifying the MANIFEST.in file to ensure certain directories (containing static resources) are included when building the library into a single file.

I assume pyinstaller can do the same, and it would solve your problem.

Kind regards, Joris Schellekens