YfD@sxdZddddgZddlZddlZdZdZd Zd d d d dddddddddddddddddddd gZd!d"d#d$d%d&d'gZd(dd)dd*dd+dd,d- d.d/ d0d1 d2d- d3d4 d5d1 d6d7 d8d4 d9d: d;d7 iZ 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 septemberZoctoberZnovemberZdecemberZmonZtueZwedZthuZfriZsatZsunZUTZUTCZGMTZZASTiZADTi,ZESTiZEDTZCSTiXZCDTZMSTiZMDTZPSTi ZPDTcCs:t|}|sdS|ddkr0d|d@,:;."[]rz z rrN) specialsposLWSZCRFWSatomendsr; phraseendsfield commentlist)selfrDrrr__init__s     zAddrlistClass.__init__cCsg}x|jt|jkr|j|j|jdkr}|j|jdkrk|j|j|j|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|rGtj|j|dfg}n|j|jdkr||_||_|j}tj|j|fg}nt|j|jdkr~g}t|j}|jd7_x7|jt|jkrz|j|j|krg|j|jdkrg|jd7_P||j }qWn|j|jdkr|j }|jrtj|ddj|jd |fg}qGtj||fg}nP|rtj|j|dfg}n(|j|j|j krG|jd7_|j|jt|jkr|j|jd kr|jd7_|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}|jx*|jt|jkr<d}|j|jdkr|rh|dj rh|j|jd|jd7_d}n|j|jdkr|jdt|jnQ|j|j|j kr|r|d j r|jPn|j|j |j}|r|r|j|qW|jt|jksk|j|jdkrxt j |S|jd|jd7_|j|j }|st St j ||S) zParse an RFC 2822 addr-spec.TrrFr:z"%s"rYr!r!)rLr?r'rDstrippopr)rgetquoterBgetatomrJrKrZ)rFZaslistZ preserve_wsZwsZdomainrrrrU_s:        .    zAddrlistClass.getaddrspeccCs7g}x!|jt|jkr)|j|j|jkrL|jd7_q |j|jdkr{|jj|jq |j|jdkr|j|jq |j|jdkr|jd7_|jdq |j|jdkrtS|j|j|j krPq |j|j q Wtj |S)z-Get the complete domain name from an address.rrH[rrY) r?r'rDr@rEr)rIgetdomainliteralrJrBr^rK)rFZsdlistrrrrZs"zAddrlistClass.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}x\|jt|jkr||j|j|krSPn|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__cCsYtd}|jdd|_x0|jD]%}||jkr,|jj|q,W|S)N)rfrgr))rFothernewaddrxrrr__add__s  zAddressList.__add__cCs7x0|jD]%}||jkr |jj|q W|S)N)rgr))rFrirkrrr__iadd__ szAddressList.__iadd__cCsCtd}x0|jD]%}||jkr|jj|qW|S)N)rfrgr))rFrirjrkrrr__sub__s  zAddressList.__sub__cCs7x0|jD]%}||jkr |jj|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 .