
    ;i*                         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Zddlm	Z	 ddl
Z
ddlZddlmZmZmZ ddlmZmZ  ej&                  e      Z G d d      Z G d	 d
      Z G d de	      Zy)a  
OpenDrop: an open source AirDrop implementation
Copyright (C) 2018  Milan Stute
Copyright (C) 2018  Alexander Heinrich

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.
    N)HTTPSConnection)	IPVersionServiceBrowserZeroconf   )AbsArchiveWriteAirDropUtilc                   ,    e Zd Zd ZddZd Zd Zd Zy)AirDropBrowserc                    t        j                  |j                  d      | _        | j                  A|j                  dk(  rt	        d|j                   d      t	        d|j                   d      t        t        | j                        gt        j                  t        j                         dk(        | _        d | _        d | _        d | _        y )	NT)ipv6awdl0z
Interface z@ does not have an IPv6 address. Make sure that `owl` is running.z does not have an IPv6 addressDarwin)
interfaces
ip_version	apple_p2p)r	   get_ip_for_interface	interfaceip_addrRuntimeErrorr   strr   V6Onlyplatformsystemzeroconfcallback_addcallback_removebrowser)selfconfigs     B/home/ubuntu/myenv/lib/python3.12/site-packages/opendrop/client.py__init__zAirDropBrowser.__init__'   s    "778H8HtT<<7*" !1!1 22rs  # !1!1 22PQ  !DLL)* ''oo'83
 !#    Nc                 r    | j                   y|| _        || _        t        | j                  d|       | _         y)zL
        Start the AirDropBrowser to discover other AirDrop devices
        Nz_airdrop._tcp.local.)r   r   r   r   r   )r   r   r   s      r!   startzAirDropBrowser.start=   s6     <<#(.%dmm5KTRr#   c                 z    | j                   j                          d | _         | j                  j                          y N)r   cancelr   close)r   s    r!   stopzAirDropBrowser.stopG   s)    r#   c                     |j                  ||      }t        j                  d|        | j                  | j                  |       y y )NzAdd service )get_service_infologgerdebugr   r   r   service_typenameinfos        r!   add_servicezAirDropBrowser.add_serviceL   sF    ((t<|D6*+(d# )r#   c                     |j                  ||      }t        j                  d|        | j                  | j                  |       y y )NzRemove service )r,   r-   r.   r   r/   s        r!   remove_servicezAirDropBrowser.remove_serviceR   sF    ((t<tf-.+  & ,r#   )NN)__name__
__module____qualname__r"   r%   r*   r3   r5    r#   r!   r   r   &   s    ,S
$'r#   r   c                   6    e Zd Zd ZddZd Zd	dZd
dZd Zy)AirDropClientc                 H    || _         |d   | _        |d   | _        d | _        y )Nr   r   )r    receiver_hostreceiver_port	http_conn)r   r    receivers      r!   r"   zAirDropClient.__init__Z   s(    %a[%a[r#   Nc                    t         j                  d| d       t        j                  | j                  |d|j                         j                  d       d       | j                         }||j                         D ]
  \  }}|||<    | j                  Tt        | j                  | j                  | j                  j                  | j                  j                               | _	        | j                  j                  d|||       | j                  j!                         }|j#                         }t        j                  | j                  |d|j                         j                  d       d	       |j$                  d
k7  r*d}	t         j                  | d|j$                          |	|fS d}	t         j                  | d       |	|fS )NzSend z requestsend_/z_request.plist)interface_namecontextPOST)bodyheadersz_response.plist   Fz request failed: Tz request successful)r-   r.   r	   write_debugr    lowerstrip_get_headersitemsr?   HTTPSConnectionAWDLr=   r>   r   get_ssl_contextrequestgetresponsereadstatus)
r   urlrG   rH   _headerskeyval	http_respresponse_bytesrT   s
             r!   	send_POSTzAirDropClient.send_POST`   s   uSE*+KKsyy{'8'8'=&>nM	
 $$&#MMO $S #$>>!0""""#{{44335	DN 	vsxHNN..0	")KKCIIK%%c*+?;	
 s"FLLC5 1)2B2B1CDE ~%% FLLC5 345~%%r#   c                 $   i }| j                   j                  r| j                   j                  |d<   t        j                  |t        j                        }| j                  d|      \  }}t        j                  |      }|j                  d      S )NSenderRecordDatafmtz	/DiscoverReceiverComputerName)r    record_dataplistlibdumps
FMT_BINARYr[   loadsget)r   discover_bodydiscover_plist_binary_rZ   responses         r!   send_discoverzAirDropClient.send_discover   s{    ;;""040G0GM,- (x22!
 !NN;8MN>>>.1 ||233r#   c                    | j                   j                  d| j                   j                  | j                   j                  dd}| j                   j                  r| j                   j                  |d<   fd}t        |t              r|g}|r||d<   nt        |d   d      5 }|j                  d	      }t        j                  |      |sHt        j                        dkD  r0d
j                  d   v rt        j                  |j                        }d d d         ||      D cg c]  }| c}|d<   |r||d<   t!        j"                  |t         j$                        }	| j'                  d|	      \  }
}|
S # 1 sw Y   exY wc c}w )Nzcom.apple.finderF)SenderComputerNameBundleIDSenderModelNameSenderIDConvertMediaFormatsr]   c              3     K   | D ]{  }t         j                  j                  |      }|t        j                        t         j                  j                  d|      t         j                  j                  |      dd}| } y w)N.r   )FileNameFileTypeFileBomPathFileIsDirectoryrq   )ospathbasenamer	   get_uti_typejoinisdir)filesfile	file_name
file_entryflps       r!   file_entriesz,AirDropClient.send_ask.<locals>.file_entries   so      	!GG,,T2	 ) + 8 8 =#%77<<Y#?')ww}}Y'?+,
 ! 	!s   BBItemsr   rb   imageFilesFileIconr^   z/Ask)r    computer_namecomputer_model
service_idra   
isinstancer   openrS   fleeprf   lenmimer	   generate_file_iconr1   rb   rc   rd   r[   )r   	file_pathis_urliconask_bodyr   ffile_headere
ask_binarysuccessri   r   s               @r!   send_askzAirDropClient.send_ask   s]   "&++";";*#{{99..#(
 ;;""+/;;+B+BH'(
	! i%"I )HW ilD) BQffSkii,CHH 1g!6L&99!&&AD	B
 -9,C Dq DHW#'HZ ^^(--

 ^^FJ7
B B
 !Es   $A1E9'	F9Fc           	         |ryddi}t        j                         }t        j                  |j                  ddt
              5 }|fD ]Q  }t        j                  j                  |      }|j                  |t        j                  j                  d|             S 	 ddd       |j                  d       | j                  d	||
      \  }}	|S # 1 sw Y   3xY w)z,
        Send a file to a receiver.
        NContent-Typezapplication/x-cpiocpiogzip)filter_namearchive_write_classrs   r   z/Upload)rH   )ioBytesIO
libarchivecustom_writerwriter   rx   ry   rz   add_abs_filer|   seekr[   )
r   r   r   rH   streamarchiver   ffr   ri   s
             r!   send_uploadzAirDropClient.send_upload   s    
  0

 %%LL /	
 	?
 [ ?WW%%a($$QS"(=>?	? 	A ^^Ivw^G
 !	? 	?s   ACCc                     ddddddd}|S )z3
        Get the headers for requests sent
        zapplication/octet-streamz
keep-alivez*/*zAirDrop/1.0zen-uszbr, gzip, deflate)r   
ConnectionAcceptz
User-AgentzAccept-LanguagezAccept-Encodingr9   )r   rH   s     r!   rM   zAirDropClient._get_headers   s$    
 7&'&2
 r#   r'   )FN)F)	r6   r7   r8   r"   r[   rk   r   r   rM   r9   r#   r!   r;   r;   Y   s#    #&J4+Z@r#   r;   c                   b     e Zd ZdZ	 	 	 	 	 ddddd fdZ ej                         dfdZ xZS )rO   zV
    This class allows to bind the HTTPConnection to a specific network interface
    N)rE   check_hostnamerD   c          
         |	9d|vr5t        t        j                  |      t        j                        r|dz   |	z   }|t	        j
                         }t        t        | #  ||||||||       |	| _	        | j                  | _        y )N%)hostportkey_file	cert_filetimeoutsource_addressrE   r   )r   	ipaddress
ip_addressIPv6AddresssocketgetdefaulttimeoutsuperrO   r"   rD   create_connection_awdl_create_connection)r   r   r   r   r   r   r   rE   r   rD   	__class__s             r!   r"   zHTTPSConnectionAWDL.__init__   s     %$i2248):O:OP#:6D?..0G!41)) 	2 		
 -"&"="=r#   c                 p   |\  }}d}t        j                  ||dt         j                        D ]  }|\  }}	}
}}d}	 t        j                   ||	|
      }|t        j                         ur|j	                  |       | j
                  dk(  r8t        j                         dk(  r!|j                  t         j                  dd       |r|j                  |       |j                  |       |c S  ||t        j                  d      # t         j                  $ r}|}||j                          Y d}~d}~ww xY w)a  Connect to *address* and return the socket object.

        Convenience function.  Connect to *address* (a 2-tuple ``(host,
        port)``) and return the socket object.  Passing the optional
        *timeout* parameter will set the timeout on the socket instance
        before attempting to connect.  If no *timeout* is supplied, the
        global default timeout setting returned by :func:`getdefaulttimeout`
        is used.  If *source_address* is set it must be a tuple of (host, port)
        for the socket to bind as a source address before making the connection.
        A host of '' or port 0 tells the OS to use the default.
        Nr   r   r   i  r   z!getaddrinfo returns an empty list)r   getaddrinfoSOCK_STREAMr   
settimeoutrD   r   r   
setsockopt
SOL_SOCKETbindconnecterrorr)   )r   addressr   r   r   r   errresafsocktypeprotori   sasocks                 r!   r   z*HTTPSConnectionAWDL.create_connection_awdl  s    
d%%dD!V5G5GH 	!C),&B%BD!}}R59&":":"<<OOG,&&'1hoo6G86SOOF$5$5vqA!IIn-R 	!( ?I,,BCC << !#JJL!s   B*DD5D00D5)NNNNN)	r6   r7   r8   __doc__r"   r   r   r   __classcell__)r   s   @r!   rO   rO      sG     "> ">J  8v779$(Dr#   rO   )r   r   r   loggingrx   r   rb   r   http.clientr   r   r   r   r   r   r   utilr   r	   	getLoggerr6   r-   r   r;   rO   r9   r#   r!   <module>r      sm   & 
   	    '   8 8 .			8	$0' 0'fS SlQD/ QDr#   