
    |;iI1                        d Z ddlmZ ddlmZ ddlmZmZmZ ddl	m
Z
mZ ddlmZmZmZmZmZmZmZmZ ddlmZ dd	lmZmZ eeeeefZe
eeeeef   Zeeeeef   f   ZeZeZ e!Z"e#Z$d
Z%ddZ& G d d      Z'y)a  Multicast DNS Service Discovery for Python, v0.14-wmcbrine
Copyright 2003 Paul Scott-Murphy, 2014 William McBrine

This module provides a framework for the use of DNS Service Discovery
using IP multicast.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
    )annotations)Iterable)heapifyheappopheappush)Unioncast   )
DNSAddressDNSEntryDNSHinfoDNSNsec
DNSPointer	DNSRecord
DNSServiceDNSText)current_time_millis)_ONE_SECOND	_TYPE_PTRd   c                     | |   }||= |s| |= yy)z[Remove a key from a DNSRecord cache

    This function must be run in from event loop.
    N )cachekeyrecordrecord_caches       B/home/ubuntu/myenv/lib/python3.12/site-packages/zeroconf/_cache.py_remove_keyr   8   s$    
 :LV#J     c                      e Zd ZdZddZddZddZddZddZddZ	ddZ
dd	Zdd
ZddZddZd dZd!dZd"dZddZd#dZd$dZ	 	 	 	 	 	 	 	 d%dZd&dZy)'DNSCachezA cache of DNS entries.c                <    i | _         g | _        i | _        i | _        y N)r   _expire_heap_expirationsservice_cacheselfs    r   __init__zDNSCache.__init__F   s!    *,
;=4624r   c                6   | j                   j                  |j                        x}i x}| j                   |j                  <   ||vxr t        |t               }|||<   |j
                  |j                  dz  z   }| j                  j                  |      |k7  r't        | j                  ||f       || j                  |<   t        |t              rI|}| j                  j                  |j                        x}i x}| j                  |j                  <   |||<   |S )zAdds an entry.

        Returns true if the entry was not already in the cache.

        This function must be run in from event loop.
        i  )r   getr   
isinstancer   createdttlr%   r   r$   r   r&   
server_key)r(   r   storenewwhenservice_recordservice_stores          r   
_async_addzDNSCache._async_addO   s    ZZ^^FJJ//E8-//EDJJvzz*E!E*VW*E&Ef~~d!23  (D0T&&v7(,Df%fj)#N!%!3!3!7!78Q8Q!RR[PRR 2 2>3L3L M,:M.)
r   c                @    d}|D ]  }| j                  |      sd} |S )zAdd multiple records.

        Returns true if any of the records were not in the cache.

        This function must be run in from event loop.
        FT)r5   )r(   entriesr1   entrys       r   async_add_recordszDNSCache.async_add_recordsm   s0      	Eu%	 
r   c                    t        |t              r#|}t        | j                  |j                  |       t        | j
                  |j                  |       | j                  j                  |d       y)zQRemoves an entry.

        This function must be run in from event loop.
        N)	r,   r   r   r&   r/   r   r   r%   pop)r(   r   r3   s      r   _async_removezDNSCache._async_removez   sU    
 fj)#N**N,E,E~VDJJ

F3fd+r   c                4    |D ]  }| j                  |        y)zXRemove multiple records.

        This function must be run in from event loop.
        N)r<   )r(   r7   r8   s      r   async_remove_recordszDNSCache.async_remove_records   s!    
  	&Eu%	&r   c                Z   t        | j                        x}sg S g }| j                  rp| j                  d   }|d   }||kD  rnVt        | j                         |d   }| j                  j	                  |      |k(  r|j                  |       | j                  rp|t        kD  rt|t        | j                        dz  kD  rY| j                  D cg c])  }| j                  j	                  |d         |d   k(  s(|+ c}| _        t        | j                         | j                  |       |S c c}w )zPurge expired entries from the cache.

        This function must be run in from event loop.

        :param now: The current time in milliseconds.
        r   r
      )	lenr$   r   r%   r+   append _MIN_SCHEDULED_RECORD_EXPIRATIONr   r>   )r(   nowexpire_heap_lenexpiredwhen_recordr2   r   r8   s           r   async_expirezDNSCache.async_expire   s(    $'t'8'8#999I#%++A.Kq>DczD%%&
 !^F  $$V,4v& ( >>#d&7&7"81"<< $(#4#4!8I8I8M8MeTUh8W[`ab[c8c!D D%%&!!'*!s   
)D(4D(c                t    | j                   j                  |j                        }|y|j                  |      S )zGets a unique entry by key.  Will return None if there is no
        matching entry.

        This function is not threadsafe and must be called from
        the event loop.
        N)r   r+   r   )r(   r8   r0   s      r   async_get_uniquezDNSCache.async_get_unique   s1     

uyy)=yyr   c                    |j                         }| j                  j                  |      }g }||S |j                         D ]3  }||j                  k(  s||j
                  k(  s#|j                  |       5 |S )zGets all matching entries by details.

        This function is not thread-safe and must be called from
        the event loop.
        )lowerr   r+   valuestypeclass_rB   )r(   nametype_rO   r   recordsmatchesr   s           r   async_all_by_detailszDNSCache.async_all_by_details   sp     jjl**..%#%?Nnn& 	'F#&--(?v&	' r   c                $    | j                  |      S )zReturns a dict of entries whose key matches the name.

        This function is not threadsafe and must be called from
        the event loop.
        )entries_with_namer(   rP   s     r   async_entries_with_namez DNSCache.async_entries_with_name   s     %%d++r   c                $    | j                  |      S )zReturns a dict of entries whose key matches the server.

        This function is not threadsafe and must be called from
        the event loop.
        )entries_with_serverrW   s     r   async_entries_with_serverz"DNSCache.async_entries_with_server   s     ''--r   c                N   t        |t              r5| j                  j                  |j                  i       j                  |      S t        t        | j                  j                  |j                  i       j                                     D ]  }|j                  |      s|c S  y)zNGets an entry by key.  Will return None if there is no
        matching entry.N)	r,   _UNIQUE_RECORD_TYPESr   r+   r   reversedlistrM   __eq__)r(   r8   cached_entrys      r   r+   zDNSCache.get   s     e12::>>%))R044U;;$T$**..B*G*N*N*P%QR 	$L||L)##	$ r   c                    |j                         }| j                  j                  |      }|yt        t	        |j                                     D ]%  }||j                  k(  s||j                  k(  s#|c S  y)a  Gets the first matching entry by details. Returns None if no entries match.

        Calling this function is not recommended as it will only
        return one record even if there are multiple entries.

        For example if there are multiple A or AAAA addresses this
        function will return the last one that was added to the cache
        which may not be the one you expect.

        Use get_all_by_details instead.
        N)rL   r   r+   r^   r_   rM   rN   rO   )r(   rP   rQ   rO   r   rR   ra   s          r   get_by_detailszDNSCache.get_by_details   so     jjl**..%?$T'..*:%;< 	$L)))f8K8K.K##	$ r   c                    |j                         }| j                  j                  |      }|g S t        |j	                               D cg c]$  }||j
                  k(  s||j                  k(  s#|& c}S c c}w )z%Gets all matching entries by details.)rL   r   r+   r_   rM   rN   rO   )r(   rP   rQ   rO   r   rR   r8   s          r   get_all_by_detailszDNSCache.get_all_by_details  sc    jjl**..%?I#'(8#9l%Uejj=PU[_d_k_kUkllls   A7 A70A7c                    | j                   j                  |j                               x}rt        |j	                               S g S )z8Returns a list of entries whose server matches the name.)r&   r+   rL   r_   rM   )r(   serverr7   s      r   rZ   zDNSCache.entries_with_server  s;    ((,,V\\^<<7<())	r   c                    | j                   j                  |j                               x}rt        |j	                               S g S )z5Returns a list of entries whose key matches the name.)r   r+   rL   r_   rM   )r(   rP   r7   s      r   rV   zDNSCache.entries_with_name  s7    jjnnTZZ\2272())	r   c                    t               }t        | j                  |            D ]I  }|j                  t        k(  s|j                  |      r)t        t        |      j                  |k(  sG|c S  y r#   )	r   r^   rV   rN   r   
is_expiredr	   r   alias)r(   rP   rk   rD   r   s        r   !current_entry_with_name_and_aliasz*DNSCache.current_entry_with_name_and_alias  sb    !#t55d;< 	Fy())#.V,22e;	 r   c                ,    t        | j                        S )z1Return a copy of the list of current cache names.)r_   r   r'   s    r   nameszDNSCache.names*  s    DJJr   c                    t        |      }|D ]O  \  }}}| j                  |||      D ]3  }|j                  }	||	z
  t        kD  s||vs!| j	                  ||d       5 Q y )Nr
   )setrT   r-   r   _async_set_created_ttl)
r(   unique_typesanswersrD   answers_rrsetrP   rQ   rO   r   created_doubles
             r   1async_mark_unique_records_older_than_1s_to_expirez:DNSCache.async_mark_unique_records_older_than_1s_to_expire.  st     G#/ 	@D%33D%H @!'.(;6F-<W//Q?	@	@r   c                J    |j                  ||       | j                  |       y)z)Set the created time and ttl of a record.N)_set_created_ttlr5   )r(   r   rD   r.   s       r   rq   zDNSCache._async_set_created_ttl@  s      	S)r   N)returnNone)r   
_DNSRecordry   bool)r7   Iterable[DNSRecord]ry   r|   )r   r{   ry   rz   )r7   r}   ry   rz   )rD   _floatry   list[DNSRecord])r8   _UniqueRecordsTypery   DNSRecord | None)rP   _strrQ   _intrO   r   ry   r   )rP   strry   r   )r8   r   ry   r   )rP   r   rQ   r   rO   r   ry   r   )rP   r   rQ   r   rO   r   ry   r   )rg   r   ry   r   )rP   r   rk   r   ry   r   )ry   z	list[str])rr   zset[tuple[_str, _int, _int]]rs   r}   rD   r~   ry   rz   )r   r   rD   r~   r.   r   ry   rz   )__name__
__module____qualname____doc__r)   r5   r9   r<   r>   rH   rJ   rT   rX   r[   r+   rc   re   rZ   rV   rl   rn   rv   rq   r   r   r   r!   r!   C   s    !5<	,&-^
  ,.*m	 @2@ %@ 	@
 
@$ r   r!   N)r   _DNSRecordCacheTyper   r   r   r{   ry   rz   )(r   
__future__r   collections.abcr   heapqr   r   r   typingr   r	   _dnsr   r   r   r   r   r   r   r   _utils.timer   constr   r   r]   r   dictr   r   r{   r   floatr~   intr   rC   r   r!   r   r   r   <module>r      s   , # $ , , 	 	 	 - )"Hj':N :xWjPQ 3Y	%9 ::; 

	

 $'  B  B r   