U
    4(T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| f|  d S N)objUnicodeDecodeError__init__)selfr   args r   N/var/www/html/media_planing_auth/env/lib/python3.8/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 nX tk
r } z:t | t	st
| f|j nd fdd| D } W 5 d}~X Y nX | 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   s^   z|  d W nJ tk
rX   zt| |  } W n" tk
rR   t| d  } Y nX Y nX | 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k
rR   t|d }Y nX z| d W nh tk
r   d| kr| dd\}}tt||}|d	d}d
||g} nt| | } Y nX t|| fS )Nr   r8   @r   Zidna)r-   r/   r   r&   r   r9   r:   splitstrr3   r5   r
   )addrr*   nmZ	localpartdomainr   r   r   sanitize_addressf   s"    
rC   c                    s   t  fdd| S )Nc                    s
   t |  S r   )rC   )r7   r*   r   r   <lambda>}       z$sanitize_addresses.<locals>.<lambda>)map)Z	addressesr*   r   rD   r   sanitize_addresses|   s    rH   c                 C   s   | rd| ksd| krdS dS )z,Used by has_bad_header to check for \r or \n
TFr   )liner   r   r   _has_newline   s    rL   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   rN   r   r   r   r      s    zConnection.__init__c                 C   s$   | j jrd | _n
|  | _d| _| S )Nr   )rN   suppresshostconfigure_host
num_emailsr   r   r   r   	__enter__   s
    
zConnection.__enter__c                 C   s   | j r| j   d S r   )rP   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   )rN   use_sslsmtplibZSMTP_SSLserverportSMTPZset_debuglevelintdebuguse_tlsZstarttlsusernamepasswordZlogin)r   rP   r   r   r   rQ      s    zConnection.configure_hostNc                 C   s   |j std|jstd| r(t|jdk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AssertionErrorsenderhas_bad_headersBadHeaderErrordatetimerP   ZsendmailrC   listrH   r0   as_bytes	as_stringmail_optionsrcpt_optionsemail_dispatchedsendr   Z_get_current_objectrR   rN   
max_emailsrU   rQ   )r   messageZenvelope_fromr   r   r   rr      s,    


zConnection.sendc                 O   s   |  t|| dS ztShortcut for send(msg).

        Takes same arguments as Message constructor.

        :versionadded: 0.3.5
        Nrr   Messager   r   kwargsr   r   r   send_message   s    zConnection.send_message)N)
r    r!   r"   __doc__r   rT   rY   rQ   rr   rz   r   r   r   r   rM      s   

#rM   c                   @   s   e Zd ZdS )ri   N)r    r!   r"   r   r   r   r   ri      s   ri   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 )"rw   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 )NrN   z%s <%s>)r   
extensionsdefault_senderr-   tuple
recipientsr;   rg   reply_toccbccbodyhtmlrj   r   msgIdr   extra_headersro   rp   attachments)r   r;   r   r   r   rg   r   r   r   r   rj   r   r   ro   rp   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   rS   r   r   r   re   &  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 n0 t,k
r2   t-s$|(d}dd|f}Y nX |
j.d|	j/|d |	j0D ]\}}|
.|| qL|
|
 qt1r~t1|_2|S )zCreates the emailrN   r   r   alternativer   r   ZSubjectZFromz, ZToT)	localtimeZDatez
Message-IDZ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&   rC   rg   r5   rl   r   rH   r   r	   rj   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   rn   rS   r   r   r   rn   |  s    zMessage.as_stringc                 C   s,   t r|   S |   | jp$dS d S )Nr   )PY34r   rm   rn   r9   r   rS   r   r   r   rm     s    zMessage.as_bytesc                 C   s   |   S r   )rn   rS   r   r   r   r     s    zMessage.__str__c                 C   s   |   S r   )rm   rS   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k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)	rg   r   r   rL   r;   	enumerater>   r   r   )r   r   headerZlinenumrK   r   r   r   rh     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   DeprecationWarningrh   )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)rr   )r   
connectionr   r   r   rr     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   propertyre   r   r   rn   rm   r   r   rh   r   rr   r   r   r   r   r   r   rw      sD                 
$

K	     rw   c                   @   s0   e Zd Zedd Zdd Zdd Zdd Zd	S )

_MailMixinc              	   #   sB   t stdg   fdd}t | z
 V  W 5 t | X 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   )rt   rd   Zoutboxr   r   _record  s    z+_MailMixin.record_messages.<locals>._recordN)rq   RuntimeErrorconnectZ
disconnect)r   r   r   r   r   record_messages  s    

z_MailMixin.record_messagesc              	   C   s"   |   }|| W 5 Q R X 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   rr   )r   rt   r   r   r   r   rr     s    
z_MailMixin.sendc                 O   s   |  t|| dS ru   rv   rx   r   r   r   rz     s    z_MailMixin.send_messagec                 C   sB   t | ddpt}zt|jd W S  tk
r<   tdY nX dS )z$Opens a connection to the mail host.rd   NrN   z9The curent application was not configured with Flask-Mail)getattrr   rM   r   KeyErrorr   r   rd   r   r   r   r     s
    z_MailMixin.connectN)r    r!   r"   r   r   rr   rz   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\   rb   rc   r]   ra   rZ   r   r`   rs   rO   r   )r   r\   rb   rc   r]   ra   rZ   r   r`   rs   rO   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 k	r| || _nd | _d S r   )rd   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   getr_   )r   configr`   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   rN   )r   r   r`   r   r   r   )r   rd   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   blinkerr[   sysrk   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<   rC   rH   rL   objectrM   r4   ri   r|   rw   r   r   r   Z	NamespaceZsignalssignalrq   r   r   r   r   <module>   sX   





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