a
    !fF                     @   s  d Z ddlmZ d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mZmZmZ ddlmZ ddlmZ ejd dkZ e oejd dkZ!e re"fZ#e"Z$ddl
m%Z% e%j&Z'ne(fZ#e)Z$dZ'e*dej+dd G dd de,Z-d1ddZ.d2ddZ/d3ddZ0d4ddZ1dd Z2G d d! d!e3Z4G d"d# d#e5Z6G d$d% d%e3Z7G d&d' d'e3Z8G d(d) d)e3Z9G d*d+ d+e9Z:G d,d- d-e9Z;e< Z=e=j>d.d/d0Z?dS )5z
    flaskext.mail
    ~~~~~~~~~~~~~

    Flask extension for sending email.

    :copyright: (c) 2010 by Dan Jacob.
    :license: BSD, see LICENSE for more details.
    )with_statementz0.9.1N)charset)encode_base64)MIMEBase)MIMEMultipart)MIMEText)Header)
formatdate
formataddr
make_msgid	parseaddr)contextmanager)current_app         )policyutf-8c                   @   s   e Zd Zdd Zdd ZdS )FlaskMailUnicodeDecodeErrorc                 G   s   || _ tj| g|R   d S N)objUnicodeDecodeError__init__)selfr   args r   K/var/www/html/python-backend/venv/lib/python3.9/site-packages/flask_mail.pyr   4   s    z$FlaskMailUnicodeDecodeError.__init__c                 C   s    t | }d|| jt| jf S )Nz%s. You passed in %r (%s))r   __str__r   type)r   originalr   r   r   r   8   s    
z#FlaskMailUnicodeDecodeError.__str__N)__name__
__module____qualname__r   r   r   r   r   r   r   3   s   r   strictc              
      s   t | tr| S zft | tsftr@t | tr6t|  } qdt| } qrt| drT|  } qrtt|  } n|  } W n\ ty } zDt | t	st
| g|jR  nd fdd| D } W Y d}~n
d}~0 0 | S )z
    Similar to smart_text, except that lazy instances are resolved to
    strings, rather than kept as lazy objects.

    If strings_only is True, don't convert (some) non-string-like objects.
    __unicode__ c                    s   g | ]}t | tqS r   )
force_textZstrings_only).0argencodingerrorsr   r   
<listcomp>X   s   zforce_text.<locals>.<listcomp>N)
isinstance	text_typestring_typesPY3byteshasattrr$   decoder   	Exceptionr   r   join)sr*   r+   er   r)   r   r&   =   s&    






r&   c                 C   sZ   z|  d W nF tyT   zt| |  } W n  tyN   t| d  } Y n0 Y n0 | S )Nasciir   )encodeUnicodeEncodeErrorr   )subjectr*   r   r   r   sanitize_subject\   s    r<   c                 C   s   t | trtt| } | \}} zt|| }W n  tyP   t|d }Y n0 z| d W nf ty   d| v r| dd\}}tt||}|d	d}d
||g} nt| | } Y n0 t|| fS )Nr   r8   @r   idna)r-   r/   r   r&   r   r9   r:   splitstrr3   r5   r
   )addrr*   nmZ	localpartdomainr   r   r   sanitize_addressf   s"    
rD   c                    s   t  fdd| S )Nc                    s
   t |  S r   )rD   )r7   r*   r   r   <lambda>}       z$sanitize_addresses.<locals>.<lambda>)map)	addressesr*   r   rE   r   sanitize_addresses|   s    rJ   c                 C   s   | rd| v sd| v rdS dS )z,Used by has_bad_header to check for \r or \n
TFr   )liner   r   r   _has_newline   s    rN   c                   @   sB   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	d
S )
ConnectionzHandles connection to host.c                 C   s
   || _ d S r   )mail)r   rP   r   r   r   r      s    zConnection.__init__c                 C   s$   | j jrd | _n
|  | _d| _| S )Nr   )rP   suppresshostconfigure_host
num_emailsr   r   r   r   	__enter__   s
    
zConnection.__enter__c                 C   s   | j r| j   d S r   )rR   quit)r   exc_type	exc_valuetbr   r   r   __exit__   s    zConnection.__exit__c                 C   s|   | j jrt| j j| j j}nt| j j| j j}|t| j j	 | j j
rT|  | j jrx| j jrx|| j j| j j |S r   )rP   use_sslsmtplibZSMTP_SSLserverportSMTPset_debuglevelintdebuguse_tlsstarttlsusernamepasswordlogin)r   rR   r   r   r   rS      s    zConnection.configure_hostNc                 C   s   |j sJ d|jsJ d| r(t|jdu r<t |_| jr~| jt|pR|jt	t
|j trl| n| |j|j tj|t d |  jd7  _| j| jjkrd| _| jr| j  |  | _dS )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)appr   r   )send_tosenderhas_bad_headersBadHeaderErrordatetimerR   ZsendmailrD   listrJ   r0   as_bytes	as_stringmail_optionsrcpt_optionsemail_dispatchedsendr   Z_get_current_objectrT   rP   
max_emailsrW   rS   )r   messageZenvelope_fromr   r   r   rv      s,    


zConnection.sendc                 O   s   |  t|i | dS ztShortcut for send(msg).

        Takes same arguments as Message constructor.

        :versionadded: 0.3.5
        Nrv   Messager   r   kwargsr   r   r   send_message   s    zConnection.send_message)N)
r    r!   r"   __doc__r   rV   r[   rS   rv   r~   r   r   r   r   rO      s   

#rO   c                   @   s   e Zd ZdS )rm   N)r    r!   r"   r   r   r   r   rm      s   rm   c                   @   s   e Zd ZdZdddZdS )
AttachmentzEncapsulates file attachment information.

    :versionadded: 0.3.5

    :param filename: filename of attachment
    :param content_type: file mimetype
    :param data: the raw file data
    :param disposition: content-disposition (if any)
    Nc                 C   s*   || _ || _|| _|pd| _|p"i | _d S )N
attachment)filenamecontent_typedatadispositionheadersr   r   r   r   r   r   r   r   r   r      s
    
zAttachment.__init__)NNNNN)r    r!   r"   r   r   r   r   r   r   r      s   
  r   c                   @   s   e Zd ZdZdddZe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dS )"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 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                 C   s   |pt jd j}t|tr"d| }|p(g | _|| _|| _|	| _|pDg | _	|pNg | _
|| _|| _|
| _t | _|| _|| _|p~g | _|pg | _|pg | _d S )NrP   z%s <%s>)r   
extensionsdefault_senderr-   tuple
recipientsr;   rk   reply_toccbccbodyhtmlrn   r   msgIdr   extra_headersrs   rt   attachments)r   r;   r   r   r   rk   r   r   r   r   rn   r   r   rs   rt   r   r   r   r     s$    





zMessage.__init__c                 C   s&   t | jt | jpdB t | jp dB S )Nr   )setr   r   r   rU   r   r   r   rj   &  s    zMessage.send_toplainc                 C   s   | j pd}t|||d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   r   r   r   	_mimetext*  s    
zMessage._mimetextc              	   C   s  t jd j}| jpd}| jpg }t|dkr@| js@| | j}nlt|dkrl| jslt	 }|
| | j n@t	 }t	d}|
| | jd |
| | jd |
| | jrtt| j||d< t| j||d< d	ttt| j||d
< t| jdd|d< | j|d< | jr6d	ttt| j||d< | jrNt| j||d< | jrt| j D ]\}}|||< q`tdtj}|D ]}	t|	j !d }
|
"|	j# t$|
 |	j%}|r|rt&'d|}|(dd)d}|*d|+ }z|o|(d W n. t,y0   t-s"|(d}dd|f}Y n0 |
j.d|	j/|d |	j0D ]\}}|
.|| qJ|
|
 qt1r|t1|_2|S )zCreates the emailrP   r   r   alternativer   r   SubjectFromz, ToT)	localtimeDatez
Message-IDCczReply-Toz[\s]+/ZNFKDr8   ignorer%   utf8UTF8r   zContent-Disposition)r   )3r   r   ascii_attachmentsr   r   lenr   r   r   r   attachr;   r<   r&   rD   rk   r5   rp   r   rJ   r   r	   rn   r   r   r   r   itemsrecompileUNICODEr   r   r?   set_payloadr   r   r   unicodedata	normalizer9   r3   substripr:   r0   
add_headerr   r   message_policyr   )r   r   r*   r   msgr   kvZSPACESr   fr   keyvaluer   r   r   _message1  sh    




zMessage._messagec                 C   s   |    S r   )r   rr   rU   r   r   r   rr   |  s    zMessage.as_stringc                 C   s,   t r|   S |   | jp$dS d S )Nr   )PY34r   rq   rr   r9   r   rU   r   r   r   rq     s    zMessage.as_bytesc                 C   s   |   S r   )rr   rU   r   r   r   r     s    zMessage.__str__c                 C   s   |   S r   )rq   rU   r   r   r   	__bytes__  s    zMessage.__bytes__c                 C   s   | j | jg| j }|D ]}t|r dS q| jrt| jrt| jdD ]P\}}|s\ dS |dkrv|d dvrv dS t|r dS t| dkrJ dS qJdS )zChecks for bad headers i.e. newlines in subject, sender or recipients.
        RFC5322: Allows multiline CRLF with trailing whitespace (FWS) in headers
        Tz
r   z	 F)	rk   r   r   rN   r;   	enumerater?   r   r   )r   r   headerZlinenumrM   r   r   r   rl     s     
zMessage.has_bad_headersc                 C   s(   ddl m} d}|t|dd |  S )Nr   )warnzIis_bad_headers is deprecated, use the new has_bad_headers method instead.r   )
stacklevel)warningsr   DeprecationWarningrl   )r   r   r   r   r   r   is_bad_headers  s    zMessage.is_bad_headersc                 C   s   | |  dS )zVerifies and sends the message.N)rv   )r   
connectionr   r   r   rv     s    zMessage.sendc                 C   s   | j | dS )zfAdds another recipient to the message.

        :param recipient: email address of recipient.
        N)r   append)r   Z	recipientr   r   r   add_recipient  s    zMessage.add_recipientc                 C   s   | j t||||| dS )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   r   r   r   r     s    zMessage.attach)r   NNNNNNNNNNNNN)r   )NNNNN)r    r!   r"   r   r   propertyrj   r   r   rr   rq   r   r   rl   r   rv   r   r   r   r   r   r   r{      sD                 
$

K	     r{   c                   @   s0   e Zd Zedd Zdd Zdd Zdd Zd	S )

_MailMixinc              	   #   sL   t stdg   fdd}t | z V  W t | nt | 0 dS )ay  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"

        You must have blinker installed in order to use this feature.
        :versionadded: 0.4
        zblinker must be installedc                    s     |  d S r   )r   )rx   ri   Zoutboxr   r   _record  s    z+_MailMixin.record_messages.<locals>._recordN)ru   RuntimeErrorconnectZ
disconnect)r   r   r   r   r   record_messages  s    
z_MailMixin.record_messagesc                 C   s6   |   }|| W d   n1 s(0    Y  dS )zSends a single message instance. If TESTING is True the message will
        not actually be sent.

        :param message: a Message instance.
        N)r   rv   )r   rx   r   r   r   r   rv     s    
z_MailMixin.sendc                 O   s   |  t|i | dS ry   rz   r|   r   r   r   r~     s    z_MailMixin.send_messagec                 C   s@   t | ddpt}zt|jd W S  ty:   tdY n0 dS )z$Opens a connection to the mail host.ri   NrP   z9The curent application was not configured with Flask-Mail)getattrr   rO   r   KeyErrorr   r   ri   r   r   r   r     s
    z_MailMixin.connectN)r    r!   r"   r   r   rv   r~   r   r   r   r   r   r     s
   


r   c                   @   s   e Zd ZdddZdS )_MailFc                 C   sF   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	|| _
d S r   )r^   rf   rg   r_   rd   r\   r   rc   rw   rQ   r   )r   r^   rf   rg   r_   rd   r\   r   rc   rw   rQ   r   r   r   r   r     s    z_Mail.__init__N)F)r    r!   r"   r   r   r   r   r   r     s    r   c                   @   s4   e Zd ZdZdddZdddZdd	 Zd
d ZdS )Mailz<Manages email messaging

    :param app: Flask instance
    Nc                 C   s&   || _ |d ur| || _nd | _d S r   )ri   init_appstater   r   r   r   r     s    zMail.__init__Fc                 C   sp   t |dd|d|d|dd|dd|d	d|d
t|d||d|d||ddS )NZMAIL_SERVERz	127.0.0.1ZMAIL_USERNAMEZMAIL_PASSWORDZ	MAIL_PORT   ZMAIL_USE_TLSFZMAIL_USE_SSLZMAIL_DEFAULT_SENDERZ
MAIL_DEBUGZMAIL_MAX_EMAILSZMAIL_SUPPRESS_SENDZMAIL_ASCII_ATTACHMENTS)r   getrb   )r   configrc   testingr   r   r   	init_mail  s    





zMail.init_mailc                 C   s0   |  |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.

        :param app: Flask application instance
        r   rP   )r   r   rc   r   r   r   )r   ri   r   r   r   r   r   .  s    
zMail.init_appc                 C   s   t | j|d S r   )r   r   )r   namer   r   r   __getattr__=  s    zMail.__getattr__)N)FF)r    r!   r"   r   r   r   r   r   r   r   r   r   r     s
   

r   z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.
)doc)r   r#   )r   )r   )r   )@r   
__future__r   __version__r   Zblinkerr]   sysro   r   emailr   email.encodersr   Zemail.mime.baser   Zemail.mime.multipartr   Zemail.mime.textr   Zemail.headerr   email.utilsr	   r
   r   r   
contextlibr   Zflaskr   version_infor0   r   r@   r/   r.   r   r`   r   
basestringunicodeadd_charsetSHORTESTr   r   r&   r<   rD   rJ   rN   objectrO   r4   rm   r   r{   r   r   r   	NamespaceZsignalssignalru   r   r   r   r   <module>   sX   






Q X;/