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

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.'.

Related

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

Capturing An AppleEvent in Applescript

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

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

a file is copied to a specific folder and renamed to x.txt how do i open x.txt and paste "X:"

EDIT: regulus6633 has made a script that's a lot better than my outline below, it works perfectly IF you're template file isn't completely empty (I think this caused an error originally). Thanks!
This script is supposed to (1) copy a x.txt to a specific folder rename it to new_name, (2) open it, (3) paste "new_name" in all caps, and (4) insert ":" followed by return & return. The first part is working, but I'm having trouble figuring out (2), (3) and (4). The code I've written so far is pasted below.
tell application "Finder"
display dialog "new_name_dialogue" default answer " "
set new_name to (text returned of result)
set Selected_Finder_Item to (folder of the front window) as text
duplicate file "Q:x:7:n7:GTD scripting:template folder:x.txt" to "Q:X:7:SI:SIAG1"
set Path_Of_X to "Q:X:7:SI:SIAG1:" & "x.txt" as string
set name of file Path_Of_X to (new_name as text) & ".txt"
#[something that let's me open the file is needed here]
#[something that pastes "new_name" & ":" in ALL CAPS]
#[something that inserts two lineshifts]
end tell
In general since you're dealing with a txt file, you do not need to "open" the file in an application and paste in text. We can read and write to text files directly from applescript. As such we read in the text from the template file, add whatever text we want to that, and then write the new text to a new file. If you then want to open and view the new file you can do that after. I did that in the "TextEdit" section of the code.
You can see at the end of the script I have subroutines to write a text file and also to change the file name to CAPS. So try the following...
-- initial variables
set templateFile to "Q:x:7:n7:GTD scripting:template folder:x.txt"
set copyFolder to "Q:X:7:SI:SIAG1:" -- notice this path ends in ":" because it's a folder
-- get the new name
display dialog "new_name_dialogue" default answer ""
set newName to (text returned of result)
set newPath to copyFolder & newName
-- get the text of the template file
set templateText to read file templateFile
-- add the file name in CAPS, a colon, and 2 returns at the beginning of templateText
set capsName to upperCase(newName)
set newText to capsName & ":" & return & return & templateText
-- write the newText to newPath
writeTo(newPath, newText, text, false)
-- open the new file in textedit
tell application "TextEdit" to open file newPath
(*============== SUBROUTINES ==============*)
on writeTo(targetFile, theData, dataType, apendData)
-- targetFile is the path to the file you want to write
-- theData is the data you want in the file.
-- dataType is the data type of theData and it can be text, list, record etc.
-- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
try
set targetFile to targetFile as text
if targetFile does not contain ":" then set targetFile to POSIX file targetFile as text
set openFile to open for access file targetFile with write permission
if apendData is false then set eof of openFile to 0
write theData to openFile starting at eof as dataType
close access openFile
return true
on error
try
close access file targetFile
end try
return false
end try
end writeTo
on upperCase(theText)
set chrIDs to id of theText
set a to {}
repeat with i from 1 to (count of chrIDs)
set chrID to item i of chrIDs
if chrID ≥ 97 and chrID ≤ 122 then set chrID to (chrID - 32)
set end of a to chrID
end repeat
return string id a
end upperCase
something that lets me open the file is needed here
tell application "TextEdit" to open Path_Of_X
something that pastes new_name in ALL CAPS
There is a really good third party scripting addition (Satimage OSAX) that you can use for things just like this (this will only work if you've downloaded the scripting addition)...
set UPPER_CASE to uppercase new_name & ":"
something that inserts two lineshifts
return & return

Resources