o
    ¯b‡—  ã                   @   s  d 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 ddlmZmZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZ eejƒG dd„ dƒƒZeejƒG dd„ dƒƒZdZ eej!ƒG dd„ dej"ƒƒZ#G dd„ dej$ƒZ%G dd„ dej&ƒZ'eej!ƒG dd„ dej(ƒƒZ)e *e'e)¡ G dd„ dej&ƒZ+eejƒG dd„ dej(ƒƒZ,e *e+e,¡ G dd„ dej&ƒZ-eej!ƒG dd „ d ej&ƒƒZ.ee.ejej/ƒ G d!d"„ d"ej(ƒZ0e *e.e0¡ eej1ej2ƒG d#d$„ d$ƒƒZ3G d%d&„ d&e3ƒZ4g d'¢Z5d(S ))a  
A module that needs a better name.

Implements new cred things for words.

How does this thing work?

  - Network connection on some port expecting to speak some protocol

  - Protocol-specific authentication, resulting in some kind of credentials object

  - twisted.cred.portal login using those credentials for the interface
    IUser and with something implementing IChatClient as the mind

  - successful login results in an IUser avatar the protocol can call
    methods on, and state added to the realm such that the mind will have
    methods called on it as is necessary

  - protocol specific actions lead to calls onto the avatar; remote events
    lead to calls onto the mind

  - protocol specific hangup, realm is notified, user is removed from active
    play, the end.
é    )ÚctimeÚtime)Úimplementer)Ú	copyright)ÚcredentialsÚerrorÚportal)ÚdeferÚprotocol)ÚfailureÚlogÚreflect)ÚregisterAdapter)Úpb)ÚewordsÚiwords)Úircc                   @   sV   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zdd
d„Zdd„ Zdd„ Z	dd„ Z
dd„ Zd	S )ÚGroupc                 C   s   || _ i | _dddœ| _d S )NÚ )ÚtopicÚtopic_author)ÚnameÚusersÚmeta©Úselfr   © r   ú7/usr/lib/python3/dist-packages/twisted/words/service.pyÚ__init__.   s
   þzGroup.__init__c                 C   s   t  t||ƒ¡S ©N)r   ÚFailureÚ	Exception)r   ÚerrÚpr   r   r   Ú_ebUserCall6   ó   zGroup._ebUserCallc                 C   s0   |D ]\}}|s|j \}}|  || ¡ ¡ qd S r   )ÚvalueÚremoveÚgetErrorMessage)r   ÚresultsÚsuccessÚresultÚuserr"   r   r   r   Ú_cbUserCall9   s   
€ýzGroup._cbUserCallc                 C   s”   t j |¡sJ d |¡ƒ‚|j| jvrEg }|| j|j< | j ¡ D ]}||ur;t |j	| |¡}|j
| j|d� | |¡ q t |¡ | j¡ t d ¡S )Nz{!r} is not a chat client©r#   )r   ÚIChatClientÚ
providedByÚformatr   r   Úvaluesr	   ÚmaybeDeferredÚ
userJoinedÚ
addErrbackr$   ÚappendÚDeferredListÚaddCallbackr-   Úsucceed)r   r,   Ú	additionsr#   Údr   r   r   Úadd?   s   ÿ
€
z	Group.addNc                 C   s†   z| j |j= W n	 ty   Y n.w g }| j  ¡ D ]}||ur4t |j| ||¡}|j| j|d� | 	|¡ qt 
|¡ | j¡ t d ¡S ©Nr.   )r   r   ÚKeyErrorr2   r	   r3   ÚuserLeftr5   r$   r6   r7   r8   r-   r9   )r   r,   ÚreasonÚremovalsr#   r;   r   r   r   r'   N   s   ÿ
€
zGroup.removec                 C   s   t  t| jƒ¡S r   )r	   r9   Úlenr   ©r   r   r   r   Úsize]   r%   z
Group.sizec                 C   sp   || u sJ ‚g }| j  ¡ D ]}||ur)t |j|| |¡}|j| j|d� | |¡ qt |¡ 	| j
¡ t d ¡S r=   )r   r2   r	   r3   Úreceiver5   r$   r6   r7   r8   r-   r9   )r   ÚsenderÚ	recipientÚmessageÚreceivesr#   r;   r   r   r   rE   `   s   
€
zGroup.receivec                 C   s`   || _ g }| j ¡ D ]}t |j| |¡}|j| j|d� | |¡ q
t 	|¡ 
| j¡ t d ¡S r=   )r   r   r2   r	   r3   ÚgroupMetaUpdater5   r$   r6   r7   r8   r-   r9   )r   r   Úsetsr#   r;   r   r   r   ÚsetMetadatak   s   
zGroup.setMetadatac                 C   s   t | j ¡ ƒS r   )Úiterr   r2   rC   r   r   r   Ú	iterusersu   s   zGroup.iterusersr   )Ú__name__Ú
__module__Ú__qualname__r   r$   r-   r<   r'   rD   rE   rL   rN   r   r   r   r   r   ,   s    

r   c                   @   sN   e Zd ZdZdZdd„ Zdd„ Zdd„ Zddd	„Zd
d„ Z	dd„ Z
dd„ ZdS )ÚUserNc                 C   s   || _ g | _tƒ | _d S r   )r   Úgroupsr   ÚlastMessager   r   r   r   r      ó   zUser.__init__c                 C   s   || _ || _tƒ | _d S r   )ÚrealmÚmindr   ÚsignOn)r   rV   rW   r   r   r   ÚloggedIn„   rU   zUser.loggedInc                    s    ‡ ‡fdd„}ˆ   ˆj¡ |¡S )Nc                    ó   ˆj  ˆ ¡ | S r   )rS   r6   ©r+   ©Úgroupr   r   r   ÚcbJoinŠ   ó   zUser.join.<locals>.cbJoin)r<   rW   r8   )r   r]   r^   r   r\   r   Újoin‰   s   z	User.joinc                    s"   ‡ ‡fdd„}ˆ   ˆj|¡ |¡S )Nc                    rZ   r   )rS   r'   r[   r\   r   r   ÚcbLeave‘   r_   zUser.leave.<locals>.cbLeave)r'   rW   r8   )r   r]   r@   ra   r   r\   r   Úleave�   s   z
User.leavec                 C   s   t ƒ | _| | j||¡S r   )r   rT   rE   rW   )r   rG   rH   r   r   r   Úsend—   s   z	User.sendc                 C   s
   t | jƒS r   )rM   rS   rC   r   r   r   Ú
itergroups›   ó   
zUser.itergroupsc                 C   s"   | j d d … D ]}|  |¡ qd S r   )rS   rb   )r   Úgr   r   r   Úlogoutž   s   ÿzUser.logoutr   )rO   rP   rQ   rV   rW   r   rY   r`   rb   rc   rd   rg   r   r   r   r   rR   z   s    
rR   zNickServ!NickServ@servicesc                   @   s‚  e 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dPdd„Zdd„ Zdd„ ZdZdZdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZejdfejdfejdfejdfgZejd fejd!fgZd"d#„ Z d$d%„ Z!d&d'„ Z"d(d)„ Z#dPd*d+„Z$dPd,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@dA„ Z/dBdC„ Z0dDdE„ Z1dFdG„ Z2dHdI„ Z3dJdK„ Z4dLdM„ Z5dNdO„ Z6dS )QÚIRCUserzM
    Protocol instance representing an IRC user connected to the server.
    Núutf-8c                 C   s    | j | _| jj| _| jj| _d S r   )Úirc_NICKSERV_PRIVMSGÚirc_PRIVMSGÚfactoryrV   r   ÚhostnamerC   r   r   r   ÚconnectionMade¼   s   
zIRCUser.connectionMadec                 C   s    | j d ur|   ¡  d | _d S d S r   )rg   Úavatar©r   r@   r   r   r   ÚconnectionLostÁ   s   

þzIRCUser.connectionLostc                 O   s„   d|vr	| j |d< d|vr| j | j¡|d< | ||d gt|ƒ }g }|D ]}t|tƒr1| d¡}| |¡ q%t	j
j|i |¤Ž d S )NÚprefixÚtori   )rm   r   ÚencodeÚencodingÚlistÚ
isinstanceÚbytesÚdecoder6   r   ÚIRCÚsendMessage)r   ÚcommandÚparameter_listÚkwÚarglistÚarglistUnicodeÚargr   r   r   r{   Ç   s   


zIRCUser.sendMessagec                 C   s,   |   |j› d|j› d| j› �d|j ¡ d S )Nú!ú@ú#)r`   r   rm   ©r   r]   r,   r   r   r   r4   Ö   s   ,zIRCUser.userJoinedc                 C   s2   |   |j› d|j› d| j› �d|j |pd¡ d S )Nr‚   rƒ   r„   Úleaving)Úpartr   rm   ©r   r]   r,   r@   r   r   r   r?   Ù   s
   ýzIRCUser.userLeftc                 C   s`   t j |¡rd|j }n|j}| dd¡}| ¡ D ]}|  |j› d|j› d| j› �||¡ qd S )Nr„   Útextz<an unrepresentable message>r‚   rƒ   )r   ÚIGroupr0   r   ÚgetÚ
splitlinesÚprivmsgrm   )r   rF   rG   rH   ÚrecipientNamer‰   ÚLr   r   r   rE   à   s   ýÿzIRCUser.receivec              
   C   sN   d|v r%|d }|  dd¡}|  | jd|j ||› d|› d| j› �¡ d S d S )Nr   r   r   r„   r‚   rƒ   )r‹   r   r   rm   )r   r]   r   r   Úauthorr   r   r   rJ   ñ   s   üýzIRCUser.groupMetaUpdatec                 C   ó   |d | _ dS )zÃ
        Password message -- Register a password.

        Parameters: <password>

        [REQUIRED]

        Note that IRC requires the client send this *before* NICK
        and USER.
        éÿÿÿÿN)Úpassword©r   rr   Úparamsr   r   r   Úirc_PASS   s   zIRCUser.irc_PASSc                 C   s¼   |d }zt |tƒr| | j¡}W n ty)   |  tt|ƒd¡ | j 	¡  Y dS w || _
|| _| jD ]\}}|  ||| jj ¡ q3| jdu rP|  t|d¡ dS | j}d| _|  ||¡ dS )zh
        Nick message -- Set your nickname.

        Parameters: <nickname>

        [REQUIRED]
        r   z;Your nickname cannot be decoded. Please use ASCII or UTF-8.Nz	Password?)rw   rx   ry   ru   ÚUnicodeDecodeErrorr�   ÚNICKSERVÚreprÚ	transportÚloseConnectionÚnicknamer   Ú_motdMessagesr{   rl   Ú_serverInfor“   ÚlogInAs)r   rr   r•   rœ   Úcoder‰   r“   r   r   r   Úirc_NICK  s.   
€ý
ù	
zIRCUser.irc_NICKc                 C   r‘   )zk
        User message -- Set your realname.

        Parameters: <user> <mode> <unused> <realname>
        r’   N)Úrealnamer”   r   r   r   Úirc_USER/  s   	zIRCUser.irc_USERc                 C   sd   |d }|d }| j du r| j ¡  dS | ¡ dkr$|  t| j d¡ dS | j }d| _ |  ||¡ dS )ú^
        Send a (private) message.

        Parameters: <msgtarget> <text to be sent>
        r   r’   NÚnickservz1Denied.  Please send me (NickServ) your password.)rœ   rš   r›   Úlowerr�   r˜   rŸ   )r   rr   r•   Útargetr“   rœ   r   r   r   rj   :  s   
ýzIRCUser.irc_NICKSERV_PRIVMSGc                 C   s6   | j j t ||¡| tj¡}|j| j| j	|fd� d S )N)ÚerrbackArgs)
rl   r   Úloginr   ÚUsernamePasswordr   ÚIUserÚaddCallbacksÚ_cbLoginÚ_ebLogin)r   rœ   r“   r;   r   r   r   rŸ   Q  s   ÿzIRCUser.logInAsz:connected to Twisted IRCzA:Your host is %(serviceName)s, running version %(serviceVersion)sz,:This server was created on %(creationDate)sz&%(serviceName)s %(serviceVersion)s w nz(:- %(serviceName)s Message of the Day - z:End of /MOTD command.c                 C   sZ   |\}}}|t ju sJ d|›�ƒ‚| `|| _|| _| jD ]\}}|  ||| jj ¡ qd S )NzRealm is buggy, got )	r   r«   rk   ro   rg   Ú_welcomeMessagesr{   rl   rž   )r   r+   Úifacero   rg   r    r‰   r   r   r   r­   n  s   
ÿzIRCUser._cbLoginc                 C   sh   |  tj¡r|  t|d¡ n|  tj¡r|  t|d¡ nt d¡ t 	|¡ |  t|d¡ | j
 ¡  d S )Nz*Already logged in.  No pod people allowed!zLogin failed.  Goodbye.zUnhandled error during login:z"Server error during login.  Sorry.)Úcheckr   ÚAlreadyLoggedInr�   r˜   ÚecredÚUnauthorizedLoginr   Úmsgr"   rš   r›   )r   r"   rœ   r   r   r   r®   z  s   ÿ

zIRCUser._ebLoginc                 C   s    | j dur|  d| j¡ dS dS )zK
        Ping message

        Parameters: <server1> [ <server2> ]
        NÚPONG)rV   r{   rm   r”   r   r   r   Úirc_PING‰  s   
ÿzIRCUser.irc_PINGc                 C   s   | j  ¡  dS )z>
        Quit

        Parameters: [ <Quit Message> ]
        N)rš   r›   r”   r   r   r   Úirc_QUIT’  s   zIRCUser.irc_QUITc                 G   s0   |r|   tjd¡ d S |  | jd|j d¡ d S )Nú:Unknown MODE flag.r„   ú+)r{   r   ÚERR_UNKNOWNMODEÚchannelModer   )r   r]   ÚmodesÚargsr   r   r   Ú_channelModeš  s   zIRCUser._channelModec                 C   sD   |r|   tjd¡ d S || ju r|   tjd¡ d S |   tjd¡ d S )Nr¹   rº   z(:You can't look at someone else's modes.)r{   r   r»   ro   ÚRPL_UMODEISÚERR_USERSDONTMATCH)r   r,   r½   r   r   r   Ú	_userMode   s   
ÿzIRCUser._userModec                    sÔ   zˆ d }t |tƒr| ˆj¡}W n ty%   ˆ tjˆ d d¡ Y dS w | d¡rM‡ ‡fdd„}ˆj	 
|dd… ¡}|jˆj|tˆ dd… ƒd� dS ‡fd	d
„}ˆj	 |¡}|jˆj|tˆ dd… ƒd� dS )z€
        User mode message

        Parameters: <nickname>
        *( ( "+" / "-" ) *( "i" / "w" / "o" / "O" / "r" ) )

        r   z2:No such nickname (could not decode your unicode!)Nr„   c                    ó$   |   tj¡ ˆ tjˆ d d¡ d S )Nr   ú:That channel doesn't exist.©Útrapr   ÚNoSuchGroupr{   r   ÚERR_NOSUCHCHANNEL©r"   ©r•   r   r   r   ÚebGroupÀ  s   ÿz!IRCUser.irc_MODE.<locals>.ebGroupé   )ÚcallbackArgsc                    s   ˆ   tjd¡ d S )Nz:No such nickname.©r{   r   ÚERR_NOSUCHNICKrÉ   rC   r   r   ÚebUserÊ  ó   z IRCUser.irc_MODE.<locals>.ebUser)rw   rx   ry   ru   r—   r{   r   rÏ   Ú
startswithrV   ÚlookupGroupr¬   r¿   ÚtupleÚ
lookupUserrÂ   )r   rr   r•   ÚchannelOrUserrË   r;   rÐ   r   rÊ   r   Úirc_MODEª  s(   
€ýú
""zIRCUser.irc_MODEc                 C   s   dS )zl
        Userhost message

        Parameters: <nickname> *( SPACE <nickname> )

        [Optional]
        Nr   r”   r   r   r   Úirc_USERHOSTÐ  s   zIRCUser.irc_USERHOSTc                    s¶   z|d ‰t ˆtƒrˆ ˆj¡‰W n ty%   ˆ tj|d d¡ Y dS w |d ‰ ˆ d¡r:ˆj	 
ˆdd… ¡}nˆj	 ˆ¡ dd„ ¡}‡ ‡fd	d
„}‡‡fdd„}| ||¡ dS )r¤   r   z6:No such nick/channel (could not decode your unicode!)Nr’   r„   rÌ   c                 S   s   | j S r   )rW   ©r,   r   r   r   Ú<lambda>ñ  s    z%IRCUser.irc_PRIVMSG.<locals>.<lambda>c                    s   | d urˆj  | dˆ i¡S d S )Nr‰   )ro   rc   )Útarg)ÚmessageTextr   r   r   ÚcbTargetô  s   ÿz%IRCUser.irc_PRIVMSG.<locals>.cbTargetc                    s   ˆ   tjˆd¡ d S )Nz:No such nick/channel.rÎ   rÉ   )r   Ú
targetNamer   r   ÚebTargetø  ó   z%IRCUser.irc_PRIVMSG.<locals>.ebTarget)rw   rx   ry   ru   r—   r{   r   rÏ   rÒ   rV   rÓ   rÕ   r8   r¬   )r   rr   r•   r§   rÝ   rß   r   )rÜ   r   rÞ   r   rk   Ú  s,   
€ýú
ÿzIRCUser.irc_PRIVMSGc                    ó”   z|d ‰ t ˆ tƒrˆ  ˆj¡‰ W n ty%   ˆ tj|d d¡ Y dS w ˆ  d¡r1ˆ dd… ‰ ‡fdd„}‡ ‡fdd	„}ˆj	 
ˆ ¡ ||¡ dS )
zm
        Join message

        Parameters: ( <channel> *( "," <channel> ) [ <key> *( "," <key> ) ] )
        r   ú1:No such channel (could not decode your unicode!)Nr„   rÌ   c                    s    ‡ ‡fdd„}ˆj  ˆ ¡ |¡S )Nc                    s>   ˆ  ˆ ˆ¡ ˆ ˆjdˆ j dd„ ˆ  ¡ D ƒ¡ ˆ ˆ ¡ d S )Nr„   c                 S   ó   g | ]}|j ‘qS r   ©r   ©Ú.0r,   r   r   r   Ú
<listcomp>  ó    zEIRCUser.irc_JOIN.<locals>.cbGroup.<locals>.cbJoin.<locals>.<listcomp>)r4   Únamesr   rN   Ú
_sendTopic)Úignr\   r   r   r^     s   ýz1IRCUser.irc_JOIN.<locals>.cbGroup.<locals>.cbJoin©ro   r`   r8   )r]   r^   rC   ©r]   r   ÚcbGroup  s   	z!IRCUser.irc_JOIN.<locals>.cbGroupc                    s   ˆ  tjdˆ  d¡ d S )Nr„   z:No such channel.)r{   r   rÈ   rÉ   ©Ú	groupNamer   r   r   rË     s   ÿz!IRCUser.irc_JOIN.<locals>.ebGroup)rw   rx   ry   ru   r—   r{   r   rÈ   rÒ   rV   ÚgetGroupr¬   ©r   rr   r•   rî   rË   r   rï   r   Úirc_JOINý  s$   
€ýú
zIRCUser.irc_JOINc                    sÌ   z|d ‰ t |d tƒr|d  ˆj¡‰ W n ty)   ˆ tj|d d¡ Y dS w ˆ  d¡r5ˆ dd… ‰ t	|ƒdkrJ|d ‰t ˆtƒrIˆ d¡‰nd‰‡‡fdd„}‡ ‡fd	d
„}ˆj
 ˆ ¡ ||¡ dS )zc
        Part message

        Parameters: <channel> *( "," <channel> ) [ <Part Message> ]
        r   z:Could not decode your unicode!Nr„   rÌ   ri   c                    s$   ‡ ‡‡fdd„}ˆj  ˆ ˆ¡ |¡S )Nc                    s   ˆ  ˆ ˆˆ¡ d S r   )r?   r[   )r]   r@   r   r   r   ra   @  rÑ   z2IRCUser.irc_PART.<locals>.cbGroup.<locals>.cbLeave)ro   rb   r8   )r]   ra   )r@   r   rí   r   rî   ?  s   z!IRCUser.irc_PART.<locals>.cbGroupc                    s,   |   tj¡ ˆ tjdˆ  d|  ¡  ¡ d S )Nr„   ú:)rÆ   r   rÇ   r{   r   ÚERR_NOTONCHANNELr(   rÉ   rï   r   r   rË   E  s   ÿz!IRCUser.irc_PART.<locals>.ebGroup)rw   rx   ry   ru   r—   r{   r   rõ   rÒ   rB   rV   rÓ   r¬   rò   r   )rð   r@   r   r   Úirc_PART%  s,   €ÿü


€zIRCUser.irc_PARTc                    rá   )
zb
        Names message

        Parameters: [ <channel> *( "," <channel> ) [ <target> ] ]
        r’   râ   Nr„   rÌ   c                    s(   ˆ   ˆ jd| j dd„ |  ¡ D ƒ¡ d S )Nr„   c                 S   rã   r   rä   rå   r   r   r   rç   g  rè   z6IRCUser.irc_NAMES.<locals>.cbGroup.<locals>.<listcomp>)ré   r   rN   rí   rC   r   r   rî   e  s   ÿz"IRCUser.irc_NAMES.<locals>.cbGroupc                    s$   |   tj¡ ˆ ˆjdˆ  g ¡ d S )Nr„   )rÆ   r   rÇ   ré   r   rÉ   ©Úchannelr   r   r   rË   j  s   z"IRCUser.irc_NAMES.<locals>.ebGroup)rw   rx   ry   ru   r—   r{   r   rÈ   rÒ   rV   rÓ   r¬   rò   r   r÷   r   Ú	irc_NAMESM  s$   	
€ýú
zIRCUser.irc_NAMESc                 C   sŽ   z|d }t |d tƒr| | j¡}W n ty$   |  tjd¡ Y dS w | d¡r0|dd… }t	|ƒdkr@|  
||d ¡ dS |  |¡ dS )zJ
        Topic message

        Parameters: <channel> [ <topic> ]
        r   z<:That channel doesn't exist (could not decode your unicode!)Nr„   rÌ   )rw   rx   ry   ru   r—   r{   r   rÈ   rÒ   rB   Ú	_setTopicÚ	_getTopic)r   rr   r•   rø   r   r   r   Ú	irc_TOPICq  s"   €þû
zIRCUser.irc_TOPICc                 C   sd   |j  d¡}|r0|j  d¡pd}|j  dd¡}|  | jd|j |¡ |  | jd|j ||¡ dS dS )zP
        Send the topic of the given group to this user, if it has one.
        r   r   z<noone>Ú
topic_dater   r„   N)r   r‹   r   r   ÚtopicAuthor)r   r]   r   r�   Údater   r   r   rê   Š  s   üzIRCUser._sendTopicc                    s(   ‡ ‡fdd„}ˆj  ˆ ¡ ˆj|¡ d S )Nc                    ó"   |   tj¡ ˆ tjdˆ d¡ d S ©Nú=rÄ   rÅ   rÉ   r÷   r   r   rË   ™  ó   
ÿz"IRCUser._getTopic.<locals>.ebGroup)rV   rÓ   r¬   rê   )r   rø   rË   r   r÷   r   rû   •  s   zIRCUser._getTopicc                    s4   ‡‡fdd„}‡ ‡fdd„}ˆj  ˆ ¡ ||¡ d S )Nc                    sH   ˆ j  ¡ }ˆ|d< ˆj|d< ttƒ ƒ|d< ‡ ‡fdd„}ˆ  |¡ |¡S )Nr   r   rý   c                    s   ˆ  tjdˆ j d¡ d S )Nr„   z.:You need to be a channel operator to do that.)r{   r   ÚERR_CHANOPRIVSNEEDEDr   rÉ   r\   r   r   ÚebSet«  s
   ýz1IRCUser._setTopic.<locals>.cbGroup.<locals>.ebSet)r   Úcopyr   Úintr   rL   r5   )r]   ÚnewMetar  )r   r   rí   r   rî   ¥  s   

z"IRCUser._setTopic.<locals>.cbGroupc                    r   r  rÅ   rÉ   r÷   r   r   rË   ´  r  z"IRCUser._setTopic.<locals>.ebGroup)rV   rÓ   r¬   )r   rø   r   rî   rË   r   )rø   r   r   r   rú   ¡  s   zIRCUser._setTopicc                 C   s<   |D ]\}}}|   tj|t|ƒd| ¡ q|   tjd¡ dS )zõ
        Send a group of LIST response lines

        @type channels: C{list} of C{(str, int, str)}
        @param channels: Information about the channels being sent:
            their name, the number of participants, and their topic.
        rô   z:End of /LISTN)r{   r   ÚRPL_LISTÚstrÚRPL_LISTEND)r   Úchannelsr   rD   r   r   r   r   rv   ¼  s   zIRCUser.listc                    sÒ   |rWz|d }t |tƒr| ˆ j¡}| d¡}W n ty,   ˆ  tj|d d¡ Y dS w g }|D ]}| 	d¡r>|dd… }| 
ˆ j |¡¡ q1tj|dd�}| d	d
„ ¡ nˆ j ¡ }‡ fdd„}| |¡ dS )zÎ
        List query

        Return information about the indicated channels, or about all
        channels if none are specified.

        Parameters: [ <channel> *( "," <channel> ) [ <target> ] ]
        r   ú,râ   Nr„   rÌ   T)ÚconsumeErrorsc                 S   s   dd„ | D ƒS )Nc                 S   ó   g | ]\}}|r|‘qS r   r   ©ræ   ÚsÚrr   r   r   rç   ë  ó    z6IRCUser.irc_LIST.<locals>.<lambda>.<locals>.<listcomp>r   )Úgsr   r   r   rÚ   ë  s    z"IRCUser.irc_LIST.<locals>.<lambda>c                    s6   dd„ ‰ t  ‡ fdd„| D ƒ¡}| ‡fdd„¡ |S )Nc                 S   s   |j | |j d¡fS )Nr   )r   r   r‹   )rD   r]   r   r   r   ÚgotSizeñ  rà   z3IRCUser.irc_LIST.<locals>.cbGroups.<locals>.gotSizec                    s   g | ]
}|  ¡  ˆ |¡‘qS r   )rD   r8   ©ræ   r]   ©r  r   r   rç   õ  s    z6IRCUser.irc_LIST.<locals>.cbGroups.<locals>.<listcomp>c                    s   ˆ   dd„ | D ƒ¡S )Nc                 S   r  r   r   r  r   r   r   rç   ÷  r  zHIRCUser.irc_LIST.<locals>.cbGroups.<locals>.<lambda>.<locals>.<listcomp>)rv   )r)   rC   r   r   rÚ   ÷  s    z4IRCUser.irc_LIST.<locals>.cbGroups.<locals>.<lambda>)r	   r7   r8   )rS   r;   rC   r  r   ÚcbGroupsð  s   ÿz"IRCUser.irc_LIST.<locals>.cbGroups)rw   rx   ry   ru   Úsplitr—   r{   r   rÈ   rÒ   r6   rV   rÓ   r	   r7   r8   rd   )r   rr   r•   ÚallChannelsr  rS   Úchr  r   rC   r   Úirc_LISTÈ  s0   
ýú


zIRCUser.irc_LISTc                    s,   ˆ   ˆ jd|j ‡ fdd„| ¡ D ƒ¡ d S )Nr„   c              	      s*   g | ]}|j ˆ jˆ jj |j d d|j f‘qS )ÚHr   )r   rm   rV   )ræ   ÚmrC   r   r   rç      s    ÿÿz'IRCUser._channelWho.<locals>.<listcomp>)Úwhor   rN   ©r   r]   r   rC   r   Ú_channelWhoü  s   
þýzIRCUser._channelWhoc                 C   s   |   tjd¡ d S )Nz:User /WHO not implemented)r{   r   ÚRPL_ENDOFWHO©r   r,   r   r   r   Ú_userWho  rÑ   zIRCUser._userWhoc                    sÌ   |sˆ  tjd¡ dS z|d ‰ tˆ tƒrˆ  ˆj¡‰ W n ty0   ˆ  tj|d d¡ Y dS w ˆ  d¡rP‡ ‡fdd„}ˆj	 
ˆ dd… ¡}| ˆj|¡ dS ‡ ‡fd	d
„}ˆj	 ˆ ¡}| ˆj|¡ dS )zC
        Who query

        Parameters: [ <mask> [ "o" ] ]
        z:/WHO not supported.Nr   z2:End of /WHO list (could not decode your unicode!)r„   c                    ó    |   tj¡ ˆ tjˆ d¡ d S ©Nz:End of /WHO list.)rÆ   r   rÇ   r{   r   r"  rÉ   ©rÖ   r   r   r   rË   *  ó   z IRCUser.irc_WHO.<locals>.ebGrouprÌ   c                    r%  r&  )rÆ   r   Ú
NoSuchUserr{   r   r"  rÉ   r'  r   r   rÐ   2  r(  zIRCUser.irc_WHO.<locals>.ebUser)r{   r   r"  rw   rx   ry   ru   r—   rÒ   rV   rÓ   r¬   r!  rÕ   r$  )r   rr   r•   rË   r;   rÐ   r   r'  r   Úirc_WHO	  s.   
€ýú
zIRCUser.irc_WHOc                    s~   ‡fdd„}‡ ‡fdd„}zˆ d }t |tƒr| ˆj¡}W n ty2   ˆ tjˆ d d¡ Y dS w ˆj 	|¡ 
||¡ dS )zV
        Whois query

        Parameters: [ <target> ] <mask> *( "," <mask> )
        c                    sN   ˆ   ˆ j| j| jˆ jj| jˆ jjddttƒ | j ƒ| jdd„ |  ¡ D ƒ¡ d S )NzHi mom!Fc                 S   s   g | ]}d |j  ‘qS )r„   rä   r  r   r   r   rç   L  s    z5IRCUser.irc_WHOIS.<locals>.cbUser.<locals>.<listcomp>)Úwhoisr   rV   r  r   rT   rX   rd   rÙ   rC   r   r   ÚcbUser@  s   õz!IRCUser.irc_WHOIS.<locals>.cbUserc                    rÃ   )Nr   ú:No such nick/channel)rÆ   r   r)  r{   r   rÏ   rÉ   rÊ   r   r   rÐ   O  s   z!IRCUser.irc_WHOIS.<locals>.ebUserr   r-  N)rw   rx   ry   ru   r—   r{   r   rÏ   rV   rÕ   r¬   )r   rr   r•   r,  rÐ   r,   r   rÊ   r   Ú	irc_WHOIS9  s   
€þzIRCUser.irc_WHOISc                 C   s   |   tjd¡ dS )zE
        Oper message

        Parameters: <name> <password>
        z:O-lines not applicableN)r{   r   ÚERR_NOOPERHOSTr”   r   r   r   Úirc_OPER^  s   zIRCUser.irc_OPERr   )7rO   rP   rQ   Ú__doc__rS   rg   ro   rV   ru   rn   rq   r{   r4   r?   rE   rJ   rœ   r“   r–   r¡   r£   rj   rŸ   r   ÚRPL_WELCOMEÚRPL_YOURHOSTÚRPL_CREATEDÚ
RPL_MYINFOr¯   ÚRPL_MOTDSTARTÚRPL_ENDOFMOTDr�   r­   r®   r·   r¸   r¿   rÂ   r×   rØ   rk   ró   rö   rù   rü   rê   rû   rú   rv   r  r!  r$  r*  r.  r0  r   r   r   r   rh   ¦   sp    
"þüöþ	


&
#(($4
0%rh   c                   @   s   e Zd ZdZeZdd„ ZdS )Ú
IRCFactorya  
    IRC server that creates instances of the L{IRCUser} protocol.

    @ivar _serverInfo: A dictionary mapping:
        "serviceName" to the name of the server,
        "serviceVersion" to the copyright version,
        "creationDate" to the time that the server was started.
    c                 C   s&   || _ || _| j jtjtƒ dœ| _d S )N)ÚserviceNameÚserviceVersionÚcreationDate)rV   r   r   r   Úversionr   rž   )r   rV   r   r   r   r   r   s  s   ýzIRCFactory.__init__N)rO   rP   rQ   r1  rh   r
   r   r   r   r   r   r8  g  s    	r8  c                   @   s<   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )ÚPBMindc                 C   ó   d S r   r   rC   r   r   r   r   ~  ó   zPBMind.__init__c                 C   s.   t  t¡}t|tƒr| d¡}||j | ¡fS ©Nri   )r   Úqualr=  rw   r
  rt   ÚinvokerÚregisterReference©r   ÚjellierrA  r   r   r   ÚjellyFor�  s   


zPBMind.jellyForc                 C   r>  r   r   )r   r,   r]   r   r   r   Úremote_userJoined‡  r?  zPBMind.remote_userJoinedc                 C   r>  r   r   )r   r,   r]   r@   r   r   r   Úremote_userLeftŠ  r?  zPBMind.remote_userLeftc                 C   r>  r   r   ©r   rF   rG   rH   r   r   r   Úremote_receive�  r?  zPBMind.remote_receivec                 C   r>  r   r   ©r   r]   r   r   r   r   Úremote_groupMetaUpdate�  r?  zPBMind.remote_groupMetaUpdateN)	rO   rP   rQ   r   rF  rG  rH  rJ  rL  r   r   r   r   r=  }  s    r=  c                   @   s2   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	d
„ZdS )ÚPBMindReferencer   c                 C   sJ   t j |¡rt| j| j|ƒ}nt| j| j|ƒ}|  dt| j| j|ƒ||¡S )NrE   )r   rŠ   r0   ÚPBGrouprV   ro   ÚPBUserÚ
callRemote)r   rF   rG   rH   Úrecr   r   r   rE   ™  s   ÿzPBMindReference.receivec                 C   s   |   dt| j| j|ƒ|¡S )NrJ   )rP  rN  rV   ro   rK  r   r   r   rJ   ¢  s   ÿzPBMindReference.groupMetaUpdatec                 C   s&   |   dt| j| j|ƒt| j| j|ƒ¡S )Nr4   ©rP  rN  rV   ro   rO  r…   r   r   r   r4   §  s
   ýzPBMindReference.userJoinedNc                 C   s(   |   dt| j| j|ƒt| j| j|ƒ|¡S )Nr?   rR  rˆ   r   r   r   r?   ®  s   üzPBMindReference.userLeftr   )rO   rP   rQ   r   rE   rJ   r4   r?   r   r   r   r   rM  ”  s    	rM  c                   @   s6   e Zd Zdd„ Zdd„ Zdd„ Zddd	„Zd
d„ ZdS )rN  c                 C   ó   || _ || _|| _d S r   )rV   ro   r]   )r   rV   ro   r]   r   r   r   r   »  ó   
zPBGroup.__init__c                 C   ó   t | jj| jj| jjfƒS r   )ÚhashrV   r   ro   r]   rC   r   r   r   ÚprocessUniqueIDÀ  ó   zPBGroup.processUniqueIDc                 C   sN   t  | j¡}t|tƒr| d¡}| jj}t|tƒr| d¡}|||j 	| ¡fS r@  )
r   rA  Ú	__class__rw   r
  rt   r]   r   rB  rC  )r   rE  rA  r]   r   r   r   rF  Ã  s   



zPBGroup.jellyForNc                 C   ó   | j  | j|¡S r   )ro   rb   r]   rp   r   r   r   Úremote_leaveÌ  r%   zPBGroup.remote_leavec                 C   rZ  r   )ro   rc   r]   ©r   rH   r   r   r   Úremote_sendÏ  r%   zPBGroup.remote_sendr   )rO   rP   rQ   r   rW  rF  r[  r]  r   r   r   r   rN  º  s    
	rN  c                   @   sX   e Zd Zdd„ Zddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zddd„Z	dd„ Z
dd„ ZdS )ÚPBGroupReferencec                 C   sF   |\}}}|| _ ttkrt| j tƒr| j  d¡| _ tj | |||g¡S r@  )r   rx   r
  rw   ry   r   ÚRemoteReferenceÚ
unjellyFor)r   Ú	unjellierÚunjellyListÚclsNamer   Úrefr   r   r   r`  Õ  s
   
zPBGroupReference.unjellyForNc                 C   ó   |   d|¡S )Nrb   ©rP  rp   r   r   r   rb   Ü  ó   zPBGroupReference.leavec                 C   re  )Nrc   rf  r\  r   r   r   rc   ß  rg  zPBGroupReference.sendc                 C   r>  r   r   r#  r   r   r   r<   â  ó   zPBGroupReference.addc                 C   r>  r   r   rC   r   r   r   rN   æ  rh  zPBGroupReference.iterusersc                 C   r>  r   r   rI  r   r   r   rE   ê  rh  zPBGroupReference.receivec                 C   r>  r   r   )r   r,   r@   r   r   r   r'   î  rh  zPBGroupReference.removec                 C   r>  r   r   )r   r   r   r   r   rL   ò  rh  zPBGroupReference.setMetadatac                 C   r>  r   r   rC   r   r   r   rD   ö  rh  zPBGroupReference.sizer   )rO   rP   rQ   r`  rb   rc   r<   rN   rE   r'   rL   rD   r   r   r   r   r^  Ó  s    

r^  c                   @   ó   e Zd Zdd„ Zdd„ ZdS )rO  c                 C   rS  r   )rV   ro   r,   )r   rV   ro   r,   r   r   r   r   ÿ  rT  zPBUser.__init__c                 C   rU  r   )rV  rV   r   ro   r,   rC   r   r   r   rW    rX  zPBUser.processUniqueIDN)rO   rP   rQ   r   rW  r   r   r   r   rO  þ  s    rO  c                   @   s`   e Zd Zdd„ Zdd„ Zdd„ Zedd„ ƒZejd	d„ ƒZd
d„ Z	dd„ Z
dd„ Zddd„ZdS )Ú
ChatAvatarc                 C   ó
   || _ d S r   )ro   )r   ro   r   r   r   r   
  re   zChatAvatar.__init__c                 C   s0   t  | j¡}t|tƒr| d¡}||j | ¡fS r@  )r   rA  rY  rw   r
  rt   rB  rC  rD  r   r   r   rF    s   

zChatAvatar.jellyForc                    s(   ‡ fdd„}ˆ j j |¡}| |¡ |S )Nc                    s(   ‡ ‡fdd„}ˆj  ˆ ¡}| |¡ |S )Nc                    s   t ˆjjˆjˆ ƒS r   )rN  ro   rV   )Úignoredr\   r   r   r^     rÑ   z7ChatAvatar.remote_join.<locals>.cbGroup.<locals>.cbJoinrì   )r]   r^   r;   rC   rí   r   rî     s   
z'ChatAvatar.remote_join.<locals>.cbGroup)ro   rV   rñ   r8   )r   rð   rî   r;   r   rC   r   Úremote_join  s   
zChatAvatar.remote_joinc                 C   r>  r   r   rC   r   r   r   r      ó   zChatAvatar.namec                 C   r>  r   r   )r   r&   r   r   r   r   %  rn  c                 C   r>  r   r   rK  r   r   r   rJ   *  rh  zChatAvatar.groupMetaUpdatec                 C   r>  r   r   rI  r   r   r   rE   .  rh  zChatAvatar.receivec                 C   r>  r   r   r…   r   r   r   r4   2  rh  zChatAvatar.userJoinedNc                 C   r>  r   r   rˆ   r   r   r   r?   6  rh  zChatAvatar.userLeftr   )rO   rP   rQ   r   rF  rm  Úpropertyr   ÚsetterrJ   rE   r4   r?   r   r   r   r   rj    s    

rj  c                   @   ri  )ÚAvatarReferencec                 C   re  )Nr`   rf  )r   rð   r   r   r   r`   ?  rg  zAvatarReference.joinc                    s,   t  ¡ ‰ | j ‡ fdd„¡ | jj ¡  ˆ S )Nc                      s
   ˆ   d ¡S r   )Úcallbackr   ©r;   r   r   rÚ   D  s   
 z&AvatarReference.quit.<locals>.<lambda>)r	   ÚDeferredÚbrokerÚnotifyOnDisconnectrš   r›   rC   r   rs  r   ÚquitB  s   zAvatarReference.quitN)rO   rP   rQ   r`   rw  r   r   r   r   rq  >  s    rq  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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 S )!Ú
WordsRealmri   c                 C   rk  r   rä   r   r   r   r   r   P  re   zWordsRealm.__init__c                 C   ó   t |ƒS r   )rR   r   r   r   r   ÚuserFactoryS  ó   zWordsRealm.userFactoryc                 C   ry  r   )r   r   r   r   r   ÚgroupFactoryV  r{  zWordsRealm.groupFactoryc                    s   ‡ ‡fdd„}|S )Nc                      s"   t ˆddd„ ƒƒ  d  ˆ _ˆ _d S )Nrg   c                   S   r>  r   r   r   r   r   r   rÚ   \  s    z:WordsRealm.logoutFactory.<locals>.logout.<locals>.<lambda>)ÚgetattrrV   rW   r   ©ro   Úfacetr   r   rg   Z  s   z(WordsRealm.logoutFactory.<locals>.logoutr   )r   ro   r  rg   r   r~  r   ÚlogoutFactoryY  s   zWordsRealm.logoutFactoryc                    s8   t ˆ tƒrˆ  ˆj¡‰ ‡ ‡‡‡fdd„}ˆ ˆ ¡ |¡S )Nc                    sl   | j d ur	t ¡ ‚ˆD ]%}|| d ƒ}|d ur0|  ˆˆ¡ ˆ ˆ_ˆˆ_ | ˆ_||ˆ | |¡f  S qtˆˆƒ‚r   )rV   r   r²   rY   r   ro   r€  ÚNotImplementedError)ro   r°   r  ©ÚavatarIdÚ
interfacesrW   r   r   r   Ú	gotAvatare  s   

û
z+WordsRealm.requestAvatar.<locals>.gotAvatar)rw   rx   ry   Ú	_encodingÚgetUserr8   )r   rƒ  rW   r„  r…  r   r‚  r   ÚrequestAvatara  s   
zWordsRealm.requestAvatarc                 C   r>  r   r   rC   r   r   r   rd   t  rh  zWordsRealm.itergroupsFTc                 C   ó   t ‚r   ©r�  r   r   r   r   rÕ   |  r?  zWordsRealm.lookupUserc                 C   r‰  r   rŠ  r   r   r   r   rÓ     r?  zWordsRealm.lookupGroupc                 C   r‰  )aÓ  
        Add the given user to this service.

        This is an internal method intended to be overridden by
        L{WordsRealm} subclasses, not called by external code.

        @type user: L{IUser}

        @rtype: L{twisted.internet.defer.Deferred}
        @return: A Deferred which fires with L{None} when the user is
        added, or which fails with
        L{twisted.words.ewords.DuplicateUser} if a user with the
        same name exists already.
        rŠ  r#  r   r   r   ÚaddUser‚  s   zWordsRealm.addUserc                 C   r‰  )aY  
        Add the given group to this service.

        @type group: L{IGroup}

        @rtype: L{twisted.internet.defer.Deferred}
        @return: A Deferred which fires with L{None} when the group is
        added, or which fails with
        L{twisted.words.ewords.DuplicateGroup} if a group with the
        same name exists already.
        rŠ  r   r   r   r   ÚaddGroup“  s   zWordsRealm.addGroupc                    ó.   ˆj r‡ ‡fdd„}ˆ ˆ ¡ |¡S ˆ ˆ ¡S )Nc                    ó   |   tj¡ ˆ ˆ ¡S r   )rÆ   r   ÚDuplicateGrouprÓ   rÉ   ©r   r   r   r   rË   ¤  ó   
z$WordsRealm.getGroup.<locals>.ebGroup)ÚcreateGroupOnRequestÚcreateGroupr5   rÓ   )r   r   rË   r   r�  r   rñ   ¡  ó   
zWordsRealm.getGroupc                    r�  )Nc                    rŽ  r   )rÆ   r   ÚDuplicateUserrÕ   rÉ   r�  r   r   rÐ   ®  r‘  z"WordsRealm.getUser.<locals>.ebUser)ÚcreateUserOnRequestÚ
createUserr5   rÕ   )r   r   rÐ   r   r�  r   r‡  «  r”  zWordsRealm.getUserc                    óH   ‡ fdd„}‡ ‡fdd„}ˆ   ¡ ‰ ˆ ˆ ¡}| ||¡ | ˆj¡ |S )Nc                    ó   t  t ˆ ¡¡S r   )r   r    r   r•  rÙ   rä   r   r   ÚcbLookup¶  r%   z'WordsRealm.createUser.<locals>.cbLookupc                    rŽ  r   )rÆ   r   r)  rz  rÉ   r�  r   r   ÚebLookup¹  r‘  z'WordsRealm.createUser.<locals>.ebLookup)r¦   rÕ   r¬   r8   r‹  ©r   r   rš  r›  r;   r   r�  r   r—  µ  ó   
zWordsRealm.createUserc                    r˜  )Nc                    r™  r   )r   r    r   r�  rí   rä   r   r   rš  Ä  r%   z(WordsRealm.createGroup.<locals>.cbLookupc                    rŽ  r   )rÆ   r   rÇ   r|  rÉ   r�  r   r   r›  Ç  r‘  z(WordsRealm.createGroup.<locals>.ebLookup)r¦   rÓ   r¬   r8   rŒ  rœ  r   r�  r   r“  Ã  r�  zWordsRealm.createGroupN)rO   rP   rQ   r†  r   rz  r|  r€  rˆ  rd   r’  r–  rÕ   rÓ   r‹  rŒ  rñ   r‡  r—  r“  r   r   r   r   rx  L  s$    

rx  c                       sD   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z‡  Z	S )ÚInMemoryWordsRealmc                    s"   t ƒ j|i |¤Ž i | _i | _d S r   )Úsuperr   r   rS   )r   Úar~   ©rY  r   r   r   Ó  s   
zInMemoryWordsRealm.__init__c                 C   s   t  | j ¡ ¡S r   )r	   r9   rS   r2   rC   r   r   r   rd   Ø  r%   zInMemoryWordsRealm.itergroupsc                 C   ó6   |j | jv rt t t ¡ ¡¡S || j|j < t |¡S r   )	r   r   r	   Úfailr   r    r   r•  r9   r#  r   r   r   r‹  Û  ó   
zInMemoryWordsRealm.addUserc                 C   r¢  r   )	r   rS   r	   r£  r   r    r   r�  r9   r   r   r   r   rŒ  á  r¤  zInMemoryWordsRealm.addGroupc              
   C   óJ   |  ¡ }z| j| }W n ty   t t t |¡¡¡ Y S w t 	|¡S r   )
r¦   r   r>   r	   r£  r   r    r   r)  r9   )r   r   r,   r   r   r   rÕ   ç  ó   ÿ
zInMemoryWordsRealm.lookupUserc              
   C   r¥  r   )
r¦   rS   r>   r	   r£  r   r    r   rÇ   r9   )r   r   r]   r   r   r   rÓ   ð  r¦  zInMemoryWordsRealm.lookupGroup)
rO   rP   rQ   r   rd   r‹  rŒ  rÕ   rÓ   Ú__classcell__r   r   r¡  r   rž  Ò  s    	rž  )r   rR   rx  rž  N)6r1  r   r   Úzope.interfacer   Útwistedr   Útwisted.credr   r   r³   r   Útwisted.internetr	   r
   Útwisted.pythonr   r   r   Útwisted.python.componentsr   Útwisted.spreadr   Útwisted.wordsr   r   Útwisted.words.protocolsr   rŠ   r   r«   rR   r˜   r/   rz   rh   ÚServerFactoryr8  ÚReferenceabler=  r_  rM  ÚsetUnjellyableForClassrN  r^  rO  rj  ÚIPerspectiverq  ÚIRealmÚIChatServicerx  rž  Ú__all__r   r   r   r   Ú<module>   sV   M(     E"'
2 (