VirtualMailManager/EmailAddress.py
author Pascal Volk <neverseen@users.sourceforge.net>
Tue, 09 Feb 2010 22:14:08 +0000
branchv0.6.x
changeset 195 05dd49fc3ea1
parent 194 6c06edb5b2d2
child 199 0684790fff7c
permissions -rw-r--r--
VMM/EmailAddress: reworked class EmailAddress again. The attributes domainname and localpart are now read-only.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     1
# -*- coding: UTF-8 -*-
162
0ac9ef587769 Updated copyright notices to include the year 2010.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 155
diff changeset
     2
# Copyright (c) 2008 - 2010, Pascal Volk
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     3
# See COPYING for distribution information.
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     4
194
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
     5
"""
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
     6
    VirtualMailManager.EmailAddress
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
     7
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
     8
    Virtual Mail Manager's EmailAddress class to handle e-mail addresses.
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
     9
"""
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    10
185
6e1ef32fbd82 VMM/*: Moved some methods from classes to modules __init__.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 162
diff changeset
    11
import re
6e1ef32fbd82 VMM/*: Moved some methods from classes to modules __init__.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 162
diff changeset
    12
6e1ef32fbd82 VMM/*: Moved some methods from classes to modules __init__.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 162
diff changeset
    13
from VirtualMailManager import chk_domainname
193
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    14
from VirtualMailManager.constants.ERROR import \
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    15
     DOMAIN_NO_NAME, INVALID_ADDRESS, LOCALPART_INVALID, LOCALPART_TOO_LONG
185
6e1ef32fbd82 VMM/*: Moved some methods from classes to modules __init__.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 162
diff changeset
    16
from VirtualMailManager.Exceptions import VMMEmailAddressException as VMMEAE
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    17
193
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    18
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    19
RE_LOCALPART = """[^\w!#$%&'\*\+-\.\/=?^_`{\|}~]"""
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    20
193
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    21
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    22
class EmailAddress(object):
194
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    23
    """Simple class for validated e-mail addresses."""
195
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    24
    __slots__ = ('_localpart', '_domainname')
193
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    25
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    26
    def __init__(self, address):
194
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    27
        """Creates a new instance from the string/unicode ``address``."""
193
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    28
        if not isinstance(address, basestring):
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    29
            raise TypeError('address is not a str/unicode object: %r' %
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    30
                            address)
195
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    31
        self._localpart = None
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    32
        self._domainname = None
194
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    33
        self._chk_address(address)
116
949c5db6447a Fixed a logical mistake in EmailAddress.__ne__() (not used),
Pascal Volk <neverseen@users.sourceforge.net>
parents: 108
diff changeset
    34
195
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    35
    @property
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    36
    def localpart(self):
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    37
        """The local-part of the address *local-part@domain*"""
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    38
        return self._localpart
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    39
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    40
    @property
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    41
    def domainname(self):
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    42
        """The domain part of the address *local-part@domain*"""
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    43
        return self._domainname
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    44
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    45
    def __eq__(self, other):
116
949c5db6447a Fixed a logical mistake in EmailAddress.__ne__() (not used),
Pascal Volk <neverseen@users.sourceforge.net>
parents: 108
diff changeset
    46
        if isinstance(other, self.__class__):
195
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    47
            return self._localpart == other.localpart and \
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    48
                    self._domainname == other.domainname
116
949c5db6447a Fixed a logical mistake in EmailAddress.__ne__() (not used),
Pascal Volk <neverseen@users.sourceforge.net>
parents: 108
diff changeset
    49
        return NotImplemented
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    50
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    51
    def __ne__(self, other):
116
949c5db6447a Fixed a logical mistake in EmailAddress.__ne__() (not used),
Pascal Volk <neverseen@users.sourceforge.net>
parents: 108
diff changeset
    52
        if isinstance(other, self.__class__):
195
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    53
            return self._localpart != other.localpart or \
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    54
                    self._domainname != other.domainname
116
949c5db6447a Fixed a logical mistake in EmailAddress.__ne__() (not used),
Pascal Volk <neverseen@users.sourceforge.net>
parents: 108
diff changeset
    55
        return NotImplemented
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    56
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    57
    def __repr__(self):
195
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    58
        return "EmailAddress('%s@%s')" % (self._localpart, self._domainname)
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    59
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    60
    def __str__(self):
195
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    61
        return "%s@%s" % (self._localpart, self._domainname)
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    62
194
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    63
    def _chk_address(self, address):
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    64
        """Checks if the string ``address`` could be used for an e-mail
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    65
        address."""
193
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    66
        parts = address.split('@')
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    67
        p_len = len(parts)
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    68
        if p_len is 2:
195
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    69
            self._localpart = check_localpart(parts[0])
193
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    70
            if len(parts[1]) > 0:
195
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    71
                self._domainname = chk_domainname(parts[1])
193
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    72
            else:
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    73
                raise VMMEAE(_(u"Missing domain name after “%s@”.") %
195
05dd49fc3ea1 VMM/EmailAddress: reworked class EmailAddress again.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 194
diff changeset
    74
                             self._localpart, DOMAIN_NO_NAME)
193
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    75
        elif p_len < 2:
133
2d5c4745efec Replaced angle quotes by quotation marks.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 116
diff changeset
    76
            raise VMMEAE(_(u"Missing '@' sign in e-mail address “%s”.") %
193
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    77
                         address, INVALID_ADDRESS)
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    78
        elif p_len > 2:
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    79
            raise VMMEAE(_(u"Too many '@' signs in e-mail address “%s”.") %
a259bdeaab5c VMM/EmailAddress: rework EmailAddress class.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 185
diff changeset
    80
                         address, INVALID_ADDRESS)
76
14c0a092d7d2 * 'VirtualMailManager/EmailAddress.py'
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    81
194
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    82
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    83
_ = lambda msg: msg
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    84
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    85
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    86
def check_localpart(localpart):
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    87
    """Validates the local-part of an e-mail address.
116
949c5db6447a Fixed a logical mistake in EmailAddress.__ne__() (not used),
Pascal Volk <neverseen@users.sourceforge.net>
parents: 108
diff changeset
    88
194
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    89
    Argument:
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    90
    localpart -- local-part of the e-mail address that should be validated
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    91
    """
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    92
    if len(localpart) < 1:
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    93
        raise VMMEAE(_(u'No local-part specified.'), LOCALPART_INVALID)
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    94
    if len(localpart) > 64:
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    95
        raise VMMEAE(_(u'The local-part “%s” is too long') % localpart,
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    96
                     LOCALPART_TOO_LONG)
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    97
    invalid_chars = set(re.findall(RE_LOCALPART, localpart))
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    98
    if invalid_chars:
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
    99
        i_chrs = u''.join((u'“%s” ' % c for c in invalid_chars))
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
   100
        raise VMMEAE(_(u"The local-part “%(l_part)s” contains invalid\
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
   101
 characters: %(i_chrs)s") % {'l_part': localpart, 'i_chrs': i_chrs},
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
   102
                     LOCALPART_INVALID)
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
   103
    return localpart
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
   104
6c06edb5b2d2 VMM/EmailAddress: reworked once more.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 193
diff changeset
   105
del _