fclient-commit Mailing List for fclient (Page 35)
Status: Pre-Alpha
Brought to you by:
jurner
You can subscribe to this list here.
| 2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(23) |
Nov
(54) |
Dec
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2008 |
Jan
(17) |
Feb
(209) |
Mar
(63) |
Apr
(31) |
May
(7) |
Jun
(39) |
Jul
(390) |
Aug
(122) |
Sep
(6) |
Oct
|
Nov
|
Dec
|
|
From: <ju...@us...> - 2008-02-02 11:26:40
|
Revision: 112
http://fclient.svn.sourceforge.net/fclient/?rev=112&view=rev
Author: jurner
Date: 2008-02-02 03:26:43 -0800 (Sat, 02 Feb 2008)
Log Message:
-----------
bit of this and that
Modified Paths:
--------------
trunk/sandbox/fcp/fcp_2_0_requests.py
Modified: trunk/sandbox/fcp/fcp_2_0_requests.py
===================================================================
--- trunk/sandbox/fcp/fcp_2_0_requests.py 2008-02-02 11:26:28 UTC (rev 111)
+++ trunk/sandbox/fcp/fcp_2_0_requests.py 2008-02-02 11:26:43 UTC (rev 112)
@@ -57,8 +57,6 @@
self._targetNames = [] # record to check if names are unique (assert order is arbitrary)
-
-
def _addItem(self, **params):
"""Private method to add an upload item"""
if self._directoryAdded:
@@ -93,6 +91,7 @@
UploadFrom=self.UploadFrom.Direct
)
+
def addDirectory(name, directory, allowUnreadableFiles=False):
"""Adds a directory to be uploaded
@param name: target name
@@ -107,6 +106,7 @@
Name=name,
)
+
def addFile(self, name, filename, contentType=None):
"""Adds a file to be uploaded
@param name: target name
@@ -121,6 +121,7 @@
UploadFrom=self.UploadFrom.Disk,
)
+
def addRedirect(self, name, redirect):
"""Adds a redirect to be uploaded
@param name: target name
@@ -135,6 +136,7 @@
UploadFrom=self.UploadFrom.Redirect
)
+
def getMessage(self, messageClass):
"""Returns the message for the request, ready to send the request to the node
@param messageClass: (L{fcp2_0_message.Message}) class to fill in
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
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.
|
|
From: <ju...@us...> - 2008-02-02 11:25:21
|
Revision: 110
http://fclient.svn.sourceforge.net/fclient/?rev=110&view=rev
Author: jurner
Date: 2008-02-02 03:25:23 -0800 (Sat, 02 Feb 2008)
Log Message:
-----------
refactor
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_consts.py
Modified: trunk/sandbox/fcp/fcp2_0_consts.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_consts.py 2008-02-02 11:24:50 UTC (rev 109)
+++ trunk/sandbox/fcp/fcp2_0_consts.py 2008-02-02 11:25:23 UTC (rev 110)
@@ -208,76 +208,89 @@
class Message:
"""Fcp messages"""
- # client s
+ # client --> node
+ AddPeer = 'AddPeer'
ClientHello = 'ClientHello'
+ ClientGet = 'ClientGet'
+ ClientPut = 'ClientPut'
+ ClientPutDiskDir = 'ClientPutDiskDir'
+ ClientPutComplexDir = 'ClientPutComplexDir'
+ FCPPlugin = 'FCPPlugin'
+ GenerateSSK = 'GenerateSSK'
+ GetConfig = 'GetConfig' # (since 1027)
+ GetNode = 'GetNode'
+ GetPluginInfo = 'GetPluginInfo'
+ GetRequestStatus = 'GetRequestStatus'
ListPeer = 'ListPeer' # (since 1045)
ListPeers = 'ListPeers'
ListPeerNotes = 'ListPeerNotes'
- AddPeer = 'AddPeer'
+ ListPersistentRequests = 'ListPersistentRequests'
+ ModifyConfig = 'ModifyConfig' # (since 1027)
ModifyPeer = 'ModifyPeer'
ModifyPeerNote = 'ModifyPeerNote'
+ ModifyPersistentRequest = 'ModifyPersistentRequest'
RemovePeer = 'RemovePeer'
- GetNode = 'GetNode'
- GetConfig = 'GetConfig' # (since 1027)
- ModifyConfig = 'ModifyConfig' # (since 1027)
+ RemovePersistentRequest = 'RemovePersistentRequest'
+ Shutdown = 'Shutdown'
+ SubscribeUSK = 'SubscribeUSK'
TestDDARequest = 'TestDDARequest' # (since 1027)
TestDDAResponse = 'TestDDAResponse' # (since 1027)
- GenerateSSK = 'GenerateSSK'
- ClientPut = 'ClientPut'
- ClientPutDiskDir = 'ClientPutDiskDir'
- ClientPutComplexDir = 'ClientPutComplexDir'
- ClientGet = 'ClientGet'
- GetPluginInfo = 'GetPluginInfo'
- FCPPlugin = 'FCPPlugin'
- SubscribeUSK = 'SubscribeUSK'
WatchGlobal = 'WatchGlobal'
- GetRequestStatus = 'GetRequestStatus'
- ListPersistentRequests = 'ListPersistentRequests'
- RemovePersistentRequest = 'RemovePersistentRequest'
- ModifyPersistentRequest = 'ModifyPersistentRequest'
- Shutdown = 'Shutdown'
-
- # node s
+
+ # node --> client
+ AllData = 'AllData'
+ CloseConnectionDuplicateClientName = 'CloseConnectionDuplicateClientName'
+ ConfigData = 'ConfigData' # (since 1027)
+ DataFound = 'DataFound'
+ EndListPeers = 'EndListPeers'
+ EndListPeerNotes = 'EndListPeerNotes'
+ EndListPersistentRequests = 'EndListPersistentRequests'
+ FCPPluginReply = 'FCPPluginReply'
+ FinishedCompression = 'FinishedCompression'
+ GetFailed = 'GetFailed'
+ IdentifierCollision = 'IdentifierCollision'
+ NodeData = 'NodeData'
NodeHello = 'NodeHello'
- CloseConnectionDuplicateClientName = 'CloseConnectionDuplicateClientName'
Peer = 'Peer'
PeerNote = 'PeerNote'
- EndListPeers = 'EndListPeers'
- EndListPeerNotes = 'EndListPeerNotes'
PeerRemoved = 'PeerRemoved'
- NodeData = 'NodeData'
- ConfigData = 'ConfigData' # (since 1027)
- TestDDAReply = 'TestDDAReply' # (since 1027)
- TestDDAComplete = 'TestDDAComplete' # (since 1027)
- SSKKeypair = 'SSKKeypair'
PersistentGet = 'PersistentGet'
PersistentPut = 'PersistentPut'
PersistentPutDir = 'PersistentPutDir'
- URIGenerated = 'URIGenerated'
+ PersistentRequestModified = 'PersistentRequestModified' # (since 1016)
+ PersistentRequestRemoved = 'PersistentRequestRemoved' # (since 1016)
+ PluginInfo = 'PluginInfo'
+ ProtocolError = 'ProtocolError'
+ PutFailed = 'PutFailed'
+ PutFetchable = 'PutFetchable'
PutSuccessful = 'PutSuccessful'
- PutFetchable = 'PutFetchable'
- DataFound = 'DataFound'
- AllData = 'AllData'
+ SimpleProgress = 'SimpleProgress'
+ SSKKeypair = 'SSKKeypair'
StartedCompression = 'StartedCompression'
- FinishedCompression = 'FinishedCompression'
- SimpleProgress = 'SimpleProgress'
- EndListPersistentRequests = 'EndListPersistentRequests'
- PersistentRequestRemoved = 'PersistentRequestRemoved' # (since 1016)
- PersistentRequestModified = 'PersistentRequestModified' # (since 1016)
- PutFailed = 'PutFailed'
- GetFailed = 'GetFailed'
- ProtocolError = 'ProtocolError'
- IdentifierCollision = 'IdentifierCollision'
+ SubscribedUSKUpdate = 'SubscribedUSKUpdate'
+ TestDDAComplete = 'TestDDAComplete' # (since 1027)
+ TestDDAReply = 'TestDDAReply' # (since 1027)
UnknownNodeIdentifier = 'UnknownNodeIdentifier'
UnknownPeerNoteType = 'UnknownPeerNoteType'
- SubscribedUSKUpdate = 'SubscribedUSKUpdate'
- PluginInfo = 'PluginInfo'
- FCPPluginReply = 'FCPPluginReply'
-
+ URIGenerated = 'URIGenerated'
+
+
# client s (internal use only)
ClientSocketTimeout = 1
ClientSocketDied = 2
ClientDisconnected = 3
+
+ ClientRequestMessages = (
+ ClientGet,
+ ClientPut,
+ ClientPutDiskDir,
+ ClientPutComplexDir,
+ )
+ ClientPluginMessages = (
+ GetPluginInfo,
+ FCPPlugin,
+ )
+
class MessageStatus:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-02 11:24:50
|
Revision: 109
http://fclient.svn.sourceforge.net/fclient/?rev=109&view=rev
Author: jurner
Date: 2008-02-02 03:24:50 -0800 (Sat, 02 Feb 2008)
Log Message:
-----------
typo
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_message.py
Modified: trunk/sandbox/fcp/fcp2_0_message.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_message.py 2008-02-02 05:14:24 UTC (rev 108)
+++ trunk/sandbox/fcp/fcp2_0_message.py 2008-02-02 11:24:50 UTC (rev 109)
@@ -185,7 +185,7 @@
def toString(self):
"""Returns the message as formated string ready to be send"""
out = [self.name, ]
- paramTypes = consts.MessageParamTypes.get(self.name, None)
+ paramTypes = types.MessageParamTypes.get(self.name, None)
for param, value in self.params.items():
if param.startswith(self.ParamPrefixPrivate):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-02 05:14:18
|
Revision: 108
http://fclient.svn.sourceforge.net/fclient/?rev=108&view=rev
Author: jurner
Date: 2008-02-01 21:14:24 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
typo
Modified Paths:
--------------
trunk/sandbox/fcp/__init__.py
Modified: trunk/sandbox/fcp/__init__.py
===================================================================
--- trunk/sandbox/fcp/__init__.py 2008-02-02 05:14:06 UTC (rev 107)
+++ trunk/sandbox/fcp/__init__.py 2008-02-02 05:14:24 UTC (rev 108)
@@ -6,6 +6,6 @@
__author__ = 'Juergen Urner'
__copyright__ = '(c) 2008 - Juergen Urner'
-__emeil__ = 'jue...@go...'
+__email__ = 'jue...@go...'
__licence__ = 'Mit'
__version__ = '0.1'
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-02 05:14:02
|
Revision: 107
http://fclient.svn.sourceforge.net/fclient/?rev=107&view=rev
Author: jurner
Date: 2008-02-01 21:14:06 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
adapt to recent
combed over documentation
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 05:13:24 UTC (rev 106)
+++ trunk/sandbox/fcp/fcp2_0_client.py 2008-02-02 05:14:06 UTC (rev 107)
@@ -3,11 +3,11 @@
Compatibility: >= Freenet 0.7 Build #1084
-@newfield event, events
+@newfield event: event, events
-@note: The client implementation never uses or watches the global queue. No (in words N-O)
-implementation should ever do so. Global is evil... so avoid it. Already filed a bug report regarding this.
+@note: The client implementation never uses or watches the global queue. No implementation
+should ever do so. Global is evil.
"""
@@ -149,7 +149,7 @@
def saveWriteFile(fpath, data):
- """Writes data to a file i the savest manner possible
+ """Writes data to a file in the savest manner possible
@param fpath: file to write
@param data: data to write to file
@return: True if successful, False otherwise
@@ -172,6 +172,9 @@
#
#*************************************************************************************************
class FcpClient(object):
+ """
+ @ivar events: events the client supports
+ """
DefaultFcpHost = os.environ.get('FCP_HOST', '127.0.0.1').strip()
try:
@@ -191,24 +194,7 @@
ExpectedNodeBuild = 1107
from fcp2_0_config import Config
- from fcp2_0_consts import (
- ConnectReason,
- DebugVerbosity,
- DisconnectReason,
- FetchError,
- FilenameCollision,
- InsertError,
- KeyType,
- LogMessages,
- PeerNodeStatus,
- PeerNoteType,
- Persistence,
- Priority,
- ProtocolError,
- ReturnType,
- UploadFrom,
- Verbosity,
- )
+ consts = consts
from fcp2_0_message import Message
import fcp2_0_params as FcParams
from fcp2_0_uri import Uri
@@ -271,10 +257,9 @@
debugVerbosity=None,
):
"""
- @param conectionName: name of the connection or None to use an arbitrary connection name
- @param debugVerbosity: verbosity level for debugging. Default is L{DebugVerbosity.Warning}
-
- @ivar events: events the client supports
+ @param connectionName: name of the connection or None to use an arbitrary connection name
+ @param debugVerbosity: verbosity level for debugging. Default is L{consts.DebugVerbosity.Warning}
+
"""
self._connectionName = self.setConnectionName(connectionName)
self._ddaTests = [] # currently running DDA tests (request0, ... requestN)
@@ -287,7 +272,7 @@
self.events = self.Events()
- self.setDebugVerbosity(self.DebugVerbosity.Warning if debugVerbosity is None else debugVerbosity)
+ self.setDebugVerbosity(consts.DebugVerbosity.Warning if debugVerbosity is None else debugVerbosity)
atexit.register(self.close)
@@ -316,7 +301,7 @@
'FcPersistentUserData': persistentUserData, # any user defined persistent data
# non persistent params
- 'FcStatus': self.Message.StatusPending,
+ 'FcStatus': consts.MessageStatus.Pending,
'FcErrorMessage': None, # did an error occur?
'FcUserData': userData, # any user defined runtime data here
@@ -358,11 +343,11 @@
):
"""Registers a message
@param msg: message to register for track keeping
+ @param userData: any user defined data
@param msgSubType: one of the message sub type consts
- @param requestIdentifier: (str)
- @param userData: (str)
@param initTime: (python time)
- @param handleCollisions: (bool)
+ @param persistentUserData: (str) user defined persistent data
+ @param filenameCollision: (bool)
@return: (str) uuid
@note: the identifier returned is unique to the client but may not be unique to the node
@@ -404,12 +389,12 @@
)
# fix some Fcp inconsistencies ClientGet vs. PersistentGet
- if msg.name == self.Message.MessagePersistentGet:
+ if msg.name == consts.Message.PersistentGet:
del msg.params['Started']
#FIX: [0001965: Persistence vs PersistenceType]
if 'PersistenceType' in msg.params:
msg['Persistence'] = msg.params.pop('PersistenceType')
- elif msg.name == self.Message.MessagePersistentPut:
+ elif msg.name == consts.Message.PersistentPut:
del msg.params['Started']
return msg
@@ -423,7 +408,7 @@
"""Closes the client
@note: make shure to call close() when done with the client
"""
- self._log.info(self.LogMessages.ClientClose)
+ self._log.info(consts.LogMessages.ClientClose)
if self._socket is not None:
self._socket.close()
self._socket = None
@@ -444,11 +429,12 @@
@param port: (int) port of the node
@param duration: (int) how many seconds try to connect before giving up
@param timeout: (int) how much time to wait before another attempt to connect
- @event: Connected(event, params). Triggered as soon as the client is connected. Params
- will be the parameters of the NodeHello message.
- @return: (Message) NodeHello if successful, None otherwise for the next iteration
+
+ @return: (L{fcp2_0_message.Message}) NodeHello if successful, None otherwise for the next iteration
+
+ @event: ClientConnected(event, message) is triggered as soon as the client is connected
"""
- self._log.info(self.LogMessages.Connecting)
+ self._log.info(consts.LogMessages.Connecting)
# try to Connect socket
if self._socket is not None:
@@ -468,7 +454,7 @@
except socket.error, d:
yield None
else:
- self._log.info(self.LogMessages.Connected)
+ self._log.info(consts.LogMessages.Connected)
# send ClientHello and wait for NodeHello
#NOTE: thought I could leave ClientHelloing up to the caller
@@ -476,49 +462,49 @@
# as expected when not doing so, the node disconnects.
# So take it over here.
self.sendMessage(
- self.Message.MessageClientHello,
+ consts.Message.ClientHello,
Name=self._connectionName,
ExpectedVersion=self.ExpectedFcpVersion,
)
while timeElapsed <= duration:
msg = self.next(dispatch=False)
- if msg.name == self.Message.MessageClientSocketTimeout:
+ if msg.name == consts.Message.ClientSocketTimeout:
timeElapsed += self.SocketTimeout
yield None
- elif msg.name == self.Message.MessageNodeHello:
+ elif msg.name == consts.Message.NodeHello:
self._nodeHelloMessage = msg
- self._log.debug(self.LogMessages.MessageReceived + msg.pprint())
+ self._log.debug(consts.LogMessages.MessageReceived + msg.pprint())
# check if version is ok
if self.versionCheckNodeHello(msg):
self.events.ClientConnected(msg)
else:
self.close()
msg = self.Message(
- self.Message.MessageClientDisconnected,
- DisconnectReason=self.DisconnectReason.VersionMissmatch
+ consts.Message.ClientDisconnected,
+ DisconnectReason=consts.DisconnectReason.VersionMissmatch
)
self.events.ClientDisconnected(msg)
yield self._nodeHelloMessage
raise StopIteration
else:
- self._log.debug(self.LogMessages.MessageReceived + msg.pprint())
+ self._log.debug(consts.LogMessages.MessageReceived + msg.pprint())
break
break
# continue polling
- self._log.info(self.LogMessages.ConnectionRetry)
+ self._log.info(consts.LogMessages.ConnectionRetry)
timeElapsed += timeout
time.sleep(timeout)
msg = self.Message(
- self.Message.MessageClientDisconnected,
- DisconnectReason=self.DisconnectReason.ConnectingFailed
+ consts.Message.ClientDisconnected,
+ DisconnectReason=consts.DisconnectReason.ConnectingFailed
)
self.events.ClientDisconnected(msg)
- self._log.info(self.LogMessages.ConnectingFailed)
+ self._log.info(consts.LogMessages.ConnectingFailed)
self.close()
raise StopIteration
@@ -540,7 +526,7 @@
def setDebugVerbosity(self, debugVerbosity):
"""Sets the verbosity level of the client
- @note: see L{DebugVerbosity}
+ @note: see L{consts.DebugVerbosity}
"""
self._log.setLevel(debugVerbosity)
@@ -548,7 +534,7 @@
def startFreenet(self, cmdline):
"""Starts freenet
@param cmdline: commandline to start freenet (like '/freenet/run.sh start' or 'c:\freenet\start.bat')
- @return: (string) whatever freenet returns
+ @return: (str) whatever freenet returns
"""
#TODO: on windows it may be necessary to hide the command window
p = subprocess.Popen(
@@ -585,9 +571,9 @@
CancelPersistentRequests = 0 # for testing... if True, cancels all PersistentRequests
- if msg.name == self.Message.MessageClientSocketTimeout:
+ if msg.name == consts.Message.ClientSocketTimeout:
return True
- self._log.debug(self.LogMessages.MessageReceived + msg.pprint())
+ self._log.debug(consts.LogMessages.MessageReceived + msg.pprint())
# check if we have an initial request corrosponding to msg
requestIdentifier = msg.get('Identifier', None)
@@ -597,7 +583,7 @@
## errors
##
####################################################
- if msg.name == self.Message.MessageIdentifierCollision:
+ if msg.name == consts.Message.IdentifierCollision:
if initialRequest is not None:
# resend request with new identifier
@@ -605,37 +591,36 @@
self._requests[newIdentifier] = initialRequest
del self._requests[requestIdentifier]
initialRequest['Identifier'] = newIdentifier
- initialRequest['FcModified'] = {self.Message.ModifiedRequestIdentifier: requestIdentifier}
+ initialRequest['FcModified'] = {consts.RequestModified.Identifier: requestIdentifier}
self.events.RequestModified(initialRequest)
self.sendMessageEx(initialRequest)
return True
- elif msg.name == self.Message.MessageProtocolError:
+ elif msg.name == consts.Message.ProtocolError:
code = msg['Code']
- if requestIdentifier is None:
- #TODO: check how to handle this
- raise self.ProtocolError(msg)
-
- if initialRequest is None:
- #TODO: check how to handle this
- raise self.ProtocolError(msg)
-
-
- if code == self.ProtocolError.ShuttingDown:
+ if code == consts.ProtocolError.ShuttingDown:
self.close()
msg = self.Message(
- self.Message.MessageClientDisconnected,
+ consts.Message.ClientDisconnected,
DisconnectReason=DisconnectReason.Shutdown,
)
self.events.ClientDisconnected(msg)
return True
+ if requestIdentifier is None:
+ #TODO: check how to handle this
+ raise consts.ProtocolError(msg)
+
+ if initialRequest is None:
+ #TODO: check how to handle this
+ raise consts.ProtocolError(msg)
+
# handle DDA errors
- elif code == self.ProtocolError.DDADenied:
- ddaRequestMsg = self.Message(self.Message.MessageTestDDARequest)
- if initialRequest.name == self.Message.MessageClientGet:
+ elif code == consts.ProtocolError.DDADenied:
+ ddaRequestMsg = self.Message(consts.Message.TestDDARequest)
+ if initialRequest.name == consts.Message.ClientGet:
ddaRequestMsg['WantWriteDirectory'] = True
directory = os.path.dirname(initialRequest['Filename'])
else:
@@ -658,44 +643,44 @@
# handle filename collisions
- elif code == self.ProtocolError.DiskTargetExists:
- handleCollision = initialRequest.get('FcFilenameCollision', self.FilenameCollision.HandleNever)
- collisionHandled = bool(handleCollision & self.FilenameCollision.CollisionHandled)
+ elif code == consts.ProtocolError.DiskTargetExists:
+ handleCollision = initialRequest.get('FcFilenameCollision', consts.FilenameCollision.HandleNever)
+ collisionHandled = bool(handleCollision & consts.FilenameCollision.CollisionHandled)
# rename filename
- if handleCollision & self.FilenameCollision.HandleRename:
+ if handleCollision & consts.FilenameCollision.HandleRename:
filename = initialRequest['Filename']
- initialRequest['FcFilenameCollision'] |= self.FilenameCollision.CollisionHandled
+ initialRequest['FcFilenameCollision'] |= consts.FilenameCollision.CollisionHandled
newFilename = namespace.unique_filename(filename, extensions=1, ispostfixed=collisionHandled)
initialRequest['Filename'] = newFilename
- initialRequest['FcModified'] = {self.Message.ModifiedRequestFilename: filename}
+ initialRequest['FcModified'] = {consts.RequestModified.Filename: filename}
self.sendMessageEx(initialRequest)
self.events.RequestModified(initialRequest)
return True
# don't handle
else:
- initialRequest['FcFilenameCollision'] &= ~self.FilenameCollision.CollisionHandled
+ initialRequest['FcFilenameCollision'] &= ~consts.FilenameCollision.CollisionHandled
# handle plugin related request failures
- elif code == self.ProtocolError.NoSuchPlugin:
- if initialRequest.name == self.Message.MessagePluginInfo:
+ elif code == consts.ProtocolError.NoSuchPlugin:
+ if initialRequest.name == consts.Message.PluginInfo:
del self._requests[requestIdentifier]
self.events.PluginInfoFailed(initialRequest)
return True
- elif initialRequest.name == self.Message.MessageFCPPluginMessage:
+ elif initialRequest.name == consts.Message.FCPPluginMessage:
del self._requests[requestIdentifier]
self.events.PluginMessageFailed(initialRequest)
return True
- elif code == self.ProtocolError.AccessDenied:
- if initialRequest.name == self.Message.MessagePluginInfo:
+ elif code == consts.ProtocolError.AccessDenied:
+ if initialRequest.name == consts.Message.PluginInfo:
del self._requests[requestIdentifier]
self.events.PluginInfoFailed(initialRequest)
return True
# TODO: just a guess that FCPPluginMessage can trigger an AccessDenied error
- elif initialRequest.name == self.Message.MessageFCPPluginMessage:
+ elif initialRequest.name == consts.Message.FCPPluginMessage:
del self._requests[requestIdentifier]
self.events.PluginMessageFailed(initialRequest)
return True
@@ -707,7 +692,7 @@
# NOTE: Fcp already removed the request
del self._requests[requestIdentifier]
initialRequest['FcErrorMessage'] = msg
- initialRequest['FcStatus'] = self.Message.StatusError | self.Message.StatusRemoved
+ initialRequest['FcStatus'] = consts.MessageStatus.Error | consts.MessageStatus.Removed
self.events.RequestFailed(initialRequest)
return True
@@ -721,7 +706,7 @@
## TestDDA drill.
##
####################################################
- elif msg.name == self.Message.MessageTestDDAReply:
+ elif msg.name == consts.Message.TestDDAReply:
directory = msg['Directory']
# find message that triggered the call
@@ -752,14 +737,14 @@
initialRequest['FcTestDDA']['TmpFile'] = fpathWrite
self.sendMessage(
- self.Message.MessageTestDDAResponse,
+ consts.Message.TestDDAResponse,
Directory=msg['Directory'],
ReadContent=readContent,
)
return True
- elif msg.name == self.Message.MessageTestDDAComplete:
+ elif msg.name == consts.Message.TestDDAComplete:
# clean up tmp file
directory = msg['Directory']
@@ -790,7 +775,7 @@
#TODO: check if errorMsg gives reasonable feedback
del self._requests[initialRequest['Identifier']]
- initialRequest['FcStatus'] = self.Message.StatusError | self.Message.StatusRemoved
+ initialRequest['FcStatus'] = consts.MessageStatus.Error | consts.MessageStatus.Removed
initialRequest['FcErrorMessage'] = initialRequest['FcTestDDA']['ErrorMsg']
self.events.ProtocolError(initialRequest)
return True
@@ -807,11 +792,11 @@
## config related
##
####################################################
- elif msg.name == self.Message.MessageConfigData:
+ elif msg.name == consts.Message.ConfigData:
self.events.ConfigData(msg)
return True
- elif msg.name == self.Message.MessageNodeData:
+ elif msg.name == consts.Message.NodeData:
self.events.NodeData(msg)
return True
@@ -821,7 +806,7 @@
## get / put related
##
####################################################
- elif msg.name == self.Message.MessageAllData:
+ elif msg.name == consts.Message.AllData:
if initialRequest is None:
return False
@@ -829,13 +814,13 @@
self.events.RequestCompleted(initialRequest)
return True
- elif msg.name == self.Message.MessageDataFound:
+ elif msg.name == consts.Message.DataFound:
if initialRequest is None:
# something is going wrong
return False
- initialRequest['FcStatus'] = self.Message.StatusComplete
+ initialRequest['FcStatus'] = consts.MessageStatus.Complete
initialRequest['FcMetadataContentType'] = msg.get('Metadata.ContentType', '')
initialRequest['FcDataLength'] = msg.get('DataLength', '')
self.events.RequestCompleted(initialRequest)
@@ -843,15 +828,15 @@
- elif msg.name == self.Message.MessageGetFailed:
+ elif msg.name == consts.Message.GetFailed:
code = msg['Code']
if initialRequest is None:
# something is going wrong
return False
# check if it is one of our requests for key information
- if code == self.FetchError.TooBig and initialRequest['FcSubType'] == self.Message.SubTypeGetKeyInfo:
- initialRequest['FcStatus'] = self.Message.StatusComplete
+ if code == self.FetchError.TooBig and initialRequest['FcSubType'] == consts.MessageSubType.GetKeyInfo:
+ initialRequest['FcStatus'] = consts.MessageStatus.Complete
initialRequest['FcMetadataContentType'] = msg.get('ExpectedMetadata.ContentType', '')
initialRequest['FcDataLength'] = msg.get('ExpectedDataLength', -1)
initialRequest['FcProgressCompleted'] = True
@@ -863,13 +848,13 @@
#TODO: check if Fcp removed the request
initialRequest['FcErrorMessage'] = msg
- initialRequest['FcStatus'] = self.Message.StatusError
+ initialRequest['FcStatus'] = consts.MessageStatus.Error
self.events.RequestFailed(initialRequest)
return True
- elif msg.name == self.Message.MessagePersistentGet:
+ elif msg.name == consts.Message.PersistentGet:
# unknown request... try to restore it
if initialRequest is None:
@@ -878,24 +863,24 @@
# not one of our requests... so cancel it
if restoredRequest is None or CancelPersistentRequests:
self.sendMessage(
- self.Message.MessageRemovePersistentRequest,
+ consts.Message.RemovePersistentRequest,
Identifier=msg['Identifier'],
Global=msg['Global'],
)
return True
# determine initial message name
- restoredRequest.name = self.Message.MessageClientGet
+ restoredRequest.name = consts.Message.ClientGet
# restore request
self._requests[requestIdentifier] = restoredRequest
- restoredRequest['FcStatus'] = self.Message.StatusStarted
+ restoredRequest['FcStatus'] = consts.MessageStatus.Started
self.events.RequestRestored(restoredRequest)
return True
# known request... filter out multiple PersistentGets
- if initialRequest['FcStatus'] == self.Message.StatusPending:
- initialRequest['FcStatus'] = self.Message.StatusStarted
+ if initialRequest['FcStatus'] == consts.MessageStatus.Pending:
+ initialRequest['FcStatus'] = consts.MessageStatus.Started
#TODO: update initialRequest with params from PersistentGet?
@@ -904,7 +889,7 @@
return True
- elif msg.name == self.Message.MessagePersistentPut:
+ elif msg.name == consts.Message.PersistentPut:
# unknown request... try to restore it
if initialRequest is None:
@@ -913,29 +898,29 @@
# not one of our requests... so cancel it
if restoredRequest is None or CancelPersistentRequests:
self.sendMessage(
- self.Message.MessageRemovePersistentRequest,
+ consts.Message.RemovePersistentRequest,
Identifier=msg['Identifier'],
Global=msg['Global'],
)
return True
# determine initial message name
- if restoredRequest['FcSubType'] == self.Message.SubTypePut:
- restoredRequest.name = self.Message.MessageClientPut
- elif restoredRequest['FcSubType'] == self.Message.SubTypePutDiskDir:
- restoredRequest.name = self.Message.MessageClientPutDiskDir
- elif restoredRequest['FcSubType'] == self.Message.SubTypePutComplexDir:
- restoredRequest.name = self.Message.MessageClientPutComplexDir
+ if restoredRequest['FcSubType'] == consts.MessageSubType.Put:
+ restoredRequest.name = consts.Message.ClientPut
+ elif restoredRequest['FcSubType'] == consts.MessageSubType.PutDiskDir:
+ restoredRequest.name = consts.Message.ClientPutDiskDir
+ elif restoredRequest['FcSubType'] == consts.MessageSubType.PutComplexDir:
+ restoredRequest.name = consts.Message.ClientPutComplexDir
# restore request
self._requests[requestIdentifier] = restoredRequest
- restoredRequest['FcStatus'] = self.Message.StatusStarted
+ restoredRequest['FcStatus'] = consts.MessageStatus.Started
self.events.RequestRestored(restoredRequest)
return True
# known request... filter out multiple PersistentGets
- if initialRequest['FcStatus'] == self.Message.StatusPending:
- initialRequest['FcStatus'] = self.Message.StatusStarted
+ if initialRequest['FcStatus'] == consts.MessageStatus.Pending:
+ initialRequest['FcStatus'] = consts.MessageStatus.Started
#TODO: update initialRequest with params from PersistentPut?
#TODO: update initialRequest with params from PersistentPut?
@@ -946,7 +931,7 @@
return True
- elif msg.name == self.Message.MessagePersistentRequestModified:
+ elif msg.name == consts.Message.PersistentRequestModified:
if initialRequest is None:
return False
@@ -962,14 +947,14 @@
# ...as long as no other param is changed at runtime we are ok
# otherwise we would have to set flags to indicate wich member
# of ClientToken changed. See --> modifyRequest()
- modified[self.Message.ModifiedRequestPersistentUserData] = None
+ modified[consts.RequestModified.PersistentUserData] = None
for i, fcParam in enumerate(self.FcParams.FcParams):
initialRequest[fcParam] = params[i]
# check if PriorityClass has changed
priorityClass = msg.get('PriorityClass', None)
if priorityClass is not None:
- modified[self.Message.ModifiedRequestPriorityClass] = None
+ modified[consts.RequestModified.PriorityClass] = None
initialRequest['PriorityClass'] = priorityClass
initialRequest['FcModified'] = modified
@@ -977,7 +962,7 @@
return True
- elif msg.name == self.Message.MessagePersistentRequestRemoved:
+ elif msg.name == consts.Message.PersistentRequestRemoved:
if initialRequest is None:
return False
@@ -985,7 +970,7 @@
return True
- elif msg.name == self.Message.MessageSimpleProgress:
+ elif msg.name == consts.Message.SimpleProgress:
if initialRequest is None:
# something went wrong
return False
@@ -1000,14 +985,14 @@
## put related
- elif msg.name == self.Message.MessageURIGenerated:
+ elif msg.name == consts.Message.URIGenerated:
if initialRequest is None: # something went wrong
return False
initialRequest['URI'] = msg['URI']
return True
- elif msg.name == self.Message.MessagePutFetchable:
+ elif msg.name == consts.Message.PutFetchable:
if initialRequest is None:
# something went wrong
return False
@@ -1016,7 +1001,7 @@
return True
- elif msg.name == self.Message.MessagePutSuccessful:
+ elif msg.name == consts.Message.PutSuccessful:
if initialRequest is None:
# something went wrong
return False
@@ -1034,27 +1019,27 @@
## Peer related messages
##
####################################################
- elif msg.name == self.Message.MessageEndListPeers:
+ elif msg.name == consts.Message.EndListPeers:
self.events.EndListPeers(msg)
return True
- elif msg.name == self.Message.MessageEndListPeerNotes:
+ elif msg.name == consts.Message.EndListPeerNotes:
self.events.EndListPeerNotes(msg.params)
return True
- elif msg.name == self.Message.MessagePeer:
+ elif msg.name == consts.Message.Peer:
self.events.Peer(msg)
return True
- elif msg.name == self.Message.MessagePeerNote:
+ elif msg.name == consts.Message.PeerNote:
self.events.PeerNote(msg)
return True
- elif msg.name == self.Message.MessagePeerRemoved:
+ elif msg.name == consts.Message.PeerRemoved:
self.events.PeerRemoved(msg)
return True
- elif msg.name == self.Message.MessageUnknownNodeIdentifier:
+ elif msg.name == consts.Message.UnknownNodeIdentifier:
self.events.UnknownNodeIdentifier(msg)
return True
@@ -1063,7 +1048,7 @@
## plugins
##
####################################################
- elif msg.name == self.Message.MessagePluginInfo:
+ elif msg.name == consts.Message.PluginInfo:
if initialRequest is None:
return False
@@ -1071,7 +1056,7 @@
self.events.PluginInfo(msg)
return True
- elif msg.name == self.Message.MessageFCPPluginReply:
+ elif msg.name == consts.Message.FCPPluginReply:
if initialRequest is None:
return False
@@ -1084,7 +1069,7 @@
## others
##
####################################################
- elif msg.name == self.Message.MessageSSKKeypair:
+ elif msg.name == consts.Message.SSKKeypair:
if requestIdentifier not in self._sskRequests:
return False
@@ -1104,9 +1089,9 @@
return True
- elif msg.name == self.Message.MessageCloseConnectionDuplicateClientName:
+ elif msg.name == consts.Message.CloseConnectionDuplicateClientName:
msg = self.Message(
- self.Message.MessageClientDisconnected,
+ consts.Message.ClientDisconnected,
DisconnectReason=DisconnectReason.DuplicateClientName,
)
self.events.ClientDisconnect(msg)
@@ -1123,13 +1108,13 @@
@note: use this method instead of run() to run the client step by step
"""
msg = self.Message.fromSocket(self._socket)
- if msg.name == self.Message.MessageClientSocketDied:
+ if msg.name == consts.Message.ClientSocketDied:
if dispatch:
- msg['DisconnectReason'] = self.DisconnectReason.SocketDied
+ msg['DisconnectReason'] = consts.DisconnectReason.SocketDied
self.events.ClientDisconnected(msg)
raise socket.error(msg['Details'])
- elif msg.name == self.Message.MessageClientSocketTimeout:
+ elif msg.name == consts.Message.ClientSocketTimeout:
if dispatch:
self.events.Idle(msg)
@@ -1160,16 +1145,16 @@
If an error handler is passed to the client it is called emidiately before the error
is raised.
"""
- self._log.debug(self.LogMessages.MessageSend + msg.pprint())
+ self._log.debug(consts.LogMessages.MessageSend + msg.pprint())
try:
msg.send(self._socket)
except socket.error, d:
- self._log.info(self.LogMessages.SocketDied)
+ self._log.info(consts.LogMessages.SocketDied)
self.close()
errorMsg = self.Message(
- self.Message.MessageClientSocketDied,
- DisconnectReason=self.DisconnectReason.SocketDied,
+ consts.Message.ClientSocketDied,
+ DisconnectReason=consts.DisconnectReason.SocketDied,
Exception=socket.error,
Details=d
)
@@ -1196,7 +1181,7 @@
@event: ConfigData(event, msg)
"""
self.sendMessage(
- self.Message.MessageGetConfig,
+ consts.Message.GetConfig,
WithSortOrder=withSortOrder,
WithCurrent=withCurrent,
WithDefaults=withDefaults,
@@ -1211,7 +1196,7 @@
"""Modifies node configuration values
@param params: (dict) containing parameters to modify
"""
- msg = self.Message(self.Message.MessageModifyConfig)
+ msg = self.Message(consts.Message.ModifyConfig)
msg.params = params
self.sendMessageEx(msg)
@@ -1230,8 +1215,8 @@
**messageParams
):
"""Requests a key from the node
- @param uri: uri of the file to request (may contain prefixes like 'freenet:' or 'http://')
- @param messageSubType: one of the Message.SubType* consts to the desired request
+ @param uri: (str) uri of the file to request (may contain prefixes like 'freenet:' or 'http://')
+ @param messageSubType: (L{consts.MessageSubType}) sub type of the message
@param userData: any non persistent data to associate to the request or None
@param persistentUserData: any string to associate to the request as persistent data or None
@param filenameCollision: what to do if the disk target alreaady exists. One of the FilenameCollision.* consts
@@ -1243,7 +1228,7 @@
"""
uri = self.Uri(uri).uri
- msg = self.Message(self.Message.MessageClientGet, URI=uri)
+ msg = self.Message(consts.Message.ClientGet, URI=uri)
for paramName, value in messageParams.items():
if value is not None:
msg[paramName] = value
@@ -1281,13 +1266,13 @@
@param uri: uri of the file to request (may contain prefixes like 'freenet:' or 'http://')
@param allowedMimeTypes: (str) list of allowed mime types
- @param binaryBlob: if True, the file is retrieved as binary blob file
- @param dsOnly: if True, retrieves the file from the local data store only
- @param ignoreDs: If True, ignores the local data store
+ @param binaryBlob: (bool) if True, the file is retrieved as binary blob file
+ @param dsOnly: (bool) if True, retrieves the file from the local data store only
+ @param ignoreDS: (bool) if True, ignores the local data store
@param maxRetries: (int) maximum number of retries or -1 to retry forver or None to leave it to the node to decide
@param maxSize: (int) maximum size of the file in bytes or None to set no limited
- @param persistence: persistence of the request as one of the L{consts.Persistence} constants
- @param priorityClass: priority of the request as one of the L{consts.Priority} consts
+ @param persistence: (L{consts.Persistence}) persistence of the request
+ @param priorityClass: (L{consts.Priority}) priority of the request
@param userData: any non persistent data to associate to the request
@param persistentUserData: any string to associate to the request as persistent data
@@ -1297,7 +1282,7 @@
"""
return self.clientGet(
uri,
- self.Message.SubTypeGetData,
+ consts.MessageSubType.GetData,
userData,
persistentUserData,
consts.FilenameCollision.HandleNever,
@@ -1313,9 +1298,9 @@
MaxSize = maxSize,
Persistence=persistence,
PriorityClass=priorityClass,
- ReturnType=self.ReturnType.Direct,
+ ReturnType=consts.ReturnType.Direct,
URI=self.Uri(uri).uri,
- Verbosity=self.Verbosity.ReportProgress,
+ Verbosity=consts.Verbosity.ReportProgress,
)
@@ -1344,11 +1329,11 @@
@param allowedMimeTypes: (str) list of allowed mime types
@param binaryBlob: if True, the file is retrieved as binary blob file
@param dsOnly: if True, retrieves the file from the local data store only
- @param ignoreDs: If True, ignores the local data store
+ @param ignoreDS: If True, ignores the local data store
@param maxRetries: (int) maximum number of retries or -1 to retry forver or None to leave it to the node to decide
@param maxSize: (int) maximum size of the file in bytes or None to set no limited
- @param persistence: persistence of the request as one of the L{consts.Persistence} constants
- @param priorityClass: priority of the request as one of the L{consts.Priority} consts
+ @param persistence: (L{consts.Persistence}) persistence of the request
+ @param priorityClass: (L{consts.Priority}) priority of the request
@param filenameCollision: what to do if the disk target alreaady exists. One of the FilenameCollision.* consts
@param userData: any non persistent data to associate to the request
@@ -1359,7 +1344,7 @@
"""
return self.clientGet(
uri,
- self.Message.SubTypeGetFile,
+ consts.MessageSubType.GetFile,
userData,
persistentUserData,
filenameCollision,
@@ -1376,9 +1361,9 @@
MaxSize = maxSize,
Persistence=persistence,
PriorityClass=priorityClass,
- ReturnType=self.ReturnType.Disk,
+ ReturnType=consts.ReturnType.Disk,
URI=self.Uri(uri).uri,
- Verbosity=self.Verbosity.ReportProgress,
+ Verbosity=consts.Verbosity.ReportProgress,
)
@@ -1399,10 +1384,10 @@
@param uri: uri of the file to request (may contain prefixes like 'freenet:' or 'http://')
@param dsOnly: if True, retrieves the file from the local data store only
- @param ignoreDs: If True, ignores the local data store
+ @param ignoreDS: If True, ignores the local data store
@param maxRetries: (int) maximum number of retries or -1 to retry forver or None to leave it to the node to decide
- @param persistence: persistence of the request as one of the L{consts.Persistence} constants
- @param priorityClass: priority of the request as one of the L{consts.Priority} consts
+ @param persistence: (L{consts.Persistence}) persistence of the request
+ @param priorityClass: (L{consts.Priority}) priority of the request
@param userData: any non persistent data to associate to the request
@param persistentUserData: any string to associate to the request as persistent data
@@ -1411,7 +1396,7 @@
# how to retrieve meta info about a key? ...idea is to provoke a GetFailed (TooBig)
return self.clientGet(
uri,
- self.Message.SubTypeGetKeyInfo,
+ consts.MessageSubType.GetKeyInfo,
userData,
persistentUserData,
consts.FilenameCollision.HandleNever,
@@ -1425,9 +1410,9 @@
MaxSize=self.MaxSizeKeyInfo,
Persistence=persistence,
PriorityClass=priorityClass,
- ReturnType=self.ReturnType.Nothing,
+ ReturnType=consts.ReturnType.Nothing,
URI=self.Uri(uri).uri,
- Verbosity=self.Verbosity.ReportProgress,
+ Verbosity=consts.Verbosity.ReportProgress,
)
@@ -1443,12 +1428,12 @@
raise ValueError('Nothing to upload')
# determine SubType
- if msg.name == self.Message.MessageClientPut:
- messageSubType = self.Message.SubTypePut
- elif msg.name == self.Message.MessageClientPutDiskDir:
- messageSubType = self.Message.SubTypePutDiskDir
+ if msg.name == consts.Message.ClientPut:
+ messageSubType = consts.MessageSubType.Put
+ elif msg.name == consts.Message.ClientPutDiskDir:
+ messageSubType = consts.MessageSubType.PutDiskDir
else:
- messageSubType = self.Message.SubTypePutComplexDir
+ messageSubType = consts.MessageSubType.PutComplexDir
self._registerRequest(
msg,
@@ -1476,7 +1461,7 @@
data,
**messageParams):
- msg = self.Message(self.Message.MessageClientPut, URI=uri)
+ msg = self.Message(consts.Message.ClientPut, URI=uri)
for paramName, value in messageParams.items():
if value is not None:
msg[paramName] = value
@@ -1517,7 +1502,7 @@
return self.clientPut(
consts.KeyType.CHK,
- self.Message.SubTypePut,
+ consts.MessageSubType.Put,
userData,
persistentUserData,
data,
@@ -1533,8 +1518,8 @@
DontCompress=dontCompress,
Persistence=persistence,
TargetFilename=targetFilename,
- UploadFrom=self.UploadFrom.Direct,
- Verbosity=self.Verbosity.ReportProgress | self.Verbosity.ReportCompression,
+ UploadFrom=consts.UploadFrom.Direct,
+ Verbosity=consts.Verbosity.ReportProgress | consts.Verbosity.ReportCompression,
)
def putFile(self,
@@ -1553,7 +1538,7 @@
):
return self.clientPut(
concts.KeyType.CHK,
- self.Message.SubTypePut,
+ consts.MessageSubType.Put,
userData,
persistentUserData,
None,
@@ -1569,8 +1554,8 @@
DontCompress=dontCompress,
Persistence=persistence,
TergetFilename=targetFilename,
- UploadFrom=self.UploadFrom.Disk,
- Verbosity=self.Verbosity.ReportProgress | self.Verbosity.ReportCompression,
+ UploadFrom=consts.UploadFrom.Disk,
+ Verbosity=consts.Verbosity.ReportProgress | consts.Verbosity.ReportCompression,
)
@@ -1596,15 +1581,15 @@
def modifyRequest(self, requestIdentifier, persistentUserData=None, priorityClass=None):
"""Modifies a request
- @param identifier: identifier of the request to modify
- @param clientToken: new client token or None
- @param priorityClass: new priority or None
+ @param requestIdentifier: identifier of the request to modify
+ @param persistentUserData: (str) persistent user data or None
+ @param priorityClass: (L{consts.Priority}) new priority or None
@note: a RequestModified event is triggered as soon as the request has actually been modified
"""
initialRequest = self._requests[requestIdentifier]
msg = self.Message(
- self.Message.MessageModifyPersistentRequest,
+ consts.Message.ModifyPersistentRequest,
Identifier=initialRequest['Identifier'],
Global=False,
)
@@ -1618,14 +1603,14 @@
def removeRequest(self, requestIdentifier):
"""Removes a request
- @param identifier: (str) identifier of the request to remove
+ @param requestIdentifier: (str) identifier of the request to remove
@note: a RequestRemoved event is triggered as soon as the request has actually been removed
"""
initialRequest = self._requests[requestIdentifier]
- initialRequest['FcStatus'] = self.Message.StatusRemoved
+ initialRequest['FcStatus'] = consts.MessageStatus.Removed
self.sendMessage(
- self.Message.MessageRemovePersistentRequest,
+ consts.Message.RemovePersistentRequest,
Global=False,
Identifier=requestIdentifier,
)
@@ -1648,36 +1633,36 @@
"""Request information about the node
@param withPrivate: if True, private data is included
@param withVolatile: if True, statistical data is included
- @param giveOppennetRef: if True, the opennet reference is retuned instead of the darknet
+ @param giveOpennetRef: if True, the opennet reference is retuned instead of the darknet
"""
self.sendMessage(
- self.Message.MessageGetNode,
+ consts.Message.GetNode,
WithPrivate=withPrivate,
WithVolatile=withVolatile,
GiveOpennetRef=giveOpennetRef,
)
- def listPeer(self, identity):
+ def listPeer(self, nodeIdentity):
"""Requests information about a peer node
- @param identifier: identifier of the peer to request information for
+ @param nodeIdentity: identity of the peer to request information for
"""
- self.jobClient.sendMessage(
- self.Message.MessageListPeer,
+ self.sendMessage(
+ consts.Message.ListPeer,
NodeIdentifier=identity,
)
- def listPeerNotes(self, identity):
+ def listPeerNotes(self, nodeIdentity):
"""Lists all text notes associated to a peer
- @param identifier: peer as returned in a call to L{peerList}
+ @param nodeIdentity: peer as returned in a call to L{listPeer}
@event: ListPeerNote(event, params)
@event: EndListPeerNotes(event, params)
@note: listPeerNotes() is only available for darknet nodes
"""
self.sendMessage(
- self.Message.MessageListPeerNotes,
- NodeIdentifier=identity
+ consts.Message.ListPeerNotes,
+ NodeIdentifier=nodeIdentity
)
@@ -1690,54 +1675,54 @@
@event: EndListPeers(event, params).
"""
self.sendMessage(
- self.Message.MessageListPeers,
+ consts.Message.ListPeers,
WithMetadata=withMetaData,
WithVolatile=withVolantile,
)
- def modifyPeer(self, identity, allowLocalAddresses=None, isDisabled=None, isListenOnly=None):
+
+ def modifyPeer(self, nodeIdentifier, allowLocalAddresses=None, isDisabled=None, isListenOnly=None):
"""Modifies a peer node
- @param identity: identity of the peer node to modify
+ @param nodeIdentifier: identitfier of the peer node to modify
@param allowLocalAddresses: if True, whatever is done
@param isDisabled: if True, the peer is disabled
@param isListenOnly: if True, the peer is set to listen only status
"""
msg = Message(
- self.Message.MessageModifyPeer,
- NodeIdentifier=identity,
+ consts.Message.ModifyPeer,
+ NodeIdentifier=nodeidentifier,
)
if allowLocalAddresses is not None:
msg['AllowLocalAddresses'] = allowLocalAddresses
if isDisabled is not None:
- msg['isDisabled'] = isDisabled
+ msg['IsDisabled'] = isDisabled
if isListenOnly is not None:
- msg['isListenOnly'] = isListenOnly
- self.jobClient.sendMessageEx(msg)
+ msg['IsListenOnly'] = isListenOnly
self.sendMessageEx(msg)
-
+
- def modifyPeerNote(self, identity, note):
+ def modifyPeerNote(self, nodeIdentifier, note):
"""Modifies the note associated to a peer
- @param identity: identity of the peer node to modify
+ @param nodeIdentifier: identitifier of the peer node to modify
@param note: (str) new note to associate to the peer
"""
self.sendMessage(
- self.Message.MessageModifyPeerNote,
- NodeIdentifier=identity,
+ consts.Message.ModifyPeerNote,
+ NodeIdentifier=nodeIdentifier,
#NOTE: currently fcp supports only this one type
- PeerNoteType=self.PeerNoteType.Private,
+ PeerNoteType=consts.PeerNoteType.Private,
NoteText=note
)
- def removePeer(self, identity):
+ def removePeer(self, nodeIdentifier):
"""Removes a peer
- @param identity: identity of the peer node to remove
+ @param nodeIdentifier: identitfier of the peer node to remove
"""
self.sendMessage(
- self.Message.MessageRemovePeer,
- NodeIdentifier=identity,
+ consts.Message.RemovePeer,
+ NodeIdentifier=nodeidentifier,
)
##########################################################
@@ -1757,7 +1742,7 @@
if identifier not in self._requests:
break
msg = self.Message(
- self.Message.MessageGetPluginInfo,
+ consts.Message.GetPluginInfo,
Identifier=identifier,
PluginName=pluginName,
Detailed=detailed,
@@ -1770,7 +1755,7 @@
def sendPluginMessage(self, pluginName, params, data=None):
"""Sends a message to a plugin
@param pluginName: name of the plugin to send the message to
- @param poarams: (dict) additional params to pass to the plugin (each parameter has to be prefixed with 'Param.')
+ @param params: (dict) additional params to pass to the plugin (each parameter has to be prefixed with 'Param.')
@param data: (str) data to pass along with the messaage or None
@return: (str) request identifier
"""
@@ -1779,7 +1764,7 @@
if identifier not in self._requests:
break
msg = self.Message(
- self.Message.MessageGetPluginInfo,
+ consts.Message.GetPluginInfo,
Identifier=identifier,
PluginName=pluginName,
**params
@@ -1802,7 +1787,7 @@
##########################################################
def generateKeypair(self, keypairType=consts.KeyType.SSK):
"""
- @param keypairType: type of keypair to generate (either L{KeyType.SSK} or L{KeyType.SSK})
+ @param keypairType: type of keypair to generate (either L{consts.KeyType.SSK} or L{consts.KeyType.SSK})
@return: identifier of the request
@event: KeypairGenerated(event, params) is triggered when the request is complete
"""
@@ -1816,7 +1801,7 @@
break
self._sskRequests.append(identifier)
self.sendMessage(
- self.Message.MessageGenerateSSK,
+ consts.Message.GenerateSSK,
Identifier=identifier,
)
return identifier
@@ -1828,7 +1813,7 @@
if __name__ == '__main__':
c = FcpClient(
connectionName='test',
- debugVerbosity=FcpClient.DebugVerbosity.Debug
+ debugVerbosity=consts.DebugVerbosity.Debug
)
for nodeHello in c.connect(): pass
@@ -2012,3 +1997,10 @@
#testGetPluginInfo()
+
+ def testListPeers():
+ c.listPeers()
+ for i in xrange(30):
+ c.next()
+
+ #testListPeers()
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-02 05:13:18
|
Revision: 106
http://fclient.svn.sourceforge.net/fclient/?rev=106&view=rev
Author: jurner
Date: 2008-02-01 21:13:24 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
adapt to recent
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_config.py
Modified: trunk/sandbox/fcp/fcp2_0_config.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_config.py 2008-02-02 05:12:51 UTC (rev 105)
+++ trunk/sandbox/fcp/fcp2_0_config.py 2008-02-02 05:13:24 UTC (rev 106)
@@ -1,23 +1,24 @@
"""Sketch for fcp config tree"""
-from fcp2_0_consts import ConfigMessageParams
+import fcp2_0_types as types
#****************************************************************************************
#
#****************************************************************************************
class ConfigItem(object):
- """Config item"""
+ """Config item
+ @ivar parent: parent item
+ @ivar name: name of the item
+ @ivar children: (dict) child items
+ @ivar values: dict of values
+ """
+
def __init__(self, parent, name):
"""
@param parent: parent item
@param name: name of the item
-
- @ivar parent: parent item
- @ivar name: name of the item
- @ivar children: (dict) child items
- @ivar values: dict of values
"""
self.parent = parent
self.name = name
@@ -35,7 +36,7 @@
out.append(parent.name)
parent = parent.parent
out.reverse()
- return ConfigMessageParams.ComponentsSep.join(out)
+ return types-ConfigMessageParams.ComponentsSep.join(out)
#****************************************************************************************
@@ -43,30 +44,29 @@
#****************************************************************************************
class Config(object):
"""Class representing fcp config tree
+
+ @ivar parent: parent item
+ @ivar name: name of the config (always None)
+ @ivar children: (dict) child items
"""
- ValueClassCurrent = ConfigMessageParams.ParamClassCurrent
- ValueClassDefault = ConfigMessageParams.ParamClassDefault
- ValueClassExpertFlag = ConfigMessageParams.ParamClassExpertFlag
- ValueClassForceWriteFlag = ConfigMessageParams.ParamClassForceWriteFlag
- ValueClassShortDescription = ConfigMessageParams.ParamClassShortDescription
- ValueClassLongDescription = ConfigMessageParams.ParamClassLongDescription
+ ValueClassCurrent = types.ConfigMessageParams.ParamClassCurrent
+ ValueClassDefault = types.ConfigMessageParams.ParamClassDefault
+ ValueClassExpertFlag = types.ConfigMessageParams.ParamClassExpertFlag
+ ValueClassForceWriteFlag = types.ConfigMessageParams.ParamClassForceWriteFlag
+ ValueClassShortDescription = types.ConfigMessageParams.ParamClassShortDescription
+ ValueClassLongDescription = types.ConfigMessageParams.ParamClassLongDescription
def __init__(self, configDataMsg=None):
"""
- @param parent: parent item
- @param name: name of the item
-
- @ivar parent: parent item
- @ivar name: name of the item
- @ivar children: (dict) child items
+ @param configDataMsg: ConfigData message to initialize the config with or None
"""
self.parent = None
self.name = None
self.children = {}
- self._configMessageParams = ConfigMessageParams()
+ self._configMessageParams = types.ConfigMessageParams()
if configDataMsg is not None:
for key, value in configDataMsg.params.items():
@@ -143,7 +143,7 @@
def walk(self):
- """Walks over the config tree, returning the next L{ConfigItemm} in turn"""
+ """Walks over the config tree, returning the next L{ConfigItem} in turn"""
def walker(node):
yield node
for child in node.children.values():
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-02 05:12:45
|
Revision: 105
http://fclient.svn.sourceforge.net/fclient/?rev=105&view=rev
Author: jurner
Date: 2008-02-01 21:12:51 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
moved types to types module
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_consts.py
Modified: trunk/sandbox/fcp/fcp2_0_consts.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_consts.py 2008-02-02 05:12:17 UTC (rev 104)
+++ trunk/sandbox/fcp/fcp2_0_consts.py 2008-02-02 05:12:51 UTC (rev 105)
@@ -2,7 +2,6 @@
"""Freennet Client Protocol consts and type mappings"""
-import base64
import logging
#************************************************************************
#
@@ -132,11 +131,16 @@
# others
class ConnectReason:
+ """Reason for connecting to the node
+ @cvar Connect: reason is a regualr connect
+ @cvar Reconnect: reason is a reconnect
+ """
Connect = 1
Reconnect = 2
class DebugVerbosity:
+ """Consts indicating the verbosity level for debugging"""
Debug = logging.DEBUG
Info = logging.INFO
Warning = logging.WARNING
@@ -156,6 +160,12 @@
class FilenameCollision:
+ """Filename collision flags
+ @cvar HandleNever: don't handle filename collisions
+ @cvar HandleRename: rename file on collisions
+ @cvar MaskHandle: bitmask indicating if collisions are hadled or not
+ @cvar CollisonHandled: if this bit is set, a collision has been handled
+ """
HandleNever = 0x0
HandleRename = 0x1
@@ -165,6 +175,7 @@
class KeyType:
+ """Supported key types"""
SSK = 'SSK@'
KSK = 'KSK@'
CHK = 'CHK@'
@@ -177,7 +188,8 @@
class LogMessages:
- """Message strings used for log infos"""
+ """Strings used for log infos"""
+
Connecting = 'connecting to node...'
Connected = 'connected to node'
ConnectionRetry = 'connecting to node failed... retrying'
@@ -193,6 +205,105 @@
+class Message:
+ """Fcp messages"""
+
+ # client s
+ ClientHello = 'ClientHello'
+ ListPeer = 'ListPeer' # (since 1045)
+ ListPeers = 'ListPeers'
+ ListPeerNotes = 'ListPeerNotes'
+ AddPeer = 'AddPeer'
+ ModifyPeer = 'ModifyPeer'
+ ModifyPeerNote = 'ModifyPeerNote'
+ RemovePeer = 'RemovePeer'
+ GetNode = 'GetNode'
+ GetConfig = 'GetConfig' # (since 1027)
+ ModifyConfig = 'ModifyConfig' # (since 1027)
+ TestDDARequest = 'TestDDARequest' # (since 1027)
+ TestDDAResponse = 'TestDDAResponse' # (since 1027)
+ GenerateSSK = 'GenerateSSK'
+ ClientPut = 'ClientPut'
+ ClientPutDiskDir = 'ClientPutDiskDir'
+ ClientPutComplexDir = 'ClientPutComplexDir'
+ ClientGet = 'ClientGet'
+ GetPluginInfo = 'GetPluginInfo'
+ FCPPlugin = 'FCPPlugin'
+ SubscribeUSK = 'SubscribeUSK'
+ WatchGlobal = 'WatchGlobal'
+ GetRequestStatus = 'GetRequestStatus'
+ ListPersistentRequests = 'ListPersistentRequests'
+ RemovePersistentRequest = 'RemovePersistentRequest'
+ ModifyPersistentRequest = 'ModifyPersistentRequest'
+ Shutdown = 'Shutdown'
+
+ # node s
+ NodeHello = 'NodeHello'
+ CloseConnectionDuplicateClientName = 'CloseConnectionDuplicateClientName'
+ Peer = 'Peer'
+ PeerNote = 'PeerNote'
+ EndListPeers = 'EndListPeers'
+ EndListPeerNotes = 'EndListPeerNotes'
+ PeerRemoved = 'PeerRemoved'
+ NodeData = 'NodeData'
+ ConfigData = 'ConfigData' # (since 1027)
+ TestDDAReply = 'TestDDAReply' # (since 1027)
+ TestDDAComplete = 'TestDDAComplete' # (since 1027)
+ SSKKeypair = 'SSKKeypair'
+ PersistentGet = 'PersistentGet'
+ PersistentPut = 'PersistentPut'
+ PersistentPutDir = 'PersistentPutDir'
+ URIGenerated = 'URIGenerated'
+ PutSuccessful = 'PutSuccessful'
+ PutFetchable = 'PutFetchable'
+ DataFound = 'DataFound'
+ AllData = 'AllData'
+ StartedCompression = 'StartedCompression'
+ FinishedCompression = 'FinishedCompression'
+ SimpleProgress = 'SimpleProgress'
+ EndListPersistentRequests = 'EndListPersistentRequests'
+ PersistentRequestRemoved = 'PersistentRequestRemoved' # (since 1016)
+ PersistentRequestModified = 'PersistentRequestModified' # (since 1016)
+ PutFailed = 'PutFailed'
+ GetFailed = 'GetFailed'
+ ProtocolError = 'ProtocolError'
+ IdentifierCollision = 'IdentifierCollision'
+ UnknownNodeIdentifier = 'UnknownNodeIdentifier'
+ UnknownPeerNoteType = 'UnknownPeerNoteType'
+ SubscribedUSKUpdate = 'SubscribedUSKUpdate'
+ PluginInfo = 'PluginInfo'
+ FCPPluginReply = 'FCPPluginReply'
+
+ # client s (internal use only)
+ ClientSocketTimeout = 1
+ ClientSocketDied = 2
+ ClientDisconnected = 3
+
+
+class MessageStatus:
+ Pending = 0x1
+ Compressing = 0x2
+ Started = 0x4
+ Complete = 0x8
+ Error = 0x10
+ Removed = 0x20
+ RestoreFailed = 0x40
+
+
+class MessageSubType:
+ """Consts indicating the subtype of a message"""
+
+ # some additional consts
+ Null = 0
+ GetData = 1
+ GetFile = 2
+ GetKeyInfo = 3
+ Put = 4
+ PutDiskDir = 5
+ PutComplexDir = 6
+
+
+
#TODO: no idea how fcp handles strings as in <Peer volatile.status=CONNECTED>
# all I could find in the sources where these constants as in PEER_NODE_STATUS_CONNECTED
# in --> freenet/node/PeerManager.java
@@ -229,6 +340,20 @@
Low = '4'
+class RequestModified:
+ """Flags indicating what of a request has been modified
+ @cvar Filename: the filename has been modified
+ @cvar Identifier: the identifier has been moodified
+ @cvar PersistentUserData: thepersistent user data has been modified
+ @cvar PriorityClass: the priority class has been modified
+ """
+ Filename = 0x8
+ Identifier = 0x4
+ PersistentUserData = 0x1
+ PriorityClass = 0x2
+
+
+
class ReturnType:
Direct = 'direct'
Disk = 'disk'
@@ -246,742 +371,3 @@
ReportProgress = 0x1
ReportCompression = 0x200
-#*************************************************************************************
-# python <--> fcp value mappings
-#*************************************************************************************
-class FcpType(object):
-
- @classmethod
- def pythonToFcp(clss, value):
- return value
-
- @classmethod
- def fcpToPython(clss, value):
- return value
-
-
-class FcpTypeString(FcpType):
-
- @classmethod
- def pythonToFcp(clss, value):
- return str(value) #TODO: unicode ???
-
- @classmethod
- def fcpToPython(clss, value):
- return value
-
-
-class FcpTypeBool(FcpType):
-
- @classmethod
- def pythonToFcp(clss, value):
- return FcpTrue if value else FcpFalse
-
- @classmethod
- def fcpToPython(clss, value):
- return value == FcpTrue
-
-
-class FcpTypeInt(FcpType):
-
- @classmethod
- def pythonToFcp(clss, value):
- return str(value)
-
- @classmethod
- def fcpToPython(clss, value):
- return int(value)
-
-
-class FcpTypeFloat(FcpType):
-
- @classmethod
- def pythonToFcp(clss, value):
- return str(value)
-
- @classmethod
- def fcpToPython(clss, value):
- return float(value)
-
-
-# GetFailed sets the ExpectedDataLenght field to '' (empty string). Fix this to show up as -1
-class FcpTypeInt_GetFailed_ExpectedDataLenght(FcpType):
-
- @classmethod
- def pythonToFcp(clss, value):
- return str(value)
-
- @classmethod
- def fcpToPython(clss, value):
- if value == '':
- return -1
- return int(value)
-
-
-class FcpTypeIntWithBounds(FcpType):
-
- def __init__(self, lowerBound, upperBound):
- self.lowerBound = lowerBound
- self.upperBound = upperBound
-
- def pythonToFcp(self, value):
- return str(value)
-
- def fcpToPython(self, value):
- return int(value)
-
-
-class FcpTypeBase64EncodedString(FcpType):
-
- @classmethod
- def pythonToFcp(clss, value):
- return base64.b64encode(value)
-
- @classmethod
- def fcpToPython(clss, value):
- return base64.b64decode(value)
-
-
-class FcpTypeTime(FcpType):
-
- @classmethod
- def pythonToFcp(clss, value):
- return str(value * 1000)
-
- @classmethod
- def fcpToPython(clss, value):
- return int(value) / 1000
-
-
-
-class FcpTypeIP(FcpType): pass
-class FcpTypeIPList(FcpType): pass
-class FcpTypeIPort(FcpType): pass
-class FcpTypeStringList(FcpType): pass
-class FcpTypeDirname(FcpType): pass
-class FcpTypeFilename(FcpType): pass
-class FcpTypeNumBytes(FcpType): pass
-class FcpTypePercent(FcpTypeFloat): pass
-class FcpTypeUri(FcpType): pass
-
-
-# special choice types for config message
-
-
-class FcpTypeChoiceFProxyCss(FcpType):
- Clean = 'Clean'
- Boxed = 'boxed'
- GrayAndBlue = 'grayandblue'
- Sky = 'sky'
-
- ChoicesAll = (Clean, Boxed, GrayAndBlue, Sky)
- ChoicesAllowMultiple = False
-
-class FcpTypeChoiceLoggerPriority(FcpType):
- Error = 'ERROR'
- Normal = 'NORMAL'
- Minor = 'MINOR'
- Debug = 'DEBUG'
-
- ChoicesAll = (Error, Normal, Minor, Debug)
- ChoicesAllowMultiple = False
-
-class FcpTypeChoiceNodeDownloadAllowedDirs(FcpType):
- All = 'all'
- Downloads = 'downloads'
- Nowhere = ''
-
- ChoicesAll = (All, Downloads, Nowhere)
- ChoicesAllowMultiple = False
-
-class FcpTypeChoiceNodeUploadAllowedDirs(FcpType):
- All = 'all'
- Nowhere = ''
- ChoicesAll = (All, Nowhere)
- ChoicesAllowMultiple = False
-
-class FcpTypeChoicePriorityPolicy(FcpType):
- Hard = 'HARD'
- Soft = 'SOFT'
-
- ChoicesAll = (Hard, Soft)
- ChoicesAllowMultiple = False
-
-
-class FcpTypeChoiceSSLVersion(FcpType):
- Stl = 'STL'
- SslV3 = 'SSLV3'
- TlsV1 = 'TLSv1'
-
- ChoicesAll = (Stl, SslV3, TlsV1)
- ChoicesAllowMultiple = False
-
-
-#***************************************************************************************
-#
-# param types for config message
-#
-# ..bit more efford here, cos we need types for user input checking
-# ...a slpoppy implementation of a dict should be enough
-#
-#***************************************************************************************
-class ConfigMessageParams(object):
-
- ComponentsSep = '.'
-
-
- # first component of a config message param is always the param class
-
- ParamClassCurrent = 'current'
- ParamClassDefault = 'default'
- ParamClassExpertFlag = 'expertFlag'
- ParamClassForceWriteFlag = 'forceWriteFlag'
- ParamClassShortDescription = 'shortDescription'
- ParamClassLongDescription = 'longDescription'
- ParamClassSortOrder = 'sortOrder'
-
- ParamClasses = (
- ParamClassCurrent,
- ParamClassDefault,
- ParamClassExpertFlag,
- ParamClassForceWriteFlag,
- ParamClassShortDescription,
- ParamClassLongDescription,
- )
-
-
-
- # all known config keys (param class stripped)
- Params = {
-
- 'console.allowedHosts': FcpTypeIPList, # host names, single IPs CIDR-maskip IPs likee 192.168.0.0/24
- 'console.bindTo': FcpTypeIPList,
- 'console.directEnabled': FcpTypeBool,
- 'console.enabled': FcpTypeBool,
- 'console.port': FcpTypeIPort,
- 'console.ssl': FcpTypeBool,
-
-
- 'fcp.allowedHosts': FcpTypeIPList,
- 'fcp.allowedHostsFullAccess': FcpTypeIPList,
- 'fcp.assumeDownloadDDAIsAllowed': FcpTypeBool,
- 'fcp.assumeUploadDDAIsAllowed': FcpTypeBool,
- 'fcp.bindTo': FcpTypeIP,
- 'fcp.enabled': FcpTypeBool,
- 'fcp.persistentDownloadsEnabled': FcpTypeBool,
- 'fcp.persistentDownloadsFile': FcpTypeFilename,
- 'fcp.persistentDownloadsInterval': FcpTypeIntWithBounds(0, None),
- 'fcp.port': FcpTypeIPort,
- 'fcp.ssl': FcpTypeBool,
-
-
- 'fproxy.CSSOverride': FcpTypeBool,
- 'fproxy.advancedModeEnabled': FcpTypeBool,
- 'fproxy.allowedHosts': FcpTypeIPList,
- 'fproxy.allowedHostsFullAccess': FcpTypeIPList,
- 'fproxy.bindTo': FcpTypeIPList,
- 'fproxy.css': FcpTypeChoiceFProxyCss,
- 'fproxy.doRobots': FcpTypeBool,
- 'fproxy.enabled': FcpTypeBool,
- 'fproxy.javascriptEnabled': FcpTypeBool,
- 'fproxy.port': FcpTypeIPort,
- 'fproxy.showPanicButton': FcpTypeBool,
- 'fproxy.ssl': FcpTypeBool,
-
-
- 'logger.dirname': FcpTypeDirname,
- 'logger.enabled': FcpTypeBool,
- 'logger.interval': FcpType, # ??? 1HOUR ??
- 'logger.maxCachedBytes': FcpTypeNumBytes,
- 'logger.maxCachedLines': FcpTypeNumBytes, # ???
- 'logger.maxZippedLogsSize': FcpTypeNumBytes, # ???
- 'logger.priority': FcpTypeChoiceLoggerPriority,
- 'logger.priorityDetail': FcpType, # ???? is it Detailed priority thresholds ???
-
-
- 'node.alwaysAllowLocalAddresses': FcpTypeBool,
- 'node.assumeNATed': FcpTypeBool,
- 'node.bindTo': FcpTypeIP,
- 'node.clientThrottleFile': FcpTypeFilename,
- 'node.databaseMaxMemory': FcpTypeNumBytes,
- 'node.disableHangCheckers': FcpTypeBool,
- 'node.disableProbabilisticHTLs': FcpTypeBool,
- 'node.downloadAllowedDirs': FcpTypeChoiceNodeDownloadAllowedDirs,
- 'node.downloadsDir': FcpTypeDirname,
- 'node.extraPeerDataDir': FcpTypeDirname,
- 'node.includeLocalAddressesInNoderefs': FcpTypeBool,
- 'node.inputBandwidthLimit': FcpTypeNumBytes, # -1 is possible as value aswell
- 'node.ipAddressOverride': FcpTypeIP,
- 'node.l10n': FcpType, # ???
- 'node.lazyResume': FcpTypeBool,
- 'node.listenPort': FcpTypeIPort,
- 'node.maxBackgroundUSKFetchers': FcpTypeIntWithBounds(0, None),
- 'node.maxHTL': FcpTypeIntWithBounds(0, None),
- 'node.name': FcpTypeString,
- 'node.nodeDir': FcpTypeDirname,
- 'node.oneConnectionPerIP': FcpTypeBool,
- 'node.outputBandwidthLimit': FcpTypeNumBytes,
- 'node.passOpennetPeersThroughDarknet': FcpTypeBool,
- 'node.persistentTempDir': FcpTypeDirname,
- 'node.storeDir': FcpTypeDirname,
- 'node.storeForceBigShrinks': FcpTypeBool,
- 'node.storeSize': FcpTypeNumBytes,
- 'node.tempDir': FcpTypeDirname,
- 'node.tempIPAddressHint': FcpTypeIP, # ???
- 'node.testingDropPacketsEvery': FcpTypeIntWithBounds(0, None),
- 'node.uploadAllowedDirs': FcpTypeChoiceNodeDownloadAllowedDirs,
-
-
- 'node.testnet.enabled': FcpTypeBool,
-
-
- 'node.load.aggressiveGC': FcpType, # ???
- 'node.load.freeHeapBytesThreshold': FcpTypeNumBytes,
- 'node.load.freeHeapPercentThreshold': FcpTypePercent,
- 'node.load.memoryChecker': FcpTypeBool,
- 'node.load.nodeThrottleFile': FcpTypeFilename,
- 'node.load.threadLimit': FcpTypeIntWithBounds(0, None),
-
-
- 'node.opennet.acceptSeedConnections': FcpTypeBool,
- 'node.opennet.alwaysAllowLocalAddresses': FcpTypeBool,
- 'node.opennet.assumeNATed': FcpTypeBool,
- 'node.opennet.bindTo': FcpTypeIP,
- 'node.opennet.enabled': FcpTypeBool,
- 'node.opennet.listenPort': FcpTypeIPort,
- 'node.opennet.maxOpennetPeers': FcpTypeIntWithBounds(0, None),
- 'node.opennet.oneConnectionPerIP': FcpTypeBool,
- 'node.opennet.testingDropPacketsEvery': FcpTypeIntWithBounds(0, None),
-
- 'node.scheduler.CHKinserter_priority_policy': FcpTypeChoicePriorityPolicy,
- 'node.scheduler.CHKrequester_priority_policy': FcpTypeChoicePriorityPolicy,
- 'node.scheduler.SSKinserter_priority_policy': FcpTypeChoicePriorityPolicy,
- 'node.scheduler.SSKrequester_priority_policy': FcpTypeChoicePriorityPolicy,
-
- 'node.updater.URI': FcpTypeUri,
- 'node.updater.autoupdate': FcpTypeBool,
- 'node.updater.enabled': FcpTypeBool,
- 'node.updater.extURI': FcpTypeUri,
- 'node.updater.revocationURI': FcpTypeUri,
-
-
- 'pluginmanager.loadplugin': FcpTypeStringList,
- 'pluginmanager2.loadedPlugins': FcpTypeStringList,
-
-
- 'ssl.sslEnable': FcpTypeBool,
- 'ssl.sslKeyPass': FcpTypeString,
- 'ssl.sslKeyStore': FcpTypeFilename,
- 'ssl.sslKeyStorePass': FcpTypeString,
- 'ssl.sslVersion': FcpTypeChoiceSSLVersion,
-
- 'toadletsymlinker.symlinks': FcpTypeStringList,
-
- }
-
-
- def __init__(self):
- pass
-
-
- def splitAll(self, paramName):
- return paramName.split(self.ComponentsSep)
-
- def splitParamClass(self, paramName):
- return paramName.split(self.ComponentsSep, 1)
-
-
- def get(self, paramName, default=None):
- try:
- return self[paramName]
- except KeyError:
- return default
-
-
- def __getitem__(self, paramName):
- paramClass, paramKey = self.splitParamClass(paramName)
- if paramClass == self.ParamClassCurrent:
- return self.Params[paramKey]
- elif paramClass == self.ParamClassDefault:
- return self.Params[paramKey]
- elif paramClass == self.ParamClassExpertFlag:
- return FcpTypeBool
- elif paramClass == self.ParamClassForceWriteFlag:
- return FcpTypeBool
- elif paramClass == self.ParamClassShortDescription:
- return FcpTypeString
- elif paramClass == self.ParamClassLongDescription:
- return FcpTypeString
- elif paramClass == self.ParamClassSortOrder:
- return FcpTypeInt
- else:
- raise ValueError('Unknown param class in: %r' % paramName)
-
-#***************************************************************************************
-#
-# param types for peer message
-#
-# ..need to do a bit more here, cos it may be needed to validate user input
-#
-#***************************************************************************************
-PeerMessageParams = {
- 'ark.number': FcpTypeInt,
- 'auth.negTypes': FcpTypeInt,
-
-
- 'location': FcpTypeFloat,
- 'opennet': FcpTypeBool,
- 'testnet': FcpTypeBool,
-
- 'metadata.timeLastConnected': FcpTypeTime,
- 'metadata.timeLastReceivedPacket': FcpTypeTime,
- 'metadata.timeLastRoutable': FcpTypeTime,
- 'metadata.timeLastSuccess': FcpTypeTime,
- 'metadata.routableConnectionCheckCount': FcpTypeInt,
- 'metadata.hadRoutableConnectionCount': FcpTypeInt,
-
- 'volatile.averagePingTime': FcpTypeFloat,
- 'volatile.overloadProbability': FcpTypePercent,
- 'volatile.routingBackoff': FcpTypeInt,
- 'volatile.routingBackoffPercent': FcpTypePercent,
- 'volatile.totalBytesIn': FcpTypeInt,
- 'volatile.totalBytesOut': FcpTypeInt,
- 'volatile.routingBackoffLength': FcpTypeInt,
- }
-
-'''all other Peer message params here....
-
->> identity=YIrE..................
->> lastGoodVersion=Fred,0.7,1.0,1106
->> physical.udp=00.000.000.000:00000
->> version=Fred,0.7,1.0,1107
->> dsaGroup.q=ALFDN...............
->> dsaGroup.p=AIYIrE..................
->> dsaPubKey.y=YSlb............
->> dsaGroup.g=UaRa...............
->> ark.pubURI=SSK@......................
->>
->> metadata.detected.udp=000.000.000.000:00000
-
->> volatile.lastRoutingBackoffReason=ForwardRejectedOverload
->> volatile.percentTimeRoutableConnection=99.4735.................
->> volatile.status=CONNECTED
-
-'''
-
-#***************************************************************************************
-#
-# param types for node message
-#
-#***************************************************************************************
-NodeMessageParams = {
- 'ark.number': FcpTypeInt,
- 'auth.negTypes': FcpTypeInt,
- 'location': FcpTypeFloat,
- 'opennet': FcpTypeBool,
- 'testnet': FcpTypeBool,
-
-
- 'volatile.allocatedJavaMemory': FcpTypeInt,
- 'volatile.availableCPUs': FcpTypeInt,
- 'volatile.averagePingTime': FcpTypeFloat,
- 'volatile.avgStoreAccessRate': FcpTypePercent,
- 'volatile.backedOffPercent': FcpTypePercent,
- 'volatile.bwlimitDelayTime': FcpTypeFloat,
- 'volatile.cacheAccess': FcpTypeInt,
- 'volatile.cachedKeys': FcpTypeInt,
- 'volatile.cachedSize': FcpTypeInt,
- 'volatile.cachedStoreHits': FcpTypeInt,
- 'volatile.cachedStoreMisses': FcpTypeInt,
- 'volatile.freeJavaMemory': FcpTypeInt,
- 'volatile.isUsingWrapper': FcpTypeBool,
- 'volatile.locationChangePerMinute': FcpTypeFloat,
- 'volatile.locationChangePerSession': FcpTypeFloat,
- 'volatile.locationChangePerSwap': FcpTypeFloat,
- 'volatile.maximumJavaMemory': FcpTypeInt,
- 'volatile.maxOverallKeys': FcpTypeInt,
- 'volatile.maxOverallSize': FcpTypeInt,
- 'volatile.networkSizeEstimate24hourRecent': FcpTypeInt,
- 'volatile.networkSizeEstimate48hourRecent': FcpTypeInt,
- 'volatile.networkSizeEstimateSession': FcpTypeInt,
- 'volatile.noSwaps': FcpTypeFloat,
- 'volatile.noSwapsPerMinute': FcpTypeFloat,
- 'volatile.numberOfARKFetchers': FcpTypeInt,
- 'volatile.numberOfBursting': FcpTypeInt,
- 'volatile.numberOfConnected': FcpTypeInt,
- 'volatile.numberOfDisabled': FcpTypeInt,
- 'volatile.numberOfDisconnected': FcpTypeInt,
- 'volatile.numberOfInsertSenders': FcpTypeInt,
- 'volatile.numberOfListening': FcpTypeInt,
- 'volatile.numberOfListenOnly': FcpTypeInt,
- 'volatile.numberOfNeverConnected': FcpTypeInt,
- 'volatile.numberOfNotConnected': FcpTypeInt,
- 'volatile.numberOfRemotePeerLocationsSeenInSwaps': FcpTypeFloat,
- 'volatile.numberOfRequestSenders': FcpTypeInt,
- 'volatile.numberOfRoutingBackedOff': FcpTypeInt,
- 'volatile.numberOfSimpleConnected': FcpTypeInt,
- 'volatile.numberOfTooNew': FcpTypeInt,
- 'volatile.numberOfTooOld': FcpTypeInt,
- 'volatile.numberOfTransferringRequestSenders': FcpTypeInt,
- 'volatile.numberWithRoutingBackoffReasons.ForwardRejectedOverload': FcpTypeInt,
- 'volatile.overallAccesses': FcpTypeInt,
- 'volatile.overallKeys': FcpTypeInt,
- 'volatile.overallSize': FcpTypeInt,
- 'volatile.percentCachedStoreHitsOfAccesses': FcpTypePercent,
- 'volatile.percentOverallKeysOfMax': FcpTypePercent,
- 'volatile.percentStoreHitsOfAccesses': FcpTypePercent,
- 'volatile.pInstantReject': FcpTypeFloat, # or percent?
- 'volatile.recentInputRate': FcpTypeFloat,
- 'volatile.recentOutputRate': FcpTypeFloat,
- 'volatile.routingMissDistance': FcpTypeFloat,
- 'volatile.runningThreadCount': FcpTypeInt,
- 'volatile.startedSwaps': FcpTypeInt,
- 'volatile.startupTime': FcpTypeTime,
- 'volatile.storeAccesses': FcpTypeInt,
- 'volatile.storeHits': FcpTypeInt,
- 'volatile.storeKeys': FcpTypeInt,
- 'volatile.storeMisses': FcpTypeInt,
- 'volatile.storeSize': FcpTypeInt,
- 'volatile.swaps': FcpTypeFloat,
- 'volatile.swapsPerMinute': FcpTypeFloat,
- 'volatile.swapsPerNoSwaps': FcpTypeFloat,
- 'volatile.swapsRejectedAlreadyLocked': FcpTypeInt,
- 'volatile.swapsRejectedLoop': FcpTypeInt,
- 'volatile.swapsRejectedNowhereToGo': FcpTypeInt,
- 'volatile.swapsRejectedRateLimit': FcpTypeInt,
- 'volatile.swapsRejectedRecognizedID': FcpTypeInt,
- 'volatile.totalInputBytes': FcpTypeInt,
- 'volatile.totalInputRate': FcpTypeInt,
- 'volatile.totalOutputBytes': FcpTypeInt,
- 'volatile.totalOutputRate': FcpTypeInt,
- 'volatile.totalPayloadOutputBytes': FcpTypeInt,
- 'volatile.totalPayloadOutputPercent': FcpTypePercent,
- 'volatile.totalPayloadOutputRate': FcpTypeInt,
- 'volatile.unclaimedFIFOSize': FcpTypeInt,
- 'volatile.uptimeSeconds': FcpTypeInt,
- 'volatile.usedJavaMemory': FcpTypeInt,
- }
-
-
-'''
->>all other NodeData message params here....
->>
->> physical.udp=000.000.000.000:00000
->> dsaPubKey.y=GgrpsNUK9m.................................................
->> version=Fred,0.7,1.0,1107
->> myName=whatever
->> ark.pubURI=SSK@...............
-
->> dsaGroup.q=ALFDNoq.....
->> dsaGroup.p=AIYIrE9VNhM3.............
->> volatile.avgConnectedPeersPerNode=15.35................
->> dsaGroup.g=UaRa.............
->> dsaPrivKey.x=Pwam..................
->> ark.privURI=SSK@.................
->> lastGoodVersion=Fred,0.7,1.0,1106
->> sig=691f............
->> identity=vMQa~..................
-
-'''
-#***************************************************************************************
-#
-# Mapping from message params to param types
-#
-# ...being lazy here, only types that are not strings are declared
-#
-#***************************************************************************************
-MessageParamTypes = {
-
- # client messages
-
- 'ListPeer': {
- 'WithMetadata': FcpTypeBool,
- 'WithVolantile': FcpTypeBool,
- },
-
- 'ListPeers': {
- 'WithMetadata': FcpTypeBool,
- 'WithVolantile': FcpTypeBool,
- },
-
- #'AddPeer': # added later as PeerMessageParams
-
- 'ModifyPeer': {
- 'AllowLocalAddresses': FcpTypeBool,
- 'IsDisabled': FcpTypeBool,
- 'ListenOnly': FcpTypeBool,
- },
-
- 'ModifyPeerNote': {
- 'NoteText': FcpTypeBase64EncodedString,
- },
-
- 'GetNode': {
- 'GiveOpennetRef': FcpTypeBool,
- 'WithPrivate': FcpTypeBool,
- 'WithVolatile': FcpTypeBool,
- },
- 'GetConfig': {
- 'WithCurrent': FcpTypeBool,
- 'WithDefaults': FcpTypeBool,
- 'WithSortOrder': FcpTypeBool,
- 'WithExpertFlag': FcpTypeBool,
- 'WithForceWriteFlag': FcpTypeBool,
- 'WithShortDescription': FcpTypeBool,
- 'WithLongDescription': FcpTypeBool,
- },
-
- #'ModifyConfig': # added later as ConfigMessageParams()
-
- 'TestDDARequest': {
- 'WantReadDirectory': FcpTypeBool,
- 'WantWriteDirectory': FcpTypeBool,
- },
- 'ClientPut': {
- 'BinaryBlob': FcpTypeBool,
- 'DontCompress': FcpTypeBool,
- 'EarlyEncode': FcpTypeBool,
- 'GetCHKOnly': FcpTypeBool,
- 'Global': FcpTypeBool,
- 'MaxRetries': FcpTypeInt,
- 'Verbosity': FcpTypeInt,
- },
- 'ClientGet': {
- 'BinaryBlob': FcpTypeBool,
- 'Global': FcpTypeBool,
- 'IgnoreDS': FcpTypeBool,
- 'DSOnly': FcpTypeBool,
- 'MaxSize': FcpTypeInt,
- 'MaxTempSize': FcpTypeInt,
- 'Verbosity': FcpTypeInt,
- },
- 'SubscribeUSK': {
- 'DontPoll': FcpTypeBool,
- },
- 'WatchGlobal': {
- 'Enabled': FcpTypeBool,
- 'VerbosityMask': FcpTypeInt,
- },
- 'GetRequestStatus': {
- 'Global': FcpTypeBool,
- 'OnlyData': FcpTypeBool,
- },
- 'RemopvePersistentRequest': {
- 'Global': FcpTypeBool,
- },
- 'ModifyPersistentRequest': {
- 'Global': FcpTypeBool,
- },
- 'GetPluginInfo': {
- 'Detailed': FcpTypeBool,
- },
-
-
-
- # node messages
-
- 'NodeHello': {
- 'Build': FcpTypeInt,
- 'CompressionCodecs': FcpTypeInt,
- 'ExtBuild': FcpTypeInt,
- 'ExtRevision': FcpTypeInt,
- 'FcpVersion': FcpTypeFloat,
- 'Testnet': FcpTypeBool,
- },
-
- #'Peer': # added later as PeerMessageParams
-
- 'PeerNote': {
- 'NoteText': FcpTypeBase64EncodedString,
- },
-
-
- #'NodeData': # added later as NodeMessageParams
- #'ConfigData': # added later as ConfigMessageParams()
-
- 'TestDDAComplete': {
- 'ReadDirectoryAllowed': FcpTypeBool,
- 'WriteDirectoryAllowed': FcpTypeBool,
- },
- 'PutFetchable': {
- 'Global': FcpTypeBool,
- },
- 'DataFound': {
- 'Global': FcpTypeBool,
- 'DataLength': FcpTypeInt,
- },
- 'AllData': {
- 'Global': FcpTypeBool,
- #NOTE: we ignore startup and completion time here as long as it is not passed in all related messages
-
- },
- 'FinishedCompression': {
- 'OriginalSize': FcpTypeInt,
- 'CompressedSize': FcpTypeInt,
- },
- 'SimpleProgress': {
- 'Total': FcpTypeInt,
- 'Required': FcpTypeInt,
- 'Failed': FcpTypeInt,
- 'FatalyFailed': FcpTypeInt,
- 'Succeeded': FcpTypeInt,
- 'Finalized': FcpTypeBool,
- },
- 'PersistentRequestRemoved': {
- 'Global': FcpTypeBool,
- },
- 'PersistentRequestModified': {
- 'Global': FcpTypeBool,
- },
- 'PutFailed': {
- 'Global': FcpTypeBool,
- 'Code': FcpTypeInt,
- },
- 'GetFailed': {
- 'Code': FcpTypeInt,
- 'ExpectedDataLength': FcpTypeInt_GetFailed_ExpectedDataLenght,
- 'Fatal': FcpTypeBool,
- 'FinalizedExpected': FcpTypeBool,
- 'Global': FcpTypeBool,
- },
- 'ProtocolError': {
- 'Code': FcpTypeInt,
- 'Global': FcpTypeBool,
- },
-
- 'IdentifierCollision': {
- 'Global': FcpTypeBool,
- },
- 'SubscribedUSKUpdate': {
- 'Edition': FcpTypeInt,
- },
- 'GetPluginInfo': {
- 'Started': FcpTypeBool,
- },
-
- }
-
-MessageParamTypes['ClientPutDiskDir'] = MessageParamTypes['ClientPut']
-MessageParamTypes['ClientComplexDir'] = MessageParamTypes['ClientPut']
-
-# TODO: "Started" param? Think we simply ignore it
-MessageParamTypes['PersistentGet'] = MessageParamTypes['ClientGet']
-MessageParamTypes['PersistentPut'] = MessageParamTypes['ClientPut']
-
-
-MessageParamTypes['ModifyConfig'] = MessageParamTypes['ConfigData'] = ConfigMessageParams()
-
-MessageParamTypes['Peer'] = MessageParamTypes['AddPeer'] = PeerMessageParams
-
-
-
-
-
-
-
-
-
-
-
-
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-02 05:12:11
|
Revision: 104
http://fclient.svn.sourceforge.net/fclient/?rev=104&view=rev
Author: jurner
Date: 2008-02-01 21:12:17 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
moved consts to consts module
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_message.py
Modified: trunk/sandbox/fcp/fcp2_0_message.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_message.py 2008-02-02 05:11:43 UTC (rev 103)
+++ trunk/sandbox/fcp/fcp2_0_message.py 2008-02-02 05:12:17 UTC (rev 104)
@@ -1,114 +1,41 @@
-"""Freennet Client Protocol message"""
+"""Freennet Client Protocol message
+"""
+
import socket
-from fcp2_0_consts import MessageParamTypes
+import fcp2_0_consts as consts
+import fcp2_0_types as types
#********************************************************************************
#
#********************************************************************************
class Message(object):
- """Class wrapping a freenet message"""
+ """Class wrapping a Fcp message
+
+ Sample use::
+
+ msg = Messsage(
+ consts.Message.ClientHello,
+ ExpectedVersion='2.0',
+ Name='MyConnectionName'
+ )
+ msg['Name'] = 'another'
+ msg['Name']
+ >> 'another'
+
+ msg.send(mySocket)
+ @ivar data: data carried along with the message or None
+ @ivar name: message name
+ @ivar params: message params
+ """
+
+
# we add a few private params...
ParamPrefixPrivate = 'Fc' # params prefixed with this are skipped when generating the message
-
- # client messages
- MessageClientHello = 'ClientHello'
- MessageListPeer = 'ListPeer' # (since 1045)
- MessageListPeers = 'ListPeers'
- MessageListPeerNotes = 'ListPeerNotes'
- MessageAddPeer = 'AddPeer'
- MessageModifyPeer = 'ModifyPeer'
- MessageModifyPeerNote = 'ModifyPeerNote'
- MessageRemovePeer = 'RemovePeer'
- MessageGetNode = 'GetNode'
- MessageGetConfig = 'GetConfig' # (since 1027)
- MessageModifyConfig = 'ModifyConfig' # (since 1027)
- MessageTestDDARequest = 'TestDDARequest' # (since 1027)
- MessageTestDDAResponse = 'TestDDAResponse' # (since 1027)
- MessageGenerateSSK = 'GenerateSSK'
- MessageClientPut = 'ClientPut'
- MessageClientPutDiskDir = 'ClientPutDiskDir'
- MessageClientPutComplexDir = 'ClientPutComplexDir'
- MessageClientGet = 'ClientGet'
- MessageGetPluginInfo = 'GetPluginInfo'
- MessageFCPPluginMessage = 'FCPPluginMessage'
- MessageSubscribeUSK = 'SubscribeUSK'
- MessageWatchGlobal = 'WatchGlobal'
- MessageGetRequestStatus = 'GetRequestStatus'
- MessageListPersistentRequests = 'ListPersistentRequests'
- MessageRemovePersistentRequest = 'RemovePersistentRequest'
- MessageModifyPersistentRequest = 'ModifyPersistentRequest'
- MessageShutdown = 'Shutdown'
-
- # node messages
- MessageNodeHello = 'NodeHello'
- MessageCloseConnectionDuplicateClientName = 'CloseConnectionDuplicateClientName'
- MessagePeer = 'Peer'
- MessagePeerNote = 'PeerNote'
- MessageEndListPeers = 'EndListPeers'
- MessageEndListPeerNotes = 'EndListPeerNotes'
- MessagePeerRemoved = 'PeerRemoved'
- MessageNodeData = 'NodeData'
- MessageConfigData = 'ConfigData' # (since 1027)
- MessageTestDDAReply = 'TestDDAReply' # (since 1027)
- MessageTestDDAComplete = 'TestDDAComplete' # (since 1027)
- MessageSSKKeypair = 'SSKKeypair'
- MessagePersistentGet = 'PersistentGet'
- MessagePersistentPut = 'PersistentPut'
- MessagePersistentPutDir = 'PersistentPutDir'
- MessageURIGenerated = 'URIGenerated'
- MessagePutSuccessful = 'PutSuccessful'
- MessagePutFetchable = 'PutFetchable'
- MessageDataFound = 'DataFound'
- MessageAllData = 'AllData'
- MessageStartedCompression = 'StartedCompression'
- MessageFinishedCompression = 'FinishedCompression'
- MessageSimpleProgress = 'SimpleProgress'
- MessageEndListPersistentRequests = 'EndListPersistentRequests'
- MessagePersistentRequestRemoved = 'PersistentRequestRemoved' # (since 1016)
- MessagePersistentRequestModified = 'PersistentRequestModified' # (since 1016)
- MessagePutFailed = 'PutFailed'
- MessageGetFailed = 'GetFailed'
- MessageProtocolError = 'ProtocolError'
- MessageIdentifierCollision = 'IdentifierCollision'
- MessageUnknownNodeIdentifier = 'UnknownNodeIdentifier'
- MessageUnknownPeerNoteType = 'UnknownPeerNoteType'
- MessageSubscribedUSKUpdate = 'SubscribedUSKUpdate'
- MessagePluginInfo = 'PluginInfo'
- MessageFCPPluginReply = 'FCPPluginReply'
- # client messages (internal use only)
- MessageClientSocketTimeout = 1
- MessageClientSocketDied = 2
- MessageClientDisconnected = 3
-
-
- # some additional consts
- SubTypeNone = 0
- SubTypeGetData = 1
- SubTypeGetFile = 2
- SubTypeGetKeyInfo = 3
- SubTypePut = 4
- SubTypePutDiskDir = 5
- SubTypePutComplexDir = 6
-
- StatusPending = 0x1
- StatusCompressing = 0x2
- StatusStarted = 0x4
- StatusComplete = 0x8
- StatusError = 0x10
- StatusRemoved = 0x20
- StatusRestoreFailed = 0x40
-
- ModifiedRequestPersistentUserData = 0x1
- ModifiedRequestPriorityClass = 0x2
- ModifiedRequestIdentifier = 0x4
- ModifiedRequestFilename = 0x8
-
-
def __init__(self, name, data=None, **params):
"""
@param name: messge name
@@ -126,8 +53,7 @@
"""Reads n bytes from socket
@param socketObj: socket to read bytes from
@param n: (int) number of bytes to read
- @return: (tuple) (error-message or None, bytes read or None) if an error occured
- or no bytes could be read
+ @return: (tuple) (error-message, bytes-read). If no error was encountered, error-message will be None
"""
error = p = None
try:
@@ -136,9 +62,9 @@
p = None
raise socket.error('Socket shut down by node')
except socket.timeout, d: # nothing in the queue
- error = clss(clss.MessageClientSocketTimeout)
+ error = clss(consts.Message.ClientSocketTimeout)
except socket.error, d:
- error = clss(clss.MessageClientSocketDied, Exception=socket.error, Details=d)
+ error = clss(consts.Message.ClientSocketDied, Exception=socket.error, Details=d)
return error, p
@@ -147,9 +73,8 @@
"""Reads a message from a socket
@param socketObj: socket to read a message from
@return: L{Message} next message from the socket. If the socket dies
- unexpectedly a L{ClientSocketDied} message is returned containing the parameters
- 'Exception' and 'Details'. If the socket times out a L{MessageClientSocketTimout}
- message is returned.
+ unexpectedly a L{consts.Message.ClientSocketDied} message is returned containing the parameters
+ 'Exception' and 'Details'. If the socket times out a L{consts.Message.ClientSocketTimeout} message is returned.
@note: SocketObj can be any object that supports a sockets recv() and sendall() methods
and raises the appropriate socket errors
@@ -183,7 +108,7 @@
# first line == message name
if msg.name is None:
msg.name = line
- paramTypes = MessageParamTypes.get(line, None)
+ paramTypes = types.MessageParamTypes.get(line, None)
# get data member
@@ -233,7 +158,7 @@
def pprint(self):
"""Returns the message as nicely formated human readable string"""
out = ['', '>>' + self.name, ]
- paramTypes = MessageParamTypes.get(self.name, None)
+ paramTypes = types.MessageParamTypes.get(self.name, None)
for param, value in self.params.items():
if param.startswith(self.ParamPrefixPrivate):
@@ -260,7 +185,7 @@
def toString(self):
"""Returns the message as formated string ready to be send"""
out = [self.name, ]
- paramTypes = MessageParamTypes.get(self.name, None)
+ paramTypes = consts.MessageParamTypes.get(self.name, None)
for param, value in self.params.items():
if param.startswith(self.ParamPrefixPrivate):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-02 05:11:39
|
Revision: 103
http://fclient.svn.sourceforge.net/fclient/?rev=103&view=rev
Author: jurner
Date: 2008-02-01 21:11:43 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
combed over docs
Modified Paths:
--------------
trunk/sandbox/fcp/fcp_2_0_requests.py
Modified: trunk/sandbox/fcp/fcp_2_0_requests.py
===================================================================
--- trunk/sandbox/fcp/fcp_2_0_requests.py 2008-02-02 05:11:00 UTC (rev 102)
+++ trunk/sandbox/fcp/fcp_2_0_requests.py 2008-02-02 05:11:43 UTC (rev 103)
@@ -97,8 +97,7 @@
"""Adds a directory to be uploaded
@param name: target name
@param directory: (abspath) of the directory to be uploaded
- @param contentType: (str) content type of the file (if desired)
-
+
@note: if you add a directory, every attempt to add anything else will fail
"""
return self._addItem(
@@ -138,8 +137,8 @@
def getMessage(self, messageClass):
"""Returns the message for the request, ready to send the request to the node
- @param messageClass: (L{Message}) class to fill in
- @return: (L{Message}) instance
+ @param messageClass: (L{fcp2_0_message.Message}) class to fill in
+ @return: (L{fcp2_0_message.Message}) instance
"""
if self.keyType in (consts.KeyType.SSK, consts.KeyType.USK) and self.privateKey is None:
raise ValueError('For %s a public key is required' % self.keyType)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-02 05:10:54
|
Revision: 102
http://fclient.svn.sourceforge.net/fclient/?rev=102&view=rev
Author: jurner
Date: 2008-02-01 21:11:00 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
added types module
Added Paths:
-----------
trunk/sandbox/fcp/fcp2_0_types.py
Added: trunk/sandbox/fcp/fcp2_0_types.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_types.py (rev 0)
+++ trunk/sandbox/fcp/fcp2_0_types.py 2008-02-02 05:11:00 UTC (rev 102)
@@ -0,0 +1,738 @@
+"""Fcp types vs. Python types
+
+This module handles type conversions from Fcp to Python and vice versa
+"""
+
+import base64
+
+import fcp2_0_consts as consts
+#*************************************************************************************
+#
+#*************************************************************************************
+class FcpType(object):
+
+ @classmethod
+ def pythonToFcp(clss, value):
+ return value
+
+ @classmethod
+ def fcpToPython(clss, value):
+ return value
+
+
+class FcpTypeString(FcpType):
+
+ @classmethod
+ def pythonToFcp(clss, value):
+ return str(value) #TODO: unicode ???
+
+ @classmethod
+ def fcpToPython(clss, value):
+ return value
+
+
+class FcpTypeBool(FcpType):
+
+ @classmethod
+ def pythonToFcp(clss, value):
+ return consts.FcpTrue if value else consts.FcpFalse
+
+ @classmethod
+ def fcpToPython(clss, value):
+ return value == consts.FcpTrue
+
+
+class FcpTypeInt(FcpType):
+
+ @classmethod
+ def pythonToFcp(clss, value):
+ return str(value)
+
+ @classmethod
+ def fcpToPython(clss, value):
+ return int(value)
+
+
+class FcpTypeFloat(FcpType):
+
+ @classmethod
+ def pythonToFcp(clss, value):
+ return str(value)
+
+ @classmethod
+ def fcpToPython(clss, value):
+ return float(value)
+
+
+# GetFailed sets the ExpectedDataLenght field to '' (empty string). Fix this to show up as -1
+class FcpTypeInt_GetFailed_ExpectedDataLenght(FcpType):
+
+ @classmethod
+ def pythonToFcp(clss, value):
+ return str(value)
+
+ @classmethod
+ def fcpToPython(clss, value):
+ if value == '':
+ return -1
+ return int(value)
+
+
+class FcpTypeIntWithBounds(FcpType):
+
+ def __init__(self, lowerBound, upperBound):
+ self.lowerBound = lowerBound
+ self.upperBound = upperBound
+
+ def pythonToFcp(self, value):
+ return str(value)
+
+ def fcpToPython(self, value):
+ return int(value)
+
+
+class FcpTypeBase64EncodedString(FcpType):
+
+ @classmethod
+ def pythonToFcp(clss, value):
+ return base64.b64encode(value)
+
+ @classmethod
+ def fcpToPython(clss, value):
+ return base64.b64decode(value)
+
+
+class FcpTypeTime(FcpType):
+
+ @classmethod
+ def pythonToFcp(clss, value):
+ return str(value * 1000)
+
+ @classmethod
+ def fcpToPython(clss, value):
+ return int(value) / 1000
+
+
+
+class FcpTypeIP(FcpType): pass
+class FcpTypeIPList(FcpType): pass
+class FcpTypeIPort(FcpType): pass
+class FcpTypeStringList(FcpType): pass
+class FcpTypeDirname(FcpType): pass
+class FcpTypeFilename(FcpType): pass
+class FcpTypeNumBytes(FcpType): pass
+class FcpTypePercent(FcpTypeFloat): pass
+class FcpTypeUri(FcpType): pass
+
+
+# special choice types for config message
+
+
+class FcpTypeChoiceFProxyCss(FcpType):
+ Clean = 'Clean'
+ Boxed = 'boxed'
+ GrayAndBlue = 'grayandblue'
+ Sky = 'sky'
+
+ ChoicesAll = (Clean, Boxed, GrayAndBlue, Sky)
+ ChoicesAllowMultiple = False
+
+class FcpTypeChoiceLoggerPriority(FcpType):
+ Error = 'ERROR'
+ Normal = 'NORMAL'
+ Minor = 'MINOR'
+ Debug = 'DEBUG'
+
+ ChoicesAll = (Error, Normal, Minor, Debug)
+ ChoicesAllowMultiple = False
+
+class FcpTypeChoiceNodeDownloadAllowedDirs(FcpType):
+ All = 'all'
+ Downloads = 'downloads'
+ Nowhere = ''
+
+ ChoicesAll = (All, Downloads, Nowhere)
+ ChoicesAllowMultiple = False
+
+class FcpTypeChoiceNodeUploadAllowedDirs(FcpType):
+ All = 'all'
+ Nowhere = ''
+ ChoicesAll = (All, Nowhere)
+ ChoicesAllowMultiple = False
+
+class FcpTypeChoicePriorityPolicy(FcpType):
+ Hard = 'HARD'
+ Soft = 'SOFT'
+
+ ChoicesAll = (Hard, Soft)
+ ChoicesAllowMultiple = False
+
+
+class FcpTypeChoiceSSLVersion(FcpType):
+ Stl = 'STL'
+ SslV3 = 'SSLV3'
+ TlsV1 = 'TLSv1'
+
+ ChoicesAll = (Stl, SslV3, TlsV1)
+ ChoicesAllowMultiple = False
+
+
+#***************************************************************************************
+#
+# param types for config message
+#
+# ..bit more efford here, cos we need types for user input checking
+# ...a slpoppy implementation of a dict should be enough
+#
+#***************************************************************************************
+class ConfigMessageParams(object):
+
+ ComponentsSep = '.'
+
+
+ # first component of a config message param is always the param class
+
+ ParamClassCurrent = 'current'
+ ParamClassDefault = 'default'
+ ParamClassExpertFlag = 'expertFlag'
+ ParamClassForceWriteFlag = 'forceWriteFlag'
+ ParamClassShortDescription = 'shortDescription'
+ ParamClassLongDescription = 'longDescription'
+ ParamClassSortOrder = 'sortOrder'
+
+ ParamClasses = (
+ ParamClassCurrent,
+ ParamClassDefault,
+ ParamClassExpertFlag,
+ ParamClassForceWriteFlag,
+ ParamClassShortDescription,
+ ParamClassLongDescription,
+ )
+
+
+
+ # all known config keys (param class stripped)
+ Params = {
+
+ 'console.allowedHosts': FcpTypeIPList, # host names, single IPs CIDR-maskip IPs likee 192.168.0.0/24
+ 'console.bindTo': FcpTypeIPList,
+ 'console.directEnabled': FcpTypeBool,
+ 'console.enabled': FcpTypeBool,
+ 'console.port': FcpTypeIPort,
+ 'console.ssl': FcpTypeBool,
+
+
+ 'fcp.allowedHosts': FcpTypeIPList,
+ 'fcp.allowedHostsFullAccess': FcpTypeIPList,
+ 'fcp.assumeDownloadDDAIsAllowed': FcpTypeBool,
+ 'fcp.assumeUploadDDAIsAllowed': FcpTypeBool,
+ 'fcp.bindTo': FcpTypeIP,
+ 'fcp.enabled': FcpTypeBool,
+ 'fcp.persistentDownloadsEnabled': FcpTypeBool,
+ 'fcp.persistentDownloadsFile': FcpTypeFilename,
+ 'fcp.persistentDownloadsInterval': FcpTypeIntWithBounds(0, None),
+ 'fcp.port': FcpTypeIPort,
+ 'fcp.ssl': FcpTypeBool,
+
+
+ 'fproxy.CSSOverride': FcpTypeBool,
+ 'fproxy.advancedModeEnabled': FcpTypeBool,
+ 'fproxy.allowedHosts': FcpTypeIPList,
+ 'fproxy.allowedHostsFullAccess': FcpTypeIPList,
+ 'fproxy.bindTo': FcpTypeIPList,
+ 'fproxy.css': FcpTypeChoiceFProxyCss,
+ 'fproxy.doRobots': FcpTypeBool,
+ 'fproxy.enabled': FcpTypeBool,
+ 'fproxy.javascriptEnabled': FcpTypeBool,
+ 'fproxy.port': FcpTypeIPort,
+ 'fproxy.showPanicButton': FcpTypeBool,
+ 'fproxy.ssl': FcpTypeBool,
+
+
+ 'logger.dirname': FcpTypeDirname,
+ 'logger.enabled': FcpTypeBool,
+ 'logger.interval': FcpType, # ??? 1HOUR ??
+ 'logger.maxCachedBytes': FcpTypeNumBytes,
+ 'logger.maxCachedLines': FcpTypeNumBytes, # ???
+ 'logger.maxZippedLogsSize': FcpTypeNumBytes, # ???
+ 'logger.priority': FcpTypeChoiceLoggerPriority,
+ 'logger.priorityDetail': FcpType, # ???? is it Detailed priority thresholds ???
+
+
+ 'node.alwaysAllowLocalAddresses': FcpTypeBool,
+ 'node.assumeNATed': FcpTypeBool,
+ 'node.bindTo': FcpTypeIP,
+ 'node.clientThrottleFile': FcpTypeFilename,
+ 'node.databaseMaxMemory': FcpTypeNumBytes,
+ 'node.disableHangCheckers': FcpTypeBool,
+ 'node.disableProbabilisticHTLs': FcpTypeBool,
+ 'node.downloadAllowedDirs': FcpTypeChoiceNodeDownloadAllowedDirs,
+ 'node.downloadsDir': FcpTypeDirname,
+ 'node.extraPeerDataDir': FcpTypeDirname,
+ 'node.includeLocalAddressesInNoderefs': FcpTypeBool,
+ 'node.inputBandwidthLimit': FcpTypeNumBytes, # -1 is possible as value aswell
+ 'node.ipAddressOverride': FcpTypeIP,
+ 'node.l10n': FcpType, # ???
+ 'node.lazyResume': FcpTypeBool,
+ 'node.listenPort': FcpTypeIPort,
+ 'node.maxBackgroundUSKFetchers': FcpTypeIntWithBounds(0, None),
+ 'node.maxHTL': FcpTypeIntWithBounds(0, None),
+ 'node.name': FcpTypeString,
+ 'node.nodeDir': FcpTypeDirname,
+ 'node.oneConnectionPerIP': FcpTypeBool,
+ 'node.outputBandwidthLimit': FcpTypeNumBytes,
+ 'node.passOpennetPeersThroughDarknet': FcpTypeBool,
+ 'node.persistentTempDir': FcpTypeDirname,
+ 'node.storeDir': FcpTypeDirname,
+ 'node.storeForceBigShrinks': FcpTypeBool,
+ 'node.storeSize': FcpTypeNumBytes,
+ 'node.tempDir': FcpTypeDirname,
+ 'node.tempIPAddressHint': FcpTypeIP, # ???
+ 'node.testingDropPacketsEvery': FcpTypeIntWithBounds(0, None),
+ 'node.uploadAllowedDirs': FcpTypeChoiceNodeDownloadAllowedDirs,
+
+
+ 'node.testnet.enabled': FcpTypeBool,
+
+
+ 'node.load.aggressiveGC': FcpType, # ???
+ 'node.load.freeHeapBytesThreshold': FcpTypeNumBytes,
+ 'node.load.freeHeapPercentThreshold': FcpTypePercent,
+ 'node.load.memoryChecker': FcpTypeBool,
+ 'node.load.nodeThrottleFile': FcpTypeFilename,
+ 'node.load.threadLimit': FcpTypeIntWithBounds(0, None),
+
+
+ 'node.opennet.acceptSeedConnections': FcpTypeBool,
+ 'node.opennet.alwaysAllowLocalAddresses': FcpTypeBool,
+ 'node.opennet.assumeNATed': FcpTypeBool,
+ 'node.opennet.bindTo': FcpTypeIP,
+ 'node.opennet.enabled': FcpTypeBool,
+ 'node.opennet.listenPort': FcpTypeIPort,
+ 'node.opennet.maxOpennetPeers': FcpTypeIntWithBounds(0, None),
+ 'node.opennet.oneConnectionPerIP': FcpTypeBool,
+ 'node.opennet.testingDropPacketsEvery': FcpTypeIntWithBounds(0, None),
+
+ 'node.scheduler.CHKinserter_priority_policy': FcpTypeChoicePriorityPolicy,
+ 'node.scheduler.CHKrequester_priority_policy': FcpTypeChoicePriorityPolicy,
+ 'node.scheduler.SSKinserter_priority_policy': FcpTypeChoicePriorityPolicy,
+ 'node.scheduler.SSKrequester_priority_policy': FcpTypeChoicePriorityPolicy,
+
+ 'node.updater.URI': FcpTypeUri,
+ 'node.updater.autoupdate': FcpTypeBool,
+ 'node.updater.enabled': FcpTypeBool,
+ 'node.updater.extURI': FcpTypeUri,
+ 'node.updater.revocationURI': FcpTypeUri,
+
+
+ 'pluginmanager.loadplugin': FcpTypeStringList,
+ 'pluginmanager2.loadedPlugins': FcpTypeStringList,
+
+
+ 'ssl.sslEnable': FcpTypeBool,
+ 'ssl.sslKeyPass': FcpTypeString,
+ 'ssl.sslKeyStore': FcpTypeFilename,
+ 'ssl.sslKeyStorePass': FcpTypeString,
+ 'ssl.sslVersion': FcpTypeChoiceSSLVersion,
+
+ 'toadletsymlinker.symlinks': FcpTypeStringList,
+
+ }
+
+
+ def __init__(self):
+ pass
+
+
+ def splitAll(self, paramName):
+ return paramName.split(self.ComponentsSep)
+
+ def splitParamClass(self, paramName):
+ return paramName.split(self.ComponentsSep, 1)
+
+
+ def get(self, paramName, default=None):
+ try:
+ return self[paramName]
+ except KeyError:
+ return default
+
+
+ def __getitem__(self, paramName):
+ paramClass, paramKey = self.splitParamClass(paramName)
+ if paramClass == self.ParamClassCurrent:
+ return self.Params[paramKey]
+ elif paramClass == self.ParamClassDefault:
+ return self.Params[paramKey]
+ elif paramClass == self.ParamClassExpertFlag:
+ return FcpTypeBool
+ elif paramClass == self.ParamClassForceWriteFlag:
+ return FcpTypeBool
+ elif paramClass == self.ParamClassShortDescription:
+ return FcpTypeString
+ elif paramClass == self.ParamClassLongDescription:
+ return FcpTypeString
+ elif paramClass == self.ParamClassSortOrder:
+ return FcpTypeInt
+ else:
+ raise ValueError('Unknown param class in: %r' % paramName)
+
+#***************************************************************************************
+#
+# param types for peer message
+#
+# ..need to do a bit more here, cos it may be needed to validate user input
+#
+#***************************************************************************************
+PeerMessageParams = {
+ 'ark.number': FcpTypeInt,
+ 'auth.negTypes': FcpTypeInt,
+
+
+ 'location': FcpTypeFloat,
+ 'opennet': FcpTypeBool,
+ 'testnet': FcpTypeBool,
+
+ 'metadata.timeLastConnected': FcpTypeTime,
+ 'metadata.timeLastReceivedPacket': FcpTypeTime,
+ 'metadata.timeLastRoutable': FcpTypeTime,
+ 'metadata.timeLastSuccess': FcpTypeTime,
+ 'metadata.routableConnectionCheckCount': FcpTypeInt,
+ 'metadata.hadRoutableConnectionCount': FcpTypeInt,
+
+ 'volatile.averagePingTime': FcpTypeFloat,
+ 'volatile.overloadProbability': FcpTypePercent,
+ 'volatile.routingBackoff': FcpTypeInt,
+ 'volatile.routingBackoffPercent': FcpTypePercent,
+ 'volatile.totalBytesIn': FcpTypeInt,
+ 'volatile.totalBytesOut': FcpTypeInt,
+ 'volatile.routingBackoffLength': FcpTypeInt,
+ }
+
+'''all other Peer message params here....
+
+>> identity=YIrE..................
+>> lastGoodVersion=Fred,0.7,1.0,1106
+>> physical.udp=00.000.000.000:00000
+>> version=Fred,0.7,1.0,1107
+>> dsaGroup.q=ALFDN...............
+>> dsaGroup.p=AIYIrE..................
+>> dsaPubKey.y=YSlb............
+>> dsaGroup.g=UaRa...............
+>> ark.pubURI=SSK@......................
+>>
+>> metadata.detected.udp=000.000.000.000:00000
+
+>> volatile.lastRoutingBackoffReason=ForwardRejectedOverload
+>> volatile.percentTimeRoutableConnection=99.4735.................
+>> volatile.status=CONNECTED
+
+'''
+
+#***************************************************************************************
+#
+# param types for node message
+#
+#***************************************************************************************
+NodeMessageParams = {
+ 'ark.number': FcpTypeInt,
+ 'auth.negTypes': FcpTypeInt,
+ 'location': FcpTypeFloat,
+ 'opennet': FcpTypeBool,
+ 'testnet': FcpTypeBool,
+
+
+ 'volatile.allocatedJavaMemory': FcpTypeInt,
+ 'volatile.availableCPUs': FcpTypeInt,
+ 'volatile.averagePingTime': FcpTypeFloat,
+ 'volatile.avgStoreAccessRate': FcpTypePercent,
+ 'volatile.backedOffPercent': FcpTypePercent,
+ 'volatile.bwlimitDelayTime': FcpTypeFloat,
+ 'volatile.cacheAccess': FcpTypeInt,
+ 'volatile.cachedKeys': FcpTypeInt,
+ 'volatile.cachedSize': FcpTypeInt,
+ 'volatile.cachedStoreHits': FcpTypeInt,
+ 'volatile.cachedStoreMisses': FcpTypeInt,
+ 'volatile.freeJavaMemory': FcpTypeInt,
+ 'volatile.isUsingWrapper': FcpTypeBool,
+ 'volatile.locationChangePerMinute': FcpTypeFloat,
+ 'volatile.locationChangePerSession': FcpTypeFloat,
+ 'volatile.locationChangePerSwap': FcpTypeFloat,
+ 'volatile.maximumJavaMemory': FcpTypeInt,
+ 'volatile.maxOverallKeys': FcpTypeInt,
+ 'volatile.maxOverallSize': FcpTypeInt,
+ 'volatile.networkSizeEstimate24hourRecent': FcpTypeInt,
+ 'volatile.networkSizeEstimate48hourRecent': FcpTypeInt,
+ 'volatile.networkSizeEstimateSession': FcpTypeInt,
+ 'volatile.noSwaps': FcpTypeFloat,
+ 'volatile.noSwapsPerMinute': FcpTypeFloat,
+ 'volatile.numberOfARKFetchers': FcpTypeInt,
+ 'volatile.numberOfBursting': FcpTypeInt,
+ 'volatile.numberOfConnected': FcpTypeInt,
+ 'volatile.numberOfDisabled': FcpTypeInt,
+ 'volatile.numberOfDisconnected': FcpTypeInt,
+ 'volatile.numberOfInsertSenders': FcpTypeInt,
+ 'volatile.numberOfListening': FcpTypeInt,
+ 'volatile.numberOfListenOnly': FcpTypeInt,
+ 'volatile.numberOfNeverConnected': FcpTypeInt,
+ 'volatile.numberOfNotConnected': FcpTypeInt,
+ 'volatile.numberOfRemotePeerLocationsSeenInSwaps': FcpTypeFloat,
+ 'volatile.numberOfRequestSenders': FcpTypeInt,
+ 'volatile.numberOfRoutingBackedOff': FcpTypeInt,
+ 'volatile.numberOfSimpleConnected': FcpTypeInt,
+ 'volatile.numberOfTooNew': FcpTypeInt,
+ 'volatile.numberOfTooOld': FcpTypeInt,
+ 'volatile.numberOfTransferringRequestSenders': FcpTypeInt,
+ 'volatile.numberWithRoutingBackoffReasons.ForwardRejectedOverload': FcpTypeInt,
+ 'volatile.overallAccesses': FcpTypeInt,
+ 'volatile.overallKeys': FcpTypeInt,
+ 'volatile.overallSize': FcpTypeInt,
+ 'volatile.percentCachedStoreHitsOfAccesses': FcpTypePercent,
+ 'volatile.percentOverallKeysOfMax': FcpTypePercent,
+ 'volatile.percentStoreHitsOfAccesses': FcpTypePercent,
+ 'volatile.pInstantReject': FcpTypeFloat, # or percent?
+ 'volatile.recentInputRate': FcpTypeFloat,
+ 'volatile.recentOutputRate': FcpTypeFloat,
+ 'volatile.routingMissDistance': FcpTypeFloat,
+ 'volatile.runningThreadCount': FcpTypeInt,
+ 'volatile.startedSwaps': FcpTypeInt,
+ 'volatile.startupTime': FcpTypeTime,
+ 'volatile.storeAccesses': FcpTypeInt,
+ 'volatile.storeHits': FcpTypeInt,
+ 'volatile.storeKeys': FcpTypeInt,
+ 'volatile.storeMisses': FcpTypeInt,
+ 'volatile.storeSize': FcpTypeInt,
+ 'volatile.swaps': FcpTypeFloat,
+ 'volatile.swapsPerMinute': FcpTypeFloat,
+ 'volatile.swapsPerNoSwaps': FcpTypeFloat,
+ 'volatile.swapsRejectedAlreadyLocked': FcpTypeInt,
+ 'volatile.swapsRejectedLoop': FcpTypeInt,
+ 'volatile.swapsRejectedNowhereToGo': FcpTypeInt,
+ 'volatile.swapsRejectedRateLimit': FcpTypeInt,
+ 'volatile.swapsRejectedRecognizedID': FcpTypeInt,
+ 'volatile.totalInputBytes': FcpTypeInt,
+ 'volatile.totalInputRate': FcpTypeInt,
+ 'volatile.totalOutputBytes': FcpTypeInt,
+ 'volatile.totalOutputRate': FcpTypeInt,
+ 'volatile.totalPayloadOutputBytes': FcpTypeInt,
+ 'volatile.totalPayloadOutputPercent': FcpTypePercent,
+ 'volatile.totalPayloadOutputRate': FcpTypeInt,
+ 'volatile.unclaimedFIFOSize': FcpTypeInt,
+ 'volatile.uptimeSeconds': FcpTypeInt,
+ 'volatile.usedJavaMemory': FcpTypeInt,
+ }
+
+
+'''
+>>all other NodeData message params here....
+>>
+>> physical.udp=000.000.000.000:00000
+>> dsaPubKey.y=GgrpsNUK9m.................................................
+>> version=Fred,0.7,1.0,1107
+>> myName=whatever
+>> ark.pubURI=SSK@...............
+
+>> dsaGroup.q=ALFDNoq.....
+>> dsaGroup.p=AIYIrE9VNhM3.............
+>> volatile.avgConnectedPeersPerNode=15.35................
+>> dsaGroup.g=UaRa.............
+>> dsaPrivKey.x=Pwam..................
+>> ark.privURI=SSK@.................
+>> lastGoodVersion=Fred,0.7,1.0,1106
+>> sig=691f............
+>> identity=vMQa~..................
+
+'''
+#***************************************************************************************
+#
+# Mapping from message params to param types
+#
+# ...being lazy here, only types that are not strings are declared
+#
+#***************************************************************************************
+MessageParamTypes = {
+
+ # client messages
+
+ 'ListPeer': {
+ 'WithMetadata': FcpTypeBool,
+ 'WithVolantile': FcpTypeBool,
+ },
+
+ 'ListPeers': {
+ 'WithMetadata': FcpTypeBool,
+ 'WithVolantile': FcpTypeBool,
+ },
+
+ #'AddPeer': # added later as PeerMessageParams
+
+ 'ModifyPeer': {
+ 'AllowLocalAddresses': FcpTypeBool,
+ 'IsDisabled': FcpTypeBool,
+ 'ListenOnly': FcpTypeBool,
+ },
+
+ 'ModifyPeerNote': {
+ 'NoteText': FcpTypeBase64EncodedString,
+ },
+
+ 'GetNode': {
+ 'GiveOpennetRef': FcpTypeBool,
+ 'WithPrivate': FcpTypeBool,
+ 'WithVolatile': FcpTypeBool,
+ },
+ 'GetConfig': {
+ 'WithCurrent': FcpTypeBool,
+ 'WithDefaults': FcpTypeBool,
+ 'WithSortOrder': FcpTypeBool,
+ 'WithExpertFlag': FcpTypeBool,
+ 'WithForceWriteFlag': FcpTypeBool,
+ 'WithShortDescription': FcpTypeBool,
+ 'WithLongDescription': FcpTypeBool,
+ },
+
+ #'ModifyConfig': # added later as ConfigMessageParams()
+
+ 'TestDDARequest': {
+ 'WantReadDirectory': FcpTypeBool,
+ 'WantWriteDirectory': FcpTypeBool,
+ },
+ 'ClientPut': {
+ 'BinaryBlob': FcpTypeBool,
+ 'DontCompress': FcpTypeBool,
+ 'EarlyEncode': FcpTypeBool,
+ 'GetCHKOnly': FcpTypeBool,
+ 'Global': FcpTypeBool,
+ 'MaxRetries': FcpTypeInt,
+ 'Verbosity': FcpTypeInt,
+ },
+ 'ClientGet': {
+ 'BinaryBlob': FcpTypeBool,
+ 'Global': FcpTypeBool,
+ 'IgnoreDS': FcpTypeBool,
+ 'DSOnly': FcpTypeBool,
+ 'MaxSize': FcpTypeInt,
+ 'MaxTempSize': FcpTypeInt,
+ 'Verbosity': FcpTypeInt,
+ },
+ 'SubscribeUSK': {
+ 'DontPoll': FcpTypeBool,
+ },
+ 'WatchGlobal': {
+ 'Enabled': FcpTypeBool,
+ 'VerbosityMask': FcpTypeInt,
+ },
+ 'GetRequestStatus': {
+ 'Global': FcpTypeBool,
+ 'OnlyData': FcpTypeBool,
+ },
+ 'RemopvePersistentRequest': {
+ 'Global': FcpTypeBool,
+ },
+ 'ModifyPersistentRequest': {
+ 'Global': FcpTypeBool,
+ },
+ 'GetPluginInfo': {
+ 'Detailed': FcpTypeBool,
+ },
+
+
+
+ # node messages
+
+ 'NodeHello': {
+ 'Build': FcpTypeInt,
+ 'CompressionCodecs': FcpTypeInt,
+ 'ExtBuild': FcpTypeInt,
+ 'ExtRevision': FcpTypeInt,
+ 'FcpVersion': FcpTypeFloat,
+ 'Testnet': FcpTypeBool,
+ },
+
+ #'Peer': # added later as PeerMessageParams
+
+ 'PeerNote': {
+ 'NoteText': FcpTypeBase64EncodedString,
+ },
+
+
+ #'NodeData': # added later as NodeMessageParams
+ #'ConfigData': # added later as ConfigMessageParams()
+
+ 'TestDDAComplete': {
+ 'ReadDirectoryAllowed': FcpTypeBool,
+ 'WriteDirectoryAllowed': FcpTypeBool,
+ },
+ 'PutFetchable': {
+ 'Global': FcpTypeBool,
+ },
+ 'DataFound': {
+ 'Global': FcpTypeBool,
+ 'DataLength': FcpTypeInt,
+ },
+ 'AllData': {
+ 'Global': FcpTypeBool,
+ #NOTE: we ignore startup and completion time here as long as it is not passed in all related messages
+
+ },
+ 'FinishedCompression': {
+ 'OriginalSize': FcpTypeInt,
+ 'CompressedSize': FcpTypeInt,
+ },
+ 'SimpleProgress': {
+ 'Total': FcpTypeInt,
+ 'Required': FcpTypeInt,
+ 'Failed': FcpTypeInt,
+ 'FatalyFailed': FcpTypeInt,
+ 'Succeeded': FcpTypeInt,
+ 'Finalized': FcpTypeBool,
+ },
+ 'PersistentRequestRemoved': {
+ 'Global': FcpTypeBool,
+ },
+ 'PersistentRequestModified': {
+ 'Global': FcpTypeBool,
+ },
+ 'PutFailed': {
+ 'Global': FcpTypeBool,
+ 'Code': FcpTypeInt,
+ },
+ 'GetFailed': {
+ 'Code': FcpTypeInt,
+ 'ExpectedDataLength': FcpTypeInt_GetFailed_ExpectedDataLenght,
+ 'Fatal': FcpTypeBool,
+ 'FinalizedExpected': FcpTypeBool,
+ 'Global': FcpTypeBool,
+ },
+ 'ProtocolError': {
+ 'Code': FcpTypeInt,
+ 'Global': FcpTypeBool,
+ },
+
+ 'IdentifierCollision': {
+ 'Global': FcpTypeBool,
+ },
+ 'SubscribedUSKUpdate': {
+ 'Edition': FcpTypeInt,
+ },
+ 'GetPluginInfo': {
+ 'Started': FcpTypeBool,
+ },
+
+ }
+
+MessageParamTypes['ClientPutDiskDir'] = MessageParamTypes['ClientPut']
+MessageParamTypes['ClientComplexDir'] = MessageParamTypes['ClientPut']
+
+# TODO: "Started" param? Think we simply ignore it
+MessageParamTypes['PersistentGet'] = MessageParamTypes['ClientGet']
+MessageParamTypes['PersistentPut'] = MessageParamTypes['ClientPut']
+
+
+MessageParamTypes['ModifyConfig'] = MessageParamTypes['ConfigData'] = ConfigMessageParams()
+
+MessageParamTypes['Peer'] = MessageParamTypes['AddPeer'] = PeerMessageParams
+
+
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-01 14:46:05
|
Revision: 101
http://fclient.svn.sourceforge.net/fclient/?rev=101&view=rev
Author: jurner
Date: 2008-02-01 06:46:08 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
added plugin related mesages
experimental Upload class to tackle single / multiple item uploads
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-01 14:44:41 UTC (rev 100)
+++ trunk/sandbox/fcp/fcp2_0_client.py 2008-02-01 14:46:08 UTC (rev 101)
@@ -23,28 +23,64 @@
# problem of knowing when the node has actually registered a request. The node does not send
# an EndListPersistentRequests on connect so it is impossible to tell when or if to restore one of
# the pending requests we stored.
+#
+#FIX: None
#---------------------------------------------------------------------------------------------------------------------------------------------
# [0001893: CloseConnectionDuplicateClientName bug or feature?]
#
# CloseConnectionDuplicateClientName
# currently fcp takes down a our connection if another client (...) uses the same connection name.
+#
+#FIX: None
#----------------------------------------------------------------------------------------------------------------------------------------------
# [0001888: explicite connection locale]
#
# Many strings are already translated by freenet, but there is no way to tell the node wich language
# to use to talk to a client. Maybe a good idea, maybe not.
+#
+#FIX: None
#-----------------------------------------------------------------------------------------------------------------------------------------------
# [0001781: unregister directories registered via TestDDARequest]
#
# With current state of the art DDA handling it is not possiblr to unregister directories (may pile
# up in memory over time).
+#
+#FIX: None
#------------------------------------------------------------------------------------------------------------------------------------------------
# [0002019: Socket dies if first message is not ClientHello]
#
# minor one
+#
+#FIX: None
+#------------------------------------------------------------------------------------------------------------------------------------------------
+# [0001965: Persistence vs PersistenceType]
+#
+# PersistentGet passes persistence field as "PersistenceType", PersistentPut as "Persistence"
+# already fixed this here in the client
+#
+# FIX: implemented in client
#-------------------------------------------------------------------------------------------------------------------------------------------------
+# [0002015: Drop the global queue]
+#
+# this one is somewhat related to [0001931: Send EndListPersistentRequests following client connect]
+#
+# We never use or watch the global queue. It is to dangerous. But problems remain when it comes
+# to restoring persistent requests. Shure these are our requests? Worst case is a client with a colliding
+# connection name flooding our client with an unknown number of left overs.
+#
+#FIX: None (that is, this case is handled as savely as possible - except from possible slowdowns - but no
+# guarantee that no unknown request may slip through)
+#-------------------------------------------------------------------------------------------------------------------------------------------------
+# [0001894: HandleCollision field in ClientGet]
+#
+# minor one. When downloading a file, filename collisions may occur. Fcp does not handle these very well
+# It checks if the tempfile (filename ?) can be created newly when the request is started. IIRC In the final
+# rename of the tempfile to filename no check is done and filename will get overwritten.
+#
+#FIX: we handle collisions in the client as savely as possible. But no guarantee either when a colliding file
+# (...) finds his way into the download directory while downloading another.
+#------------------------------------------------------------------------------------------------------------------------------------------------
-
import atexit
import cPickle
import logging
@@ -143,13 +179,16 @@
except ValueError:
DefaultFcpPort = 9481
+
+
#TODO: check if required
# suggested by Mathew Toseland to use about 32k for mimeType requests
# basic sizes of keys are: 1k for SSks and 32k for CHKs
# without MaxSize DataFound will have DataLength set to 0 (?!)
MaxSizeKeyInfo = '32000'
SocketTimeout = 0.1
- Version = '2.0'
+ ExpectedFcpVersion = 2.0
+ ExpectedNodeBuild = 1107
from fcp2_0_config import Config
from fcp2_0_consts import (
@@ -159,6 +198,7 @@
FetchError,
FilenameCollision,
InsertError,
+ KeyType,
LogMessages,
PeerNodeStatus,
PeerNoteType,
@@ -207,8 +247,14 @@
'PeerNote',
+ # plugins
+ 'PluginInfo',
+ 'PluginInfoFailed',
+ 'PluginMessage'
+ 'PluginMessagefailed',
+
# others
- 'SSKKeypair',
+ 'KeypairGenerated',
###############################
@@ -232,10 +278,11 @@
"""
self._connectionName = self.setConnectionName(connectionName)
self._ddaTests = [] # currently running DDA tests (request0, ... requestN)
- self._sskRequests = {} # currently pending ssk requests (sskIdentifier --> request)
+ self._sskRequests = [] # currently pending ssk requests (identifier1... identiferN)
self._requests = {} # currently running requests (requestIdentifier --> request)
self._log = logging.getLogger(self.__class__.__name__)
+ self._nodeHelloMessage = None
self._socket = None
self.events = self.Events()
@@ -359,8 +406,11 @@
# fix some Fcp inconsistencies ClientGet vs. PersistentGet
if msg.name == self.Message.MessagePersistentGet:
del msg.params['Started']
+ #FIX: [0001965: Persistence vs PersistenceType]
if 'PersistenceType' in msg.params:
msg['Persistence'] = msg.params.pop('PersistenceType')
+ elif msg.name == self.Message.MessagePersistentPut:
+ del msg.params['Started']
return msg
@@ -385,9 +435,9 @@
self._ddaTests = []
self._requests = {}
- self._sskRequests = {}
+ self._sskRequests = []
-
+
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
@@ -428,18 +478,31 @@
self.sendMessage(
self.Message.MessageClientHello,
Name=self._connectionName,
- ExpectedVersion=self.Version,
+ ExpectedVersion=self.ExpectedFcpVersion,
)
while timeElapsed <= duration:
msg = self.next(dispatch=False)
+
if msg.name == self.Message.MessageClientSocketTimeout:
timeElapsed += self.SocketTimeout
yield None
+
elif msg.name == self.Message.MessageNodeHello:
+ self._nodeHelloMessage = msg
self._log.debug(self.LogMessages.MessageReceived + msg.pprint())
- self.events.ClientConnected(msg)
- yield msg
+ # check if version is ok
+ if self.versionCheckNodeHello(msg):
+ self.events.ClientConnected(msg)
+ else:
+ self.close()
+ msg = self.Message(
+ self.Message.MessageClientDisconnected,
+ DisconnectReason=self.DisconnectReason.VersionMissmatch
+ )
+ self.events.ClientDisconnected(msg)
+ yield self._nodeHelloMessage
raise StopIteration
+
else:
self._log.debug(self.LogMessages.MessageReceived + msg.pprint())
break
@@ -497,6 +560,18 @@
stdout, stderr = p.communicate()
return stdout
+
+ def versionCheckNodeHello(self, nodeHelloMessage):
+ """Performa a version check of the client against the specified NodeHello message
+ @return: (bool) True if version is ok, False otherwise
+ @note: if this check returns False the client will emidiately disconnect in L{connect()}
+ and triggers a ClientDisconnected event. Overwrite to adjust
+ """
+ if nodeHelloMessage['FCPVersion'] >= self.ExpectedFcpVersion:
+ if nodeHelloMessage['Build'] >= self.ExpectedNodeBuild:
+ return True
+ return False
+
#########################################################
##
## runtime related methods
@@ -553,7 +628,7 @@
self.Message.MessageClientDisconnected,
DisconnectReason=DisconnectReason.Shutdown,
)
- self.events.ClientDisconnect(msg)
+ self.events.ClientDisconnected(msg)
return True
@@ -564,12 +639,8 @@
ddaRequestMsg['WantWriteDirectory'] = True
directory = os.path.dirname(initialRequest['Filename'])
else:
-
- #TODO: determine directory for other cases
- raise RuntimeError(NotImplemented)
-
ddaRequestMsg['WantReadDirectory'] = True
- directory = None
+ directory = os.path.dirname(initialRequest['Filename'])
ddaRequestMsg['Directory'] = directory
@@ -607,6 +678,30 @@
initialRequest['FcFilenameCollision'] &= ~self.FilenameCollision.CollisionHandled
+ # handle plugin related request failures
+ elif code == self.ProtocolError.NoSuchPlugin:
+ if initialRequest.name == self.Message.MessagePluginInfo:
+ del self._requests[requestIdentifier]
+ self.events.PluginInfoFailed(initialRequest)
+ return True
+ elif initialRequest.name == self.Message.MessageFCPPluginMessage:
+ del self._requests[requestIdentifier]
+ self.events.PluginMessageFailed(initialRequest)
+ return True
+
+ elif code == self.ProtocolError.AccessDenied:
+ if initialRequest.name == self.Message.MessagePluginInfo:
+ del self._requests[requestIdentifier]
+ self.events.PluginInfoFailed(initialRequest)
+ return True
+ # TODO: just a guess that FCPPluginMessage can trigger an AccessDenied error
+ elif initialRequest.name == self.Message.MessageFCPPluginMessage:
+ del self._requests[requestIdentifier]
+ self.events.PluginMessageFailed(initialRequest)
+ return True
+
+
+
# only requests should get through to here
# NOTE: Fcp already removed the request
@@ -776,10 +871,6 @@
elif msg.name == self.Message.MessagePersistentGet:
- # NOTE:
- # Fcp does no good job in handling persistent requests and identifiers. Already dropped some
- # notes and reports regarding this. See freenet-tech mailing list [Fcp notes and issues]
-
# unknown request... try to restore it
if initialRequest is None:
restoredRequest = self._restorePersistentRequestFromNode(msg)
@@ -793,7 +884,10 @@
)
return True
+ # determine initial message name
restoredRequest.name = self.Message.MessageClientGet
+
+ # restore request
self._requests[requestIdentifier] = restoredRequest
restoredRequest['FcStatus'] = self.Message.StatusStarted
self.events.RequestRestored(restoredRequest)
@@ -810,7 +904,48 @@
return True
+ elif msg.name == self.Message.MessagePersistentPut:
+
+ # unknown request... try to restore it
+ if initialRequest is None:
+ restoredRequest = self._restorePersistentRequestFromNode(msg)
+
+ # not one of our requests... so cancel it
+ if restoredRequest is None or CancelPersistentRequests:
+ self.sendMessage(
+ self.Message.MessageRemovePersistentRequest,
+ Identifier=msg['Identifier'],
+ Global=msg['Global'],
+ )
+ return True
+
+ # determine initial message name
+ if restoredRequest['FcSubType'] == self.Message.SubTypePut:
+ restoredRequest.name = self.Message.MessageClientPut
+ elif restoredRequest['FcSubType'] == self.Message.SubTypePutDiskDir:
+ restoredRequest.name = self.Message.MessageClientPutDiskDir
+ elif restoredRequest['FcSubType'] == self.Message.SubTypePutComplexDir:
+ restoredRequest.name = self.Message.MessageClientPutComplexDir
+
+ # restore request
+ self._requests[requestIdentifier] = restoredRequest
+ restoredRequest['FcStatus'] = self.Message.StatusStarted
+ self.events.RequestRestored(restoredRequest)
+ return True
+
+ # known request... filter out multiple PersistentGets
+ if initialRequest['FcStatus'] == self.Message.StatusPending:
+ initialRequest['FcStatus'] = self.Message.StatusStarted
+
+ #TODO: update initialRequest with params from PersistentPut?
+ #TODO: update initialRequest with params from PersistentPut?
+
+ self.events.RequestStarted(initialRequest)
+ return True
+
+ return True
+
elif msg.name == self.Message.MessagePersistentRequestModified:
if initialRequest is None:
return False
@@ -925,21 +1060,49 @@
####################################################
##
+ ## plugins
+ ##
+ ####################################################
+ elif msg.name == self.Message.MessagePluginInfo:
+ if initialRequest is None:
+ return False
+
+ del self._requests[requestIdentifier]
+ self.events.PluginInfo(msg)
+ return True
+
+ elif msg.name == self.Message.MessageFCPPluginReply:
+ if initialRequest is None:
+ return False
+
+ del self._requests[requestIdentifier]
+ self.events.PluginMessage(msg)
+ return True
+
+ ####################################################
+ ##
## others
##
####################################################
elif msg.name == self.Message.MessageSSKKeypair:
- if initialRequest is None:
- self.events.SSKKeypair(msg)
- return True
+ if requestIdentifier not in self._sskRequests:
+ return False
- initialRequest['Uri'] = msg['InsertUri']
- initialRequest['FcRequestUri'] = msg['RequestUri']
- self.sendMessageEx(initialRequest)
+ self._sskRequests.remove(requestIdentifier)
+ #TODO:no idea if the node may pass uris with prefixes like 'freenet:'... strip it anyways
+ insertURI = self.Uri(msg['InsertURI']).uri
+ requestURI = self.Uri(msg['RequestURI']).uri
+ keyType = consts.KeyType.USK if requestIdentifier.startswith(consts.KeyType.USK) else consts.KeyType.SSK
+ if keyType == consts.KeyType.USK:
+ insertURI = requestURI.replace(consts.KeyType.SSK, consts.KeyType.USK, 1)
+ requestURI = requestURI.replace(consts.KeyType.SSK, consts.KeyType.USK, 1)
+
+ msg['InsertURI'] = insertURI
+ msg['RequestURI'] = requestURI
+ msg['FcKeyType'] = keyType
+ self.events.KeypairGenerated(msg)
return True
-
-
elif msg.name == self.Message.MessageCloseConnectionDuplicateClientName:
msg = self.Message(
@@ -1273,6 +1436,38 @@
## ClientPut related methods
##
########################################################
+ def clientPutUpload(self, upload, userData=None, persistentUserData=''):
+
+ msg = upload.getMessage(self.Message)
+ if msg is None:
+ raise ValueError('Nothing to upload')
+
+ # determine SubType
+ if msg.name == self.Message.MessageClientPut:
+ messageSubType = self.Message.SubTypePut
+ elif msg.name == self.Message.MessageClientPutDiskDir:
+ messageSubType = self.Message.SubTypePutDiskDir
+ else:
+ messageSubType = self.Message.SubTypePutComplexDir
+
+ self._registerRequest(
+ msg,
+ userData,
+ messageSubType,
+ time.time(),
+ persistentUserData,
+ #filenameCollision=filenameCollision,
+ )
+
+ if upload.keyType in (consts.KeyType.SSK, consts.KeyType.USK):
+ msg['FcRequestUri'] = upload.publicKey
+ #NOTE: the caller may use the 'FcInsertUri' member to store the private key
+
+
+ self.sendMessageEx(msg)
+ return msg['Identifier']
+
+
def clientPut(self,
uri,
messageSubType,
@@ -1303,9 +1498,11 @@
#TODO: method names
#CHK
+
+
def putData(self,
data,
-
+
contentType=None,
dontCompress=None,
maxRetries=None,
@@ -1316,10 +1513,11 @@
userData=None,
persistentUserData='',
):
+ """"""
return self.clientPut(
- self.Uri.KeyCHK,
- self.Message.SubTypePutData,
+ consts.KeyType.CHK,
+ self.Message.SubTypePut,
userData,
persistentUserData,
data,
@@ -1334,34 +1532,48 @@
MaxRetries=maxRetries,
DontCompress=dontCompress,
Persistence=persistence,
- TergetFilename=targetFilename,
+ TargetFilename=targetFilename,
UploadFrom=self.UploadFrom.Direct,
Verbosity=self.Verbosity.ReportProgress | self.Verbosity.ReportCompression,
)
- def putFile(self):
- pass
+ def putFile(self,
+ filename,
+
+ contentType=None,
+ dontCompress=None,
+ maxRetries=None,
+ persistence=consts.Persistence.Connection,
+ priorityClass=consts.Priority.Medium,
+ targetFilename=None,
+
+ userData=None,
+ persistentUserData='',
+
+ ):
+ return self.clientPut(
+ concts.KeyType.CHK,
+ self.Message.SubTypePut,
+ userData,
+ persistentUserData,
+ None,
+
+ # fcp params
+ Filename=filename,
+ ContentType=contentType,
+ #EarlyEncode='false',
+ #GetCHKOnly='false',
+ Global=False,
+ Identifier=None,
+ MaxRetries=maxRetries,
+ DontCompress=dontCompress,
+ Persistence=persistence,
+ TergetFilename=targetFilename,
+ UploadFrom=self.UploadFrom.Disk,
+ Verbosity=self.Verbosity.ReportProgress | self.Verbosity.ReportCompression,
+ )
- #KSK
- def putNamedData(self):
- pass
-
- def putReference(self):
- pass
-
-
- #SSK
- def putUpdatableData(self):
- pass
-
-
- #USK
- def putVersionedData(self):
- pass
-
-
-
########################################################
##
## request related methods
@@ -1530,18 +1742,79 @@
##########################################################
##
+ ## plugins
+ ##
+ ##########################################################
+ #TODO: curently it is just a guess the a plugin may respond with a IdentifierCollision
+ 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
+ msg = self.Message(
+ self.Message.MessageGetPluginInfo,
+ Identifier=identifier,
+ PluginName=pluginName,
+ Detailed=detailed,
+ )
+ self._requests[identifier] = msg
+ self.sendMessageEx(msg)
+ return identifier
+
+
+ def sendPluginMessage(self, pluginName, params, data=None):
+ """Sends a message to a plugin
+ @param pluginName: name of the plugin to send the message to
+ @param poarams: (dict) additional params to pass to the plugin (each parameter has to be prefixed with 'Param.')
+ @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
+ msg = self.Message(
+ self.Message.MessageGetPluginInfo,
+ Identifier=identifier,
+ PluginName=pluginName,
+ **params
+ )
+ if data is not None:
+ msg['DataLength'] = len(data)
+ msg.data = data
+
+ self._requests[identifier] = msg
+ self.sendMessageEx(msg)
+ return identifier
+
+
+
+
+ ##########################################################
+ ##
## others
##
##########################################################
- def generateSSK(self):
+ def generateKeypair(self, keypairType=consts.KeyType.SSK):
"""
- @event: SSKKeypair(event, params), triggered when the request is complete
+ @param keypairType: type of keypair to generate (either L{KeyType.SSK} or L{KeyType.SSK})
@return: identifier of the request
+ @event: KeypairGenerated(event, params) is triggered when the request is complete
"""
+
+ 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 = uuid.uuid_time()
+ identifier = keypairType + uuid.uuid_time()
if identifier not in self._sskRequests:
break
+ self._sskRequests.append(identifier)
self.sendMessage(
self.Message.MessageGenerateSSK,
Identifier=identifier,
@@ -1562,7 +1835,7 @@
if nodeHello is not None:
- #for i in xrange(5):
+ #for i in xrange(50):
# c.next()
@@ -1623,9 +1896,26 @@
def testPutData():
- identifier = c.putData(
+ myIdentifier = c.putData(
'test123',
+ #persistence=c.Persistence.Reboot,
)
+
+ for i in xrange(100):
+ c.next()
+ c.removeRequest(myIdentifier)
+ for i in xrange(5):
+ c.next()
+
+ #testPutData()
+
+
+ def testPutFile():
+ fpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test.jpg')
+
+ identifier = c.putFile(
+ fpath,
+ )
for i in xrange(1000):
c.next()
@@ -1633,11 +1923,9 @@
for i in xrange(5):
c.next()
- #testPutData()
-
+ #testPutFile()
-
def testConfigData():
from fcp2_0_config import Config
@@ -1688,32 +1976,39 @@
#testNodeData()
- def testGenerateSSK():
+ def testGenerateKeypair():
- #def cb(event, msg):
- # pass
-
-
- #c.events.NodeData += cb
- c.generateSSK()
+ def cb(event, msg):
+ print msg.pprint()
+
+ c.events.KeypairGenerated += cb
+ c.generateKeypair('SSK@')
+ c.generateKeypair('USK@')
for i in xrange(10):
c.next()
- #testGenerateSSK()
+ #testGenerateKeypair()
- def testListPeers():
- c.listPeers()
- for i in xrange(10):
- c.next()
-
- #testListPeers()
+ def testListPeers():
+ c.listPeers()
+ for i in xrange(10):
+ c.next()
+
- def testGetNode():
- c.getNode()
- for i in xrange(10):
- c.next()
+ #testListPeers()
- #testGetNode()
+ def testGetNode():
+ c.getNode()
+ for i in xrange(10):
+ c.next()
+
+ #testGetNode()
-
\ No newline at end of file
+ def testGetPluginInfo():
+ c.getPluginInfo('plugins.XMLLibrarian')
+ for i in xrange(10):
+ c.next()
+
+ #testGetPluginInfo()
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-01 14:44:41
|
Revision: 100
http://fclient.svn.sourceforge.net/fclient/?rev=100&view=rev
Author: jurner
Date: 2008-02-01 06:44:41 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
refactor a bit and a few more messages
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_consts.py
Modified: trunk/sandbox/fcp/fcp2_0_consts.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_consts.py 2008-02-01 14:43:34 UTC (rev 99)
+++ trunk/sandbox/fcp/fcp2_0_consts.py 2008-02-01 14:44:41 UTC (rev 100)
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
"""Freennet Client Protocol consts and type mappings"""
import base64
@@ -125,8 +127,8 @@
PeerExists = '29'
OpennetDisabled = 30
DarknetPeerOnly = 31
+ NoSuchPlugin = 32
-
# others
class ConnectReason:
@@ -150,6 +152,7 @@
SocketDied = 2
ConnectingFailed = 3
DuplicateConnectionName = 4
+ VersionMismatch = 5 #TODO: implement???
class FilenameCollision:
@@ -161,6 +164,18 @@
CollisionHandled = 0x10000000 # a filename collision has already been handled
+class KeyType:
+ SSK = 'SSK@'
+ KSK = 'KSK@'
+ CHK = 'CHK@'
+ USK = 'USK@'
+ SVK = 'SVK@'
+ Invalid = ''
+ TypesAll = (SSK, KSK, CHK, USK, SVK)
+
+
+
+
class LogMessages:
"""Message strings used for log infos"""
Connecting = 'connecting to node...'
@@ -234,15 +249,8 @@
#*************************************************************************************
# python <--> fcp value mappings
#*************************************************************************************
-#TODO: reqork Clss.validateFcpValue
-
class FcpType(object):
- # consts for validation
- ValidatesInvalid = 0x0
- ValidatesValid = 0x1
- ValidatesIncomlete = 0x2
-
@classmethod
def pythonToFcp(clss, value):
return value
@@ -250,28 +258,19 @@
@classmethod
def fcpToPython(clss, value):
return value
-
- @classmethod
- def validateFcpValue(clss, value):
- return clss.ValidatesValid
-
-
+
+
class FcpTypeString(FcpType):
@classmethod
def pythonToFcp(clss, value):
- return str(value) #TODO: ??? unicode ???
+ return str(value) #TODO: unicode ???
@classmethod
def fcpToPython(clss, value):
return value
-
- @classmethod
- def validateFcpValue(clss, value):
- return clss.ValidatesValid
-
class FcpTypeBool(FcpType):
@classmethod
@@ -282,12 +281,6 @@
def fcpToPython(clss, value):
return value == FcpTrue
- @classmethod
- def validateFcpValue(clss, value):
- if value in ('true', 'false'):
- return self.ValidatesValid
- return self.ValidatesInvalid
-
class FcpTypeInt(FcpType):
@@ -299,13 +292,6 @@
def fcpToPython(clss, value):
return int(value)
- @classmethod
- def validateFcpValue(clss, value):
- try:
- return int(value)
- except ValueError:
- return None
-
class FcpTypeFloat(FcpType):
@@ -317,15 +303,7 @@
def fcpToPython(clss, value):
return float(value)
- @classmethod
- def validateFcpValue(clss, value):
- try:
- return float(value)
- except ValueError:
- return None
-
-
# GetFailed sets the ExpectedDataLenght field to '' (empty string). Fix this to show up as -1
class FcpTypeInt_GetFailed_ExpectedDataLenght(FcpType):
@@ -339,17 +317,7 @@
return -1
return int(value)
- @classmethod
- def validateFcpValue(clss, value):
- if value == '':
- return -1
- try:
- return int(value)
- except ValueError:
- return None
-
-
class FcpTypeIntWithBounds(FcpType):
def __init__(self, lowerBound, upperBound):
@@ -362,23 +330,7 @@
def fcpToPython(self, value):
return int(value)
- def validateFcpValue(self, value):
- try:
- n = int(value)
- except ValueError:
- return None
-
- if self.lowerBound is not None:
- if n >= self.lowerBound:
- return n
- if self.upperBound is not None:
- if n <= self.upperBound:
- return n
-
- return None
-
-
class FcpTypeBase64EncodedString(FcpType):
@classmethod
@@ -389,13 +341,6 @@
def fcpToPython(clss, value):
return base64.b64decode(value)
- @classmethod
- def validateFcpValue(clss, value):
- pass
- #TODO: no idea
-
-
-
class FcpTypeTime(FcpType):
@@ -407,45 +352,19 @@
def fcpToPython(clss, value):
return int(value) / 1000
- @classmethod
- def validateFcpValue(clss, value):
- try:
- return clss.fcpToPython(value)
- except ValueEror:
- return none
-class FcpTypeIP(FcpType):
- pass
+class FcpTypeIP(FcpType): pass
+class FcpTypeIPList(FcpType): pass
+class FcpTypeIPort(FcpType): pass
+class FcpTypeStringList(FcpType): pass
+class FcpTypeDirname(FcpType): pass
+class FcpTypeFilename(FcpType): pass
+class FcpTypeNumBytes(FcpType): pass
+class FcpTypePercent(FcpTypeFloat): pass
+class FcpTypeUri(FcpType): pass
-#TODO: check if comma separated or colon separated
-class FcpTypeIPList(FcpType):
- pass
-
-class FcpTypeIPort(FcpType):
- pass
-class FcpTypeStringList(FcpType):
- pass
-
-class FcpTypeDirname(FcpType):
- pass
-
-class FcpTypeFilename(FcpType):
- pass
-
-
-class FcpTypeNumBytes(FcpType):
- pass
-
-class FcpTypePercent(FcpTypeFloat):
- pass
-
-
-class FcpTypeUri(FcpType):
- pass
-
-
# special choice types for config message
@@ -864,8 +783,6 @@
>> identity=vMQa~..................
'''
-
-
#***************************************************************************************
#
# Mapping from message params to param types
@@ -955,16 +872,21 @@
'ModifyPersistentRequest': {
'Global': FcpTypeBool,
},
+ 'GetPluginInfo': {
+ 'Detailed': FcpTypeBool,
+ },
+
# node messages
'NodeHello': {
+ 'Build': FcpTypeInt,
'CompressionCodecs': FcpTypeInt,
+ 'ExtBuild': FcpTypeInt,
+ 'ExtRevision': FcpTypeInt,
+ 'FcpVersion': FcpTypeFloat,
'Testnet': FcpTypeBool,
-
- #TODO: ExtBuild et al. ???
-
},
#'Peer': # added later as PeerMessageParams
@@ -1032,7 +954,10 @@
},
'SubscribedUSKUpdate': {
'Edition': FcpTypeInt,
- },
+ },
+ 'GetPluginInfo': {
+ 'Started': FcpTypeBool,
+ },
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-01 14:43:33
|
Revision: 99
http://fclient.svn.sourceforge.net/fclient/?rev=99&view=rev
Author: jurner
Date: 2008-02-01 06:43:34 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
added a few message
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_message.py
Modified: trunk/sandbox/fcp/fcp2_0_message.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_message.py 2008-02-01 14:43:03 UTC (rev 98)
+++ trunk/sandbox/fcp/fcp2_0_message.py 2008-02-01 14:43:34 UTC (rev 99)
@@ -11,7 +11,7 @@
# we add a few private params...
- ParamPrefixPrivate = 'Fc'
+ ParamPrefixPrivate = 'Fc' # params prefixed with this are skipped when generating the message
# client messages
@@ -33,6 +33,8 @@
MessageClientPutDiskDir = 'ClientPutDiskDir'
MessageClientPutComplexDir = 'ClientPutComplexDir'
MessageClientGet = 'ClientGet'
+ MessageGetPluginInfo = 'GetPluginInfo'
+ MessageFCPPluginMessage = 'FCPPluginMessage'
MessageSubscribeUSK = 'SubscribeUSK'
MessageWatchGlobal = 'WatchGlobal'
MessageGetRequestStatus = 'GetRequestStatus'
@@ -75,6 +77,8 @@
MessageUnknownNodeIdentifier = 'UnknownNodeIdentifier'
MessageUnknownPeerNoteType = 'UnknownPeerNoteType'
MessageSubscribedUSKUpdate = 'SubscribedUSKUpdate'
+ MessagePluginInfo = 'PluginInfo'
+ MessageFCPPluginReply = 'FCPPluginReply'
# client messages (internal use only)
MessageClientSocketTimeout = 1
@@ -87,7 +91,7 @@
SubTypeGetData = 1
SubTypeGetFile = 2
SubTypeGetKeyInfo = 3
- SubTypePutData = 4
+ SubTypePut = 4
SubTypePutDiskDir = 5
SubTypePutComplexDir = 6
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-01 14:43:04
|
Revision: 98
http://fclient.svn.sourceforge.net/fclient/?rev=98&view=rev
Author: jurner
Date: 2008-02-01 06:43:03 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
some fixes
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_uri.py
Modified: trunk/sandbox/fcp/fcp2_0_uri.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_uri.py 2008-02-01 14:42:18 UTC (rev 97)
+++ trunk/sandbox/fcp/fcp2_0_uri.py 2008-02-01 14:43:03 UTC (rev 98)
@@ -3,6 +3,8 @@
import base64
import re
import urlparse
+
+import fcp2_0_consts as consts
#**************************************************************************************
# freenet base64 for keys
#**************************************************************************************
@@ -38,7 +40,7 @@
#***************************************************************************************
KeyPat = re.compile(
r'''
-^(CHK | SSK | SVK | USK) @
+^(CHK | SSK | SVK | USK @)
(
[a-z0-9\-~]{43},
[a-z0-9\-~]{43},
@@ -49,8 +51,8 @@
def keyType(uri):
"""Returns the ky type of a freenet key or None if the type could not be determined"""
- if uri.startswith('KSK@'):
- return 'KSK'
+ if uri.startswith(consts.KeyType.KSK):
+ return consts.KeyType.KSK
result = KeyPat.match(uri)
if result is None:
return None
@@ -67,32 +69,26 @@
class Uri(object):
+
+ KeyType = consts.KeyType
+
- KeyTypeSSK = 'SSK'
- KeyTypeKSK = 'KSK'
- KeyTypeCHK = 'CHK'
- KeyTypeUSK = 'USK'
- KeyTypeSVK = 'SVK'
- KeyTypeInvalid = ''
- KeysTypesAll = (KeyTypeSSK, KeyTypeKSK, KeyTypeCHK, KeyTypeUSK, KeyTypeSVK)
-
-
def __init__(self, uri):
self.uri = stripUri(uri)
result = keyType(self.uri)
- self.keyType = self.KeyTypeInvalid if result is None else result
+ self.keyType = self.KeyType.Invalid if result is None else result
def __nonzero__(self):
- return self.keyType != self.KeyTypeInvalid
+ return self.keyType != self.KeyType.Invalid
def split(self):
"""Splits the uri
@return: tuple(freenet-key, file-name)
"""
- if self.keyType() != self.KeyUnknown:
+ if self.keyType() != self.KeyType.Invalid:
head, sep, tail = self.uri.partition('/')
return head, tail
return self.uri, ''
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-01 14:42:16
|
Revision: 97
http://fclient.svn.sourceforge.net/fclient/?rev=97&view=rev
Author: jurner
Date: 2008-02-01 06:42:18 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
experimental to tackle uploads
Added Paths:
-----------
trunk/sandbox/fcp/fcp_2_0_requests.py
Added: trunk/sandbox/fcp/fcp_2_0_requests.py
===================================================================
--- trunk/sandbox/fcp/fcp_2_0_requests.py (rev 0)
+++ trunk/sandbox/fcp/fcp_2_0_requests.py 2008-02-01 14:42:18 UTC (rev 97)
@@ -0,0 +1,231 @@
+"""fcp request objects"""
+
+import fcp2_0_consts as consts
+#******************************************************************************************************************
+#
+#******************************************************************************************************************
+class Upload(object):
+ """Wrapper class to represent a freenet upload
+
+ @note: you can upload one or more items of any kind (data, files, redirects), except from directories
+ wich have to be the only item to upload
+ """
+
+
+ ReservedParamPrefix = 'Fc' # params prefixed with this are skipped when generating the message
+
+ ItemTypeData = 0
+ ItemTypeDirectory = 1
+ ItemTypeFile = 2
+ ItemTypeRedirect = 3
+
+ def __init__(self,
+ keyType,
+ dontCompress=None,
+ earlyEncode=None,
+ maxRetries=None,
+ persistence=consts.Persistence.Connection,
+ priorityClass=consts.Priority.Medium,
+
+ privateKey=None,
+ ):
+ """
+ @param keyType: (L{consts.KeyType}) the desired key type to upload
+ @param dontCompress:
+ @param earlyEncode:
+ @param maxRetries:
+ @param persistence:
+ @param priorityClass:
+
+ @param privateKey: (str) privateKey if keyType is SSK or USK
+ """
+
+ if keyType not in consts.KeyType.TypesAll:
+ raise ValueError('Invalid key type: %r' % keyType)
+
+ self.items = []
+ self.keyType = keyType
+ self.params = {
+ 'DontCompress': dontCompress,
+ 'EarlyEncode': earlyEncode,
+ 'MaxRetries': maxRetries,
+ 'Persistence': persistence,
+ 'PriorityClass': priorityClass,
+ }
+ self.privateKey = privateKey
+ self._directoryAdded = False
+ self._targetNames = [] # record to check if names are unique (assert order is arbitrary)
+
+
+
+
+ def _addItem(self, **params):
+ """Private method to add an upload item"""
+ if self._directoryAdded:
+ raise ValueError('A directory has already been added, no other items allowed')
+
+ if itemType == self.ItemTypeDirectory:
+ if self._directoryAdded:
+ raise ValueError('An item has already been added, no additional directory allowed')
+ else:
+ self._directoryAdded = True
+
+ name = params['Name']
+ if name in self._targetNames:
+ raise ValueError('Target name already exists: %r' % name)
+
+ self.targetNames.append(name)
+ self.iotems.append(params)
+
+
+ def addData(self, name, data, contentType=None):
+ """Adds data to be uploaded
+ @param name: target name
+ @param data: (str) data to upload
+ @param contentType: (str) content type of the data (if desired)
+ """
+ return self._addItem(
+ FcItemType=self.ItemTypeData,
+ FcData=data,
+ ContentType=contentType,
+ DataLength=len(data),
+ Name=name,
+ UploadFrom=self.UploadFrom.Direct
+ )
+
+ def addDirectory(name, directory, allowUnreadableFiles=False):
+ """Adds a directory to be uploaded
+ @param name: target name
+ @param directory: (abspath) of the directory to be uploaded
+ @param contentType: (str) content type of the file (if desired)
+
+ @note: if you add a directory, every attempt to add anything else will fail
+ """
+ return self._addItem(
+ FcItemType=self.ItemTypeDirectory,
+ AllowUnreadableFiles=allowUnreadableFiles,
+ Filename=directory,
+ Name=name,
+ )
+
+ def addFile(self, name, filename, contentType=None):
+ """Adds a file to be uploaded
+ @param name: target name
+ @param filename: (abspath) of the file to be uploaded
+ @param contentType: (str) content type of the file (if desired)
+ """
+ return self._addItem(
+ FcItemType=self.ItemTypeFile,
+ ContentType=contentType,
+ Filename=filename,
+ Name=name,
+ UploadFrom=self.UploadFrom.Disk,
+ )
+
+ def addRedirect(self, name, redirect):
+ """Adds a redirect to be uploaded
+ @param name: target name
+ @param redirect: (freenet-key) to redirect to
+ """
+ return self._addItem(
+ FcItemType=self.ItemTypeRedirect,
+ ContentType=contentType,
+ DataLength=len(data),
+ Name=name,
+ TargetURI=redirect,
+ UploadFrom=self.UploadFrom.Redirect
+ )
+
+ def getMessage(self, messageClass):
+ """Returns the message for the request, ready to send the request to the node
+ @param messageClass: (L{Message}) class to fill in
+ @return: (L{Message}) instance
+ """
+ if self.keyType in (consts.KeyType.SSK, consts.KeyType.USK) and self.privateKey is None:
+ raise ValueError('For %s a public key is required' % self.keyType)
+ elif self.keyType in (consts.KeyType.CHK, consts.KeyType.KSK) and self.privateKey is not None:
+ raise ValueError('For %s no public key is required' % self.keyType)
+
+
+ n = len(self.items)
+ if n == 0:
+ return None
+
+ elif n == 1 and self.itemTypes[0] == self.ItemTypeDirectory:
+ msg = messageClass(messageClass.MessageClientPutDiskDir, **self.params)
+ params = self.items[0]
+ for param, value in params.items():
+ if value is None:
+ continue
+ if param.startswith(self.ReservedParamPrefix):
+ continue
+
+ if param == 'Name':
+ param = 'TargetFilename'
+ elif param == 'ContentType':
+ param = 'Metadata.ContentType'
+ msg[param] = value
+
+ elif n == 1:
+ msg = messageClass(messageClass.MessageClientPut, **self.params)
+ params = self.items[0]
+ for param, value in params.items():
+ if value is None:
+ continue
+ if param.startswith(self.ReservedParamPrefix):
+ continue
+
+ if param == 'Name':
+ param = 'TargetFilename'
+ elif param == 'ContentType':
+ param = 'Metadata.ContentType'
+ msg[param] = value
+
+ if params['FcItemType'] == self.ItemTypeData:
+ msg.data = params['FcData']
+
+ #TODO: USK@s allowed for complex dirs?
+ else:
+
+ #NOTE: for simplicity we take the first item as default item and its name
+ # as TargetName if that causes any problems, pass it twice
+ msg = messageClass(messageClass.MessageClientPutComplexDir, **self.params)
+ msg.data = ''
+ defaultName = temParams[0]['Name']
+ msg['DefaultName'] = defaultName
+ params = {'TargetFilename': defaultName}
+ for itemParams in self.items:
+ k = 0
+ for param, value in itemParams.items():
+ if value is None:
+ continue
+ if param.startswith(self.ReservedParamPrefix):
+ if param == 'FcData':
+ msg.data += data
+ continue
+
+ if param == 'ContentType':
+ param = 'Metadata.ContentType'
+ param = 'Files.%s.%s' % (k, param)
+ msg[param] = value
+ k += 1
+
+ if not msg.data:
+ msg.data = None
+
+ # set some defaults
+ msg['Global'] = consts.FcpFalse
+ msg['Verbosity'] = consts.Verbosity.ReportProgress | consts.Verbosity.ReportCompression
+
+ # compose URI
+ if self.KeyType == consts.KeyType.CHK:
+ msg['URI'] == consts.KeyType.CHK
+ elif self.KeyType == consts.KeyType.KSK:
+ msg['URI'] == consts.KeyType.KSK + '/' + params.pop('TargetFilename')
+ elif self.KeyType == consts.KeyType.SSK:
+ msg['URI'] == consts.KeyType.SSK + self.privateKey + '/' + params.pop('TargetFilename')
+ elif self.KeyType == consts.KeyType.USK:
+ msg['URI'] == consts.KeyType.USH + self.privateKey + '/' + params.pop('TargetFilename')
+
+ return msg
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-02-01 14:41:45
|
Revision: 96
http://fclient.svn.sourceforge.net/fclient/?rev=96&view=rev
Author: jurner
Date: 2008-02-01 06:41:38 -0800 (Fri, 01 Feb 2008)
Log Message:
-----------
comb over
Modified Paths:
--------------
trunk/sandbox/fcp/fcp_lib/numbers.py
Modified: trunk/sandbox/fcp/fcp_lib/numbers.py
===================================================================
--- trunk/sandbox/fcp/fcp_lib/numbers.py 2008-01-30 17:17:10 UTC (rev 95)
+++ trunk/sandbox/fcp/fcp_lib/numbers.py 2008-02-01 14:41:38 UTC (rev 96)
@@ -14,51 +14,63 @@
@return: (str) formated number
>>> format_num_bytes(100)
- '100 b'
+ '100B'
>>> format_num_bytes(1000)
- '1.00 kb'
+ '1.00KB'
>>> format_num_bytes(1024, conform=False)
- '1.00 kb'
+ '1.00KiB'
>>> format_num_bytes(1000, short=False)
- '1.00 Kilobyte'
+ '1.00Kilobyte'
"""
-
- if short:
- names = ('b', 'kb', 'mb', 'gb', 'tb', 'pb', 'eb', 'zb', 'yb')
- else:
- names = ('Byte',
- 'Kilobyte',
- 'Megabyte',
- 'Gigabyte',
- 'Terabyte',
- 'Petabyte',
- 'Exabyte',
- 'Zettabyte',
- 'Yottabyte'
- )
if conform:
factor = 1000
+ if short:
+ names = ('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')
+ else:
+ names = ('Byte',
+ 'Kilobyte',
+ 'Megabyte',
+ 'Gigabyte',
+ 'Terabyte',
+ 'Petabyte',
+ 'Exabyte',
+ 'Zettabyte',
+ 'Yottabyte'
+ )
else:
factor = 1024
-
- num = float(num)
+ if short:
+ names = ('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB')
+ else:
+ names = ('Byte',
+ 'Kibibyte',
+ 'Mebibyte',
+ 'Gibibyte',
+ 'Tebibyte',
+ 'Pebibyte',
+ 'Exibyte',
+ 'Zebibyte',
+ 'Yobiabyte'
+ )
+
name = names[0]
if num >= factor:
+ num = float(num)
for tmp_name in names[1: ]:
num /= factor
name = tmp_name
if num < factor:
break
else:
- return '%i %s' % (num, name)
+ return '%i%s' % (num, name)
-
-
- return '%01.2f %s' % (num, name)
+ return '%01.2f%s' % (num, name)
+
+
#***************************************************************
#
#***************************************************************
@@ -233,7 +245,6 @@
num = pat.sub('', num)
return num
-
#*****************************************************************
#
#****************************************************************
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-01-30 17:17:08
|
Revision: 95
http://fclient.svn.sourceforge.net/fclient/?rev=95&view=rev
Author: jurner
Date: 2008-01-30 09:17:10 -0800 (Wed, 30 Jan 2008)
Log Message:
-----------
thises and thats
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-01-30 17:16:34 UTC (rev 94)
+++ trunk/sandbox/fcp/fcp2_0_client.py 2008-01-30 17:17:10 UTC (rev 95)
@@ -1043,20 +1043,14 @@
WithLongDescription=withLongDescription,
)
- def getNode(self,
- withPrivate=True,
- withVolatile=True,
- giveOpennetRef=True,
- ):
+
+ def modifyConfig(self, params):
+ """Modifies node configuration values
+ @param params: (dict) containing parameters to modify
"""
- @event: NodeData(event, msg)
- """
- self.sendMessage(
- self.Message.MessageGetNode,
- WithPrivate=self.fcpBool(withPrivate),
- WithVolatile=self.fcpBool(withVolatile),
- GiveOpennetRef=self.fcpBool(giveOpennetRef),
- )
+ msg = self.Message(self.Message.MessageModifyConfig)
+ msg.params = params
+ self.sendMessageEx(msg)
########################################################
@@ -1427,22 +1421,35 @@
#TODO: check how Fcp responds when the identifier is unknwon or something else goes
# werong. Maybe a ProtocolError.NoSuchIdentifier ???
+
+
########################################################
##
## Peer related methods
##
########################################################
- def getNode(self, withPrivate=True, withVolantile=True):
+ def getNode(self,
+ withPrivate=True,
+ withVolatile=True,
+ giveOpennetRef=True,
+ ):
+ """Request information about the node
+ @param withPrivate: if True, private data is included
+ @param withVolatile: if True, statistical data is included
+ @param giveOppennetRef: if True, the opennet reference is retuned instead of the darknet
+ """
self.sendMessage(
- self.Message.MessageGetNode,
- WithPrivate=withPrivate,
- WithVolatile=withVolantile,
- )
-
-
+ self.Message.MessageGetNode,
+ WithPrivate=withPrivate,
+ WithVolatile=withVolatile,
+ GiveOpennetRef=giveOpennetRef,
+ )
def listPeer(self, identity):
+ """Requests information about a peer node
+ @param identifier: identifier of the peer to request information for
+ """
self.jobClient.sendMessage(
self.Message.MessageListPeer,
NodeIdentifier=identity,
@@ -1478,21 +1485,31 @@
def modifyPeer(self, identity, allowLocalAddresses=None, isDisabled=None, isListenOnly=None):
+ """Modifies a peer node
+ @param identity: identity of the peer node to modify
+ @param allowLocalAddresses: if True, whatever is done
+ @param isDisabled: if True, the peer is disabled
+ @param isListenOnly: if True, the peer is set to listen only status
+ """
msg = Message(
self.Message.MessageModifyPeer,
NodeIdentifier=identity,
)
if allowLocalAddresses is not None:
- msg['AllowLocalAddresses'] = self.fcpBool(allowLocalAddresses)
+ msg['AllowLocalAddresses'] = allowLocalAddresses
if isDisabled is not None:
- msg['isDisabled'] = self.fcpBool(isDisabled)
+ msg['isDisabled'] = isDisabled
if isListenOnly is not None:
- msg['isListenOnly'] = self.fcpBool(isListenOnly)
+ msg['isListenOnly'] = isListenOnly
self.jobClient.sendMessageEx(msg)
self.sendMessageEx(msg)
def modifyPeerNote(self, identity, note):
+ """Modifies the note associated to a peer
+ @param identity: identity of the peer node to modify
+ @param note: (str) new note to associate to the peer
+ """
self.sendMessage(
self.Message.MessageModifyPeerNote,
NodeIdentifier=identity,
@@ -1503,6 +1520,9 @@
def removePeer(self, identity):
+ """Removes a peer
+ @param identity: identity of the peer node to remove
+ """
self.sendMessage(
self.Message.MessageRemovePeer,
NodeIdentifier=identity,
@@ -1624,16 +1644,25 @@
def cb(event, msg):
root=Config(configDataMsg=msg)
+
+ print
+ print '***************************************'
+ print '* walking config tree'
+ print '***************************************'
for node in root.walk():
- key = node.key()
- if key is None: # skip root
+ if node.name is None: # skip root
continue
- print key
- for keyName, values in sorted(node.values.items()):
- print ' ' + keyName
- for valueClass, (value, valueType) in sorted(values.items()):
- print ' %s=%r (%s)' % (valueClass, value, valueType)
-
+ print node.key()
+ for valueClass, (value, valueType) in sorted(node.values.items()):
+ print ' %s=%r (%s)' % (valueClass, value, valueType)
+
+ print
+ print '***************************************'
+ print '* generating dict from config tree'
+ print '***************************************'
+ for key, value in root.toMessageParams().items():
+ print '%s: %s (%s)' % (key, value, type(value))
+
#c.setDebugVerbosity(c.DebugVerbosity.Warning)
c.events.ConfigData += cb
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-01-30 17:16:35
|
Revision: 94
http://fclient.svn.sourceforge.net/fclient/?rev=94&view=rev
Author: jurner
Date: 2008-01-30 09:16:34 -0800 (Wed, 30 Jan 2008)
Log Message:
-----------
refactored and a few fixes
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_config.py
Modified: trunk/sandbox/fcp/fcp2_0_config.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_config.py 2008-01-30 14:36:38 UTC (rev 93)
+++ trunk/sandbox/fcp/fcp2_0_config.py 2008-01-30 17:16:34 UTC (rev 94)
@@ -6,14 +6,28 @@
#
#****************************************************************************************
class ConfigItem(object):
+ """Config item"""
+
def __init__(self, parent, name):
+ """
+ @param parent: parent item
+ @param name: name of the item
+
+ @ivar parent: parent item
+ @ivar name: name of the item
+ @ivar children: (dict) child items
+ @ivar values: dict of values
+ """
self.parent = parent
self.name = name
self.children = {}
self.values = {}
def key(self):
+ """Returns the key of the config item
+ @return: (str) key
+ """
out = []
parent = self
while parent is not None:
@@ -21,7 +35,7 @@
out.append(parent.name)
parent = parent.parent
out.reverse()
- return '.'.join(out)
+ return ConfigMessageParams.ComponentsSep.join(out)
#****************************************************************************************
@@ -31,20 +45,39 @@
"""Class representing fcp config tree
"""
+ ValueClassCurrent = ConfigMessageParams.ParamClassCurrent
+ ValueClassDefault = ConfigMessageParams.ParamClassDefault
+ ValueClassExpertFlag = ConfigMessageParams.ParamClassExpertFlag
+ ValueClassForceWriteFlag = ConfigMessageParams.ParamClassForceWriteFlag
+ ValueClassShortDescription = ConfigMessageParams.ParamClassShortDescription
+ ValueClassLongDescription = ConfigMessageParams.ParamClassLongDescription
+
+
def __init__(self, configDataMsg=None):
+ """
+ @param parent: parent item
+ @param name: name of the item
+
+ @ivar parent: parent item
+ @ivar name: name of the item
+ @ivar children: (dict) child items
+ """
+
self.parent = None
self.name = None
self.children = {}
- self.values = {} # for consistency
- self.configMessageParams = ConfigMessageParams()
+ self._configMessageParams = ConfigMessageParams()
if configDataMsg is not None:
for key, value in configDataMsg.params.items():
- self[key] = value
+ self.addNewValue(key, value)
-
def __getitem__(self, key):
+ """Returns the item associated to a key
+ @param key: (str) key to retrieve the item for (not including ValueClass prefix)
+ @return: (L{ConfigItem})
+ """
components = key.split('.')
parent = self
while components:
@@ -55,49 +88,69 @@
parent = item
return parent
-
- def __setitem__(self, key, value):
- paramClass, components = self.configMessageParams.splitParamClass(key)
- paramType = self.configMessageParams.get(key, None)
- components = self.configMessageParams.splitAll(components)
- valueName = components.pop()
-
- #TODO: how to handle non existent keys?
+
+ def addNewValue(self, key, value):
+ """Adds a value to an item
+ @param key: (str) key to add the value to (including ParamClass prefix)
+ @param value to associate
+ @note: if the item does not exist, it is created
+ """
+ paramClass, components = self._configMessageParams.splitParamClass(key)
+ paramType = self._configMessageParams.get(key, None)
if paramType is None:
- # log somehow
- return False
-
- # create new config item if necessary
+ raise ValueError('Unknown key: %r' % components)
+
+ # find or create new config item if necessary
+ components = self._configMessageParams.splitAll(components)
parent = self
for component in components:
item = parent.children.get(component, None)
if item is None:
item = ConfigItem(parent, component)
- self.children[component] = item
+ parent.children[component] = item
parent = item
+ parent.values[paramClass] = (value, paramType)
+
+
+
+ def removeParamClass(self, key):
+ """Removes the paramClass component if necessary
+ @param key: (str) key to remove the param class from
+ @return: (str) key
+ @note: if the key does not contain the paramClass it is returned unchanged
+ """
+ head, tail = self._configMessageParams.splitParamClass(key)
+ if head in self._configMessageParams.ParamClasses:
+ return tail
+ return tail
- # assign value
- values = parent.values.get(valueName, None)
- if values is None:
- values = {}
- parent.values[valueName] = values
- values[paramClass] = (value, paramType)
- return True
-
+ def toMessageParams(self):
+ """Dumps the contents of the config to a dict
+ @note: you can use this dict as params for FcpClient.modifyConfig()
+ """
+ out = {}
+ for node in self.walk():
+ if node.name is None:
+ continue
+
+ key = node.key()
+ result = node.values.get(self.ValueClassCurrent, None)
+ if result is not None:
+ out[key] = result[0]
+ return out
+
+
def walk(self):
+ """Walks over the config tree, returning the next L{ConfigItemm} in turn"""
def walker(node):
yield node
for child in node.children.values():
for x in walker(child):
yield x
- return walker(self)
-
+ return walker(self)
- def key(self):
- return None
-
#****************************************************************************************************
#
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-01-30 14:36:33
|
Revision: 93
http://fclient.svn.sourceforge.net/fclient/?rev=93&view=rev
Author: jurner
Date: 2008-01-30 06:36:38 -0800 (Wed, 30 Jan 2008)
Log Message:
-----------
...
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-01-30 14:35:57 UTC (rev 92)
+++ trunk/sandbox/fcp/fcp2_0_client.py 2008-01-30 14:36:38 UTC (rev 93)
@@ -1625,8 +1625,17 @@
def cb(event, msg):
root=Config(configDataMsg=msg)
for node in root.walk():
- print node.key()
+ key = node.key()
+ if key is None: # skip root
+ continue
+ print key
+ for keyName, values in sorted(node.values.items()):
+ print ' ' + keyName
+ for valueClass, (value, valueType) in sorted(values.items()):
+ print ' %s=%r (%s)' % (valueClass, value, valueType)
+ #c.setDebugVerbosity(c.DebugVerbosity.Warning)
+
c.events.ConfigData += cb
c.getConfig()
for i in xrange(10):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-01-30 14:35:57
|
Revision: 92
http://fclient.svn.sourceforge.net/fclient/?rev=92&view=rev
Author: jurner
Date: 2008-01-30 06:35:57 -0800 (Wed, 30 Jan 2008)
Log Message:
-----------
re
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_config.py
Modified: trunk/sandbox/fcp/fcp2_0_config.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_config.py 2008-01-30 14:35:33 UTC (rev 91)
+++ trunk/sandbox/fcp/fcp2_0_config.py 2008-01-30 14:35:57 UTC (rev 92)
@@ -1,5 +1,7 @@
"""Sketch for fcp config tree"""
+
+from fcp2_0_consts import ConfigMessageParams
#****************************************************************************************
#
#****************************************************************************************
@@ -26,242 +28,15 @@
#
#****************************************************************************************
class Config(object):
-
"""Class representing fcp config tree
-
"""
- #{'current': {'valueType': (8, None), 'allowedHosts': 'true'}, 'default': {'valueType': (8, None), 'allowedHosts': 'true'}}
-
- ValueClassCurrent = 'current'
- ValueClassDefault = 'default'
- ValueClassExpertFlag = 'expertFlag'
- ValueClassForceWriteFlag = 'forceWriteFlag'
- ValueClassShortDescription = 'shortDescription'
- ValueClassLongDescription = 'longDescription'
- ValueClassSortOrder = 'sortOrder'
- ValueClassType = 'valueType'
-
- ValueClassesFcp = (
- ValueClassDefault,
- ValueClassExpertFlag,
- ValueClassForceWriteFlag,
- ValueClassShortDescription,
- ValueClassLongDescription,
- )
- ValueClassAll = ValueClassesFcp + (ValueClassType, )
-
-
- ValueTypeUnknown = 0
- ValueTypeBool = 1
- ValueTypeInt = 2 # params: LowerLimit, UpperLimit
- ValueTypeBytes = 3 # may have params: LowerLimit, UpperLimit
- ValueTypeFilename = 4
- ValueTypeDirname = 5
- ValueTypePort = 6
- ValueTypeIP = 7
- ValueTypeIPList = 8
- ValueTypeChoice = 9
- ValueTypeChoiceDirname = 10
- ValueTypePercent = 11
- ValueTypeString = 12
- ValueTypeUri = 13
- ValueTypeStringList = 14
-
-
- class ChoiceFProxyCss:
- Clean = 'Clean'
- Boxed = 'boxed'
- GrayAndBlue = 'grayandblue'
- Sky = 'sky'
-
- ChoicesAll = (Clean, Boxed, GrayAndBlue, Sky)
- ChoicesAllowMultiple = False
-
- class ChoiceLoggerPriority:
- Error = 'ERROR'
- Normal = 'NORMAL'
- Minor = 'MINOR'
- Debug = 'DEBUG'
-
- ChoicesAll = (Error, Normal, Minor, Debug)
- ChoicesAllowMultiple = False
-
- class ChoiceNodeDownloadAllowedDirs:
- All = 'all'
- Downloads = 'downloads'
- Nowhere = ''
-
- ChoicesAll = (All, Downloads, Nowhere)
- ChoicesAllowMultiple = False
-
- class ChoiceNodeUploadAllowedDirs:
- All = 'all'
- Nowhere = ''
- ChoicesAll = (All, Nowhere)
- ChoicesAllowMultiple = False
-
- class ChoicePriorityPolicy:
- Hard = 'HARD'
- Soft = 'SOFT'
-
- ChoicesAll = (Hard, Soft)
- ChoicesAllowMultiple = False
-
-
- class ChoiceSSLVersion:
- Stl = 'STL'
- SslV3 = 'SSLV3'
- TlsV1 = 'TLSv1'
-
- ChoicesAll = (Stl, SslV3, TlsV1)
- ChoicesAllowMultiple = False
-
-
- KeyConsole = 'console'
- KeyFcp = 'fcp'
- KeyFproxy = 'fproxy'
- KeyLogger = 'logger'
- KeyNode = 'node'
- KeyNodeLoad = 'node.load'
- KeyNodeOpennet = 'node.opennet'
- KeyNodeScheduler = 'node.scheduler'
- KeyNodeUpdaterer = 'node.updater'
- KeyPluginmanager = 'pluginmanager'
- KeyPluginmanager2 = 'pluginmanager2'
- KeySSL = 'ssl'
- KeyToadletSymlinker = 'toadletsymlinker'
-
- Keys = {
-
- 'console.allowedHosts': (ValueTypeIPList, None), # host names, single IPs CIDR-maskip IPs likee 192.168.0.0/24
- 'console.bindTo': (ValueTypeIPList, None),
- 'console.directEnabled': (ValueTypeBool, None),
- 'console.enabled': (ValueTypeBool, None),
- 'console.port': (ValueTypePort, None),
- 'console.ssl': (ValueTypeBool, None),
-
-
- 'fcp.allowedHosts': (ValueTypeIPList, None),
- 'fcp.allowedHostsFullAccess': (ValueTypeIPList, None),
- 'fcp.assumeDownloadDDAIsAllowed': (ValueTypeBool, None),
- 'fcp.assumeUploadDDAIsAllowed': (ValueTypeBool, None),
- 'fcp.bindTo': (ValueTypeIP, None),
- 'fcp.enabled': (ValueTypeBool, None),
- 'fcp.persistentDownloadsEnabled': (ValueTypeBool, None),
- 'fcp.persistentDownloadsFile': (ValueTypeFilename, None),
- 'fcp.persistentDownloadsInterval': (ValueTypeInt, (0, None)),
- 'fcp.port': (ValueTypePort, None),
- 'fcp.ssl': (ValueTypeBool, None),
-
-
- 'fproxy.CSSOverride': (ValueTypeBool, None),
- 'fproxy.advancedModeEnabled': (ValueTypeBool, None),
- 'fproxy.allowedHosts': (ValueTypeIPList, None),
- 'fproxy.allowedHostsFullAccess': (ValueTypeIPList, None),
- 'fproxy.bindTo': (ValueTypeIPList, None),
- 'fproxy.css': (ValueTypeChoice, ChoiceFProxyCss),
- 'fproxy.doRobots': (ValueTypeBool, None),
- 'fproxy.enabled': (ValueTypeBool, None),
- 'fproxy.javascriptEnabled': (ValueTypeBool, None),
- 'fproxy.port': (ValueTypePort, None),
- 'fproxy.showPanicButton': (ValueTypeBool, None),
- 'fproxy.ssl': (ValueTypeBool, None),
-
-
- 'logger.dirname': (ValueTypeDirname, None),
- 'logger.enabled': (ValueTypeBool, None),
- 'logger.interval': (ValueTypeUnknown, None), # ??? 1HOUR ??
- 'logger.maxCachedBytes': (ValueTypeBytes, None),
- 'logger.maxCachedLines': (ValueTypeInt, (0, None)), # ???
- 'logger.maxZippedLogsSize': (ValueTypeBytes, None), # ???
- 'logger.priority': (ValueTypeChoice, ChoiceLoggerPriority),
- 'logger.priorityDetail': (ValueTypeUnknown, None), # ???? Detailed priority thresholds
-
-
- 'node.alwaysAllowLocalAddresses': (ValueTypeBool, None),
- 'node.assumeNATed': (ValueTypeBool, None),
- 'node.bindTo': (ValueTypeIP, None),
- 'node.clientThrottleFile': (ValueTypeFilename, None),
- 'node.databaseMaxMemory': (ValueTypeBytes, None),
- 'node.disableHangCheckers':( ValueTypeBool, None),
- 'node.disableProbabilisticHTLs': (ValueTypeBool, None),
- 'node.downloadAllowedDirs': (ValueTypeChoiceDirname, ChoiceNodeDownloadAllowedDirs),
- 'node.downloadsDir': (ValueTypeDirname, None),
- 'node.extraPeerDataDir': (ValueTypeDirname, None),
- 'node.includeLocalAddressesInNoderefs': (ValueTypeBool, None),
- 'node.inputBandwidthLimit': (ValueTypeBytes, (-1, None) ),
- 'node.ipAddressOverride': (ValueTypeIP, None),
- 'node.l10n': (ValueTypeUnknown, None), # ???
- 'node.lazyResume': (ValueTypeBool, None),
- 'node.listenPort': (ValueTypePort, None),
- 'node.maxBackgroundUSKFetchers': (ValueTypeInt, (0, None) ),
- 'node.maxHTL': (ValueTypeInt, (0, None) ),
- 'node.name': (ValueTypeString, None),
- 'node.nodeDir': (ValueTypeDirname, None),
- 'node.oneConnectionPerIP': (ValueTypeBool, None),
- 'node.outputBandwidthLimit': (ValueTypeBytes, None),
- 'node.passOpennetPeersThroughDarknet': (ValueTypeBool, None),
- 'node.persistentTempDir': (ValueTypeDirname, None),
- 'node.storeDir': (ValueTypeDirname, None),
- 'node.storeForceBigShrinks': (ValueTypeBool, None),
- 'node.storeSize': (ValueTypeBytes, None),
- 'node.tempDir': (ValueTypeDirname, None),
- 'node.tempIPAddressHint': (ValueTypeIP, None), # ???
- 'node.testingDropPacketsEvery': (ValueTypeInt, (0, None) ),
- 'node.uploadAllowedDirs': (ValueTypeChoiceDirname, ChoiceNodeDownloadAllowedDirs),
-
-
- 'node.testnet.enabled': (ValueTypeBool, None),
-
- 'node.load.aggressiveGC': (ValueTypeUnknown, None), # ???
- 'node.load.freeHeapBytesThreshold': (ValueTypeBytes, None),
- 'node.load.freeHeapPercentThreshold': (ValueTypePercent, None),
- 'node.load.memoryChecker': (ValueTypeBool, None),
- 'node.load.nodeThrottleFile': (ValueTypeFilename, None),
- 'node.load.threadLimit': (ValueTypeInt, (0, None) ),
-
-
- 'node.opennet.acceptSeedConnections': (ValueTypeBool, None),
- 'node.opennet.alwaysAllowLocalAddresses': (ValueTypeBool, None),
- 'node.opennet.assumeNATed': (ValueTypeBool, None),
- 'node.opennet.bindTo': (ValueTypeIP, None),
- 'node.opennet.enabled': (ValueTypeBool, None),
- 'node.opennet.listenPort': (ValueTypePort, None),
- 'node.opennet.maxOpennetPeers': (ValueTypeInt, (0, None) ),
- 'node.opennet.oneConnectionPerIP': (ValueTypeBool, None),
- 'node.opennet.testingDropPacketsEvery': (ValueTypeInt, (0, None)),
-
- 'node.scheduler.CHKinserter_priority_policy': (ValueTypeChoice, ChoicePriorityPolicy),
- 'node.scheduler.CHKrequester_priority_policy': (ValueTypeChoice, ChoicePriorityPolicy),
- 'node.scheduler.SSKinserter_priority_policy': (ValueTypeChoice, ChoicePriorityPolicy),
- 'node.scheduler.SSKrequester_priority_policy': (ValueTypeChoice, ChoicePriorityPolicy),
-
- 'node.updater.URI': (ValueTypeUri, None),
- 'node.updater.autoupdate': (ValueTypeBool, None),
- 'node.updater.enabled': (ValueTypeBool, None),
- 'node.updater.extURI': (ValueTypeUri, None),
- 'node.updater.revocationURI': (ValueTypeUri, None),
-
-
- 'pluginmanager.loadplugin': (ValueTypeStringList, None),
- 'pluginmanager2.loadedPlugins': (ValueTypeStringList, None),
-
-
- 'ssl.sslEnable': (ValueTypeBool, None),
- 'ssl.sslKeyPass': (ValueTypeString, None),
- 'ssl.sslKeyStore': (ValueTypeFilename, None),
- 'ssl.sslKeyStorePass': (ValueTypeString, None),
- 'ssl.sslVersion': (ValueTypeChoice, ChoiceSSLVersion),
-
- 'toadletsymlinker.symlinks': (ValueTypeStringList, None),
- }
-
-
def __init__(self, configDataMsg=None):
self.parent = None
self.name = None
self.children = {}
+ self.values = {} # for consistency
+ self.configMessageParams = ConfigMessageParams()
if configDataMsg is not None:
for key, value in configDataMsg.params.items():
@@ -281,15 +56,14 @@
return parent
-
def __setitem__(self, key, value):
- valueClass, components = key.split('.', 1)
- valueType = self.Keys.get(components, None)
- components, valueName = components.rsplit('.', 1)
- components = components.split('.')
+ paramClass, components = self.configMessageParams.splitParamClass(key)
+ paramType = self.configMessageParams.get(key, None)
+ components = self.configMessageParams.splitAll(components)
+ valueName = components.pop()
- #TODO: how to handle undefinmed keys?
- if valueType is None:
+ #TODO: how to handle non existent keys?
+ if paramType is None:
# log somehow
return False
@@ -307,12 +81,10 @@
if values is None:
values = {}
parent.values[valueName] = values
- values[self.ValueClassType] = valueType
- values[valueClass] = value
+ values[paramClass] = (value, paramType)
return True
-
-
+
def walk(self):
def walker(node):
@@ -322,6 +94,7 @@
yield x
return walker(self)
+
def key(self):
return None
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-01-30 14:35:28
|
Revision: 91
http://fclient.svn.sourceforge.net/fclient/?rev=91&view=rev
Author: jurner
Date: 2008-01-30 06:35:33 -0800 (Wed, 30 Jan 2008)
Log Message:
-----------
fixes
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_consts.py
Modified: trunk/sandbox/fcp/fcp2_0_consts.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_consts.py 2008-01-30 13:23:25 UTC (rev 90)
+++ trunk/sandbox/fcp/fcp2_0_consts.py 2008-01-30 14:35:33 UTC (rev 91)
@@ -574,7 +574,7 @@
'logger.enabled': FcpTypeBool,
'logger.interval': FcpType, # ??? 1HOUR ??
'logger.maxCachedBytes': FcpTypeNumBytes,
- 'logger.maxCachedLines': FcpTypeIntWithBounds(0, None), # ???
+ 'logger.maxCachedLines': FcpTypeNumBytes, # ???
'logger.maxZippedLogsSize': FcpTypeNumBytes, # ???
'logger.priority': FcpTypeChoiceLoggerPriority,
'logger.priorityDetail': FcpType, # ???? is it Detailed priority thresholds ???
@@ -661,30 +661,42 @@
}
+ def __init__(self):
+ pass
+
+
def splitAll(self, paramName):
return paramName.split(self.ComponentsSep)
def splitParamClass(self, paramName):
return paramName.split(self.ComponentsSep, 1)
+
+ def get(self, paramName, default=None):
+ try:
+ return self[paramName]
+ except KeyError:
+ return default
+
+
def __getitem__(self, paramName):
paramClass, paramKey = self.splitParamClass(paramName)
if paramClass == self.ParamClassCurrent:
- return self.Params[paramName]
+ return self.Params[paramKey]
elif paramClass == self.ParamClassDefault:
- return self.Params[paramName]
- elif paramClass == ParamClassExpertFlag:
+ return self.Params[paramKey]
+ elif paramClass == self.ParamClassExpertFlag:
return FcpTypeBool
- elif paramClass == ParamClassForceWriteFlag:
+ elif paramClass == self.ParamClassForceWriteFlag:
return FcpTypeBool
- elif paramClass == ParamClassShortDescription:
+ elif paramClass == self.ParamClassShortDescription:
return FcpTypeString
- elif paramClass == ParamClassLongDescription:
+ elif paramClass == self.ParamClassLongDescription:
return FcpTypeString
- elif paramClass == ParamClassSortOrder:
+ elif paramClass == self.ParamClassSortOrder:
return FcpTypeInt
else:
- raise ValueError('Unkinown param class in: %r' % paramName)
+ raise ValueError('Unknown param class in: %r' % paramName)
#***************************************************************************************
#
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-01-30 13:23:25
|
Revision: 90
http://fclient.svn.sourceforge.net/fclient/?rev=90&view=rev
Author: jurner
Date: 2008-01-30 05:23:25 -0800 (Wed, 30 Jan 2008)
Log Message:
-----------
fix
Modified Paths:
--------------
trunk/sandbox/fcp/test_fcp/test_fcp2_0_client.py
Modified: trunk/sandbox/fcp/test_fcp/test_fcp2_0_client.py
===================================================================
--- trunk/sandbox/fcp/test_fcp/test_fcp2_0_client.py 2008-01-30 13:22:48 UTC (rev 89)
+++ trunk/sandbox/fcp/test_fcp/test_fcp2_0_client.py 2008-01-30 13:23:25 UTC (rev 90)
@@ -679,7 +679,7 @@
# respond with a ProtocolError
self.socket.setResponseMessage(
'ProtocolError',
- Code='25', # DDADenied
+ Code=25, # DDADenied
Identifier=msg['Identifier'],
ExtraDescription='An error occured',
Fatal='false',
@@ -692,7 +692,7 @@
self.failIf(msg is None)
self.assertEqual(msg.name, self.fcpClient.Message.MessageTestDDARequest)
self.assertEqual(msg['Directory'], DIR)
- self.assertEqual(msg['WantWriteDirectory'], 'true')
+ self.failIf(not msg['WantWriteDirectory'])
# respond with a TestDDAReply message
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-01-30 13:22:42
|
Revision: 89
http://fclient.svn.sourceforge.net/fclient/?rev=89&view=rev
Author: jurner
Date: 2008-01-30 05:22:48 -0800 (Wed, 30 Jan 2008)
Log Message:
-----------
adapt to type conversions
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-01-30 13:21:55 UTC (rev 88)
+++ trunk/sandbox/fcp/fcp2_0_client.py 2008-01-30 13:22:48 UTC (rev 89)
@@ -1432,6 +1432,16 @@
## Peer related methods
##
########################################################
+ def getNode(self, withPrivate=True, withVolantile=True):
+ self.sendMessage(
+ self.Message.MessageGetNode,
+ WithPrivate=withPrivate,
+ WithVolatile=withVolantile,
+ )
+
+
+
+
def listPeer(self, identity):
self.jobClient.sendMessage(
self.Message.MessageListPeer,
@@ -1462,8 +1472,8 @@
"""
self.sendMessage(
self.Message.MessageListPeers,
- WithMetadata=self.fcpBool(withMetaData),
- WithVolatile=self.fcpBool(withVolantile),
+ WithMetadata=withMetaData,
+ WithVolatile=withVolantile,
)
@@ -1654,4 +1664,18 @@
#testGenerateSSK()
+ def testListPeers():
+ c.listPeers()
+ for i in xrange(10):
+ c.next()
+
+ #testListPeers()
+
+ def testGetNode():
+ c.getNode()
+ for i in xrange(10):
+ c.next()
+
+ #testGetNode()
+
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ju...@us...> - 2008-01-30 13:21:51
|
Revision: 88
http://fclient.svn.sourceforge.net/fclient/?rev=88&view=rev
Author: jurner
Date: 2008-01-30 05:21:55 -0800 (Wed, 30 Jan 2008)
Log Message:
-----------
continued working on type conversions
Modified Paths:
--------------
trunk/sandbox/fcp/fcp2_0_consts.py
Modified: trunk/sandbox/fcp/fcp2_0_consts.py
===================================================================
--- trunk/sandbox/fcp/fcp2_0_consts.py 2008-01-30 13:21:04 UTC (rev 87)
+++ trunk/sandbox/fcp/fcp2_0_consts.py 2008-01-30 13:21:55 UTC (rev 88)
@@ -231,17 +231,48 @@
ReportProgress = 0x1
ReportCompression = 0x200
-
#*************************************************************************************
# python <--> fcp value mappings
#*************************************************************************************
#TODO: reqork Clss.validateFcpValue
+class FcpType(object):
+
+ # consts for validation
+ ValidatesInvalid = 0x0
+ ValidatesValid = 0x1
+ ValidatesIncomlete = 0x2
+
+ @classmethod
+ def pythonToFcp(clss, value):
+ return value
+
+ @classmethod
+ def fcpToPython(clss, value):
+ return value
+
+ @classmethod
+ def validateFcpValue(clss, value):
+ return clss.ValidatesValid
+
+
+class FcpTypeString(FcpType):
+
+ @classmethod
+ def pythonToFcp(clss, value):
+ return str(value) #TODO: ??? unicode ???
+
+ @classmethod
+ def fcpToPython(clss, value):
+ return value
+
+ @classmethod
+ def validateFcpValue(clss, value):
+ return clss.ValidatesValid
-FcpTrue = 'true'
-FcpFalse = 'false'
-class FcpTypeBool(object):
+
+class FcpTypeBool(FcpType):
@classmethod
def pythonToFcp(clss, value):
@@ -254,11 +285,11 @@
@classmethod
def validateFcpValue(clss, value):
if value in ('true', 'false'):
- return str(value)
- return None
+ return self.ValidatesValid
+ return self.ValidatesInvalid
-class FcpTypeInt(object):
+class FcpTypeInt(FcpType):
@classmethod
def pythonToFcp(clss, value):
@@ -276,8 +307,27 @@
return None
+class FcpTypeFloat(FcpType):
+
+ @classmethod
+ def pythonToFcp(clss, value):
+ return str(value)
+
+ @classmethod
+ def fcpToPython(clss, value):
+ return float(value)
+
+ @classmethod
+ def validateFcpValue(clss, value):
+ try:
+ return float(value)
+ except ValueError:
+ return None
+
+
+
# GetFailed sets the ExpectedDataLenght field to '' (empty string). Fix this to show up as -1
-class FcpTypeInt_GetFailed_ExpectedDataLenght(object):
+class FcpTypeInt_GetFailed_ExpectedDataLenght(FcpType):
@classmethod
def pythonToFcp(clss, value):
@@ -300,7 +350,7 @@
-class FcpTypeIntWithBounds(object):
+class FcpTypeIntWithBounds(FcpType):
def __init__(self, lowerBound, upperBound):
self.lowerBound = lowerBound
@@ -329,27 +379,25 @@
-class FcpTypeBase64EncodedString(object):
+class FcpTypeBase64EncodedString(FcpType):
@classmethod
def pythonToFcp(clss, value):
- return base64.encode(value)
+ return base64.b64encode(value)
@classmethod
def fcpToPython(clss, value):
- return base64.decode(value)
+ return base64.b64decode(value)
@classmethod
def validateFcpValue(clss, value):
pass
#TODO: no idea
- # we add a few private params...
- ParamPrefixPrivate = 'Fc'
+
-
-class FcpTypeTime(object):
+class FcpTypeTime(FcpType):
@classmethod
def pythonToFcp(clss, value):
@@ -362,12 +410,452 @@
@classmethod
def validateFcpValue(clss, value):
try:
- return self.fcpToPython(value)
+ return clss.fcpToPython(value)
except ValueEror:
return none
+
+class FcpTypeIP(FcpType):
+ pass
+
+#TODO: check if comma separated or colon separated
+class FcpTypeIPList(FcpType):
+ pass
+
+class FcpTypeIPort(FcpType):
+ pass
+
+class FcpTypeStringList(FcpType):
+ pass
+
+class FcpTypeDirname(FcpType):
+ pass
+
+class FcpTypeFilename(FcpType):
+ pass
+
+
+class FcpTypeNumBytes(FcpType):
+ pass
+
+class FcpTypePercent(FcpTypeFloat):
+ pass
+
+
+class FcpTypeUri(FcpType):
+ pass
+
+
+# special choice types for config message
+
+
+class FcpTypeChoiceFProxyCss(FcpType):
+ Clean = 'Clean'
+ Boxed = 'boxed'
+ GrayAndBlue = 'grayandblue'
+ Sky = 'sky'
+
+ ChoicesAll = (Clean, Boxed, GrayAndBlue, Sky)
+ ChoicesAllowMultiple = False
+
+class FcpTypeChoiceLoggerPriority(FcpType):
+ Error = 'ERROR'
+ Normal = 'NORMAL'
+ Minor = 'MINOR'
+ Debug = 'DEBUG'
+
+ ChoicesAll = (Error, Normal, Minor, Debug)
+ ChoicesAllowMultiple = False
+
+class FcpTypeChoiceNodeDownloadAllowedDirs(FcpType):
+ All = 'all'
+ Downloads = 'downloads'
+ Nowhere = ''
+
+ ChoicesAll = (All, Downloads, Nowhere)
+ ChoicesAllowMultiple = False
+
+class FcpTypeChoiceNodeUploadAllowedDirs(FcpType):
+ All = 'all'
+ Nowhere = ''
+ ChoicesAll = (All, Nowhere)
+ ChoicesAllowMultiple = False
+
+class FcpTypeChoicePriorityPolicy(FcpType):
+ Hard = 'HARD'
+ Soft = 'SOFT'
+
+ ChoicesAll = (Hard, Soft)
+ ChoicesAllowMultiple = False
+
+
+class FcpTypeChoiceSSLVersion(FcpType):
+ Stl = 'STL'
+ SslV3 = 'SSLV3'
+ TlsV1 = 'TLSv1'
+
+ ChoicesAll = (Stl, SslV3, TlsV1)
+ ChoicesAllowMultiple = False
+
+
#***************************************************************************************
#
+# param types for config message
+#
+# ..bit more efford here, cos we need types for user input checking
+# ...a slpoppy implementation of a dict should be enough
+#
+#***************************************************************************************
+class ConfigMessageParams(object):
+
+ ComponentsSep = '.'
+
+
+ # first component of a config message param is always the param class
+
+ ParamClassCurrent = 'current'
+ ParamClassDefault = 'default'
+ ParamClassExpertFlag = 'expertFlag'
+ ParamClassForceWriteFlag = 'forceWriteFlag'
+ ParamClassShortDescription = 'shortDescription'
+ ParamClassLongDescription = 'longDescription'
+ ParamClassSortOrder = 'sortOrder'
+
+ ParamClasses = (
+ ParamClassCurrent,
+ ParamClassDefault,
+ ParamClassExpertFlag,
+ ParamClassForceWriteFlag,
+ ParamClassShortDescription,
+ ParamClassLongDescription,
+ )
+
+
+
+ # all known config keys (param class stripped)
+ Params = {
+
+ 'console.allowedHosts': FcpTypeIPList, # host names, single IPs CIDR-maskip IPs likee 192.168.0.0/24
+ 'console.bindTo': FcpTypeIPList,
+ 'console.directEnabled': FcpTypeBool,
+ 'console.enabled': FcpTypeBool,
+ 'console.port': FcpTypeIPort,
+ 'console.ssl': FcpTypeBool,
+
+
+ 'fcp.allowedHosts': FcpTypeIPList,
+ 'fcp.allowedHostsFullAccess': FcpTypeIPList,
+ 'fcp.assumeDownloadDDAIsAllowed': FcpTypeBool,
+ 'fcp.assumeUploadDDAIsAllowed': FcpTypeBool,
+ 'fcp.bindTo': FcpTypeIP,
+ 'fcp.enabled': FcpTypeBool,
+ 'fcp.persistentDownloadsEnabled': FcpTypeBool,
+ 'fcp.persistentDownloadsFile': FcpTypeFilename,
+ 'fcp.persistentDownloadsInterval': FcpTypeIntWithBounds(0, None),
+ 'fcp.port': FcpTypeIPort,
+ 'fcp.ssl': FcpTypeBool,
+
+
+ 'fproxy.CSSOverride': FcpTypeBool,
+ 'fproxy.advancedModeEnabled': FcpTypeBool,
+ 'fproxy.allowedHosts': FcpTypeIPList,
+ 'fproxy.allowedHostsFullAccess': FcpTypeIPList,
+ 'fproxy.bindTo': FcpTypeIPList,
+ 'fproxy.css': FcpTypeChoiceFProxyCss,
+ 'fproxy.doRobots': FcpTypeBool,
+ 'fproxy.enabled': FcpTypeBool,
+ 'fproxy.javascriptEnabled': FcpTypeBool,
+ 'fproxy.port': FcpTypeIPort,
+ 'fproxy.showPanicButton': FcpTypeBool,
+ 'fproxy.ssl': FcpTypeBool,
+
+
+ 'logger.dirname': FcpTypeDirname,
+ 'logger.enabled': FcpTypeBool,
+ 'logger.interval': FcpType, # ??? 1HOUR ??
+ 'logger.maxCachedBytes': FcpTypeNumBytes,
+ 'logger.maxCachedLines': FcpTypeIntWithBounds(0, None), # ???
+ 'logger.maxZippedLogsSize': FcpTypeNumBytes, # ???
+ 'logger.priority': FcpTypeChoiceLoggerPriority,
+ 'logger.priorityDetail': FcpType, # ???? is it Detailed priority thresholds ???
+
+
+ 'node.alwaysAllowLocalAddresses': FcpTypeBool,
+ 'node.assumeNATed': FcpTypeBool,
+ 'node.bindTo': FcpTypeIP,
+ 'node.clientThrottleFile': FcpTypeFilename,
+ 'node.databaseMaxMemory': FcpTypeNumBytes,
+ 'node.disableHangCheckers': FcpTypeBool,
+ 'node.disableProbabilisticHTLs': FcpTypeBool,
+ 'node.downloadAllowedDirs': FcpTypeChoiceNodeDownloadAllowedDirs,
+ 'node.downloadsDir': FcpTypeDirname,
+ 'node.extraPeerDataDir': FcpTypeDirname,
+ 'node.includeLocalAddressesInNoderefs': FcpTypeBool,
+ 'node.inputBandwidthLimit': FcpTypeNumBytes, # -1 is possible as value aswell
+ 'node.ipAddressOverride': FcpTypeIP,
+ 'node.l10n': FcpType, # ???
+ 'node.lazyResume': FcpTypeBool,
+ 'node.listenPort': FcpTypeIPort,
+ 'node.maxBackgroundUSKFetchers': FcpTypeIntWithBounds(0, None),
+ 'node.maxHTL': FcpTypeIntWithBounds(0, None),
+ 'node.name': FcpTypeString,
+ 'node.nodeDir': FcpTypeDirname,
+ 'node.oneConnectionPerIP': FcpTypeBool,
+ 'node.outputBandwidthLimit': FcpTypeNumBytes,
+ 'node.passOpennetPeersThroughDarknet': FcpTypeBool,
+ 'node.persistentTempDir': FcpTypeDirname,
+ 'node.storeDir': FcpTypeDirname,
+ 'node.storeForceBigShrinks': FcpTypeBool,
+ 'node.storeSize': FcpTypeNumBytes,
+ 'node.tempDir': FcpTypeDirname,
+ 'node.tempIPAddressHint': FcpTypeIP, # ???
+ 'node.testingDropPacketsEvery': FcpTypeIntWithBounds(0, None),
+ 'node.uploadAllowedDirs': FcpTypeChoiceNodeDownloadAllowedDirs,
+
+
+ 'node.testnet.enabled': FcpTypeBool,
+
+
+ 'node.load.aggressiveGC': FcpType, # ???
+ 'node.load.freeHeapBytesThreshold': FcpTypeNumBytes,
+ 'node.load.freeHeapPercentThreshold': FcpTypePercent,
+ 'node.load.memoryChecker': FcpTypeBool,
+ 'node.load.nodeThrottleFile': FcpTypeFilename,
+ 'node.load.threadLimit': FcpTypeIntWithBounds(0, None),
+
+
+ 'node.opennet.acceptSeedConnections': FcpTypeBool,
+ 'node.opennet.alwaysAllowLocalAddresses': FcpTypeBool,
+ 'node.opennet.assumeNATed': FcpTypeBool,
+ 'node.opennet.bindTo': FcpTypeIP,
+ 'node.opennet.enabled': FcpTypeBool,
+ 'node.opennet.listenPort': FcpTypeIPort,
+ 'node.opennet.maxOpennetPeers': FcpTypeIntWithBounds(0, None),
+ 'node.opennet.oneConnectionPerIP': FcpTypeBool,
+ 'node.opennet.testingDropPacketsEvery': FcpTypeIntWithBounds(0, None),
+
+ 'node.scheduler.CHKinserter_priority_policy': FcpTypeChoicePriorityPolicy,
+ 'node.scheduler.CHKrequester_priority_policy': FcpTypeChoicePriorityPolicy,
+ 'node.scheduler.SSKinserter_priority_policy': FcpTypeChoicePriorityPolicy,
+ 'node.scheduler.SSKrequester_priority_policy': FcpTypeChoicePriorityPolicy,
+
+ 'node.updater.URI': FcpTypeUri,
+ 'node.updater.autoupdate': FcpTypeBool,
+ 'node.updater.enabled': FcpTypeBool,
+ 'node.updater.extURI': FcpTypeUri,
+ 'node.updater.revocationURI': FcpTypeUri,
+
+
+ 'pluginmanager.loadplugin': FcpTypeStringList,
+ 'pluginmanager2.loadedPlugins': FcpTypeStringList,
+
+
+ 'ssl.sslEnable': FcpTypeBool,
+ 'ssl.sslKeyPass': FcpTypeString,
+ 'ssl.sslKeyStore': FcpTypeFilename,
+ 'ssl.sslKeyStorePass': FcpTypeString,
+ 'ssl.sslVersion': FcpTypeChoiceSSLVersion,
+
+ 'toadletsymlinker.symlinks': FcpTypeStringList,
+
+ }
+
+
+ def splitAll(self, paramName):
+ return paramName.split(self.ComponentsSep)
+
+ def splitParamClass(self, paramName):
+ return paramName.split(self.ComponentsSep, 1)
+
+ def __getitem__(self, paramName):
+ paramClass, paramKey = self.splitParamClass(paramName)
+ if paramClass == self.ParamClassCurrent:
+ return self.Params[paramName]
+ elif paramClass == self.ParamClassDefault:
+ return self.Params[paramName]
+ elif paramClass == ParamClassExpertFlag:
+ return FcpTypeBool
+ elif paramClass == ParamClassForceWriteFlag:
+ return FcpTypeBool
+ elif paramClass == ParamClassShortDescription:
+ return FcpTypeString
+ elif paramClass == ParamClassLongDescription:
+ return FcpTypeString
+ elif paramClass == ParamClassSortOrder:
+ return FcpTypeInt
+ else:
+ raise ValueError('Unkinown param class in: %r' % paramName)
+
+#***************************************************************************************
+#
+# param types for peer message
+#
+# ..need to do a bit more here, cos it may be needed to validate user input
+#
+#***************************************************************************************
+PeerMessageParams = {
+ 'ark.number': FcpTypeInt,
+ 'auth.negTypes': FcpTypeInt,
+
+
+ 'location': FcpTypeFloat,
+ 'opennet': FcpTypeBool,
+ 'testnet': FcpTypeBool,
+
+ 'metadata.timeLastConnected': FcpTypeTime,
+ 'metadata.timeLastReceivedPacket': FcpTypeTime,
+ 'metadata.timeLastRoutable': FcpTypeTime,
+ 'metadata.timeLastSuccess': FcpTypeTime,
+ 'metadata.routableConnectionCheckCount': FcpTypeInt,
+ 'metadata.hadRoutableConnectionCount': FcpTypeInt,
+
+ 'volatile.averagePingTime': FcpTypeFloat,
+ 'volatile.overloadProbability': FcpTypePercent,
+ 'volatile.routingBackoff': FcpTypeInt,
+ 'volatile.routingBackoffPercent': FcpTypePercent,
+ 'volatile.totalBytesIn': FcpTypeInt,
+ 'volatile.totalBytesOut': FcpTypeInt,
+ 'volatile.routingBackoffLength': FcpTypeInt,
+ }
+
+'''all other Peer message params here....
+
+>> identity=YIrE..................
+>> lastGoodVersion=Fred,0.7,1.0,1106
+>> physical.udp=00.000.000.000:00000
+>> version=Fred,0.7,1.0,1107
+>> dsaGroup.q=ALFDN...............
+>> dsaGroup.p=AIYIrE..................
+>> dsaPubKey.y=YSlb............
+>> dsaGroup.g=UaRa...............
+>> ark.pubURI=SSK@......................
+>>
+>> metadata.detected.udp=000.000.000.000:00000
+
+>> volatile.lastRoutingBackoffReason=ForwardRejectedOverload
+>> volatile.percentTimeRoutableConnection=99.4735.................
+>> volatile.status=CONNECTED
+
+'''
+
+#***************************************************************************************
+#
+# param types for node message
+#
+#***************************************************************************************
+NodeMessageParams = {
+ 'ark.number': FcpTypeInt,
+ 'auth.negTypes': FcpTypeInt,
+ 'location': FcpTypeFloat,
+ 'opennet': FcpTypeBool,
+ 'testnet': FcpTypeBool,
+
+
+ 'volatile.allocatedJavaMemory': FcpTypeInt,
+ 'volatile.availableCPUs': FcpTypeInt,
+ 'volatile.averagePingTime': FcpTypeFloat,
+ 'volatile.avgStoreAccessRate': FcpTypePercent,
+ 'volatile.backedOffPercent': FcpTypePercent,
+ 'volatile.bwlimitDelayTime': FcpTypeFloat,
+ 'volatile.cacheAccess': FcpTypeInt,
+ 'volatile.cachedKeys': FcpTypeInt,
+ 'volatile.cachedSize': FcpTypeInt,
+ 'volatile.cachedStoreHits': FcpTypeInt,
+ 'volatile.cachedStoreMisses': FcpTypeInt,
+ 'volatile.freeJavaMemory': FcpTypeInt,
+ 'volatile.isUsingWrapper': FcpTypeBool,
+ 'volatile.locationChangePerMinute': FcpTypeFloat,
+ 'volatile.locationChangePerSession': FcpTypeFloat,
+ 'volatile.locationChangePerSwap': FcpTypeFloat,
+ 'volatile.maximumJavaMemory': FcpTypeInt,
+ 'volatile.maxOverallKeys': FcpTypeInt,
+ 'volatile.maxOverallSize': FcpTypeInt,
+ 'volatile.networkSizeEstimate24hourRecent': FcpTypeInt,
+ 'volatile.networkSizeEstimate48hourRecent': FcpTypeInt,
+ 'volatile.networkSizeEstimateSession': FcpTypeInt,
+ 'volatile.noSwaps': FcpTypeFloat,
+ 'volatile.noSwapsPerMinute': FcpTypeFloat,
+ 'volatile.numberOfARKFetchers': FcpTypeInt,
+ 'volatile.numberOfBursting': FcpTypeInt,
+ 'volatile.numberOfConnected': FcpTypeInt,
+ 'volatile.numberOfDisabled': FcpTypeInt,
+ 'volatile.numberOfDisconnected': FcpTypeInt,
+ 'volatile.numberOfInsertSenders': FcpTypeInt,
+ 'volatile.numberOfListening': FcpTypeInt,
+ 'volatile.numberOfListenOnly': FcpTypeInt,
+ 'volatile.numberOfNeverConnected': FcpTypeInt,
+ 'volatile.numberOfNotConnected': FcpTypeInt,
+ 'volatile.numberOfRemotePeerLocationsSeenInSwaps': FcpTypeFloat,
+ 'volatile.numberOfRequestSenders': FcpTypeInt,
+ 'volatile.numberOfRoutingBackedOff': FcpTypeInt,
+ 'volatile.numberOfSimpleConnected': FcpTypeInt,
+ 'volatile.numberOfTooNew': FcpTypeInt,
+ 'volatile.numberOfTooOld': FcpTypeInt,
+ 'volatile.numberOfTransferringRequestSenders': FcpTypeInt,
+ 'volatile.numberWithRoutingBackoffReasons.ForwardRejectedOverload': FcpTypeInt,
+ 'volatile.overallAccesses': FcpTypeInt,
+ 'volatile.overallKeys': FcpTypeInt,
+ 'volatile.overallSize': FcpTypeInt,
+ 'volatile.percentCachedStoreHitsOfAccesses': FcpTypePercent,
+ 'volatile.percentOverallKeysOfMax': FcpTypePercent,
+ 'volatile.percentStoreHitsOfAccesses': FcpTypePercent,
+ 'volatile.pInstantReject': FcpTypeFloat, # or percent?
+ 'volatile.recentInputRate': FcpTypeFloat,
+ 'volatile.recentOutputRate': FcpTypeFloat,
+ 'volatile.routingMissDistance': FcpTypeFloat,
+ 'volatile.runningThreadCount': FcpTypeInt,
+ 'volatile.startedSwaps': FcpTypeInt,
+ 'volatile.startupTime': FcpTypeTime,
+ 'volatile.storeAccesses': FcpTypeInt,
+ 'volatile.storeHits': FcpTypeInt,
+ 'volatile.storeKeys': FcpTypeInt,
+ 'volatile.storeMisses': FcpTypeInt,
+ 'volatile.storeSize': FcpTypeInt,
+ 'volatile.swaps': FcpTypeFloat,
+ 'volatile.swapsPerMinute': FcpTypeFloat,
+ 'volatile.swapsPerNoSwaps': FcpTypeFloat,
+ 'volatile.swapsRejectedAlreadyLocked': FcpTypeInt,
+ 'volatile.swapsRejectedLoop': FcpTypeInt,
+ 'volatile.swapsRejectedNowhereToGo': FcpTypeInt,
+ 'volatile.swapsRejectedRateLimit': FcpTypeInt,
+ 'volatile.swapsRejectedRecognizedID': FcpTypeInt,
+ 'volatile.totalInputBytes': FcpTypeInt,
+ 'volatile.totalInputRate': FcpTypeInt,
+ 'volatile.totalOutputBytes': FcpTypeInt,
+ 'volatile.totalOutputRate': FcpTypeInt,
+ 'volatile.totalPayloadOutputBytes': FcpTypeInt,
+ 'volatile.totalPayloadOutputPercent': FcpTypePercent,
+ 'volatile.totalPayloadOutputRate': FcpTypeInt,
+ 'volatile.unclaimedFIFOSize': FcpTypeInt,
+ 'volatile.uptimeSeconds': FcpTypeInt,
+ 'volatile.usedJavaMemory': FcpTypeInt,
+ }
+
+
+'''
+>>all other NodeData message params here....
+>>
+>> physical.udp=000.000.000.000:00000
+>> dsaPubKey.y=GgrpsNUK9m.................................................
+>> version=Fred,0.7,1.0,1107
+>> myName=whatever
+>> ark.pubURI=SSK@...............
+
+>> dsaGroup.q=ALFDNoq.....
+>> dsaGroup.p=AIYIrE9VNhM3.............
+>> volatile.avgConnectedPeersPerNode=15.35................
+>> dsaGroup.g=UaRa.............
+>> dsaPrivKey.x=Pwam..................
+>> ark.privURI=SSK@.................
+>> lastGoodVersion=Fred,0.7,1.0,1106
+>> sig=691f............
+>> identity=vMQa~..................
+
+'''
+
+
+#***************************************************************************************
+#
# Mapping from message params to param types
#
# ...being lazy here, only types that are not strings are declared
@@ -377,12 +865,17 @@
# client messages
+ 'ListPeer': {
+ 'WithMetadata': FcpTypeBool,
+ 'WithVolantile': FcpTypeBool,
+ },
+
'ListPeers': {
'WithMetadata': FcpTypeBool,
'WithVolantile': FcpTypeBool,
},
- #'AddPeer': {}, # ??? check
+ #'AddPeer': # added later as PeerMessageParams
'ModifyPeer': {
'AllowLocalAddresses': FcpTypeBool,
@@ -409,7 +902,7 @@
'WithLongDescription': FcpTypeBool,
},
- #'ModifyConfig': # ??? check
+ #'ModifyConfig': # added later as ConfigMessageParams()
'TestDDARequest': {
'WantReadDirectory': FcpTypeBool,
@@ -462,15 +955,15 @@
},
- #'Peer': {}, # ??? check
+ #'Peer': # added later as PeerMessageParams
'PeerNote': {
'NoteText': FcpTypeBase64EncodedString,
},
- #'NodeData': {}, # ??? check
- #'ConfigData': {}, # ??? check
+ #'NodeData': # added later as NodeMessageParams
+ #'ConfigData': # added later as ConfigMessageParams()
'TestDDAComplete': {
'ReadDirectoryAllowed': FcpTypeBool,
@@ -485,7 +978,7 @@
},
'AllData': {
'Global': FcpTypeBool,
- #NOTE: we ignore startup and completion time here, as long as it is not passed in all messages
+ #NOTE: we ignore startup and completion time here as long as it is not passed in all related messages
},
'FinishedCompression': {
@@ -529,8 +1022,6 @@
'Edition': FcpTypeInt,
},
-
-
}
MessageParamTypes['ClientPutDiskDir'] = MessageParamTypes['ClientPut']
@@ -541,6 +1032,19 @@
MessageParamTypes['PersistentPut'] = MessageParamTypes['ClientPut']
+MessageParamTypes['ModifyConfig'] = MessageParamTypes['ConfigData'] = ConfigMessageParams()
-
+MessageParamTypes['Peer'] = MessageParamTypes['AddPeer'] = PeerMessageParams
+
+
+
+
+
+
+
+
+
+
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|