
    3fi`                         d dl Z d dlZd dlmZ d dlmZ ddlmZ  ej                  e	      Z
dZdZ G d d      Z G d	 d
e      Z G d de      Z G d de      Zy)    N)BytesIO)Path   )ApiComponenti  0 c                   ^    e Zd ZddZed        Zej                  d        Zed        Zd Zy)AttachableMixinNc                 L    d| _         || _        | j                  |      | _        y)z Defines the functionality for an object to be attachable.
        Any object that inherits from this class will be attachable
        (if the underlying api allows that)

        N)!_AttachableMixin__attachment_name*_AttachableMixin__attachment_name_property_gk!_AttachableMixin__attachment_type)selfattachment_name_propertyattachment_types      S/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/O365/utils/attachment.py__init__zAttachableMixin.__init__   s%     "&*B'!%/!:    c                     | j                   | j                   S | j                  rt        | | j                  d      S 	 t        | d      }|S # t        $ r t        | dd      }Y |S w xY w)z Name of the attachment

        :getter: get attachment name
        :setter: set new name for the attachment
        :type: str
         subjectname)r
   r   getattrAttributeError)r   attachment_names     r   r   zAttachableMixin.attachment_name   sx     !!-)))**4!@!@"EE
<")$	": #" " <")$";""<s   A A%$A%c                     || _         y N)r
   )r   values     r   r   zAttachableMixin.attachment_name/   s
    !&r   c                     | j                   S )z1 Type of attachment

        :rtype: str
        )r   r   s    r   r   zAttachableMixin.attachment_type3   s     %%%r   c                     t               )M Returns a dict to communicate with the server

        :rtype: dict
        )NotImplementedErrorr   s    r   to_api_datazAttachableMixin.to_api_data;   s    
 "##r   NN)	__name__
__module____qualname__r   propertyr   setterr   r#    r   r   r   r      sN    ; # #* ' ' & &$r   r   c                   $     e Zd Z fdZd Z xZS )UploadSessionRequestc                 ^    t         |   |j                  |j                         || _        y )Nprotocolmain_resource)superr   r/   r0   _attachment)r   parent
attachment	__class__s      r   r   zUploadSessionRequest.__init__E   s,    &//'-';'; 	 	=%r   c                    | j                  d      | j                  j                  | j                  d      | j                  j                  | j                  d      | j                  j                  i}| j                  j
                  r(| j                  j
                  || j                  d      <   | j                  d      |i}|S )NattachmentTyper   sizeisInlineAttachmentItem)_ccr2   r   r   r8   	is_inline)r   attachment_itemdatas      r   r#   z UploadSessionRequest.to_api_dataJ   s    HH%&(8(8(H(HHHVd..33HHVd..33

 %%484D4D4N4NODHHZ01)*O<r   )r%   r&   r'   r   r#   __classcell__r5   s   @r   r,   r,   C   s    &
	r   r,   c                   `     e Zd ZdZddiZddd fdZd Zd Zd	 Zdd
Z	ddZ
d Zd Z xZS )BaseAttachmentzF BaseAttachment class is the base object for dealing with attachments attach/messages/{id}/attachmentsNr3   c                V
   |j                  dt        |dd             |j                  dt        |dd             t        |   di | d| _        d| _        d| _        d| _        d| _        d| _	        d| _
        d| _        |j                  dd      | _        d| _        |rzt        |t               rA| j"                  |v r3|j                  | j"                        }|j                  | j%                  d      d      | _        |j                  | j%                  d      d      | _        |j                  | j%                  d	      d      | _        |j                  | j%                  d
      d      | _        |j                  | j%                  d      d      | _
        d|j                  dd      j'                         v rdnd| _        d| _        |j                  | j%                  d      d      | _        nf|j                  d|j                  d
            }|t)        d      |j                  d      | _
        |j                  d      | _        |j                  d      | _        | j                  rt+        |      nd| _	        | j                  r| j                  j                  n|j                  d
      | _        | j                  r$| j                  j-                         j.                  nd| _        ngt        |t0              r-t+        |      | _	        | j                  j                  | _        n*t        |t*              r#|| _	        | j                  j                  | _        nt        |t2        t4        f      r|\  }}t        |t6              rW|j9                         j:                  | _        t=        j>                  |jA                               jC                  d      | _
        nt+        |      | _	        || _        n]t        |tD              rMd| _        || _	        |jF                  | _        |jI                         | _
        |j
                  | j                  d<   | j                  | j                  r| j                  jK                         r| j                  jM                  d      5 }t=        j>                  |jO                               jC                  d      | _
        ddd       d| _        | j                  j-                         j.                  | _        yyyyy# 1 sw Y   >xY w)a   Creates a new attachment, optionally from existing cloud data

        :param attachment: attachment data (dict = cloud data,
         other = user data)
        :type attachment: dict or str or Path or list[str] or AttachableMixin
        :param BaseAttachments parent: the parent Attachments
        :param Protocol protocol: protocol to use if no parent specified
         (kwargs)
        :param str main_resource: use this resource instead of parent resource
         (kwargs)
        r/   Nr0   fileFon_cloudid	contentIdIsInliner   contentBytesitem@odata.typer   r8   pathz8Must provide a valid "path" or "name" for the attachmentcontenton_diskattachment_idzutf-8rbTr*   )(
setdefaultr   r1   r   r   r   rR   
content_idr<   r4   rP   rQ   getrH   r8   
isinstancedict_cloud_data_keyr;   lower
ValueErrorr   statst_sizestrtuplelistr   	getbuffernbytesbase64	b64encodegetvaluedecoder   r   r#   existsopenread)	r   r4   r3   kwargs	file_pathfile_objcustom_namerG   r5   s	           r   r   zBaseAttachment.__init__[   s    	*gfj$&GH/!&/4@	B 	"6"	%!

:u5	*d+'':5!+0D0D!EJ)3)MD&&0nnTXXk5JD&QDO%/^^DHHZ4H%%PDN *txx/? FDI#->>$((>2J26$8DL5;z~~%r@++0576368> (#(DL *txx/? FDI *vz~~f7M NI (( *E F F#->>)#<DL#->>)#<DL)3)HD&9=d9o4DO9=!5!5&0nnV&< IBF// 4 4 6 > >W[DIJ,"&z"2 OO00	J-", OO00	J6(2%+h0 ( 2 2 4 ; ;DI#)#3#3H4E4E4G#H#O#OPW#XDL&*8nDO'	J8'-$",&66	)557.8.H.H]+||#DOO<R<R<T__))$/ Q4#)#3#3DIIK#@#G#G#PDLQ# OO002::		 =U#k lQ Qs   *8TT(c                     | j                   S )z% Returns the size of this attachment )r8   r   s    r   __len__zBaseAttachment.__len__   s    yyr   c                 4    | j                   |j                   k(  S r   )rR   )r   others     r   __eq__zBaseAttachment.__eq__   s    !!U%8%888r   c                    d| j                  dj                  | j                              | j                  d      | j                  i}| j
                  r| j
                  || j                  d      <   | j                  dk(  rJ| j                  || j                  d      <   | j                  | j                  || j                  d      <   |S | j                  || j                  d      <   |S )	r!   rN   z{}_attachment_typer   r9   rG   rL   rJ   rM   )r   formatr   r;   r   r<   rP   rU   )r   r>   s     r   r#   zBaseAttachment.to_api_data   s    
 txx ''(<(<= ?HHVdii) >>)-D*%&6)-1\\D.)**.2ooTXXk*+  &*\\D&!"r   c                    | j                   syt        |xs d      }|j                         st        j	                  d       y|xs | j
                  }|j                  dd      j                  dd      }	 ||z  }|j                  d      5 }|j                  t        j                  | j                                ddd       || _        d	| _        | j                  j                         j                  | _        t        j	                  d
       y	# 1 sw Y   VxY w# t         $ r)}t        j#                  dt%        |             Y d}~yd}~ww xY w)z  Save the attachment locally to disk

        :param str location: path string to where the file is to be saved.
        :param str custom_name: a custom name to be saved as
        :return: Success / Failure
        :rtype: bool
        Fr   z$the location provided does not exist/-\wbNTzfile saved locally.zfile failed to be saved: %s)rP   r   rg   logdebugr   replacerh   writerc   	b64decoder4   rQ   r\   r]   r8   	Exceptionerrorr^   )r   locationrm   r   rO   rG   es          r   savezBaseAttachment.save   s    ||B' II<='dii||C%--dB7	d?D4 ;D

6++DLL9:;"DODL,,.66DIII+, ; ;  	II3SV<	s1   6D /D;AD DD 	E%E		Ec                 t   | j                   ry|r(t        |dd      r|r|j                  st        d      |j	                  | j
                  j                  d      j                  |j                              }|j                  j                  || j                               }t        |      S | j                  dk(  rl|j                  j                  | j                  | j                   rt#        | j                         nd| j$                  | j&                  | j(                  d	g       yt        d
      yy)a   Attach this attachment to an existing api_object. This
        BaseAttachment object must be an orphan BaseAttachment created for the
        sole purpose of attach it to something and therefore run this method.

        :param api_object: object to attach to
        :param on_cloud: if the attachment is on cloud or not
        :return: Success / Failure
        :rtype: bool
        TattachmentsNz5A valid object id is needed in order to attach a filerC   rI   r>   rG   )rR   rO   r   rP   rQ   z%Only file attachments can be attached)rH   r   	object_idRuntimeError	build_url
_endpointsrV   rt   conpostr#   boolr   r   addrR   r4   r^   r   rP   rQ   )r   
api_objectrH   urlresponses        r   rC   zBaseAttachment.attach   s$    == '*mTB!++&OQ Q !**4??+>+>x+H+O+O!++ ,P ,- . &>>..s9I9I9K.LH~%''61**..)-);); 15 !$ OO!-EI $		#'<<#'<<1 0  ''NOO3 C:r   c                 "    | j                         S r   )__repr__r   s    r   __str__zBaseAttachment.__str__"  s    }}r   c                 8    dj                  | j                        S )NzAttachment: {})rt   r   r   s    r   r   zBaseAttachment.__repr__%  s    &&tyy11r   r   r$   )F)r%   r&   r'   __doc__r   r   ro   rr   r#   r   rC   r   r   r?   r@   s   @r   rB   rB   V   sF    P89J^;$ ^;@9(@*PX2r   rB   c                        e Zd ZdZdddZeZd fd	Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd ZddZ xZS )BaseAttachmentsz! A Collection of BaseAttachments rD   z /messages/{id}/attachments/{ida})r   r4   c                     t         |   |j                  |j                         || _        g | _        g | _        d| _        |r| j                  |       d| _        y)z Attachments must be a list of path strings or dictionary elements

        :param Account parent: parent object
        :param attachments: list of attachments
        :type attachments: list[str] or list[Path] or str or Path or dict
        r.   TFN)	r1   r   r/   r0   _parent_BaseAttachments__attachments%_BaseAttachments__removed_attachmentsuntrackr   )r   r3   r   r5   s      r   r   zBaseAttachments.__init__2  sZ     	&//'-';'; 	 	=%'"HH[!r   c                 ,    t        | j                        S r   )iterr   r   s    r   __iter__zBaseAttachments.__iter__D  s    D&&''r   c                      | j                   |   S r   )r   )r   keys     r   __getitem__zBaseAttachments.__getitem__G  s    !!#&&r   c                 X    || j                   D ch c]  }|j                   c}v S c c}w r   )r   r   )r   rM   r4   s      r   __contains__zBaseAttachments.__contains__J  s%    $:L:LMJ
MMMMs   'c                 ,    t        | j                        S r   )lenr   r   s    r   ro   zBaseAttachments.__len__M  s    4%%&&r   c                     t        | j                        }t        | j                  dd      }|r|dk(  rydj	                  |      S )Nhas_attachmentsFr   zNumber of Attachments: unknownzNumber of Attachments: {})r   r   r   r   rt   )r   r   parent_has_attachmentss      r   r   zBaseAttachments.__str__P  sD    $,,-!(7H%!P!kQ&63.55kBBr   c                 "    | j                         S r   )r   r   s    r   r   zBaseAttachments.__repr__X  s    ||~r   c                 >    t        t        | j                              S r   )r   r   r   r   s    r   __bool__zBaseAttachments.__bool__[  s    C**+,,r   c                 x    | j                   D cg c]   }|j                  du r|j                         " c}S c c}w )r!   F)r   rH   r#   r   r4   s     r   r#   zBaseAttachments.to_api_data^  sA    
 <@;M;M .Z##u, &&( . 	. .s   %7c                     | j                   D ]*  }|j                  s| j                  j                  |       , g | _         | j	                          | j                          y)z Clear the attachments N)r   rH   r   append_update_parent_attachments_track_changesr   s     r   clearzBaseAttachments.clearf  sV    ,, 	>J""**11*=	>  '')r   c                     t        | j                  dd      	 5| j                  du r&| j                  j                  j	                  d       yyy)zY Update the track_changes on the parent to reflect
        a needed update on this field r   NFr   )r   r   r   r   r   r   s    r   r   zBaseAttachments._track_changeso  sN     4<<!1 $%)-)>LL''++M: *?%r   c                 ~    	 t        t        | j                              | j                  _        y# t
        $ r Y yw xY w)z7 Tries to update the parent property 'has_attachments' N)r   r   r   r   r   r   r   s    r   r   z*BaseAttachments._update_parent_attachmentsw  s5    	+/D4F4F0G+HDLL( 		s   -0 	<<c                 "   |rt        |t        t        f      r|g}t        |t        t        t
        f      r!|D cg c]  }| j                  ||        }}nqt        |t              rV| j                  |v rH|j                  | j                  g       D cg c]"  }| j                  | j                  |i| d      $ }}nt        d      | j                  j                  |       | j                          | j                          yyc c}w c c}w )z Add more attachments

        :param attachments: list of attachments
        :type attachments: list[str] or list[Path] or str or Path or dict
        rE   T)r3   rH   zGAttachments must be a str or Path or a list, tuple or set of the formerN)rW   r^   r   r`   r_   set_attachment_constructorrX   rY   rV   r[   r   extendr   r   )r   r   r4   attachments_temps       r   r   zBaseAttachments.add~  s&    +T{3*m+eS'9: '2$3" 00D0I$3  $3 K "&*&:&:k&I  OOD$8$8"=	$? # %)$@$@)):6t! %A %# $?  $? ! "D E E %%&67++-!/ 
$3$?s   D'Dc                    t        |t        t        f      r,|D ch c]   }t        |t              r|j                  n|" }}n=t        |t
              r|h}n)t        |t              r|j                  h}nt        d      g }| j                  D ]J  }|j                  |vr|j                  |       #|j                  s0| j                  j                  |       L || _        | j                          | j                          yc c}w )z Remove the specified attachments

        :param attachments: list of attachments
        :type attachments: list[str] or list[Path] or str or Path or dict
        z(Incorrect parameter type for attachmentsN)rW   r`   r_   rB   r   r^   r[   r   r   rH   r   r   r   )r   r   r4   new_attachmentss       r   removezBaseAttachments.remove  s     kD%=1 ?JK0:  **nE 'OO!+, KK K S)&-K^4&++,KGHH,, 	$Jk1&&z2&&..55"$	$ -'')+Ks   %Dc                    | j                   j                  sCt        j                  dj	                  | j                   j
                  j                               y| j                   j                  s8t        dj	                  | j                   j
                  j                              | j                  | j                  j                  d      j	                  | j                   j                              }| j                   j                  j                  |      }|sy|j                         j                  dg       }d| _        | j                  | j                   |i       d| _        y)z Downloads this message attachments into memory.
        Need a call to 'attachment.save' to save them on disk.

        :return: Success / Failure
        :rtype: bool
        z1Parent {} has no attachments, skipping out early.Fz2Attempted to download attachments of an unsaved {}r   r   r   T)r   r   rz   r{   rt   r5   r%   r   r   r   r   rV   r   jsonr   r   rY   )r   r   r   r   s       r   download_attachmentsz$BaseAttachments.download_attachments  s#    ||++IICJJLL**3356 ||%%DKKLL**3356 6 nnT__00?FF||%% G ' ( <<##'',mmo))'26 $&&45 r   c                 
    nt          j                  D ]  }|j                  du s|j                  t        k  rՉ j                   j                  j                  d      j                   j                  j                              } j                  j                  j                  ||j                               }|s y|j                         }|j                  d      |_        |j                   j!                  d      d      |_        n j                   j                  j                  d      j                   j                  j                              }t%         |	      }|j                         } j                  j                  j                  ||      }|s y|j                         }|j                   j!                  d
      d      t&        j)                  dj                               |j                   j!                  d      d      }|r$t&        j)                  dj                  |             0t&        j+                  dj                  |j,                                y fd}	|j.                  r5|j.                  j1                  d      5 fd}
 |	|
      }ddd       n7t3        t5        j6                  |j"                              fd} |	|      }s yd|_          j8                  D ]  }|j                  s|j                   j                   j                  j                  d      j                   j                  j                  |j                              } j                  j                  j;                  |      }|r y g  _        t&        j=                  dj                   j                  j                               y# 1 sw Y   xY w)z Push new, unsaved attachments to the cloud and remove removed
        attachments. This method should not be called for non draft messages.
        NFr   r   r   rI   rL   create_upload_session)r3   r4   	uploadUrlzResumable upload on url: {}expirationDateTimez*Expiration Date for this upload url is: {}z=Create upload session response without upload_url for file {}c                    d}	  |        }|s	 yt        |      }dt        t        |            dj                  |||z   dz
        d}||z  }j                  j                  j                  d||      }|sy	|j                  d
k(  r	 y|j                         }t        j                  dj                  |j                  d                   )Nr   Tzapplication/octet-streamzbytes {}-{}/{}r   )zContent-typezContent-LengthzContent-RangePUT)r>   headersF   zSuccessfully put {} bytesnextExpectedRanges)r   r^   rt   r   r   naive_requeststatus_coder   rz   r{   rV   )	read_byte_chunkcurrent_bytesr>   transfer_bytesr   r   	file_sizer   
upload_urls	         r   write_streamzBBaseAttachments._update_attachments_to_cloud.<locals>.write_stream  s    ()"#2#4D#' %8  $7 .1YN0J25c$i.244:F=;H;I<JLM<N;D5F	'G *^;M (,||'7'7'E'EjRWCGFM (F (OH $,','33s: %
  $ (0}} #		*E*L*L$(HH-A$B+D !E; #r   rS   )modec                  &    j                         S r   ri   )
chunk_sizerG   s   r   <lambda>z>BaseAttachments._update_attachments_to_cloud.<locals>.<lambda>6  s    dii
6K r   )r   c                  &     j                        S r   r   )bufferr   s   r   r   z>BaseAttachments._update_attachments_to_cloud.<locals>.<lambda>:  s    6;;z3J r   Tr4   )rI   idaz&Successfully updated attachments on {})DEFAULT_UPLOAD_CHUNK_SIZEr   rH   r8   UPLOAD_SIZE_LIMIT_SIMPLEr   r   rV   rt   r   r   r   r   r#   r   rR   r;   rP   r,   rz   infor   r   r4   rh   r   rc   r~   r   deleter{   )r   r   r4   r   r   r>   request	file_dataexpiration_dater   read_from_fileupload_completedr   r   rG   r   r   s   ``           @@@@r   _update_attachments_to_cloudz,BaseAttachments._update_attachments_to_cloud  sp   
 $.#9Z?X
,, X	+J""e+&OO	 88..)<)<])K)R)R<<11 *S *3 4C  $||//44Sz?U?U?W4XH#$#==?D 04xx~J,)-$((>2JD)QJ& ..++,CDKK#||55 L 78C 3$:VG ' 3 3 5I#||//44Sy4IH#$#==?D!%$((;*?!FJHH:AA*MN&*hhtxx8L/Mt&TO&!M!T!T+"- .!)		 #;;A6*//;RT$!$F ",,'2277T7B \d-KN/;N/[,\ \ "))9)9*:L:L)M!N*J+7+X(+$&*
#qX	+t 44 	!J""z'?'?'KnnT__%8%8%F%M%M||--:3K3K &N &M N  <<++2237 	! &("		:AALL""$ 	% 9\ \s   -O88P	r   )r%   r&   r'   r   r   rB   r   r   r   r   r   ro   r   r   r   r#   r   r   r   r   r   r   r   r?   r@   s   @r   r   r   )  sq    + 48J -$('N'C-.;"><$Lpr   r   )rc   loggingior   pathlibr   utilsr   	getLoggerr%   rz   r   r   r   r,   rB   r   r*   r   r   <module>r      sf        g!* + 2$ 2$j< &P2\ P2fhl hr   