SF.net SVN: fclient: [111] trunk/sandbox/fcp/fcp2_0_client.py
Status: Pre-Alpha
Brought to you by:
jurner
|
From: <ju...@us...> - 2008-02-02 11:26:27
|
Revision: 111
http://fclient.svn.sourceforge.net/fclient/?rev=111&view=rev
Author: jurner
Date: 2008-02-02 03:26:28 -0800 (Sat, 02 Feb 2008)
Log Message:
-----------
bit of this and that
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_client.py
Modified: trunk/sandbox/fcp/fcp2_0_client.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_client.py 2008-02-02 11:25:23 UTC (rev 110)
+++ trunk/sandbox/fcp/fcp2_0_client.py 2008-02-02 11:26:28 UTC (rev 111)
@@ -1,6 +1,6 @@
"""Freenet client protocol 2.0 implementation
-Compatibility: >= Freenet 0.7 Build #1084
+Compatibility: >= Freenet 0.7 Build #1107
@newfield event: event, events
@@ -102,7 +102,7 @@
hack = SysPathHack(3)
-from fcp_lib import events, namespace, uuid
+from fcp_lib import events, namespace
del hack
@@ -242,6 +242,8 @@
# others
'KeypairGenerated',
+ 'USKUpdated',
+
###############################
'ProtocolError',
@@ -305,9 +307,6 @@
'FcErrorMessage': None, # did an error occur?
'FcUserData': userData, # any user defined runtime data here
- # params for AllData
- 'FcData': '', # if data was requested via requestData you will find it here
-
# params for SSKKeypair
'FcInsertUri': None,
'FcRequestUri': None,
@@ -352,7 +351,7 @@
@return: (str) uuid
@note: the identifier returned is unique to the client but may not be unique to the node
"""
- identifier = self.FcParams.newUuid()
+ identifier = self.FcParams.newUuid(uuids=self._requests)
# add additional params to msg
msg = self._addFcParamsToRequest(
@@ -419,10 +418,13 @@
saveRemoveFile(initialRequest['FcTestDDA']['TmpFile'])
self._ddaTests = []
- self._requests = {}
self._sskRequests = []
+ self._requests = {}
+
+ def closeFreenet(self):
+ """Shuts down the freenet node"""
+ self.sendMessage(consts.Message.Shutdown)
-
def connect(self, host=DefaultFcpHost, port=DefaultFcpPort, duration=20, timeout=0.5):
"""Iterator to stablish a connection to a freenet node
@param host: (str) host of th node
@@ -520,7 +522,7 @@
@param connectionName: (str) connection name or None to use an arbitrary connection name
@return: (str) connection name
"""
- self._connectionName = uuid.uuid_time() if connectionName is None else connectionName
+ self._connectionName = self.FcParams.newUuid() if connectionName is None else connectionName
return self._connectionName
@@ -578,6 +580,9 @@
# check if we have an initial request corrosponding to msg
requestIdentifier = msg.get('Identifier', None)
initialRequest = None if requestIdentifier is None else self._requests.get(requestIdentifier, None)
+
+
+
####################################################
##
## errors
@@ -614,9 +619,9 @@
raise consts.ProtocolError(msg)
if initialRequest is None:
- #TODO: check how to handle this
- raise consts.ProtocolError(msg)
+ return False
+
# handle DDA errors
elif code == consts.ProtocolError.DDADenied:
ddaRequestMsg = self.Message(consts.Message.TestDDARequest)
@@ -684,9 +689,8 @@
del self._requests[requestIdentifier]
self.events.PluginMessageFailed(initialRequest)
return True
-
-
+
# only requests should get through to here
# NOTE: Fcp already removed the request
@@ -810,7 +814,7 @@
if initialRequest is None:
return False
- initialRequest['FcData'] = msg.data
+ initialRequest.data = msg.data
self.events.RequestCompleted(initialRequest)
return True
@@ -819,11 +823,12 @@
if initialRequest is None:
# something is going wrong
return False
-
+
initialRequest['FcStatus'] = consts.MessageStatus.Complete
initialRequest['FcMetadataContentType'] = msg.get('Metadata.ContentType', '')
initialRequest['FcDataLength'] = msg.get('DataLength', '')
- self.events.RequestCompleted(initialRequest)
+ if initialRequest['FcSubType'] != consts.MessageSubType.GetData:
+ self.events.RequestCompleted(initialRequest)
return True
@@ -1052,7 +1057,7 @@
if initialRequest is None:
return False
- del self._requests[requestIdentifier]
+ self._pluginRequests[requestIdentifier]
self.events.PluginInfo(msg)
return True
@@ -1069,6 +1074,15 @@
## others
##
####################################################
+ elif msg.name == consts.Message.CloseConnectionDuplicateClientName:
+ msg = self.Message(
+ consts.Message.ClientDisconnected,
+ DisconnectReason=DisconnectReason.DuplicateClientName,
+ )
+ self.events.ClientDisconnect(msg)
+ return True
+
+
elif msg.name == consts.Message.SSKKeypair:
if requestIdentifier not in self._sskRequests:
return False
@@ -1088,13 +1102,11 @@
self.events.KeypairGenerated(msg)
return True
-
- elif msg.name == consts.Message.CloseConnectionDuplicateClientName:
- msg = self.Message(
- consts.Message.ClientDisconnected,
- DisconnectReason=DisconnectReason.DuplicateClientName,
- )
- self.events.ClientDisconnect(msg)
+ elif msg.name == consts.Message.SubscribedUSKUpdate:
+ if initialRequest is None:
+ return False
+
+ self.events.USKUpdated(msg)
return True
@@ -1105,7 +1117,6 @@
def next(self, dispatch=True):
"""Pumps the next message waiting
@param dispatch: if True the message is dispatched to L{handleMessage}
- @note: use this method instead of run() to run the client step by step
"""
msg = self.Message.fromSocket(self._socket)
if msg.name == consts.Message.ClientSocketDied:
@@ -1133,6 +1144,9 @@
@raise SocketError: if the socket connection to the node dies unexpectedly
If an error handler is passed to the client it is called emidiately before the error
is raised.
+
+ @note: you can use this method to send a message to the node, bypassing all
+ track keeping methods of the client
"""
return self.sendMessageEx(self.Message(name, data=data, **params))
@@ -1144,6 +1158,9 @@
@raise SocketError: if the socket connection to the node dies unexpectedly.
If an error handler is passed to the client it is called emidiately before the error
is raised.
+
+ @note: you can use this method to send a message to the node, bypassing all
+ track keeping methods of the client
"""
self._log.debug(consts.LogMessages.MessageSend + msg.pprint())
try:
@@ -1416,6 +1433,25 @@
)
+
+ #TODO: persists until connection is closed... can this request be removed?
+ # Anyway. It is not listed in consts.Message.ClientRequestMessages,
+ # so any attempts will fail (wink)
+ def subscribeUSK(self, uri, dontPoll=True):
+ """Asks the node to notify the client when an USK is updated
+ @param uri: uri of the USK to subscribe to
+ @param dontPoll: if True, whatever ???
+ @return: (str) identifer of the request
+ """
+ identifier = self.FcParams.newUuid(uuids=self._requests)
+ self.sendMessage(
+ consts.Message.SubscribeUSK,
+ Identifier=identifier,
+ URI=uri,
+ DontPoll=dontPoll,
+ )
+ return identifier
+
########################################################
##
## ClientPut related methods
@@ -1585,9 +1621,14 @@
@param persistentUserData: (str) persistent user data or None
@param priorityClass: (L{consts.Priority}) new priority or None
+ @note: you can use this method to modify requests as listed in L{consts.Message.ClientRequestMessages}.
+ All attempts to modify other requests will fail
@note: a RequestModified event is triggered as soon as the request has actually been modified
"""
initialRequest = self._requests[requestIdentifier]
+ if initialRequest.name not in consts.Message.ClientRequestMessages:
+ raise ValueError('Can not modify request: %s' % initialRequest.name)
+
msg = self.Message(
consts.Message.ModifyPersistentRequest,
Identifier=initialRequest['Identifier'],
@@ -1598,6 +1639,7 @@
msg['ClientToken'] = self.FcParams.messageToParams(initialRequest)
if priorityClass is not None:
msg['PriorityClass'] = priorityClass
+
self.sendMessageEx(msg)
@@ -1605,21 +1647,54 @@
"""Removes a request
@param requestIdentifier: (str) identifier of the request to remove
- @note: a RequestRemoved event is triggered as soon as the request has actually been removed
+ @note: you can use this method to remove requests as listed in L{consts.Message.ClientRequestMessages}
+ or L{consts.Message.ClientPluginMessages}. All attempts to remove other requests will fail
+ @note: if the request is one the requests listed in L{consts.Message.ClientRequestMessages}
+ a RequestRemoved event is triggered as soon as the request has actually been removed
"""
initialRequest = self._requests[requestIdentifier]
- initialRequest['FcStatus'] = consts.MessageStatus.Removed
- self.sendMessage(
- consts.Message.RemovePersistentRequest,
- Global=False,
- Identifier=requestIdentifier,
- )
+ if initialRequest.name in consts.Message.ClientRequestMessages:
+ initialRequest['FcStatus'] = consts.MessageStatus.Removed
+ self.sendMessage(
+ consts.Message.RemovePersistentRequest,
+ Global=False,
+ Identifier=requestIdentifier,
+ )
+ else:
+ del self._requests[requestIdentifier]
- #TODO: check how Fcp responds when the identifier is unknwon or something else goes
+ #TODO: check how Fcp responds when the identifier is unknown or something else goes
# werong. Maybe a ProtocolError.NoSuchIdentifier ???
-
-
+
+ def resendRequest(self, requestMessage):
+ """Resends a request
+ @param requestMessage: (L{fcp2_0_message.Message})
+ @return: (str) request identifier
+
+ @note: you can use this method to resend requests as listed in L{consts.Message.ClientRequestMessages}
+ or L{consts.Message.ClientPluginMessages}. All attempts to resend other requests will fail
+ @note: the request passed is not removed in the call. Use L{removeRequest} if necessary
+ """
+ if requestMessage.name in consts.Message.ClientRequestMessages:
+ self._registerRequest(
+ requestMessage,
+ requestMessage['FcUserData'],
+ requestMessage['FcMessageSubType'],
+ time.time(), # TOSO: reset init time?
+ requestMessage['FcPersistentUserData'],
+ requestMessage['FcFilenameCollision=filenameCollision'],
+ )
+ elif requestMessage.name in consts.Message.ClientPluginMessages:
+ identifier = self.FcParam.newUuid(uuids=self._requests)
+ initialRequest['Identifier'] = identifier
+ self._requests[identifier] = initialRequest
+ else:
+ raise ValueError('Can not resend request: %s' % requestMessage.name)
+
+ self.sendMessageEx(msg)
+ return requestMessage['Identifier']
+
########################################################
##
## Peer related methods
@@ -1730,17 +1805,15 @@
## plugins
##
##########################################################
- #TODO: curently it is just a guess the a plugin may respond with a IdentifierCollision
+ #TODO: curently it is just a guess the a plugin may respond with a IdentifierCollision. To make
+ # shure we register plugin related stuff as request
def getPluginInfo(self, pluginName, detailed=False):
"""Requests information about a plugin
@param pluginName: (str) name of the plugin to request info for
@param detailed: (bool) If True, detailed information is returned
@return: (str) request identifier
"""
- while True:
- identifier = uuid.uuid_time()
- if identifier not in self._requests:
- break
+ identifier = self.FcParam.newUuid(uuids=self._requests)
msg = self.Message(
consts.Message.GetPluginInfo,
Identifier=identifier,
@@ -1759,10 +1832,7 @@
@param data: (str) data to pass along with the messaage or None
@return: (str) request identifier
"""
- while True:
- identifier = uuid.uuid_time()
- if identifier not in self._requests:
- break
+ identifier = self.FcParam.newUuid(uuids=self._requests)
msg = self.Message(
consts.Message.GetPluginInfo,
Identifier=identifier,
@@ -1795,10 +1865,7 @@
if keypairType not in (consts.KeyType.SSK, consts.KeyType.USK):
raise ValueError('keypairType must be %s or %s' % (consts.KeyType.SSK, consts.KeyType.USK))
- while True:
- identifier = keypairType + uuid.uuid_time()
- if identifier not in self._sskRequests:
- break
+ identifier = keypairType + self.FcParams.newUuid(self._sskRequests)
self._sskRequests.append(identifier)
self.sendMessage(
consts.Message.GenerateSSK,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|