
    ZhiQ                       U d dl mZ d dlmZ d dlZd dlZd dlZd dlZ	d dl
Z
d dlZd dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ d dl m!Z! d dl"m#Z# d dl$Z$d dl%m&Z& d dl%m'Z' e	jP                  rd dl)Z* ejV                  dejX                  dd        G d de-      Z.d1d2dZ/d3d4dZ0d3d5dZ1	 d3	 	 	 	 	 d6dZ2d7dZ3 G d d      Z4 G d de5      Z6 G d d       Z7 G d! d"      Z8 G d# d$      Z9 G d% d&e9      Z: G d' d(e9      Z; e$jx                         Z=d)e>d*<   e=j                  d+d,-      Z@d.e>d/<   d8d0ZAy)9    )annotationsN)contextmanager)charset)policy)encode_base64)Header)MIMEBase)MIMEMultipart)MIMEText)
formataddr)
formatdate)
make_msgid)	parseaddr)
guess_type)TracebackType)current_app)Flaskutf-8c                  ,     e Zd Zd fdZd fdZ xZS )FlaskMailUnicodeDecodeErrorc                ,    || _         t        |   |  y N)objsuper__init__)selfr   args	__class__s      <D:\EasyAligner\venv\Lib\site-packages\flask_mail/__init__.pyr   z$FlaskMailUnicodeDecodeError.__init__$   s    $    c                p    t         |          }| d| j                  dt        | j                         dS )Nz. You passed in z ())r   __str__r   type)r   originalr   s     r   r#   z#FlaskMailUnicodeDecodeError.__str__(   s6    7?$+DHH<r$txx.9IKKr    )r   t.Anyr   r&   returnNoner'   str)__name__
__module____qualname__r   r#   __classcell__)r   s   @r   r   r   #   s     L Lr    r   c                r   t        | t              r| S 	 t        | t              rt        | ||      }|S t        |       }	 |S # t        $ rl}t        | t              st        | g|j                   |dj                  | j                  D cg c]  }t        |||       nc c}w c}      }Y d}~|S d}~ww xY w)zz
    Similar to smart_text, except that lazy instances are resolved to
    strings, rather than kept as lazy objects.
     N)	
isinstancer*   bytesUnicodeDecodeError	Exceptionr   r   join
force_text)sencodingerrorsouteargs         r   r6   r6   -   s    
 !S	Naa6*C J a&C J  N!Y'-a9!&&9q@hhQVVLVc
3&9VLMJNs)   A A 	B6
A B1
B
B11B6c                    	 | j                  d       | S # t        $ rJ 	 t        | |      j                         } Y | S # t        $ r t        | d      j                         } Y Y | S w xY ww xY w)Nasciir   )encodeUnicodeEncodeErrorr   )subjectr8   s     r   sanitize_subjectrB   C   sw    8w N  8	8Wh/668G N " 	8Wg.557GN	88s$    	A(<#A$A(#A$$A(c                0   t        | t              rt        t        |             } | \  }} 	 t	        ||      j                         }	 | j                  d       t        || f      S # t        $ r t	        |d      j                         }Y Dw xY w# t        $ r d| v r^| j                  dd      \  }}t        t	        ||            }|j                  d      j                  d      }dj                  ||g      } nt	        | |      j                         } Y w xY w)Nr   r>   @   idna)r1   r*   r   r6   r   r?   r@   splitdecoder5   r   )addrr8   nm	localpartdomains        r   sanitize_addressrM   O   s   $D)*HB*B!((*	3G r4j!!  *B '')*
  3$; $

3 2IvF9h78I]]6*11':F88Y/0D$)002D3s$   A$ B $#B
	B
BDDc                @    | D cg c]  }t        ||       c}S c c}w r   )rM   )	addressesr8   r;   s      r   sanitize_addressesrP   h   s$     4==9aQ)9===s   c                    d| v xs d| v S )z,Used by has_bad_header to check for \r or \n
 )lines    r   _has_newlinerV   n   s    4<'44<'r    c                  ^    e Zd ZdZd	dZd
dZ	 	 	 	 	 	 	 	 ddZddZ	 d	 	 	 	 	 ddZddZ	y)
ConnectionzHandles connection to host.c                .    || _         d | _        d| _        y Nr   )mailhost
num_emails)r   r[   s     r   r   zConnection.__init__v   s    	<@	 r    c                z    | j                   j                  rd | _        n| j                         | _        d| _        | S rZ   )r[   suppressr\   configure_hostr]   r   s    r   	__enter__zConnection.__enter__{   s2    99DI++-DIr    c                R    | j                   | j                   j                          y y r   )r\   quit)r   exc_type	exc_valuetbs       r   __exit__zConnection.__exit__   s!     99 IINN !r    c                   | j                   j                  r?t        j                  | j                   j                  | j                   j
                        }n>t        j                  | j                   j                  | j                   j
                        }|j                  t        | j                   j                               | j                   j                  r|j                          | j                   j                  rP| j                   j                  r:|j                  | j                   j                  | j                   j                         |S r   )r[   use_sslsmtplibSMTP_SSLserverportSMTPset_debuglevelintdebuguse_tlsstarttlsusernamepasswordlogin)r   r\   s     r   r`   zConnection.configure_host   s     99##DII$4$4diinnED<<		 0 0$))..ADC		0199MMO99$))"4"4JJtyy))499+=+=>r    Nc                   |j                   sJ d       |j                  sJ d       |j                         rt        |j                  t        j
                         |_        | j                  t| j                  j                  t        |xs |j                        t        t        |j                               |j                         |j                  |j                         t        j                         }t         j#                  ||       | xj$                  dz  c_        | j$                  | j&                  j(                  k(  rDd| _        | j                  r0| j                  j+                          | j-                         | _        yyy)zVerifies and sends message.

        :param message: Message instance.
        :param envelope_from: Email address to be used in MAIL FROM command.
        zNo recipients have been addedzRThe message does not specify a sender and a default sender has not been configuredN)messagerE   r   )send_tosenderhas_bad_headersBadHeaderErrordatetimer\   sendmailrM   listrP   as_bytesmail_optionsrcpt_optionsr   _get_current_objectemail_dispatchedsendr]   r[   
max_emailsrd   r`   )r   ry   envelope_fromapps       r   r   zConnection.send   s3    ? ??~~ 	
&	
~
 ""$  <<99;GL99 II !@'..A'89  "$$$$ --/c731??dii222DOyy		  //1	  3r    c                8    | j                  t        |i |       yztShortcut for send(msg).

        Takes same arguments as Message constructor.

        :versionadded: 0.3.5
        Nr   Messager   r   kwargss      r   send_messagezConnection.send_message   s     			'4*6*+r    )r[   Mailr'   r(   )r'   zte.Self)re   ztype[BaseException]rf   BaseExceptionrg   r   r'   r(   )r'   zsmtplib.SMTP | smtplib.SMTP_SSLr   )ry   r   r   str | tuple[str, str] | Noner'   r(   r   r&   r   r&   r'   r(   )
r+   r,   r-   __doc__r   rb   rh   r`   r   r   rT   r    r   rX   rX   s   sc    %!
+8EKX	& OS&2&2/K&2	&2P,r    rX   c                      e Zd Zy)r}   N)r+   r,   r-   rT   r    r   r}   r}      s    r    r}   c                  6    e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 ddZy)
Attachmenta?  Encapsulates file attachment information.

    :param filename: filename of attachment
    :param content_type: file mimetype
    :param data: the raw file data
    :param disposition: content-disposition (if any)

    .. versionchanged:: 0.10.0
        The `data` argument is required.

    .. versionadded: 0.3.5
    Nc                    |t        d      || _        ||t        |      d   }|t        |t              rd}nd}|| _        || _        |xs d| _        |i }|| _        y )Nz The 'data' argument is required.r   z
text/plainzapplication/octet-stream
attachment)	
ValueErrordatar   r1   r*   filenamecontent_typedispositionheadersr   r   r   r   r   r   s         r   r   zAttachment.__init__   s}     <?@@!%	H$8%h/2L$$+9$,!- + ;|?G'.r    NNNNN)
r   
str | Noner   r   r   str | bytes | Noner   r   r   dict[str, str] | None)r+   r,   r-   r   r   rT   r    r   r   r      sM      $#'#'"&)-// !/ !	/
  / '/r    r   c                  8   e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZedd       Zedd       Zej                  dd       ZdddZ	ddZ
dd	Zdd
ZddZddZddZddZddZddZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 d dZy)!r   a;  Encapsulates an email message.

    :param subject: email subject header
    :param recipients: list of email addresses
    :param body: plain text message
    :param html: HTML message
    :param alts: A dict or an iterable to go through dict() that contains multipart
                 alternatives
    :param sender: email sender address, or **MAIL_DEFAULT_SENDER** by default
    :param cc: CC list
    :param bcc: BCC list
    :param attachments: list of Attachment instances
    :param reply_to: reply-to address
    :param date: send date
    :param charset: message character set
    :param extra_headers: A dictionary of additional headers for the message
    :param mail_options: A list of ESMTP options to be used in MAIL FROM command
    :param rcpt_options:  A list of ESMTP options to be used in RCPT commands
    Nc                   |xs t         j                  d   j                  }t        |t              r|d    d|d    d}|xs g | _        || _        || _        |
| _        |xs g | _	        |xs g | _
        || _        t        |xs i       | _        || _        || _        t!               | _        || _        || _        |xs g | _        |xs g | _        |	xs g | _        y )Nr[   r    <rE   >)r   
extensionsdefault_senderr1   tuple
recipientsrA   r{   reply_toccbccbodydictaltshtmlr~   r   msgIdr   extra_headersr   r   attachments)r   rA   r   r   r   r   r{   r   r   r   r   r~   r   r   r   r   s                   r   r   zMessage.__init__  s    $ H;11&9HHfe$q	{"VAYKq1F7A7GR#-36>/1xR03	r $	$($4	 $	"&	$,
#*4A'3'9r'3'9r-8->Br    c                    t        | j                        }| j                  r|j                  | j                         | j                  r|j                  | j                         |S r   )setr   r   updater   )r   r:   s     r   rz   zMessage.send_to=  sC    $//"88JJtxx 77JJtww
r    c                8    | j                   j                  d      S Nr   )r   getra   s    r   r   zMessage.htmlI  s    yy}}V$$r    c                `    || j                   j                  dd        y || j                   d<   y r   )r   pop)r   values     r   r   zMessage.htmlM  s'    =IIMM&$' %DIIfr    c                >    | j                   xs d}t        |||      S )zCreates a MIMEText object with the given subtype (default: 'plain')
        If the text is unicode, the utf-8 charset is used.
        r   )_subtype_charset)r   r   )r   textsubtyper   s       r   	_mimetextzMessage._mimetextT  s!     ,,)'wAAr    c           
        t         j                  d   j                  }| j                  xs d}| j                  xs g }t        |      dk(  r(| j                  s| j                  | j                        }nt        |      dkD  rA| j                  s5t               }|j                  | j                  | j                               nt               }t        d      }|j                  | j                  | j                  d             | j                  j                         D ]&  \  }}|j                  | j                  ||             ( |j                  |       | j                  r"t        t        | j                        |      |d<   t        | j                   |      |d<   dj#                  t%        t'        t)        | j*                  |                        |d	<   t-        | j.                  d
      |d<   | j0                  |d<   | j2                  r:dj#                  t%        t'        t)        | j2                  |                        |d<   | j4                  rt        | j4                  |      |d<   | j6                  r'| j6                  j                         D ]
  \  }}	|	||<    t9        j:                  dt8        j<                        }
|D ]:  }t?        |j@                  jC                  d       }|jE                  |jF                         tI        |       |jJ                  |jJ                  }|ratM        jN                  d|jJ                        }|jQ                  dd      jS                  d      }|
jU                  d|      jW                         }	 |jQ                  d       |jY                  d|jZ                  |       |j^                  j                         D ]  \  }}|jY                  ||        |j                  |       = t`        jb                  |_0        |S # t\        $ r$ |jY                  d|jZ                  dd|f       Y w xY w)zCreates the emailr[   r   r   alternativeplainSubjectFromz, ToT)	localtimeDatez
Message-IDCczReply-Toz[\s]+/NFKDr>   ignorer0   zContent-Disposition)r   UTF8 )2r   r   ascii_attachmentsr   r   lenr   r   r   r
   attachitemsrA   rB   r6   rM   r{   r5   r   r   rP   r   r   r~   r   r   r   r   recompileUNICODEr	   r   rG   set_payloadr   r   r   unicodedata	normalizer?   rH   substrip
add_headerr   r@   r   r   ro   )r   r   r8   r   msgr   mimetypecontentkvSPACESr   fr   keyr   s                   r   _messagezMessage._message[  si   '226:LL<<*7&&," {q ..+C!$))/CJJt~~dii01  /C'6Kt~~diiAB%)YY__%6!'""4>>'8#DE &7 JJ{#<<-j.FQC	N&t{{H=FIId3'9$//8'T#UVWD	 d;F JJL77		$s+=dggx+P'Q"RSCI==.t}}hGC
O**0021A 3 Hbjj1%J*1177<=AMM*//*!"".%..$*44VZ=P=PQH'wAHHQH%zz#x8>>@HOOG, LL-z/E/EPX !  )00668
US%( 9 JJqM= &@ [[

# * LL-".."("h!7 ! s   P*QQc                >    | j                         j                         S r   )r   	as_stringra   s    r   r   zMessage.as_string  s    }}((**r    c                >    | j                         j                         S r   )r   r   ra   s    r   r   zMessage.as_bytes  s    }}''))r    c                "    | j                         S r   )r   ra   s    r   r#   zMessage.__str__  s    ~~r    c                "    | j                         S r   )r   ra   s    r   	__bytes__zMessage.__bytes__  s    }}r    c                   | j                   g| j                  }| j                  r|j                  | j                         |D ]-  }t	        |t
              r|d    d|d    d}t        |      s- y | j                  r~t        | j                        rit        | j                  j                  d            D ]B  \  }}|s y|dkD  r	|d   dvr yt        |      r yt        |j                               dk(  sB y y)	zChecks for bad headers i.e. newlines in subject, sender or recipients.
        RFC5322: Allows multiline CRLF with trailing whitespace (FWS) in headers
        r   r   rE   r   Tz
z	 F)r{   r   r   appendr1   r   rV   rA   	enumeraterG   r   r   )r   r   headerlinenumrU   s        r   r|   zMessage.has_bad_headers  s     ;;11==NN4==)F&%("1I;b15F#  <<DLL)%.t||/A/A&/I%JMGT#{tAwe';##D)#4::<(A-# &K r    c                Z    t        j                  dt        d       | j                         S )Nzs'is_bad_headers' is renamed to 'has_bad_headers'. The old name is deprecated and will be removed in Flask-Mail 1.0.   
stacklevel)warningswarnDeprecationWarningr|   ra   s    r   is_bad_headerszMessage.is_bad_headers  s+    A		
 ##%%r    c                &    |j                  |        y)zVerifies and sends the message.N)r   )r   
connections     r   r   zMessage.send  s     	r    c                :    | j                   j                  |       y)zfAdds another recipient to the message.

        :param recipient: email address of recipient.
        N)r   r   )r   	recipients     r   add_recipientzMessage.add_recipient  s     	y)r    c           	     T    | j                   j                  t        |||||             y)zAdds an attachment to the message.

        :param filename: filename of attachment
        :param content_type: file mimetype
        :param data: the raw file data
        :param disposition: content-disposition (if any)
        N)r   r   r   r   s         r   r   zMessage.attach  s(     	xt['J	
r    )r   NNNNNNNNNNNNNN)rA   r*   r   "list[str | tuple[str, str]] | Noner   r   r   r   r   z3dict[str, str] | c.Iterable[tuple[str, str]] | Noner{   r   r   r  r   r  r   zlist[Attachment] | Noner   r   r~   zfloat | Noner   r   r   r   r   list[str] | Noner   r  )r'   zset[str | tuple[str, str]])r'   r   )r   r   r'   r(   )r   )r   r   r   r*   r'   r   )r'   r	   r)   )r'   r2   )r'   bool)r   rX   r'   r(   )r  str | tuple[str, str]r'   r(   r   )r   r   r   r   r   r   r   r   r   r   r'   r(   )r+   r,   r-   r   r   propertyrz   r   setterr   r   r   r   r#   r   r|   r   r   r  r   rT   r    r   r   r      s   , 9=DH/31526/315!"/3)-)-!&?&? 7&? 	&?
 &? B&? -&? /&? 0&? -&? /&? &? &? -&? '&?  '!&?P 	 	 % % 
[[& &BOb+* <&
*  $#'#'"&)-

 !
 !	

  
 '
 

r    r   c                  6    e Zd Zedd       ZddZddZd	dZy)

_MailMixinc              #  z   K   g dfd}t         j                  |      5   ddd       y# 1 sw Y   yxY ww)a3  Records all messages. Use in unit tests for example::

            with mail.record_messages() as outbox:
                response = app.test_client.get("/email-sending-view/")
                assert len(outbox) == 1
                assert outbox[0].subject == "testing"

        :versionadded: 0.4
        c                (    j                  |       y r   )r   )r   ry   outboxs     r   recordz*_MailMixin.record_messages.<locals>.record  s    MM'"r    N)r   r   ry   r   r'   r(   )r   connected_to)r   r  r  s     @r   record_messagesz_MailMixin.record_messages  s3      	# **62L 322s   ;/	;8;c                p    | j                         5 }|j                  |       ddd       y# 1 sw Y   yxY w)zSends a single message instance. If TESTING is True the message will
        not actually be sent.

        :param message: a Message instance.
        N)connectr   )r   ry   r   s      r   r   z_MailMixin.send  s%     \\^zLL$ ^^s   ,5c                8    | j                  t        |i |       yr   r   r   s      r   r   z_MailMixin.send_message  s     			'4*6*+r    c                    t        | dd      xs t        }	 t        |j                  d         S # t        $ r}t        d      |d}~ww xY w)z$Opens a connection to the mail host.r   Nr[   z:The current application was not configured with Flask-Mail)getattrr   rX   r   KeyErrorRuntimeError)r   r   errs      r   r  z_MailMixin.connect(  sQ    dE4(7K	cnnV455 	L	s   / 	A	AA	N)r'   zc.Iterator[list[Message]])ry   r   r'   r(   r   )r'   rX   )r+   r,   r-   r   r  r   r   r  rT   r    r   r  r     s#     $%,	r    r  c                  @    e Zd Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZy)_Mailc                    || _         || _        || _        || _        || _        || _        || _        || _        |	| _        |
| _	        || _
        y r   )rm   ru   rv   rn   rs   rj   r   rr   r   r_   r   )r   rm   ru   rv   rn   rs   rj   r   rr   r   r_   r   s               r   r   z_Mail.__init__5  sS       	,
$ !2r    N)rm   r*   ru   r   rv   r   rn   
int | Noners   r  rj   r  r   r   rr   rq   r   r  r_   r  r   r  )r+   r,   r-   r   rT   r    r   r  r  4  ss    33 3 	3
 3 3 3 #3 3 3 3  3r    r  c                  D    e Zd ZdZdddZ	 d		 	 	 	 	 	 	 d
dZddZddZy)r   zManages email messaging.Nc                R    || _         || j                  |      | _        y d | _        y r   )r   init_appstate)r   r   s     r   r   zMail.__init__S  s%    ?'+}}S'9DJDJr    c                   t        |j                  dd      |j                  d      |j                  d      |j                  dd      |j                  dd      |j                  d	d      |j                  d
      t        |j                  d|            |j                  d      |j                  d|      |j                  dd            S )NMAIL_SERVERz	127.0.0.1MAIL_USERNAMEMAIL_PASSWORD	MAIL_PORT   MAIL_USE_TLSFMAIL_USE_SSLMAIL_DEFAULT_SENDER
MAIL_DEBUGMAIL_MAX_EMAILSMAIL_SUPPRESS_SENDMAIL_ASCII_ATTACHMENTS)r  r   rq   )r   configrr   testings       r   	init_mailzMail.init_mail[  s     JJ}k2JJ'JJ'JJ{B'JJ~u-JJ~u-JJ,-

</0JJ()JJ+W5JJ/7
 	
r    c                    | j                  |j                  |j                  |j                        }t	        |di       |_        ||j
                  d<   |S )zInitializes your mail settings from the application settings.

        You can use this if you want to set up your Mail instance
        at configuration time.
        r   r[   )r2  r0  rr   r1  r  r   )r   r   r"  s      r   r!  zMail.init_appl  sG     szz399ckkB !lB7!&vr    c                0    t        | j                  |d       S r   )r  r"  )r   names     r   __getattr__zMail.__getattr__y  s    tzz4..r    r   )r   zFlask | Noner'   r(   )FF)r0  zdict[str, t.Any]rr   z
bool | intr1  r  r'   r  )r   r   r'   r  r5  r*   r'   r&   )r+   r,   r-   r   r   r2  r!  r6  rT   r    r   r   r   P  s@    " TY
&
/9
LP
	
"/r    r   zblinker.Namespacesignalszemail-dispatchedz
Signal sent when an email is dispatched. This signal will also be sent
in testing mode, even though the email will not actually be sent.
)doczblinker.NamedSignalr   c                    | dk(  r;dd l }t        j                  dt        d       |j                  j                  d      S t        |       )N__version__r   zThe '__version__' attribute is deprecated and will be removed in Flask-Mail 1.0. Use feature detection or 'importlib.metadata.version("flask-mail")' instead.r   r   z
flask-mail)importlib.metadatar   r   r   metadataversionAttributeError)r5  	importlibs     r   r6  r6    sK    }!E 	
 !!)),77

r    )r   strict)r7   r&   r8   r*   r9   r*   r'   r*   )r   )rA   r*   r8   r*   r'   r*   )rI   r  r8   r*   r'   r*   )rO   z!c.Iterable[str | tuple[str, str]]r8   r*   r'   z	list[str])rU   r*   r'   r  r7  )B
__future__r   collections.abcabccr   rk   r   typingtr   r   
contextlibr   emailr   r   email.encodersr   email.headerr   email.mime.baser	   email.mime.multipartr
   email.mime.textr   email.utilsr   r   r   r   	mimetypesr   typesr   blinkerflaskr   r   TYPE_CHECKINGtyping_extensionsteadd_charsetSHORTESTr3   r   r6   rB   rM   rP   rV   rX   r4   r}   r   r   r  r  r   	Namespacer8  __annotations__signalr   r6  rT   r    r   <module>r\     sS   "  	      %   (  $ . $ " " " !      ??"   GW--tW =L"4 L,	"4 CJ>0><?>>(
X, X,v	Y 	+/ +/\}
 }
@1 1h3J 38*/: */Z /W..0	 0(/	 )7 ) % r    