1 votes

Auto-incrémentation du nom de l'événement dans le calendrier

Si je configure un événement pour qu'il se répète chaque jour, est-il possible d'auto-incrémenter un nombre à la fin de son nom ?

Par exemple, tous les jours à 21h00, je voudrais une alerte indiquant "Jour #", où # est le nombre de jours écoulés depuis le début de l'événement.

2voto

Un AppleScript est un moyen d'y parvenir. Voir MacScripter / Calendrier : Incrémentation de la propriété Name pour les événements récurrents qui a un script faisant chaque année un événement qui dit "le #e anniversaire de John Doe". Le script est également ci-dessous, pour votre commodité.

main()

on main()
   set calendar_name to "Anniversaries"
   set number_of_anniversaries to 75

   -- Get the required info from Contacts in iCalendar or intermediate form.
   set seed_data to get_seed_data()
   if (seed_data is {}) then
       display dialog "None of your contacts have anniversaries!" buttons {"!"} default button 1 with icon stop
   else
       -- Compose an iCalendar spec for a calendar containing the required events and save it to an .ics file on the desktop.
       set iCalendar_text to compose_ics(seed_data, number_of_anniversaries)
       write_ics_file(iCalendar_text, (path to desktop as text) & (calendar_name & ".ics"))

       -- Import the file into Calendar as a new calendar.
       import_calendar(calendar_name)
   end if
end main

-- Identify "anniversary" custom dates in Contacts and return the corresponding names, ids, and dates adapted for use in the construction of an iCalendar spec. Monogamous and once-only marriages assumed!
on get_seed_data()
   tell application "System Events" to set Contacts_open to (application process "Contacts") exists

   -- Get the name, id, and custom-date data for every person in Contacts. 
   tell application "Contacts"
       launch
       set {names, ids, {date_labels, date_values}} to {name, id, {label, value} of custom dates} of people
       if (not Contacts_open) then quit
   end tell

   -- Find any "anniversary" date labels and store the associated person/date data converted as follows:
   -- name: as the start of an iCalendar SUMMARY entry, with the name in the genitive and a trailing space.
   -- id: as a complete iCalendar URL entry, the id being part of an "addressbook"-protocol URL.
   -- "anniversary" date value: as event start and end dates in zoneless ISO format, but stored as integers instead of text for ease and speed of manipulation.
   set seed_data to {}
   repeat with person from 1 to (count names)
       set these_labels to item person of date_labels
       if (these_labels contains "anniversary") then
           repeat with custom_date from 1 to (count these_labels)
               if (item custom_date of these_labels is "anniversary") then
                   set start_date to item custom_date of item person of date_values
                   set end of seed_data to {|SUMMARY start|:"SUMMARY:" & (item person of names) & "'s ", |URL entry|:"URL;VALUE=URI:addressbook://" & item person of ids, |start date|:ISOT_integer(start_date), |end date|:ISOT_integer(start_date + days)}
                   exit repeat
               end if
           end repeat
       end if
   end repeat

   return seed_data
end get_seed_data

-- Put together an iCalendar specification for a calendar containing recurring events whose initial summaries indicate weddings and recurrence summaries indicate the inividual anniversaries.
on compose_ics(seed_data, number_of_anniversaries)
   -- The list of iCalendar components could get very long, so it'll be referenced via a script object for speed of access.
   script iCalendar
       property components : {}
   end script

   -- Initialise a VEVENT template. It'll serve for both main events and recurrence instances.
   set VEVENT_template to {"BEGIN:VEVENT", missing value, missing value, missing value, missing value, missing value, missing value, missing value, missing value, missing value, "END:VEVENT"}
   -- Get process and host data for use in the UIDs.
   set my_Name to name of current application
   tell application "System Events" to set unix_id to unix id of first application process whose displayed name is my_Name
   set host_name to host name of (system info)
   -- Prepare to use CRLF line endings.
   set CRLF to return & linefeed
   set astid to AppleScript's text item delimiters
   set AppleScript's text item delimiters to CRLF

   -- Create and store the opening VCALENDAR spiel.
   set beginning of iCalendar's components to {"BEGIN:VCALENDAR", "VERSION:2.0", "PRODID:-//Apple Inc.//iCal 4.0.4//EN", "CALSCALE:GREGORIAN"} as text

   -- Create and store the VEVENT sections for each main event.
   repeat with event_number from 1 to (count seed_data)
       set {|SUMMARY start|:SUMMARY_start, |URL entry|:URL_entry, |start date|:start_date, |end date|:end_date} to item event_number of seed_data
       -- Load the VEVENT template with the data for the main, recurring event.
       set item 2 of VEVENT_template to "CREATED:" & ISOT_GMT(current date)
       set item 3 of VEVENT_template to "UID:" & new_UID(unix_id, host_name, event_number)
       set item 4 of VEVENT_template to "DTEND;VALUE=" & end_date
       set leap_wedding to (start_date mod 10000 is 229) -- Did these idiots get married on 29th February?
       if (leap_wedding) then
           set using_Mar1 to (button returned of (display dialog (text 9 thru -1 of SUMMARY_start & "wedding is/was on 29th February! Are the non-leap anniversaries celebrated on 28th February or 1st March?") buttons {"28th February", "1st March"} default button 2 with icon note) is "1st March")
           if (using_Mar1) then -- The anniversaries have to recur on the 60th day of every year …
               set item 5 of VEVENT_template to "RRULE:FREQ=YEARLY;INTERVAL=1;BYYEARDAY=60;COUNT=" & (number_of_anniversaries + 1)
           else -- … or else on the last day of every February.
               set item 5 of VEVENT_template to "RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=2;BYMONTHDAY=-1;COUNT=" & (number_of_anniversaries + 1)
           end if
       else -- Normal anniversaries simply recur on the same date every year.
           set item 5 of VEVENT_template to "RRULE:FREQ=YEARLY;INTERVAL=1;COUNT=" & (number_of_anniversaries + 1)
       end if
       set item 6 of VEVENT_template to SUMMARY_start & "wedding"
       set item 7 of VEVENT_template to "DTSTART;VALUE=DATE:" & start_date
       set item 8 of VEVENT_template to "DTSTAMP:" & ISOT_GMT(current date)
       set item 9 of VEVENT_template to "SEQUENCE:7" -- Cheating with the sequence number!
       set item 10 of VEVENT_template to URL_entry

       -- Coerce the template to text and append the resulting VEVENT entry to the component list.
       set end of iCalendar's components to VEVENT_template as text

       -- Now create the required number of linked VEVENTS for the anniversaries, inserting the relevant dates and summaries into the template and coercing it to text each time.
       repeat with anniversary_number from 1 to number_of_anniversaries
           set start_date to start_date + 10000 -- Add 1 to the year.
           set end_date to end_date + 10000 -- Ditto.
           if (leap_wedding) then
               -- Use months and days pertinent to the anniverary-date convention.
               set y to start_date div 10000
               if (isLeapYear(y)) then
                   set start_date to y * 10000 + 229
                   set end_date to y * 10000 + 301
               else if (using_Mar1) then
                   set start_date to y * 10000 + 301
                   set end_date to y * 10000 + 302
               else
                   set start_date to y * 10000 + 228
               end if
           end if
           set item 4 of VEVENT_template to "DTEND;VALUE=DATE:" & end_date
           -- This entry links this VEVENT to an expression date of the original event's recurrence.
           set item 5 of VEVENT_template to "RECURRENCE-ID;VALUE=DATE:" & start_date
           set item 6 of VEVENT_template to SUMMARY_start & anniversary_number & ordinal(anniversary_number) & " anniversary"
           set item 7 of VEVENT_template to "DTSTART;VALUE=DATE:" & start_date
           set item 8 of VEVENT_template to "DTSTAMP:" & ISOT_GMT(current date)
           set item 9 of VEVENT_template to "SEQUENCE:8" -- Cheating with the sequence number!

           -- Append this linked-VEVENT text to the output components.
           set end of iCalendar's components to VEVENT_template as text
       end repeat
   end repeat

   -- Lastly, append the END:VCALENDAR line.
   set end of iCalendar's components to "END:VCALENDAR" & CRLF
   -- When all the components are gathered, coerce the lot into one text.
   set iCalendar_text to iCalendar's components as text

   set AppleScript's text item delimiters to astid

   return iCalendar_text
end compose_ics

on write_ics_file(iCalendar_text, hfs_path)
   set fRef to (open for access file hfs_path with write permission)
   try
       set eof fRef to 0
       write iCalendar_text as «class utf8» to fRef
   end try
   close access fRef
end write_ics_file

-- Delete any current calendar with the given name and import an .ics file to a replacement.
on import_calendar(calendar_name)
   tell application "Calendar"
       activate
       if (calendar calendar_name exists) then delete calendar calendar_name
       -- This assumes there'll be at most one calendar with the name, but it's easy to modify.
   end tell

   -- "Double-click" the ics file. Calendar will offer to import the new events.
   tell application "Finder" to open file (calendar_name & ".ics") of desktop

   -- In the Add Events dialog, select the bottom item ("New Calendar") in the pop-up menu and hit return. The calendar should be created automatically with the name of the ics file.
   tell application "System Events"
       tell application process "Calendar" -- GUI Scripting.
           repeat until (window 2 exists)
               delay 0.2
           end repeat
           tell pop up button 1 of window 1
               perform action "AXPress" -- Click the pop-up menu button.
               perform action "AXPress" of menu item -1 of menu 1 -- Click the "New Calendar" item.
           end tell
       end tell
       keystroke return -- "Click" the dialog's "OK" button.
   end tell
end import_calendar

-- Return the "yyyymmdd" representation of a date as an integer.
on ISOT_integer(theDate)
   set {year:y, month:m, day:d} to theDate
   return y * 10000 + m * 100 + d
end ISOT_integer

-- Return the GMT equivalent of a date in ISOT format.
on ISOT_GMT(theDate)
   set {year:y, month:m, day:d, time:t} to theDate - (time to GMT)
   return ((y * 10000 + m * 100 + d) as text) & "T" & text 2 thru -1 of ((1000000 + t div hours * 10000 + t mod hours div minutes * 100 + t mod minutes) as text) & "Z"
end ISOT_GMT

-- Construct an "@"-style UID from the current date and time and the given data.
on new_UID(unix_id, host_name, iteration)
   return ISOT_GMT(current date) & "-" & unix_id & "-" & iteration & "@" & host_name
end new_UID

on isLeapYear(y)
   return ((y mod 4 is 0) and (y mod 400 is not in {100, 200, 300}))
end isLeapYear

on ordinal(n)
   set units to n mod 10
   if ((units > 3) or ((n - units) mod 100 is 10) or (units < 1)) then
       return "th"
   else
       return item units of {"st", "nd", "rd"}
   end if
end ordinal

0 votes

Ce script est beaucoup plus long que nécessaire pour moi, et il est difficile de l'analyser pour en extraire les éléments dont j'ai besoin. De plus, les réponses par lien uniquement sont déconseillées car elles risquent de ne plus fonctionner à l'avenir. Pourriez-vous reprendre les points/parties clés de ce script et les expliquer dans votre réponse, en les modifiant éventuellement pour mieux répondre à cette question ?

0 votes

@theonlygusti - J'ai modifié ma question pour inclure le script. Si vous pouvez éditer mon message pour qu'il suive mieux les directives, je vous en serais reconnaissant.

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X