
    Djzi                       d Z ddlmZ ddlZddlmZ ddlmZ ddlmZm	Z	 ddl
mZ ddlmZmZ dd	lmZmZ ddlZdd
lmZ ddlmZ ddlmZmZ ddlmZ ddlmZmZmZm Z m!Z!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,m-Z- dZ. G d de/          Z0 G d de1e          Z2 ed           G d d                      Z3 G d d          Z4d>d!Z5dd"d?d'Z6d@d*Z7d+d,dAd2Z8d+d3dBd6Z9dCd:Z:dDd=Z;dS )Ez<Shared context and authentication helpers for the Typer CLI.    )annotationsN)	ExitStack)	dataclass)datetimetimezone)Enum)PathPurePosixPath)AnyOptional)confirm)Console)PyiCloudServiceutils)resolve_cookie_directory)PyiCloudAPIResponseExceptionPyiCloudAuthRequiredExceptionPyiCloudFailedLoginException PyiCloudNoTrustedNumberAvailablePyiCloudServiceUnavailable$PyiCloudTrustedDevicePromptException*PyiCloudTrustedDeviceVerificationException)configurable_ssl_verification   )AccountIndexEntryload_accountsprune_accountsremember_account)OutputFormat
write_jsoncommand_optionsc                      e Zd ZdZdS )CLIAbortz+Abort execution with a user-facing message.N)__name__
__module____qualname____doc__     O/home/thesage/.hermes/venv/lib/python3.11/site-packages/pyicloud/cli/context.pyr#   r#   )   s        5555r)   r#   c                  *    e Zd ZdZdZdZdZdZd
dZd	S )LogLevelzSupported log levels.errorwarninginfodebugreturnintc                    | t           j        u rt          j        S | t           j        u rt          j        S | t           j        u rt          j        S t          j        S )z Return the stdlib logging level.)r,   ERRORloggingINFODEBUGWARNINGselfs    r*   logging_levelzLogLevel.logging_level5   sK     8>!!= 8=  <8>!!= r)   N)r1   r2   )	r$   r%   r&   r'   r4   r8   r6   r7   r;   r(   r)   r*   r,   r,   -   sB        EGDE	 	 	 	 	 	r)   r,   T)frozenc                      e Zd ZU dZdZded<   dZded<   dZded<   dZd	ed
<   dZ	d	ed<   dZ
d	ed<   dZded<   dZded<   dZded<   dZd	ed<   ej        Zded<   ej        Zded<   dS )CLICommandOptionsz5Command-local options captured from the leaf command.NOptional[str]usernamepasswordOptional[bool]china_mainlandTboolinteractiveFaccept_termswith_familysession_dir
http_proxyhttps_proxyno_verify_sslr,   	log_levelr   output_format)r$   r%   r&   r'   r@   __annotations__rA   rC   rE   rF   rG   rH   rI   rJ   rK   r,   r8   rL   r   TEXTrM   r(   r)   r*   r>   r>   A   s         ??"H"""""H""""%)N))))KLK!%K%%%% $J$$$$!%K%%%%M"*I****"."3M333333r)   r>   c                     e Zd ZdZdOdZedPd            ZedQd            ZedQd            Z	dRdZ
dRdZdSd ZdTd"ZdUdVd$ZedWd&            ZdXd(ZdXd)ZdYd+ZdZd,Zd-d.d[d2Zd\d3Zd\d4Zd]d5Zed^d8            Zd_d:ZdRd;Zd`d<Zdad@ZdbdAZdbdBZdcdCZ dcdDZ!dddEZ"dddFZ#ededI            Z$dcdJZ%	 dUdfdLZ&dgdNZ'd#S )hCLIStatez.Shared CLI state and authenticated API access.r@   r?   rA   rC   rB   rE   rD   rF   rG   rH   rI   rJ   rK   rL   r,   rM   r   r1   Nonec                  |pd                                 | _        || _        || _        || _        || _        || _        || _        || _        |	| _	        |
| _
        || _        || _        t                      | _        t          d          | _        t!                      | _        d| _        d| _        | j        pd| _        d| _        dS )zDCapture the CLI options and shared runtime state for one invocation. T)stderrNF)stripr@   rA   rC   rE   rF   rG   rH   rI   rJ   rK   rL   rM   r   consoleerr_consoler   _stack_api
_probe_api_resolved_username_logging_configured)r:   r@   rA   rC   rE   rF   rG   rH   rI   rJ   rK   rL   rM   s                r*   __init__zCLIState.__init__V   s    " "R..00 ,&(&&$&*"*yy"$///kk/3	59151F$#(   r)   optionsr>   
'CLIState'c                     | |j         |j        |j        |j        |j        |j        |j        |j        |j        |j	        |j
        |j                  S )z0Build CLI state from one leaf command's options.r@   rA   rC   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rb   )clsr_   s     r*   from_optionszCLIState.from_options{   se     s%%"1+ -++)+!/'!/
 
 
 	
r)   c                *    t          | j                  S )z5Return whether the user explicitly passed --username.)rD   r@   r9   s    r*   has_explicit_usernamezCLIState.has_explicit_username   s     DM"""r)   c                (    | j         t          j        u S )z0Return whether the current command expects JSON.)rM   r   JSONr9   s    r*   json_outputzCLIState.json_output   s     !\%666r)   c                    | j                             t          | j         | j        pd| j        pd                     dS )zOpen CLI-scoped resources.rT   )
verify_sslrI   rJ   N)rY   enter_contextr   rK   rI   rJ   r9   s    r*   openzCLIState.open   sX     	!!)#11?0b ,2  	
 	
 	
 	
 	
r)   c                8    | j                                          dS )zClose CLI-scoped resources.N)rY   closer9   s    r*   ro   zCLIState.close   s     	r)   payloadr   c                0    t          | j        |           dS )zWrite a JSON payload to stdout.N)r    rW   )r:   rp   s     r*   r    zCLIState.write_json   s     	4<)))))r)   strc                    t          j        |          r*t          j        |           |                                  dS |                                  dS )z0Delete a stored keyring password for a username.TF)r   password_exists_in_keyringdelete_password_in_keyringprune_local_accountsr:   r@   s     r*   delete_keyring_passwordz CLIState.delete_keyring_password   sV     +H55 	,X666%%'''4!!###ur)   Nc                v    |p| j         p| j                                        }|sdS t          j        |          S )z8Return whether a keyring password exists for a username.F)r\   r@   rV   r   rt   )r:   r@   	candidates      r*   has_keyring_passwordzCLIState.has_keyring_password   sB     I!8IDMPPRR	 	5/	:::r)   r	   c                D    t          t          | j                            S )z9Return the resolved session root for this CLI invocation.)r	   r   rH   r9   s    r*   session_rootzCLIState.session_root   s     ,T-=>>???r)   list[AccountIndexEntry]c                6    t          | j        | j                  S )z?Return discoverable local accounts after opportunistic pruning.)r   r}   r{   r9   s    r*   local_accountszCLIState.local_accounts   s     d/1JKKKr)   c                *    |                                  S )z=Prune stale indexed accounts and return the discoverable set.)r   r9   s    r*   rv   zCLIState.prune_local_accounts   s     ""$$$r)   Optional[AccountIndexEntry]c                P    t          | j                                      |          S )z<Return the indexed account entry for a username, if present.)r   r}   getrw   s     r*   account_entryzCLIState.account_entry   s#     T.//33H===r)   c                z    | j         | j         S |                     |          }|dS |                    d          S )zHResolve China mainland mode for an account from command or stored state.NrC   )rC   r   r   )r:   r@   entrys      r*   resolved_china_mainlandz CLIState.resolved_china_mainland   sF     *&&""8,,=4yy)***r)   Tselectapir   r   c                   t          | j        |j        |j        j        |j        j        |j        | j                   |r|j        | _        dS dS )z3Persist an account entry for later local discovery.)r@   session_pathcookiejar_pathrC   keyring_hasN)	r   r}   account_namesessionr   r   is_china_mainlandr{   r\   )r:   r   r   s      r*   r   zCLIState.remember_account   sh     	%1;501	
 	
 	
 	
  	7&)&6D###	7 	7r)   c                $   | j         r| j         S |                                 }|st          d          t          |          dk    r1d                    d |D                       }t          d|           |d         d         | _         | j         S )z8Resolve the Apple ID to use for the current CLI command.z?No local accounts were found; pass --username to bootstrap one.r   
c              3  ,   K   | ]}d |d          V  dS )  - r@   Nr(   ).0r   s     r*   	<genexpr>z-CLIState._resolve_username.<locals>.<genexpr>   s0      QQu :uZ'8 : :QQQQQQr)   zCMultiple local accounts were found; pass --username to choose one.
r   r@   )r\   r   r#   lenjoin)r:   accountsr_   s      r*   _resolve_usernamezCLIState._resolve_username   s    " 	+**&&(( 	Q   x==1iiQQQQQQQG   
 #+1+j"9&&r)   c                    	 dS )zGReturn the default message for commands that require an active session.zdYou are not logged into any iCloud accounts. To log in, run: icloud auth login --username <apple-id>r(   r9   s    r*   not_logged_in_messagezCLIState.not_logged_in_message  s    6	
 	
r)   c                    d| d| S )zKReturn the message for account-targeted commands without an active session.z#You are not logged into iCloud for $. Run: icloud auth login --username r(   rw   s     r*   !not_logged_in_for_account_messagez*CLIState.not_logged_in_for_account_message
  s%    7( 7 7,47 7	
r)   	usernames	list[str]c                J    d                     d | D                       }d| S )zBReturn the message for ambiguous active-session account selection.r   c              3      K   | ]	}d | V  
dS )r   Nr(   )r   r@   s     r*   r   z?CLIState.multiple_logged_in_accounts_message.<locals>.<genexpr>  s+      HH(-8--HHHHHHr)   zNMultiple logged-in iCloud accounts were found; pass --username to choose one.
)r   )r   r_   s     r*   #multiple_logged_in_accounts_messagez,CLIState.multiple_logged_in_accounts_message  s;     ))HHiHHHHH 	
r)   #tuple[Optional[str], Optional[str]]c                    | j         r	| j         dfS t          j        |          }|r|dfS | j        sdS t          j        |d          dfS )zAReturn the password and its source for an interactive login flow.explicitkeyring)NNT)rE   prompt)rA   r   get_password_from_keyringrE   get_password)r:   r@   keyring_passwords      r*   _password_for_loginzCLIState._password_for_login  sh    = 	-=*,, :8DD 	/#Y.. 	:!(===xGGr)   c                ~    | j         rdS t          j        | j                                                   d| _         dS )z?Apply the requested log level once for the current CLI process.N)levelT)r]   r5   basicConfigrL   r;   r9   s    r*   _configure_loggingzCLIState._configure_logging*  sB    # 	F$.">">"@"@AAAA#'   r)   c                F    | j         r| j         S t          j        |          S )zEReturn a non-interactive password for service-level reauthentication.)rA   r   r   rw   s     r*   _stored_password_for_sessionz%CLIState._stored_password_for_session1  s'     = 	!= .x888r)   r   countr2   c                    |dk    s| j         sdS t          j        |d          }	 t          |          }n"# t          $ r}t          d          |d}~ww xY w|dk     s||k    rt          d          |S )zDPrompt for a zero-based selection index when multiple choices exist.r   r   0)defaultzInvalid device selection.N)rE   typerr   r2   
ValueErrorr#   )r:   r   r   rawidxexcs         r*   _prompt_indexzCLIState._prompt_index8  s    A::T-:1l63///	Ac((CC 	A 	A 	A677S@	A77cUll6777
s   7 
AAAc                   t          t          |dg           pg           }|r| j                            d           t	          |          D ]%\  }}| j                            d| d|            &|                     dt          |                    }| j                            d           	 |                    ||                    n# t          $ r}t          d          |d}~ww xY w| j
        st          d	          	 |                                st          d
          t          |dd          }|r| j                            |           t          |dd          }|dk    r| j                            d           n |dk    r| j                            d           n\# t          $ r}t          d          |d}~wt          $ r}t          d          |d}~wt          $ r}t          d          |d}~ww xY wd}	t          |	          D ]}
t!          j        d          }	 |                    |          }n"# t&          $ r}t          d          |d}~ww xY w|r n<|	|
z
  dz
  }|dk    rt          d          | j                            d| d           |j        s|                                 dS dS )zHComplete Apple's HSA2 flow using a security key or code-based challenge.fido2_devicesz#Security key verification required.  z: Security key zSelect security key indexz,Touch the selected security key to continue.z!Security key verification failed.NzLTwo-factor authentication is required, but interactive prompts are disabled.zBThis 2FA challenge requires a security key. Connect one and retry.two_factor_delivery_noticetwo_factor_delivery_methodunknowntrusted_devicez5Requested a 2FA prompt on your trusted Apple devices.smszRequested a 2FA code by SMS.zQTwo-factor authentication requires a trusted phone number, but none was returned.z0Failed to request the 2FA trusted-device prompt.z#Failed to request the 2FA SMS code.   zEnter 2FA codez-Failed to verify the 2FA trusted-device code.r   r   zFailed to verify the 2FA code.zInvalid 2FA code. z attempt(s) remaining.)listgetattrrW   print	enumerater   r   confirm_security_key	Exceptionr#   rE   request_2fa_coder   r   r   ranger   r   validate_2fa_coder   is_trusted_sessiontrust_session)r:   r   r   index_deviceselected_indexr   noticedelivery_methodmax_attemptsattemptcodeis_validremaining_attemptss                 r*   _handle_2fazCLIState._handle_2faE  s   WS/2>>D"EE =	LDEEE"+M":": G Gw""#E#E#Ee#E#EFFFF!//+S-?-? N LMNNNM((~)FGGGG M M MBCCLM # b  O++-- "\   !&BDII /L&&v...")#/KY"W"W"&666L&&O    %--L&&'EFFF3   -   8   F  0 O O ODEE3NOL ..  |$455"44T::HHA   "G   E%1G%;a%?"%**"#CDDD""S);SSS    % 	 	  	 sa   0C 
C,C''C,B"F) )
H3GHG  H-G==H-I
I"II"c                `   t          |j        pg           }|st          d          | j                            d           t          |          D ]>\  }}|                    d          rdnd}| j                            d| d|            ?|                     dt          |                    }||         }| j	        st          d	          |
                    |          st          d
          t          j        d          }|                    ||          st          d          dS )z5Complete Apple's legacy two-step authentication flow.zITwo-step authentication is required but no trusted devices are available.zTrusted devices:phoneNumberzSMS trusted devicezTrusted devicer   z: zSelect trusted device indexzJTwo-step authentication is required, but interactive prompts are disabled.z)Failed to send the 2SA verification code.zEnter 2SA verification codezFailed to verify the 2SA code.N)r   trusted_devicesr#   rW   r   r   r   r   r   rE   send_verification_coder   r   validate_verification_code)r:   r   devicesr   devicelabelr   r   s           r*   _handle_2sazCLIState._handle_2sa  sc   s*0b11 	[   	-...&w// 	6 	6ME6(.

=(A(AW$$GW  L4E44U445555++,I3w<<XX( 	\   ))&11 	HFGGG|9::--fd;; 	=;<<<	= 	=r)   c                ,   | j         | j         S |                                 }|                     |          \  }}|st          d          |                                  	 t          |||                     |          | j        | j        | j	                  }ng# t          $ rZ}|dk    r<t          j        |          r(t          j        |           |                                  t          d|           |d}~ww xY wt          j        |          s+| j        r$t!          d          rt          j        ||           |j        r|                     |           n|j        r|                     |           || _         |                     |           |S )z8Return a PyiCloudService, bootstrapping login if needed.Nz6No password supplied and no stored password was found.)apple_idrA   rC   cookie_directoryrF   rG   r   zBad username or password for zSave password in keyring?)rZ   r   r   r#   r   r   r   rH   rF   rG   r   r   rt   ru   rv   rE   r   store_password_in_keyringrequires_2far   requires_2sar   r   )r:   r@   rA   password_sourcer   errs         r*   get_login_apizCLIState.get_login_api  s    9 9))++$($<$<X$F$F!/ 	USTTT!!!	P!!!#;;HEE!%!1!. ,  CC , 	P 	P 	P)++0P1 1+ 0:::))+++E8EEFFCO	P 0::	@ 	@ 344	@
 +Hh??? 	"S!!!! 	"S!!!	c"""
s   !7B 
C=#AC88C=c                ,   | j         | j         S | j        r|                                 }|                     |          }|                                }|d         s"t          |                     |                    |                     |          }|                     ||          s>|                                }|d         s"t          |                     |                    || _         | 	                    |           |S | 
                                }|s!t          |                                           t          |          dk    r,t          |                     d |D                                 |d         \  }}|                     |j                  }|                     ||          sC|                                }|d         s't          |                     |j                            || _         | 	                    |           |S )zDReturn an authenticated PyiCloudService backed by an active session.Nauthenticatedr   c                "    g | ]\  }}|j         S r(   r   )r   r   _statuss      r*   
<listcomp>z$CLIState.get_api.<locals>.<listcomp>  s    HHH,#wS%HHHr)   r   )rZ   rf   r   build_probe_apiget_auth_statusr#   r   build_session_api_hydrate_api_from_prober   active_session_probesr   r   r   r   )r:   r@   	probe_apistatusr   active_probesr   s          r*   get_apizCLIState.get_api  s&    9 9% 	--//H,,X66I..00F/* QtEEhOOPPP((22C//Y?? U,,..o. U"4#I#I(#S#STTTDI!!#&&&J2244 	945577888}!!88HH-HHH    +1-	7$$Y%;<<++C;; 	((**F/* ::9;QRR   	c"""
r)   c           	         |                                   t          || j        |                     |          | j        | j        | j        d          S )z>Build a non-authenticating PyiCloudService for session probes.Fr   rA   rC   r   rF   rG   authenticate)r   r   rA   r   rH   rF   rG   rw   s     r*   r   zCLIState.build_probe_api  s[     	!!!]77AA!-*(
 
 
 	
r)   c           	         |                                   t          ||                     |          |                     |          | j        | j        | j        d          S )zEBuild a session-backed API that can satisfy service reauthentication.Fr  )r   r   r   r   rH   rF   rG   rw   s     r*   r   zCLIState.build_session_api	  sg     	!!!66x@@77AA!-*(
 
 
 	
r)   r   Optional[PyiCloudService]c                   |dS t          |dd          }t          |t                    r|sdS t          |          | _        t          | dd          }|                    d          }t          |t                    r6t          |t                    r!d|v r|                    d|d         i           d|v rt          | d|d                    d	S )
zAPopulate auth-derived state on a session-backed API from a probe.NFdataparamsdsInfodsidwebservices_webservicesT)r   
isinstancedictr  r   updatesetattr)r   r   
probe_datar  ds_infos        r*   r   z CLIState._hydrate_api_from_probe  s     5Y55
*d++ 	: 	5
##h--..**fd## 	5
7D(A(A 	5fPWFWFWMM676?3444J&&CM)BCCCtr)   c                    | j         | j         S |                                 }|                     |          | _         | j         S )zFReturn a cached non-authenticating PyiCloudService for session probes.)r[   r   r   rw   s     r*   get_probe_apizCLIState.get_probe_api0  sB     ?&?"))++..x88r)   dict[str, Any]c                   |p|                                  }t          |j        j                  }t          |j        j                  }t          |          t          |          |                                |                                dS )z0Return session storage paths and presence flags.)r   r   has_session_filehas_cookiejar_file)r  r	   r   r   r   rr   exists)r:   r   r   r   r   s        r*   auth_storage_infozCLIState.auth_storage_info9  s    
 /4--//	I-:;;i/>??--!.11 , 3 3 5 5"0"7"7"9"9	
 
 	
r)   ,list[tuple[PyiCloudService, dict[str, Any]]]c                   g }|                                  D ]}t          |d                   }t          |d                   }|                                s|                                sU|                     |d                   }|                                }|d         r.|                     |d           |                    ||f           |S )zDReturn authenticated sessions discoverable from local session files.r   r   r@   r   Fr   )r   r	   r  r   r   r   append)r:   probesr   r   r   r   r   s          r*   r   zCLIState.active_session_probesH  s     @B((** 		- 		-En 566L!%(8"9::N '')) ^-B-B-D-D &&uZ'899C((**Fo& -%%c%%888sFm,,,r)   )r@   r?   rA   r?   rC   rB   rE   rD   rF   rD   rG   rD   rH   r?   rI   r?   rJ   r?   rK   rD   rL   r,   rM   r   r1   rR   )r_   r>   r1   r`   )r1   rD   )r1   rR   )rp   r   r1   rR   )r@   rr   r1   rD   N)r@   r?   r1   rD   )r1   r	   )r1   r~   )r@   rr   r1   r   )r@   rr   r1   rB   )r   r   r   rD   r1   rR   )r1   rr   )r@   rr   r1   rr   )r   r   r1   rr   )r@   rr   r1   r   )r@   rr   r1   r?   )r   rr   r   r2   r1   r2   )r   r   r1   rR   )r1   r   )r@   rr   r1   r   )r   r   r   r  r1   rD   )r   r  r1   r  )r1   r  )(r$   r%   r&   r'   r^   classmethodrd   propertyrf   ri   rm   ro   r    rx   r{   r}   r   rv   r   r   r   r   r   r   staticmethodr   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r(   r)   r*   rQ   rQ   S   s*       88#) #) #) #)J 
 
 
 [
$ # # # X#
 7 7 7 X7
	
 	
 	
 	
   
* * * *
   ; ; ; ; ; @ @ @ X@
L L L L
% % % %
> > > >
+ + + + HL 7 7 7 7 7 7' ' ' '(
 
 
 

 
 
 
 
 
 
 \
H H H H( ( ( (9 9 9 9   B  B  B  B H= = = =2, , , ,\) ) ) )V
 
 
 

 
 
 
    \0    04
 
 
 
 
     r)   rQ   ctxtyper.Contextr1   c                j   |                                  }|j        }t          |t                    r|S t	          di | j                            t          i           }t                              |          }|	                                 |
                    |j                   ||_        || _        |S )z1Return the resolved CLI state for a leaf command.r(   )	find_rootobjr  rQ   r>   metar   COMMAND_OPTIONS_META_KEYrd   rm   call_on_closero   )r"  root_ctxstater_   resolveds        r*   	get_stater-  Y  s     }}HLE%"" MM#(,,/G"L"LMMG$$W--HMMOOO8>***HLCGOr)   r   r   rr   r   r?   c                   	  |            S # t           $ r}t          |  d|           |d}~wt          t          f$ r2}|rt          |  d| d|           |t          |  d          |d}~ww xY w)zBWrap a service call with user-facing service-unavailable handling.z service unavailable: Nz  requires re-authentication for r   z4 requires re-authentication. Run: icloud auth login.)r   r#   r   r   )r   fnr   r   s       r*   service_callr0  j  s    rtt% G G G%<<s<<==3F)+GH    	 D D, D D5AD D   JJJ
 
	s   	 
A1+A1-A,,A1valueOptional[datetime]c                B   | dS |                                  }|                    d          r|dd         dz   }	 t          j        |          }n'# t          $ r}t          j        d          |d}~ww xY w|j         |                    t          j
                  }|S )z"Parse an ISO-8601 datetime string.NZz+00:00z$Expected an ISO-8601 datetime value.)tzinfo)rV   endswithr   fromisoformatr   r   BadParameterr6  replacer   utc)r1  
normalizeddtr   s       r*   parse_datetimer>  |  s     }tJ3 0_x/
R#J// R R R !GHHcQR	yZZx|Z,,Is   A 
A5A00A5F)require_uniquer   r   queryr?  rD   c                   |                                                                 t          t          d fd j                            }|D ]P}t          t          |dd                                                                                     }|r
|k    r|c S Qg }t                      }|D ]}t          t          |dd                                                     }t          |dd          t          |dd          g}t          fd|D                       sp|pt          t          |                    }	|	|v r|
                    |	           |                    |           |st          d	| d
          |rGt          |          dk    r4d                    d |D                       }
t          d| d|
           |d         S )z6Return a device matched by id or common display names.zFind Myc                      j         S r  )r   )r   s   r*   <lambda>z resolve_device.<locals>.<lambda>  s	     r)   r   idrT   namedeviceDisplayNamec              3     K   | ];}t          |                                                                          k    V  <d S r  )rr   rV   lower)r   rz   lowereds     r*   r   z!resolve_device.<locals>.<genexpr>  sW       
 
:CC	NN  ""((**g5
 
 
 
 
 
r)   zNo device matched 'z'.r   r   c              3     K   | ]=}d t          |dd           dt          |dd           dt          |dd           dV  >dS )	r   rD  rT   z (rE  z / rF  )N)r   )r   r   s     r*   r   z!resolve_device.<locals>.<genexpr>  s       
 

 	;vtR((; ;++; ; v2B77; ; ;
 
 
 
 
 
r)   zMultiple devices matched 'z'. Use a device id instead.
r   )rV   rH  r   r0  r   rr   r   setanyrD  addr  r#   r   r   )r   r@  r?  r   r   
identifiermatchesseen_ids
candidates
dedupe_keyr_   rI  s   `          @r*   resolve_devicerT    s;    kkmm!!##GY 3 3 3 3#BRSSS G   r223399;;AACC
 	*//MMMGH  r223399;;
FFB''F/44

  
 
 
 
GQ
 
 
 
 
 	 23r&zz??
!!Z   v 86U666777 

#g,,**)) 
 

 "
 
 
 
 
 VVVWVV
 
 	
 1:r)   )trashpathrU  c                   |r| j         n| j        }t          |pd          }t          |          dv r|S |j        D ]}|dv r||         }|S )zResolve an iCloud Drive node./>   .rX  >   rT   rX  )rU  rootr
   rr   parts)driverV  rU  noder<  parts         r*   resolve_drive_noder_    sm      /5;;UZDt{s++J
:*$$   9DzKr)   responser   rR   c                B   t          | d          r2|                     d          D ]}|r|                    |           dS t          | d          rJt          | j        d          r7	 | j                            d          }|sdS |                    |           4dS dS )z;Write a download response to a file, streaming if possible.iter_contenti    )
chunk_sizeNr   read)hasattrrb  writer   rd  )r`  file_outchunks      r*   _write_to_fileri    s    x(( **d*;; 	& 	&E &u%%%x "GHL&$A$A "	"L%%d++E NN5!!!		"" " " "r)   outputr	   c                F   t          | d          p$t          | d          ot          | j        d          }|st          d          |j                            dd           |                    d          5 }t          | |           ddd           dS # 1 swxY w Y   dS )	z#Stream a download response to disk.rb  r   rd  z,The download response could not be streamed.T)parentsexist_okwbN)re  r   r#   parentmkdirrm   ri  )r`  rj  
can_streamrg  s       r*   write_response_to_pathrr    s     >22 %  BWX\6%B%B   GEFFF
Mt444	T		 +hx***+ + + + + + + + + + + + + + + + + +s   8BBB)r"  r#  r1   rQ   )r   rr   r   r?   )r1  r?   r1   r2  )r   r   r@  rr   r?  rD   )rV  rr   rU  rD   )r`  r   r1   rR   )r`  r   rj  r	   r1   rR   )<r'   
__future__r   r5   
contextlibr   dataclassesr   r   r   enumr   pathlibr	   r
   typingr   r   r   clickr   rich.consoler   pyicloudr   r   pyicloud.baser   pyicloud.exceptionsr   r   r   r   r   r   r   pyicloud.ssl_contextr   account_indexr   r   r   r   rj  r   r    r(  RuntimeErrorr#   rr   r,   r>   rQ   r-  r0  r>  rT  r_  ri  rr  r(   r)   r*   <module>r     sW   B B " " " " " "              ! ! ! ! ! ! ' ' ' ' ' ' ' '       ' ' ' ' ' ' ' '                                    + + + + + + + + 2 2 2 2 2 2                  ? > > > > >            - , , , , , , ,, 6 6 6 6 6| 6 6 6    sD   ( $4 4 4 4 4 4 4 4"C C C C C C C CL   " CG      $   " PU + + + + + +\ ;@      " " " "+ + + + + +r)   