+
    Ki'0  c                   s    ^ RI t ^ RIt^ RIt^ RIHt  ^ RIHt Rt^ RIH	t	 ^ RI
Ht ^ RIHt ^ R	IHt ^ R
IHt . t. ROtRR.t ! R R4      tRR ltR tR tR tRR ltR tR R ltR tR#   ] d    Rt L^i ; i)i    N)datetime)ClientTF)settingsGame)logger)
human_size)find_prefixsavesconfigc                   s   a  ] tR t^t o . ROtRR.tV 3R lR ltV 3R lR lt]V 3R lR l4       t	V 3R	 lR
 lt
V 3R lR ltV 3R lR ltRtV tR# )SaveInfor   configsc                    < V ^8  d   QhRS[ /# )   gamer   format__classdict__   "9/usr/lib/python3.14/site-packages/lutris/util/savesync.py__annotate__SaveInfo.__annotate__   s     * *T *    c                sl   Wn         V P                   P                  '       g   \        R V P                   ,          4      hV P                   P                  P                  R,          P	                  R4      pV'       g   \        RV P                   ,          4      hW n        V P                  4       V n        R# )%s has no configurationr   save_config%s has no save configurationN)r   r	   
ValueError
game_levelgetr   get_basedirbasedir)selfr   r   s   && r   __init__ZSaveInfo.__init__   s    	yy6BCCii&&11&9==mL;diiGHH!,'')r   c                r   r   returnstrr   r   r   r   r   &   s      S r   c                s^   V P                   P                  '       g   \        R V P                   ,          4      hV P                   P                  P                  R,          R,          pVP	                  R4      ;'       g    V P                   P
                  pV'       g   \        R4      h\        P                  P                  \        V P                   P                  P                  P	                  R4      4      4      pV P                   P                  R8X  Ed   V P                   P                  P                  P	                  RR4      pV'       dL   VP                  R	4      '       g5   \        P                  P                  V P                   P
                  V4      pV P                   P                  P                  P	                  RR4      pV'       dL   VP                  R	4      '       g5   \        P                  P                  V P                   P
                  V4      pV'       g   \        V4      pR
V9   d1   TP                  R
V P                   P
                  ;'       g    T4      pRV9   dX   \        P                   ! R4      ;'       g    RpVP                  R\        P                  P                  VRV,          4      4      pV# R
V9   d'   VP                  R
V P                   P
                  4      pRV9   d0   \        P                  P#                  VP                  RR4      4      pV# )r   r   r   r   zNo save directory providedexeZwineZprefixZ /z$GAMEDIRz$USERDIRZUSERZ	steamuserzdrive_c/users/%sZ~)r   r	   r   r   r   	directoryospathdirnamer$   Zgame_configZrunner_nameZ
startswithjoinr   ZreplaceZgetenvZ
expanduser)r   r   r   Zprefix_pathr%   Zusernames   &     r   r   ZSaveInfo.get_basedir&   s/   yy6BCCii&&11&9-H//),CC		0C0C9::ggooc$))*:*:*F*F*J*J5*Q&RS99  F*))**66::8RHK;#9#9##>#> ggll499+>+>L))""..225"=C3>>#..ggll499#6#6<)#.W$!//*dii6I6I6X6X[YW$99V,;;!//*bggll;PbemPm6no 	 W$!//*dii6I6IJW$'',,W__Z-MNr   c                &   < V ^8  d   QhRS[ RS[/# r   r)   r"   )r$   dictr   r   r   r   r   E   s     
 
3 
4 
r   c                s   / pV P                  R 4      p \        P                  P                  V 4      '       d9   \        P                  ! V 4      V\        P                  P                  V 4      &   V# \        P                  ! V 4       Fw  w  r#pV\        V 4      ^,           R pV FV  p\        P                  ! \        P                  P                  W&4      4      V\        P                  P                  WV4      &   KX  	  Ky  	  V# )r&   N)	Zrstripr(   r)   isfileZstatbasenameZwalklenr+   )r)   
path_filesZrootZ_dirsfilesr   	path_files   &      r   get_dir_infoZSaveInfo.get_dir_infoD   s    
{{377>>$13Jrww''-."$''$-D3t9q=?+G"	?Awwrww||TXGd?e
277<<;< # #0 r   c                r,   r-   )r$   Zlistr   r   r   r   r   Q   s      C D r   c           	     s   a V P                  V4      o. p\        SV3R  lRR7       F7  pSV,          pVP                  RVRVP                  RVP                  /4       K9  	  V# )c                 *   < SV ,          P                   # Nst_mtime)kr2      &r   <lambda>Z*SaveInfo.format_dir_info.<locals>.<lambda>T       *Q-:P:Pr   TZkeyZreversefileZsizemodified)r5   sortedappendst_sizer9   )r   r)   Zoutputr4   fstatsr2   s   &&   @r   format_dir_infoZSaveInfo.format_dir_infoQ   sg    &&t,

0PZ^_I	*FMMIFNN ` r   c                r   r!   )r.   r   r   r   r   r   _   s     
 
 
r   c                s6   RV P                   RV P                  /pV P                   Fn  pW P                  9   g   K  / p\        P                  P                  V P                   V P                  V,          4      pWCR&   V P                  V4      VR&   W1V&   Kp  	  V# )zbReturn list of files with their details for each type along with metadata related to the save infor   r	   r)   r3   )r   r   
save_typesr(   r)   r+   rE   )r   ZresultssectionZsection_datar)      &    r   get_save_filesZSaveInfo.get_save_files_   s    "DLL(D<L<LMG***%'ww||DLL$2B2B72KL'+V$(,(<(<T(BW%#/  ' r   c                s&   < V ^8  d   QhRS[ RS[ /# )r   titler)   r#   r   r   r   r   r   k   s     9 9s 9# 9r   c           
     s  a V P                  V4      oS'       g   R # \        V4       \        R\        V4      ,          4       ^ p\        SV3R lRR7       Ft  pSV,          pW5P                  ,          p\        V: R\        VP                  4      : R\        P                  ! VP                  4      P                  R4      : 24       Kv  	  \        R\        V4      ,          4       R # )	NZ=c                 r6   r7   r8   )r:   
save_filesr;   r   r<   Z,SaveInfo.print_dir_details.<locals>.<lambda>r   r=   r   Tr>    (z)		%czTotal size: %s)
r5   printr1   rA   rC   r   r    fromtimestampr9   strftime)r   rJ   r)   Z
total_size	save_filerD   rK   s   &&&   @r   print_dir_detailsZSaveInfo.print_dir_detailsk   s    &&t,
ecCJ

0PZ^_I	*F..(Jj8(:P:PQWQ`Q`:a:j:jko:pr ` 	J!778r   )r   r   r   N)r   logsr   screenshots)Z__name__Z
__module__Z__qualname__Z__firstlineno__rF   Zdefault_synced_typesr    r   Zstaticmethodr5   rE   rI   rR   Z__static_attributes__Z__classdictcell__)r   s   @r   r
   r
      s[     <J#Y/* * < 
 
 
 
9 9r   r
   c           	      s    \        V 4      pTR8X  d2   \	        \
        P                  ! TP                  4       4      ^R7       R# TP                   Fn  pY2P                  9   g   K  TP                  TP                  4       \        P                  P                  TP                  TP                  T,          4      4       Kp  	  R#   \         d    \        P                  ! R T 4        R# i ; i)z#Save information for %s unavailableNjsonZindent)r
   r   r   errorrN   rU   ZdumpsrI   rF   r   rR   Z
capitalizer(   r)   r+   r   )r   Zoutput_format	save_inforG   s   &&  r   show_save_statsrY   |   s    TN	
 djj1134Q? ++G///++&&("'',,y7H7H)J_J_`gJh*i ,  :DAs   C "C+*C+c                 sp   VP                  R 4      p\        \        V4      4       F  p\        P                  P
                  ! VRV^,            !  pV\        9   d   K8  V P                  V4      '       g)   \        P                  ! RV4       V P                  V4       \        P                  V4       K  	  R# )r&   NzCreating Webdav folder %s)ZsplitZranger1   r(   r)   r+   DIR_CREATE_CACHEexistsr   ZdebugZmkdirrB   )clientr)   ZpartsZirelpaths   &&   r   create_dirsr^      s    JJsOE3u:'',,gA/&&}}W%%LL4g>LL!( r   c                  s   \         '       g   \        P                  ! R 4       R# \        P                  ! R4      p V '       g   \        P                  ! R4       R# \        P                  ! R4      pV'       g   \        P                  ! R4       R# \        P                  ! R4      pV'       g   \        P                  ! R4       R# \        WV3^2R7      # )	z'Python package 'webdav4' not installed.Nwebdav_hostz No remote host set (webdav_host)webdav_userz$No remote username set (webdav_user)webdav_passz$No remote password set (webdav_pass))ZauthZtimeout)WEBDAV_AVAILABLEr   rW   r   read_settingr   )r_   r`   ra   s      r   get_webdav_clientrd      s    >?''6K78''6K;<''6K;<++$>KKr   c           	      s   V P                  V4      '       g   . # V P                  V4      p. pV F  pVR ,          R8w  d   K  \        P                  P	                  \
        P                  R\        P                  P                  VR,          4      ,          4      pV P                  \        P                  P	                  VR,          R4      V4       VP                  V4       K  	  V# )Ztyper'   z%s.jsonZnamesaveinfo.json)
r[   Zlsr(   r)   r+   r   	CACHE_DIRr0   Zdownload_filerB   )r\   Zgame_base_dirZbase_dir_contentr   Zsave_folderZlocal_save_infos   &&    r   get_existing_savesrg      s    ==''	yy/E'v+-'',,x'9'99rwwGWGWXcdjXkGl;lmRWW\\+f*=OQ`a_% ( Lr   c                 s8   V'       g   \         p \        V 4      p\        RT ,          4       \        P                  ! R4      pT'       g   \        P                  ! R4       R# \        4       pT'       g   R# TP                  4       p^ pT FM  pYW,          P                  R. 4       F.  p\        TR,          4      T8  g   K  \        TR,          4      pK0  	  KO  	  \        P                  ! 4        RT 2p	\        P                  P!                  Y0P"                  T	4      p
\%        YJ4       Rp\        P                  P!                  \        P&                  T4      p\)        TR	R
R7      ;_uu_ 4       p\*        P,                  ! Y]^R7       RRR4       TP/                  T\        P                  P!                  Y4      4       TR,          R,          p\        P                  P1                  T4      '       d    \        P                  P3                  T4      pT\5        TR,          4      ^,           R p\%        T\        P                  P!                  Y4      4       TR,          R,           Fo  p\        P                  P!                  YR,          4      p\        P                  P!                  YTR,          4      p\        TRT4       TP/                  TT4       Kq  	  R#   \         d    \        P                  ! R T 4        R# i ; i  + '       g   i     EL; i)zCan't get save info for %sNzUploading save for %swebdav_saves_path<No save path for the remote host (webdav_saves_path setting)r3   r@   -re   Zwutf-8ZencodingrV   r   r)   r   r?   Z>)
SYNC_TYPESr
   r   r   rW   rN   r   rc   rd   rI   r   intplatformZnoder(   r)   r+   slugr^   rf   openrU   ZdumpZupload_filer/   r*   r1   )r   ZsectionsrX   rh   r\   rK   Zmax_timerG   rQ   Zsave_idZsave_dest_dirsave_info_namesave_info_pathsave_info_fileZbasepathr]   Zupload_file_sourceZupload_file_dests   &&                r   upload_saveru      sO   TN	
 

!D
() --.ABST F ))+JH#,00"=I9Z()H4y45 > 
 !8*-GGGLL!2IIwGM&$NWW\\("4"4nEN	ncG	4	4		*Q7 
5
~rww||M'RS'"6*H	ww~~h77??8,s:i01A578G]<=(11	WW\\(f4EF77<<	&@QR #'78-/?@	 2O  148> 
5	4	4s   K 1L"LLL	c                 s    \        V R RR7      ;_uu_ 4       p\        P                  ! V4      pRRR4       V#   + '       g   i     X# ; i)Zrrk   rl   N)rq   rU   Zload)rs   rt   rX   s   &  r   load_save_inforv      s;    	ncG	4	4IIn-	 
5 
5	4s	   8A		c                s$    V ^8  d   QhR\         /# )r   rs   r#   )r   s   "r   r   r      s     O OC Or   c                s    \         P                  P                  \         P                  P                  V 4      4      w  rVP	                  R^R7      w  r4RVR\
        P                  ! \        V4      4      /# )zBParse the filename of a save info file and extract its informationrj   )Zmaxsplithostnamer    )r(   r)   Zsplitextr0   Zrsplitr    rO   rn   )rs   rr   Z_extrw   ZtsrH   r   parse_save_inforx      s]    77++BGG,<,<^,LMN!((q(9LH*h.D.DSW.MNNr   c           
      s    \        V 4      p\	        RT ,          4       \
        P                  ! R4      pT'       g   \        P                  ! R4       R# \        4       pT'       g   R# \        P                  P                  Y P                  4      p\        Y44      pTP                  4       pT EF  p\        T4      pTR,          p	\	        RT	: RTR,          P                  R	4      : R
24       \!        T4      p
/ p\"         EF  pY9  d   K  Y,          P%                  R. 4       Uu/ uF  qR,          TbK  	  ppYl,          P%                  R. 4       Uu/ uF  qR,          TbK  	  ppR. R. R. R. /Y&   TP'                  4        F  w  ppTP%                  T4      pT'       g   Y,          R,          P)                  T4       RTT,          R&   TR,          TT,          R,          8  d1   \	        RT,          4       Y,          R,          P)                  T4       TR,          TT,          R,          8  g   K  \	        RT,          4       Y,          R,          P)                  T4       K  	  TP'                  4        F=  w  ppTP%                  R4      '       d   K  Y,          R,          P)                  T4       K?  	  EK  	  Rp\"         F7  pY9  d   K  Y,          P'                  4        F  w  ppT'       g   K  RpK  	  K9  	  T'       g1   \	        R\        P                  P+                  T4      ,          4       M:\	        R\        P                  P+                  T4      ,          4       \	        T4       \        P,                  ! T4       EK  	  R#   \         d    \        P                  ! R T 4        R# i ; iu upi u upi )r   NzChecking sync of save for %srh   ri   rw   zHost: rL   r    rM   Z)r3   r?   unsyncedZnewerZolderZmissingTZseenr@   zLocal file %s is newerzLocal file %s is olderFu#   🟢 Save %s synced with local gameu(   🟠 Save %s out of sync with local game)r
   r   r   rW   rN   r   rc   rd   r(   r)   r+   rp   rg   rI   rx   rP   rv   
SAVE_TYPESr   ZitemsrB   r0   Zremove)r   rX   rh   r\   Zremote_basedirZexisting_savesZcurrent_save_filesZ	save_pathZsave_info_metaZhostZremote_save_infory   rG   Z	file_infor3   Zlocal_filesZfilenameZremote_fileZout_of_syncZ_keyZvalues   &                    r   
save_checkr{      s   TN	
 

(4
/0 --.ABST FWW\\"3YY?N'?N"113#	(3j)~j'A'J'J4'PQR))4!zG0CSC\C`C`ahjlCmnCmiv&	1CmEnI[IdIhIhiprtIuvIuIV,i7IuKv!+R"gr9VX YH'2'8'8':#)#ii1"%j188B*.h'Z(5?:+FF2X=>%g.55h?Z(5?:+FF2X=>%g.55h? (; (-{{}#)==((!),33H= (5% ". !G&'0668e5"&K  9 " 7"'':J:J9:UUV<rww?O?OPY?ZZ[(O
		)U $!  3T:2 ovs   N *O O"N=<N=)r   rS   r	   rT   )Ztextr7   )rU   r(   ro   r    Zwebdav4.clientr   rb   ZImportErrorZlutrisr   Zlutris.gamer   Zlutris.util.logr   Zlutris.util.stringsr   Zlutris.util.wine.prefixr   rZ   rz   rm   r
   rY   r^   rd   rg   ru   rv   rx   r{   ) r   r   <module>r|      s     	  %   " * / 7
x 
a9 a9H"	)L&0AfO=a  s   A/ /	A;:A;