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 c1567f801455c137acdd24a1c3f816eb9fa58c8f
parent 938f43a2d04f3806ac8f539594dd1bd6197c3449
Author: Jaromil <jaromil@dyne.org>
Date:   Sun,  4 Jan 2015 11:41:57 +0100

reorganized extract_mails functions

Diffstat:
Msrc/zlibs/addressbook | 117++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/zlibs/search | 122+++++++++++++++++++++++++++++++++++++++----------------------------------------
2 files changed, 119 insertions(+), 120 deletions(-)

diff --git a/src/zlibs/addressbook b/src/zlibs/addressbook @@ -222,67 +222,63 @@ forget() { # remove_address "${head[(ws:,:)1]}" } +# extract all addresses found in a list of email files from stdin +extract_mails() { + _mails=`cat` + # we switch dryrun temporarily off to use learn() + # without modifying the addressbook + _dryrun=$DRYRUN + DRYRUN=1 + + # learn from senders, recipients or all + _action="$1" + + typeset -a learned + for m in ${(f)_mails}; do + _l=`hdr $m | learn $_action` + # handles results on multiple lines (recipients, all) + for ii in ${(f)_l}; do + learned+=("$ii") + done + done + + DRYRUN=$_dryrun + # eliminates duplicates + typeset -A result + for i in ${learned}; do + _e=${i[(ws:,:)1]} + [[ "${result[$_e]}" = "" ]] && { + _n=${i[(ws:,:)2]} + result+=("$_e" "$_n") + print - "$_n <$_e>" + } + done + notice "${#result} addresses extracted" +} + # extract all addresses found into a maildir extract_maildir() { ## first arg is a directory md="$1" func "extract maildir: $md" ## extract from a maildir - maildircheck "$md" && { - _action="$2" - case $_action in - all) ;; - recipient) ;; - sender) ;; - *) _action="all" ;; - esac - - # search files - _mails=`find $md -type f` - # search symlinks - _mails+=`find $md -type l` - - # TODO ismailfile() to check if file is a mail? - - # we switch dryrun temporarily off to use learn() - # without modifying the addressbook - _dryrun=$DRYRUN - DRYRUN=1 - - notice "Extracting and listing $_action in maildir: $md" - act "please wait while scanning `print $_mails | wc -l` mail files..." - typeset -a learned - - for i in ${(f)_mails}; do - _l=`hdr $i | learn $_action` - # handles results on multiple lines (recipients, all) - for ii in ${(f)_l}; do - learned+=("$ii") - done - done - - DRYRUN=$_dryrun - # eliminates duplicates - typeset -A result - for i in ${learned}; do - _e=${i[(ws:,:)1]} - [[ "${result[$_e]}" = "" ]] && { - _n=${i[(ws:,:)2]} - result+=("$_e" "$_n") - print - "$_n <$_e>" - } - done - notice "Unique $_action found: ${#result}" - # counts which addresses are known to us - _known=0 - for i in ${(k)result}; do - lookup_email ${i} - [[ $? = 0 ]] && { - _known=$(( $_known + 1 )) } - done - act "addresses known: $_known" - return 0 - } + maildircheck "$md" || return 1 + + _action="$2" + case $_action in + all) ;; + recipient) ;; + sender) ;; + *) _action="all" ;; + esac + + # search files + _mails=`find $md -type f` + # search symlinks + _mails+=`find $md -type l` + + print - ${_mails} | extract_mails "$_action" + return 0 } # extract all entries in addressbook or all addresses in a pgp keyring @@ -389,9 +385,14 @@ extract() { } func "extract from search query" - # args are simply strings, then run a search and extract addresses - nm_search ${=PARAM} - extract_maildir "$MAILDIRS"/cache/notmuch/results all + + # we switch dryrun temporarily off to use learn() + # without modifying the addressbook + _dryrun=$DRYRUN + DRYRUN=1 + + # run a search and list email files + nm_search ${=PARAM} | extract_mails } diff --git a/src/zlibs/search b/src/zlibs/search @@ -43,7 +43,7 @@ nm_setup() { mkdir -p $nm_dir # setup the default tags for all new messages - deftags=${1} + deftags="$1" act "notmuch setup $deftags" @@ -97,7 +97,24 @@ nm_index() { notice "Indexing completed" } + nm_search() { + func "notmuch --config=${nm_dir}/rc search --output=files ${=PARAM}" + + # launch the search with notmuch + search_results=`nm search --output=files ${=PARAM}` + [[ $? = 0 ]] || { + error "notmuch search failed with an error" + return 1 } + act "`print ${search_results} | wc -l` results found" + for i in ${(f)search_results}; do + print $i + done +} + + +# run a search with notmuch and show results with alot +alot_search() { read_account nm_setup @@ -178,25 +195,6 @@ EOF alot -c "$MAILDIRS"/cache/alot/rc -n "$MAILDIRS"/cache/notmuch/rc \ search ${=PARAM} return $? - - func "notmuch --config=${nm_dir}/rc search --output=files ${=PARAM}" - - # launch the search with notmuch - search_results=`nm search --output=files ${=PARAM}` - act "`print ${search_results} | wc -l` results found" - [[ $? = 0 ]] || { - error "notmuch search failed with an error" - return 1 } - - # populate the maildir with results - _resdir="$MAILDIRS"/cache/notmuch/results - func "notmuch results in $_resdir" - rm -rf "$_resdir" - act "populating a maildir with results" - maildirmake $_resdir - for i in ${(f)search_results}; do - ln -s $i "$_resdir/new/`basename $i`" - done } search() { @@ -230,7 +228,7 @@ search() { } # run search across emails - nm_search ${=PARAM} + alot_search ${=PARAM} } backup() { @@ -245,59 +243,59 @@ backup() { # check if the name of a maildir is among params # we need at least 2 maildirs, the second is the destination for p in ${PARAM}; do - c=$(( $c + 1 )) - - if [ $c = ${#PARAM} ]; then - # last one is always the destination - func "destination is ${p}" - fold+=(${p}) - - elif [ -r "${p}" ]; then - - { maildircheck ${p} } && { - func "param ${p} is a maildir" - fold+=(${p}) - { test ${#fold} = 1 } && { - # base path is the dir of the first folder - pushd `dirname ${p}` - basedir=`pwd` - popd } - } - - elif [ -r "${MAILDIRS}/${p}" ]; then - - { maildircheck ${MAILDIRS}/${p} } && { - func "param ${p} is a jaro maildir" - fold+=(${MAILDIRS}/${p}) - } - - else # not a folder, add it to expressions array - func "param ${p} is an expression" - expr+=(${p}) - fi + c=$(( $c + 1 )) + + if [ $c = ${#PARAM} ]; then + # last one is always the destination + func "destination is ${p}" + fold+=(${p}) + + elif [ -r "${p}" ]; then + + { maildircheck ${p} } && { + func "param ${p} is a maildir" + fold+=(${p}) + { test ${#fold} = 1 } && { + # base path is the dir of the first folder + pushd `dirname ${p}` + basedir=`pwd` + popd } + } + + elif [ -r "${MAILDIRS}/${p}" ]; then + + { maildircheck ${MAILDIRS}/${p} } && { + func "param ${p} is a jaro maildir" + fold+=(${MAILDIRS}/${p}) + } + + else # not a folder, add it to expressions array + func "param ${p} is an expression" + expr+=(${p}) + fi done { test ${#fold} -lt 2 } && { - error "Not enough folders specified for backup: minimum is 2" - act "When specifying more than 2, the last one is the destination" - return 1 + error "Not enough folders specified for backup: minimum is 2" + act "When specifying more than 2, the last one is the destination" + return 1 } dst=${fold[${#fold}]} { test -r "$dst" } || { maildirmake "${dst}" } { test ${#expr} = 0 } && { - error "No expression set for backup, please indicate what you want to backup" - act "For example: d:10y-2y (all mails older than 1 year up to 10 years ago)" - act "Or a simple search string, all expressions can be verified using search." - return 1 + error "No expression set for backup, please indicate what you want to backup" + act "For example: d:10y-2y (all mails older than 1 year up to 10 years ago)" + act "Or a simple search string, all expressions can be verified using search." + return 1 } # forge the folder string for mairix conf folders="" for f in ${=fold}; do - { test $f = $dst } || { - folders="$folders`basename $f`:" } + { test $f = $dst } || { + folders="$folders`basename $f`:" } done notice "Backup of all mails in '$folders' matching expression '$expr'" @@ -321,8 +319,8 @@ mformat=maildir EOF mairix -F -f ${mairixrc} -t -M ${expr} { test -r $basedir/$tempdst } && { - merge $basedir/$tempdst $dst - notice "Destination folder size is `du -hs $dst | awk '{print $1}'`" + merge $basedir/$tempdst $dst + notice "Destination folder size is `du -hs $dst | awk '{print $1}'`" } ${=rm} ${mairixrc}