Yosemite Calendar - exporting calendars as .ics files

Discussion in 'Mac Programming' started by Schubi, Nov 7, 2014.

  1. Schubi macrumors newbie

    Joined:
    Mar 22, 2013
    #1
    Following up on my thread Mavericks Lion Calendar - exporting calendars as .ics files I was wondering if anyone could take a look at the Yosemite Calendar and help with fixing a script that has been very useful to me over the past years.

    The functionality is actually very simple - the script backs up each calendar found within the Calendar app and saves it as an .ics file in a file directory:

    Code:
    -- IMPORTANT: BEFORE RUNNING THIS SCRIPT, OPEN THE CALENDAR AND SELECT CALENDAR 'BIRTHDAYS'
    -- Basic settings
    set timeStamp to do shell script "date \"+%Y%m%d\""
    set backup_folder to "/Users/ros/Backup/Calendar/"
    do shell script "mkdir -p " & quoted form of backup_folder & quoted form of timeStamp
    set savePath to backup_folder & timeStamp
    
    -- Begin script
    tell application "Calendar"
    	launch
    	activate
    	delay 2
    	set calNames to name of every calendar
    end tell
    
    tell application "System Events"
    	tell process "Calendar"
    		set frontmost to true
    		
    		-- Left-hand menu of Calendar, containing named calendars	
    		set myOutline to outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar"
    		set allRows to rows of myOutline
    		
    		-- List of named calendars
    		set calNameVals to get value of static text of UI element 1 of every row of myOutline
    		
    		-- For all named calendars, check whether it's the same name as one of calNames, if so export that calendar
    		set countLoop to 0
    		repeat with i from 2 to (count calNameVals)
    			set countLoop to countLoop + 1
    			set calName to item 1 of item i of calNameVals
    			repeat with myName in calNames
    				if (myName as string = calName as string) then
    					tell row i of myOutline
    						select
    						delay 1
    					end tell
    					click menu item "Export…" of menu 1 of menu item "Export" of menu 1 of menu bar item "File" of menu bar 1
    					delay 1
    					if countLoop = 1 then
    						keystroke "g" using {command down, shift down}
    						delay 1
    						keystroke savePath
    						delay 1
    						click button "Go" of sheet 1 of sheet 1 of window 1
    					end if
    					click button "Export" of sheet 1 of window 1
    					
    					-- Change the delay time if your computer is running to slow or too fast					
    					delay 15
    				end if
    			end repeat
    		end repeat
    	end tell
    end tell

    Here's the error message that comes up:
    [​IMG]


    And here are the reply messages from the 'Script Editor' when the script is run:
    Code:
    tell current application
    	do shell script "date \"+%Y%m%d\""
    		--> "20141108"
    	do shell script "mkdir -p '/Users/ros/Backup/Calendar/''20141108'"
    		--> ""
    end tell
    tell application "Calendar"
    	launch
    	activate
    	get name of every calendar
    		--> {"Entertainment", "Transportation", "Relationship", "Sexuality", "Education", "Food", "Socialising", "Household", "Employment", "Errands", "Health", "Sports", "Rest", "ToDoTo", "Holidays", "Hygiene", "Location", "Birthdays"}
    end tell
    tell application "System Events"
    	set frontmost of process "Calendar" to true
    	get outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of process "Calendar"
    		--> outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar"
    	get every row of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar"
    		--> {row 1 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 2 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 3 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 4 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 5 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 6 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 7 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 8 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 9 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 10 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 11 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 12 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 13 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 14 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 15 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 16 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 17 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 18 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 19 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar", row 20 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar"}
    	get value of static text of UI element 1 of every row of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar" of application process "Calendar"
    		--> {{"Cloud Calendar"}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {"Other"}, {}}
    Result:
    error "Can’t get item 1 of {}." number -1728 from item 1 of {}

    Assuming that's an easy fix again. Thanks a lot for looking into it!
     
  2. kryten2, Nov 8, 2014
    Last edited: Nov 8, 2014

    kryten2 macrumors 6502a

    Joined:
    Mar 17, 2012
    Location:
    Belgium
    #2
    Replace this :

    Code:
    -- List of named calendars
    set calNameVals to get value of static text of UI element 1 of every row of myOutline
    with this :

    Code:
    set calNameVals to get value of every UI element of UI element 1 of every row of myOutline
    		
    (*
    		-- Repeat works but uses more gets
    		set calNameVals to {}
    		repeat with aRow in every row of myOutline
    			if exists static text of UI element 1 of aRow then
    				set end of calNameVals to value of static text of UI element 1 of aRow
    			else
    				set end of calNameVals to value of text field of UI element 1 of aRow
    			end if
    		end repeat
    *)
    
     
  3. Schubi thread starter macrumors newbie

    Joined:
    Mar 22, 2013
    #3
    Welcome back kryten2 - and thanks for picking this up again! :D

    I tested the script and it basically works again, however there's only one delay value at the end that controls when the next calendar in the list is selected and backed-up. This is a problem as most of my calendars could finish within 10 seconds, however one large calendar takes about 200 seconds to complete. Backing-up 18 calendars times 3+ minutes 'blocks' the computer for a full hour, which of course is not nice!

    Do you think there could be a way to have the script without a default delay time to 'wait' for a specific calendar backup to finish before moving on to the next calendar? As in 'taking the exact needed time' before moving on to the next calendar?

    If not - a big thanks for all the effort in helping getting this running in the past!
     

    Attached Files:

  4. kryten2 macrumors 6502a

    Joined:
    Mar 17, 2012
    Location:
    Belgium
    #4
    Only if Apple would be so kind to show a progress window when exporting calendars. Unfortunately that's not the case. However you can use this :

    Code:
    -- change the delay time
    if (calName as string = "nameofcalendarthattakes200seconds") then 
    delay 200
    else
    delay 15
    end if
     
  5. Schubi thread starter macrumors newbie

    Joined:
    Mar 22, 2013
  6. Loyd-01a macrumors member

    Joined:
    Oct 10, 2014
    #6
    Hello,
    I try to implement the delay code posted by kryten2 in my script.
    So, I wonder how do you know how long each calendar needs to be backed up (10 seconds, 200 seconds, etc.)?
    Thank you
     
  7. kryten2 macrumors 6502a

    Joined:
    Mar 17, 2012
    Location:
    Belgium
    #7
    You export the calendar manually and time how long it takes.
     
  8. Loyd-01a macrumors member

    Joined:
    Oct 10, 2014
    #8
    Thank you for your answer.
    But this is exactly my question !
    When you export the calendar manually how to know that the export process has finished ? There's no indication for that..
    Thank you
     
  9. kryten2 macrumors 6502a

    Joined:
    Mar 17, 2012
    Location:
    Belgium
    #9
    You look at the file size of the .ics file in a Finder window. Let's say the calendar you export is 5Mb in size, delete it and export it again and watch the Finder window as the .ics file is created and grows in size to 5Mb and time it.
     
  10. Loyd-01a macrumors member

    Joined:
    Oct 10, 2014
    #10
    Thank you very much. This is what I am searching for !
     
  11. Loyd-01a macrumors member

    Joined:
    Oct 10, 2014
    #11
    Hello,

    Just another small question : How to exclude, in the script, a specific calendar from being backed up ?
    Thank you
     
  12. uncouthmike macrumors newbie

    Joined:
    Nov 5, 2017
    #12
    Hi there, is anyone still using this script? After discovering that Google does not keep any history of calendars and losing all my data to a bungling employee, I need to make sure I can daily back up our calendars to a system that I have control over (sync isn't sufficient, as of course if someone deletes a ton of calendar entries, it all syncs very nicely).

    The problem I have discovered (currently trying it on macos 12.6) is that it exports the first calendar fine, but then the Calendar app freezes when the panel comes up to export the second calendar. You see the directory displayed briefly, then it is grayed out and its beachball time. I have to force quit calendar...
     
  13. Loyd-01a macrumors member

    Joined:
    Oct 10, 2014
    #13
    Hello,

    I have the same problem !
     
  14. kryten2 macrumors 6502a

    Joined:
    Mar 17, 2012
    Location:
    Belgium
    #14
    I'm afraid I can't be of much help this time as I don't run Siera or High Siera so I can't test it.
     
  15. uncouthmike macrumors newbie

    Joined:
    Nov 5, 2017
    #15
    kryten2 is it working correctly for you under an earlier version of Macos? If so which one?
     
  16. kryten2 macrumors 6502a

    Joined:
    Mar 17, 2012
    Location:
    Belgium
    #16
    The title says Yosemite so I assume it still works on Yosemite. To be honest, I don't use the Calendar app at all so my way of quick testing is to create the calendars but with no events or appointments in them. I simply don't have the time to simulate a real life calendar. I do have El Capitan running in a VM so I could do a test on that. When that will be I can't say.
     

Share This Page