# GNU Mailutils -- a suite of utilities for electronic mail
# Copyright (C) 2009-2021 Free Software Foundation, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General
# Public License along with this library. If not, see
# .
from mailutils.c_api import mailbox
from mailutils import message
from mailutils import folder
from mailutils import url
from mailutils.error import MailboxError
class MailboxBase:
def open (self, mode=0):
"""Open the connection.
'mode' may be a string, consisting of the characters described
below, giving the access mode for the mailbox.
mode Meaning
--------------------------------------------------------
r Open for reading.
w Open for writing.
a Open for appending to the end of the mailbox.
c Create the mailbox if it does not exist.
"""
if isinstance (mode, str):
from mailutils import stream
flags = 0
for m in mode:
if m == 'r':
flags = flags | stream.MU_STREAM_READ
elif m == 'w':
flags = flags | stream.MU_STREAM_WRITE
elif m == 'a':
flags = flags | stream.MU_STREAM_APPEND
elif m == 'c':
flags = flags | stream.MU_STREAM_CREAT
if flags & stream.MU_STREAM_READ and flags & stream.MU_STREAM_WRITE:
flags = (flags & ~(stream.MU_STREAM_READ | \
stream.MU_STREAM_WRITE)) | \
stream.MU_STREAM_RDWR
mode = flags
status = mailbox.open (self.mbox, mode)
if status:
raise MailboxError (status)
def close (self):
"""Close the connection."""
status = mailbox.close (self.mbox)
if status:
raise MailboxError (status)
def flush (self, expunge=False):
"""Flush the mailbox."""
status = mailbox.flush (self.mbox, expunge)
if status:
raise MailboxError (status)
def messages_count (self):
"""Return the number of messages in mailbox."""
status, total = mailbox.messages_count (self.mbox)
if status:
raise MailboxError (status)
return total
def messages_recent (self):
"""Return the number of recent messages in mailbox."""
status, recent = mailbox.messages_recent (self.mbox)
if status:
raise MailboxError (status)
return recent
def message_unseen (self):
"""Return the number of first unseen message in mailbox."""
status, recent = mailbox.message_unseen (self.mbox)
if status:
raise MailboxError (status)
return unseen
def get_message (self, msgno):
"""Retrieve message number 'msgno'."""
status, c_msg = mailbox.get_message (self.mbox, msgno)
if status:
raise MailboxError (status)
return message.Message (c_msg)
def append_message (self, msg):
"""Append 'msg' to the mailbox."""
status = mailbox.append_message (self.mbox, msg.msg)
if status:
raise MailboxError (status)
def expunge (self):
"""Remove all messages marked for deletion."""
status = mailbox.expunge (self.mbox)
if status:
raise MailboxError (status)
def sync (self):
"""Synchronize the mailbox."""
status = mailbox.sync (self.mbox)
if status:
raise MailboxError (status)
def get_uidls (self):
"""Get UIDL list."""
status, uidls = mailbox.get_uidls (self.mbox)
if status:
raise MailboxError (status)
return uidls
def lock (self):
"""Lock the mailbox."""
status = mailbox.lock (self.mbox)
if status:
raise MailboxError (status)
def unlock (self):
"""Unlock the mailbox."""
status = mailbox.unlock (self.mbox)
if status:
raise MailboxError (status)
def get_size (self):
"""Return the mailbox size."""
status, size = mailbox.get_size (self.mbox)
if status:
raise MailboxError (status)
return size
def get_folder (self):
"""Get the Folder object."""
status, fld = mailbox.get_folder (self.mbox)
if status:
raise MailboxError (status)
return folder.Folder (fld)
def get_url (self):
"""Get the Url object."""
status, u = mailbox.get_url (self.mbox)
if status:
raise MailboxError (status)
return url.Url (u)
def __next__ (self):
if self.__count >= self.__len:
self.__count = 0
raise StopIteration
else:
self.__count += 1
return self.get_message (self.__count)
def __getitem__ (self, msgno):
return self.get_message (msgno)
def __iter__ (self):
self.__count = 0
self.__len = self.messages_count ()
return self
def __getattr__ (self, name):
if name == 'size':
return self.get_size ()
elif name == 'folder':
return self.get_folder ()
elif name == 'url':
return self.get_url ()
else:
raise AttributeError(name)
def __len__ (self):
return self.messages_count ()
def __str__ (self):
return '' % (self.get_url (), self.messages_count ())
class Mailbox (MailboxBase):
__owner = False
def __init__ (self, name):
if isinstance (name, mailbox.MailboxType):
self.mbox = name
else:
self.mbox = mailbox.MailboxType ()
self.__owner = True
status = mailbox.create (self.mbox, name)
if status:
raise MailboxError (status)
def __del__ (self):
if self.__owner:
mailbox.destroy (self.mbox)
del self.mbox
class MailboxDefault (MailboxBase):
def __init__ (self, name=None):
"""MailboxDefault creates a Mailbox object for the supplied
mailbox 'name'. Before creating, the name is expanded using
the rules below:
% --> system mailbox for the real uid
%user --> system mailbox for the given user
~/file --> /home/user/file
~user/file --> /home/user/file
+file --> /home/user/Mail/file
=file --> /home/user/Mail/file
"""
self.mbox = mailbox.MailboxType ()
status = mailbox.create_default (self.mbox, name)
if status:
raise MailboxError (status)
def __del__ (self):
mailbox.destroy (self.mbox)
del self.mbox