pymailq.store – Mails queue storage objects

The store module provide several objects to convert mails queue content into python structures.

PostqueueStore Objects

class pymailq.store.PostqueueStore[source]

Postfix mails queue informations storage.

The PostqueueStore provides methods to load Postfix queued mails informations into Python structures. Thoses structures are based on Mail and MailHeaders classes which can be processed by a MailSelector instance.

The PostqueueStore class defines the following attributes:

mails

Loaded MailClass objects list().

loaded_at

datetime.datetime instance to store load date and time informations, useful for datas deprecation tracking. Updated on load() call with datetime.datetime.now() method.

postqueue_cmd

list object to store Postfix command and arguments to view the mails queue content. This property use Postfix mails content parsing command defined in pymailq.CONFIG attribute under the key ‘list_queue’. Command and arguments list is build on call with the configuration data.

spool_path

Postfix spool path string. Default is "/var/spool/postfix".

postqueue_mailstatus

Postfix known queued mail status list. Default is ['active', 'deferred', 'hold'].

mail_id_re

Python compiled regular expression object (re.RegexObject) provided by re.compile() method to match postfix IDs. Recognized IDs are either:

  • hexadecimals, 8 to 12 chars length (regular queue IDs)
  • encoded in a 52-character alphabet, 11 to 16 chars length (long queue IDs)

They can be followed with * or !. Default used regular expression is:

r"^([A-F0-9]{8,12}|[B-Zb-z0-9]{11,16})[*!]?$".
mail_addr_re

Python compiled regular expression object (re.RegexObject) provided by re.compile() method to match email addresses. Default used regular expression is: r"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+$"

MailClass

The class used to manipulate/parse mails individually. Default is Mail.

See also

Python modules:

datetime – Basic date and time types

re – Regular expression operations

Postfix manual:
postqueue – Postfix queue control

RFC 3696 – Checking and Transformation of Names

The PostqueueStore instance provides the following methods:

PostqueueStore.load([method])[source]

Load content from postfix mails queue.

Mails are loaded using postqueue command line tool or reading directly from spool. The optionnal argument, if present, is a method string and specifies the method used to gather mails informations. By default, method is set to "postqueue" and the standard Postfix queue control tool: postqueue is used.

Optionnal argument parse controls whether mails are parsed or not. This is useful to load every known mail headers for later filtering.

Parameters:
  • method (str) – Method used to load mails from Postfix queue
  • filename (str) – File to load mails from
  • parse (bool) – Controls whether loaded mails are parsed or not.

Provided method str() name is directly used with getattr() to find a self._load_from_<method> method.

PostqueueStore._load_from_postqueue()[source]

Load content from postfix queue using postqueue command output.

Output lines from _get_postqueue_output are parsed to build Mail objects. Sample Postfix queue control tool (postqueue) output:

C0004979687     4769 Tue Apr 29 06:35:05  sender@domain.com
(error message from mx.remote1.org with parenthesis)
                                         first.rcpt@remote1.org
(error message from mx.remote2.org with parenthesis)
                                         second.rcpt@remote2.org
                                         third.rcpt@remote2.org

Parsing rules are pretty simple:

  • Line starts with a valid Mail.qid: create new Mail object with qid, size, date and sender informations from line.

    Queue ID Size Reception date and time Sender
    C0004979687 4769 Tue Apr 29 06:35:05 user@domain.com
  • Line starts with a parenthesis: store error messages to last created Mail object’s errors attribute.

  • Any other matches: add new recipient to the recipients attribute of the last created Mail object.

Optionnal argument filename can be set with a file containing output of the postqueue command. In this case, output lines of postqueue command are directly read from filename and parsed, the postqueue command is never used.

Optionnal argument parse controls whether mails are parsed or not. This is useful to load every known mail headers for later filtering.

Parameters:
  • filename (str) – File to load mails from
  • parse (bool) – Controls whether loaded mails are parsed or not.
PostqueueStore._load_from_spool()[source]

Load content from postfix queue using files from spool.

Mails are loaded using the command defined in postqueue_cmd attribute. Some informations may be missing using the _load_from_spool() method, including at least Mail.status field.

Optionnal argument parse controls whether mails are parsed or not. This is useful to load every known mail headers for later filtering.

Loaded mails are stored as Mail objects in mails attribute.

Parameters:parse (bool) – Controls whether loaded mails are parsed or not.

Warning

Be aware that parsing mails on disk is slow and can lead to high load usage on system with large mails queue.

PostqueueStore._get_postqueue_output()[source]

Get Postfix postqueue command output.

This method used the postfix command defined in postqueue_cmd attribute to view the mails queue content.

Command defined in postqueue_cmd attribute is runned using a subprocess.Popen instance.

Returns:Command’s output lines.
Return type:list()

See also

Python module:
subprocess – Subprocess management
PostqueueStore._is_mail_id(mail_id)[source]

Check mail_id for a valid postfix queued mail ID.

Validation is made using a re.RegexObject stored in the mail_id_re attribute of the PostqueueStore instance.

Parameters:mail_id (str) – Mail Postfix queue ID string
Returns:True or false
Return type:bool()
PostqueueStore.summary()[source]

Summarize the mails queue content.

Returns:Mail queue summary as dict

Sizes are in bytes.

Example response:

{
    'total_mails': 500,
    'total_mails_size': 709750,
    'average_mail_size': 1419.5,
    'max_mail_size': 2414,
    'min_mail_size': 423,
    'top_errors': [
        ('mail transport unavailable', 484),
        ('Test error message', 16)
    ],
    'top_recipient_domains': [
        ('test-domain.tld', 500)
    ],
    'top_recipients': [
        ('user-3@test-domain.tld', 200),
        ('user-2@test-domain.tld', 200),
        ('user-1@test-domain.tld', 100)
    ],
    'top_sender_domains': [
        ('test-domain.tld', 500)
    ],
    'top_senders': [
        ('sender-1@test-domain.tld', 100),
        ('sender-2@test-domain.tld', 100),
        ('sender-7@test-domain.tld', 50),
        ('sender-4@test-domain.tld', 50),
        ('sender-5@test-domain.tld', 50)
    ],
    'top_status': [
        ('deferred', 500),
        ('active', 0),
        ('hold', 0)
    ],
    'unique_recipient_domains': 1,
    'unique_recipients': 3,
    'unique_sender_domains': 1,
    'unique_senders': 8
}

Mail Objects

class pymailq.store.Mail(mail_id[, size[, date[, sender]]])[source]

Simple object to manipulate email messages.

This class provides the necessary methods to load and inspect mails content. This object functionnalities are mainly based on email module’s provided class and methods. However, email.message.Message instance’s stored informations are extracted to extend Mail instances attributes.

Initialization of Mail instances are made the following way:

Parameters:
  • mail_id (str) – Mail’s queue ID string
  • size (int) – Mail size in Bytes (Default: 0)
  • date (datetime.datetime) – Acceptance date and time in mails queue. (Default: None)
  • sender (str) – Mail sender string as seen in mails queue. (Default: empty str())

The Mail class defines the following attributes:

qid

Mail Postfix queue ID string, validated by _is_mail_id() method.

size

Mail size in bytes. Expected type is int().

parsed

bool() value to track if mail’s content has been loaded from corresponding spool file.

parse_error

Last encountered parse error message str().

date

datetime object of acceptance date and time in mails queue.

status

Mail’s queue status str().

sender

Mail’s sender str() as seen in mails queue.

recipients

Recipients list() as seen in mails queue.

errors

Mail deliver errors list() as seen in mails queue.

head

Mail’s headers MailHeaders structure.

postcat_cmd

This property use Postfix mails content parsing command defined in pymailq.CONFIG attribute under the key ‘cat_message’. Command and arguments list is build on call with the configuration data.

The Mail instance provides the following methods:

Mail.parse()[source]

Parse message content.

This method use Postfix mails content parsing command defined in postcat_cmd attribute. This command is runned using subprocess.Popen instance.

Parsed headers become attributes and are retrieved with help of message_from_string() function provided by the email module.

See also

Postfix manual:
postcat – Show Postfix queue file contents
Mail.dump()[source]

Dump mail’s gathered informations to a dict object.

Mails informations are splitted in two parts in dictionnary. postqueue key regroups every informations directly gathered from Postfix queue, while headers regroups MailHeaders attributes converted from mail content with the parse() method.

If mail has not been parsed with the parse() method, informations under the headers key will be empty.

Returns:Mail gathered informations
Return type:dict
Mail.show()[source]

Return mail detailled representation for printing

Returns:Representation as str

MailHeaders Objects

class store.MailHeaders[source]

Simple object to store mail headers.

Object’s attributes are dynamically created when parent Mail object’s method parse() is called. Those attributes are retrieved with help of message_from_string() method provided by the email module.

Standard RFC 822-style mail headers becomes attributes including but not limited to:

  • Received
  • From
  • To
  • Cc
  • Bcc
  • Sender
  • Reply-To
  • Subject

Case is kept while creating attribute and access will be made with Mail.From or Mail.Received for example. All those attributes will return list of values.

See also

Python modules:

email – An email and MIME handling package

email.message.Message – Representing an email message

RFC 822 – Standard for ARPA Internet Text Messages