summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--README.md10
-rwxr-xr-xbin/mailsync47
-rwxr-xr-xbin/mw36
-rw-r--r--mw.14
-rw-r--r--share/domains.csv1
-rw-r--r--share/imapnotify-temp15
-rw-r--r--share/mbsync-temp2
-rw-r--r--share/mutt-temp2
-rw-r--r--share/mutt-wizard.muttrc2
10 files changed, 93 insertions, 28 deletions
diff --git a/Makefile b/Makefile
index 623aaf7..31f9aaa 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
.POSIX:
-PREFIX = /usr/local
+PREFIX ?= /usr/local
MANPREFIX = $(PREFIX)/share/man
install:
diff --git a/README.md b/README.md
index 07995cf..db4db34 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ https://muttwizard.com/
Get this great stuff without effort:
-- A full-featured and autoconfigured email client on the terminal with neomutt
+- A full-featured and autoconfigured email client on the terminal built with neomutt
- Mail stored offline enabling the ability to:
* view and write emails while you're away from
the internet
@@ -54,6 +54,8 @@ A user of Arch-based distros can also install the current mutt-wizard release fr
### Optional Dependencies
+- `goimapnotify` - required for push notifications.
+ [Check here for reference](https://wiki.archlinux.org/title/Isync#With_imapnotify).
- `pam-gnupg` - Automatically logs you into your GPG key on login so you will
never need to input your password once logged on to your system. Check the
repo and directions out [here](https://github.com/cruegge/pam-gnupg).
@@ -134,6 +136,12 @@ To give you an example of the interface, here's an idea:
- <kbd>ctrl-b</kbd> - open a menu to select a URL you want to open in your browser.
- <kbd>p</kbd> - encrypt/sign your message (in compose view, before sending the email).
+## Enable push notifications per mail
+**Note**: Replace the `fulladdrs` with your actual email address. You have to do this for each new mail you want to setup instant notifications.
+```bash
+systemctl enable --user goimapnotify@fulladdrs.service
+```
+
## Additional functionality
- `pam-gnupg` - Automatically logs you into your GPG key on login, so you will
diff --git a/bin/mailsync b/bin/mailsync
index cbd36ff..7bca2d0 100755
--- a/bin/mailsync
+++ b/bin/mailsync
@@ -24,6 +24,9 @@ eval "$(grep -h -- \
"$HOME/.config/zsh/.zshenv" "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.config/zsh/.zshrc" \
"$HOME/.pam_environment" 2>/dev/null)"
+# For non-interactive shell (e.g. cron job) run only when the GPG key (in $GNUPGHOME or pass --homedir) is unlocked
+tty -s || (echo "dummy" | gpg --sign --batch --pinentry-mode error -o /dev/null > /dev/null 2>&1) || exit
+
export GPG_TTY="$(tty)"
[ -n "$MBSYNCRC" ] && alias mbsync="mbsync -c $MBSYNCRC" || MBSYNCRC="$HOME/.mbsyncrc"
@@ -45,7 +48,7 @@ case "$(uname)" in
notify() { [ -n "$pgrepoutput" ] && for x in ${displays:-:0}; do
export DISPLAY="$x"
- notify-send --app-name="mutt-wizard" "$1" "$2"
+ notify-send --app-name="mutt-wizard" -- "$1" "$2"
done ;}
;;
esac
@@ -55,7 +58,7 @@ syncandnotify() {
case "$1" in
imap) mbsync -q "$2" ;;
pop) mpop -q "$2" ;;
- esac
+ esac || return 1
new=$(find\
"$HOME/.local/share/mail/$2/"[Ii][Nn][Bb][Oo][Xx]/new/ \
"$HOME/.local/share/mail/$2/"[Ii][Nn][Bb][Oo][Xx]/cur/ \
@@ -63,16 +66,17 @@ syncandnotify() {
newcount=$(echo "$new" | sed '/^\s*$/d' | wc -l)
case 1 in
$((newcount > 5)) )
- echo "$newcount new mail for $2."
- [ -z "$MAILSYNC_MUTE" ] && notify "New Mail!" "📬 $newcount new mail(s) in \`$2\` account."
+ echo "$newcount new mails for $2." >/dev/tty
+ [ -z "$MAILSYNC_MUTE" ] && notify "New Mail!" "📬 $newcount new mails in \`$2\` account."
;;
$((newcount > 0)) )
- echo "$newcount new mail for $2."
+ echo "$newcount new mail(s) for $2." >/dev/tty
[ -z "$MAILSYNC_MUTE" ] &&
for file in $new; do
- # Extract and decode subject and sender from mail.
- subject="$(sed -n "/^Subject:/ s|Subject: *|| p" "$file" |
- perl -CS -MEncode -ne 'print decode("MIME-Header", $_)')"
+ # Extract and decode subject and sender from mail.
+ subject=$(awk '/^Subject: / && ++n == 1,/^.*: / && ++i == 2' "$file" | sed '$d' |
+ perl -CS -MEncode -ne 'print decode("MIME-Header", $_)' |
+ sed 's/^Subject: //' | tr -d '\n\t')
from="$(sed -n "/^From:/ s|From: *|| p" "$file" |
perl -CS -MEncode -ne 'print decode("MIME-Header", $_)')"
from="${from% *}" ; from="${from%\"}" ; from="${from#\"}"
@@ -96,15 +100,34 @@ else
done || echo "error $arg"; done)"
fi
+pids= # PIDs of backgrounded subshells
+count=0 # number of accounts in $tosync
+failed=0 # number of failed sync attempts
for account in $tosync; do
+ count=$((count+1))
case $account in
- Channel*) syncandnotify imap "${account##* }" & ;;
- account*) syncandnotify pop "${account##* }" & ;;
- error*) echo "ERROR: Account ${account##* } not found." ;;
+ Channel*)
+ syncandnotify imap "${account##* }" &
+ pids="$pids $!"
+ ;;
+ account*)
+ syncandnotify pop "${account##* }" &
+ pids="$pids $!"
+ ;;
+ error*)
+ echo "ERROR: Account ${account##* } not found."
+ failed=$((failed+1))
+ ;;
esac
done
-wait
+IFS=' '
+for pid in $pids; do
+ wait $pid || failed=$((failed+1))
+done
+
+# Abort if no account sync succeeded
+[ "$count" -gt "$failed" ] || exit 1
notmuch new --quiet
diff --git a/bin/mw b/bin/mw
index 44086be..b7ded22 100755
--- a/bin/mw
+++ b/bin/mw
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
set -a
@@ -12,12 +12,14 @@ msmtprc="${XDG_CONFIG_HOME:-$HOME/.config}/msmtp/config"
msmtplog="${XDG_STATE_HOME:-$HOME/.local/state}/msmtp/msmtp.log"
mbsyncrc="${MBSYNCRC:-$HOME/.mbsyncrc}"
mpoprc="${XDG_CONFIG_HOME:-$HOME/.config}/mpop/config"
+imapnotify="${XDG_CONFIG_HOME:-$HOME/.config}/imapnotify"
mpoptemp="$muttshare/mpop-temp"
mbsynctemp="$muttshare/mbsync-temp"
mutttemp="$muttshare/mutt-temp"
msmtptemp="$muttshare/msmtp-temp"
onlinetemp="$muttshare/online-temp"
notmuchtemp="$muttshare/notmuch-temp"
+imapnotifytemp="$muttshare/imapnotify-temp"
# With the use of templates, it's impossible to use parameter substitution.
# Therefore, some default variables that might be otherwise overwritten are set
# here.
@@ -29,14 +31,19 @@ maxmes="0"
alias mbsync='mbsync -c "$mbsyncrc"'
-# mbsync now requires "Far/Near" rather than "Master/Slave", but Ubuntu/Debian
-# have the older version.
-if command -V apt-get >/dev/null 2>&1; then
- master="Master"
- slave="Slave"
-else
+# mbsync >=1.4.0 requires "Far/Near" rather than "Master/Slave."
+mbver="$(mbsync -v)"
+mbver="${mbver#* }"
+mbver="${mbver%.*}"
+# Comparing two float numbers in bash is a pain in the butt, so we get rid of
+# dots and turn them into nice integers
+mbver="${mbver/\./}"
+if [ "${mbver}" -gt 14 ]; then
master="Far"
slave="Near"
+else
+ master="Master"
+ slave="Slave"
fi
for x in "/etc/ssl/certs/ca-certificates.crt" \
@@ -63,7 +70,6 @@ list() { getaccounts && [ -n "$accounts" ] && echo "$accounts" || exit 1; }
prepmsmtp() {
mkdir -p "${msmtprc%/*}" "${msmtplog%/*}"
- ln -s "$msmtprc" "$HOME/.msmtprc" 2>/dev/null
envsubst <"$msmtptemp" >>"$msmtprc"
}
@@ -78,6 +84,10 @@ prepmpop() {
envsubst <"$mpoptemp" >>"$mpoprc"
}
+prepimapnotify() {
+ mkdir -p "$imapnotify" ; envsubst < "$imapnotifytemp" >> "$imapnotify/$fulladdr.yaml"
+}
+
prepmutt() {
mkdir -p "${muttrc%/*}" "$accdir"
envsubst <"$mutttemp" >"$accdir/$fulladdr.muttrc"
@@ -85,6 +95,7 @@ prepmutt() {
! grep -q "^source.*mutt-wizard.muttrc" "$muttrc" && echo "source $muttshare/mutt-wizard.muttrc" >>"$muttrc"
! grep "^source.*.muttrc" "$muttrc" | grep -qv "$muttshare/mutt-wizard.muttrc" && echo "source $accdir/$fulladdr.muttrc" >>"$muttrc"
echo "macro index,pager i$idnum '<sync-mailbox><enter-command>source $accdir/$fulladdr.muttrc<enter><change-folder>!<enter>;<check-stats>' \"switch to $fulladdr\"" >>"$muttrc"
+ neomutt -v | grep -q lmdb && ! grep -q "^set header_cache_backend.*lmdb" "$muttrc" && echo "set header_cache_backend = \"lmdb\"" >>"$muttrc"
}
getprofiles() {
@@ -106,6 +117,7 @@ getprofiles() {
prepmsmtp
prepmutt
prepnotmuch
+ prepimapnotify
}
parsedomains() {
@@ -181,7 +193,7 @@ askinfo() {
}
insertpass() {
- printf "%s" "$password" | pass insert -fe "$PASSWORD_STORE_DIR/$passprefix$fulladdr"
+ printf "%s" "$password" | pass insert -fe "$passprefix$fulladdr"
}
errorexit() {
@@ -208,7 +220,7 @@ getboxes() {
if [ -n "${force+x}" ]; then
mailboxes="$(printf "INBOX\\nDrafts\\nJunk\\nTrash\\nSent\\nArchive")"
else
- info="$(curl --location-trusted -s -m 5 --user "$login:$(pass "$passprefix$fulladdr")" --url "${protocol:-imaps}://$imap:${iport:-993}")"
+ info="$(curl --proxy "$proxy" --location-trusted -s -m 5 --user "$login:$(pass "$passprefix$fulladdr")" --url "${protocol:-imaps}://$imap:${iport:-993}")"
[ -z "$info" ] && errorexit
mailboxes="$(echo "$info" | grep -v HasChildren | sed "s/.*\" //;s/\"//g" | tr -d '\r')"
fi
@@ -288,6 +300,7 @@ Options allowed with -a:
-X Delete an account's local email too when deleting.
-o Configure address, but keep mail online.
-f Assume typical English mailboxes without attempting log-on.
+ -R Use a proxy server for curl (useful for bypassing network restrictions)
NOTE: Once at least one account is added, you can run
\`mbsync -a\` to begin downloading mail.
@@ -320,9 +333,10 @@ reorder() {
' "$tempfile" >>"$muttrc"
}
-while getopts "rfpXlhodTYD:y:i:I:s:S:u:a:n:P:x:m:t:" o; do case "${o}" in
+while getopts "rfpXlhodTYD:y:i:I:s:S:u:a:n:P:x:m:t:R:" o; do case "${o}" in
l) setact list ;;
r) setact reorder ;;
+ R) proxy="$OPTARG" ;;
d) setact delete ;;
D)
setact delete
diff --git a/mw.1 b/mw.1
index 4a136ee..d442ed0 100644
--- a/mw.1
+++ b/mw.1
@@ -70,8 +70,12 @@ SMTP server port (assumed to be 465 if not specified)
.TP
.B -x
Account password. You will be prompted for the password interactively if this option is not given.
+.TP
.B -P
Pass Prefix. The password will be stored using pass at <passprefix><email>
+.TP
+.B -R
+Use a proxy server for curl (useful for bypassing network restrictions)
.SH OTHER OPTIONS
.TP
.B -f
diff --git a/share/domains.csv b/share/domains.csv
index beb7a1e..374dce7 100644
--- a/share/domains.csv
+++ b/share/domains.csv
@@ -304,6 +304,7 @@ ukr.net,imap.ukr.net,993,smtp.ukr.net,465
umbc.edu,imap.gmail.com,993,smtp.gmail.com,587
uni-duesseldorf.de,mail.hhu.de,993,mail.hhu.de,465
uni-jena.de,imap.uni-jena.de,993,smtp.uni-jena.de,587
+uni-weimar.de,mailgate.uni-weimar.de,993,mailgate.uni-weimar.de,465
uni.edu.pe,imap.gmail.com,993,smtp.gmail.com,587
uni.strath.ac.uk,outlook.office365.com,993,smtp.office365.com,587
unilodz.eu,outlook.office365.com,993,smtp.office365.com,587
diff --git a/share/imapnotify-temp b/share/imapnotify-temp
new file mode 100644
index 0000000..a81cba2
--- /dev/null
+++ b/share/imapnotify-temp
@@ -0,0 +1,15 @@
+{
+ "host": "$imap",
+ "port": $iport,
+ "tls": true,
+ "tlsOptions": {
+ "rejectUnauthorized": false
+ },
+ "username": "$login",
+ "password": "",
+ "passwordCmd": "pass $passprefix$fulladdr",
+ "onNewMail": "mailsync",
+ "onNewMailPost": "",
+ "boxes": [ "INBOX" ]
+}
+
diff --git a/share/mbsync-temp b/share/mbsync-temp
index 4e77b09..ead3920 100644
--- a/share/mbsync-temp
+++ b/share/mbsync-temp
@@ -4,7 +4,7 @@ Port $iport
User $login
PassCmd "pass $passprefix$fulladdr"
AuthMechs LOGIN
-SSLType $imapssl
+TLSType $imapssl
CertificateFile $sslcert
MaildirStore $fulladdr-local
diff --git a/share/mutt-temp b/share/mutt-temp
index 63841ad..82e16ef 100644
--- a/share/mutt-temp
+++ b/share/mutt-temp
@@ -6,7 +6,7 @@ set sendmail = "msmtp -a $fulladdr"
alias me $realname <$fulladdr>
set folder = "$folder"
set header_cache = "$cachedir/$safename/headers"
-set message_cachedir = "$cachedir/$safename/bodies"
+set message_cache_dir = "$cachedir/$safename/bodies"
set mbox_type = Maildir
set hostname = "$hostname"
source $muttshare/switch.muttrc
diff --git a/share/mutt-wizard.muttrc b/share/mutt-wizard.muttrc
index 27ae216..f236bc4 100644
--- a/share/mutt-wizard.muttrc
+++ b/share/mutt-wizard.muttrc
@@ -101,7 +101,7 @@ macro index \eh "<pipe-message>$prefix/libexec/gpg-wks-client --receive | msmtp
macro index,pager a "<enter-command>set my_pipe_decode=\$pipe_decode pipe_decode<return><pipe-message>abook --add-email<return><enter-command>set pipe_decode=\$my_pipe_decode; unset my_pipe_decode<return>" "add the sender address to abook"
macro index \Cr "T~U<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "mark all messages as read"
macro index O "<shell-escape>mailsync<enter>" "run mailsync to sync all mail"
-macro index \Cf "<enter-command>unset wait_key<enter><shell-escape>printf 'Enter a search term to find with notmuch: '; read x; echo \$x >~/.cache/mutt_terms<enter><limit>~i \"\`notmuch search --output=messages \$(cat ~/.cache/mutt_terms) | head -n 600 | perl -le '@a=<>;s/\^id:// for@a;$,=\"|\";print@a' | perl -le '@a=<>; chomp@a; s/\\+/\\\\+/g for@a; s/\\$/\\\\\\$/g for@a;print@a' \`\"<enter>" "show only messages matching a notmuch pattern"
+macro index \Cf "<enter-command>unset wait_key<enter><shell-escape>printf 'Enter a search term to find with notmuch: '; read x; echo \$x >\"\${XDG_CACHE_HOME:-\$HOME/.cache}/mutt_terms\"<enter><limit>~i \"\`notmuch search --output=messages \$(cat \"\${XDG_CACHE_HOME:-\$HOME/.cache}/mutt_terms\") | head -n 600 | perl -le '@a=<>;s/\^id:// for@a;$,=\"|\";print@a' | perl -le '@a=<>; chomp@a; s/\\+/\\\\+/g for@a; s/\\$/\\\\\\$/g for@a;print@a' \`\"<enter>" "show only messages matching a notmuch pattern"
macro index A "<limit>all\n" "show all messages (undo limit)"
# Sidebar mappings