Skip to content

gabrys/pymalist

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

+ What is pymalist

Pymalist is a minimal and modular mail list software for Python

+ How does pymalist work

pymalist works like this:

# using fetcher it fetches mail
 * if NothingMore exception is raised program ends
 * if other exception is raised, it is being passed to reactor
   and program ends
# mail is processed with processor
# processed mail is distributed with distributor
# go to #1

In component raises an exception (other than NothingMore) it
gets handled by reactor.

You have to supply fetcher, processor, distributor and reactor
objects the the play method. Basically you need to write a few
lines of code to do it, but you can use built-in fetchers,
distributors, processors and reactors.

[[code]]

   ---------------                  ---------------
  |               |   exception    |               |
  |    fetcher    |--------------->|    reactor    |
  |               |                |               |
   ---------------                  ---------------
          |                             ^     ^
          |                             |     |
   ---------------                      |     |
  |               |       exception     |     |
  |   processor   |---------------------      |
  |               |                           |
   ---------------                            |
          |                                   |
          |                                   |
   ---------------                            |
  |               |         exception         |
  |  distributor  |---------------------------
  |               |
   ---------------

[[/code]]

+ The basic components

The basic fetchers are:
* Pop3Fetcher - to fetch mails from dedicated POP3 account
* StdInFetcher - to get one mail from stdin (from procmail)

The basic distributors are:
* SmtpDistributor - to distribute mails with SMTP server
* MultipleDistributor - distribute mails with many distributors
* DeliverToDistributor - distribute to given list of
                         recipients using given distributor

The basic processors are:
* SingleListProcessor - used for a sigle list list
                        (does not check To: header)
* ManyListsProcessor - container of many SingleListProcessors
                       that directs the mail to be processed
                       by right one

The basic reactor is:
* StdErrLogger - loggs each exception to standard error

+ Example mail list server

Example script, that fetches all mail from POP3 account processes
two mail lists and distributes mails with SMTP server and send each
copy of mail to archive mail address using the same SMTP distributor
as for distributing the emails to real recipients:

[[code]]

from pymalist import play
from fetchers import *
from processors import *
from distributors import *
from reactors import *

pop3 = Pop3Fetcher(
    host     = 'pop3.example.com',
    user     = 'example',
    password = 'hackyou',
    ssl      = True,
)

smtp = SmtpDistributor(
    host     = 'smtp.example.com',
    user     = 'example',
    password = 'hackyou',
    tls      = True,
)

play(
    fetcher = pop3,
    distributor = MultipleDistributor(
        smtp,
        DeliverToDistributor(['archive@example.com'], smtp),
    )

    processor = MoreListsProcessor(
        SingleListProcessor(
            list_mail = 'Red mail list <red@list.example.com>',
            subject_prefix = '[Red] ',
            subscribers = ['you@example.com', 'me@example.com']
        ),
        SingleListProcessor(
            list_mail = 'Green mail list <green@list.example.com>',
            subject_prefix = '[Green] ',
            subscribers = ['you@example.com', 'me@example.com']
        ),
    ),
    reactor=StdErrLogger(),
)

[[/code]]

You'll want to run the script periodically (for example in cron).

+ Customization or adding new features

If you need another logic to fetch, distribute, process or react
to exceptions, you need to create a custom fetcher, distributor,
processor or reactor.

Every fetcher object must have "fetch" method, that returns
the next mail as a email.Message object. Convert it from message
string by email.message_from_string(message_string). If there
is no new mail, raise fetchers.NothingMore exception.

Every distributor object must have "distribute" method, that
gets mail message (email.Message) with has additional
properties set:

* ml_sender - the original sender
* ml_send_to - addresses to send message to
* ml_list - "Mail List Name" <address@somewhere>

Distributor should distribute the mails (but of course it can
do anything - store, archive, send, play music, eject CD tray
and play 8-bit music on PC speaker).

Every processor must have "process" method, that takes one
argument - the mail message fetched and returns mail message
enhanced with at least ml_sender, ml_send_to and ml_list
properties (see above for explanation). An exception should
be raised if the message should not be distributed because of
some violation (person can't post to list or something). If
message should be delivered, but there is zero recipients,
just set ml_send_to property to empty list: [].

Every reactor implements "react" method that takes two
arguments: type of error (currently string "fetcher",
"processor" or "distributor") and the exception that was
raised. NothingMore exception raised by fetcher is not passed
to reactor.

+ Why did I write this

I wrote this software in a few hours, because I didn't find
any good mail list software that was flexible enough to

* read email from a remote mailbox (with POP3 or IMAP)
* distribute emails with a remote SMTP server (possibly using
  the same mailbox)
* require no root permissions
* is modular enough

I know my mail list is not perfect, because it has no
input/output queues, no (un)subscribe features nor mail
archive, but using the concepts of fetchers, distributors,
processors and reactors they can be easily plugged-in.

Author: Piotr Gabryjeluk
Started: 22 May 2009

About

Highly modular mail list for Python

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages