o
    Uh                     @   s   d dl Z d dlZd dlmZ d dlmZ d dlmZ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 d	d
lmZmZmZmZmZ G dd dZdddZG dd dZG dd dZG dd deZdS )    N)count)Optional)AuthenticatorBEGIN)get_bus)MessageMessageTypeParser)	ProxyBase
unwrap_msg)message_bus   )MessageFiltersFilterHandleReplyMatcherRouterClosedcheck_replyablec                   @   s`   e Zd ZdZdejdejfddZdddefd	d
Z	defddZ
dd Zdd Zdd ZdS )DBusConnectionaP  A plain D-Bus connection with no matching of replies.

    This doesn't run any separate tasks: sending and receiving are done in
    the task that calls those methods. It's suitable for implementing servers:
    several worker tasks can receive requests and send replies.
    For a typical client pattern, see :class:`DBusRouter`.
    readerwriterc                 C   s4   || _ || _t | _tdd| _d | _t | _	d S )Nr   )start)
r   r   r	   parserr   outgoing_serialunique_nameasyncioLock	send_lock)selfr   r    r   f/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/jeepney/io/asyncio.py__init__   s   zDBusConnection.__init__Nserialmessagec             	      sv   | j 4 I dH & |du rt| j}| j|| | j I dH  W d  I dH  dS 1 I dH s4w   Y  dS )z.Serialise and send a :class:`~.Message` objectN)r   nextr   r   write	serialisedrainr   r#   r"   r   r   r   send    s   
.zDBusConnection.sendreturnc                    sB   	 | j  }|dur|S | jdI dH }|st| j | q)z5Return the next available message from the connectionTNi   )r   get_next_messager   readEOFErroradd_data)r   msgbr   r   r   receive(   s   
zDBusConnection.receivec                    s    | j   | j  I dH  dS )zClose the D-Bus connectionN)r   closewait_closedr   r   r   r   r2   4   s   
zDBusConnection.closec                       | S Nr   r4   r   r   r   
__aenter__9      zDBusConnection.__aenter__c                    s   |   I d H  d S r6   )r2   r   exc_typeexc_valexc_tbr   r   r   	__aexit__<   s   zDBusConnection.__aexit__)__name__
__module____qualname____doc__r   StreamReaderStreamWriterr    r   r)   r1   r2   r7   r=   r   r   r   r   r      s    r   SESSIONc           
   	      s   t | }t|I dH \}}t }|D ]!}|| | I dH  |dI dH }|s0td|| q|t	 | I dH  t
||}t|4 I dH }ttt| dI dH }	|	d |_W d  I dH  |S 1 I dH stw   Y  |S )zHOpen a plain D-Bus connection

    :return: :class:`DBusConnection`
    Ni   z#Socket closed before authentication
   r   )r   r   open_unix_connectionr   r%   r'   r,   r-   feedr   r   
DBusRouterwait_forProxyr   Hellor   )
busbus_addrr   r   authrreq_datar0   connrouter
reply_bodyr   r   r   open_dbus_connection@   s*   


rS   c                   @   s   e Zd ZdZdZdZdZdefddZe	dd Z
ddd	d
ZdefddZddddeej fddZdd Zdd ZdefddZdd ZdS )rH   zA 'client' D-Bus connection which can wait for a specific reply.

    This runs a background receiver task, and makes it possible to send a
    request and wait for the relevant reply.
    NrP   c                 C   s*   || _ t | _t | _t|  | _d S r6   )	_connr   _repliesr   _filtersr   create_task	_receiver	_rcv_task)r   rP   r   r   r   r    j   s   zDBusRouter.__init__c                 C   s   | j jS r6   )rT   r   r4   r   r   r   r   p   s   zDBusRouter.unique_namer!   c                   s   | j j||dI dH  dS )z&Send a message, don't wait for a replyr!   N)rT   r)   r(   r   r   r   r)   t   s   zDBusRouter.sendr*   c                    s|   t | | j rtdt| jj}| j|t	
 }| j||dI dH  |I dH W  d   S 1 s7w   Y  dS )zSend a method call message and wait for the reply

        Returns the reply message (method return or error message type).
        zThis DBusRouter has stoppedr!   N)r   rY   doner   r$   rT   r   rU   catchr   Futurer)   )r   r#   r"   	reply_futr   r   r   send_and_get_replyx   s   
$zDBusRouter.send_and_get_replyr   )queuebufsizer_   c                C   s   t | j||p
t|S )ar  Create a filter for incoming messages

        Usage::

            with router.filter(rule) as queue:
                matching_msg = await queue.get()

        :param MatchRule rule: Catch messages matching this rule
        :param asyncio.Queue queue: Send matching messages here
        :param int bufsize: If no queue is passed in, create one with this size
        )r   rV   r   Queue)r   ruler_   r`   r   r   r   filter   s   zDBusRouter.filterc                    r5   r6   r   r4   r   r   r   r7      r8   zDBusRouter.__aenter__c                    sb   | j  r| j   dS | j   ttj | j I d H  W d    dS 1 s*w   Y  dS )NF)rY   rZ   resultcancel
contextlibsuppressr   CancelledErrorr9   r   r   r   r=      s   



zDBusRouter.__aexit__r/   c              	   C   sN   | j |rdS t| j|D ]}z|j| W q tjy$   Y qw dS )zHandle one received messageN)	rU   dispatchlistrV   matchesr_   
put_nowaitr   	QueueFull)r   r/   rc   r   r   r   	_dispatch   s   zDBusRouter._dispatchc                    s.   z	 | j  I dH }| | q| j  w )z'Receiver loop - runs in a separate taskTN)rT   r1   rn   rU   drop_all)r   r/   r   r   r   rX      s   
zDBusRouter._receiver)r>   r?   r@   rA   _nursery_mgr_send_cancel_scope_rcv_cancel_scoper   r    propertyr   r)   r   r^   r   r   ra   rc   r7   r=   rn   rX   r   r   r   r   rH   `   s    
rH   c                   @   s2   e Zd ZdZdZdZd
ddZdd Zdd	 ZdS )open_dbus_routerzOpen a D-Bus 'router' to send and receive messages

    Use as an async context manager::

        async with open_dbus_router() as router:
            ...
    NrD   c                 C   s
   || _ d S r6   )rL   )r   rL   r   r   r   r       s   
zopen_dbus_router.__init__c                    s0   t | jI d H | _t| j| _| j I d H S r6   )rS   rL   rP   rH   req_ctxr7   r4   r   r   r   r7      s   zopen_dbus_router.__aenter__c                    s,   | j |||I d H  | j I d H  d S r6   )ru   r=   rP   r2   r9   r   r   r   r=      s   zopen_dbus_router.__aexit__rD   )	r>   r?   r@   rA   rP   ru   r    r7   r=   r   r   r   r   rt      s    
rt   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )rJ   a  An asyncio proxy for calling D-Bus methods

    You can call methods on the proxy object, such as ``await bus_proxy.Hello()``
    to make a method call over D-Bus and wait for a reply. It will either
    return a tuple of returned data, or raise :exc:`.DBusErrorResponse`.
    The methods available are defined by the message generator you wrap.

    :param msggen: A message generator object.
    :param ~asyncio.DBusRouter router: Router to send and receive messages.
    c                    s   t  | || _d S r6   )superr    _router)r   msggenrQ   	__class__r   r   r       s   
zProxy.__init__c                 C   s   d | j| jS )NzProxy({}, {}))format_msggenrx   r4   r   r   r   __repr__   s   zProxy.__repr__c                    s    fdd}|S )Nc                     s<    | i |}|j jtju sJ j|I d H }t|S r6   )headermessage_typer   method_callrx   r^   r   )argskwargsr/   replymake_msgr   r   r   inner   s
   z!Proxy._method_call.<locals>.innerr   )r   r   r   r   r   r   _method_call   s   zProxy._method_call)r>   r?   r@   rA   r    r~   r   __classcell__r   r   rz   r   rJ      s
    
rJ   rv   )r   rf   	itertoolsr   typingr   jeepney.authr   r   jeepney.busr   jeepneyr   r   r	   jeepney.wrappersr
   r   jeepney.bus_messagesr   commonr   r   r   r   r   r   rS   rH   rt   rJ   r   r   r   r   <module>   s    
0 X