Browse Source

Merge branch 'shortcuts'

pull/276/head
Roland Puntaier 5 years ago
parent
commit
c9857afc86
6 changed files with 247 additions and 207 deletions
  1. +1
    -1
      README.md
  2. +1
    -5
      bin/mailsync
  3. +184
    -164
      bin/mw
  4. +14
    -11
      mw.1
  5. +8
    -9
      test/dotests
  6. +39
    -17
      test/test_mw.bats

+ 1
- 1
README.md View File

@@ -41,7 +41,7 @@ Once everything is setup, you'll use `neomutt` to access your mail.
- `mw ls` -- list existing accounts - `mw ls` -- list existing accounts
- `mw pass` -- revise an account's password - `mw pass` -- revise an account's password
- `mw delete` -- deleted an added account - `mw delete` -- deleted an added account
- `mw purge` -- delete all accounts and settings
- `mw purge` -- delete all accounts and settings (**DANGER**)
- `mw cron` -- toggle/configure a cronjob to sync mail - `mw cron` -- toggle/configure a cronjob to sync mail


## Dependencies ## Dependencies


+ 1
- 5
bin/mailsync View File

@@ -15,11 +15,7 @@ fi
configdir=${XDG_CONFIG_HOME:-$HOME/.config} configdir=${XDG_CONFIG_HOME:-$HOME/.config}
maildir="${MAILDIR:-$HOME/Mail}" maildir="${MAILDIR:-$HOME/Mail}"
lastrun=${XDG_CACHE_HOME:-$HOME/.cache}/.mailsynclastrun lastrun=${XDG_CACHE_HOME:-$HOME/.cache}/.mailsynclastrun
if [[ -f $configdir/isync/mbsyncrc ]]; then
mbsyncrc="$configdir/isync/mbsyncrc"
else
mbsyncrc="$HOME/.mbsyncrc"
fi
mbsyncrc="$configdir/isync/mbsyncrc"
mbsyncbin="$prefix/bin/mbsync -c $mbsyncrc" mbsyncbin="$prefix/bin/mbsync -c $mbsyncrc"


# Run only if user logged in (prevent cron errors) # Run only if user logged in (prevent cron errors)


+ 184
- 164
bin/mw View File

@@ -1,23 +1,23 @@
#!/bin/sh #!/bin/sh


if [ "$#" -gt 1 ]; then if [ "$#" -gt 1 ]; then
echo "To many arguments. You will be asked."
exit
echo "To many arguments. You will be asked."
exit
fi fi


if [ -z "$prefix" ]; then if [ -z "$prefix" ]; then
case "$(uname)" in
Linux) prefix="/usr" ;;
*) prefix="/usr/local" ;;
esac
case "$(uname)" in
Linux) prefix="/usr" ;;
*) prefix="/usr/local" ;;
esac
fi fi


command -V gpg >/dev/null 2>&1 && GPG="gpg" || GPG="gpg2" command -V gpg >/dev/null 2>&1 && GPG="gpg" || GPG="gpg2"
[ -z "$PASSWORD_STORE_DIR" ] && PASSWORD_STORE_DIR="$HOME/.password-store" [ -z "$PASSWORD_STORE_DIR" ] && PASSWORD_STORE_DIR="$HOME/.password-store"
[ -r "$PASSWORD_STORE_DIR/.gpg-id" ] && [ -r "$PASSWORD_STORE_DIR/.gpg-id" ] &&
"$GPG" --list-secret-keys $(cat "$PASSWORD_STORE_DIR/.gpg-id") >/dev/null 2>&1 || {
printf "\`pass\` must be installed and initialized to encrypt passwords.\\nBe sure it is installed and run \`pass init <yourgpgemail>\`.\\nIf you don't have a GPG public private key pair, run \`$GPG --full-gen-key\` first.\\n"
exit
"$GPG" --list-secret-keys $(cat "$PASSWORD_STORE_DIR/.gpg-id") >/dev/null 2>&1 || {
printf "\`pass\` must be installed and initialized to encrypt passwords.\\nBe sure it is installed and run \`pass init <yourgpgemail>\`.\\nIf you don't have a GPG public private key pair, run \`$GPG --full-gen-key\` first.\\n"
exit
} }
! command -v "$prefix/bin/mbsync" >/dev/null && printf "\`mbsync\` must be installed to run mutt-wizard.\\n" && exit ! command -v "$prefix/bin/mbsync" >/dev/null && printf "\`mbsync\` must be installed to run mutt-wizard.\\n" && exit
! command -v "$prefix/bin/msmtp" >/dev/null && printf "\`msmtp\` must be installed.\\n" && exit ! command -v "$prefix/bin/msmtp" >/dev/null && printf "\`msmtp\` must be installed.\\n" && exit
@@ -27,72 +27,71 @@ mwconfigdir=${XDG_CONFIG_HOME:-$HOME/.config}
# Main mutt config location # Main mutt config location
mwmuttdir="$mwconfigdir/mutt" mwmuttdir="$mwconfigdir/mutt"
# Directory for account settings # Directory for account settings
mwaccrcdir="$mwmuttdir/accounts"
mwaccmuttdir="$mwmuttdir/accounts"
# Location of mail storage # Location of mail storage
mwmaildir="${MAILDIR:-$HOME/mail}" mwmaildir="${MAILDIR:-$HOME/mail}"
# Regex to confirm valid email address # Regex to confirm valid email address
mwemailre=".\+@.\+\\..\+" mwemailre=".\+@.\+\\..\+"
mwshare="$prefix/share/mutt-wizard" mwshare="$prefix/share/mutt-wizard"
if [ -n "$XDG_CONFIG_HOME" ]; then
mwmbsyncrc="$mwconfigdir/isync/mbsyncrc"
else
mwmbsyncrc="$HOME/.mbsyncrc"
fi
mwsharerc="$mwshare/mutt-wizard.muttrc"
mwcachedir="${XDG_CACHE_HOME:-$HOME/.cache}/mutt-wizard"
mwmuttrc="$mwmuttdir/muttrc" mwmuttrc="$mwmuttdir/muttrc"
mwmbsyncrc="$mwconfigdir/isync/mbsyncrc"
mwmsmtprc="$mwconfigdir/msmtp/config" mwmsmtprc="$mwconfigdir/msmtp/config"
mwsharerc="$mwshare/mutt-wizard.muttrc"
mwcachedir="${XDG_CACHE_HOME:-$HOME/.cache}/mutt-wizard"
mwssltype="IMAPS" mwssltype="IMAPS"
mbsyncbin="$prefix/bin/mbsync -c $mwmbsyncrc" mbsyncbin="$prefix/bin/mbsync -c $mwmbsyncrc"
msmtpbin="$prefix/bin/msmtp" msmtpbin="$prefix/bin/msmtp"
takemwaddr(){
_mwaddrmwtype(){
mwacc="$mwaddr" # let the user always just deal with his email mwacc="$mwaddr" # let the user always just deal with his email
mwaccmutt="${mwaddr//[.@]/_}" # but mutt would not show it with an @ or . mwaccmutt="${mwaddr//[.@]/_}" # but mutt would not show it with an @ or .
mwacccachedir=$mwcachedir/${mwaddr//[.@]/_} # @ cannot stay because of mutt, . could mwacccachedir=$mwcachedir/${mwaddr//[.@]/_} # @ cannot stay because of mutt, . could
mwaccmaildir="$mwmaildir/$mwaccmutt" # folder name as shown by mutt and opens with gf in vim mwaccmaildir="$mwmaildir/$mwaccmutt" # folder name as shown by mutt and opens with gf in vim
mwaccmuttrc="$mwaccmuttdir/$mwidnum-$mwacc.mwonofftype.$mwtype.muttrc"
mwpass=mutt-wizard-$mwaddr
[ -n "$mwidnum" ] && mwaccmuttrc="$mwaccmuttdir/$mwidnum-$mwacc.mwonofftype.$mwtype.muttrc"
} }


for x in "/etc/ssl/certs/ca-certificates.crt" "/etc/pki/tls/certs/ca-bundle.crt" "/etc/ssl/ca-bundle.pem" "/etc/pki/tls/cacert.pem" "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem" "/etc/ssl/cert.pem" "/usr/local/share/ca-certificates/"
for mwcrt in "/etc/ssl/certs/ca-certificates.crt" "/etc/pki/tls/certs/ca-bundle.crt" "/etc/ssl/ca-bundle.pem" "/etc/pki/tls/cacert.pem" "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem" "/etc/ssl/cert.pem" "/usr/local/share/ca-certificates/"
do do
[ -f "$x" ] && sslcert="$x" && break
[ -f "$mwcrt" ] && mwsslcert="$mwcrt" && break
done || { echo "CA Certificate not found. Please install one or link it to /etc/ssl/certs/ca-certificates.crt" && exit 1 ;} done || { echo "CA Certificate not found. Please install one or link it to /etc/ssl/certs/ca-certificates.crt" && exit 1 ;}


getaccounts() {
accounts="$(find "$mwaccrcdir" -type f | grep -o "[0-9]-.*.muttrc" | sed "s/-/: /;s/\.muttrc//" | sort -n)"
_mwgetaccounts() {
mwaccounts="$(find "$mwaccmuttdir" -type f | grep -o "[1-9]-.*.muttrc" | sed "s/-/: /;s/\.muttrc//" | sort -n)"
} }


mwlist() {
getaccounts && [ -n "$accounts" ] && echo "$accounts"
_mwlist() {
_mwgetaccounts && [ -n "$mwaccounts" ] && echo "${mwaccounts//.mwonofftype./ }"
} }


mwadd() {
asktype && askinfo && tryconnect && finalize || mwdelete
_mwadd() {
_mwasktype && _mwaskinfo && _mwtryconnect && _mwfinalize || _mwdelete
} }


getprofiles() {
unset msmtp_header msmtp_profile mutt_profile mbsync_profile
_mwgetprofiles() {
unset mwmsmtpheader mwmsmtpprofile mwmuttprofile mwmbsyncprofile
printf "Creating profiles for \`%s\`..." "$mwaddr" printf "Creating profiles for \`%s\`..." "$mwaddr"
msmtp_header="defaults
mwmsmtpheader="defaults
auth on auth on
tls on tls on
tls_trust_file $sslcert
tls_trust_file $mwsslcert
logfile ${XDG_LOG_HOME:-$HOME}/msmtp.log logfile ${XDG_LOG_HOME:-$HOME}/msmtp.log
" "
msmtp_profile="account $mwacc
mwmsmtpprofile="account $mwacc
host $mwsmtp host $mwsmtp
port $mwsport port $mwsport
from $mwaddr from $mwaddr
user $mwlogin user $mwlogin
passwordeval \"pass $mwpass\" passwordeval \"pass $mwpass\"
$starttlsoff
$mwstarttlsoff
" "
mbsync_profile="IMAPStore $mwacc-remote
mwmbsyncprofile="IMAPStore $mwacc-remote
Host $mwimap Host $mwimap
Port $mwiport Port $mwiport
User $mwlogin User $mwlogin
PassCmd \"pass $mwpass\" PassCmd \"pass $mwpass\"
SSLType $mwssltype SSLType $mwssltype
CertificateFile $sslcert
CertificateFile $mwsslcert


MaildirStore $mwacc-local MaildirStore $mwacc-local
Subfolders Verbatim Subfolders Verbatim
@@ -112,7 +111,7 @@ MaxMessages 0
" "


if [ "$mwtype" = "offline" ]; then if [ "$mwtype" = "offline" ]; then
mutt_profile="# vim: filetype=neomuttrc
mwmuttprofile="# vim: filetype=neomuttrc
# muttrc file for account $mwaddr # muttrc file for account $mwaddr
set realname = \"$mwname\" set realname = \"$mwname\"
set from = \"$mwaddr\" set from = \"$mwaddr\"
@@ -126,7 +125,7 @@ macro index gm \"<shell-escape>mailsync $mwacc<enter>\" \"sync mail $mwaddr\"
unmailboxes * unmailboxes *
" "
else else
mutt_profile="# vim: filetype=neomuttrc
mwmuttprofile="# vim: filetype=neomuttrc
# muttrc file for account $mwaddr # muttrc file for account $mwaddr
set realname = \"$mwname\" set realname = \"$mwname\"
set from = \"$mwaddr\" set from = \"$mwaddr\"
@@ -149,16 +148,16 @@ fi
printf "DONE.\\n" printf "DONE.\\n"
} }


askinfo() {
_mwaskinfo() {
if [ -z "$mwaddr" ]; then if [ -z "$mwaddr" ]; then
printf "Type the \033[31memail address\033[0m\\n\t\033[36m"
read -r mwaddr
printf "\033[0m"
while ! echo "$mwaddr" | grep "$mwemailre" >/dev/null; do
printf "That is not a valid \033[31memail address\033[0m, please retype\\n\t\033[36m"
read -r mwaddr
printf "\033[0m"
done
printf "Type the \033[31memail address\033[0m\\n\t\033[36m"
read -r mwaddr
printf "\033[0m"
while ! echo "$mwaddr" | grep "$mwemailre" >/dev/null; do
printf "That is not a valid \033[31memail address\033[0m, please retype\\n\t\033[36m"
read -r mwaddr
printf "\033[0m"
done
fi fi
mwdomain="$(echo "$mwaddr" | sed "s/.*@//")" mwdomain="$(echo "$mwaddr" | sed "s/.*@//")"
printf "\\nSearching for \033[32m%s\033[0m in \033[34m\`domains.csv\`\033[0m..." "$mwdomain" printf "\\nSearching for \033[32m%s\033[0m in \033[34m\`domains.csv\`\033[0m..." "$mwdomain"
@@ -183,74 +182,92 @@ EOF
gmail.com) printf "\033[31mGmail: \"less secure\" must be enabled before you continue.\\nDo it now, if you have not done it already:\\nhttps://support.google.com/accounts/answer/6010255\\n\033[0m" ;; gmail.com) printf "\033[31mGmail: \"less secure\" must be enabled before you continue.\\nDo it now, if you have not done it already:\\nhttps://support.google.com/accounts/answer/6010255\\n\033[0m" ;;
protonmail.ch|protonmail.com|pm.me) printf "\033[31mProtonmail: Users must install and configure Protonmail Bridge for the sync to work:\\nhttps://protonmail.com/bridge/\\n\033[0m" && ssltype="None" ;; protonmail.ch|protonmail.com|pm.me) printf "\033[31mProtonmail: Users must install and configure Protonmail Bridge for the sync to work:\\nhttps://protonmail.com/bridge/\\n\033[0m" && ssltype="None" ;;
esac esac
[ "$mwsport" = 465 ] && starttlsoff="tls_starttls off"
[ "$mwsport" = 465 ] && mwstarttlsoff="tls_starttls off"
fi fi
if [ -z "$mwname" ]; then if [ -z "$mwname" ]; then
printf "Name to associate to email.\\n\t"
read -r mwname
printf "Name to associate to email.\\n\t"
read -r mwname
fi fi
takemwaddr
if [ -z "$mwlogin" ]; then if [ -z "$mwlogin" ]; then
printf "Type your account username if different from your email address.\\n\033[34mFor most accounts you can probably leave this blank.\033[0m\\n\tLogin(?): \033[36m"
read -r mwlogin
printf "\033[0m"
[ -z "$mwlogin" ] && mwlogin="$mwaddr"
printf "Type your account username if different from your email address.\\n\033[34mFor most accounts you can probably leave this blank.\033[0m\\n\tLogin(?): \033[36m"
read -r mwlogin
printf "\033[0m"
[ -z "$mwlogin" ] && mwlogin="$mwaddr"
fi fi
# if the user has a pass entry he could provide it via mwpass # if the user has a pass entry he could provide it via mwpass
if [ -z "$mwpass" ]; then if [ -z "$mwpass" ]; then
mwpass=mutt-wizard-$mwaddr
getpass
mwpass=mutt-wizard-$mwaddr
_mwgetpass
fi
unset mwidnum
_mwaddrmwtype
_mwgetprofiles
mkdir -p "$mwmuttdir" "$mwaccmuttdir" "${mwmsmtprc%/*}" "${mwmbsyncrc%/*}"
if [ ! -f "$mwmsmtprc" ]; then
echo "$mwmsmtpheader" > "$mwmsmtprc"
else
sed -i "/account $mwacc/,/^\(\s*$\|account\)/d" "$mwmsmtprc"
fi fi
getprofiles
mkdir -p "$mwmuttdir" "$mwaccrcdir" "$mwconfigdir/msmtp" "${mwmbsyncrc%/*}"
[ ! -f "$mwmsmtprc" ] && echo "$msmtp_header" > "$mwmsmtprc"
echo "$msmtp_profile" >> "$mwmsmtprc"
echo "$mwmsmtpprofile" >> "$mwmsmtprc"
case "$mwservice" in case "$mwservice" in
protonmail.ch|protonmail.com|pm.me) protonfinger || return 1 ;; protonmail.ch|protonmail.com|pm.me) protonfinger || return 1 ;;
esac esac
echo "$mbsync_profile" >> "$mwmbsyncrc"
# new idnum = first one missing
getaccounts
for x in $(seq 1 9); do echo "$accounts" | grep "$x": >/dev/null 2>&1 || { export idnum="$x"; break ;}; done
mwaccrc="$mwaccrcdir/$idnum-$mwacc.muttrc"
echo "$mutt_profile" > "$mwaccrc"
[ -f "$mwmbsyncrc" ] && sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
echo "$mwmbsyncprofile" >> "$mwmbsyncrc"
#mwaccmuttrc
mwaccmuttrc="$mwaccmuttdir/$(find "$mwaccmuttdir" -type f | grep -m 1 -o "[1-9]-$mwacc.mwonofftype.$mwtype.muttrc")"
if [[ ! -f "$mwaccmuttrc" ]]; then
# new mwidnum = first one missing
_mwgetaccounts
for mwx in $(seq 1 9); do echo "$mwaccounts" | grep "$mwx:" >/dev/null 2>&1 || { export mwidnum="$mwx"; break ;}; done
mwaccmuttrc="$mwaccmuttdir/$mwidnum-$mwacc.mwonofftype.$mwtype.muttrc"
else
mwidnum=${mwaccmuttrc%%-*}
mwidnum=${mwidnum##*/}
fi
echo "$mwmuttprofile" > "$mwaccmuttrc"
[ ! -f "$mwmuttrc" ] && echo "# vim: filetype=neomuttrc" > "$mwmuttrc" && echo "muttrc created." [ ! -f "$mwmuttrc" ] && echo "# vim: filetype=neomuttrc" > "$mwmuttrc" && echo "muttrc created."
! grep "source.*mutt-wizard.muttrc" "$mwmuttrc" >/dev/null && echo "source $mwsharerc # mw-autogenerated" >> "$mwmuttrc"
! grep "source $mwsharerc" "$mwmuttrc" >/dev/null && echo "source $mwsharerc # mw-autogenerated" >> "$mwmuttrc"
if [ "$mwtype" = "offline" ]; then if [ "$mwtype" = "offline" ]; then
! grep "^macro .* gM .*" "$mwmuttrc" >/dev/null && echo "macro index gM '<shell-escape>mailsync -Va<enter>' \"sync all mail\" # mw-autogenerated" >> "$mwmuttrc"
! grep "^macro .* gM .*" "$mwmuttrc" >/dev/null && echo "macro index gM '<shell-escape>mailsync -Va<enter>' \"sync all mail\" # mw-autogenerated" >> "$mwmuttrc"
fi fi
! grep "^source.*$mwaccrc" "$mwmuttrc" >/dev/null && echo "source $mwaccrc # mw-autogenerated" >> "$mwmuttrc"
! grep "^source.*$mwaccmuttrc" "$mwmuttrc" >/dev/null && echo "source $mwaccmuttrc # mw-autogenerated" >> "$mwmuttrc"
return 0 return 0
} }


protonfinger() {
_mwprotonfinger() {
printf "Getting Protonmail bridge fingerprint...\\n" printf "Getting Protonmail bridge fingerprint...\\n"
fingerprint="$($msmtpbin --serverinfo --host=127.0.0.1 --port=1025 --tls --tls-certcheck=off)" || return 1
sed -i "s/account $mwacc/&\ntls_trust_file\ntls_fingerprint $fingerprint/" "$mwmsmtprc"
mwfingerprint="$($msmtpbin --serverinfo --host=127.0.0.1 --port=1025 --tls --tls-certcheck=off)" || return 1
sed -i "s/account $mwacc/&\ntls_trust_file\ntls_fingerprint $mwfingerprint/" "$mwmsmtprc"
} }


getpass() {
_mwgetpass() {
while : ; do pass rm -f "$mwpass" >/dev/null 2>&1 while : ; do pass rm -f "$mwpass" >/dev/null 2>&1
pass insert "$mwpass" && break; done ;} pass insert "$mwpass" && break; done ;}


formatShortcut() {
while read -r data; do { echo "macro index,pager g$1 \"<change-folder>$data<enter>\" \"go to $2\" # mw-autogenerated"
echo "macro index,pager M$1 \"<save-message>$data<enter>\" \"move mail to $2\" # mw-autogenerated"
echo "macro index,pager C$1 \"<copy-message>$data<enter>\" \"copy mail to $2\" # mw-autogenerated"; } >> "$mwaccrc"
done
}


tryconnect() {
_mwtryconnect() {
if [ ! -d "$mwaccmaildir" ]; then
mwaccmaildirWasThere="NO" # we need to remove again for "online"
mkdir -p "$mwaccmaildir"
fi
if [ -z "$mailboxes" ]; then if [ -z "$mailboxes" ]; then
if [ ! -d "$mwaccmaildir" ]; then
mwaccmaildirWasThere="NO" # we need to remove again for "online"
mkdir -p "$mwaccmaildir"
fi
mailboxes="$($mbsyncbin -l $mwacc | sed 's/\//./')" >/dev/null 2>&1 mailboxes="$($mbsyncbin -l $mwacc | sed 's/\//./')" >/dev/null 2>&1
fi fi
if [ -n "$mailboxes" ]; then if [ -n "$mailboxes" ]; then
mwspoolfile=$(echo "$mailboxes" | grep -i -m 1 inbox | sed -ne 's/.*/+\0/p')
[ -z "$mwspoolfile" ] && return 1

#make directories
printf "\033[32mMailboxes detected.\033[0m\\n" printf "\033[32mMailboxes detected.\033[0m\\n"
echo "$mailboxes" | xargs -I {} mkdir -p "$mwaccmaildir/{}"
echo "$mailboxes" | xargs -I {} mkdir -p "$mwaccmaildir/{}/"{cur,new,tmp}
record=$(echo "$mailboxes" | grep -i -m 1 sent | sed -ne 's/.*/+\0/p')
[ -z "$mwrecord" ] && mkdir -p "$mwaccmaildir/Sent/"{cur,new,tmp} && record="Sent"
postponed=$(echo "$mailboxes" | grep -i -m 1 draft | sed -ne 's/.*/+\0/p')
[ -z "$mwpostponed" ] && mkdir -p "$mwaccmaildir/Drafts/"{cur,new,tmp} && postponed="Drafts"
trash=$(echo "$mailboxes" | grep -i -m 1 trash | sed -ne 's/.*/+\0/p')
[ -z "$mwtrash" ] && mkdir -p "$mwaccmaildir/Trash/"{cur,new,tmp} && trash="Trash"

return 0 return 0
else else
printf "\033[31m\033[31mLog-on not successful.\033[0m\\nIt seems that either you inputted the wrong password or server settings, or there are other requirements for your account out of the control of mutt-wizard.\\n" printf "\033[31m\033[31mLog-on not successful.\033[0m\\nIt seems that either you inputted the wrong password or server settings, or there are other requirements for your account out of the control of mutt-wizard.\\n"
@@ -258,125 +275,128 @@ tryconnect() {
fi fi
} }


finalize() {
sed -i "/# mw-autogenerated/d" "$mwaccrc"
sed -i "/^mailboxes\|^set record\|^set postponed\|^set trash\|^set spoolfile/d" "$mwaccrc"
idnum=${mwaccrc%%-*}
idnum=${idnum##*/}
muttsync=$(printf '<sync-mailbox><enter-command>source %s<enter><change-folder>!<enter>;<check-stats>' $mwaccrc)
echo "macro index,pager i$idnum '$muttsync' \"switch to $mwaddr\" # mw-autogenerated" >> "$mwaccrc"
command -V urlview >/dev/null 2>&1 && [ ! -f "$HOME/.urlview" ] && echo "COMMAND \$BROWSER" > "$HOME/.urlview"

echo "folder-hook \$folder '$muttsync' # mw-autogenerated" >> "$mwaccrc"
boxes="$(find "$mwaccmaildir/" -mindepth 1 -maxdepth 1 | sed "s/\ /\\\ /g;s/^.*\//=/")"
if [ "$boxes" = "" ]; then

_mwfinalize() { # new mwaccmuttrc
mwboxes="$(find "$mwaccmaildir/" -name cur | sed "s,$mwaccmaildir/,,g;s,/cur,,")"
if [[ "$mwboxes" =~ ^[[:space:]]*$ ]]; then
printf "\033[31mNo local mailboxes have been detected for %s.\033[0m\\nThis means that mbsync has not been successfully run.\\nRun mbsync, and if it has an error, be sure to check your password and server settings manually if needbe.\\n" "$mwacc" printf "\033[31mNo local mailboxes have been detected for %s.\033[0m\\nThis means that mbsync has not been successfully run.\\nRun mbsync, and if it has an error, be sure to check your password and server settings manually if needbe.\\n" "$mwacc"
return return
fi fi
printf "Setting default mailboxes for your Inbox, Sent, Drafts and Trash in mutt...\\n"
spoolfile=$(echo "$boxes" | grep -i -m 1 inbox | sed 's/=/+/g')
record=$(echo "$boxes" | grep -i -m 1 sent | sed 's/=/+/g')
postponed=$(echo "$boxes" | grep -i -m 1 draft | sed 's/=/+/g')
trash=$(echo "$boxes" | grep -i -m 1 trash | sed 's/=/+/g')
cat >> "$mwaccrc" <<EOF
set spoolfile = "$spoolfile"
set record = "$record"
set postponed = "$postponed"
set trash = "$trash"
mwaccmutt="${email//[.@]/_}"
muttsync=$(printf '<sync-mailbox><enter-command>source %s<enter><change-folder>!<enter>;<check-stats>' $mwaccmuttrc)
cat >> "$mwaccmuttrc" <<EOF

set spoolfile = "$mwspoolfile"
set record = "$mwrecord"
set postponed = "$mwpostponed"
set trash = "$mwtrash"

folder-hook \$folder '$muttsync'
macro index,pager i$mwidnum '$muttsync' "switch to $mwacc"

mailboxes =$mwaccmutt ===================== $(echo "$mwboxes" | sed -e "s/ //g;s/.*/\"=\0\"/g" | tr "\n" " ")
EOF EOF
echo "mailboxes =$mwaccmutt ===================== $(echo "$boxes" | sed -e "s/^\|$/\"/g" | tr "\n" " ")" >> "$mwaccrc"
printf "Setting up your keyboard shortcuts for jumping between mailboxes...\\n"
echo "$boxes" | grep -i inbox | head -n 1 | formatShortcut i inbox
echo "$boxes" | grep -i sent | head -n 1 | formatShortcut s sent
echo "$boxes" | grep -i draft | head -n 1 | formatShortcut d drafts
echo "$boxes" | grep -i trash | head -n 1 | formatShortcut t trash
echo "$boxes" | grep -i spam | head -n 1 | formatShortcut S spam
echo "$boxes" | grep -i junk | head -n 1 | formatShortcut j junk
echo "$boxes" | grep -i archive | head -n 1 | formatShortcut a archive
for mwabox in $mwboxes; do
mwbox=${mwabox##*/}
mwbox=${mwbox##*.}
mwboxi=${mwbox::2}
mwboxi=${mwboxi,,}
cat >> $mwaccmuttrc <<EOF

macro index,pager i$mwboxi "<change-folder>=$mwabox<enter>" "go to $mwbox"
macro index,pager M$mwboxi "<save-message>=$mwabox<enter>" "move mail to $mwbox"
macro index,pager C$mwboxi "<copy-message>=$mwabox<enter>" "copy mail to $mwbox"
EOF
done
if [ "$mwtype" = "offline" ]; then if [ "$mwtype" = "offline" ]; then
notmuchauto
_mwnotmuchauto
printf "All done.\\n\033[33mYou can now run \`\033[32mmailsync [%s]\033[33m\` to sync your mail.\033[0m\\n" "$mwacc" printf "All done.\\n\033[33mYou can now run \`\033[32mmailsync [%s]\033[33m\` to sync your mail.\033[0m\\n" "$mwacc"
else else
mkdir -p "$mwacccachedir" mkdir -p "$mwacccachedir"
sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc" sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
[ "$mwaccmaildirWasThere" = "NO" ] && rm -rf "$mwaccmaildir/"
[ "$mwaccmaildirWasThere" = "NO" ] && rm -rf "$mwaccmaildir"
fi fi
return 0 return 0
} }


confirm() {
printf "[y/N]: Do you want to %s?\\n\t" "$@" && read -r input && ! echo "$input" | grep -i "^y$\|^yes$" >/dev/null && printf "That doesn't seem like a yes to me.\\n\\n" && return 1
_mwconfirm() {
printf "[y/N]: Do you want to %s?\\n\t" "$@" && read -r mwinput && ! echo "$mwinput" | grep -i "^y$\|^yes$" >/dev/null && printf "That doesn't seem like a yes to me.\\n\\n" && return 1
return 0 ; return 0 ;
} }


mwpick() {
_mwpick() {
printf "Select an accounts to %s:\\n" "$1" printf "Select an accounts to %s:\\n" "$1"
mwlist
read -r input
[ -z "$input" ] && return 1
mwaddr="$(echo "$accounts" | grep "$input": | awk '{print $2}')"
takemwaddr
_mwlist
[ -z "$mwpick" ] && read -r mwpick
mwidnum="$mwpick"
[ -z "$mwidnum" ] && return 1
mwaddr="$(echo "$mwaccounts" | grep "$mwidnum:" | sed "s/\.mwonofftype\./ /" | awk '{print $2}')"
mwtype="$(echo "$mwaccounts" | grep "$mwidnum:" | sed "s/\.mwonofftype\./ /" | awk '{print $3}')"
_mwaddrmwtype
[ -z "$mwacc" ] && printf "Invalid response." && return 1 [ -z "$mwacc" ] && printf "Invalid response." && return 1
return 0 ; return 0 ;
} }


mwdelete() {
sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
rm -rf "$mwacccachedir"
rm -rf "$mwaccrcdir/"[1-9]"-$mwacc.muttrc"
sed -i "/[0-9]-$mwacc.muttrc/d" "$mwmuttrc"
sed -i "/account $mwacc/,/^\(\s*$\|account\)/d" "$mwmsmtprc"
_mwdelete() {
rm -f "$mwaccmuttrc"
sed -i "/$mwaccmuttrc/d" "$mwmuttrc"
if [ "$mwtype" = "offline" ]; then
sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
sed -i "/account $mwacc/,/^\(\s*$\|account\)/d" "$mwmsmtprc"
else
rm -rf "$mwacccachedir"
fi
} }


mwcron() {
_mwcron() {
! pgrep cron >/dev/null && echo "No cron manager running. Install/enable one and then select this option again." && return 1 ! pgrep cron >/dev/null && echo "No cron manager running. Install/enable one and then select this option again." && return 1
if crontab -l | grep mailsync >/dev/null; then if crontab -l | grep mailsync >/dev/null; then
echo "Active mail sync cronjob detected. Do you want to remove it?" echo "Active mail sync cronjob detected. Do you want to remove it?"
printf "\033[36m\t" printf "\033[36m\t"
read -r rmyn
[ -z "$mwcronremove" ] && read -r mwcronremove
printf "\033[0m" printf "\033[0m"
echo "$rmyn" | grep -i "^y\(es\)*$" >/dev/null && crontab -l | sed '/mailsync/d' | crontab - >/dev/null && echo "Mail sync turned off."
echo "$mwcronremove" | grep -i "^y\(es\)*$" >/dev/null && crontab -l | sed '/mailsync/d' | crontab - >/dev/null && echo "Mail sync turned off."
else else
echo "How many minutes between each mail sync?" echo "How many minutes between each mail sync?"
printf "\033[36m\t" printf "\033[36m\t"
read -r minnum
[ -z $mwcronminutes ] && read -r mwcronminutes
printf "\033[0m" printf "\033[0m"
while ! echo "$minnum" | grep "^[0-9]\+$" >/dev/null; do
while ! echo "$mwcronminutes" | grep "^[1-9]\+$" >/dev/null; do
printf "That doesn't look like a number. How many minutes between each mail sync?\\n\033[36m\t" printf "That doesn't look like a number. How many minutes between each mail sync?\\n\033[36m\t"
read -r minnum
read -r mwcronminutes
printf "\033[0m" printf "\033[0m"
done done
(crontab -l; echo "*/$minnum * * * * export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus; export DISPLAY=:0; $(type mailsync | cut -d' ' -f3)") | crontab - &&
echo "Cronjob added. Mail will sync every $minnum minutes. Be sure you have your cron manager running."
(crontab -l; echo "*/$mwcronminutes * * * * export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus; export DISPLAY=:0; $(type mailsync | cut -d' ' -f3)") | crontab - &&
echo "Cronjob added. Mail will sync every $mwcronminutes minutes. Be sure you have your cron manager running."
fi fi
} }


asktype() {
if [ -z "$mwtype" ]; then
while : ; do
printf "[yes/no]: Local mail via mbsync? No: Mutt remotes (slower)\\n\t"
read -r offnot
case "$offnot" in
[Yy][Ee][Ss]) mwtype="offline" && break ;;
[Nn][Oo]) mwtype="online" && break ;;
*) echo "Write out either yes or no completely. Try again or press ctrl-c to quit." ;;
esac
done
fi
_mwasktype() {
if [ -z "$mwtype" ]; then
while : ; do
printf "[yes/no]: Local mail via mbsync? No: Mutt remotes (slower)\\n\t"
read -r mwoffline
case "$mwoffline" in
[Yy][Ee][Ss]) mwtype="offline" && break ;;
[Nn][Oo]) mwtype="online" && break ;;
*) echo "Write out either yes or no completely. Try again or press ctrl-c to quit." ;;
esac
done
fi
} }


mwpurge() {
confirm "delete all account data" || exit
rm -rf "$mwmbsyncrc" "$mwaccrcdir" "$mwconfigdir/msmtp" "${mwmbsyncrc%/*}" "$mwcachedir"
pgrep cron >/dev/null && crontab -l | sed '/mailsync/d' | crontab - >/dev/null
_mwpurge() {
_mwconfirm "delete all account data" || exit
rm -rf "$mwaccmuttdir" "${mwmsmtprc%/*}" "${mwmbsyncrc%/*}" "$mwcachedir"
sed -i "/\# mw-autogenerated/d" "$mwmuttrc" sed -i "/\# mw-autogenerated/d" "$mwmuttrc"
pgrep cron >/dev/null && crontab -l | sed '/mailsync/d' | crontab - >/dev/null
echo "All configs and account settings have been purged." echo "All configs and account settings have been purged."
} }


notmuchauto() {
_mwnotmuchauto() {
[ -z "$NOTMUCH_CONFIG" ] && NOTMUCH_CONFIG="$HOME/.notmuch-config" [ -z "$NOTMUCH_CONFIG" ] && NOTMUCH_CONFIG="$HOME/.notmuch-config"
[ -f "$NOTMUCH_CONFIG" ] && return 0 [ -f "$NOTMUCH_CONFIG" ] && return 0
nmbasic="[database]
mwnmbasic="[database]
path=$mwmaildir path=$mwmaildir
[user] [user]
name=$mwname name=$mwname
@@ -391,19 +411,19 @@ synchronize_flags=true
[crypto] [crypto]
gpg_path=$GPG" gpg_path=$GPG"
mkdir -p "${NOTMUCH_CONFIG%/*}" mkdir -p "${NOTMUCH_CONFIG%/*}"
echo "$nmbasic" > "$NOTMUCH_CONFIG"
echo "$mwnmbasic" > "$NOTMUCH_CONFIG"
} }


trap 'echo -e "\033[0m\n"; exit' STOP INT ABRT KILL trap 'echo -e "\033[0m\n"; exit' STOP INT ABRT KILL


if [ "${BASH_SOURCE[0]}" = "${0}" ]; then if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
case "$1" in case "$1" in
ls) mwlist ;;
add) mwadd ;;
pass) mwpick "change the password of" && getpass ;;
delete) mwpick delete && confirm "delete the \`$mwacc\` profile" && mwdelete ;;
purge) mwpurge ;;
cron) mwcron ;;
ls) _mwlist ;;
add) _mwadd ;;
pass) _mwpick "change the password of" && _mwgetpass ;;
delete) _mwpick delete && _mwconfirm "delete the \`$mwacc\` profile" && _mwdelete ;;
purge) _mwpurge ;;
cron) _mwcron ;;
*) cat << EOF *) cat << EOF
mw: mutt-wizard, auto-configure email accounts for mutt mw: mutt-wizard, auto-configure email accounts for mutt
including downloadable mail with \`isync\`. including downloadable mail with \`isync\`.


+ 14
- 11
mw.1 View File

@@ -26,12 +26,18 @@ list all email accounts configured by mutt-wizard
delete the configuration files for an already configured email account delete the configuration files for an already configured email account
.TP .TP
.B purge .B purge
totally purge all local mutt-wizard/mbync/msmtp settings
.I totally
purges all local
.I .config/mutt/accounts/1-*
.I mbsyncrc
and
.I .config/msmtp/config
settings.
.TP .TP
.B cron .B cron
toggle a cronjob that will automatically sync mail with
.B mailsync
as often as you wish
toggle a cronjob that will periodically sync mail with
.B mailsync.
Use mailsync instead of mbsync, also manually.
.SH DETAILS .SH DETAILS
.TP .TP
.B Mail location .B Mail location
@@ -65,14 +71,11 @@ will delete downloaded mail for for safety (and time)'s sake. If you want to del
mutt-wizard has many default settings that focus on making it aesthetically pleasing and supplying more vim-like bindings. These can be found in mutt-wizard has many default settings that focus on making it aesthetically pleasing and supplying more vim-like bindings. These can be found in
.I /usr/share/mutt-wizard/mutt-wizard.muttrc .I /usr/share/mutt-wizard/mutt-wizard.muttrc
and the default mailcap file can be found in and the default mailcap file can be found in
.I
/usr/share/mutt-wizard/mailcap.
Any of these settings can be overwritten in
.I /usr/share/mutt-wizard/mailcap.
After the line sourcing the mutt-wizard default, you can overwrite settings in your
.I $XDG_CONFIG_HOME/mutt/muttrc, .I $XDG_CONFIG_HOME/mutt/muttrc,
but be mindful that your overriding binds should appear after the
.I
mutt-wizard.muttrc
file is sourced.
Else you can keep mutt-wizard from adding a sourcing line, if you have the following comment in your muttrc:
.B # source /usr/share/mutt-wizard/mutt-wizard.muttrc
.TP .TP
.B Detecting server settings .B Detecting server settings
mutt-wizard has a repository of email services and their server information kept in mutt-wizard has a repository of email services and their server information kept in


+ 8
- 9
test/dotests View File

@@ -5,10 +5,6 @@ echo Unit Test:
echo echo
bats --tap test_mw.bats bats --tap test_mw.bats


echo
echo Integration tests with a working email:
echo

#modify #modify
if [[ -z $MAILDIR ]] || [[ -z $mwaddr ]]; then if [[ -z $MAILDIR ]] || [[ -z $mwaddr ]]; then
echo "First do:" echo "First do:"
@@ -17,6 +13,10 @@ if [[ -z $MAILDIR ]] || [[ -z $mwaddr ]]; then
exit exit
fi fi


echo
echo "Integration tests need working email $mwaddr"
echo "CTRL-C to skip"

cd .. && sudo make install && OK="OK" cd .. && sudo make install && OK="OK"


if [[ "$OK" == "OK" ]]; then if [[ "$OK" == "OK" ]]; then
@@ -31,25 +31,24 @@ if [[ "$OK" == "OK" ]]; then


rm -rf $mwaccmaildir rm -rf $mwaccmaildir



[ -f "${PASSWORD_STORE_DIR:-~/.password-store}/$mwpass.gpg" ] || pass insert $mwpass [ -f "${PASSWORD_STORE_DIR:-~/.password-store}/$mwpass.gpg" ] || pass insert $mwpass


echo "= manual test 1 ="
echo "= Test 1 ="
mwtype=online mw add mwtype=online mw add
echo "=> In another window, start mutt and verify that mails are shown" echo "=> In another window, start mutt and verify that mails are shown"
echo "=> Then anwer with N" echo "=> Then anwer with N"
mw purge mw purge
rm -rf $mwaccmaildir rm -rf $mwaccmaildir


echo "= manual test 2 ="
echo "= Test 2 ="
mwtype=offline mw add mwtype=offline mw add
mailsync mailsync
echo "=> In another window, start mutt and verify that mails are shown" echo "=> In another window, start mutt and verify that mails are shown"
echo "=> Press i1, wait, press i2. Verify that mutt is fast again after i2." echo "=> Press i1, wait, press i2. Verify that mutt is fast again after i2."
echo "=> Press gm and gM, to start mailsync." echo "=> Press gm and gM, to start mailsync."
echo "=> Anwer with y."
echo "=> Anwer with Y and check that mbsyncrc, msmtp/config and mutt/accounts are gone."
mw purge mw purge
rm -rf $mwaccmaildir
fi fi


cd $CD cd $CD

+ 39
- 17
test/test_mw.bats View File

@@ -12,9 +12,11 @@ run_only_test() {
fi fi
} }


#these are called for every test
setup() setup()
{ {
#run_only_test 4
run_only_test 6
rm -rf mwtesttmp
XDG_CONFIG_HOME=mwtesttmp/config \ XDG_CONFIG_HOME=mwtesttmp/config \
MAILDIR=mwtesttmp/share/mail \ MAILDIR=mwtesttmp/share/mail \
XDG_CACHE_HOME=mwtesttmp/cache \ XDG_CACHE_HOME=mwtesttmp/cache \
@@ -23,11 +25,11 @@ setup()
export mwname="real name" export mwname="real name"
export mwaddr="full.addr@gmail.com" export mwaddr="full.addr@gmail.com"
export mwlogin="$mwaddr" export mwlogin="$mwaddr"
export mailboxes="[Gmail]/INBOX"
export mwshare=$PWD/../share export mwshare=$PWD/../share
function pass() { return 0; } function pass() { return 0; }
export pass export pass
} }

teardown() teardown()
{ {
if [ -z "$TEST_FUNCTION" ] if [ -z "$TEST_FUNCTION" ]
@@ -44,12 +46,9 @@ teardown()


#2 #2
@test "add online" { @test "add online" {
export mwtype=online
rm -rf mwtesttmp
export mailboxes="[Gmail]/Drafts"
run mwadd
mwtype="online" run _mwadd
[ -f mwtesttmp/config/mutt/muttrc ] [ -f mwtesttmp/config/mutt/muttrc ]
[ -f mwtesttmp/config/mutt/accounts/1-$mwaddr.muttrc ]
[ -f mwtesttmp/config/mutt/accounts/1-$mwaddr.mwonofftype.online.muttrc ]
[ "$(cat mwtesttmp/config/isync/mbsyncrc | sed -ne '/^\s*\w/p')" = "" ] [ "$(cat mwtesttmp/config/isync/mbsyncrc | sed -ne '/^\s*\w/p')" = "" ]
[ ! "$(cat mwtesttmp/config/msmtp/config | sed -ne '/^account/p')" = "" ] [ ! "$(cat mwtesttmp/config/msmtp/config | sed -ne '/^account/p')" = "" ]
[ ! -f mwtesttmp/config/notmuch-config ] [ ! -f mwtesttmp/config/notmuch-config ]
@@ -57,12 +56,11 @@ teardown()


#3 #3
@test "add offline unsuccessful" { @test "add offline unsuccessful" {
export mwtype=offline
rm -rf mwtesttmp
run mwadd
export mailboxes="[Gmail]/OTHER"
mwtype="offline" run _mwadd
[ -f mwtesttmp/config/mutt/muttrc ] [ -f mwtesttmp/config/mutt/muttrc ]
[ -d mwtesttmp/config/mutt/accounts ] [ -d mwtesttmp/config/mutt/accounts ]
[ ! -f mwtesttmp/config/mutt/accounts/1-$mwaddr.muttrc ]
[ ! -f mwtesttmp/config/mutt/accounts/1-$mwaddr.mwonofftype.offline.muttrc ]
[ "$(cat mwtesttmp/config/isync/mbsyncrc | sed -ne '/^\s*\w/p')" = "" ] [ "$(cat mwtesttmp/config/isync/mbsyncrc | sed -ne '/^\s*\w/p')" = "" ]
[ "$(cat mwtesttmp/config/msmtp/config | sed -ne '/^account/p')" = "" ] [ "$(cat mwtesttmp/config/msmtp/config | sed -ne '/^account/p')" = "" ]
[ ! -f mwtesttmp/config/notmuch-config ] [ ! -f mwtesttmp/config/notmuch-config ]
@@ -70,18 +68,42 @@ teardown()


#4 #4
@test "add offline successfully" { @test "add offline successfully" {
export mwtype=offline
export mailboxes="[Gmail]/Drafts"
rm -rf mwtesttmp
run mwadd
mwtype="offline" run _mwadd
[ -f mwtesttmp/config/mutt/muttrc ] [ -f mwtesttmp/config/mutt/muttrc ]
[ -d mwtesttmp/config/mutt/accounts ] [ -d mwtesttmp/config/mutt/accounts ]
[ -f mwtesttmp/config/mutt/accounts/1-$mwaddr.muttrc ]
[ -f mwtesttmp/config/mutt/accounts/1-$mwaddr.mwonofftype.offline.muttrc ]
[ -f mwtesttmp/config/notmuch-config ] [ -f mwtesttmp/config/notmuch-config ]
cat mwtesttmp/config/isync/mbsyncrc | sed -ne '/^\s*\w/p' cat mwtesttmp/config/isync/mbsyncrc | sed -ne '/^\s*\w/p'
[ ! "$(cat mwtesttmp/config/isync/mbsyncrc | sed -ne '/^\s*\w/p')" = "" ] [ ! "$(cat mwtesttmp/config/isync/mbsyncrc | sed -ne '/^\s*\w/p')" = "" ]
[ ! "$(cat mwtesttmp/config/msmtp/config | sed -ne '/^account/p')" = "" ] [ ! "$(cat mwtesttmp/config/msmtp/config | sed -ne '/^account/p')" = "" ]
run mwlist
run _mwlist
[ "$(echo $lines | awk '{print $2}')" = "$mwaddr" ] [ "$(echo $lines | awk '{print $2}')" = "$mwaddr" ]
} }


#5
@test "delete account" {
mwtype="online" run _mwadd
mwtype="offline" run _mwadd
mwpick="1" _mwpick delete && _mwdelete
[ ! -f mwtesttmp/config/mutt/accounts/1-$mwaddr.mwonofftype.online.muttrc ]
[ ! "$(cat mwtesttmp/config/isync/mbsyncrc | sed -ne '/^\s*\w/p')" = "" ]
[ ! "$(cat mwtesttmp/config/msmtp/config | sed -ne '/^account/p')" = "" ]
}

#6
@test "cron" {
mwtype="online" run _mwadd
function pgrep() { return 0; }
export pgrep
function crontab() { echo 'none'; }
export crontab
mwcronminutes=99 run _mwcron
chkline="${lines[2]}"
[ "${chkline::14}" = "Cronjob added." ]
function crontab() { echo 'mailsync'; }
export crontab
mwcronremove=y run _mwcron
chkline="${lines[1]}"
[ "${chkline#*turned}" = " off." ]
}


Loading…
Cancel
Save