Tuesday, November 11, 2008

Folder Actions on a Mac

I have finally found a solution to my problem with manualy executing Single.sh.  I tried folder actions which didn't work for me.  Single.sh never got executed and if it did, everything got effed up.  My solution: launchd.
Launchd reads in a bunch of plists and executes commands within those plists once a certain condition is met.  This normally is an event such as system startup or login, or it is a time such as on Wednesdays or the 3rd of each month.  It just so happens that there are incredibly useful conditions that I didn't even know launchd supported.
There was two conditions that may have worked for me, depending on how I set it up.
1) Run when a chosen file is modified
2) Run if anything is placed into a chosen folder

Condition #2 is what I needed.  It's basically folder actions without depending on Finder(or whatever executes them).  The system only depends on launchd which will always be running.

I used Lingon to add a new "My Agents" plist(a user-specific launch agent).  I used Lingon because it manages the background tasks(launchctl) and a nice interface to all the options available to a launchd plist.  In short, it's extremely easy to set it up.
Steps to set this up:
1) If you don't have a folder called bin in your home directory, create it
2) download open Lingon
3) Click the plus in the top left and then click Create.  Don't change anything in this window.
4) give it a name such as com.[your name].moveepisode
5) put /Users/[your short username]/bin/moveepisode   into the What textbox
6) under When, locate the bottom textbox and click "Path..." beside it.  Choose where your completed files get moved to.
7) hit command-S to save it and then logout and login to your mac

Nothing will happen right now because /Users/[your short username]/bin/moveepisode doesn't exist.  We need to create it, but first a bit of how I do this.

My Torrent directory tree looks something like
TORRENTS/
    Incomplete/
         Tv Shows/ 

    Done/
         Tv Shows -> See Note below
TV Shows/
         Incoming/
              Logs/
              Links/
              Temp/
              Single.sh
         Show1
         Show2
         Show3
Note: Done/Tv Shows is a symbolic link that points to TORRENTS/TV Shows/Incoming/Temp.  This link makes it all work.
EDIT: blogger is effing the formatting up no matter what I do.  TV Shows is a subdirectory of TORRENTS, not a sibling.

I use Save Path in Vuze so that files move to a folder in the default save path which is named after the category.  I have Auto Category installed which is setup with a regular expression on the torrent name and it assigns the category Tv Shows.
I have vuze set to download to a TORRENTS/Incomplete/,  Save Path moves torrents with category Tv Shows to TORRENTS/Incomplete/Tv Shows.  After a torrent is removed, Save Path moves those same torrents to TORRENTS/Done/Tv Shows.  That folder is a symbolic link to TORRENTS/TV Shows/Incoming/Temp so the files are really there instead of Done/Tv Shows.  Launchd then executes moveepisode because Temp is no longer empty.  <3 seconds later, I have a log and a properly organized episode.
The contents of /Users/[your short username]/bin/moveepisode is:
#!/bin/bash
cd "/Volumes/DATA/TORRENTS/TV Shows/Incoming"
mv Temp/*.avi .
find . -depth 1 -name "*.avi" >list
cat list | while read line; do
 ./Single.sh "$line";
done
rm list
This script changes to the incoming directory, moves all the files in Temp to the incoming directory, gets a list of all the avi videos in that directory and executes Single.sh for each one. Note: I use a file, list, instead of piping the output of find directly into while so I can debug if I need to.

The only line you need to change is the line beginning with cd.  It needs to be changed to your Incoming directory.  Make sure the directory is in quotes.  After you save it, open up Terminal and paste the following line in and press enter
chmod a+x ~/bin/moveepisode
For those who don't know, the tilde(~) represents your home directory.


You are now finished.  Enjoy.