# HG changeset patch # User Pascal Volk # Date 1265787499 0 # Node ID d2712e8c724e246663b4fcd0e529af504b7b0734 # Parent 65a3163bd11398aff99e37d570ddb2a51de3d9ff VMM/{Relocated,Handler}: reworked Relocated class, adjusted Handler. diff -r 65a3163bd113 -r d2712e8c724e VirtualMailManager/Handler.py --- a/VirtualMailManager/Handler.py Wed Feb 10 02:13:35 2010 +0000 +++ b/VirtualMailManager/Handler.py Wed Feb 10 07:38:19 2010 +0000 @@ -177,23 +177,21 @@ relocatedExists = staticmethod(relocatedExists) def __getAccount(self, address, password=None): - self.__dbConnect() address = EmailAddress(address) if not password is None: password = self.__pwhash(password) + self.__dbConnect() return Account(self._dbh, address, password) def __getAlias(self, address): + address = EmailAddress(address) self.__dbConnect() - address = EmailAddress(address) return Alias(self._dbh, address) - def __getRelocated(self, address, destination=None): - self.__dbConnect() + def __getRelocated(self, address): address = EmailAddress(address) - if destination is not None: - destination = EmailAddress(destination) - return Relocated(self._dbh, address, destination) + self.__dbConnect() + return Relocated(self._dbh, address) def __getDomain(self, domainname, transport=None): if transport is None: @@ -659,14 +657,21 @@ acc.enable(self._Cfg.dget('misc.dovecot_version'), service) def relocatedAdd(self, emailaddress, targetaddress): - relocated = self.__getRelocated(emailaddress, targetaddress) - relocated.save() + """Creates a new `Relocated` entry in the database. If there is + already a relocated user with the given *emailaddress*, only the + *targetaddress* for the relocated user will be updated.""" + relocated = self.__getRelocated(emailaddress) + relocated.setDestination(EmailAddress(targetaddress)) def relocatedInfo(self, emailaddress): + """Returns the target address of the relocated user with the given + *emailaddress*.""" relocated = self.__getRelocated(emailaddress) return relocated.getInfo() def relocatedDelete(self, emailaddress): + """Deletes the relocated user with the given *emailaddress* from + the database.""" relocated = self.__getRelocated(emailaddress) relocated.delete() diff -r 65a3163bd113 -r d2712e8c724e VirtualMailManager/Relocated.py --- a/VirtualMailManager/Relocated.py Wed Feb 10 02:13:35 2010 +0000 +++ b/VirtualMailManager/Relocated.py Wed Feb 10 07:38:19 2010 +0000 @@ -2,102 +2,114 @@ # Copyright (c) 2008 - 2010, Pascal Volk # See COPYING for distribution information. -"""Virtual Mail Manager's Relocated class to manage relocated users.""" +""" + VirtualMailManager.Relocated -import VirtualMailManager.constants.ERROR as ERR + Virtual Mail Manager's Relocated class to handle relocated users. +""" + from VirtualMailManager.Domain import Domain from VirtualMailManager.EmailAddress import EmailAddress from VirtualMailManager.Exceptions import VMMRelocatedException as VMMRE -import VirtualMailManager as VMM +from VirtualMailManager.constants.ERROR import NO_SUCH_DOMAIN, \ + NO_SUCH_RELOCATED, RELOCATED_ADDR_DEST_IDENTICAL, RELOCATED_EXISTS + + +_ = lambda msg: msg + class Relocated(object): - """Class to manage e-mail addresses of relocated users.""" - __slots__ = ('_addr', '_dest', '_gid', '_isNew', '_dbh') - def __init__(self, dbh, address, destination=None): + """Class to handle e-mail addresses of relocated users.""" + __slots__ = ('_addr', '_dest', '_gid', '_dbh') + + def __init__(self, dbh, address): + """Creates a new *Relocated* instance. The ``address`` is the + old e-mail address of the user. + + Use `setDestination()` to set/update the new address, where the + user has moved to.""" if isinstance(address, EmailAddress): self._addr = address else: raise TypeError("Argument 'address' is not an EmailAddress") - if destination is None: - self._dest = None - elif isinstance(destination, EmailAddress): - self._dest = destination - else: - raise TypeError("Argument 'destination' is not an EmailAddress") - if address == destination: - raise VMMRE(_(u"Address and destination are identical."), - ERR.RELOCATED_ADDR_DEST_IDENTICAL) self._dbh = dbh self._gid = 0 - self._isNew = False - self._setAddr() - self._exists() - if self._isNew and VMM.VirtualMailManager.accountExists(self._dbh, - self._addr): - raise VMMRE(_(u"There is already an account with address “%s”.") %\ - self._addr, ERR.ACCOUNT_EXISTS) - if self._isNew and VMM.VirtualMailManager.aliasExists(self._dbh, - self._addr): - raise VMMRE( - _(u"There is already an alias with the address “%s”.") %\ - self._addr, ERR.ALIAS_EXISTS) + self._dest = None - def _exists(self): - dbc = self._dbh.cursor() - dbc.execute("SELECT gid FROM relocated WHERE gid = %s AND address = %s", - self._gid, self._addr._localpart) - gid = dbc.fetchone() - dbc.close() - if gid is None: - self._isNew = True + self.__set_gid() + self.__load() - def _setAddr(self): - dom = Domain(self._dbh, self._addr._domainname) + def __set_gid(self): + """Sets the `_gid` attribute, based on the `_addr.domainname`.""" + dom = Domain(self._dbh, self._addr.domainname) self._gid = dom.getID() if self._gid == 0: - raise VMMRE(_(u"The domain “%s” doesn't exist.") %\ - self._addr._domainname, ERR.NO_SUCH_DOMAIN) + raise VMMRE(_(u"The domain “%s” doesn't exist.") % + self._addr.domainname, NO_SUCH_DOMAIN) + + def __load(self): + """Loads the destination address from the database into the + `_dest` attribute.""" + dbc = self._dbh.cursor() + dbc.execute( + 'SELECT destination FROM relocated WHERE gid=%s AND address=%s', + self._gid, self._addr.localpart) + destination = dbc.fetchone() + dbc.close() + if destination: + self._dest = EmailAddress(destination[0]) - def save(self): - if self._dest is None: - raise VMMRE( - _(u"No destination address specified for relocated user."), - ERR.RELOCATED_MISSING_DEST) - if self._isNew: - dbc = self._dbh.cursor() - dbc.execute("INSERT INTO relocated VALUES (%s, %s, %s)", - self._gid, self._addr._localpart, str(self._dest)) - self._dbh.commit() - dbc.close() + def setDestination(self, destination): + """Sets/updates the new address of the relocated user.""" + update = False + if isinstance(destination, EmailAddress): + if self._addr == destination: + raise VMMRE(_(u'Address and destination are identical.'), + RELOCATED_ADDR_DEST_IDENTICAL) + if self._dest: + if self._dest == destination: + raise VMMRE( + _(u'The relocated user “%s” already exists.') % + self._addr, RELOCATED_EXISTS) + else: + self._dest = destination + update = True + else: + self._dest = destination else: - raise VMMRE( - _(u"The relocated user “%s” already exists.") % self._addr, - ERR.RELOCATED_EXISTS) + raise TypeError("Argument 'destination' is not an EmailAddress") + + dbc = self._dbh.cursor() + if not update: + dbc.execute('INSERT INTO relocated VALUES (%s, %s, %s)', + self._gid, self._addr.localpart, str(self._dest)) + else: + dbc.execute('UPDATE relocated SET destination=%s \ +WHERE gid=%s AND address=%s', + str(self._dest), self._gid, self._addr.localpart) + self._dbh.commit() + dbc.close() def getInfo(self): - dbc = self._dbh.cursor() - dbc.execute('SELECT destination FROM relocated WHERE gid=%s\ - AND address=%s', - self._gid, self._addr._localpart) - destination = dbc.fetchone() - dbc.close() - if destination is not None: - return destination[0] + """Returns the address to which mails should be sent.""" + if self._dest: + return self._dest else: - raise VMMRE( - _(u"The relocated user “%s” doesn't exist.") % self._addr, - ERR.NO_SUCH_RELOCATED) + raise VMMRE(_(u"The relocated user “%s” doesn't exist.") % + self._addr, NO_SUCH_RELOCATED) def delete(self): + """Deletes the relocated entry from the database.""" + if not self._dest: + raise VMMRE(_(u"The relocated user “%s” doesn't exist.") % + self._addr, NO_SUCH_RELOCATED) dbc = self._dbh.cursor() dbc.execute("DELETE FROM relocated WHERE gid = %s AND address = %s", - self._gid, self._addr._localpart) - rowcount = dbc.rowcount - dbc.close() - if rowcount > 0: + self._gid, self._addr.localpart) + if dbc.rowcount > 0: self._dbh.commit() - else: - raise VMMRE( - _(u"The relocated user “%s” doesn't exist.") % self._addr, - ERR.NO_SUCH_RELOCATED) + dbc.close() + self._dest = None + +del _