
    +c0                        d Z ddlZddlmZ ddlmZ ddlZddlmZ ddl	Z	ddl
mZmZ 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mZmZ dd
lmZmZ ddlmZ ddlmZmZ ddl m!Z!m"Z" ddl#m$Z$ ddl%m&Z& ddl'm(Z(m)Z)m*Z* g dZ+ G d d      Z,d Z-d Z. G d d      Z/ G d de/      Z0 G d de!      Z1d Z2d#dej                  fdZ3	 d$de0fd Z4e5d!k(  r e4       Z6 e7d"e6jp                         yy)%z'Synchronous IO wrappers around jeepney
    N)deque)
ECONNRESET)count)DefaultSelector
EVENT_READ)Optional)warn)ParserMessageMessageTypeHeaderFields)AuthenticatorBEGIN)get_bus)FileDescriptorfds_buf_size)	ProxyBase
unwrap_msg)Router)message_bus   )MessageFiltersFilterHandlecheck_replyable)open_dbus_connectionDBusConnectionProxyc                   *    e Zd Zd Zd Zd Zd Zd Zy)_Futurec                     d | _         y N_resultselfs    5/usr/lib/python3/dist-packages/jeepney/io/blocking.py__init__z_Future.__init__    s	        c                 ,    t        | j                        S r!   )boolr#   r$   s    r&   donez_Future.done#   s    DLL!!r(   c                     d|f| _         y NFr"   )r%   	exceptions     r&   set_exceptionz_Future.set_exception&   s    y)r(   c                     d|f| _         y )NTr"   )r%   results     r&   
set_resultz_Future.set_result)   s    f~r(   c                 ,    | j                   \  }}|r|S |r!   r"   )r%   successvalues      r&   r1   z_Future.result,   s    Lr(   N)__name__
__module____qualname__r'   r+   r/   r2   r1    r(   r&   r   r      s    "*&r(   r   c                 6    | t        j                         | z   S y r!   )time	monotonictimeouts    r&   timeout_to_deadliner?   3   s    ~~'))r(   c                 J    | !t        | t        j                         z
  d      S y )Ng        )maxr;   r<   )deadlines    r&   deadline_to_timeoutrC   8   s$    8dnn..33r(   c                       e Zd ZdZddej                  fdZd Zd Zdede	e
ej                     ffdZd	 Zd
 ZddZd Zd Zy)DBusConnectionBasez8Connection machinery shared by this module and threadingsockc                     || _         || _        t               | _        t	        d      | _        t               | _        | j                  j                  |t              | _
        d | _        y )Nr   )start)rF   
enable_fdsr
   parserr   outgoing_serialr   selectorregisterr   
select_keyunique_name)r%   rF   rI   s      r&   r'   zDBusConnectionBase.__init__@   sO    	$h$1~')--00zBr(   c                     | S r!   r9   r$   s    r&   	__enter__zDBusConnectionBase.__enter__I   s    r(   c                 $    | j                          yr-   )close)r%   exc_typeexc_valexc_tbs       r&   __exit__zDBusConnectionBase.__exit__L   s    

r(   messagereturnc                     |t        | j                        }| j                  rt        j                  d      nd }|j	                  ||      }||fS )Ni)serialfds)nextrK   rI   array	serialise)r%   rX   r\   r]   datas        r&   
_serialisezDBusConnectionBase._serialiseP   sL    >$../F"&//ekk#t  C 8Syr(   c                     | j                   j                  |gt        j                  t        j                  |fg      }|t        |      k  r| j                   j                  ||d         y y r!   )rF   sendmsgsocket
SOL_SOCKET
SCM_RIGHTSlensendall)r%   ra   r]   
bytes_sents       r&   _send_with_fdsz!DBusConnectionBase._send_with_fdsW   s_    YY&&Ff''):):C@A


 D	!IId:;/0 "r(   c                     	 | j                   j                         }||S | j                  t        |            \  }}| j                   j	                  ||       Z)Nr=   )r]   )rJ   get_next_message_read_some_datarC   add_data)r%   rB   msgbr]   s        r&   _receivezDBusConnectionBase._receive`   sZ    ++..0C
))2Eh2O)PFAsKK   , r(   Nc                     | j                   j                  |      D ]Z  \  }}|| j                  k(  s| j                  r| j	                         c S t        | j                  j                  d            g fc S  t        )Ni   )	rL   selectrN   rI   _read_with_fdsunwrap_readrF   recvTimeoutError)r%   r>   keyevs       r&   rn   z"DBusConnectionBase._read_some_datai   sm    }}++G4 	AGCdoo%??..00&tyy~~d';<b@@	A r(   c                 &   | j                   j                         }| j                  j                  |t	                     \  }}}}|t        t        dd      z  r| j                          t        d      t        |      t        j                  |      fS )N
MSG_CTRUNCr   z&Unable to receive all file descriptors)rJ   bytes_desiredrF   recvmsgr   getattrre   rS   RuntimeErrorrv   r   from_ancdata)r%   nbytesra   ancdataflags_s         r&   ru   z!DBusConnectionBase._read_with_fdss   sv    **,"&))"3"3FLN"Kgua76<33JJLGHH4 ."="=g"FFFr(   c                 l    | j                   j                          | j                  j                          y)zClose the connectionN)rL   rS   rF   r$   s    r&   rS   zDBusConnectionBase.close{   s     		r(   Fr!   )r6   r7   r8   __doc__re   r'   rQ   rW   r   bytesr   r_   rb   rk   rr   rn   ru   rS   r9   r(   r&   rE   rE   >   sZ    B V]]  ' uhu{{>S6T 1-Gr(   rE   c                        e Zd Zddej                  f fdZed        ZddefdZeZ	dddefd	Z
ddd
ZddddZddddee   fdZdddefdZ xZS )r   rF   c                     t         |   ||       t        t              | _        t               | _        t        t        |       | _	        | j                  j                         }|d   | _        y )Nr   )superr'   r   r   _routerr   _filtersr   r   	bus_proxyHellorO   )r%   rF   rI   hello_reply	__class__s       r&   r'   zDBusConnection.__init__   sW    z* g&( {D1nn**,&q>r(   c                 4    t        dd       | j                  S )Nz@conn.router is deprecated, see the docs for APIs to use instead.   
stacklevel)r	   r   r$   s    r&   routerzDBusConnection.router   s    O	||r(   NrX   c                     | j                  ||      \  }}|r| j                  ||       y| j                  j                  |       y)z.Serialise and send a :class:`~.Message` objectN)rb   rk   rF   ri   )r%   rX   r\   ra   r]   s        r&   sendzDBusConnection.send   s;    OOGV4	cc*IId#r(   r=   rY   c                6    | j                  t        |            S )a+  Return the next available message from the connection

        If the data is ready, this will return immediately, even if timeout<=0.
        Otherwise, it will wait for up to timeout seconds, or indefinitely if
        timeout is None. If no message comes in time, it raises TimeoutError.
        )rr   r?   )r%   r>   s     r&   receivezDBusConnection.receive   s     }}09::r(   c                    | j                  |      }| j                  j                  |       | j                  j	                  |      D ]  }|j
                  j                  |        y)z\Receive one message and apply filters

        See :meth:`filter`. Returns nothing.
        r=   N)r   r   incomingr   matchesqueueappend)r%   r>   rp   filters       r&   recv_messageszDBusConnection.recv_messages   sV    
 ll7l+c"mm++C0 	%FLL$	%r(   )r>   unwrapc                   t        |       t        |      }|d}nt        dd       t        | j                        }| j                  ||       	 | j                  t        |            }|j                  j                  j                  t        j                  d      }||k(  r|rt        |      S |S | j                  j                  |       | j                   j#                  |      D ]  }|j$                  j'                  |        )zSend a message, wait for the reply and return it

        Filters are applied to other messages received before the reply -
        see :meth:`add_filter`.
        FzePassing unwrap= to .send_and_get_reply() is deprecated and will break in a future version of Jeepney.r   r   )r\   r=   )r   r?   r	   r^   rK   send_messager   rC   headerfieldsgetr   reply_serialr   r   r   r   r   r   r   )	r%   rX   r>   r   rB   r\   msg_inreply_tor   s	            r&   send_and_get_replyz!DBusConnection.send_and_get_reply   s     	 &w/>F >JKM d**+'&1\\*=h*G\HF}}++//0I0I2NH6!%f-- LL!!&)--//7 ,##F+, r(   r   )r   bufsizer   c                L    |t        |      }t        | j                  ||      S )a  Create a filter for incoming messages

        Usage::

            with conn.filter(rule) as matches:
                # matches is a deque containing matched messages
                matching_msg = conn.recv_until_filtered(matches)

        :param jeepney.MatchRule rule: Catch messages matching this rule
        :param collections.deque queue: Matched messages will be added to this
        :param int bufsize: If no deque is passed in, create one with this size
        )maxlen)r   r   r   )r%   ruler   r   s       r&   r   zDBusConnection.filter   s&     =)EDMM477r(   c                    t        |      }t        |      dk(  r*| j                  t        |             t        |      dk(  r*|j	                         S )aZ  Process incoming messages until one is filtered into queue

        Pops the message from queue and returns it, or raises TimeoutError if
        the optional timeout expires. Without a timeout, this is equivalent to::

            while len(queue) == 0:
                conn.recv_messages()
            return queue.popleft()

        In the other I/O modules, there is no need for this, because messages
        are placed in queues by a separate task.

        :param collections.deque queue: A deque connected by :meth:`filter`
        :param float timeout: Maximum time to wait in seconds
        r   r=   )r?   rh   r   rC   popleft)r%   r   r>   rB   s       r&   recv_until_filteredz"DBusConnection.recv_until_filtered   sI      'w/%jAo':8'DE %jAo}}r(   r   r!   )r6   r7   r8   re   r'   propertyr   r   r   r   r   r   r   r   r   r   r   __classcell__r   s   @r&   r   r      s    
*V]] 
*  
$G $ L!% ;' ; (, % 6:$ ,< 7;A 8Xe_ 8" 59 W r(   r   c                   4     e Zd ZdZdd fd
Zd Zd Z xZS )r   aj  A blocking proxy for calling D-Bus methods

    You can call methods on the proxy object, such as ``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.

    You can set a time limit on a call by passing ``_timeout=`` in the method
    call, or set a default when creating the proxy. The ``_timeout`` argument
    is not passed to the message generator.
    All timeouts are in seconds, and :exc:`TimeoutErrror` is raised if it
    expires before a reply arrives.

    :param msggen: A message generator object
    :param ~blocking.DBusConnection connection: Connection to send and receive messages
    :param float timeout: Default seconds to wait for a reply, or None for no limit
    Nr=   c                @    t         |   |       || _        || _        y r!   )r   r'   _connection_timeout)r%   msggen
connectionr>   r   s       r&   r'   zProxy.__init__  s     %r(   c                 z    | j                   dnd| j                    }d| j                   d| j                   | dS )N z
, timeout=zProxy(z, ))r   _msggenr   )r%   extras     r&   __repr__zProxy.__repr__  sA    }},Z3O~R(8(8'9%BBr(   c                 F     t        j                         fd       }|S )Nc                      |j                  dj                        } | i |}|j                  j                  t        j
                  u sJ t        j                  j                  ||            S )Nr   r=   )	popr   r   message_typer   method_callr   r   r   )argskwargsr>   rp   make_msgr%   s       r&   innerz!Proxy._method_call.<locals>.inner  so    jjT]];GD+F+C::**k.E.EEEEd..AAW B   r(   )	functoolswraps)r%   r   r   s   `` r&   _method_callzProxy._method_call  s%    		"	 
#	 r(   )r6   r7   r8   r   r'   r   r   r   r   s   @r&   r   r      s    " 7;  
C
r(   r   c                 X    | s't        t        t        j                  t                    | S )zRaise ConnectionResetError from an empty read.

    Sometimes the socket raises an error itself, sometimes it gives no data.
    I haven't worked out when it behaves each way.
    )ConnectionResetErrorr   osstrerror)rq   s    r&   rv   rv     s"     ":r{{:/FGGHr(   rY   c           	      &   t        j                   t         j                        t        |      fd}	  |j                  |        t	        |      }|D ]@  } |j
                  |       |j                  t         |j                  d                   B  |j
                  t               j                  d       S # t         j                  $ r%}j                          t        d| d      |d}~w j                           xY w)z=Create a socket and authenticate ready to send D-Bus messages)familyc                 B    j                  t                      | | S r!   )
settimeoutrC   )methr   rB   rF   s     r&   with_sock_deadlinez'prep_socket.<locals>.with_sock_deadline1  s    +H56T{r(   )rI   i   zDid not authenticate in z secondsN)re   AF_UNIXr?   connectr   ri   feedrv   rw   r   r>   rS   rx   r   )	addrrI   r>   r   authrreq_dataerB   rF   s	          @@r&   prep_socketr   )  s    ==/D
 #7+H4<<.4 	IHt||X6JJ{#5dii#FGH	I 	4<</ 	OODK >> P

5gYhGHaO

s   A;C D C::Dc                 P    t        |       }t        |||      }t        ||      }|S )a  Connect to a D-Bus message bus

    Pass ``enable_fds=True`` to allow sending & receiving file descriptors.
    An error will be raised if the bus does not allow this. For simplicity,
    it's advisable to leave this disabled unless you need it.

    D-Bus has an authentication step before sending or receiving messages.
    This takes < 1 ms in normal operation, but there is a timeout so that client
    code won't get stuck if the server doesn't reply. *auth_timeout* configures
    this timeout in seconds.
    r=   )r   r   r   )busrI   auth_timeoutbus_addrrF   conns         r&   r   r   G  s,     s|Hx\BD$
+DKr(   __main__zUnique name:)Fg       @)SESSIONFg      ?)9r   r_   collectionsr   errnor   r   	itertoolsr   r   	selectorsr   r   re   r;   typingr   warningsr	   jeepneyr
   r   r   r   jeepney.authr   r   jeepney.busr   jeepney.fdsr   r   jeepney.wrappersr   r   jeepney.routingr   jeepney.bus_messagesr   commonr   r   r   __all__r   r?   rC   rE   r   r   rv   r   r   r6   r   printrO   r9   r(   r&   <module>r      s         	 1     > > -  4 2 " , A A (
@ @Fr' rj%I %P > 79* z!D	.$**+ r(   