|
1 # -*- coding: UTF-8 -*- |
|
2 # Copyright (c) 2008 - 2012, 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 _ |