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:
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