Capturing An AppleEvent in Applescript - macos

Ok Unity3d allows you to set your external script editor in the application preferences. So I want to use applescript to launch my own editor. This applescript has worked pretty well for me so far but I have been unable to jump to the line number.
According to Unity the "line number should be sent through a parameter in an AppleEvent. It should be of typeChar and of keyAEPosition ('kpos') The structure sent through this parameter has the following layout:"
struct TheSelectionRange
{
short unused1; // 0 (not used)
short lineNum; // line to select (<0 to specify range)
long startRange; // start of selection range (if line < 0)
long endRange; // end of selection range (if line < 0)
long unused2; // 0 (not used)
long theDate; // modification date/time
};
"lineNum should be populated with the correct line. The other fields will not be populated with anything than 0 and -1."
So how come I don't see any of this coming through my input? how do I capture this apple event?
My Script:
on run input
set element to item 1 of input
if (element is in {{}, {""}, ""}) then
return
else
tell application "System Events"
set ProcessList to name of every process
if "iTerm" is in ProcessList then
set iterm_running to true
else
set iterm_running to false
end if
log iterm_running
end tell
tell application "iTerm"
activate
if (count terminal) < 1 then
set term to (make new terminal)
else
set term to current terminal
end if
tell term
set create_session to false
try
do shell script ("/usr/local/bin/vim --servername UNITY --remote-send ''")
set create_session to false
on error errorMessage number errorNumber
set create_session to true
end try
if iterm_running then
if create_session then
launch session "Default Session"
activate current session
tell current session
set name to "Unity"
write text "/usr/local/bin/vim --servername UNITY --remote-silent \"$(echo \"/Volumes/" & input & "\" | tr : /)\""
end tell
else
do shell script ("/usr/local/bin/vim --servername UNITY --remote-silent \"$(echo \"/Volumes/" & input & "\" | tr : /)\"")
end if
else
activate current session
tell current session
set name to "Unity"
write text "/usr/local/bin/vim --servername UNITY --remote-silent \"$(echo \"/Volumes/" & input & "\" | tr : /)\""
end tell
end if
end tell
end tell
end if
return input
end run

If you handle the open event, you should see some parameters, including the line number:
on open (x,y)
display dialog x
display dialog y
-- use x and y in your own script
end open

Related

Automator + Applescript - An error “Can’t make "f" into type alias.” - text replacement

So I established to replace a specific text inside a text file using variables, but the problem is when it comes to the second variable/ another text it simply shows me this message: “Can’t make "f" into type alias.”
I don’t know what’s wrong with the code… when I’m using it for the first variable it simply works, how Can I fix it?
Thay’s how the code looks like and just simply does the job with the first variable
“use framework "Foundation"
use AppleScript version "2.4"
use scripting additions
property NSString : a reference to current application's NSString
on run {input, parameter}
set stringToFind to (item 1 of input) as text
set stringToReplace to (item 2 of input) as text
set theTextFile to (item 3 of input)
set theContent to read (theTextFile as alias) as text
set newContent to my replace_text(theContent, stringToFind, stringToReplace)
try
set fileRef to (open for access theTextFile with write permission)
set eof of fileRef to 0 # truncate file
write newContent to fileRef
close access fileRef
on error
close access fileRef
end try
# display dialog (item 1 of input) & return & (item 2 of input) & return & (item 3 of input)
return
end run
on replace_text(atext, xfind, xreplace)
return ((NSString's stringWithString:atext)'s stringByReplacingOccurrencesOfString:xfind withString:xreplace) as text
end replace_text”
But when I’m trying to use it for the second time in the same automator workflow it just gives me this message…
“Can’t make "f" into type alias.”
“F” - I typed as a variable that replaces the old text…
enter image description here
enter image description here
enter image description here
enter image description here

'starts with" not working when checking a 'localhost' url

I'm writing a handler that will focus on a Safari tab when the window name starts with a substring. Why is this script not working? I've verified the text and it returns true when I isolate the strings (e.g. "localhost:8080..." starts with "localhost" -- #> true.
log focusTabStartingWithName("localhost")
to focusTabStartingWithName(theNameStarting as text)
tell application "Safari"
set found to false
repeat with nextWindow in every window
set tabList to every tab of nextWindow
try
repeat with nextTab in tabList
set tabName to (name of nextTab) as text
log "[" & tabName & "]:" & theNameStarting & ":" & (tabName starts with theNameStarting)
-- #> localhost:8080/somewebapp:localhost:false INCORRECT!!!
set found to tabName starts with theNameStarting
if found then
tell nextWindow
set current tab to nextTab
set visible to true
end tell
exit repeat
end if
end repeat
on error
log "Error encountered getting the next tab in the list"
end try
if found then exit repeat
end repeat
end tell
return found
end focusTabStartingWithName
Change line 1 to:
log focusTabStartingWithName("http://10.")
Change line 9 to:
set tabName to (URL of nextTab) as text
At your leisure, you can change some of your variable names to more appropriate ones but the above should work as long as the localhost IP begins with '10.'.

How do I pause and resume an AppleScript without a dialog box?

I am working to outline a workflow in AppleScript. The script takes the next task I need to do from Omnifocus and requires me to determine if I can do it in 2 minutes or less. If I can, it starts a timer and I want it to wait until I actually do the task. Right now I have a dialog box pop up and I can mark the task complete when I am done with it. Unfortunately, some of the tasks I need to do are in Omnifocus and I can't do anything in Omnifocus with the dialog box open.
I would like to avoid using the dialog box so I can work in Omnifocus while the script is running. I'd like to be able to tell the script I'm done so it can stop the timer, tell me how long it took to do the task and then go on to mark the task complete in Omnifocus. I initially thought the best way to do this would be by entering a key combination. After a bit of research, I don't think I can do this in AppleScript. I am open to any idea of how to allow me to work in the middle of my script and then tell the program I am done with the task.
Here's my code:
on run {}
with timeout of (30 * 60) seconds
tell application "OmniFocus"
activate
end tell
tell application "OmniFocus"
tell default document to tell front document window
set perspective name to "Daily Wrap-Up"
tell content to set TreeList to (value of first leaf)
repeat with ListItem in TreeList
set ProjectName to name of containing project of ListItem as text
set TaskName to " - " & name of ListItem
set NoteName to " - " & note of ListItem
display dialog "The task is:" & return & ProjectName & TaskName & NoteName & return & "Can you do this in 2 minutes or less?" buttons {"Yes", "No"} default button "Yes"
set Button_Returned to button returned of result
if Button_Returned = "Yes" then
say "Get to work!"
set T1 to minutes of (current date)
set T1s to seconds of (current date)
display dialog "Click when done." buttons {"Complete", "Cancel"} default button "Complete"
set Button_Returned to button returned of result
if Button_Returned = "Complete" then
set T2 to minutes of (current date)
set T2s to seconds of (current date)
set TT_ to ((T2 * 60) + T2s) - ((T1 * 60) + T1s)
say "that took you" & TT_ & "seconds to complete"
display dialog ProjectName & TaskName & NoteName buttons {"Complete", "Defer", "Cancel"} default button "Complete"
set Button_Returned to button returned of result
if Button_Returned = "Complete" then
mark complete ListItem
tell application "OmniFocus"
compact default document
end tell
else if Button_Returned = "Defer" then
display dialog "Defer for how long (in minutes)?" default answer "60"
set TimeAdd to text returned of result
set defer date of ListItem to ((current date) + (TimeAdd * minutes))
tell application "OmniFocus"
compact default document
end tell
else if Button_Returned = "Cancel" then
tell application "OmniFocus"
compact default document
end tell
else if Button_Returned = "No" then
tell application "OmniFocus"
compact default document
end tell
end if
else if Button_Returned = "No" then
display dialog "Breakdown task."
set perspective name to "Projects"
end if
end if
end repeat
end tell
end tell
end timeout
end run
Thanks in advance for any help.
I don't have OmniFocus on my machine, so I can't properly compile this much less test it, but in vanilla AppleScript you can do something like the following:
global start_time, end_time, TreeList, current_task_index, TaskName, NoteName
on run
tell application "OmniFocus"
tell default document to tell front document window
set perspective name to "Daily Wrap-Up"
tell content to set TreeList to (value of first leaf)
end
end
set current_task_index to 1
beginTask()
end
on reopen
-- inserted try block to aid debugging
try
set end_time to (current date)
set elapsed_time to end_time -start_time
say "that took you " & elapsed_time & " seconds to complete"
display dialog ProjectName & TaskName & NoteName buttons {"Complete", "Defer", "Cancel"} default button "Complete"
set Button_Returned to button returned of result
if Button_Returned = "Complete" then
mark complete ListItem
tell application "OmniFocus"
compact default document
end tell
else if Button_Returned = "Defer" then
display dialog "Defer for how long (in minutes)?" default answer "60"
set TimeAdd to text returned of result
set defer date of ListItem to ((current date) + (TimeAdd * minutes))
tell application "OmniFocus"
compact default document
end tell
else if Button_Returned = "Cancel" then
tell application "OmniFocus"
compact default document
end tell
else if Button_Returned = "No" then
tell application "OmniFocus"
compact default document
end tell
end if
else if Button_Returned = "No" then
display dialog "Breakdown task."
set perspective name to "Projects"
end if
set current_task_index to current_task_index + 1
if current_task_index <= count of TreeList then
beginTask()
else
quit
end
on error errstr number errnum
display alert "Error " & errnum & ": " & errstr
end try
end
on idle
(*
you can use this handler if you want the app to give you a countdown, or
announce a time limit, or anything that needs doing while you're working on the task
*)
end
on beginTask()
tell application "OmniFocus"
tell default document to tell front document window
set perspective name to "Daily Wrap-Up"
set ListItem to item current_task_index of TreeList
set ProjectName to name of containing project of ListItem as text
set TaskName to " - " & name of ListItem
set NoteName to " - " & note of ListItem
display dialog "The task is:" & return & ProjectName & TaskName & NoteName & return & "Can you do this in 2 minutes or less?" buttons {"Yes", "No"} default button "Yes"
set Button_Returned to button returned of result
if Button_Returned = "Yes" then
say "Get to work!"
set start_time to (current date)
end if
end tell
end tell
end
Copy this into the script editor, debug it, and save it as an application with the 'Stay open after run handler' checkbox checked. Operation is as follows:
When OmniFocus is ready, run this script application. It will prompt you to begin the first task.
When you have finished the first task, double-click the script application icon again to invoke the reopen handler. The script will present you with the elapsed time for the first task, give you the choices you outlined, and then prompt you to begin the second task.
After the last task is complete, the script will automatically quit.
The global variable at the beginning allow necessary data to be passed between handlers as the script progresses.
If you want something more complex — e.g., a floating window or menu bar item that gives you more fine-grained control — then you'll need to start using ASOC to build that up. But that's fine-tuning; this should give you a general structure.

Mysterious AppleScript error: "4.294967323E+9Mahabalipuram" doesn’t understand the “write” message

A user of a script of mine which communicates via AppleScript with iPhoto is getting this error, which I can't reproduce: 918:955: execution error: iPhoto got an error: "4.294967323E+9Mahabalipuram" doesn’t understand the “write” message. (-1708)
The AppleScript that produces the error is:
set nul to character id 0
set text item delimiters to nul
set albumsFile to "/Users/[user]/Downloads/blah.blah"
set fp to open for access (POSIX file albumsFile) with write permission
tell application "iPhoto"
repeat with anAlbum in albums
if anAlbum's type is regular album then
set albumName to anAlbum's name
if albumName is not "Last Import" then
set albumPhotoIds to (id of every photo of anAlbum) as Unicode text
if length of albumPhotoIds is greater than 0 then
set currentAlbum to anAlbum
repeat while currentAlbum's parent exists
set currentAlbum to currentAlbum's parent
set albumName to currentAlbum's name & " > " & albumName
end repeat
set albumId to anAlbum's id
set albumData to {"", albumId, albumName, ""} as Unicode text
write albumData to fp as Unicode text
write albumPhotoIds to fp as Unicode text
write nul to fp as Unicode text
end if
end if
end if
end repeat
end tell
close access fp
Does anyone have any ideas as to what is going wrong here? There's a bit more background in this Github issue: https://github.com/jawj/iphoto-flickr/issues/7
This may work (untested); it comes up typically with this kind of error. But, as adayzone points out, it is probably best to re-structure the script.
tell me to write albumData to fp as Unicode text
tell me to write albumPhotoIds to fp as Unicode text
tell me to write nul to fp as Unicode text
It's also good to illustrate how tell works (and sometimes "gets in the way")
Write is from StandardAdditions, not iPhoto, so you can't tell iPhoto to write. It would be something along the lines of:
property nul : character id 0
set text item delimiters to nul
set albumsFile to (path to downloads folder as text) & "blah.txt"
tell application "iPhoto"
repeat with anAlbum in albums
if anAlbum's type is regular album then
set albumName to anAlbum's name
if albumName is not "Last Import" then
set albumPhotoIds to (id of every photo of anAlbum)
if length of albumPhotoIds is greater than 0 then
set currentAlbum to anAlbum
repeat while currentAlbum's parent exists
set currentAlbum to currentAlbum's parent
set albumName to currentAlbum's name & " > " & albumName
end repeat
set albumId to anAlbum's id
set albumData to {"", albumId, albumName, ""} as Unicode text
my writeIt(albumsFile, albumData, albumPhotoIds)
end if
end if
end if
end repeat
end tell
on writeIt(albums_File, album_Data, album_PhotoIds)
try
set fp to open for access albums_File with write permission
write album_Data to fp
write album_PhotoIds to fp
write nul to fp
close access fp
on error
try
close access fp
end try
end try
end writeIt

Look for file names that match a rule with Applescript

A client has a massive WordPress uploads folder with 7 or 8 size versions of each file.
I'm looking to filter out all images that have -NNNxNNN as part of the file name - "NNN" being any number. For eg:
Originally uploaded file: 7Metropolis711.jpg
Example resized version of same file: 7Metropolis711-792x373.jpg
I'm using Automator for this, and I'm just looking for the Applescript to filter out those files from the inputted folder of files.. IE:
Here is another approach:
on run {input}
set newList to {}
repeat with aFile in input
tell application "System Events" to set fileName to name of aFile
try
set variableName to do shell script "echo " & quoted form of fileName & " | grep -Eo [0-9]{3}x[0-9]{3}"
on error
set end of newList to (aFile's contents)
end try
end repeat
return newList
end run
Try this. You can see a handler "isFormatNNNxNNN(fileName)" which tests the file name for your format. Obviously remove the first 2 lines of the code. They're used so I could test this in AppleScript Editor. They should equal your input variable in Automator.
EDIT: based on your comments I modified the script to account for more than one "-" in the file name. Now I start looking at the text in front of the file extension since I assume your format is the last characters in the file name.
It didn't work in Automator because you have to put "on run {input, parameters}" around the code. I have done that now so just copy/paste this into automator.
on run {input, parameters}
set newList to {}
repeat with aFile in input
if not (my isFormatNNNxNNN(aFile)) then set end of newList to (contents of aFile)
end repeat
return newList
end run
on isFormatNNNxNNN(theFile)
set theBool to false
try
tell application "System Events"
set fileName to name of theFile
set fileExt to name extension of theFile
end tell
set endIndex to (count of fileExt) + 2
set nameText to text -(endIndex + 7) thru -endIndex of fileName
if nameText starts with "-" then
if character 5 of nameText is "x" then
-- test for numbers
text 2 thru 4 of nameText as number
text 6 thru 8 of nameText as number
set theBool to true
end if
end if
end try
return theBool
end isFormatNNNxNNN

Resources