VirtualMailManager/Alias.py
branchv0.6.x
changeset 221 371ae0b4443d
parent 216 0c8c053b451c
child 222 d0c16e70a9fb
equal deleted inserted replaced
220:8b8d632f0ef3 221:371ae0b4443d
     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:
   129             raise AErr(_(u"The alias %r doesn't exist.") % str(self._addr),
   144             raise AErr(_(u"The alias %r doesn't exist.") % str(self._addr),
   130                        NO_SUCH_ALIAS)
   145                        NO_SUCH_ALIAS)
   131         return iter(self._dests)
   146         return iter(self._dests)
   132 
   147 
   133     def delete(self):
   148     def delete(self):
   134         """Deletes the alias with all it's destinations."""
   149         """Deletes the alias with all its destinations."""
   135         if not self._dests:
   150         if not self._dests:
   136             raise AErr(_(u"The alias %r doesn't exist.") % str(self._addr),
   151             raise AErr(_(u"The alias %r doesn't exist.") % str(self._addr),
   137                        NO_SUCH_ALIAS)
   152                        NO_SUCH_ALIAS)
   138         self.__delete()
   153         self.__delete()
   139         del self._dests[:]
   154         del self._dests[:]