# HG changeset patch # User Pascal Volk # Date 1267551658 0 # Node ID 311eee429f6743fd9758d9d34ecb451db672888a # Parent a51809f7940b4b17f6f94e4cbb48fff94bb206c4 VMM/maillocation: rewrote MailLocation class. Renamed MailLocation.py to maillocation.py. diff -r a51809f7940b -r 311eee429f67 VirtualMailManager/MailLocation.py --- a/VirtualMailManager/MailLocation.py Mon Mar 01 05:31:43 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2008 - 2010, Pascal Volk -# See COPYING for distribution information. - -"""Virtual Mail Manager's MailLocation class to manage the mail_location -for accounts.""" - -import re - -import VirtualMailManager.constants.ERROR as ERR -from VirtualMailManager.errors import MailLocationError as MLE - -RE_MAILLOCATION = """^\w{1,20}$""" - -class MailLocation(object): - """A wrapper class thats provide access to the maillocation table""" - __slots__ = ('__id', '__maillocation', '_dbh') - def __init__(self, dbh, mid=None, maillocation=None): - """Creates a new MailLocation instance. - - Either mid or maillocation must be specified. - - Keyword arguments: - dbh -- a pyPgSQL.PgSQL.connection - mid -- the id of a maillocation (long) - maillocation -- the value of the maillocation (str) - """ - self._dbh = dbh - if mid is None and maillocation is None: - raise MLE(_('Either mid or maillocation must be specified.'), - ERR.MAILLOCATION_INIT) - elif mid is not None: - try: - self.__id = long(mid) - except ValueError: - raise MLE(_('mid must be an int/long.'), ERR.MAILLOCATION_INIT) - self._loadByID() - else: - if re.match(RE_MAILLOCATION, maillocation): - self.__maillocation = maillocation - self._loadByName() - else: - raise MLE( - _(u'Invalid folder name ā€œ%sā€, it may consist only of\n\ -1 - 20 single byte characters (A-Z, a-z, 0-9 and _).') % maillocation, - ERR.MAILLOCATION_INIT) - - def _loadByID(self): - dbc = self._dbh.cursor() - dbc.execute('SELECT maillocation FROM maillocation WHERE mid = %s', - self.__id) - result = dbc.fetchone() - dbc.close() - if result is not None: - self.__maillocation = result[0] - else: - raise MLE(_('Unknown mid specified.'), ERR.UNKNOWN_MAILLOCATION_ID) - - def _loadByName(self): - dbc = self._dbh.cursor() - dbc.execute('SELECT mid FROM maillocation WHERE maillocation = %s', - self.__maillocation) - result = dbc.fetchone() - dbc.close() - if result is not None: - self.__id = result[0] - else: - self._save() - - def _save(self): - dbc = self._dbh.cursor() - dbc.execute("SELECT nextval('maillocation_id')") - self.__id = dbc.fetchone()[0] - dbc.execute('INSERT INTO maillocation(mid,maillocation) VALUES(%s,%s)', - self.__id, self.__maillocation) - self._dbh.commit() - dbc.close() - - def getID(self): - """Returns the unique ID of the maillocation.""" - return self.__id - - def getMailLocation(self): - """Returns the value of maillocation, ex: 'Maildir'""" - return self.__maillocation - diff -r a51809f7940b -r 311eee429f67 VirtualMailManager/maillocation.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VirtualMailManager/maillocation.py Tue Mar 02 17:40:58 2010 +0000 @@ -0,0 +1,100 @@ +# -*- coding: UTF-8 -*- +# Copyright (c) 2008 - 2010, Pascal Volk +# See COPYING for distribution information. + +""" + VirtualMailManager.maillocation + + Virtual Mail Manager's maillocation module to handle Dovecot's + mail_location setting for accounts. + +""" + +from VirtualMailManager.pycompat import any + + +__all__ = ('MailLocation', + 'MAILDIR_ID', 'MBOX_ID', 'MDBOX_ID', 'SDBOX_ID', + 'MAILDIR_NAME', 'MBOX_NAME', 'MDBOX_NAME', 'SDBOX_NAME') + +MAILDIR_ID = 0x1 +MBOX_ID = 0x2 +MDBOX_ID = 0x3 +SDBOX_ID = 0x4 +MAILDIR_NAME = 'Maildir' +MBOX_NAME = 'mail' +MDBOX_NAME = 'mdbox' +SDBOX_NAME = 'dbox' + +_storage = { + MAILDIR_ID: dict(dovecot_version=10, postfix=True, prefix='maildir:', + directory=MAILDIR_NAME), + MBOX_ID: dict(dovecot_version=10, postfix=True, prefix='mbox:', + directory=MBOX_NAME), + MDBOX_ID: dict(dovecot_version=20, postfix=False, prefix='mdbox:', + directory=MDBOX_NAME), + SDBOX_ID: dict(dovecot_version=12, postfix=False, prefix='dbox:', + directory=SDBOX_NAME), +} + +_type_id = { + 'maildir': MAILDIR_ID, + MBOX_NAME: MBOX_ID, + MDBOX_NAME: MDBOX_ID, + SDBOX_NAME: SDBOX_ID, +} + + +class MailLocation(object): + """A small class for mail_location relevant information.""" + __slots__ = ('_info') + + def __init__(self, mid=None, type_=None): + """Creates a new MailLocation instance. + + Either mid or type_ must be specified. + + Keyword arguments: + mid -- the id of a mail_location (int) + one of the maillocation constants: `MAILDIR_ID`, `MBOX_ID`, + `MDBOX_ID` and `SDBOX_ID` + type_ -- the type/mailbox format of the mail_location (str) + one of the maillocation constants: `MAILDIR_NAME`, `MBOX_NAME`, + `MDBOX_NAME` and `SDBOX_NAME` + """ + assert any((mid, type_)) + if mid: + assert isinstance(mid, (int, long)) and mid in _storage + self._info = _storage[mid] + else: + assert isinstance(type_, basestring) and type_.lower() in _type_id + self._info = _storage[_type_id[type_.lower()]] + + def __str__(self): + return '%(prefix)s~/%(directory)s' % self._info + + @property + def directory(self): + """The mail_location's directory name.""" + return self._info['directory'] + + @property + def dovecot_version(self): + """The required Dovecot version (concatenated major and minor + parts) for this mailbox format.""" + return self._info['dovecot_version'] + + @property + def postfix(self): + """`True` if Postfix supports this mailbox format, else `False`.""" + return self._info['postfix'] + + @property + def prefix(self): + """The prefix of the mail_location.""" + return self._info['prefix'] + + @property + def mail_location(self): + """The mail_location, e.g. ``maildir:~/Maildir``""" + return self.__str__() diff -r a51809f7940b -r 311eee429f67 doc/source/vmm_constants_error.rst --- a/doc/source/vmm_constants_error.rst Mon Mar 01 05:31:43 2010 +0000 +++ b/doc/source/vmm_constants_error.rst Tue Mar 02 17:40:58 2010 +0000 @@ -147,6 +147,8 @@ Can't create a new MailLocation instance + obsolete? + .. data:: NOT_EXECUTABLE The binary is not executable @@ -196,10 +198,14 @@ Can't initialize a new Transport instance + obsolete? + .. data:: UNKNOWN_MAILLOCATION_ID There is no MailLocation entry with the given ID + obsolete? + .. data:: UNKNOWN_SERVICE The specified service is unknown