Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using soffice within python, Command works in terminal but not in Python subprocess

I am having the most frustrating problem with libreoffice in Python

when I run the following in terminal I have no problem at all, the pdf file is produced where I want it and life is dandy:

cd /Applications/LibreOffice.app/Contents/MacOS/

./soffice --convert-to pdf --outdir {output_folder} {path_to_docx_file}/{title}.docx

However when I have tried to add this to my python script:

SOFFICE = r'/Applications/LibreOffice.app/Contents/MacOS/soffice'

subprocess.Popen([SOFFICE, "--convert-to", "pdf", "--outdir", "{output_folder} ", "{path_to_docx_file}/{title}.docx"])

I get an error saying :

Error: source file could not be loaded

I have tried opening up all the permissions of all of the binaries and files and this still doesn't work in the python script. What am I doing wrong?

like image 754
brucey31 Avatar asked Mar 12 '23 00:03

brucey31


2 Answers

It's because you need to change the current working directory, not just give an absolute path to the command.

subprocess.Popen(["/Applications/LibreOffice.app/Contents/MacOS/soffice", "--convert-to", "pdf", "--outdir", "{output_folder} ", "{path_to_docx_file}/{title}.docx"])

Should be replaced with:

subprocess.Popen(["soffice", "--convert-to", "pdf", "--outdir", "{output_folder} ", "{path_to_docx_file}/{title}.docx"], cwd="/Applications/LibreOffice.app/Contents/MacOS/")

Even if it seems to be quite similar, there's a major difference between those two calls: the current working directory.

With the script:

subprocess.Popen(["/Applications/LibreOffice.app/Contents/MacOS/soffie", "--convert-to", "pdf", "--outdir", "{output_folder} ", "file.docx"])

If you're calling the python script in the ~ directory, it will try to reach ~/file.docx.

But, in the second one :

subprocess.Popen(["soffice", "--convert-to", "pdf", "--outdir", "{output_folder} ", "file.docx"], cwd="/Applications/LibreOffice.app/Contents/MacOS/")

It will try to reach the file in "/Applications/LibreOffice.app/Contents/MacOS/file.docx", which is the same behaviour of what you're doing with the cd command (in fact, the cd command changes the current directory, so giving the cwd argument is the same as making a cd call).

You can also use absolute paths for all your files and it will solve the problem too but it's not what you're trying to do. It depends on the software you are trying to build and it's purpose.

It's why the prompt says that the file does not exist. The program can't find the file in WHERE_YOU_CALL_THE_SCRIPT/{path_to_docx_file}/{title}.docx because I suppose that the file is in /Applications/LibreOffice.app/Contents/MacOS/{path_to_docx_file}/{title}.docx.

like image 90
Alexis Clarembeau Avatar answered Apr 09 '23 05:04

Alexis Clarembeau


I have experienced the same problem. (I used absolute paths, so Alexis's answer did not solve the issue for me).

After a lot of experiments, I have found out that using os.system instead of subprocess.Popen does not raise the same problem, so maybe this can be used as a quick fix.

In greater detail, I have created the following method that works in my environment.

def makePdfFromDoc_linux_batch(input_folder_path, target_folder_path):
    input_folder_files = os.path.join(input_folder_path, "*.doc")
    os.system("/Applications/LibreOffice.app/Contents/MacOS/soffice --headless --convert-to pdf --outdir " + target_folder_path + " " + input_folder_files)

However, I have no clues on the causes of this problem. Since os.system displays a different behaviour, it may depend on the environment that subprocess.Popen generates to run the command - but I have no actual evidence for this.

I have found this blog post, where the same problem is experienced seems to appear in a ruby environment. It did not really help me understand the root of the issue, but actually I was in a hurry, so maybe it can be more helpful to you.

like image 32
Andrea Rossi Avatar answered Apr 09 '23 05:04

Andrea Rossi