
    g                    <   S r SSKJr  SSKrSSKJrJr  SSKJrJ	r	J
r
  SSKJr  SSKrSSKrSSKrSSKrSSKrSSKJrJr  SSKJrJrJrJrJrJrJr  SS	KJr  SS
KJ r J!r!  SSK"J#r#  SSK$J%r&  SSK'J(r(  SSK)J*r*J+r+  SSK,J-r-J.r.  SSK/J0r0  SSK1J2r2  SSK3J4r4J5r5  SSK6J7r7  SSK8J9r9  SSK:J;r;J<r<J=r=  SSK>J?r?  SSK@JArA  SSKBJCrCJDrDJErEJFrFJGrGJHrH  SSKIJJrJJKrKJLrLJMrMJNrNJOrOJPrPJQrQ  SSKRJSrS  SSKTJUrUJVrV  SSKWJXrX  SSKYJZrZ  SSK[J\r\  SS K]J^r^  SS!K_J`r`Jara  SS"KbJcrc  \(       a  SS#KTJdrd  SS$KeJfrf  SS%KgJhrh  \	 " S& S'5      5       ri\	 " S( S)5      5       rj\	 " S* S+5      5       rk\	 " S, S-5      5       rl\	 " S. S/5      5       rm\	 " S0 S15      5       rn\	 " S2 S35      5       ro " S4 S55      rpg)6Base HACS class.    )annotationsN)	AwaitableCallable)asdict	dataclassfield)	timedelta)TYPE_CHECKINGAny)AIOGitHubAPIExceptionGitHub	GitHubAPIGitHubAuthenticationExceptionGitHubExceptionGitHubNotModifiedExceptionGitHubRatelimitException)AIOGitHubAPIRepository)ClientSessionClientTimeout)AwesomeVersion)async_create)ConfigEntry)EVENT_HOMEASSISTANT_FINAL_WRITEPlatform)HomeAssistantcallback)async_dispatcher_send)async_track_time_interval)IssueSeverityasync_create_issue)Integration)dt   )DOMAINTVURL_BASE)HacsUpdateCoordinator)HacsDataClient)HacsCategoryHacsDisabledReasonHacsDispatchEventHacsGitHubRepo	HacsStageLovelaceMode)AddonRepositoryExceptionHacsExceptionHacsExecutionStillInProgressHacsExpectedExceptionHacsNotModifiedExceptionHacsRepositoryArchivedExceptionHacsRepositoryExistException$HomeAssistantCoreRepositoryException)REPOSITORY_CLASSES)HACS_MANIFEST_KEYS_TO_EXPORTREPOSITORY_KEYS_TO_EXPORT)async_exists)
json_loads)LOGGER)QueueManager)async_load_from_storeasync_save_to_store)async_register_static_path)HacsRepository)HacsData)ValidationManagerc                  p    \ rS rSr% SrSrS\S'   SrS\S'   SrS\S'   Sr	S\S	'   S
r
S\S'   SS jrS rSrg)RemovedRepositoryL   zRemoved repository.N
str | None
repositoryreasonlinkstrremoval_typeFboolacknowledgedc                \    U H&  nX   c  M
  US;   d  M  U R                  X!U   5        M(     g)zUpdate data of the repository.N)rJ   rK   rM   rO   )__setattr__selfdatakeys      &/config/custom_components/hacs/base.pyupdate_dataRemovedRepository.update_dataV   s8    Cy      3i0     c                v    U R                   U R                  U R                  U R                  U R                  S.$ )z)Return a JSON representation of the data.rI   rJ   rK   rM   rO   r[   rS   s    rV   to_jsonRemovedRepository.to_jsonc   s5     //kkII -- --
 	
rY    )rT   dict)__name__
__module____qualname____firstlineno____doc__rI   __annotations__rJ   rK   rM   rO   rW   r]   __static_attributes__r_   rY   rV   rF   rF   L   sA    !J
!FJD*L#L$1
rY   rF   c                  2   \ rS rSr% SrSrS\S'   SrS\S'   \" \	S	9r
S
\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   S rS\S!'   S"rS\S#'   SrS\S$'   SrS\S%'   S)S& jrS*S' jrS(rg)+HacsConfigurationn   zHacsConfiguration class.zappdaemon/apps/rL   appdaemon_pathFrN   	appdaemondefault_factoryzdict[str, Any]configNzConfigEntry | Noneconfig_entryALLcountrydebugdev frontend_repo_urlfrontend_repozwww/community/plugin_pathzpython_scripts/python_script_pathpython_script   intrelease_limitz	hacs:hacssidepanel_iconHACSsidepanel_titlezthemes/
theme_paththemetokenc                    [        U 5      $ )zReturn a json string.)r   r\   s    rV   r]   HacsConfiguration.to_json   s    d|rY   c                    [        U[        5      (       d  [        S5      eU H  nUS;   a  M  U R                  X!U   5        M!     g)zSet attributes from dicts.zConfiguration is not valid.>   rs   	netdaemonexperimentalr}   N)
isinstancer`   r1   rQ   rR   s      rV   update_from_dict"HacsConfiguration.update_from_dict   sC    $%% =>>CMMSs), rY   r_   )returnrL   )rT   r`   r   None)ra   rb   rc   rd   re   rk   rf   rl   r	   r`   ro   rp   rr   rs   rt   rv   rw   rx   ry   rz   r}   r~   r   r   r   r   r]   r   rg   r_   rY   rV   ri   ri   n   s    "+NC+It"48FN8'+L$+GSE4CsM3'K'//M4M3%NC%!OS!JE4E3-rY   ri   c                  F    \ rS rSr% SrSrS\S'   SrS\S'   \" S5      r	S	r
g)
HacsCore   zHACS Core info.Nzpathlib.Path | Noneconfig_pathAwesomeVersion | None
ha_versionyamlr_   )ra   rb   rc   rd   re   r   rf   r   r/   lovelace_moderg   r_   rY   rV   r   r      s%    '+K$+(,J%, (MrY   r   c                      \ rS rSr% Sr\" \S9rS\S'   \" \	S9r
S\S'   \" \S9rS\S'   \" \S9rS\S	'   \" \S9rS\S
'   Srg)
HacsCommon   zCommon for HACS.rm   set[str]
categorieszdict[str, str]renamed_repositoriesarchived_repositoriesignored_repositoriesskipr_   N)ra   rb   rc   rd   re   r	   setr   rf   r`   r   r   r   r   rg   r_   rY   rV   r   r      sS     5J5+0+F.F&+C&@8@%*3%?(?3/D(/rY   r   c                  `    \ rS rSr% SrSrS\S'   SrS\S'   SrS\S'   Sr	S\S	'   Sr
S\S
'   Srg)
HacsStatus   zHacsStatus.TrN   startupFnewactive_frontend_endpoint_pluginactive_frontend_endpoint_themeinital_fetch_doner_   N)ra   rb   rc   rd   re   r   rf   r   r   r   r   rg   r_   rY   rV   r   r      s:    GTC,1#T1+0"D0#t#rY   r   c                  ~    \ rS rSr% SrSrS\S'   SrS\S'   \R                  r
SrS\S	'   SrS\S
'   \SS j5       rSrg)
HacsSystem   zHACS System info.NzHacsDisabledReason | Nonedisabled_reasonFrN   runningaction	generatorc                    U R                   SL$ )zReturn if HACS is disabled.N)r   r\   s    rV   disabledHacsSystem.disabled   s     ##4//rY   r_   )r   rN   )ra   rb   rc   rd   re   r   rf   r   r.   SETUPstager   r   propertyr   rg   r_   rY   rV   r   r      sI    15O.5GTOOEFDIt0 0rY   r   c                  h   \ rS rSr% Sr\" \S9rS\S'   \" \S9r	S\S'   \" \
S9rS\S	'   \" \
S9rS\S
'   \" \
S9rS\S'   \SS j5       r\SS j5       r\SS j5       rS S jrS!S"S jjrS#S jrS#S jrS$S jrS%S&S jjr  S'     S(S jjr  S'     S(S jjrS)S jrS*S jrS+S jrS,S jrSrg)-HacsRepositories   zHACS Repositories.rm   r   _default_repositorieszset[HacsRepository]_repositorieszdict[str, HacsRepository]_repositories_by_full_name_repositories_by_idzdict[str, RemovedRepository]"_removed_repositories_by_full_namec                ,    [        U R                  5      $ )zReturn a list of repositories.)listr   r\   s    rV   list_allHacsRepositories.list_all   s     D&&''rY   c                H    [        U R                  R                  5       5      $ )z&Return a list of removed repositories.)r   r   valuesr\   s    rV   list_removedHacsRepositories.list_removed   s     D;;BBDEErY   c                ~    U R                    Vs/ s H!  oR                  R                  (       d  M  UPM#     sn$ s  snf )z)Return a list of downloaded repositories.)r   rT   	installed)rS   repos     rV   list_downloaded HacsRepositories.list_downloaded   s.     "&!3!3K!3yy7J7J!3KKKs   ::c                b    U R                    H  nUR                  R                  U:X  d  M    g   g)z.Check if a given category has been downloaded.TF)r   rT   category)rS   r   rI   s      rV   category_downloaded$HacsRepositories.category_downloaded   s,    ..J''83 / rY   c                j   [        UR                  R                  5      nUS:X  a  gU R                  R	                  U5      =n(       ax  UR                  R
                  UR                  R
                  :X  a  gU R                  U5        UR                  R
                  UR                  l        SUR                  l        UnXR                  ;  a  U R                  R                  U5        XR                  U'   XR                  UR                  R                  '   U(       a  U R                  U5        gg)Register a repository.0NF)rL   rT   idr   get	full_name
unregisterr   r   addr   full_name_lowermark_default)rS   rI   defaultrepo_idregistered_repos        rV   registerHacsRepositories.register   s    joo(()c>"66::7CC?C##--1J1JJOOO,-7__-F-FO  *',O  $(J///"":.,6  )KU''
(G(GHj) rY   c                   [        UR                  R                  5      nUS:X  a  gU R                  US9(       d  gU R	                  U5      (       a  U R
                  R                  U5        XR                  ;   a  U R                  R                  U5        U R                  R                  US5        U R                  R                  UR                  R                  S5        g)zUnregister a repository.r   Nrepository_id)rL   rT   r   is_registered
is_defaultr   remover   r   popr   r   rS   rI   r   s      rV   r   HacsRepositories.unregister   s    joo(()c>!!!8??7##&&--g6+++%%j1  $$Wd3''++JOO,K,KTRrY   c                    [        UR                  R                  5      nUS:X  a  gU R                  US9(       d  gU R                  R                  U5        g)zMark a repository as default.r   Nr   )rL   rT   r   r   r   r   r   s      rV   r   HacsRepositories.mark_default  sH    joo(()c>!!!8""&&w/rY   c                    [        UR                  R                  5      nX2:X  a  gUS:w  a%  [        SUR                  R                   SU 35      eX!R                  l        U R                  U5        g)zUpdate a repository id.Nr   zThe repo id for z is already set to )rL   rT   r   
ValueErrorr   r   )rS   rI   r   existing_repo_ids       rV   set_repository_id"HacsRepositories.set_repository_id  sp    z112&s"":??#B#B"C D%%5$68  %j!rY   Nc                .    U(       d  gXR                   ;   $ )z!Check if a repository is default.F)r   rS   r   s     rV   r   HacsRepositories.is_default)  s     : :::rY   c                H    Ub  XR                   ;   $ Ub  X R                  ;   $ gz$Check if a repository is registered.F)r   r   )rS   r   repository_full_names      rV   r   HacsRepositories.is_registered/  s1     $ $<$<<<+'+J+JJJrY   c                    Ub  U R                  U5      nUb  U R                  U5      nWc  gUR                  R                  $ r   )	get_by_idget_by_full_namerT   r   )rS   r   r   r   s       rV   is_downloadedHacsRepositories.is_downloaded;  sG     $>>-0D+(()=>D<yy"""rY   c                Z    U(       d  gU R                   R                  [        U5      5      $ )zGet repository by id.N)r   r   rL   r   s     rV   r   HacsRepositories.get_by_idI  s$    ''++C,>??rY   c                d    U(       d  gU R                   R                  UR                  5       5      $ )Get repository by full name.N)r   r   lowerrS   r   s     rV   r   !HacsRepositories.get_by_full_nameO  s)    #..223G3M3M3OPPrY   c                    XR                   ;   $ )z!Check if a repository is removed.)r   r   s     rV   
is_removedHacsRepositories.is_removedU  s    #'N'NNNrY   c                |    U R                   R                  U5      =n(       a  U$ [        US9nX R                   U'   U$ )r   )rI   )r   r   rF   )rS   r   removeds      rV   removed_repository#HacsRepositories.removed_repositoryY  sC    ==AABVWW7WN#/CDHO//0DErY   r_   )r   zlist[HacsRepository])r   zlist[RemovedRepository])r   r*   r   rN   )F)rI   rB   r   rN   r   r   rI   rB   r   r   )rI   rB   r   rL   N)r   rH   r   rN   )NN)r   rH   r   rH   r   rN   )r   rH   r   HacsRepository | None)r   rH   r   r	  )r   rL   r   rN   )r   rL   r   rF   )ra   rb   rc   rd   re   r	   r   r   rf   r   r`   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  rg   r_   rY   rV   r   r      s    &+C&@8@).s)CM&C<ARV<W 9W5:45P2PGL]aGb&(Db( ( F F L L*4S&
0"; %)+/
!
 )
 
	
 %)+/#!# )# 
	#@QOrY   r   c                  Z   \ rS rSr% SrSrS\S'   SrS\S'   SrS\S	'   Sr	S
\S'   Sr
S\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   SrS\S'   S=S jr\S>S j5       rS?S  jrS@S! jrS=S" jrSAS# jrSAS$ jrSBS% jrSCS& jrS'S(.     SDS) jjrS'SSS*S+.             SES, jjrSFS=S- jjrSS*S*S..         SGS/ jjr S=S0 jr!\"SFSHS1 jj5       r#S=S2 jr$SFS=S3 jjr%SFS=S4 jjr&SIS5 jr'SFS=S6 jjr(SFS=S7 jjr)SFS=S8 jjr*SFS=S9 jjr+SFS=S: jjr,S=S; jr-S<r.g)JHacsBaseic  r   NzHacsData | NonerT   zHacsDataClient | Nonedata_clientrH   frontend_versionzGitHub | NonegithubzGitHubAPI | None	githubapizHomeAssistant | NonehasszIntegration | NoneintegrationzQueueManager | NonequeuezAIOGitHubAPIRepository | NonerI   zClientSession | NonesessionHacsStage | Noner   zValidationManager | None
validationr   versionc                    [        5       U l        [        5       U l        0 U l        [        5       U l        [        U l        / U l	        [        5       U l        [        5       U l        [        5       U l        g)zInitialize.N)r   commonri   configurationcoordinatorsr   corer=   logrecurring_tasksr   repositoriesr   statusr   systemr\   s    rV   __init__HacsBase.__init__t  sS     l.0GIJ	9;,. l lrY   c                .    U R                   R                  $ )z Return the HACS integration dir.)r  	file_pathr\   s    rV   integration_dirHacsBase.integration_dir  s     )))rY   c                    U(       a  U R                   U:X  a  gXl         UbS  U R                  R                  SU R                   5        U R                  [        R
                  SU R                   05        gg)zSet HACS stage.NzStage changed: %sr   )r   r  infoasync_dispatchr,   STAGE)rS   r   s     rV   	set_stageHacsBase.set_stage  sZ    TZZ5(
HHMM-tzz: 1 7 7'4::9NO rY   c                l   U R                   R                  U:X  a  gXR                   l        U[        R                  :w  a  U R                  R                  SU5        U[        R                  :X  aE  U R                  R                  U R                  R                  R                  U R                  5        gg)zDisable HACS.NzHACS is disabled - %s)r   r   r+   REMOVEDr  errorINVALID_TOKENr  add_jobr  rp   async_start_reauth)rS   rJ   s     rV   disable_hacsHacsBase.disable_hacs  s    ;;&&&0&,#'///HHNN2F;'555IId00==PPRVR[R[\ 6rY   c                    U R                   R                  b-  SU R                   l        U R                  R                  S5        gg)zEnable HACS.NzHACS is enabled)r   r   r  r(  r\   s    rV   enable_hacsHacsBase.enable_hacs  s4    ;;&&2*.DKK'HHMM+, 3rY   c                    XR                   R                  ;  aY  U R                  R                  SU5        U R                   R                  R	                  U5        [        5       U R                  U'   gg)zEnable HACS category.zEnable category: %sN)r  r   r  r(  r   r(   r  rS   r   s     rV   enable_hacs_categoryHacsBase.enable_hacs_category  sU    ;;111HHMM/:KK""&&x0*?*ADh' 2rY   c                    XR                   R                  ;   a]  U R                  R                  SU5        U R                   R                  R	                  U5        U R
                  R	                  U5        gg)zDisable HACS category.zDisabling category: %sN)r  r   r  r(  r   r  r9  s     rV   disable_hacs_categoryHacsBase.disable_hacs_category  sV    {{---HHMM2H=KK""&&x0!!(+ .rY   c                  ^ ^^#    UUU 4S jn T R                   R                  U5      I Sh  vN   [        T R                   T5      I Sh  vN $  N"! [         a'  nT R                  R	                  STU5         SnAgSnAff = f N:7f)zSave a file.c            	       > [        T[        T[        5      (       a  SOS[        T[        5      (       a  SOS [        T[        5      (       a  SOS S9 n U R                  T5        S S S 5        [        R
                  R                  T5      (       ad  TR                  S5      (       aN  [        TS5       n[        R                   " TS-   S5       n[        R                  " X5        S S S 5        S S S 5        S	T;   a  TR                  S
5      (       a  TR                  S5      S   nTR                  S5      S   nU SU 3n[        R
                  R                  U5      (       a3  TR                  R                  SU5        [        R                  " U5        g g g g ! , (       d  f       GN<= f! , (       d  f       N= f! , (       d  f       N= f)Nwwbzutf-8ignore)modeencodingerrorsz.jsrbz.gzthemesz.yaml/z/themes/r   zRemoving old theme file %s)openr   rL   writeospathisfileendswithgzipshutilcopyfileobjsplitexistsr  r(  r   )	file_handlerf_inf_outfilenamebasecombinedcontentr$  rS   s	         rV   _write_file-HacsBase.async_save_file.<locals>._write_file  sg   &w44S$$.w$<$<$#-gs#;#;x	
 ""7+ ww~~i((%%e,,i.$!YYy5'8$?5"..t; @ /
 9$););G)D)D$??3/3 z215"V8H:677>>(++HHMM">IIIh' ,	 *E$!  @? /.s0   F3F=F,%F=
F),
F:	6F==
GNzCould not write data to %s - %sF)r  async_add_executor_jobBaseExceptionr  r/  r;   )rS   r$  r\  r]  r/  s   ```  rV   async_save_fileHacsBase.async_save_file  su     	(2	))22;??? "$))Y777 @ 	 HHNN<iO	 8sI   	BA AA BBBA 
BA>9B>BBc           	     :  #     U R                  U R                  R                  5      I Sh  vN nUR                  R                  R
                  R                  =(       d    S=nS-
  S:  a  [        R                  " US-
  S-  5      $ [        R                  " [        R                  " UR                  R                  R
                  R                  5      5      nU R                  R                  SUR                  R                  R
                  R                  UR                   SUR                    SUR"                   35        U R%                  [&        R(                  5        g GN:! [*         a%  nU R                  R-                  U5         SnAgSnAff = f7f)zEHelper to calculate the number of repositories we can fetch data for.Nr   i  
   z*GitHub API ratelimited - %s remaining (%s):)async_github_api_methodr  
rate_limitrT   	resourcesr  	remainingmathfloorr#   as_localutc_from_timestampresetr  r(  hourminutesecondr3  r+   
RATE_LIMITr`  	exception)rS   responselimitrn  rs  s        rV   async_can_updateHacsBase.async_can_update  s5    	*!99$..:S:STTH"--1166@@EAEMRTTzz54<2"566KK 5 5hmm6M6M6R6R6X6X YZEHHMM<'',,66::,a~Qu||n=
 0;;< ! U 	* HHy))	*sL   F(E) E&AE) F	CE) %F&E) )
F3FFFFT)raise_exceptionc                 #    Sn U" U0 UD6I Sh  vN $  N! [          a+  nU R                  [        R                  5        Un SnAOSnAf[         a+  nU R                  [        R
                  5        Un SnAOZSnAf[         a  nUeSnAf[         a  nUn SnAO7SnAf[         a'  nU R                  R                  U5        Un SnAOSnAff = fU(       a  Ub  [        U5      eg7f)zCall a GitHub API methodN)r   r3  r+   r0  r   rr  r   r   r`  r  rs  r1   )rS   methodrx  argskwargs
_exceptionrs  s          rV   rf   HacsBase.async_github_api_method  s      
	#00000, 	#0>>?"J' 	#0;;<"J) 	O 	#"J 	# HHy)"J	# z5
++sx   C+  C+ 
C!AC+C!A;6C+;CB

CBC+C+CC+CC+F)checkrefr   r   c               ~  #    XR                   R                  ;   a"  U[        R                  :w  a  [	        SU 35      eUS:X  a
  [        5       eUS:X  d  UR                  S5      (       a
  [        5       eU[        ;  a  U R                  R                  SUU5        gU R                   R                  R                  U5      =nb  Un[        U   " X5      nU(       GaN   UR                  U5      I Sh  vN   UR                  R                  (       a  U R                   R                  R!                  UR"                  R$                  5        U R&                  R(                  (       d  U R                  R+                  SU5        U R,                  R.                  (       a  [1        SU S	35      eUR                  R                  $ U R,                  R.                  (       a'  UR2                  R5                  S
UR6                  5        O'UR2                  R5                  SUR6                  5         U R&                  R@                  (       a  SUR"                  l         Ub  XXR"                  l!        O{U RD                  bn  U(       ag  UR"                  R@                  (       aL  U RG                  [H        RJ                  SUR"                  R$                  UR"                  RB                  S.5        U RL                  RO                  X5        g GN! [8        [:        4 aL  n	U R,                  R<                  (       a'  UR2                  R+                  SUR6                  U	5         Sn	A	gSn	A	f[>         aQ  n	U R                   R                  R!                  UR"                  R$                  5        [1        SU SU	 S35      U	eSn	A	ff = f7f)r   z	Skipping zhome-assistant/corezhome-assistant/addonszhassio-addons/zA%s is not a valid repository category, %s will not be registered.NzValidation for %s failed.z::error:: Validation for z failed.z%s Validation completedz%s Registration completedz%s Registration Failed - %szValidation for z failed with .Fregistration)r   rI   r   )(r  r   r-   INTEGRATIONr3   r7   
startswithr0   r8   r  warningr   r   async_registrationvalidaterF  r   rT   r   r  r   r/  r   r   r1   loggerr(  stringr6   r5   r   r   r   r   r  r)  r,   
REPOSITORYr  r   )
rS   r   r   r  r  r   r   renamedrI   rs  s
             rV   async_register_repository"HacsBase.async_register_repository  s      ;;#3#33#~'A'AA+i8L7M,NOO#88688#::>R>]>]?
 ?
 +,,--HHS$
 {{77;;<PQQG^#* %7%A$%]
! 33C888&&--KK$$(()B)BC;;..'BDXY{{))+7 4865=?  &..555;;%%%%**+DjFWFWX%%**+F
HYHYZ ;;??"'JOO$!.OO yy$:??3F3F##%00"0&0oo&?&?)3);); 	"":7[ 9 12QR ;;((%%++5z7H7H) ( !  $$Z__%>%>?#%,&.-:9+QH !!!sk   CN=L 2L3CL N=AL N=&L *CN=L N:AMN=N:)AN55N::N=c           
       #    U R                  [        R                  5        U R                  5       I Sh  vN   [	        U R
                  S5      I Sh  vN =n(       aE  U H?  nUS   (       a  M  U R                  R                  S5        [        U R
                  SSS9    O   U R                  R                  [        U R
                  U R                  [        SS	95      5        U R                  R                  [        U R
                  U R                  [        SS	95      5        U R                  R                  [        U R
                  U R                  [        S
S	95      5        U R                  R                  [        U R
                  U R                  [        SS95      5        U R                  R                  [        U R
                  U R                   [        SS95      5        U R                  R                  [        U R
                  U R"                  [        S
S	95      5        U R
                  R$                  R'                  [(        U R*                  R,                  5      nU R.                  R0                  =n(       a  UR3                  U5        U R                  R5                  S[7        U R                  5      5        SU R8                  l        U R=                  [>        R@                  0 5        U RC                  5       I Sh  vN   U R                  5       I Sh  vN   U R                  [        RD                  5        U R=                  [>        RF                  SS05        U R#                  5       I Sh  vN   U R!                  5       I Sh  vN   U R=                  [>        R@                  0 5        g GN GNh N N NG N17f)z#Tasks that are started after setup.NcriticalrO   zURGENT!: Check the HACS panel!zURGENT!z**Check the HACS panel!**)titlemessage0   )hours   r{   )minutesrd  z&There are %s scheduled recurring tasksFforceT)$r+  r.   STARTUPasync_load_hacs_from_githubr?   r  r  r  $async_create_persistent_notificationr  appendr   r
   +async_update_downloaded_custom_repositories#async_get_all_category_repositoriesasync_check_rate_limitasync_process_queue"async_handle_critical_repositoriesbusasync_listen_oncer   rT   async_force_writer  rp   async_on_unloadrs   lenr  r   r)  r,   STATUS!async_handle_removed_repositoriesRUNNINGRELOAD)rS   _r  r   unsubrp   s         rV   startup_tasksHacsBase.startup_tasks`  s    y(()..0002499jIII8I N++HH%%&FG8		<W  ! 	##%		00#	
 	##%		4KKY]_M`	
 	##%		4CCYUVEW	
 	##%dii1L1Li`aNbc	
 	##%dii1I1I9]_K`a	
 	##%		4BBITUDV	
 		//+TYY-H-H
  --:::<:((/?TEYEYAZ[#-44b94466666888y(()-44woF55777&&(((-44b9C 	1Ij 	78 	8(sq   3ON8ON;O0JO	N>
O!O "AO:O;OO&O;O>O OOO)headerskeep_urlnologc                 #    Uc  gU(       d  SU;   a  UR                  SS5      nU R                  R                  SU5        SnUS:  an   U R                  R	                  U[        SS9US	9I Sh  vN nUR                  S
:X  a  UR                  5       I Sh  vN $ [        SUR                   SU 35      eg NH N"! [         aH    U R                  R                  SUSU-
  5        US-  n[        R                  " S5      I Sh  vN     M  [         a-  nU(       d  U R                  R                  SU5         SnAgSnAff = f7f)z'Download files, and return the content.Nztags/ru   zTrying to download %sr   r{   <   )total)urltimeoutr     zGot status code z when trying to download aB  A timeout of 60! seconds was encountered while downloading %s, using over 60 seconds to download a single file is not normal. This is not a problem with HACS but how your host communicates with GitHub. Retrying up to 5 times to mask/hide your host/network problems to stop the flow of issues opened about it. Tries left %s   r$   zDownload failed - %s)replacer  rs   r  r   r   r  readr1   TimeoutErrorr  asynciosleepr`  rs  )	rS   r  r  r  r  r  timeoutsrequestrs  s	            rV   async_download_fileHacsBase.async_download_file  sL     ;GsN++gr*C.4l#J $ 0 0)3# !1 !  >>S(!(//#&'('@G   0     $ \	 AmmA&&& J HH&&'=yIJsy   AE%B= 0B91'B= B;B= EB= 8E9B= ;B= =AEDEE	E#D?:E?EEc                N  #    [         R                  /nU R                  R                  [	        S5      :  a  [
        R                  " 5       nU ISh  vN   U R                  R                  R                  n/ U R                  R                  l	        U R                  R                  R                  U R                  R                  US9I Sh  vN   X0R                  R                  l	        SSS5      ISh  vN   O@U R                  R                  R                  U R                  R                  US9I Sh  vN   U R                  R                  R                  U R                  R                  U5      I Sh  vN   g GN. N N! , ISh  vN  (       d  f       Na= f Nh N(7f)zRecreate entities.z2024.6.0N)entry	platforms)r   UPDATEr  r   r   r  Lockr  rp   
_on_unloadr  config_entriesasync_unload_platformsasync_forward_entry_setups)rS   r  unload_platforms_lock	on_unloads       rV   async_recreate_entities HacsBase.async_recreate_entities  sU    __%	 99."<<$+LLN!,, ..;;FF	=?""//:ii..EE,,99' F    >G""//: -,, ))**AA((55# B    ii&&AA++Y
 	
 	
 - -,,,	
s{   AF%F F%A7FFF,F%7F8A F%8F!9AF%:F#;F%FF%FFFF%#F%c                0    [        U R                  X5        g)zDispatch a signal with data.N)r   r  )rS   signalrT   s      rV   r)  HacsBase.async_dispatch  s     	dii6rY   c                :   [        5       U R                  l        [        R                  [        R
                  [        R                  4 H  nU R                  [        U5      5        M     [        R                  U R                  R                  R                  ;   d.  U R                  R                  [        R                  5      (       a  U R                  [        R                  5        U R                  R                  R                  SS5      (       d.  U R                  R                  [        R                   5      (       a  U R                  [        R                   5        U R"                  R$                  (       a   U R                  [        R&                  5        gg)zSet the active categories.frontendreload_themesN)r   r  r   r*   r  PLUGINTEMPLATEr:  PYTHON_SCRIPTr  ro   
componentsr  r   serviceshas_serviceTHEMEr  rl   	APPDAEMONr9  s     rV   set_active_categoriesHacsBase.set_active_categories  s   !$%11<3F3FH]H]^H%%l8&<= _ &&$))*:*:*E*EE  44\5O5OPP%%l&@&@A99))
 
22<3E3EFF%%l&8&89''%%l&<&<= (rY   c                  #    U R                   R                  (       a  g U R                  R                  [        R
                  5      nSnUca  SnU R                  [        R
                  [        R
                  SS9I Sh  vN   U R                  R                  [        R
                  5      nO_U R                   R                  (       dD  U R                  R                  S5        U R                  R                  UR                  5       5        Uc  [        S5      eSUR                  l        U R"                  R$                  R&                  UR                  l        SUR                  l        SUR                  l        U(       a  U R/                  5       I Sh  vN   UR0                  U l        U R                  R5                  U5        g GNJ N4! [         ap  nS[7        U5      ;   a  U R                  R9                  S5        OU R                  R9                  S	U5        U R;                  [<        R>                  5         SnAgSnAff = f7f)
zLoad HACS from GitHub.NFT)r   r   r   z%Scheduling update of hacs/integrationzUnknown error403z1GitHub API is ratelimited, or the token is wrong.zCould not load HACS! - %s) r  r   r  r   r-   r  r  r*   r   r  r/  r  r   common_updater1   rT   r   r  r  r  installed_versionr   releasesr  repository_objectrI   r   rL   r  r3  r+   	LOAD_HACS)rS   r  rI   should_recreate_entitiesrs  s        rV   r  $HacsBase.async_load_hacs_from_github  s    ;;(("	<**;;N<V<VWJ',$!+/(44)7)C)C)55  5   
 "..??@Z@Z[
[[((FG

z779:!#O44(,JOO%040@0@0H0H0O0OJOO-"'JOO'+JOO$'22444(::DO**:6+$ 5  	<I&!!G !!"=yI0::;;	<sU   IA G  G
DG G0G 	I
G G 
I	A&I?II		Ic                8  #    U R                   R                  (       a  gU R                  R                  S5        [        R
                  " U R                  R                  =(       d    /  Vs/ s H  nU R                  U5      PM     sn6 I Sh  vN   gs  snf  N
7f)zGet all category repositories.NzLoading known repositories)	r   r   r  r(  r  gatherr  r   ,async_get_category_repositories_experimental)rS   r  r   s      rV   r  ,HacsBase.async_get_all_category_repositories;  s     ;;23nn !% 6 6 <" < <H AA(K <
 	
 	
	
s   A)B+BBBBc                j  #    U R                   R                  SU5         U R                  R                  USS9I Sh  vN nU R                  R                  X!5      I Sh  vN   UR                  5        GH  u  pEUS   nU R                  R                  R                  U5      (       a  U R                  R                  U   nU R                  R                  U5      (       a  Mp  X`R                  R                  ;   a  M  U R                  R!                  U5      =n(       d  M  U R                  R#                  Xt5        U R                  R%                  U5        UR                  R&                  b.  UR                  R&                  R)                  5       US   :  d  GM*  UR                  R+                  0 [-        [.        5      EUE5        UR                  S	5      =nc  GMm  UR0                  R+                  0 [-        [2        5      EUE5        GM     US
:X  a  SU R4                  l        U R8                  [:        R<                  :X  a  U R                  R>                   H  nUR                  R@                  U:X  d  M  UR                  RB                  (       a  M<  U R                  RE                  UR                  RF                  5      (       a  Mr  URH                  R                  SURJ                  5        U R                  RM                  U5        M     U RO                  [P        RR                  0 5        U RT                  U   RW                  5         g GN! [         a    U R                   R                  SU5         g[
         a&  nU R                   R                  SX5         SnAgSnAff = f GNP7f)z!Update all category repositories.zFetching updated content for %sTr  NzNo updates for %szCould not update %s - %sr   last_fetchedmanifestr  z%%s Unregister stale custom repository),r  rs   r  get_datar4   r1   r/  rT   register_unknown_repositoriesitemsr  r   r   r  r  r   r   r   r   r  	timestamprW   r`   r:   repository_manifestr9   r  r   r   r.   r  r   r   r   r   r   r  r  r   r)  r,   r  r  async_update_listeners)	rS   r   category_datars  r   	repo_data	repo_namerI   r  s	            rV   r  5HacsBase.async_get_category_repositories_experimentalG  s    8(C	"&"2"2";";Ht";"TTM ii55mNNN"/"5"5"7G!+.I{{//33I>> KK<<YG	  ++I66KK===!..??	JJzJ!!33JH!!..z:??//7OO00::<y?XXOO//0`48Q3R0`V_0`a$-MM*$==J"66BBNt$@ANXN! #8( }$,0DKK)::***"//88
OO,,8&OO555 --889K9KLL%%++?ARAR %%00< 9 	-88"=(#::<] U' 	HHNN.9 	HHNN5xK	 	Os~   N3M MM N3 N0!B?N3$A6N3>N3"BN3=N32N3BN3M &N-<N3>	N-N(#N3(N--N3c                  #    U R                   R                  (       a(  U R                   R                  [        R                  :w  a  gU R
                  R                  S5        U R                  5       I Sh  vN nU R
                  R                  SU5        US:  a)  U R                  5         U R                  5       I Sh  vN   gg NP N7f)zCheck rate limit.Nz Checking if ratelimit has liftedz#Ratelimit indicate we can update %sr   )
r   r   r   r+   rr  r  rs   rv  r6  r  )rS   r  
can_updates      rV   r  HacsBase.async_check_rate_limit{  s     {{##t{{'B'BFXFcFc'c9:0022
<jI>**,,,  3 -s%   A3C
5C6A	C
?C C
C
c                  ^ ^#    T R                   R                  (       a  T R                  R                  S5        gT R                  R
                  (       d  T R                  R                  S5        gT R                  R                  (       a  T R                  R                  S5        gUU 4S jmT" 5       I Sh  vN   g N7f)zProcess the queue.zHACS is disabledNzNothing in the queuezQueue is already runningc                   >#    TR                   R                  (       d#  TR                  R                  5       I S h  vN   g TR	                  5       I S h  vN n TR
                  R                  SU TR                   R                  5        U S:w  a4   TR                   R                  U 5      I S h  vN   T" 5       I S h  vN   g g  N Nr N! [         a     g f = f N7f)Nz-Can update %s repositories, items in queue %sr   )
r  has_pending_tasksrT   async_writerv  r  rs   pending_tasksexecuter2   )r  _handle_queuerS   s    rV   r  3HacsBase.async_process_queue.<locals>._handle_queue  s     :://ii++---#4466JHHNN?

((
 Q**,,Z888 $o%%  .6 93  &sc   9CCCC;CC 0C
1C 5
C?C CC
C 
CCCC)r   r   r  rs   r  r  r   )rS   r  r  s   ` @rV   r  HacsBase.async_process_queue  s{     ;;HHNN-.zz++HHNN12::HHNN56	&$ os   B7C;C<Cc                  #    U R                   R                  (       a  gSnU R                  R                  S5         U R                  R                  SSS9I Sh  vN nU H2  nU R                  R                  US   5      nUR                  U5        M4     U R                  R                   GHY  nU R                  R                  UR                  5      =nc  M.  UR                  R                  U R                  R                   ;   a  M^  UR                  R"                  (       a  UR$                  S:w  a  ['        U R(                  [*        S	UR                  R,                   3S[*        [.        R0                  SUR                  R                  UR2                  UR                  R,                  S
.S9  U R                  R5                  SUR                  R                  UR2                  5        GMD  GMG  SnUR7                  5         GM\     U(       a#  U R                  R9                  5       I Sh  vN   gg GN! [         a     gf = f N7f)zHandle removed repositories.NFzLoading removed repositoriesr  Tr  rI   r  removed_)namerJ   repositry_id)r  domainissue_id
is_fixableissue_domainseveritytranslation_keytranslation_placeholdersz~You have '%s' installed with HACS this repository has been removed from HACS, please consider removing it. Removal reason (%s))r   r   r  r(  r  r  r1   r  r  rW   r   r   rI   rT   r   r  r   r   rM   r!   r  r%   r   r    WARNINGrJ   r  r   r  )rS   r  need_to_saveremoved_repositoriesitemr  rI   s          rV   r  *HacsBase.async_handle_removed_repositories  s    ;;45	)-)9)9)B)B9W[)B)\#\  )D''::4;MNG% ) ((55G"//@@ASASTT
]((DKK,L,LL(('':5&!YY%#+JOO,>,>+?!@#(%+!.!6!6(1$.OO$=$=&-nn,6OO,>,>2 HH$$. #11 6.  $!!#= 6@ ))''))) Q $] 		P *sG   :IH9 H6H9 GI/I	0I6H9 9
IIIIc                  ^ ^^#    T R                   R                  (       a  gT R                  R                  S5        Sm[        R
                  " 5       mS	UU4S jjnT R                  R                   H  nUR                  R                  T R                  R                  ;   d  M3  T R                  R                  UR                  R                  5      (       a  Mi  TS-  mT R                  R                  U" U5      5        M     S
UU 4S jjnT R                   R"                  =n(       a#  UR%                  T R&                  U" 5       S5        O!T R&                  R%                  U" 5       S5        T R                  R)                  S5        g7f)zExecute the task.NzEStarting recurring background task for downloaded custom repositoriesr   c                z   >#    U R                  SS9I Sh  vN   TS-  mT(       d  TR                  5         gg N"7f)zUpdate a repositoryT)ignore_issuesNr$   )update_repositoryr   )rI   repositories_to_updaterepositories_updateds    rV   r  OHacsBase.async_update_downloaded_custom_repositories.<locals>.update_repository  sD      ..T.BBB"a'")$((* * Cs   ;9#;r$   c                    >#    TR                  5       I Sh  vN   TR                  R                  5        H  n U R                  5         M     g N67f)zUpdate all coordinators.N)waitr  r   r  )coordinatorr  rS   s    rV   update_coordinatorsQHacsBase.async_update_downloaded_custom_repositories.<locals>.update_coordinators  sB     &++---#00779224  : .s   AA7Ar  zARecurring background task for downloaded custom repositories doner  r   r   )r   r   r  r(  r  Eventr  r   rT   r   r  r   r   r   r  r   r  rp   async_create_background_taskr  rs   )rS   r  r  rI   r  rp   r  r  s   `     @@rV   r  4HacsBase.async_update_downloaded_custom_repositories  s&    ;;]^!"&}}	+ 	+ ++;;J((DKK,B,BB))44Z__5G5GHH&!+&

0<= <	5 	5  --:::<:55		.02G II223F3HJ_`Z[s   BF&2FB0Fc                  #    [        U R                  S9n/ n/ nSn U R                  R                  SSS9I Sh  vN nU(       d  U R                  R                  S5        g[        U R                  S5      I Sh  vN nU=(       d    /  H  nUR                  US   5        M     / nU H  nU R                  R                  US   5      n	SU	l        U R                  R                  US   5      n
US   US	   US
   SS.nUS   U;  as  U
bp  U
R                  R                   (       aU  U R                  R#                  SUS   5        SnSUS'   UR%                  U
R'                  5       5        U
R)                  5         UR                  U5        U	R+                  U5        M     UR-                  5       I Sh  vN   [/        U R                  SU5      I Sh  vN   U(       aP  U R                  R#                  S5        U R                  R1                  U R                  R3                  S5      5        gg GN! [        [
        4 a     g[         a     GNf = f GN N N7f)zHandle critical repositories.)r  Fr  Tr  NzNo critical repositoriesrI   rJ   rK   )rI   rJ   rK   rO   z0Removing repository %s, it is marked as criticalrO   zRestarting Home Assistantd   )r>   r  r  r  r   r4   r1   r  rs   r?   r  r  r  rM   r   rT   r   r  r   	uninstallr   rW   r  r@   async_create_task
async_stop)rS   r  critical_queueinstoredr  was_installedstored_criticalstoredrI   removed_repor   s              rV   r  +HacsBase.async_handle_critical_repositories  s6    %4995	!--66zD6QQH HHNN56 5dii LL%++FOOF<01 , "J,,??
<@XYL(2L%$$55j6NOD )6$X."6* $	F ,'x7#		(;(;HH%%J"<0 %)M-2F>*"&&t~~'78KKM""6*$$V,1 #6 $$&&& "$))ZIII HH9:II''		(<(<S(AB e R*,DE 	 		 MD 	' 	Jsu   IH4 H1H4 <I;I<D9I5I6IIAI1H4 4II	IIIIIIc                N  #    U R                   R                  (       dF  [        U R                  U R                  R                  R                  S5      5      I Sh  vN (       d  gU R                  R                  S5        U R                  R                  S:H  nU R                  R                  SU R                  R                  U5        [        U R                  [        U R                  R                  R                  S5      US9I Sh  vN   SU R                   l        g N N7f)z@Setup the http endpoints for plugins if its not already handled.zwww/communityNzSetting up plugin endpointstoragez1<HacsFrontend> %s mode, cache for /hacsfiles/: %s)cache_headersT)r  r   r;   r  ro   rN  r  r(  r  r   rA   r'   )rS   	use_caches     rV   $async_setup_frontend_endpoint_plugin-HacsBase.async_setup_frontend_endpoint_plugin@  s     ;;66LIItyy'',,_=E
 ?
 ?
 23II++y8	?II##	
 )IIII!!/2#	
 	
 	
 7;3)?
	
s%   AD%D!B/D%
D#D%#D%)r  r  r  r  r  r  r  rI   r   r  r   r!  )r   zpathlib.Path)r   r  r   r   )rJ   r+   r   r   )r   r*   r   r   )r$  rL   r\  r   r   rN   )r   r|   )rz  zCallable[[], Awaitable[TV]]rx  rN   r   z	TV | None)r   rL   r   r*   r  rN   r  rH   r   rH   r   rN   r   r   r  )
r  rL   r  dict | Noner  rN   r  rN   r   zbytes | None)r  r,   rT   r7  r   r   )r   rL   r   r   )/ra   rb   rc   rd   re   rT   rf   r  r  r  r  r  r  r  rI   r  r   r  r  r!  r   r%  r+  r3  r6  r:  r=  ra  rv  rf  r  r  r  r  r   r)  r  r  r  r  r  r  r  r  r  r5  rg   r_   rY   rV   r  r  c  s    D/ )-K&-#'j' FM "&I&!%D
%&*K#*!%E%04J-4$(G!("E"+/J(/%)G")
# * *P
]-B,%8N2 !%	+ 	 
L $(R8!R8 R8
 R8 R8 "R8 R8 
R8hD:T  $99 	9
 9 9 
9v
0 7 7>('<R

2=h
-@1*f&\P<C|;rY   r  )qre   
__future__r   r  collections.abcr   r   dataclassesr   r   r	   datetimer
   rQ  rj  rM  pathlibrR  typingr   r   aiogithubapir   r   r   r   r   r   r   aiogithubapi.objects.repositoryr   aiohttp.clientr   r   awesomeversionr   0homeassistant.components.persistent_notificationr   r  homeassistant.config_entriesr   homeassistant.constr   r   homeassistant.corer   r    homeassistant.helpers.dispatcherr   homeassistant.helpers.eventr   $homeassistant.helpers.issue_registryr    r!   homeassistant.loaderr"   homeassistant.utilr#   constr%   r&   r'   r  r(   r  r)   enumsr*   r+   r,   r-   r.   r/   
exceptionsr0   r1   r2   r3   r4   r5   r6   r7   r  r8   repositories.baser9   r:   utils.file_systemr;   
utils.jsonr<   utils.loggerr=   utils.queue_managerr>   utils.storer?   r@   utils.workaroundsrA   rB   
utils.datarC   validate.managerrD   rF   ri   r   r   r   r   r   r  r_   rY   rV   <module>rW     sr    "  / 0 0    	   %   C 7 ) 5 I 6 B A R , ! ' ' . ' 	 	 	 - V + "   - C 91$3 
 
 
B "- "- "-J ) ) ) 0 0 0 $ $ $ 0 0 0 \ \ \~s; s;rY   