o […dEã@s¤dZgd¢ZddlZddlZdZdZdZgd¢Zgd¢Zddddd d d d d d d d dd dœZ dd„Z dd„Z dd„Z dd„Z dd„ZGdd„dƒZGdd„deƒZdS)zcEmail address parsing code. Lifted directly from rfc822.py. This should eventually be rewritten. )Ú mktime_tzÚ parsedateÚ parsedate_tzÚquoteéNú Úz, )ÚjanÚfebÚmarÚaprÚmayÚjunÚjulÚaugÚsepÚoctÚnovÚdecÚjanuaryÚfebruaryÚmarchÚaprilr ÚjuneÚjulyÚaugustÚ septemberÚoctoberÚnovemberÚdecember)ÚmonÚtueÚwedÚthuÚfriÚsatÚsunipþÿÿiÔþÿÿi þÿÿi¨ýÿÿiDýÿÿiàüÿÿ)ÚUTÚUTCÚGMTÚZÚASTÚADTÚESTÚEDTÚCSTÚCDTÚMSTÚMDTÚPSTÚPDTcCs,t|ƒ}|sdS|ddurd|d<t|ƒS)zQConvert a date string to a time tuple. Accounts for military timezones. Né r)Ú _parsedate_tzÚtuple)ÚdataÚres©r9ú'/usr/lib/python3.10/email/_parseaddr.pyr-s  rc CsÎ|sdS| ¡}|s dS|d d¡s|d ¡tvr|d=n|d d¡}|dkr6|d|dd…|d<t|ƒdkrQ|d d¡}t|ƒdkrQ||dd…}t|ƒdkrƒ|d}| d¡}|d kri| d¡}|dkr~|d|…||d…g|dd…<n| d ¡t|ƒd kr‹dS|dd …}|\}}}}}|rž|rž|s dS| ¡}|tvrµ|| ¡}}|tvrµdSt  |¡d}|d krÄ|d 8}|d dkrÐ|dd …}| d ¡}|dkrÞ||}}|d dkrî|dd …}|sîdS|d  ¡sù||}}|d dkr|dd …}| d ¡}t|ƒdkr|\} } d} nAt|ƒdkr&|\} } } n4t|ƒdkrXd|dvrX|d d¡}t|ƒdkrI|\} } d} nt|ƒdkrV|\} } } ndSdSzt |ƒ}t |ƒ}t | ƒ} t | ƒ} t | ƒ} Wn t y{YdSw|dkr|dkr‹|d7}n|d7}d} |  ¡}|tvrŸt|} nzt |ƒ} Wn t y¯Ynw| dkr½| d¡r½d} | rÛ| dkrËd } | } nd} | | dd| dd} |||| | | ddd | g S)a†Convert 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Ú.édéDiliÐié<)ÚsplitÚendswithÚlowerÚ _daynamesÚrfindÚlenÚfindÚappendÚ _monthnamesÚindexÚisdigitÚintÚ ValueErrorÚupperÚ _timezonesÚ startswith)r7ÚiÚstuffÚsÚddÚmmÚyyÚtmÚtzÚthhÚtmmÚtssÚtzoffsetÚtzsignr9r9r:r59s¾      "                 ÿ      ÿ r5cCs"t|ƒ}t|tƒr|dd…S|S)z&Convert a time string to a time tuple.Nr4)rÚ isinstancer6©r7Útr9r9r:r¶s  rcCs8|ddurt |dd…d¡St |¡}||dS)zETurn a 10-tuple as returned by parsedate_tz() into a POSIX timestamp.r4Né)rA)ÚtimeÚmktimeÚcalendarÚtimegmrir9r9r:r¿s   rcCs| dd¡ dd¡S)zøPrepare 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:rÉsrc@s|eZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z ddd„Z dd„Z dd„Z dd„Zddd„Zdd„ZdS) Ú 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|_|j dd¡|_||_g|_ dS)zƒInitialize a new instance. `field' is an unparsed address header field, containing one or more addresses. z ()<>@,:;."[]rz z rGrN) ÚspecialsÚposÚLWSÚCRÚFWSÚatomendsrrÚ phraseendsÚfieldÚ commentlist©Úselfr|r9r9r:Ú__init__Ýs zAddrlistClass.__init__cCsšg}|jt|jƒkrH|j|j|jdvr.|j|jdvr&| |j|j¡|jd7_n|j|jdkr?|j | ¡¡nn|jt|jƒks t |¡S)z&Skip white space and extract comments.z r<ú() rvrPr|rwrRr}Ú getcommentÚ EMPTYSTRINGÚjoin)rÚwslistr9r9r:Úgotonextðsø zAddrlistClass.gotonextcCsHg}|jt|jƒkr"| ¡}|r||7}n| d¡|jt|jƒks |S)zVParse all addresses. Returns a list containing all of the addresses. )rr)rvrPr|Ú getaddressrR)rÚresultÚadr9r9r:Ú getaddrlistþs  ûzAddrlistClass.getaddrlistcCsêg|_| ¡|j}|j}| ¡}| ¡g}|jt|jƒkr-|r,t |j¡|dfg}n«|j|jdvrI||_||_| ¡}t |j¡|fg}n|j|jdkrg}t|jƒ}|jd7_|jt|jƒkrŽ| ¡|j|kr€|j|jdkr€|jd7_n||  ¡}|jt|jƒksgnI|j|jdkrº|  ¡}|jr±t |¡dd |j¡d |fg}n't |¡|fg}n|rÈt |j¡|dfg}n|j|j|j vrØ|jd7_| ¡|jt|jƒkró|j|jd kró|jd7_|S) zParse the next address.rz.@rDr<ú;úú@TrD)r|rvr†rPÚ getdomainr)rÚ expectrouteÚadlistr9r9r:r‘Gs4 õþðzAddrlistClass.getrouteaddrcCsZg}| ¡|jt|jƒkryd}|j|jdkr3|r$|d ¡s$| ¡| d¡|jd7_d}n1|j|jdkrG| dt| ¡ƒ¡n|j|j|j vr]|r\|d ¡s\| ¡n| |  ¡¡| ¡}|rq|rq| |¡|jt|jƒks|jt|jƒks‰|j|jdkrŽt   |¡S| d¡|jd7_| ¡|  ¡}|s¦t St   |¡|S) zParse an RFC 2822 addr-spec.TrGrAr<Frqz"%s"rš)r†rvrPr|ÚstripÚpoprRrÚgetquoterzÚgetatomrƒr„r›)rÚaslistÚ preserve_wsÚwsÚdomainr9r9r:rgs<  î   zAddrlistClass.getaddrspeccCsòg}|jt|jƒkrt|j|j|jvr|jd7_nQ|j|jdkr,|j | ¡¡n@|j|jdkr<| | ¡¡n0|j|jdkrQ|jd7_| d¡n|j|jdkr[tS|j|j|j vren| |  ¡¡|jt|jƒks t  |¡S)z-Get the complete domain name from an address.r<rú[rGrš) rvrPr|rwr}rRr‚Úgetdomainliteralrƒrzr¡r„)rÚsdlistr9r9r:r›s$ ï zAddrlistClass.getdomainTcCsì|j|j|kr dSdg}d}|jd7_|jt|jƒkrq|r,| |j|j¡d}n6|j|j|vr<|jd7_n5|rN|j|jdkrN| | ¡¡q|j|jdkrYd}n | |j|j¡|jd7_|jt|jƒkst |¡S)aæParse 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|rvrPrRr‚rƒr„)rÚ begincharÚendcharsÚ allowcommentsÚslistrr9r9r:Ú getdelimited¤s* ò zAddrlistClass.getdelimitedcCó| ddd¡S)z1Get a quote-delimited fragment from self's field.rqz" F©r­©rr9r9r:r ÉózAddrlistClass.getquotecCr®)z7Get a parenthesis-delimited fragment from self's field.rz) Tr¯r°r9r9r:r‚Ír±zAddrlistClass.getcommentcCsd| ddd¡S)z!Parse an RFC 2822 domain-literal.z[%s]r¦z] Fr¯r°r9r9r:r§ÑszAddrlistClass.getdomainliteralNcCspdg}|dur |j}|jt|jƒkr3|j|j|vrn| |j|j¡|jd7_|jt|jƒkst |¡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|rRrƒr„)rrzÚatomlistr9r9r:r¡Õsû zAddrlistClass.getatomcCs¶g}|jt|jƒkrY|j|j|jvr|jd7_n6|j|jdkr+| | ¡¡n&|j|jdkr<|j | ¡¡n|j|j|jvrH |S| |  |j¡¡|jt|jƒks |S)zýParse 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|ryrRr r}r‚r{r¡)rr”r9r9r:rŽésþö zAddrlistClass.getphraselist)T©N)Ú__name__Ú __module__Ú __qualname__Ú__doc__r€r†rŠr‡r‘rr›r­r r‚r§r¡rŽr9r9r9r:rtÓs ; & %  rtc@sHeZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dS)Ú AddressListz@An AddressList encapsulates a list of parsed RFC 2822 addresses.cCs(t ||¡|r| ¡|_dSg|_dSr³)rtr€rŠÚ addresslistr~r9r9r:r€s  zAddressList.__init__cCs t|jƒSr³)rPr¹r°r9r9r:Ú__len__ s zAddressList.__len__cCs>tdƒ}|jdd…|_|jD] }||jvr|j |¡q|Sr³©r¸r¹rR©rÚotherÚnewaddrÚxr9r9r:Ú__add__ s   €zAddressList.__add__cCs&|jD] }||jvr|j |¡q|Sr³)r¹rR©rr½r¿r9r9r:Ú__iadd__ó   €zAddressList.__iadd__cCs.tdƒ}|jD] }||jvr|j |¡q|Sr³r»r¼r9r9r:Ú__sub__s    €zAddressList.__sub__cCs&|jD] }||jvr|j |¡q|Sr³)r¹ÚremoverÁr9r9r:Ú__isub__$rÃzAddressList.__isub__cCs |j|Sr³)r¹)rrTr9r9r:Ú __getitem__+s zAddressList.__getitem__N) r´rµr¶r·r€rºrÀrÂrÄrÆrÇr9r9r9r:r¸s  r¸)r·Ú__all__rlrnrrƒÚ COMMASPACErSrNrYrr5rrrrtr¸r9r9r9r:Ús0û  }   /