#!/bin/bash # Script moves tagged mails to their respective folders if they are still lying around in INBOX # It also moved mails tagged with "del" to the Trash folder, "archive" to Archive, and "spam" to Spam folder CURDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) CSV="$CURDIR"/tag-list.csv # Table of tags/folders MAILDIR="$HOME/Mails/FSFE" # Maildir TRASHTAG="del" # Tag of trashed mails TRASHFOL="Trash" # Trash bin folder SPAMTAG="spam" # Tag of spam mails SPAMFOL="INBOX.Junk" # Spam folder ARCHTAG="archive" # Archive tag ARCHFOL="ARCHIVE" # Archive folder LOG="$CURDIR"/move-tag.log # Location of logfile USETAGS=".+" # List of tags which shall be moved THREADTAGS=".+" # List of tags for which single, but connected messages in INBOX shall be tagged BL_USETAGS="" BL_THREADTAGS="$TRASHTAG|$SPAMTAG|$ARCHTAG|draft" touch "$LOG" # Create logfile or update time stamp function pdate { DATE=$(date +%y-%m-%d_%H:%M:%S) echo "[$DATE]" } function logrun { # Write command itself to log, and pipe errors to log echo "$(pdate) $@" >> "$LOG" eval "$@" 2>> "$LOG" } while read line; do TAG=$(echo $line | cut -d";" -f1) FOL=$(echo $line | cut -d";" -f2) if ! $(echo $BL_USETAGS | grep -qE "${TAG}($|\|)") && $(echo $TAG | grep -qE "$USETAGS"); then BL_USETAGS="$TAG,$BL_USETAGS" # Add current tag to list of tags which do not have to be searched for another time # TRASH tag "del" if [ "$TAG" = "$TRASHTAG" ]; then HITFILES=$(notmuch search --output=files --exclude=false tag:$TRASHTAG and not path:$TRASHFOL/**) # Files which are tagged with "del" but not in Trash bin FOL="$TRASHFOL" # Set destination folder to Trash # SPAM tag "spam" elif [ "$TAG" = "$SPAMTAG" ]; then HITFILES=$(notmuch search --output=files --exclude=false tag:$SPAMTAG and not path:$SPAMFOL/**) # Files which are tagged with "spam" but not in Spam folder FOL="$SPAMFOL" # Set destination folder to INBOX.Junk # ARCHIVE tag "archive" elif [ "$TAG" = "$ARCHTAG" ]; then HITFILES=$(notmuch search --output=files --exclude=false tag:$ARCHTAG and not path:$ARCHFOL/**) # Files which are tagged with "archive" but not in ARCHIVE folder # Folder will be derived from the current position later # DEFAULT else # For some tags, also tag its threads if ! $(echo $BL_THREADTAGS | grep -qE "${TAG}($|\|)") && $(echo $TAG | grep -qE "$THREADTAGS"); then # If one file is tagged (except del, spam, archive), also tag the other mails of its thread respectively, IF they are located in INBOX [TODO: is this the best approach?]. Only then they can be moved by this script # 1. Get thread ids of all entries with the searched tag THREADS=$(notmuch search --exclude=false tag:$TAG and date:$(date -d "-6 weeks" +%Y-%m-%d)..$(date -d "+1 year" +%Y-%m-%d) | cut -d" " -f1 | cut -d":" -f2) # 2. Get message ids of all messages in these threads MID= for t in $THREADS; do MID="$MID "$(notmuch search --output=messages --exclude=false thread:$t) # MID consists of many something like "id:5XXX0CD1.305516@fsfe.org" done # 3. Tag all message ids of messages which are still in INBOX for m in $MID; do if $(notmuch search --exclude=false --output=files "$m" | grep -q "$MAILDIR/INBOX/"); then logrun notmuch tag +"$TAG" -- "$m" fi done # Search for these lone messages in INBOX HITFILES=$(notmuch search --output=files --exclude=false path:INBOX/** and tag:$TAG | grep "$MAILDIR/INBOX/") fi fi # Move files to their destination folders for m in $HITFILES; do # Destination folder is derived from the current location if [ "$TAG" = "$ARCHTAG" ]; then SUBFOL=$(echo $m | sed -E "s|($MAILDIR)/(.+?)/cur/.*|\2|g") FOL="$ARCHFOL/$SUBFOL" fi DESTFOL="$MAILDIR/$FOL/cur" if [ ! -e "$DESTFOL" ]; then logrun mkdir -p "$DESTFOL" fi logrun mv "$m" "$DESTFOL" done fi done < "$CSV"