SF.net SVN: fclient: [40] trunk/fclient
Status: Pre-Alpha
Brought to you by:
jurner
|
From: <jU...@us...> - 2007-11-04 17:28:44
|
Revision: 40
http://fclient.svn.sourceforge.net/fclient/?rev=40&view=rev
Author: jUrner
Date: 2007-11-04 09:28:46 -0800 (Sun, 04 Nov 2007)
Log Message:
-----------
added support to handle multiple clients
Added Paths:
-----------
trunk/fclient/fclient_ui/
trunk/fclient/fclient_ui/__init__.py
trunk/fclient/fclient_ui/fcp_client_manager.py
Added: trunk/fclient/fclient_ui/__init__.py
===================================================================
--- trunk/fclient/fclient_ui/__init__.py (rev 0)
+++ trunk/fclient/fclient_ui/__init__.py 2007-11-04 17:28:46 UTC (rev 40)
@@ -0,0 +1 @@
+
Added: trunk/fclient/fclient_ui/fcp_client_manager.py
===================================================================
--- trunk/fclient/fclient_ui/fcp_client_manager.py (rev 0)
+++ trunk/fclient/fclient_ui/fcp_client_manager.py 2007-11-04 17:28:46 UTC (rev 40)
@@ -0,0 +1,299 @@
+
+
+from PyQt4 import QtCore
+#**************************************************************************************
+#
+#**************************************************************************************
+class Priority(object):
+ """Priority"""
+ __slots__ = ('name', 'value')
+
+
+ def __init__(self, name, value):
+ """
+ @param name: (str) name of the priority
+ @param value: (int) value of the priority
+ """
+ self.name = name
+ self.value = value
+ def __int__(self): return self.value
+ def __long__(self): return self.__int__()
+
+#**************************************************************************************
+#
+#**************************************************************************************
+class Priorities(QtCore.QObject):
+ """Class handling poll priorities
+
+ >>> p = Priorities(None)
+ >>> priority = p['Highest']
+ >>> priority.name
+ 'Highest'
+ >>> int(priority)
+ 0
+
+ >>> p['Highest'] = 33
+ >>> int(priority)
+ 33
+
+ >>> for translatedName, priority in p.listPriorityNames(): priority.name
+ 'Highest'
+ 'High'
+ 'Normal'
+ 'Low'
+ 'Lowest'
+ """
+
+ # cheat a bit to get dynamic translation working
+ def trUtf8(self, what): return what
+
+
+ def __init__(self, parent):
+ """
+ @param parent: (QObject) parent or None
+ @note: supported priorities are: 'Highest', 'High', 'Normal', 'Low', 'Lowest'
+ """
+ QtCore.QObject.__init__(self, parent)
+
+ self._values = (
+ Priority(self.trUtf8('Highest'), 0),
+ Priority(self.trUtf8('High'), 100),
+ Priority(self.trUtf8('Normal'), 300),
+ Priority(self.trUtf8('Low'), 600),
+ Priority(self.trUtf8('Lowest'), 1000),
+ )
+ self._valuesDict = {}
+ for priority in self._values:
+ self._valuesDict[priority.name] = priority
+
+
+ def __getitem__(self, name):
+ """Returns the a priority given its name"""
+ return self._valuesDict[name]
+
+
+ def __setitem__(self, name, value):
+ """Sets the value of a priority
+ @param name: (str) name of the priority
+ @param value: (int) value in milisecomds
+ """
+ self._valuesDict[name].value = value
+
+
+ def listPriorityNames(self):
+ """Returns a list containing all priorities
+ @return: (list) [(QString) translatedName, (Priority) priority]
+ """
+ out = []
+ for priority in self._values:
+ out.append( (QtCore.QObject.trUtf8(self, priority.name), priority) )
+ return out
+
+#*****************************************************************************
+#
+#*****************************************************************************
+class FcpClientManager(QtCore.QObject):
+ """Manager to handle multiple Fcp clients
+ """
+
+
+ def __init__(self, parent):
+ """
+ @param parent: (QObject) parent or None
+ @ivar fcpClients: dict mapping connection names to FcpClients
+ @ivar priorities: L{Priorities} the manager supports
+ """
+ QtCore.QObject.__init__(self, parent)
+
+ self.fcpClients = {}
+ self.priorities = Priorities(self)
+
+
+ def stopFcpClient(self, name): #TODO: name of client or client???
+ """Stops a FcpClient
+ @name: (str) connection name of the client to stop
+ @note: the client is not closed in the call. To close the connection call FcpClient.close()
+ """
+ handler = self.fcpClients.pop(name)
+ handler.stop()
+
+
+ def newFcpClient(self,
+ name,
+ eventConnectedHandler,
+ connectPriority=None,
+ pollPriority=None,
+ ):
+ """Creates a new Fcp client
+ @param name: (str) unique connection name
+ @param eventConnectedHandler: method that handles FcpClient.EventConnected
+ @param connectPriority: (L{Priority}) priority when establishing node connection
+ @param pollPriority: (L{Priority}) runtime priority
+ @return: (FcpClient) instance
+
+ @note: the eventConnectedHandler handler passed is automatically connected
+ to FcpClient.EventConnected. No need to connect to receive events.
+ """
+ if name in self.fcpClients:
+ raise ValueError('Fcp client already exists: %r' % name)
+
+ # some magic here to determine the client version to use
+ from fclient_lib.fcp.fcp2_0 import FcpClient
+ fcpClient = FcpClient(
+ connectionName=name,
+ #verbosity=FcpClient.Verbosity.Debug,
+ )
+ fcpClient.events.ClientConnected += eventConnectedHandler
+ handler = FcpClientHandler(
+ fcpClient,
+ self.handleFcpClientDisconnected,
+ connectPriority if connectPriority is not None else self.priorities['Normal'],
+ pollPriority if pollPriority is not None else self.priorities['Normal'],
+ )
+ self.fcpClients[name] = handler
+ fcpClient.events.ClientDisconnected += handler.handleFcpClientDisconnected
+ handler.connect()
+ return fcpClient
+
+
+ def setPriority(self, name, connectPriority=None, pollPriority=None):
+ """Sets priorities of a FcpClient
+ @param connectPriority: (L{Priority}) priority when establishing node connection
+ @param pollPriority: (L{Priority}) runtime priority
+ """
+ handler = self.fcpClients[name]
+ if connectPriority is not None:
+ handler.setConnectPriority(connectPriority)
+ if pollPriority is not None:
+ handler.setPollPriority(pollPriority)
+
+
+ def handleFcpClientDisconnected(self, handler, params):
+ """Handles FcpClient.EventDisconnect"""
+
+ disconnectReason = params['DisconnectReason']
+ fcpClient = handler.fcpClient
+
+ # see how to handle the cases
+ if disconnectReason == fcpClient.DisconnectReason.Shutdown:
+ handler.stop()
+
+ elif disconnectReason == fcpClient.DisconnectReason.SocketDied:
+ # 1. wait some time, cos more alerts may come in
+ # 2. inform user
+ # 3. reconnect if desired
+ pass
+
+ elif disconnectReason == fcpClient.DisconnectReason.ConnectFailed:
+ # 1. wait some time, cos more alerts may come in
+ # 2. inform user
+ # 3. reconnect if desired
+ pass
+
+ else:
+ raise ValueError('Unknown disconnect reason: %r' % disconnectReason)
+
+
+
+#**************************************************************************************
+#
+#**************************************************************************************
+class FcpClientHandler(object):
+ """Handles one single FcpClient
+ """
+
+
+ def __init__(self, fcpClient, handleFcpClientDisconnected, connectPriority, pollPriority):
+ """
+ @param fcpClient: FcpClient to handle
+ @param handleFcpClientDisconnected: handler to call when the client disconnects
+ @param connectPriority: (L{Priority}) priority when establishing node connection
+ @param pollPriority: (L{Priority}) runtime priority
+ """
+ self.fcpClient = fcpClient
+ self.handleFcpClientDisconnected = handleFcpClientDisconnected
+ self.connectMethod = fcpClient.connect()
+
+ self.connectPriority = connectPriority
+ self.pollPriority = pollPriority
+
+ self.connectTimer = QtCore.QTimer()
+ QtCore.QObject.connect(
+ self.connectTimer,
+ QtCore.SIGNAL('timeout()'),
+ self.handleConnect
+ )
+
+ self.pollTimer = QtCore.QTimer()
+ QtCore.QObject.connect(
+ self.pollTimer,
+ QtCore.SIGNAL('timeout()'),
+ self.fcpClient.next
+ )
+
+
+ def connect(self):
+ """Establishes the connection from the client to the node"""
+ self.stop()
+ self.connectTimer.start(int(self.connectPriority))
+
+
+ def start(self):
+ """Starts polling the FcpClient"""
+ self.pollTimer.start(int(self.pollPriority))
+
+
+ def stop(self):
+ """Stops polling the FcpClient"""
+ self.connectTimer.stop()
+ self.pollTimer.stop()
+
+
+ def setPollPriority(self, priority):
+ """Adjusts the poll priority of the FcpClient
+ @param priority: L{Priority}
+ """
+ isActive = self.pollTimer.isActive()
+ self.pollTimer.stop()
+ if isActive:
+ self.pollTimer.start(int(priority))
+ self.pollPriority = priority
+
+
+ def setConnectPriority(self, priority):
+ """Adjusts the priority wich is used to establish a connection to the node
+ @param priority: L{Priority}
+ """
+ isActive = self.connectTimer.isActive()
+ self.connectTimer.stop()
+ if isActive:
+ self.connectTimer.start(int(priority))
+ self.connectPriority = priority
+
+
+ def handleFcpClientDisconnected(self, params):
+ """Handles FcpClient.EventDisconnect"""
+ self.stop()
+ self.handleFcpClientDisconnected(self, params)
+
+
+ def handleConnect(self):
+ """Handles establishing of the node connection"""
+ self.connectTimer.stop()
+ try:
+ result = self.connectMethod.next()
+ if result is not None:
+ self.nodeHello = result
+ self.pollTimer.start(int(self.pollPriority))
+ return
+ except StopIteration:
+ return
+ self.connectTimer.start(int(self.connectPriority))
+
+#******************************************************************************************
+#
+#******************************************************************************************
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|