Back to index

python3.2  3.2.2
Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes | Static Private Attributes
mailbox.Maildir Class Reference
Inheritance diagram for mailbox.Maildir:
Inheritance graph
[legend]
Collaboration diagram for mailbox.Maildir:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def add
def remove
def discard
def __setitem__
def get_message
def get_bytes
def get_file
def iterkeys
def __contains__
def __len__
def flush
def lock
def unlock
def close
def list_folders
def get_folder
def add_folder
def remove_folder
def clean
def next
def __delitem__
def get
def __getitem__
def get_string
def keys
def itervalues
def __iter__
def values
def iteritems
def items
def clear
def pop
def popitem
def update

Static Public Attributes

string colon = ':'

Private Member Functions

def _create_tmp
def _refresh
def _lookup

Private Attributes

 _paths
 _toc
 _toc_mtimes
 _last_read
 _skewfactor
 _onetime_keys

Static Private Attributes

int _count = 1

Detailed Description

A qmail-style Maildir mailbox.

Definition at line 255 of file mailbox.py.


Constructor & Destructor Documentation

def mailbox.Maildir.__init__ (   self,
  dirname,
  factory = None,
  create = True 
)
Initialize a Maildir instance.

Reimplemented from mailbox.Mailbox.

Definition at line 260 of file mailbox.py.

00260 
00261     def __init__(self, dirname, factory=None, create=True):
00262         """Initialize a Maildir instance."""
00263         Mailbox.__init__(self, dirname, factory, create)
00264         self._paths = {
00265             'tmp': os.path.join(self._path, 'tmp'),
00266             'new': os.path.join(self._path, 'new'),
00267             'cur': os.path.join(self._path, 'cur'),
00268             }
00269         if not os.path.exists(self._path):
00270             if create:
00271                 os.mkdir(self._path, 0o700)
00272                 for path in self._paths.values():
00273                     os.mkdir(path, 0o700)
00274             else:
00275                 raise NoSuchMailboxError(self._path)
00276         self._toc = {}
00277         self._toc_mtimes = {}
00278         for subdir in ('cur', 'new'):
00279             self._toc_mtimes[subdir] = os.path.getmtime(self._paths[subdir])
00280         self._last_read = time.time()  # Records last time we read cur/new
00281         self._skewfactor = 0.1         # Adjust if os/fs clocks are skewing

Here is the caller graph for this function:


Member Function Documentation

def mailbox.Maildir.__contains__ (   self,
  key 
)
Return True if the keyed message exists, False otherwise.

Reimplemented from mailbox.Mailbox.

Definition at line 398 of file mailbox.py.

00398 
00399     def __contains__(self, key):
00400         """Return True if the keyed message exists, False otherwise."""
00401         self._refresh()
00402         return key in self._toc

Here is the call graph for this function:

def mailbox.Mailbox.__delitem__ (   self,
  key 
) [inherited]

Definition at line 54 of file mailbox.py.

00054 
00055     def __delitem__(self, key):
00056         self.remove(key)

Here is the call graph for this function:

def mailbox.Mailbox.__getitem__ (   self,
  key 
) [inherited]
Return the keyed message; raise KeyError if it doesn't exist.

Definition at line 75 of file mailbox.py.

00075 
00076     def __getitem__(self, key):
00077         """Return the keyed message; raise KeyError if it doesn't exist."""
00078         if not self._factory:
00079             return self.get_message(key)
00080         else:
00081             with contextlib.closing(self.get_file(key)) as file:
00082                 return self._factory(file)

Here is the call graph for this function:

Here is the caller graph for this function:

def mailbox.Mailbox.__iter__ (   self) [inherited]

Definition at line 119 of file mailbox.py.

00119 
00120     def __iter__(self):
00121         return self.itervalues()

Here is the call graph for this function:

def mailbox.Maildir.__len__ (   self)
Return a count of messages in the mailbox.

Reimplemented from mailbox.Mailbox.

Definition at line 403 of file mailbox.py.

00403 
00404     def __len__(self):
00405         """Return a count of messages in the mailbox."""
00406         self._refresh()
00407         return len(self._toc)

Here is the call graph for this function:

def mailbox.Maildir.__setitem__ (   self,
  key,
  message 
)
Replace the keyed message; raise KeyError if it doesn't exist.

Reimplemented from mailbox.Mailbox.

Definition at line 334 of file mailbox.py.

00334 
00335     def __setitem__(self, key, message):
00336         """Replace the keyed message; raise KeyError if it doesn't exist."""
00337         old_subpath = self._lookup(key)
00338         temp_key = self.add(message)
00339         temp_subpath = self._lookup(temp_key)
00340         if isinstance(message, MaildirMessage):
00341             # temp's subdir and suffix were specified by message.
00342             dominant_subpath = temp_subpath
00343         else:
00344             # temp's subdir and suffix were defaults from add().
00345             dominant_subpath = old_subpath
00346         subdir = os.path.dirname(dominant_subpath)
00347         if self.colon in dominant_subpath:
00348             suffix = self.colon + dominant_subpath.split(self.colon)[-1]
00349         else:
00350             suffix = ''
00351         self.discard(key)
00352         new_path = os.path.join(self._path, subdir, key + suffix)
00353         os.rename(os.path.join(self._path, temp_subpath), new_path)
00354         if isinstance(message, MaildirMessage):
00355             os.utime(new_path, (os.path.getatime(new_path),
00356                                 message.get_date()))

Here is the call graph for this function:

def mailbox.Maildir._create_tmp (   self) [private]
Create a file in the tmp subdirectory and open and return it.

Definition at line 480 of file mailbox.py.

00480 
00481     def _create_tmp(self):
00482         """Create a file in the tmp subdirectory and open and return it."""
00483         now = time.time()
00484         hostname = socket.gethostname()
00485         if '/' in hostname:
00486             hostname = hostname.replace('/', r'\057')
00487         if ':' in hostname:
00488             hostname = hostname.replace(':', r'\072')
00489         uniq = "%s.M%sP%sQ%s.%s" % (int(now), int(now % 1 * 1e6), os.getpid(),
00490                                     Maildir._count, hostname)
00491         path = os.path.join(self._path, 'tmp', uniq)
00492         try:
00493             os.stat(path)
00494         except OSError as e:
00495             if e.errno == errno.ENOENT:
00496                 Maildir._count += 1
00497                 try:
00498                     return _create_carefully(path)
00499                 except OSError as e:
00500                     if e.errno != errno.EEXIST:
00501                         raise
00502             else:
00503                 raise
00504 
00505         # Fall through to here if stat succeeded or open raised EEXIST.
00506         raise ExternalClashError('Name clash prevented file creation: %s' %
00507                                  path)

Here is the call graph for this function:

Here is the caller graph for this function:

def mailbox.Maildir._lookup (   self,
  key 
) [private]
Use TOC to return subpath for given key, or raise a KeyError.

Definition at line 544 of file mailbox.py.

00544 
00545     def _lookup(self, key):
00546         """Use TOC to return subpath for given key, or raise a KeyError."""
00547         try:
00548             if os.path.exists(os.path.join(self._path, self._toc[key])):
00549                 return self._toc[key]
00550         except KeyError:
00551             pass
00552         self._refresh()
00553         try:
00554             return self._toc[key]
00555         except KeyError:
00556             raise KeyError('No message with key: %s' % key)

Here is the call graph for this function:

Here is the caller graph for this function:

def mailbox.Maildir._refresh (   self) [private]
Update table of contents mapping.

Definition at line 508 of file mailbox.py.

00508 
00509     def _refresh(self):
00510         """Update table of contents mapping."""
00511         # If it has been less than two seconds since the last _refresh() call,
00512         # we have to unconditionally re-read the mailbox just in case it has
00513         # been modified, because os.path.mtime() has a 2 sec resolution in the
00514         # most common worst case (FAT) and a 1 sec resolution typically.  This
00515         # results in a few unnecessary re-reads when _refresh() is called
00516         # multiple times in that interval, but once the clock ticks over, we
00517         # will only re-read as needed.  Because the filesystem might be being
00518         # served by an independent system with its own clock, we record and
00519         # compare with the mtimes from the filesystem.  Because the other
00520         # system's clock might be skewing relative to our clock, we add an
00521         # extra delta to our wait.  The default is one tenth second, but is an
00522         # instance variable and so can be adjusted if dealing with a
00523         # particularly skewed or irregular system.
00524         if time.time() - self._last_read > 2 + self._skewfactor:
00525             refresh = False
00526             for subdir in self._toc_mtimes:
00527                 mtime = os.path.getmtime(self._paths[subdir])
00528                 if mtime > self._toc_mtimes[subdir]:
00529                     refresh = True
00530                 self._toc_mtimes[subdir] = mtime
00531             if not refresh:
00532                 return
00533         # Refresh toc
00534         self._toc = {}
00535         for subdir in self._toc_mtimes:
00536             path = self._paths[subdir]
00537             for entry in os.listdir(path):
00538                 p = os.path.join(path, entry)
00539                 if os.path.isdir(p):
00540                     continue
00541                 uniq = entry.split(self.colon)[0]
00542                 self._toc[uniq] = os.path.join(subdir, entry)
00543         self._last_read = time.time()

Here is the caller graph for this function:

def mailbox.Maildir.add (   self,
  message 
)
Add message and return assigned key.

Reimplemented from mailbox.Mailbox.

Definition at line 282 of file mailbox.py.

00282 
00283     def add(self, message):
00284         """Add message and return assigned key."""
00285         tmp_file = self._create_tmp()
00286         try:
00287             self._dump_message(message, tmp_file)
00288         except BaseException:
00289             tmp_file.close()
00290             os.remove(tmp_file.name)
00291             raise
00292         _sync_close(tmp_file)
00293         if isinstance(message, MaildirMessage):
00294             subdir = message.get_subdir()
00295             suffix = self.colon + message.get_info()
00296             if suffix == self.colon:
00297                 suffix = ''
00298         else:
00299             subdir = 'new'
00300             suffix = ''
00301         uniq = os.path.basename(tmp_file.name).split(self.colon)[0]
00302         dest = os.path.join(self._path, subdir, uniq + suffix)
00303         try:
00304             if hasattr(os, 'link'):
00305                 os.link(tmp_file.name, dest)
00306                 os.remove(tmp_file.name)
00307             else:
00308                 os.rename(tmp_file.name, dest)
00309         except OSError as e:
00310             os.remove(tmp_file.name)
00311             if e.errno == errno.EEXIST:
00312                 raise ExternalClashError('Name clash with existing message: %s'
00313                                          % dest)
00314             else:
00315                 raise
00316         if isinstance(message, MaildirMessage):
00317             os.utime(dest, (os.path.getatime(dest), message.get_date()))
00318         return uniq

Here is the call graph for this function:

Here is the caller graph for this function:

def mailbox.Maildir.add_folder (   self,
  folder 
)
Create a folder and return a Maildir instance representing it.

Definition at line 441 of file mailbox.py.

00441 
00442     def add_folder(self, folder):
00443         """Create a folder and return a Maildir instance representing it."""
00444         path = os.path.join(self._path, '.' + folder)
00445         result = Maildir(path, factory=self._factory)
00446         maildirfolder_path = os.path.join(path, 'maildirfolder')
00447         if not os.path.exists(maildirfolder_path):
00448             os.close(os.open(maildirfolder_path, os.O_CREAT | os.O_WRONLY,
00449                 0o666))
00450         return result

def mailbox.Maildir.clean (   self)
Delete old files in "tmp".

Definition at line 470 of file mailbox.py.

00470 
00471     def clean(self):
00472         """Delete old files in "tmp"."""
00473         now = time.time()
00474         for entry in os.listdir(os.path.join(self._path, 'tmp')):
00475             path = os.path.join(self._path, 'tmp', entry)
00476             if now - os.path.getatime(path) > 129600:   # 60 * 60 * 36
00477                 os.remove(path)

def mailbox.Mailbox.clear (   self) [inherited]
Delete all messages.

Definition at line 147 of file mailbox.py.

00147 
00148     def clear(self):
00149         """Delete all messages."""
00150         for key in self.keys():
00151             self.discard(key)

Here is the call graph for this function:

def mailbox.Maildir.close (   self)
Flush and close the mailbox.

Reimplemented from mailbox.Mailbox.

Definition at line 422 of file mailbox.py.

00422 
00423     def close(self):
00424         """Flush and close the mailbox."""
00425         return

Here is the caller graph for this function:

def mailbox.Maildir.discard (   self,
  key 
)
If the keyed message exists, remove it.

Reimplemented from mailbox.Mailbox.

Definition at line 323 of file mailbox.py.

00323 
00324     def discard(self, key):
00325         """If the keyed message exists, remove it."""
00326         # This overrides an inapplicable implementation in the superclass.
00327         try:
00328             self.remove(key)
00329         except KeyError:
00330             pass
00331         except OSError as e:
00332             if e.errno != errno.ENOENT:
00333                 raise

Here is the call graph for this function:

def mailbox.Maildir.flush (   self)
Write any pending changes to disk.

Reimplemented from mailbox.Mailbox.

Definition at line 408 of file mailbox.py.

00408 
00409     def flush(self):
00410         """Write any pending changes to disk."""
00411         # Maildir changes are always written immediately, so there's nothing
00412         # to do.
00413         pass

Here is the caller graph for this function:

def mailbox.Mailbox.get (   self,
  key,
  default = None 
) [inherited]
Return the keyed message, or default if it doesn't exist.

Definition at line 68 of file mailbox.py.

00068 
00069     def get(self, key, default=None):
00070         """Return the keyed message, or default if it doesn't exist."""
00071         try:
00072             return self.__getitem__(key)
00073         except KeyError:
00074             return default

Here is the call graph for this function:

Here is the caller graph for this function:

def mailbox.Maildir.get_bytes (   self,
  key 
)
Return a bytes representation or raise a KeyError.

Reimplemented from mailbox.Mailbox.

Definition at line 375 of file mailbox.py.

00375 
00376     def get_bytes(self, key):
00377         """Return a bytes representation or raise a KeyError."""
00378         f = open(os.path.join(self._path, self._lookup(key)), 'rb')
00379         try:
00380             return f.read().replace(linesep, b'\n')
00381         finally:
00382             f.close()

Here is the call graph for this function:

def mailbox.Maildir.get_file (   self,
  key 
)
Return a file-like representation or raise a KeyError.

Reimplemented from mailbox.Mailbox.

Definition at line 383 of file mailbox.py.

00383 
00384     def get_file(self, key):
00385         """Return a file-like representation or raise a KeyError."""
00386         f = open(os.path.join(self._path, self._lookup(key)), 'rb')
00387         return _ProxyFile(f)

Here is the call graph for this function:

def mailbox.Maildir.get_folder (   self,
  folder 
)
Return a Maildir instance for the named folder.

Definition at line 435 of file mailbox.py.

00435 
00436     def get_folder(self, folder):
00437         """Return a Maildir instance for the named folder."""
00438         return Maildir(os.path.join(self._path, '.' + folder),
00439                        factory=self._factory,
00440                        create=False)

def mailbox.Maildir.get_message (   self,
  key 
)
Return a Message representation or raise a KeyError.

Reimplemented from mailbox.Mailbox.

Definition at line 357 of file mailbox.py.

00357 
00358     def get_message(self, key):
00359         """Return a Message representation or raise a KeyError."""
00360         subpath = self._lookup(key)
00361         f = open(os.path.join(self._path, subpath), 'rb')
00362         try:
00363             if self._factory:
00364                 msg = self._factory(f)
00365             else:
00366                 msg = MaildirMessage(f)
00367         finally:
00368             f.close()
00369         subdir, name = os.path.split(subpath)
00370         msg.set_subdir(subdir)
00371         if self.colon in name:
00372             msg.set_info(name.split(self.colon)[-1])
00373         msg.set_date(os.path.getmtime(os.path.join(self._path, subpath)))
00374         return msg

Here is the call graph for this function:

def mailbox.Mailbox.get_string (   self,
  key 
) [inherited]
Return a string representation or raise a KeyError.

Uses email.message.Message to create a 7bit clean string
representation of the message.

Definition at line 87 of file mailbox.py.

00087 
00088     def get_string(self, key):
00089         """Return a string representation or raise a KeyError.
00090 
00091         Uses email.message.Message to create a 7bit clean string
00092         representation of the message."""
00093         return email.message_from_bytes(self.get_bytes(key)).as_string()

Here is the call graph for this function:

def mailbox.Mailbox.items (   self) [inherited]
Return a list of (key, message) tuples. Memory intensive.

Definition at line 135 of file mailbox.py.

00135 
00136     def items(self):
00137         """Return a list of (key, message) tuples. Memory intensive."""
00138         return list(self.iteritems())

Here is the call graph for this function:

Here is the caller graph for this function:

def mailbox.Mailbox.iteritems (   self) [inherited]
Return an iterator over (key, message) tuples.

Definition at line 126 of file mailbox.py.

00126 
00127     def iteritems(self):
00128         """Return an iterator over (key, message) tuples."""
00129         for key in self.keys():
00130             try:
00131                 value = self[key]
00132             except KeyError:
00133                 continue
00134             yield (key, value)

Here is the call graph for this function:

Here is the caller graph for this function:

def mailbox.Maildir.iterkeys (   self)
Return an iterator over keys.

Reimplemented from mailbox.Mailbox.

Definition at line 388 of file mailbox.py.

00388 
00389     def iterkeys(self):
00390         """Return an iterator over keys."""
00391         self._refresh()
00392         for key in self._toc:
00393             try:
00394                 self._lookup(key)
00395             except KeyError:
00396                 continue
00397             yield key

Here is the call graph for this function:

Here is the caller graph for this function:

def mailbox.Mailbox.itervalues (   self) [inherited]
Return an iterator over all messages.

Definition at line 110 of file mailbox.py.

00110 
00111     def itervalues(self):
00112         """Return an iterator over all messages."""
00113         for key in self.keys():
00114             try:
00115                 value = self[key]
00116             except KeyError:
00117                 continue
00118             yield value

Here is the call graph for this function:

Here is the caller graph for this function:

def mailbox.Mailbox.keys (   self) [inherited]
Return a list of keys.

Definition at line 106 of file mailbox.py.

00106 
00107     def keys(self):
00108         """Return a list of keys."""
00109         return list(self.iterkeys())

Here is the call graph for this function:

Here is the caller graph for this function:

Return a list of folder names.

Definition at line 426 of file mailbox.py.

00426 
00427     def list_folders(self):
00428         """Return a list of folder names."""
00429         result = []
00430         for entry in os.listdir(self._path):
00431             if len(entry) > 1 and entry[0] == '.' and \
00432                os.path.isdir(os.path.join(self._path, entry)):
00433                 result.append(entry[1:])
00434         return result

def mailbox.Maildir.lock (   self)
Lock the mailbox.

Reimplemented from mailbox.Mailbox.

Definition at line 414 of file mailbox.py.

00414 
00415     def lock(self):
00416         """Lock the mailbox."""
00417         return

Here is the caller graph for this function:

def mailbox.Maildir.next (   self)
Return the next message in a one-time iteration.

Definition at line 558 of file mailbox.py.

00558 
00559     def next(self):
00560         """Return the next message in a one-time iteration."""
00561         if not hasattr(self, '_onetime_keys'):
00562             self._onetime_keys = iter(self.keys())
00563         while True:
00564             try:
00565                 return self[next(self._onetime_keys)]
00566             except StopIteration:
00567                 return None
00568             except KeyError:
00569                 continue
00570 

Here is the caller graph for this function:

def mailbox.Mailbox.pop (   self,
  key,
  default = None 
) [inherited]
Delete the keyed message and return it, or default.

Definition at line 152 of file mailbox.py.

00152 
00153     def pop(self, key, default=None):
00154         """Delete the keyed message and return it, or default."""
00155         try:
00156             result = self[key]
00157         except KeyError:
00158             return default
00159         self.discard(key)
00160         return result

Here is the call graph for this function:

Here is the caller graph for this function:

def mailbox.Mailbox.popitem (   self) [inherited]
Delete an arbitrary (key, message) pair and return it.

Definition at line 161 of file mailbox.py.

00161 
00162     def popitem(self):
00163         """Delete an arbitrary (key, message) pair and return it."""
00164         for key in self.keys():
00165             return (key, self.pop(key))     # This is only run once.
00166         else:
00167             raise KeyError('No messages in mailbox')

Here is the call graph for this function:

def mailbox.Maildir.remove (   self,
  key 
)
Remove the keyed message; raise KeyError if it doesn't exist.

Reimplemented from mailbox.Mailbox.

Definition at line 319 of file mailbox.py.

00319 
00320     def remove(self, key):
00321         """Remove the keyed message; raise KeyError if it doesn't exist."""
00322         os.remove(os.path.join(self._path, self._lookup(key)))

Here is the call graph for this function:

Here is the caller graph for this function:

def mailbox.Maildir.remove_folder (   self,
  folder 
)
Delete the named folder, which must be empty.

Definition at line 451 of file mailbox.py.

00451 
00452     def remove_folder(self, folder):
00453         """Delete the named folder, which must be empty."""
00454         path = os.path.join(self._path, '.' + folder)
00455         for entry in os.listdir(os.path.join(path, 'new')) + \
00456                      os.listdir(os.path.join(path, 'cur')):
00457             if len(entry) < 1 or entry[0] != '.':
00458                 raise NotEmptyError('Folder contains message(s): %s' % folder)
00459         for entry in os.listdir(path):
00460             if entry != 'new' and entry != 'cur' and entry != 'tmp' and \
00461                os.path.isdir(os.path.join(path, entry)):
00462                 raise NotEmptyError("Folder contains subdirectory '%s': %s" %
00463                                     (folder, entry))
00464         for root, dirs, files in os.walk(path, topdown=False):
00465             for entry in files:
00466                 os.remove(os.path.join(root, entry))
00467             for entry in dirs:
00468                 os.rmdir(os.path.join(root, entry))
00469         os.rmdir(path)

Here is the call graph for this function:

def mailbox.Maildir.unlock (   self)
Unlock the mailbox if it is locked.

Reimplemented from mailbox.Mailbox.

Definition at line 418 of file mailbox.py.

00418 
00419     def unlock(self):
00420         """Unlock the mailbox if it is locked."""
00421         return

def mailbox.Mailbox.update (   self,
  arg = None 
) [inherited]
Change the messages that correspond to certain keys.

Definition at line 168 of file mailbox.py.

00168 
00169     def update(self, arg=None):
00170         """Change the messages that correspond to certain keys."""
00171         if hasattr(arg, 'iteritems'):
00172             source = arg.items()
00173         elif hasattr(arg, 'items'):
00174             source = arg.items()
00175         else:
00176             source = arg
00177         bad_key = False
00178         for key, message in source:
00179             try:
00180                 self[key] = message
00181             except KeyError:
00182                 bad_key = True
00183         if bad_key:
00184             raise KeyError('No message with key(s)')

Here is the caller graph for this function:

def mailbox.Mailbox.values (   self) [inherited]
Return a list of messages. Memory intensive.

Definition at line 122 of file mailbox.py.

00122 
00123     def values(self):
00124         """Return a list of messages. Memory intensive."""
00125         return list(self.itervalues())

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

int mailbox.Maildir._count = 1 [static, private]

Definition at line 478 of file mailbox.py.

Definition at line 279 of file mailbox.py.

Definition at line 561 of file mailbox.py.

Definition at line 263 of file mailbox.py.

Definition at line 280 of file mailbox.py.

Definition at line 275 of file mailbox.py.

Definition at line 276 of file mailbox.py.

string mailbox.Maildir.colon = ':' [static]

Definition at line 258 of file mailbox.py.


The documentation for this class was generated from the following file: