Monitoring the Downloads folder with Keyboard Maestro
When you search for folder organization, you can’t help but find Hazel. It’s a great program to help organize your files and put them where they belong. Only problem is, at $42, it’s expensive. That’s more than Keyboard Maestro, Scrivener, and a few other tools. Since I have Keyboard Maestro, I can emulate a lot of that functionality.
Enter the Monitor Download Folder macro. With a combination of Keyboard Maestro and some Shell Scripting, I can move downloaded files around to keep things tidy.
The first thing to do is set up a “Folder Trigger.” For this example, it’s on the Downloads folder. We also want to choose, “Ignore partial or changing files.” For most applications this works fine. But, not always for a browser. The macro may trigger before the file is done. To compensate, we can add some scripting.
Borrowing a very cool solution from Jeff Hester on the Keyboard Maestro forums, we can use LSOF (List of Open Files) to see when a download completes.
In my example, I’m checking to see if Firefox has any open files. The Keyboard Maestro example uses Safari. So, change this as needed for the browser or application you choose. I have another macro when using DevonAgent.
If “grep” returns a result, the file is still downloading. We wait then check the process again. When the variable is empty, the file is complete and we can proceed.
The next step is to move the file. Using the built-in Keyboard Maestro IF-Then condition, we can move the file
%TriggerValue% to a directory.
%TriggerValue% is the name of the file that changed in the Download directory.
As shown, if the filename contains “sql” it will be moved to the chosen location.
The IF block can be repeated for each type of file you want to work with. Such as a file extension that ends in .jpg or .pdf, or contains “Unix” or whatever you are working with. Combining blocks allows you to move different files around as they come into your Downloads folder.
This works well, but can be a little hard to manage if you need to dozens of file types or conditions. For that, we can add a bit more scripting to handle more conditions as text.
By adding another Execute Shell Script block after the download is complete, we can use the CASE statement to determine what file we have and where it should go.
In my example, I have additional conditions for filenames that contain BDD, Java, Groovy, C Programming, etc.
Earlier in the script I set a variable to %TriggerValue% so I have the name of the file. I can then use this in a case statement:
case "$KMVAR_instance_fileName" in
This allows the Keyboard Maestro instance of the shell to use variables from the Keyboard Maestro macro itself.
shopt -s nocasematch allows the CASE statement to be case Insensitive when checking matching conditions. This matches sql, Sql, SQL.
The CASE statement uses Wildcards and OR conditions such as
"*bdd*"|"*selenium*"|"*gherkin*") to capture a couple of related file types.
c?programming) matches c-programming, c_programming, and c programming.
source and target are variables that represent the file that was downloaded and the root folder of where to move files.
mv "$source" "$target/Automation Programming";;
Moves the files to the root volume, then appends Automation Programming to make a complete directory.
$target make things a little shorter for typing and expandable for the future.
We now have a perfectly workable solution for moving and organizing files as they’re downloaded.