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 }