How to display email subjects in an fvwm menu.

I got tired of opening and email client everytime i got new mail just to have it be SPAM. So i wrote up alittle something that will display the subject of all your new and/or old mail in a your mail box. The only requirement is that your mail box be in maildir format ( new cur tmp).

Heres what you have to add to your .fvwm2rc file. Edit the path to the mail_menu.sh file. The default location is /home/$USER/.fvwm/scripts/

AddToMenu FvwmNewMailMenu
+ DynamicPopupAction Function FvwmNewMailMenu

DestroyFunc FvwmNewMailMenu
AddToFunc FvwmNewMailMenu
+ I DestroyMenu recreate FvwmNewMailMenu
+ I AddToMenu FvwmNewMailMenu
+ I PipeRead '/home/$USER/.fvwm/scripts/mail_menu.sh new'

AddToMenu FvwmOldMailMenu
+ DynamicPopupAction Function FvwmOldMailMenu

DestroyFunc FvwmOldMailMenu
AddToFunc FvwmOldMailMenu
+ I DestroyMenu recreate FvwmOldMailMenu
+ I AddToMenu FvwmOldMailMenu
+ I PipeRead '/home/$USER/.fvwm/scripts/mail_menu.sh old'

DestroyMenu MenuFvwmMail
AddToMenu   MenuFvwmMail
+ "New Mails" Popup FvwmNewMailMenu
+ "Old Mails" Popup FvwmOldMailMenu

Then add this to your root menu

+ "Check Mails" Popup MenuFvwmMail

And heres the bash script. You need to edit the mail_path so that it points to your maildir. Default is /home/$USER/Mail.

#!/bin/bash
mail_path=/home/$USER/Mail
case $1 in
	new)	
	for new in `ls $mail_path/new/*` 
		do 
			echo "+ \"`cat $new|grep Subject:| fold -w 35 | head -n 1`\" Nop" 
		done ;;
	old) for cur in `ls $mail_path/cur/*` 
		do 
			echo "+ \"`cat $cur|grep Subject:| fold -w 35 | head -n 1`\" Nop"
		done ;;
esac

The only problem i have with it is i havent been able figure out how to shorten the subject down so its only a few words long. Eventually i plan on rewriting it in perl and haveing the option to read either mbox or maildir and make it an fvwm module. That will be my first major perl script. Hope you all enjoy it.

VoiDeR

I suppose you could do something like this:

echo "+ \"`cat $new|grep Subject:`| fold -w 8 | head -n 1\" Nop"

Where “8”, above, depicts the length. There’s 1001 other ways to achieve the same thing. :slight_smile:

– Thomas Adam

Thanks ThomasAdam that works great i edited my post to add that.

VoiDeR

You can create also a copy of each mail in your procmailrc:

:0 c * | newMail.pl

and pipe it to a perlscript:

[code]#!/usr/bin/perl -w

use strict;
use MIME::Parser;

my $FvwmCommand = “FvwmCommand”;
my $FvwmFunction = “MailPopup”;
my $maxlength = 60;

sub prep_string {
my $s = shift;
chomp $s;
$s = substr($s, 0, $maxlength - 1);
$s =~ s/\/\\\\/g;
$s =~ s/"/\\\"/g;
$s =~ s/$/$$/g;
return $s;
}

my $parser = new MIME::Parser;

$parser->ignore_errors(1);
$parser->output_to_core(1);
$parser->decode_headers(1);

my $entity = eval { $parser->parse(*STDIN) };
my $error = ($@ || $parser->last_error);

my $head = $entity->head;

my $subject = prep_string($head->get(‘Subject’));
my $from = prep_string($head->get(‘From’));
my $to = prep_string($head->get(‘To’));

my $command = “$FvwmFunction “$subject” “$from” “$to””;

open(FD, “|$FvwmCommand -c”);
print FD $command;
close(FD);
[/code]

I use a similar script to display a menu for 20 seconds and to change an icon in my FvwmButtons Module:

btw, the MIME::Parser decodes RFC-1522 MIME headers like:
=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?=

Wow Sascha that is really cool. Does it automaticly popup when you recive new mail?

VoiDeR

Yes… I pipe every incoming mail through procmail and thus the script processes every mail as soon as it arrives…
Of course, my “real” configuration first checks where I’m logged in and then executes FvwmCommand on this hosts… But this part is very environment specific. Therefore the script only demonstrats how to parse a mail…

Sascha

Hi

After seeing the shot of Sascha I though the same thing would be nice!

And I did it! It took me some time because I use a bash script and no a perl script (my knowledge is already bad in bash and zero in perl…).

So Here is the bash script:

[code]#!/bin/bash

FVWM=ps -ef|grep '[f]vwm -s'

make sure we are running fvwm

if [ -n “$FVWM” ]
then
exit 0
fi

tmp_mail=/tmp/tmp_mail

cat > $tmp_mail

to=grep -v "\-To" < $tmp_mail |grep -m 1 "To:"|tr " " "_"
subject=grep -m 1 "Subject:" < $tmp_mail |tr " " "_"
from=grep -m 1 "From:" < $tmp_mail |tr " " "_"

rm $tmp_mail

fvwmfunction=‘MailPopup’\ “$from”\ “$subject”\ “$to”

echo “$fvwmfunction”|FvwmCommand -c[/code]

In procmailrc:

[code]# where the fvwm script is
fvwm_scripts=$HOME/.fvwm/scripts/
PATH=$PATH:$fvwm_scripts

Parse every incoming mail to a bash script

displaying a mailpopup when running fvwm

:0 c
*
|newMail.sh

[/code]

In my fvwm config:

[code]############################################################################################################################

MailPopup function

Purpose: popup a FvwmButtons instance when a new mail arrives.

A bash script is responsible for the retriving of the From, Subject and

To headers of the mail. This part is higly environment dependent.

#########

DestroyFunc MailPopup
AddToFunc MailPopup

  • I DestroyModuleConfig FvwmMail: *
  • I PipeRead “echo *FvwmMail: Geometry 350x60-70+$[StrutTop]”
  • I *FvwmMail: Columns 5
  • I *FvwmMail: Font “Shadow=0 1 SE:xft:Sans:pixelsize=11”
  • I *FvwmMail: Colorset 8
  • I *FvwmMail: Frame 0
  • I *FvwmMail: Padding 0 0
  • I *FvwmMail: Rows 3
  • I *FvwmMail: (1x3, Frame 0, Icon mail_big.png, Action (Mouse 1) Exec exec aterm -tr -bg black -fg white -trsb -sh 30 +sb -T '.: M u t t :.' -e mutt, Action (Mouse 3) Exec exec aterm -tr -bg black -fg white -trsb -sh 30 +sb -T '.: M u t t :.' -e mutt -y)
  • I *FvwmMail: (4x1, Title(Side) $0)
  • I *FvwmMail: (4x1, Title(Side) $1)
  • I *FvwmMail: (4x1, Title(Side) $2)
  • I Module FvwmButtons FvwmMail
  • I Schedule 20000 KillModule FvwmButtons FvwmMail

[/code]

And you’ll get something like:

Enjoy!!!

Brice

ps: the bash script might need additional debugging but it works quite well, as well as my IconBox

Hummm the test part in the bash script is creating matters! Also please notice that fvwm is run under debian with the “-s” option, so adapt.

Here is the last version of the beginning of the script, I hope this one is fine.

[code]#!/bin/bash

FVWM=ps -ef|grep '[f]vwm -s'|tr " " "_"

make sure we are running fvwm

if [ -z “$FVWM” ]
then
exit 0
fi

tmp_mail=/tmp/tmp_mail
[/code]

I someone has some idea for improving it, you’re welcome!

Brice

I use fetchmail myself!

In such a case, it parses the emails and displays for 1-2 seconds, not much.

A locking mechanism seems to be hard to implement… Maybe a “+ I KillModule FvwmButtons FvwmMail” at first can be a good thing.

Brice

Since I first saw this, I’ve thought it was a brilliant idea, and Sasha’s and Bricem’s variants are just too impressive.

Anyway, here’s my take on this, which includes From: and To: headers as well as the subject.

Screenshot with no e-mails:

Screenshot with e-mails received:

fvwmshowmail.sh

[code]#! /bin/bash

fvwmshowmail.sh

-----------

Script to print mail header info in an Fvwm menu

HOME=/home/rob
MYMAILDIR=${HOME}/.newmailcount

for MMF in ls -v --color=none ${MYMAILDIR}
do
grep -m 1 “^From: " “${MYMAILDIR}/${MMF}” | sed 's/”/\"/g;s/^/+ %mail.png%"/;s/$/"/’
grep -m 1 “^Subject: " “${MYMAILDIR}/${MMF}” | sed 's/”/\"/g;s/^/+ “/;s/$/”/’
grep -m 1 “^To: " “${MYMAILDIR}/${MMF}” | sed 's/”/\"/g;s/^/+ “/;s/$/”/’
echo “+ “” Nop”
done

if [ ls ${MYMAILDIR} | wc -l -ne 0 ]
then
echo “Test (x newmailclear.sh) + %mail_edit.png%“sylpheed-claws” Exec exec newmailclear.sh”
else
echo “+ %no.png%“no new e-mails””
echo “+ “” Nop”
echo “Test (x newmailclear.sh) + %mail_edit.png%“sylpheed-claws” Exec exec newmailclear.sh”
fi[/code]

Add the following chunks to your .fvwm2rc:

[code]AddToMenu MenuFvwmNewMail

  • DynamicPopupAction Function MenuFvwmNewMail

DestroyFunc MenuFvwmNewMail
AddToFunc MenuFvwmNewMail

  • I DestroyMenu recreate MenuFvwmNewMail
  • I AddToMenu MenuFvwmNewMail
  • I AddToMenu MenuFvwmNewMail “new e-mails” Title
  • I PipeRead ‘/home/$USER/bin/fvwmshowmail.sh’

scripts

AddToMenu Scripts “scripts” Title
Test (x bash) + %mail_mailbox.png%“new e-mails” Popup MenuFvwmNewMail[/code]

newmailclear.sh (this runs your e-mail client, sylpheed-claws in my case, and clears down the headers copied into ~/.newmailcount/)

[code]#! /bin/bash

Script to clear mail headers copied into ~/.newmailcount/

#$HOME=/home/rob

sylpheed-claws &

if [ -d $HOME/.newmailcount ]
then
if [ -e $HOME/.newmailcount/1 ]
then
rm -f $HOME/.newmailcount/*
else
exit 0
fi
else
mkdir $HOME/.newmailcount
fi

exit 0[/code]

And the following entry at the top of your .procmailrc will copy the headers of all received mail into ~/.newmailcount/

:0 ch * $HOME/.newmailcount/.

I hope you find this useful.

Regards,

Rob

Wow thanks PainlessRob. that is really slick. I wish i had half the scripting abilitys as you guys. Im adding this to my config asap.

VoiDeR

I’d like to use one of these scripts but I have one problem with all of them.

I do not recieve my mail on my computer automatically.
I have a few emailadresses (all available via imap or pop3). Is there a way to get these mails in my local inbox as soon as a mail arrives on the mailserver? or should I periodically check for new mail or something? how do you guys do this?

thanks in advance

Johan

I use fetchmail to get my email off of my pop accounts. Then i set up a cron job to check for new mail every 10 mins. Id suggest checking in to fetchmail to recieve mail. Is really easy to setup and is pretty configurealbe.

VoiDeR

Hi Johan,

As well as fetchmail for getting mail, I use procmail to pre-sort all received mail into the correct sub-directories. You can sort by almost any criteria: the subject, who the mail is from, who it is addressed to, country of origin, attachment type, etc. And I also use procmail to copy the header of each newly received mail to a special folder (~/.newmailcount/ mentioned above) for counting new mails.

Regards,

Rob