VMM/account: Account._count_aliases() cast the EmailAddress to str,
in order to avoid errors from the database.
# -*- coding: UTF-8 -*-# Copyright (c) 2008 - 2011, Pascal Volk# See COPYING for distribution information.""" VirtualMailManager.emailaddress ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Virtual Mail Manager's EmailAddress class to handle e-mail addresses."""importrefromVirtualMailManager.domainimportcheck_domainname,get_gidfromVirtualMailManager.constantsimport \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 '%s'")%address,INVALID_ADDRESS)elifp_len>2:raiseEAErr(_(u"Too many '@' signs in address '%s'")%address,INVALID_ADDRESS)ifnotparts[0]:raiseEAErr(_(u"Missing local-part in address '%s'")%address,LOCALPART_INVALID)ifnotparts[1]:raiseEAErr(_(u"Missing domain name in address '%s'")%address,DOMAIN_NO_NAME)self._localpart=check_localpart(parts[0])self._domainname=check_domainname(parts[1])classDestinationEmailAddress(EmailAddress):"""Provides additionally the domains group ID - when the domain is known in the database."""__slots__=('_gid')def__init__(self,address,dbh):"""Creates a new DestinationEmailAddress instance Arguments: `address`: string/unicode a e-mail address like user@example.com `dbh`: pyPgSQL.PgSQL.Connection/pyPgSQL.PgSQL.connection a database connection for the database access """super(DestinationEmailAddress,self).__init__(address)self._gid=0self._find_domain(dbh)def_find_domain(self,dbh):"""Checks if the domain is known"""self._gid=get_gid(dbh,self._domainname)ifself._gid:self._localpart=self._localpart.lower()@propertydefgid(self):"""The domains group ID. 0 if the domain is not known."""returnself._giddefcheck_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 "u"characters: %(i_chars)s")%{'l_part':localpart,'i_chars':i_chars},LOCALPART_INVALID)returnlocalpartdel_