nix-config/home/modules/mail/mailsync.nix

133 lines
3.9 KiB
Nix

{ config, pkgs, ... }:
let
shell = "${pkgs.dash}/bin/dash";
pidof = "${pkgs.procps}/bin/pidof";
pgrep = "${pkgs.procps}/bin/pgrep";
grep = "${pkgs.gnugrep}/bin/grep";
sed = "${pkgs.gnused}/bin/sed";
awk = "${pkgs.gawk}/bin/awk";
perl = "${pkgs.perl}/bin/perl";
find = "${pkgs.findutils}/bin/find";
notifySend = "${pkgs.libnotify}/bin/notify-send";
notmuch = "${pkgs.notmuch}/bin/notmuch";
head = "${pkgs.coreutils}/bin/head";
touch = "${pkgs.coreutils}/bin/touch";
tr = "${pkgs.coreutils}/bin/tr";
mbsyncrc = "${config.home.homeDirectory}/.mbsyncrc";
mbsync = "${pkgs.isync}/bin/mbsync -c ${mbsyncrc}";
maildir = "${config.home.homeDirectory}/Maildir";
passwordStoreDir = "${config.home.homeDirectory}/.password-store";
notmuchConfig = "${config.home.homeDirectory}/.config/notmuch/default/config";
gnupghome = "${config.home.homeDirectory}/.gnupg";
lastrun = "${config.home.homeDirectory}/.mailsynclastrun";
in pkgs.writeScriptBin "mailsync" ''
#!${shell}
# Run only if not already running in other instance
${pidof} mbsync >/dev/null && {
echo "mbsync is already running."
exit
}
export PASSWORD_STORE_DIR="${passwordStoreDir}"
export NOTMUCH_CONFIG="${notmuchConfig}"
export GNUPGHOME="${gnupghome}"
export GPG_TTY=$TTY
notify() {
pgrepoutput="$(${pgrep} -a X\(org\|wayland\))"
displays="$(echo "$pgrepoutput" | ${grep} -wo "[0-9]*:[0-9]\+" | sort -u)"
[ -n "$pgrepoutput" ] && for x in ''${displays:-0:}; do
export DISPLAY=$x
${notifySend} \
--app-name="email" \
"email" \
"📬 $2 new mail(s) in \`$1\` account."
done
}
messageinfo() {
from="$1"
subject="$2"
pgrepoutput="$(${pgrep} -a X\(org\|wayland\))"
displays="$(echo "$pgrepoutput" | ${grep} -wo "[0-9]*:[0-9]\+" | sort -u)"
[ -n "$pgrepoutput" ] && for x in ''${displays:-0:}; do
export DISPLAY=$x
${notifySend} \
--app-name="email" \
"📧$from:" \
"$subject"
done
}
# Check account for new mail. Notify if there is new content.
syncandnotify() {
accounts="$1"
acc="$(echo "$account" | ${sed} "s/.*\///")"
if [ -z "$opts" ]; then
${mbsync} "$acc"
else
${mbsync} "$opts" "$acc"
fi
new=$(
${find} \
"${maildir}/$acc/INBOX/new/" \
"${maildir}/$acc/Inbox/new/" \
"${maildir}/mail/$acc/inbox/new/" \
-type f \
-newer "${lastrun}" \
2> /dev/null
)
newcount=$(echo "$new" | ${sed} '/^\s*$/d' | wc -l)
if [ "$newcount" -gt 5 ]; then
notify "$acc" "$newcount"
elif [ "$newcount" -gt 0 ]; then
for file in $new; do
# Extract subject and sender from mail.
from=$(
${awk} '/^From: / && ++n ==1,/^\<.*\>:/' "$file" | \
${perl} -CS -MEncode -ne 'print decode("MIME-Header", $_)' | \
${awk} '{ $1=""; if (NF>=3)$NF=""; print $0 }' | \
${sed} 's/^[[:blank:]]*[\"'\'''\<]*//;s/[\"'\'''\>]*[[:blank:]]*$//'
)
subject=$(
${awk} '/^Subject: / && ++n == 1,/^\<.*\>: / && ++i == 2' "$file" | \
${head} -n 1 | ${perl} -CS -MEncode -ne 'print decode("MIME-Header", $_)' | \
${sed} 's/^Subject: //' | \
${sed} 's/^{[[:blank:]]*[\"'\'''\<]*//;s/[\"'\'''\>]*[[:blank:]]*$//' | \
${tr} -d '\n'
)
messageinfo "$from" "$subject" &
done
fi
}
# Sync accounts passed as argument or all.
if [ "$#" -eq "0" ]; then
accounts="$(${awk} '/^Channel/ {print $2}' "${mbsyncrc}")"
else
for arg in "$@"; do
[ "''${arg%''${arg#?}}" = '-' ] && \
opts="''${opts:+''${opts} }''${arg}" && \
shift 1
done
accounts=$*
fi
# Parallelize multiple accounts
for account in $accounts; do
syncandnotify "''${account}" &
done
wait
${notmuch} new 2>/dev/null
#Create a touch file that indicates the time of the last run of mailsync
${touch} "${lastrun}"
''