
    lju                       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	m
Z
mZmZ d dlmZmZ d dl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  edd      Z edd      Z  G d dee      Z!ejD                   G d de!e             Z#ejD                   G d de!e             Z$ejD                   G d de!ee             Z%ejD                   G d dee%             Z&ejD                   G d dee%             Z'y)    )annotationsN)Path)
quote_plus)AnyDictListOptionalTypeVar)mediautils)PlayablePlexPartialObjectPlexHistoryPlexSessioncached_data_property)
BadRequest)ArtistMixinsAlbumMixinsTrackMixinsPlayedUnplayedMixin)PlaylistTAudioAudio)boundTTrackTrackc                      e Zd ZdZdZd Zed        Zed        Zed        Z	d Z
d Zed	        ZddZ	 	 d	 	 	 	 	 	 	 ddZy
)r   a   Base class for all audio objects including :class:`~plexapi.audio.Artist`,
        :class:`~plexapi.audio.Album`, and :class:`~plexapi.audio.Track`.

        Attributes:
            addedAt (datetime): Datetime the item was added to the library.
            art (str): URL to artwork image (/library/metadata/<ratingKey>/art/<artid>).
            artBlurHash (str): BlurHash string for artwork image.
            distance (float): Sonic Distance of the item from the seed item.
            fields (List<:class:`~plexapi.media.Field`>): List of field objects.
            guid (str): Plex GUID for the artist, album, or track (plex://artist/5d07bcb0403c64029053ac4c).
            images (List<:class:`~plexapi.media.Image`>): List of image objects.
            index (int): Plex index number (often the track number).
            key (str): API URL (/library/metadata/<ratingkey>).
            lastRatedAt (datetime): Datetime the item was last rated.
            lastViewedAt (datetime): Datetime the item was last played.
            librarySectionID (int): :class:`~plexapi.library.LibrarySection` ID.
            librarySectionKey (str): :class:`~plexapi.library.LibrarySection` key.
            librarySectionTitle (str): :class:`~plexapi.library.LibrarySection` title.
            listType (str): Hardcoded as 'audio' (useful for search filters).
            moods (List<:class:`~plexapi.media.Mood`>): List of mood objects.
            musicAnalysisVersion (int): The Plex music analysis version for the item.
            ratingKey (int): Unique key identifying the item.
            summary (str): Summary of the artist, album, or track.
            thumb (str): URL to thumbnail image (/library/metadata/<ratingKey>/thumb/<thumbid>).
            thumbBlurHash (str): BlurHash string for thumbnail image.
            title (str): Name of the artist, album, or track (Jason Mraz, We Sing, Lucky, etc.).
            titleSort (str): Title to use when sorting (defaults to title).
            type (str): 'artist', 'album', or 'track'.
            updatedAt (datetime): Datetime the item was updated.
            userRating (float): Rating of the item (0.0 - 10.0) equaling (0 stars - 5 stars).
            viewCount (int): Count of times the item was played.
    trackc                   t        j                  |j                  j                  d            | _        |j                  j                  d      | _        |j                  j                  d      | _        t        j                  t        |j                  j                  d            | _	        |j                  j                  d      | _
        t        j                  t        |j                  j                  d            | _        |j                  j                  dd      | _        t        j                  |j                  j                  d	            | _        t        j                  |j                  j                  d
            | _        t        j                  t        |j                  j                  d            | _        |j                  j                  d      | _        |j                  j                  d      | _        d| _        t        j                  t        |j                  j                  d            | _        t        j                  t        |j                  j                  d            | _        |j                  j                  d      | _        |j                  j                  d      | _        |j                  j                  d      | _        |j                  j                  d      | _        |j                  j                  d| j2                        | _        |j                  j                  d      | _        t        j                  |j                  j                  d            | _        t        j                  t        |j                  j                  d            | _        t        j                  t        |j                  j                  dd            | _        y)/ Load attribute values from Plex XML response. addedAtartartBlurHashdistanceguidindexkey lastRatedAtlastViewedAtlibrarySectionIDlibrarySectionKeylibrarySectionTitleaudiomusicAnalysisVersion	ratingKeysummarythumbthumbBlurHashtitle	titleSorttype	updatedAt
userRating	viewCountr   N)r   
toDatetimeattribgetr!   r"   r#   castfloatr$   r%   intr&   r'   r)   r*   r+   r,   r-   listTyper/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   selfdatas     :/DATA/.local/lib/python3.12/site-packages/plexapi/audio.py	_loadDatazAudio._loadData7   sd   ''	(BC;;??5);;??=9

5$++//**EFKKOOF+	ZZT[[__W%=>
;;??5"- ++DKKOOM,JK!,,T[[__^-LM %

3@R0S T!%1D!E#';;??3H#I $)JJsDKKOODZ4[$\!C)EF{{y1[[__W-
![[___=[[__W-
djjAKKOOF+	))$++//+*FG**UDKKOOL,IJCa)HI    c                V    | j                  | j                  t        j                        S N)	findItems_datar   FieldrB   s    rD   fieldszAudio.fieldsR       ~~djj%++66rF   c                V    | j                  | j                  t        j                        S rH   )rI   rJ   r   ImagerL   s    rD   imageszAudio.imagesV   rN   rF   c                V    | j                  | j                  t        j                        S rH   )rI   rJ   r   MoodrL   s    rD   moodszAudio.moodsZ       ~~djj%**55rF   c                D    |r| j                   j                  |d      S dS )zW Returns the full URL for the audio item. Typically used for getting a specific track. T)includeTokenN)_serverurlrB   parts     rD   rY   z	Audio.url^   s#    <@t||48JdJrF   c                    | j                   S )0 Returns str, default title for a new syncItem. )r4   rL   s    rD   _defaultSyncTitlezAudio._defaultSyncTitleb   s    zzrF   c                     | j                   dk(  S )z8 Returns True if the audio has been sonically analyzed.    )r/   rL   s    rD   hasSonicAnalysiszAudio.hasSonicAnalysisf   s     ((A--rF   Nc                p   ddl m}m}m} | j                  j                         }	 || j                  d      }
|r|n| j                         |
_        | j                  |
_        | j                  |
_
        | j                  |
_        | j                  j                  |
_        | j                  j                  j                  | j                         }d|j"                   dt%        | j&                         |
_        |j+                  |      |
_        |j/                  |      |
_        |	j3                  |
||      S )a   Add current audio (artist, album or track) as sync item for specified device.
            See :func:`~plexapi.myplex.MyPlexAccount.sync` for possible exceptions.

            Parameters:
                bitrate (int): maximum bitrate for synchronized music, better use one of MUSIC_BITRATE_* values from the
                               module :mod:`~plexapi.sync`.
                client (:class:`~plexapi.myplex.MyPlexDevice`): sync destination, see
                                                               :func:`~plexapi.myplex.MyPlexAccount.sync`.
                clientId (str): sync destination, see :func:`~plexapi.myplex.MyPlexAccount.sync`.
                limit (int): maximum count of items to sync, unlimited if `None`.
                title (str): descriptive title for the new :class:`~plexapi.sync.SyncItem`, if empty the value would be
                             generated from metadata of current media.

            Returns:
                :class:`~plexapi.sync.SyncItem`: an instance of created syncItem.
        r   )SyncItemPolicyMediaSettingsNz
library://z/item/)clientclientId)plexapi.syncrc   rd   re   rX   myPlexAccountr^   r4   	rootTitler@   contentTypeMETADATA_TYPEmetadataTypemachineIdentifierlibrarysectionByIDr+   uuidr   r'   locationcreatepolicycreateMusicmediaSettingssync)rB   bitraterf   rg   limitr4   rc   rd   re   myplex	sync_itemsections               rD   rw   z
Audio.synck   s    $ 	A@++-T\\40	#(%d.D.D.F	"jj	 $	!%!3!3	&*ll&D&D	#,,&&2243H3HI)',,vj>R=ST	!==/	"/";";G"D	{{9Vh{GGrF   c                    | j                    d}i }|||d<   |||d<   |t        j                  |      z  } | j                  |fdt	        |       i|S )a  Returns a list of sonically similar audio items.

        Parameters:
            limit (int): Maximum count of items to return. Default 50 (server default)
            maxDistance (float): Maximum distance between tracks, 0.0 - 1.0. Default 0.25 (server default).
            **kwargs: Additional options passed into :func:`~plexapi.base.PlexObject.fetchItems`.

        Returns:
            List[:class:`~plexapi.audio.Audio`]: list of sonically similar audio items.
        z/nearestry   maxDistancecls)r'   r   joinArgs
fetchItemsr6   )rB   ry   r~   kwargsr'   paramss         rD   sonicallySimilarzAudio.sonicallySimilar   sw    " 
(#!##F7O"$/F=!u~~f%%t
T

 
 	
rF   )NNNNNN)rB   r   ry   zOptional[int]r~   zOptional[float]returnzList[TAudio])__name__
__module____qualname____doc__rl   rE   r   rM   rQ   rT   rY   r^   propertyra   rw   r    rF   rD   r   r      s    @ MJ6 7 7 7 7 6 6K . ."HL  $'+


 %

 

rF   c                      e Zd ZdZdZdZd Zed        Zed        Z	ed        Z
ed        Zed	        Zed
        Zed        Zed        Zed        Zd Zd Zd ZddZd ZddZddZd Zd Zed        Zy)ArtistaC   Represents a single Artist.

        Attributes:
            TAG (str): 'Directory'
            TYPE (str): 'artist'
            albumSort (int): Setting that indicates how albums are sorted for the artist
                (-1 = Library default, 0 = Newest first, 1 = Oldest first, 2 = By name).
            audienceRating (float): Audience rating.
            collections (List<:class:`~plexapi.media.Collection`>): List of collection objects.
            countries (List<:class:`~plexapi.media.Country`>): List country objects.
            genres (List<:class:`~plexapi.media.Genre`>): List of genre objects.
            guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
            key (str): API URL (/library/metadata/<ratingkey>).
            labels (List<:class:`~plexapi.media.Label`>): List of label objects.
            locations (List<str>): List of folder paths where the artist is found on disk.
            rating (float): Artist rating (7.9; 9.8; 8.1).
            similar (List<:class:`~plexapi.media.Similar`>): List of similar objects.
            styles (List<:class:`~plexapi.media.Style`>): List of style objects.
            theme (str): URL to theme resource (/library/metadata/<ratingkey>/theme/<themeid>).
            ultraBlurColors (:class:`~plexapi.media.UltraBlurColors`): Ultra blur color object.
    	Directoryartistc                   t         j                  | |       t        j                  t        |j
                  j                  dd            | _        t        j                  t        |j
                  j                  d            | _	        | j                  j                  dd      | _
        t        j                  t        |j
                  j                  d            | _        |j
                  j                  d      | _        y)	r    	albumSortz-1audienceRating	/childrenr(   ratingthemeN)r   rE   r   r=   r?   r;   r<   r   r>   r   r'   replacer   r   rA   s     rD   rE   zArtist._loadData   s    d#Cd)KL#jj@P0QR88##K4jj(AB[[__W-
rF   c                V    | j                  | j                  t        j                        S rH   rI   rJ   r   
CollectionrL   s    rD   collectionszArtist.collections       ~~djj%*:*:;;rF   c                V    | j                  | j                  t        j                        S rH   )rI   rJ   r   CountryrL   s    rD   	countrieszArtist.countries       ~~djj%--88rF   c                V    | j                  | j                  t        j                        S rH   rI   rJ   r   GenrerL   s    rD   genreszArtist.genres   rN   rF   c                V    | j                  | j                  t        j                        S rH   rI   rJ   r   GuidrL   s    rD   guidszArtist.guids   rU   rF   c                V    | j                  | j                  t        j                        S rH   rI   rJ   r   LabelrL   s    rD   labelszArtist.labels   rN   rF   c                >    | j                  | j                  dd      S )NpathLocation)etag)	listAttrsrJ   rL   s    rD   	locationszArtist.locations   s    ~~djj&z~BBrF   c                V    | j                  | j                  t        j                        S rH   )rI   rJ   r   SimilarrL   s    rD   similarzArtist.similar   r   rF   c                V    | j                  | j                  t        j                        S rH   rI   rJ   r   StylerL   s    rD   styleszArtist.styles   rN   rF   c                V    | j                  | j                  t        j                        S rH   findItemrJ   r   UltraBlurColorsrL   s    rD   ultraBlurColorszArtist.ultraBlurColors       }}TZZ)>)>??rF   c              #  >   K   | j                         D ]  }|  y wrH   )albums)rB   albums     rD   __iter__zArtist.__iter__        [[]EK #   c                ^    | j                         j                  |dd| j                  i      S )z Returns the :class:`~plexapi.audio.Album` that matches the specified title.

            Parameters:
                title (str): Title of the album to return.
        r   	artist.id)r4   libtypefilters)r|   r<   r0   )rB   r4   s     rD   r   zArtist.album   s4     ||~!! $..1 " 
 	
rF   c           	          | j                         j                  ddi |j                  di       d| j                  id|S )zH Returns a list of :class:`~plexapi.audio.Album` objects by the artist. r   r   r   )r   r   r   )r|   searchpopr0   )rB   r   s     rD   r   zArtist.albums  sM    $t||~$$ 
Nvzz)R0N+t~~N
 
 	
rF   Nc                    | j                    d}|| j                  |t        |      S ||| j                  |t        ||      S t        d      )a   Returns the :class:`~plexapi.audio.Track` that matches the specified title.

            Parameters:
                title (str): Title of the track to return.
                album (str): Album name (default: None; required if title not specified).
                track (int): Track number (default: None; required if title not specified).

            Raises:
                :exc:`~plexapi.exceptions.BadRequest`: If title or album and track parameters are missing.
        
/allLeavestitle__iexactparentTitle__iexactr&   z7Missing argument: title or album and track are required)r'   	fetchItemr   r   )rB   r4   r   r   r'   s        rD   r   zArtist.track  s]     
*%>>#uE>BB5#4>>#u%u>UURSSrF   c                P    | j                    d} | j                  |t        fi |S )zH Returns a list of :class:`~plexapi.audio.Track` objects by the artist. r   r'   r   r   rB   r   r'   s      rD   trackszArtist.tracks"  s*    
*%tsE4V44rF   c                (    | j                  |||      S )z/ Alias of :func:`~plexapi.audio.Artist.track`. r   )rB   r4   r   r   s       rD   r<   z
Artist.get'  s    zz%..rF   c                    g }| j                         D ]G  }|r*t        j                  j                  ||j                        n|}| |j
                  ||fi |z  }I |S )a	   Download all tracks from the artist. See :func:`~plexapi.base.Playable.download` for details.

            Parameters:
                savepath (str): Defaults to current working dir.
                keep_original_name (bool): True to keep the original filename otherwise
                    a friendlier filename is generated.
                subfolders (bool): True to separate tracks in to album folders.
                **kwargs: Additional options passed into :func:`~plexapi.base.PlexObject.getStreamURL`.
        )r   osr   joinparentTitledownload)rB   savepathkeep_original_name
subfoldersr   	filepathsr   	_savepaths           rD   r   zArtist.download+  s]     	[[]EEOXu/@/@AU]I	3EPPPI # rF   c                j    d| j                   ddd}| j                         j                  d|dd      S )	zO Returns a list of :class:`~plexapi.audio.Track` popular tracks by the artist. zCompilation,Liver4   r   )zalbum.subformat!r   groupzratingCount>>r   zratingCount:descd   )r   r   sortry   )r0   r|   r   )rB   r   s     rD   popularTrackszArtist.popularTracks;  sG     !3	
 ||~$$#	 % 
 	
rF   c           	     v    | j                    d}t        t        | j                  |t        d            d      S )zO Returns a :class:`~plexapi.playlist.Playlist` artist radio station or `None`. z?includeStations=1Stations)r   rtagN)r'   nextiterr   r   )rB   r'   s     rD   stationzArtist.stationJ  s4    
,-D(LMtTTrF   c                    t        j                  | j                        }t        t	        d      dz  |d   z  |dd  dz        S )L Returns the Plex Media Server data directory where the metadata is stored. MetadataArtistsr   r`   N.bundler   sha1hashr%   strr   rB   	guid_hashs     rD   metadataDirectoryzArtist.metadataDirectoryO  sG     NN499-	4
#i/)A,>IabM?RYAZZ[[rF   )NNN)NFF)r   r   r   r   TAGTYPErE   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r<   r   r   r   r   r   r   rF   rD   r   r      s   * CD. < < 9 9 7 7 6 6 7 7 C C 9 9 7 7 @ @


T$5
/ 
U
 \ \rF   r   c                      e Zd ZdZdZdZd Zed        Zed        Z	ed        Z
ed        Zed	        Zed
        Zed        Zed        Zd ZddZd ZddZd ZddZd Zed        Zy)Albuma   Represents a single Album.

        Attributes:
            TAG (str): 'Directory'
            TYPE (str): 'album'
            audienceRating (float): Audience rating.
            collections (List<:class:`~plexapi.media.Collection`>): List of collection objects.
            formats (List<:class:`~plexapi.media.Format`>): List of format objects.
            genres (List<:class:`~plexapi.media.Genre`>): List of genre objects.
            guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
            key (str): API URL (/library/metadata/<ratingkey>).
            labels (List<:class:`~plexapi.media.Label`>): List of label objects.
            leafCount (int): Number of items in the album view.
            loudnessAnalysisVersion (int): The Plex loudness analysis version level.
            originallyAvailableAt (datetime): Datetime the album was released.
            parentGuid (str): Plex GUID for the album artist (plex://artist/5d07bcb0403c64029053ac4c).
            parentKey (str): API URL of the album artist (/library/metadata/<parentRatingKey>).
            parentRatingKey (int): Unique key identifying the album artist.
            parentTheme (str): URL to artist theme resource (/library/metadata/<parentRatingkey>/theme/<themeid>).
            parentThumb (str): URL to album artist thumbnail image (/library/metadata/<parentRatingKey>/thumb/<thumbid>).
            parentTitle (str): Name of the album artist.
            rating (float): Album rating (7.9; 9.8; 8.1).
            studio (str): Studio that released the album.
            styles (List<:class:`~plexapi.media.Style`>): List of style objects.
            subformats (List<:class:`~plexapi.media.Subformat`>): List of subformat objects.
            ultraBlurColors (:class:`~plexapi.media.UltraBlurColors`): Ultra blur color object.
            viewedLeafCount (int): Number of items marked as played in the album view.
            year (int): Year the album was released.
    r   r   c                j   t         j                  | |       t        j                  t        |j
                  j                  d            | _        | j                  j                  dd      | _        t        j                  t        |j
                  j                  d            | _        t        j                  t        |j
                  j                  d            | _        t        j                  |j
                  j                  d      d      | _        |j
                  j                  d      | _        |j
                  j                  d	      | _        t        j                  t        |j
                  j                  d
            | _        |j
                  j                  d      | _        |j
                  j                  d      | _        |j
                  j                  d      | _        t        j                  t        |j
                  j                  d            | _        |j
                  j                  d      | _        t        j                  t        |j
                  j                  d            | _        t        j                  t        |j
                  j                  d            | _        y)r    r   r   r(   	leafCountloudnessAnalysisVersionoriginallyAvailableAtz%Y-%m-%d
parentGuid	parentKeyparentRatingKeyparentThemeparentThumbr   r   studioviewedLeafCountyearN)r   rE   r   r=   r>   r;   r<   r   r'   r   r?   r   r   r:   r  r  r  r  r  r  r   r   r  r  r	  rA   s     rD   rE   zAlbum._loadDataz  s   d##jj@P0QR88##K4C)EF',zz#t{{G`7a'b$%*%5%5dkkooF]6^`j%k"++//,75$zz#t{{?P/QR;;??=9;;??=9;;??=9jj(ABkkooh/$zz#t{{?P/QRJJsDKKOOF$;<	rF   c                V    | j                  | j                  t        j                        S rH   r   rL   s    rD   r   zAlbum.collections  r   rF   c                V    | j                  | j                  t        j                        S rH   )rI   rJ   r   FormatrL   s    rD   formatszAlbum.formats  s    ~~djj%,,77rF   c                V    | j                  | j                  t        j                        S rH   r   rL   s    rD   r   zAlbum.genres  rN   rF   c                V    | j                  | j                  t        j                        S rH   r   rL   s    rD   r   zAlbum.guids  rU   rF   c                V    | j                  | j                  t        j                        S rH   r   rL   s    rD   r   zAlbum.labels  rN   rF   c                V    | j                  | j                  t        j                        S rH   r   rL   s    rD   r   zAlbum.styles  rN   rF   c                V    | j                  | j                  t        j                        S rH   )rI   rJ   r   	SubformatrL   s    rD   
subformatszAlbum.subformats  s    ~~djj%//::rF   c                V    | j                  | j                  t        j                        S rH   r   rL   s    rD   r   zAlbum.ultraBlurColors  r   rF   c              #  >   K   | j                         D ]  }|  y wrH   )r   )rB   r   s     rD   r   zAlbum.__iter__  r   r   Nc                   | j                    d}|(t        |t              s| j                  |t        |      S |t        |t              r8t        |t              r|}n|}| j                  |t        | j
                  |      S t        d      )ay   Returns the :class:`~plexapi.audio.Track` that matches the specified title.

            Parameters:
                title (str): Title of the track to return.
                track (int): Track number (default: None; required if title not specified).

            Raises:
                :exc:`~plexapi.exceptions.BadRequest`: If title or track parameter is missing.
        r   r   r   z,Missing argument: title or track is required)r'   
isinstancer?   r   r   r4   r   )rB   r4   r   r'   r&   s        rD   r   zAlbum.track  s     
)$Zs%;>>#uE>BB*UC"8%%>>#u$**TY>ZZGHHrF   c                P    | j                    d} | j                  |t        fi |S )zG Returns a list of :class:`~plexapi.audio.Track` objects in the album. r   r   r   s      rD   r   zAlbum.tracks  s*    
)$tsE4V44rF   c                &    | j                  ||      S )z. Alias of :func:`~plexapi.audio.Album.track`. r   )rB   r4   r   s      rD   r<   z	Album.get  s    zz%''rF   c                8    | j                  | j                        S )z4 Return the album's :class:`~plexapi.audio.Artist`. r   r  rL   s    rD   r   zAlbum.artist      ~~dnn--rF   c                b    g }| j                         D ]  }| |j                  ||fi |z  } |S )a   Download all tracks from the album. See :func:`~plexapi.base.Playable.download` for details.

            Parameters:
                savepath (str): Defaults to current working dir.
                keep_original_name (bool): True to keep the original filename otherwise
                    a friendlier filename is generated.
                **kwargs: Additional options passed into :func:`~plexapi.base.PlexObject.getStreamURL`.
        )r   r   )rB   r   r   r   r   r   s         rD   r   zAlbum.download  s<     	[[]E2DOOOI #rF   c                8    | j                    d| j                   S r]    - )r   r4   rL   s    rD   r^   zAlbum._defaultSyncTitle  s    ""#3tzzl33rF   c                    t        j                  | j                        }t        t	        d      dz  |d   z  |dd  dz        S r   r   Albumsr   r`   Nr   r   r   s     rD   r   zAlbum.metadataDirectory  sG     NN499-	4
#h.1=9QR=/QX@YYZZrF   r   )NF)r   r   r   r   r   r   rE   r   r   r  r   r   r   r   r  r   r   r   r   r<   r   r   r^   r   r   r   rF   rD   r   r   V  s    : CD=& < < 8 8 7 7 6 6 7 7 7 7 ; ; @ @I*5
(.4 [ [rF   r   c                      e Zd ZdZd ZdZd Zed        Zed        Z	ed        Z
ed        Zed        Zed	        Zed
        Zed        Zd Zd Zd Zd ZddZed        Z	 	 	 	 	 	 	 	 ddZy)r   a
   Represents a single Track.

        Attributes:
            TAG (str): 'Directory'
            TYPE (str): 'track'
            audienceRating (float): Audience rating.
            chapters (List<:class:`~plexapi.media.Chapter`>): List of Chapter objects.
            chapterSource (str): Unknown
            collections (List<:class:`~plexapi.media.Collection`>): List of collection objects.
            duration (int): Length of the track in milliseconds.
            genres (List<:class:`~plexapi.media.Genre`>): List of genre objects.
            grandparentArt (str): URL to album artist artwork (/library/metadata/<grandparentRatingKey>/art/<artid>).
            grandparentGuid (str): Plex GUID for the album artist (plex://artist/5d07bcb0403c64029053ac4c).
            grandparentKey (str): API URL of the album artist (/library/metadata/<grandparentRatingKey>).
            grandparentRatingKey (int): Unique key identifying the album artist.
            grandparentTheme (str): URL to artist theme resource  (/library/metadata/<grandparentRatingkey>/theme/<themeid>).
                (/library/metadata/<grandparentRatingkey>/theme/<themeid>).
            grandparentThumb (str): URL to album artist thumbnail image
                (/library/metadata/<grandparentRatingKey>/thumb/<thumbid>).
            grandparentTitle (str): Name of the album artist for the track.
            guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
            labels (List<:class:`~plexapi.media.Label`>): List of label objects.
            media (List<:class:`~plexapi.media.Media`>): List of media objects.
            originalTitle (str): The artist for the track.
            parentGuid (str): Plex GUID for the album (plex://album/5d07cd8e403c640290f180f9).
            parentIndex (int): Disc number of the track.
            parentKey (str): API URL of the album (/library/metadata/<parentRatingKey>).
            parentRatingKey (int): Unique key identifying the album.
            parentThumb (str): URL to album thumbnail image (/library/metadata/<parentRatingKey>/thumb/<thumbid>).
            parentTitle (str): Name of the album for the track.
            primaryExtraKey (str) API URL for the primary extra for the track.
            rating (float): Track rating (7.9; 9.8; 8.1).
            ratingCount (int): Number of listeners who have scrobbled this track, as reported by Last.fm.
            skipCount (int): Number of times the track has been skipped.
            sourceURI (str): Remote server URI (server://<machineIdentifier>/com.plexapp.plugins.library)
                (remote playlist item only).
            viewOffset (int): View offset in milliseconds.
            year (int): Year the track was released.
    r   c                >   t         j                  | |       t        j                  | |       t        j                  t
        |j                  j                  d            | _        |j                  j                  d      | _	        t        j                  t        |j                  j                  d            | _        |j                  j                  d      | _        |j                  j                  d      | _        |j                  j                  d      | _        t        j                  t        |j                  j                  d            | _        |j                  j                  d      | _        |j                  j                  d	      | _        |j                  j                  d
      | _        |j                  j                  d      | _        |j                  j                  d      | _        t        j                  t        |j                  j                  d            | _        |j                  j                  d      | _        t        j                  t        |j                  j                  d            | _        |j                  j                  d      | _        |j                  j                  d      | _        |j                  j                  d      | _        t        j                  t
        |j                  j                  d            | _        t        j                  t        |j                  j                  d            | _        t        j                  t        |j                  j                  d            | _        |j                  j                  d      | _        t        j                  t        |j                  j                  dd            | _        t        j                  t        |j                  j                  d            | _         y)r    r   chapterSourcedurationgrandparentArtgrandparentGuidgrandparentKeygrandparentRatingKeygrandparentThemegrandparentThumbgrandparentTitleoriginalTitler  parentIndexr  r  r  r   primaryExtraKeyr   ratingCount	skipCountsource
viewOffsetr   r	  N)!r   rE   r   r   r=   r>   r;   r<   r   r'  r?   r(  r)  r*  r+  r,  r-  r.  r/  r0  r  r1  r  r  r  r   r2  r   r3  r4  	sourceURIr6  r	  rA   s     rD   rE   zTrack._loadData  s   d#4&#jj@P0QR![[___=

3
(CD"kkoo.>?#{{/@A"kkoo.>?$)JJsDKKOODZ4[$\! $0B C $0B C $0B C![[___=++//,7 ::c4;;??=+IJ5$zz#t{{?P/QR;;??=9;;??=9#{{/@Ajj(AB ::c4;;??=+IJC)EF2**S$++//,*JKJJsDKKOOF$;<	rF   c                V    | j                  | j                  t        j                        S rH   )rI   rJ   r   ChapterrL   s    rD   chapterszTrack.chapters7  r   rF   c                V    | j                  | j                  t        j                        S rH   r   rL   s    rD   r   zTrack.collections;  r   rF   c                V    | j                  | j                  t        j                        S rH   r   rL   s    rD   r   zTrack.genres?  rN   rF   c                V    | j                  | j                  t        j                        S rH   r   rL   s    rD   r   zTrack.guidsC  rU   rF   c                V    | j                  | j                  t        j                        S rH   r   rL   s    rD   r   zTrack.labelsG  rN   rF   c                V    | j                  | j                  t        j                        S rH   )rI   rJ   r   MediarL   s    rD   r   zTrack.mediaK  rN   rF   c                b    | j                         D cg c]  }|s|j                   c}S c c}w )z This does not exist in plex xml response but is added to have a common
            interface to get the locations of the track.

            Returns:
                List<str> of file paths where the track is found on disk.
        )	iterPartsfilerZ   s     rD   r   zTrack.locationsO  s+     '+nn&6?&6d$		&6???s   ,,c                    | j                   S )z Returns the track number. )r&   rL   s    rD   trackNumberzTrack.trackNumberY  s     zzrF   c                    | j                    d| j                   dt        | j                        j	                  d       d| j
                   S )z) Returns a filename for use in download. r!     )r/  r   r   rE  zfillr4   rL   s    rD   _prettyfilenamezTrack._prettyfilename^  sN    ''(D,<,<+=STEUEUAVA\A\]^A_@``cdhdndncopprF   c                8    | j                  | j                        S )z3 Return the track's :class:`~plexapi.audio.Album`. r  rL   s    rD   r   zTrack.albumb  r  rF   c                8    | j                  | j                        S )z4 Return the track's :class:`~plexapi.audio.Artist`. )r   r+  rL   s    rD   r   zTrack.artistf  s    ~~d1122rF   c                R    | j                    d| j                   d| j                   S r   )r/  r   r4   rL   s    rD   r^   zTrack._defaultSyncTitlej  s+    ''(D,<,<+=SMMrF   Nc                R    | j                   j                  |d| j                        S )z3 Get the Plex Web URL with the correct parameters. details)baseendpointr'   )rX   _buildWebURLr  )rB   rO  s     rD   
_getWebURLzTrack._getWebURLn  s"    ||((dYDNN([[rF   c                    t        j                  | j                        }t        t	        d      dz  |d   z  |dd  dz        S r#  )r   r   r  r   r   r   s     rD   r   zTrack.metadataDirectoryr  sG     NN4??3	4
#h.1=9QR=/QX@YYZZrF   c                F     | j                         j                  | |fi |S )a  Returns a sonic adventure from the current track to the specified track.

        Parameters:
            to (:class:`~plexapi.audio.Track`): The target track for the sonic adventure.
            **kwargs: Additional options passed into :func:`~plexapi.library.MusicSection.sonicAdventure`.

        Returns:
            List[:class:`~plexapi.audio.Track`]: list of tracks in the sonic adventure.
        )r|   sonicAdventure)rB   tor   s      rD   rU  zTrack.sonicAdventurex  s$     -t||~,,T2@@@rF   rH   )rB   r   rV  r   r   r   r   zlist[TTrack])r   r   r   r   r   r   rE   r   r:  r   r   r   r   r   r   r   rE  rI  r   r   r^   rR  r   rU  r   rF   rD   r   r     s   &N CD=: 9 9 < < 7 7 6 6 7 7 7 7 @ @  q.3N\ [ [
AAA A 
	ArF   c                      e Zd ZdZdZd Zy)TrackSessionzh Represents a single Track session
        loaded from :func:`~plexapi.server.PlexServer.sessions`.
    Tc                \    t         j                  | |       t        j                  | |       yr    N)r   rE   r   rA   s     rD   rE   zTrackSession._loadData       d#dD)rF   N)r   r   r   r   _SESSIONTYPErE   r   rF   rD   rX  rX         L*rF   rX  c                      e Zd ZdZdZd Zy)TrackHistoryzm Represents a single Track history entry
        loaded from :func:`~plexapi.server.PlexServer.history`.
    Tc                \    t         j                  | |       t        j                  | |       yrZ  )r   rE   r   rA   s     rD   rE   zTrackHistory._loadData  r[  rF   N)r   r   r   r   _HISTORYTYPErE   r   rF   rD   r_  r_    r]  rF   r_  )(
__future__r   r   pathlibr   urllib.parser   typingr   r   r   r	   r
   plexapir   r   plexapi.baser   r   r   r   r   plexapi.exceptionsr   plexapi.mixinsr   r   r   r   plexapi.playlistr   r   r   r   registerPlexObjectr   r   r   rX  r_  r   rF   rD   <module>rl     s"   " 	  # 5 5   d d ) V V % 
	)		)X
2 X
v c\	<c\ c\L R[	;R[ R[j YA	8[YA YAx 	*; 	* 	* 	*; 	* 	*rF   