VirtualMailManager/EmailAddress.py
branchv0.6.x
changeset 193 a259bdeaab5c
parent 185 6e1ef32fbd82
child 194 6c06edb5b2d2
equal deleted inserted replaced
192:0854fb9f3bc5 193:a259bdeaab5c
     4 
     4 
     5 """Virtual Mail Manager's EmailAddress class to handle e-mail addresses."""
     5 """Virtual Mail Manager's EmailAddress class to handle e-mail addresses."""
     6 
     6 
     7 import re
     7 import re
     8 
     8 
     9 import VirtualMailManager.constants.ERROR as ERR
       
    10 from VirtualMailManager import chk_domainname
     9 from VirtualMailManager import chk_domainname
       
    10 from VirtualMailManager.constants.ERROR import \
       
    11      DOMAIN_NO_NAME, INVALID_ADDRESS, LOCALPART_INVALID, LOCALPART_TOO_LONG
    11 from VirtualMailManager.Exceptions import VMMEmailAddressException as VMMEAE
    12 from VirtualMailManager.Exceptions import VMMEmailAddressException as VMMEAE
       
    13 
    12 
    14 
    13 RE_LOCALPART = """[^\w!#$%&'\*\+-\.\/=?^_`{\|}~]"""
    15 RE_LOCALPART = """[^\w!#$%&'\*\+-\.\/=?^_`{\|}~]"""
    14 
    16 
       
    17 
    15 class EmailAddress(object):
    18 class EmailAddress(object):
    16     __slots__ = ('_localpart', '_domainname')
    19     __slots__ = ('_localpart', '_domainname')
       
    20 
    17     def __init__(self, address):
    21     def __init__(self, address):
       
    22         if not isinstance(address, basestring):
       
    23             raise TypeError('address is not a str/unicode object: %r' %
       
    24                             address)
    18         self._localpart = None
    25         self._localpart = None
    19         self._domainname = None
    26         self._domainname = None
    20         self.__chkAddress(address)
    27         self.__chkAddress(address)
    21 
    28 
    22     def __eq__(self, other):
    29     def __eq__(self, other):
    23         if isinstance(other, self.__class__):
    30         if isinstance(other, self.__class__):
    24             return self._localpart == other._localpart\
    31             return self._localpart == other._localpart and \
    25                     and self._domainname == other._domainname
    32                     self._domainname == other._domainname
    26         return NotImplemented
    33         return NotImplemented
    27 
    34 
    28     def __ne__(self, other):
    35     def __ne__(self, other):
    29         if isinstance(other, self.__class__):
    36         if isinstance(other, self.__class__):
    30             return self._localpart != other._localpart\
    37             return self._localpart != other._localpart or \
    31                     or self._domainname != other._domainname
    38                     self._domainname != other._domainname
    32         return NotImplemented
    39         return NotImplemented
    33 
    40 
    34     def __repr__(self):
    41     def __repr__(self):
    35         return "EmailAddress('%s@%s')" % (self._localpart, self._domainname)
    42         return "EmailAddress('%s@%s')" % (self._localpart, self._domainname)
    36 
    43 
    37     def __str__(self):
    44     def __str__(self):
    38         return "%s@%s" % (self._localpart, self._domainname)
    45         return "%s@%s" % (self._localpart, self._domainname)
    39 
    46 
    40     def __chkAddress(self, address):
    47     def __chkAddress(self, address):
    41         try:
    48         parts = address.split('@')
    42             localpart, domain = address.split('@')
    49         p_len = len(parts)
    43         except ValueError:
    50         if p_len is 2:
       
    51             self._localpart = self.__chkLocalpart(parts[0])
       
    52             if len(parts[1]) > 0:
       
    53                 self._domainname = chk_domainname(parts[1])
       
    54             else:
       
    55                 raise VMMEAE(_(u"Missing domain name after “%s@”.") %
       
    56                              self._localpart, DOMAIN_NO_NAME)
       
    57         elif p_len < 2:
    44             raise VMMEAE(_(u"Missing '@' sign in e-mail address “%s”.") %
    58             raise VMMEAE(_(u"Missing '@' sign in e-mail address “%s”.") %
    45                          address, ERR.INVALID_ADDRESS)
    59                          address, INVALID_ADDRESS)
    46         except AttributeError:
    60         elif p_len > 2:
    47             raise VMMEAE(_(u"“%s” doesn't look like an e-mail address.") %
    61             raise VMMEAE(_(u"Too many '@' signs in e-mail address “%s”.") %
    48                          address, ERR.INVALID_ADDRESS)
    62                          address, INVALID_ADDRESS)
    49         if len(domain) > 0:
       
    50             domain = chk_domainname(domain)
       
    51         else:
       
    52             raise VMMEAE(_(u"Missing domain name after “%s@”.") % localpart,
       
    53                          ERR.DOMAIN_NO_NAME)
       
    54         localpart = self.__chkLocalpart(localpart)
       
    55         self._localpart, self._domainname = localpart, domain
       
    56 
    63 
    57     def __chkLocalpart(self, localpart):
    64     def __chkLocalpart(self, localpart):
    58         """Validates the local-part of an e-mail address.
    65         """Validates the local-part of an e-mail address.
    59 
    66 
    60         Arguments:
    67         Arguments:
    61         localpart -- local-part of the e-mail address that should be validated (str)
    68         localpart -- local-part of the e-mail address that should be validated
    62         """
    69         """
    63         if len(localpart) < 1:
    70         if len(localpart) < 1:
    64             raise VMMEAE(_(u'No local-part specified.'),
    71             raise VMMEAE(_(u'No local-part specified.'), LOCALPART_INVALID)
    65                 ERR.LOCALPART_INVALID)
       
    66         if len(localpart) > 64:
    72         if len(localpart) > 64:
    67             raise VMMEAE(_(u'The local-part “%s” is too long') %
    73             raise VMMEAE(_(u'The local-part “%s” is too long') % localpart,
    68                 localpart, ERR.LOCALPART_TOO_LONG)
    74                          LOCALPART_TOO_LONG)
    69         ic = set(re.findall(RE_LOCALPART, localpart))
    75         ic = set(re.findall(RE_LOCALPART, localpart))
    70         if len(ic):
    76         if len(ic):
    71             ichrs = ''
    77             ichrs = u''.join((u'“%s” ' % c for c in ic))
    72             for c in ic:
       
    73                 ichrs += u"“%s” " % c
       
    74             raise VMMEAE(_(u"The local-part “%(lpart)s” contains invalid\
    78             raise VMMEAE(_(u"The local-part “%(lpart)s” contains invalid\
    75  characters: %(ichrs)s") % {'lpart': localpart, 'ichrs': ichrs},
    79  characters: %(ichrs)s") % {'lpart': localpart, 'ichrs': ichrs},
    76                 ERR.LOCALPART_INVALID)
    80                          LOCALPART_INVALID)
    77         return localpart
    81         return localpart
    78