Checking of initial version.
[pdftools:pdfjoin.git] / pdftools / pdfjoin / __init__.py
1 #!/usr/bin/env python
2 """
3 pdftools.pdfjoin - Join PDF documents into a single file.
4 """
5 #
6 # Copyright 2012 by Hartmut Goebel <h.goebel@goebel-consult.de>
7 #
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.
12 #
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.
17 #
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/>.
20 #
21
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"
26
27 # ignore some warnings for pyPDF < 1.13
28 import warnings
29 warnings.filterwarnings('ignore', "the sets module is deprecated")
30 warnings.filterwarnings('ignore', "the md5 module is deprecated")
31
32 from pyPdf.pdf import PdfFileWriter, PdfFileReader
33
34 import logging
35 from logging import log
36 import tempfile
37
38 class DecryptionError(ValueError): pass
39
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()
43
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)
49
50             if inpdf.isEncrypted:
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?")
55
56             for page in inpdf.pages:
57                 outpdf.addPage(page)
58             outpdf.write(outfile)
59
60     if dry_run:
61         log(20, 'dry-run is selected. Not writing to %r', outfilename)
62     else:
63         log(19, 'Writing %r', outfilename)
64         # copy the data to th real outfile
65         outfile.seek(0)
66         open(outfilename, 'wb').writelines(outfile)
67
68 def password_hook():
69     import getpass
70     return getpass.getpass()
71
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)
75