Re: Checking from an external file?

Milan Obuch <[email protected]> Sun, 18 May 2025 10:44:36 +0200
Newsgroups gmane.mail.maildrop
Message-ID <[email protected]>
On Sun, 18 May 2025 17:40:10 +1000
Philip Rhoades via Courier-maildrop
<[email protected]> wrote:

> Milan,
> 
> Thanks so much for responding - see inline comments:
> 

I can add some as well :)

> On 2025-05-18 16:29, Milan Obuch wrote:
> > On Sun, 18 May 2025 10:50:33 +1000
> > Philip Rhoades via Courier-maildrop
> > <[email protected]> wrote:
> >   
> >> People,
> >> 
> >> Part of my .mailfilter looks like this:
> >> 
> >> # .spam ^Subject: Uppper {{{3
> >> if ( /^Subject:  INQ /:h \
> >>      || /^Subject:  \(/:h \
> >>      || /^Subject: (Top|Luxury) Watches/:h \
> >>      || /^Subject: 180/:h \
> >>      || /^Subject: 4mJ/:h \
> >>      || /^Subject: =?UTF/:h \
> >>      || /^Subject: ? eat this.../:h \
> >>      || /^Subject: \*\*/:h \
> >>      || /^Subject: \.You/:h \
> >>      || /^Subject: \[CONFINDENTIAL\]/:h \
> >>      || /^Subject: \[Mayo Clinic Research\]/:h \
> >>      || /^Subject: A .*(reverse|Daily).*(payment|Sprinkle)/:h \
> >>      || /^Subject: Action Required/:h \
> >>      || /^Subject: ACH/:h \
> >>      || /^Subject: ACTIVEZ/:h \
> >> 
> >> etc.
> >> 
> >> Is it possible to have a separate file with all the lines in so
> >> that section of .mailfilter could be reduced to something like:
> >> 
> >> # .spam ^Subject: Uppper {{{3
> >> if ( /^Subject:  "/home/phr/Maildir/spam_upper.txt" /:h )
> >> 
> >> ?
> >>   
> > 
> > Why not?
> > 
> > I am doing something similar with List-Id header, simplified version
> > here:  
> 
> 
> I will have a closer look at this code to understand it better but
> see below.
> 

Maybe a bit more explanation could help you...

> >   if (/^List-Id: *(.*)/)

This tests for existence of List-Id mail header, commonly used by
mailing list software to mark mail as being sent via mailing list, and
record which one it was.

For your use case, substitute ^List-Id: with ^Subject:

> >    {ListId = $MATCH1

This way, ListId value is being set to List-Id header value, so it can
be processed below.

> >     if ($ListId =~ /.*\<(.*)\>/)

List-Id mail header commonly contains some free text human readable
description and list identifier, the later enclosed in angle brackets
(<>).

> >      ListId = $MATCH1

Extract true list identifier.

> >     if (gdbmopen('.list.db','R'))

Open db file for reading.

> >      echo 'gdbmopen error R1'

Report problem in log.

> >     else
> >      {MAILDIR = gdbmfetch($ListId)

Extract desired folder for given list identifier.

> >       gdbmclose

Close database.

> >       if ($MAILDIR)

Folder for given identifier found, use it below.

> >        {exception {to "$HOME/Maildir/$MAILDIR/"

Put mail in designated folder if it exist, use default folder in case
of any error, so the mail does not get lost.

> >                   }
> >        }
> >      }
> >    }  
> 
> 
> I think I get the idea but I might need to experiment with a test
> user to properly understand it.
> 

I hope my detailed notes (maybe too detailed for you, but I have no
idea about level of your experience, so I went rather to detail here)
help you in your experiments.

> > File .list.db contains mappings from mailing list header to maildir
> > folder, it is created from .list text file, containing List-Id and
> > maildir folder name delimited by spaces/tabs, which, for this list,
> > is
> > 
> > courier-maildrop.lists.sourceforge.net 
> > .Software.Courier.courier-maildrop  
> 
> 
> Right.
> 
> 
> > This file is converted into .list.db with following code:
> > 
> >    {if (gdbmopen('.list.db','N'))
> >      echo 'gdbmopen error N1'
> >     else
> >      {foreach (`cat $HOME/.list`) =~ /\S+\s+\S+/
> >        {$MATCH =~ /(\S+)\s+(\S+)/;
> >         if (gdbmstore($MATCH1,$MATCH2))
> >          echo "gdbm $MATCH1 => $MATCH2 problem!"
> >        }
> >       gdbmclose
> >      }
> >    }  
> 
> 
> Right.
> 
> 
> > (yes, in maildrop - it is triggered when .list file is changed)  
> 
> 
> Right - I am a bit anxious about a db - I guess I preferred just text 
> files for simplicity etc but this might work . .
> 

I think the same. When I wrote those recipes, years ago, I do no longer
remember how much years, I found the database functions in maildrop are
simpler actually, and probably more efficient than sequential tests.
Think of it as some kind of cache - file parsing occurs once, when file
is changed, and then quick lookup is done on mail delivery.

Actually, if you need just some string presence test for your use case,
there is lookup function in maildrop, which could be just the right one
for you, but my first response was based on what I actually use, and my
use case requires not only presence test, but some associated value for
the string found as well.

> > I have 101 lines in my .list file, so while its handling looks
> > somewhat complex, it is simpler to maintain long-term... and when I
> > created this, I was willing to spend some time to learn things and
> > automatize mail processing when possible.  
> 
> 
> Yes, I am too - however one reason for looking into this idea was 
> because when I added 2,534 lines to my .mailfilter file, I got a core 
> dump . . even with verbose = 5 I can't see why . . I thought looking
> up a separate file might help sort out problems.
> 

Ah, yes, using some kind of lookup for grouping similar case greatly
reduces complexity of maildrop recipe, which in turn makes it easier to
look for some syntax problem or anything weird you may have encountered.

Regards,
Milan