9 """ |
9 """ |
10 |
10 |
11 from VirtualMailManager.Domain import get_gid |
11 from VirtualMailManager.Domain import get_gid |
12 from VirtualMailManager.EmailAddress import EmailAddress |
12 from VirtualMailManager.EmailAddress import EmailAddress |
13 from VirtualMailManager.errors import AliasError as AErr |
13 from VirtualMailManager.errors import AliasError as AErr |
|
14 from VirtualMailManager.pycompat import all |
14 from VirtualMailManager.constants.ERROR import ALIAS_ADDR_DEST_IDENTICAL, \ |
15 from VirtualMailManager.constants.ERROR import ALIAS_ADDR_DEST_IDENTICAL, \ |
15 ALIAS_EXCEEDS_EXPANSION_LIMIT, ALIAS_EXISTS, NO_SUCH_ALIAS |
16 ALIAS_EXCEEDS_EXPANSION_LIMIT, ALIAS_EXISTS, NO_SUCH_ALIAS |
16 |
17 |
17 |
18 |
18 _ = lambda msg: msg |
19 _ = lambda msg: msg |
42 dest_add = self._dests.append |
43 dest_add = self._dests.append |
43 for dest in dests: |
44 for dest in dests: |
44 dest_add(EmailAddress(dest[0])) |
45 dest_add(EmailAddress(dest[0])) |
45 dbc.close() |
46 dbc.close() |
46 |
47 |
47 def __check_expansion(self, limit): |
48 def __check_expansion(self, count_new, limit): |
48 """Checks the current expansion limit of the alias.""" |
49 """Checks the current expansion limit of the alias.""" |
49 dcount = len(self._dests) |
50 dcount = len(self._dests) |
50 failed = False |
51 failed = False |
51 if dcount == limit: |
52 if dcount == limit or dcount + count_new > limit: |
52 failed = True |
53 failed = True |
53 errmsg = _( |
54 errmsg = _( |
54 u"""Can't add new destination to alias %(address)r. |
55 u"""Can't add %(count_new)i new destination(s) to alias %(address)r. |
55 Currently this alias expands into %(count)i/%(limit)i recipients. |
56 Currently this alias expands into %(count)i/%(limit)i recipients. |
56 One more destination will render this alias unusable. |
57 %(count_new)i additional destination(s) will render this alias unusable. |
57 Hint: Increase Postfix' virtual_alias_expansion_limit""") |
58 Hint: Increase Postfix' virtual_alias_expansion_limit""") |
58 elif dcount > limit: |
59 elif dcount > limit: |
59 failed = True |
60 failed = True |
60 errmsg = _( |
61 errmsg = _( |
61 u"""Can't add new destination to alias %(address)r. |
62 u"""Can't add %(count_new)i new destination(s) to alias %(address)r. |
62 This alias already exceeds it's expansion limit (%(count)i/%(limit)i). |
63 This alias already exceeds it's expansion limit (%(count)i/%(limit)i). |
63 So its unusable, all messages addressed to this alias will be bounced. |
64 So its unusable, all messages addressed to this alias will be bounced. |
64 Hint: Delete some destination addresses.""") |
65 Hint: Delete some destination addresses.""") |
65 if failed: |
66 if failed: |
66 raise AErr(errmsg % {'address': str(self._addr), 'count': dcount, |
67 raise AErr(errmsg % {'address': str(self._addr), 'count': dcount, |
67 'limit': limit}, |
68 'limit': limit, 'count_new': count_new}, |
68 ALIAS_EXCEEDS_EXPANSION_LIMIT) |
69 ALIAS_EXCEEDS_EXPANSION_LIMIT) |
69 |
70 |
70 def __delete(self, destination=None): |
71 def __delete(self, destination=None): |
71 """Deletes a destination from the alias, if ``destination`` is |
72 """Deletes a destination from the alias, if ``destination`` is |
72 not ``None``. If ``destination`` is None, the alias with all |
73 not ``None``. If ``destination`` is None, the alias with all |
87 |
88 |
88 def __len__(self): |
89 def __len__(self): |
89 """Returns the number of destinations of the alias.""" |
90 """Returns the number of destinations of the alias.""" |
90 return len(self._dests) |
91 return len(self._dests) |
91 |
92 |
92 def add_destination(self, destination, expansion_limit): |
93 def add_destinations(self, destinations, expansion_limit, warnings=None): |
93 """Adds the ``destination`` `EmailAddress` to the alias.""" |
94 """Adds the `EmailAddress`es from *destinations* list to the |
94 assert isinstance(destination, EmailAddress) |
95 destinations of the alias. |
95 if self._addr == destination: |
96 |
96 raise AErr(_(u"Address and destination are identical."), |
97 Destinations, that are already assigned to the alias, will be |
97 ALIAS_ADDR_DEST_IDENTICAL) |
98 removed from *destinations*. When done, this method will return |
98 if destination in self._dests: |
99 a set with all destinations, that was saved in the database. |
99 raise AErr(_( |
100 """ |
100 u'The alias %(a)r has already the destination %(d)r.') % |
101 destinations = set(destinations) |
101 {'a': str(self._addr), 'd': str(destination)}, |
102 assert destinations and \ |
102 ALIAS_EXISTS) |
103 all(isinstance(dest, EmailAddress) for dest in destinations) |
103 self.__check_expansion(expansion_limit) |
104 if not warnings is None: |
|
105 assert isinstance(warnings, list) |
|
106 if self._addr in destinations: |
|
107 destinations.remove(self._addr) |
|
108 if not warnings is None: |
|
109 warnings.append(self._addr) |
|
110 duplicates = destinations.intersection(set(self._dests)) |
|
111 if duplicates: |
|
112 destinations.difference_update(set(self._dests)) |
|
113 if not warnings is None: |
|
114 warnings.extend(duplicates) |
|
115 if not destinations: |
|
116 return destinations |
|
117 self.__check_expansion(len(destinations), expansion_limit) |
104 dbc = self._dbh.cursor() |
118 dbc = self._dbh.cursor() |
105 dbc.execute('INSERT INTO alias (gid, address, destination) \ |
119 dbc.executemany("INSERT INTO alias VALUES (%d, '%s', %%s)" % |
106 VALUES (%s, %s, %s)', |
120 (self._gid, self._addr.localpart), |
107 self._gid, self._addr.localpart, str(destination)) |
121 (str(destination) for destination in destinations)) |
108 self._dbh.commit() |
122 self._dbh.commit() |
109 dbc.close() |
123 dbc.close() |
110 self._dests.append(destination) |
124 self._dests.extend(destinations) |
|
125 return destinations |
111 |
126 |
112 def del_destination(self, destination): |
127 def del_destination(self, destination): |
113 """Deletes the specified ``destination`` address from the alias.""" |
128 """Deletes the specified ``destination`` address from the alias.""" |
114 assert isinstance(destination, EmailAddress) |
129 assert isinstance(destination, EmailAddress) |
115 if not self._dests: |
130 if not self._dests: |