
    i-                    8   S r SSKJr  SSK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  SSKJr  SSKrSS	KJrJrJr  SS
KJr  SSKJrJrJrJr  SrSrSr\R@                  " \!5      r"      S S jr#    S!S 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 jr*    S'           S*S jjr+\" SS9 " S S5      5       r,\" SS9 " S S5      5       r-\" SS9 " S S5      5       r.g)+zA
Implements the DIAL-protocol to communicate with the Chromecast
    )annotations)	dataclass)
HTTPStatusN)UUID)Any   )CAST_TYPE_AUDIOCAST_TYPE_CHROMECASTCAST_TYPE_GROUP)ZeroConfInstanceRequired)ZEROCONF_ERRORSCastInfoHostServiceInfoMDNSServiceInfoz!{urn:schemas-upnp-org:device-1-0}zhttp://{}:8008zhttps://{}:8443c                   Sn[        U [        5      (       a  U R                  U R                  S4$  U(       d  [        eUR                  SU R                  5      nU(       a  [        R                  SU U5        O[        R                  SU 5         [        U5      U4-   $ ! [         a    [        R                  SSS9   N/f = f)z#Resolve host and port from service.Nz_googlecast._tcp.local.z<get_info_from_service resolved service %s to service_info %sz2get_info_from_service failed to resolve service %szget_info_from_service raised:T)exc_info)
isinstancer   hostportr   get_service_infoname_LOGGERdebugr   _get_host_from_zc_service_info)servicezconfservice_infos      H/home/sebas/venvs/catt/lib/python3.13/site-packages/pychromecast/dial.pyget_host_from_servicer      s     L'?++gllD11F**--.GVMMN MMD *,7</II	  F 	5EFs   AB  :B   C Cc                &   SnSnU (       a  U R                   (       as  [        U R                  5      S:  a$  [        R                  " U R                  S   5      nO'U R
                  b  U R
                  R                  5       nUb  U R                   nX4$ )z5Get hostname or IP + port from zeroconf service_info.Nr   )r   len	addressessocket	inet_ntoaserverlower)r   r   r   s      r   r   r   >   s     DD))|%%&*##L$:$:1$=>D  ,&&,,.D$$D<    c                   SS0n [         R                  R                  XS9n[         R                  R                  XAUS9$ ! [         R                  R
                   a  nUR                  [        R                  :w  a  e [        R                  SU 5        SUS'   [         R                  R                  XS9n[         R                  R                  XAUS9s SnA$ SnAff = f)	zHelp open an URL.zcontent-typezapplication/json)headers)timeoutcontextz3Failed to fetch %s, retrying with empty host header r   N)urllibrequestRequesturlopenerror	HTTPErrorcoder   	FORBIDDENr   r   )urlr*   r+   r)   reqerrs         r   _urlopenr8   N   s    12GMnn$$S$:~~%%cG%LL<<!! M88z+++ 	KSQnn$$S$:~~%%cG%LLMs   :A CA4CCCc                   U R                  5        H1  n[        Xa5      u  n  nU(       d  M  [        R                  SXg5          O   U(       a  [        R                  W5      U-   n	O[        R                  W5      U-   n	[        U5      n
U(       a  U
(       d
  [        5       n[        XU5       nUR                  5       nSSS5        U[        R                  " WR                  S5      5      4$ ! , (       d  f       N5= f)z Query a cast device via http(s).zResolved service %s to %sNzutf-8)copyr   r   r   FORMAT_BASE_URL_HTTPSformatFORMAT_BASE_URL_HTTPboolget_ssl_contextr8   readjsonloadsdecode)servicesr   pathsecurer*   r+   r   r   _r5   has_contextresponsedatas                r   _get_statusrK   d   s     ==?*7:
a4MM5wE	 # #**4047"))$/$6w-Kk!#	#	(H}} 
)$**T[[1233 
)	(s   -C--
C;c                     [         R                  " [         R                  5      n SU l        [         R                  U l        U $ )zCreate an SSL context.F)ssl
SSLContextPROTOCOL_TLS_CLIENTcheck_hostname	CERT_NONEverify_mode)r+   s    r   r?   r?      s/    nnS445G"G--GNr'   c           
        [         nSnU R                  S:w  a	  [        nSnOSn Sn[        U R                  USSUU5      u  phSU;   a;  US   n	U	R                  S0 5      n
U
R                  S	S5      nU	R                  S
U5      nU(       d  [        n[        R                  SXE5        [!        U R                  U R"                  U R$                  U R&                  U R(                  U R                  UU5      $ ! [        R                  R                  [        R                  R                  [        [        4 a2  n[        R                  SUUU R                  5        [         n SnANSnAff = f)z6Add cast type and manufacturer to a CastInfo instance.Unknown manufacturerI  zGoogle Inc.z	<unknown>T*/setup/eureka_info?params=device_info,namedevice_infocapabilitiesdisplay_supportedmanufacturerzcast type: %s, manufacturer: %sz<Failed to determine cast type for host %s (%s) (services:%s)N)r
   r   r   rK   rD   getr	   r   r   r-   r1   r2   URLErrorOSError
ValueErrorwarningr   uuid
model_namefriendly_namer   )	cast_infor   r*   r+   	cast_typerZ   r   rY   statusrW   rX   r7   s               r   get_cast_typerf      sW    %I)L~~#	$&!	- $&""<LD &$]3*~rB$0$4$45H$$O!*~|L$+	MM;YU  	 	 LL""LL!!	
 	- OON""	 -I	-s   BC5 5AE)7(E$$E)c           	         Uc  [        U S5      1n [        UUSSUS-  U5      u  pV[        nSnUR                  SS5      n	S	n
S
nSnSnSU;   a  US   nUR                  S0 5      nUR                  SS5      nUR                  SS5      nUR                  SU	5      n	UR                  SU5      nUR                  SU
5      n
UR                  SS5      nOUR                  SS5      nU(       d  [        nSnU(       a  [        UR                  SS5      5      n[        U	UU
UUU5      $ ! [        R                  R                  [        R                  R
                  4 a    [        UUSSUS-  U5      u  pV GNOf = f! [        R                  R                  [        R                  R
                  [        [        4 a+  n[        R                  SU U[!        U5      5         SnAgSnAff = f)z@Return a filled in DeviceStatus object for the specified device.NrU   rV   T   Fr   zUnknown ChromecastrT   zUnknown model namerW   rX   rY   multizone_supportedra   rZ   ssdp_udn-r,   z)Failed to get device info for %s: %s (%s))r   rK   r-   r1   r2   r\   r
   r[   r	   r   replaceDeviceStatusr]   r^   r   r   type)r   rD   r   r*   r+   rG   re   rd   rY   rb   rZ   ra   ri   udnrW   rX   r`   r7   s                     r   get_device_inforp      s   ?'d34H	#<!IA$ )	 

6+?@-)
#F" /K&??>2>L , 0 01Dd K"."2"23H$"O'OOFMBM$zBJ&??><HL//*d3C**Z.C 'IC,-D
 	
M &&(=(=> 	#<!IAv	^ LL""FLL$9$97JO A4dSViXs<   E; D' C>E; 'AE84E; 7E88E; ;AG(=!G##G(MultizoneInfoc                J   UR                  SS5      nUR                  SS5      nSnU(       a  [        UR                  SS5      5      nUR                  SS5      nUR                  SS	5      nSnSnUS
:X  a  SU;   a  U nUS   nO[	        U5      S:X  a  US   n[        X$Xx5      $ )z:Parse group JSON data and return a MultizoneInfo instance.r   zUnknown group namer`   Nrk   r,   elected_leader:r   self	cast_portrh   r   )r[   r   rl   rsplitr!   rq   )	r   groupr   ro   r`   rs   elected_leader_splitleader_hostleader_ports	            r   _get_group_infor|     s    99V12D
))FD
!CD
CKKR()YY/4N)00a8KKK5$8K(	!	"a	'*1-[>>r'   c           	     $    Uc  [        U S5      1n[        UUSSUU5      u  pV/ nSU;   a2  SUS   ;   a)  US   S    H  nUR                  [        X5      5        M     / n	SU;   a2  SUS   ;   a)  US   S    H  nU	R                  [        X5      5        M     [	        Xy5      $ ! [
        R                  R                  [
        R                  R                  [        [        4 a*  n
[        R                  SX
[        U
5      5         Sn
A
gSn
A
ff = f)	zCReturn a filled in MultizoneStatus object for the specified device.NrU   z#/setup/eureka_info?params=multizoneT	multizonedynamic_groupsgroupsz.Failed to get multizone status for %s: %s (%s))r   rK   appendr|   MultizoneStatusr-   r1   r2   r\   r]   r^   r   r   rn   )r   rD   r   r*   r+   rG   re   r   rx   r   r7   s              r   get_multizone_statusr   (  s   'd34H1
	 & %59L%L,-=>%%od&BC ? & X1D%D,X6od:; 7 ~66LL""FLL$9$97JO <dc	
 	s   B B# #AD% D

DT)frozenc                  B    \ rS rSr% SrS\S'   S\S'   S\S'   S	\S
'   Srg)rq   iP  zMultizone info container.strrb   UUID | Noner`   z
str | Noner   z
int | Noner    N__name__
__module____qualname____firstlineno____doc____annotations____static_attributes__r   r'   r   rq   rq   P  s    #


r'   c                  .    \ rS rSr% SrS\S'   S\S'   Srg)r   iZ  zMultizone status container.zlist[MultizoneInfo]r   r   r   Nr   r   r'   r   r   r   Z  s    %''r'   r   c                  V    \ rS rSr% SrS\S'   S\S'   S\S'   S\S'   S\S	'   S
\S'   Srg)rm   ib  zDevice status container.r   rb   ra   rZ   r   r`   rd   r>   ri   r   Nr   r   r'   r   rm   rm   b  s'    "O
Nr'   rm   )r   z!HostServiceInfo | MDNSServiceInfor   zeroconf.Zeroconf | Nonereturnz:tuple[str | None, int | None, zeroconf.ServiceInfo | None])r   zzeroconf.ServiceInfo | Noner   ztuple[str | None, int | None])r5   r   r*   floatr+   ssl.SSLContext | Noner   r   )rD   z&set[HostServiceInfo | MDNSServiceInfo]r   r   rE   r   rF   r>   r*   r   r+   r   r   ztuple[str | None, Any])r   zssl.SSLContext)N   N)
rc   r   r   r   r*   r   r+   r   r   r   )NNr   N)r   r   rD   -set[HostServiceInfo | MDNSServiceInfo] | Noner   r   r*   r   r+   r   r   zDeviceStatus | None)r   r   rx   r   r   rq   )r   r   rD   r   r   r   r*   r   r+   r   r   zMultizoneStatus | None)/r   
__future__r   dataclassesr   httpr   rA   loggingr#   rM   urllib.requestr-   r`   r   typingr   zeroconfconstr	   r
   r   r1   r   modelsr   r   r   r   XML_NS_UPNP_DEVICEr=   r;   	getLoggerr   r   r   r   r8   rK   r?   rf   rp   r|   r   rq   r   rm   r   r'   r   <module>r      s%   # !     
     I I + O O8 ' ) 


H
%J.J7OJ?J>-" M,444#4 4 	4
 4 #4 4< '+%)	::#: : #	:
 :~ ?C&*%)H
H;H $H 	H
 #H HV?0 ?C&*%)%
%;% $% 	%
 #% %P $   $      $  r'   