#!/usr/bin/env python # -*- coding: utf-8 -*- # # Author: Mark J Cox # # version 1.0 - 13 Sept 2009 """ LICENSE: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. """ VCF_FILENAME = "20090914-test.vcf" NICE_FONT = "Gentium Basic Regular" NICE_FONT_HEADINGS = "Gentium Basic Bold" import sys, os, urllib, re import tempfile try: import vobject except ImportError,err: print "You need to install vobject from http://vobject.skyhouseconsulting.com/ " sys.exit(1) try: import scribus except ImportError,err: print "This Python script is written for the Scribus scripting interface." sys.exit(1) def add_data(pageWidth,leftMargin,rightMargin,topMargin,bottomMargin,pageHeight,startpos, title, left, middle, image, notes): y = topMargin + startpos imageWidth = 12 imageHeight = 13 Height = 1 Width = pageWidth - leftMargin - rightMargin TitleBox = scribus.createText(leftMargin, y, Width, Height) scribus.setTextAlignment(scribus.ALIGN_LEFT, TitleBox) scribus.setText(title, TitleBox) scribus.selectText(0,scribus.getTextLength(TitleBox), TitleBox) scribus.setStyle("ptitle",TitleBox) scribus.setFillColor("Black",TitleBox) # Now expand the box to fit the text while (scribus.textOverflows(TitleBox) >0): Height+=1 scribus.sizeObject(Width,++Height,TitleBox) titlepos = Height+1 Height1 = 1 Width = (pageWidth - leftMargin - rightMargin - imageWidth)/2 + 6 TextBox = scribus.createText(leftMargin, y+titlepos, Width, Height1) scribus.setTextAlignment(scribus.ALIGN_LEFT, TextBox) scribus.setText(left, TextBox) scribus.selectText(0,scribus.getTextLength(TextBox), TextBox) scribus.setStyle("pmain",TextBox) # Now expand the box to fit the text while (scribus.textOverflows(TextBox) >0): Height1+=1 scribus.sizeObject(Width,Height1,TextBox) Height2 = 1 AddressWidth = (pageWidth - leftMargin - rightMargin - imageWidth)/2 - 6 MiddleBox = scribus.createText(leftMargin + Width, y+titlepos, AddressWidth, Height2) scribus.setTextAlignment(scribus.ALIGN_LEFT, MiddleBox) scribus.setText(middle, MiddleBox) scribus.selectText(0,scribus.getTextLength(MiddleBox),MiddleBox) scribus.setStyle("pmain",MiddleBox) # Now expand the box to fit the text while (scribus.textOverflows(MiddleBox) >0): Height2+=1 scribus.sizeObject(AddressWidth,Height2,MiddleBox) Height3 = 0 if notes: Height3 = 1 NotesWidth = (pageWidth - leftMargin - rightMargin -imageWidth) NotesBox = scribus.createText(leftMargin , y+titlepos + max(Height1, Height2) +2, NotesWidth, Height3) scribus.setTextAlignment(scribus.ALIGN_LEFT, NotesBox) scribus.setText("Note: %s" % notes, NotesBox) scribus.selectText(0,scribus.getTextLength(NotesBox),NotesBox) scribus.setStyle("pmain",NotesBox) # Now expand the box to fit the text while (scribus.textOverflows(NotesBox) >0): Height3+=1 scribus.sizeObject(NotesWidth,Height3,NotesBox) Height3 += 2 # But maybe the box overflows the page, needs a new page if (y+max(Height1,Height2,imageHeight)+Height3+titlepos > pageHeight-bottomMargin): scribus.deleteObject(TitleBox) scribus.deleteObject(MiddleBox) scribus.deleteObject(TextBox) if notes: scribus.deleteObject(NotesBox) raise Exception('pagetoosmall') # Now place the contact image if image: f = scribus.createImage(pageWidth-rightMargin-imageWidth,topMargin+startpos+titlepos,imageWidth,imageHeight) (tmp_fd,tmp_fn) = tempfile.mkstemp(suffix='jpg') fd = os.fdopen(tmp_fd,"w+b") data = urllib.urlopen(image).read() fd.write(data) fd.close() scribus.loadImage(tmp_fn,f) # os.unlink(tmp_fn) # Can't remove them as scribus just links to file scribus.setScaleImageToFrame(scaletoframe=1, proportional=1, name=f) Height2 = max(Height2, imageHeight) return titlepos+max(Height1,Height2)+Height3 def main(argv): # Setup for Franklin Covey compact blank paper, 108x171mm holes punched left # Although we specify mm units in newDocument scribus API wants points topts = scribus.pt/scribus.mm page_margins = (5*topts,15*topts,5*topts,15*topts) scribus.newDocument((108*topts,171*topts), page_margins, scribus.PORTRAIT, 1, scribus.UNIT_MILLIMETERS, scribus.PAGE_2, scribus.NOFACINGPAGES, scribus.FIRSTPAGERIGHT) pageWidth, pageHeight = scribus.getPageSize() topMargin, rightMargin, leftMargin, bottomMargin = scribus.getPageMargins() scribus.createCharStyle(name="ctitle",fillcolor="White",fontsize=10,baselineoffset=-100,font=NICE_FONT_HEADINGS) scribus.createCharStyle(name="cmain",fontsize=9,font=NICE_FONT) scribus.createParagraphStyle(name="ptitle",charstyle="ctitle",alignment=scribus.ALIGN_LEFT,leftmargin=2) scribus.createParagraphStyle(name="pmain",linespacingmode=1,charstyle="cmain",alignment=scribus.ALIGN_LEFT,leftmargin=2) file = open(VCF_FILENAME, 'r') add = '' startpos = 0 page = 0 num = 0 vcards = [] # Make up the title as the FN and add optional nickname and org name for vcard in vobject.readComponents(file.read()): title = "" try: title = vcard.fn.value try: title += " (%s)" % vcard.nickname.value except: pass if vcard.fn.value != vcard.org.value[0]: title += ", %s" % vcard.org.value[0] except: pass vcard.title = title vcards.append(vcard) vcards.sort(lambda x,y: cmp(x.n.value.family+x.title, y.n.value.family+y.title)) for vcard in vcards: num+=1 scribus.statusMessage("Running script, working on contact %d (page %d)" %(num,page+1)) scribus.progressReset() # if num > 30: # break; # Left column is email address and phone numbers left = "" try: for email in vcard.email_list: left += "%s\n" % (email.value) except: pass try: for tel in vcard.tel_list: phone = re.sub("\+44\s+","0",tel.value) left += "%s: %s\n" % (tel.type_param.lower(), phone) except: pass # Middle column is the postal address try: address = "%s" % vcard.adr_list[0].value address = re.sub("\n[,]*\s+","\n", address) except: address = "" # Underneath put the notes try: notes = vcard.note.value except: notes = "" # Expecting an image URL for the contact try: image = vcard.photo.value except: image = "" isnotplaced = 3 # just to make sure no infinite loop if we messed up the code while (isnotplaced > 0): try: height = add_data(pageWidth,leftMargin,rightMargin,topMargin,bottomMargin,pageHeight,startpos, vcard.title, left, address, image, notes) startpos += height+2 isnotplaced = 0 add = '' except Exception, inst: if (str(inst) == 'pagetoosmall'): # it didn't fit on the page, so start a new one page +=1 scribus.newPage(-1) # swap margins for 2nd page leftMargin, rightMargin = rightMargin, leftMargin startpos = 0 isnotplaced-=1 else: print "Unexpected error:", sys.exc_info()[0] raise def main_wrapper(argv): try: scribus.statusMessage("Running script....") scribus.progressReset() main(argv) finally: if scribus.haveDoc(): scribus.setRedraw(True) scribus.statusMessage("") scribus.progressReset() if __name__ == '__main__': main_wrapper(sys.argv)