e f/C@sdZddddgZddlZddlZdZdZd Zd d d d dddddddddddddddddddd gZd!d"d#d$d%d&d'gZidd(6dd)6dd*6dd+6d, d-6d. d/6d0 d16d, d26d3 d46d0 d56d6 d76d3 d86d9 d:6d6 d;6Z d<dZ d=d>Z d?dZ d@dZ dAdZGdBdCdCZGdDdEdEeZdS)FzcEmail address parsing code. Lifted directly from rfc822.py. This should eventually be rewritten. mktime_tz parsedate parsedate_tzquoteN z, ZjanZfebZmarZaprZmayZjunZjulZaugsepoctZnovZdecZjanuaryZfebruaryZmarchZaprilZjuneZjulyZaugustZ septemberZoctoberZnovemberZdecemberZmonZtueZwedZthuZfriZsatZsunZUTZUTCZGMTZiZASTi,ZADTiZESTZEDTiXZCSTZCDTiZMSTZMDTi ZPSTZPDTcCs=t|}|sdS|ddkr3d|d|djd}|dkr|d|dd|d@,:;."[]rz z rrN) specialsposLWSZCRFWSatomendsr; phraseendsfield commentlist)selfrDrrr__init__s     zAddrlistClass.__init__cCsg}x|jt|jkr|j|j|jdkr|j|jdkrn|j|j|jn|jd7_q |j|jdkr|jj|jq Pq Wtj|S)z&Skip white space and extract comments.z r() r?r'rDr@r)rE getcomment EMPTYSTRINGjoin)rFZwslistrrrgotonextszAddrlistClass.gotonextcCsUg}xH|jt|jkrP|j}|r@||7}q |jdq W|S)zVParse all addresses. Returns a list containing all of the addresses. r)rr)r?r'rD getaddressr))rFresultZadrrr getaddrlists  zAddrlistClass.getaddrlistcCsg|_|j|j}|j}|j}|jg}|jt|jkr|rPtj|j|dfg}qPn|j|jdkr||_||_|j}tj|j|fg}nz|j|jdkrg}t|j}|jd7_x=|jt|jkr|j|j|krm|j|jdkrm|jd7_Pn||j }qWn|j|jdkr|j }|jrtj|ddj|jd |fg}qPtj||fg}nS|r%tj|j|dfg}n+|j|j|j krP|jd7_n|j|jt|jkr|j|jd kr|jd7_n|S) zParse the next address.rz.@rr;)rFZoldposZoldclplistZ returnlistZaddrspecZfieldlenZ routeaddrrrrrMsL      %    %  3" .zAddrlistClass.getaddresscCs |j|jdkrdSd}|jd7_|jd}x|jt|jkr|rs|jd}n|j|jdkr|jd7_Pnr|j|jdkr|jd7_d}nD|j|jd kr|jd7_n|j}|jd7_P|jqBW|S) zParse a route address (Return-path value). This method just skips all the route stuff and returns the addrspec. rQNFrr>@Tr)rDr?rLr' getdomainrU)rFZ expectrouteZadlistrrrrV?s.     zAddrlistClass.getrouteaddrcCsg}|jx3|jt|jkrEd}|j|jdkr|rk|dj rk|jn|jd|jd7_d}n|j|jdkr|jdt|jnT|j|j|j kr|r|d j r|jnPn|j|j |j}|r|r|j|qqW|jt|jkst|j|jdkrt j |S|jd|jd7_|jt j ||j S) zParse an RFC 2822 addr-spec.TrrFr:z"%s"rYr!r!)rLr?r'rDstrippopr)rgetquoterBgetatomrJrKrZ)rFZaslistZ preserve_wsZwsrrrrU_s4        .   zAddrlistClass.getaddrspeccCsg}x|jt|jkr|j|j|jkrL|jd7_q |j|jdkr{|jj|jq |j|jdkr|j|jq |j|jdkr|jd7_|jdq |j|j|jkrPq |j|j q Wt j |S)z-Get the complete domain name from an address.rrH[r) r?r'rDr@rEr)rIgetdomainliteralrBr^rJrK)rFZsdlistrrrrZszAddrlistClass.getdomainTcCs-|j|j|krdSdg}d}|jd7_x|jt|jkr|ry|j|j|jd}n|j|j|kr|jd7_Pnk|r|j|jdkr|j|jq;n6|j|jdkrd}n|j|j|j|jd7_q;Wtj|S)aParse a header fragment delimited by special characters. `beginchar' is the start character for the fragment. If self is not looking at an instance of `beginchar' then getdelimited returns the empty string. `endchars' is a sequence of allowable end-delimiting characters. Parsing stops when one of these is encountered. If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed within the parsed fragment. rFrrHr9T)rDr?r'r)rIrJrK)rFZ begincharZendcharsZ allowcommentsZslistrrrr getdelimiteds(    zAddrlistClass.getdelimitedcCs|jdddS)z1Get a quote-delimited fragment from self's field.r:z" F)ra)rFrrrr]szAddrlistClass.getquotecCs|jdddS)z7Get a parenthesis-delimited fragment from self's field.rHz) T)ra)rFrrrrIszAddrlistClass.getcommentcCsd|jdddS)z!Parse an RFC 2822 domain-literal.z[%s]r_z] F)ra)rFrrrr`szAddrlistClass.getdomainliteralNcCsdg}|dkr!|j}nx\|jt|jkr|j|j|krVPn|j|j|j|jd7_q$Wtj|S)aParse an RFC 2822 atom. Optional atomends specifies a different set of end token delimiters (the default is to use self.atomends). This is used e.g. in getphraselist() since phrase endings must not include the `.' (which is legal in phrases).rNr)rBr?r'rDr)rJrK)rFrBZatomlistrrrr^s   zAddrlistClass.getatomcCsg}x|jt|jkr|j|j|jkrL|jd7_q |j|jdkrx|j|jq |j|jdkr|jj|jq |j|j|jkrPq |j|j |jq W|S)zParse a sequence of RFC 2822 phrases. A phrase is a sequence of words, which are in turn either RFC 2822 atoms or quoted-strings. Phrases are canonicalized by squeezing all runs of continuous whitespace into one space. rr:rH) r?r'rDrAr)r]rErIrCr^)rFrWrrrrSszAddrlistClass.getphraselist)__name__ __module__ __qualname____doc__rGrLrOrMrVrUrZrar]rIr`r^rSrrrrr=s     ; ! %   r=c@sjeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS) AddressListz@An AddressList encapsulates a list of parsed RFC 2822 addresses.cCs5tj|||r(|j|_n g|_dS)N)r=rGrO addresslist)rFrDrrrrGszAddressList.__init__cCs t|jS)N)r'rg)rFrrr__len__szAddressList.__len__cCs\td}|jdd|_x3|jD](}||jkr,|jj|q,q,W|S)N)rfrgr))rFothernewaddrxrrr__add__s  zAddressList.__add__cCs:x3|jD](}||jkr |jj|q q W|S)N)rgr))rFrirkrrr__iadd__szAddressList.__iadd__cCsFtd}x3|jD](}||jkr|jj|qqW|S)N)rfrgr))rFrirjrkrrr__sub__ s  zAddressList.__sub__cCs:x3|jD](}||jkr |jj|q q W|S)N)rgremove)rFrirkrrr__isub__szAddressList.__isub__cCs |j|S)N)rg)rFr+rrr __getitem__szAddressList.__getitem__N) rbrcrdrerGrhrlrmrnrprqrrrrrfs      rf)re__all__r7r8rTrJZ COMMASPACEr*r%r0rr rrrr=rfrrrrs6  u %