a
    )(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   4lib/python3.9/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   s    zGroup._ebUserCallc                 C   s0   |D ]&\}}|s|j \}}| ||  qd S r   )valueremovegetErrorMessage)r   resultsZsuccessresultuserr"   r   r   r   _cbUserCall9   s    
zGroup._cbUserCallc                 C   s   t j|sJ d||j| jvrg }|| j|j< | j D ]6}||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*   Z	additionsr#   dr   r   r   add?   s    z	Group.addNc                 C   s   z| j |j= W n ty    Y n\0 g }| j  D ]8}||ur0t|j| ||}|j| j|d |	| q0t
|| j td S Nr,   )r   r   KeyErrorr0   r	   r1   userLeftr3   r$   r4   r5   r6   r+   r7   )r   r*   reasonZremovalsr#   r8   r   r   r   r&   N   s    zGroup.removec                 C   s   t t| jS r   )r	   r7   lenr   r   r   r   r   size]   s    z
Group.sizec                 C   sp   || u sJ g }| j  D ]8}||urt|j|| |}|j| j|d || qt|	| j
 td S r:   )r   r0   r	   r1   receiver3   r$   r4   r5   r6   r+   r7   )r   sender	recipientmessageZreceivesr#   r8   r   r   r   rA   `   s    zGroup.receivec                 C   s`   || _ g }| j D ].}t|j| |}|j| j|d || qt	|
| j td S r:   )r   r   r0   r	   r1   groupMetaUpdater3   r$   r4   r5   r6   r+   r7   )r   r   Zsetsr#   r8   r   r   r   setMetadatak   s    zGroup.setMetadatac                 C   s   t | j S r   )iterr   r0   r?   r   r   r   	iterusersu   s    zGroup.iterusers)N)__name__
__module____qualname__r   r$   r+   r9   r&   r@   rA   rF   rH   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      s    zUser.__init__c                 C   s   || _ || _t | _d S r   )realmmindr   signOn)r   rO   rP   r   r   r   loggedIn   s    zUser.loggedInc                    s     fdd}  j|S )Nc                    s   j   | S r   )rM   r4   r)   groupr   r   r   cbJoin   s    zUser.join.<locals>.cbJoin)r9   rP   r6   )r   rU   rV   r   rT   r   join   s    z	User.joinc                    s"    fdd}  j||S )Nc                    s   j   | S r   )rM   r&   rS   rT   r   r   cbLeave   s    zUser.leave.<locals>.cbLeave)r&   rP   r6   )r   rU   r=   rX   r   rT   r   leave   s    z
User.leavec                 C   s   t  | _|| j||S r   )r   rN   rA   rP   )r   rC   rD   r   r   r   send   s    z	User.sendc                 C   s
   t | jS r   )rG   rM   r?   r   r   r   
itergroups   s    zUser.itergroupsc                 C   s"   | j d d  D ]}| | qd S r   )rM   rY   )r   gr   r   r   logout   s    zUser.logout)N)rI   rJ   rK   rO   rP   r   rR   rW   rY   rZ   r[   r]   r   r   r   r   rL   z   s   
rL   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#dQd*d+Z$dRd,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 )S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factoryrO   r   hostnamer?   r   r   r   connectionMade   s    
zIRCUser.connectionMadec                 C   s   | j d ur|    d | _d S r   )r]   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rb|d}|| qJt	j
j|i | d S )Nprefixtor_   )rc   r   encodeencodinglist
isinstancebytesdecoder4   r   IRCsendMessage)r   ZcommandZparameter_listkwZarglistZarglistUnicodeargr   r   r   rq      s    


zIRCUser.sendMessagec                 C   s,   |  |j d|j d| j d|j  d S )N!@#)rW   r   rc   r   rU   r*   r   r   r   r2      s    zIRCUser.userJoinedc                 C   s2   |  |j d|j d| j d|j |p*d d S )Nrt   ru   rv   Zleaving)partr   rc   r   rU   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 || q2d S )Nrv   textz<an unrepresentable message>rt   ru   )r   IGroupr.   r   get
splitlinesprivmsgrc   )r   rB   rC   rD   ZrecipientNamerz   Lr   r   r   rA      s    zIRCUser.receivec              
   C   sJ   d|v rF|d }| dd}| | jd|j || d| d| j  d S )Nr   r   r   rv   rt   ru   )r|   r   r   rc   )r   rU   r   r   authorr   r   r   rE      s    zIRCUser.groupMetaUpdatec                 C   s   |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   rh   paramsr   r   r   irc_PASS   s    zIRCUser.irc_PASSc                 C   s   |d }zt |tr || j}W n0 tyR   | tt|d | j	  Y dS 0 || _
|| _| jD ]\}}| ||| jj  qf| jdu r| t|d n| 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?)rm   rn   ro   rk   UnicodeDecodeErrorr~   NICKSERVrepr	transportloseConnectionnicknamer   _motdMessagesrq   rb   _serverInfor   logInAs)r   rh   r   r   coderz   r   r   r   r   irc_NICK  s*    


zIRCUser.irc_NICKc                 C   s   |d | _ dS )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   s`   |d }|d }| j du r&| j  n6| dkrD| t| j d n| 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   rh   r   targetr   r   r   r   r   r`   :  s    
zIRCUser.irc_NICKSERV_PRIVMSGc                 C   s6   | j jt||| tj}|j| j| j	|fd d S )N)ZerrbackArgs)
rb   r   Zloginr   ZUsernamePasswordr   IUseraddCallbacks_cbLogin_ebLogin)r   r   r   r8   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  q8d S )NzRealm is buggy, got )	r   r   ra   re   r]   _welcomeMessagesrq   rb   r   )r   r)   ifacere   r]   r   rz   r   r   r   r   n  s    
zIRCUser._cbLoginc                 C   sh   | tjr| t|d n>| tjr8| 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.)Z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 )zK
        Ping message

        Parameters: <server1> [ <server2> ]
        NZPONG)rO   rq   rc   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   s.   |r|  tjd n| | jd|j d d S )N:Unknown MODE flag.rv   +)rq   r   ERR_UNKNOWNMODEZchannelModer   )r   rU   modesargsr   r   r   _channelMode  s    zIRCUser._channelModec                 C   s@   |r|  tjd n(|| ju r.|  tjd n|  tjd d S )Nr   r   z(:You can't look at someone else's modes.)rq   r   r   re   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yJ   tj d d Y dS 0 |dr fdd}j	
|dd }|jj|t dd d n6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!)Nrv   c                    s$   |  tj tj d d d S )Nr   :That channel doesn't exist.trapr   NoSuchGrouprq   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.rq   r   ERR_NOSUCHNICKr   r?   r   r   ebUser  s    z IRCUser.irc_MODE.<locals>.ebUser)rm   rn   ro   rk   r   rq   r   r   
startswithrO   lookupGroupr   r   tuple
lookupUserr   )r   rh   r   channelOrUserr   r8   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yJ   tj|d d Y dS 0 |d  drt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   rv   r   c                 S   s   | j S r   )rP   r*   r   r   r   <lambda>      z%IRCUser.irc_PRIVMSG.<locals>.<lambda>c                    s   | d urj | d iS d S )Nrz   )re   rZ   )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  s    z%IRCUser.irc_PRIVMSG.<locals>.ebTarget)rm   rn   ro   rk   r   rq   r   r   r   rO   r   r   r6   r   )r   rh   r   r   r   r   r   )r   r   r   r   ra     s(    

zIRCUser.irc_PRIVMSGc                    s   z"|d  t  tr  j W n( tyJ   tj|d d Y dS 0  drb 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!)Nrv   r   c                    s     fdd}j  |S )Nc                    s>      jd j dd   D    d S )Nrv   c                 S   s   g | ]
}|j qS r   r   .0r*   r   r   r   
<listcomp>  r   zEIRCUser.irc_JOIN.<locals>.cbGroup.<locals>.cbJoin.<locals>.<listcomp>)r2   namesr   rH   
_sendTopic)ZignrT   r   r   rV     s    z1IRCUser.irc_JOIN.<locals>.cbGroup.<locals>.cbJoinre   rW   r6   )rU   rV   r?   rU   r   cbGroup  s    	z!IRCUser.irc_JOIN.<locals>.cbGroupc                    s    tjd  d d S )Nrv   z:No such channel.)rq   r   r   r   	groupNamer   r   r   r     s    z!IRCUser.irc_JOIN.<locals>.ebGroup)rm   rn   ro   rk   r   rq   r   r   r   rO   getGroupr   r   rh   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yR   tj|d d Y dS 0  drj dd  t	|dkr|d t tr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!Nrv   r   r_   c                    s$    fdd}j  |S )Nc                    s      d S r   )r<   rS   )rU   r=   r   r   r   rX   @  s    z2IRCUser.irc_PART.<locals>.cbGroup.<locals>.cbLeave)re   rY   r6   )rU   rX   )r=   r   r   r   r   ?  s    z!IRCUser.irc_PART.<locals>.cbGroupc                    s,   |  tj tjd  d|    d S )Nrv   :)r   r   r   rq   r   ERR_NOTONCHANNELr'   r   r   r   r   r   E  s    z!IRCUser.irc_PART.<locals>.ebGroup)rm   rn   ro   rk   r   rq   r   r   r   r>   rO   r   r   r   r   )r   r=   r   r   irc_PART%  s&    

zIRCUser.irc_PARTc                    s   z"|d  t  tr  j W n( tyJ   tj|d d Y dS 0  drb dd  fdd} fdd	}j	
 || dS )
zb
        Names message

        Parameters: [ <channel> *( "," <channel> ) [ <target> ] ]
        r   r   Nrv   r   c                    s(      jd| j dd |  D  d S )Nrv   c                 S   s   g | ]
}|j qS r   r   r   r   r   r   r   g  r   z6IRCUser.irc_NAMES.<locals>.cbGroup.<locals>.<listcomp>)r   r   rH   r   r?   r   r   r   e  s    z"IRCUser.irc_NAMES.<locals>.cbGroupc                    s$   |  tj jd  g  d S )Nrv   )r   r   r   r   r   r   channelr   r   r   r   j  s    z"IRCUser.irc_NAMES.<locals>.ebGroup)rm   rn   ro   rk   r   rq   r   r   r   rO   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yH   | tjd Y dS 0 |dr`|dd }t	|dkr~| 
||d  n
| | dS )zJ
        Topic message

        Parameters: <channel> [ <topic> ]
        r   z<:That channel doesn't exist (could not decode your unicode!)Nrv   r   )rm   rn   ro   rk   r   rq   r   r   r   r>   	_setTopic	_getTopic)r   rh   r   r   r   r   r   	irc_TOPICq  s    
zIRCUser.irc_TOPICc                 C   s`   |j d}|r\|j dpd}|j dd}| | jd|j | | | jd|j || dS )zP
        Send the topic of the given group to this user, if it has one.
        r   r   z<noone>
topic_dater   rv   N)r   r|   r   r   ZtopicAuthor)r   rU   r   r   dater   r   r   r     s    zIRCUser._sendTopicc                    s(    fdd}j  j| d S )Nc                    s"   |  tj tjd d d S N=r   r   r   r   r   r   r     s    
z"IRCUser._getTopic.<locals>.ebGroup)rO   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 )Nrv   z.:You need to be a channel operator to do that.)rq   r   ZERR_CHANOPRIVSNEEDEDr   r   rT   r   r   ebSet  s
    z1IRCUser._setTopic.<locals>.cbGroup.<locals>.ebSet)r   copyr   intr   rF   r3   )rU   ZnewMetar   )r   r   r   r   r     s    

z"IRCUser._setTopic.<locals>.cbGroupc                    s"   |  tj tjd d d S r   r   r   r   r   r   r     s    
z"IRCUser._setTopic.<locals>.ebGroup)rO   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)rq   r   ZRPL_LISTstrZRPL_LISTEND)r   channelsr   r@   r   r   r   r   rl     s    zIRCUser.listc                    s   |rz,|d }t |tr$| j}|d}W n( tyX    tj|d d Y dS 0 g }|D ],}|	dr||dd }|
 j| qbt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   Nrv   r   T)ZconsumeErrorsc                 S   s   dd | D S )Nc                 S   s   g | ]\}}|r|qS r   r   r   srr   r   r   r     r   z6IRCUser.irc_LIST.<locals>.<lambda>.<locals>.<listcomp>r   )Zgsr   r   r   r     r   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|   )r@   rU   r   r   r   gotSize  s    z3IRCUser.irc_LIST.<locals>.cbGroups.<locals>.gotSizec                    s   g | ]}|   |qS r   )r@   r6   r   rU   r   r   r   r     r   z6IRCUser.irc_LIST.<locals>.cbGroups.<locals>.<listcomp>c                    s     dd | D S )Nc                 S   s   g | ]\}}|r|qS r   r   r   r   r   r   r     r   zHIRCUser.irc_LIST.<locals>.cbGroups.<locals>.<lambda>.<locals>.<listcomp>)rl   )r(   r?   r   r   r     r   z4IRCUser.irc_LIST.<locals>.cbGroups.<locals>.<lambda>)r	   r5   r6   )rM   r8   r?   r   r   cbGroups  s    z"IRCUser.irc_LIST.<locals>.cbGroups)rm   rn   ro   rk   splitr   rq   r   r   r   r4   rO   r   r	   r5   r6   r[   )r   rh   r   ZallChannelsr   rM   Zchr   r   r?   r   irc_LIST  s.    



zIRCUser.irc_LISTc                    s,      jd|j  fdd| D  d S )Nrv   c              	      s*   g | ]"}|j  j jj |j d d|j fqS )Hr   )r   rc   rO   )r   mr?   r   r   r      s   z'IRCUser._channelWho.<locals>.<listcomp>)Zwhor   rH   r   rU   r   r?   r   _channelWho  s    
zIRCUser._channelWhoc                 C   s   |  tjd d S )Nz:User /WHO not implemented)rq   r   RPL_ENDOFWHOr   r*   r   r   r   _userWho  s    zIRCUser._userWhoc                    s   |s tjd dS z"|d  t tr6 j W n( ty`    tj|d d Y dS 0  dr fdd}j	
 dd }|j| n( 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!)rv   c                    s    |  tj tj d d S Nz:End of /WHO list.)r   r   r   rq   r   r   r   r   r   r   r   r   *  s    z IRCUser.irc_WHO.<locals>.ebGroupr   c                    s    |  tj tj d d S r   )r   r   
NoSuchUserrq   r   r   r   r   r   r   r   2  s    zIRCUser.irc_WHO.<locals>.ebUser)rq   r   r   rm   rn   ro   rk   r   r   rO   r   r   r   r   r   )r   rh   r   r   r8   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yd   tj d d Y dS 0 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 )rv   r   r   r   r   r   r   L  r   z5IRCUser.irc_WHOIS.<locals>.cbUser.<locals>.<listcomp>)Zwhoisr   rO   r   r   rN   rQ   r[   r   r?   r   r   cbUser@  s    z!IRCUser.irc_WHOIS.<locals>.cbUserc                    s$   |  tj tj d d d S )Nr   :No such nick/channel)r   r   r   rq   r   r   r   r   r   r   r   O  s    z!IRCUser.irc_WHOIS.<locals>.ebUserr   r   N)rm   rn   ro   rk   r   rq   r   r   rO   r   r   )r   rh   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)rq   r   ZERR_NOOPERHOSTr   r   r   r   irc_OPER^  s    zIRCUser.irc_OPER)N)N)N)7rI   rJ   rK   __doc__rM   r]   re   rO   rk   rd   rg   rq   r2   r<   rA   rE   r   r   r   r   r   r`   r   r   ZRPL_WELCOMEZRPL_YOURHOSTZRPL_CREATEDZ
RPL_MYINFOr   ZRPL_MOTDSTARTZRPL_ENDOFMOTDr   r   r   r   r   r   r   r   r   ra   r   r   r   r   r   r   r   rl   r   r   r   r   r   r   r   r   r   r   r^      sn   
"	


&
#(($4
0%r^   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)rO   r   r   r   versionr   r   )r   rO   r   r   r   r   r   s  s    zIRCFactory.__init__N)rI   rJ   rK   r   r^   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   s   d S r   r   r?   r   r   r   r   ~  s    zPBMind.__init__c                 C   s.   t t}t|tr|d}||j| fS Nr_   )r   qualr   rm   r   rj   invokerregisterReferencer   jellierr   r   r   r   jellyFor  s    


zPBMind.jellyForc                 C   s   d S r   r   )r   r*   rU   r   r   r   remote_userJoined  s    zPBMind.remote_userJoinedc                 C   s   d S r   r   )r   r*   rU   r=   r   r   r   remote_userLeft  s    zPBMind.remote_userLeftc                 C   s   d S r   r   r   rB   rC   rD   r   r   r   remote_receive  s    zPBMind.remote_receivec                 C   s   d S r   r   r   rU   r   r   r   r   remote_groupMetaUpdate  s    zPBMind.remote_groupMetaUpdateN)	rI   rJ   rK   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 )NrA   )r   r{   r.   PBGrouprO   re   PBUser
callRemote)r   rB   rC   rD   Zrecr   r   r   rA     s    zPBMindReference.receivec                 C   s   |  dt| j| j||S )NrE   )r  r  rO   re   r
  r   r   r   rE     s    zPBMindReference.groupMetaUpdatec                 C   s&   |  dt| j| j|t| j| j|S )Nr2   r  r  rO   re   r  rw   r   r   r   r2     s
    zPBMindReference.userJoinedNc                 C   s(   |  dt| j| j|t| j| j||S )Nr<   r  ry   r   r   r   r<     s    zPBMindReference.userLeft)N)rI   rJ   rK   r   rA   rE   r2   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   s   || _ || _|| _d S r   )rO   re   rU   )r   rO   re   rU   r   r   r   r     s    zPBGroup.__init__c                 C   s   t | jj| jj| jjfS r   )hashrO   r   re   rU   r?   r   r   r   processUniqueID  s    zPBGroup.processUniqueIDc                 C   sN   t | j}t|tr |d}| jj}t|tr<|d}|||j	| fS r   )
r   r   	__class__rm   r   rj   rU   r   r  r  )r   r  r   rU   r   r   r   r    s    



zPBGroup.jellyForNc                 C   s   | j | j|S r   )re   rY   rU   rf   r   r   r   remote_leave  s    zPBGroup.remote_leavec                 C   s   | j | j|S r   )re   rZ   rU   r   rD   r   r   r   remote_send  s    zPBGroup.remote_send)N)rI   rJ   rK   r   r  r  r  r  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   sF   |\}}}|| _ ttkr2t| j tr2| j d| _ tj| |||gS r   )r   rn   r   rm   ro   r   RemoteReference
unjellyFor)r   Z	unjellierZunjellyListZclsNamer   refr   r   r   r    s
    
zPBGroupReference.unjellyForNc                 C   s   |  d|S )NrY   r  rf   r   r   r   rY     s    zPBGroupReference.leavec                 C   s   |  d|S )NrZ   r  r  r   r   r   rZ     s    zPBGroupReference.sendc                 C   s   d S r   r   r   r   r   r   r9     s    zPBGroupReference.addc                 C   s   d S r   r   r?   r   r   r   rH     s    zPBGroupReference.iterusersc                 C   s   d S r   r   r  r   r   r   rA     s    zPBGroupReference.receivec                 C   s   d S r   r   )r   r*   r=   r   r   r   r&     s    zPBGroupReference.removec                 C   s   d S r   r   )r   r   r   r   r   rF     s    zPBGroupReference.setMetadatac                 C   s   d S r   r   r?   r   r   r   r@     s    zPBGroupReference.size)N)N)rI   rJ   rK   r  rY   rZ   r9   rH   rA   r&   rF   r@   r   r   r   r   r    s   

r  c                   @   s   e Zd Zdd Zdd ZdS )r  c                 C   s   || _ || _|| _d S r   )rO   re   r*   )r   rO   re   r*   r   r   r   r     s    zPBUser.__init__c                 C   s   t | jj| jj| jjfS r   )r  rO   r   re   r*   r?   r   r   r   r    s    zPBUser.processUniqueIDN)rI   rJ   rK   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   s
   || _ d S r   )re   )r   re   r   r   r   r   
  s    zChatAvatar.__init__c                 C   s0   t | j}t|tr |d}||j| fS r   )r   r   r  rm   r   rj   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  re   rO   )ZignoredrT   r   r   rV     s    z7ChatAvatar.remote_join.<locals>.cbGroup.<locals>.cbJoinr   )rU   rV   r8   r?   r   r   r     s    
z'ChatAvatar.remote_join.<locals>.cbGroup)re   rO   r   r6   )r   r   r   r8   r   r?   r   remote_join  s    
zChatAvatar.remote_joinc                 C   s   d S r   r   r?   r   r   r   r      s    zChatAvatar.namec                 C   s   d S r   r   )r   r%   r   r   r   r   %  s    c                 C   s   d S r   r   r
  r   r   r   rE   *  s    zChatAvatar.groupMetaUpdatec                 C   s   d S r   r   r  r   r   r   rA   .  s    zChatAvatar.receivec                 C   s   d S r   r   rw   r   r   r   r2   2  s    zChatAvatar.userJoinedNc                 C   s   d S r   r   ry   r   r   r   r<   6  s    zChatAvatar.userLeft)N)rI   rJ   rK   r   r  r  propertyr   setterrE   rA   r2   r<   r   r   r   r   r    s   

r  c                   @   s   e Zd Zdd Zdd ZdS )AvatarReferencec                 C   s   |  d|S )NrW   r  )r   r   r   r   r   rW   ?  s    zAvatarReference.joinc                    s,   t   | j fdd | jj   S )Nc                      s
     d S r   )callbackr   r8   r   r   r   D  r   z&AvatarReference.quit.<locals>.<lambda>)r	   ZDeferredZbrokerZnotifyOnDisconnectr   r   r?   r   r"  r   quitB  s    zAvatarReference.quitN)rI   rJ   rK   rW   r#  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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 )!
WordsRealmr_   c                 C   s
   || _ d S r   r   r   r   r   r   r   P  s    zWordsRealm.__init__c                 C   s   t |S r   )rL   r   r   r   r   userFactoryS  s    zWordsRealm.userFactoryc                 C   s   t |S r   )r   r   r   r   r   groupFactoryV  s    zWordsRealm.groupFactoryc                    s    fdd}|S )Nc                      s"   t ddd   d   _ _d S )Nr]   c                   S   s   d S r   r   r   r   r   r   r   \  r   z:WordsRealm.logoutFactory.<locals>.logout.<locals>.<lambda>)getattrrO   rP   r   re   facetr   r   r]   Z  s    z(WordsRealm.logoutFactory.<locals>.logoutr   )r   re   r)  r]   r   r(  r   logoutFactoryY  s    zWordsRealm.logoutFactoryc                    s8   t  tr j  fdd} |S )Nc                    sp   | j d urt D ]J}|| d }|d ur|   __ | _||| |f  S qtd S r   )rO   r   r   rR   r   re   r*  NotImplementedError)re   r   r)  avatarId
interfacesrP   r   r   r   	gotAvatare  s    

z+WordsRealm.requestAvatar.<locals>.gotAvatar)rm   rn   ro   	_encodinggetUserr6   )r   r-  rP   r.  r/  r   r,  r   requestAvatara  s    
zWordsRealm.requestAvatarc                 C   s   d S r   r   r?   r   r   r   r[   t  s    zWordsRealm.itergroupsFTc                 C   s   t d S r   r+  r   r   r   r   r   |  s    zWordsRealm.lookupUserc                 C   s   t d S r   r3  r   r   r   r   r     s    zWordsRealm.lookupGroupc                 C   s   t dS )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.
        Nr3  r   r   r   r   addUser  s    zWordsRealm.addUserc                 C   s   t dS )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.
        Nr3  r   r   r   r   addGroup  s    zWordsRealm.addGroupc                    s.   j r$ fdd} |S  S )Nc                    s   |  tj  S r   )r   r   DuplicateGroupr   r   r   r   r   r   r     s    z$WordsRealm.getGroup.<locals>.ebGroup)createGroupOnRequestcreateGroupr3   r   )r   r   r   r   r7  r   r     s    zWordsRealm.getGroupc                    s.   j r$ fdd} |S  S )Nc                    s   |  tj  S r   )r   r   DuplicateUserr   r   r7  r   r   r     s    z"WordsRealm.getUser.<locals>.ebUser)createUserOnRequest
createUserr3   r   )r   r   r   r   r7  r   r1    s    zWordsRealm.getUserc                    sH    fdd} fdd}     }||| |j |S )Nc                    s   t t S r   )r   r    r   r:  r   r   r   r   cbLookup  s    z'WordsRealm.createUser.<locals>.cbLookupc                    s   |  tj  S r   )r   r   r   r%  r   r7  r   r   ebLookup  s    z'WordsRealm.createUser.<locals>.ebLookup)r   r   r   r6   r4  r   r   r=  r>  r8   r   r7  r   r<    s    
zWordsRealm.createUserc                    sH    fdd} fdd}     }||| |j |S )Nc                    s   t t S r   )r   r    r   r6  r   r   r   r   r=    s    z(WordsRealm.createGroup.<locals>.cbLookupc                    s   |  tj  S r   )r   r   r   r&  r   r7  r   r   r>    s    z(WordsRealm.createGroup.<locals>.ebLookup)r   r   r   r6   r5  r?  r   r7  r   r9    s    
zWordsRealm.createGroupN)rI   rJ   rK   r0  r   r%  r&  r*  r2  r[   r8  r;  r   r   r4  r5  r   r1  r<  r9  r   r   r   r   r$  L  s"   

r$  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   rM   )r   arr   r  r   r   r     s    zInMemoryWordsRealm.__init__c                 C   s   t | j S r   )r	   r7   rM   r0   r?   r   r   r   r[     s    zInMemoryWordsRealm.itergroupsc                 C   s6   |j | jv r ttt S || j|j < t|S r   )	r   r   r	   failr   r    r   r:  r7   r   r   r   r   r4    s    zInMemoryWordsRealm.addUserc                 C   s6   |j | jv r ttt S || j|j < t|S r   )	r   rM   r	   rD  r   r    r   r6  r7   r   r   r   r   r5    s    zInMemoryWordsRealm.addGroupc              
   C   sN   |  }z| j| }W n( ty>   ttt| Y S 0 t	|S d S r   )
r   r   r;   r	   rD  r   r    r   r   r7   )r   r   r*   r   r   r   r     s    zInMemoryWordsRealm.lookupUserc              
   C   sN   |  }z| j| }W n( ty>   ttt| Y S 0 t	|S d S r   )
r   rM   r;   r	   rD  r   r    r   r   r7   )r   r   rU   r   r   r   r     s    zInMemoryWordsRealm.lookupGroup)
rI   rJ   rK   r   r[   r4  r5  r   r   __classcell__r   r   rC  r   r@    s   	r@  )r   rL   r$  r@  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   rL   r   r-   rp   r^   ZServerFactoryr   ZReferenceabler   r  r  ZsetUnjellyableForClassr  r  r  r  ZIPerspectiver   ZIRealmZIChatServicer$  r@  __all__r   r   r   r   <module>   sT   M(     E"'
2 (