o
    l>j                     @  s   d Z ddlmZ ddlZddlZddl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 dZG d	d
 d
eddZd3ddZd4ddZd5ddZed6ddZd7ddZd8d d!Zd9d&d'Zd:d)d*Zd;d1d2ZdS )<z0Local account discovery index for the Typer CLI.    )annotationsN)contextmanager)datetimetimezone)Path)CallableIterator	TypedDictzaccounts.jsonc                   @  s:   e Zd ZU dZded< ded< ded< ded< ded< d	S )
AccountIndexEntryz!Persisted local account metadata.strusernamelast_used_atsession_pathcookiejar_pathboolchina_mainlandN)__name__
__module____qualname____doc____annotations__ r   r   O/home/thesage/.local/lib/python3.10/site-packages/pyicloud/cli/account_index.pyr
      s   
 r
   F)totalsession_root
str | Pathreturnr   c                 C  s   t | t S )z6Return the JSON file path for the local account index.)r   ACCOUNT_INDEX_FILENAMEr   r   r   r   account_index_path      r   
index_pathdict[str, AccountIndexEntry]c           
   	   C  s  zt | jdd}W n ty   i  Y S  tt jfy#   i  Y S w t|tr.|dnd}t|ts7i S i }|	 D ]I\}}t|t
rKt|tsLq=|d}|d}|d}t|t
ret|t
sfq=|t|t
rn|nd||d	||< |d
}	t|	tr|	|| d
< q=|S )z+Load indexed accounts from a specific path.utf-8encodingaccountsNr   r   r    r   r   r   r   r   )jsonloads	read_textFileNotFoundErrorOSErrorJSONDecodeError
isinstancedictgetitemsr   r   )
r!   rawr&   
normalizedr   entryr   r   r   r   r   r   r   _load_accounts_from_path    s:   






r6   c                 C  s   t t| S )z Load indexed accounts from disk.)r6   r   r   r   r   r   load_accountsC   r    r7   Iterator[Path]c                 c  s(   t | }|jjddd ||j d}|jdddm}zddl}W n ty7   |V  Y W d   dS w ||	 |j
 z|V  W ||	 |j n
||	 |j w z|  W n tyi   Y n tyq   Y nw W d   dS W d   dS W d   dS 1 sw   Y  dS )	zHSerialize account index updates when the platform supports file locking.Tparentsexist_okz.lockza+r#   r$   r   N)r   parentmkdirwith_suffixsuffixopenfcntlImportErrorflockfilenoLOCK_EXLOCK_UNunlinkr,   r-   )r   r!   	lock_path	lock_filerA   r   r   r   _locked_indexI   s:   ("rJ   r&   Nonec                 C  s   t t| | dS )z!Persist indexed accounts to disk.N)_save_accounts_to_pathr   )r   r&   r   r   r   _save_accountsd   s   rM   c                   s   sz|    W dS  ty   Y dS w | jjddd d fddt D i}d}zGtjdd| jd	| j d	d
dd%}|t	j
|dddd  |  t|  t|j}W d   n1 sew   Y  t||  W dS  ty   |durz|   W   ty   Y  w  w )z,Persist indexed accounts to a specific path.NTr9   r&   c                   s   i | ]}| | qS r   r   .0r   r&   r   r   
<dictcomp>z   s    z*_save_accounts_to_path.<locals>.<dictcomp>wr#   .z.tmpF)r%   dirprefixr?   delete   )indent	sort_keys
)rG   r,   r<   r=   sortedtempfileNamedTemporaryFilenamewriter)   dumpsflushosfsyncrD   r   replace	Exception)r!   r&   payload	temp_path	temp_filer   rP   r   rL   l   sN   

rL   r5   keyring_hasCallable[[str], bool]r   c                 C  s,   t | d  pt | d  p|| d S )Nr   r   r   )r   exists)r5   ri   r   r   r   _is_discoverable   s
   
rl   list[AccountIndexEntry]c                   sn   t |  }t|} fdd| D |krt| W d   n1 s'w   Y  fddtD S )z4Drop stale entries and return discoverable accounts.c                       i | ]\}}t | r||qS r   rl   )rO   r   r5   ri   r   r   rQ          z"prune_accounts.<locals>.<dictcomp>Nc                   s   g | ]} | qS r   r   rN   )retainedr   r   
<listcomp>   s    z"prune_accounts.<locals>.<listcomp>)rJ   r6   r2   rL   r[   )r   ri   r!   r&   r   )ri   rr   r   prune_accounts   s   


	rt   r   r   r   r   r   bool | Nonec          
        s   t | J} fddt| D }||}|tjtjd ||d}	|dur.||	d< n|dur<d|v r<|d |	d< |	||< t	|| |	W  d   S 1 sQw   Y  dS )z7Upsert one account entry and prune any stale neighbors.c                   rn   r   ro   )rO   	username_r5   rp   r   r   rQ      rq   z$remember_account.<locals>.<dictcomp>)tzr(   Nr   )
rJ   r6   r2   r1   r   nowr   utc	isoformatrL   )
r   r   r   r   r   ri   r!   r&   previousr5   r   rp   r   remember_account   s$   





$r|   )r   r   r   r   )r!   r   r   r"   )r   r   r   r"   )r   r   r   r8   )r   r   r&   r"   r   rK   )r!   r   r&   r"   r   rK   )r5   r
   ri   rj   r   r   )r   r   ri   rj   r   rm   )r   r   r   r   r   r   r   r   r   ru   ri   rj   r   r
   )r   
__future__r   r)   rb   r\   
contextlibr   r   r   pathlibr   typingr   r   r	   r   r
   r   r6   r7   rJ   rM   rL   rl   rt   r|   r   r   r   r   <module>   s*    



#


(

