(*

Applescript to export data including all notes from Now Contact

Now Contact's notes aren't included in a vcf export which works pretty well otherwise for importing to Apple's Address Book application. And a text based export includes only actual "Notes" and not Appointments, Phone calls, etc which show up in the Notes area. These items are accessible via Applescript, but only via Now Up-to-Date. This script gets all calendar type items with Contact persons attached, saves them in a list, then gets all persons in Contact and adds the calendar based notes to the normal Notes, and sorts them chronologically or in reverse chronological order.
this data is written to a csv file which AddressBook can read, and also as a vcf vcard file with name and company info with notes. A full vcard export from Contact should allow the Notes vcards to be imported, with duplicates "Updating" they should match with the correct contact.
*)
--open your linked contact file and calendar file in Now Up-to-Date and Now Contact
--before running this script
--The script creates csv file with all data
--and vcf card file with info to match (name, company, etc) and all notes
--The Now Contact vcf export seems to do a pretty good job, but doesn't get notes
--do a full vcf export from Now, import it into Apple Address Book
--then run this script to create a vcf with matching names and notes, import,
--and let Address Book update the contacts with notes

--notes can be sorted chronologically, or reverse.
--reverse may be more convenient in Address Book, since it shows the top
--of the notes field
set noteOrder to "Chronological"
--set noteOrder to "Reverse Chronological"

set exportfilevcard to choose file name with prompt "Choose vcf export file" default name "contactupdatenotes.vcf"
set exportfile to choose file name with prompt "Choose csv export file" default name "contactupdate.csv"
set theLine to "\"First\",\"Middle\",\"Last\",\"Company\",\"Department\",\"Job Title\",\"Street (work)\",\"Street 2 (work)\",\"City (work)\",\"State (work)\",\"Zip (work)\",\"Country (work)\",\"Street (home)\",\"Street 2 (home)\",\"City (home)\",\"State (home)\",\"Zip (home)\",\"Country (home)\",\"Phone (work)\",\"Phone (home)\",\"Phone (mobile)\",\"Phone (fax)\",\"Phone (other)\",\"Email (work)\",\"Email (home)\",\"URL\",\"Note\""
set theList to {}
set theData to {}



tell application "Now Up-To-Date"
	--the category in up to date, all my person related items were category 3
	--this might have to be changed?
	set theCat to 3
	set theList to {}
	set theData to {}
	repeat with eventIndex from 1 to count every event of category theCat of document 1
		--repeat with eventIndex from 1 to 20
		set theP to name of event eventIndex of category theCat of document 1
		set theE to event eventIndex of category theCat of document 1
		if exists person 1 of theE then
			set theD to description of theE
			set theName to name of theE
			--display dialog theD as string
			set theP to person 1 of theE
			set thePfirst to firstname of theP
			set thePlast to lastname of theP
			set thePCompany to companyname of theP
			set thePLink to contactlink of theP
			--display dialog (thePLink as string)
			set theEStartdatetime to startdatetime of theE
			set theEStartdate to startdate of theE
			set theEStarttime to starttime of theE
			set theEType to eventtype of theE
			--return theEStartdate
			set theESTring to ""
			set theESTring to theEStartdatetime & " " & theEType & ": " & theName & return & theD as string
			--display dialog theESTring as string
			set thePersonList to {thePfirst, thePlast, thePCompany}
			set matchPerson to false
			--display dialog (count of theList)
			set c to count of theList
			repeat with z from 1 to c
				if item z of theList = thePersonList then
					--it's a match, add event
					set matchPerson to true
					set newList to {}
					set inserted to false
					set ec to count (item z of theData)
					--display dialog (item z of theData)
					repeat with ecc from 1 to ec
						if theEStartdatetime < (item 1 of item ecc of item z of theData) and not inserted then
							set end of newList to {{theEStartdatetime}, {theESTring}}
							set inserted to true
						end if
						set end of newList to item ecc of item z of theData
						
					end repeat
					if not inserted then
						set end of newList to {{theEStartdatetime}, {theESTring}}
					end if
					set item z of theData to newList
				end if
			end repeat
			--no match, add person, then event
			if not matchPerson then
				set theList to theList & {thePersonList}
				set theData to theData & {{{{theEStartdatetime}, {theESTring}}}}
			end if
		end if
	end repeat
end tell


set myFileReference to open for access exportfile with write permission
set eof of myFileReference to 0
write theLine & return to myFileReference
close access myFileReference
set myFileReference to open for access exportfilevcard with write permission
set eof of myFileReference to 0
close access myFileReference

tell application "Now Contact"
	set theListCount to count theList
	set c to count every person in document 1
	repeat with i from 1 to c
		set theP to person i of document 1
		--name is in dictionary but doesn't seem to be accessible from the variable theP
		--have to say person i of document 1
		set theName to name of person i of document 1
		set theFirstName to first name of theP
		set theMiddleName to middle name of theP
		set theLastName to last name of theP
		set theCompany to company of theP
		set thedepartment to department of theP
		set theTitle to title of theP
		set theSalutation to salutation of theP
		set theWorkAddresList to my list_proc(the work address of theP, return, "")
		set theWorkAddress to item 1 of theWorkAddresList
		if ((count theWorkAddresList) > 1) then
			set theWorkAddress2 to item 2 of theWorkAddresList
		else
			set theWorkAddress2 to ""
		end if
		set theWorkCity to work city of theP
		set theWorkState to work state of theP
		set theWorkZip to work zip of theP
		set theWorkCountry to work country of theP
		set thehomeAddresList to my list_proc(the home address of theP, return, "")
		set theHomeAddress to item 1 of thehomeAddresList
		if ((count thehomeAddresList) > 1) then
			set theHomeAddress2 to item 2 of thehomeAddresList
		else
			set theHomeAddress2 to ""
		end if
		set theHomeCity to home city of theP
		set theHomeState to home state of theP
		set theHomeZip to home zip of theP
		set theHomeCountry to home country of theP
		set theWorkPhone to work phone of theP
		set theHomePhone to home phone of theP
		set theFaxPhone to fax phone of theP
		set theMobilePhone to mobile phone of theP
		set theOtherPhone to other phone of theP
		set theEmail1 to email 1 of theP
		set theEmail2 to email 2 of theP
		set theURL to URL of theP
		set theCustom1 to custom 1 of theP
		set theCustom2 to custom 2 of theP
		set theCustom3 to custom 3 of theP
		set theCustom4 to custom 4 of theP
		(*
		set theCustom5 to custom 5 of theP
		set theCustom6 to custom 6 of theP
		set theCustom7 to custom 7 of theP
		set theCustom8 to custom 8 of theP
		set theCustom9 to custom 9 of theP
		set theCustom10 to custom 10 of theP
		set theCustom11 to custom 11 of theP
		set theCustom12 to custom 12 of theP
		set theKeywords to Keywords of theP
		set theCategory to category of theP
		*)
		set thePersonList to {theFirstName, theLastName, theCompany}
		set matchPerson to false
		set matchNum to 0
		set noteList to {}
		repeat with m from 1 to theListCount
			if item m of theList = thePersonList then
				set matchPerson to true
				set matchNum to m
				set noteList to item m of theData
			end if
		end repeat
		set theNotes to ""
		tell person i of document 1
			set nc to 1
			repeat
				try
					set theEStartdatetime to note date of note nc
					set theESTring to theEStartdatetime & " note: " & note title of note nc & return & note text of note nc
					set newList to {}
					set inserted to false
					set ec to count noteList
					repeat with ecc from 1 to ec
						if theEStartdatetime < (item 1 of item ecc of noteList) and not inserted then
							set end of newList to {{theEStartdatetime}, {theESTring}}
							set inserted to true
						end if
						set end of newList to item ecc of noteList
						
					end repeat
					if not inserted then
						set end of newList to {{theEStartdatetime}, {theESTring}}
					end if
					set noteList to newList
				on error
					exit repeat
				end try
				--display dialog notestring
				set nc to nc + 1
			end repeat
			repeat with eachNote in noteList
				if noteOrder = "Chronological" then
					set theNotes to theNotes & item 2 of eachNote & return
				else if noteOrder = "Reverse Chronological" then
					set theNotes to item 2 of eachNote & return & theNotes
				end if
			end repeat
		end tell
		
		--set theLine to "First,Middle,Last,Company,Department,Job Title,Street,Street,City,State,Zip,Country,Street,Street,City,State,Zip,Country,Phone (work),Phone (home),Phone (mobile),Phone (fax),Phone (other),Email (home),Email (work),URL,Note"
		set theLine to ""
		set theLine to theLine & "\"" & my list_proc(theFirstName, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theMiddleName, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theLastName, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theCompany, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(thedepartment, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theTitle, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theWorkAddress, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theWorkAddress2, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theWorkCity, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theWorkState, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theWorkZip, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theWorkCountry, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theHomeAddress, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theHomeAddress2, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theHomeCity, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theHomeState, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theHomeZip, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theHomeCountry, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theWorkPhone, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theHomePhone, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theMobilePhone, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theFaxPhone, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theOtherPhone, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theEmail1, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theEmail2, "\"", "\"\"") & "\"," as string
		set theLine to theLine & "\"" & my list_proc(theURL, "\"", "\"\"") & "\"," as string
		set theNotesUse to my list_proc(theNotes, ASCII character 13, ASCII character 11) as string
		set theNotesUse to my list_proc(theNotesUse, ASCII character 10, ASCII character 11) as string
		set theLine to theLine & "\"" & my list_proc(theNotesUse, "\"", "\"\"") & "\"" as string
		set myFileReference to open for access exportfile with write permission
		write theLine & return starting at ((get eof of myFileReference) + 1) to myFileReference
		close access myFileReference
		
		--we only need to export as vcard if there are notes
		--otherwise Contact's export to vcf does a better job
		--so conditional here for notes having info
		if theNotes ≠ "" then
			set theFirstName to my escaper(theFirstName)
			set theLastName to my escaper(theLastName)
			set theMiddleName to my escaper(theMiddleName)
			set theSalutation to my escaper(theSalutation)
			set theName to my escaper(theName)
			set theCompany to my escaper(theCompany)
			set theTitle to my escaper(theTitle)
			set theNotesUse to my list_proc(theNotes, ((ASCII character 13) & (ASCII character 10) as string), ASCII character 11) as string
			set theNotesUse to my list_proc(theNotesUse, (ASCII character 13), ASCII character 11) as string
			set theNotesUse to my list_proc(theNotesUse, (ASCII character 10), ASCII character 11) as string
			--set theNotesUse to my list_proc(theNotesUse, (ASCII character 11), ASCII character 10) as string
			set theNotesUse to my escaper(theNotesUse)
			
			
			set vName to theLastName & ";" & theFirstName & ";" & theMiddleName & ";" & theSalutation & ";" & "" as string
			
			set vCard to "BEGIN:VCARD
VERSION:3.0
N:" & vName & "
FN:" & theName & "
ORG:" & theCompany & ";" & thedepartment & "
TITLE:" & theTitle & "
NOTE:" & theNotesUse & "
END:VCARD"
			set myFileReference to open for access exportfilevcard with write permission
			write vCard & return starting at ((get eof of myFileReference) + 1) to myFileReference
			close access myFileReference
			
		end if
	end repeat
	
	
end tell

on escaper(theString)
	--escape backslashes with backslashes, escape comma, colon, semicolon
	--vertical tabs to \n
	set theString to my list_proc(theString, "\\", "\\\\") as string
	set theString to my list_proc(theString, ",", "\\,") as string
	set theString to my list_proc(theString, ";", "\\;") as string
	set theString to my list_proc(theString, ":", "\\:") as string
	set theString to my list_proc(theString, ASCII character 11, "\\n") as string
	return theString
end escaper


on list_proc(searchList, search_string, replace_string)
	set AppleScript's text item delimiters to the search_string
	set searchListlist to every text item of searchList
	set AppleScript's text item delimiters to replace_string
	set searchList to the searchListlist as string
	set AppleScript's text item delimiters to ""
	
	if replace_string = "" then
		return searchListlist
	else
		return searchList
	end if
	
end list_proc

-- linux_macosx_hints_etc page