Thread: SF.net SVN: fclient: [25] trunk/fclient
Status: Pre-Alpha
Brought to you by:
jurner
From: <jU...@us...> - 2007-11-01 14:53:12
|
Revision: 25 http://fclient.svn.sourceforge.net/fclient/?rev=25&view=rev Author: jUrner Date: 2007-11-01 07:53:13 -0700 (Thu, 01 Nov 2007) Log Message: ----------- implemented a basic widget to play around with peers Added Paths: ----------- trunk/fclient/fclient_widgets/ trunk/fclient/fclient_widgets/__init__.py trunk/fclient/fclient_widgets/peer_widget.py Added: trunk/fclient/fclient_widgets/__init__.py =================================================================== --- trunk/fclient/fclient_widgets/__init__.py (rev 0) +++ trunk/fclient/fclient_widgets/__init__.py 2007-11-01 14:53:13 UTC (rev 25) @@ -0,0 +1 @@ + Added: trunk/fclient/fclient_widgets/peer_widget.py =================================================================== --- trunk/fclient/fclient_widgets/peer_widget.py (rev 0) +++ trunk/fclient/fclient_widgets/peer_widget.py 2007-11-01 14:53:13 UTC (rev 25) @@ -0,0 +1,211 @@ +"""Sketch for a widget handling node peers + +""" + +import os, sys + +#--> rel import hack +def parentdir(n, fpath): + fpath = os.path.abspath(fpath) + for i in xrange(n): + fpath = os.path.dirname(fpath) + return fpath +sys.path.insert(0, parentdir(2, __file__)) + + +import config +from fclient_lib import fcp +from fclient_lib.pyex import numbers + + +sys.path.pop(0) +del parentdir +#<-- rel import hack + + +import time +from PyQt4 import QtCore, QtGui +#*************************************************************************************************** +# +#*************************************************************************************************** +class PeerWidget(QtGui.QTreeWidget): + + HeaderIndexStatus = 0 + HeaderIndexName = 1 + HeaderIndexLastConnected = 2 + HeaderIndexNotes = 3 + + + def __init__(self, parent, cfg=None): + + self._cfg = cfg + self._fcpClient = None + self._fcpEvents = None + self._isCreated = False + self._peers = {} # identity --> item + + QtGui.QWidget.__init__(self, parent) + + # setup config + if self._cfg is None: + self._cfg = config.Config(self) + + # setup tree + self.setUniformRowHeights(True) + headerLabels = [ + self.trUtf8('Status'), + self.trUtf8('Name'), + self.trUtf8('LastConnected'), + self.trUtf8('Notes'), + ] + self.setHeaderLabels(headerLabels) + #self.setRootIsDecorated(False) + self.setColumnCount(len(headerLabels)) + + header = self.header() + header.setResizeMode(header.ResizeToContents) + header.setStretchLastSection(True) + + + + def showEvent(self, event): + if not self._isCreated: + self._isCreated = True + self._cfg.connectFcpNode(self.handleClientConnected) + + + def handleClientConnected(self, event, params): + self._fcpEvents = ( + #(self._cfg.fcpClient.EventClientConnected, self.handleClientConnected), + (self._cfg.fcpClient.EventClientDisconnected, self.handleClientDisconnected), + + (self._cfg.fcpClient.EventPeer, self.handlePeer), + (self._cfg.fcpClient.EventEndListPeers, self.handleEndListPeers), + (self._cfg.fcpClient.EventPeerRemoved, self.handlePeerRemoved), + (self._cfg.fcpClient.EventUnknownNodeIdentifier, self.handleUnknownNodeIdentifier), + ) + + # take care to not connect twice + for event, observer in self._fcpEvents: + if not observer in event: + event += observer + + self.clear() + self._peers = {} + self._cfg.fcpClient.listPeers() + + + + def handleClientDisconnected(self, event, params): + pass + + + def handlePeer(self, event, params): + + timeLastConnected = params.get('metadata.timeLastConnected', None) + timeLastConnected = self.timeToTimeDelta(timeLastConnected) + + identity = params['identity'] + item = self._peers.get(identity, None) + # add item if necessary + if item is None: + itemStrings = [ + params.get('volatile.status', ''), + params.get('myName', ''), + timeLastConnected, + '' + ] + item = QtGui.QTreeWidgetItem(self, itemStrings) + item.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(identity)) + self._peers[identity] = item + + # update item + else: + item.settext(self.HeaderIndexLastConnected, timeLastConnected) + + + + def handleEndListPeers(self, event, params): + pass + + + + def handlePeerRemoved(self, peer): + pass + + + def handleUnknownNodeIdentifier(self, params): + pass + + + + def timeToTimeDelta(self, t): + try: + t = self._cfg.fcpClient.pythonTime(t) + except: + t = self.trUtf8('Unknown') + else: + if t == 0: + t = self.trUtf8('Never') + else: + t = numbers.format_time_delta(t, time.time()) + return t + + + + def identityFromItem(self, item): + v = item.data(0, QtCore.Qt.UserRole) + return str(v.toString()) + + + +'''######################################################## +Sample Peer message +>> Peer +>> lastGoodVersion=Fred,0.7,1.0,1069 +>> myName=Ismael +>> auth.negTypes=1;2 +>> volatile.routingBackoffLength=1000 +>> physical.udp=91.3.73.112:8904;91.3.60.151:8904 +>> metadata.timeLastRoutable=1192973814473 +>> metadata.routableConnectionCheckCount=37063 +>> volatile.totalBytesIn=0 +>> metadata.detected.udp=91.3.118.59:8904 +>> version=Fred,0.7,1.0,1070 +>> location=0.6583927959165321 +>> volatile.percentTimeRoutableConnection=6.111216037557672 +>> volatile.averagePingTime=1.0 +>> volatile.overloadProbability=0.0 +>> volatile.idle=953190074 +>> volatile.routingBackoff=0 +>> opennet=false +>> metadata.timeLastReceivedPacket=1192973814459 +>> metadata.hadRoutableConnectionCount=2265 +>> volatile.status=DISCONNECTED +>> volatile.totalBytesOut=571619 +>> ark.number=28 +>> identity=VFe6SIPloo42YOs8woDvPtnboEl2i1qMR~1vQx5tPwI +>> dsaGroup.q=ALFDNoq81R9Y1kQNVBc5kzmk0VvvCWosXY5t9E9S1tN5 +>> dsaGroup.p=AIYIrE9VNhM38qPjirGGT-PJjWZBHY0q-JxSYyDFQfZQeOhrx4SUpdc~SppnWD~UHymT7WyX28eV3YjwkVyc~--H5Tc83hPjx8qQc7kQbrMb~CJy7QBX~YSocKGfioO-pwfRZEDDguYtOJBHPqeenVDErGsfHTCxDDKgL2hYM8Ynj8Kes0OcUzOIVhShFSGbOAjJKjeg82XNXmG1hhdh2tnv8M4jJQ9ViEj425Mrh6O9jXovfPmcdYIr3C~3waHXjQvPgUiK4N5Saf~FOri48fK-PmwFZFc-YSgI9o2-70nVybSnBXlM96QkzU6x4CYFUuZ7-B~je0ofeLdX7xhehuk +>> dsaPubKey.y=dmlrTkJrXzfi17AVinCIV9rJKQa9FkFV8ZjzJ~lyuEtWl8b7S-RqMocZEbtjDAWVV79yxCBD-dpmbz0X7EbnCUlDhlO-2kqo3eqDwMNf3CjU6qbSBmvzp2BkNYXt1EO6VYNVojbVyxv1mX~IGcXREXJrvIdxj64cJiESKZglJX0Rv2owCFvZBGCslEgqENPbKXT8QqIGkYUiSrDWGM-CVnHkjeBfZjIAvmcjTMMeADV6kyZ7yshG-pmxABL6Z2IAr69bM9VZ26acSV55TCZbuKdsVgC6B7G8ucm9WdKC2~tEdBns-0RZMfh4eOH969MTRXojLR5RpzbNFr-OeNRAvQ +>> volatile.routingBackoffPercent=0.0 +>> metadata.timeLastConnected=1192973814473 +>> testnet=false +>> dsaGroup.g=UaRatnDByf0QvTlaaAXTMzn1Z15LDTXe-J~gOqXCv0zpz83CVngSkb--bVRuZ9R65OFg~ATKcuw8VJJwn1~A9p5jRt2NPj2EM7bu72O85-mFdBhcav8WHJtTbXb4cxNzZaQkbPQUv~gEnuEeMTc80KZVjilQ7wlTIM6GIY~ZJVHMKSIkEU87YBRtIt1R~BJcnaDAKBJv~oXv1PS-6iwQRFMynMEmipfpqDXBTkqaQ8ahiGWA41rY8d4jDhrzIgjvkzfxkkcCpFFOldwW8w8MEecUoRLuhKnY1sm8nnTjNlYLtc1Okeq-ba0mvwygSAf4wxovwY6n1Fuqt8yZe1PDVg +>> ark.pubURI=SSK@1VhLypie-suqO-7MrMEK7YZLvTHkXstKqhq3noy-PY4,RROa7KmxsjivsNKHIlEy9kHmM6VyVJ0lLRbcdwTQRK4,AQACAAE/ark +>>EndMessage +###########################################################''' + +#*************************************************************************************************** +# +#*************************************************************************************************** +if __name__ == '__main__': + import sys + + app = QtGui.QApplication(sys.argv) + w = PeerWidget(None) + w.show() + res = app.exec_() + sys.exit(res) + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
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. |
From: <jU...@us...> - 2007-11-04 17:33:30
|
Revision: 44 http://fclient.svn.sourceforge.net/fclient/?rev=44&view=rev Author: jUrner Date: 2007-11-04 09:33:33 -0800 (Sun, 04 Nov 2007) Log Message: ----------- bit of renaming Modified Paths: -------------- trunk/fclient/fclient_ui/fcp_client_manager.py trunk/fclient/fclient_widgets/peer_widget.py Modified: trunk/fclient/fclient_ui/fcp_client_manager.py =================================================================== --- trunk/fclient/fclient_ui/fcp_client_manager.py 2007-11-04 17:31:30 UTC (rev 43) +++ trunk/fclient/fclient_ui/fcp_client_manager.py 2007-11-04 17:33:33 UTC (rev 44) @@ -109,7 +109,7 @@ self.priorities = Priorities(self) - def stopFcpClient(self, name): #TODO: name of client or client??? + def stopClient(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() @@ -118,7 +118,7 @@ handler.stop() - def newFcpClient(self, + def newClient(self, name, eventConnectedHandler, connectPriority=None, Modified: trunk/fclient/fclient_widgets/peer_widget.py =================================================================== --- trunk/fclient/fclient_widgets/peer_widget.py 2007-11-04 17:31:30 UTC (rev 43) +++ trunk/fclient/fclient_widgets/peer_widget.py 2007-11-04 17:33:33 UTC (rev 44) @@ -112,7 +112,7 @@ """ if not self._isCreated: self._isCreated = True - self._fcpClient = self._cfg.fcpClientManager.newFcpClient('MeName', self.handleClientConnected) + self._fcpClient = self._cfg.fcpClientManager.newClient('MeName', self.handleClientConnected) ############################################################# ## This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |