Rename client.py to plugin.py, as all client logic has already been moved to client_nb.py

Introduce a get_instance factory method for all plugins and other xmpp related classes. This will help us to decouple plugs in order to make them testable.
This commit is contained in:
Stephan Erb 2009-01-09 00:49:58 +00:00
parent e00f871b26
commit bc3445881f
11 changed files with 75 additions and 42 deletions

View File

@ -13,7 +13,7 @@ Thanks and credits to the xmpppy developers. See: http://xmpppy.sourceforge.net/
import simplexml, protocol, auth_nb, transports_nb, roster_nb
import dispatcher_nb, features_nb, idlequeue, bosh, tls_nb, proxy_connectors
from client_nb import NonBlockingClient
from client import PlugIn
from plugin import PlugIn
from protocol import *
# vim: se ts=3:

View File

@ -21,7 +21,7 @@ See client_nb.py
'''
from protocol import NS_SASL, NS_SESSION, NS_STREAMS, NS_BIND, NS_AUTH
from protocol import Node, NodeProcessed, isResultNode, Iq, Protocol, JID
from client import PlugIn
from plugin import PlugIn
import base64
import random
import itertools
@ -127,7 +127,7 @@ class SASL(PlugIn):
self.password = password
self.on_sasl = on_sasl
self.realm = None
def plugin(self, owner):
if 'version' not in self._owner.Dispatcher.Stream._document_attrs:
self.startsasl = SASL_UNSUPPORTED
@ -255,8 +255,8 @@ class SASL(PlugIn):
# Openfire)
old_features = self._owner.Dispatcher.Stream.features
self._owner.Dispatcher.PlugOut()
dispatcher_nb.Dispatcher().PlugIn(self._owner, after_SASL=True,
old_features=old_features)
dispatcher_nb.Dispatcher.get_instance().PlugIn(self._owner,
after_SASL=True, old_features=old_features)
self._owner.Dispatcher.restoreHandlers(handlers)
self._owner.User = self.username

View File

@ -1,6 +1,5 @@
''' XML canonicalisation methods (for XEP-0116) '''
# -*- coding:utf-8 -*-
## src/common/stanza_session.py
## c14n.py
##
## Copyright (C) 2007-2008 Brendan Taylor <whateley AT gmail.com>
##
@ -18,6 +17,8 @@
## You should have received a copy of the GNU General Public License
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
''' XML canonicalisation methods (for XEP-0116) '''
from simplexml import ustr
def c14n(node):

View File

@ -1,6 +1,5 @@
## client_nb.py
## based on client.py, changes backported up to revision 1.60
##
## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov
## modified by Dimitur Kirov <dkirov@gmail.com>
@ -21,9 +20,7 @@
Client class establishs connection to XMPP Server and handles authentication
'''
import socket
import transports_nb, dispatcher_nb, auth_nb, roster_nb, protocol, bosh
from protocol import NS_TLS
import logging
@ -185,7 +182,7 @@ class NonBlockingClient:
if proxy['type'] == 'bosh':
# Setup BOSH transport
self.socket = bosh.NonBlockingBOSH(
self.socket = bosh.NonBlockingBOSH.get_instance(
on_disconnect=self.disconnect,
raise_event=self.raise_event,
idlequeue=self.idlequeue,
@ -206,7 +203,7 @@ class NonBlockingClient:
if not proxy or proxy['type'] != 'bosh':
# Setup ordinary TCP transport
self.socket = transports_nb.NonBlockingTCP(
self.socket = transports_nb.NonBlockingTCP.get_instance(
on_disconnect=self.disconnect,
raise_event=self.raise_event,
idlequeue=self.idlequeue,
@ -297,7 +294,7 @@ class NonBlockingClient:
if self.__dict__.has_key('Dispatcher'):
self.Dispatcher.PlugOut()
self.got_features = False
dispatcher_nb.Dispatcher().PlugIn(self)
dispatcher_nb.Dispatcher.get_instance().PlugIn(self)
on_next_receive('RECEIVE_DOCUMENT_ATTRIBUTES')
elif mode == 'FAILURE':
@ -451,13 +448,13 @@ class NonBlockingClient:
def _on_doc_attrs(self):
''' Plug authentication objects and start auth. '''
if self._sasl:
auth_nb.SASL(self._User, self._Password,
auth_nb.SASL.get_instance(self._User, self._Password,
self._on_start_sasl).PlugIn(self)
if not self._sasl or self.SASL.startsasl == 'not-supported':
if not self._Resource:
self._Resource = 'xmpppy'
auth_nb.NonBlockingNonSASL(self._User, self._Password, self._Resource,
self._on_old_auth).PlugIn(self)
auth_nb.NonBlockingNonSASL.get_instance(self._User, self._Password,
self._Resource, self._on_old_auth).PlugIn(self)
return
self.SASL.auth()
return True
@ -479,7 +476,7 @@ class NonBlockingClient:
self.connected = None # FIXME: is this intended?
self._on_sasl_auth(None)
elif self.SASL.startsasl == 'success':
auth_nb.NonBlockingBind().PlugIn(self)
auth_nb.NonBlockingBind.get_instance().PlugIn(self)
self.onreceive(self._on_auth_bind)
return True
@ -495,7 +492,7 @@ class NonBlockingClient:
def initRoster(self):
''' Plug in the roster. '''
if not self.__dict__.has_key('NonBlockingRoster'):
roster_nb.NonBlockingRoster().PlugIn(self)
roster_nb.NonBlockingRoster.get_instance().PlugIn(self)
def getRoster(self, on_ready=None):
''' Return the Roster instance, previously plugging it in and
@ -509,7 +506,7 @@ class NonBlockingClient:
Can also request roster from server if according agrument is set.'''
if requestRoster:
# FIXME: used somewhere?
roster_nb.NonBlockingRoster().PlugIn(self)
roster_nb.NonBlockingRoster.get_instance().PlugIn(self)
self.send(dispatcher_nb.Presence(to=jid, typ=typ))
###############################################################################

View File

@ -22,9 +22,9 @@ different handlers to different XMPP stanzas and namespaces.
import simplexml, sys, locale
from xml.parsers.expat import ExpatError
from client import PlugIn
from protocol import NS_STREAMS, NS_XMPP_STREAMS, NS_HTTP_BIND, Iq, Presence, \
Message, Protocol, Node, Error, ERR_FEATURE_NOT_IMPLEMENTED, StreamError
from plugin import PlugIn
from protocol import (NS_STREAMS, NS_XMPP_STREAMS, NS_HTTP_BIND, Iq, Presence,
Message, Protocol, Node, Error, ERR_FEATURE_NOT_IMPLEMENTED, StreamError)
import logging
log = logging.getLogger('gajim.c.x.dispatcher_nb')
@ -52,6 +52,16 @@ class Dispatcher():
XMPPDispatcher().PlugIn(client_obj)
elif client_obj.protocol_type == 'BOSH':
BOSHDispatcher().PlugIn(client_obj, after_SASL, old_features)
@classmethod
def get_instance(cls, *args, **kwargs):
'''
Factory Method for object creation.
Use this instead of directly initializing the class in order to make
unit testing much easier.
'''
return cls(*args, **kwargs)
class XMPPDispatcher(PlugIn):

View File

@ -1,4 +1,4 @@
## client.py
## plugin.py
##
## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov
##
@ -82,5 +82,16 @@ class PlugIn:
if hasattr(self,'plugout'):
return self.plugout()
del self._owner
@classmethod
def get_instance(cls, *args, **kwargs):
'''
Factory Method for object creation.
Use this instead of directly initializing the class in order to make
unit testing easier. For testing, this method can be patched to inject
mock objects.
'''
return cls(*args, **kwargs)
# vim: se ts=3:

View File

@ -55,6 +55,16 @@ class ProxyConnector:
self.old_on_receive = old_on_receive
self.start_connecting()
@classmethod
def get_instance(cls, *args, **kwargs):
'''
Factory Method for object creation.
Use this instead of directly initializing the class in order to make
unit testing much easier.
'''
return cls(*args, **kwargs)
def start_connecting(self):
raise NotImplementedError

View File

@ -22,7 +22,7 @@ mass-renaming of contacts.
'''
from protocol import JID, Iq, Presence, Node, NodeProcessed, NS_ROSTER
from client import PlugIn
from plugin import PlugIn
import logging
log = logging.getLogger('gajim.c.x.roster_nb')

View File

@ -16,7 +16,7 @@
## GNU General Public License for more details.
import socket
from client import PlugIn
from plugin import PlugIn
import sys
import os

View File

@ -25,7 +25,7 @@ connection handling.
'''
from simplexml import ustr
from client import PlugIn
from plugin import PlugIn
from idlequeue import IdleObject
import proxy_connectors
import tls_nb
@ -74,22 +74,27 @@ DISCONNECT_TIMEOUT_SECONDS = 5
#: size of the buffer which reads data from server
# if lower, more stanzas will be fragmented and processed twice
RECV_BUFSIZE = 32768 # 2x maximum size of ssl packet, should be plenty
#RECV_BUFSIZE = 16 # FIXME: (#2634) gajim breaks with this setting: it's inefficient but should work.
# FIXME: (#2634) gajim breaks with #RECV_BUFSIZE = 16
# it's inefficient but should work. Problem is that connect machine makes wrong
# assumptions and that we only check for pending data in sockets but not in SSL
# buffer...
DATA_RECEIVED='DATA RECEIVED'
DATA_SENT='DATA SENT'
DATA_RECEIVED = 'DATA RECEIVED'
DATA_SENT = 'DATA SENT'
DISCONNECTED = 'DISCONNECTED'
DISCONNECTING = 'DISCONNECTING'
CONNECTING = 'CONNECTING'
PROXY_CONNECTING = 'PROXY_CONNECTING'
CONNECTED = 'CONNECTED'
STATES = [DISCONNECTED, CONNECTING, PROXY_CONNECTING, CONNECTED, DISCONNECTING]
# Transports have different arguments in constructor and same connect() method.
STATES = (DISCONNECTED, CONNECTING, PROXY_CONNECTING, CONNECTED, DISCONNECTING)
class NonBlockingTransport(PlugIn):
'''
Abstract class representing a transport.
Subclasses CAN have different constructor signature but connect method SHOULD
be the same.
'''
def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls,
certs):
@ -322,15 +327,14 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
proxyclass = proxy_connectors.SOCKS5Connector
elif self.proxy_dict['type'] == 'http' :
proxyclass = proxy_connectors.HTTPCONNECTConnector
proxyclass(
send_method = self.send,
onreceive = self.onreceive,
old_on_receive = self.on_receive,
on_success = self._on_connect,
on_failure = self._on_connect_failure,
xmpp_server = self.proxy_dict['xmpp_server'],
proxy_creds = self.proxy_dict['credentials']
)
proxyclass.get_instance(
send_method=self.send,
onreceive=self.onreceive,
old_on_receive=self.on_receive,
on_success=self._on_connect,
on_failure=self._on_connect_failure,
xmpp_server=self.proxy_dict['xmpp_server'],
proxy_creds=self.proxy_dict['credentials'])
def _on_connect(self):
'''
@ -351,7 +355,7 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
NonBlockingTLS module
'''
cacerts, mycerts = self.certs
result = tls_nb.NonBlockingTLS(cacerts, mycerts).PlugIn(self)
result = tls_nb.NonBlockingTLS.get_instance(cacerts, mycerts).PlugIn(self)
if result:
on_succ()
else:

View File

@ -21,7 +21,7 @@ from common import gajim
import common.xmpp
from common.xmpp.idlequeue import IdleObject
from common.xmpp import dispatcher_nb, simplexml
from common.xmpp.client import *
from common.xmpp.plugin import *
from common.xmpp.simplexml import ustr
from common.xmpp.transports_nb import DATA_RECEIVED, DATA_SENT
from common.zeroconf import zeroconf