VMM/{Relocated,Handler}: reworked Relocated class, adjusted Handler. v0.6.x
authorPascal Volk <neverseen@users.sourceforge.net>
Wed, 10 Feb 2010 07:38:19 +0000
branchv0.6.x
changeset 197 d2712e8c724e
parent 196 65a3163bd113
child 198 02d467e4fbab
VMM/{Relocated,Handler}: reworked Relocated class, adjusted Handler.
VirtualMailManager/Handler.py
VirtualMailManager/Relocated.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()
 
--- 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 _