jaromail

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

mutt (10777B)


      1 #!/usr/bin/env zsh
      2 #
      3 # Jaro Mail, your humble and faithful electronic postman
      4 #
      5 # a tool to easily and privately handle your e-mail communication
      6 #
      7 # Copyright (C) 2017 Dyne.org Foundation
      8 #
      9 # JaroMail is designed, written and maintained by Denis Roio <jaromil@dyne.org>
     10 #
     11 # This source  code is free  software; you can redistribute  it and/or
     12 # modify it under the terms of  the GNU Public License as published by
     13 # the Free  Software Foundation; either  version 3 of the  License, or
     14 # (at your option) any later version.
     15 #
     16 # This source code is distributed in  the hope that it will be useful,
     17 # but  WITHOUT ANY  WARRANTY;  without even  the  implied warranty  of
     18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     19 # Please refer to the GNU Public License for more details.
     20 #
     21 # You should have received a copy of the GNU Public License along with
     22 # this source code; if not, write to:
     23 # Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     24 
     25 
     26 is_mutt_kz() {
     27 	fn is_mutt_kz
     28 	req=(MAILDIRS)
     29 	ckreq || return 1
     30 
     31     rm -f "$MAILDIRS/.mutt/notmuch"
     32     touch "$MAILDIRS/.mutt/notmuch"
     33     kz=`mutt -v | awk '/Configure options.*enable-notmuch/ { print $0 }'`
     34     if [[ "$kz" = "" ]]; then
     35          return 1
     36     else
     37         act "Notmuch powered mutt-kz detected, enabling extra features"
     38         return 0
     39     fi
     40 }
     41 
     42 use_notmuch() {
     43 	fn is_notmuch
     44 	req=(MAILDIRS subcommand)
     45 	ckreq || return 1
     46 	[[ -r "$MAILDIRS"/cache/notmuch/rc ]] &&
     47 		[[ "$subcommand" != "peek" ]]
     48 }
     49 
     50 x_mutt() {
     51 	fn x_mutt $*
     52 	req=(MAILDIRS WORKDIR)
     53 	ckreq || return 1
     54 
     55 	# main conf
     56     ${=mkdir} "$MAILDIRS/.mutt"
     57     ${=mkdir} "$MAILDIRS/.mutt"/cache
     58     rm -f "$MAILDIRS/.mutt"/rc
     59 
     60 
     61 	# detect the default gpg key to always encrypt also to self
     62 	# update: do not re-encrypt if already done
     63 	gpgkey=""
     64 	[[ -r $HOME/.gnupg/gpg.conf ]] && {
     65 		gpgkey=`awk '/^default-key/ { print $2 }' $HOME/.gnupg/gpg.conf`
     66 		act "GPG key in use: $gpgkey"
     67 	}
     68 
     69     cat<<EOF > "$MAILDIRS/.mutt"/rc
     70 #### Mutt config automatically generated by Jaro Mail
     71 ### do not edit: this file is overwritten by jaro update
     72 ### put your customizations in \$MAILDIRS/Identity.txt
     73 
     74 unset use_domain
     75 set folder = '$MAILDIRS'
     76 set spoolfile = '$MAILDIRS/known/'
     77 set record = '$MAILDIRS/sent/'
     78 set postponed= '$MAILDIRS/postponed/'
     79 set tmpdir = '$MAILDIRS/.mutt/cache'
     80 set sendmail = "$WORKDIR/bin/jaro -q queue"
     81 set header_cache= '$MAILDIRS/.mutt/cache'
     82 set maildir_header_cache_verify=no
     83 set editor = "$WORKDIR/bin/jaro -q edit"
     84 set mailcap_path = "$MAILDIRS/.mutt/mailcap:$MAILDIRS/mailcap:$HOME/.mailcap:/etc/mailcap:/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap"
     85 
     86 # Little Brother Database
     87 set query_command = "$WORKDIR/bin/jaro -q complete '%s'"
     88 macro index,pager a "<pipe-message>$WORKDIR/bin/jaro -l whitelist -q learn sender<enter>" "add to whitelist everyone in the message"
     89 macro index,pager A "<pipe-message>$WORKDIR/bin/jaro -l whitelist -q learn all<enter>" "add all addresses in whitelist"
     90 macro index,pager z "<pipe-message>$WORKDIR/bin/jaro -l blacklist -q learn sender<enter>" "add sender to blacklist"
     91 
     92 
     93 # specific configuration files
     94 source '$WORKDIR/.mutt/gpg'
     95 source '$WORKDIR/.mutt/crypto'
     96 source '$WORKDIR/.mutt/general'
     97 source '$WORKDIR/.mutt/formats'
     98 source '$WORKDIR/.mutt/keybindings'
     99 source '$WORKDIR/.mutt/colors'
    100 
    101 # identity built parsing accounts and global file
    102 source '$MAILDIRS/Identity.txt'
    103 source '$MAILDIRS/.mutt/identity'
    104 
    105 # pointer to password tempfile and dynamic settings
    106 # must be before mboxes to set folder on imap peek
    107 source '$MAILDIRS/.mutt/muttpass'
    108 
    109 # mailboxes in order of priority
    110 source '$MAILDIRS/.mutt/mboxes'
    111 
    112 # extra settings for mutt-kz (notmuch enabled)
    113 source '$MAILDIRS/.mutt/notmuch'
    114 
    115 # crypto support
    116 source '$MAILDIRS/.mutt/crypto'
    117 EOF
    118 
    119 	# identity
    120 	rm -f "$MAILDIRS/.mutt/identity"
    121 	touch "$MAILDIRS/.mutt/identity"
    122 	cat <<EOF > $MAILDIRS/.mutt/identity
    123 set realname = '$name'
    124 set from = '${name} <${email}>'
    125 EOF
    126 	[[ "$gpgkey" = "" ]] ||
    127 		print "set pgp_sign_as = '${gpgkey}'" >> $MAILDIRS/.mutt/identity
    128 	[[ -r ~/.signature ]] &&
    129 		print "set signature = '~/.signature'" >> $MAILDIRS/.mutt/identity
    130 	[[ "$my_hdr" = "" ]] ||
    131 		print "$my_hdr" >> $MAILDIRS/.mutt/identity
    132 
    133 
    134 	rm -f "$MAILDIRS/.mutt/crypto"
    135 	touch "$MAILDIRS/.mutt/crypto"
    136 	# support opmux or fallback to gpgewrap
    137 	cryptowrap=${$(command -v opmux):-gpgewrap}
    138 
    139 	case $cryptowrap in
    140 		*opmux)
    141 			cat <<EOF > "$MAILDIRS/.mutt/crypto"
    142 # Generated by JaroMail at every execution
    143 set pgp_long_ids
    144 
    145 set pgp_decode_command="OPMUX_MUA=mutt ${cryptowrap} --passphrase-fd 0 \
    146 	--quiet --batch --output - %f"
    147 set pgp_verify_command="OPMUX_MUA=mutt ${cryptowrap} --quiet --batch \
    148 	--output - --verify %s %f"
    149 set pgp_decrypt_command="OPMUX_MUA=mutt ${cryptowrap} --passphrase-fd 0 \
    150 	--quiet --batch --output - %f"
    151 
    152 set pgp_encrypt_only_command="${cryptowrap} --batch --quiet --output - \
    153 	--encrypt --textmode --armor --always-trust -r '%r' %f"
    154 set pgp_encrypt_sign_command="${cryptowrap} --passphrase-fd 0 --batch \
    155 	--quiet --textmode --output - --encrypt --sign %?a?-u %a? --armor \
    156 	--always-trust -r '%r' %f"
    157 
    158 set pgp_list_pubring_command="${cryptowrap} --batch --quiet --with-colons \
    159 	--list-keys %r"
    160 
    161 ## XXX: currently added in Identity.txt
    162 # set pgp_decryption_okay="^opmux: SUCCESS\.$"
    163 EOF
    164 			;;
    165 		gpgewrap)
    166 			[[ "$gpgkey" = "" ]] || {
    167 				cat <<EOF > "$MAILDIRS/.mutt/crypto"
    168 # Generated by JaroMail at every execution
    169 # create a pgp/mime encrypted attachment
    170 set pgp_encrypt_only_command="gpgewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust --encrypt-to $gpgkey -- -r %r -- '%f'"
    171 set pgp_encrypt_sign_command="gpgewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust --encrypt-to $gpgkey -- -r %r -- '%f'"
    172 EOF
    173 			}
    174 			;;
    175 	esac
    176 
    177 	unset cryptowrap
    178 
    179     # MUTT MAILCAP
    180 
    181 	# charset conversion
    182     cat <<EOF > $MAILDIRS/.mutt/mailcap
    183 text/plain; iconv -f iso-8859-1 -t utf-8; test=charset=%{charset} \
    184   && test x`echo \"$charset\" | tr a-z A-Z` = xISO-8859-1; copiousoutput
    185 text/plain; cat %s
    186 EOF
    187 
    188 	# HTML conversion
    189     wwwtext=w3m
    190     if command -v elinks > /dev/null; then
    191     cat <<EOF >> $MAILDIRS/.mutt/mailcap
    192 text/html; elinks -dump -dump-charset %{charset} %s; nametemplate=%s.html; copiousoutput
    193 EOF
    194     elif command -v w3m > /dev/null; then
    195     cat <<EOF >> $MAILDIRS/.mutt/mailcap
    196 text/html; w3m -I %{charset} -T text/html %s; nametemplate=%s.html; copiousoutput
    197 EOF
    198     elif command -v lynx > /dev/null; then
    199     cat <<EOF >> $MAILDIRS/.mutt/mailcap
    200 text/html; lynx -dump -assume_charset=%{charset} %s; nametemplate=%s.html; copiousoutput
    201 EOF
    202     fi
    203 
    204 	command -v vcal > /dev/null && {
    205 		# VCAL conversion
    206 	cat <<EOF >> $MAILDIRS/.mutt/mailcap
    207 text/calendar; vcal --all %s; nametemplate=%s.vcal; copiousoutput
    208 EOF
    209 	}
    210 
    211     { test -r "${MAILDIRS}/Applications.txt" } && {
    212 
    213         # here is the tweak to open attachments
    214         # with Mutt without blocking it (fork)
    215 
    216         apptypes=`cat "${MAILDIRS}/Applications.txt"`
    217         for t in ${(f)apptypes}; do
    218             eval `print $t | awk '
    219     { print "_type=" $1 "; _app=" $2 ";" }'`
    220             cat <<EOF >> $MAILDIRS/.mutt/mailcap
    221 ${_type}; a="${MAILDIRS}/tmp" && f=\`basename %s\` && rm -f "\$a"/"\$f" && cp %s "\$a"/"\$f" && ${_app} "\$a"/"\$f"
    222 EOF
    223         done
    224         cat <<EOF >> $MAILDIRS/.mutt/mailcap
    225 application/*; a="${MAILDIRS}/tmp" && f=\`basename %s\` && rm -f "\$a"/"\$f" && cp %s "\$a"/"\$f" && jaro preview "\$a"/"\$f"
    226 EOF
    227     } # Applications.txt
    228 
    229 
    230 
    231 	rm -f "$MAILDIRS/.mutt/notmuch"
    232 	touch "$MAILDIRS/.mutt/notmuch"
    233     # when peeking and using mutt-kz use the sidebar
    234     is_mutt_kz && {
    235 
    236 		# avoid hangs at boot for files not found
    237 		mkdir -p $MAILDIRS/.notmuch
    238 		touch $MAILDIRS/.notmuch/xapian
    239 
    240         cat <<EOF >> "$MAILDIRS/.mutt/notmuch"
    241 set sidebar_width	 = 25
    242 set sidebar_visible	 = no
    243 
    244 color sidebar_new white default
    245 color progress default magenta
    246 
    247 bind index p sidebar-prev
    248 bind index n sidebar-next
    249 bind index <space> sidebar-open
    250 
    251 macro pager S "<enter-command>toggle sidebar_visible<enter>"
    252 macro index S "<enter-command>toggle sidebar_visible<enter>"
    253 
    254 EOF
    255 
    256 		use_notmuch && {
    257 			# enable mutt-kz extra functions for notmuch integration
    258 			cat <<EOF >> "$MAILDIRS/.mutt/notmuch"
    259 
    260 bind index / vfolder-from-query
    261 bind pager / vfolder-from-query
    262 
    263 set index_format="%2C %Z %?GI?%GI& ? %[%d/%b]  %-16.16F (%4c) %?M?(%3M)& ? %s %>"
    264 # for tags at end of index add %?g?%g?
    265 set virtual_spoolfile = yes
    266 virtual-mailboxes \
    267 "  Today" "notmuch://?query=     date:1d.. and tag:inbox" \
    268 "  Last week" "notmuch://?query= date:1w.. and tag:inbox" \
    269 "  Last month" "notmuch://?query=date:1M.. and tag:inbox" \
    270 "  Last year" "notmuch://?query=date:1y.. and tag:inbox" \
    271 "  Last 3yrs" "notmuch://?query=date:3y.. and tag:inbox" \
    272 \
    273 "ATTACHMENTS" "notmuch://?query=attachment:* and tag:inbox" \
    274 "  Today" "notmuch://?query=attachment:* and date:1d.. and tag:inbox" \
    275 "  Last week" "notmuch://?query=attachment:* and date:1w.. and tag:inbox" \
    276 "  Last month" "notmuch://?query=attachment:* and date:1M.. and tag:inbox" \
    277 "  Last year" "notmuch://?query=attachment:* and date:1y.. and tag:inbox" \
    278 "  Last 3yrs" "notmuch://?query=attachment:* and date:3y.. and tag:inbox"
    279 
    280 EOF
    281 		}
    282 	}
    283     rm -f $MAILDIRS/.mutt/mboxes
    284 
    285     for i; do _fa+=" $i "; done
    286     func "exec: mutt -F $MUTTDIR/rc ${=muttflags} ${_fa}"
    287 
    288 	ztmp
    289 	_mboxes=$ztmpfile
    290 
    291 
    292     # this one is empty and sources files in temp when necessary
    293     rm -f "$MAILDIRS/.mutt/muttpass"
    294     touch "$MAILDIRS/.mutt/muttpass"
    295     if [[ "$subcommand" = "peek" ]]; then
    296 		func "x_mutt peek"
    297 		# when peeking don't mark unread messages as Old
    298 		# and sort date received with no threading (latest up)
    299 		# also set the spoolfile name to INBOX (imap's default)
    300 		sysread -o 1 <<EOF > "$MAILDIRS/.mutt/muttpass"
    301 set imap_pass = \`$WORKDIR/bin/jaro -a ${account} askpass\`
    302 unset mark_old
    303 set sort=reverse-date-received
    304 set folder=${iproto}://${ilogin}@${imap}:${imap_port}
    305 set spoolfile=${iproto}://${ilogin}@${imap}:${imap_port}/INBOX
    306 EOF
    307 
    308 		print -n "mailboxes +INBOX +priv" > $_mboxes
    309 	else
    310 		print -n "mailboxes +known +priv" > $_mboxes
    311 	fi
    312 
    313     # make the mailboxes according to filters and such
    314 
    315     for f in `cat "$MAILDIRS/Filters.txt" | awk '
    316     /^#/ {next}
    317     /^./ { print $4 }'`; do
    318         # MUTT (generate mailboxes priority this parser)
    319         print  " \\" >> $_mboxes
    320         print -n " +${f} " >> $_mboxes
    321     done
    322     print " \\" >> $_mboxes
    323     print " +unsorted.ml +unsorted" >> $_mboxes
    324 
    325     uniq $_mboxes > $MAILDIRS/.mutt/mboxes
    326 
    327     # schedule deletion of muttpass file after use
    328     sched +3 "
    329 rm -f $MAILDIRS/.mutt/muttpass
    330 touch $MAILDIRS/.mutt/muttpass"
    331 
    332     mutt -F $MUTTDIR/rc ${=muttflags} ${=_fa}
    333     return $?
    334 }