o }5hE@sdZgdZddlZddlZdZdZdZgdZgdZddddd d d d d d d d dd dZ ddZ ddZ ddZ ddZ ddZGdddZGdddeZdS)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)UTUTCGMTZASTADTESTEDTCSTCDTMSTMDTPSTPDTcCs,t|}|sdS|ddurd|d<t|S)zQConvert a date string to a time tuple. Accounts for military timezones. N r) _parsedate_tztuple)dataresr9'/usr/lib/python3.10/email/_parseaddr.pyr-s  rc Cs|sdS|}|s dS|dds|dtvr|d=n|dd}|dkr6|d|dd|d<t|dkrQ|dd}t|dkrQ||dd}t|dkr|d}|d}|d kri|d}|dkr~|d|||dg|dd<n|d t|d krdS|dd }|\}}}}}|r|r|sdS|}|tvr||}}|tvrdSt |d}|d kr|d 8}|d dkr|dd }|d }|dkr||}}|d dkr|dd }|sdS|d s||}}|d dkr|dd }|d }t|dkr|\} } d} nAt|dkr&|\} } } n4t|dkrXd|dvrX|dd}t|dkrI|\} } d} nt|dkrV|\} } } ndSdSzt |}t |}t | } t | } t | } Wn t y{YdSw|dkr|dkr|d7}n|d7}d} | }|tvrt|} nzt |} Wn t yYnw| dkr|drd} | r| dkrd } | } nd} | | dd| dd} |||| | | ddd | g S)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)r7istuffsddmmyytmtzthhtmmtsstzoffsettzsignr9r9r:r59s      "                        r5cCs"t|}t|tr|ddS|S)z&Convert a time string to a time tuple.Nr4)r isinstancer6r7tr9r9r:rs  rcCs8|ddurt|dddSt|}||dS)zETurn a 10-tuple as returned by parsedate_tz() into a POSIX timestamp.r4N)rA)timemktimecalendartimegmrir9r9r:rs   rcCs|ddddS)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)strr9r9r:rsrc@s|eZdZdZddZddZddZdd Zd d Zd d Z ddZ dddZ ddZ ddZ ddZdddZddZdS) 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. cCsZd|_d|_d|_d|_|j|j|_|j|j|j|_|jdd|_||_g|_ dS)zInitialize a new instance. `field' is an unparsed address header field, containing one or more addresses. z ()<>@,:;."[]rz z rGrN) specialsposLWSCRFWSatomendsrr phraseendsfield commentlistselfr|r9r9r:__init__s zAddrlistClass.__init__cCsg}|jt|jkrH|j|j|jdvr.|j|jdvr&||j|j|jd7_n|j|jdkr?|j|nn|jt|jks t|S)z&Skip white space and extract comments.z r<() rvrPr|rwrRr} getcomment EMPTYSTRINGjoin)rwslistr9r9r:gotonexts zAddrlistClass.gotonextcCsHg}|jt|jkr"|}|r||7}n|d|jt|jks |S)zVParse all addresses. Returns a list containing all of the addresses. )rr)rvrPr| getaddressrR)rresultadr9r9r: getaddrlists  zAddrlistClass.getaddrlistcCsg|_||j}|j}|}|g}|jt|jkr-|r,t|j|dfg}n|j|jdvrI||_||_|}t|j|fg}n|j|jdkrg}t|j}|jd7_|jt|jkr||j|kr|j|jdkr|jd7_n|| }|jt|jksgnI|j|jdkr| }|jrt|dd|jd |fg}n't||fg}n|rt|j|dfg}n|j|j|j vr|jd7_||jt|jkr|j|jd kr|jd7_|S) zParse the next address.rz.@rDr<;@TrD)r|rvrrP getdomainr)r expectrouteadlistr9r9r:rGs4 zAddrlistClass.getrouteaddrcCsZg}||jt|jkryd}|j|jdkr3|r$|ds$||d|jd7_d}n1|j|jdkrG|dt|n|j|j|j vr]|r\|ds\|n|| |}|rq|rq|||jt|jks|jt|jks|j|jdkrt |S|d|jd7_|| }|st St ||S) zParse an RFC 2822 addr-spec.TrGrAr<Frqz"%s"r)rrvrPr|strippoprRrgetquoterzgetatomrrr)raslist preserve_wswsdomainr9r9r:rgs<     zAddrlistClass.getaddrspeccCsg}|jt|jkrt|j|j|jvr|jd7_nQ|j|jdkr,|j|n@|j|jdkr<||n0|j|jdkrQ|jd7_|dn|j|jdkr[tS|j|j|j vren|| |jt|jks t |S)z-Get the complete domain name from an address.r<r[rGr) rvrPr|rwr}rRrgetdomainliteralrrzrr)rsdlistr9r9r:rs$  zAddrlistClass.getdomainTcCs|j|j|kr dSdg}d}|jd7_|jt|jkrq|r,||j|jd}n6|j|j|vr<|jd7_n5|rN|j|jdkrN||q|j|jdkrYd}n ||j|j|jd7_|jt|jkst|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<rrpT)r|rvrPrRrrr)r begincharendchars allowcommentsslistrr9r9r: getdelimiteds*  zAddrlistClass.getdelimitedcC|dddS)z1Get a quote-delimited fragment from self's field.rqz" Frrr9r9r:rzAddrlistClass.getquotecCr)z7Get a parenthesis-delimited fragment from self's field.rz) Trrr9r9r:rrzAddrlistClass.getcommentcCsd|dddS)z!Parse an RFC 2822 domain-literal.z[%s]rz] Frrr9r9r:rszAddrlistClass.getdomainliteralNcCspdg}|dur |j}|jt|jkr3|j|j|vrn||j|j|jd7_|jt|jkst|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<)rzrvrPr|rRrr)rrzatomlistr9r9r:rs zAddrlistClass.getatomcCsg}|jt|jkrY|j|j|jvr|jd7_n6|j|jdkr+||n&|j|jdkr<|j|n|j|j|jvrH |S|| |j|jt|jks |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. r<rqr) rvrPr|ryrRrr}rr{r)rrr9r9r:rs zAddrlistClass.getphraselist)TN)__name__ __module__ __qualname____doc__rrrrrrrrrrrrrr9r9r9r:rts ; & %  rtc@sHeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS) AddressListz@An AddressList encapsulates a list of parsed RFC 2822 addresses.cCs(t|||r||_dSg|_dSr)rtrr addresslistr~r9r9r:rs  zAddressList.__init__cCs t|jSr)rPrrr9r9r:__len__ s zAddressList.__len__cCs>td}|jdd|_|jD] }||jvr|j|q|SrrrrRrothernewaddrxr9r9r:__add__ s   zAddressList.__add__cCs&|jD] }||jvr|j|q|Sr)rrRrrrr9r9r:__iadd__   zAddressList.__iadd__cCs.td}|jD] }||jvr|j|q|Srrrr9r9r:__sub__s    zAddressList.__sub__cCs&|jD] }||jvr|j|q|Sr)rremoverr9r9r:__isub__$rzAddressList.__isub__cCs |j|Sr)r)rrTr9r9r: __getitem__+s zAddressList.__getitem__N) rrrrrrrrrrrr9r9r9r:rs  r)r__all__rlrnrr COMMASPACErSrNrYrr5rrrrtrr9r9r9r:s0  }   /