summaryrefslogtreecommitdiff
path: root/bin/movemymail
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2022-03-19 23:17:15 -0700
committerSean Whitton <spwhitton@spwhitton.name>2022-03-20 15:01:21 -0700
commitbacca5472be0acb8029b5204c39c071f2ab8eefc (patch)
tree936180b0cebec2f23d929b572b0a896a0616c151 /bin/movemymail
parent0f132e0a7cc2a90a325a5615abd15f7b1c49a820 (diff)
downloaddotfiles-bacca5472be0acb8029b5204c39c071f2ab8eefc.tar.gz
rewrite movemymail
Diffstat (limited to 'bin/movemymail')
-rwxr-xr-xbin/movemymail113
1 files changed, 55 insertions, 58 deletions
diff --git a/bin/movemymail b/bin/movemymail
index 05527c35..bb99686b 100755
--- a/bin/movemymail
+++ b/bin/movemymail
@@ -1,68 +1,65 @@
-#!/bin/bash
+#!/usr/bin/perl
-. $HOME/.shenv
+use 5.032;
+use strict;
+use warnings;
+use autodie ":all";
-if [ -e "$HOME/.nomovemymail" ]; then
- echo >&2 "no movemymail"
- exit 1
-fi
+use Fcntl qw(LOCK_EX LOCK_NB);
+use Net::Domain "hostfqdn";
-space=$(df -khP "$HOME/.fmail" | sed -e1d | awk '{ print $4 }')
-if ! [[ $space =~ G$ ]]; then
- echo >&2 "free disc space is low; no movemymail"
- exit 1
-fi
+# Ensure only one copy of this script is ever running, and then we assume that
+# mbsync isn't already running either, as always invoked via this script.
+open our $us, "<", $0 or die $!;
+exit 0 unless flock $us, LOCK_EX|LOCK_NB;
-# if using notmuch on this machine, sync its database to maildir & git
-if [ -f "$HOME/.fmail/.notmuch/xapian/iamglass" ]; then
- mr -d "$HOME/lib/nmbug-spw" autoci
+die "no movemymail\n" if -e "$ENV{HOME}/.nomovemymail";
+open my $df, "-|", "df", "-kP", "$ENV{HOME}/.fmail";
+<$df>, my @df_fields = split " ", <$df>;
+$df_fields[3] > 1048576 or die "free space low; no movemymail\n";
- # ensure all drafts are in the drafts folder
- floating_drafts=$(notmuch search --output=files -- tag:draft and not folder:drafts and not tag:deleted)
- if [ ! -z "$floating_drafts" ]; then
- # TODO for each entry in $floating_drafts, if it contains the
- # substring ".fmail/annex", remove it from $floating_drafts
- # (mdmv used to do this, but now I plan to upload it to
- # Debian, it doesn't)
- chronic mdmv $floating_drafts $HOME/.fmail/drafts
- fi
+our $on_athena = hostfqdn eq "athena.silentflame.com";
- # ensure all spam is in the spam folder to train FastMail's spam filter
- floating_spam=$(notmuch search --output=files -- tag:spam and not folder:spam)
- if [ ! -z "$floating_spam" ]; then
- # TODO for each entry in $floating_drafts, if it contains the
- # substring ".fmail/annex", remove it from $floating_drafts
- # (mdmv used to do this, but now I plan to upload it to
- # Debian, it doesn't)
- chronic mdmv $floating_spam $HOME/.fmail/spam
- fi
+# Sync notmuch's database to maildir and to git.
+if (-d "$ENV{HOME}/.fmail/.notmuch/xapian") {
+ # Skip on athena because it's v. slow atm.
+ system "mr", "-d", "$ENV{HOME}/lib/nmbug-spw", "autoci" unless $on_athena;
- # ensure all deleted messages are in the trash folder
- floating_deleted=$(notmuch search --output=files -- tag:deleted and not folder:trash)
- if [ ! -z "$floating_deleted" ]; then
- # TODO for each entry in $floating_drafts, if it contains the
- # substring ".fmail/annex", remove it from $floating_drafts
- # (mdmv used to do this, but now I plan to upload it to
- # Debian, it doesn't)
- chronic mdmv $floating_deleted $HOME/.fmail/trash
- fi
-fi
+ # Ensure messages tagged in Emacs are in the appropriate folder. In the
+ # case of spam, this should train FastMail's spam filter.
+ search2folder("drafts", "tag:draft", "and", "not", "tag:deleted");
+ search2folder("spam", "tag:spam");
+ search2folder("trash", "tag:deleted");
+}
-if offline; then
- echo >&2 ERROR: We\'re offline\; cannot sync mail
- exit 1
-else
- # this shouldn't be necessary because there is
- # /etc/network/if-up.d/postfix, but it's cheap so just call again
- # here
- postqueue -f
+system [0, 1], "offline";
+$? >> 8 == 0 and die "we're offline; cannot further sync mail\n";
- if pgrep -u $USER mbsync 2>/dev/null; then
- (killall --user $USER mbsync 2>/dev/null && sleep 5) || true
- killall -9 --user $USER mbsync 2>/dev/null || true
- fi
- mbsync fastmail
-fi
+system "postqueue", "-f";
+system "mbsync", "fastmail";
-# to confirm queue was flushed before I close laptop lid
-mailq
+# athena's 'notmuch new' cronjob is responsible for imap-dl(1) runs. We have
+# this here rather than separate cronjob entries so that hitting 'G' in
+# athena's Emacs inbox displays new mail from the other accounts.
+if ($on_athena) {
+ system "imap-dl", "$ENV{HOME}/.config/mailscripts/imap-dl.selene";
+ system "imap-dl", "$ENV{HOME}/.config/mailscripts/imap-dl.catmail";
+}
+
+# Useful to see if any mail has got stuck before closing laptop lid.
+`mailq` =~ "Mail queue is empty" or warn "WARNING: Outbox not empty.\n";
+
+sub search2folder {
+ my ($folder, @terms) = @_;
+ open my $search, "-|", "notmuch", "search", "--output=files", "--",
+ "(", @terms, ")", "and", "not", "folder:$folder";
+ my @matches;
+ for (<$search>) {
+ next if m{^$ENV{HOME}/.fmail/annex/};
+ chomp;
+ # If notmuch's database is out-of-date the file may no longer exist
+ # because it's already been moved by a previous run of this script.
+ -f and push @matches, $_
+ }
+ @matches and system "mdmv", @matches, "$ENV{HOME}/.fmail/$folder";
+}