o
    ›¨Êhÿ7  ã                   @   sv   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
mZ ddlmZmZmZmZ G d	d
„ d
eeƒZdS )é    )Ú	b64decode)ÚMessage)ÚunquoteN)ÚSimpleUploadedFileé   )ÚEmailParserÚEmailBytesParser)Ú
angle_wrapÚget_content_dispositionÚparse_address_listÚparse_rfc2822datec                       s0  e Zd ZdZ‡ fdd„Zedd„ ƒZedd„ ƒZedd	„ ƒZed
d„ ƒZ	edd„ ƒZ
edd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZdd„ Zdd„ Zdd„ Z‡ fdd„Zdd„ Zd d!„ Zd"d#„ Zd7d%d&„Zd'd(„ Zed)d*„ ƒZed+d,„ ƒZed-d.„ ƒZe	$	/	$d8d0d1„ƒZed9d2d3„ƒZe	4d:d5d6„ƒZ‡  ZS );ÚAnymailInboundMessagezö
    A normalized, parsed inbound email message.

    A subclass of email.message.Message, with some additional
    convenience properties, plus helpful methods backported
    from Python 3.6+ email.message.EmailMessage (or really, MIMEPart)
    c                    s>   t t| ƒj|i |¤Ž d | _d | _d | _d | _d | _d | _d S ©N)	Úsuperr   Ú__init__Úenvelope_senderÚenvelope_recipientÚstripped_textÚstripped_htmlÚspam_detectedÚ
spam_score)ÚselfÚargsÚkwargs©Ú	__class__© úA/var/www/html/env/lib/python3.10/site-packages/anymail/inbound.pyr       s   
zAnymailInboundMessage.__init__c                 C   s2   |   d¡}t|ƒdkr|d S t|ƒdkrdS |S )zEmailAddress ÚFromr   r   N)Úget_address_headerÚlen)r   Ú
from_emailr   r   r   r!   0   s   
z AnymailInboundMessage.from_emailc                 C   ó
   |   d¡S )z+list of EmailAddress objects from To headerÚTo©r   ©r   r   r   r   Úto<   ó   
zAnymailInboundMessage.toc                 C   r"   )z+list of EmailAddress objects from Cc headerÚCcr$   r%   r   r   r   ÚccB   r'   zAnymailInboundMessage.ccc                 C   s   | d S )z$str value of Subject header, or NoneÚSubjectr   r%   r   r   r   ÚsubjectH   s   zAnymailInboundMessage.subjectc                 C   r"   )z>datetime.datetime from Date header, or None if missing/invalidÚDate)Úget_date_headerr%   r   r   r   ÚdateM   r'   zAnymailInboundMessage.datec                 C   r"   )z5Contents of the (first) text/plain body part, or Noneú
text/plain©Ú_get_body_contentr%   r   r   r   ÚtextS   ó   
zAnymailInboundMessage.textc                 C   r"   )z4Contents of the (first) text/html body part, or Noneú	text/htmlr0   r%   r   r   r   ÚhtmlX   r3   zAnymailInboundMessage.htmlc                 C   ó   dd„ |   ¡ D ƒS )z;list of attachments (as MIMEPart objects); excludes inlinesc                 S   s   g | ]}|  ¡ r|‘qS r   )Úis_attachment©Ú.0Úpartr   r   r   Ú
<listcomp>`   s    z5AnymailInboundMessage.attachments.<locals>.<listcomp>©Úwalkr%   r   r   r   Úattachments]   ó   z!AnymailInboundMessage.attachmentsc                 C   r6   )z4dict of Content-ID: attachment (as MIMEPart objects)c                 S   s*   i | ]}|  ¡ r|d  rt|d  ƒ|“qS )ú
Content-ID)Úis_inline_attachmentr   r8   r   r   r   Ú
<dictcomp>e   s
    ÿÿz<AnymailInboundMessage.inline_attachments.<locals>.<dictcomp>r<   r%   r   r   r   Úinline_attachmentsb   r?   z(AnymailInboundMessage.inline_attachmentsc                 C   s"   |   |¡}|durt|ƒ}|pg S )zVReturn the value of header parsed into a (possibly-empty) list of EmailAddress objectsN)Úget_allr   )r   ÚheaderÚvaluesr   r   r   r   h   s   
z(AnymailInboundMessage.get_address_headerc                 C   s   | | }|durt |ƒ}|S )z?Return the value of header parsed into a datetime.date, or NoneN)r   )r   rE   Úvaluer   r   r   r-   o   s   z%AnymailInboundMessage.get_date_headerc                 C   s2   |   ¡ D ]}| ¡ |kr| ¡ s| ¡   S qd S r   )r=   Úget_content_typer7   Úget_content_text)r   Úcontent_typer:   r   r   r   r1   v   s
   €z'AnymailInboundMessage._get_body_contentc                    s,   zt t| ƒ ¡ W S  ty   t| ƒ Y S w r   )r   r   r
   ÚAttributeErrorr%   r   r   r   r
   �   s
   ÿz-AnymailInboundMessage.get_content_dispositionc                 C   ó   |   ¡ dkS )NÚ
attachment©r
   r%   r   r   r   r7   ˆ   ó   z#AnymailInboundMessage.is_attachmentc                 C   rL   )NÚinlinerN   r%   r   r   r   rA   Œ   rO   z*AnymailInboundMessage.is_inline_attachmentc                 C   sx   |   ¡ }|dkr.|  ¡ }t|ƒdksJ ‚z|d  ¡ W S  ty-   |d  ¡  d¡ Y S w |dkr6tdƒ‚| jdd�S )	zReturn the raw payload bytesÚmessager   r   úutf-8Ú	multipartzUget_content_bytes() is not valid on multipart messages (perhaps you want as_bytes()?)T©Údecode)Úget_content_maintypeÚget_payloadr    Úas_bytesrK   Ú	as_stringÚencodeÚ
ValueError)r   ÚmaintypeÚpayloadr   r   r   Úget_content_bytes�   s   ÿz'AnymailInboundMessage.get_content_bytesNc                 C   s€   |   ¡ }|dkr|  ¡ }t|ƒdksJ ‚|d  ¡ S |dkr"tdƒ‚| jdd�}|du r.|S |p4|  d	¡}|p8d
}|j||d�S )z"Return the payload decoded to textrQ   r   r   rS   zUget_content_text() is not valid on multipart messages (perhaps you want as_string()?)TrT   NzUS-ASCIIÚreplace)Úerrors)rV   rW   r    rY   r[   Úget_content_charsetrU   )r   Úcharsetr`   r\   r]   r   r   r   rI   ¢   s   z&AnymailInboundMessage.get_content_textc                 C   s4   | d du rdS |   ¡ }|  ¡ }|  ¡ }t|||ƒS )z8Return the attachment converted to a Django UploadedFileúContent-DispositionN)Úget_filenamerH   r^   r   )r   ÚnamerJ   Úcontentr   r   r   Úas_uploaded_file¸   s   z&AnymailInboundMessage.as_uploaded_filec                 C   s*   t |tjƒr|  | d¡¡S t| ƒ |¡S )z5Returns a new AnymailInboundMessage parsed from str srR   )Ú
isinstanceÚsixÚ	text_typeÚparse_raw_mime_bytesrZ   r   Úparsestr)ÚclsÚsr   r   r   Úparse_raw_mimeÇ   s   z$AnymailInboundMessage.parse_raw_mimec                 C   s   t | ƒ |¡S )z7Returns a new AnymailInboundMessage parsed from bytes b)r   Ú
parsebytes)rm   Úbr   r   r   rk   Ð   s   z*AnymailInboundMessage.parse_raw_mime_bytesc                 C   s.   t | d¡tjƒrt| ƒ |¡S t| ƒ |¡S )zCReturns a new AnymailInboundMessage parsed from file-like object fpr   )rh   Úreadri   Úbinary_typer   Úparser   )rm   Úfpr   r   r   Úparse_raw_mime_fileÕ   s   z)AnymailInboundMessage.parse_raw_mime_filerR   c                 C   s¦  |durt | ƒj|dd�}| d¡ n| ƒ }|dur!|d= ||d< |dur,|d= ||d< |dur7|d= ||d< |durB|d= ||d< |durez| ¡ }W n tyW   |}Y nw |D ]
\}}| ||¡ qZ|d= |d	= d
|d< d|d	< | ƒ }d|d	< | |¡ | ƒ }d|d	< | |¡ |dur¢| ƒ }d|d	< |j||d� | |¡ |	dur¹| ƒ }d|d	< |j|	|
d� | |¡ |durÑ|D ]}| ¡ rË| |¡ q¿| |¡ q¿|S )aí  
        Returns a new AnymailInboundMessage constructed from params.

        This is designed to handle the sorts of email fields typically present
        in ESP parsed inbound messages. (It's not a generalized MIME message constructor.)

        :param raw_headers: {str|None} base (or complete) message headers as a single string
        :param from_email: {str|None} value for From header
        :param to: {str|None} value for To header
        :param cc: {str|None} value for Cc header
        :param subject: {str|None} value for Subject header
        :param headers: {sequence[(str, str)]|mapping|None} additional headers
        :param text: {str|None} plaintext body
        :param text_charset: {str} charset of plaintext body; default utf-8
        :param html: {str|None} html body
        :param html_charset: {str} charset of html body; default utf-8
        :param attachments: {list[MIMEBase]|None} as returned by construct_attachment
        :return: {AnymailInboundMessage}
        NT)Úheadersonlyr   r#   r(   r*   zMIME-VersionúContent-Typez1.0zmultipart/mixedzmultipart/relatedzmultipart/alternativer/   )rb   r4   )r   rl   Úset_payloadÚitemsrK   Ú
add_headerÚattachrA   )rm   Úraw_headersr!   r&   r)   r+   Úheadersr2   Útext_charsetr5   Úhtml_charsetr>   ÚmsgÚheader_itemsre   rG   ÚrelatedÚalternativesr:   rM   r   r   r   Ú	constructÝ   sd   ÿ



zAnymailInboundMessage.constructc                 C   s   | j |j| ¡ |j||jd�S )N)rJ   rf   ÚfilenameÚ
content_idrb   )Úconstruct_attachmentrJ   rr   re   rb   )rm   Úfiler‡   r   r   r   Ú'construct_attachment_from_uploaded_file2  s   ûz=AnymailInboundMessage.construct_attachment_from_uploaded_fileFc           	      C   s®   | ƒ }||d< |d urdnd|d< |d ur%|j d|dd� |j d|dd� |d ur/t|ƒ|d< |r5t|ƒ}|}| ¡ d	krOt|tjƒrG| ¡ }|  |¡g}d }| 	||¡ |S )
Nrx   rP   rM   rc   re   )rE   r†   r@   rQ   )
Ú	set_paramr	   r   rV   rh   ri   rs   rU   ro   ry   )	rm   rJ   rf   rb   r†   r‡   Úbase64r:   r]   r   r   r   rˆ   >  s$   z*AnymailInboundMessage.construct_attachment)NN)NNNNNNNrR   NrR   Nr   )NNNF) Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úpropertyr!   r&   r)   r+   r.   r2   r5   r>   rC   r   r-   r1   r
   r7   rA   r^   rI   rg   Úclassmethodro   rk   rv   r…   rŠ   rˆ   Ú__classcell__r   r   r   r   r      s\    












þTÿr   )rŒ   r   Úemail.messager   Úemail.utilsr   ri   Údjango.core.files.uploadedfiler   Ú_email_compatr   r   Úutilsr	   r
   r   r   Úobjectr   r   r   r   r   Ú<module>   s    