o a@sddlZddlZddlmZddlmZddlmZmZddl m Z ddl m Z m Z mZddlmZmZddlmZd d lmZmZmZmZmZGd d d ZdddZGdddZGdddZGdddeZdS)N)count)Optional) AuthenticatorBEGIN)get_bus)Message MessageTypeParser) ProxyBase unwrap_msg) message_bus)MessageFilters FilterHandle ReplyMatcher RouterClosedcheck_replyablec@s`eZdZdZdejdejfddZdddefd d Z d efd d Z ddZ ddZ ddZ dS)DBusConnectionaPA 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`. readerwritercCs4||_||_t|_tdd|_d|_t|_ dS)Nr )start) rrr parserroutgoing_serial unique_nameasyncioLock send_lock)selfrrr4/usr/lib/python3/dist-packages/jeepney/io/asyncio.py__init__s  zDBusConnection.__init__Nserialmessagec sv|j4IdH&|durt|j}|j|||jIdHWdIdHdS1IdHs4wYdS)z.Serialise and send a :class:`~.Message` objectN)rnextrrwrite serialisedrainrr#r"rrrsend s .zDBusConnection.sendreturncsB |j}|dur |S|jdIdH}|st|j|q)z5Return the next available message from the connectionTNi)rget_next_messagerreadEOFErroradd_data)rmsgbrrrreceive(s  zDBusConnection.receivecs |j|jIdHdS)zClose the D-Bus connectionN)rclose wait_closedrrrrr24s zDBusConnection.closec|SNrr4rrr __aenter__9zDBusConnection.__aenter__cs|IdHdSr6)r2rexc_typeexc_valexc_tbrrr __aexit__<szDBusConnection.__aexit__)__name__ __module__ __qualname____doc__r StreamReader StreamWriterr rr)r1r2r7r=rrrrrs  rSESSIONc st|}t|IdH\}}t}|D]!}|||IdH|dIdH}|s0td||q|t |IdHt ||}t |4IdH}t t t|dIdH} | d|_WdIdH|S1IdHstwY|S)zHOpen a plain D-Bus connection :return: :class:`DBusConnection` Niz#Socket closed before authentication r)rropen_unix_connectionrr%r'r,r-feedrr DBusRouterwait_forProxyr Hellor) busbus_addrrrauthrreq_datar0connrouter reply_bodyrrropen_dbus_connection@s*     rSc@seZdZdZdZdZdZdefddZe ddZ ddd d Z d e fd d Z ddddeejfddZddZddZde fddZddZdS)rHzA '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. NrPcCs*||_t|_t|_t||_dSr6) _connr_repliesr_filtersr create_task _receiver _rcv_task)rrPrrrr jszDBusRouter.__init__cCs|jjSr6)rTrr4rrrrpszDBusRouter.unique_namer!cs|jj||dIdHdS)z&Send a message, don't wait for a replyr!N)rTr)r(rrrr)tszDBusRouter.sendr*cs|t||jrtdt|jj}|j|t }|j ||dIdH|IdHWdS1s7wYdS)zSend a method call message and wait for the reply Returns the reply message (method return or error message type). zThis DBusRouter has stoppedr!N) rrYdonerr$rTrrUcatchrFuturer))rr#r" reply_futrrrsend_and_get_replyxs  $zDBusRouter.send_and_get_replyr )queuebufsizer_cCst|j||p t|S)arCreate 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 )rrVrQueue)rruler_r`rrrfilters zDBusRouter.filtercr5r6rr4rrrr7r8zDBusRouter.__aenter__csb|jr |jdS|jttj|jIdHWddS1s*wYdS)NF)rYrZresultcancel contextlibsuppressrCancelledErrorr9rrrr=s    zDBusRouter.__aexit__r/c CsN|j|rdSt|j|D]}z|j|Wqtjy$YqwdS)zHandle one received messageN) rUdispatchlistrVmatchesr_ put_nowaitr QueueFull)rr/rcrrr _dispatchs zDBusRouter._dispatchcs.z |jIdH}||q|jw)z'Receiver loop - runs in a separate taskTN)rTr1rnrUdrop_all)rr/rrrrXs  zDBusRouter._receiver)r>r?r@rA _nursery_mgr_send_cancel_scope_rcv_cancel_scoperr propertyrr)rr^rrrarcr7r=rnrXrrrrrH`s  rHc@s2eZdZdZdZdZd ddZddZdd ZdS) 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: ... NrDcCs ||_dSr6)rL)rrLrrrr s zopen_dbus_router.__init__cs0t|jIdH|_t|j|_|jIdHSr6)rSrLrPrHreq_ctxr7r4rrrr7s zopen_dbus_router.__aenter__cs,|j|||IdH|jIdHdSr6)rur=rPr2r9rrrr=szopen_dbus_router.__aexit__rD) r>r?r@rArPrur r7r=rrrrrts  rtcs0eZdZdZfddZddZddZZS)rJaAn 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. cst|||_dSr6)superr _router)rmsggenrQ __class__rrr s  zProxy.__init__cCsd|j|jS)Nz Proxy({}, {}))format_msggenrxr4rrr__repr__szProxy.__repr__csfdd}|S)Ncs<|i|}|jjtjusJj|IdH}t|Sr6)header message_typer method_callrxr^r )argskwargsr/replymake_msgrrrinners z!Proxy._method_call..innerr)rrrrrr _method_callszProxy._method_call)r>r?r@rAr r~r __classcell__rrrzrrJs  rJrv)rrf itertoolsrtypingr jeepney.authrr jeepney.busrjeepneyrrr jeepney.wrappersr r jeepney.bus_messagesr commonrrrrrrrSrHrtrJrrrrs     0 X