Re: mailman/rss?

dvanhorn <[email protected]> Wed, 29 Oct 2003 01:45:22 -0600
Newsgroups gmane.org.ballistichelmet.devel
Message-ID <[email protected]>
dvanhorn wrote:
> dvanhorn wrote:
>>latest-mail-list.ss gets the latest post to an archive using http, so
>>potentially, you could fetch archives of any list running Mailman.
>  
> That's a lie.  It fetches from the list's local mbox file.  It could easily do
> both, tho.  I'll have to add that feature.

[ rambling ideas about updating this code... ]

We can get a small mbox file containing this month's posts from either http or
a local file.  If we use the local file we need a base path.  Say,

   (define base-path "/usr/local/mailman/archives/public/")

as is the case on the BH machine.  The location of the mbox for this month's
posts is then:

   (build-path base-path list-name (string-append year-month ".txt"))

list-name and year-month would be strings like "heads" and "Oct-2003", in
which case we would read /usr/local/mailman/archives/public/heads/Oct-2003.txt
to get the latest posts.  If the file doesn't exist, we can try the month
before and so on until something is found.

To read a message you would do the following, where path is the above value:

   (call-with-input-file path port->rfc822-message)

We'll see port->rfc822-message in a second.

If we need to use http, we can define a base URL, eg.

   (define base-url (string->url "http://list.cs.brown.edu/pipermail/"))

The URL would be constructed as follows:

   (combine-url/relative base-url list-name (string-append year-month ".txt"))

To read a message you would do the following, where url is the above value:

   (call/input-url url get-pure-port port->rfc822-message)

port->rfc822-message would take an input-port and return a structure
representing an RFC 822 message.  The structure is defined as

   (define-struct rfc822-message (from-address from-date header body))

The from-address and from-date are read from the so-called From_ line that
delineate messages.  Note that this is different than the value of the "From:"
header.

header is a string that contains a series of CRLF-delimitted fields, and ends
with two CRLFs (the first one terminates the last field, and the second
terminates the header).  See Help Desk's info on the header type defined in
(lib "head.ss" "net").  We use (extract-field field-string header) -> string
or #f to get header values from the message.

The body is the rest of the message with >From unquoting performed.

port->rfc822-message essentially does the following:

>From mbox(5):

HOW A MESSAGE IS READ
     A reader scans through an mbox file looking for From_ lines.
     Any From_ line marks the beginning of a message.  The reader
     should not attempt to take advantage of the fact that  every
     From_ line (past the beginning of the file) is preceded by a
     blank line.

     Once the reader finds a message,  it  extracts  a  (possibly
     corrupted)  envelope  sender  and  delivery  date out of the
     From_ line.  It then reads until the next From_ line or  end
     of  file,  whichever  comes  first.  It strips off the final
     blank line and deletes  the  quoting  of  >From_  lines  and
     >>From_ lines and so on.  The result is an RFC 822 message.

Once we read a list of messages contained in the file we can print those
messages using RSS or HTML or whatever.  That should be the easy part.

Of course we don't have to report just the latest N messages.  We could define
any predicate to limit the set of messages we report.  We could, for example,
report any message from Jon, or match a regular expression against the title
header, and so on.

-d