Jump to content

Help with Alfred + Automator/AppleScript


Recommended Posts

Hello,

 

Some context

 

I often deal with folder structures like this:

 

top_project_folder

    section1_subfolder1

            filename_a.png

            filename_b.png

    section1_subfolder2

            filename_a.png

            filename_b.png

    section2_subfolder1

            filename_a.png

            filename_b.png

    section2_subfolder2

            filename_a.png

            filename_b.png

  

And I need to transform them into this:

 

top_project folder

    section1_subfolder

            filename_a.png

            filename_b.png

            filename_c.png

            filename_d.png

    section2_subfolder

            filename_a.png

            filename_b.png

            filename_c.png

            filename_d.png

 

 

I'm not a programmer, so I set up an Automator workflow which allows me to select multiple folders, rename the files inside sequentially, then put these files into a new folder. There are three interactive prompts:

 

  • one asking for the name of the project, stored in a variable folder
  • one showing a Finder window, allowing me to select folders (in my example above, I would select section1_subfolder1 and section2_subfolder2)
  • one asking for a number to append to the created folder, which will be in the form of projectname_section[number].

 

I made this into an application, that you can download here: link

 

So far no problem, I can launch the app from alfred without issue

 

The problem.

 

The problem is when I try to shorten the process by passing the argument in Alfred to the Automator script:

automator -d folder={query} /Users/Newbie/Documents/Scripts/folder_cleanup_alfred.workflow;

The app was converted into a workflow format beforehand, where I had deleted the prompt to enter the value of the variable folder, as it's managed by the argument in Alfred. The workflow is here: link

 

Two issues:

  • The process opens a Terminal window, which is not cool as it doesn't close on its own
  • The paramater is passed to the script (as shown by the Terminal window), but Automator tells me that the argument is incorrect.

 

The other problem

 

I tried to use AppleScript, to get more flexibility, but the process of opening an interactive Finder window to select multiple folders is way above my head, and copy-pasting this solution doesn't do anything for me. So I got stuck at this point.

 

I have a preference to an AppleScript solution, because it doesn't open the Terminal, but if you can show me how to successfully pass an Alfred argument to the Automator wokflow bash command, that would be already great!

 

I hope it was clear enough.

 

Thanks

Edited by Cedric
Link to comment

I tried to use AppleScript, to get more flexibility, but the process of opening an interactive Finder window to select multiple folders is way above my head, and copy-pasting this solution doesn't do anything for me. So I got stuck at this point.

 

I think you're trying to do that the wrong way around, tbh. Generally, you'd want to start with a selection in Finder, then call a workflow. Indeed, Alfred can do this natively, so if you can implement your script as a File Action, you won't need to worry about scripting Finder.

Link to comment

 

I think you're trying to do that the wrong way around, tbh. Generally, you'd want to start with a selection in Finder, then call a workflow. Indeed, Alfred can do this natively, so if you can implement your script as a File Action, you won't need to worry about scripting Finder.

 

Thanks for the pointer. Indeed, I could use Alfred to get the filepaths, with something like this:

set input to "/Users/Newbie/Desktop/section1_subfolder1    /Users/Newbie/Desktop/section1_subfolder2"

-- This is what Alfred sends to the script via {query}. Then I create a list named input, containing POSIX path of all selected folders

set AppleScript's text item delimiters to "    "
set input to every text item of input

-- I now ask for the project name and the section number so I can create a new folder called [Project] Section [Section number]

display dialog "Project name:" default answer ""
set project_name to text returned of result

display dialog "Section Number:" default answer ""
set section_number to text returned of result

(The subfolders do not necessarily have good names, so I have to operate section by section).

 

 

And then it starts to be way too complicated for my copy/paste skills.

 

. I should now:

- select all files across the folders in the input list

- rename all files using project_name and a sequential numbering

- create a new folder using project_name&"Number"&section_number

- move all files in the newly created folder

 

The solutions I found go way over my head, and I haven't been able to even rename some test folders.

 

I would be really grateful for some help here, if possible.

 

Thanks!

Edited by Cedric
Link to comment

What you're trying to do isn't really that complicated. It is complicated to do in AppleScript.

 

Sorry, but I'm not interested in struggling to implement something in AppleScript that is trivial to do in a programming language that isn't completely rubbish.

 

Most other coders on the forum have a similar attitude to AppleScript. They hate it and only use it when absolutely necessary (i.e. for talking to Mac apps).

 

Someone might come along and help you with the AppleScript, but I think you'd get more support if you tried Ruby or Python instead.

Link to comment

What you're trying to do isn't really that complicated. It is complicated to do in AppleScript.

 

Sorry, but I'm not interested in struggling to implement something in AppleScript that is trivial to do in a programming language that isn't completely rubbish.

 

Most other coders on the forum have a similar attitude to AppleScript. They hate it and only use it when absolutely necessary (i.e. for talking to Mac apps).

 

Someone might come along and help you with the AppleScript, but I think you'd get more support if you tried Ruby or Python instead.

 

I did the initial app in Automator because I have a very limited knowledge of programming (copy/paste level). From there it seemed easier to try something in AppleScript, because they are somewhat related, and AppleScript. I have no special love for AppleScript, so maybe I can try to copy/past some python/ruby stuff. Or should I look at bash?

 

Thanks!

Link to comment
Afraid I couldn't open your app: my Mac says it's corrupted.
 
I did have a look at the automator man page, and you're using it wrong.
 
automator -d folder={query} /Users/Newbie/Documents/Scripts/folder_cleanup_alfred.workflow;
 
should be
 
automator -D folder="{query}" /Users/Newbie/Documents/Scripts/folder_cleanup_alfred.workflow
 

 

Capital D, and quotes around {query} are always a good idea.
Link to comment

 

Afraid I couldn't open your app: my Mac says it's corrupted.
 
I did have a look at the automator man page, and you're using it wrong.
 
automator -d folder={query} /Users/Newbie/Documents/Scripts/folder_cleanup_alfred.workflow;
 
should be
 
automator -D folder="{query}" /Users/Newbie/Documents/Scripts/folder_cleanup_alfred.workflow
 

 

Capital D, and quotes around {query} are always a good idea.

 

 

I resaved the app and saved it as a zip. Maybe Dropbox was doing something funny with it? I don't know why It said it was corrupted. I'm using El Capitan 10.11.3 btw.

 

Did you successfullly use this automator line? I tried all combinations of capital or lower D and with and without quotes, and I had always the same result: The workflow DID skip the part for which I had entered an argument, and successfully started with the second question. But every time it sends me a feedback saying

The action "Set Value of variable" wasn't given the correct data

The second prompt that appears in the workflow is normally prefilled with the value entered via bash. But every time, I used automator -D, the second prompt does not have the value prefilled, and I get the error message.

 

Thanks so much for following up on this!

Link to comment

No, I don't use Automator except to wrap scripts. I just read the man page and noticed that the command you posted was incorrect.

 
It looks like your workflow is all kinds of confused. You have it set to accept files and folders and you are trying to pass variables and you're asking the user for variables. No wonder it isn't working.
 
I'd try and fix it, but I'm really not sure what it is you're trying to do.
Edited by deanishe
Link to comment

You're right, my workflow was confused. I now edited the automator workflow and here is the script that Alfred runs.

#!/bin/bash
arr="{query}"
set -- $arr
automator -D project_name="$1" -D section_number="$2" /Users/.../Alfred.alfredpreferences/workflows/.../folder_cleanup.workflow

And it's working beautifully!

 

This is great, and all the files are in the worfklow so it will work on my other computers.

This shows that with even with my limited coding knowledge, I can create interesting workflows, at least for my personal use.

I'll definitly think about doing more of them in the future.

 

The mistake that kept me blocked was silly, and I accidentally closed the page while writing about it, which is sillier.

So I'll edit this response when I have the time to add the full explanation.

 

A question: is it possible to give the automator function a relative path to the workflow, rather than the absolute one?

 

Second question: My workflow requires two arguments separated by a space (that Alfred recognizes as a single argument with a space inside). How could I modify the script so it tells me if I forgot to put 2 arguments? Maybe counting the number of array items, and using an IF?

 

IF array != 2, echo {error_message}.

 

I understand that the echo becomes another {query} than can be passed to a notification that would show warn the user?

 

Thanks for your help!

Edited by Cedric
Link to comment

Glad to hear you got it working.
 

A question: is it possible to give the automator function a relative path to the workflow, rather than the absolute one?


Indeed it is. I was going to point out that your workflow won't run on other people's computers because of the absolute path.

When Alfred runs a workflow, the working directory is the workflow root (where info.plist is), so just use folder_cleanup.workflow or ./folder_cleanup.workflow instead of the absolute path (assuming folder_cleanup.workflow is also in the workflow's root directory).
 

Second question: My workflow requires two arguments separated by a space (that Alfred recognizes as a single argument with a space inside). How could I modify the script so it tells me if I forgot to put 2 arguments? Maybe counting the number of array items, and using an IF?
 
IF array != 2, echo {error_message}.
 
I understand that the echo becomes another {query} than can be passed to a notification that would show warn the user?
 
Thanks for your help!


You're getting a single variable because you've coded it that way.

Alfred has no concept of variables in your code (except with Run NSAppleScript actions). Your code is basically text to Alfred, and it performs a search/replace for {query} in the contents of the Script box before executing it.

You've enclosed {query} in quotes, therefore if the query is one two, Alfred will rewrite your code to read arr="one two", i.e. a single variable.

I'm sure there is a way to make it into two variables in bash, but I don't know what it is because I'm not very good with bash.

What I would do is put my code in an external script and call that with {query} as the argument (without quotes!): 

/bin/bash myscript.sh {query}

Alfred would rewrite this to /bin/bash myscript.sh one two before running it, which would pass two arguments to myscript.sh accessible as $1 and $2.

Link to comment

I have completely rewritten my workflow to make it work even if the project name contains one or more space.

The code doesn't care, and simply checks that a section number is correctly entered.

I did as you said as well, and got the .sh script on a dedicated file, using /bin myscript.sh {query} to set the positional parameters.

 

This workflow now works exactly as intended, thank you for your help!

#!/bin/bash

#code under MIT licence, modified from Stack Overflow, Unix.com and Ask Ubuntu answers, from the users below:
#bashist http://stackoverflow.com/a/6968547
#Ignacio Vazquez-Abrams http://stackoverflow.com/a/2210386
#robotronic http://www.unix.com/shell-programming-and-scripting/42417-what-does-mean-double-pipe.html
#geirha http://askubuntu.com/a/29596

#the positional parameters are set from Alfred's script filter

#test if the last parameter is a valid integer. 
if [[ ${@: -1} =~ ^[0-9]+$ ]]; then

#run the automator workflow. ${@:1:($#-1)} = All parameters but the last; {@: -1} = last parameter
  automator -D project_name="${@:1:($#-1)}" -D section_number="${@: -1}" folder_cleanup.workflow

#If the last parameter was not a valid integer, send a notification
else  echo 'Incorrect section number? Try again'

fi
Edited by Cedric
Link to comment

Glad you got it working!

 

Also glad for the extensive comments in your code: bash is too esoteric for me, and I wouldn't understand what's going on without the comments.

 

If it looks like black magic to you, too, you might want to have a look at Python or Ruby. Far easier to understand than bash (especially Python) and way more powerful (both languages).

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