+
    Ki  c                   s   R t ^ RIt^ RIt^ RIt^ RIHt ^ RIHtHtH	t	H
t
 ^ RIHtHt ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ R	IHt ^ R
I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& ^ RI'H(t( ^ RI)H*t* ^ RI+H,t,H-t-H.t. ^ RI/H0t0 ^ RI1H2t2  ! R R]&4      t3 ! R R]34      t4 ! R R]34      t5 ! R R]$4      t6 ! R R]"4      t7R# )zitch.io serviceN)gettext)AnyDictListOptional)
quote_plus	urlencode)Gtk)settings)games)UnavailableGameError)InputDialog)AUTO_ELF_EXEAUTO_WIN32_EXE)InstallerFile)get_runner_human_name)SERVICE_LOGINOnlineService)ServiceGame)ServiceMedia)linux)
Downloader)	HTTPErrorRequestUnauthorizedAccessError)logger)slugifyc                   s   a  ] tR t^t o RtRtR	t]P                  P                  ]
P                  R4      tR.tV 3R lR ltRtV tR# )
ItchIoCoverzitch.io game coveritchiozitchio/coverz%s.pngc                sL   < V ^8  d   QhRS[ S[S[3,          RS[S[,          /# )   detailsreturn)r   strr   r   format__classdict__   ";/usr/lib/python3.14/site-packages/lutris/services/itchio.py__annotate__ZItchIoCover.__annotate__%   s'      T#s(^      c                s    RV9   d   VR,          '       d
   VR,          # RV9   d   VR,          '       d
   VR,          #  R# \         P                  ! RV4       R# )zExtract cover from APIZstill_cover_urlZ	cover_urlz#No field 'cover_url' in API game %sN)r   warning)selfr      &&r%   get_media_urlZItchIoCover.get_media_url%   s`     '())011'!{##{++ $  NN@'Jr'    N)i;  i   )__name__
__module____qualname____firstlineno____doc__servicesizeospathjoinr   	CACHE_DIRZ	dest_pathZfile_patternsr+   __static_attributes____classdictcell__r#      @r%   r   r      s=     GDX//@IJM r'   r   c                   s    ] tR t^3tRtRtRtR# )ItchIoCoverMediumzitch.io game cover, at 60% sizer,   N)i   i   r-   r.   r/   r0   r1   r3   r8   r,   r'   r%   r<   r<   3   s
    )Dr'   r<   c                   s    ] tR t^9tRtRtRtR# )ItchIoCoverSmallzitch.io game cover, at 30% sizer,   N)i_   iK   r=   r,   r'   r%   r>   r>   9   s
    )Dr'   r>   c                   s8   a  ] tR t^?t o RtRt]R 4       tRtV t	R# )
ItchIoGamezitch.io Gamer   c                s    \        4       p\        VR,          4      Vn        \        VR,          4      Vn        VR,          Vn        \        P                  ! V4      Vn        V# )z0Return a Itch.io game instance from the API infoidtitle)	r?   r    appidr   slugnamejsonZdumpsr   )ZclsZigameZservice_games   && r%   newZItchIoGame.newD   sP     "| t-#E'N3!'N#zz%0r'   r,   N)
r-   r.   r/   r0   r1   r2   ZclassmethodrF   r8   r9   r:   r;   r%   r?   r?   ?   s     G r'   r?   c                   s  a  ] tR t^Ot o RtRt]! R4      tRtRt	Rt
RtR]R]R]/tRtRtR	tR
R.t]P*                  P-                  ]P0                  R4      t]P*                  P-                  ]P0                  R4      t]P*                  P-                  ]R4      t]P*                  P-                  ]R4      t]P*                  P-                  ]R4      t]P*                  P-                  ]R4      t/ tRRRR/t RRRR/t!RMt"RNR lt#]$R 4       t%V 3R lR lt&R t'R t(R t)RNR  lt*R! t+RNR" lt,RNR# lt-R$ t.RNR% lt/R& t0R' t1R( t2R) t3R* t4R+ t5R, t6ROR- lt7R. t8R/ t9ROV 3R0 lR1 llt:ROR2 lt;R3 t<R4 t=R5 t>]?RPV 3R6 lR7 ll4       t@R8 tAV 3R9 lR: ltBV 3R; lR< ltCV 3R= lR> ltDV 3R? lR@ ltEV 3RA lRB ltFRNRC ltGRD tHRPRE ltIRF tJRG tKRH tLV 3RI lRJ ltMRK tNRLtOV tPR# )QItchIoServicezService class for itch.ior   itch.ioTZbanner_smallZ
banner_medZbannerzhttps://api.itch.iozhttps://itch.io/loginzhttps://itch.io/my-feedzhttps://itch.io/dashboardzitchio/api/zitchio/api-keyzprofile/owned-keys.jsonzprofile/collections.jsongames/collections/Zp_linuxr   Z	p_windowswineZWindowsZLinuxNc           
     s   R V n         \        R4      p\        RVRVR\        R4      RR/4      pVP                  4       pV\        P
                  P                  8w  d#   VP                  4        V P                  4        R# VP                  pV'       dQ   \        V P                  R	4      ;_uu_ 4       pVP                  V4       RRR4       \        P                  ! V 4       R# V P                  4        R#   + '       g   i     L:; i)
FzLutris needs an API key to connect to itch.io. You can obtain one
from the itch.io <a href='https://itch.io/user/settings/api-keys'>API keys page</a>.

You should give Lutris its own API key instead of sharing them.parentquestionrA   zItch.io API keyZinitial_value Nw)is_login_in_progress_r   Zrunr   ZResponseTypeZOKZdestroylogoutZ
user_valueopenapi_key_pathZwriter   Zfire)r)   rL   rM   Zapi_key_dialogZresultapi_keykey_file   &&     r%   loginZItchIoService.login{   s     %*!N
 %&H,-	
  ##%S%%(((""$KKM ++d''--w' .t$KKM	 .-s   2C66D	c                s    V P                   .# )z2Return a list of all files used for authentication)rT   r)      &r%   credential_filesZItchIoService.credential_files   s     !!""r'   c                s0   < V ^8  d   QhRS[ S[,          /# )r   r   )r   r    r!   r$   r%   r&   ItchIoService.__annotate__   s     # #hsm #r'   c                s    \         P                  P                  V P                  4      '       g   R # \	        V P                  R4      ;_uu_ 4       pVP                  4       uuR R R 4       #   + '       g   i     R # ; i)Nr)r4   r5   existsrT   rS   Zread)r)   rV      & r%   load_api_keyZItchIoService.load_api_key   sK    ww~~d//00$##S))X==? *)))s   A++A<	c                sD    V P                  4       pV'       d   R RV 2/# / # )ZAuthorizationzBearer )r`   )r)   rU   r_   r%   get_headersZItchIoService.get_headers   s*    ##%#wwi%899Ir'   c                s    V P                  4       '       g   R#  V P                  4       pT;'       d    RT9   #   \        \        3 d    \        P
                  ! R4        R# i ; i)z2Check if service is connected and can call the APIFz!Not connected to itch.io account.Zuser)Zis_authenticatedfetch_profiler   r   r   r(   )r)   profiler_   r%   is_connectedZItchIoService.is_connected   sc    $$&&	((*G ,,6W,, 23 	NN>?	s   9 'A$#A$c                sh   V P                  4       '       g   \        P                  ! R4       R# V P                  4       p. p\	        4       pV Fa  pVR,          V9   d   K  \
        P                  V4      pVP                  V4       VP                  4        VP                  VR,          4       Kc  	  V# )zLoad the user's itch.io libraryzUser not connected to itch.ioNrA   )
rd   r   error	get_gamessetr?   rF   appendZsaveadd)r)   libraryr	   ZseengameZ_games   &     r%   loadZItchIoService.load   s      ""LL89.."uDG}$NN4(ELLJJLHHT']#  r'   c                sl   RP                  V P                  V4      pVe>   \        V\        4      '       d(   VRP                  \	        V\
        R7      4      ,          p \        VV P                  4       R7      pVP                  4        VP                  #   \         d    T P                  4        h i ; i)zMake API request{}/{}?{}Z	quote_via)headers)r"   api_url
isinstancedictr   r   r   ra   getrE   r   rR   )r)   r5   queryurlZrequest   &&&  r%   make_api_requestZItchIoService.make_api_request   s    nnT\\40E4!8!85<<	%: FGGC	((*G KKM<<& 	 KKM		s   6B B3c                s$    V P                  R4      # )z*Do API request to get users online profilerc   rx   rY   rZ   r%   rb   ZItchIoService.fetch_profile   s    $$Y//r'   c                &    V P                  RV4      # )z5Do API request to get games owned by user (paginated)zprofile/owned-keysry   r)   ru   r*   r%   fetch_owned_keysZItchIoService.fetch_owned_keys   s    $$%95AAr'   c                rz   )z#Do API request to users collectionszprofile/collectionsry   r{   r*   r%   fetch_collectionsZItchIoService.fetch_collections   s    $$%:EBBr'   c                *    V P                  RV 24      # )z-Do API request to get info about a collectionrJ   ry   r)   collection_idr*   r%   fetch_collectionZItchIoService.fetch_collection   s    $$|M?%CDDr'   c                s.    V P                  RV R2V4      # )z7Do API request to get the list of games in a collectionrJ   z/collection-gamesry   )r)   r   ru   s   &&&r%   fetch_collection_gamesZ$ItchIoService.fetch_collection_games   s     $$|M?BS%TV[\\r'   c                r~   )zDo API request to get game inforI   ry   )r)   game_idr*   r%   
fetch_gameZItchIoService.fetch_game   s    $$vgY%788r'   c                sB    RpVe   RV/pV P                  RV R2V4      # )z.Do API request to get downloadables of a game.Ndownload_key_idrI   z/uploadsry   )r)   r   dl_keyru      &&& r%   fetch_uploadsZItchIoService.fetch_uploads   s3    &/E$$vgYh%?GGr'   c                s@    RpVe   RV/pV P                  RV 2V4      # )z,Do API request to get downloadable of a gameNr   uploads/ry   )r)   uploadr   ru   r   r%   fetch_uploadZItchIoService.fetch_upload   s1    &/E$$xx%8%@@r'   c                sF    RpVe   RV/pV P                  RV RV 2V4      # )z"Do API request to get game patchesNr   zbuilds/z/upgrade-paths/ry   )r)   Z	installedZtargetr   ru   s   &&&& r%   fetch_build_patchesZ!ItchIoService.fetch_build_patches  s8    &/E$$wyk%QSXYYr'   c                s    RP                  V P                  RV R24      pVe,   RV/pVRP                  \        V\        R7      4      ,          pV# )z%Create download link for installationrm   r   z	/downloadr   rn   ro   )r"   rq   r   r   )r)   Z	upload_idr   rv   ru   rw   r%   get_download_linkZItchIoService.get_download_link  sN    nnT\\Xi[	+JK&/E5<<	%: FGGC
r'   c                \    \         P                  P                  V P                  V R24      # )z3Create basic cache key based on game slug and appid.json)r4   r5   r6   games_cache_path)r)   rB   r*   r%   get_game_cacheZItchIoService.get_game_cache  s#    ww||D11eWE?CCr'   c                sr   \         P                  ! V P                  RR7       V Fz  pV P                  VR,          4      p\         P                  P                  V P                  V4      p\        VRRR7      ;_uu_ 4       p\        P                  ! W%4       RRR4       K|  	  R#   + '       g   i     K  ; i)z+Store information about owned keys in cacheTZexist_okr@   rO   utf-8ZencodingN)	r4   makedirsr   r   r5   r6   rS   rE   dump)r)   r	   rk   filenamekey_path
cache_file   &&    r%   _cache_gamesZItchIoService._cache_games  s    
D))D9D**4:6Hww||D$9$98DHhg66*		$+ 76  766s    B%%B6c                s   . pRpV'       gs   \         P                  P                  V P                  4      '       dD   \	        V P                  RRR7      ;_uu_ 4       p\
        P                  ! V4      pRRR4       RpEMR^/pRpV'       d   V P                  V4      p\        VR	,          \        4      '       dN   W'R	,          ,          p\        VR	,          4      \        VR
,          4      8X  d   VR;;,          ^,          uu&   MMMV^,          pK  \         P                  ! \         P                  P                  V P                  R4      RR7       \	        V P                  RRR7      ;_uu_ 4       p\
        P                  ! W$4       RRR4       . pV F2  p	V	P!                  R/ 4      p
V	R,          V
R&   VP#                  V
4       K4  	  V'       d   V P%                  V4       V#   + '       g   i     EL~; i  + '       g   i     Ly; i)z'Get all owned library keys from itch.ioTr]   r   r   NFpage  
owned_keysper_pagezprofile/r   rO   rk   r@   r   )r4   r5   r^   key_cache_filerS   rE   rl   r|   rr   listlenintr   r6   
cache_pathr   rt   rh   r   )r)   
force_loadr   
fresh_datarV   ru   safetyresponser	   keyrk   s   &&         r%   get_owned_gamesZItchIoService.get_owned_games"  s   

t/B/B C Cd))3AAX!YYx0
 BJQKEF007h|4d;;<"88J8L12c(::N6OOf*!KKT__jADQd))3AAX		*/ B C7762&D&)$iD"#LL 
 e$? BAA( BAs   G(4G<(G9	<H	c                r   )zACreate basic cache key based on collection slug and collection_idr   )r4   r5   r6   collection_cache_pathr   r*   r%   get_collection_cacheZ"ItchIoService.get_collection_cacheI  s$    ww||D66=/8OPPr'   c                s`   \         P                  ! V P                  RR7       V P                  VR,          4      p\         P                  P                  V P                  V4      p\        VRRR7      ;_uu_ 4       p\        P                  ! W4       RRR4       R#   + '       g   i     R# ; i)z,Store information about collections in cacheTr   r@   rO   r   r   N)	r4   r   r   r   r5   r6   rS   rE   r   )r)   
collectionr   r   r      &&   r%   _cache_collectionZItchIoService._cache_collectionM  sq    
D..>,,Z-=>77<< : :HE(C'22jIIj- 3222s   ;BB-	c                    < V ^8  d   QhRS[ /# )r   collection_list)r   r!   r$   r%   r&   r\   U  s     A A Ar'   c           	     s8   . p\        4       pV EF  pRpV P                  VR,          4      pV'       g_   \        P                  P	                  V4      '       d:   \        VRRR7      ;_uu_ 4       p\        P                  ! V4      pRRR4       RpEM. VR&   R	^/p	R
p
V
'       d   V P                  VR,          V	4      p\        VR,          \        4      '       d[   VR;;,          VR,          ,          uu&   \        VR,          4      \        VR,          4      8X  d   V	R	;;,          ^,          uu&   MMMV
^,          p
K  VR,           Uu. uF  pRV9   g   K  RVR,          9   g   K  VNK   	  upVR&   VR,           F  pVR,          pV P                  VR,          4      pRVP                  R. 4      9   g   K=  VP                  R^ 4      ^ 8  g   KV  \        P                  P	                  V4      '       g   K}  \        VRRR7      ;_uu_ 4       p\        P                  ! V4      pRV9   d   VR,          VR&   RRR4       K  	  V P                  V4       V'       d/   T P!                  VR,           Uu. uF  qR,          NK  	  up4       VR,           FE  pVR,          pVR,          V9  g   K  VP#                  VR,          4       VP%                  V4       KG  	  EK  	  V#   + '       g   i     ELk; iu upi   + '       g   i     EK  ; iu upi )z(Get all games from a list of collectionsTr@   r]   r   r   NFr	   r   r   Zcollection_gamesr   rk   can_be_boughttraits	min_pricer   )rg   r   r4   r5   r^   rS   rE   rl   r   rr   r   r   r   r   rt   r   r   ri   rh   )r)   r   r   r	   Zknown_appidsr   r   r   rV   ru   r   r   Zcol_gamerk   Zgame_cache_pathZcached_games   &&&             r%   get_games_in_collectionsZ&ItchIoService.get_games_in_collectionsU  s    u *JJ$($=$=j>N$O!BGGNN3H$I$I/wGG8!%8!4J H"
 ')
7##:::d;KUSH!(+=">EE"7+x8J/KK+x(:;<HZDX@YY!&MQ.M!aKF .8-@'-@FhDVH[_cklrcs[sHH-@'
7#
 !+7 3 3H#F+D&*&9&9$t*&EO'488Hb+AA HH[!4q8GGNN?;;!/3IIX*.))H*=K0K?:EFW:X%6 7 JI !4 &&z2!!JwDW"XDWF#3#3DW"XY&w//':\1 $$T$Z0LL&	 0i *r g HGG,' JII #Ys0   0K)	K=K=+K=*L	8L
)K:Lc                s   . pV'       gq   \         P                  P                  V P                  4      '       dB   \	        V P                  R RR7      ;_uu_ 4       p\
        P                  ! V4      pRRR4       V# V P                  4       P                  R. 4      p\	        V P                  RRR7      ;_uu_ 4       p\
        P                  ! W#4       RRR4       V#   + '       g   i     T# ; i  + '       g   i     T# ; i)r]   r   r   NcollectionsrO   )
r4   r5   r^   collection_list_cache_filerS   rE   rl   r}   rt   r   )r)   r   r   rV      &&  r%   get_collection_listZ!ItchIoService.get_collection_list  s    t/N/N O Od55sWMMQY"ii1 N  00266}bIKd55sWMMQY		+0 N NM  NMs   C;C0C-	0D	c                s   V P                  4       pV P                  4       pV Uu. uF4  q3P                  RR4      P                  4       R8X  g   K)  RV9   g   K2  VNK6  	  pp\	        V4      ^ 8  d   V P                  V4      pMWP                  V4      ,           p. pV FO  pVP                  R4      pV'       d
   VR8X  g   K%  V P                  V4      '       g   K>  VP                  V4       KQ  	  V# u upi )z$Return games from the user's libraryrA   rN   lutrisr@   classificationrk   )r   r   rt   Zcasefoldr   r   _get_detail_runnersrh   )	r)   Zowned_gamesr   ZcolZlutris_collectionsr	   Zfiltered_gamesrk   r   s	   &        r%   rf   ZItchIoService.get_games  s     **, ..0 .9x[cGGGR<P<Y<Y<[_g<gclptwlwcc[x!"Q&112DEE  "?"?"LLED!XX&67N!^v%=++D11"))$/	 
  ys   &C3C3C3c                s  a S'       g   \        R4      hV P                  S4      p/ p\        P                  P	                  V4      '       d7   \        VRRR7      ;_uu_ 4       p\        P                  ! V4      pRRR4       M4 V P                  S4      P                  R/ 4      pV P                  V.4       VP                  R. 4      pRV9  d   R# R	V9   d
   VR	,          # VP                  R
^ 4      '       g   R# V P                  R4      p\        V3R lV 4       V4      pR	V9   d
   VR	,          # R#   + '       g   i     L; i  \         d     R# i ; i)z#Retrieve cache information on a keyzMissing Itch.io app IDr]   r   r   Nrk   r   r   r   r   Tc              3   sF   <"   T F  qR ,          S8X  g   K  Vx  K  	  R# 5ir@   Nr,   ).0xrB      & r%   	<genexpr>Z(ItchIoService.get_key.<locals>.<genexpr>  s     <1T7e+;QQs   !
!)Z
ValueErrorr   r4   r5   r^   rS   rE   rl   r   rt   r   r   r   next)r)   rB   Zgame_filenamerk   Z	game_filer   rj   s   &f     r%   get_keyZItchIoService.get_key  s-   566++E277>>-((mS7;;yyy+ <;u-11&"=!!4&) (B'&($)**xxQ'' &&t,<<dC$)**5 <;  s   #D53E 5E	EEc                s   V P                  V4      p V P                  W4      p/ p. pTR,           F  pTR,          T P                  9  d   K  TP	                  RTP                  RR4      P                  4       P                  4       RTP                  RR4      P                  4       RTP                  R^ 4      R\        TR,          4      /4       K  	  T'       d   YTR	&   T#   \         d    . u # i ; i)
z0Return a list of bonus content for itch.io game.uploadstyperD   r   rN   Z
total_sizer3   r@   zBonus Content)	r   r   r   extra_typesrh   rt   ZstripZ
capitalizer    )r)   rB   r   r   Z
all_extrasextrasr   rW   r%   
get_extrasZItchIoService.get_extras  s    ll5!	((4G 
i((Ff~T%5%55MMFJJz26<<>IIKFJJvr288: &**VQ"7#fTl+	 ) *0'#  	I	s   C# #C32C3c                sR   < V ^8  d   QhRS[ S[S[3,          RS[RS[S[,          /# )r   r   fix_missing_platformsr   )r   r    r   Zboolr   r!   r$   r%   r&   r\     s1      T#s(^ D \`ad\e r'   c                s   . pV P                  R. 4      p\        P                  P                  4        F  w  rEWC9   g   K  VP	                  V4       K   	  V'       d   V'       g   \
        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       gN   \        P                  ! RV P                  R4      4       \        \        P                  P                  4       4      # V# )aX  Extracts the runners available for a given game, given its details.
This test the traits for specific platforms, and returns the runners
in a priority order- Linux is first, which occasionally matters.

Normally, if a game has no platforms we'll assume a default set of runners,
but 'fix_missing_platforms' may be set to false to turn this off.r   c              3   sV   "   T F  qP                  R 4      '       g   K  Vx  K!  	  R# 5i)Zp_N)
startswith)r   Ztr_   r%   r   Z4ItchIoService._get_detail_runners.<locals>.<genexpr>  s     ?&QLL,>qq&s   )
)TFzaThe itch.io game '%s' has no platforms lists; Lutris will assume all supported runners will work.rA   )
rt   rG   runners_by_traitZitemsrh   anyr   r(   r   Zvalues)r   r   runnersr   Ztraitrunnerr   r%   r   Z!ItchIoService._get_detail_runners  s     Xr**;;AACMEv& D !3?&?333?&???wKK( M::AACDDr'   c                s    VR ,          # )rC   r,   )r)   db_gamer*   r%   get_installed_slugZ ItchIoService.get_installed_slug  s    vr'   c                R   < V ^8  d   QhRS[ S[S[3,          RS[ S[S[3,          /# r   r   r   r   r    r   r!   r$   r%   r&   r\     s+     	 	$sCx. 	T#s(^ 	r'   c                s    \         P                  ! VR,          4      pV P                  V4      pV'       d   V P                  V^ ,          V4      # \        P
                  ! R4       / # )(Auto generate installer for itch.io gamer   zNo supported platforms found)rE   loadsr   _generate_installerr   r(   r)   r   r   r   r   r%   generate_installerZ ItchIoService.generate_installer  sQ    **WY/0**73++GAJ@@56	r'   c                sL   < V ^8  d   QhRS[ S[S[3,          RS[S[,          /# r   )r   r    r   r   rs   r!   r$   r%   r&   r\   "  s'      4S> d4j r'   c                sZ   \         P                  ! VR,          4      pV P                  V4      pV Uu. uF  q@P                  WA4      NK  	  pp\	        V4      ^8  dI   V FB  p\        VR,          4      pTR;;,          RT;'       g
    VR,          ,           ,          uu&   KD  	  V# u upi )r   r   r   versionZ )rE   r   r   r   r   r   )r)   r   r   r   r   Z
installers	installerZrunner_human_names   &&      r%   generate_installersZ!ItchIoService.generate_installers"  s    **WY/0**73NUVgF..v?g
Vz?Q'	$9)H:M$N!)$/@/W/WIhDW(XX$ (  Ws   B(c                r   r   r   r!   r$   r%   r&   r\   0  s,     
 
4S> 
d3PS8n 
r'   c                s(   VR 8X  d   R\         /pRRRRR//RRRRR	//.pM6VR
8X  d   R\        /pRRR//RR/.pM\        P                  ! RV R24       / # RVR,          RRRVR,          RV P	                  V4      RVRVR,          RRRR/.RVRV//# )r   Zexeextractfile
itchuploaddst$CACHEmergesrc$GAMEDIRrK   ZtaskrD   Zcreate_prefixZinstall_or_extractZ'z&' is not a supported runner for itchior   rH   rC   	game_slugr   ZitchidrB   scriptfiles%N/A:Select the installer from itch.iork   r   )r   r   r   r(   r   )r)   r   r   Zgame_configr   rw   r%   r   Z!ItchIoService._generate_installer0  s    W ,/KV\5(CD5(E:>?F v .1K89<PR^;_`FNNQvh&LMNI GFOyGFO009fgg&<)PQRV
 	
r'   c                s<   < V ^8  d   QhRS[ S[S[3,          RS[/# r   r   r!   r$   r%   r&   r\   L  s#     - -c3h -C -r'   c                s    \         P                  ! VR ,          4      pV P                  V4      pV'       d
   V^ ,          # R# )r   rN   )rE   r   r   r   r   r%   get_installed_runner_nameZ'ItchIoService.get_installed_runner_nameL  s6    **WY/0**73$wqz,",r'   c                s6   < V ^8  d   QhRS[ RS[S[,          /# r   )rs   r   r    r!   r$   r%   r&   r\   Q  s     > >$ >49 >r'   c                s    \         P                  ! VR ,          4      pV P                  VRR7      pV Uu. uF  q@P                  V,          NK  	  up# u upi )r   Fr   )rE   r   r   platforms_by_runner)r)   r   r   r   r]   r   r%   get_game_platformsZ ItchIoService.get_game_platformsQ  sN    **WY/0**7%*P5<=W((++W===s   Ac                s   ^ pV'       d   RV9   d
   VR,          MT.pM)V P                  VR,          V4      pRV9   d
   VR,          pV FG  pVR,          V P                  9   d   K  V P                  VR,          4      pV'       d	   Wt8  g   KE  TpKI  	  V'       d5   \        P                  ! W@P
                  VR,          R7      p\        V4      # R# )i    r   
service_idr   r   
updated_at)Zinstalled_at__lessthanr2   r   F)r   r   _rfc3999_to_timestampgames_dbZget_games_wherer@   r   )	r)   r   r   r   Zstampr   Z_uploadtsZdbgs	   &&&&     r%   _check_update_with_dbZ#ItchIoService._check_update_with_dbW  s    +3v+=vh'6JG(()>DGG#!),Gv$"2"22++GL,ABBrz  **',gg'R^J_C s8Or'   c                s\  a  . pS P                  VR,          4      pRpRpRp/ p\        P                  P                  VR,          R4      p\        P                  P	                  V4      '       Ed   \        VRR7      ;_uu_ 4       p	\        P                  ! V	4      pRRR4       RV9   d    S P                  VR,          V4      pRV9   d
   VR,          MTpS P                  VR,          V4      pV'       d|   S P                  VP                  R^ 4      4      p\!        VP                  R^ 4      4      V8  d   R# \!        \"        P"                  P%                  4       P'                  4       4      VR&   V'       g   S P)                  WV4      pV'       Ed0   RRRVR,          RVR,          RS P+                  V4      RVR,          RRVR,          R. RRRRRR//.//pV'       d   RRVRR R!V3V 3R" ll//.VR,          R&   MRR#/.VR,          R&   VR,          R$8X  d'   VR,          R,          P-                  R%R&RRR'//4       MAVR,          R(8X  d4   VR,          R,          P-                  R%R&RRR)VR,          ,          //4       V'       d(   VR,          R,          P-                  R*R+VRVR%R//4       VP-                  V4       V#   + '       g   i     EL4; i  \         dE   p
T
P                  R	8X  d)   \        P                  ! R
TR,          TR,          4       Rp Rp
?
EL5Rp
?
ii ; i),zCheck for updatesr   NFZ	directoryz.lutrisgame.jsonr   r   r   i  z%Upload %s for %s seems to be removed.rD   Tr   dater   rH   rC   Zinstaller_slugr   r   r   Zextendsr   r   r   r   r   r   r   rv   r   z
update.zip
downloaderc                 P   < \        WP                  R SP                  4       R7      # T)Z	overwriterp   r   Zdownload_filera   Zfrv   r)      &&r%   <lambda>Z5ItchIoService.get_update_installers.<locals>.<lambda>  s    : #__dN^N^N`Dr'   r   r   r   r   r   rK   z$GAMEDIR/drive_c/%s
write_jsondata)r   r4   r5   r6   r^   rS   rE   rl   r   r   r   Zcoder   infor   rt   r   datetimenow	timestampr   r   rh   )r)   r   Zpatch_installersr   r   ZoutdatedZ	patch_urlr   Zinfo_filenameZ	info_filere   r   r   s   f&           r%   get_update_installersZ#ItchIoService.get_update_installerso  s   ll7<01	W[%9;MN77>>-((mg66)yy+ 74(!..tH~sCF19V1CVH-F $ 6 6tH~s KI 33FJJ|Q4OPB488FA./25#&x'8'8'<'<'>'H'H'J#KDL 11'GH89 01T44W='(+w'78R"V\5($KL"I  %!9&(	 +'
0	(#G, 2>?f0g/h	(#G,x G+(#K077uhzBC "f,(#K077uh7LwW]7^_` (#K077!FD&-RV#WX ##I.] 766  ! (zzS($KTRZ^]dek]lm#'	(s%   K-AK K	L+'9L&&L+c                s    . # )z1itch.io does currently not officially support dlcr,   )r)   r   r   Z
only_owneds   &&&&r%   get_dlc_installers_runnerZ'ItchIoService.get_dlc_installers_runner  s    	r'   c                s^  a a S P                  VP                  4      p S P                  VP                  V4      p. p. p. p	. p
RpRp\        R T;'       g    .  4       4      p\        T3R lTP                   4       4      pTP                  P                  R4      '       g   TP                  pRS P                  RTP                  RTP                  R	TP                  R
\        \        P                  P                  4       P!                  4       4      /pT'       d   \#        T4      ^ 8  d   TR,           F  pT'       d,   TR,          S P$                  9   d   TP'                  T4       K6  TR,          R8X  g   KF  TP                  R$9   g   KY  S P)                  TRR7      pTP                  T9  d   K  RTR,          9   pS P+                  TR,          T4      TR&   TR,          ^8X  d   K  TP'                  T4       K  	  \#        T4      ^ 8  dx   T'       gp   TP-                  R R7       T^ ,          p\/        TR,          4      TR&   RT9   d   \/        TR,          4      TR&   S P1                  TR,          T4      pTR,          pT'       d|   TP2                  R,          P'                  RRTRRRR//4       T	P'                  \5        TP                  SR TRT;'       g    TP6                  ;'       g    RR!T3T 3R" ll/4      4       T F  p\/        TR,          4      T9  d   K  S P1                  TR,          T4      pT
P'                  \5        TP                  \/        TR,          4      R TRTR,          R!T3T 3R# ll/4      4       K  	  Y3#   \         d   p\        ThRp?ii ; i)%z?Replace the user provided file with download links from itch.ioNz	setup.zipc              3   s2   "   T F  qR ,          x  K  	  R# 5ir   r,   )r   r   r_   r%   r   4ItchIoService.get_installer_files.<locals>.<genexpr>  s     !I3HaD''3Hs   c              3   sh   <"   T F'  qP                   S8X  g   K  VP                  4       x  K)  	  R # 5iN)r@   Zcopy)r   Z_fileinstaller_file_idr   r%   r   r    s'     f.DUTeHeLEJJLL.Ds   22zN/Ar2   rB   rC   r   r   r   r   ZdefaultFr   demor   r   Weightc                 s    V R ,          # )r  r,   )r   rZ   r%   r   3ItchIoService.get_installer_files.<locals>.<lambda>  s	    VH-=r'   )r   r@   r   Zbuild_idZbuildr   r   r   r   z$GAMEDIR/.lutrisgame.jsonr   rv   r   c                 r   r   r   r   r   r%   r   r        *D$JZJZJ\;r'   c                 r   r   r   r   r   r%   r   r  *  r  r'   )r   rK   )r   Zservice_appidr   r   r
   rg   r   Zscript_filesrv   r   r@   r   r   r   r   r   r   r   r   rh   r   get_file_weightZsortr    r   r   r   r   )r)   r   r  Zselected_extrasr   r   ZexZfilteredr   r   Zextra_filesZlinkr   Zselected_extras_idsr   r   r   Zupload_runnersZis_demoZextras   f&f&                r%   get_installer_filesZ!ItchIoService.get_installer_files  sl    ll9223	/(()@)@#FG !!I?3H3Hb3H!IIfi.D.Dffxx""5))88D twwY,,I''i&&C))--/99;<
 s./!3!),,&F6Nd>N>N,NMM&)&>Y.I4D4DHY4Y%)%=%=f\a%=%bN ''~= $x(88G'+';';F:<NPW'XF8$h'4/ OOF+! -, x=1TMM=M>a[F .DNV# #F:$6 7W))&,<Dj)H[)00f6QSZ\abc LL''%t"H$L$L$L$L$D '
 E5;'::))%+s;D''d$t"E*$5$D '
	 $ !!}  	/&B.	/s   N N, N''N,c                s.    V P                  W. 4      w  r4V# )z.Similar to get_installer_files but for patches)r
  )r)   r   r  r   Z_extra_filesrw   r%   get_patch_filesZItchIoService.get_patch_files3  s     #66yUWXr'   c                s  a VP                  R 4      '       d   ^# VP                  4       o\        ;QJ d    V3R lR 4       F  '       g   K   RM	  RM! V3R lR 4       4      '       d   ^# ^ pVP                  R4      '       d
   V^,          p\        P                  P
                  '       d   RV9   g   RV9   d
   V^,          pMRV9   d
   V^,          pV'       d
   V^@,          pV# )	z.rpmc              3   s,   <"   T F	  qS9   x  K  	  R # 5ir  r,   )r   Zpattern
name_lowerr   r%   r   Z0ItchIoService.get_file_weight.<locals>.<genexpr>?  s     e4d*$4ds   TFz.debZ386Z32Z64)Z	wallpaperZ
backgroundZartworkZposter)ZendswithZlowerr   r   ZLINUX_SYSTEMZ	is_64_bit)r)   rD   r  Zweightr  s   &&& @r%   r	  ZItchIoService.get_file_weight:  s    ==  ZZ\
3e4de333e4deee==  dNF'''}$t|$dNFr'   c                r   )r   r   )rs   r!   r$   r%   r&   r\   N  s      T r'   c                s    VP                  R 4      pV'       d`   \        P                  ! V4      pVP                  R4      pVf   VP                  R4      pVe    \        V\        4      '       d
   VR,          # R# )r   Z
created_atZpublished_at:Ni
   NrN   )rt   rE   r   rr   r    )r)   r   r   Zrelease_dater   r%   get_game_release_dateZ#ItchIoService.get_game_release_dateN  sc    ++i(jj)G";;|4L#&{{>:'J|S,I,I#C((r'   c                s    \         P                   P                  VR VP                  R4       4      P                  4       # )NZ.)r   ZfromisoformatZrfindr   )r)   Z_sr*   r%   r   Z#ItchIoService._rfc3999_to_timestamp\  s1      ..r/BHHSM/BCMMOOr'   )rP   )	Z
soundtrackZbookZvideoZdocumentationZmodZaudio_assetsZgraphical_assetsZ
sourcecodeZotherr  )F)T)Qr-   r.   r/   r0   r1   r@   rQ   rD   ZiconZonlineZdrm_freeZ
has_extrasr>   r<   r   ZmediasZdefault_formatrq   Z	login_urlZredirect_urisr4   r5   r6   r   r7   r   rT   r   r   r   r   Z	key_cacher   r   r   rX   Zpropertyr[   r`   ra   rd   rl   rx   rb   r|   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rf   r   r   Zstaticmethodr   r   r   r   r   r   r   r   r   r  r
  r  r	  r  r   r8   r9   r:   r;   r%   rG   rG   O   sI    #	BY<DDFHJ('+F
 N#G'I.0KLMh00-@J77<< 2 24DELWW\\*.GHN!#j:T!Uww||J9GGLL^DI!7K@!9gw?
K!F # ## #	-$$0BCE]9HAZD,%NQ.A AF	2"H0   6	 	 
 
8- -
> >0X td"L( P Pr'   rG   )8r1   r   rE   r4   r    rQ   Ztypingr   r   r   r   Zurllib.parser   r   Zgi.repositoryr   r   r   Zlutris.databaser	   r   Zlutris.exceptionsr
   Zlutris.gui.dialogsr   Zlutris.installerr   r   Zlutris.installer.installer_filer   Zlutris.runnersr   Zlutris.services.baser   r   Zlutris.services.service_gamer   Zlutris.services.service_mediar   Zlutris.utilr   Zlutris.util.downloaderr   Zlutris.util.httpr   r   r   Zlutris.util.logr   Zlutris.util.stringsr   r   r<   r>   r?   rG   r,   r'   r%   <module>r     s       	   , , .   - 2 * 9 9 0 = 4 6  - H H " ', , {   OPM OPr'   