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„ 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
é    )ÚBytesIO)ÚdeferÚprotocol)Úbasic)Úlogc                 C   sæ   | dkrdS | dd… dkrd}nd}d}t | ƒ}|dkr"| d¡ 	 | d¡}|dkr<|dkr;| d¡ || ¡ fS n2|dkrN| d¡}|dkrMd| fS n |dkr`|dkr\|| ¡ fS d| fS |d	krn|dkrn|| ¡ fS ||7 }q#)
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   s<   


þ
ÿîr   c                 C   s   t dd„ | ƒS )zMunch a string into an 'atom'c                 S   s   | t ttdƒg d¢ ƒvS )Né!   ©é"   é'   é\   )ÚmapÚchrÚrange)Úxr   r   r   Ú<lambda>6   s    zmakeAtom.<locals>.<lambda>)Úfilter©r   r   r   r   ÚmakeAtom3   s   r"   c                 C   sL   t dƒg d¢ }g }| D ]}t|ƒ|v r| d¡ | |¡ qd |¡} | S )Nr   r   r   r   )r   ÚordÚappendÚjoin)ÚsÚ	mustquoteÚresultÚcr   r   r   ÚmakeWord9   s   

r*   c                 C   sD   t | ƒdkr| dkrd S t | ƒdkr | dd… dkr | dd … } | S )Nr   ó   .r   r
   s   ..)Úlenr!   r   r   r   Ú	parseTextD   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)Úselfr0   r1   r2   r3   r   r   r   Ú__init__P   ó   
zDefinition.__init__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r5   r   r   r   r   r.   M   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(   ©r4   r   r   r   r5   a   ó   
zDictClient.__init__c                 C   s   d| _ d| _d S )NÚconnÚcommand)Ústater   r=   r   r   r   ÚconnectionMadee   r>   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©r4   r   r   r   r   rF   i   s   zDictClient.sendLinec                 C   sª   z|  d¡}W n
 ty   Y d S w | jdkrd}n't|ƒdk r3t d| ¡ |  d¡ | j ¡  d S t	|d d… ƒ}|dd … }t
| d|› d| j› �| jƒ}||ƒ d S )	Nzutf-8r3   é   z-DictClient got invalid line from server -- %szInvalid line from serveré   Ú	dictCode_Ú_)ÚdecodeÚUnicodeErrorr   r,   r   ÚmsgÚprotocolErrorÚ	transportÚLoseConnectionÚintÚgetattrrA   ÚdictCode_default)r4   r   ÚcodeÚmethodr   r   r   ÚlineReceivedo   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   rN   rO   rP   ÚloseConnectionrG   r   r   r   rT   �   s   
zDictClient.dictCode_defaultc                 C   ó   dS )z*We are about to get kicked off, do nothingNr   rG   r   r   r   ÚdictCode_221_ready‡   ó   zDictClient.dictCode_221_readyc                 C   s   d| _ |  ¡  dS )zGreeting messageÚreadyN)rA   ÚdictConnectedrG   r   r   r   ÚdictCode_220_conn‹   s   zDictClient.dictCode_220_connc                 C   ó   |   d¡ | j ¡  d S )NzAccess denied©rO   rP   rX   r=   r   r   r   ÚdictCode_530_conn�   ó   
zDictClient.dictCode_530_connc                 C   r_   )NzServer temporarily unavailabler`   r=   r   r   r   ÚdictCode_420_conn”   rb   zDictClient.dictCode_420_connc                 C   r_   )Nz(Server shutting down at operator requestr`   r=   r   r   r   ÚdictCode_421_conn˜   rb   zDictClient.dictCode_421_connc                 C   sR   | j dks	J dƒ‚d| _d| _d| _ d t| d¡ƒt| d¡ƒ¡}|  |¡ dS )zSend a dict DEFINE commandr\   z4DictClient.sendDefine called when not in ready stateNÚdefinezDEFINE {} {}úUTF-8)rA   r(   r<   Úformatr"   Úencoder*   rF   )r4   ÚdatabaseÚwordr@   r   r   r   Ú
sendDefineœ   s   ÿÿþzDictClient.sendDefinec                 C   sR   | j dks	J dƒ‚d| _d| _d| _ d t|ƒt|ƒt|ƒ¡}|  | d¡¡ dS )zSend a dict MATCH commandr\   z3DictClient.sendMatch called when not in ready stateNÚmatchzMATCH {} {} {}rf   )rA   r(   r<   rg   r"   rF   rh   )r4   ri   Ústrategyrj   r@   r   r   r   Ú	sendMatch¬   s   ÿýzDictClient.sendMatchc                 C   ó   d| _ |  d ¡ dS ©zInvalid databaser\   N©r   ÚdefineFailedrG   r   r   r   ÚdictCode_550_define»   ó   zDictClient.dictCode_550_definec                 C   ro   rp   ©r   ÚmatchFailedrG   r   r   r   ÚdictCode_550_matchÀ   rt   zDictClient.dictCode_550_matchc                 C   ro   )zInvalid strategyr\   Nru   rG   r   r   r   ÚdictCode_551_matchÅ   rt   zDictClient.dictCode_551_matchc                 C   ro   ©zNo matchr\   Nrq   rG   r   r   r   ÚdictCode_552_defineÊ   rt   zDictClient.dictCode_552_definec                 C   ro   ry   ru   rG   r   r   r   ÚdictCode_552_matchÏ   rt   zDictClient.dictCode_552_matchc                 C   s
   g | _ dS )zn definitions retrievedN)r(   rG   r   r   r   ÚdictCode_150_defineÔ   s   
zDictClient.dictCode_150_definec                 C   sn   d| _ t|ƒ\}}t|ƒ\}}t|ƒ\}}|r|r|s'|  d¡ | j ¡  dS | j t|||g ƒ¡ g | _dS )zDefinition text followsr3   zInvalid server responseN)	r   r   rO   rP   rX   r(   r$   r.   r<   )r4   r   rj   r1   r2   r   r   r   ÚdictCode_151_defineØ   s   

zDictClient.dictCode_151_definec                 C   s   d| _ g | _g | _dS )zn matches found, text followsr3   N)r   r(   r<   rG   r   r   r   ÚdictCode_152_matchå   s   
zDictClient.dictCode_152_matchc                 C   s>   t |ƒ}|dkrd| _| j| jd _d| _dS | j |¡ dS )z"A line of definition text receivedNr@   éÿÿÿÿ)r-   r   r<   r(   r3   r$   )r4   r   r   r   r   r   ÚdictCode_text_defineë   s   
zDictClient.dictCode_text_definec                 C   sF   dd„ }t |ƒ}|dkrd| _t|| jƒ| _d| _dS | j |¡ dS )zOne line of match text receivedc                 S   s    t | ƒ\}}t |ƒ\}}||fS r/   )r   )r&   Úp1ÚtÚp2r   r   r   Úlø   s   z)DictClient.dictCode_text_match.<locals>.lNr@   )r-   r   r   r<   r(   r$   )r4   r   r„   r   r   r   r   ÚdictCode_text_matchõ   s   
zDictClient.dictCode_text_matchc                 C   ó    | j }d| _ d| _|  |¡ dS ©ÚokNr\   )r(   rA   Ú
defineDone©r4   r   r‚   r   r   r   ÚdictCode_250_define  ó   zDictClient.dictCode_250_definec                 C   r†   r‡   )r(   rA   Ú	matchDonerŠ   r   r   r   ÚdictCode_250_match  rŒ   zDictClient.dictCode_250_matchc                 C   rY   )z5override to catch unexpected dict protocol conditionsNr   ©r4   Úreasonr   r   r   rO     r[   zDictClient.protocolErrorc                 C   rY   )zCoverride to be notified when the server is ready to accept commandsNr   r=   r   r   r   r]     r[   zDictClient.dictConnectedc                 C   rY   )z8override to catch reasonable failure responses to DEFINENr   r�   r   r   r   rr     r[   zDictClient.defineFailedc                 C   rY   )z#override to catch successful DEFINENr   ©r4   r(   r   r   r   r‰     r[   zDictClient.defineDonec                 C   rY   )z7override to catch reasonable failure responses to MATCHNr   r�   r   r   r   rv   #  r[   zDictClient.matchFailedc                 C   rY   )z"override to catch successful MATCHNr   r‘   r   r   r   r�   '  r[   zDictClient.matchDone)(r7   r8   r9   r:   r<   rC   rA   r   r(   Úfactoryr5   rB   rF   rW   rT   rZ   r^   ra   rc   rd   rk   rn   rs   rw   rx   rz   r{   r|   r}   r~   r€   r…   r‹   rŽ   rO   r]   rr   r‰   rv   r�   r   r   r   r   r;   W   sL    
r;   c                   @   s   e Zd ZdS )ÚInvalidResponseN)r7   r8   r9   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 d S r/   )r’   ÚdoneÚdÚerrbackr“   Ú
clientDoner�   r   r   r   rO   3  s   þzDictLookup.protocolErrorc                 C   s@   | j jdkr| j| j jŽ  d S | j jdkr| j| j jŽ  d S d S )Nre   rl   )r’   Ú	queryTyperk   Úparamrn   r=   r   r   r   r]   8  s
   ÿzDictLookup.dictConnectedc                 C   ó&   | j j g ¡ | j  ¡  | j ¡  d S r/   ©r’   r–   Úcallbackr˜   rP   rX   r�   r   r   r   rr   >  ó   
zDictLookup.defineFailedc                 C   ó&   | j j |¡ | j  ¡  | j ¡  d S r/   rœ   r‘   r   r   r   r‰   C  rž   zDictLookup.defineDonec                 C   r›   r/   rœ   r�   r   r   r   rv   H  rž   zDictLookup.matchFailedc                 C   rŸ   r/   rœ   r‘   r   r   r   r�   M  rž   zDictLookup.matchDoneN)
r7   r8   r9   r:   rO   r]   rr   r‰   rv   r�   r   r   r   r   r”   0  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•   )r4   r™   rš   r–   r   r   r   r5   Y  r6   zDictLookupFactory.__init__c                 C   s   d| _ | `dS )zCalled by client when done.r   N)r•   r–   r=   r   r   r   r˜   _  s   zDictLookupFactory.clientDonec                 C   s   | j  |¡ d S r/   )r–   r—   ©r4   Ú	connectorÚerrorr   r   r   ÚclientConnectionFailedd  s   z(DictLookupFactory.clientConnectionFailedc                 C   s   | j s| j |¡ d S d S r/   )r•   r–   r—   r¡   r   r   r   ÚclientConnectionLostg  s   ÿz&DictLookupFactory.clientConnectionLostc                 C   s   |   ¡ }| |_|S r/   )r   r’   )r4   ÚaddrÚpr   r   r   ÚbuildProtocolk  s   zDictLookupFactory.buildProtocol)r7   r8   r9   r:   r”   r   r•   r5   r˜   r¤   r¥   r¨   r   r   r   r   r    S  s    r    c                 C   s6   t  ¡ }td||f|ƒ}ddlm} | | ||¡ |S )z"Look up a word using a dict serverre   r   ©Úreactor©r   ÚDeferredr    Útwisted.internetrª   Ú
connectTCP)ÚhostÚportri   rj   r–   r’   rª   r   r   r   re   q  s
   re   c                 C   s8   t  ¡ }td|||f|ƒ}ddlm} | | ||¡ |S )z Match a word using a dict serverrl   r   r©   r«   )r¯   r°   ri   rm   rj   r–   r’   rª   r   r   r   rl   |  s
   rl   N)r:   r   r   r­   r   r   Útwisted.protocolsr   Útwisted.pythonr   r   r"   r*   r-   r.   rE   r;   Ú	Exceptionr“   r”   ÚClientFactoryr    re   rl   r   r   r   r   Ú<module>   s"   !	
 V#