1

I have created a script with an array containing file names. The script searches for pdf files through directories and sub-directories by recursion and adds them to an array. It then outputs a string into the command line for pdftk so as to merge them.

pdftk takes arguments such as:

pdftk inputpdf1.pdf inputpdf2.pdf cat output output.pdf

However, it seems that the inputted path is not correct as per the error message I get from the windows cmd (listed above). I get the same error on Ubuntu.

    Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\student3>cd C:\Documents and Settings\student3\Desktop
\Test

C:\Documents and Settings\student3\Desktop\Test>pdftest.py
Merging C:\Documents and Settings\student3\Desktop\Test\1.pdf
pdftk "C:\Documents and Settings\student3\Desktop\Test\1.pdf" cat outputC:\Docum
ents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
pdftk "C:\Documents and Settings\student3\Desktop\Test\1.pdf" cat outputC:\Docum
ents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
Merging C:\Documents and Settings\student3\Desktop\Test\2.pdf
pdftk "C:\Documents and Settings\student3\Desktop\Test\2.pdf" cat outputC:\Docum
ents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
pdftk "C:\Documents and Settings\student3\Desktop\Test\2.pdf" cat outputC:\Docum
ents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
Merging C:\Documents and Settings\student3\Desktop\Test\brian\1.pdf
pdftk "C:\Documents and Settings\student3\Desktop\Test\brian\1.pdf" cat outputC:
\Documents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
pdftk "C:\Documents and Settings\student3\Desktop\Test\brian\1.pdf" cat outputC:
\Documents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
Merging C:\Documents and Settings\student3\Desktop\Test\brian\2.pdf
pdftk "C:\Documents and Settings\student3\Desktop\Test\brian\2.pdf" cat outputC:
\Documents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
pdftk "C:\Documents and Settings\student3\Desktop\Test\brian\2.pdf" cat outputC:
\Documents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
Merging C:\Documents and Settings\student3\Desktop\Test\testing\1.pdf
pdftk "C:\Documents and Settings\student3\Desktop\Test\testing\1.pdf" cat output
C:\Documents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
pdftk "C:\Documents and Settings\student3\Desktop\Test\testing\1.pdf" cat output
C:\Documents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
Merging C:\Documents and Settings\student3\Desktop\Test\testing\2.pdf
pdftk "C:\Documents and Settings\student3\Desktop\Test\testing\2.pdf" cat output
C:\Documents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
pdftk "C:\Documents and Settings\student3\Desktop\Test\testing\2.pdf" cat output
C:\Documents and Settings\student3\Desktop\Test\Output\.pdf
Error: Unexpected text in page reference, here:
   outputC:\Documents
   Exiting.
   Acceptable keywords, here, are: "even", "odd", or "end".
Errors encountered.  No output created.
Done.  Input errors, so no output created.
Finished Processing

C:\Documents and Settings\student3\Desktop\Test>

This is the code for the script:

#----------------------------------------------------------------------------------------------
# Name:        pdfMerger
# Purpose:     Automatic merging of all PDF files in a directory and its sub-directories and
#              rename them according to the folder itself. Requires the pyPDF Module
#
# Current:     Processes all the PDF files in the current directory
# To-Do:       Process the sub-directories.
#
# Version: 1.0
# Author:      Brian Livori
#
# Created:     03/08/2011
# Copyright:   (c) Brian Livori 2011
# Licence:     Open-Source
#---------------------------------------------------------------------------------------------
#!/usr/bin/env python

import os
import glob
import sys
import fnmatch
import subprocess

path = str(os.getcwd())


x = 0

def process_file(_, path, filelist):
    os.path.walk(os.path.realpath(topdir), process_file, ())
    input_param = " ".join('"' + x + '"' for x in glob.glob(os.path.join(path, "*.pdf"))

    output_param = '"' + os.path.join(path, os.path.basename(path) + ".pdf") + '"'

    cmd = "pdftk " + input_param + " cat output " + output_param
    os.system(cmd)


    for filenames in os.walk (path):
         if "Output" in filenames:
            filenames.remove ("Output")

    if os.path.exists(final_output) != True:

                    os.mkdir(final_output)
                    sp = subprocess.Popen(cmd)
                    sp.wait()


    else:

                   sp = subprocess.Popen(cmd)
                   sp.wait()




def files_recursively(topdir):
 os.path.walk(os.path.realpath(topdir), process_file, ())

files_recursively(path)

print "Finished Processing"

What exactly am I doing wrong?

File "C:\Documents and Settings\student3\Desktop\Test\pdftest2.py", line 32
    output_param = '"' + os.path.join(path, os.path.basename(path) + ".pdf") + '"'
               ^
SyntaxError: invalid syntax
Bobrovsky
  • 13,789
  • 19
  • 80
  • 130
Brian
  • 1,951
  • 16
  • 56
  • 101

2 Answers2

3

You need to escape the paths by enclosing them in double quotes, because of the whitespaces. Otherwise, your shell will interpret every whitespace as a seperator for a new file.

" ".join('"' + str(f) + '"' for f in filesArr)

Several more things:

  1. You call PDFTK for every PDF. You should put that out of the loop and build a input list of files. (Assuming you want to merge all input pdfs into one output pdf
  2. You are missing a space after cat output

    ... " cat output " + outputpath + ext)

  3. Your outputpath variable is empty.

Edit:

Your code is a little bit confusing. I would change the process_file method to this:

def process_file(_, path, filelist):
    input_param = " ".join('"' + x + '"' for x in glob.glob(os.path.join(path, "*.pdf"))
    output_param = '"C:\ENTER\OUTPUT\PATH\HERE.PDF"'
    cmd = "pdftk " + input_param + " cat output " + output_param
    os.system(cmd)

I don't really understand why you need all those assignments there.

Edit 2:

Here my full script:

#!/usr/bin/env python

import os
import glob

def process_file(_, path, filelist):
    input_param = " ".join('"' + x + '"' for x in glob.glob(os.path.join(path, "*.pdf"))))
    output_param = '"' + os.path.join(path, os.path.basename(path) + ".pdf") + '"'
    cmd = "pdftk " + input_param + " cat output " + output_param
    print cmd
    os.system(cmd)

def files_recursively(topdir):
    os.path.walk(os.path.realpath(topdir), process_file, ())

if  __name__ == "__main__":
    files_recursively(os.getcwd())

And here on Pastebin

Commands it produces:

pdftk "/home/user/pdf/Test1.pdf" "/home/user/pdf/Test3.pdf" "/home/user/pdf/Test2.pdf" cat output "/home/user/pdf/pdf.pdf"
pdftk "/home/user/pdf/Sub3/Test1.pdf" "/home/user/pdf/Sub3/Test3.pdf" "/home/user/pdf/Sub3/Test2.pdf" cat output "/home/user/pdf/Sub3/Sub3.pdf"
pdftk "/home/user/pdf/Sub2/Test1.pdf" "/home/user/pdf/Sub2/Test3.pdf" "/home/user/pdf/Sub2/Test2.pdf" cat output "/home/user/pdf/Sub2/Sub2.pdf"
pdftk "/home/user/pdf/Sub2/SubSub21/Test1.pdf" "/home/user/pdf/Sub2/SubSub21/Test3.pdf" "/home/user/pdf/Sub2/SubSub21/Test2.pdf" cat output "/home/user/pdf/Sub2/SubSub21/SubSub21.pdf"
pdftk "/home/user/pdf/Sub2/SubSub22/Test1.pdf" "/home/user/pdf/Sub2/SubSub22/Test3.pdf" "/home/user/pdf/Sub2/SubSub22/Test2.pdf" cat output "/home/user/pdf/Sub2/SubSub22/SubSub22.pdf"
pdftk "/home/user/pdf/Sub1/Test1.pdf" "/home/user/pdf/Sub1/Test3.pdf" "/home/user/pdf/Sub1/Test2.pdf" cat output "/home/user/pdf/Sub1/Sub1.pdf"
pdftk "/home/user/pdf/Sub1/SubSub2/Test1.pdf" "/home/user/pdf/Sub1/SubSub2/Test3.pdf" "/home/user/pdf/Sub1/SubSub2/Test2.pdf" cat output "/home/user/pdf/Sub1/SubSub2/SubSub2.pdf"
pdftk "/home/user/pdf/Sub1/SubSub1/Test1.pdf" "/home/user/pdf/Sub1/SubSub1/Test3.pdf" "/home/user/pdf/Sub1/SubSub1/Test2.pdf" cat output "/home/user/pdf/Sub1/SubSub1/SubSub1.pdf"
Jacob
  • 41,721
  • 6
  • 79
  • 81
  • I still get the same error. I think it's something that has to do with os.getcwd() – Brian Aug 10 '11 at 12:00
  • You probably didn't escape the output path? Print your `cmd` variable to the shell before executing and edit it into your question. – Jacob Aug 10 '11 at 12:01
  • How do you do that exactly, I mean, output the cmd variable? – Brian Aug 10 '11 at 12:05
  • Just `print cmd` after you do this: `cmd = ("pdftk " + str_fl + " cat output" + outputpath + ext)` – Jacob Aug 10 '11 at 12:06
  • Ahh you meant from Python. Sorry for the misunderstanding. Done. – Brian Aug 10 '11 at 12:12
  • Edited my answer with some more issues. – Jacob Aug 10 '11 at 12:23
  • I edited the code so it's: ['code'] pdftk *.pdf cat ouput output.pdf That should merge all the pdfs in the current directory. The outputpath should be the current directory the script is in, so for example if it is in "test" the script should rename the output pdf to"test.pdf". It was working when I tried it with pyPDF. – Brian Aug 10 '11 at 12:31
  • Will that code allow you to iterate through sub-directories? It's the most important part for me to iterate through folders and sub-folders. As far as I can understand it does not. – Brian Aug 10 '11 at 13:28
  • The iteration through subqueries is not done in process_files, but here: `os.path.walk(os.path.realpath(topdir), process_file, ())`. So in your process_files routine, you only need to get all pdfs and merge them, if I understood your logic correctly. – Jacob Aug 10 '11 at 13:31
  • The PDF files have to be merged seperately so the PDF files in a sub-directory called "Test" will be merged to "Test.pdf" and the files in the sub-directory "Test 2" will be merged to "Test 2.pdf" – Brian Aug 10 '11 at 13:34
  • I changed the output_param to output_param = path and it's giving me incorrect syntax – Brian Aug 10 '11 at 13:49
  • You need to enclose `path` in double-quotes PLUS you need to add the name of the pdf to it like this: `output_param='"' + os.path.join(path, os.path.basename(path) + ".pdf") + '"'` – Jacob Aug 10 '11 at 13:50
  • it must be something in the indentation.. I tried to indent and dedent it but I'm still getting the same error. I included it in my original question. – Brian Aug 10 '11 at 14:08
0

Instead of os.system() you should use subprocess.Popen - this module's contents deal properly with spaces in filenames if you give the command and arguments as a list.

On Windows: the Popen class uses CreateProcess() to execute the child program, which operates on strings. If args is a sequence, it will be converted to a string using the list2cmdline method. Please note that not all MS Windows applications interpret the command line the same way: The list2cmdline is designed for applications using the same rules as the MS C runtime.

In your example, that would be

cmd = ["pdftk"] + files_arr + "cat", "output", outputpath + ext]

and then

sp = subprocess.Popen(cmd)
sp.wait()
glglgl
  • 89,107
  • 13
  • 149
  • 217