Si configuro un evento para que se repita cada día, ¿es posible autoincrementar un número al final de su nombre?
Por ejemplo, cada día a las 21:00 me gustaría una alerta que diga "Día #" donde # es el número de días desde que comenzó el evento.
Si configuro un evento para que se repita cada día, ¿es posible autoincrementar un número al final de su nombre?
Por ejemplo, cada día a las 21:00 me gustaría una alerta que diga "Día #" donde # es el número de días desde que comenzó el evento.
Un AppleScript es una forma de hacerlo. Véase MacScripter / Calendario: Incremento de la propiedad Nombre para eventos recurrentes que tiene un script que hace cada año un evento que dice "El #aniversario de Juan Pérez". El script también está abajo, para su comodidad.
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
Que script es mucho más largo de lo necesario para mí, y es difícil de analizar para obtener sólo las partes que necesito. Además, se desaconsejan las respuestas con enlaces, ya que pueden no funcionar en el futuro. ¿Podrías tomar los puntos/partes clave de ese script y explicarlos en tu respuesta, quizás modificándolos para que se adapten mejor a esta pregunta?
AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.