Jump to content

Progress Bar (or progress display of any kind -menubar, etc)


Recommended Posts

Hey workflow gurus!

 

I have implemented a workflow to perform various file hashing functions (md5, sha1, sha256) on selected files, and display results in a LargeType window, or optionally send to a CSV and open in Numbers.app. It also supports triggering via both a Hotkey as well as a Keyword, and supports queueing up files and then processing the queue later. It's pretty nifty and I'm almost done polishing it and I plan to make it publicly available.

 

One thing I'm having a hard time with is- on large files (e.g. 1GB+) the hashing takes a bit of time as Alfred churns through a Bash script, and there's no feedback to the user that anything's happening. I'd like to show some type of progress bar or progress display in the menu bar etc. I have been banging my head on this for a while now but I can't figure out a good solution.

 

I know AppleScript supports the concept of Progress (see Mac Automation Scripting Guide - Displaying Progress) but when I tried this from inside Alfred, it just didn't work properly and always stayed at 0%, even though the exact same script when run from Script Editor worked fine.

 

I've found a couple of "helper apps" that I am considering but none are very actively maintained and I was really hoping for a "native" solution that didn't involve adding more 3rd party tools and dealing with licenses etc.

links:

https://cocoadialog.com/ -- related https://github.com/cocoadialog/cocoadialog/issues/108

https://github.com/tsntsumi/ProgressDialog

https://www.bluem.net/en/projects/pashua/ - GitHub page: https://github.com/BlueM/Pashua

 

Anyone got any ideas for this?

thank you

Edited by luckman212
Link to comment

For an example of what I'm talking about, try pasting this script into Script Editor and running it

set n to 5
set progress total steps to n
set progress description to "Script Progress"
set progress additional description to "This should be helpful"

repeat with i from 1 to n
  delay 1
  set progress completed steps to i
end repeat

If you save that as an Application and run it, you get a very nice popup progress bar...

image.png.32c7811ed1d2833a638aaee72345425b.png

But, running this code from within Alfred does nothing.

 

Also, I've tried using cocoaDialog (both 2.1.1 and the 3.0b7) and can't get either of them to run from within a workflow, I think possibly due to SIP/code signing issuues.

Link to comment

You can show a progress bar in Alfred itself using its rerun feature.

 

The problem is that Alfred needs to run your script several times a second to get progress status, which means you have to do your hashing (or whatever long-running function you're using) in a separate, background process that writes its progress to a file your Script Filter can read it from.

 

Link to comment
1 hour ago, deanishe said:

You can show a progress bar in Alfred itself using its rerun feature.

 

Thanks - would that be possible if no Alfred window is showing? Because primarily this workflow is triggered via hotkey only. Got any links or examples where I can read up more about the `rerun` thing?

Link to comment
6 hours ago, luckman212 said:

would that be possible if no Alfred window is showing?

 

The suggestion was to show the progress bar in Alfred. It doesn’t need to be showing all the time, you can call it to check on the progress. See DownVid and UploadFile (disclaimer: I wrote them, but that is also why I’m recommending them — I know how they work). See the dvp and ufp windows? That’s how it’d show (but it updates in place).

 

6 hours ago, luckman212 said:

Got any links or examples where I can read up more about the `rerun` thing?

 

See the documentation. Alfred itself also ships a Workflow that explains it (the documentation points you to it).

Link to comment

I also sometimes want to have a way to see some kind of progress (mainly to see if my process as complete), so I used an Automator Process that is called from Alfred so a gear icon appears in the menubar to clearly show that the script is running. However, it stays at 0 and quit when it's done. So, it is a little like what you are after. I thought why not run an AppleScript applet from Alfred and found a way that can also accept an argument to the applet using JXA. For some reasons, the on run argv doesn't work directly to get the input arguments so we need to use the Objective-C bridge.

 

In short, you write a JXA application (applet) using Apple Script Editor that would do the action that you want while updating the progress bar. Move the bundled application into your Alfred Workflow directory and call it (start it) from Alfred using a Bash script like:

 

open ./progress_example.app --args "$1"

As for the JXA script, it should look like this (edit to make it do the things that you want...):

ObjC.import('Foundation')
const args = $.NSProcessInfo.processInfo.arguments
const argv = []
const argc = args.count
for (let i = 0; i < argc; i++) { argv.push(ObjC.unwrap(args.objectAtIndex(i))) }
delete args


// Modify what is here after so your applet makes the action that you want
// Use argv[1] and up for the input arguments
Progress.description =  "Progress indicator; Input Args = " + argv[1]
Progress.totalUnitCount = 25;

for (var i = 1; i < 26; i++) {
    Progress.additionalDescription = "Step at: " + i
    Progress.completedUnitCount = i
    delay(0.1)
}

Here is an example in a Workflow: https://d.pr/f/rQPVmD

 

So, if you want to see your progress directly in Alfred you can use the rerun feature or if you want to have a popup that shows you the progress while you do something else, then you can try my solution and see if it fit for you. Also, it should also be possible with cocoaDialog or something else, but I didn't have the time to try it at the moment.

Link to comment
  • 3 weeks later...

@GuiB Thank you for posting this! It's a very interesting solution. I'm not sure I'm up to the challenge of rewriting my bash script in JavaScript so I'll have to see about that. Also, I need the output of the program to be passed along as a parameter to the next step in the Alfred workflow. Not sure how to do that since the "meat" of the task is now running in a subprocess. I guess maybe in the JXA script it should output results to a /tmp file and then when control returns to Alfred, it can read that file back in and push it back into the {query} ?

Link to comment

@luckman212, yes to use the output of the script I would use an Alfred External Trigger that is triggered by the JXA so we can do something from Alfred. So, yes you can write to a file or directly use the argument to the Alfred External Trigger. I've made an example here: https://d.pr/f/2rzrt1

 

Here is the inside JXA script for those wanting to see directly without downloading:

ObjC.import('Foundation')
const args = $.NSProcessInfo.processInfo.arguments
const argv = []
const argc = args.count
for (let i = 0; i < argc; i++) { argv.push(ObjC.unwrap(args.objectAtIndex(i))) }
delete args


// Use argv[1] and up for the input arguments
Progress.description =  "Progress indicator; Input Args = " + argv[1]
Progress.totalUnitCount = 25;

for (var i = 1; i < 26; i++) {
    Progress.additionalDescription = "Step at: " + i
    Progress.completedUnitCount = i
    delay(0.1)
}

Application('Alfred 3').runTrigger('progress_bar', {inWorkflow: 'gbProgressBarExample', withArgument: "Total Count = " + Progress.totalUnitCount})

 

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...