
    DjE                     @   U d 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 ddlm	Z	m
Z
mZmZ ddlmZ ddlmZmZmZ ddlmZ dd	lmZ d
Zeed<    ej        e          Zej        ed<   dZeed<   	 dde de
dej!        de"ddf
dZ# G d de          Z$ G d d          Z%dS )zFind my iPhone service.    N)datetime	timedelta)MappingProxyType)AnyCallableIteratorOptional)Response)PyiCloudAuthRequiredExceptionPyiCloudNoDevicesExceptionPyiCloudServiceUnavailable)BaseService)PyiCloudSessionz
US/Pacific_FMIP_CLIENT_CONTEXT_TIMEZONE_LOGGER   _MAX_REFRESH_RETRIESFintervalfunc
stop_eventlocatereturnc                    t          j                    t          |           z   }|                    |           s|t          j                    k     rc	  ||           n2# t          $ r%}t
                              d|           Y d}~nd}~ww xY wt          j                    t          |           z   }|                    |           dS dS )z:Thread function to monitor the FindMyiPhoneServiceManager.)seconds)timeoutz%FindMyiPhone monitor thread error: %sN)r   nowr   wait	Exceptionr   debug)r   r   r   r   
next_eventexcs         Y/home/thesage/.hermes/venv/lib/python3.11/site-packages/pyicloud/services/findmyiphone.py_monitor_threadr#      s     $<>>Ih,G,G,GGJooho// F&&LV L L LEsKKKKKKKKL!)H*E*E*EEJ ooho// F F F F Fs   A 
B)B		Bc                   f    e Zd ZdZ	 	 ddedededeeef         dedz  d	df fd
Z	dde
de
d	dfdZde
d	dfdZd dZde
d	dfdZd!de
d	dfdZdeez  d	dfdZd	efdZd	efdZd	ed         fdZd	efdZed	e
fd            Zed"d            Zed	eeeef                  fd            Z xZS )#FindMyiPhoneServiceManagerzThe 'Find my iPhone' iCloud service

    This connects to iCloud and return phone data including the near-realtime
    latitude and longitude.
    FNservice_roottoken_endpointsessionparamsrefresh_intervalr   c                    t                                          |||           || _        ||nd| _        | d}| d| _        | d| _        | d| _        | d| _        | d| _        | d	| _	        | d
| _
        i | _        g | _        d| _        d| _        d| _        t!          j                    | _        |                     d           dS )z*Initialize the FindMyiPhoneServiceManager.Ng     r@z/fmipservice/client/webz/initClientz/refreshClientz
/playSoundz/sendMessagez/lostDevicez/remoteWipeWithUserAuthz/fmipWebAuthenticateTr   )super__init___with_family_refresh_interval_fmip_init_url_fmip_refresh_url_fmip_sound_url_fmip_message_url_fmip_lost_url_fmip_erase_url_erase_token_url_devices_devices_names_server_ctx
_user_info_monitor	threadingEventr   _refresh_client_with_reauth)	selfr&   r'   r(   r)   with_familyr*   fmip_endpoint	__class__s	           r"   r.   z#FindMyiPhoneServiceManager.__init__.   s    	w777"- 0 <* 	 !-EEE&3#@#@#@)6&F&F&F'4$@$@$@)6&D&D&D&3#@#@#@'4$M$M$M(6%L%L%L02)+261548+4?+<+<(((55555    r   retryc                    | j                                          	 |                     |           nn# t          $ ra |du r t                              d           d| _        | j        j        	                    d           | 
                    |d           Y dS w xY w|                     |           |                                  dS )z
        Refreshes the FindMyiPhoneService endpoint with re-authentication.
        This ensures that the location data is up-to-date.
        r,   TzRe-authenticating sessionN)force_refresh)r   rE   )r   set_refresh_clientr   r   r   r:   r(   serviceauthenticater?   _initialize_devices_start_monitor_thread)r@   r   rE   s      r"   r?   z6FindMyiPhoneServiceManager._refresh_client_with_reauthP   s     	
	   ////, 	 	 	}}MM5666#DL --D-AAA,,F$,GGGFF	 	   ///""$$$$$s   2 A'BBc                    d}t                      }| j        r| j        r| j                            dd          r|t          k     rd | j                            di                                           D             }|sn||k    rt                              d|           ne|}t          j	        d           | 
                    |           |d	z  }| j        r-| j        r&| j                            dd          r|t          k     | j        st                      t                              d
t          | j                             dS )z;Initializes the devices for the FindMyiPhoneServiceManager.r   
hasMembersFc                 J    h | ] \  }}|                     d           dk    |!S )deviceFetchStatusLOADING)get).0kvs      r"   	<setcomp>zAFindMyiPhoneServiceManager._initialize_devices.<locals>.<setcomp>x   s>       Aq55,--:: :::rD   membersInfoz>No progress on LOADING family members after retry %d, stoppingg?r,      zNumber of devices found: %dN)rH   r/   r;   rS   r   itemsr   r   timesleeprI   r8   r   infolen)r@   r   retriesprev_loading_keysloading_keyss        r"   rL   z.FindMyiPhoneServiceManager._initialize_devicesg   sy    &)ee		 ##L%88	 ...  O//rBBHHJJ  L
   000T    ,JsOOO   ///qLG+ 		 ##L%88	 ...( } 	/,...2C4F4FGGGGGrD   c                     | j         sht          j        t          | j        | j        | j        dd          | _        | j                                         | j        	                                 dS dS )z=Starts the monitor thread for the FindMyiPhoneServiceManager.)r   r   r   T)targetkwargsdaemonN)
is_aliver=   Threadr#   rI   r0   r   r<   clearstartr@   s    r"   rM   z0FindMyiPhoneServiceManager._start_monitor_thread   s    } 	"%,& 0 $ 6"&/ 
   DM O!!###M!!!!!	" 	"rD   c                    ddddd| j         t          ddi}| j        r/| j        |d<   |r#d	|d
<   |d                             d	dd           | j                            | j        r| j        n| j        | j        |          }|	                                }|
                    d          | _        | j        rd| j        v r
d| j        d<   |
                    d          | _        d|vrt                              d           dS t                              dt          |d                              |d         D ]q}|d         }|| j        vr>t!          || j        | | j        | j        | j        | j        | j                  | j        |<   Q| j        |                             |           rt-          | j                                                  | _        dS )zx
        Refreshes the FindMyiPhoneService endpoint, this ensures that the location data
        is up-to-date.
        clientContextziCloud Find (Web)z2.0z3.0rY   r   )appName
appVersion
apiVersiondeviceListVersionfmlytimezoneinactiveTimeserverContextTisUpdatingAllLocationsall)shouldLocateselectedDevice)urlr)   json	theftLossNuserInfocontentzFMIP returned 0 deviceszFMIP returned %d devicesid)manager	sound_urllost_urlmessage_url	erase_urlerase_token_url)r/   r   r:   updater(   postr2   r1   r)   rz   rS   r;   r   r   r^   r8   AppleDevicer3   r5   r4   r6   r7   listkeysr9   )r@   r   req_jsonreqrespdevice_info	device_ids          r"   rI   z*FindMyiPhoneServiceManager._refresh_client   s    .##%&)9 ! 
$
  		(,(8H_% 5912)00(,*/    ))*.*:S&&@S; * 
 

  #xxzz88O44 	1t/? ? ?,0D[)((:..D  MM3444F0#d9o2F2FGGG	? 	= 	=K(.I--+6K "2!0 $ 6"2$($9	, 	, 	,i(( i(//<<<<"4=#5#5#7#788rD   Tc                 2    |                      |           dS )z:Public method to refresh the FindMyiPhoneService endpoint.r,   N)r?   )r@   r   s     r"   refreshz"FindMyiPhoneServiceManager.refresh   s    (((77777rD   keyr   c                     | j         s|                     d           t          |t                    r| j        |         }| j        |         S )zGets a device by name or index.Tr,   )rf   r?   
isinstanceintr9   r8   r@   r   s     r"   __getitem__z&FindMyiPhoneServiceManager.__getitem__   sO    } 	:,,D,999c3 	+%c*C}S!!rD   c                     | j          S )z%String representation of the devices.)r8   rj   s    r"   __str__z"FindMyiPhoneServiceManager.__str__   s    -!!rD   c                     |  S )Representation of the device. rj   s    r"   __repr__z#FindMyiPhoneServiceManager.__repr__   s
    yrD   c                     | j         s|                     d           t          | j                                                  S )zIterates over the devices.Tr,   )rf   r?   iterr8   valuesrj   s    r"   __iter__z#FindMyiPhoneServiceManager.__iter__   sA     } 	:,,D,999DM((**+++rD   c                 d    | j         s|                     d           t          | j                  S )zReturns the number of devices.Tr,   )rf   r?   r^   r8   rj   s    r"   __len__z"FindMyiPhoneServiceManager.__len__   s3    } 	:,,D,9994=!!!rD   c                 F    | j         duo| j                                         S )z"Indicates if the service is alive.N)r<   rf   rj   s    r"   rf   z#FindMyiPhoneServiceManager.is_alive   s$     }D(ET]-C-C-E-EErD   "MappingProxyType[str, AppleDevice]c                 *    t          | j                  S )zReturns the devices.)r   r8   rj   s    r"   devicesz"FindMyiPhoneServiceManager.devices  s      ...rD   c                 <    | j         rt          | j                   ndS )zReturns the user info.N)r;   r   rj   s    r"   	user_infoz$FindMyiPhoneServiceManager.user_info
  s!     59OM000MrD   )FNFr   N)T)r   r   )__name__
__module____qualname____doc__strr   dictr   floatr.   boolr?   rL   rM   rI   r   r   r   r   r   r   r   r   propertyrf   r   r	   r   r   __classcell__)rC   s   @r"   r%   r%   '   ss         )- 6  6 6  6 !	 6
 S#X 6  $, 6 
 6  6  6  6  6  6D% %$ %t %PT % % % %.&H$ &H4 &H &H &H &HP" " " ">9d >9t >9 >9 >9 >9@8 8d 8d 8 8 8 8"sSy "] " " " "" " " " "#    ,(=1 , , , ," " " " " F$ F F F XF / / / X/ N8$4S#X$>? N N N XN N N N NrD   r%   c                      e Zd ZdZdeeef         deeef         dededededed	ed
dfdZe	d
e
fd            Zd-dZe	d
eeeef                  fd            Zd.deee                  d
eeef         fdZd/d-dZ	 	 	 	 	 d0	 d-dZ	 	 d1dededed
dfdZd
efdZ	 	 d1deded
dfdZe	d
eeef         fd            Zd
efd Zd
efd!Ze	d
efd"            Ze	d
efd#            Ze	d
efd$            Ze	d
efd%            Ze	d
efd&            Ze	d
efd'            Ze	d
efd(            Z e	d
efd)            Z!e	d
efd*            Z"d
efd+Z#d
efd,Z$dS )2r   zApple device.r}   r)   r   r   r   r   r   r   r   Nc	                 v    || _         || _        || _        || _        || _        || _        || _        || _        dS )zInitialize the Apple device.N)_content_manager_params
_sound_url	_lost_url
_erase_urlr7   _message_url)	r@   r}   r)   r   r   r   r   r   r   s	            r"   r.   zAppleDevice.__init__  sD     )04;'-(&(%4!,rD   c                     | j         j        S )zGets the session.)r   r(   rj   s    r"   r(   zAppleDevice.session)  s     }$$rD   c                     || _         dS )zUpdates the device data.N)r   r@   datas     r"   r   zAppleDevice.update.  s    rD   c                 2    | j         du rdS | j        d         S )zUpdates the device location.FNlocation)location_availabler   rj   s    r"   r   zAppleDevice.location2  s$     "e++4}Z((rD   
additionalc                 d    g d}|||z  }i }|D ]}| j                             |          ||<    |S )zkReturns status information for device.

        This returns only a subset of possible properties.
        )batteryLeveldeviceDisplayNamedeviceStatusname)r   rS   )r@   r   fields
propertiesfields        r"   statuszAppleDevice.status9  s\    

 
 
 !j F%'
 	9 	9E $ 1 1% 8 8JurD   Find My iPhone Alertc                     | j         du rt          d          | j        d         |ddid}| j                            | j        | j        |           dS )	zSend a request to the device to play a sound.

        It's possible to pass a custom message by changing the `subject`.
        Fz&Sound is not available for this devicer~   rq   T)devicesubjectrl   r)   rz   N)sound_availabler   r   r(   r   r   r   )r@   r   r   s      r"   
play_soundzAppleDevice.play_soundL  sj    
 5((,-UVVVmD)$d^ 
  
 	$/$,TJJJJJrD   This is a noteFc                     | j         du rt          d          | j        d         |d||||d}| j                            | j        | j        |           dS )zSend a request to the device to a display a message.

        It's possible to pass a custom message by changing the `subject`.
        Fz*Messaging is not available for this devicer~   T)r   r   userTexttextsoundvibratestrober   N)messaging_availabler   r   r(   r   r   r   )r@   r   messagesoundsr   r   r   s          r"   display_messagezAppleDevice.display_message[  s{     #u,,,<  
 mD) 
  
 	$+DLtLLLLLrD   *This device has been lost. Please call me. numberr   newpasscodec                     | j         du rt          d          |d|dd| j        d         |d}| j                            | j        | j        |           dS )zSend a request to the device to trigger 'lost mode'.

        The device will show the message in `text`, and if a number has
        been passed, then the person holding the device can call
        the number without entering the passcode.
        Fz*Lost mode is not available for this deviceTr~   )r   r   ownerNbrlostModeEnabledtrackingEnabledr   passcoder   N)lost_mode_availabler   r   r(   r   r   r   )r@   r   r   r   r   s        r"   lost_devicezAppleDevice.lost_devicex  sz     #u,,,<  
 ##mD)# 
  
 	$.DIIIIIrD   c                     d| j         j                            d          i}| j                             | j        |                                          }d|vs
d|d         vrt          d          |d         d         S )z3Get the erase token for the Find My iPhone service.dsWebAuthTokensession_token)ry   rz   tokensmmeFMIPWebEraseDeviceTokenz(Find My iPhone erase token not available)r(   r   rS   r   r7   rz   r   r   s     r"   _get_erase_tokenzAppleDevice._get_erase_token  s     dl/33ODD 
 |  T%: FFKKMM4#?tH~#U#U,-WXXXH~:;;rD   c                     | j         du rt          d          |                                 || j        d         |d}| j                            | j        | j        |           dS )z5Send a request to the device to start a remote erase.Fz&Erase is not available for this devicer~   )	authTokenr   r   r   r   N)erase_availabler   r   r   r(   r   r   r   )r@   r   r   r   s       r"   erase_devicezAppleDevice.erase_device  sw     5((,-UVVV ..00mD)#	 
  
 	$/$,TJJJJJrD   c                 Z    | j         j        s| j                                          | j        S )zGets the device data.r   rf   r   r   rj   s    r"   r   zAppleDevice.data  s-     }% 	$M!!###}rD   c                 f    | j         j        s| j                                          | j        |         S )%Gets an attribute of the device data.r   r   s     r"   r   zAppleDevice.__getitem__  s0    }% 	$M!!###}S!!rD   c                     | j         j        s| j                                          || j        v r| j        |         S t	          dt          |           j         d| d          )r   'z' object has no attribute ')r   rf   r   r   AttributeErrortyper   )r@   attrs     r"   __getattr__zAppleDevice.__getattr__  sn    }% 	$M!!###4=  =&&GT

#GGGGG
 
 	
rD   c                 8    | j                             dd          S )zGets the device name.r   r   r   rS   rj   s    r"   r   zAppleDevice.name  s     y}}VR(((rD   c                 8    | j                             dd          S )zGets the device model.deviceModelr   r  rj   s    r"   modelzAppleDevice.model       y}}]B///rD   c                 8    | j                             dd          S )zGets the device model name.r   r   r  rj   s    r"   
model_namezAppleDevice.model_name  s     y}}0"555rD   c                 8    | j                             dd          S )zGets the device type.deviceClassr   r  rj   s    r"   device_typezAppleDevice.device_type  r  rD   c                 8    | j                             dd          S )z3Indicates if lost mode is available for the device.lostModeCapableFr  rj   s    r"   r   zAppleDevice.lost_mode_available  s     y}}.666rD   c                 `    | j                             di                               dd          S )z3Indicates if messaging is available for the device.featuresMSGFr  rj   s    r"   r   zAppleDevice.messaging_available  *     y}}Z,,00>>>rD   c                 `    | j                             di                               dd          S )z/Indicates if sound is available for the device.r  SNDFr  rj   s    r"   r   zAppleDevice.sound_available  r  rD   c                 `    | j                             di                               dd          S )z/Indicates if erase is available for the device.r  WIPFr  rj   s    r"   r   zAppleDevice.erase_available  r  rD   c                     | j                             di                               dd          od| j        v o| j        d         duS )z2Indicates if location is available for the device.r  LOCFr   N)r   rS   r   rj   s    r"   r   zAppleDevice.location_available  sO     IMM*b))--eU;; 6dm+6j)5	
rD   c                 $    | j          d| j         S )z$String representation of the device.z: )r  r   rj   s    r"   r   zAppleDevice.__str__  s    /00TY000rD   c                     d|  dS )r   z<AppleDevice(z)>r   rj   s    r"   r   zAppleDevice.__repr__  s    't''''rD   r   )N)r   )r   r   FFF)r   r   )%r   r   r   r   r   r   r   r%   r.   r   r   r(   r   r	   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r
  r   r   r   r   r   r   r   r   r   rD   r"   r   r     s<       -c3h- S#X- ,	-
 - - - - - 
- - - -, % % % % X%    )(4S>2 ) ) ) X) $s)!4 S#X    &K K K K K" ' M 
M M M M@ A	J JJ J 	J
 
J J J J:	<# 	< 	< 	< 	< AK KK K 
	K K K K$ d38n    X"# " " " "	
3 	
 	
 	
 	
 )c ) ) ) X) 0s 0 0 0 X0 6C 6 6 6 X6 0S 0 0 0 X0 7T 7 7 7 X7 ?T ? ? ? X? ? ? ? ? X? ? ? ? ? X? 
D 
 
 
 X
1 1 1 1 1(# ( ( ( ( ( (rD   r   r   )&r   loggingr=   r[   r   r   typesr   typingr   r   r   r	   requestsr
   pyicloud.exceptionsr   r   r   pyicloud.services.baser   pyicloud.sessionr   r   r   __annotations__	getLoggerr   r   Loggerr   r   r   r>   r   r#   r%   r   r   rD   r"   <module>r#     s            ( ( ( ( ( ( ( ( " " " " " " 4 4 4 4 4 4 4 4 4 4 4 4               
 / . . . . . , , , , , ,%1 s 1 1 1+'+H55 5 5 5 c    RWF FF#F1:FJNF	F F F FfN fN fN fN fN fN fN fNRs( s( s( s( s( s( s( s( s( s(rD   