Shortly after creating my CSS-based signature, I wanted more... more versions of my signature to be displayed randomly, anyway. So, after looking around at the various plugins to get this functionality. I was ultimately disappointed, because they either do too little, or too much. All I want is the same Thunderbird-driven "select your signature file" function, but with randomness!
So, I built my own, and I think it's worth taking a look at if you're interested in something similar.
Basically, my solution is composed of a couple files which can be merged to form a random signature (and any supporting graphic files, etc). These should be placed in your normal directory holding your signature. For this example, let's say this is the directory /Users/jbloggs/signature:
- signature-template.html - my normal signature (and all of it's support files) but with a minor change: I've replaced the tagline with a marker "[TAGLINE]".
- taglines.txt - this is a list of all my taglines that I want to randomly choose from for each e-mail. There is one tagline per line and any characters that might be special to the shell must be escaped properly.
Other files required to make up this solution are the following, which are to be placed in the directory /Library/StartupItems/SignatureRandomizer, which is owned by root, has its group set to wheel and has permissions 0755 (drwxr-xr-x)
- SignatureRandomizer.watchdog - this is the magical bit. This shell script monitors my signature.html file to see if it has been used, and if it has, it creates another one by randomly selecting a line from my taglines.txt file and inserts it into the signature-template.html.
- SignatureRandomizer - this script controls the watchdog-script.
- StartupParameters.plist - this is required to automatically start the service when my Mac boots up.
SignatureRandomizer.watchdog
This is a relatively small script that, once it starts, keeps running all the time (or until it is killed). It monitors the signature.html file and, if it has been accessed since it was created, then a new signature file is created by merging a random line from the taglines.txt file into the signature-template.html. If the signature file has not been used since it was created, then the script does nothing more and goes back to sleep (for 5 seconds). If this seems wasteful for any reason, I've been running this for sometime now. Since my last reboot, 3 days ago, the watchdog script itself has consumed only 1, single second of CPU time.
If you curious how it works, there is basically a loop which first tells itself to do nothing for 5 seconds, then, checks the signature.html file for usage. If it has, then it counts how many lines are in the taglines.txt file, then grabs one and stores it in "line". Next, it looks for the token "[TAGLINE]" in the signature-template.html file and replaces it with the contents of "line". The new version of signature-template.html is now stored in signature.html. What is not clear in the script is that when a new signature.html file is written, the Mac OS filesystem sets the access time and modification time to be the same. If another application (like Thunderbird) reads that signature file later, the access time will be updated and become later than the modification time. Within 5 seconds, the watchdog script will wake up and detect this, and create a new one.
USERPATH=/Users/jbloggs
TAGLINES=${USERPATH}/signature/taglines.txt
TEMPLATE=${USERPATH}/signature/signature-template.html
SIGNATURE=${USERPATH}/signature/signature.html
HOLDER="\[TAGLINE\]"
# All the magic below.
# Simply check to see if the signature file has been accessed since it was created and, if so, modify it.
while sleep 5
do
# If the signature file was not accessed since it was modifyied...
if [ ! -N "$SIGNATURE" ]
then
# Modify it
lines=(`wc -l < $TAGLINES`)
let "randomline = $RANDOM % $lines + 1"
line=`sed -n "${randomline}p" < $TAGLINES`
sed "/${HOLDER}/s//${line}/" <${TEMPLATE} >${SIGNATURE}
fi
done
SignatureRandomizer
The watchdog script above works and works well, but I don't really want to run it manually everytime I plan to send e-mails. So, I decided to run this as a Mac OS X StartupItem. This script and the StartupParameter.plist file make this happen. It allows both the normal Mac bootup process and any authorized user to start up the watchdog-script when necessary or shut it down, or restart it. It can do this because it maintains the watchdog-script's PID or Process ID in a file called "SignatureRandomizer.pid" in the StartupItems/SignatureRandomizer directory. This is created and deleted automatically by this script.
#!/bin/sh
##
# SignatureRandomizer
##
. /etc/rc.common
MYPATH=/Library/StartupItems/SignatureRandomizer
StartService ()
{
if [ -e ${MYPATH}/SignatureRandomizer.pid ]; then
echo "SignatureRandomizer may already be running. Stopping first (restart)"
StopService
fi
if [ -x ${MYPATH}/SignatureRandomizer.watchdog ]; then
echo "Starting SignatureRandomizer."
${MYPATH}/SignatureRandomizer.watchdog &
echo $! > ${MYPATH}/SignatureRandomizer.pid
] fi
}
StopService ()
{
if [ -e ${MYPATH}/SignatureRandomizer.pid ]; then
echo "Stopping SignatureRandomizer."
kill -9 `cat ${MYPATH}/SignatureRandomizer.pid`
rm ${MYPATH}/SignatureRandomizer.pid
else
echo "SignatureRandomizer not running (or at least, there is no PID file)."
fi
}
RestartService ()
{
StopService
StartService
}
RunService "$1"
StartupParameters.plist
This special file is what is required to get the startup process to know how to interact with the SignatureRandomzier scripts above. This is short and simple. In fact, it's probably more than we even need.
//
// SignatureRandomizer
//
{
Description = "Signature Randomizer";
Provides = ("SignatureRandomizer");
Messages =
{
start = "Starting Signature Randomizer";
stop = "Stopping Signature Randomizer";
restart = "Restarting Signature Randomizer";
};
}
Make sure that you set the owner/group and permissions to SignatureRandomizer, SignatureRandomizer.watchdog and StarupParameters so that they look like this:
-rwxr-xr-x 2 root wheel 872 Jul 25 23:40 SignatureRandomizer
-rwxr-xr-x 2 root wheel 661 Jul 25 23:38 SignatureRandomizer.watchdog
-rw-r--r-- 2 root wheel 296 Jul 25 23:27 StartupParameters.plist
Reboot and it should begin working! Enjoy!