Monday, November 8, 2010

Thunderbird new mail notification for freedesktop compliant systems

For a while it bothered me, that Thunderbird doesn't not provide an integrated new mail notification for freedesktop compliant systems - it doesn't display new mail icon in system tray. While there is moztraybiff add-on - it's not up to date for a while already, and it requires recompilation for each particular OS.

Recently I came across Mailbox Alert add-on which allows executing a custom program when new mail appears in a given folder (it can be conveniently configured for each folder separately). This gave me an idea how to make a simple new mail notification alert. So I wrote a small script for that (it uses wmctrl utility which appeared not to be installed by default on my OpenIndiana and Debian Linux where I tested this script, but it's available for installation from standard repositories).

Create let's say ~/bin/tb_new_mail_alert.sh as follows:
#!/bin/bash

# Author: Shmerl
# Date : November, 2010

. ~/bin/helpers/locking.sh

TB_WINDOW_SUBTITLE='Mozilla Thunderbird'
NEW_MAIL_ALERT_ICON='/usr/share/icons/gnome/48x48/status/mail-unread.png'

exclusive_lock_require `basename $0` 1 2>&1 > /dev/null
zenity --notification --window-icon="$NEW_MAIL_ALERT_ICON" --text='New mail has arrived!'

# Currently it just raises some matching window.
# This can be modified to address specific cases like
# two Thunderbirds running in parallel using different profiles etc.
# In that case the script can take profile name as a parameter and
# use that to alter the lock name and window subtitle pick.

if [ `wmctrl -l | grep -c "${TB_WINDOW_SUBTITLE}"` -ne 0 ]
then
wmctrl -a "$TB_WINDOW_SUBTITLE" # bring to front
fi

Note: On Debian I'm using it with actual Thunderbird, but if you want to use it with Icedove you should modify TB_WINDOW_SUBTITLE value above accordingly.

Here is locking.sh (included as ~/bin/helpers/locking.sh) which is needed to ensure that only one instance of the notification script will be able to run (thanks to Jason Weathered from Stack Overflow for this example).

#!/bin/bash

#
# The code is taken from Stack Overflow
# Thanks to Jason Weathered
#

function exclusive_lock_try() # [lockname]
{
local LOCK_NAME="${1:-`basename $0`}"

LOCK_DIR="/tmp/.${LOCK_NAME}.lock"
local LOCK_PID_FILE="${LOCK_DIR}/${LOCK_NAME}.pid"

if [ -e "$LOCK_DIR" ]
then
local LOCK_PID="`cat "$LOCK_PID_FILE" 2> /dev/null`"
if [ ! -z "$LOCK_PID" ] && ps -p "$LOCK_PID" &> /dev/null
then
# locked by non-dead process
echo "\"$LOCK_NAME\" lock currently held by PID $LOCK_PID"
return 1
else
# orphaned lock, take it over
( echo $$ > "$LOCK_PID_FILE" ) 2> /dev/null &&
local LOCK_PID="$$"
fi
fi
if [ "`trap -p EXIT`" != "" ]
then
# already have an EXIT trap
echo "Cannot get lock, already have an EXIT trap"
return 1
fi
if [ "$LOCK_PID" != "$$" ] &&
! ( umask 077 && mkdir "$LOCK_DIR" && umask 177 &&
echo $$ > "$LOCK_PID_FILE" ) 2> /dev/null
then
local LOCK_PID="`cat "$LOCK_PID_FILE" 2> /dev/null`"
# unable to acquire lock, new process got in first
echo "\"$LOCK_NAME\" lock currently held by PID $LOCK_PID"
return 1
fi
trap "/bin/rm -rf \"$LOCK_DIR\"; exit;" EXIT

return 0 # got lock
}

function exclusive_lock_retry() # [lockname] [retries] [delay]
{
local LOCK_NAME="$1"
local MAX_TRIES="${2:-5}"
local DELAY="${3:-2}"

local TRIES=0
local LOCK_RETVAL

while [ "$TRIES" -lt "$MAX_TRIES" ]
do
if [ "$TRIES" -gt 0 ]
then
sleep "$DELAY"
fi
local TRIES=$(( $TRIES + 1 ))

if [ "$TRIES" -lt "$MAX_TRIES" ]
then
exclusive_lock_try "$LOCK_NAME" > /dev/null
else
exclusive_lock_try "$LOCK_NAME"
fi
LOCK_RETVAL="${PIPESTATUS[0]}"

if [ "$LOCK_RETVAL" -eq 0 ]
then
return 0
fi
done

return "$LOCK_RETVAL"
}

function exclusive_lock_require() # [lockname] [retries] [delay]
{
if ! exclusive_lock_retry "$@"
then
exit 1
fi
}


Make sure you point zenity to the existing icon (I used Gnome's mail-unread.png in the example above. After you set up these scripts and install Mailbox Alert add-on, right click on the mail folder in Thunderbird for which you want to receive notifications, and select "Mailbox Alert". Enable "Execute Command" field there and point it to the tb_new_mail_alert.sh and you should be set.

A useful thing to add would be an indication of current number of new messages since Mailbox Alert allows to pass it to the script. The downside so far - the notification doesn't go away, until the icon is actually clicked. If add-on would provide some action hook for "no more new mail" kind of event - this could be improved.

No comments:

Post a Comment