
    =h3                        d Z ddlZddlZddlZddlZddlmZmZ ddlm	Z	m
Z
mZmZmZ ddlmZ ddlmZ dZd	Z ej&                  d
      Z ej&                  d      Z G d dej,                        Z G d deej0                        Zy)z?
An ``asyncio.Protocol`` subclass for lower level IO handling.
    N)Optionalcast   )SMTPDataErrorSMTPReadTimeoutErrorSMTPResponseExceptionSMTPServerDisconnectedSMTPTimeoutError)SMTPResponse)
SMTPStatus)SMTPProtocoli    s   (?:\r\n|\n|\r(?!\n))s   (?m)^\.c                       e Zd ZdZddeej                     fdZddZddZ	dee
   ddfd	Zdd
Zdej                  ddfdZy)FlowControlMixina  
    Reusable flow control logic for StreamWriter.drain().
    This implements the protocol methods pause_writing(),
    resume_writing() and connection_lost().  If the subclass overrides
    these it must call the super methods.
    StreamWriter.drain() must wait for _drain_helper() coroutine.

    Copied from stdlib as per recommendation: https://bugs.python.org/msg343685.
    Logging and asserts removed, type annotations added.
    Nloopc                     |t        j                         | _        n|| _        d| _        t	        j
                         | _        d| _        y NF)asyncioget_event_loop_loop_pausedcollectionsdeque_drain_waiters_connection_lost)selfr   s     c/var/www/html/phonemate/phone_mate_backend/venv/lib/python3.12/site-packages/aiosmtplib/protocol.py__init__zFlowControlMixin.__init__*   sC    < //1DJDJ 	 !&    returnc                     d| _         y NT)r   r   s    r   pause_writingzFlowControlMixin.pause_writing6   s	    r   c                 x    d| _         | j                  D ]$  }|j                         r|j                  d        & y r   )r   r   done
set_resultr   waiters     r   resume_writingzFlowControlMixin.resume_writing9   s0    ))F;;=!!$' *r   excc                     d| _         | j                  sy | j                  D ]8  }|j                         r||j	                  d        (|j                  |       : y r!   )r   r   r   r%   r&   set_exception)r   r*   r(   s      r   connection_lostz FlowControlMixin.connection_lost@   sN     $||))F;;=;%%d+((- *r   c                 N  K   | j                   rt        d      | j                  sy | j                  j	                         }| j
                  j                  |       	 | d {    | j
                  j                  |       y 7  # | j
                  j                  |       w xY wwNConnection lost)r   ConnectionResetErrorr   r   create_futurer   appendremover'   s     r   _drain_helperzFlowControlMixin._drain_helperM   s       &'899||))+""6*	/LL&&v. &&v.s0   AB%B "B#B 'B%B B""B%streamasyncio.Future[None]c                     t         N)NotImplementedErrorr   r6   s     r   _get_close_waiterz"FlowControlMixin._get_close_waiterY   s    !!r   r9   r   N)__name__
__module____qualname____doc__r   r   AbstractEventLoopr   r#   r)   	Exceptionr-   r5   StreamWriterr<    r   r   r   r      s_    	
&Xg&?&?@ 
&(.8I#6 .4 .
/"(<(< "AW "r   r   c            	           e Zd Z	 ddeej
                     ddf fdZdej                  ddfdZddZ	e
defd	       Zd
ej                  ddfdZdee   ddf fdZdeddfdZdefdZdee   fdZdee   fdZddee   defdZdeddfdZdddedee   defdZ	 ddedee   defdZ	 	 d dej<                  dee   dee   defdZ  xZ!S )!r   Nr   r   c                     t         |   |       d| _        t               | _        d | _        d | _        d | _        | j                  j                         | _
        d| _        y )N)r   F)superr   	_over_ssl	bytearray_buffer_response_waiter	transport_command_lockr   r2   _closed_future
_quit_sent)r   r   	__class__s     r   r   zSMTPProtocol.__init__^   sX     	d# {HL:>596:jj6N6N6Pr   r6   r7   c                     | j                   S r9   )rO   r;   s     r   r<   zSMTPProtocol._get_close_waiterl   s    """r   c                 $    | j                          y r9   )_retrieve_response_exceptionr"   s    r   __del__zSMTPProtocol.__del__o   s     	))+r   c                 j    t        | j                  duxr | j                  j                                S )z<
        Check if our transport is still connected.
        N)boolrM   
is_closingr"   s    r   is_connectedzSMTPProtocol.is_connectedt   s-    
 DNN$.Rt~~7P7P7R3RSSr   rM   c                     t        t        j                  |      | _        |j	                  d      d u| _        | j                  j                         | _        t        j                         | _
        d| _        y )N
sslcontextF)r   r   	TransportrM   get_extra_inforI   r   r2   rL   LockrN   rP   )r   rM   s     r   connection_madezSMTPProtocol.connection_made{   sW    g//;"11,?tK $

 8 8 :$\\^r   r*   c                    t         |   |       | j                  sUt        d      }|r||_        | j
                  r5| j
                  j                         s| j
                  j                  |       d | _        d | _	        y r/   )
rH   r-   rP   r	   	__cause__rL   r%   r,   rM   rN   )r   r*   smtp_excrQ   s      r   r-   zSMTPProtocol.connection_lost   sj    $-.?@H%("$$T-B-B-G-G-I%%33H=!r   datac                    | j                   t        d|      | j                   j                         ry | j                  j	                  |       |j                  d      }|dk(  s||dz   |dz    dk(  ry 	 | j                         }|| j                   j                  |       y y # t        $ r%}| j                   j                  |       Y d }~y d }~ww xY w)Nz4data_received called without a response waiter set:    
         -)
rL   RuntimeErrorr%   rK   extendrfind_read_response_from_bufferr&   rC   r,   )r   rc   last_linebreakresponser*   s        r   data_receivedzSMTPProtocol.data_received   s      (FthO  ""'')D! E*b NQ&!);<D	;668H #%%00: $  	5!!//44	5s   7B& &	C/CCc                     t        d      }| j                  r5| j                  j                         s| j                  j                  |       y)NzUnexpected EOF receivedF)r	   rL   r%   r,   )r   r*   s     r   eof_receivedzSMTPProtocol.eof_received   s@    $%>?  )>)>)C)C)E!!//4 r   c                     | j                   rN| j                   j                         r4| j                   j                         s| j                   j                         S y)z
        Return any exception that has been set on the response waiter.

        Used to avoid 'Future exception was never retrieved' warnings
        N)rL   r%   	cancelled	exceptionr"   s    r   rT   z)SMTPProtocol._retrieve_response_exception   sI     !!%%**,))335((2244r   c                    d}t               }d}d}	 | j                  j                  d|      }|dk(  rnt        | j                  ||dz          }t	        |      t
        kD  rt        t        j                  d      	 t        |dd	       }|t	        |      z  }t	        |      r|j                  d       |j                  |dd j                  d             |d	d dk7  rd}n|r6t!        |t        |      j                  d
d            }| j                  d|= |S y# t        $ r< |j                  d
d      }t        t        j                  j                  d|       dw xY w)z7Parse the actual response (if any) from the data bufferrf   r   FTre   r   zResponse too longNrg   zutf-8ignore)errorszMalformed SMTP response line: rh   s    	
ri   surrogateescape)rJ   rK   findbyteslenMAX_LINE_LENGTHr   r   unrecognized_commandint
ValueErrordecodeinvalid_responsevaluerk   stripr   )	r   codemessageoffsetmessage_completeline_end_indexline
error_textro   s	            r   rm   z'SMTPProtocol._read_response_from_buffer   sx   + !\\..uf=N#f~/ABCD4y?*+335H 48} c$iF7|u%NN48>>*56AayD #' 7 : #eGn++G5FGH WfW%O-  ![[[B
+//554ZLA s   <D AE!timeoutc                   K   | j                   t        d      	 t        j                  | j                   |       d{   }	 | j                  	d| _         |S | j                  j                         | _         |S 7 ;# t        t        j                  f$ r}t        d      |d}~ww xY w# | j                  d| _         w | j                  j                         | _         w xY ww)a  
        Get a status response from the server.

        This method must be awaited once per command sent; if multiple commands
        are written to the transport without awaiting, response data will be lost.

        Returns an :class:`.response.SMTPResponse` namedtuple consisting of:
          - server response code (e.g. 250, or such, if all goes well)
          - server response string (multiline responses are converted to a
            single, multiline string).
        Nr0   z%Timed out waiting for server response)	rL   r	   r   wait_forTimeoutErrorr   rM   r   r2   )r   r   resultr*   s       r   read_responsezSMTPProtocol.read_response   s        (():;;		C"++D,A,A7KKF
 ~~%(,%  )-

(@(@(B% Lg223 	Y&'NOUXX	Y ~~%(,%(,

(@(@(B%sD   C!#A< A:A< 6C!:A< <B&B!!B&&B) )5CC!c                 (   | j                   | j                   j                         rt        d      	 t        t        j
                  | j                         j                  |       y # t        t        f$ r t        d| j                   d      d w xY w)Nr0   z
Transport z does not support writing.)
rM   rX   r	   r   r   WriteTransportwriteAttributeErrorr:   rj   )r   rc   s     r   r   zSMTPProtocol.write  s    >>!T^^%>%>%@():;;	''8>>tD 34 	T^^..HI	s   3A' '*Br   argsc                T  K   | j                   t        d      dj                  |      dz   }| j                   4 d{    | j                  |       |dk(  rd| _        | j                  |       d{   }ddd      d{    |S 7 M7 7 
# 1 d{  7  sw Y   S xY ww)zj
        Sends an SMTP command along with any args to the server, and returns
        a response.
        NServer not connected       
s   QUIT
Tr   )rN   r	   joinr   rP   r   )r   r   r   commandro   s        r   execute_commandzSMTPProtocol.execute_command  s      %()?@@))D/G+%%%JJw+%"&!///@@H &%  & A &%%% sW   <B(BB(3B5B6B:B(BB(BB(B%BB% B(r   c                   K   | j                   t        d      t        j                  d|      }t        j                  d|      }|j                  d      s|dz  }|dz  }| j                   4 d{    | j                  d       | j                  |       d{   }|j                  t        j                  k7  r t        |j                  |j                        | j                  |       | j                  |       d{   }|j                  t        j                  k7  r t        |j                  |j                        ddd      d{    |S 7 7 7 W7 # 1 d{  7  sw Y   S xY ww)z
        Sends an SMTP DATA command to the server, followed by encoded message content.

        Automatically quotes lines beginning with a period per RFC821.
        Lone \\r and \\n characters are converted to \\r\\n
        characters.
        Nr   r   s   ..s   .
s   DATA
r   )rN   r	   LINE_ENDINGS_REGEXsubPERIOD_REGEXendswithr   r   r   r   start_inputr   r   	completed)r   r   r   start_responsero   s        r   execute_data_commandz!SMTPProtocol.execute_data_command,  sB     %()?@@$((':""5'2(wG8%%%JJ{##'#5#5g#5#FFN""j&<&<<#N$7$79O9OPPJJw!///@@H}}
 4 44#HMM83C3CDD &%  &F
 A &%%% sn   A/E61E2E65'E EA'E EAE E6EE6E E E6 E3&E)'E3.E6tls_contextserver_hostnamec           	        K   | j                   rt        d      | j                  t        d      | j                  4 d{    | j	                  d       | j                  |       d{   }|j                  t        j                  k7  r t        |j                  |j                        | j                  | j                  j                         rt        d      	 | j                  j                  t        t         j"                  | j                        | |d||       d{   }|| _        ddd      d{    |S 7 7 7 "# t$        t         j$                  f$ r}t'        d	      |d}~wt(        $ r}t'        d
      |d}~wt*        $ r}t        d      |d}~ww xY w7 j# 1 d{  7  sw Y   S xY ww)zG
        Puts the connection to the SMTP server into TLS mode.
        zAlready using TLS.Nr   s
   STARTTLS
r   r0   F)server_sider   ssl_handshake_timeoutz#Timed out while upgrading transportz,Connection aborted while upgrading transportz*Connection reset while upgrading transport)rI   rj   rN   r	   r   r   r   r   readyr   r   rM   rX   r   	start_tlsr   r   r   r   r
   ConnectionAbortedErrorConnectionError)r   r   r   r   ro   tls_transportr*   s          r   r   zSMTPProtocol.start_tlsL  s     >>344%()?@@%%%JJ'!///@@H}}
 0 00+HMM8;K;KLL ~~%)B)B)D,->??&*jj&:&://@ %$3*1 '; ' !( +DN? &%B C &@! !'"6"67 W&'LMSVV) &B # ,@5 &%%%B s   ?G EG 'F*,E-A2F* AE&E	'E+F*2G =F(>G F*	EF%$E00F%<FF%F  F%%F*(G *F=0F31F=8G r9   r=   )NN)"r>   r?   r@   r   r   rB   r   rD   r<   rU   propertyrW   rY   BaseTransportr_   rC   r-   r{   rp   rr   BaseExceptionrT   r   rm   floatr   r   r   r   ssl
SSLContextstrr   __classcell__)rQ   s   @r   r   r   ]   s    59 w001  
 #(<(< #AW #,
 Td T T )>)>  4  "8I#6 "4 ";% ;D ;6d h}.E +H\,B +Z8E? l 8
% 
D 
 8<%-e_	, :>'/	F *.#'	/^^/ "#/ %	/
 
/r   r   )rA   r   r   rer   typingr   r   rx   r   r   r   r	   r
   ro   r   r   __all__r}   compiler   r   Protocolr   BaseProtocolr   rE   r   r   <module>r      s      	 
 !  #   RZZ 89 rzz+&<"w'' <"~^#W%9%9 ^r   