Objective: Converting ppt to pdf using python 3.6.1
Scenario: MS Office is not installed in windows server
Code used:
from subprocess import Popen, PIPE
import time
def convert(src, dst):
d = {'src': src, 'dst': dst}
commands = [
'/usr/bin/docsplit pdf --output %(dst)s %(src)s' % d,
'oowriter --headless -convert-to pdf:writer_pdf_Export %(dst)s %(src)s' % d,
]
for i in range(len(commands)):
command = commands[i]
st = time.time()
process = Popen(command, stdout=PIPE, stderr=PIPE, shell=True) # I am aware of consequences of using `shell=True`
out, err = process.communicate()
errcode = process.returncode
if errcode != 0:
raise Exception(err)
en = time.time() - st
print ('Command %s: Completed in %s seconds' % (str(i+1), str(round(en, 2))))
if __name__ == '__main__':
src = 'C:\xxx\ppt'
dst = 'C:\xxx\ppt\destination'
convert(src, dst)
Error Encountered:
Traceback (most recent call last):
File "C:/PythonFolder/ppt_to_pdf.py", line 134, in <module>
convert(src, dst)
File "C:/PythonFolder/ppt_to_pdf.py", line 123, in convert
process = Popen(command, stdout=PIPE, stderr=PIPE, shell=True) # I am aware of consequences of using `shell=True`
File "C:\Python 3.6.1\lib\subprocess.py", line 707, in __init__
restore_signals, start_new_session)
File "C:\Python 3.6.1\lib\subprocess.py", line 990, in _execute_child
startupinfo)
ValueError: embedded null character
Does anyone know how to fix this error?
Or any other python library that will help in this case.
Since you're running on Windows, the command /usr/bin/docsplit pdf --output %(dst)s %(src)s won't convert the PPT, since it seems it's for Linux. Popen might be having trouble handling that command, causing the error.
Converting a PPT to a PDF in the command line on Windows is kinda hard. I think your best bet is to install LibreOffice and run with headless mode. There's also a SuperUser question on it where the asker ends up using C# interop libraries, but I think that requires Microsoft Office to be installed.
Thanks.
Related
We use Jenkins to run our cronjobs. We run Centos 6.8 on our server. Jenkins is version 1.651.
I'm running into a funny problem. When I run my script from the terminal, it works fine. I don't get any errors.
When I run the same script in Jenkins, it fails and says there's no such file or directory.
The error message from the Jenkins output I get is this:
Traceback (most recent call last):
File "runMTTRScript.py", line 256, in <module>
main()
File "runMTTRScript.py", line 252, in main
startTest(start, end, impalaHost)
File "runMTTRScript.py", line 72, in startTest
getResults(start, end)
File "runMTTRScript.py", line 111, in getResults
proc1 = subprocess.Popen(cmd, stdout=processlistOut)
File "/glide/lib64/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/glide/lib64/python2.7/subprocess.py", line 1335, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Here's the code that the error above is complaining about:
with open(JAVAOUT + "_processList" + outfileDate, 'w') as processlistOut, \
open(JAVAOUT + "_innodb" + outfileDate, 'w') as innodbOut:
cmd = ["java", "-cp", "MTTR4hrs-1.0.5-SNAPSHOT-allinone.jar", "com.servicenow.bigdata.MTTR4hrs", "-c", "config.properties", "-m", DBIFILE, "-d", start, end, "-f", "processlist", "-ds", "dbi"]
proc1 = subprocess.Popen(cmd, stdout=processlistOut)
cmd = ["java", "-cp", "MTTR4hrs-1.0.5-SNAPSHOT-allinone.jar", "com.servicenow.bigdata.MTTR4hrs", "-c", "config.properties", "-m", DBIFILE, "-d", start, end, "-f", "engineinnodbstatus", "-ds", "dbi"]
proc2 = subprocess.Popen(cmd, stdout=innodbOut)
Why would it complain that a file is not there from Jenkins but be fine when I run it from cmd line? Could this also be some race condition in python that I'm not aware of too? The "with...open" doesn't open a file fast enough for the Popen to make use of? I'm also open to the fact that it might be some OS problem too (too many open files, something stupid, etc.).
As I started asking on a previous question, I'm extracting a tarball using the tarfile module of python. I don't want the extracted files to be written on the disk, but rather get piped directly to another program, specifically bgzip.
#!/usr/bin/env python
import tarfile, subprocess, re
mov = []
def clean(s):
s = re.sub('[^0-9a-zA-Z_]', '', s)
s = re.sub('^[^a-zA-Z_]+', '', s)
return s
with tarfile.open("SomeTarballHere.tar.gz", "r:gz") as tar:
for file in tar.getmembers():
if file.isreg():
mov = file.name
proc = subprocess.Popen(tar.extractfile(file).read(), stdout = subprocess.PIPE)
proc2 = subprocess.Popen('bgzip -c > ' + clean(mov), stdin = proc, stdout = subprocess.PIPE)
mov = None
But now I get stuck on this:
Traceback (most recent call last):
File "preformat.py", line 12, in <module>
proc = subprocess.Popen(tar.extractfile(file).read(), stdout = subprocess.PIPE)
File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
raise child_exception
OSError: [Errno 36] File name too long
Is there any workaround for this? I have been using the LightTableLinux.tar.gz (it contains the files for a text editor program) as a tarball to test the script on it.
The exception is raised in the forked-off child process when trying to execute the target program from this invocation:
proc = subprocess.Popen(tar.extractfile(file).read(), stdout = subprocess.PIPE)
This
reads the contents of an entry in the tar file
tries to execute a program with the name of the contents of that entry.
Also your second invocation won't work, as you are trying to use shell redirection without using shell=True in Popen():
proc2 = subprocess.Popen('bgzip -c > ' + clean(mov), stdin = proc, stdout = subprocess.PIPE)
The redirect may also not be necessary, as you should be able to simply redirect the output from bgzip to a file from python directly.
Edit: Unfortunately, despite extractfile() returning a file-like object, Popen() expects a real file (with a fileno). Hence, a little wrapping is required:
with tar.extractfile(file) as tarfile, file(clean(mov), 'wb') as outfile:
proc = subprocess.Popen(
('bgzip', '-c'),
stdin=subprocess.PIPE,
stdout=outfile,
)
shutil.copyfileobj(tarfile, proc.stdin)
proc.stdin.close()
proc.wait()
I would like to run an exe from this directory:/home/pi/pi_sensors-master/bin/Release/
This exe is then run by tying mono i2c.exe and it runs fine.
I would like to get this output in python which is in a completely different directory.
I know that I should use subprocess.check_output to take the output as a string.
I tried to implement this in python:
import subprocess
import os
cmd = "/home/pi/pi_sensors-master/bin/Release/"
os.chdir(cmd)
process=subprocess.check_output(['mono i2c.exe'])
print process
However, I received this error:
The output would usually be a data stream with a new number each time, is it possible to capture this output and store it as a constantly changing variable?
Any help would be greatly appreciated.
Your command syntax is incorrect, which is actually generating the exception. You want to call mono i2c.exe, so your command list should look like:
subprocess.check_output(['mono', 'i2c.exe']) # Notice the comma separation.
Try the following:
import subprocess
import os
executable = "/home/pi/pi_sensors-master/bin/Release/i2c.exe"
print subprocess.check_output(['mono', executable])
The sudo is not a problem as long as you give the full path to the file and you are sure that running the mono command as sudo works.
I can generate the same error by doing a ls -l:
>>> subprocess.check_output(['ls -l'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 537, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
However when you separate the command from the options:
>>> subprocess.check_output(['ls', '-l'])
# outputs my entire folder contents which are quite large.
I strongly advice you to use the subprocess.Popen -object to deal with external processes. Use Popen.communicate() to get the data from both stdout and stderr. This way you should not run into blocking problems.
import os
import subprocess
executable = "/home/pi/pi_sensors-master/bin/Release/i2c.exe"
proc = subprocess.Popen(['mono', executable])
try:
outs, errs = proc.communicate(timeout=15) # Times out after 15 seconds.
except TimeoutExpired:
proc.kill()
outs, errs = proc.communicate()
Or you can call the communicate in a loop if you want a 'data-stream' of sort, an answer from this question:
from subprocess import Popen, PIPE
executable = "/home/pi/pi_sensors-master/bin/Release/i2c.exe"
p = Popen(["mono", executable], stdout=PIPE, bufsize=1)
for line in iter(p.stdout.readline, b''):
print line,
p.communicate() # close p.stdout, wait for the subprocess to exit
I am trying to execute a command in python and read its output on command line in windows.
I have written the following code so far:
def build():
command = "cobuild archive"
print "Executing build"
pipe = Popen(command,stdout=PIPE,stderr=PIPE)
while True:
line = pipe.stdout.readline()
if line:
print line
I want to execute the command cobuild archive in command line and read it's output. However, the above code is giving me this error.
File "E:\scripts\utils\build.py", line 33, in build
pipe = Popen(command,stdout=PIPE,stderr=PIPE)
File "C:\Python27\lib\subprocess.py", line 679, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 893, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
The following code worked. I needed to pass shell=True for the arguments
def build():
command = "cobuild archive"
pipe = Popen(command,shell=True,stdout=PIPE,stderr=PIPE)
while True:
line = pipe.stdout.readline()
if line:
print line
if not line:
break
WindowsError: [Error 2] The system cannot find the file specified
This error says that the subprocess module is unable to locate your executable(.exe)
here "cobuild archive"
Suppose, if your executable in this path: "C:\Users\..\Desktop",
then, do,
import os
os.chdir(r"C:\Users\..\Desktop")
and then use your subprocess
Do you mind to post your code with the correct indentations please? They have a large effect in python - another way of doing this is:
import commands
# the command to execute
cmd = "cobuild archive"
# execute and get stdout
output = commands.getstatusoutput( cmd )
# do something with output
# ...
Update:
The commands module has been removed in Python 3, so this is a solution for python 2 only.
https://docs.python.org/2/library/commands.html
I want to run terminal commands within a python file. It is working fine and I can also get the terminal messages on a gui window using subprocess.Popen.
import subprocess
import wx
import os
def main():
p = subprocess.Popen(['ls'], stdout = subprocess.PIPE)
text = p.stdout.readlines()
text = "".join(text)
wx.MessageBox("file names:\n%s" % text, "info")
if __name__ == '__main__':
app = wx.PySimpleApp()
main()
But when I run a command for which terminal should ask answers of some questions, I am getting error?
Traceback (most recent call last):
File "to_make_new_project_folder.py", line 19, in <module> main()
File "to_make_new_project_folder.py", line 10, in main p = subprocess.Popen(['gr_modtool add -t general square_ff'], stdout = subprocess.PIPE)
File "/usr/lib/python2.7/subprocess.py", line 711, in init errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1308, in _execute_child raise child_exception
OSError: [Errno 2] No such file or directory
Does someone have idea how to answer the question from terminal using a gui window?
You should try passing in stdin=PIPE as well to popen
Based on your stack trace, the error you're receiving is OSError: No such file or directory, coming up from subprocess. It looks to me like Popen can't find the file that you're trying to execute, and is therefore failing.