U
    n5{i%  ã                   @   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edœdd„Z	edœdd„Z
dS )ÚAbstractGroupc                 C   s   || _ || _d S ©N)ÚnameÚaccount)Úselfr   r   © r   ú@/tmp/pip-unpacked-wheel-mnhg7r0q/twisted/words/im/basesupport.pyÚ__init__   s    zAbstractGroup.__init__c                 C   s
   t | dƒS )z‹finds group commands

        these commands are methods on me that start with imgroup_; they are
        called with no arguments
        Zimgroup_r   ©r   r   r   r   ÚgetGroupCommands   s    zAbstractGroup.getGroupCommandsc                 C   s
   t | dƒS )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
        Z	imtarget_r   )r   Útargetr   r   r   ÚgetTargetCommands#   s    	zAbstractGroup.getTargetCommandsc                 C   s    | j jst‚| j j | j¡ d S r   )r   Úclientr   Z	joinGroupr   r   r   r   r   Újoin.   s    zAbstractGroup.joinc                 C   s    | j jst‚| j j | j¡ d S r   )r   r   r   Z
leaveGroupr   r   r   r   r   Úleave3   s    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   s   | j › d| jj› �S ©Nú@©r   r   ÚaccountNamer   r   r   r   Ú__str__;   s    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edœdd	„Zedœd
d„ZdS )ÚAbstractPersonc                 C   s   || _ || _t| _d S r   )r   r   r
   Ústatus)r   r   ZbaseAccountr   r   r   r   @   s    zAbstractPerson.__init__c                 C   s
   t | dƒS )z�finds person commands

        these commands are methods on me that start with imperson_; they are
        called with no arguments
        Z	imperson_r   r   r   r   r   ÚgetPersonCommandsE   s    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   r,   r   r   r   r   r!   S   s    zAbstractPerson.__repr__c                 C   s   | j › d| jj› �S r"   r$   r   r   r   r   r&   V   s    zAbstractPerson.__str__N)	r'   r(   r)   r   r-   r.   r*   r!   r&   r   r   r   r   r+   ?   s
   r+   c                   @   sN   e Zd ZU dZdZee ed< dd„ Zdd„ Z	e
feddœ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 _ q$q|| _|| _|| _d S r   )r    Ú	__bases__Ú
issubclassr   r1   r   ÚchatZ_logonDeferred)r   r   ÚchatuiZlogonDeferredÚbaser   r   r   r   d   s    
zAbstractClientMixin.__init__c                 C   s   | j  | ¡ d S r   )r1   ÚconnectionMader   r   r   r   r7   o   s    z"AbstractClientMixin.connectionMade)Úreasonr   c                 C   s$   | j  | |¡ |  ¡  | j | |¡S r   )r   Ú_clientLostÚunregisterAsAccountClientr1   ÚconnectionLost©r   r8   r   r   r   r;   r   s    z"AbstractClientMixin.connectionLostc                 C   s   | j  | ¡ dS )z*Tell the chat UI that I have `signed off'.N)r4   ZunregisterAccountClientr   r   r   r   r:   w   s    z-AbstractClientMixin.unregisterAsAccountClient)r'   r(   r)   Ú__doc__r1   r   r   Ú__annotations__r   r7   r   r   r;   r:   r   r   r   r   r0   Z   s   
r0   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edœ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%   rA   rB   rC   rD   rE   r   r   r   r   Ÿ   s    zAbstractAccount.__init__c                 C   s$   dD ]}t | |ƒst| |i ƒ qd S )N)rF   rG   )ÚhasattrÚsetattr)r   Úkr   r   r   ÚupgrateToVersion2ª   s    
z!AbstractAccount.upgrateToVersion2c              	   C   s:   t j | ¡}dD ]$}z
||= W q tk
r2   Y qX q|S )N)r   Ú	_isOnlineÚ_isConnecting)r   Ú	VersionedÚ__getstate__ÚKeyError)r   ÚstaterJ   r   r   r   rO   °   s    
zAbstractAccount.__getstate__c                 C   s   | j S r   )rL   r   r   r   r   ÚisOnline¹   s    zAbstractAccount.isOnlinec                 C   sR   | j sD| jsDd| _ |  |¡}| | j¡ | |j¡ | | j¡ |S t 	d¡‚dS )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 progressN)
rM   rL   Ú_startLogOnZaddCallbackÚ	_cb_logOnZregisterAccountClientZ
addErrbackÚ_loginFailedr   ZConnectError)r   r5   Údr   r   r   ÚlogOn¼   s    

zAbstractAccount.logOnc                 C   s.   | j  |¡}|dkr*|  || ¡}|| j |< |S )zkGroup factory.

        @param name: Name of the group on this account.
        @type name: string
        N)rF   ÚgetÚ_groupFactory)r   r   Úgroupr   r   r   ÚgetGroupÓ   s
    
zAbstractAccount.getGroupc                 C   s.   | j  |¡}|dkr*|  || ¡}|| j |< |S )zmPerson factory.

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

        Factored out of L{logOn}.

        @returntype: Deferred L{interfaces.IClient}
        N)ÚNotImplementedError)r   r5   r   r   r   rT   ë   s    zAbstractAccount._startLogOnc                 C   s   d| _ d| _|| _|S )Nr   rS   )rM   rL   r   )r   r   r   r   r   rU   ô   s    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   )rM   rL   r<   r   r   r   rV   ú   s    zAbstractAccount._loginFailedc                 C   s   d | _ d| _d| _|S )Nr   )r   rM   rL   )r   r   r8   r   r   r   r9     s    zAbstractAccount._clientLostr   c                 C   s   d  | j| j| j| j| j¡S )Nz<{}: {} ({}@{}:{})>)Úformatr    r%   rB   rD   rE   r   r   r   r   r!     s    ûzAbstractAccount.__repr__)r'   r(   r)   r=   rL   rM   r   r   rZ   r+   r]   ZpersistanceVersionr   rK   rO   rR   rX   r\   r^   rT   rU   rV   r9   r*   r!   r   r   r   r   r?   |   s&   		r?   N)r=   Útypingr   Ztwisted.internetr   Ztwisted.internet.protocolr   r   Ztwisted.persistedr   Ztwisted.python.failurer   Ztwisted.python.reflectr	   Ztwisted.words.im.localsr
   r   r   r+   r0   rN   r?   r   r   r   r   Ú<module>   s   )"