maildir_watch.sh 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. #!/usr/bin/env bash
  2. # Watch Maildir inboxes for new mails and send a summary notification with notify-send. Tested and "works perfectly" with dunst.
  3. # Dependencies: inotifywait from inotify-tools package.
  4. maildir_path="$HOME/.mail" # Path to Maildir root.
  5. mailboxes=(inbox lists INBOX) # Mailboxes to watch.
  6. watchdirs=$(for box in ${mailboxes[*]}; do echo ${maildir_path}/$box/new; done)
  7. # Let inotifywait monitor changes and output each event on it's own line.
  8. while read line; do
  9. # Split inotify output to get path and the file that was added.
  10. parts=($(echo "$line" | sed -e 's/ \(CREATE\|MOVED_TO\) / /'))
  11. inbox_path="${parts[0]}"
  12. inbox=$(echo "$inbox_path" | grep -Po "(?<=/)\w+(?=/new)")
  13. mail="${parts[1]}"
  14. # Get subject and trim length.
  15. subject=$(grep -i "Subject:" ${inbox_path}/${mail} | cut -c1-30)
  16. # Get from field and display name or email.
  17. from_row=$(grep -i "^From:" ${inbox_path}/${mail} | sed 's/From:\s*//I')
  18. from_name=$(echo "$from_row" | grep -Po "[^<>]+(?=(?:<|$))")
  19. from_email=$(echo "$from_row" | grep -Po "(?<=<).+(?=>)")
  20. from="From: "
  21. if [ -n "$from_name" ]; then
  22. from="${from}${from_name}"
  23. elif [ -n "$from_email" ]; then
  24. from="${from}${from_email}"
  25. else
  26. from="${from}<unknown>"
  27. fi
  28. from=$(echo ${from} | cut -c1-30)
  29. # Get the body. First scroll down to body then strip signature, Content lines, random ID line, empty lines, join lines, substitute spaces to get more text and limit length.
  30. # TODO simplyfy by passing to HTML stripper or something.
  31. body=$(sed '1,/^$/d' "${inbox_path}/${mail}" | grep -v "^Content-.*:" | grep -v "^--[[:xdigit:]]\+" | sed -n '/-- /q;p' | sed '/^ *$/d' | tr "\\n" ' ' | sed 's/\s\s*/ /g' | cut -c1-80)
  32. # Notify summary string.
  33. out_summary=$(printf "[%s] %s, %s\\n" "$inbox" "$from" "$subject")
  34. # Notify body string.
  35. out_body=$(printf ", Body: %s [...]\\n" "$body")
  36. # Send the message with the name this scrip was invoked with.
  37. notify-send --app-name "${0##*/}" "$out_summary" "$out_body"
  38. done < <(inotifywait --monitor --event create --event moved_to ${watchdirs} 2>/dev/null)