o
    ¯bä  ã                   @   sÄ   d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	 ddl
mZ G dd„ dƒZG d	d
„ d
ƒZG dd„ dƒZG dd„ dƒZG dd„ deƒZeejƒG dd„ deƒƒZG dd„ dejƒZdd„ ZdS )z
Utility classes for spread.
é    )Úimplementer)ÚdeferÚ
interfaces)Úbasic)ÚFailure)Úpbc                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚLocalMethodc                 C   s   || _ || _d S ©N)ÚlocalÚname)Úselfr
   r   © r   ú5/usr/lib/python3/dist-packages/twisted/spread/util.pyÚ__init__   ó   
zLocalMethod.__init__c                 O   s   | j j| jg|¢R i |¤ŽS r	   )r
   Ú
callRemoter   )r   ÚargsÚkwr   r   r   Ú__call__   s   zLocalMethod.__call__N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r      s    r   c                   @   s$   e Zd ZdZdZdd„ Zdd„ ZdS )ÚLocalAsRemotezN
    A class useful for emulating the effects of remote behavior locally.
    é   c                 O   s|   t | d| ƒrt| d| ƒ|i |¤ŽS zt| d| ƒ}t ||i |¤Ž¡W S  ty=   tƒ }| jr6| ¡  t |¡ Y S w )ax  
        Call a specially-designated local method.

        self.callRemote('x') will first try to invoke a method named
        sync_x and return its result (which should probably be a
        Deferred).  Second, it will look for a method called async_x,
        which will be called and then have its result (or Failure)
        automatically wrapped in a Deferred.
        Úsync_Úasync_)	ÚhasattrÚgetattrr   ÚsucceedÚBaseExceptionr   ÚreportAllTracebacksÚprintTracebackÚfail)r   r   r   r   ÚmethodÚfr   r   r   r   #   s   
üzLocalAsRemote.callRemotec                 C   s
   t | |ƒS r	   )r   )r   r   r   r   r   ÚremoteMethod8   ó   
zLocalAsRemote.remoteMethodN)r   r   r   Ú__doc__r    r   r%   r   r   r   r   r      s
    r   c                   @   s*   e Zd ZdZd
dd„Zdd„ Zdd„ Zd	S )ÚLocalAsyncForwarderzD
    A class useful for forwarding a locally-defined interface.
    r   c                 C   s$   |  |¡sJ ‚|| _|| _|| _d S r	   )Ú
providedByÚ	forwardedÚinterfaceClassÚfailWhenNotImplemented)r   r*   r+   r,   r   r   r   r   A   s   
zLocalAsyncForwarder.__init__c                 O   s   t | j|ƒ|i |¤ŽS r	   )r   r*   )r   r#   r   r   r   r   r   Ú_callMethodG   s   zLocalAsyncForwarder._callMethodc                 O   sP   | j  |¡rtj| j|g|¢R i |¤Ž}|S | jr#t ttd| ƒ¡S t 	d ¡S )NzNo Such Method in Interface: %s)
r+   ÚqueryDescriptionForr   ÚmaybeDeferredr-   r,   r"   r   ÚNotImplementedErrorr   )r   r#   r   r   Úresultr   r   r   r   J   s   ÿ
zLocalAsyncForwarder.callRemoteN)r   )r   r   r   r'   r   r-   r   r   r   r   r   r(   <   s
    
r(   c                   @   s:   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )ÚPagerz5
    I am an object which pages out information.
    Nc                 O   s>   t |ƒr|| _|| _|| _nd| _d| _|| _|j | ¡ dS )zƒ
        Create a pager with a Reference to a remote collector and
        an optional callable to invoke upon completion.
        Nr   )ÚcallableÚcallbackÚcallbackArgsÚcallbackKeywordÚ_stillPagingÚ	collectorÚbrokerÚregisterPageProducer)r   r8   r4   r   r   r   r   r   r   [   s   zPager.__init__c                 C   s:   | j s| jjddd� | jdur| j| ji | j¤Ž | j S )ú5
        (internal) Method called by Broker.
        ÚendedPagingF©ÚpbanswerN)r7   r8   r   r4   r5   r6   ©r   r   r   r   ÚstillPagingj   s
   
zPager.stillPagingc                 C   s   | j jd|  ¡ dd� dS )r;   ÚgotPageFr=   N)r8   r   ÚnextPager?   r   r   r   ÚsendNextPaget   s   zPager.sendNextPagec                 C   s   t ƒ ‚)zO
        Override this to return an object to be sent to my collector.
        )r0   r?   r   r   r   rB   z   s   zPager.nextPagec                 C   s
   d| _ dS )z4
        Call this when you're done paging.
        r   N)r7   r?   r   r   r   Ú
stopPaging€   s   
zPager.stopPagingr	   )	r   r   r   r'   r   r@   rC   rB   rD   r   r   r   r   r2   V   s    

r2   c                   @   s"   e Zd ZdZddd„Zdd„ ZdS )	ÚStringPagerz:
    A simple pager that splits a string into chunks.
    é    Nc                 O   s2   || _ d| _|| _tj| ||g|¢R i |¤Ž d S )Nr   )ÚstringÚpointerÚ	chunkSizer2   r   )r   r8   ÚstrI   r4   r   r   r   r   r   r   Œ   s    zStringPager.__init__c                 C   sD   | j | j| j| j … }|  j| j7  _| jt| j ƒkr |  ¡  |S r	   )rG   rH   rI   ÚlenrD   ©r   Úvalr   r   r   rB   ’   s
   zStringPager.nextPage)rF   N)r   r   r   r'   r   rB   r   r   r   r   rE   ‡   s    
rE   c                   @   sB   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dS )Ú	FilePagerzC
    Reads a file in chunks and sends the chunks as they come.
    Nc                 O   s0   g | _ tj| ||g|¢R i |¤Ž |  |¡ d S r	   )Úchunksr2   r   ÚstartProducing)r   r8   Úfdr4   r   r   r   r   r   r       s   zFilePager.__init__c                    s*   t  ¡  |ˆ ¡ˆ _ˆ j ‡ fdd„¡ d S )Nc                    s   ˆ   ¡ S r	   )rD   )Úxr?   r   r   Ú<lambda>§   s    z*FilePager.startProducing.<locals>.<lambda>)r   Ú
FileSenderÚbeginFileTransferÚdeferredÚaddBoth)r   rQ   r   r?   r   rP   ¥   s   zFilePager.startProducingc                 C   s   || _ |s| j  ¡  d S d S r	   )ÚproducerÚresumeProducing)r   rX   Ú	streamingr   r   r   ÚregisterProducer©   s   ÿzFilePager.registerProducerc                 C   s
   d | _ d S r	   )rX   r?   r   r   r   ÚunregisterProducer®   r&   zFilePager.unregisterProducerc                 C   ó   | j  |¡ d S r	   )rO   Úappend)r   Úchunkr   r   r   Úwrite±   ó   zFilePager.writec                 C   s6   | j sdS | j  d¡}| j ¡  | jjd|dd� dS )zD
        Get the first chunk read and send it to collector.
        Nr   rA   Fr=   )rO   ÚpoprX   rY   r8   r   rL   r   r   r   rC   ´   s
   
zFilePager.sendNextPager	   )
r   r   r   r'   r   rP   r[   r\   r`   rC   r   r   r   r   rN   š   s    
rN   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚCallbackPageCollectorzµ
    I receive pages from the peer. You may instantiate a Pager with a
    remote reference to me. I will call the callback with a list of pages
    once they are all received.
    c                 C   s   g | _ || _d S r	   )Úpagesr4   )r   r4   r   r   r   r   Ç   r   zCallbackPageCollector.__init__c                 C   r]   r	   )rd   r^   )r   Úpager   r   r   Úremote_gotPageË   ra   z$CallbackPageCollector.remote_gotPagec                 C   s   |   | j¡ d S r	   )r4   rd   r?   r   r   r   Úremote_endedPagingÎ   ra   z(CallbackPageCollector.remote_endedPagingN)r   r   r   r'   r   rf   rg   r   r   r   r   rc   À   s
    rc   c                 O   s,   t  ¡ }| j|t|jƒg|¢R i |¤Ž |S )zr
    A utility method that will call a remote method which expects a
    PageCollector as the first argument.
    )r   ÚDeferredr   rc   r4   )ÚreferenceableÚ
methodNamer   r   Údr   r   r   ÚgetAllPagesÒ   s    rl   N)r'   Úzope.interfacer   Útwisted.internetr   r   Útwisted.protocolsr   Útwisted.python.failurer   Útwisted.spreadr   r   r   r(   r2   rE   Ú	IConsumerrN   ÚReferenceablerc   rl   r   r   r   r   Ú<module>   s   	 1%