Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Sync subscribed iCal calendars to MobileMe via script Apps
As discussed in many places, the MobileMe cloud does not serve calendars you have subscribed to out to the iPhone -- only local calendars are synced. I need to see a calendar which my secretary maintains, so I created an AppleScript which duplicates that calendar into one local to my Mac, which then syncs to the iPhone.

My AppleScript skills are rudimentary, but here it is:
(* 
Script to duplicate Calendar orgCalendar into target dupCalendar
E.H. 12.9.2008
*)

property myCopies : 0
property myUpdates : 0
property myObsoletes : 0
property orgCalendar : "Sekretariat"
property dupCalendar : "Sekretariat copy"
property dupEvents : {}
property myDeletes : {}

set myCopies to 0
set myUpdates to 0
set myObsoletes to 0
set dupEvents to {}


tell application "iCal"
    
    -- set theCalendars to every calendar
    set theCalendarNames to title of every calendar
    set theOrgCalendar to a reference to calendar orgCalendar
    
    if theCalendarNames contains dupCalendar then
        set theCalendar to a reference to calendar dupCalendar
    else
        set theCalendar to make new calendar with properties {title:dupCalendar}
        --set theCalendar to make new calendar with properties {title:dupCalendar, color:"{65535, 0, 0}"}
    end if
    
    set the eventList to uid of every event of theOrgCalendar as list
    set the eventCount to the count of the eventList
    
    repeat with theUId in eventList
        tell theOrgCalendar
            set theEvent to (the first event whose uid is theUId)
            -- set theProperties to the properties of theEvent as record
            set theDate to the start date of theEvent
            set theSummary to the summary of theEvent
            set theStampDate to the stamp date of theEvent
        end tell
        
        tell theCalendar
            try
                set theOldEvent to (the first event of theCalendar whose (start date) is theDate as date)
                set similar_found to true
            on error
                set similar_found to false
                set theEndDate to the end date of theEvent
                set theAllDay to the allday event of theEvent
                set theLocation to the location of theEvent
                -- Funny construction to work araund the fact that location may be missing a value
                try
                    if theLocation is equal to "" then
                    end if
                on error
                    set theLocation to ""
                end try
                set theDescription to the description of theEvent
                try
                    if theDescription is equal to "" then
                    end if
                on error
                    set theDescription to ""
                end try
                if theAllDay is true then -- work around a funny bug with all day events
                    set theDate to (theDate as date) + 2 * hours
                    set theEndDate to (theEndDate as date) + 2 * hours
                end if
                set newEvent to make new event at end with properties {summary:theSummary, location:theLocation, start date:theDate, end date:theEndDate, allday event:theAllDay, description:theDescription}
                -- make new event at end with properties theProperties
                set the end of dupEvents to (the uid of newEvent)
                
                set myCopies to (myCopies + 1)
            end try
        end tell
        
        set second_necessary to false
        if similar_found is true then
            set theOldSummary to the summary of theOldEvent
            if theSummary is not equal to theOldSummary then
                --is there a different one?
                try
                    set theOldEvent1 to (the second event of theCalendar whose (start date) is theDate as date)
                    set theOldSummary to the summary of theOldEvent1
                    if theSummary is equal to theOldSummary then
                        set theOldEvent to theOldEvent1
                        set the end of dupEvents to (the uid of theOldEvent)
                    else
                        -- cycle repeat ?
                    end if
                on error
                    -- beep
                    try
                        set theEvent1 to (the second event of theOrgCalendar whose (start date) is theDate as date)
                        set second_necessary to true
                    on error
                        set the end of dupEvents to (the uid of theOldEvent)
                    end try
                end try
            else
                set the end of dupEvents to (the uid of theOldEvent)
            end if
            
            if second_necessary is true then
                set theEndDate to the end date of theEvent
                tell theCalendar
                    set theOldEvent to make new event at end with properties {summary:theSummary, start date:theDate, end date:theEndDate}
                end tell
                set the end of dupEvents to (the uid of theOldEvent)
            end if
            
            set theOldStampDate to the stamp date of theOldEvent
            if theStampDate is greater than theOldStampDate then
                -- update the event
                set summary of theOldEvent to theSummary -- capitalization may have changed
                set theAllDay to the allday event of theEvent
                set allday event of theOldEvent to theAllDay
                set theEndDate to the end date of theEvent
                if theAllDay is true then -- work around a funny bug with all day events
                    set theEndDate to (theEndDate as date) + 2 * hours
                end if
                set end date of theOldEvent to theEndDate
                set theDescription to the description of theEvent
                try
                    if theDescription is equal to "" then
                    end if
                on error
                    set theDescription to ""
                end try
                set description of theOldEvent to theDescription
                
                set myUpdates to myUpdates + 1
            end if
        end if
        
    end repeat
end tell

-- Delete obsolete events

set myObsoletes to 0
set myDeletes to {}

tell application "iCal"
    set myUIDs to uid of events of theCalendar
end tell

repeat with myUID in myUIDs
    if dupEvents does not contain myUID then
        set the end of myDeletes to myUID
        set myObsoletes to (myObsoletes + 1)
    end if
end repeat

tell application "iCal"
    repeat with myDel in myDeletes
        delete (every event of theCalendar whose uid is myDel)
    end repeat
end tell

-- delete duplicates

set myDeletes to {}

tell application "iCal"
    set myStarts to start date of events of theCalendar
    set mySummaries to summary of events of theCalendar
    set myUIDs to uid of events of theCalendar
    set myLength to length of myUIDs
end tell

repeat with i from 1 to (myLength - 1)
    set thisStart to (item i of myStarts)
    set thisSumm to (item i of mySummaries)
    repeat with j from (i + 1) to myLength
        set thatStart to (item j of myStarts)
        set thatSumm to (item j of mySummaries)
        if thisSumm is equal to thatSumm and thisStart is equal to thatStart then
            set the end of myDeletes to (item j of myUIDs)
            exit repeat
        end if
    end repeat
end repeat

set n to count of myDeletes

tell application "iCal"
    
    repeat with myDel in myDeletes
        delete (every event of theCalendar whose uid is myDel)
    end repeat
    
    -- set the visible of calendar theCalendar to false
    
end tell

display dialog (myCopies & " records duplicated, " & myUpdates & " records updated and " & myObsoletes & " obsolete ones deleted") as text
To adopt this to your own needs, simply replace the names associated with orgCalendar (the original calendar) and dupCalendar (the duplicate the script will create) near the top of the script.

[robg adds: I tested this, and it works as described. This previous hint describes a manual solution to the problem, and the comments offer some script alternatives. This version, however, seems more robust and makes updating easier.

The advantage of using a script is that you can then use iCal (or Automator) to set up an event to run the script automatically, keeping your "fake" subscribed calendar up to date. I did just that with this script, setting up a repeating event in iCal to run the script once a week. If you're going to do this, you may want to comment out the final display dialog line, so that you don't have a window popping up on your screen each week.]
    •    
  • Currently 1.50 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (2 votes cast)
 
[25,900 views]  

Sync subscribed iCal calendars to MobileMe via script | 13 comments | Create New Account
Click here to return to the 'Sync subscribed iCal calendars to MobileMe via script' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Sync subscribed iCal calendars to MobileMe via script
Authored by: andya on Sep 17, '08 08:05:14AM
this worked with my wife's published calendar, but not the birthdays calendar (from address book), nor apple's u.s. holiday calendar http://ical.mac.com/ical/US32Holidays.ics

any idea what's happening?

[ Reply to This | # ]
Sync subscribed iCal calendars to MobileMe via script
Authored by: JackSloth on Sep 17, '08 10:00:04AM

Thank you so much. This really helped me.

I have a shared calendar with my wife using the calendaring feature on Leopard server. After spending months getting that to just work, imagine how upset I was to find it wouldn't sync with my iPhone. So this script really helped.

In iCal I created a group. In there I created a new calendar just for running scripts. It runs your script nightly. I also put the new duped calendar in this group. I then hid the group so I don't have to see the script alarm or any duplicated events. MobileMe syncs it to my iPhone.

Great!



[ Reply to This | # ]
Sync subscribed iCal calendars to MobileMe via script
Authored by: JackSloth on Sep 18, '08 08:07:41AM
Just to update my last post.

The one problem with using iCal to run the script is that you then get a clutter of script trigger events on your iPhone (if you are using Push with MobileMe). Unfortunately, MobileMe doesn't allow you to deselect calendars in the syncing process.

What I did was delete the script calendar. So what I am going to try is a Preference Pane Utility callled "Do Something When" http://www.azarhi.com/Projects/DSW/index.php It will launch programs or open files when something happens. So you can set it to launch the script when iCal opens. I have two calendars that I am duplicating. I therefore have twoscripts. I set up this Preference Pane launch each script at launch and quit of iCal. I have to open iCal to make a change to the calendar right? I set one of the scripts to run after a 180 second delay so they aren't running at the same time.


[ Reply to This | # ]
Sync subscribed iCal calendars to MobileMe via script
Authored by: pdengler on Sep 17, '08 11:37:58AM

I'm not really experienced with Scripts - I managed to get the script to work so that it created the new Calandar in iCal but there are events in it (it's a once/month meeting)...any ideas on where I went wrong? I only replaced the name of my calendar in two places at the beginning of the script...



[ Reply to This | # ]
Sync subscribed iCal calendars to MobileMe via script
Authored by: BlackjackJoe on Sep 17, '08 02:34:50PM

I'm getting an AppleScript Error: "The variable theOldEvent is not defined." when I try to run this script. The lines highlighted with the error are:

if similar_found is true then
set theOldSummary to the summary of theOldEvent

Any ideas how to fix this?

Thanks.



[ Reply to This | # ]
Sync subscribed iCal calendars to MobileMe via script
Authored by: vivekv80 on Sep 19, '08 10:15:11AM

Can someone post on how to setup an automator flow or iCal Alarm to trigger this script at a specific time. I am not able to set up an ical alarm that triggers these applescripts at regular intervals. Also when i run these applescripts, I get "Event timed out" message.



[ Reply to This | # ]
Sync subscribed iCal calendars to MobileMe via script
Authored by: NoComment on Sep 23, '08 02:59:34AM

Great script, this could solve the misery of external calendars on the iphone.

Unfortunately this script seems to skip reoccuring events, as some other people already noticed here. Would be great if this could be added, too!



[ Reply to This | # ]
Sync subscribed iCal calendars to MobileMe via script
Authored by: dfobert on Sep 23, '08 11:08:06AM

This drove me out of my mind for a while so I had to post. If you try to run the script as written (and commenting out the last section as the OP recommends) it will run find at the command line and fail if you try to execute it with launchd. Here's the details:

I spent a little bit of time and set this up to automatically run every 15 minutes through via launchd (using Lingon.) However, for some reason the script would not run. I opened up the terminal, ran the command "launchctl list" and found out that it was exiting with a status of 1, making the daemon drop it. The fix was to add ; exit 0 after the applescript. Works like a charm.

So if you're using Lingon, make sure that the "What" field reads something like:

osascript /Users/yourname/Documents/iCalGoogleSync.scpt ; exit 0
and it should work just fine

If you're new with Lingon and Applescript, I read through this blog post and found it a good refresher.



[ Reply to This | # ]
Sync subscribed iCal calendars to MobileMe via script
Authored by: franconi on Oct 28, '08 04:05:01PM

This hint is great. I am already using it for my iPhone.

Any clue on how to deal with recurring events? Once we have that, it's perfect.



[ Reply to This | # ]
Sync subscribed iCal calendars to MobileMe via script
Authored by: adrianlambert on Feb 18, '09 04:34:05AM

I'm also having timed out problems. I also had to change the allday events to 12 from 2 where they were in the script (due to the mentioned bug) otherwise the allday's were appearing on the day before.



[ Reply to This | # ]
Sync subscribed iCal calendars to MobileMe via BusySync
Authored by: LouieNet on May 05, '09 09:27:56AM
Have you guys tried BusySync from BusyMac? I think it might solve the problem of syncing a subscribed calendar to MobileMe / iPhone. I think I'll do the free trial and see....

http://www.busymac.com

---
G4 cube, 17" Powerbook G4, iMac 20", Mac mini, PowerMac 7500 (w/ G4 upgrade card)

[ Reply to This | # ]

Sync subscribed iCal calendars to MobileMe via script
Authored by: horhey23 on Oct 08, '09 12:50:32AM

Seems iPhone OS 3.1 now syncs subscribed calendars in iCal. Of coure Apple gives no heads up on this. I was manully syncing my subscribed calendars and noticed the duplicates. Had to do some rigamarole to get these off the iPhone.

Now if we could just select which calendars to sync. Having daily Applescript alarms in my iPhone calendar is not desirable. Just need those to run on the Mac.



[ Reply to This | # ]
Sync subscribed iCal calendars to MobileMe via script
Authored by: riffraf on Oct 09, '09 12:26:41PM

Yeah, just noticed this yesterday and did some searching today to see if I was imagining this... Couldn't figure out where all my dupes were coming from.

In addition to choosing which calendars display on the iPhone, it would be excellent if the mobileme web interface also displayed subscribed calendars.

I guess I don't get what's so hard about this... :-(



[ Reply to This | # ]