3 pdftools.pdfjoin - Join PDF documents into a single file.
6 # Copyright 2012 by Hartmut Goebel <h.goebel@goebel-consult.de>
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 __author__ = "Hartmut Goebel <h.goebel@goebel-consult.de>"
23 __copyright__ = "Copyright 2012 by Hartmut Goebel <h.goebel@goebel-consult.de>"
24 __licence__ = "GNU General Public License version 3 (GPL v3)"
25 __version__ = "0.1dev"
27 # ignore some warnings for pyPDF < 1.13
29 warnings.filterwarnings('ignore', "the sets module is deprecated")
30 warnings.filterwarnings('ignore', "the md5 module is deprecated")
32 from pyPdf.pdf import PdfFileWriter, PdfFileReader
35 from logging import log
38 class DecryptionError(ValueError): pass
40 def join(outfilename, infilenames, dry_run=False):
41 # use a temporary file since the outfilename may be an inputfile, too.
42 outfile = tempfile.TemporaryFile()
44 outpdf = PdfFileWriter()
45 for infilename in infilenames:
46 log(19, 'Reading %r', infilename)
47 with open(infilename, 'rb') as infh:
48 inpdf = PdfFileReader(infh)
51 log(16, 'File is encrypted')
52 # try empty password first
53 if not inpdf.decrypt('') and not inpdf.decrypt(password_hook()):
54 raise DecryptionError("Can't decrypt PDF. Wrong Password?")
56 for page in inpdf.pages:
61 log(20, 'dry-run is selected. Not writing to %r', outfilename)
63 log(19, 'Writing %r', outfilename)
64 # copy the data to th real outfile
66 open(outfilename, 'wb').writelines(outfile)
70 return getpass.getpass()
72 def main(opts, outfilename, infilenames, password_hook=password_hook):
73 logging.basicConfig(level=20-opts.verbose, format="%(message)s")
74 join(outfilename, infilenames, dry_run=opts.dry_run)