VMM/maillocation: Use the hex version, since we are able to convert
it to an string, in case of a failure.
# -*- coding: UTF-8 -*-# Copyright (c) 2008 - 2010, Pascal Volk# See COPYING for distribution information.""" VirtualMailManager.EmailAddress Virtual Mail Manager's EmailAddress class to handle e-mail addresses."""importrefromVirtualMailManager.Domainimportcheck_domainnamefromVirtualMailManager.constants.ERRORimport \DOMAIN_NO_NAME,INVALID_ADDRESS,LOCALPART_INVALID,LOCALPART_TOO_LONGfromVirtualMailManager.errorsimportEmailAddressErrorasEAErrRE_LOCALPART=re.compile(r"[^\w!#$%&'\*\+-\.\/=?^_`{\|}~]")_=lambdamsg:msgclassEmailAddress(object):"""Simple class for validated e-mail addresses."""__slots__=('_localpart','_domainname')def__init__(self,address):"""Creates a new instance from the string/unicode ``address``."""assertisinstance(address,basestring)self._localpart=Noneself._domainname=Noneself._chk_address(address)@propertydeflocalpart(self):"""The local-part of the address *local-part@domain*"""returnself._localpart@propertydefdomainname(self):"""The domain part of the address *local-part@domain*"""returnself._domainnamedef__eq__(self,other):ifisinstance(other,self.__class__):returnself._localpart==other.localpartand \self._domainname==other.domainnamereturnNotImplementeddef__ne__(self,other):ifisinstance(other,self.__class__):returnself._localpart!=other.localpartor \self._domainname!=other.domainnamereturnNotImplementeddef__hash__(self):returnhash((self._localpart.lower(),self._domainname.lower()))def__repr__(self):return"EmailAddress('%s@%s')"%(self._localpart,self._domainname)def__str__(self):return'%s@%s'%(self._localpart,self._domainname)def_chk_address(self,address):"""Checks if the string ``address`` could be used for an e-mail address. If so, it will assign the corresponding values to the attributes `_localpart` and `_domainname`."""parts=address.split('@')p_len=len(parts)ifp_len<2:raiseEAErr(_(u"Missing the '@' sign in address %r")%address,INVALID_ADDRESS)elifp_len>2:raiseEAErr(_(u"Too many '@' signs in address %r")%address,INVALID_ADDRESS)ifnotparts[0]:raiseEAErr(_(u'Missing local-part in address %r')%address,LOCALPART_INVALID)ifnotparts[1]:raiseEAErr(_(u'Missing domain name in address %r')%address,DOMAIN_NO_NAME)self._localpart=check_localpart(parts[0])self._domainname=check_domainname(parts[1])defcheck_localpart(localpart):"""Returns the validated local-part `localpart`. Throws a `EmailAddressError` if the local-part is too long or contains invalid characters. """iflen(localpart)>64:raiseEAErr(_(u"The local-part '%s' is too long")%localpart,LOCALPART_TOO_LONG)invalid_chars=set(RE_LOCALPART.findall(localpart))ifinvalid_chars:i_chars=u''.join((u'"%s" '%cforcininvalid_chars))raiseEAErr(_(u"The local-part '%(l_part)s' contains invalid \characters: %(i_chars)s")%{'l_part':localpart,'i_chars':i_chars},LOCALPART_INVALID)returnlocalpartdel_