+
    Ki  c                   s    ^ RI t ^ RIt^ RIt^ RIt^ RIHtHtHtHtH	t	H
t
HtHt ^ RIHt ^ RIHt ^ RIHtHt ^ RIHt ^ RIHt ]'       d   ^ RIHt  ! R	 R
4      tR R lt ! R R4      tR# )    N)TYPE_CHECKINGAnyCallableDictIterableListOptionalTuple)ServiceGameCollection)system)	HTTPErrordownload_file)logger)TrashPortal)BaseServicec                   s   a  ] tR t^t o RtRV 3R lR llt]V 3R lR l4       t]V 3R lR l4       t]V 3R	 lR
 l4       t	V 3R lR lt
V 3R lR ltRtV tR# )	MediaPathzAn object to describe a media file along with the media size- which
is defined by Lutris, not the size of the image in the file. Note that
the file may not exist.Nc          	      sP   < V ^8  d   QhRS[ RRRS[S[S[S[3,          ,          /# )   pathservice_mediaServiceMediasize)strr   r   intformat__classdict__   "B/usr/lib/python3.14/site-packages/lutris/services/service_media.py__annotate__MediaPath.__annotate__   s4     / /S / /xPUVY[^V^P_G` /    c                sT    Wn         W n        T;'       g    VP                  V n        R # Nr   r   r   )selfr   r   r   s   &&&&r   __init__ZMediaPath.__init__   s"    	*..M..	r   c                    < V ^8  d   QhRS[ /# r   returnr   r   r   r   r   r      s      s r   c                s(    V P                   ^ ,          # r    r   r"      &r   widthZMediaPath.width       yy|r   c                r$   r%   r'   r   r   r   r   r       s       r   c                s(    V P                   ^,          # )i   r)   r*   r+   r   heightZMediaPath.height   r-   r   c                r$   r%   )Zboolr   r   r   r   r   $   s     _ _ _r   c                s    \         P                  ! V P                  R R7      ;'       d*    \        P                  P	                  V P                  4      # )TZexclude_empty)r
   path_existsr   osZisfiler*   r+   r   existsZMediaPath.exists#   s5    !!$))4@^^RWW^^TXT]T]E^^r   c                s:   < V ^8  d   QhRS[ S[S[3,          RR/# )r   max_sizer&   r   )r   r   r   r   r   r   r   '   s#      U38_  r   c                sX   WP                   8w  d   V^ ,          V P                  ,          pV^,          V P                  ,          p\        W#4      p\	        V P                  V,          4      p\	        V P                  V,          4      p\        V P                  V P                  WV34      # V # r(   )r   r,   r.   Zminr   r   r   r   )r"   r3   Zx_factorZy_factorZfactorZscaled_widthZscaled_heights   &&     r   scale_to_fitZMediaPath.scale_to_fit'   s    yy {TZZ/H{T[[0H,FtzzF23Lf 45MTYY(:(:\<YZZr   c                r$   r%   )r   r   r   r   r   r   1   s      # r   c                    V P                   # r    )r   r*   r+   r   __repr__ZMediaPath.__repr__1   s    yyr   r!   r    )__name__
__module____qualname____firstlineno____doc__r#   propertyr,   r.   r2   r4   r6   __static_attributes____classdictcell__r      @r   r   r      sf     / /
     _ _  r   r   c                sF    V ^8  d   QhR\         \        ,          R\        /# )r   possible_pathsr&   )r   r   r      "r   r   r   5   s     
 
tI 
9 
r   c                s    \        V 4      ^8  d)   V  F  pVP                  '       g   K  Vu # 	  V ^ ,          # V '       g   \        R4      hV ^ ,          # )zSelects the best path from a list of paths to media. This will take the first
one that exists and has contents, or the just first one if none are usable.z0resolve_media_path() requires at least one path.)Zlenr2   Z
ValueError)rA   mps   & r   resolve_media_pathrE   5   sR     >Q Byyy	 ! ! KLL!r   c                   s   a  ] tR t^Bt o Rt]t]tRtRt	]t
]t]tRtRtR tR tV 3R lR ltV 3R	 lR
 ltRV 3R lR lltV 3R lR ltV 3R lR ltR t]R 4       t]R 4       tR tR tRtV tR# )r   z,Information about the service's media formatZremoteTz%sc                s    V P                   '       dK   \        P                  ! V P                   4      '       g#   \        P                  ! V P                   4       R # R # R # r    )	dest_pathr
   r0   r1   Zmakedirsr*   r+   r   r#   ZServiceMedia.__init__O   s7    >>>&"4"4T^^"D"DKK' #E>r   c                s6    V P                   ^ ,          V,          # r(   )file_patterns)r"   slug   &&r   get_filenameZServiceMedia.get_filenameS   s    !!!$t++r   c                s6   < V ^8  d   QhRS[ RS[S[,          /# )r   rH   r&   )r   r   r   r   r   r   r   ServiceMedia.__annotate__V   s#     q qS qT)_ qr   c           
     s    V P                    Uu. uF=  p\        \        P                  P	                  V P
                  W!,          4      V 4      NK?  	  up# u upi )zReturns a list of each path where the media might be found. At most one of these should
be found, but they are in a priority order - the first is in the preferred format.)rG   r   r1   r   joinrF   )r"   rH   Zpatterns   && r   get_possible_media_pathsZ%ServiceMedia.get_possible_media_pathsV   sC     ^b]o]op]oRY	"'',,t~~w~FM]oppps   AAc                sn   < V ^8  d   QhRS[ S[RS[. S[3,          3,          ,          RS[S[,          /# )r   servicesr   r&   )r   r   r   r   r   r   r   r   r   r   rK   [   s:       }hr3w6G'G!HI	)	r   c                s  a  V UUu. uF9  q"^ ,          P                   P                  4        F  q3! 4       V^,          3NK  	  K;  	  pppR V 3R llp\        WER7       Fs  w  rgVP                  '       g   K  V! 4       pV'       g   K*  VP	                  V4       F4  p	V	P
                  '       g   K  V	P                  S P                  4      u u # 	  Ku  	  R# u uppi )a  Returns the media path to use when none of the possible paths (above) actually exist.
This may be scaled down so it no taller than this media's height.

This method finds the media that is nearest to the size of this media, and
then evaluates the provided callables to obtain slugs, starting with the nearest
match. As soon as it finds a media that exists, it will return it. If it finds
none, it returns None.
c                sl    V ^8  d   QhR\         \        \        . \        3,          3,          R\        /# )r   mediar&   )r   r   r   r   r   rB   rC   r   r   Z:ServiceMedia.get_fallback_media_path.<locals>.__annotate__i   s1     	M 	MeL(2s72C$CD 	M 	Mr   c                 s   < \        V ^ ,          P                  ^,          SP                  ^,          ,
          4      pV ^ ,          P                  ^,          SP                  ^,          8  d   V# VR,           # )r    i  )Zabsr   )rO   Zdiffr"   s   & r   
similarityZ8ServiceMedia.get_fallback_media_path.<locals>.similarityi   sR    uQx}}Q'$))A,67D 8==+tyy|;4LLr   )ZkeyN)mediasZvaluesZsortedcan_be_fallbackrM   r2   r4   r   )
r"   rN   ZtZmtrQ   rP   rO   Zslug_functionrH   rD   s
   f&        r   get_fallback_media_pathZ$ServiceMedia.get_fallback_media_path[   s     )1P1Q4;;;M;M;OR241,;O,P	M 	M %+6$B E$$$$4#<<TB999#%??499#== C	 %C  Qs   ?CNc                sx   < V ^8  d   QhRS[ RS[S[P                  ,          RS[S[P                  ,          RR/# )r   rH   completion_functionerror_functionr&   N)r   r   r   ZCompletionFunctionZErrorFunctionr   r   r   r   rK   w   sI     " "" &k&D&DE" !!:!:;	"
 
"r   c                s   V P                  V4       Uu. uF@  p\        P                  P                  VP                  4      '       g   K4  VP                  NKB  	  ppV'       d   \	        WRVR7       R# V'       d
   V! 4        R# R# u upi )zqSends each media file for a game to the trash, and invokes callsbacks when this
has been completed or has failed.)rT   rU   N)rM   r1   r   r2   r   )r"   rH   rT   rU   rD   Zpathss   &&&&  r   trash_mediaZServiceMedia.trash_mediaw   sc     $(#@#@#Fb#FR"''..Y[Y`Y`Ja#FbWef ! ! cs   1B
Bc                sL   < V ^8  d   QhRS[ S[S[3,          RS[S[,          /# )r   detailsr&   )r   r   r   r   r   r   r   r   rK      s'     : :T#s(^ : :r   c                s    V P                   V9  d%   \        P                  ! R V P                   V4       R# WP                   ,          '       g   R# V P                  WP                   ,          ,          # )zNo field '%s' in API game %sN)	api_fieldr   Zwarningurl_pattern)r"   rW   rI   r   get_media_urlZServiceMedia.get_media_url   sN    >>(NN94>>7S~~&&'.."999r   c                s6   < V ^8  d   QhRS[ S[S[3,          /# r%   )r   r   r   r   r   r   rK      s      S#X r   c                s*   V P                   R8X  d   / # \        P                  ! V P                  4      p/ pV FW  pVR,          '       g   K  \        P
                  ! VR,          4      pV P                  V4      pV'       g   KL  WRVR,          &   KY  	  V# )z.Return URLs for icons and logos from a serviceZlocalrW   rH   )sourcer	   Zget_for_serviceservicejsonZloadsrZ   )r"   Zservice_gamesrQ   ZgamerW   Z	media_urls   &     r   get_media_urlsZServiceMedia.get_media_urls   s}    ;;'!I-==dllK!#!D	??jji1G**73I#,4<  " r   c                sx   V'       g   R# \         P                  P                  V P                  V P	                  V4      4      p\
        P                  ! VRR7      '       d   R# \
        P                  ! V4      '       d   \         P                  ! V4      p\        P                  ! 4       VP                  ,
          R\        P                  ! \        ^^4      4      ,          8  d   V# \         P                  ! V4        \        W#RR7      #   \         d#   p\         P"                  ! RY%4        Rp?R# Rp?ii ; i)z#Downloads the banner if not presentNTr/   )Zraise_errorszFailed to download %s: %siQ )r1   r   rL   rF   rJ   r
   r0   ZstattimeZst_mtimerandomZchoiceZrangeZunlinkr   r   r   Zerror)r"   rH   ZurlZ
cache_pathZcache_statsZexs   &&&   r   downloadZServiceMedia.download   s    WW\\$..$2C2CD2IJ
j==j))''*-Kyy{[111IeTUWYl@[4[[!!IIj!	? tDD 	?LL4c>>	?s   ?D D9D44D9c                r5   )zpThe size this media is stored in when customized; we accept
whatever we get when we download the media, however.r)   r*   r+   r   custom_media_storage_sizeZ&ServiceMedia.custom_media_storage_size   s     yyr   c                r5   )zDThe size this media should be shown at when in the configuration UI.r)   r*   r+   r   config_ui_sizeZServiceMedia.config_ui_size   s     yyr   c                    R# )zAUpdate the desktop, if this media type appears there. Most don't.N r*   r+   r   run_system_update_desktop_iconsZ,ServiceMedia.run_system_update_desktop_icons       r   c                rd   )z+Used if the media requires extra processingNre   r*   r+   r   renderZServiceMedia.render   rg   r   re   )NN)r7   r8   r9   r:   r;   ZNotImplementedr\   r   r[   ZvisiblerF   rG   rX   rY   rR   r#   rJ   rM   rS   rV   rZ   r^   ra   r<   rb   rc   rf   rh   r=   r>   r?   r@   r   r   r   B   s     6GDFGI"MIKO(,q q
 8" ": :  ?$  
  P: :r   r   )r]   r1   r`   r_   Ztypingr   r   r   r   r   r   r   r   Zlutris.database.servicesr	   Zlutris.utilr
   Zlutris.util.httpr   r   Zlutris.util.logr   Zlutris.util.portalsr   Zlutris.services.baser   r   rE   r   re   r   r   <module>ri      sK     	   V V V :  5 " +0! !H
|: |:r   