VirtualMailManager/relocated.py
changeset 760 b678a1c43027
parent 748 659c4476c57c
child 761 e4e656f19771
equal deleted inserted replaced
748:659c4476c57c 760:b678a1c43027
     1 # -*- coding: UTF-8 -*-
       
     2 # Copyright (c) 2008 - 2014, Pascal Volk
       
     3 # See COPYING for distribution information.
       
     4 """
       
     5     VirtualMailManager.relocated
       
     6     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       
     7 
       
     8     Virtual Mail Manager's Relocated class to handle relocated users.
       
     9 """
       
    10 
       
    11 from VirtualMailManager.domain import get_gid
       
    12 from VirtualMailManager.emailaddress import EmailAddress, \
       
    13      DestinationEmailAddress
       
    14 from VirtualMailManager.errors import RelocatedError as RErr
       
    15 from VirtualMailManager.constants import DOMAIN_INVALID, NO_SUCH_DOMAIN, \
       
    16      NO_SUCH_RELOCATED, RELOCATED_ADDR_DEST_IDENTICAL, RELOCATED_EXISTS
       
    17 
       
    18 
       
    19 _ = lambda msg: msg
       
    20 
       
    21 
       
    22 class Relocated(object):
       
    23     """Class to handle e-mail addresses of relocated users."""
       
    24     __slots__ = ('_addr', '_dest', '_gid', '_dbh')
       
    25 
       
    26     def __init__(self, dbh, address):
       
    27         """Creates a new *Relocated* instance.  The ``address`` is the
       
    28         old e-mail address of the user.
       
    29 
       
    30         Use `setDestination()` to set/update the new address, where the
       
    31         user has moved to.
       
    32 
       
    33         """
       
    34         assert isinstance(address, EmailAddress)
       
    35         self._addr = address
       
    36         self._dbh = dbh
       
    37         self._gid = get_gid(self._dbh, self._addr.domainname)
       
    38         if not self._gid:
       
    39             raise RErr(_(u"The domain '%s' does not exist.") %
       
    40                        self._addr.domainname, NO_SUCH_DOMAIN)
       
    41         self._dest = None
       
    42 
       
    43         self._load()
       
    44 
       
    45     def __nonzero__(self):
       
    46         """Returns `True` if the Relocated is known, `False` if it's new."""
       
    47         return self._dest is not None
       
    48 
       
    49     def _load(self):
       
    50         """Loads the destination address from the database into the
       
    51         `_dest` attribute.
       
    52 
       
    53         """
       
    54         dbc = self._dbh.cursor()
       
    55         dbc.execute('SELECT destination FROM relocated WHERE gid = %s AND '
       
    56                     'address = %s', (self._gid, self._addr.localpart))
       
    57         destination = dbc.fetchone()
       
    58         dbc.close()
       
    59         if destination:
       
    60             destination = DestinationEmailAddress(destination[0], self._dbh)
       
    61             if destination.at_localhost:
       
    62                 raise RErr(_(u"The destination address' domain name must not "
       
    63                              u"be localhost."), DOMAIN_INVALID)
       
    64             self._dest = destination
       
    65 
       
    66     @property
       
    67     def address(self):
       
    68         """The Relocated's EmailAddress instance."""
       
    69         return self._addr
       
    70 
       
    71     def set_destination(self, destination):
       
    72         """Sets/updates the new address of the relocated user."""
       
    73         update = False
       
    74         assert isinstance(destination, DestinationEmailAddress)
       
    75         if destination.at_localhost:
       
    76             raise RErr(_(u"The destination address' domain name must not be "
       
    77                          u"localhost."), DOMAIN_INVALID)
       
    78         if self._addr == destination:
       
    79             raise RErr(_(u'Address and destination are identical.'),
       
    80                        RELOCATED_ADDR_DEST_IDENTICAL)
       
    81         if self._dest:
       
    82             if self._dest == destination:
       
    83                 raise RErr(_(u"The relocated user '%s' already exists.") %
       
    84                            self._addr, RELOCATED_EXISTS)
       
    85             else:
       
    86                 self._dest = destination
       
    87                 update = True
       
    88         else:
       
    89             self._dest = destination
       
    90 
       
    91         dbc = self._dbh.cursor()
       
    92         if not update:
       
    93             dbc.execute('INSERT INTO relocated (gid, address, destination) '
       
    94                         'VALUES (%s, %s, %s)',
       
    95                         (self._gid, self._addr.localpart, str(self._dest)))
       
    96         else:
       
    97             dbc.execute('UPDATE relocated SET destination = %s WHERE gid = %s '
       
    98                         'AND address = %s',
       
    99                         (str(self._dest), self._gid, self._addr.localpart))
       
   100         self._dbh.commit()
       
   101         dbc.close()
       
   102 
       
   103     def get_info(self):
       
   104         """Returns the address to which mails should be sent."""
       
   105         if not self._dest:
       
   106             raise RErr(_(u"The relocated user '%s' does not exist.") %
       
   107                        self._addr, NO_SUCH_RELOCATED)
       
   108         return self._dest
       
   109 
       
   110     def delete(self):
       
   111         """Deletes the relocated entry from the database."""
       
   112         if not self._dest:
       
   113             raise RErr(_(u"The relocated user '%s' does not exist.") %
       
   114                        self._addr, NO_SUCH_RELOCATED)
       
   115         dbc = self._dbh.cursor()
       
   116         dbc.execute('DELETE FROM relocated WHERE gid = %s AND address = %s',
       
   117                     (self._gid, self._addr.localpart))
       
   118         if dbc.rowcount > 0:
       
   119             self._dbh.commit()
       
   120         dbc.close()
       
   121         self._dest = None
       
   122 
       
   123 del _