I’m new to Applescript, so please forgive my ignorance
Situation: Apple’s new iPod Touch can show and sync your iCal calendar, but you cannot enter new events directly on the iPod. However you can enter/edit contacts in the address book directly on the iPod (I know the iPhone provides event entry on the device, but is no option for me as I live in Belgium and we don’t have the iPhone (yet). (and I don’t want to hack it).
Question: would it be possible using Applescript to read out the address book on your Mac, select certain entries and convert these to an event? And delete the address book contact afterwards?
Let my clarify with an example:
I want to schedule a lunch meeting in my calendar, but I only have my iPod Touch (with no wifi connection available for the moment) at hand
on my iPod Touch I enter a contact:
first name: “2CAL1” (or other identifier)
last name: “Lunch with Carol”
address: “20/09/2007 @ 12-14”
later at home, I sync my iPod with my Mac => contact 2CAL1 (and 2CAL2, 2CAL3, …) is transferred to my Mac Address Book
I run the script:
it parses my Address Book for all 2CALx entries (x=1,2,3, …)
it puts the last name field in the Event description field
it takes the date/time from the address field
it saves the event in iCal
it deletes the 2CALx contacts from Address Book
at next sync, the 2CALx contacts are deleted on my Touch and the iCal entries are transferred.
This would be a work-around for entering events on the move, without hacking the iPod (it might be a bit weird since you’re entering an appointment in your contacts list, but it’s the only way I see it possibe without breaking anything).
Would this be feasible? Do you see other, better ways to do this without altering the iPod Touch software?
If possible, could you point me in the right direction for writing a script as described above?
I see no reason this wouldn’t work. An initial thought would be to add some kind of special character indicator in a predictable field in the contact so that your script knows which ones to translate to an event. I’m about to walk out the door to go home, but if you’ll reply to this post, I can probably lead you in the right direction. I’ve done some iCal and Address Book scripting in the past.
This is what I’ve come up with after a few hours of experimenting with Applescript:
tell application "Address Book"
set total_2CAL to 0
repeat with this_person in (get selection)
set total_2CAL to total_2CAL + 1
set ical_date to home page of this_person
set start_time to company of this_person
set duration to note of this_person
tell application "iCal"
tell calendar "SPHI"
set theCurrentDate to current date
make new event at end with properties {description:"Event Description", summary:"Event Name", location:"Event Location", start date:ical_date, end date:ical_date + duration * minutes}
end tell
end tell
end repeat
display dialog "Log: " & total_2CAL & " contacts were converted"
end tell
It works without the duration field. When I add this field, the script gives produces error “can’t make missing parameter into type number”. It -logically- expects the duration field to be numeric, whereas the note field is a text field. I’ve also tried with other fields like zip for example, but without success.
I’ve added the 2CAL indicator in the name field to identify the records to be processed. But the script as it is for the moment takes the selected entries from the address book. I haven’t found out yet how to make this script work “automatically”, i.e. without opening address book and selecting entries first.
The code above are my first lines ever in Applescript, so please correct and point me to the right direction where needed !!
you should coerce the text class to number class like
make new event at end with properties {description:"Event Description", summary:"Event Name", location:"Event Location", start date:ical_date, end date:ical_date + (duration as integer) * minutes}
I took the liberty of changing the script a bit. basically because I could not get yours to work with how I entered the data in AB.
In Addressbook entries are:
First Name: 2CAL
Last Name: Event Name
Nickname: Start date , example just the time 10:00 , or the day 18/09/2007 or a day and time 18/09/2007 10:00
job title : allday, for and all day events, ( which can be more than one day )
department: end time, example, just the time 22:00 , or the new day 19/09/2007 or a new day and time 19/09/2007 10:00
company: location
Note: Discription
start time and end times can also be left blank
and you can use allday event with or with out any dates set.
tell application "Address Book"
set total_2CAL to 0
repeat with this_person in (get selection)
set total_2CAL to total_2CAL + 1
set ical_date to nickname of this_person as string
set duration to department of this_person as string
set Event_name to last name of this_person as string
set Event_Description to note of this_person as string
set Event_Location to organization of this_person as string
set allday to "no"
set allday to job title of this_person as string
if duration is "missing value" then
set duration to ical_date
end if
my cal_set(ical_date, Event_name, Event_Location, duration, Event_Description, allday)
end repeat
display dialog "Log: " & total_2CAL & " contacts were converted"
log allday
end tell
on cal_set(ical_date, Event_name, Event_Location, duration, Event_Description, allday)
set Event_Start_date to date ical_date
set Event_end_Date to date duration
set startTime to date ical_date of Event_Start_date
log duration
set endTime to date duration of Event_end_Date
tell application "iCal"
tell calendar "marks"
make new event at end with properties {description:Event_Description, summary:Event_name, location:Event_Location, start date:startTime, end date:endTime}
end tell
end tell
if allday is "allday" then
log allday
tell application "iCal"
tell calendar "marks"
set thisEvent to (some event whose summary is Event_name)
set allday event of thisEvent to true
end tell
end tell
end if
end cal_set
**noticed a small edit that needed doing ( company needs to be, set Event_Location to organization of this_person as string, rather than set Event_Location to company of this_person as string)
Now:
Will search the Addressbook for entries marked for iCal events. ( so no need to select)
Will update the Addressbook entry with a “- Sent to Ical” tag
Will ignore entries already sent to iCal. (using the “- Sent to Ical” tag )
Will add a " - (iP)" to end of event summery to show as iPhone event
property iCalName : "yourCal" (*calendar name*)
property toCAL : "2CAL" (*iPhone Tag, to search for events*)
property from_iPhone : " - (iP)" (*tag for iCal to add to end of summery, showing event came from iPhone*)
property synced : "- Sent to Ical" as string (*inserted into the addressbook entry, showing it has been sent to iCal,
Also used to stop entry being sent twice when script is run*)
tell application "Address Book"
(*check for Addressbook entries*)
set total_2CAL to 0
(*if Addressbook entries suffix contain '2CAL' and '- Sent to Ical' then the will be processed *)
set thesePeople to (people whose first name contains toCAL and suffix does not contain synced)
(*repeat for each for found entry. get the details*)
repeat with this_person from 1 to number of items in (thesePeople)
set this_person to item this_person of thesePeople
set total_2CAL to total_2CAL + 1
set ical_date to nickname of this_person as string
set duration to department of this_person as string
set Event_name to last name of this_person as string
set Event_Description to note of this_person as string
set Event_Location to organization of this_person as string
log Event_Location
(*get date settings for ical*)
set allday to "no"
--set allday to street of address of this_person as string
set allday to job title of this_person as string
if duration is "missing value" then
set duration to ical_date
end if
(*go to ical set up*)
my cal_set(ical_date, Event_name, Event_Location, duration, Event_Description, allday, this_person)
end repeat
(**)
display dialog "Log: " & total_2CAL & " contacts were converted"
end tell
--------------------------------SUB-Routines---------------------
on cal_set(ical_date, Event_name, Event_Location, duration, Event_Description, allday, this_person)
(*process the dates*)
set Event_Start_date to date ical_date
set Event_end_Date to date duration
set startTime to date ical_date of Event_Start_date
log duration
set endTime to date duration of Event_end_Date
(*make ical event*)
tell application "iCal"
tell calendar iCalName
set nEWevent to make new event at end with properties {description:Event_Description, summary:(Event_name & from_iPhone as string), location:Event_Location, start date:startTime, end date:endTime}
tell event nEWevent
--set EventID to uid of nEWevent (**)
(*go to all day event check, and setup*)
my all_day(allday, nEWevent)
(*go to addressbook tag marker*)
my sycdone(this_person, synced)
end tell
end tell
end tell
end cal_set
on all_day(allday, nEWevent)
(*check if all day was needed*)
if allday is "allday" then
log allday
(*if yes, set the newly made event to an all day event*)
tell application "iCal"
tell calendar "marks"
--set thisEvent to (some event whose summary is Event_name)
set allday event of nEWevent to true
end tell
end tell
end if
end all_day
(*to stop the addressbook entry being sent to iCall more than once the suffix of the
entry will be updated to "- Sent to Ical". If you want to have the entry re-sent, just edit the Addressbook entry, and clear "- Sent to Ical" from the Suffix*)
on sycdone(this_person, synced)
(*mark the addressbook entry as "- Sent to Ical"*)
tell application "Address Book"
set suffix of this_person to synced
save addressbook
end tell
end sycdone