Thread: SF.net SVN: fclient: [255] trunk/sandbox
Status: Pre-Alpha
Brought to you by:
jurner
|
From: <ju...@us...> - 2008-02-26 09:51:02
|
Revision: 255
http://fclient.svn.sourceforge.net/fclient/?rev=255&view=rev
Author: jurner
Date: 2008-02-26 01:50:39 -0800 (Tue, 26 Feb 2008)
Log Message:
-----------
renames
Added Paths:
-----------
trunk/sandbox/fcp2/
trunk/sandbox/fcp2/__init__.py
trunk/sandbox/fcp2/boards/frost.py
trunk/sandbox/fcp2/client.py
trunk/sandbox/fcp2/config.py
trunk/sandbox/fcp2/consts.py
trunk/sandbox/fcp2/events.py
trunk/sandbox/fcp2/fcp_lib/events.py
trunk/sandbox/fcp2/fcp_lib/namespace.py
trunk/sandbox/fcp2/fcp_lib/numbers.py
trunk/sandbox/fcp2/fcp_lib/tools.py
trunk/sandbox/fcp2/message.py
trunk/sandbox/fcp2/params.py
trunk/sandbox/fcp2/scripts/
trunk/sandbox/fcp2/scripts/gen_docs.py
trunk/sandbox/fcp2/scripts/gen_messagecheatsheet.py
trunk/sandbox/fcp2/test_fcp/client.py
trunk/sandbox/fcp2/test_fcp/dummy_socket.py
trunk/sandbox/fcp2/test_fcp/test_all.py
trunk/sandbox/fcp2/test_fcp/test_client.py
trunk/sandbox/fcp2/test_fcp/test_config.py
trunk/sandbox/fcp2/test_fcp/test_message.py
trunk/sandbox/fcp2/types.py
trunk/sandbox/fcp2/uri.py
Removed Paths:
-------------
trunk/sandbox/fcp2/001.py
trunk/sandbox/fcp2/__init__.py
trunk/sandbox/fcp2/boards/frost.py
trunk/sandbox/fcp2/fcp2_0_client.py
trunk/sandbox/fcp2/fcp2_0_config.py
trunk/sandbox/fcp2/fcp2_0_consts.py
trunk/sandbox/fcp2/fcp2_0_message.py
trunk/sandbox/fcp2/fcp2_0_params.py
trunk/sandbox/fcp2/fcp2_0_uri.py
trunk/sandbox/fcp2/fcp_lib/events.py
trunk/sandbox/fcp2/fcp_lib/namespace.py
trunk/sandbox/fcp2/fcp_lib/numbers.py
trunk/sandbox/fcp2/oo1.py
trunk/sandbox/fcp2/scripts/gen_docs.py
trunk/sandbox/fcp2/scripts/gen_messagecheatsheet.py
trunk/sandbox/fcp2/test_fcp/dummy_socket.py
trunk/sandbox/fcp2/test_fcp/dummy_socket.pyc
trunk/sandbox/fcp2/test_fcp/test_fcp2_0_client.py
trunk/sandbox/fcp2/test_fcp/test_fcp2_0_config.py
trunk/sandbox/fcp2/test_fcp/test_fcp2_0_message.py
Copied: trunk/sandbox/fcp2 (from rev 79, trunk/sandbox/fcp)
Deleted: trunk/sandbox/fcp2/001.py
===================================================================
--- trunk/sandbox/fcp/001.py 2008-01-27 02:16:50 UTC (rev 79)
+++ trunk/sandbox/fcp2/001.py 2008-02-26 09:50:39 UTC (rev 255)
@@ -1,107 +0,0 @@
-
-import random
-import uuid
-#*********************************************************************************************
-#
-#*********************************************************************************************
-def validateFcpBool(value):
- if value in ('true', 'false'):
- return value
- return None
-
-def validateFloat(value):
- try:
- return float(value)
- except ValueError:
- return None
-
-def validateInt(value):
- try:
- return int(value)
- except ValueError:
- return None
-
-def validateUuid(value):
- result = uuid.UUID_EXACT_MATCH_PAT.match(value)
- if result:
- return result.group(0)
- return None
-
-#*********************************************************************************************
-#
-#*********************************************************************************************
-FcParamsSep = '\x01'
-
-FcParams = (
- ('FcSubType', validateInt),
- ('FcInitTime', validateFloat), # can not take it from uuid cos requests may be resend multiple times
- ('FcHandleCollisions', validateFcpBool),
- ('FcCollisionHandled', validateFcpBool),
- ('FcRequestIdentifier', validateUuid),
- ('FcRandomBytes', validateInt),
- )
-
-
-ISubType = 0
-IRequestIdentifier = 1
-IInitTime = 2
-IHandleCollisions = 3
-ICollisionHandled = 4
-IRandomBytes = 5
-
-def paramsFromRequest(msg):
- """
-
- >>> params = [1, 123.456, 'false', 'false', uuid.uuid_time(), 123456789]
- >>> identifier = FcParamsSep.join( [str(i) for i in params] )
- >>> result = paramsFromRequest({'Identifier': identifier})
- >>> result == params
- True
-
- """
- identifier = msg.get('Identifier', None)
- if identifier is None:
- return None
-
- params = identifier.split(FcParamsSep)
- if len(params) != len(FcParams):
- return None
-
- for i, (paramName, paramValidator) in enumerate(FcParams):
- result = paramValidator(params[i])
- if result is None:
- return None
- params[i] = result
-
- return params
-
-def identifierFromRequest(msg):
- """
-
- >>> msg = {'FcSubType':1, 'FcInitTime':1.234, 'FcHandleCollisions':'false', 'FcCollisionHandled':'flase', 'FcRequestIdentifier':uuid.uuid_time(), 'FcRandomBytes':1234567879}
- >>> identifierFromRequest(msg)
-
- """
-
-
- params = []
- for paramName, paramValidator in FcParams:
- params.append(msg[paramName])
-
- params[-1] = random.getrandbits(32) # add some random bits to be able to
- # handle IdentifierCollisions(FcRequestIdentifier
- # remains the same, identifier kown to node changes)
-
- return FcParamsSep.join( [str(i) for i in params] )
-
-
-s = '1\x011.234\x01false\x01flase\x01{fc0125cc-c76f-11dc-9099-fce464f183f6}\x011234567879'
-print len(s)
-#*********************************************************************************
-#
-#*********************************************************************************
-if __name__ == '__main__2':
- import doctest
- doctest.testmod()
-
-
Deleted: trunk/sandbox/fcp2/__init__.py
===================================================================
--- trunk/sandbox/fcp/__init__.py 2008-01-27 02:16:50 UTC (rev 79)
+++ trunk/sandbox/fcp2/__init__.py 2008-02-26 09:50:39 UTC (rev 255)
@@ -1,11 +0,0 @@
-"""Python wrapper for the freenet client protocol
-
-See: [http://www.freenetproject.org]
-"""
-
-
-__author__ = 'Juergen Urner'
-__copyright__ = '(c) 2008 - Juergen Urner'
-__emeil__ = 'jue...@go...'
-__licence__ = 'Mit'
-__version__ = '0.1'
\ No newline at end of file
Copied: trunk/sandbox/fcp2/__init__.py (from rev 241, trunk/sandbox/fcp/__init__.py)
===================================================================
--- trunk/sandbox/fcp2/__init__.py (rev 0)
+++ trunk/sandbox/fcp2/__init__.py 2008-02-26 09:50:39 UTC (rev 255)
@@ -0,0 +1,17 @@
+"""Python wrapper for the freenet client protocol
+
+See: [http://www.freenetproject.org] and [http://wiki.freenetproject.org/FreenetFCPSpec2Point0]
+"""
+
+
+__author__ = 'Juergen Urner'
+__copyright__ = '(c) 2008 - Juergen Urner'
+__email__ = 'jue...@ar...'
+__licence__ = 'Mit'
+__version__ = '0.1'
+
+#****************************************************************************************
+#
+#****************************************************************************************
+def getFcpClient():
+ pass
Deleted: trunk/sandbox/fcp2/boards/frost.py
===================================================================
--- trunk/sandbox/fcp/boards/frost.py 2008-01-27 02:16:50 UTC (rev 79)
+++ trunk/sandbox/fcp2/boards/frost.py 2008-02-26 09:50:39 UTC (rev 255)
@@ -1,99 +0,0 @@
-
-import os, sys, time
-
-#--> rel import hack
-class SysPathHack(object):
- def __init__(self, n):
- fpath = os.path.abspath(__file__)
- for i in xrange(n): fpath = os.path.dirname(fpath)
- sys.path.insert(0, fpath)
- def __del__(self): sys.path.pop(0)
-hack = SysPathHack(2)
-
-from fcp2_0_client import FcpClient
-
-
-del hack
-#<-- rel import hack
-#**********************************************************************
-#
-#**********************************************************************
-#c = FcpClient()
-#c.connect()
-
-
-
-#KSK@frost|message|news|*currentDate*-*boardName*-*slot*.xml
-
-class FrostDate(object):
-
- def __init__(self, year, month, day):
- self.year = year
- self.month = month
- self.day = day
-
- @classmethod
- def now(clss):
- t = time.gmtime(time.time())
- instance = clss(t.tm_year, t.tm_mon, t.tm_mday)
- return instance
-
- def toString(self):
- return '%s.%s.%s' % (self.year, self.month, self.day)
-
-
-
-
-class FrostBoard(object):
-
- def __init__(self):
-
- self.fcpClient = FcpClient(debugVerbosity=FcpClient.DebugVerbosity.Debug)
- for nodeHello in self.fcpClient.connect():
- pass
- self.fcpClient.events.RequestCompleted += self.handleRequestCompleted
-
-
- def handleRequestCompleted(self, event, request):
-
- self.fcpClient.removeRequest(request['Identifier'])
- print request['FcData']
-
-
-
- def readBoard(self, boardName, section, startDate=None):
-
- slot = -1
- while True:
- slot += 1
- if slot > 30: break
-
- ksk = 'KSK@frost|message|%s|%s-%s-%s.xml' % (section, startDate.toString(), boardName, slot)
- print ksk
-
- self.fcpClient.getData(
- uri=ksk,
- maxSize='33000'
- )
-
- for i in xrange(300):
- self.fcpClient.next()
-
-
-
-
-board = FrostBoard()
-
-
-t = FrostDate.now()
-print t.toString()
-
-board.readBoard('de.freenet', 'news', FrostDate.now())
-
-
-
-
-
-
-
-
Copied: trunk/sandbox/fcp2/boards/frost.py (from rev 200, trunk/sandbox/fcp/boards/frost.py)
===================================================================
--- trunk/sandbox/fcp2/boards/frost.py (rev 0)
+++ trunk/sandbox/fcp2/boards/frost.py 2008-02-26 09:50:39 UTC (rev 255)
@@ -0,0 +1,101 @@
+
+import os, sys, time
+
+#--> rel import hack
+class SysPathHack(object):
+ def __init__(self, n):
+ fpath = os.path.abspath(__file__)
+ for i in xrange(n): fpath = os.path.dirname(fpath)
+ sys.path.insert(0, fpath)
+ def __del__(self): sys.path.pop(0)
+hack = SysPathHack(2)
+
+from fcp2_0_client import FcpClient
+
+
+del hack
+#<-- rel import hack
+#**********************************************************************
+#
+#**********************************************************************
+#c = FcpClient()
+#c.connect()
+
+
+
+#KSK@frost|message|news|*currentDate*-*boardName*-*slot*.xml
+
+class FrostDate(object):
+
+ def __init__(self, year, month, day):
+ self.year = year
+ self.month = month
+ self.day = day
+
+ @classmethod
+ def now(clss):
+ t = time.gmtime(time.time())
+ instance = clss(t.tm_year, t.tm_mon, t.tm_mday)
+ return instance
+
+ def toString(self):
+ return '%s.%s.%s' % (self.year, self.month, self.day)
+
+
+
+
+class FrostBoard(object):
+
+ def __init__(self):
+
+ self.fcpClient = FcpClient(debugVerbosity=FcpClient.consts.DebugVerbosity.Debug)
+ nodeHello = self.fcpClient.connect()
+ if nodeHello is None:
+ return False
+
+ self.fcpClient.events.RequestCompleted += self.handleRequestCompleted
+
+
+ def handleRequestCompleted(self, event, request):
+
+ #self.fcpClient.removeRequest(request['Identifier'])
+ print request.data
+
+
+
+ def readBoard(self, boardName, section, startDate=None):
+
+ slot = -1
+ while True:
+ slot += 1
+ if slot > 10: break
+
+ ksk = 'KSK@frost|message|%s|%s-%s-%s.xml' % (section, startDate.toString(), boardName, slot)
+ print ksk
+
+ self.fcpClient.getData(
+ uri=ksk,
+ maxSize='33000'
+ )
+
+ for i in xrange(50):
+ self.fcpClient.next()
+
+
+
+if __name__ == '__main__':
+ board = FrostBoard()
+
+
+ t = FrostDate.now()
+ print t.toString()
+
+ board.readBoard('de.freenet', 'news', FrostDate.now())
+
+
+
+
+
+
+
+
Copied: trunk/sandbox/fcp2/client.py (from rev 254, trunk/sandbox/fcp/client.py)
===================================================================
--- trunk/sandbox/fcp2/client.py (rev 0)
+++ trunk/sandbox/fcp2/client.py 2008-02-26 09:50:39 UTC (rev 255)
@@ -0,0 +1,2307 @@
+"""Freenet client protocol 2.0 implementation
+
+Compatibility: >= Freenet 0.7 Build #1107
+
+
+@newfield event: Event, Events
+@newfield requestparam: RequestParam, RequestParams
+
+@note: The client implementation never uses or watches the global queue. No implementation
+should ever do so. Global is evil.
+@note: the client is not thread save.
+
+
+Sample code. Connect to the freenet node::
+ client = FcpClient()
+ nodeHello = client.connect()
+ if nodeHello is None:
+ pass
+ # something went wrong ..could not connect to the freenet node
+ else:
+ pass
+ # everything went well ..we are connected now
+
+Request data associated to a freenet key::
+ myRequestIdentifier = client.getData('CHK@ABCDE.......')
+ myRequest = c.getRequest(myIdentifier)
+ client.run()
+ print myRequest.data
+
+Usually you would connect handlers to client events to do processing or handle errors::
+ def handleSuccess(event, request):
+ print 'Here is the data:', request.data
+
+ def handleFailure(event, request):
+ print 'Too bad, something went wrong'
+
+ client.events.RequestCompleted += handleSuccess
+ client.events.RequestFailed += handleFailure
+
+ client.getData('CHK@ABCDE.......')
+ c.run()
+
+
+Instead of calling run() you may run the client step by step::
+ client.getData('CHK@ABCDE.......')
+ for i in xrange(50):
+ client.next()
+
+
+You may disconnect event handlers aswell::
+
+ client.events.RequestCompleted -= handleSuccess
+ client.events.RequestFailed -= handleFailure
+
+
+Multiple event handlers may be connected / disconnected at once::
+
+ client.events += (
+ (client.events.RequestCompleted, handleSuccess),
+ (client.events.RequestFailed, handleFailure)
+ )
+
+
+"""
+
+#Bug reports filed and open:
+#--------------------------------------------------------------------------------------------------------------------------------------------
+# [0001931: Send EndListPersistentRequests following client connect]
+#
+# PendingRequests currently get lost if a.) the node goes down b.) if the client goes down unexpectedly.
+# This affects IdentifierCollision + FilenameCollision + ClientPut when a SSK needs to be created first
+#
+# we can handle this case none short of maintaining a file keeping messages. But still there is the
+# 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.
+#------------------------------------------------------------------------------------------------------------------------------------------------
+# [0002083: RemovePersistentRequest ignores unknown requests]
+#
+# minor one, but related to it a major one: you can not change the Priority of requests with
+# Persistence=conncetion
+#
+#FIX: workaround for the "related" part
+#------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+# Todos
+#------------------------------------------------------------------------------------------------------------------------------------------------
+# clean up
+#
+# x. move saveWriteFile and friends to a separate module
+#
+#------------------------------------------------------------------------------------------------------------------------------------------------
+# Fcp types vs. Python types
+#
+# x. Fcp seems to use kibibytes. Autoconvert to kilobytes?
+# x. time intervals
+#
+#------------------------------------------------------------------------------------------------------------------------------------------------
+# logging
+#
+# x. should uris (...) always be visible in log output? Certainly in memory. Maybe a specialized
+# "save" logger could be useful (like for user feedback).
+#
+#------------------------------------------------------------------------------------------------------------------------------------------------
+# runtime
+#
+# x. if the socket dies the client disconnects automatically, clearing all requests.
+# No idea how to handle this. Would require at least an EndListPersistentRequest
+# from the node to check wich requests arrived at the node ..and an auto resend
+# requests the node does not know about.
+#
+#------------------------------------------------------------------------------------------------------------------------------------------------
+# request status
+#
+# x. have to set a dedicated flag when a request is about to be modified or removed
+# Fcp gets confused if we disconnect emidiately after sending a modify or remove request
+# Curretnly the RequestStatus.Completed flag is removed and later set again to get some
+# control over the process.
+#
+# TODO: check if this is a bug in Fcp
+# NOTE: seems to be fixed in [build 1112], fixes removed
+#-------------------------------------------------------------------------------------------------------------------------------------------------
+import atexit
+import copy
+import logging
+import os
+import socket
+import subprocess
+import sys
+import time
+
+
+#--> rel import hack
+class _RelImportHack(object):
+ def __init__(self, n):
+ fpath = os.path.abspath(__file__)
+ for i in xrange(n): fpath = os.path.dirname(fpath)
+ sys.path.insert(0, fpath)
+ def __del__(self): sys.path.pop(0)
+hack = _RelImportHack(2)
+
+
+import fcp.fcp2_0_consts as consts
+from fcp.fcp2_0_events import Events
+from fcp.fcp2_0_config import Config
+from fcp.fcp2_0_message import Message
+import fcp.fcp2_0_params as FcParams
+from fcp.fcp2_0_uri import Uri
+
+from fcp.fcp_lib import namespace
+from fcp.fcp_lib import tools
+
+
+del hack
+#<-- rel import hack
+
+logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
+#*************************************************************************************************
+#
+#*************************************************************************************************
+class FcpClient(object):
+ """
+ @ivar events: events the client supports
+ """
+
+ DefaultFcpHost = os.environ.get('FCP_HOST', '127.0.0.1').strip()
+ try:
+ DefaultFcpPort = int(os.environ.get('FCP_PORT', '').strip())
+ 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 = 32768
+ MinimumRunTime = 1 # minimum time (seconds) the client will run when run() is called (FIX: 0001931)
+ SocketTimeout = 0.1
+ ExpectedFcpVersion = 2.0
+ ExpectedNodeBuild = 1107
+
+ consts = consts
+ Config = Config
+ Message = Message
+ FcParams = FcParams
+ Uri = Uri
+
+
+ def __init__(self,
+ connectionName=None,
+ debugVerbosity=None,
+ ):
+ """
+ @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)
+ self._requests = {} # currently running requests (requestIdentifier --> request)
+
+ self._logEvent = logging.getLogger(consts.LoggerNames.ClientEvents)
+ self._logMessage = logging.getLogger(consts.LoggerNames.ClientMessages)
+ self._logRuntime = logging.getLogger(consts.LoggerNames.ClientRuntime)
+
+ self._nodeHelloMessage = None
+ self._socket = None
+
+ self.events = Events()
+ for event in self.events:
+ event += self._captureEvent
+
+ self.setDebugVerbosity(consts.DebugVerbosity.Warning if debugVerbosity is None else debugVerbosity)
+ atexit.register(self.close)
+
+
+ ###############################################################
+ ##
+ ## private methods
+ ##
+ ###############################################################
+ def _close(self, msg):
+ """Closes the client
+ @param msg: message to pass to the ClientDisconnected event or None to not inform listeners
+ """
+ self._logRuntime.info(consts.LogMessages.ClientClose)
+
+ # clean left over DDA test tmp files
+ for initialRequest in self._ddaTests:
+ if initialRequest['FcTestDDA'].get('TmpFile', None) is not None:
+ tools.saveRemoveFile(initialRequest['FcTestDDA']['TmpFile'])
+
+ self._ddaTests = []
+ self._requests = {}
+
+ if self._socket is None:
+ #TODO: complain or not?
+ pass
+ else:
+ self._socket.close()
+ self._socket = None
+ if msg is not None:
+ self.events.ClientDisconnected(msg)
+
+
+ def _finalizeRequest(self, msg, request, event):
+ """Finalzes a request
+ @param msg: message that is the reason for finalizing
+ @param request: request to finalize
+ @param event: event to trigger or None
+
+ @note: this method sets the requests L{consts.RequestStatus.RemovedFromQueue} and
+ L{consts.RequestStatus.Completed} flags accordingly
+ @note: Fcp removes Get / Put requests with Persistence == connection emidiately
+ from its queue. Same goes all requests on ProtocolError. We inform the caller
+ that the request has been completed and remove it fom our queue if necessary.
+ Non Get / Put requests will be removed in any case.
+ """
+ removeRequest = msg.name in (consts.Message.ProtocolError, consts.Message.PersistentRequestRemoved)
+ if not removeRequest:
+ #NOTE: non Get / Put related requests do not have a Persistence param
+ removeRequest = request.params.get('Persistence', consts.Persistence.Connection) == consts.Persistence.Connection
+ if removeRequest:
+ request['FcRequestStatus'] |= consts.RequestStatus.RemovedFromQueue
+
+ request['FcRequestStatus'] |= consts.RequestStatus.Completed
+ if event is not None:
+ event(request)
+
+ if removeRequest:
+ del self._requests[request['Identifier']]
+
+
+ def _registerRequest(self,
+ msg,
+ requestType,
+ userData=None,
+ identifier=None,
+ initTime=None,
+ persistentUserData='',
+ filenameCollision=consts.FilenameCollision.HandleNever,
+ ):
+ """Registers a request
+ @param msg: message to register
+ @param requestType: (L{consts.RequestType}) type of request to register
+ @param filenameCollision: (L{consts.FilenameCollision}) how to handle filename collisions.
+ Default is L{consts.FilenameCollision.HandleNever}
+ @param identifier: (str) identifier of the request or None to create a new one
+ @param initTime: (int) init time of the request or None to set it to now
+ @param persistentUserData: (str) anyuser defined persistent data
+ @param userData: (any) any user defined non persistent data
+
+ @return: (str) identifer of therequest
+ @note: the identifier returned is unique to the client but may not be unique to the node
+ """
+ identifier = self.FcParams.newUuid(uuids=self._requests) if identifier is None else identifier
+
+ if requestType & (consts.RequestType.MaskGet | consts.RequestType.MaskPut):
+
+ msg.params.update({
+
+ # persistent params that will go into identifier
+ 'FcRequestType': requestType, # identifies sub message types
+ 'FcInitTime': time.time() if initTime is None else initTime, # when was the request started?
+ 'FcFilenameCollision': filenameCollision, # handle fielanem collisions?
+ 'FcPersistentUserData': persistentUserData, # any user defined persistent data
+
+ # non persistent params
+ 'FcRequestStatus': consts.RequestStatus.Null,
+ 'FcErrorMessage': None, # error message in case an error occured
+ 'FcUserData': userData, # any user defined runtime data here
+
+ # params for SSKKeypair
+ 'FcPrivateKey': None,
+ 'FcPublicKey': None,
+
+ # params from DataFound
+ 'FcMetadataContentType': '', # contecnt type
+ 'FcDataLength': '', # content size
+
+ # params from PersistentRequestModified
+ 'FcModified': {},
+
+ # params for DDA test
+ 'FcTestDDA': {},
+
+ # params for SimpleProgress
+ 'FcProgressTotal': '0',
+ 'FcProgressRequired': '0',
+ 'FcProgressFailed': '0',
+ 'FcProgressFatalyFailed': '0',
+ 'FcProgressSucceeeded': '0',
+
+ })
+ # equip msg with some persistent pparams
+ if msg.get('ClientToken', None) is None:
+ msg['ClientToken'] = self.FcParams.messageToParams(msg)
+
+ elif requestType & consts.RequestType.MaskGenerateKeypair:
+ msg.params.update({
+ 'FcRequestType': requestType, # identifies sub message types
+ 'FcRequestStatus': consts.RequestStatus.Null,
+ 'FcInitTime': initTime, # when was the request started?
+ 'FcModified': {},
+
+ 'FcPrivateKey': None,
+ 'FcPublicKey': None,
+ })
+
+ elif requestType & consts.RequestType.PluginMessage:
+ msg.params.update({
+ 'FcRequestType': requestType, # identifies sub message types
+ 'FcRequestStatus': consts.RequestStatus.Null,
+ 'FcInitTime': initTime, # when was the request started?
+ 'FcModified': {},
+
+ 'FcPluginReply': None,
+ })
+
+
+
+ else:
+ msg.params.update({
+ 'FcRequestType': requestType, # identifies sub message types
+ 'FcRequestStatus': consts.RequestStatus.Null,
+ 'FcInitTime': initTime, # when was the request started?
+ 'FcModified': {},
+ })
+
+ msg['FcRequestStatus'] |= consts.RequestStatus.Null
+ msg['Identifier'] = identifier
+ self._requests[identifier] = msg
+
+
+ def _captureEvent(self, event, request):
+ if event != self.events.Idle:
+ self._logEvent.debug(consts.LogMessages.EventTriggered + event.name)
+
+ ###############################################################
+ ##
+ ## connection related methods
+ ##
+ ###############################################################
+ def close(self):
+ """Closes the client
+ @note: make shure to call close() when done with the client
+ """
+ msg = self.Message(
+ consts.Message.ClientDisconnected,
+ DisconnectReason=consts.DisconnectReason.Close,
+ Param=None,
+ )
+ self._close(msg)
+
+
+ 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):
+ """Connects to the freenet node
+ @param host: (str) host of th node
+ @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
+
+ @return: (L{fcp2_0_message.Message}) NodeHello or None if no connection could be established
+ """
+ nodeHello = None
+ for nodeHello in self.iterConnect(host=host, port=port, duration=duration, timeout=timeout):
+ pass
+ return nodeHello
+
+
+ def iterConnect(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
+ @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
+
+ @return: (L{fcp2_0_message.Message}) NodeHello if successful, None ot...
[truncated message content] |