o
    ¯b  ã                   @   s    d Z ddlmZ ddlmZ ddlmZmZ ddlm	Z	 ddl
mZ ddlmZ ddlmZmZ G d	d
„ d
ƒZG dd„ dƒZG dd„ dƒZG dd„ de	jƒZdS )zyInstance Messenger base classes for protocol support.

You will find these useful if you're adding a new protocol to IM.
é    )ÚType)Úerror)ÚProtocolÚconnectionDone)Ústyles)ÚFailure©ÚprefixedMethods)ÚOFFLINEÚOfflineErrorc                   @   sP   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdefdd„Z	defdd„Z
dS )ÚAbstractGroupc                 C   s   || _ || _d S ©N)ÚnameÚaccount)Úselfr   r   © r   ú>/usr/lib/python3/dist-packages/twisted/words/im/basesupport.pyÚ__init__   s   
zAbstractGroup.__init__c                 C   ó
   t | dƒS )z‹finds group commands

        these commands are methods on me that start with imgroup_; they are
        called with no arguments
        Úimgroup_r   ©r   r   r   r   ÚgetGroupCommands   ó   
zAbstractGroup.getGroupCommandsc                 C   r   )a(  finds group commands

        these commands are methods on me that start with imgroup_; they are
        called with a user present within this room as an argument

        you may want to override this in your group in order to filter for
        appropriate commands on the given user
        Ú	imtarget_r   )r   Útargetr   r   r   ÚgetTargetCommands#   s   
	zAbstractGroup.getTargetCommandsc                 C   ó    | j jst‚| j j | j¡ d S r   )r   Úclientr   Ú	joinGroupr   r   r   r   r   Újoin.   ó   zAbstractGroup.joinc                 C   r   r   )r   r   r   Ú
leaveGroupr   r   r   r   r   Úleave3   r    zAbstractGroup.leaveÚreturnc                 C   s   d| j › d| j›d�S )Nú<ú ú>)Ú	__class__r   r   r   r   r   Ú__repr__8   s   zAbstractGroup.__repr__c                 C   ó   | j › d| jj› �S ©Nú@©r   r   ÚaccountNamer   r   r   r   Ú__str__;   ó   zAbstractGroup.__str__N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r"   Ústrr(   r.   r   r   r   r   r      s    r   c                   @   s@   e Zd Zdd„ Zdd„ Zdd„ Zdefdd	„Zdefd
d„ZdS )ÚAbstractPersonc                 C   s   || _ || _t| _d S r   )r   r   r
   Ústatus)r   r   ÚbaseAccountr   r   r   r   @   s   
zAbstractPerson.__init__c                 C   r   )z�finds person commands

        these commands are methods on me that start with imperson_; they are
        called with no arguments
        Ú	imperson_r   r   r   r   r   ÚgetPersonCommandsE   r   z AbstractPerson.getPersonCommandsc                 C   s   dS )z#
        Returns a string.
        z--r   r   r   r   r   ÚgetIdleTimeM   s   zAbstractPerson.getIdleTimer#   c                 C   s   d| j › d| j›d| j› d�S )Nr$   r%   ú/r&   )r'   r   r5   r   r   r   r   r(   S   s   zAbstractPerson.__repr__c                 C   r)   r*   r,   r   r   r   r   r.   V   r/   zAbstractPerson.__str__N)	r0   r1   r2   r   r8   r9   r3   r(   r.   r   r   r   r   r4   ?   s    r4   c                   @   sL   e Zd ZU dZdZee ed< dd„ Zdd„ Z	e
fdefd	d
„Zdd„ ZdS )ÚAbstractClientMixinz–Designed to be mixed in to a Protocol implementing class.

    Inherit from me first.

    @ivar _logonDeferred: Fired when I am done logging in.
    NÚ
_protoBasec                 C   s<   | j jD ]}t|tƒr|| j _ nq	 || _|| _|| _d S r   )r'   Ú	__bases__Ú
issubclassr   r<   r   ÚchatÚ_logonDeferred)r   r   ÚchatuiÚlogonDeferredÚbaser   r   r   r   d   s   
þ
zAbstractClientMixin.__init__c                 C   s   | j  | ¡ d S r   )r<   ÚconnectionMader   r   r   r   rD   o   s   z"AbstractClientMixin.connectionMadeÚreasonc                 C   s$   | j  | |¡ |  ¡  | j | |¡S r   )r   Ú_clientLostÚunregisterAsAccountClientr<   ÚconnectionLost©r   rE   r   r   r   rH   r   s   z"AbstractClientMixin.connectionLostc                 C   s   | j  | ¡ dS )z*Tell the chat UI that I have `signed off'.N)r?   ÚunregisterAccountClientr   r   r   r   rG   w   s   z-AbstractClientMixin.unregisterAsAccountClient)r0   r1   r2   Ú__doc__r<   r   r   Ú__annotations__r   rD   r   r   rH   rG   r   r   r   r   r;   Z   s   
 r;   c                   @   sŽ   e Zd ZdZdZdZdZeZe	Z
dZdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdefdd„ZdS )ÚAbstractAccounta  Base class for Accounts.

    I am the start of an implementation of L{IAccount<interfaces.IAccount>}, I
    implement L{isOnline} and most of L{logOn}, though you'll need to implement
    L{_startLogOn} in a subclass.

    @cvar _groupFactory: A Callable that will return a L{IGroup} appropriate
        for this account type.
    @cvar _personFactory: A Callable that will return a L{IPerson} appropriate
        for this account type.

    @type _isConnecting: boolean
    @ivar _isConnecting: Whether I am in the process of establishing a
    connection to the server.
    @type _isOnline: boolean
    @ivar _isOnline: Whether I am currently on-line with the server.

    @ivar accountName:
    @ivar autoLogin:
    @ivar username:
    @ivar password:
    @ivar host:
    @ivar port:
    r   Né   c                 C   s4   || _ || _|| _|| _|| _|| _i | _i | _d S r   )r-   Ú	autoLoginÚusernameÚpasswordÚhostÚportÚ_groupsÚ_persons)r   r-   rO   rP   rQ   rR   rS   r   r   r   r   Ÿ   s   
zAbstractAccount.__init__c                 C   s$   dD ]}t | |ƒst| |i ƒ qd S )N)rT   rU   )ÚhasattrÚsetattr)r   Úkr   r   r   ÚupgrateToVersion2ª   s
   
€þz!AbstractAccount.upgrateToVersion2c              	   C   s6   t j | ¡}dD ]}z||= W q ty   Y qw |S )N)r   Ú	_isOnlineÚ_isConnecting)r   Ú	VersionedÚ__getstate__ÚKeyError)r   ÚstaterX   r   r   r   r]   °   s   
ÿzAbstractAccount.__getstate__c                 C   s   | j S r   )rZ   r   r   r   r   ÚisOnline¹   s   zAbstractAccount.isOnlinec                 C   sN   | j s"| js"d| _ |  |¡}| | j¡ | |j¡ | | j¡ |S t 	d¡‚)a=  Log on to this account.

        Takes care to not start a connection if a connection is
        already in progress.  You will need to implement
        L{_startLogOn} for this to work, and it would be a good idea
        to override L{_loginFailed} too.

        @returntype: Deferred L{interfaces.IClient}
        é   zConnection in progress)
r[   rZ   Ú_startLogOnÚaddCallbackÚ	_cb_logOnÚregisterAccountClientÚ
addErrbackÚ_loginFailedr   ÚConnectError)r   rA   Údr   r   r   ÚlogOn¼   s   


zAbstractAccount.logOnc                 C   ó.   | j  |¡}|du r|  || ¡}|| j |< |S )zkGroup factory.

        @param name: Name of the group on this account.
        @type name: string
        N)rT   ÚgetÚ_groupFactory)r   r   Úgroupr   r   r   ÚgetGroupÓ   ó
   
zAbstractAccount.getGroupc                 C   rk   )zmPerson factory.

        @param name: Name of the person on this account.
        @type name: string
        N)rU   rl   Ú_personFactory)r   r   Úpersonr   r   r   Ú	getPersonß   rp   zAbstractAccount.getPersonc                 C   s   t ƒ ‚)z{Start the sign on process.

        Factored out of L{logOn}.

        @returntype: Deferred L{interfaces.IClient}
        )ÚNotImplementedError)r   rA   r   r   r   rb   ë   s   zAbstractAccount._startLogOnc                 C   s   d| _ d| _|| _|S )Nr   ra   )r[   rZ   r   )r   r   r   r   r   rd   ô   ó   zAbstractAccount._cb_logOnc                 C   s   d| _ d| _|S )z¨Errorback for L{logOn}.

        @type reason: Failure

        @returns: I{reason}, for further processing in the callback chain.
        @returntype: Failure
        r   )r[   rZ   rI   r   r   r   rg   ú   s   zAbstractAccount._loginFailedc                 C   s   d | _ d| _d| _|S )Nr   )r   r[   rZ   )r   r   rE   r   r   r   rF     ru   zAbstractAccount._clientLostr#   c                 C   s   d  | j| j| j| j| j¡S )Nz<{}: {} ({}@{}:{})>)Úformatr'   r-   rP   rR   rS   r   r   r   r   r(     s   ûzAbstractAccount.__repr__)r0   r1   r2   rK   rZ   r[   r   r   rm   r4   rq   ÚpersistanceVersionr   rY   r]   r`   rj   ro   rs   rb   rd   rg   rF   r3   r(   r   r   r   r   rM   |   s(    		rM   N)rK   Útypingr   Útwisted.internetr   Útwisted.internet.protocolr   r   Útwisted.persistedr   Útwisted.python.failurer   Útwisted.python.reflectr	   Útwisted.words.im.localsr
   r   r   r4   r;   r\   rM   r   r   r   r   Ú<module>   s   )"