U
    
W[*  ã                   @   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„ Z
dd	„ Zd
d„ Zdd„ ZG dd„ dƒZG dd„ dejƒZG dd„ deƒZG dd„ deƒZG dd„ dejƒZdd„ Zdd„ ZdS )zE
Dict client protocol implementation.

@author: Pavel Pergamenshchik
é    )Úbasic)ÚdeferÚprotocol)Úlog)ÚBytesIOc                 C   sê   | dkrdS | dd… dkr"d}nd}d}t | ƒ}|dkrD| d¡ | d¡}|dkrv|dkrÜ| d¡ || ¡ fS nf|dkrš| d¡}|dkrÜd| fS nB|dkrÀ|dkr¶|| ¡ fS d| fS n|d	krÜ|dkrÜ|| ¡ fS ||7 }qDdS )
zQChew one dqstring or atom from beginning of line and return (param, remaningline)ó    )Nr   r   é   ó   "é   ó   \Nó    )r   Úread)ÚlineÚmodeÚresÚioÚa© r   ú8/usr/lib/python3/dist-packages/twisted/protocols/dict.pyÚ
parseParam   s4    





r   c                 C   s   t dd„ | ƒS )zMunch a string into an 'atom'c                 S   s   | t ttdƒdddg ƒkS )Né!   é"   é'   é\   )ÚmapÚchrÚrange)Úxr   r   r   Ú<lambda>5   r   zmakeAtom.<locals>.<lambda>)Úfilter©r   r   r   r   ÚmakeAtom2   s    r!   c                 C   sN   t dƒdddg }g }| D ]$}t|ƒ|kr4| d¡ | |¡ qd |¡} | S )Nr   r   r   r   r   r   )r   ÚordÚappendÚjoin)ÚsZ	mustquoteÚresultÚcr   r   r   ÚmakeWord9   s    

r(   c                 C   sH   t | ƒdkr| dkrd S t | ƒdkr@| dd… dkr@| dd … } | S d S )Nr   ó   .r   r
   s   ..)Úlenr    r   r   r   Ú	parseTextE   s
    r+   c                   @   s   e Zd ZdZdd„ ZdS )Ú
DefinitionzA word definitionc                 C   s   || _ || _|| _|| _d S ©N)ÚnameÚdbÚdbdescÚtext)Úselfr.   r/   r0   r1   r   r   r   Ú__init__Q   s    zDefinition.__init__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r3   r   r   r   r   r,   O   s   r,   c                   @   s  e Zd ZdZdZdZdZd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d*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Z d2d3„ Z!d4d5„ Z"d6d7„ Z#d8d9„ Z$d:d;„ Z%d<d=„ Z&d>d?„ Z'dS )@Ú
DictClientzdict (RFC2229) clientNi   c                 C   s   d | _ d | _d S r-   )Údatar&   ©r2   r   r   r   r3   c   s    zDictClient.__init__c                 C   s   d| _ d| _d S )NZconnÚcommand)Ústater   r:   r   r   r   ÚconnectionMadeh   s    zDictClient.connectionMadec                 C   s,   t |ƒ| jd krtdƒ‚tj | |¡ dS )z3Throw up if the line is longer than 1022 charactersr
   z(DictClient tried to send a too long lineN)r*   Ú
MAX_LENGTHÚ
ValueErrorr   ÚLineReceiverÚsendLine©r2   r   r   r   r   rA   m   s    zDictClient.sendLinec                 C   s¨   z|  d¡}W n tk
r$   Y d S X | jdkr6d}nNt|ƒdk rht d| ¡ |  d¡ | j ¡  d S t	|d d… ƒ}|dd … }t
| d|| jf | jƒ}||ƒ d S )Nzutf-8r1   é   z-DictClient got invalid line from server -- %szInvalid line from serveré   zdictCode_%s_%s)ÚdecodeÚUnicodeErrorr   r*   r   ÚmsgÚprotocolErrorÚ	transportZLoseConnectionÚintÚgetattrr<   ÚdictCode_default)r2   r   ÚcodeÚmethodr   r   r   ÚlineReceivedt   s    


zDictClient.lineReceivedc                 C   s&   t  d| ¡ |  d¡ | j ¡  dS )zUnknown messagez3DictClient got unexpected message from server -- %szUnexpected server messageN)r   rG   rH   rI   ÚloseConnectionrB   r   r   r   rL   ‡   s    
zDictClient.dictCode_defaultc                 C   s   dS )z*We are about to get kicked off, do nothingNr   rB   r   r   r   ÚdictCode_221_readyŽ   s    zDictClient.dictCode_221_readyc                 C   s   d| _ |  ¡  dS )zGreeting messageÚreadyN)r<   ÚdictConnectedrB   r   r   r   ÚdictCode_220_conn“   s    zDictClient.dictCode_220_connc                 C   s   |   d¡ | j ¡  d S )NzAccess denied©rH   rI   rP   r:   r   r   r   ÚdictCode_530_conn™   s    
zDictClient.dictCode_530_connc                 C   s   |   d¡ | j ¡  d S )NzServer temporarily unavailablerU   r:   r   r   r   ÚdictCode_420_connž   s    
zDictClient.dictCode_420_connc                 C   s   |   d¡ | j ¡  d S )Nz(Server shutting down at operator requestrU   r:   r   r   r   ÚdictCode_421_conn£   s    
zDictClient.dictCode_421_connc                 C   sR   | j dkstdƒ‚d| _d| _d| _ dt| d¡ƒt| d¡ƒf }|  |¡ dS )zSend a dict DEFINE commandrR   z4DictClient.sendDefine called when not in ready stateNÚdefinezDEFINE %s %súUTF-8)r<   ÚAssertionErrorr&   r9   r!   Úencoder(   rA   )r2   ÚdatabaseÚwordr;   r   r   r   Ú
sendDefine¨   s     zDictClient.sendDefinec                 C   sR   | j dkstdƒ‚d| _d| _d| _ dt|ƒt|ƒt|ƒf }|  | d¡¡ dS )zSend a dict MATCH commandrR   z3DictClient.sendMatch called when not in ready stateNÚmatchzMATCH %s %s %srZ   )r<   r[   r&   r9   r!   rA   r\   )r2   r]   Ústrategyr^   r;   r   r   r   Ú	sendMatch²   s    zDictClient.sendMatchc                 C   s   d| _ |  d ¡ dS ©zInvalid databaserR   N©r   ÚdefineFailedrB   r   r   r   ÚdictCode_550_define»   s    zDictClient.dictCode_550_definec                 C   s   d| _ |  d ¡ dS rc   ©r   ÚmatchFailedrB   r   r   r   ÚdictCode_550_matchÁ   s    zDictClient.dictCode_550_matchc                 C   s   d| _ |  d ¡ dS )zInvalid strategyrR   Nrg   rB   r   r   r   ÚdictCode_551_matchÇ   s    zDictClient.dictCode_551_matchc                 C   s   d| _ |  d ¡ dS ©zNo matchrR   Nrd   rB   r   r   r   ÚdictCode_552_defineÍ   s    zDictClient.dictCode_552_definec                 C   s   d| _ |  d ¡ dS rk   rg   rB   r   r   r   ÚdictCode_552_matchÓ   s    zDictClient.dictCode_552_matchc                 C   s
   g | _ dS )zn definitions retrievedN)r&   rB   r   r   r   ÚdictCode_150_defineÙ   s    zDictClient.dictCode_150_definec                 C   sl   d| _ t|ƒ\}}t|ƒ\}}t|ƒ\}}|r6|r6|sL|  d¡ | j ¡  n| j t|||g ƒ¡ g | _dS )zDefinition text followsr1   zInvalid server responseN)	r   r   rH   rI   rP   r&   r#   r,   r9   )r2   r   r^   r/   r0   r   r   r   ÚdictCode_151_defineÞ   s    
zDictClient.dictCode_151_definec                 C   s   d| _ g | _g | _dS )zn matches found, text followsr1   N)r   r&   r9   rB   r   r   r   ÚdictCode_152_matchì   s    zDictClient.dictCode_152_matchc                 C   s<   t |ƒ}|dkr,d| _| j| jd _d| _n| j |¡ dS )z"A line of definition text receivedNr;   éÿÿÿÿ)r+   r   r9   r&   r1   r#   )r2   r   r   r   r   r   ÚdictCode_text_defineó   s    zDictClient.dictCode_text_definec                 C   sD   dd„ }t |ƒ}|dkr4d| _t|| jƒ| _d| _n| j |¡ dS )zOne line of match text receivedc                 S   s    t | ƒ\}}t |ƒ\}}||fS r-   )r   )r%   Zp1ÚtZp2r   r   r   Úl   s    z)DictClient.dictCode_text_match.<locals>.lNr;   )r+   r   r   r9   r&   r#   )r2   r   rt   r   r   r   r   ÚdictCode_text_matchþ   s    zDictClient.dictCode_text_matchc                 C   s    | j }d| _ d| _|  |¡ dS ©ÚokNrR   )r&   r<   Ú
defineDone©r2   r   rs   r   r   r   ÚdictCode_250_define  s    zDictClient.dictCode_250_definec                 C   s    | j }d| _ d| _|  |¡ dS rv   )r&   r<   Ú	matchDonery   r   r   r   ÚdictCode_250_match  s    zDictClient.dictCode_250_matchc                 C   s   dS )z5override to catch unexpected dict protocol conditionsNr   ©r2   Úreasonr   r   r   rH     s    zDictClient.protocolErrorc                 C   s   dS )zCoverride to be notified when the server is ready to accept commandsNr   r:   r   r   r   rS   "  s    zDictClient.dictConnectedc                 C   s   dS )z8override to catch reasonable failure responses to DEFINENr   r}   r   r   r   re   '  s    zDictClient.defineFailedc                 C   s   dS )z#override to catch successful DEFINENr   ©r2   r&   r   r   r   rx   ,  s    zDictClient.defineDonec                 C   s   dS )z6override to catch resonable failure responses to MATCHNr   r}   r   r   r   rh   1  s    zDictClient.matchFailedc                 C   s   dS )z"override to catch successful MATCHNr   r   r   r   r   r{   6  s    zDictClient.matchDone)(r4   r5   r6   r7   r9   r>   r<   r   r&   Úfactoryr3   r=   rA   rO   rL   rQ   rT   rV   rW   rX   r_   rb   rf   ri   rj   rl   rm   rn   ro   rp   rr   ru   rz   r|   rH   rS   re   rx   rh   r{   r   r   r   r   r8   Y   sJ   
	r8   c                   @   s   e Zd ZdS )ÚInvalidResponseN)r4   r5   r6   r   r   r   r   r   <  s   r   c                   @   s@   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S )Ú
DictLookupzNUtility class for a single dict transaction. To be used with DictLookupFactoryc                 C   s(   | j js$| j j t|ƒ¡ | j  ¡  d S r-   )r€   ÚdoneÚdÚerrbackr   Ú
clientDoner}   r   r   r   rH   D  s    zDictLookup.protocolErrorc                 C   s>   | j jdkrt| j| j jƒ n| j jdkr:t| j| j jƒ d S )NrY   r`   )r€   Ú	queryTypeZapplyr_   Úparamrb   r:   r   r   r   rS   J  s    zDictLookup.dictConnectedc                 C   s&   | j j g ¡ | j  ¡  | j ¡  d S r-   ©r€   r„   Úcallbackr†   rI   rP   r}   r   r   r   re   Q  s    
zDictLookup.defineFailedc                 C   s&   | j j |¡ | j  ¡  | j ¡  d S r-   r‰   r   r   r   r   rx   W  s    
zDictLookup.defineDonec                 C   s&   | j j g ¡ | j  ¡  | j ¡  d S r-   r‰   r}   r   r   r   rh   ]  s    
zDictLookup.matchFailedc                 C   s&   | j j |¡ | j  ¡  | j ¡  d S r-   r‰   r   r   r   r   r{   c  s    
zDictLookup.matchDoneN)
r4   r5   r6   r7   rH   rS   re   rx   rh   r{   r   r   r   r   r‚   A  s   r‚   c                   @   s@   e Zd ZdZeZdZdd„ Zdd„ Zdd„ Z	d	d
„ Z
dd„ ZdS )ÚDictLookupFactoryz-Utility factory for a single dict transactionNc                 C   s   || _ || _|| _d| _d S )Nr   )r‡   rˆ   r„   rƒ   )r2   r‡   rˆ   r„   r   r   r   r3   o  s    zDictLookupFactory.__init__c                 C   s   d| _ | `dS )zCalled by client when done.r   N)rƒ   r„   r:   r   r   r   r†   v  s    zDictLookupFactory.clientDonec                 C   s   | j  |¡ d S r-   )r„   r…   ©r2   Z	connectorÚerrorr   r   r   ÚclientConnectionFailed|  s    z(DictLookupFactory.clientConnectionFailedc                 C   s   | j s| j |¡ d S r-   )rƒ   r„   r…   rŒ   r   r   r   ÚclientConnectionLost€  s    z&DictLookupFactory.clientConnectionLostc                 C   s   |   ¡ }| |_|S r-   )r   r€   )r2   ZaddrÚpr   r   r   ÚbuildProtocol…  s    zDictLookupFactory.buildProtocol)r4   r5   r6   r7   r‚   r   rƒ   r3   r†   rŽ   r   r‘   r   r   r   r   r‹   j  s   r‹   c                 C   s6   t  ¡ }td||f|ƒ}ddlm} | | ||¡ |S )z"Look up a word using a dict serverrY   r   ©Úreactor©r   ZDeferredr‹   Útwisted.internetr“   Z
connectTCP)ÚhostÚportr]   r^   r„   r€   r“   r   r   r   rY   Œ  s
    rY   c                 C   s8   t  ¡ }td|||f|ƒ}ddlm} | | ||¡ |S )z Match a word using a dict serverr`   r   r’   r”   )r–   r—   r]   ra   r^   r„   r€   r“   r   r   r   r`   —  s
    r`   N)r7   Ztwisted.protocolsr   r•   r   r   Ztwisted.pythonr   r   r   r   r!   r(   r+   r,   r@   r8   Ú	Exceptionr   r‚   ZClientFactoryr‹   rY   r`   r   r   r   r   Ú<module>   s    "

 d)"