AppleScript repeat loop can't be re-executed without closing script - applescript

Playing with AppleScript I have found when you build a repeat to increment through a block if you cancel it you have to close the script to be able to start over:
property foobar : 0
tell application "BBEdit"
activate
select insertion point before first character of text document 1
repeat
## some magic
end repeat
end tell
Is there a way on cancel you can reset the property back to 0 in the script so that it can be rerun again? Also, when the repeat loop is ran and finished you still have to close the script to be able to rerun it, even after setting the foobar back to 0 with set foobar to 0. Research didn't show anything on Apple.se, SO, superuser or Apple discussion. How can you get the script to reset without having to close it?

You can do this, you will be prompted to restart or cancel the script.
property foobar : 0
tell application "BBEdit"
activate
repeat
set foobar to 0
select insertion point before first character of text document 1
repeat
## some magic
end repeat
display dialog "Restart Script" buttons {"Cancel", "Restart"} default button 2
end repeat
end tell

I'm confused on what you need the property property foobar : 0 for later in the script. If you just don't make it a property, it resets every time you run the script, so you don't have the problem... but I feel like I've got to be missing something.
I mean, what is that needs to be retained between runs such that you're making foobar an Applescript property, instead of just defining it as a variable?
set foobar to 0
Let me know what I'm missing here...

Related

how do you force apple script + aws vault to wait for mfa access

I have an apple script like this
#!/bin/zsh
tell application "iTerm"
activate
select first window
# Create new tab
tell current window
create tab with default profile
end tell
# Split pane
tell current session of current window
split vertically with default profile
split vertically with default profile
split vertically with default profile
end tell
# Exec commands
tell first session of current tab of current window
write text "aws-vault exec my-role -d 12h --no-session"
write text "start him"
end tell
tell second session of current tab of current window
write text "start her"
end tell
tell third session of current tab of current window
write text "start you"
end tell
tell fourth session of current tab of current window
write text "start me"
end tell
end tell
the problem is the script doesn't wait for me to fill in the mfa information from aws command. I've also tried aws-command; start him but that just exits and doesn't execute start him at all. Anyone run into this before?
I don't think this is really possible, because Apple Script has no way of knowing that the aws command requires mfa information and if you are done typing that information.
But there are 2 very hacky ways in which you could achieve this:
Using delay
This option is probably very unreliable, but it may do the job.
You can use the delay command to make AppleScript wait X seconds until it runs write text "start him". Lets say it takes you around 10 seconds to type out the mfa information, then you would use delay 10. Below is how the code would look like.
# more code above...
tell first session of current tab of current window
write text "aws-vault exec my-role -d 12h --no-session"
delay 10 # <-- change this value to your liking
write text "start him"
end tell
# more code below...
Using display dialog
I personally feel this may be the most reliable option for you. What you can do is have a dialog box open and once you have typed out the mfa information, click "Ok" so that the script resumes. So you'd have something like this:
# more code above...
tell first session of current tab of current window
write text "aws-vault exec my-role -d 12h --no-session"
display dialog "Click Ok once you are done "
write text "start him"
end tell
# more code below...
Just a small warning: I haven't tested the above code as I do not own a macOS computer.

Repeat in an if block?

I am trying to make a program that requires the person to select a file and am trying to confirm it. I ran into an issue when I tried to add a repeat in the if block. Is there any workaround for this because this is incredibly frustrating. Thanks in advance! :)
display dialog "Select the program"
tell application "Finder"
set filePath to POSIX path of (choose file)
end tell
display dialog "Are you sure this is the program that you have selected?"
buttons {"Yes", "No"}
if the button returned is "No" then
end repeat
else
Even though this may lead to my death, I'll answer. Study this:
set correctChoice to false
repeat until correctChoice is true -- "is true" is actually unnecessary
--I took this next line out because it's unnecessary - you can put this text in the prompt of the choose file, below
-- display dialog "Select the program"
-- this doesn't need to be (and shouldn't be) in a Finder tell block, so I took that out, too:
set filePath to POSIX path of (choose file with prompt "Select the program")
set myQuery to display dialog "Are you sure this is the program that you have selected?" buttons {"Yes", "No"}
if the button returned of myQuery is "No" then
--there is no repeat loop! Where do you want it? I assume you want the repeat outside of this process
--end repeat
else
set correctChoice to true
end if
end repeat
--maybe do other stuff
Doing what I assume you were attempting means putting the whole thing inside a repeat loop, which stops when a boolean variable is set to true. The if/then either keeps the original false value of the boolean, or sets it to true, thus allowing us to leave the repeat loop.
A "workaround" is a term for something needed to work within limitation or bug in language. You didn't need a workaround - you need to get your code right. Start simple (!!) and learn how various blocks work before you try to force the code to do what you think it should do.

Applescript to check App Store

Thanks for taking the time to read my question.
It's pretty simple, but i am a complete noobie to this, so am having some trouble.
Is it possible to have an applescript that will check the mac app store for updates, and if there are, output the number of updates to someplace?
A good example of this is (if you are aware of it) the geeklets that check for unread mail, and then outputs it to the desktop.
EDIT:
I downloaded a geeklet for the unread mail (as referenced above), and using that as a starting point, I tried to write my own script.
set run_bool to 1
tell application "System Events"
set run_bool to count (every process whose name is "App Store")
end tell
if run_bool is 1 then
tell application "App Store"
set update_count to 0
set output_string to ""
repeat with upd in Apps in Updates
if upd's download is not true then
set update_count to update_count + 1
end if
end repeat
if update_count is 0 then
set output_string to "zero"
else if update_count is 1 then
set output_string to "one"
else
set output_string to "two"
end if
end tell
else
set output_string to "not running"
end if
return output_string
now this is not my final code, but simply to check to see if it will work and what the output would be.
On compilation I get an error saying
error "The variable Updates is not defined." number -2753 from "Updates"
as well as
Syntax Error
Expected end of line but found unknown token
Also, when I stopped compilation, this appeared below the last line in my code
tell application "GeekTool Helper"
activate
«event ascrgsdf»
Any help is appreciated.
#foo is pretty right on with his idea. This code only requires one line. In the second line, I used display notification, but you substitute it with you preferred method to pass on the value.
tell application "System Events" to tell (first application process whose ¬
frontmost is true) to set returnValue to title of ((first menu item whose title ¬
begins with "App Store") of menu "Apple" of menu bar 1)
display notification returnValue
Result:
"App Store…, 1 update"
menu bar items are accessible everywhere (e.g. windowed/numeral desktop mode, fullscreen mode, dock hidden/disabled).
Make sure accessibility is enabled for Script Editor, or whichever app you use to invoke the script, to gain access to the UI.
There is just one weird thing: if I had used begins with "App Store..." instead of begins with "App Store", the code would be a dud. I don't know why - it might has to do with escaped characters and the .... Anyone who knows please enlighten me with a comment.
As for your code, I can tell from AppleScript Dictionary that Updates is not a property of App Store.app. Nor is any other categories in the UI. To get to the Dictionary, open Script Editor and press CMD+SHIFT+O
In addition, if you want to use return statement, you need an explicit handler. In other words, you need to wrap the code between on run and end run.

AppleScript ASObjC Runner Not Displaying Progress Of Shell Script

Ok, so I have the progress bar made, using ASObjC Runner, but it doesn't show the progress of the shell script, and also doesn't hide the progress bar after the shell script completes. Anyone know why?
Here is the code now:
display alert "You may have to restart your computer after using this tool!" buttons {"Ok"} default button 1
set question to display dialog "RMR (Remove My Redirect)
Are you unable to go to a website at home because of that annoying St. Bernard Redirect?
If the answer is Yes, then RMR is your solution! Simply Choose Remove to remove it, and Replace to put it back." buttons {"Remove", "Replace", "Erase Evidence"} default button 3
set answer to button returned of question
if answer is equal to "Remove" then do shell script "mv /Library/LaunchDaemons/com.stbernard.rfcd.plist ~/"
if answer is equal to "Replace" then do shell script "mv ~/com.stbernard.rfcd.plist /Library/LaunchDaemons/"
if answer is equal to "Erase Evidence" then set question to display dialog "Are you sure? RMR will be deleted forever." buttons {"Yes", "No"} default button 2
set answer to button returned of question
if answer is equal to "No" then do shell script "echo"
if answer is equal to "Yes" then ¬
tell application "ASObjC Runner"
reset progress
set properties of progress window to {button title:"Cancel", button visible:true, message:"Removing...", detail:"Please be patient", indeterminate:false, max value:100, current value:0}
activate
show progress
end tell
repeat with i from 1 to 100
do shell script "srm -rf ~/Downloads/RMR.app; history -c; killall Terminal"
tell application "ASObjC Runner"
activate
set properties of progress window to {detail:"Progress: " & i, current value:i}
if button was pressed of progress window then
exit repeat
end if
end tell
end repeat
tell application "ASObjC Runner" to hide progress
Thanks in advance!
Also, here is a link to the app in case you need it: RMR
Two thoughts: 1. There for sure are issues with do shell script being synchronous/asynchronous. Since you hand out the work load, not sure what the pb does with that. 2. Start off by stripping out the guts of your script, leaving just the flow, the dialogs and the if clauses. Replace all the stuff (do shell scripts, etc) with delay statements, in order to first test your pb.
However, you're looking for |answer| being set to "Yes", but it will never be set to "Yes" in your script. That's not an option in the dialog box.??? You need to reduce and test parts of your script bit by bit.
I would also avoid using that helper app, which may be part of your problem. You can do a progress bar without it, as you can see in the answer to your previous question: stackoverflow.com/questions/27517042/…
– jweaks

Select a particular tab in terminal depending upon the content using applescript and best practices

This is an application specific problem. I am trying to find and select a tab in Terminal.app depending on contents within. Here is what I'm doing:
tell application "Terminal"
set foundTabs to (every tab of every window) whose contents contains "selectme"
repeat with possibleTab in foundTabs
try
set selected of possibleTab to true
end try
end repeat
end tell
This isn't acting as expected and is pretty foolproof. I wonder if someone can suggest a way to do this with much less code (for instance, the looping shouldn't really be necessary, but applescript is an elusive language).
Thanks
Thing is, the following Applescript will do what you want, but unless your "selectme" string is very unique, you will find it in many tabs.
But anyway, here you go:
tell application "Terminal"
set allWindows to number of windows
repeat with i from 1 to allWindows
set allTabs to number of tabs of window i
repeat with j from 1 to allTabs
if contents of tab j of window i contains "selectme" then
set frontmost of window i to true
set selected of tab j of window i to true
end if
end repeat
end repeat
end tell

Resources