Getting today's events from iCal with Applescript - applescript

I iterate over all the events in iCal to get only today's events, but I don't think this is efficient. Is there a function/method to get only today's events?
tell application "iCal"
tell calendar "Lotus Notes"
set today to (current date)
set this_year to year of today
set this_month to month of today
set this_day to day of today
repeat with c in every event
set d to start date of c
set the_year to year of d
set the_month to month of d
set the_day to day of d
if (the_year = this_year) and (the_month = this_month) and (the_day = this_day) then
show c
end if
end repeat
end tell
end tell

Try this:
set {year:y, month:m, day:d} to current date
set str to (m as string) & " " & (d as string) & " " & (y as string)
set today to date str
set tomorrow to today + 60 * 60 * 24
tell application "iCal"
tell calendar "Lotus Notes"
set curr to every event whose start date is greater than or equal to today ¬
and start date is less than or equal to tomorrow
end tell
end tell

Related

Is there a reason my AppleScript is running so slow?

I have a script to run from a command line prompt. The command,
followed by some text, will set a reminder in the Reminder.app with a
due date of next friday. The script is taking about 100 seconds to run
which seem very high.
on nextWeekday(wd)
set today to current date
set twd to weekday of today
if twd is wd then
set d to 7
else
set d to (7 + (wd - twd)) mod 7
end if
return today + (d * days)
end nextWeekday
on run argv
set nextFriday to nextWeekday(Friday)
tell application "Reminders"
set newLable to argv as string
set myList to list "Do."
tell myList
set newReminder to make new reminder
set name of newReminder to newLable
#set remind me date of newReminder to theDay
set allday due date of newReminder to nextFriday
end tell
end tell
end run
The code in the .bash_profile is as follows:
function reme() {
cd
cd /Users/jamieauburn/Documents/projects/reminder
osax reme.scpt $1
}
Have I got something wrong in the script?
You have a lot of unnecessary things here. Your script can be written much more compactly, and it becomes about 4 times faster.
on run argv
tell (current date) to set nextFriday to it + (6 - (its weekday)) * days
tell application "Reminders" to tell list "Do."
make new reminder with properties {name:(argv as string), allday due date:nextFriday}
end tell
end run

How to convert an Apple Mail received date, month, to a string or number?

I am doing a simple step through messages in my inbox. I want to write out the date to a text file. The date is coming through as "Sunday April 2, 2017 at 12:12:12:. All I want to do is convert this to "4/2/17". I keep getting "April" as the month and cannot coerce it to "4" MM format.
tell application "Mail"
repeat with aMessage in messages of inbox
set sSender to (get aMessage's sender)
set recDate to (date received of aMessage)
set sMonth to month of recDate
set sDate to day of recDate & "/" & month of recDate & "/" & year of recDate
end tell
I have tried using a shell echo, or coercing sMonth to a string or integer. No matter what I keep getting "April" instead of a number and "rich text" instead of string.
I don't mind using a shell command, but I am not good with Linux and I do not want to convert the current date (I need to use the date of a past email). I know I must be missing something simple.
First of all to avoid the terminology confusion (rich text instead of text) move the code to create the date string into a handler.
To get 4 from the month just coerce it to integer, then coerce all components to text. To strip the 20 from the year just use only the last two characters.
tell application "Mail"
repeat with aMessage in messages of inbox
set sSender to (get aMessage's sender)
set sDate to my dateString(date received of aMessage)
end repeat
end tell
on dateString(theDate)
tell theDate to set {yr, mn, dy} to {year as text, its month as integer as text, day as text}
return mn & "/" & dy & "/" & text -2 thru -1 of yr -- 4/27/18
end dateString
If you want to add leading zeros to the day and month components use another handler to pad the values
on dateString(theDate)
tell theDate to set {yr, mn, dy} to {year as text, its month as integer as text, day as text}
return pad(mn) & "/" & pad(dy) & "/" & text -2 thru -1 of yr -- 04/27/18
end dateString
on pad(v)
return text -2 thru -1 of ("0" & v)
end pad
This works for me using the latest version of macOS High Sierra
property theShortDate : missing value
tell application "Mail"
repeat with aMessage in messages of inbox
set sSender to (get aMessage's sender)
set recDate to (date received of aMessage) as string
my shortDate(recDate)
log "This E-Mail Was Sent From: " & sSender & " " & "on" & " " & theShortDate
end repeat
end tell
on shortDate(recDate)
set AppleScript's text item delimiters to ","
set theLongDate to recDate
set currentMonth to (word 1 of text item 2 of theLongDate)
set currentDay to (word 2 of text item 2 of theLongDate)
set currentYear to (word 1 of text item 3 of theLongDate)
set monthList to {January, February, March, April, May, June, July, August, September, October, November, December}
repeat with x from 1 to 12
if currentMonth = ((item x of monthList) as string) then
set theRequestNumber to (text -2 thru -1 of ("0" & x))
exit repeat
end if
end repeat
set currentMonth to theRequestNumber
set currentDay to (text -2 thru -1 of ("0" & currentDay))
set theShortDate to (currentMonth & "/" & currentDay & "/" & currentYear) as string
end shortDate

Why is this AppleScript idle timer not triggering correctly?

I am trying to create a timer that increments at a certain time (in this case, whenever the time is xx:03:24) and sends a notification when it reaches a user-inputted value. Once it does so, it resets the increment and repeats until manually quit.
However, this code is not reliably triggering when it is supposed to. Does anyone have a guess as to why?
on quit
continue quit
end quit
tell application "Notifications Scripting"
set event handlers script path to (path to me)
end tell
global actions, newActions
using terms from application "Notifications Scripting"
on notification activated
tell application "Safari"
activate
set winlist to every window
repeat with win in winlist
set numtabs to 0
try
set tablist to every tab of win
set numtabs to length of tablist
end try
if numtabs is greater than 0 then
repeat with t in tablist
if "fallenlondon.storynexus.com" is in (URL of t as string) then
tell application "System Events"
tell window id (id of win as integer) of application "Safari" to set current tab to tab (index of t as integer)
end tell
end if
end repeat
end if
end repeat
end tell
end notification activated
end using terms from
display dialog "How many actions do you want to build up before being notified?" default answer "1"
set actions to (text returned of result) as number
set newActions to 0
on idle
if ((seconds of (current date)) = 24) and ((minutes of (current date)) mod 10 = 3) then
set newActions to (newActions + 1)
set delayTime to 540
else
set delayTime to 0.5
end if
if newActions ≥ actions then
if newActions = 1 then
tell application "Notifications Scripting" to display notification "Fallen London" message "You have " & newActions & " new action!" sound name "Glass"
else
tell application "Notifications Scripting" to display notification "Fallen London" message "You have " & newActions & " new actions!" sound name "Glass"
end if
set newActions to 0
end if
return delayTime
end idle
I would not expect your idle implementation to work reliably. It is not a precision timing mechanism; therefore the following assumption is unsound:
if ((seconds of (current date)) = 24) and ((minutes of (current date)) mod 10 = 3) then
You're attempting to hit a 1-second window in a 10-minute loop here, and if you miss that window it'll be another 10 minutes till you get to try again.
A reliable way to do it is to store a date representing the time upon which to next trigger, then periodically check if the current date is now after that date and trigger if it does:
to nextTriggerDate() -- returns next xx:x3:23 date
set d to current date
set {d's minutes, d's seconds} to {((d's minutes) div 10 * 10) + 3, 23}
if d < (current date) then set d to d + 10 * minutes
d
end nextTriggerDate
property _triggerDate : nextTriggerDate()
on idle
if (current date) > _triggerDate then
set _triggerDate to nextTriggerDate()
-- DO STUFF HERE...
end if
return 1
end idle
Alternatively, you could use NSTimer via the AppleScript-ObjC bridge, which is designed specifically for this type of task, or set up a launchd script to run an AppleScript on the specified times if you don't want to be tied to a stay-open applet.
I think you have a few things working against you with your code.
First thing to note is that only the code within the idle handler will be called on each idle event. In other words, if you're expecting the main body of your script to run with each idle process, it will not.
try this as an example...
on run
display dialog "hello!" giving up after 3
end run
on idle
display dialog "Idle test!" giving up after 3
return 5
on idle
When you save the code above as a stay open script, you'll get one dialog that says "hello" then you'll get the "Idle test!" message several times, until you quit the script. Remember to save it as "Stay Open"
To fix this, if you expect all the code outside of the idle handler to run, create a custom function from it that you call from your idle handler.
on yourCustomFunction()
-- All the code you want to run prior when the idle function is called
end yourCustomFunction
on idle
yourCustomFunction()
-- any other additional code you want to run here
return 5
end idle
Another thing I'd like to point out. You don't need to tell application "Notifications Scripting", you can just display notification as shown below.
on idle
if ((seconds of (current date)) = 24) and ((minutes of (current date)) mod 10 = 3) then
set newActions to (newActions + 1)
set delayTime to 540
else
set delayTime to 0.5
end if
if newActions ≥ actions then
if newActions = 1 then
display notification "You have " & newActions & " new action!" with title "Fallen London" sound name "Glass"
else
display notification "You have " & newActions & " new actions!" with title "Fallen London" sound name "Glass"
end if
set newActions to 0
end if
return delayTime
end idle
Lastly, I would recommend adding an on run handler rather than just writing your code in the script without it.

Applescript to create set iCal events

I use iCal to kept track of my shifts, the event info is the same three standard shift types and I usually copy and paste them as there's no pattern.
I'm trying to work out if theres away using Applescript to speed it up. I'd like to input some dates and shift type have Applescript create the events.
I tried to see if I could adapt this for each shift type:
Reading iCal info from file to make iCal event
eg so I just had a list of dates but I couldn't even get the original to run with out getting an invalid date error.
Here's one way. Note I'm on Mountain Lion so the app is Calendar, not iCal... but the commands are the same if you're using iCal. Most likely your date error is because your dates have to be in applescript date format. Notice here that I take the start and end dates, which are initially in string format, and convert them to applescript dates before I add the event to Calendar.
set calendarName to "Home"
set theSummary to "Event Title"
set theDescrption to "The notes for the event"
set theLocation to "Karl's House"
set startDate to "July 4, 2013 6:30:00 PM"
set endDate to "July 5, 2013 1:00:00 AM"
set startDate to date startDate
set endDate to date endDate
tell application "Calendar"
tell (first calendar whose name is calendarName)
make new event at end of events with properties {summary:theSummary, start date:startDate, end date:endDate, description:theDescrption, location:theLocation}
end tell
end tell
You can create a date object with something like date "7/4/2013 6:00 PM", but the recognized formats depend on the region or date formats selected in System Preferences.
set input to "7/4 night
7/5 day"
set y to year of (current date)
set text item delimiters to " "
repeat with l in paragraphs of input
set d to text item 1 of l
set type to text item 2 of l
if type is "night" then
set sd to date (d & "/" & y & " 5:00 PM")
set ed to date (d & "/" & y & " 11:00 PM")
else if type is "day" then
set sd to date (d & "/" & y & " 9:00 AM")
set ed to date (d & "/" & y & " 5:00 PM")
end if
tell application "Calendar" to tell calendar "test"
make new event with properties {start date:sd, end date:ed, summary:"work"}
end tell
end repeat

Applescript to repeat complete script for files in a folder

I have managed to get all this code together now and just need the last step to work. Any help would be greatly appreciated.
I have setup this script to open an .xlsx file in a folder, change the date, save it then PDF to another folder. It then creates a mail by looking up the client code (found in the excel file) to subsequently look for this code in a Database.xlsx file and return the e-mail address of the client and add it to the "To" field in mail. It then attaches the newly created PDF to this mail and I can just click and send.
The script stops after the first .xlsx file has been opened, just so I can check the details is correct before it PDF's and creates the mail.
My question is: How do I get this process to repeat for each file in the initial folder? I have tried the repeat function, but to no avail.
Any help would be greatly appreciated.
Thank you.
--Complete script for updating invoice, saving (as PDF too in seperate folder) and e-mailing invoices
--Select the first file in a folder and then repeat for the next
set theFolder to POSIX path of (choose folder with prompt "Choose Folder containing .xlsx invoices")
set theFolderList to list folder theFolder without invisibles
repeat with x from 1 to count of theFolderList
set theFile to theFolder & item x of theFolderList
set theNewFile to theFolder & theFile
tell application "Microsoft Excel"
activate
open theFile
set ActiveClientCode to value of range ("B1")
end tell
--Change date of one cell to date of next month
tell application "Microsoft Excel"
activate
open "/Users/pienaar0/Documents/AdminAssist/" & ActiveClientCode & ".xlsx"
set d to value of cell ("A1")
set d to my MonthAdd(d)
set value of cell ("A1") to d
end tell
on MonthAdd(d)
set m to ((month of d as integer) + 1)
set ddd to day of d
if m > 12 then
set m to m - 12
set year of d to (year of d) + 1
end if
if {m} is in {4, 6, 9, 11} and ddd = 31 then --AppleScript treats "Apr 31" as May 1,
set day of d to 30
end if
set month of d to m
if m = 2 and month of d as integer = 3 then --AppleScript treats "Feb 31" as Mar 3,
set day of d to 1 -- Mar 1
set d to d - (1 * days) -- last day of Feb
end if
return d
end MonthAdd
property dialog_timeout : 36000
display dialog "Make sure the invoice is correct before clicking OK" buttons {"OK"} giving up after dialog_timeout
set the user_choice to the button returned of the result
--Save document and PDF
tell application "Microsoft Excel"
save active workbook
save active workbook in "Macintosh HD:Users:pienaar0:Documents:AdminAssistPDF:" & ActiveClientCode & ".pdf" as PDF file format
end tell
--Find e-mail address, and Name in Database (Check filepath and ranges)
tell application "Microsoft Excel"
open "Users/pienaar0/Documents/Database.xlsx"
set searchRange to range ("D2:D5")
set foundRange to find searchRange what ActiveClientCode with match case
set fRow to first row index of foundRange
set ClientEmail to value of range ("C" & fRow as text)
set ClientFirstname to value of range ("A" & fRow as text)
(* do something with the foundRange *)
end tell
--Create e-mail
tell application "Mail"
set theMessage to make new outgoing message with properties {visible:true, subject:"Your monthly invoice", content:"Dear " & ClientFirstname & ",
I trust this mail finds you well?
Please find attached your monthly invoice for your immediate consideration.
Regards,
AdminAssist
"}
set message signature of theMessage to signature "Replies & Forwards"
delay 1
tell content of theMessage
make new attachment with properties {file name:"/Users/pienaar0/Documents/AdminAssist/PDF/" & ActiveClientCode & " Sheet1.pdf"}
tell theMessage
make new to recipient at end of to recipients with properties {address:ClientEmail}
end tell
end tell
end tell
end repeat
You need to move your handler outside of the repeat block:
property dialog_timeout : 36000
--Complete script for updating invoice, saving (as PDF too in seperate folder) and e-mailing invoices
--Select the first file in a folder and then repeat for the next
set theFolder to POSIX path of (choose folder with prompt "Choose Folder containing .xlsx invoices")
tell application "System Events" to set theFolderList to name of every file of folder theFolder whose visible is true
repeat with x from 1 to count of theFolderList
set theFile to theFolder & item x of theFolderList
set theNewFile to theFolder & theFile
tell application "Microsoft Excel"
activate
open theFile
set ActiveClientCode to value of range ("B1")
end tell
--Change date of one cell to date of next month
tell application "Microsoft Excel"
activate
open "/Users/pienaar0/Documents/AdminAssist/" & ActiveClientCode & ".xlsx"
set d to value of cell ("A1")
set d to my MonthAdd(d)
set value of cell ("A1") to d
end tell
display dialog "Make sure the invoice is correct before clicking OK" buttons {"OK"} giving up after dialog_timeout
set the user_choice to the button returned of the result
--Save document and PDF
tell application "Microsoft Excel"
save active workbook
save active workbook in "Macintosh HD:Users:pienaar0:Documents:AdminAssistPDF:" & ActiveClientCode & ".pdf" as PDF file format
end tell
--Find e-mail address, and Name in Database (Check filepath and ranges)
tell application "Microsoft Excel"
open "Users/pienaar0/Documents/Database.xlsx"
set searchRange to range ("D2:D5")
set foundRange to find searchRange what ActiveClientCode with match case
set fRow to first row index of foundRange
set ClientEmail to value of range ("C" & fRow as text)
set ClientFirstname to value of range ("A" & fRow as text)
(* do something with the foundRange *)
end tell
--Create e-mail
tell application "Mail"
set theMessage to make new outgoing message with properties {visible:true, subject:"Your monthly invoice", content:"Dear " & ClientFirstname & ",
I trust this mail finds you well?
Please find attached your monthly invoice for your immediate consideration.
Regards,
AdminAssist
"}
set message signature of theMessage to signature "Replies & Forwards"
delay 1
tell content of theMessage
make new attachment with properties {file name:"/Users/pienaar0/Documents/AdminAssist/PDF/" & ActiveClientCode & " Sheet1.pdf"}
tell theMessage
make new to recipient at end of to recipients with properties {address:ClientEmail}
end tell
end tell
end tell
end repeat
on MonthAdd(d)
set m to ((month of d as integer) + 1)
set ddd to day of d
if m > 12 then
set m to m - 12
set year of d to (year of d) + 1
end if
if {m} is in {4, 6, 9, 11} and ddd = 31 then --AppleScript treats "Apr 31" as May 1,
set day of d to 30
end if
set month of d to m
if m = 2 and month of d as integer = 3 then --AppleScript treats "Feb 31" as Mar 3,
set day of d to 1 -- Mar 1
set d to d - (1 * days) -- last day of Feb
end if
return d
end MonthAdd

Resources