VirtualMailManager/EmailAddress.py
branchv0.6.x
changeset 194 6c06edb5b2d2
parent 193 a259bdeaab5c
child 195 05dd49fc3ea1
equal deleted inserted replaced
193:a259bdeaab5c 194:6c06edb5b2d2
     1 # -*- coding: UTF-8 -*-
     1 # -*- coding: UTF-8 -*-
     2 # Copyright (c) 2008 - 2010, Pascal Volk
     2 # Copyright (c) 2008 - 2010, Pascal Volk
     3 # See COPYING for distribution information.
     3 # See COPYING for distribution information.
     4 
     4 
     5 """Virtual Mail Manager's EmailAddress class to handle e-mail addresses."""
     5 """
       
     6     VirtualMailManager.EmailAddress
       
     7 
       
     8     Virtual Mail Manager's EmailAddress class to handle e-mail addresses.
       
     9 """
     6 
    10 
     7 import re
    11 import re
     8 
    12 
     9 from VirtualMailManager import chk_domainname
    13 from VirtualMailManager import chk_domainname
    10 from VirtualMailManager.constants.ERROR import \
    14 from VirtualMailManager.constants.ERROR import \
    14 
    18 
    15 RE_LOCALPART = """[^\w!#$%&'\*\+-\.\/=?^_`{\|}~]"""
    19 RE_LOCALPART = """[^\w!#$%&'\*\+-\.\/=?^_`{\|}~]"""
    16 
    20 
    17 
    21 
    18 class EmailAddress(object):
    22 class EmailAddress(object):
    19     __slots__ = ('_localpart', '_domainname')
    23     """Simple class for validated e-mail addresses."""
       
    24     __slots__ = ('localpart', 'domainname')
    20 
    25 
    21     def __init__(self, address):
    26     def __init__(self, address):
       
    27         """Creates a new instance from the string/unicode ``address``."""
    22         if not isinstance(address, basestring):
    28         if not isinstance(address, basestring):
    23             raise TypeError('address is not a str/unicode object: %r' %
    29             raise TypeError('address is not a str/unicode object: %r' %
    24                             address)
    30                             address)
    25         self._localpart = None
    31         self.localpart = None
    26         self._domainname = None
    32         self.domainname = None
    27         self.__chkAddress(address)
    33         self._chk_address(address)
    28 
    34 
    29     def __eq__(self, other):
    35     def __eq__(self, other):
    30         if isinstance(other, self.__class__):
    36         if isinstance(other, self.__class__):
    31             return self._localpart == other._localpart and \
    37             return self.localpart == other.localpart and \
    32                     self._domainname == other._domainname
    38                     self.domainname == other.domainname
    33         return NotImplemented
    39         return NotImplemented
    34 
    40 
    35     def __ne__(self, other):
    41     def __ne__(self, other):
    36         if isinstance(other, self.__class__):
    42         if isinstance(other, self.__class__):
    37             return self._localpart != other._localpart or \
    43             return self.localpart != other.localpart or \
    38                     self._domainname != other._domainname
    44                     self.domainname != other.domainname
    39         return NotImplemented
    45         return NotImplemented
    40 
    46 
    41     def __repr__(self):
    47     def __repr__(self):
    42         return "EmailAddress('%s@%s')" % (self._localpart, self._domainname)
    48         return "EmailAddress('%s@%s')" % (self.localpart, self.domainname)
    43 
    49 
    44     def __str__(self):
    50     def __str__(self):
    45         return "%s@%s" % (self._localpart, self._domainname)
    51         return "%s@%s" % (self.localpart, self.domainname)
    46 
    52 
    47     def __chkAddress(self, address):
    53     def _chk_address(self, address):
       
    54         """Checks if the string ``address`` could be used for an e-mail
       
    55         address."""
    48         parts = address.split('@')
    56         parts = address.split('@')
    49         p_len = len(parts)
    57         p_len = len(parts)
    50         if p_len is 2:
    58         if p_len is 2:
    51             self._localpart = self.__chkLocalpart(parts[0])
    59             self.localpart = check_localpart(parts[0])
    52             if len(parts[1]) > 0:
    60             if len(parts[1]) > 0:
    53                 self._domainname = chk_domainname(parts[1])
    61                 self.domainname = chk_domainname(parts[1])
    54             else:
    62             else:
    55                 raise VMMEAE(_(u"Missing domain name after “%s@”.") %
    63                 raise VMMEAE(_(u"Missing domain name after “%s@”.") %
    56                              self._localpart, DOMAIN_NO_NAME)
    64                              self.localpart, DOMAIN_NO_NAME)
    57         elif p_len < 2:
    65         elif p_len < 2:
    58             raise VMMEAE(_(u"Missing '@' sign in e-mail address “%s”.") %
    66             raise VMMEAE(_(u"Missing '@' sign in e-mail address “%s”.") %
    59                          address, INVALID_ADDRESS)
    67                          address, INVALID_ADDRESS)
    60         elif p_len > 2:
    68         elif p_len > 2:
    61             raise VMMEAE(_(u"Too many '@' signs in e-mail address “%s”.") %
    69             raise VMMEAE(_(u"Too many '@' signs in e-mail address “%s”.") %
    62                          address, INVALID_ADDRESS)
    70                          address, INVALID_ADDRESS)
    63 
    71 
    64     def __chkLocalpart(self, localpart):
       
    65         """Validates the local-part of an e-mail address.
       
    66 
    72 
    67         Arguments:
    73 _ = lambda msg: msg
    68         localpart -- local-part of the e-mail address that should be validated
    74 
    69         """
    75 
    70         if len(localpart) < 1:
    76 def check_localpart(localpart):
    71             raise VMMEAE(_(u'No local-part specified.'), LOCALPART_INVALID)
    77     """Validates the local-part of an e-mail address.
    72         if len(localpart) > 64:
    78 
    73             raise VMMEAE(_(u'The local-part “%s” is too long') % localpart,
    79     Argument:
    74                          LOCALPART_TOO_LONG)
    80     localpart -- local-part of the e-mail address that should be validated
    75         ic = set(re.findall(RE_LOCALPART, localpart))
    81     """
    76         if len(ic):
    82     if len(localpart) < 1:
    77             ichrs = u''.join((u'“%s” ' % c for c in ic))
    83         raise VMMEAE(_(u'No local-part specified.'), LOCALPART_INVALID)
    78             raise VMMEAE(_(u"The local-part “%(lpart)s” contains invalid\
    84     if len(localpart) > 64:
    79  characters: %(ichrs)s") % {'lpart': localpart, 'ichrs': ichrs},
    85         raise VMMEAE(_(u'The local-part “%s” is too long') % localpart,
    80                          LOCALPART_INVALID)
    86                      LOCALPART_TOO_LONG)
    81         return localpart
    87     invalid_chars = set(re.findall(RE_LOCALPART, localpart))
       
    88     if invalid_chars:
       
    89         i_chrs = u''.join((u'“%s” ' % c for c in invalid_chars))
       
    90         raise VMMEAE(_(u"The local-part “%(l_part)s” contains invalid\
       
    91  characters: %(i_chrs)s") % {'l_part': localpart, 'i_chrs': i_chrs},
       
    92                      LOCALPART_INVALID)
       
    93     return localpart
       
    94 
       
    95 del _