jaromail

a commandline tool to easily and privately handle your e-mail
git clone git://parazyd.org/jaromail.git
Log | Files | Refs | Submodules | README

commit 094315f11e2bf04a70a81b0e06bec6b427631f50
parent 2203f35f467e883ab236d71bab9dbcb6c1465788
Author: Jaromil <jaromil@dyne.org>
Date:   Tue, 28 Aug 2012 12:54:56 +0200

fix and speedup to addressbook filtering

Diffstat:
Msrc/jaro | 19+++++++++++++++----
Msrc/zlibs/addressbook | 31+++++++++++--------------------
Msrc/zlibs/email | 17++++++++++++-----
Msrc/zlibs/filters | 8++++----
4 files changed, 42 insertions(+), 33 deletions(-)

diff --git a/src/jaro b/src/jaro @@ -60,9 +60,12 @@ list=whitelist # global variables for accounts typeset -h name login host protocol port password auth folders accountopt +# global variables for addressbook +typeset -h hostname addressbook addressbook_tmp + # global array for maildirs (filled by list_maildirs) typeset -al maildirs - + # global variable for exit code typeset exitcode exitcode=0 @@ -175,6 +178,14 @@ ${=mkdir} "$TMPDIR" error "Cannot create temporary directory: $TMPDIR" return 1 } +# make sure we have an addressbook +# use the one in RAM if present, for acceleration +hostname=$(hostname) # gather the current hostname +addressbook=$WORKDIR/addressbook +addressbook_tmp=$TMPDIR/${USER}.${hostname}.addressbook +{ test -r "$addressbook" } || { create_addressbook } +{ test -r "$addressbook_tmp" } && { addressbook="$addressbook_tmp" } + ${=mkdir} "$WORKDIR/cache" ${=mkdir} "$WORKDIR/log" ${=mkdir} "$WORKDIR/certs" @@ -216,7 +227,7 @@ TRAPINT() { else exit 1; fi } - + check_bin() { # check for required programs for req in pinentry fetchmail procmail mutt; do @@ -457,8 +468,8 @@ main() cat $JAROMAILEXEC | awk 'BEGIN { v=1 } !/^#/ { exit }' return 0 } { option_is_set -q } && { QUIET=1 } - { option_is_set -D } && { DEBUG=1 - func "Debug messages ON" } + { option_is_set -D } && { DEBUG=1; QUIET=0 + func "All debug messages ON" } { option_is_set -n } && { DRYRUN=1 act "Dry run, show operations without executing them." } diff --git a/src/zlibs/addressbook b/src/zlibs/addressbook @@ -26,7 +26,7 @@ # Jaro Brother DB create_addressbook() { func "create addressbook" - { test -r $WORKDIR/addressbook } && { + { test -r "$WORKDIR/addressbook" } && { error "Addressbook already exists: $WORKDIR/addressbook" return 1 } @@ -51,7 +51,7 @@ EOF } insert_address() { func "insert address: $1, $2" - cat <<EOF | ${SQL} -batch $WORKDIR/addressbook 2> /dev/null + cat <<EOF | ${SQL} -batch ${addressbook} 2> /dev/null INSERT INTO $list (email, name) VALUES ("${1}", "${2}"); EOF @@ -73,7 +73,7 @@ EOF remove_address() { func "remove address <$1> from $list" - cat <<EOF | ${SQL} -batch $WORKDIR/addressbook + cat <<EOF | ${SQL} -batch ${addressbook} DELETE FROM $list WHERE email IS "${1}"; EOF @@ -82,7 +82,7 @@ EOF } search_name() { func "search_name from $list like $1" - cat <<EOF | ${SQL} -column -batch $WORKDIR/addressbook + cat <<EOF | ${SQL} -column -batch ${addressbook} .width 64 128 SELECT * FROM $list WHERE name LIKE "%${1}%"; @@ -90,7 +90,7 @@ EOF } search_email() { func "search email from $list is $1" - cat <<EOF | ${SQL} -column -batch $WORKDIR/addressbook + cat <<EOF | ${SQL} -column -batch ${addressbook} SELECT rowid FROM $list WHERE email IS "${1}"; EOF @@ -98,7 +98,6 @@ EOF } complete() { func "complete from $list: ${PARAM[1]}" - { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } act "Searching for \"${PARAM[1]}\" in $list" { test "$OS" = "MAC" } && { @@ -119,7 +118,6 @@ complete() { } isknown() { func "is known in $list: (string from stdin)" - { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } head="`${WORKDIR}/bin/fetchaddr -x From: -a`" @@ -137,7 +135,6 @@ isknown() { learn() { func "learn ${PARAM[1]} from mail in stdin" - { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } what=sender { test -z ${PARAM[1]} } || { what=${PARAM[1]} } @@ -172,7 +169,6 @@ learn() { forget() { func "forget sender from mail in stdin" - { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } act "Expecting mail from stdin pipe" head="`${WORKDIR}/bin/fetchaddr -x From:`" @@ -182,12 +178,11 @@ forget() { } list_addresses() { func "list addresses in ${PARAM[1]}" - { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } { test ${PARAM[1]} } && { list=${PARAM[1]} } act "Listing all contents for $list" - cat <<EOF | ${SQL} -column -header -batch $WORKDIR/addressbook + cat <<EOF | ${SQL} -column -header -batch ${addressbook} .width 32 40 SELECT * FROM $list; EOF @@ -197,9 +192,8 @@ EOF # import addresbook email from VCard import_vcard() { func "import VCard from file ${PARAM[1]}" - { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } - { test -r ${PARAM[1]} } || { + { test -r "${PARAM[1]}" } || { error "File not found: import ${PARAM[1]}" return 1 } @@ -265,12 +259,11 @@ BEGIN { newcard=0; c=0; name=""; email=""; } # export addressbook to vcard export_vcard() { - { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } act "Export addressbook into vCard $WORKDIR/addressbook.vcf" tmp=$TMPDIR/export.$datestamp.$RANDOM - cat <<EOF | ${SQL} -column -header -batch $WORKDIR/addressbook \ + cat <<EOF | ${SQL} -column -header -batch ${addressbook} \ | grep -v '^email' > $tmp .width 40 100 .mode list @@ -302,8 +295,6 @@ EOF } edit_abook() { - { test ! -r ${WORKDIR}/addressbook } && { create_addressbook } - # take argument even without option -l { test -z ${PARAM[1]} } || { list=${PARAM[1]} } @@ -313,7 +304,7 @@ edit_abook() { tmpread=$TMPDIR/abook.read.$datestamp.$RANDOM newlock $tmpread - cp $WORKDIR/addressbook $tmpread + cp ${addressbook} $tmpread cat <<EOF | ${SQL} -column -header -batch $tmpread \ | grep -v '^email' > $tmp .width 40 100 @@ -422,10 +413,10 @@ EOF func "Inserting the updated addressbook" tmpwrite=$TMPDIR/abook.write.$datestamp.$RANDOM newlock $tmpwrite - cp $WORKDIR/addressbook $tmpwrite + cp ${addressbook} $tmpwrite cat $tmp | ${SQL} -batch $tmpwrite 2> /dev/null unlink $tmp - cp $tmpwrite $WORKDIR/addressbook + cp $tmpwrite ${addressbook} unlink $tmpwrite notice "Addressbook updated" } diff --git a/src/zlibs/email b/src/zlibs/email @@ -113,11 +113,11 @@ fetch() { # get_imap_info # return here if the imap folders are all empty - { test ${imap_info[${#imap_info}]} = 0 } && { - act "Mailbox is empty, nothing to fetch." - return 0 } + # { test ${imap_info[${#imap_info}]} = 0 } && { + # act "Mailbox is empty, nothing to fetch." + # return 0 } - notice "Total occupation is `human_size ${imap_info[${#imap_info}]}`" + # notice "Total occupation is `human_size ${imap_info[${#imap_info}]}`" { test $DRYRUN != 1 } && { @@ -176,6 +176,11 @@ EOF rm -f $WORKDIR/log/procmail.log unlock $WORKDIR/log/procmail-${datestamp}.log fi + + # copy addressbook in RAM for speedup + newlock $addressbook_tmp + cp $WORKDIR/addressbook $addressbook_tmp + act "please wait while downloading mails..." cat $tmp | fetchmail -f $tmp @@ -183,6 +188,7 @@ EOF # to avoid writing the password in clear on filesystem unlink $tmp + unlink $addressbook_tmp total=`mailstat -k $WORKDIR/log/procmail.log | tail -n1 | awk '{print $2}'` briefing=`mailstat -kt $WORKDIR/log/procmail.log |awk '!/procmail/ { print " " $2 "\t" $3 }'|sort -nr` @@ -324,7 +330,8 @@ EOF later() { func "Saving message from stdin into remember" - filename=$USER.$(hostname).$datestamp.$RANDOM + filename=$USER.${hostname}.$datestamp.$RANDOM + # hostname was set by the main jaro routine func "Filename: $filename" maildircheck ${MAILDIRS}/remember { test $? = 0 } || { maildirmake ${MAILDIRS}/remember } diff --git a/src/zlibs/filters b/src/zlibs/filters @@ -127,7 +127,7 @@ require "fileinto"; if header :contains "From" [ EOF newlock $TMPDIR/blacklist.sieve.$id - cat <<EOF | ${SQL} -batch $WORKDIR/addressbook \ + cat <<EOF | ${SQL} -batch ${addressbook} \ >> $TMPDIR/blacklist.sieve.$id SELECT email FROM blacklist; EOF @@ -187,7 +187,7 @@ PF_RECURSE = yes # blacklist filters :0 w: -* ? \$JARO -l blacklist -q query from: +* ? \$JARO -l blacklist -q isknown zz.blacklist/ # if its a mailinglist bounce, save it to zz.bounces @@ -291,7 +291,7 @@ cat <<EOF >> $sieve if header :contains "From" [ EOF newlock $TMPDIR/whitelist.sieve.$id -cat <<EOF | ${SQL} -batch $WORKDIR/addressbook \ +cat <<EOF | ${SQL} -batch ${addressbook} \ >> $TMPDIR/whitelist.sieve.$id SELECT email FROM whitelist; EOF @@ -332,7 +332,7 @@ EOF # whitelisting filters :0 w: -* ? \$JARO -l whitelist -q query from: +* ? \$JARO -l whitelist -q isknown known/ # spam filters