o
    Óó·i&—  ã                   @   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   ú[C:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-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,   ÚreasonZ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ÚmessageZreceivesr#   r;   r   r   r   rD   `   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   Zsetsr#   r;   r   r   r   ÚsetMetadatak   s   
zGroup.setMetadatac                 C   s   t | j ¡ ƒS r   )Úiterr   r2   rB   r   r   r   Ú	iterusersu   s   zGroup.iterusersr   )Ú__name__Ú
__module__Ú__qualname__r   r$   r-   r<   r'   rC   rD   rI   rK   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   rS   rT   r   r   r   ÚloggedIn„   rR   zUser.loggedInc                    s    ‡ ‡fdd„}ˆ   ˆj¡ |¡S )Nc                    ó   ˆj  ˆ ¡ | S r   )rP   r6   ©r+   ©Úgroupr   r   r   ÚcbJoinŠ   ó   zUser.join.<locals>.cbJoin)r<   rT   r8   )r   rZ   r[   r   rY   r   Újoin‰   s   z	User.joinc                    s"   ‡ ‡fdd„}ˆ   ˆj|¡ |¡S )Nc                    rW   r   )rP   r'   rX   rY   r   r   ÚcbLeave‘   r\   zUser.leave.<locals>.cbLeave)r'   rT   r8   )r   rZ   r@   r^   r   rY   r   Úleave�   s   z
User.leavec                 C   s   t ƒ | _| | j||¡S r   )r   rQ   rD   rT   )r   rF   rG   r   r   r   Úsend—   s   z	User.sendc                 C   s
   t | jƒS r   )rJ   rP   rB   r   r   r   Ú
itergroups›   ó   
zUser.itergroupsc                 C   s"   | j d d … D ]}|  |¡ qd S r   )rP   r_   )r   Úgr   r   r   Úlogoutž   s   ÿzUser.logoutr   )rL   rM   rN   rS   rT   r   rV   r]   r_   r`   ra   rd   r   r   r   r   rO   z   s    
rO   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ÚfactoryrS   r   ÚhostnamerB   r   r   r   ÚconnectionMade¼   s   
zIRCUser.connectionMadec                 C   s    | j d ur|   ¡  d | _d S d S r   )rd   Ú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Útorf   )rj   r   ÚencodeÚencodingÚlistÚ
isinstanceÚbytesÚdecoder6   r   ÚIRCÚsendMessage)r   ÚcommandZparameter_listÚkwZarglistZarglistUnicodeÚargr   r   r   rx   Ç   s   


zIRCUser.sendMessagec                 C   s,   |   |j› d|j› d| j› �d|j ¡ d S )Nú!ú@ú#)r]   r   rj   ©r   rZ   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~   Zleaving)Úpartr   rj   ©r   rZ   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Úprivmsgrj   )r   rE   rF   rG   ZrecipientNamer‚   ÚLr   r   r   rD   à   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   rj   )r   rZ   r   r   Úauthorr   r   r   rH   ñ   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   ro   Ú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?)rt   ru   rv   rr   ÚUnicodeDecodeErrorr†   ÚNICKSERVÚreprÚ	transportÚloseConnectionÚnicknamer   Ú_motdMessagesrx   ri   Ú_serverInfor‹   ÚlogInAs)r   ro   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)Z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Š   NZnickservz1Denied.  Please send me (NickServ) your password.)r”   r’   r“   Úlowerr†   r�   r—   )r   ro   r�   Útargetr‹   r”   r   r   r   rg   :  s   
ýzIRCUser.irc_NICKSERV_PRIVMSGc                 C   s6   | j j t ||¡| tj¡}|j| j| j	|fd� d S )N)ZerrbackArgs)
ri   r   Úloginr   Z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Ÿ   rh   rl   rd   Ú_welcomeMessagesrx   ri   r–   )r   r+   Úifacerl   rd   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�   ÚecredZ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> ]
        NZPONG)rS   rx   rj   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~   ú+)rx   r   ÚERR_UNKNOWNMODEZchannelModer   )r   rZ   Ú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.)rx   r   r­   rl   ZRPL_UMODEISZ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   ÚNoSuchGrouprx   r   ÚERR_NOSUCHCHANNEL©r"   ©r�   r   r   r   ÚebGroupÀ  s   ÿz!IRCUser.irc_MODE.<locals>.ebGroupé   )ZcallbackArgsc                    s   ˆ   tjd¡ d S )Nz:No such nickname.©rx   r   ÚERR_NOSUCHNICKr¸   rB   r   r   ÚebUserÊ  ó   z IRCUser.irc_MODE.<locals>.ebUser)rt   ru   rv   rr   r�   rx   r   r½   Ú
startswithrS   ÚlookupGroupr    r°   ÚtupleÚ
lookupUserr±   )r   ro   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   )rT   ©r,   r   r   r   Ú<lambda>ñ  s    z%IRCUser.irc_PRIVMSG.<locals>.<lambda>c                    s   | d urˆj  | dˆ i¡S d S )Nr‚   )rl   r`   )Z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)rt   ru   rv   rr   r�   rx   r   r½   rÀ   rS   rÁ   rÃ   r8   r    )r   ro   r�   r�   rÊ   rÌ   r   )rÉ   r   rË   r   rh   Ú  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   rK   Ú
_sendTopic)ZignrY   r   r   r[     s   ýz1IRCUser.irc_JOIN.<locals>.cbGroup.<locals>.cbJoin©rl   r]   r8   )rZ   r[   rB   ©rZ   r   ÚcbGroup  s   	z!IRCUser.irc_JOIN.<locals>.cbGroupc                    s   ˆ  tjdˆ  d¡ d S )Nr~   z:No such channel.)rx   r   r·   r¸   ©Ú	groupNamer   r   r   rº     s   ÿz!IRCUser.irc_JOIN.<locals>.ebGroup)rt   ru   rv   rr   r�   rx   r   r·   rÀ   rS   ÚgetGroupr    ©r   ro   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»   rf   c                    s$   ‡ ‡‡fdd„}ˆj  ˆ ˆ¡ |¡S )Nc                    s   ˆ  ˆ ˆˆ¡ d S r   )r?   rX   )rZ   r@   r   r   r   r^   @  r¿   z2IRCUser.irc_PART.<locals>.cbGroup.<locals>.cbLeave)rl   r_   r8   )rZ   r^   )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¶   rx   r   ÚERR_NOTONCHANNELr(   r¸   rÛ   r   r   rº   E  s   ÿz!IRCUser.irc_PART.<locals>.ebGroup)rt   ru   rv   rr   r�   rx   r   rá   rÀ   rA   rS   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   rK   rÙ   rB   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)rt   ru   rv   rr   r�   rx   r   r·   rÀ   rS   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»   )rt   ru   rv   rr   r�   rx   r   r·   rÀ   rA   Ú	_setTopicÚ	_getTopic)r   ro   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   ZtopicAuthor)r   rZ   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)rS   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.)rx   r   ZERR_CHANOPRIVSNEEDEDr   r¸   rY   r   r   ÚebSet«  s
   ýz1IRCUser._setTopic.<locals>.cbGroup.<locals>.ebSet)r   Úcopyr   Úintr   rI   r5   )rZ   Z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)rS   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)rx   r   ZRPL_LISTÚstrZRPL_LISTEND)r   Úchannelsr   rC   r   r   r   r   rs   ¼  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)Z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   )Z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„   )rC   rZ   r   r   r   ÚgotSizeñ  rÍ   z3IRCUser.irc_LIST.<locals>.cbGroups.<locals>.gotSizec                    s   g | ]
}|  ¡  ˆ |¡‘qS r   )rC   r8   ©rÓ   rZ   ©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>)rs   )r)   rB   r   r   rÈ   ÷  s    z4IRCUser.irc_LIST.<locals>.cbGroups.<locals>.<lambda>)r	   r7   r8   )rP   r;   rB   rü   r   ÚcbGroupsð  s   ÿz"IRCUser.irc_LIST.<locals>.cbGroups)rt   ru   rv   rr   Úsplitr�   rx   r   r·   rÀ   r6   rS   rÁ   r	   r7   r8   ra   )r   ro   r�   ZallChannelsró   rP   Úchrý   r   rB   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   rj   rS   )rÓ   ÚmrB   r   r   rÔ      s    ÿÿz'IRCUser._channelWho.<locals>.<listcomp>)Zwhor   rK   ©r   rZ   r   rB   r   Ú_channelWhoü  s   
þýzIRCUser._channelWhoc                 C   s   |   tjd¡ d S )Nz:User /WHO not implemented)rx   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¶   rx   r   r  r¸   ©rÄ   r   r   r   rº   *  ó   z IRCUser.irc_WHO.<locals>.ebGroupr»   c                    r  r	  )rµ   r   Ú
NoSuchUserrx   r   r  r¸   r
  r   r   r¾   2  r  zIRCUser.irc_WHO.<locals>.ebUser)rx   r   r  rt   ru   rv   rr   r�   rÀ   rS   rÁ   r    r  rÃ   r  )r   ro   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>)Zwhoisr   rS   rñ   r   rQ   rU   ra   rÇ   rB   r   r   ÚcbUser@  s   õz!IRCUser.irc_WHOIS.<locals>.cbUserc                    r²   )Nr   ú:No such nick/channel)rµ   r   r  rx   r   r½   r¸   r¹   r   r   r¾   O  s   z!IRCUser.irc_WHOIS.<locals>.ebUserr   r  N)rt   ru   rv   rr   r�   rx   r   r½   rS   rÃ   r    )r   ro   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)rx   r   ZERR_NOOPERHOSTrŒ   r   r   r   Úirc_OPER^  s   zIRCUser.irc_OPERr   )7rL   rM   rN   Ú__doc__rP   rd   rl   rS   rr   rk   rn   rx   r4   r?   rD   rH   r”   r‹   rŽ   r™   rš   rg   r—   r   ZRPL_WELCOMEZRPL_YOURHOSTZRPL_CREATEDZ
RPL_MYINFOr£   ZRPL_MOTDSTARTZRPL_ENDOFMOTDr•   r¡   r¢   r©   rª   r°   r±   rÅ   rÆ   rh   rß   râ   rå   rè   r×   rç   ræ   rs   r   r  r  r  r  r  r   r   r   r   re   ¦   sp    
"þüöþ	


&
#(($4
0%re   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)ZserviceNameZserviceVersionZcreationDate)rS   r   r   r   Úversionr   r–   )r   rS   r   r   r   r   r   s  s   ýzIRCFactory.__init__N)rL   rM   rN   r  re   r
   r   r   r   r   r   r  g  s    	r  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   rB   r   r   r   r   ~  ó   zPBMind.__init__c                 C   s.   t  t¡}t|tƒr| d¡}||j | ¡fS ©Nrf   )r   Úqualr  rt   rò   rq   ÚinvokerÚregisterReference©r   Újellierr  r   r   r   ÚjellyFor�  s   


zPBMind.jellyForc                 C   r  r   r   )r   r,   rZ   r   r   r   Úremote_userJoined‡  r  zPBMind.remote_userJoinedc                 C   r  r   r   )r   r,   rZ   r@   r   r   r   Úremote_userLeftŠ  r  zPBMind.remote_userLeftc                 C   r  r   r   ©r   rE   rF   rG   r   r   r   Úremote_receive�  r  zPBMind.remote_receivec                 C   r  r   r   ©r   rZ   r   r   r   r   Úremote_groupMetaUpdate�  r  zPBMind.remote_groupMetaUpdateN)	rL   rM   rN   r   r  r  r   r"  r$  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 )NrD   )r   rƒ   r0   ÚPBGrouprS   rl   ÚPBUserÚ
callRemote)r   rE   rF   rG   Zrecr   r   r   rD   ˜  s   ÿzPBMindReference.receivec                 C   s   |   dt| j| j|ƒ|¡S )NrH   )r(  r&  rS   rl   r#  r   r   r   rH   ¡  s   ÿzPBMindReference.groupMetaUpdatec                 C   s&   |   dt| j| j|ƒt| j| j|ƒ¡S )Nr4   ©r(  r&  rS   rl   r'  r   r   r   r   r4   ¦  s
   ýzPBMindReference.userJoinedNc                 C   s(   |   dt| j| j|ƒt| j| j|ƒ|¡S )Nr?   r)  r�   r   r   r   r?   ­  s   üzPBMindReference.userLeftr   )rL   rM   rN   r   rD   rH   r4   r?   r   r   r   r   r%  ”  s    	r%  c                   @   s6   e Zd Zdd„ Zdd„ Zdd„ Zddd	„Zd
d„ ZdS )r&  c                 C   ó   || _ || _|| _d S r   )rS   rl   rZ   )r   rS   rl   rZ   r   r   r   r   º  ó   
zPBGroup.__init__c                 C   ó   t | jj| jj| jjfƒS r   )ÚhashrS   r   rl   rZ   rB   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   r  Ú	__class__rt   rò   rq   rZ   r   r  r  )r   r  r  rZ   r   r   r   r  Â  s   



zPBGroup.jellyForNc                 C   ó   | j  | j|¡S r   )rl   r_   rZ   rm   r   r   r   Úremote_leaveË  r%   zPBGroup.remote_leavec                 C   r1  r   )rl   r`   rZ   ©r   rG   r   r   r   Úremote_sendÎ  r%   zPBGroup.remote_sendr   )rL   rM   rN   r   r.  r  r2  r4  r   r   r   r   r&  ¹  s    
	r&  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   s*   |\}}}|  d¡| _tj | |||g¡S r  )rv   r   r   ÚRemoteReferenceÚ
unjellyFor)r   Z	unjellierZunjellyListZclsNamer   Úrefr   r   r   r7  Ô  s   
zPBGroupReference.unjellyForNc                 C   ó   |   d|¡S )Nr_   ©r(  rm   r   r   r   r_   Ù  ó   zPBGroupReference.leavec                 C   r9  )Nr`   r:  r3  r   r   r   r`   Ü  r;  zPBGroupReference.sendc                 C   r  r   r   r  r   r   r   r<   ß  ó   zPBGroupReference.addc                 C   r  r   r   rB   r   r   r   rK   ã  r<  zPBGroupReference.iterusersc                 C   r  r   r   r!  r   r   r   rD   ç  r<  zPBGroupReference.receivec                 C   r  r   r   )r   r,   r@   r   r   r   r'   ë  r<  zPBGroupReference.removec                 C   r  r   r   )r   r   r   r   r   rI   ï  r<  zPBGroupReference.setMetadatac                 C   r  r   r   rB   r   r   r   rC   ó  r<  zPBGroupReference.sizer   )rL   rM   rN   r7  r_   r`   r<   rK   rD   r'   rI   rC   r   r   r   r   r5  Ò  s    

r5  c                   @   ó   e Zd Zdd„ Zdd„ ZdS )r'  c                 C   r*  r   )rS   rl   r,   )r   rS   rl   r,   r   r   r   r   ü  r+  zPBUser.__init__c                 C   r,  r   )r-  rS   r   rl   r,   rB   r   r   r   r.    r/  zPBUser.processUniqueIDN)rL   rM   rN   r   r.  r   r   r   r   r'  û  s    r'  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   )rl   )r   rl   r   r   r   r     rb   zChatAvatar.__init__c                 C   s0   t  | j¡}t|tƒr| d¡}||j | ¡fS r  )r   r  r0  rt   rò   rq   r  r  r  r   r   r   r  
  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   )r&  rl   rS   )ZignoredrY   r   r   r[     r¿   z7ChatAvatar.remote_join.<locals>.cbGroup.<locals>.cbJoinrØ   )rZ   r[   r;   rB   rÙ   r   rÚ     s   
z'ChatAvatar.remote_join.<locals>.cbGroup)rl   rS   rÝ   r8   )r   rÜ   rÚ   r;   r   rB   r   Úremote_join  s   
zChatAvatar.remote_joinc                 C   r  r   r   rB   r   r   r   r     ó   zChatAvatar.namec                 C   r  r   r   )r   r&   r   r   r   r   "  rA  c                 C   r  r   r   r#  r   r   r   rH   '  r<  zChatAvatar.groupMetaUpdatec                 C   r  r   r   r!  r   r   r   rD   +  r<  zChatAvatar.receivec                 C   r  r   r   r   r   r   r   r4   /  r<  zChatAvatar.userJoinedNc                 C   r  r   r   r�   r   r   r   r?   3  r<  zChatAvatar.userLeftr   )rL   rM   rN   r   r  r@  Úpropertyr   ÚsetterrH   rD   r4   r?   r   r   r   r   r>    s    

r>  c                   @   r=  )ÚAvatarReferencec                 C   r9  )Nr]   r:  )r   rÜ   r   r   r   r]   <  r;  zAvatarReference.joinc                    s,   t  ¡ ‰ | j ‡ fdd„¡ | jj ¡  ˆ S )Nc                      s
   ˆ   d ¡S r   )Úcallbackr   ©r;   r   r   rÈ   A  s   
 z&AvatarReference.quit.<locals>.<lambda>)r	   ZDeferredZbrokerZnotifyOnDisconnectr’   r“   rB   r   rF  r   Úquit?  s   zAvatarReference.quitN)rL   rM   rN   r]   rG  r   r   r   r   rD  ;  s    rD  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 )!Ú
WordsRealmrf   c                 C   r?  r   rÑ   r   r   r   r   r   M  rb   zWordsRealm.__init__c                 C   ó   t |ƒS r   )rO   r   r   r   r   ÚuserFactoryP  ó   zWordsRealm.userFactoryc                 C   rI  r   )r   r   r   r   r   ÚgroupFactoryS  rK  zWordsRealm.groupFactoryc                    s   ‡ ‡fdd„}|S )Nc                      s"   t ˆddd„ ƒƒ  d  ˆ _ˆ _d S )Nrd   c                   S   r  r   r   r   r   r   r   rÈ   Y  s    z:WordsRealm.logoutFactory.<locals>.logout.<locals>.<lambda>)ÚgetattrrS   rT   r   ©rl   Úfacetr   r   rd   W  s   z(WordsRealm.logoutFactory.<locals>.logoutr   )r   rl   rO  rd   r   rN  r   ÚlogoutFactoryV  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   )rS   r   r¦   rV   r   rl   rP  ÚNotImplementedError)rl   r¤   rO  ©ÚavatarIdÚ
interfacesrT   r   r   r   Ú	gotAvatarb  s   

û
z+WordsRealm.requestAvatar.<locals>.gotAvatar)rt   ru   rv   Ú	_encodingÚgetUserr8   )r   rS  rT   rT  rU  r   rR  r   ÚrequestAvatar^  s   
zWordsRealm.requestAvatarc                 C   r  r   r   rB   r   r   r   ra   q  r<  zWordsRealm.itergroupsFTc                 C   ó   t ‚r   ©rQ  r   r   r   r   rÃ   y  r  zWordsRealm.lookupUserc                 C   rY  r   rZ  r  r   r   r   rÁ   |  r  zWordsRealm.lookupGroupc                 C   rY  )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.
        NrZ  r  r   r   r   ÚaddUser  s   zWordsRealm.addUserc                 C   rY  )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.
        NrZ  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¾   «  ra  z"WordsRealm.getUser.<locals>.ebUser)ÚcreateUserOnRequestÚ
createUserr5   rÃ   )r   r   r¾   r   r`  r   rW  ¨  rd  zWordsRealm.getUserc                    óH   ‡ fdd„}‡ ‡fdd„}ˆ   ¡ ‰ ˆ ˆ ¡}| ||¡ | ˆj¡ |S )Nc                    ó   t  t ˆ ¡¡S r   )r   r    r   re  rÇ   rÑ   r   r   ÚcbLookup³  r%   z'WordsRealm.createUser.<locals>.cbLookupc                    r^  r   )rµ   r   r  rJ  r¸   r`  r   r   ÚebLookup¶  ra  z'WordsRealm.createUser.<locals>.ebLookup)rœ   rÃ   r    r8   r[  ©r   r   rj  rk  r;   r   r`  r   rg  ²  ó   
zWordsRealm.createUserc                    rh  )Nc                    ri  r   )r   r    r   r_  rÙ   rÑ   r   r   rj  Á  r%   z(WordsRealm.createGroup.<locals>.cbLookupc                    r^  r   )rµ   r   r¶   rL  r¸   r`  r   r   rk  Ä  ra  z(WordsRealm.createGroup.<locals>.ebLookup)rœ   rÁ   r    r8   r\  rl  r   r`  r   rc  À  rm  zWordsRealm.createGroupN)rL   rM   rN   rV  r   rJ  rL  rP  rX  ra   rb  rf  rÃ   rÁ   r[  r\  rÝ   rW  rg  rc  r   r   r   r   rH  I  s$    

rH  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   rP   )r   Úarz   ©r0  r   r   r   Ð  s   
zInMemoryWordsRealm.__init__c                 C   s   t  | j ¡ ¡S r   )r	   r9   rP   r2   rB   r   r   r   ra   Õ  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   re  r9   r  r   r   r   r[  Ø  ó   
zInMemoryWordsRealm.addUserc                 C   rr  r   )	r   rP   r	   rs  r   r    r   r_  r9   r  r   r   r   r\  Þ  rt  zInMemoryWordsRealm.addGroupc              
   C   óJ   |  ¡ }z| j| }W n ty   t t t |¡¡¡ Y S w t 	|¡S r   )
rœ   r   r>   r	   rs  r   r    r   r  r9   )r   r   r,   r   r   r   rÃ   ä  ó   ÿ
zInMemoryWordsRealm.lookupUserc              
   C   ru  r   )
rœ   rP   r>   r	   rs  r   r    r   r¶   r9   )r   r   rZ   r   r   r   rÁ   í  rv  zInMemoryWordsRealm.lookupGroup)
rL   rM   rN   r   ra   r[  r\  rÃ   rÁ   Ú__classcell__r   r   rq  r   rn  Ï  s    	rn  )r   rO   rH  rn  N)6r  r   r   Zzope.interfacer   Ztwistedr   Ztwisted.credr   r   r§   r   Ztwisted.internetr	   r
   Ztwisted.pythonr   r   r   Ztwisted.python.componentsr   Ztwisted.spreadr   Ztwisted.wordsr   r   Ztwisted.words.protocolsr   rƒ   r   rŸ   rO   r�   r/   rw   re   ZServerFactoryr  ZReferenceabler  r6  r%  ZsetUnjellyableForClassr&  r5  r'  r>  ZIPerspectiverD  ZIRealmZIChatServicerH  rn  Ú__all__r   r   r   r   Ú<module>   sV   M(     E!%
2 (