~dricottone/mail-filters

b1a1f1c45b92fbfdba87ad9babc58a9caa2b177b — Dominic Ricottone 2 years ago 4286bae
Significant updates

digestion and parcels are now hard dependencies.

The awk approach to handling Mailman digests is now deprecated and
removed.
9 files changed, 80 insertions(+), 192 deletions(-)

M Makefile
M README.md
M src/ao3.awk
M src/fanfiction.awk
M src/freebsd.awk
D src/mailman.awk
M src/mailman.sh
A src/open-in-browser.sh
D src/ubuntu.awk
M Makefile => Makefile +2 -4
@@ 9,9 9,8 @@ install:
	install -m755 src/freebsd.awk $(INSTALL_DIR)/freebsd.awk
	install -m755 src/googlegroups.awk $(INSTALL_DIR)/googlegroups.awk
	install -m755 src/html.sh $(INSTALL_DIR)/html.sh
	install -m755 src/mailman.awk $(INSTALL_DIR)/mailman.awk
	install -m755 src/mailman.sh $(INSTALL_DIR)/mailman.sh
	install -m755 src/ubuntu.awk $(INSTALL_DIR)/ubuntu.awk
	install -m755 src/open-in-browser.sh $(INSTALL_DIR)/open-in-browser.sh

uninstall:
	rm $(INSTALL_DIR)/ao3.awk


@@ 20,8 19,7 @@ uninstall:
	rm $(INSTALL_DIR)/freebsd.awk
	rm $(INSTALL_DIR)/googlegroups.awk
	rm $(INSTALL_DIR)/html.sh
	rm $(INSTALL_DIR)/mailman.awk
	rm $(INSTALL_DIR)/mailman.sh
	rm $(INSTALL_DIR)/ubuntu.awk
	rm $(INSTALL_DIR)/open-in-browser.sh
	rmdir $(INSTALL_DIR)


M README.md => README.md +37 -33
@@ 1,25 1,25 @@
# mail-filters

A set of text processing scripts that 'clean' plaintext email messages. This includes
My mail filters for `aerc` and/or `mutt`.

It's a set of text processing scripts that 'clean' plaintext email messages,
such as...

 + removing cruft and repetitive text
 + removing non-plaintext MIME parts
 + inserting ANSI color codes
 + standardizing whitespace



## Installation

Run `sudo make install`. All it's going to do is copy the filters to /usr/local/share, though. I don't know why I even wrote this.

Install [digestion](https://git.dominic-ricottone.com/~dricottone/digestion)
and [parcels](https://git.dominic-ricottone.com/~dricottone/parcels).

Run `sudo make install`.

## Uninstallation

Run `make uninstall`. Again, all we're doing is copying files... This is a bit much...


Run `make uninstall`.

## Recommended aerc configuration:



@@ 27,21 27,20 @@ In `aerc.conf`:

```
[filters]
text/html                =path/to/html.sh
from,Archive of Our Own  =path/to/ao3.awk
from,FanFiction          =path/to/fanfiction.awk
to,~.@lists.ubuntu.com   =path/to/ubuntu.awk
to,~.@lists.debian.org   =path/to/debian.awk
from,~.@freebsd.org      =path/to/freebsd.awk
from,~.+@googlegroups.com=path/to/googlegroups.awk
from,~.+@archlinux.org   =path/to/mailman.sh
from,~.+@python.org      =path/to/mailman.sh
from,~.+@gnu.org         =path/to/mailman.sh
text/*                   =cat
text/html                     =/usr/local/share/mail-filters/html.sh
from,Archive of Our Own       =/usr/local/bin/parcels | /usr/local/share/mail-filters/ao3.awk
from,FanFiction               =/usr/local/bin/parcels | /usr/local/share/mail-filters/fanfiction.awk
from,ProPublica's Daily Digest=/usr/local/bin/parcels
to,~.@lists.ubuntu.com        =/usr/local/bin/parcels
to,~.@lists.debian.org        =/usr/local/bin/parcels | /usr/local/share/mail-filters/debian.awk
from,~.@freebsd.org           =/usr/local/bin/parcels | /usr/local/share/mail-filters/freebsd.awk
from,~.+@googlegroups.com     =/usr/local/bin/parcels | /usr/local/share/mail-filters/googlegroups.awk
from,~.+@lists.archlinux.org  =/usr/local/share/mail-filters/mailman.sh
from,~.+@python.org           =/usr/local/share/mail-filters/mailman.sh
from,~.+@gnu.org              =/usr/local/share/mail-filters/mailman.sh
text/*                        =/usr/local/bin/parcels
```

If possible, install [digestion](https://git.dominic-ricottone.com/digestion) as well. `mailman.sh` will automatically make use of it.


## Recommended mutt configuration



@@ 58,33 57,38 @@ tmp=$(mktemp /tmp/filter.XXXXXXXX)
cat > "$TMP"

if grep --quiet -e '^From: Archive of Our Own' "$TMP"; then
  cat "$TMP" | path/to/ao3.awk
  cat "$TMP" | /usr/local/bin/parcels | /usr/local/share/mail-filters/ao3.awk
elif grep --quiet -e '^From: FanFiction' "$TMP"; then
  cat "$TMP" | path/to/fanfiction.awk
  cat "$TMP" | /usr/local/bin/parcels | /usr/local/share/mail-filters/fanfiction.awk
elif grep --quiet -e '^From: ProPublica\'s Daily Digest' "$TMP"; then
  cat "$TMP" | /usr/local/bin/parcels
elif grep --quiet -e '^To:.*@lists.ubuntu.com' "$TMP"; then
  cat "$TMP" | path/to/ubuntu.awk
  cat "$TMP" | /usr/local/bin/parcels
elif grep --quiet -e '^To:.*@lists.debian.org' "$TMP"; then
  cat "$TMP" | path/to/debian.awk
  cat "$TMP" | /usr/local/bin/parcels | /usr/local/share/mail-filters/debian.awk
elif grep --quiet -e '^From:.*@freebsd.org' "$TMP"; then
  cat "$TMP" | path/to/freebsd.awk
  cat "$TMP" | /usr/local/bin/parcels | /usr/local/share/mail-filters/freebsd.awk
elif grep --quiet -e '^From:.*@googlegroups.com' "$TMP"; then
  cat "$TMP" | path/to/googlegroups.awk
  cat "$TMP" | /usr/local/bin/parcels | /usr/local/share/mail-filters/googlegroups.awk
elif grep --quiet -e '^From:.*@archlinux.org' "$TMP"; then
  cat "$TMP" | path/to/mailman.sh
  cat "$TMP" | /usr/local/share/mail-filters/mailman.sh
elif grep --quiet -e '^From:.*@python.org' "$TMP"; then
  cat "$TMP" | path/to/mailman.sh
  cat "$TMP" | /usr/local/share/mail-filters/mailman.sh
elif grep --quiet -e '^From:.*@gnu.org' "$TMP"; then
  cat "$TMP" | path/to/mailman.sh
  cat "$TMP" | /usr/local/share/mail-filters/mailman.sh
else
  cat "$TMP"
  cat "$TMP" | /usr/local/bin/parcels
fi

rm -f "$TMP"
```


`mailman.sh` is a simple wrapper around `digestion` that gracefully handles the
that binary being unavailable. Meanwhile `parcels` is critical to using these
mail filters, so it is mandatory.

## License

All materials of this repository are licensed under BSD-3. A copy of this license is included in the file LICENSE.md.
All materials of this repository are licensed under BSD-3. A copy is included
here as `LICENSE.md`.


M src/ao3.awk => src/ao3.awk +9 -7
@@ 6,16 6,18 @@
# from Archive of Our Own (AO3), highlighting descriptive information

BEGIN {
  highlight="\033[44m";
  dim="\033[2m";
  cyan="\033[36m";
  reset="\033[0m";

  comma_replacement=reset ", " highlight;
  skip=0;

  comma_replacement=reset ", " dim cyan;
}
{
  # stop processing at end of mail
  if ($0 ~ /^You're receiving this email/) exit 0;
  # skip footer
  if ($0 ~ /^You're receiving this email/) skip=1;
  if ($0 ~ /^URLs:/) skip=0;

  if ($0 ~ /\([1-9][0-9]* words\)/) {
    matched=match($0, /\([1-9][0-9]* words\)/);


@@ 40,15 42,15 @@ BEGIN {
  }
  else if ($0 ~ /^(Relationships|Characters):/) {
    gsub(/, /,comma_replacement);
    $2=highlight $2
    $2=dim cyan $2
    $0=$0 reset
  }
  else if ($0 ~ /^Additional Tags:/) {
    gsub(/, /,comma_replacement);
    $3=highlight $3
    $3=dim cyan $3
    $0=$0 reset
  }

  print $0;
  if (skip==0) print $0;
}


M src/fanfiction.awk => src/fanfiction.awk +10 -8
@@ 3,21 3,23 @@
# fanfiction.awk
# ==============
# A filter (as for mutt or aerc) intended to clean & decorate plaintext mail
# from FanFiction.net, highlighting descriptive information
# from FanFiction.net, dim cyaning descriptive information

BEGIN {
  highlight="\033[44m";
  dim="\033[2m";
  cyan="\033[36m";
  reset="\033[0m";

  comma_replacement=reset ", " highlight;
  brace_replacement=reset "] " highlight;
  skip=0;

  comma_replacement=reset ", " dim cyan;
  brace_replacement=reset "] " dim cyan;
  close_brace_replacement=reset "] ";
}
{
  # stop processing at end of mail, marked by website URL
  if ($0 ~ /^FanFiction http/) exit 0;
  if ($0 ~ /^FanFiction \[/) skip=1;
  if ($0 ~ /^URLs:/) skip=0;

  if ($0 ~ /^New (story|chapter) from/) {
    $4=cyan $4;


@@ 29,10 31,10 @@ BEGIN {
  }
  else if ($0 ~ /^Character:/) {
    if ($2 ~ /^\[/) {
      $2="[" highlight substr($2,2);
      $2="[" dim cyan substr($2,2);
    }
    else {
      $2=highlight $2;
      $2=dim cyan $2;
    }
    gsub(/, /,comma_replacement);
    gsub(/\] /,brace_replacement);


@@ 44,6 46,6 @@ BEGIN {
    }
  }

  print $0;
  if (skip==0) print $0;
}


M src/freebsd.awk => src/freebsd.awk +0 -30
@@ 38,21 38,6 @@ BEGIN {
      else if ($0 !~ /^=/) {
        $0=dim cyan $0 reset;
      }

      # highlight release names
      for (i=10; i<=12; i++) {
        for (j=1; j<=4; j++) {
          release=i "." j "-STABLE";
          replacement=yellow release cyan;
          gsub(release,replacement);

          for (k=1; k<=9; k++) {
            release=i "." j "-RELEASE-p" k;
            replacement=yellow release cyan;
            gsub(release,replacement);
          }
        }
      }
    }
    else {
      # highlight section titles


@@ 66,21 51,6 @@ BEGIN {
      else if ($1=="#") {
        $0=cyan $0 reset;
      }

      # highlight release names
      for (i=10; i<=12; i++) {
        for (j=1; j<=4; j++) {
          release=i "." j "-STABLE";
          replacement=yellow release reset;
          gsub(release,replacement);

          for (k=1; k<=9; k++) {
            release=i "." j "-RELEASE-p" k;
            replacement=yellow release reset;
            gsub(release,replacement);
          }
        }
      }
    }

    if (do_not_print==0) print $0;

D src/mailman.awk => src/mailman.awk +0 -52
@@ 1,52 0,0 @@
#!/bin/awk -f

# mailman.awk
# ===========
# A filter (as for mutt or aerc) intended to clean & decorate plaintext mail
# from mailman servers, highlighting header information

BEGIN {
  in_todays_topics=0;
  do_not_print=0;

  dim="\033[2m";
  cyan="\033[36m";
  reset="\033[0m";
}
{
  # skip blocks of non-text (HTML, PGP Signatures, non-text MIME parts)
  if (do_not_print==1 && $0 ~ /(<\/html>|END PGP SIGNATURE)/) do_not_print=0;
  else if ($0 ~ /(<html>|BEGIN PGP SIGNATURE)/) do_not_print=1;

  else {
    # identify "Today's Topics"
    if (in_todays_topics==1 && $0 ~ /^-{5,}/) in_todays_topics=0;
    else if ($0 ~ /^Today's Topics:/) in_todays_topics=1;

    # highlight "Today's Topics"
    if (in_todays_topics==1) {
      matched=match($0, /\([^)]+\)/);
      if (matched!=0) {
        original=substr($0, RSTART, RLENGTH);
        replacement=reset original;
        sub(/\([^)]+\)/,replacement);
      }
      if ($0 ~ /^ +[1-9][0-9]?\./) {
        $1=$1 dim cyan;
        $0=$0 reset;
      }
      else if ($0 !~ /^Today's Topics:/) {
        $0=dim cyan $0 reset
      }
    }

    # highlight header lines
    else if ($0 ~ /^(Subject|Date|From|To|Cc):/) {
      $1=$1 dim cyan;
      $0=$0 reset;
    }

    if (do_not_print==0) print $0;
  }
}


M src/mailman.sh => src/mailman.sh +7 -4
@@ 4,10 4,13 @@
# ==========
# A filter (as for mutt or aerc) which runs digestion and an awk filter.

if command -v /usr/local/share/mail-filters/digestion 2>&1 >/dev/null; then
  /usr/local/share/mail-filters/digestion -length $(tput cols) \
    | /usr/local/share/mail-filters/mailman.awk
DIGESTION_INSTALL_DIR=/usr/local/bin
MAILFILTERS_INSTALL_DIR=/usr/local/share/mail-filters

if command -v $DIGESTION_INSTALL_DIR/digestion 2>&1 >/dev/null; then
  $DIGESTION_INSTALL_DIR/digestion -length $(tput cols) \
    | $MAILFILTERS_INSTALL_DIR/mailman.awk
else
    /usr/local/share/mail-filters/mailman.awk
  $MAILFILTERS_INSTALL_DIR/mailman.awk
fi


A src/open-in-browser.sh => src/open-in-browser.sh +15 -0
@@ 0,0 1,15 @@
#!/bin/sh

# open-in-browser.sh
# ==================
# A wrapper around parcels which opens a selected URL in a browser.

PARCELS_INSTALL_DIR=/usr/local/bin
BROWSER=firefox

url="$($PARCELS_INSTALL_DIR/parcels -n "$1")"
if [ -z "$url" ]; then
  exit 1
fi
exec $BROSWER "$url"


D src/ubuntu.awk => src/ubuntu.awk +0 -54
@@ 1,54 0,0 @@
#!/bin/awk -f

# ubuntu.awk
# ==========
# A filter (as for mutt or aerc) intended to clean & decorate plaintext mail
# to @lists.ubuntu.com, highlighting header information and hiding URLs

BEGIN {
  in_header=0;
  in_references=0;
  do_not_print_blank=0;

  dim="\033[2m";
  cyan="\033[36m";
  reset="\033[0m";

  colon_replacement=": " reset
}
{
  # identify header/references section
  if (in_header==1 && $0 ~ /^={5,}/) in_header=0;
  else if ($0 ~ /^={5,}/) in_header=1;
  else if (in_references==1 && $0 ~ /^\s+$/) in_references=0;
  else if ($0 ~ /^References:/) in_references=1;

  if (in_header==1) {
    if ($0 !~ /={5,}/) {
      $0=dim cyan $0 reset;
    }
  }
  else {
    # skip next line if blank
    if ($0 ~ /^(A security issue affects|Summary|Details|Software Description|Update instructions):/) do_not_print_blank=2;

    # highlight header details (except references)
    if ($0 ~ /^- [A-Za-z]/) {
      $2=dim cyan $2;
      $0=$0 reset;
      sub(/: /,colon_replacement);
    }
    else if (in_references==0 && $0 ~ /^  [A-Za-z]/) {
      $1=dim cyan $1 reset;
      $0="  " $0;
    }
  }

  if (do_not_print_blank==0) print $0;
  else {
    if ($0 !~ /^\s*$/) print $0;
    do_not_print_blank=do_not_print_blank-1;
  }
}