Dead Ink Vinyl

Musings of David L Kinney

Christmas Cards and AppleScript

My Christmas cards should go out in the mail today or tomorrow. Amy and I got a late start by not getting our picture to the photo shop until mid-December. Then we needed to assemble the names of everyone to which were going to send cards. I volunteered for that, viewing it as a great chance to dump everybody’s contact info into Address Book. I had read several weeks earlier that Address Book had the ability to print labels, I figured that I was set!

I poured over our wedding invitation responses and entered all of the information. I even included the names of spouses and children. I then showed Amy a preview of the labels — and she turned up her nose.

This being our first Christmas as husband and wife, she really enjoyed getting cards addressed to “David and Amy Kinney”. The labels that would be printed by Address Book would only be to a single person. Ah ha!, I thought, This is my chance to learn AppleScript! I told Amy that I would take care of it and set about learning AppleScript and how to extract the information I needed from Address Book. The general plan was to use “The Snafu Family” if there were children, “Foo & Bar Snafu” if there was a spouse, and “Dr. Foo Snafu” if there was no family.

I found out that most of the work was in putting the data into an application that would print labels, not in extracting the data from Address Book. Coding the extraction of information from Address Book took less than ten hours, including learning the language. To drop the data into an application that printed labels, I investigated Word, Excel, and AppleWorks. I settled on AppleWorks because of its stronger support for AppleScript. After great weeping and gnashing of teeth, I finally negotiated with AppleWorks enough to let me do what I wanted. It took me about 30 hours.

The AppleScript is below. It covers many actions that do not seem to be covered well in tutorials or examples online.

on getBaseFileName()
  return "XmasCards"
end getBaseFileName

on getBaseFileExtension()
  return ".cwk"
end getBaseFileExtension

on getSourceFolder()
  tell application "Finder"
    set bootVolume to startup disk as string
  end tell
  set srcFolder to bootVolume & "Users:dlkinney:Desktop:"
  return srcFolder
end getSourceFolder

on getYear()
  set now to current date
  set thisYear to year of now
  return thisYear
end getYear

on getSourceFile()
  set srcFolder to getSourceFolder()
  set srcFile to srcFolder & getBaseFileName() & getBaseFileExtension()
  tell application "Finder"
    if not (exists file srcFile) then
      error "File " & srcFile & " does not exist."
    end if
  end tell
  return srcFile
end getSourceFile

on createCopy(srcFile, theYear)
  set srcFolder to getSourceFolder()
  set fileName to getBaseFileName()
  set fileExt to getBaseFileExtension()
  tell application "Finder"
    (*
    set dstFile to srcFolder & fileName & theYear & fileExt
    if dstFile exists then
      delete dstFile
    end if
    *)
    set dupFile to (duplicate file srcFile) as string
    return dupFile
  end tell
  return dupFile
end createCopy

on addRecord(theFile, srcAddr, srcStreet, srcCity, srcState, srcZip)
  tell application "AppleWorks 6"
    open theFile

    set mydoc to front document
    set mydb to database of mydoc

    tell mydb
      if (count of records) is equal to 0 then
        make new record at beginning
      end if

      set myrec to (first record)
      set addressee of myrec to srcAddr
      set street of myrec to srcStreet
      set city of myrec to srcCity
      set state of myrec to srcState
      set zipcode of myrec to srcZip

      make new record at end with data myrec
    end tell

    save mydoc
  end tell
end addRecord

set allAddresses to {}
tell application "Address Book"
  activate
  set everyPerson to every person in group "Xmas Cards"
  repeat with thisPerson in everyPerson
    (* reset variables *)
    set noAddress to false
    set noSpouse to false
    set noChildren to false

    tell thisPerson
      (* name *)
      set firstName to first name
      set lastName to last name
      set prefix to title

      (* home address *)
      set everyAddress to (every address whose label is equal to "home")
      if length of everyAddress is greater than 0 then
        set thisAddress to first item of everyAddress
        tell thisAddress
          set homeStreet to street
          set homeCity to city
          set homeState to state
          set homeZip to zip
        end tell
      else
        set noAddress to true
      end if

      (* family *)
      set everySpouse to (every related name whose label is equal to "spouse")
      if length of everySpouse is greater than 0 then
        set spouse to first item of everySpouse
        tell spouse
          set spouseName to value of spouse
        end tell
      else
        set noSpouse to true
      end if
      set everyChild to (every related name whose label is equal to "child")
      if length of everyChild is equal to 0 then
        set noChildren to true
      end if

      if not noAddress then
        (* addressee; e.g., "Dr. David Kinney", "David & Amy Kinney", "Kinney Family" *)
        if noChildren then
          if noSpouse then
            if prefix exists then
              set addressee to prefix & " " & firstName & " " & lastName
            else
              set addressee to firstName & " " & lastName
            end if
          else
            set addressee to firstName & " & " & spouseName & " " & lastName
          end if
        else
          set addressee to "The " & lastName & " Family"
        end if

        script XmasAddress
          property xmasRecipient : addressee
          property xmasStreet : homeStreet
          property xmasCity : homeCity
          property xmasState : homeState
          property xmasZipCode : homeZip
        end script

        set tmpAddress to XmasAddress

        set allAddresses to allAddresses & tmpAddress
      end if
    end tell
  end repeat
end tell

set srcFile to getSourceFile()
set theFile to createCopy(srcFile, "2003")
repeat with xmasaddr in allAddresses
  set xRecipient to xmasRecipient of xmasaddr
  set xStreet to xmasStreet of xmasaddr
  set xCity to xmasCity of xmasaddr
  set xState to xmasState of xmasaddr
  set xZip to xmasZipCode of xmasaddr
  addRecord(theFile, xRecipient, xStreet, xCity, xState, xZip)
end repeat

Written by dlkinney

January 3, 2004 at 8:30 pm

Posted in Uncategorized

One Response

Subscribe to comments with RSS.

  1. I’m still having this problem in 2007! I also just married and these are our first christmas cards and my wife has the same requirement. However, the issue still doesn’t seem to be solved.

    Thanks for the ideas.
    Maybe I will learn applescript

    danny

    December 14, 2007 at 11:42 pm


Comments are closed.