diff options
Diffstat (limited to 'bin/mw')
-rwxr-xr-x | bin/mw | 442 |
1 files changed, 230 insertions, 212 deletions
@@ -1,89 +1,91 @@ #!/bin/sh + command -V gpg >/dev/null 2>&1 && GPG="gpg" || GPG="gpg2" -[ -r "$HOME/.password-store/.gpg-id" ] && - "$GPG" --list-secret-keys $(cat "$HOME/.password-store/.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" +[ -z ${PASSWORD_STORE_DIR+x} ] && PASSWORD_STORE_DIR="$HOME/.password-store" +[ -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 \`%s --full-gen-key\` first.\\n" "$GPG" exit } -! command -v mbsync >/dev/null && printf "\`mbsync\` must be installed to run mutt-wizard.\\n" && exit - -case "$(uname)" in - Linux) prefix="/usr" ;; - *) prefix="/usr/local" ;; -esac -muttdir="$HOME/.config/mutt" # Main mutt config location -accdir="$muttdir/accounts" # Directory for account settings -maildir="$HOME/.local/share/mail" # Location of mail storage -namere="^[a-z_][a-z0-9_-]*$" # Regex to ensure viable username -emailre=".\+@.\+\\..\+" # Regex to confirm valid email address +prefix="/usr/local" +pass_prefix="mw-" +muttdir="${XDG_CONFIG_HOME:-$HOME/.config}/mutt" # Main mutt config location +accdir="$muttdir/accounts" # Directory for account settings +maildir="${XDG_DATA_HOME:-$HOME/.local/share}/mail" # Location of mail storage +emailre=".+@.+\..+" # Regex to confirm valid email address muttshare="$prefix/share/mutt-wizard" -mbsyncrc="$HOME/.mbsyncrc" +mbsyncrc="${MBSYNCRC:-$HOME/.mbsyncrc}" mwconfig="$muttshare/mutt-wizard.muttrc" -cachedir="$HOME/.cache/mutt-wizard" +cachedir="${XDG_CACHE_HOME:-$HOME/.cache}/mutt-wizard" muttrc="$muttdir/muttrc" -msmtprc="$HOME/.config/msmtp/config" -ssltype="IMAPS" # This is later changed to `None` later in the script if using Protonmail +msmtprc="${XDG_CONFIG_HOME:-$HOME/.config}/msmtp/config" +msmtplog="${XDG_CONFIG_HOME:-$HOME/.config}/msmtp/msmtp.log" +MARKER="# mw-autogenerated" +alias mbsync='mbsync -c "$mbsyncrc"' -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" +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/" do [ -f "$x" ] && sslcert="$x" && break done || { echo "CA Certificate not found. Please install one or link it to /etc/ssl/certs/ca-certificates.crt" && exit 1 ;} -getaccounts() { accounts="$(find "$accdir" -type f | grep -o "[0-9]-.*.muttrc" | sed "s/-/: /;s/\..*//" | sort -n)" ;} +getaccounts() { accounts="$(find -L "$accdir" -type f | grep -o "[0-9]-.*.muttrc" | sed "s/-/: /;s/\.muttrc$//" | sort -n)" ;} + list() { getaccounts && [ -n "$accounts" ] && echo "$accounts" ;} getprofiles() { \ unset msmtp_header msmtp_profile mutt_profile mbsync_profile - printf "Creating profiles for \`%s\`..." "$title" msmtp_header="defaults auth on tls on tls_trust_file $sslcert -logfile ~/.config/msmtp/msmtp.log +logfile $msmtplog " -msmtp_profile="account $title +msmtp_profile="account $fulladdr host $smtp -port $sport +port ${sport:-587} from $fulladdr user $login -passwordeval \"pass mutt-wizard-$title\" +passwordeval \"pass $pass_prefix$fulladdr\" +$tlsline " -mbsync_profile="IMAPStore $title-remote +mbsync_profile="IMAPStore $fulladdr-remote Host $imap -Port $iport +Port ${iport:-993} User $login -PassCmd \"pass mutt-wizard-$title\" -SSLType $ssltype +PassCmd \"pass $pass_prefix$fulladdr\" +AuthMechs LOGIN +SSLType ${ssltype:-IMAPS} CertificateFile $sslcert -MaildirStore $title-local +MaildirStore $fulladdr-local Subfolders Verbatim -Path ~/.local/share/mail/$title/ -Inbox ~/.local/share/mail/$title/INBOX +Path ${XDG_DATA_HOME:-$HOME/.local/share}/mail/$fulladdr/ +Inbox ${XDG_DATA_HOME:-$HOME/.local/share}/mail/$fulladdr/INBOX Flatten . -Channel $title +Channel $fulladdr Expunge Both -Master :$title-remote: -Slave :$title-local: +Master :$fulladdr-remote: +Slave :$fulladdr-local: Patterns * !\"[Gmail]/All Mail\" Create Both SyncState * -MaxMessages $maxmes +MaxMessages ${maxmes:-0} +ExpireUnread no # End profile " -if [ "$accounttype" = "offline" ]; then +if [ -z "${online+x}" ]; then mutt_profile="# vim: filetype=neomuttrc -# muttrc file for account $title +# muttrc file for account $fulladdr set realname = \"$realname\" set from = \"$fulladdr\" -set sendmail = \"msmtp -a $title\" +set sendmail = \"msmtp -a $fulladdr\" alias me $realname <$fulladdr> -set folder = \"$maildir/$title\" -set header_cache = $cachedir/$title/headers -set message_cachedir = $cachedir/$title/bodies +set folder = \"$maildir/$fulladdr\" +set header_cache = $cachedir/$fulladdr/headers +set message_cachedir = $cachedir/$fulladdr/bodies set mbox_type = Maildir bind index,pager gg noop @@ -91,21 +93,21 @@ bind index,pager g noop bind index,pager M noop bind index,pager C noop bind index gg first-entry -macro index o \"<shell-escape>mailsync -V $title<enter>\" \"run mbsync to sync $title\" +macro index o \"<shell-escape>mw -y $fulladdr<enter>\" \"run mbsync to sync $fulladdr\" unmailboxes * " else mutt_profile="# vim: filetype=neomuttrc -# muttrc file for account $title +# muttrc file for account $fulladdr set realname = \"$realname\" set from = \"$fulladdr\" -set sendmail = \"$prefix/bin/msmtp -a $title\" +set sendmail = \"msmtp -a $fulladdr\" alias me $realname <$fulladdr> -set folder = \"imaps://$fulladdr@$imap:$iport\" +set folder = \"imaps://$login@$imap:${iport:-993}\" set imap_user = \"$login\" -set header_cache = $cachedir/$title/headers -set message_cachedir = $cachedir/$title/bodies -set imap_pass = \`pass mutt-wizard-$title\` +set header_cache = $cachedir/$fulladdr/headers +set message_cachedir = $cachedir/$fulladdr/bodies +set imap_pass = \"\`pass $pass_prefix$fulladdr\`\" set mbox_type = Maildir set ssl_starttls = yes @@ -119,180 +121,144 @@ bind index gg first-entry unmailboxes * " fi - printf "DONE.\\n" +} + +parsedomains(){ serverinfo="$(grep "^${fulladdr#*@}" "$muttshare/domains.csv" 2>/dev/null)" + + [ -z "$serverinfo" ] && serverinfo="$(grep "$(echo "${fulladdr#*@}" | sed "s/\.[^\.]*$/\.\\\*/")" "$muttshare/domains.csv" 2>/dev/null)" + + IFS=, read -r service imapsugg iportsugg smtpsugg sportsugg <<EOF +$serverinfo +EOF + imap="${imap:-$imapsugg}" + smtp="${smtp:-$smtpsugg}" + sport="${sport:-$sportsugg}" + iport="${iport:-$iportsugg}" +} + +delete() { if [ -z "${fulladdr+x}" ]; then + echo "Select the account your would like to delete (by number):" + list + read -r input + match="^$input:" + else + match=" $fulladdr$" + getaccounts + fi + + fulladdr="$(echo "$accounts" | grep "$match" | cut -f2 -d' ')" + + [ -z "$fulladdr" ] && echo "Invalid account name given." && return 1 + + sed -ibu "/IMAPStore $fulladdr-remote$/,/# End profile/d" "$mbsyncrc" ; rm -rf "$mbsyncrc"bu + rm -rf "${cachedir:?}/${fulladdr:?}" "$accdir/"[1-9]"-$fulladdr.muttrc" + sed -ibu "/[0-9]-$fulladdr.muttrc/d" "$muttrc" ; rm -f "$muttrc"bu + sed -ibu "/account $fulladdr/,/^\(\s*$\|account\)/d" "$msmtprc"; rm -f "$msmtprc"bu + pass rm -f "$pass_prefix$fulladdr" >/dev/null 2>&1 } askinfo() { \ - printf "Insert the \033[31memail address\033[0m that you want to autoconfigure for mutt/mbsync\\n\tEmail: \033[36m" - read -r fulladdr - printf "\033[0m" - while ! echo "$fulladdr" | grep "$emailre" >/dev/null; do - printf "That is not a valid \033[31memail address\033[0m, please retype the desired email.\\n\\nEmail: \033[36m\t" + [ -z "$fulladdr" ] && echo "Give the full email address to add:" && + read -r fulladdr + while ! echo "$fulladdr" | grep -qE "$emailre"; do + echo "\`$fulladdr\` is not a valid email address. Please retype the address:" read -r fulladdr - printf "\033[0m" done - domain="$(echo "$fulladdr" | sed "s/.*@//")" - printf "\\nSearching for \033[32m%s\033[0m in \033[34m\`domains.csv\`\033[0m..." "$domain" - serverinfo="$(grep "^$domain" "$muttshare/domains.csv" 2>/dev/null)" - if [ -z "$serverinfo" ]; then - printf "Your email domain is not in mutt-wizard's database yet.\\nmutt-wizard will still autoconfigure everything, but you will have to manually type in your service's IMAP and SMTP server information.\\nYou can usually quickly find this by internet searching for it.\\n" - printf "Insert the IMAP server for your email provider (excluding the port number)\\n\033[36m\t" + { [ -z "$imap" ] || [ -z "$smtp" ] ;} && parsedomains + [ -z "$imap" ] && echo "Give your email server's IMAP address (excluding the port number):" && read -r imap - printf "\033[0mWhat is your server's IMAP port number? (Usually something like 993)\\n\033[36m\t" - read -r iport - printf "\033[0mInsert the SMTP server for your email provider (excluding the port number)\\n\033[36m\t" + [ -z "$smtp" ] && echo "Give your email server's SMTP address (excluding the port number):" && read -r smtp - printf "\033[0mWhat is your server's SMTP port number? (Usually 587 or 465)\\n\033[36m\t" - read -r sport - printf "\033[0m\\nGreat! If you want to be helpful, copy the line below and you can add it to the \`domains.csv\` file on Github.\\nThis will make things easier for others who use your email provider.\\n\\n%s,%s,%s,%s,%s\\n\\nAlthough be sure to test to see if these settings work first! ;-)\\n" "$domain" "$imap" "$iport" "$smtp" "$sport" + [ "$sport" = 465 ] && tlsline="tls_starttls off" + [ -z "$realname" ] && echo "Give the name you would like to be identified by on the email account:" && + read -r realname + login="${login:-$fulladdr}" + if [ -n "${password+x}" ]; then + createpass else - IFS=, read -r service imap iport smtp sport <<EOF -$serverinfo -EOF - printf "\\n\033[3;33mCongrats!\033[0m Server info has automatically been found, so you won't have to look anything up!\\n\t\033[1mIMAP server\033[0m: %s\\n\t\033[1mIMAP port\033[0m: %s\\n\t\033[1mSMTP server\033[0m: %s\\n\t\033[1mSMTP port\033[0m: %s\\nThis data will be used by the wizard.\\n" "$imap" "$iport" "$smtp" "$sport" - case "$service" in - gmail.com) printf "\033[31mREMEMBER: Gmail users must enable \"less secure\" (third-party) applications first for the sync to work:\\nhttps://support.google.com/accounts/answer/6010255\\n\033[0m" ;; - protonmail.ch|protonmail.com|pm.me) printf "\033[31mREMEMBER: Protonmail users must install and configure Protonmail Bridge first for the sync to work:\\nhttps://protonmail.com/bridge/\\n\033[0m" && ssltype="None" ;; - esac + getpass fi - printf "Enter the \033[35mfull name\033[0m you want to be identified by on this account.\\n\tReal name: " - read -r realname - printf "Enter a short, \033[36mone-word identifier\033[0m for this email account that will distinguish them from any other accounts you add.\\n\tAccount name: " - read -r title - while ! echo "$title" | grep "$namere" >/dev/null || ls "$accdir"/[0-9]"-$title.muttrc" >/dev/null 2>&1; do - printf "\033[31mTry again\033[0m. Pick a nickname that is one word only including lowercase letters and _ or - and that you have \033[1mnot\033[0m used before.\\n\tAccount name: \033[36m\t" - read -r title - printf "\033[0m" - done - printf "If your account has a special username different from your address, insert it now. Otherwise leave this prompt totally blank.\\n\033[34mMost accounts will not have a separate login, so you should probably leave this blank.\033[0m\\n\tLogin(?): \033[36m" - read -r login - printf "\033[0m" - [ -z "$login" ] && login="$fulladdr" - [ "$accounttype" = "offline" ] && printf "If you want to limit the number of messages kept offline to a number, enter that number below. If you do not want to limit your mail and would like \`mbsync\` to sync all mail, press enter without typing a number.\\n\t" && read -r maxmes - echo "$maxmes" | grep "[1-9]" >/dev/null || maxmes="0" - getpass - getprofiles - mkdir -p "$muttdir" "$accdir" "$cachedir/$title/bodies" "$HOME/.config/msmtp" - getaccounts - for x in $(seq 1 9); do echo "$accounts" | grep "$x" >/dev/null 2>&1 || { export idnum="$x"; break ;}; done +} + +createpass() { echo "$password" > "$PASSWORD_STORE_DIR/$pass_prefix$fulladdr" + "$GPG" -qer "$(cat "$PASSWORD_STORE_DIR/.gpg-id")" "$PASSWORD_STORE_DIR/$pass_prefix$fulladdr" + rm -f "$PASSWORD_STORE_DIR/$pass_prefix$fulladdr" ;} + +writeinfo() { mkdir -p "$muttdir" "$accdir" "$cachedir/$fulladdr/bodies" "${XDG_CONFIG_HOME:-$HOME/.config}/msmtp" "$maildir/$fulladdr" + + # Get accounts and find the first missing account number (max. 9). + getaccounts; for x in $(seq 1 9); do echo "$accounts" | grep -q "$x" || { export idnum="$x"; break ;}; done + + # Configure msmtprc for sending mail. [ ! -f "$msmtprc" ] && echo "$msmtp_header" > "$msmtprc" echo "$msmtp_profile" >> "$msmtprc" + # On Ubuntu/Debian, a link is needed since they use an older version. command -V apt-get >/dev/null 2>&1 && ln -s "$msmtprc" "$HOME/.msmtprc" 2>/dev/null - case "$service" in - protonmail.ch|protonmail.com|pm.me) protonfinger || return 1 ;; - esac - echo "$mutt_profile" > "$accdir/$idnum-$title.muttrc" + + # Create the mbsync config file. + mkdir -p "${mbsyncrc%/*}" echo "$mbsync_profile" >> "$mbsyncrc" - notmuchauto - [ ! -f "$muttrc" ] && echo "# vim: filetype=neomuttrc" > "$muttrc" && echo "muttrc created." - ! grep "^source.*mutt-wizard.muttrc" "$muttrc" >/dev/null && echo "source $mwconfig # mw-autogenerated" >> "$muttrc" - ! grep "^source.*.muttrc" "$muttrc" | grep -v "$mwconfig" >/dev/null && echo "source $accdir/$idnum-$title.muttrc # mw-autogenerated" >> "$muttrc" - echo "macro index,pager i$idnum '<sync-mailbox><enter-command>source $accdir/$idnum-$title.muttrc<enter><change-folder>!<enter>;<check-stats>' \"switch to $fulladdr\" # mw-autogenerated" >> "$muttrc" -} -protonfinger() { printf "Getting Protonmail bridge fingerprint...\\n" - fingerprint="$(msmtp --serverinfo --tls --tls-certcheck=off -a "$title")" || return 1 - sed -ibu "s/account $title/&\ntls_trust_file\ntls_fingerprint $fingerprint/" "$msmtprc" ; rm -f "$msmtprc"bu + # Create a muttrc for viewing mail. + echo "$mutt_profile" > "$accdir/$idnum-$fulladdr.muttrc" + [ ! -f "$muttrc" ] && echo "# vim: filetype=neomuttrc" > "$muttrc" + ! grep -q "^source.*mutt-wizard.muttrc" "$muttrc" && echo "source $mwconfig $MARKER" >> "$muttrc" + ! grep "^source.*.muttrc" "$muttrc" | grep -qv "$mwconfig" && echo "source $accdir/$idnum-$fulladdr.muttrc $MARKER" >> "$muttrc" + echo "macro index,pager i$idnum '<sync-mailbox><enter-command>source $accdir/$idnum-$fulladdr.muttrc<enter><change-folder>!<enter>;<check-stats>' \"switch to $fulladdr\" $MARKER" >> "$muttrc" + + notmuchauto # Create a notmuch config file if not present already. } -getpass() { while : ; do pass rm -f "mutt-wizard-$title" >/dev/null 2>&1 - pass insert "mutt-wizard-$title" && break; done ;} +getpass() { while : ; do pass rm -f "$pass_prefix$fulladdr" >/dev/null 2>&1 + pass insert "$pass_prefix$fulladdr" && 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"; } >> "$accdir/$idnum-$title.muttrc" - done ;} +formatShortcut() { toappend="$toappend +macro index,pager g$1 \"<change-folder>=$3<enter>\" \"go to $2\" $MARKER +macro index,pager M$1 \";<save-message>=$3<enter>\" \"move mail to $2\" $MARKER +macro index,pager C$1 \";<copy-message>=$3<enter>\" \"copy mail to $2\" $MARKER" >> "$accdir/$idnum-$fulladdr.muttrc" ;} -tryconnect() { mkdir -p "$maildir/$title" - if mailboxes="$(mbsync -l "$title" | sed 's/\//./')" >/dev/null 2>&1 && [ -n "$mailboxes" ]; then - [ "$accounttype" = "online" ] && sed -ibu "/IMAPStore $title-remote$/,/# End profile/d" "$mbsyncrc" ; rm -f "$mbsyncrc"bu - printf "\033[32mMailboxes detected.\033[0m\\n" - echo "$mailboxes" | xargs -I {} mkdir -p "$maildir/$title/{}" +setBox() { toappend="$toappend +set $1 = \"+$2\" $MARKER" ;} + +getboxes() { [ -n "${force+x}" ] && mailboxes="INBOX +Drafts +Junk +Trash +Sent +Archive" && return 0 + if mailboxes="$(mbsync -l "$fulladdr" | sed 's/\//./')" >/dev/null 2>&1 && [ -n "$mailboxes" ]; then + [ -n "${online+x}" ] && sed -ibu "/IMAPStore $fulladdr-remote$/,/# End profile/d" "$mbsyncrc" ; rm -f "$mbsyncrc"bu return 0 else + echo "$mailboxes" 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" return 1 fi ;} -finalize() { \ - boxes="$(find "$maildir/$title/" -mindepth 1 -maxdepth 1 | sed "s/\ /\\\ /g;s/^.*\//=/")" - [ -z "$boxes" ] && 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" "$title" && return - 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') - sed -ibu "/^mailboxes\|^set record\|^set postponed\|^set trash\|^set spoolfile/d" "$accdir/$idnum-$title.muttrc" ; rm -f "$accdir/$idnum-$title.muttrcbu" - { echo "set spoolfile = \"$spoolfile\""; echo "set record = \"$record\""; echo "set postponed = \"$postponed\""; echo "set trash = \"$trash\""; } >> "$accdir/$idnum-$title.muttrc" - echo "mailboxes =$title ===================== $(echo "$boxes" | sed -e "s/^\|$/\"/g" | tr "\n" " ")" >> "$accdir/$idnum-$title.muttrc" - printf "Setting up your keyboard shortcuts for jumping between mailboxes...\\n" - sed -ibu "/# mw-autogenerated/d" "$accdir/$idnum-$title.muttrc" ; rm -f "$accdir/$idnum-$title.muttrcbu" - 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 - [ "$accounttype" = "offline" ] && printf "All done.\\n\033[33mYou should now be able to run \`\033[32mmbsync %s\033[33m\` to begin to download your mail.\033[0m\\n" "$title" +finalize() { echo "$mailboxes" | xargs -I {} mkdir -p "$maildir/$fulladdr/{}/cur" "$maildir/$fulladdr/{}/tmp" "$maildir/$fulladdr/{}/new" + sed -ibu "/$MARKER/d" "$accdir/$idnum-$fulladdr.muttrc" ; rm -f "$accdir/$idnum-$fulladdr.muttrcbu" + toappend="mailboxes $(echo "$mailboxes" | sed "s/^/\"=/;s/$/\"/" | paste -sd ' ' )" + for x in $mailboxes; do + case $x in + *[Ii][Nn][Bb][Oo][Xx]*) formatShortcut i inbox "$x"; setBox spoolfile "$x" ;; + *[Ss][Ee][Nn][Tt]*) setBox record "$x"; formatShortcut s sent "$x" ;; + *[Dd][Rr][Aa][Ff][Tt][Ss]*) setBox postponed "$x"; formatShortcut d drafts "$x" ;; + *[Tt][Rr][Aa][Ss][Hh]*) formatShortcut t trash "$x"; setBox trash "$x" ;; + *[Jj][Uu][Nn][Kk]*) formatShortcut j junk "$x" ;; + *[Aa][Rr][Cc][Hh][Ii][Vv][Ee]*) formatShortcut a archive "$x" ;; + *[Ss][Pp][Aa][Mm]*) formatShortcut S spam "$x" ;; + esac + done + echo "$toappend" >> "$accdir/$idnum-$fulladdr.muttrc" + [ -z "${online+x}" ] && printf "\033[33mYou should now be able to run \`\033[32mmw -y %s\033[33m\` to begin to download your mail.\033[0m\\n" "$fulladdr" command -V urlview >/dev/null 2>&1 && [ ! -f "$HOME/.urlview" ] && echo "COMMAND \$BROWSER" > "$HOME/.urlview" - return 0 -} - -confirm() { printf "Do you want to %s? [y/N]\\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 - printf "Are you really, really sure 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 return 0 ;} -pick() { printf "Select an accounts to %s:\\n" "$1" - list - read -r input - [ -z "$input" ] && return 1 - title="$(echo "$accounts" | grep "$input" | awk '{print $2}')" - [ -z "$title" ] && printf "Invalid response." && return 1 - return 0 ;} - -delete() { sed -ibu "/IMAPStore $title-remote$/,/# End profile/d" "$mbsyncrc" ; rm -rf "$mbsyncrc"bu - rm -rf "${cachedir:?}/${title:?}" "$accdir/"[1-9]"-$title.muttrc" - sed -ibu "/[0-9]-$title.muttrc/d" "$muttrc" ; rm -f "$muttrc"bu - sed -ibu "/account $title/,/^\(\s*$\|account\)/d" "$msmtprc"; rm -f "$msmtprc"bu - } - -choosecron() { ! 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 - echo "Active mail sync cronjob detected. Do you want to remove it?" - printf "\033[36m\t" - read -r rmyn - printf "\033[0m" - echo "$rmyn" | grep -i "^y\(es\)*$" >/dev/null && crontab -l | sed '/mailsync/d' | crontab - >/dev/null && echo "Mail sync turned off." - else - echo "How many minutes between each mail sync?" - printf "\033[36m\t" - read -r minnum - printf "\033[0m" - while ! echo "$minnum" | grep "^[0-9]\+$" >/dev/null; do - printf "That doesn't look like a number. How many minutes between each mail sync?\\n\033[36m\t" - read -r minnum - printf "\033[0m" - done - (crontab -l; echo "*/$minnum * * * * export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus; export DISPLAY=:0; . \$HOME/.profile; $(type mailsync | cut -d' ' -f3)") | crontab - && - echo "Cronjob added. Mail will sync every $minnum minutes. Be sure you have your cron manager running." - fi ;} - -asktype() { while : ; do - printf "Do you want to keep your mail for this account offline with mbsync? [yes/no]\\n\t" - read -r offnot - case "$offnot" in - [Yy][Ee][Ss]) accounttype="offline" && break ;; - [Nn][Oo]) accounttype="online" && break ;; - *) echo "Write out either yes or no completely. Try again or press ctrl-c to quit." ;; - esac; done ;} - -purge() { confirm "delete all account data" || exit - rm -rf "$mbsyncrc" "$accdir" "$HOME/.config/msmtp" "$cachedir" - echo "All configs and account settings have been purged." - sed -ibu "/\# mw-autogenerated/d" "$muttrc" ; rm -f "$muttrc"bu -} +syncwrapper() { mbsync "${1:--a}" & + ( kill -46 "$(pidof "${STATUSBAR:-dwmblocks}")" >/dev/null 2>&1 ) 2>/dev/null + wait + ( kill -46 "$(pidof "${STATUSBAR:-dwmblocks}")" >/dev/null 2>&1 ) 2>/dev/null + notmuch new ;} notmuchauto() { \ [ -z "$NOTMUCH_CONFIG" ] && NOTMUCH_CONFIG="$HOME/.notmuch-config" @@ -304,7 +270,7 @@ name=$realname primary_email=$fulladdr [new] tags=unread;inbox; -ignore= +ignore=.mbsyncstate;.uidvalidity [search] exclude_tags=deleted;spam; [maildir] @@ -313,28 +279,80 @@ synchronize_flags=true gpg_path=$GPG" echo "$nmbasic" > "$NOTMUCH_CONFIG" ;} -trap 'echo -e "\033[0m\n"' INT +setact() { if [ -n "${action+x}" ] && [ "$action" != "$1" ]; then + echo "Running $1 with $action..." + echo "Incompatible options given. Only one action may be specified per run." + return 1 + else + action="$1" + fi; } -case "$1" in - ls) list ;; - add) asktype && askinfo && tryconnect && finalize || delete ;; - pass) pick "change the password of" && getpass ;; - delete) pick delete && confirm "delete the \`$title\` profile" && delete ;; - purge) purge ;; - cron) choosecron ;; +trap 'echo -e "\033[0m\n"; exit' INT ABRT + +while getopts "fplhodYD:y:i:I:s:S:u:a:n:x:m:" o; do case "${o}" in + l) setact list || exit 1 ;; + d) setact delete || exit 1 ;; + D) setact delete || exit 1 ; fulladdr="$OPTARG" ;; + y) setact sync || exit 1 ; fulladdr="$OPTARG" ;; + Y) setact sync || exit 1 ;; + a) setact add || exit 1 ; fulladdr="$OPTARG" ;; + i) setact add || exit 1 ; imap="$OPTARG" ;; + I) setact add || exit 1 ; iport="$OPTARG" ;; + s) setact add || exit 1 ; smtp="$OPTARG" ;; + S) setact add || exit 1 ; sport="$OPTARG" ;; + u) setact add || exit 1 ; login="$OPTARG" ;; + n) setact add || exit 1 ; realname="$OPTARG" ;; + m) setact add || exit 1 ; maxmes="$OPTARG" ;; + o) setact add || exit 1 ; online=True ;; + f) setact add || exit 1 ; force=True ;; + x) setact add || exit 1 ; password="$OPTARG" ;; + p) echo "NOTE: Protonmail users must install and configure Protonmail Bridge first for the first sync to work." + imap="127.0.0.1" + iport="1143" + smtp="127.0.0.1" + sport="1025" + ssltype="None" + tlsline="tls_fingerprint $(msmtp --serverinfo --host=$smtp --port=$sport --tls --tls-certcheck=off | awk '/SHA256:/ {print $2}')" + setact add || exit 1 + ;; *) cat << EOF mw: mutt-wizard, auto-configure email accounts for mutt including downloadable mail with \`isync\`. -Allowed options: - add Add and autoconfigure an email address (9 max.) - ls List configured accounts - delete Pick an account to delete - purge Delete all accounts and settings - cron Enable or disable an autosync via cronjob - all else Print this message +Main actions: + -a your@email.com Add an email address + -l List email addresses configured + -d Remove an already added address + -D your@email.com Force remove account without confirmation + -y your@email.com Sync mail for account by name + -Y Sync mail for all accounts + +Options allowed with -a: + -u Account login name if not full address + -n "Real name" to be on the email account + -i IMAP server address + -I IMAP server port + -s SMTP server address + -S SMTP server port + -x Password for account (recommended to be in double quotes) + -p Install for a Protonmail account. + -o Configure address, but keep mail online. + -b Assume typical English mailboxes without attempting log-on. NOTE: Once at least one account is added, you can run \`mbsync -a\` to begin downloading mail. + +To change an account's password, run \`pass edit ${pass_prefix}your@email.com\`. EOF +exit 1 +;; +esac done + +! command -v mbsync >/dev/null && [ -z "${force+x}" ] && printf "\`mbsync (isync package)\` must be installed to run mutt-wizard.\\n" && exit + +case "$action" in + list) list ;; + add) askinfo && getprofiles && writeinfo && getboxes && finalize || { delete ; exit 1 ;} ;; + delete) delete $fulladdr ;; + sync) syncwrapper $fulladdr ;; esac |