#!/usr/bin/python
# cover.py -- add an autogenerated cover page to a PDF document
import sys, os, getopt, string, pwd
from CoreGraphics import *
## definitions
subject_title = 'Subject:'
from_title = 'From:'
to_title = 'To:'
date_title = 'Date'
pages_title = 'Sheets to follow:'
subject_text = None
from_name = 'auto'
to_name = None
date_string = None
pages_string = None
body_file = None
body_string = None
body_type = None
output_file = 'cover.pdf'
page_rect = CGRectMake (0, 0, 612, 792)
page_inset = (72, 72)
default_logo_size = (120, 120)
header_font_size = 14
logos = []
## functions
def body (c, rect):
global body_type
for (f, r) in logos:
pdf = CGPDFDocumentCreateWithProvider (CGDataProviderCreateWithFilename (f))
if pdf:
# FIXME: cg has a bug where releasing a document that has pages drawn
# in a pdf context but not output causes a crash when the pages
# are finally output (pages don't retain their document)
pdf.thisown = 0
c.drawPDFDocument (r, pdf, 1)
# Insert rtf header & footer from ~/Library/Fax
# [email protected], 12 Nov 2003
p = pwd.getpwuid (os.getuid ())
user = p and p[0]
fn = '/Users/'+user+'/Library/Fax/'
foot_rect = CGRectMake(0, 0, 612, 72)
footer = CGDataProviderCreateWithFilename (fn+'footer.rtf')
c.drawRTFTextInRect (footer, foot_rect)
header = CGDataProviderCreateWithFilename (fn+'header.rtf')
h = c.drawRTFTextInRect (header, rect)
rect = CGRectMake (rect.origin.x, rect.origin.y,
rect.size.width, (rect.origin.y + rect.size.height)
- (h.origin.y + h.size.height))
html = make_header_html ()
tr = c.drawHTMLTextInRect (CGDataProviderCreateWithString (html),
rect, header_font_size)
rect = CGRectMake (rect.origin.x, rect.origin.y,
rect.size.width, (rect.origin.y + rect.size.height)
- (tr.origin.y + tr.size.height))
p = None
if body_file:
p = CGDataProviderCreateWithFilename (body_file)
if not body_type:
bits = string.split (body_file, '.')
if len (bits) > 1:
suff = string.lower (bits[-1])
if suff == 'rtf':
body_type = 'rtf'
elif suff == 'html' or suff == 'htm':
body_type = 'html'
elif body_string:
p = CGDataProviderCreateWithString (body_string)
if p:
if body_type == 'rtf':
c.drawRTFTextInRect (p, rect)
elif body_type == 'html':
c.drawHTMLTextInRect (p, rect)
else:
c.drawPlainTextInRect (p, rect)
# Encoding the header section as HTML is the easiest way to get nice
# alignment of the two columns
def make_header_html ():
global date_string, from_name
def make_row (title, body, format=None):
f = ''; F = ''
if format:
f = '<%(format)s>' % vars ()
F = '</%(format)s>' % vars ()
return ('<tr><td valign=top >%(title)s: '
'%(f)s%(body)s%(F)s</td></tr>\n' % vars())
if date_string == 'now':
f = os.popen ('date "+%d.%m.%Y, %H:%M:%S"')
# read the date, dropping the trailing newline
date_string = f.read () [:-1]
f.close ()
if from_name == 'auto':
p = pwd.getpwuid (os.getuid ())
from_name = p and p[4];
return ('<html>\n'
+ '<head><meta http-equiv=Content-Type content="text/html; charset=UTF-8"></head>\n'
+ '<body text=\"#000000\">\n<table>\n'
+ (to_name and make_row ("
A", to_name) or '')
+ (from_name and make_row ("
De", from_name) or '')
+ (date_string and make_row (date_title, date_string) or '')
+ (subject_text and make_row ("
Sujet", subject_text, 'b') or '')
+ (pages_string and make_row ("
Nombre de pages à suivre", pages_string) or '')
+ '<tr><td> </td></tr>\n'
+ '</table>\n</body>\n</html>')
## entry point
def usage ():
print '''
usage: python cover.py [OPTION]... PDF-FILES...
Add a cover page to one or more PDF documents.
-f, --from=STRING
-F, --from-title=STRING
-t, --to=STRING
-T, --to-title=STRING
-s, --subject=STRING
-S, --subject-title=STRING
-d, --date=STRING (use STRING='now' for current date)
-D, --date-title=STRING
-n, --count=STRING
-N, --count-title=STRING
-b, --body=STRING
-B, --body-file=FILENAME
-T, --body-type=TYPE
-p, --page-rect=X,Y,W,H
-o, --output=FILENAME
-l, --logo=FILENAME[@X,Y,W,H]
-H, --header-font-size=SIZE
'''
def main ():
global subject_title, from_title, to_title, pages_title
global subject_text, from_name, to_name, pages_string, body_file, body_string
global body_type, output_file, page_rect, date_string, logos
global header_font_size
def parse_rect (s):
a = string.split (s, ',')
return (CGRectMake (float (a[0]), float (a[1]),
float (a[2]), float (a[3])))
try:
opts,args = getopt.getopt (sys.argv[1:],
'f:F:t:T:s:S
B:T
l:d
:n:N:',
['from=', 'from-title=', 'to=', 'to-title=',
'subject=', 'subject-title=', 'body=',
'body-file=', 'body-type=', 'page-rect=',
'output=', 'logo=', 'date=', 'date-title=',
'count=', 'count-title=', 'header-font-size='])
except getopt.GetoptError:
usage ()
sys.exit (1)
for o,a in opts:
if o in ('-f', '--from'):
from_name = a
if o in ('-F', '--from-title'):
from_title = a
elif o in ('-t', '--to'):
to_name = a
elif o in ('-T', '--to-title'):
to_title = a
elif o in ('-s', '--subject'):
subject_text = a
elif o in ('-S', '--subject-title'):
subject_title = a
elif o in ('-b', '--body'):
body_string = a
elif o in ('-B', '--body-file'):
body_file = a
elif o in ('-T', '--body-type'):
body_type = a
elif o in ('-p', '--page-rect'):
page_rect = parse_rect (a)
elif o in ('-o', '--output'):
output_file = a
elif o in ('-l', '--logo'):
a = string.split (a, '@')
if len (a) > 1:
r = parse_rect (a[1])
else:
r = CGRectMake (page_rect.origin.x + page_rect.size.width
- page_inset[0] - default_logo_size[0],
page_rect.origin.y + page_rect.size.height
- page_inset[1] - default_logo_size[1],
default_logo_size[0], default_logo_size[1])
logos = logos + [(a[0], r)]
elif o in ('-d', '--date'):
date_string = a
elif o in ('-n', '--count'):
pages_string = a
elif o in ('-N', '--count-title'):
pages_title = a
elif o in ('-H', '--header-font-size'):
header_font_size = float (a)
c = CGPDFContextCreateWithFilename (output_file, page_rect)
c.beginPage (page_rect);
body (c, page_rect.inset (page_inset[0], page_inset[1]))
c.endPage ()
for f in args:
pdf = CGPDFDocumentCreateWithProvider (CGDataProviderCreateWithFilename (f));
if pdf:
# FIXME: see above for why this is necessary
pdf.thisown = 0
for page in range (1, pdf.getNumberOfPages () + 1):
rect = pdf.getMediaBox (page)
c.beginPage (rect)
c.drawPDFDocument (rect, pdf, page)
c.endPage ()
# serialized the constructed PDF document to its file
c.finish ()
if __name__ == '__main__':
main ()