Skip to content

protocols.imap_server¤

protocols.imap_server ¤

Classes¤

protocols.imap_server.Server ¤

Server(logfile, secretary)

Bases: connectors.Server[imap_object.EMail], imaplib.IMAP4_SSL

IMAP server connector using mandatory SSL. Non-SSL connection is not implemented on purpose, because the Internet is a dangerous place and SSL only adds a little bit of safety, but it’s better than going out naked.

This class inherits from the Python standard class imaplib.IMAP4_SSL, so all the method are available, although most of them are re-wrapped here for direct and higher-level data handling.

The connection credentials are passed from core.secretary.Secretary.load_connectors from the settings.ini file of the current config subfolder.

Examples:

Mandatory content of the settings.ini file to declare IMAP connection credentials:

[imap]
    user = me@server.com
    password = xyz
    server = mail.server.com
    entries = 20
Attributes¤
protocols.imap_server.Server.mailbox instance-attribute ¤
mailbox: str = ''

The currently-opened or last-opened mailbox (aka (sub)folder).

protocols.imap_server.Server.folders instance-attribute ¤
folders: list[str]

The list of all IMAP mailboxes (folders and subfolders) found on the current server. This attribute is auto-set when initializing a connection to a server. It gets refreshed when new folders are added programmatically at runtime.

protocols.imap_server.Server.inbox instance-attribute ¤
inbox: str

The case-sensitive name of the system top-level and default mailbox. Gmail and Dovecot comply with the standard and call it INBOX, but Outlook/Office365 gets creative and call it Inbox. This attribute is properly set for the current server and should be used for portability instead of hard-coding "INBOX" in filters.

protocols.imap_server.Server.junk instance-attribute ¤
junk: str

The case-sensitive name of the server spam mailbox, typically called Junk or Spam.

protocols.imap_server.Server.trash instance-attribute ¤
trash: str

The case-sensitive name of the server trashbin mailbox.

protocols.imap_server.Server.sent instance-attribute ¤
sent: str

The case-sensitive name of the server mailbox where copies of sent emails are kept. Note that some client store sent emails in the same folder as the email they reply to.

protocols.imap_server.Server.archive instance-attribute ¤
archive: str

The case-sensitive name of the server mailbox where old emails may be automatically archived. Not all servers use it.

protocols.imap_server.Server.drafts instance-attribute ¤
drafts: str

The case-sensitive name of the server mailbox where emails written but not yet sent may be saved.

protocols.imap_server.Server.flagged instance-attribute ¤
flagged: str

The case-sensitive name of the server mailbox where emails marked as important (having the standard flag \Flagged) may be moved or duplicated. Not all servers use it.

protocols.imap_server.Server.n_messages instance-attribute ¤
n_messages: int

Default number of emails to retrieve (starting from the most recent). Set from the entries config parameter.

protocols.imap_server.Server.server instance-attribute ¤
server: str

URL or IP of the mailserver. Set from the server config parameter.

protocols.imap_server.Server.user instance-attribute ¤
user: str

Username of the mail account on the mailserver.

protocols.imap_server.Server.password instance-attribute ¤
password: str

Password of the mail account on the mailserver.

protocols.imap_server.Server.port instance-attribute ¤
port: int = 993

Connection port on the mailserver. Defaults to 993 (IMAP SSL).

Functions¤
protocols.imap_server.Server.build_subfolder_name ¤
build_subfolder_name(path: list) -> str

Assemble a complete subfolder name using the separator of the server.

Path should be the complete list of parent folders, e.g. path = ["INBOX", "Money", "Taxes"] will be assembled as INBOX.Money.Taxes or INBOX/Money/Taxes, depending on server’s defaults.

Then, replace the INBOX marker with the actual case-sensitive inbox name. This is to deal with Outlook/Office365 discrepancies in folders name.

PARAMETER DESCRIPTION
path

the tree of parents folders

TYPE: list

RETURNS DESCRIPTION
path

IMAP-encoded UTF-8 path

TYPE: str

protocols.imap_server.Server.split_subfolder_path ¤
split_subfolder_path(folder: str) -> list[str]

Find out what kind of separator is used on server for IMAP subfolder and split the parent folders into a list of folders.

Most servers use dots, like INBOX.Money.Taxes, but Outlook/Office365 uses slashes, like INBOX/Money/Taxes.

PARAMETER DESCRIPTION
folder

IMAP folder path

TYPE: str

RETURNS DESCRIPTION
tree

list of parent folders

TYPE: list

protocols.imap_server.Server.encode_imap_folder ¤
encode_imap_folder(folder: str) -> bytes

Ensure the subfolders are properly separated using the actual server separator (. or /) and encode the names in IMAP-custom UTF-7, taking care of non-latin characters and enquoting strings containing whitespaces. The result is ready for direct use in IMAP server commands.

This function takes fully-formed IMAP mailbox folder pathes, like INBOX.Money.Taxes or INBOX/Money/Taxes and will replace the subfolder separators with the server separator. The main INBOX will also be replaced by the proper, case-sensitive, inbox name for the current server.

PARAMETER DESCRIPTION
folder

IMAP folder as Python string

TYPE: str

RETURNS DESCRIPTION
folder

IMAP folder as IMAP-custom UTF-7 bytes.

TYPE: bytes

protocols.imap_server.Server.get_imap_folders ¤
get_imap_folders()

List all inbox subfolders as plain text, to be reused by filter definitions. Update the Server.folders list.

protocols.imap_server.Server.get_email ¤
get_email(uid: str, mailbox=None) -> imap_object.EMail | None

Get an arbitrary email by its UID. If no mailbox is specified, use the one defined when we got objects in self.set_objects().

If a mailbox is specified, we select it temporarilly and we restore the original mailbox used to get objects. If no mailbox is selected, we use the previously-selected one, typically in Server.get_objects.

PARAMETER DESCRIPTION
uid

the unique ID of the email in the mailbox. Be aware that this ID is unique only in the scope of one mailbox (aka IMAP (sub)folder) because it is defined as the positional order of reception of each email in the mailbox.

TYPE: str

RETURNS DESCRIPTION
message

the email object.

TYPE: imap_object.EMail

protocols.imap_server.Server.get_objects ¤
get_objects(mailbox: str, n_messages=-1)

Get the n last emails in a mailbox. Update the Server.objects list.

Processed email get logged with the number

PARAMETER DESCRIPTION
mailbox

the full path of the mailbox. It will be sanitized for folder/subfolder separator and actual INBOX name internally.

TYPE: str

n_messages

number of messages to fetch, starting with the most recent. If -1, the preference set in settings.ini will be used. Any other value will set it temporarily.

TYPE: int DEFAULT: -1

protocols.imap_server.Server.run_filters ¤
run_filters(filter, action, runs=1)

Run the function filter and execute the function action if the filtering condition is met

PARAMETER DESCRIPTION
filter

function performing checking arbitrary conditions on emails, returning True if the action should be performed. It will get an EMail object as argument.

TYPE: callable

action

function performing the actual action. It will get an EMail object as argument.

TYPE: callable

runs

how many times a filter should run at most on each email. -1 means no limit.

TYPE: int DEFAULT: 1

protocols.imap_server.Server.close_connection ¤
close_connection()

High-level method to logout from a server

protocols.imap_server.Server.create_folder ¤
create_folder(folder: str)

Create an IMAP (sub)folder recursively if needed (create the parent(s) if missing, then create the child).

Calls Server.create at each recursivity level, so IMAP folder names are fully sanitized.

protocols.imap_server.Server.create ¤
create(mailbox: str)

Create a new mailbox. This is a wrapper over imaplib.IMAP4.create method, where mailbox is directly encoded to IMAP-custom UTF-7 format through Server.encode_imap_folder.

The direct use of this function is discouraged, see Server.create_folder for a nicer method. Namely, this will error if trying to create a subfolder of a non-existing parent folder, and does not update Server.folders.

protocols.imap_server.Server.append ¤
append(mailbox: str, flags: str, email: email.message.EmailMessage) -> str

Add an arbitrary email to the specified mailbox.

PARAMETER DESCRIPTION
mailbox

Name of the target mailbox.

TYPE: str

flags

IMAP flags (RFC 3501 style), e.g.:

  • (\\Seen) → mark as read
  • (\\Flagged) → mark as important

Custom flags are allowed as long as they do not start with \.

TYPE: str

email

Fully constructed email message ready for storage.

TYPE: email.message.EmailMessage

RETURNS DESCRIPTION
str

status

TYPE: str