fEdZgdZddlZddlZdZdZdZgdZgdZddddd d d d d d d d dd dZ dZ dZ dZ dZ dZGddZGddeZy)zcEmail address parsing code. Lifted directly from rfc822.py. This should eventually be rewritten. ) mktime_tz parsedate parsedate_tzquoteN z, )janfebmaraprmayjunjulaugsepoctnovdecjanuaryfebruarymarchaprilr junejulyaugust septemberoctobernovemberdecember)montuewedthufrisatsunipii iiDi)UTUTCGMTZASTADTESTEDTCSTCDTMSTMDTPSTPDTcHt|}|sy|dd|d<t|S)zQConvert a date string to a time tuple. Accounts for military timezones. N r) _parsedate_tztuple)dataress '/usr/lib/python3.12/email/_parseaddr.pyrr-s0  C  1v~A :c |sy|j}|sy|djds|djtvr|d=n'|dj d}|dk\r|d|dzd|d<t |dk(r*|djd}t |dk(r||ddz}t |dk(rP|d}|j d}|d k(r|j d}|dkDr|d|||dg|ddn|jd t |d kry|dd }|\}}}}}|r|r|sy|j}|tvr||j}}|tvrytj|dz}|d kDr|d z}|d dk(r|dd }|j d }|dkDr||}}|d dk(r|dd }|sy|djs||}}|d dk(r|dd }|jd }t |dk(r|\} } d} nkt |dk(r|\} } } nVt |dk(rGd|dvr@|djd}t |dk(r|\} } d} nt |dk(r|\} } } nyy t|}t|}t| } t| } t| } |dkr|dkDr|dz }n|dz }d} |j}|tvr t|} n$ t|} | dk(r|jdrd} | r!| dkrd } | } nd} | | dzdz| dzdzzz} |||| | | ddd | g S#t$rYywxYw#t$rYawxYw)aConvert date to extended time tuple. The last (additional) element is the time zone offset in seconds, except if the timezone was specified as -0000. In that case the last element is None. This indicates a UTC timestamp that explicitly declaims knowledge of the source timezone, as opposed to a +0000 timestamp that indicates the source timezone really was UTC. Nr,-+r :0.dDilii<)splitendswithlower _daynamesrfindlenfindappend _monthnamesindexisdigitint ValueErrorupper _timezones startswith)r9istuffsddmmyytmtzthhtmmtsstzoffsettzsigns r;r7r79s  :: 2wH Q;2==-H a<F yHFx}d2hnb5HHI BS#q!R ::E *   s$+7L. L=. L:9L:= M M cFt|}t|tr|ddS|S)z&Convert a time string to a time tuple.Nr6)r isinstancer8r9ts r;rrs&TA!U!u r<c||dtj|dddzStj|}||dz S)zETurn a 10-tuple as returned by parsedate_tz() into a POSIX timestamp.r6N)rD)timemktimecalendartimegmrms r;rrsA Aw{{48e+,, OOD !47{r<cF|jddjddS)zPrepare string to be used in a quoted string. Turns backslash and double quote characters into quoted pairs. These are the only characters that need to be quoted inside a quoted string. Does not add the surrounding double quotes. \z\\"z\")replace)strs r;rrs" ;;tV $ , ,S% 88r<cbeZdZdZdZdZdZdZdZdZ dZ dd Z d Z d Z d ZddZdZy ) AddrlistClassaAddress parser class by Ben Escoto. To understand what this class does, it helps to have a copy of RFC 2822 in front of you. Note: this class interface is deprecated and may be removed in the future. Use email.utils.AddressList instead. c,d|_d|_d|_d|_|j|jz|_|j|jz|jz|_|j j dd|_||_g|_ y)zInitialize a new instance. `field' is an unparsed address header field, containing one or more addresses. z ()<>@,:;."[]rz z rJrN) specialsposLWSCRFWSatomendsrx phraseendsfield commentlistselfrs r;__init__zAddrlistClass.__init__sz ( 88dgg% 0477: --//R8 r<cJg}|jt|jkr|j|j|jdzvrY|j|jdvr(|j |j|j|xjdz c_nG|j|jdk(r*|j j |j nn#|jt|jkrtj|S)z&Skip white space and extract comments.z r?() r~rSrrrUr getcomment EMPTYSTRINGjoin)rwslists r;gotonextzAddrlistClass.gotonextshhTZZ(zz$((#txx&'88::dhh'v5MM$**TXX"67A DHH%,  ''(9:hhTZZ(''r<cg}|jt|jkrL|j}|r||z }n|j d|jt|jkrL|S)zVParse all addresses. Returns a list containing all of the addresses. )rr)r~rSr getaddressrU)rresultads r; getaddrlistzAddrlistClass.getaddrlists^ hhTZZ("B"  h' hhTZZ(  r<cg|_|j|j}|j}|j}|jg}|jt |j k\r*|rft j|j|dfg}n?|j |jdvrB||_||_|j}t j|j|fg}n|j |jdk(rg}t |j }|xjdz c_|jt |j krw|j|j|kr3|j |jdk(r|xjdz c_n%||jz}|jt |j krn|j |jdk(rp|j}|jr;t j|dzdj|jzd z|fg}n{t j||fg}nb|r&t j|j|dfg}n:|j |j|jvr|xjdz c_|j|jt |j kr1|j |jd k(r|xjdz c_|S) zParse the next address.rz.@rGr?;) rrr~ getphraselistrSrSPACEr getaddrspecr getrouteaddrr})roldposoldclplist returnlistaddrspecfieldlen routeaddrs r;rzAddrlistClass.getaddress s   ""$  88s4:: &$zz$*:*:;U1XFG ZZ !T )DH$D '')H ::d&6&67BCJ ZZ !S (J4::H HHMH((S_, 88h&4::dhh+?3+FHHMH'$//*;; ((S_,ZZ !S ())+I$zz%047"xx(8(89 :#*E HHMHr<c|j|jdk7ryd}|xjdz c_|jd}|jt|jkr |r|j d}n|j|jdk(r|xjdz c_ |S|j|jdk(r|xjdz c_d}nZ|j|jd k(r|xjdz c_n(|j }|xjdz c_ |S|j|jt|jkr |S) zParse a route address (Return-path value). This method just skips all the route stuff and returns the addrspec. rNFr?r>@TrG)rr~rrS getdomainr)r expectrouteadlists r;rzAddrlistClass.getrouteaddrGs& ::dhh 3 &   A  hhTZZ( # DHH%,A  DHH%,A " DHH%,A ))+A   MMO!hhTZZ($ r<cg}|j|jt|jkrgd}|j|jdk(rN|r#|dj s|j |j d|xjdz c_d}n|j|jdk(r,|j dt|jznj|j|j|jvr&|r#|dj s|j nh|j |j|j}|r|r|j ||jt|jkrg|jt|jk\s|j|jdk7rtj|S|j d|xjdz c_|j|j}|stStj||zS) zParse an RFC 2822 addr-spec.TrJrDr?Frwz"%s"r)rr~rSrstrippoprUrgetquotergetatomrrr)raslist preserve_wswsdomains r;rzAddrlistClass.getaddrspecgs hhTZZ(Kzz$((#s*&*"2"2"4JJL c"A # DHH%, fuT]]_'==>DHH%6&*"2"2"4JJL dlln-Br b!%hhTZZ(( 88s4:: &$**TXX*>#*E##F+ + c A  ! '&00r<cg}|jt|jkr|j|j|jvr|xjdz c_n,|j|jdk(r*|jj |j n|j|jdk(r |j |jn|j|jdk(r'|xjdz c_|j dng|j|jdk(rtS|j|j|jvrnC|j |j|jt|jkrtj|S)z-Get the complete domain name from an address.r?r[rJr) r~rSrrrrUrgetdomainliteralrrrr)rsdlists r;rzAddrlistClass.getdomains=hhTZZ(zz$((#txx/A DHH%,  ''(9:DHH%, d3356DHH%,A  c"DHH%,#"DHH%6 dlln-#hhTZZ($''r<c|j|j|k7rydg}d}|xjdz c_|jt|jkr|r+|j|j|jd}n|j|j|vr|xjdz c_n|r<|j|jdk(r |j|j |j|jdk(rd}n(|j|j|j|xjdz c_|jt|jkrt j |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. rFr?rrvT)rr~rSrUrrr)r begincharendchars allowcommentsslistrs r; getdelimitedzAddrlistClass.getdelimiteds% ::dhh 9 , A hhTZZ( TZZ12DHH%1A 4::dhh#73#> T__./DHH%- TZZ12 HHMHhhTZZ( &&r<c(|jdddS)z1Get a quote-delimited fragment from self's field.rwz" Frrs r;rzAddrlistClass.getquotes  eU33r<c(|jdddS)z7Get a parenthesis-delimited fragment from self's field.rz) Trrs r;rzAddrlistClass.getcomments  eT22r<c.d|jdddzS)z!Parse an RFC 2822 domain-literal.z[%s]rz] Frrs r;rzAddrlistClass.getdomainliterals))#ue<<rs     I > AQA$$$$$   z;z9kkZ -'--'r<