o
    l>j                    @   sJ  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mZ ddl	m
Z
mZmZ ddlmZmZmZmZmZmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZmZmZ ddlm Z  ddl!m"Z" e#e$Z%ej&e'd< G dd deZ(de)e*ef de+e)e*ef  fddZ,eG dd deZ-G dd de*e
Z.G dd de*e
Z/G dd de*e
Z0G dd de*e
Z1ddd Z2e)e*e*f e'd!< G d"d# d#eZ3G d$d% d%eZ4G d&d' d'e4Z5G d(d) d)e4Z6G d*d+ d+e Z7G d,d- d-eeZ8G d.d/ d/e8Z9G d0d1 d1e9Z:G d2d3 d3e9Z;G d4d5 d5e8Z<G d6d7 d7Z=G d8d9 d9e=Z>dS ):zPhoto service.    N)ABCabstractmethod)datetimetimezone)EnumIntEnumunique)Any	GeneratorIterableIteratorOptionalcast)	urlencode)Response)CONTENT_TYPECONTENT_TYPE_TEXT)PyiCloudAPIResponseExceptionPyiCloudException$PyiCloudServiceNotActivatedException)BaseService)PyiCloudSession_LOGGERc                       s4   e Zd ZdZddd					d fd	d
Z  ZS )PhotosServiceExceptionzPhoto service exception.N)photoalbumr   PhotoAsset|Noner   BasePhotoAlbum|Nonereturnc                   s   t  j|  || _|| _d S N)super__init__r   r   )selfr   r   args	__class__ T/home/thesage/.local/lib/python3.10/site-packages/pyicloud/services/photos_legacy.pyr!      s   
zPhotosServiceException.__init__)r   r   r   r   r   N)__name__
__module____qualname____doc__r!   __classcell__r&   r&   r$   r'   r      s    r   payloadr   c                 C   s`   |  drg S |  d}t|tsg S g }|D ]}t|tsq| dr(g   S || q|S )z=Return non-error record dicts from a CloudKit modify payload.errorsrecordsserverErrorCode)get
isinstancelistdictappend)r-   r/   valid_recordsrecordr&   r&   r'   _valid_modify_records(   s   




r8   c                   @   s   e Zd ZdZdZdZdZdS )AlbumTypeEnumzAlbum typesr         N)r(   r)   r*   r+   ALBUMFOLDERSMART_ALBUMr&   r&   r&   r'   r9   9   s
    r9   c                   @   s<   e 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S )SmartAlbumEnumzSmart albums names.LibraryBursts	FavoritesHiddenLive	PanoramaszRecently DeletedScreenshotszSlo-moz
Time-lapseVideosN)r(   r)   r*   r+   
ALL_PHOTOSBURSTS	FAVORITESHIDDENLIVE	PANORAMASRECENTLY_DELETEDSCREENSHOTSSLO_MO
TIME_LAPSEVIDEOSr&   r&   r&   r'   r?   B   s    r?   c                   @   s   e Zd ZdZdZdZdS )DirectionEnumzDirection names.	ASCENDING
DESCENDINGN)r(   r)   r*   r+   rT   rU   r&   r&   r&   r'   rS   R   s    rS   c                   @   s,   e Zd ZdZdZdZdZdZdZdZ	dZ
d	S )
ListTypeEnumzList type names.2CPLAssetAndMasterByAssetDateWithoutHiddenOrDeleted&CPLAssetAndMasterDeletedByExpungedDate"CPLAssetAndMasterHiddenByAssetDate(CPLAssetAndMasterInSmartAlbumByAssetDate&CPLBurstStackAssetAndMasterByAssetDate#CPLContainerRelationLiveByAssetDatesharedstreamN)r(   r)   r*   r+   DEFAULTDELETEDrK   r>   STACK	CONTAINERSHARED_STREAMr&   r&   r&   r'   rV   Y   s    rV   c                   @   s@   e 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S )ObjectTypeEnumzObject type names.)CPLAssetByAssetDateWithoutHiddenOrDeleted"CPLAssetBurstStackAssetByAssetDateCPLAssetDeletedByExpungedDatez(CPLAssetInSmartAlbumByAssetDate:FavoriteCPLAssetHiddenByAssetDatez$CPLAssetInSmartAlbumByAssetDate:Livez(CPLAssetInSmartAlbumByAssetDate:Panoramaz*CPLAssetInSmartAlbumByAssetDate:Screenshotz%CPLAssetInSmartAlbumByAssetDate:Slomoz)CPLAssetInSmartAlbumByAssetDate:Timelapsez%CPLAssetInSmartAlbumByAssetDate:Video)CPLContainerRelationNotDeletedByAssetDateN)r(   r)   r*   r+   ALLBURSTr_   FAVORITErK   rL   PANORAMA
SCREENSHOTSLOMO	TIMELAPSEVIDEOra   r&   r&   r&   r'   rc   e   s    rc   PrimarySyncREGULAR_CUSTOM_ZONE)zoneNamezoneTypePRIMARY_ZONEc                   @   s   e Zd ZdZdded dB ddfddZdefdd	Zd
eeB ddfddZ	de
d fddZdedefddZdeded fddZ	dd
eddddfddZdddZdeddfddZdS ) AlbumContainerzf
    Container for photo albums.
    This provides a way to access all the albums in the library.
    NalbumsBasePhotoAlbumr   c                 C   s4   |d urdd |D | _ ni | _ t| j  | _d S )Nc                 S   s   i | ]}|j |qS r&   )id).0r   r&   r&   r'   
<dictcomp>   s    z+AlbumContainer.__init__.<locals>.<dictcomp>)_albumsr3   keys_index)r"   rw   r&   r&   r'   r!      s   
zAlbumContainer.__init__c                 C   s
   t | jS r   )lenr|   r"   r&   r&   r'   __len__   s   
zAlbumContainer.__len__keyc                 C   sR   t |tr| j| j|  S || jv r| j| S | |}|dur"|S td| )z#Returns the album for the given id.NzPhoto album does not exist: )r2   intr|   r~   findKeyError)r"   r   r   r&   r&   r'   __getitem__   s   



zAlbumContainer.__getitem__c                 C   s   t | j S r   )iterr|   valuesr   r&   r&   r'   __iter__   s   zAlbumContainer.__iter__namec                 C      |  |duS )z+Checks if an album exists in the container.N)r   )r"   r   r&   r&   r'   __contains__      zAlbumContainer.__contains__c                 C   s&   | j  D ]}||jkr|  S qdS )z2Finds an album by name, returns None if not found.N)r|   r   fullname)r"   r   r   r&   r&   r'   r      s
   
zAlbumContainer.finddefaultzBasePhotoAlbum | Nonec                 C   s   | j ||S )z=Returns the album for the given key, or default if not found.)r|   r1   )r"   r   r   r&   r&   r'   r1      s   zAlbumContainer.getr   c                 C   s    || j |j< t| j  | _dS )z"Appends an album to the container.N)r|   ry   r3   r}   r~   )r"   r   r&   r&   r'   r5      s   zAlbumContainer.appendidxc                 C   s.   |dk s|t | jkrtd| j| j|  S )z%Returns the album at the given index.r   zPhoto album index out of range)r   r~   
IndexErrorr|   )r"   r   r&   r&   r'   index   s   zAlbumContainer.indexr   )r   rx   r   N)r(   r)   r*   r+   r3   r!   r   r   strr   r   r   boolr   r   r   r1   r5   r   r&   r&   r&   r'   rv   }   s$    


rv   c                	   @   s   e Zd ZdZ	dddded dee ddfd	d
Zede	fddZ
ede	fddZdeeeeeef  f deeeeeef f eeeef  f fddZdS )BasePhotoLibraryzrRepresents a library in the user's photos.

    This provides access to all the albums as well as the photos.
    NservicePhotosService
asset_type
PhotoAsset
upload_urlr   c                 C   s   || _ || _d | _|| _d S r   )r   r   r|   _upload_url)r"   r   r   r   r&   r&   r'   r!      s   
zBasePhotoLibrary.__init__c                 C      t )Returns the photo albums.NotImplementedErrorr   r&   r&   r'   _get_albums      zBasePhotoLibrary._get_albumsc                 C   s   | j du r
|  | _ | j S )r   N)r|   r   r   r&   r&   r'   rw      s   

zBasePhotoLibrary.albumsresponsec                 C   s   i }g }| dg }t|ts||fS |D ]U}t|tsq| d}|dkrY| di }t|ts2q| di }t|ts>q| di }	t|	tsJq|	 d}
t|
trX|||
< q|dkrjt| dtrj|| q||fS )	zParses the asset response.r/   
recordTypeCPLAssetfields	masterRefvalue
recordName	CPLMaster)r1   r2   r3   r4   r   r5   )r"   r   asset_recordsmaster_recordsr/   recrecord_typer   
master_refmaster_value	master_idr&   r&   r'   parse_asset_response   s6   








z%BasePhotoLibrary.parse_asset_responser   )r(   r)   r*   r+   typer   r   r!   r   rv   r   propertyrw   r4   r3   r	   tupler   r&   r&   r&   r'   r      s*    	
&r   c                       sV  e Zd ZU dZejejej	e
jddejejeje
jdddddd	gdejejeje
jdddd
dd	gdejejeje
jdddddd	gdejejeje
jddejejeje
jdddddd	gdejejeje
jdddddd	gdejejeje
jdddddd	gdejejeje
jdddddd	gdejejeje
jddej ej ej e
jddiZ!e"ee"e#e$f f e%d< 	d+ddde"e#e#f de&e# ddf fddZ'd+de&e# de(e"e#e$f  fddZ)de"e#e$f de&d fddZ*de+fdd Z,e-j.fd!e#d"e-de&d fd#d$Z/d%e#de&d& fd'd(Z0e1d,d)d*Z2  Z3S )-PhotoLibraryz.Represents the user's primary photo libraries.N)obj_type	list_type	directionquery_filter
smartAlbumEQUALSSTRINGro   r   r   	fieldName
comparator
fieldValuerp   rn   rk   rl   rm   rL   SMART_ALBUMSr   r   zone_idr   r   c                    s   t  j|t|d || _| jj dt| jj | _| jj	j
| jddi| jdttid}| }|d}d }t|trc|rc|d }t|trc|d	i }	t|	trc|	d
i }
t|
trc|
d}|dkrptd tdd S )Nr   r   z/records/query?r   CheckIndexingStatequeryzoneIDurljsonheadersr/   r   r   stater   FINISHEDz*iCloud Photo Library not finished indexingzNiCloud Photo Library not finished indexing. Please try again in a few minutes.)r    r!   r   r   r   service_endpointr   paramsr   sessionpostr   r   r   r1   r2   r3   r4   r   debugr   )r"   r   r   r   requestr   r/   indexing_statefirst_recordr   r   r$   r&   r'   r!   j  s>   








zPhotoLibrary.__init__	parent_idc                 C   s   ddi| j d}|rdd|dddg|d	 d
< | jjj| j|ttid}| }|d }d|v rS|d |d< | jjj| j|ttid}| }||d  d|v s1|	 D ] }|d 
drw|d d d tjjkrw|| j|d d qW|S )zFetches records.r   CPLAlbumByPositionLiver   parentIdr   r   )r   r   r   r   filterByr   r/   continuationMarkerr   	albumTyper   r   )r   )r   r   r   r   r   r   r   r   extendcopyr1   r9   r=   r   _fetch_records)r"   r   r   r   r   r/   r7   r&   r&   r'   r     sH   zPhotoLibrary._fetch_recordsr7   
PhotoAlbumc           	      C   s  d|d vs|d  dr|d d d rdS |d }t|d d d d}dd	d
|ddg}|d  di  d}t}|d  drU|d d d tjjkrUt}t	j
}|d  di  dddkrit	j}|d  di  dd}|| ||tjtj|| j|| d| j||d |dS )z#Converts a record to a photo album.albumNameEncr   	isDeletedr   Nr   utf-8r   r   r   r   r   r   sortAscending   recordModificationDater   recordChangeTag)libraryr   	record_idr   r   r   r   r   r   r   record_change_tagrecord_modification_date)r1   base64	b64decodedecoder   r9   r=   r   PhotoAlbumFolderrS   rT   rU   rV   ra   rc   r   r   )	r"   r7   r   
album_namer   r   
album_typer   r   r&   r&   r'   _convert_record_to_album  sT   z%PhotoLibrary._convert_record_to_albumc                    sJ   t  fdd j D }  D ]} |}|dur"|| q|S )zReturns photo albums.c              	      s,   g | ]\}}t d | j jd |qS ))r   r   r   r   r&   )SmartPhotoAlbumr   r   )rz   r   propsr   r&   r'   
<listcomp>  s    z,PhotoLibrary._get_albums.<locals>.<listcomp>N)rv   r   itemsr   r   r5   )r"   rw   r7   r   r&   r   r'   r      s   


zPhotoLibrary._get_albumsr   r   c              
   C   s   dddt |ddid|jiddiddiddiddiddd	g| jd
d}| jj}t| jj	}| d| }z| jj
j||ttid}| }|dg }	|	sXW dS W n typ }
 ztd|
 td|
d}
~
ww | |	d S )z2Creates a new album, returns the request response.createCPLAlbumr   r   r   r   )r   r   r   
isExpungedsortTyper   )r   r   operationTyper7   T
operationsr   atomic/records/modify?r   r   r/   NzFailed to create album: %szFailed to create album)r   	b64encodeencoder   r   r   r   r   r   r   r   r   r   r   r   r1   r   r   errorr   r   )r"   r   r   dataendpointr   r   respr-   r/   exr&   r&   r'   create_album  sV   #
zPhotoLibrary.create_albumpathr   c           	      C   s   | j std| jd dS tj|}| jj	
 }||d< | j  dt| }t|d}| jjj||d}W d   n1 sBw   Y  | }d|v rVtd	|d d
d |d D }d|vsgd|vridS | | j|d |d S )z.Upload a photo from path, returns a recordNamez5Uploads are not supported for photo library zone '%s'rs   Nfilenamez/upload?rb)r   r  r.    c                 S   s   i | ]}|d  |qS )r   r&   )rz   r   r&   r&   r'   r{   m  s    
z,PhotoLibrary.upload_file.<locals>.<dictcomp>r/   r   r   )r   r   r  r   r1   osr
  basenamer   r   r   r   openr   r   r   r   r   )	r"   r
  r  r   r   file_objr   json_responser/   r&   r&   r'   upload_fileR  s2   
zPhotoLibrary.upload_filec                 C   s   t t| jtj S )zReturns the All Photos album.)r   r   rw   r?   rH   r   r&   r&   r'   allv  s   zPhotoLibrary.allr   r   r   )4r(   r)   r*   r+   r?   rH   rc   ri   rV   r^   rS   rU   rQ   ro   r>   rT   rR   rp   rP   rn   rI   rj   r`   rJ   rk   rM   rl   rO   rm   rL   rN   r_   rK   r   r4   r   r	   __annotations__r   r!   r3   r   r   rv   r   r9   r<   r	  r  r   r  r,   r&   r&   r$   r'   r      s   
 s
$)1

<
<$r   c                       s<   e Zd ZdZdddeddf fddZdefd	d
Z  ZS )PhotoStreamLibraryz"Represents a shared photo library.r   r   shared_streams_urlr   Nc                    s   t  j|td d || _d S )Nr   )r    r!   PhotoStreamAssetr  )r"   r   r  r$   r&   r'   r!     s   
zPhotoStreamLibrary.__init__c                 C   s   t  }| j dt| jj }| jjj|i ttid}|	 }|d D ]7}t
| |d d |d |d |d |d	 |d d
 |d |d d |d d |d |ddd}|| q#|S )zReturns albums.?r  rw   
attributesr   albumlocation	albumctag	albumguid	ownerdsidcreationDatesharingtypeallowcontributionsispubliciswebuploadsupported	publicurlN)r   r   album_location
album_ctag
album_guid
owner_dsidcreation_datesharing_typeallow_contributions	is_publicis_web_upload_supported
public_url)rv   r  r   r   r   r   r   r   r   r   SharedPhotoStreamAlbumr1   r5   )r"   rw   r   r   r   r   shared_streamr&   r&   r'   r     s.   





zPhotoStreamLibrary._get_albums)	r(   r)   r*   r+   r   r!   rv   r   r,   r&   r&   r$   r'   r  |  s    r  c                   @   s   e Zd ZdZdededeeef dededdfd	d
Zde	fddZ
edeeef fddZedddZedefddZedefddZejfdededed fddZdS )r   z_The 'Photos' iCloud service.

    This also acts as a way to access the user's primary library.service_rootr   r   r   r  r   Nc                 C   sn   t j| |||d | j d| _|| _d | _| jddd i | _d | _	t
| | d| jd  dd| _d S )	N)r2  r   r   z5/database/1/com.apple.photos.cloud/production/privateT)
remapEnumsgetCurrentSyncToken/dsidz/sharedstreams/webgetalbumslist)r  )r   r!   r2  r   r   
_librariesr   update_photo_assets_root_libraryr  _shared_library)r"   r2  r   r   r   r  r&   r&   r'   r!     s"   
zPhotosService.__init__c                 C   s"   | j du rt| t| jd| _ | j S )zCBuild the primary library lazily so shared-only callers still work.Nr   )r:  r   ru   r   r   r&   r&   r'   _get_root_library  s   
zPhotosService._get_root_libraryc                 C   s   | j sE| j d}| jj|| jdttid}| }|d }|  | j	d}|D ]}|
dsA|d d }t| |d | jd	||< q(|| _ | j S )
zReturns photo libraries.z/changes/databasez{})r   r  r   zones)rootshareddeletedr   rs   r<  )r7  r   r   r   r   r   r   r   r=  r;  r1   r   r   )r"   r   r   r   r>  	librarieszone	zone_namer&   r&   r'   rB    s,   

zPhotosService.librariesr   c                 C   
   |   jS )z"Returns the primary photo library.)r=  r  r   r&   r&   r'   r       
zPhotosService.allc                 C   rE  )z"Returns the standard photo albums.)r=  rw   r   r&   r&   r'   rw     rF  zPhotosService.albumsc                 C      | j jS )z Returns the shared photo albums.)r;  rw   r   r&   r&   r'   shared_streams     zPhotosService.shared_streamsr   r   c                 C   s   |   ||S )z1Creates a new album in the primary photo library.)r=  r	  )r"   r   r   r&   r&   r'   r	    s   zPhotosService.create_albumr  )r(   r)   r*   r+   r   r   r4   r	   r!   r   r=  r   r   rB  r  rv   rw   rH  r9   r<   r   r	  r&   r&   r&   r'   r     s@    

"r   c                   @   s>  e Zd ZdZdejfdededede	dedd	fd
dZ
eedefddZede	fddZedefddZde	dede	ded fddZdeddfddZdeeeeeef  f ded fddZdFddZedefdd Zedefd!d"Zejd#edd	fd$d"Zd#edd	fd%d&Zdefd'd(Zeded fd)d*Zeedefd+d,Z ed-e	de	dedeeef fd.d/Z!ededeeef fd0d1Z"edefd2d3Z#ede	fd4d5Z$ded fd6d7Z%de	fd8d9Z&defd:d;Z'defd<d=Z(d>edd?fd@dAZ)d>e	eB ddfdBdCZ*d>edefdDdEZ+d	S )Grx   zAn abstract photo album.d   r   r   r   	page_sizer   r   Nc                 C   s(   || _ || _|| _|| _|| _d | _d S r   )_name_library
_page_size
_direction
_list_type_len)r"   r   r   r   rK  r   r&   r&   r'   r!     s   
zBasePhotoAlbum.__init__c                 C   r   z.Gets the full name of the album including pathr   r   r&   r&   r'   r        zBasePhotoAlbum.fullnamec                 C   s   | j dk r| j S dS )zGets the page size.rJ  )rN  r   r&   r&   r'   rK        zBasePhotoAlbum.page_sizec                 C   rG  )zGet the Photo service)rM  r   r   r&   r&   r'   r   %  rI  zBasePhotoAlbum.servicer   )r   NNc                 C   sH   t d|}| jjj|  | j||d |dttid}| }| 	|S )Nr      )offsetrK  r   r   )
maxr   r   r   _get_url_get_payloadr   r   r   _process_photo_list_response)r"   r   r   rK  rV  r   r  r&   r&   r'   _get_photos_at*  s   


zBasePhotoAlbum._get_photos_atphoto_idr   c                 C   sZ   | j jj|  | |ttid}| }| |D ]}|j	|kr%|  S qt
d| )zReturns a photo by id.r   Photo does not exist: )r   r   r   rX  _get_photo_payloadr   r   r   rZ  ry   r   )r"   r\  r   r  r   r&   r&   r'   
_get_photo<  s   
zBasePhotoAlbum._get_photor   c                 c   sX    | j |\}}|D ]}|d }||}|std| q| j | j||V  qd S )Nr   z+No asset record found for master record: %s)rM  r   r1   r   r   r   r   )r"   r   r   r   master_recordrecord_nameasset_recordr&   r&   r'   rZ  I  s   
z+BasePhotoAlbum._process_photo_list_responsec                 C   s   t | || jdS )z#Returns a photo at the given index.r   )nextr[  rO  )r"   r   r&   r&   r'   r   Y  s   zBasePhotoAlbum.photoc                 C      | j S )zGets the album title.r   r   r&   r&   r'   title]     zBasePhotoAlbum.titlec                 C   rd  )zGets the album name.)rL  r   r&   r&   r'   r   b  rg  zBasePhotoAlbum.namer   c                 C   s   | j |kr| | dS dS )zSets the album name.N)rL  renamer"   r   r&   r&   r'   r   g  s   
c                 C      t d)Renames the album.zAlbum name is read-onlyr   ri  r&   r&   r'   rh  m     zBasePhotoAlbum.renamec                 C   rj  )Deletes the album.zAlbum delete is not implementedr   r   r&   r&   r'   deleteq  rl  zBasePhotoAlbum.deletec                 c   s    d| _ | jtjkrt| d }nd}t }	 d}| || j| jD ]}|d7 }|j|v r5t	
d|j q"||j |V  q"|| jk rJt	
d| || jd k rSdS | jtjkr^|| }n|| }q)zReturns the album photos.Nr   r   Tz#Duplicate photo found: %s, skippingz Less than page size returned: %drU  )rQ  rO  rS   rU   r   setr[  rK  ry   r   r   add)r"   rV  
photos_idsnum_resultsr   r&   r&   r'   photosu  s.   


zBasePhotoAlbum.photosc                 C   r   zGets the album id.r   r   r&   r&   r'   ry     rS  zBasePhotoAlbum.idrV  c                 C   r   )z/Returns the payload for the photo list request.r   r"   rV  rK  r   r&   r&   r'   rY    s   zBasePhotoAlbum._get_payloadc                 C   r   )z1Returns the payload for the photo record request.r   r"   r\  r&   r&   r'   r^    r   z!BasePhotoAlbum._get_photo_payloadc                 C   r   )z+Returns the URL for the photo list request.r   r   r&   r&   r'   rX    r   zBasePhotoAlbum._get_urlc                 C   r   )z*Returns the number of photos in the album.r   r   r&   r&   r'   _get_len  r   zBasePhotoAlbum._get_lenc                 C   rd  r   )rs  r   r&   r&   r'   r        zBasePhotoAlbum.__iter__c                 C   s   | j d u r
|  | _ | j S r   )rQ  rw  r   r&   r&   r'   r     s   

zBasePhotoAlbum.__len__c                 C   rd  r   )rf  r   r&   r&   r'   __str__  rx  zBasePhotoAlbum.__str__c                 C   s   dt | j d|  dS )N<z: 'z'>)r   r(   r   r&   r&   r'   __repr__     zBasePhotoAlbum.__repr__r   zPhotoAsset | Nonec                 C   s"   z|  |W S  ty   Y dS w )zGets a photo by id.N)r_  r   r"   r   r&   r&   r'   r1     s
   zBasePhotoAlbum.getc              
   C   s   t |tr:t| }|dk r|| }|dk s||krtdzt| || jdW S  ty9 } ztd|d}~ww | | }rC|S t	d| )zGets a photo by index.r   zPhoto index out of ranger   Nr]  )
r2   r   r   r   rc  r[  rO  StopIterationr1   r   )r"   r   	album_lenexcr   r&   r&   r'   r     s   

zBasePhotoAlbum.__getitem__c                 C   r   )z,Checks if a photo exists in the album by id.N)r1   r}  r&   r&   r'   r     r   zBasePhotoAlbum.__contains__)r   r   ),r(   r)   r*   r+   rS   rT   r   r   rV   r   r!   r   r   r   rK  r   r   r
   r[  r_  r4   r3   r	   rZ  r   rf  r   setterrh  r   rn  rs  ry   rY  r^  rX  rw  r   r   ry  r{  r1   r   r   r&   r&   r&   r'   rx     s    




rx   c                       s  e Zd ZdZ						d2dededededed	ed
ede	e
eeef   de	eeef  dede	e de	e de	e ddf fddZedefddZedefddZdeddfddZdefddZdddefdd Zde	d fd!d"Zedefd#d$Zdefd%d&Zdefd'd(Zd)eded	edeeef fd*d+Zd,edeeef fd-d.Z	d3d)eded	ed/edeeef f
d0d1Z  ZS )4r   zA photo album.NrJ  r   r   r   r   r   r   r   r   r   rK  r   r   r   r   c                    sX   t  j||||
|d || _|| _|| _|| _|| _|| _|| _|	r'|	| _	d S t
| _	d S )N)r   r   r   rK  r   )r    r!   
_record_id	_obj_type_query_filter_url
_parent_id_record_change_tag_record_modification_date_zone_idru   )r"   r   r   r   r   r   r   r   r   r   rK  r   r   r   r$   r&   r'   r!     s"   

zPhotoAlbum.__init__c                 C   rd  rt  )r  r   r&   r&   r'   ry     rg  zPhotoAlbum.idc                 C   s   | j g}| jh}| j}|d ur<||v rtd| j n!|| | jj|}|d u r,n|	|j  t
|dd }|d usdt|S )Nz+Cycle detected in album parent chain for %sr  r5  )r   ry   r  r   warningrp  rM  rw   r1   r5   getattrjoinreversed)r"   partsvisitedr   parentr&   r&   r'   r     s   

zPhotoAlbum.fullnamer   c           	      C   s   | j |krdS d| jd| jd| jddt|ddiidd	gd
}| jj	 dt
| jj }| jjj||ttid}| }t|}|sOtd| d|d }t|trr|d| j| _|di }|di d| j| _|| _ dS )rk  NTr8  r   r   r   r   r   r   r   r   r   r   r   r   r   r  zFailed to rename albumr   r   r   r   r   )rL  r  r  r  r   r  r  r   r   r   r   r   r   r   r   r   r   r8   r   r2   r4   r1   r  )	r"   r   r  r   r   r-   r/   latestr   r&   r&   r'   rh    sV   





zPhotoAlbum.renamec              
   C   s   d| j d| j| jddddiiddgd	}| jj d
t| jj }z@| jjj||t	t
id}| }t|}|s=W dS |d }t|tra|d| j| _|di di d| j| _W dS W dS  ty| } ztd| td| d|d}~ww )rm  Tr8  r   r   r   r   )r   r   r   r   r   r  r   r  Fr   r   r   r   z%Failed to delete photo from album: %sz!Failed to delete photo from albumr  N)r  r  r  r   r   r   r   r   r   r   r   r   r8   r2   r4   r1   r  r   r   r  r   )r"   r  r   r   r-   r/   r  r  r&   r&   r'   rn  Q  s^   




zPhotoAlbum.deleter   r   c           	   
   C   s*  d| j dd|jiddid| jidd|j d| j dd	gd
}| jj dt| jj }zL| jjj||t	t
id}| }t|}|sIW dS |D ]-}|ddks\|d| jkrx|d| j| _|di di d| j| _ W dS qKW dS  ty } ztd| W Y d}~dS d}~ww )z$Adds an existing photo to the album.Tr   r   i   )itemIdpositioncontainerIdCPLContainerRelationz-IN-)r   r   r   r   r  r   r  Fr   r   r   r   r   r   z Failed to add photo to album: %sN)r  ry   r  r   r   r   r   r   r   r   r   r   r8   r1   r  r  r   r   r  )	r"   r   r  r   r   r-   r/   r7   r  r&   r&   r'   	add_photo  s^   



zPhotoAlbum.add_photoc                 C   sN   t | jtsdS | j|}|du rdS | |s%td td| |d|S )Uploads a photo to the album.NzFailed to add photo to album)r   r   )r2   rM  r   r  r  r   r  r   )r"   r
  photo_assetr&   r&   r'   upload  s   

zPhotoAlbum.uploadc                 C   s   | j j d| j S )zReturns the container ID.:)r  r   r  r   r&   r&   r'   _get_container_id  rT  zPhotoAlbum._get_container_idc                 C   s   | j j dt| j j }| j jj|dddddd| jgdd	d
d| jdgitt	id}|
 }zt|d d d d d d d W S  ttttfy]   tjd| j|dd Y dS w )Nz/internal/records/query/batch?batchr   HyperionIndexCountLookupindexCountIDINSTRING_LISTr   r   r   r   T)resultsLimitr   zoneWider   r  r   r/   r   	itemCountr   z+Unexpected Photos count response for %s: %r)exc_info)r   r   r   r   r   r   r  r  r   r   r   r   r   r   	TypeError
ValueErrorr   r   r"   r   r   r   r&   r&   r'   rw    sJ   

zPhotoAlbum._get_lenc                 C   rd  r   )r  r   r&   r&   r'   rX    rx  zPhotoAlbum._get_urlrV  c                 C   s   |  || j||| jS r   )_list_query_genrP  r  ru  r&   r&   r'   rY    s   zPhotoAlbum._get_payloadr\  c                 C   s&   |  d| jtjdddd|ddgS )Nr   r   r   r   r   r   r   )r  rP  rS   rT   rv  r&   r&   r'   r^    s   zPhotoAlbum._get_photo_payloadrr  c                 C   sX   |j ddd|j ddddd|ddgd|g d	| jd
}|r*|d d | |S )Nr   r   r   r   r   	startRankINT64r  )aresJPEGFullWidthresJPEGFullHeightresJPEGFullFileTyperesJPEGFullFingerprintresJPEGFullResresJPEGLargeWidthresJPEGLargeHeightresJPEGLargeFileTyperesJPEGLargeFingerprintresJPEGLargeResresJPEGMedWidthresJPEGMedHeightresJPEGMedFileTyperesJPEGMedFingerprintresJPEGMedResresJPEGThumbWidthresJPEGThumbHeightresJPEGThumbFileTyperesJPEGThumbFingerprintresJPEGThumbResresVidFullWidthresVidFullHeightresVidFullFileTyperesVidFullFingerprintresVidFullResresVidMedWidthresVidMedHeightresVidMedFileTyperesVidMedFingerprintresVidMedResresVidSmallWidthresVidSmallHeightresVidSmallFileTyperesVidSmallFingerprintresVidSmallResresSidecarWidthresSidecarHeightresSidecarFileTyperesSidecarFingerprintresSidecarResitemTypedataClassTypefilenameEncoriginalOrientationresOriginalWidthresOriginalHeightresOriginalFileTyperesOriginalFingerprintresOriginalResresOriginalAltWidthresOriginalAltHeightresOriginalAltFileTyperesOriginalAltFingerprintresOriginalAltResresOriginalVidComplWidthresOriginalVidComplHeightresOriginalVidComplFileTyperesOriginalVidComplFingerprintresOriginalVidComplResr   r   dateExpungedremappedRefr   r   r   r   adjustmentRenderType	assetDate	addedDate
isFavoriteisHiddenorientationdurationassetSubtypeassetSubtypeV2assetHDRType
burstFlagsburstFlagsExtburstId
captionEnclocationEnclocationV2EnclocationLatitudelocationLongitudeadjustmentTypetimeZoneOffsetvidComplDurValuevidComplDurScalevidComplDispValuevidComplDispScalevidComplVisibilityStatecustomRenderedValuer  r  r  
isKeyAsset)r   r  desiredKeysr   r   r   )r   r  r   )r"   rV  r   r   rr  r   r   r&   r&   r'   r    s$   

cwzPhotoAlbum._list_query_gen)NNrJ  NNNr   )r(   r)   r*   r+   r   r   rc   rV   rS   r   r3   r4   r	   r   r!   r   ry   r   rh  r   rn  r  r  r  rw  rX  rY  r^  r  r,   r&   r&   r$   r'   r     s    	
%449,


r   c                   @   s"   e Zd ZdZded fddZdS )r   zA Photo Album Folder.r   r   c                 C      dS r  Nr&   r"   r
  r&   r&   r'   r    r   zPhotoAlbumFolder.uploadN)r(   r)   r*   r+   r   r  r&   r&   r&   r'   r     s    r   c                       s   e Zd ZdZ				ddededededed	e	d
e
eee	ef   de
ee	e	f  dede
e	 ddf fddZede	fddZde
d fddZede	fddZede	fddZ  ZS )r   zA Smart Photo Album.NrJ  r   r   r   r   r   r   r   r   rK  r   r   c                    s*   t  j||j|j|||||||	|
d d S )N)r   r   r   r   r   r   r   r   r   rK  r   )r    r!   r   )r"   r   r   r   r   r   r   r   r   rK  r   r$   r&   r'   r!     s   
zSmartPhotoAlbum.__init__c                 C   rd  rt  re  r   r&   r&   r'   ry     rg  zSmartPhotoAlbum.idr   c                 C   r  r	  r&   r
  r&   r&   r'   r    r   zSmartPhotoAlbum.uploadc                 C   rd  rR  re  r   r&   r&   r'   r     rg  zSmartPhotoAlbum.fullnamec                 C   s
   | j j S )zGets the container ID.)r  r   r   r&   r&   r'   r    rF  z!SmartPhotoAlbum._get_container_id)NNrJ  N)r(   r)   r*   r+   r   r?   rc   rV   rS   r   r   r3   r4   r	   r   r!   r   ry   r  r   r  r,   r&   r&   r$   r'   r     sH    
	
r   c                       sx  e Zd ZdZ						d7dededed	ed
edededededededee deddf fddZ	e
defddZe
defddZe
defddZe
defddZe
defddZe
defd d!Ze
dee fd"d#Zd$eded%edeeef fd&d'Zd(edeeef fd)d*Zd(edd+fd,d-Zdefd.d/Zdefd0d1Zdefd2d3Zd4eddfd5d6Z  ZS )8r0  zA Shared Stream Photo Album.ownedFNrJ  r   r   r&  r'  r(  r)  r*  r+  r,  r-  r.  r/  rK  r   c              
      s   t  j||tj|d || _|| _|| _|| _zt	t
|d tj| _W n tttfy9   t	dtj| _Y nw || _|	| _|
| _|| _|| _d S )N)r   r   r   rK       @@r   )r    r!   rV   rb   _album_location_album_ctag_album_guid_owner_dsidr   fromtimestampr   r   utcr*  r  r  OverflowError_sharing_type_allow_contributions
_is_public_is_web_upload_supported_public_url)r"   r   r   r&  r'  r(  r)  r*  r+  r,  r-  r.  r/  rK  r$   r&   r'   r!     s,   

zSharedPhotoStreamAlbum.__init__c                 C   rd  rt  )r  r   r&   r&   r'   ry     rg  zSharedPhotoStreamAlbum.idc                 C   rd  r   re  r   r&   r&   r'   r     s   zSharedPhotoStreamAlbum.fullnamec                 C   rd  )zGets the sharing type.)r  r   r&   r&   r'   r+    rg  z#SharedPhotoStreamAlbum.sharing_typec                 C   rd  )z"Gets if contributions are allowed.)r  r   r&   r&   r'   r,    rg  z*SharedPhotoStreamAlbum.allow_contributionsc                 C   rd  )zGets if the album is public.)r  r   r&   r&   r'   r-    rg  z SharedPhotoStreamAlbum.is_publicc                 C   rd  )z"Gets if web uploads are supported.)r  r   r&   r&   r'   r.  $  rg  z.SharedPhotoStreamAlbum.is_web_upload_supportedc                 C   rd  )zGets the public URL.)r  r   r&   r&   r'   r/  )  rg  z!SharedPhotoStreamAlbum.public_urlrV  r   c                 C   s   | j | jt|| t|dS )N)r  r  limitrV  )r  r  r   ru  r&   r&   r'   rY  .  s
   
z#SharedPhotoStreamAlbum._get_payloadr\  c                 C   rj  )Nz@_get_photo_payload is not implemented for SharedPhotoStreamAlbumr   rv  r&   r&   r'   r^  8  s   z)SharedPhotoStreamAlbum._get_photo_payloadr   c                 C   sd   d}	 |  |tj| j}d}|D ]}|d7 }|j|kr|  S q|| jk r&n||7 }qtd| )z
        Fetch a single photo by id by paging through the shared stream.
        This avoids an upfront call to get the album size and does not
        require fetching the entire album in one request.
        r   Tr   r]  )r[  rS   rT   rK  ry   r   )r"   r\  rV  pagephoto_countr   r&   r&   r'   r_  @  s   


z!SharedPhotoStreamAlbum._get_photoc                 C   s   | j  dt| jj S )Nzwebgetassets?)r  r   r   r   r   r&   r&   r'   rX  S  r|  zSharedPhotoStreamAlbum._get_urlc                 C   sF   | j  dt| jj }| jjj|d| jittid}|	 }|d S )Nzwebgetassetcount?r  r  albumassetcount)
r  r   r   r   r   r   r  r   r   r   r  r&   r&   r'   rw  V  s   zSharedPhotoStreamAlbum._get_lenc                 C   r  )rm  Fr&   r   r&   r&   r'   rn  e  r   zSharedPhotoStreamAlbum.deleter   c                 C   r  )rk  Nr&   ri  r&   r&   r'   rh  j  r   zSharedPhotoStreamAlbum.rename)r  FFFNrJ  )r(   r)   r*   r+   r   r   r   r   r   r!   r   ry   r   r+  r,  r-  r.  r/  rS   r4   r	   rY  r^  r_  rX  rw  rn  rh  r,   r&   r&   r$   r'   r0    s    	
)


r0  c                   @   s  e Zd ZU dZdedeeef deeef ddfddZd	d	d	d
dZ	eeef e
d< dddddZeeef e
d< dddddddZeeef e
d< ddddddZeeef e
d< edefddZedefddZedefd d!Zedefd"d#Zed$d% Zedefd&d'ZdEd)ed*edefd+d,Zedefd-d.Zedefd/d0Zed1d2 Zedefd3d4Zedefd5d6Zedeeeeef f fd7d8ZdFdee fd:d;Zd<edeeef fd=d>Z dFdee! fd?d@Z"defdAdBZ#defdCdDZ$dS )Gr   zA photo.r   r`  rb  r   Nc                 C   s   || _ || _|| _d | _d S r   )_service_master_record_asset_record	_versions)r"   r   r`  rb  r&   r&   r'   r!   s  s   
zPhotoAsset.__init__imagemovie)zpublic.heiczpublic.jpegz
public.pngzcom.apple.quicktime-movie
ITEM_TYPESz.HEICz.JPGz.PNG.MOVFILE_TYPE_EXTENSIONSresOriginal
resJPEGMedresJPEGThumbresOriginalVidCompl	resVidMedresVidSmall)originalmediumthumboriginal_videomedium_videothumb_videoPHOTO_VERSION_LOOKUP)r,  r-  r.  thumb_imagemedium_imageVIDEO_VERSION_LOOKUPc                 C   
   | j d S )zGets the photo id.r   r  r   r&   r&   r'   ry     rF  zPhotoAsset.idc                 C   r6  )z(Gets the master record id for the photo.r   r  r   r&   r&   r'   r     rF  zPhotoAsset.master_idc                 C   r6  )z'Gets the asset record id for the photo.r   r7  r   r&   r&   r'   asset_id  rF  zPhotoAsset.asset_idc                 C   s   t | jd d d dS )zGets the photo file name.r   r  r   r   )r   r   r  r   r   r&   r&   r'   r    s
   zPhotoAsset.filenamec                 C   s   | j d d d d S )zGets the photo size.r   r  r   sizer8  r   r&   r&   r'   r:    s   zPhotoAsset.sizec                 C   rd  )zGets the photo created date.)
asset_dater   r&   r&   r'   created  rg  zPhotoAsset.createdF
field_namemasterc                 C   s^   z|r| j n| j}|d | d }t|d tjW S  tttt	fy.   tdtj Y S w )zDRead a millisecond timestamp field from the master or asset records.r   r   r  r   )
r  r  r   r  r   r  r   r  r  r  )r"   r=  r>  r7   	raw_valuer&   r&   r'   _record_timestamp  s   zPhotoAsset._record_timestampc                 C   
   |  dS )Gets the photo asset date.r  r@  r   r&   r&   r'   r;    rF  zPhotoAsset.asset_datec                 C   rA  )zGets the photo added date.r  rC  r   r&   r&   r'   
added_date  rF  zPhotoAsset.added_datec                 C   s$   | j d d d | j d d d fS )zGets the photo dimensions.r   r  r   r  r8  r   r&   r&   r'   
dimensions  s   zPhotoAsset.dimensionsc                 C   s   d}z| j d d d }W n ty+   z| j d d d }W n	 ty(   Y nw Y nw || jv r6| j| S | j dr@dS dS )	zGets the photo item type.r  r   r  r   r  )z.heicz.pngz.jpgz.jpegr!  r"  )r  r   r#  r  lowerendswith)r"   	item_typer&   r&   r'   rH    s$   

zPhotoAsset.item_typec                 C   s   | j dkod| jd v S )z#Check if the photo is a live photo.r!  r  r   )rH  r  r   r&   r&   r'   is_live_photo  s   
zPhotoAsset.is_live_photoc                 C   s`   | j s-i | _ | jdkr| j}n| j}| D ]\}}| d| jd v r,| || j |< q| j S )zGets the photo versions.r"  Resr   )r   rH  r5  r2  r   r  _get_photo_version)r"   typed_version_lookupr   prefixr&   r&   r'   versions  s   
zPhotoAsset.versionsr,  c                 C   s   || j vrdS | j | d S )zReturns the photo download URL.Nr   )rN  )r"   versionr&   r&   r'   download_url  s   
zPhotoAsset.download_urlrM  c                 C   s:  i }| j d }|| d}|r|d |d< nd |d< || d}|r-|d |d< nd |d< || d}|rL|d d |d< |d d	 |d
< nd |d< d |d
< || d}|re|d |d< nd |d< | j|d< | jr|d}|r| j|d dkrtj| j\}	}
| j|d}|	 | }||d< |S )Nr   Widthr   widthHeightheightrJ  r:  downloadURLr   FileTyper   r  r"  r$  )	r  r1   r  rI  r#  r  r
  splitextr%  )r"   rM  rO  r   width_entryheight_entry
size_entry
type_entryversion_typefilename_base_	extensionlive_photo_video_filenamer&   r&   r'   rK    s:   


zPhotoAsset._get_photo_versionc                 K   s<   || j vrdS | jjj| j | d fddi|}|j S )zReturns the photo file.Nr   streamT)rN  r  r   r1   rawread)r"   rO  kwargsr   r&   r&   r'   download9  s   

zPhotoAsset.downloadc                 C   s6  | j j}t| j j}| d| }| j jj|d| jd | jd | jd| jddddiid	d
g| jd ddt	t
id}|jdkrGdS | }|drRdS |d}t|tr|D ]}t|trm|drm dS q^|r|d }t|tr|di }	t|	tr|	di }
t|
trd|
v rt|
d S dS )zDeletes the photo.r   r8  r   r   r   r   r   r   r  r   r   Tr   r     Fr.   r/   r0   r   r   )r  r   r   r   r   r   r  r1   r  r   r   status_coder   r2   r3   r4   r   )r"   r  r   r   r  r-   r/   r7   r   r   
is_deletedr&   r&   r'   rn  E  sR   







zPhotoAsset.deletec                 C   s   dt | j d| j dS )Nrz  z: id=>)r   r(   ry   r   r&   r&   r'   r{  u  s   zPhotoAsset.__repr__)F)r,  )%r(   r)   r*   r+   r   r4   r   r	   r!   r#  r  r%  r2  r5  r   ry   r   r9  r  r:  r   r<  r   r@  r;  rD  rE  rH  rI  rN  r   rP  rK  bytesre  rn  r{  r&   r&   r&   r'   r   p  s   
 




	
 -0r   c                   @   sX   e Zd ZdZedefddZedefddZede	fddZ
edefd	d
ZdS )r  zA Shared Stream Photo Assetr   c                 C   s   | j di di ddS )zGets the photo like count.pluginFields	likeCountr   r   )r  r1   r   r&   r&   r'   
like_count|  s   zPhotoStreamAsset.like_countc                 C   s"   t | jdi di ddS )zGets if the photo is liked.rk  likedByCallerr   F)r   r  r1   r   r&   r&   r'   liked  s
   zPhotoStreamAsset.likedc                 C   s   | j dddS )rB  originalCreationDateT)r>  rC  r   r&   r&   r'   r;    s   zPhotoStreamAsset.asset_datec              
   C   sZ   z| j di }|di }|dd}|durt|W S dW S  tttfy,   Y dS w )zGets the photo asset size.r   resOriginalFileSizer   r   N)r  r1   r   r   r  r  )r"   r   res_sizer   r&   r&   r'   r:    s   zPhotoStreamAsset.sizeN)r(   r)   r*   r+   r   r   rm  r   ro  r   r;  r:  r&   r&   r&   r'   r  y  s    r  )?r+   r   loggingr  abcr   r   r   r   enumr   r   r   typingr	   r
   r   r   r   r   urllib.parser   requestsr   pyicloud.constr   r   pyicloud.exceptionsr   r   r   pyicloud.services.baser   pyicloud.sessionr   	getLoggerr(   r   Loggerr  r   r4   r   r3   r8   r9   r?   rS   rV   rc   ru   rv   r   r   r  r   rx   r   r   r   r0  r   r  r&   r&   r&   r'   <module>   s`     &>=   &f X   H	3   