I want to download different apps with a bash script on macOS.
As there are some larger downloads (e.g. Office 365) I would like to include a progress bar in a regular macOS Window.
The applications download+install script looks like this
cd ~/Downloads/ && { curl -O https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg ; cd -; }
sudo hdiutil attach ~/Downloads/googlechrome.dmg
sudo cp -r /Volumes/Google\ Chrome/Google\ Chrome.app /Applications/
diskutil unmount Google\ Chrome
But this does not show any progress for the user (script will run in background).
I found the following example and edited it a bit to my likings
chromedl() {
osascript <<AppleScript
set progress description to "Loading"
set progress additional description to "Please wait"
set progress total steps to 3
repeat with i from 1 to 4
set theSourceCode to do shell script "curl -L -m 30 seconds [url=https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg]https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg]"
set progress completed steps to i
end repeat
display dialog "Progress bar is complete."
AppleScript
But this creates a curl execution error.
Please help me with a functioning Curl Download + Progress Bar script
A basic progress spinner window is easy enough to create using AppleScriptObjectiveC. Copy the following into Script Editor and run it in the foreground (command-control-R, or use the menu command Script→Run in Foreground, which appears when you hold down the control key).
use framework "AppKit"
use AppleScript version "2.4" -- Yosemite 10.10 or later required
use scripting additions
-- convenience properties to make ASOC more readable
property ca : current application
property NSPanel : class "NSPanel"
property NSView : class "NSView"
property NSProgressIndicator : class "NSProgressIndicator"
property NSTextField : class "NSTextField"
property HUD_mask : 8192
property nonactivating_mask : 128
global progress_panel, progress_indicator, label_field
make_progress_panel()
progress_indicator's startAnimation:me
progress_panel's orderFront:me
-- just hang it out there for 5 seconds as proof of concept
delay 5
progress_panel's |close|()
on make_progress_panel()
-- make floating panel
set content_rect to ca's NSMakeRect(200, 800, 140, 80)
set progress_panel to NSPanel's alloc's initWithContentRect:content_rect styleMask:(HUD_mask + nonactivating_mask) backing:(ca's NSBackingStoreBuffered) defer:true
set progress_panel's floatingPanel to true
-- make progress indicator
set progress_rect to ca's NSMakeRect(0, 0, 40, 40)
set progress_indicator to NSProgressIndicator's alloc's initWithFrame:progress_rect
set progress_indicator's indeterminate to true
set progress_indicator's |style| to 1
set progress_indicator's translatesAutoresizingMaskIntoConstraints to false
--make text field
set label_field to NSTextField's labelWithString:"Downloading"
set label_field's translatesAutoresizingMaskIntoConstraints to false
-- make container view, and add subviews
set content_view to NSView's alloc's initWithFrame:content_rect
content_view's addSubview:label_field
content_view's addSubview:progress_indicator
progress_indicator's sizeToFit()
set progress_panel's contentView to content_view
-- view constraints, for alignment
set pi_y_centering to progress_indicator's centerYAnchor's constraintEqualToAnchor:(content_view's centerYAnchor)
set lf_y_centering to label_field's centerYAnchor's constraintEqualToAnchor:(content_view's centerYAnchor)
pi_y_centering's setActive:true
lf_y_centering's setActive:true
set lf_left_margin to content_view's leadingAnchor's constraintEqualToAnchor:(label_field's leadingAnchor) |constant|:-10
lf_left_margin's setActive:true
set pi_left_margin to label_field's trailingAnchor's constraintEqualToAnchor:(progress_indicator's leadingAnchor) |constant|:-10
pi_left_margin's setActive:true
set pi_right_margin to progress_indicator's trailingAnchor's constraintGreaterThanOrEqualToAnchor:(content_view's trailingAnchor) |constant|:10
pi_left_margin's setActive:true
end make_progress_panel
The simplest way to make this work with curl, I think, is to detach the curl process entirely and recover its pid, like so (the code at the end detaches the process and sends the output to oblivion, then returns the pid):
set curl_pid to do shell script "curl -L [url=...] &> /dev/null & echo $!"
Once you have the pid you can set up a loop (or an idle handler, if you create an app) and periodically check to see if the process is still active:
try
set b to do shell script "pgrep curl | grep " & curl_pid
on error
progress_indicator's stopAnimation:me
progress_panel's |close|()
end try
If you want a determinate progress bar, that's easy enough to manage, but you have to figure out a way to measure progress. This link suggests you can get the headers for a file first and extract the file size; you could compare that against the actual on-disk file size as the download progresses, and feed the ratio into the progress bar.
Related
I keep getting an error when I try to run this as part of a much bigger script. Doesn't like "to the folders". Only thing that changed on my end was an update to the MAC OS operating system (currently on Big Sur 11.6.5).
tell application "Finder" to set myFolders to the folders of theDestinationFolder
set folderCount to count myFolders
set loggingCounter to 0
repeat with aFolder in myFolders
set progress description to "Processing folder " & (loggingCounter + 1) & " of " & folderCount
set progress additional description to ""
set progress total steps to folderCount
set progress completed steps to loggingCounter
organizeSubfolder(aFolder)
set loggingCounter to loggingCounter + 1
end repeat
So im trying to use shellscript "afplay " in applescript to play an .m4a file I bundled into the app resource. Not entirely sure how it works.
Got this after a bit of searching around,
set soundPath to POSIX path of (path to resource "Sound File.aiff")
do shell script "afplay " & quoted form of soundPath
This isnt really what I want.
playAudio() -- place this Line To call the handler to Play An Audio File.
on playAudio()
set audioFile to path to resource "Sound File.aiff"
set theFile to POSIX path of audioFile
do shell script "afplay -q 1 -t 25 " & " " & quoted form of theFile
end playAudio
-- Command Line OPTIONS For Playing Audio Files
(*
afplay [option...] audio_file
Options: (may appear before or after arguments)
{-v | --volume} VOLUME
set the volume for playback of the file
{-h | --help}
print help
{ --leaks}
run leaks analysis
{-t | --time} TIME
play for TIME seconds
{-r | --rate} RATE
play at playback rate
{-q | --rQuality} QUALITY
set the quality used for rate-scaled playback (default is 0 - low quality, 1 - high quality)
{-d | --debug}
debug print output
*)
I am trying to support this legacy application where we use wise installer to create our application installer. I can see that script will take parameters.
What I want is that when user run installer, the install dialog should have values pre-filled. For this I did some research and found that I can put those parameters in a file and then call installer with a tag and parameters file name.
Here is syntax that I tired
MyAppSetup.exe /M="C:\USERS\User1\DOCUMENTS\MyAppSetup.txt"
where MyAppSetup.txt has parameter names and it values. MyAppSetup.txt contents is as below
COMPANY="ABC"
SERIALNUMBER="123"
...
...
Now installer runs correctly, but values are not prefilled.
But if I run the installer in silent mode, it dose uses the parameters correctly.
Here is syntax to run the same script in silent mode.
MyAppSetup.exe /S /M="C:\USERS\User1\DOCUMENTS\MyAppSetup.txt"
I would really appreciate if someone can guide me on how to call installer visually and have values prefilled.
Here are some useful links that I found
What are the command line parameters available for WiseScript?
Wise Setup.exe Switches
Use a .ini file, then the installer will read those values and populate the dialog quite nicely. Here's an example of a C:\MyApp\MyAppSettings.ini:
[settings]
COMPANY=ABC
SERIALNUMBER=123
...and a .wse that will populate a dialog:
item: Set Variable
Variable=MAINDIR
Value=C:\MyApp
end
item: Set Variable
Variable=COMPANY
end
item: Set Variable
Variable=SERIAL
end
item: Read INI Value
Variable=COMPANY
Pathname=%MAINDIR%\MyAppSettings.ini
Section=settings
Item=COMPANY
end
item: Read INI Value
Variable=SERIAL
Pathname=%MAINDIR%\MyAppSettings.ini
Section=settings
Item=SERIALNUMBER
end
item: Custom Dialog Set
Name=My App Settings
item: Dialog
Title=My App Settings
Width=290
Height=238
Font Name=Helv
Font Size=8
item: Static
Rectangle=5 5 105 20
Enabled Color=00000000000000001111111111111111
Create Flags=01010000000000000000000000000000
Text=Company Name
end
item: Editbox
Rectangle=114 7 230 22
Help Context=16711681
Enabled Color=00000000000000001111111111111111
Create Flags=01010000100000010000000000000000
Text=%COMPANY%
end
item: Static
Rectangle=5 25 105 40
Enabled Color=00000000000000001111111111111111
Create Flags=01010000000000000000000000000000
Text=Serial Number
end
item: Editbox
Rectangle=114 26 230 41
Help Context=16711681
Enabled Color=00000000000000001111111111111111
Create Flags=01010000100000010000000000000000
Text=%SERIAL%
end
item: Push Button
Rectangle=182 145 217 160
Enabled Color=00000000000000001111111111111111
Create Flags=01010000000000010000000000000000
Text=&Next
end
end
end
Iam building the .dmg file using ant script, inturn it uses applescript will peovide below.
Below is the error iam getting.
installer.mac:
[mkdir] Created dir: /Users/damuammu/Desktop/spark-Mac/target/installer
[mkdir] Created dir:
/Users/damuammu/Desktop/spark-Mac/target/MixTalx_app/.background
[copy] Copying 1 file to
/Users/damuammu/Desktop/spark-Mac/target/MixTalx_app/.background
[symlink] ln -s /Applications
/Users/damuammu/Desktop/spark-Mac/target/MixTalx_app/Applications
[echo] Create tmp.dmg
[exec] created: /Users/damuammu/Desktop/spark-Mac/target/tmp.dmg
[echo] Attach tmp.dmg
[exec] /dev/disk2 Apple_partition_scheme
[exec] /dev/disk2s1 Apple_partition_map
[exec] /dev/disk2s2 Apple_HFS
/Users/damuammu/Desktop/spark-Mac/target/tmp
[exec] cp:
/Users/damuammu/Desktop/spark-Mac/build/installer/mac/RightDSStore: No
such file or directory
[exec] Result: 1
[exec] mac/dmg_spark.scpt: execution error: Finder got an error:
Can’t set item "Spark.app" of disk "MixTalx_2.6.3" to {140, 250}.
(-10006)
BUILD FAILED
/Users/damuammu/Desktop/spark-Mac/build/build.xml:775: exec returned: 1
Below is the applescript
on run {volumeName, artPath, theHeight, theWidth, x1, y1, x2, y2, iconSize}
tell application "Finder"
tell disk (volumeName as string)
open
delay 2
set dsStore to "\"" & "/Volumes/" & volumeName & "/" & ".DS_STORE\""
tell container window
set current view to icon view
set toolbar visible to false
set statusbar visible to false
set the bounds to {10, 10, 658, 482}
set statusbar visible to false
end tell
set opts to the icon view options of container window
set the arrangement of opts to not arranged
set the icon size of opts to 128
--iconSize
set background picture of opts to file ".background:dmgBackground.png"
-- Icon positions
delay 2
set position of item "Spark.app" to {140, 250}
set position of item "Applications" to {395, 250}
delay 2
update without registering applications
end tell
delay 10
end tell
end run
Please can anyone suggest on this issue.
The error occurs in your ant script before the AppleScript is run. The error is here:
[exec] cp:
/Users/damuammu/Desktop/spark-Mac/build/installer/mac/RightDSStore: No
such file or directory
What the AppleScript does is make your mounted DMG volume look pretty. Since not everything gets put properly in the DMG, the Applescript later fails with:
[exec] mac/dmg_spark.scpt: execution error: Finder got an error:
Can’t set item "Spark.app" of disk "MixTalx_2.6.3" to {140, 250}.
(-10006)
However, what you need to do is fix the ant script failing with the first error.
This popup kills many of my tests. Even simple DOM interactions like .exists? timeout. Is there any way of detecting that it appeared and dismissing it?
Warning: Unresponsive script.
A script on this page may be busy, or it may have stopped responding. You can stop the script now, or you can continue to see if the script will complete.
dom.max_script_run_time=999
dom.max_chrome_script_run_time=19
These websites aren't designed nor influenced by me. I am merely scraping and sending them instructions as customer.
I run a small autoit3 application that kills popups. If I recall correctly, it waits a little bit to see if the popup is handled before it kills it. This removed many frustrations for me. I also had a version of this that would match certain keywords in the title or body that was read from a file - that allowed me to avoid killing something that needed to stay.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; AutoIt Version: 3.1.0 ;
; Author: Dave McNulla ;
; Script Function: Close unwanted popups during test automation. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Opt("GUIOnEventMode", 1) ; Change to OnEvent mode
Opt("WinTextMatchMode", 1) ;0=best, 1=quick
Opt("WinTitleMatchMode", 2) ;1=start, 2=subStr, 3=exact, 4=advanced
Opt("TrayIconHide", 0) ;0=show, 1=hide
Opt("TrayMenuMode", 0) ;0=default
TraySetIcon("Shell32.dll", 98)
dim $SleepTime = 2000
dim $Max = 100
$Message = "{ENTER}"
$ButtonClick = "[CLASS:Button; TEXT:OK]"
$Title = "[CLASS:#32770;TITLE:Internet Explorer]"
While 1
If WinExists($Title) Then
WinActivate($Title)
Sleep($SleepTime)
ControlClick($Title, "", $ButtonClick)
EndIf
Sleep($SleepTime)
If $Max < 1 Then Exit(1)
WEnd