o
    <gE                     @   s  d dl Z d dlmZ d dlmZ d dlmZmZ d dlm	Z	 d dl
mZ d dlmZ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m Z  d dl!m"Z" d dl#m$Z$ d dl%m&Z& d dl'm(Z(m)Z) edZ*de*_+edZ,ej-e,_+dZ.dZ/G dd de0Z1h dZ2dd Z3dd Z4G dd dZ5G dd  d e5eZ6G d!d" d"e5eZ7G d#d$ d$e5eZ8G d%d& d&Z9G d'd( d(e9Z:dS ))    Ncharset)encoders)	generatormessage_from_string)HeaderParseError)Header)Addressparser)Message)MIMEBase)MIMEMessage)MIMEMultipart)MIMEText)
formataddr
formatdategetaddresses
make_msgid)BytesIOStringIO)Path)settings)DNS_NAME)	force_strpunycodeutf-8zapplication/octet-streami  c                   @   s   e Zd ZdS )BadHeaderErrorN)__name__
__module____qualname__ r    r    K/var/www/html/venv/lib/python3.10/site-packages/django/core/mail/message.pyr   #   s    r   >   reply-to	resent-cc	resent-to
resent-bccresent-fromresent-sendercctobccfromsenderc                    s    pt j t|}d|v sd|v rtd|| f z|d W n. tyN   |  tv r=d fddt	|fD }nt
|  }Y | |fS Y | |fS w |  dkr[t
| }| |fS )	z6Forbid multi-line headers to prevent header injection.
z;Header values can't contain newlines (got %r for header %r)ascii, c                 3   s    | ]}t | V  qd S N)sanitize_address).0addrencodingr    r!   	<genexpr>C   s    

z,forbid_multi_line_headers.<locals>.<genexpr>subject)r   DEFAULT_CHARSETstrr   encodeUnicodeEncodeErrorlowerADDRESS_HEADERSjoinr   r   )namevalr6   r    r5   r!   forbid_multi_line_headers7   s*   


rB   c           
   
   C   s\  d}t | ts=t| } z	t| \}}W n tttfy$   td|  w |r/td|| f |jp3d}|j	}|j
p;d}n| \}}d|vrMtd| d|dd\}}|| | }d	|v scd
|v rgtdz|d t| }W n ty   t|| }Y nw z|d W n ty   t|| }Y nw t|}t||d}	t||	jfS )zF
    Format a pair of (name, address) or an email address string.
    NzInvalid address "%s"z2Invalid address; only %s could be parsed from "%s" @zInvalid address ""   r-   r.   z7Invalid address; address parts cannot contain newlines.r/   )usernamedomain)
isinstancetupler   r
   get_mailboxr   
ValueError
IndexErrordisplay_name
local_partrH   rsplitr;   r   r<   r   r	   r   	addr_spec)
r4   r6   addresstokenrestnm	localpartrH   address_partsparsed_addressr    r    r!   r2   N   sH   



r2   c                   @   s    e Zd ZdddZdddZdS )		MIMEMixinFr-   c                 C   ,   t  }tj|dd}|j| ||d | S )a&  Return the entire formatted message as a string.
        Optional `unixfrom' when True, means include the Unix From_ envelope
        header.

        This overrides the default as_string() implementation to not mangle
        lines that begin with 'From '. See bug #13433 for details.
        Fmangle_from_unixfromlinesep)r   r   	Generatorflattengetvalueselfr^   r_   fpgr    r    r!   	as_string}      zMIMEMixin.as_stringc                 C   rZ   )a"  Return the entire formatted message as bytes.
        Optional `unixfrom' when True, means include the Unix From_ envelope
        header.

        This overrides the default as_bytes() implementation to not mangle
        lines that begin with 'From '. See bug #13433 for details.
        Fr[   r]   )r   r   BytesGeneratorra   rb   rc   r    r    r!   as_bytes   rh   zMIMEMixin.as_bytesN)Fr-   )r   r   r   rg   rj   r    r    r    r!   rY   |   s    
rY   c                   @   s   e Zd Zdd ZdS )SafeMIMEMessagec                 C   s"   t ||d\}}t| || d S )Nr/   )rB   r   __setitem__rd   r@   rA   r    r    r!   rl      s   zSafeMIMEMessage.__setitem__N)r   r   r   rl   r    r    r    r!   rk      s    rk   c                   @   s(   e Zd Zd	ddZdd Zd
ddZdS )SafeMIMETextplainNc                 C   s   || _ tj| |||d d S )N)_subtype_charset)r6   r   __init__)rd   _textrp   rq   r    r    r!   rr      s   zSafeMIMEText.__init__c                 C   $   t ||| j\}}t| || d S r1   )rB   r6   r   rl   rm   r    r    r!   rl         zSafeMIMEText.__setitem__c                 C   sJ   |dkrt |tjstdd | D }|rtnt}tj| ||d d S )Nr   c                 s   s$    | ]}t |jd dtkV  qdS )surrogateescape)errorsN)lenr;   RFC5322_EMAIL_LINE_LENGTH_LIMIT)r3   liner    r    r!   r7      s    
z+SafeMIMEText.set_payload.<locals>.<genexpr>r   )rI   Charsetany
splitlinesutf8_charset_qputf8_charsetr   set_payload)rd   payloadr   has_long_linesr    r    r!   r      s   zSafeMIMEText.set_payload)ro   Nr1   )r   r   r   rr   rl   r   r    r    r    r!   rn      s    
rn   c                   @   s    e Zd Z	dddZdd ZdS )SafeMIMEMultipartmixedNc                 K   s"   || _ tj| |||fi | d S r1   )r6   r   rr   )rd   rp   boundary	_subpartsr6   _paramsr    r    r!   rr      s   zSafeMIMEMultipart.__init__c                 C   rt   r1   )rB   r6   r   rl   rm   r    r    r!   rl      ru   zSafeMIMEMultipart.__setitem__)r   NNN)r   r   r   rr   rl   r    r    r    r!   r      s    
r   c                   @   s   e Zd ZdZdZdZdZ										dddZd d	d
Zdd Z	dd Z
d ddZd!ddZd"ddZdd Zdd Zdd Zd"ddZdd ZdS )#EmailMessagez"A container for email information.ro   r   NrC   c                 C   s  |rt |trtdt|| _ng | _|	r%t |	trtdt|	| _ng | _|r9t |tr3tdt|| _ng | _|
rMt |
trGtdt|
| _ng | _|pTtj	| _
|| _|p\d| _g | _|rx|D ]}t |trr| | qe| j|  qe|p{i | _|| _dS )g
        Initialize a single email message (which can be sent to multiple
        recipients).
        z%"to" argument must be a list or tuplez%"cc" argument must be a list or tuplez&"bcc" argument must be a list or tuplez+"reply_to" argument must be a list or tuplerC   N)rI   r:   	TypeErrorlistr)   r(   r*   reply_tor   DEFAULT_FROM_EMAIL
from_emailr8   bodyattachmentsr   attachextra_headers
connection)rd   r8   r   r   r)   r*   r   r   headersr(   r   
attachmentr    r    r!   rr      s>   







zEmailMessage.__init__Fc                 C   s$   ddl m} | js||d| _| jS )Nr   )get_connection)fail_silently)django.core.mailr   r   )rd   r   r   r    r    r!   r      s   zEmailMessage.get_connectionc                 C   s   | j ptj}t| j| j|}| |}| j|d< | j	d| j
|d< | |d| j | |d| j | |d| j dd | jD }d|vrNttjd	|d
< d|vrYttd|d< | j D ]\}}| dkrl|||< q^|S )NSubjectFromToCczReply-Toc                 S   s   g | ]}|  qS r    )r=   )r3   keyr    r    r!   
<listcomp>      z(EmailMessage.message.<locals>.<listcomp>date)	localtimeDatez
message-id)rH   z
Message-IDr+   )r6   r   r9   rn   r   content_subtype_create_messager8   r   getr   _set_list_header_if_not_emptyr)   r(   r   r   EMAIL_USE_LOCALTIMEr   r   itemsr=   )rd   r6   msgheader_namesr@   valuer    r    r!   message  s$   

zEmailMessage.messagec                 C   s   dd | j | j | j D S )z
        Return a list of all recipients of the email (includes direct
        addressees as well as Cc and Bcc entries).
        c                 S   s   g | ]}|r|qS r    r    )r3   emailr    r    r!   r   %  r   z+EmailMessage.recipients.<locals>.<listcomp>)r)   r(   r*   )rd   r    r    r!   
recipients   s   zEmailMessage.recipientsc                 C   s   |   sdS | || gS )zSend the email message.r   )r   r   send_messages)rd   r   r    r    r!   send'  s   zEmailMessage.sendc                 C   s   t |tr|dus|durtd| j| dS |du r!td|p+t|d p+t}|dd\}}|dkrOt |t	rOz|
 }W n tyN   t}Y nw | j|||f dS )a  
        Attach a file with the given filename and content. The filename can
        be omitted and the mimetype is guessed, if not provided.

        If the first parameter is a MIMEBase subclass, insert it directly
        into the resulting message attachments.

        For a text/* mimetype (guessed or specified), when a bytes object is
        specified as content, decode it as UTF-8. If that fails, set the
        mimetype to DEFAULT_ATTACHMENT_MIME_TYPE and don't decode the content.
        NzLcontent and mimetype must not be given when a MIMEBase instance is provided.zcontent must be provided.r   /rF   text)rI   r   rL   r   append	mimetypes
guess_typeDEFAULT_ATTACHMENT_MIME_TYPEsplitbytesdecodeUnicodeDecodeError)rd   filenamecontentmimetypebasetypesubtyper    r    r!   r   /  s,   

zEmailMessage.attachc                 C   sP   t |}|d}| }| |j|| W d   dS 1 s!w   Y  dS )al  
        Attach a file from the filesystem.

        Set the mimetype to DEFAULT_ATTACHMENT_MIME_TYPE if it isn't specified
        and cannot be guessed.

        For a text/* mimetype (guessed or specified), decode the file's content
        as UTF-8. If that fails, set the mimetype to
        DEFAULT_ATTACHMENT_MIME_TYPE and don't decode the content.
        rbN)r   openreadr   r@   )rd   pathr   filer   r    r    r!   attach_fileW  s
   "zEmailMessage.attach_filec                 C   s
   |  |S r1   )_create_attachmentsrd   r   r    r    r!   r   g  s   
zEmailMessage._create_messagec                 C   sr   | j r7| jptj}|}t| j|d}| js| r|| | j D ]}t	|t
r.|| q!|| j|  q!|S N)rp   r6   )r   r6   r   r9   r   mixed_subtyper   is_multipartr   rI   r   _create_attachment)rd   r   r6   body_msgr   r    r    r!   r   j  s   


z EmailMessage._create_attachmentsc                 C   s   | dd\}}|dkr| jptj}t|||}|S |dkr>|dkr>t|tr,| }nt|ts7t	t
|}t||}|S t||}|| t| |S )z
        Convert the content, mimetype pair into a MIME attachment object.

        If the mimetype is message/rfc822, content may be an
        email.Message or EmailMessage object, as well as a str.
        r   rF   r   r   rfc822)r   r6   r   r9   rn   rI   r   r   r   r   r   rk   r   r   Encodersencode_base64)rd   r   r   r   r   r6   r   r    r    r!   _create_mime_attachmentx  s    






z$EmailMessage._create_mime_attachmentc                 C   sP   |  ||}|r&z|d W n ty   dd|f}Y nw |jdd|d |S )zg
        Convert the filename, content, mimetype triple into a MIME attachment
        object.
        r/   r   rC   zContent-Dispositionr   )r   )r   r;   r<   
add_header)rd   r   r   r   r   r    r    r!   r     s   zEmailMessage._create_attachmentc                 C   sJ   |r#z| j | }W n ty   ddd |D }Y nw |||< dS dS )zt
        Set msg's header, either from self.extra_headers, if present, or from
        the values argument.
        r0   c                 s   s    | ]}t |V  qd S r1   )r:   )r3   vr    r    r!   r7     s    z=EmailMessage._set_list_header_if_not_empty.<locals>.<genexpr>N)r   KeyErrorr?   )rd   r   headervaluesr   r    r    r!   r     s   z*EmailMessage._set_list_header_if_not_empty)
rC   rC   NNNNNNNN)F)NNNr1   )r   r   r   __doc__r   r   r6   rr   r   r   r   r   r   r   r   r   r   r   r   r    r    r    r!   r      s6    

6


(
r   c                       sT   e Zd ZdZdZ											d fdd	Zdd Zd	d
 Zdd Z  Z	S )EmailMultiAlternativesz
    A version of EmailMessage that makes it easy to send multipart/alternative
    messages. For example, including text and HTML versions of the text is
    made easier.
    alternativerC   Nc                    s,   t  |||||||||
|
 |	pg | _dS )r   N)superrr   alternatives)rd   r8   r   r   r)   r*   r   r   r   r   r(   r   	__class__r    r!   rr     s   zEmailMultiAlternatives.__init__c                 C   s,   |du s|du rt d| j||f dS )z-Attach an alternative content representation.Nz+Both content and mimetype must be provided.)rL   r   r   )rd   r   r   r    r    r!   attach_alternative  s   z)EmailMultiAlternatives.attach_alternativec                 C   s   |  | |S r1   )r   _create_alternativesr   r    r    r!   r     s   z&EmailMultiAlternatives._create_messagec                 C   sT   | j ptj}| jr(|}t| j|d}| jr|| | jD ]
}|| j|  q|S r   )	r6   r   r9   r   r   alternative_subtyper   r   r   )rd   r   r6   r   r   r    r    r!   r     s   

z+EmailMultiAlternatives._create_alternatives)rC   rC   NNNNNNNNN)
r   r   r   r   r   rr   r   r   r   __classcell__r    r    r   r!   r     s$     r   );r   r   r   r{   r   r   r   r   email.errorsr   email.headerr   email.headerregistryr	   r
   email.messager   email.mime.baser   email.mime.messager   email.mime.multipartr   email.mime.textr   email.utilsr   r   r   r   ior   r   pathlibr   django.confr   django.core.mail.utilsr   django.utils.encodingr   r   r   body_encodingr~   QPr   ry   rL   r   r>   rB   r2   rY   rk   rn   r   r   r   r    r    r    r!   <module>   sF    

. s