[英]Progress Bar in Applescript window
I want to download different apps with a bash script on macOS.我想在 macOS 上使用 bash 脚本下载不同的应用程序。
As there are some larger downloads (eg Office 365) I would like to include a progress bar in a regular macOS Window.由于有一些较大的下载(例如 Office 365),我想在常规 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.但这会产生 curl 执行错误。
Please help me with a functioning Curl Download + Progress Bar script请帮助我使用功能正常的 Curl 下载 + 进度条脚本
A basic progress spinner window is easy enough to create using AppleScriptObjectiveC.一个基本的进度微调器 window 很容易使用 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).将以下内容复制到 Script Editor 并在前台运行(command-control-R,或使用菜单命令 Script→Run in Foreground,按住 control 键时会出现)。
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): 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:获得 pid 后,您可以设置循环(或空闲处理程序,如果您创建应用程序)并定期检查进程是否仍处于活动状态:
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.随着下载的进行,您可以将其与实际的磁盘文件大小进行比较,并将比率输入进度条。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.