fclient-commit Mailing List for fclient (Page 34)
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-04 11:53:19
|
Revision: 137 http://fclient.svn.sourceforge.net/fclient/?rev=137&view=rev Author: jurner Date: 2008-02-04 03:53:08 -0800 (Mon, 04 Feb 2008) Log Message: ----------- remove3d checks... ClientPutComplexDir does not like them 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-04 11:51:16 UTC (rev 136) +++ trunk/sandbox/fcp/fcp2_0_message.py 2008-02-04 11:53:08 UTC (rev 137) @@ -199,13 +199,6 @@ out.append('%s=%s' % (param, value)) if self.data: - assert 'DataLength' in self.params, 'DataLength member required' - n = None - try: - n = int(self['DataLength']) - except ValueError: pass - assert n is not None, 'DataLength member must be an integer' - assert n == len(self.data), 'DataLength member must corrospond to lenght of data' out.append('Data') out.append(self.data) else: @@ -214,3 +207,5 @@ + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-04 11:51:38
|
Revision: 136 http://fclient.svn.sourceforge.net/fclient/?rev=136&view=rev Author: jurner Date: 2008-02-04 03:51:16 -0800 (Mon, 04 Feb 2008) Log Message: ----------- fix 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-04 11:50:30 UTC (rev 135) +++ trunk/sandbox/fcp/fcp2_0_config.py 2008-02-04 11:51:16 UTC (rev 136) @@ -36,7 +36,7 @@ out.append(parent.name) parent = parent.parent out.reverse() - return types-ConfigMessageParams.ComponentsSep.join(out) + return types.ConfigMessageParams.ComponentSep.join(out) #**************************************************************************************** @@ -129,7 +129,6 @@ """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: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-04 11:50:53
|
Revision: 135 http://fclient.svn.sourceforge.net/fclient/?rev=135&view=rev Author: jurner Date: 2008-02-04 03:50:30 -0800 (Mon, 04 Feb 2008) Log Message: ----------- fixes 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-04 11:49:28 UTC (rev 134) +++ trunk/sandbox/fcp/fcp2_0_client.py 2008-02-04 11:50:30 UTC (rev 135) @@ -113,6 +113,7 @@ from fcp2_0_config import Config from fcp2_0_message import Message import fcp2_0_params as FcParams +from fcp2_0_requests import Upload from fcp2_0_uri import Uri @@ -203,6 +204,7 @@ Message = Message FcParams = FcParams Uri = Uri + Upload = Upload @@ -339,7 +341,7 @@ fcParams[self.FcParams.IFilenameCollision], ) - # fix some Fcp inconsistencies ClientGet vs. PersistentGet + #FIX: remove Started param from PersistentGet / Put if msg.name == consts.Message.PersistentGet: del msg.params['Started'] #FIX: [0001965: Persistence vs PersistenceType] @@ -1462,7 +1464,7 @@ ## ClientPut related methods ## ######################################################## - def clientPutUpload(self, upload, userData=None, persistentUserData=''): + def putUpload(self, upload, userData=None, persistentUserData=''): msg = upload.getMessage(self.Message) if msg is None: @@ -1486,10 +1488,9 @@ ) if upload.keyType in (consts.KeyType.SSK, consts.KeyType.USK): - msg['FcRequestUri'] = upload.publicKey + msg['FcInsertUri'] = upload.privateKey #NOTE: the caller may use the 'FcInsertUri' member to store the private key - self.sendMessageEx(msg) return msg['Identifier'] @@ -1505,6 +1506,8 @@ msg = self.Message(consts.Message.ClientPut, URI=uri) for paramName, value in messageParams.items(): if value is not None: + if param == 'ContentType': + param = 'Metadata.ContentType' msg[paramName] = value if data is not None: msg.data = data @@ -1892,7 +1895,7 @@ if nodeHello is not None: - #for i in xrange(50): + #for i in xrange(10): # c.next() @@ -1970,7 +1973,13 @@ #persistence=c.Persistence.Reboot, ) - for i in xrange(100): + #u = c.Upload(c.consts.KeyType.USK, privateKey='USK@eeqMkAamPTUz983Sfr4Ce-ckPUwFgpuTwB~wce0BK3E,rMfH3jUrLRz23fltO-LGEEjnni9DwNKlPzWzaDqOTe8,AQACAAE/') + #u.addData('foo/0/', 'test1234') + #u.addData('bar', 'test12345678') + #u.addData('baz', 'test12345678') + #c.putUpload(u) + + for i in xrange(500): c.next() #c.removeRequest(myIdentifier) #for i in xrange(5): @@ -1982,9 +1991,12 @@ def testPutFile(): fpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test.jpg') - identifier = c.putFile( - fpath, - ) + #identifier = c.putFile( + # fpath, + # ) + u = c.Upload(c.consts.KeyType.CHK) + u.addFile('', fpath) + c.putUpload(u) for i in xrange(1000): c.next() @@ -1993,6 +2005,7 @@ # c.next() #testPutFile() + def testConfigData(): @@ -2027,7 +2040,7 @@ for i in xrange(10): c.next() - #testConfigData() + testConfigData() @@ -2049,6 +2062,7 @@ def cb(event, msg): print msg.pprint() + pass c.events.KeypairGenerated += cb c.generateKeypair('SSK@') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-04 11:49:35
|
Revision: 134 http://fclient.svn.sourceforge.net/fclient/?rev=134&view=rev Author: jurner Date: 2008-02-04 03:49:28 -0800 (Mon, 04 Feb 2008) Log Message: ----------- reworked events Modified Paths: -------------- trunk/sandbox/fcp/fcp_lib/events.py Modified: trunk/sandbox/fcp/fcp_lib/events.py =================================================================== --- trunk/sandbox/fcp/fcp_lib/events.py 2008-02-04 03:17:38 UTC (rev 133) +++ trunk/sandbox/fcp/fcp_lib/events.py 2008-02-04 11:49:28 UTC (rev 134) @@ -1,104 +1,63 @@ """Signals and events""" -#*********************************************************************** +#********************************************************************* # -# event handler. Mostly taken from -#http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410686 -# -#*********************************************************************** -class EventMeta(type): - """Metaclass for events""" - - class Event(object): - """Event handler - - @ivar observers: list of observers of the event - """ - - def __init__(self, name): - """ - @param name: (str) name of the event - """ - self.name = name - self.observers = [] - - def __call__(self, *args, **kwargs): - """Dispatches the event and additional parameters to all observers registerd""" - for o in self.observers: - o(self, *args, **kwargs) - - def __contains__(self, observer): - """Checks if an observer is aleady registered - @return: bool - """ - return observer in self.observers - - def __iadd__(self, observer): - """Adds an observer to the event - @note: the observer will be called with the event as first paraeter, - followed by any number of *args or **kwargs passed by the caller of an event - """ - self.observers.append(observer) - return self - - def __isub__(self, observer): - """Removes the first occurence of an observer from the event""" - self.observers.remove(observer) - return self - - def __new__(clss, name, bases, kws): - events = kws.get('_events_', None) - if events is None: - raise ValueError('Event classes must implement an "_event_" attribute') - for event_name in events: - kws[event_name] = clss.Event(event_name) - return type.__new__(clss, name, bases, kws) - - +#********************************************************************* class Events(object): - """Base class for events + """Events - Derrived classes should list events they support in the "_events_" tuple. - Each event name is automagically set as attribute of the event - class. + Class to bundle events. Usually you would add events to it by + adding one or more event classes as inner classes. As soon + as the class is instantiated the events will be auto initialized + and available as callable objects. - Listeners may register to receiving events by calling __iadd__, - unregister by calling __isub__ on these attributes. Callback are - always called with the event as first argument, followed by additional - arguments, depending on the event. + >>> class MyEvents(Events): + ... class event1(Event): pass + ... class event2(Event): pass - @note: always make shure to disconnnect when event notification is no longer desired - - - >>> class MyEvents(Events): - ... _events_ = ('FooEvent', 'BarEvent') - ... >>> events = MyEvents() - >>> def cb(event): - ... print 'Received: %s' % event.name + >>> sorted([event.name for event in events]) + ['event1', 'event2'] - >>> events.FooEvent += cb - >>> events.FooEvent() - Received: FooEvent + >>> def myCallback(event, arg): print arg + >>> events += (events.event1, myCallback), (events.event2, myCallback) + >>> events.event1('foo') + foo + >>> events.event2('bar') + bar - >>> events.FooEvent -= cb - >>> events.FooEvent() + >>> events -= (events.event1, myCallback), (events.event2, myCallback) + >>> events.event1('foo') - >>> events += ( (events.FooEvent, cb), (events.BarEvent, cb) ) - >>> events.FooEvent() - Received: FooEvent - >>> events.BarEvent() - Received: BarEvent + >>> events.event1 += myCallback + >>> events.event1('foo') + foo - >>> events -= ( (events.FooEvent, cb), (events.BarEvent, cb) ) - >>> events.FooEvent() + >>> events.event1 -= myCallback + >>> events.event1('foo') + + @note: this class is a bit of a hack. You may not add any (not with underscore starting) + attrs, methods to it except from events + """ - >>> events.BarEvent() + def __init__(self): + """""" + for name in dir(self): + if not name.startswith('_'): + event = getattr(self, name) + setattr(self, name, event(name)) + + - """ - __metaclass__ = EventMeta - _events_ = () - + def __iter__(self): + """Iterator over all events of the instance + @return: (L{Event}) next event in turn + """ + for name in dir(self): + if not name.startswith('_'): + event = getattr(self, name) + yield getattr(self, name) + def __iadd__(self, events): """Adds one or more events / observers at once @param events: tuple( (event, observer), (event, observer), ...) @@ -114,8 +73,60 @@ for event, observer in events: event -= observer return self + +#********************************************************************* +# +#********************************************************************* +class Event(object): + """Event class + + @ivar name: name of the event + @ivar observers: observers listening to the event + + >>> event = Event('myEventsName') + >>> event.name + 'myEventsName' + + >>> def myCallback(event, arg): print arg + >>> event += myCallback + >>> event('foo') + foo + + >>> event -= myCallback + >>> event('foo') + """ + + def __init__(self, name): + """ + @param name: name of the event + """ + self.name = name + self.observers = [] + + def __call__(self, *args, **kwargs): + """Dispatches the event and additional parameters to all observers registerd""" + for o in self.observers: + o(self, *args, **kwargs) + + def __contains__(self, observer): + """Checks if an observer is aleady registered + @return: bool + """ + return observer in self.observers - + def __iadd__(self, observer): + """Adds an observer to the event + @note: the observer will be called with the event as first paraeter, + followed by any number of *args or **kwargs passed by the caller of an event + """ + self.observers.append(observer) + return self + + def __isub__(self, observer): + """Removes the first occurence of an observer from the event""" + self.observers.remove(observer) + return self + #********************************************************************* # #********************************************************************* This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-04 03:17:32
|
Revision: 133 http://fclient.svn.sourceforge.net/fclient/?rev=133&view=rev Author: jurner Date: 2008-02-03 19:17:38 -0800 (Sun, 03 Feb 2008) Log Message: ----------- added a few utility scripts Added Paths: ----------- trunk/sandbox/fcp/scripts/ trunk/sandbox/fcp/scripts/__init__.py trunk/sandbox/fcp/scripts/fcpscripts_consts.py trunk/sandbox/fcp/scripts/gen_docs.py trunk/sandbox/fcp/scripts/gen_messagecheatsheet.py Added: trunk/sandbox/fcp/scripts/__init__.py =================================================================== --- trunk/sandbox/fcp/scripts/__init__.py (rev 0) +++ trunk/sandbox/fcp/scripts/__init__.py 2008-02-04 03:17:38 UTC (rev 133) @@ -0,0 +1 @@ + Added: trunk/sandbox/fcp/scripts/fcpscripts_consts.py =================================================================== --- trunk/sandbox/fcp/scripts/fcpscripts_consts.py (rev 0) +++ trunk/sandbox/fcp/scripts/fcpscripts_consts.py 2008-02-04 03:17:38 UTC (rev 133) @@ -0,0 +1,29 @@ +"""Some consts for scripts""" + +import os +#************************************************************************** +# +#************************************************************************** +FcpDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +DocDir = os.path.join(FcpDir, 'doc') +EpydocFolder = 'epydoc' +EpydocDir = os.path.join(DocDir, EpydocFolder) + +FilenameMessageCheatSheet = 'MessageCheatSheet.html' + +WikiBaseUri = 'http://wiki.freenetproject.org/' +WikiStartPage = WikiBaseUri + 'FreenetFCPSpec2Point0' +WikiFcpPrefix = 'FCP2p0' + +#************************************************************************** +# some helpers +#************************************************************************** +def saveCreateDir(directory): + if not os.path.isdir(directory): + os.mkdir(directory) + +def enshureDocDirExists(): + saveCreateDir(DocDir) + saveCreateDir(EpydocDir) + + \ No newline at end of file Added: trunk/sandbox/fcp/scripts/gen_docs.py =================================================================== --- trunk/sandbox/fcp/scripts/gen_docs.py (rev 0) +++ trunk/sandbox/fcp/scripts/gen_docs.py 2008-02-04 03:17:38 UTC (rev 133) @@ -0,0 +1,59 @@ +"""Generates epydoc documentation for the package + +gen_docs.py + +@note: the script assumes it is located in the scripts subdirectory of the fcp package +@note: Use gen_docs.py -? or --help to print out this help text +""" + +from __future__ import with_statement + +import sys, os +from epydoc import cli +import subprocess + +import fcpscripts_consts as consts +import gen_messagecheatsheet +#************************************************************************************** +# +#************************************************************************************** +def main(): + """""" + + consts.enshureDocDirExists() + print 'calling epydoc' + sys.argv = [ + __file__, + '-v', + '-o%s' % consts.EpydocDir, + '--src-code-tab-width', '4', + #'--debug', + consts.FcpDir, + ] + cli.cli() + print 'ok' + + # create a redirect to 'epydoc/index.html' + print 'creating redirect' + with open(os.path.join(consts.DocDir, 'index.html'), 'w') as fp: + fp.write('''<html> + <head> + <meta http-equiv="Refresh" content="0; URL=%s"> + </head> +</html> +''' % (consts.EpydocFolder + '/' + 'index.html') ) + + print 'done' + +#************************************************************************************** +# +#************************************************************************************** +if __name__ == '__main__': + wantsHelp = len(sys.argv) > 1 and sys.argv[1] or None + if wantsHelp not in ('-?', '--help'): + sys.exit(main()) + + print __doc__ + + + Added: trunk/sandbox/fcp/scripts/gen_messagecheatsheet.py =================================================================== --- trunk/sandbox/fcp/scripts/gen_messagecheatsheet.py (rev 0) +++ trunk/sandbox/fcp/scripts/gen_messagecheatsheet.py 2008-02-04 03:17:38 UTC (rev 133) @@ -0,0 +1,203 @@ +"""Dumps a cheatsheet for all Fcp messages as taken from the freenet wiki to 'MessageCheatSheet.html' + +gen_cheatsheet.py [path-to-tidy-executable] + +@note: this script assumes it is located in the 'scripts' folder of the fcp package +@note: tidy has to be installed +@note: if tidy can not be run by typing 'tidy' into your shell, you have to pass +the full path to the tidy executable +@note: the script will dump documentations for Fcp messages from the freenet wiki [http://wiki.freenetproject.org/]. +If you don't like that, don't use this script. +@note: the cheat sheet comes equipped with anchors to jump to a specified message (..MessageCheatSheet.html#NodeHello) +@note: gen_cheatsheet.py -? or --help will print out this help text + +""" +from __future__ import with_statement + + +import os, sys + +import cStringIO +import shutil +import subprocess +import urllib +from xml.etree import cElementTree as ET + +import fcpscripts_consts as consts +#******************************************************************************* +# +#******************************************************************************* +Dir = os.path.dirname(os.path.abspath(__file__)) + + +#TODO: does shell=True work on windows? +UseShell = True + + +def tidyPage(data, commandline): + p = subprocess.Popen( + args=commandline, + shell=UseShell, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + stdin, stderr = p.communicate(input=data) + return stdin + + +def readPage(url, tidy): + fp = urllib.urlopen(url) + try: + data = fp.read() + data = tidyPage(data, tidy) + + # remove namespace decl tidy added + data = data.split('\n', 1)[1] + data = '<html>\n' + data + + return ET.fromstring(data) + finally: + fp.close() + + +def parentMap(tree): + m = {} + for parent in tree.getiterator(): + for child in parent: + m[child] = parent + return m + + +def createCheatSheet(tidy=None): + + if tidy is None: + tidy = 'tidy' + TidyToXml = '%s --output-xml yes --doctype omit --numeric-entities yes --show-warnings no' % tidy + TidyToHtml = '%s --input-xml --output-html yes --indent yes --show-warnings no' % tidy + + buf = cStringIO.StringIO() + tree = readPage(consts.WikiStartPage, TidyToXml) + + tables = tree.findall('.//table') + if tables: + + # assert refs to messages are located in table 0 + table = tables[0] + + # get all refs to messages + As = table.findall('.//a') + As.sort(cmp=lambda x,y: cmp(x.attrib.get('href', 0), y.attrib.get('href', 0)) ) + for a in As: + hrefMessage = a.attrib.get('href', None) + if hrefMessage is not None: + + uri = consts.WikiBaseUri + hrefMessage + tree = readPage(uri, TidyToXml) + + # find <div class="page"> + DIVs = tree.findall(".//div") + for div in DIVs: + clss = div.attrib.get('class', None) + if clss == 'page': + + parentmap = parentMap(div) + #print parents + + # remove all forms and scripts + if 'ondblclick' in div.attrib: + del div.attrib['ondblclick'] + + forms = div.findall('.//form') + for form in forms: + parent = parentmap[form] + parent.remove(form) + + # disable all refs + As = div.findall('.//a') + for a in As: + href = a.attrib.get('href', None) + if href is not None: + if 'href' in a.attrib: + del a.attrib['href'] + + # place an anchor to message name and some deco + a = ET.Element('a', {'name': hrefMessage.replace(consts.WikiFcpPrefix, '')}) + div.insert(0, a) + hr = ET.Element('hr') + div.append(hr) + + tree = ET.ElementTree(div) + tree.write(buf) + # + fpathCheatSheet = os.path.join(Dir, consts.FilenameMessageCheatSheet) + with open(fpathCheatSheet, 'w') as fp: + fp.write(tidyPage(buf.getvalue(), TidyToHtml) ) + return fpathCheatSheet + + +def main(tidy=None): + print 'generating message cheat sheet from: %s' % consts.WikiStartPage + fpath = createCheatSheet(tidy) + print 'done' + + +#******************************************************************************* +# +#******************************************************************************* +if __name__ == '__main__': + if len(sys.argv) > 1: + param = sys.argv[1] + if param in ('-?', '--help'): + print __doc__ + else: + main(param) + main() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-04 03:16:43
|
Revision: 132 http://fclient.svn.sourceforge.net/fclient/?rev=132&view=rev Author: jurner Date: 2008-02-03 19:16:48 -0800 (Sun, 03 Feb 2008) Log Message: ----------- docs 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-04 03:16:21 UTC (rev 131) +++ trunk/sandbox/fcp/fcp2_0_uri.py 2008-02-04 03:16:48 UTC (rev 132) @@ -69,18 +69,27 @@ class Uri(object): - + """Class wrappinf a freenet Uri + + @ivar keyType: L{consts.KeyType} of the uri + @ivar uri: (str) uri contained in the instance + """ + KeyType = consts.KeyType def __init__(self, uri): + """ + @param uri: (str) freenet uri (may be an uri like http://..CHK@ or + freenet:CHK@ or whatever or a a freenet key) + """ self.uri = stripUri(uri) - result = keyType(self.uri) self.keyType = self.KeyType.Invalid if result is None else result def __nonzero__(self): + """Checks if the uri contained in the instance is a vaild freenet uri""" return self.keyType != self.KeyType.Invalid This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-04 03:16:16
|
Revision: 131 http://fclient.svn.sourceforge.net/fclient/?rev=131&view=rev Author: jurner Date: 2008-02-03 19:16:21 -0800 (Sun, 03 Feb 2008) Log Message: ----------- for completeness, added ClientHello to types Modified Paths: -------------- trunk/sandbox/fcp/fcp2_0_types.py Modified: trunk/sandbox/fcp/fcp2_0_types.py =================================================================== --- trunk/sandbox/fcp/fcp2_0_types.py 2008-02-04 03:14:49 UTC (rev 130) +++ trunk/sandbox/fcp/fcp2_0_types.py 2008-02-04 03:16:21 UTC (rev 131) @@ -332,7 +332,7 @@ def splitAll(self, paramName): """Splits a parameter name into its components - @param (str) paramName: parameter name to split + @param paramName: (str) parameter name to split @return: (list) components """ return paramName.split(self.ComponentSep) @@ -340,7 +340,7 @@ def splitParamClass(self, paramName): """Splits the parameter class from a parameter name - @param (str) paramName: parameter name to split + @param paramName: (str) parameter name to split @return: (tuple) paramClass, tail """ return paramName.split(self.ComponentSep, 1) @@ -565,6 +565,9 @@ 'MaxTempSize': FcpTypeInt, 'Verbosity': FcpTypeInt, }, + 'ClientHello': { + 'ExpectedVersion': FcpTypeInt, + }, 'ClientPut': { 'BinaryBlob': FcpTypeBool, 'DontCompress': FcpTypeBool, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-04 03:14:45
|
Revision: 130 http://fclient.svn.sourceforge.net/fclient/?rev=130&view=rev Author: jurner Date: 2008-02-03 19:14:49 -0800 (Sun, 03 Feb 2008) Log Message: ----------- added cosnst 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-04 03:14:24 UTC (rev 129) +++ trunk/sandbox/fcp/fcp2_0_consts.py 2008-02-04 03:14:49 UTC (rev 130) @@ -296,6 +296,7 @@ class MessageStatus: + Null = 0x0 Pending = 0x1 Compressing = 0x2 Started = 0x4 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-04 03:14:19
|
Revision: 129 http://fclient.svn.sourceforge.net/fclient/?rev=129&view=rev Author: jurner Date: 2008-02-03 19:14:24 -0800 (Sun, 03 Feb 2008) Log Message: ----------- fixes request.status 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-03 13:16:37 UTC (rev 128) +++ trunk/sandbox/fcp/fcp2_0_client.py 2008-02-04 03:14:24 UTC (rev 129) @@ -102,14 +102,19 @@ hack = SysPathHack(3) -from fcp_lib import events, namespace +from fcp_lib import namespace del hack #<-- rel import hack -import fcp2_0_message import fcp2_0_consts as consts +from fcp2_0_events import Events +from fcp2_0_config import Config +from fcp2_0_message import Message +import fcp2_0_params as FcParams +from fcp2_0_uri import Uri + logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) @@ -193,67 +198,14 @@ ExpectedFcpVersion = 2.0 ExpectedNodeBuild = 1107 - from fcp2_0_config import Config consts = consts - from fcp2_0_message import Message - import fcp2_0_params as FcParams - from fcp2_0_uri import Uri + Config = Config + Message = Message + FcParams = FcParams + Uri = Uri - class Events(events.Events): - """All events the client supports""" - _events_ = ( - - 'Idle', - - 'ClientConnected', - 'ClientDisconnected', - - 'RequestCompleted', # the request is not removed neither from node nor client - 'RequestFailed', # the request is already removed from node and client - 'RequestFetchable', - 'RequestModified', - 'RequestProgress', - 'RequestRestored', - 'RequestStarted', - - - # config related events - 'ConfigData', - 'NodeData', - - - #Peer related events - 'EndListPeers', - 'Peer', - 'PeerRemoved', - 'UnknownNodeIdentifier', - 'EndListPeerNotes', - 'PeerNote', - - - # plugins - 'PluginInfo', - 'PluginInfoFailed', - 'PluginMessage' - 'PluginMessagefailed', - - # others - 'KeypairGenerated', - - 'USKUpdated', - - ############################### - - 'ProtocolError', - - - - ) - - - def __init__(self, connectionName=None, debugVerbosity=None, @@ -272,7 +224,7 @@ self._nodeHelloMessage = None self._socket = None - self.events = self.Events() + self.events = Events() self.setDebugVerbosity(consts.DebugVerbosity.Warning if debugVerbosity is None else debugVerbosity) atexit.register(self.close) @@ -814,11 +766,12 @@ if initialRequest is None: return False + initialRequest['FcStatus'] = consts.MessageStatus.Complete # Fcp removes requests from queue with Persistence.Connection.. so do we if initialRequest.params.get('Persistence', consts.Persistence.Connection) == consts.Persistence.Connection: + initialRequest['FcStatus'] |= consts.MessageStatus.Removed del self._requests[requestIdentifier] - initialRequest['FcStatus'] = consts.MessageStatus.Complete initialRequest.data = msg.data self.events.RequestCompleted(initialRequest) return True @@ -831,8 +784,7 @@ initialRequest['FcMetadataContentType'] = msg.get('Metadata.ContentType', '') initialRequest['FcDataLength'] = msg.get('DataLength', '') if initialRequest['FcSubType'] != consts.MessageSubType.GetData: - initialRequest['FcStatus'] = consts.MessageStatus.Complete - + initialRequest['FcStatus'] |= consts.MessageStatus.Removed # Fcp removes requests from queue with Persistence.Connection.. so do we if initialRequest.params.get('Persistence', consts.Persistence.Connection) == consts.Persistence.Connection: del self._requests[requestIdentifier] @@ -843,21 +795,24 @@ elif msg.name == consts.Message.GetFailed: if initialRequest is None: return False - + + initialRequest['FcStatus'] = consts.MessageStatus.Null + # Fcp removes requests from queue with Persistence.Connection.. so do we if initialRequest.params.get('Persistence', consts.Persistence.Connection) == consts.Persistence.Connection: + initialRequest['FcStatus'] = consts.MessageStatus.Removed del self._requests[requestIdentifier] # check if it is one of our requests for key information code = msg['Code'] if code == consts.FetchError.TooBig and initialRequest['FcSubType'] == consts.MessageSubType.GetKeyInfo: - initialRequest['FcStatus'] = consts.MessageStatus.Complete + initialRequest['FcStatus'] |= consts.MessageStatus.Complete initialRequest['FcMetadataContentType'] = msg.get('ExpectedMetadata.ContentType', '') initialRequest['FcDataLength'] = msg.get('ExpectedDataLength', -1) self.events.RequestCompleted(initialRequest) else: initialRequest['FcErrorMessage'] = msg - initialRequest['FcStatus'] = consts.MessageStatus.Error + initialRequest['FcStatus'] |= consts.MessageStatus.Error self.events.RequestFailed(initialRequest) return True @@ -1004,12 +959,14 @@ if initialRequest is None: return False + initialRequest['FcStatus'] = consts.MessageStatus.Error + # Fcp removes requests from queue with Persistence.Connection.. so do we if initialRequest.params.get('Persistence', consts.Persistence.Connection) == consts.Persistence.Connection: + initialRequest['FcStatus'] |= consts.MessageStatus.Removed del self._requests[requestIdentifier] initialRequest['FcErrorMessage'] = msg - initialRequest['FcStatus'] = consts.MessageStatus.Error self.events.RequestFailed(initialRequest) return True @@ -1031,6 +988,11 @@ # as long as no corrosponding params are passed in DataFound # we ignore them initialRequest['FcStatus'] = consts.MessageStatus.Complete + + if initialRequest.params.get('Persistence', consts.Persistence.Connection) == consts.Persistence.Connection: + initialRequest['FcStatus'] |= consts.MessageStatus.Removed + del self._requests[requestIdentifier] + initialRequest['URI'] = msg['URI'] self.events.RequestCompleted(initialRequest) return True @@ -1062,7 +1024,7 @@ return True elif msg.name == consts.Message.UnknownNodeIdentifier: - self.events.UnknownNodeIdentifier(msg) + self.events.PeerUnknown(msg) return True #################################################### @@ -1315,10 +1277,10 @@ @return: (str) request identifier - @param event: RequestCompleted(event, message) triggered when the request is complete - @param event: RequestFailed(event, message) triggered when the request failes - @param event: RequestStarted(event, message) triggered when as the request is started - @param event: RequestModified(event, message) trigggered if the request identifier changes + @event: RequestCompleted(event, message) triggered when the request is complete + @event: RequestFailed(event, message) triggered when the request failes + @event: RequestStarted(event, message) triggered when as the request is started + @event: RequestModified(event, message) trigggered if the request identifier changes or the request is modified otherwise (see L{modifyRequest}) @note: if persistence is L{consts.Persistence.Connection} the request is removed from the client @@ -1384,10 +1346,10 @@ @return: (str) request identifier - @param event: RequestCompleted(event, message) triggered when the request is complete - @param event: RequestFailed(event, message) triggered when the request failes - @param event: RequestStarted(event, message) triggered when as the request is started - @param event: RequestModified(event, message) trigggered if the request identifier changes, + @event: RequestCompleted(event, message) triggered when the request is complete + @event: RequestFailed(event, message) triggered when the request failes + @event: RequestStarted(event, message) triggered when as the request is started + @event: RequestModified(event, message) trigggered if the request identifier changes, filename changes or the request is modified otherwise (see L{modifyRequest}) @note: if persistence is L{consts.Persistence.Connection} the request is removed from the client @@ -1444,10 +1406,10 @@ @return: (str) request identifier - @param event: RequestCompleted(event, message) triggered when the request is complete - @param event: RequestFailed(event, message) triggered when the request failes - @param event: RequestStarted(event, message) triggered when as the request is started - @param event: RequestModified(event, message) trigggered if the request identifier changes + @event: RequestCompleted(event, message) triggered when the request is complete + @event: RequestFailed(event, message) triggered when the request failes + @event: RequestStarted(event, message) triggered when as the request is started + @event: RequestModified(event, message) trigggered if the request identifier changes or the request is modified otherwise (see L{modifyRequest}) @note: if persistence is L{consts.Persistence.Connection} the request is removed from the client @@ -1726,7 +1688,7 @@ requestMessage['FcMessageSubType'], time.time(), # TOSO: reset init time? requestMessage['FcPersistentUserData'], - requestMessage['FcFilenameCollision=filenameCollision'], + requestMessage['FcFilenameCollision'] & consts.FilenameCollision.MaskHandle, ) elif requestMessage.name in consts.Message.ClientPluginMessages: identifier = self.FcParam.newUuid(uuids=self._requests) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-03 13:16:37
|
Revision: 128 http://fclient.svn.sourceforge.net/fclient/?rev=128&view=rev Author: jurner Date: 2008-02-03 05:16:37 -0800 (Sun, 03 Feb 2008) Log Message: ----------- fix Modified Paths: -------------- trunk/sandbox/fcp/boards/frost.py Modified: trunk/sandbox/fcp/boards/frost.py =================================================================== --- trunk/sandbox/fcp/boards/frost.py 2008-02-03 13:16:02 UTC (rev 127) +++ trunk/sandbox/fcp/boards/frost.py 2008-02-03 13:16:37 UTC (rev 128) @@ -81,14 +81,15 @@ +if __name__ == '__amain__': + board = FrostBoard() -board = FrostBoard() + t = FrostDate.now() + print t.toString() -t = FrostDate.now() -print t.toString() + board.readBoard('de.freenet', 'news', FrostDate.now()) -board.readBoard('de.freenet', 'news', FrostDate.now()) @@ -96,4 +97,3 @@ - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-03 13:16:02
|
Revision: 127 http://fclient.svn.sourceforge.net/fclient/?rev=127&view=rev Author: jurner Date: 2008-02-03 05:16:02 -0800 (Sun, 03 Feb 2008) Log Message: ----------- a few more tests 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-02-03 13:14:59 UTC (rev 126) +++ trunk/sandbox/fcp/test_fcp/test_fcp2_0_client.py 2008-02-03 13:16:02 UTC (rev 127) @@ -35,8 +35,7 @@ #*********************************************************************************** class BaseTestClient(unittest.TestCase): """Base class that does not connect to FcpClient prior to each test""" - - + def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) @@ -65,7 +64,6 @@ def connectClient(self): """Connects to the client""" - enum = self.fcpClient.connect(duration=0.2, timeout=0.1) msg = enum.next() self.failIf(msg is not None) @@ -76,9 +74,9 @@ FCPVersion='2.0', Node='Fred', Version=str(self.fcpClient.ExpectedFcpVersion), - Revision='99999999', + Revision='999999999999', Build='999999', - ExRevision='999999', + ExRevision='9999999999', Testnet='false', CompressionCodecs='1', ConnectionIdentifier='any', @@ -88,7 +86,6 @@ self.messages.pop(0) self.events.pop(0) - def assertHasNextEvent(self, expectedEvent=None, messageName=None, @@ -142,23 +139,22 @@ return msg - def assertHasNextMessage(self, - messageName, - param1=None, - param2=None, - param3=None, - param4=None, - param5=None, - data=None - ): + messageName, + param1=None, + param2=None, + param3=None, + param4=None, + param5=None, + data=None + ): """Tests if we received a certain message from the client - @param messageName: expected mesageName or None if no message is expected - @param param1: tuple(paramName, value) of a message parameter expected - @param data: data expected along with the message or None - - @return: message if a message was received or None - """ + @param messageName: expected mesageName or None if no message is expected + @param param1: tuple(paramName, value) of a message parameter expected + @param data: data expected along with the message or None + + @return: message if a message was received or None + """ if messageName is None: self.failIf(self.messages) else: @@ -188,14 +184,12 @@ if data is not None: self.assertEqual(data, msg.data) return msg - - + def sendResponseMessage(self, messageName, data=None, **params): """Posts a message to the client""" self.socket.sendResponseMessage(messageName, data=data, **params) self.fcpClient.next() - def setUp(self): self.oldSocketModule = fcp2_0_client.socket fcp2_0_client.socket = self.socketModule @@ -211,9 +205,7 @@ # capture all messages the client sent self.messages = [] # messages the client send self.socket.setBytesReceiver(self._captureMessagesFromClient) - - - + def tearDown(self): fcp2_0_client.socket = self.oldSocketModule @@ -221,7 +213,6 @@ for eventName in self.fcpClient.Events._events_: event = getattr(self.fcpClient.events, eventName) event -= self._captureEventsFromClient - # clean up tmpfiles for fpath in self.tmpfiles: os.remove(fpath) @@ -254,7 +245,7 @@ self.failUnless(self.socket.closed) - def testConnectFailed(self): + def testConnect_Failure(self): # simulate a failed connection attempt enum = self.fcpClient.connect(duration=0.2, timeout=0.1) @@ -281,10 +272,9 @@ # did the client clean up our socket? self.failUnless(self.socket.closed) - - + - def testConnecSucceeded(self): + def testConnect_Success(self): # simulate a successful connection attempt enum = self.fcpClient.connect(duration=0.2, timeout=0.1) @@ -303,9 +293,9 @@ FCPVersion='2.0', Node='Fred', Version=str(self.fcpClient.ExpectedFcpVersion), - Revision='99999999', - Build='999999', - ExRevision='999999', + Revision='999999999999', + Build='9999999999', + ExRevision='9999999999', Testnet='false', CompressionCodecs='1', ConnectionIdentifier='any', @@ -321,32 +311,125 @@ self.assertHasNextEvent(None) - #*********************************************************************************** # #*********************************************************************************** -#TODO: testCloseOnVersionMismatch -#TODO: testCloseOnDuplicateConnectionName -#TODO: testShutdown - -class TestConnection(BaseTestConnectedClient): +class TestDisconnectReason(BaseTestConnectedClient): - def testBrokenSocket(self): + def testDuplicateClientName(self): + self.sendResponseMessage('CloseConnectionDuplicateClientName') + msg = self.assertHasNextEvent( + self.fcpClient.events.ClientDisconnected, + consts.Message.ClientDisconnected, + ('DisconnectReason', consts.DisconnectReason.DuplicateClientName), + ) + self.failUnless('Param' in msg.params) + self.assertEqual(msg['Param'], None) + + self.assertHasNextEvent(None) + + + def testSocketDied_Receive(self): + self.socket.close() + self.fcpClient.next() + # check if ClientDisconnected events has been triggered + msg = self.assertHasNextEvent( + self.fcpClient.events.ClientDisconnected, + consts.Message.ClientDisconnected, + ('DisconnectReason', consts.DisconnectReason.SocketDied), + #('Param', ClientSocketDiedMessage) # can not test here + ) + self.failUnless('Param' in msg.params) + self.assertEqual(msg['Param'].name, consts.Message.ClientSocketDied) + + self.assertHasNextEvent(None) + + + def testSocketDied_Send(self): + + self.socket.close() + # send a test message self.assertRaises(socket.error, self.fcpClient.sendMessage, 'test' ) # check if ClientDisconnected events has been triggered - self.assertHasNextEvent( + msg = self.assertHasNextEvent( self.fcpClient.events.ClientDisconnected, - consts.Message.ClientSocketDied, + consts.Message.ClientDisconnected, + ('DisconnectReason', consts.DisconnectReason.SocketDied), + #('Param', ClientSocketDiedMessage) # can not test here ) + self.failUnless('Param' in msg.params) + self.assertEqual(msg['Param'].name, consts.Message.ClientSocketDied) + self.assertHasNextEvent(None) - + + + def testShutdown(self): + + self.fcpClient.closeFreenet() + + msg = self.assertHasNextMessage(consts.Message.Shutdown) + self.sendResponseMessage( + 'ProtocolError', + Code='18', # Shutting down + ) + + # check events the client triggered + msg = self.assertHasNextEvent( + self.fcpClient.events.ClientDisconnected, + consts.Message.ClientDisconnected, + ('DisconnectReason', consts.DisconnectReason.Shutdown) + #('Param', NodeHelloMessage) # can not test here + ) + self.failUnless('Param' in msg.params) + self.assertEqual(msg['Param'], None) + + self.assertHasNextEvent(None) + def testVersionMismatch(self): + + # cheat a bit and reconnect client + enum = self.fcpClient.connect(duration=0.2, timeout=0.1) + msg = enum.next() + self.failIf(msg is not None) + + # check messages the client send message + self.assertHasNextMessage(consts.Message.ClientHello) + + #NOTE: have to send directly via socket here (our sendResponseMessage + # calls client.next() autkmatically) + self.socket.sendResponseMessage( + 'NodeHello', + FCPVersion='0.0', + Node='Fred', + Version=str(self.fcpClient.ExpectedFcpVersion), + Revision='0', + Build='0', + ExRevision='0', + Testnet='false', + CompressionCodecs='1', + ConnectionIdentifier='any', + NodeLanguage='en', + ) + msg = enum.next() + + # check events the client triggered + msg = self.assertHasNextEvent( + self.fcpClient.events.ClientDisconnected, + consts.Message.ClientDisconnected, + ('DisconnectReason', consts.DisconnectReason.VersionMissmatch) + #('Param', NodeHelloMessage) # can not test here + ) + self.failUnless('Param' in msg.params) + self.assertEqual(msg['Param'].name, consts.Message.NodeHello) + + self.assertHasNextEvent(None) + #*********************************************************************************** # #*********************************************************************************** @@ -369,7 +452,7 @@ self.assertEqual(myRequest['FcStatus'], consts.MessageStatus.Pending) - def testGetData(self): + def testGetData_Success(self): # request a arbitrary file myIdentifier = self.fcpClient.getData( @@ -429,14 +512,53 @@ ) self.assertHasNextEvent( self.fcpClient.events.RequestCompleted, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Complete), data=data ) self.assertHasNextEvent(None) - def testgetFile(self): + def testGetData_Failure(self): # request a arbitrary file + myIdentifier = self.fcpClient.getData( + 'arbitrary-uri', + ) + myRequest = self.fcpClient.getRequest(myIdentifier) + + # respond to the file request + self.sendResponseMessage( + 'PersistentGet', + Started='false', + **myRequest.params + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestStarted, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Started) + ) + self.assertHasNextEvent(None) + + # finalize request + self.sendResponseMessage( + 'GetFailed', + Code='28', # All data not found + Identifier=myIdentifier, + Global='false', + # blah.. more here + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestFailed, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Error) + ) + self.assertHasNextEvent(None) + + + def testGetFile_Success(self): + + # request a arbitrary file myIdentifier = self.fcpClient.getFile( 'arbitrary-uri', 'arbitryry.txt' @@ -476,6 +598,142 @@ ) self.assertHasNextEvent(None) + + def testGetFile_Failure(self): + + # request a arbitrary file + myIdentifier = self.fcpClient.getFile( + 'arbitrary-uri', + 'arbitryry.txt' + ) + myRequest = self.fcpClient.getRequest(myIdentifier) + self.assertHasNextMessage(consts.Message.ClientGet) + + # respond to the file request + self.sendResponseMessage( + 'PersistentGet', + Started='false', + **myRequest.params + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestStarted, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Started) + ) + self.assertHasNextEvent(None) + + # finalize request + self.sendResponseMessage( + 'GetFailed', + Code='28', # All data not found + Identifier=myIdentifier, + Global='false', + # blah.. more here + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestFailed, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Error) + ) + self.assertHasNextEvent(None) + + + + def testGetKeyInfo_Success(self): + + # request a arbitrary uri + myIdentifier = self.fcpClient.getKeyInfo( + 'arbitrary-uri', + persistence=consts.Persistence.Forever, # cheat a bit, so we can test multiple cases + ) + myRequest = self.fcpClient.getRequest(myIdentifier) + self.assertHasNextMessage(consts.Message.ClientGet) + + # respond to the file request + self.sendResponseMessage( + 'PersistentGet', + Started='false', + **myRequest.params + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestStarted, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Started) + ) + self.assertHasNextEvent(None) + + # finalize request + data = 'foo' + params = { + 'Identifier': myIdentifier, + 'Global': 'false', + 'DataLength': 123456, + 'Metadata.ContentType': 'any', + } + self.sendResponseMessage( + 'DataFound', + **params + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestCompleted, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Complete) + ) + self.assertHasNextEvent(None) + + # test specdial case where ProtocolError.TooBig is handled as success + self.sendResponseMessage( + 'GetFailed', + Code='21', # Too big + Identifier=myIdentifier, + Global='false', + # blah.. more here + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestCompleted, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Complete) + ) + self.assertHasNextEvent(None) + + + def testGetKeyInfo_Failure(self): + + # request a arbitrary file + myIdentifier = self.fcpClient.getKeyInfo( + 'arbitrary-uri', + ) + myRequest = self.fcpClient.getRequest(myIdentifier) + self.assertHasNextMessage(consts.Message.ClientGet) + + # respond to the file request + self.sendResponseMessage( + 'PersistentGet', + Started='false', + **myRequest.params + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestStarted, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Started) + ) + self.assertHasNextEvent(None) + + # finalize request + self.sendResponseMessage( + 'GetFailed', + Code='28', # All data not found + Identifier=myIdentifier, + Global='false', + # blah.. more here + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestFailed, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Error) + ) + self.assertHasNextEvent(None) + #*********************************************************************************** # #*********************************************************************************** @@ -585,6 +843,7 @@ self.sendResponseMessage( 'PersistentGet', Identifier=myIdentifier, + Global='false', ReturnType='disk', Verbosity='1', PersistenceType='forever', @@ -622,12 +881,12 @@ ) self.messages = [] self.events = [] - - + # throw a PersistentGet at the client with the identifier we hacked self.sendResponseMessage( 'PersistentGet', Identifier=identifier, + Global='false', ReturnType='disk', Verbosity='1', PersistenceType='forever', @@ -913,7 +1172,7 @@ tests = ( TestConnect, - TestConnection, + TestDisconnectReason, TestClientGet, TestRequests, TestRestoreRequests, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-03 13:14:54
|
Revision: 126 http://fclient.svn.sourceforge.net/fclient/?rev=126&view=rev Author: jurner Date: 2008-02-03 05:14:59 -0800 (Sun, 03 Feb 2008) Log Message: ----------- persistence == connection is now handled ++ some fixes 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-03 13:13:56 UTC (rev 125) +++ trunk/sandbox/fcp/fcp2_0_client.py 2008-02-03 13:14:59 UTC (rev 126) @@ -485,7 +485,8 @@ self.close() msg = self.Message( consts.Message.ClientDisconnected, - DisconnectReason=consts.DisconnectReason.VersionMissmatch + DisconnectReason=consts.DisconnectReason.VersionMissmatch, + Param=msg, ) self.events.ClientDisconnected(msg) yield self._nodeHelloMessage @@ -503,7 +504,8 @@ msg = self.Message( consts.Message.ClientDisconnected, - DisconnectReason=consts.DisconnectReason.ConnectingFailed + DisconnectReason=consts.DisconnectReason.ConnectingFailed, + Param=None, ) self.events.ClientDisconnected(msg) self._log.info(consts.LogMessages.ConnectingFailed) @@ -605,7 +607,8 @@ self.close() msg = self.Message( consts.Message.ClientDisconnected, - DisconnectReason=DisconnectReason.Shutdown, + DisconnectReason=consts.DisconnectReason.Shutdown, + Param=None, ) self.events.ClientDisconnected(msg) return True @@ -810,45 +813,49 @@ elif msg.name == consts.Message.AllData: if initialRequest is None: return False - + + # Fcp removes requests from queue with Persistence.Connection.. so do we + if initialRequest.params.get('Persistence', consts.Persistence.Connection) == consts.Persistence.Connection: + del self._requests[requestIdentifier] + + initialRequest['FcStatus'] = consts.MessageStatus.Complete initialRequest.data = msg.data self.events.RequestCompleted(initialRequest) return True elif msg.name == consts.Message.DataFound: - 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', '') if initialRequest['FcSubType'] != consts.MessageSubType.GetData: + initialRequest['FcStatus'] = consts.MessageStatus.Complete + + # Fcp removes requests from queue with Persistence.Connection.. so do we + if initialRequest.params.get('Persistence', consts.Persistence.Connection) == consts.Persistence.Connection: + del self._requests[requestIdentifier] self.events.RequestCompleted(initialRequest) return True - + - elif msg.name == consts.Message.GetFailed: - code = msg['Code'] if initialRequest is None: - # something is going wrong return False + # Fcp removes requests from queue with Persistence.Connection.. so do we + if initialRequest.params.get('Persistence', consts.Persistence.Connection) == consts.Persistence.Connection: + del self._requests[requestIdentifier] + # check if it is one of our requests for key information - if code == self.FetchError.TooBig and initialRequest['FcSubType'] == consts.MessageSubType.GetKeyInfo: + code = msg['Code'] + if code == consts.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 - #TODO: check if Fcp removed the request - self.events.RequestCompleted(initialRequest) else: - - #TODO: check if Fcp removed the request - initialRequest['FcErrorMessage'] = msg initialRequest['FcStatus'] = consts.MessageStatus.Error self.events.RequestFailed(initialRequest) @@ -975,7 +982,6 @@ elif msg.name == consts.Message.SimpleProgress: if initialRequest is None: - # something went wrong return False initialRequest['FcProgressTotal'] = msg['Total'] @@ -989,11 +995,24 @@ ## put related elif msg.name == consts.Message.URIGenerated: - if initialRequest is None: # something went wrong + if initialRequest is None: return False initialRequest['URI'] = msg['URI'] return True + elif msg.name == consts.Message.PutFailed: + if initialRequest is None: + return False + + # Fcp removes requests from queue with Persistence.Connection.. so do we + if initialRequest.params.get('Persistence', consts.Persistence.Connection) == consts.Persistence.Connection: + del self._requests[requestIdentifier] + + initialRequest['FcErrorMessage'] = msg + initialRequest['FcStatus'] = consts.MessageStatus.Error + self.events.RequestFailed(initialRequest) + return True + elif msg.name == consts.Message.PutFetchable: if initialRequest is None: @@ -1006,12 +1025,12 @@ elif msg.name == consts.Message.PutSuccessful: if initialRequest is None: - # something went wrong return False # TODO: StartupTime and CompletionTime are passed, but # as long as no corrosponding params are passed in DataFound # we ignore them + initialRequest['FcStatus'] = consts.MessageStatus.Complete initialRequest['URI'] = msg['URI'] self.events.RequestCompleted(initialRequest) return True @@ -1075,9 +1094,10 @@ elif msg.name == consts.Message.CloseConnectionDuplicateClientName: msg = self.Message( consts.Message.ClientDisconnected, - DisconnectReason=DisconnectReason.DuplicateClientName, + DisconnectReason=consts.DisconnectReason.DuplicateClientName, + Param=None, ) - self.events.ClientDisconnect(msg) + self.events.ClientDisconnected(msg) return True @@ -1119,9 +1139,13 @@ msg = self.Message.fromSocket(self._socket) if msg.name == consts.Message.ClientSocketDied: if dispatch: - msg['DisconnectReason'] = consts.DisconnectReason.SocketDied + msg = self.Message( + consts.Message.ClientDisconnected, + DisconnectReason=consts.DisconnectReason.SocketDied, + Param=msg, + ) self.events.ClientDisconnected(msg) - raise socket.error(msg['Details']) + #raise socket.error(msg['Param']['Details']) elif msg.name == consts.Message.ClientSocketTimeout: if dispatch: @@ -1166,14 +1190,12 @@ except socket.error, d: self._log.info(consts.LogMessages.SocketDied) self.close() - - errorMsg = self.Message( - consts.Message.ClientSocketDied, - DisconnectReason=consts.DisconnectReason.SocketDied, - Exception=socket.error, - Details=d + msg = self.Message( + consts.Message.ClientDisconnected, + DisconnectReason=consts.DisconnectReason.SocketDied, + Param=self.Message(consts.Message.ClientSocketDied, Exception=socket.error, Details=d) ) - self.events.ClientDisconnected(errorMsg) + self.events.ClientDisconnected(msg) raise socket.error(d) return msg @@ -1288,12 +1310,19 @@ @param maxSize: (int) maximum size of the file in bytes or None to set no limited @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 + + @return: (str) request identifier - @return: (str) request identifier - @note: if a filename collision is handled a RequestFilenameChanged event is triggered + @param event: RequestCompleted(event, message) triggered when the request is complete + @param event: RequestFailed(event, message) triggered when the request failes + @param event: RequestStarted(event, message) triggered when as the request is started + @param event: RequestModified(event, message) trigggered if the request identifier changes + or the request is modified otherwise (see L{modifyRequest}) + + @note: if persistence is L{consts.Persistence.Connection} the request is removed from the client + as soon as it completes or failes """ return self.clientGet( uri, @@ -1349,13 +1378,20 @@ @param maxSize: (int) maximum size of the file in bytes or None to set no limited @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 @param persistentUserData: any string to associate to the request as persistent data @return: (str) request identifier - @note: if a filename collision is handled a RequestFilenameChanged event is triggered + + @param event: RequestCompleted(event, message) triggered when the request is complete + @param event: RequestFailed(event, message) triggered when the request failes + @param event: RequestStarted(event, message) triggered when as the request is started + @param event: RequestModified(event, message) trigggered if the request identifier changes, + filename changes or the request is modified otherwise (see L{modifyRequest}) + + @note: if persistence is L{consts.Persistence.Connection} the request is removed from the client + as soon as it completes or failes """ return self.clientGet( uri, @@ -1407,6 +1443,15 @@ @param persistentUserData: any string to associate to the request as persistent data @return: (str) request identifier + + @param event: RequestCompleted(event, message) triggered when the request is complete + @param event: RequestFailed(event, message) triggered when the request failes + @param event: RequestStarted(event, message) triggered when as the request is started + @param event: RequestModified(event, message) trigggered if the request identifier changes + or the request is modified otherwise (see L{modifyRequest}) + + @note: if persistence is L{consts.Persistence.Connection} the request is removed from the client + as soon as it completes or failes """ # how to retrieve meta info about a key? ...idea is to provoke a GetFailed (TooBig) return self.clientGet( @@ -1902,9 +1947,9 @@ for i in xrange(50): c.next() - c.removeRequest(identifier) - for i in xrange(5): - c.next() + #c.removeRequest(identifier) + #for i in xrange(5): + # c.next() #testGetData() @@ -1917,30 +1962,42 @@ 'CHK@q4~2soHTd9SOINIoXmg~dn7LNUAOYzN1tHNHT3j4c9E,gcVRtoglEhgqN-DJolXPqJ4yX1f~1gBGh89HNWlFMWQ,AAIC--8/snow_002%20%2810%29.jpg', filename, filenameCollision=c.FilenameCollision.HandleRename, - persistence=consts.Persistence.Forever, + #persistence=consts.Persistence.Forever, ) for i in xrange(50): c.next() - c.removeRequest(identifier) - for i in xrange(5): - c.next() + #c.removeRequest(identifier) + #for i in xrange(5): + # c.next() #testGetFile() def testGetKeyInfo(): + + + identifier = c.getKeyInfo( 'CHK@q4~2soHTd9SOINIoXmg~dn7LNUAOYzN1tHNHT3j4c9E,gcVRtoglEhgqN-DJolXPqJ4yX1f~1gBGh89HNWlFMWQ,AAIC--8/snow_002%20%2810%29.jpg', + #persistence=c.consts.Persistence.Reboot, ) - - for i in xrange(50): + + + def cb(event, msg): + if event == c.events.RequestCompleted: + pass + #c.sendMessage(c.consts.Message.GetRequestStatus, Identifier=identifier) + c.events.RequestCompleted += cb + + for i in xrange(55): c.next() - c.removeRequest(identifier) - for i in xrange(5): - c.next() + #c.removeRequest(identifier) + #for i in xrange(5): + # c.next() + c.events.RequestCompleted -= cb #testGetKeyInfo() @@ -1953,9 +2010,9 @@ for i in xrange(100): c.next() - c.removeRequest(myIdentifier) - for i in xrange(5): - c.next() + #c.removeRequest(myIdentifier) + #for i in xrange(5): + # c.next() #testPutData() @@ -1969,9 +2026,9 @@ for i in xrange(1000): c.next() - c.removeRequest(identifier) - for i in xrange(5): - c.next() + #c.removeRequest(identifier) + #for i in xrange(5): + # c.next() #testPutFile() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-03 13:13:51
|
Revision: 125 http://fclient.svn.sourceforge.net/fclient/?rev=125&view=rev Author: jurner Date: 2008-02-03 05:13:56 -0800 (Sun, 03 Feb 2008) Log Message: ----------- beautifications Modified Paths: -------------- trunk/sandbox/fcp/fcp2_0_types.py Modified: trunk/sandbox/fcp/fcp2_0_types.py =================================================================== --- trunk/sandbox/fcp/fcp2_0_types.py 2008-02-03 13:13:25 UTC (rev 124) +++ trunk/sandbox/fcp/fcp2_0_types.py 2008-02-03 13:13:56 UTC (rev 125) @@ -186,10 +186,10 @@ # #*************************************************************************************** class ConfigMessageParams(object): - - ComponentsSep = '.' + """Parameter --> FcpType mapping for config related messages""" - + ComponentSep = '.' + # first component of a config message param is always the param class ParamClassCurrent = 'current' @@ -208,9 +208,7 @@ ParamClassShortDescription, ParamClassLongDescription, ) - - - + # all known config keys (param class stripped) Params = { @@ -220,8 +218,7 @@ 'console.enabled': FcpTypeBool, 'console.port': FcpTypeIPort, 'console.ssl': FcpTypeBool, - - + 'fcp.allowedHosts': FcpTypeIPList, 'fcp.allowedHostsFullAccess': FcpTypeIPList, 'fcp.assumeDownloadDDAIsAllowed': FcpTypeBool, @@ -233,8 +230,7 @@ 'fcp.persistentDownloadsInterval': FcpTypeIntWithBounds(0, None), 'fcp.port': FcpTypeIPort, 'fcp.ssl': FcpTypeBool, - - + 'fproxy.CSSOverride': FcpTypeBool, 'fproxy.advancedModeEnabled': FcpTypeBool, 'fproxy.allowedHosts': FcpTypeIPList, @@ -247,18 +243,16 @@ '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.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, @@ -290,11 +284,9 @@ 'node.tempIPAddressHint': FcpTypeIP, # ??? 'node.testingDropPacketsEvery': FcpTypeIntWithBounds(0, None), 'node.uploadAllowedDirs': FcpTypeChoiceNodeDownloadAllowedDirs, - - - 'node.testnet.enabled': FcpTypeBool, - + 'node.testnet.enabled': FcpTypeBool, + 'node.load.aggressiveGC': FcpType, # ??? 'node.load.freeHeapBytesThreshold': FcpTypeNumBytes, 'node.load.freeHeapPercentThreshold': FcpTypePercent, @@ -302,7 +294,6 @@ 'node.load.nodeThrottleFile': FcpTypeFilename, 'node.load.threadLimit': FcpTypeIntWithBounds(0, None), - 'node.opennet.acceptSeedConnections': FcpTypeBool, 'node.opennet.alwaysAllowLocalAddresses': FcpTypeBool, 'node.opennet.assumeNATed': FcpTypeBool, @@ -324,11 +315,9 @@ 'node.updater.extURI': FcpTypeUri, 'node.updater.revocationURI': FcpTypeUri, - 'pluginmanager.loadplugin': FcpTypeStringList, 'pluginmanager2.loadedPlugins': FcpTypeStringList, - - + 'ssl.sslEnable': FcpTypeBool, 'ssl.sslKeyPass': FcpTypeString, 'ssl.sslKeyStore': FcpTypeFilename, @@ -336,22 +325,32 @@ 'ssl.sslVersion': FcpTypeChoiceSSLVersion, 'toadletsymlinker.symlinks': FcpTypeStringList, - } - def __init__(self): pass - def splitAll(self, paramName): - return paramName.split(self.ComponentsSep) + """Splits a parameter name into its components + @param (str) paramName: parameter name to split + @return: (list) components + """ + return paramName.split(self.ComponentSep) + def splitParamClass(self, paramName): - return paramName.split(self.ComponentsSep, 1) + """Splits the parameter class from a parameter name + @param (str) paramName: parameter name to split + @return: (tuple) paramClass, tail + """ + return paramName.split(self.ComponentSep, 1) def get(self, paramName, default=None): + """Returns the type of a parameter or default + @param paramName: (str) name of the parameter to retuen the type for + @return: (FcpType) + """ try: return self[paramName] except KeyError: @@ -359,6 +358,10 @@ def __getitem__(self, paramName): + """Returns the type of a parameter + @param paramName: (str) name of the parameter to retuen the type for + @return: (FcpType) + """ paramClass, paramKey = self.splitParamClass(paramName) if paramClass == self.ParamClassCurrent: return self.Params[paramKey] @@ -387,8 +390,7 @@ PeerMessageParams = { 'ark.number': FcpTypeInt, 'auth.negTypes': FcpTypeInt, - - + 'location': FcpTypeFloat, 'opennet': FcpTypeBool, 'testnet': FcpTypeBool, @@ -440,8 +442,7 @@ 'location': FcpTypeFloat, 'opennet': FcpTypeBool, 'testnet': FcpTypeBool, - - + 'volatile.allocatedJavaMemory': FcpTypeInt, 'volatile.availableCPUs': FcpTypeInt, 'volatile.averagePingTime': FcpTypeFloat, @@ -527,14 +528,14 @@ >>all other NodeData message params here.... >> >> physical.udp=000.000.000.000:00000 ->> dsaPubKey.y=GgrpsNUK9m................................................. +>> dsaPubKey.y=GarpsNUKe................................................. >> version=Fred,0.7,1.0,1107 >> myName=whatever >> ark.pubURI=SSK@............... >> dsaGroup.q=ALFDNoq..... >> dsaGroup.p=AIYIrE9VNhM3............. ->> volatile.avgConnectedPeersPerNode=15.35................ +>> volatile.avgConnectedPeersPerNode=00.00................ >> dsaGroup.g=UaRa............. >> dsaPrivKey.x=Pwam.................. >> ark.privURI=SSK@................. @@ -553,93 +554,111 @@ MessageParamTypes = { # client messages - + # + #'AddPeer': # added later as PeerMessageParams + 'ClientGet': { + 'BinaryBlob': FcpTypeBool, + 'Global': FcpTypeBool, + 'IgnoreDS': FcpTypeBool, + 'DSOnly': FcpTypeBool, + 'MaxSize': FcpTypeInt, + 'MaxTempSize': FcpTypeInt, + 'Verbosity': FcpTypeInt, + }, + 'ClientPut': { + 'BinaryBlob': FcpTypeBool, + 'DontCompress': FcpTypeBool, + 'EarlyEncode': FcpTypeBool, + 'GetCHKOnly': FcpTypeBool, + 'Global': FcpTypeBool, + 'MaxRetries': FcpTypeInt, + 'Verbosity': FcpTypeInt, + }, + 'GetConfig': { + 'WithCurrent': FcpTypeBool, + 'WithDefaults': FcpTypeBool, + 'WithSortOrder': FcpTypeBool, + 'WithExpertFlag': FcpTypeBool, + 'WithForceWriteFlag': FcpTypeBool, + 'WithShortDescription': FcpTypeBool, + 'WithLongDescription': FcpTypeBool, + }, + 'GetNode': { + 'GiveOpennetRef': FcpTypeBool, + 'WithPrivate': FcpTypeBool, + 'WithVolatile': FcpTypeBool, + }, + 'GetPluginInfo': { + 'Detailed': FcpTypeBool, + }, + 'GetRequestStatus': { + 'Global': FcpTypeBool, + 'OnlyData': FcpTypeBool, + }, 'ListPeer': { 'WithMetadata': FcpTypeBool, 'WithVolantile': FcpTypeBool, }, - 'ListPeers': { 'WithMetadata': FcpTypeBool, 'WithVolantile': FcpTypeBool, }, - - #'AddPeer': # added later as PeerMessageParams - 'ModifyPeer': { 'AllowLocalAddresses': FcpTypeBool, 'IsDisabled': FcpTypeBool, 'ListenOnly': FcpTypeBool, }, - + #'ModifyConfig': # added later as ConfigMessageParams() 'ModifyPeerNote': { 'NoteText': FcpTypeBase64EncodedString, }, - - 'GetNode': { - 'GiveOpennetRef': FcpTypeBool, - 'WithPrivate': FcpTypeBool, - 'WithVolatile': FcpTypeBool, + 'ModifyPersistentRequest': { + 'Global': 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, + 'RemopvePersistentRequest': { 'Global': FcpTypeBool, - 'MaxRetries': FcpTypeInt, - 'Verbosity': FcpTypeInt, }, - 'ClientGet': { - 'BinaryBlob': FcpTypeBool, - 'Global': FcpTypeBool, - 'IgnoreDS': FcpTypeBool, - 'DSOnly': FcpTypeBool, - 'MaxSize': FcpTypeInt, - 'MaxTempSize': FcpTypeInt, - 'Verbosity': FcpTypeInt, - }, 'SubscribeUSK': { 'DontPoll': FcpTypeBool, }, + 'TestDDARequest': { + 'WantReadDirectory': FcpTypeBool, + 'WantWriteDirectory': FcpTypeBool, + }, 'WatchGlobal': { 'Enabled': FcpTypeBool, 'VerbosityMask': FcpTypeInt, }, - 'GetRequestStatus': { + + # node messages + # + 'AllData': { 'Global': FcpTypeBool, - 'OnlyData': FcpTypeBool, + #NOTE: we ignore startup and completion time here as long as it is not passed in all related messages }, - 'RemopvePersistentRequest': { + #'ConfigData': # added later as ConfigMessageParams() + 'DataFound': { 'Global': FcpTypeBool, + 'DataLength': FcpTypeInt, }, - 'ModifyPersistentRequest': { - 'Global': FcpTypeBool, + 'FinishedCompression': { + 'OriginalSize': FcpTypeInt, + 'CompressedSize': FcpTypeInt, }, + 'GetFailed': { + 'Code': FcpTypeInt, + 'ExpectedDataLength': FcpTypeInt_GetFailed_ExpectedDataLenght, + 'Fatal': FcpTypeBool, + 'FinalizedExpected': FcpTypeBool, + 'Global': FcpTypeBool, + }, 'GetPluginInfo': { - 'Detailed': FcpTypeBool, + 'Started': FcpTypeBool, }, - - - - # node messages - + 'IdentifierCollision': { + 'Global': FcpTypeBool, + }, + #'NodeData': # added later as NodeMessageParams 'NodeHello': { 'Build': FcpTypeInt, 'CompressionCodecs': FcpTypeInt, @@ -648,37 +667,27 @@ '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': { + 'PersistentRequestModified': { 'Global': FcpTypeBool, - }, - 'DataFound': { + }, + 'PersistentRequestRemoved': { 'Global': FcpTypeBool, - 'DataLength': FcpTypeInt, }, - 'AllData': { + 'ProtocolError': { + 'Code': FcpTypeInt, 'Global': FcpTypeBool, - #NOTE: we ignore startup and completion time here as long as it is not passed in all related messages - + }, + 'PutFailed': { + 'Global': FcpTypeBool, + 'Code': FcpTypeInt, + }, + 'PutFetchable': { + 'Global': FcpTypeBool, }, - 'FinishedCompression': { - 'OriginalSize': FcpTypeInt, - 'CompressedSize': FcpTypeInt, - }, 'SimpleProgress': { 'Total': FcpTypeInt, 'Required': FcpTypeInt, @@ -687,38 +696,13 @@ '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, + 'TestDDAComplete': { + 'ReadDirectoryAllowed': FcpTypeBool, + 'WriteDirectoryAllowed': FcpTypeBool, }, - } MessageParamTypes['ClientPutDiskDir'] = MessageParamTypes['ClientPut'] @@ -728,9 +712,7 @@ 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-03 13:13:21
|
Revision: 124 http://fclient.svn.sourceforge.net/fclient/?rev=124&view=rev Author: jurner Date: 2008-02-03 05:13:25 -0800 (Sun, 03 Feb 2008) Log Message: ----------- fix 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 18:30:56 UTC (rev 123) +++ trunk/sandbox/fcp/fcp2_0_consts.py 2008-02-03 13:13:25 UTC (rev 124) @@ -45,7 +45,7 @@ TransferFailed = 18 SplitfileError = 19 InvalidUri = 20 - TooBig = '21' + TooBig = 21 MetadataTooBig = 22 TooManyBlocks = 23 NotEnoughMetastrings = 24 @@ -148,15 +148,17 @@ class DisconnectReason: """Reasons for client disconnect + @cvar ConnectingFailed: connection could not be established + @cvar DuplicateClientName: another client opend a connection with the same connection name @cvar Shutdown: regular shutdown of the connection @cvar SocketDied: connection to the node died unexpectingly - @cvar ConnectFailed: connection could not be established + @cvar VersionMissmatch: node or Fcp version did not match """ - Shutdown = 1 - SocketDied = 2 - ConnectingFailed = 3 - DuplicateConnectionName = 4 - VersionMismatch = 5 #TODO: implement??? + ConnectingFailed = 1 + DuplicateClientName = 2 + Shutdown = 3 + SocketDied = 4 + VersionMissmatch = 5 #TODO: implement??? class FilenameCollision: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-02 18:31:33
|
Revision: 123 http://fclient.svn.sourceforge.net/fclient/?rev=123&view=rev Author: jurner Date: 2008-02-02 10:30:56 -0800 (Sat, 02 Feb 2008) Log Message: ----------- some new methods Modified Paths: -------------- trunk/fclient/fclient_lib/pyex/numbers.py Modified: trunk/fclient/fclient_lib/pyex/numbers.py =================================================================== --- trunk/fclient/fclient_lib/pyex/numbers.py 2008-02-02 18:30:26 UTC (rev 122) +++ trunk/fclient/fclient_lib/pyex/numbers.py 2008-02-02 18:30:56 UTC (rev 123) @@ -2,6 +2,7 @@ """ +import re #*************************************************************** # #*************************************************************** @@ -13,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) + + #*************************************************************** # #*************************************************************** @@ -134,6 +147,107 @@ #***************************************************************** # #**************************************************************** +HEX_PREFIXES = ('0x', '0X', '&H', '&h') +NUM_DIGITS = "0123456789abcdefghijklmnopqrstuvwxyz" + + +def to_base(to_base, num, base=10, hex_prefixes=HEX_PREFIXES): + """Converts a number to the desired base + @param to_base: base to convert the number to (2-36 and 256) + @param num: number to convert + @param base: base of the number to convert + @param hex_prefixes: prefixes for hexadecimal numbers to be recognized by the function + + @return: (str) converted number + + + >>> to_base(2, 10) + '1010' + >>> to_base(10, '1010', base=2) + '10' + >>> to_base(2, '1010', base=2) + '1010' + + >>> to_base(10, '0xFF', base=16) + '255' + + >>> to_base(256, '0x61', base=16) + 'a' + >>> to_base(2, 'a', base=256) + '1100001' + + + >>> result = to_base(2, 'Hello World!', 256) + >>> result + '10010000110010101101100011011000110111100100000010101110110111101110010011011000110010000100001' + >>> result = to_base(256, result, base=2) + >>> result + 'Hello World!' + + """ + if num < 0: + raise ValueError('negative numbers not supported: %r' % num) + if to_base < 2 or to_base > 36 and not to_base == 256: + raise ValueError('bes must be in range 2-36 or 256, found: %r' % to_base) + if base < 2 or base > 36 and not base == 256: + raise ValueError('bes must be in range 2-36 or 256, found: %r' % base) + + if base == 256: + tmp_num = 0 + for char in num: + tmp_num = (tmp_num << 8) + ord(char) + num = tmp_num + else: + # let int() handle it + if base == 16: + num = strip_hex_prefix(num, hex_prefixes=hex_prefixes) + num = int('%s' % num, base) + + if to_base == 10 and base != 256: + return str(num) + + out = '' + if to_base == 256: + while num: + num, tail = divmod(num, to_base) + out += chr(tail) + return out[-1::-1] if out else '\x00' + else: + while num: + num, tail = divmod(num, to_base) + out += NUM_DIGITS[tail] + return out[-1::-1] if out else '0' + + + +def strip_hex_prefix(num, hex_prefixes=HEX_PREFIXES): + """Strips prefixes from hexadecimal numbers + @param num: number to strip prefix from + @param hex_prefixes: list containing prefixes to strip + @return: (str) stripped number + + >>> strip_hex_prefix('0xFF') + 'FF' + >>> strip_hex_prefix('&HFF') + 'FF' + >>> strip_hex_prefix(10) + '10' + >>> strip_hex_prefix('') + '' + + """ + if not isinstance(num, basestring): + num = '%s' % num + else: + pat = re.compile( + '\A(%s)' % '|'.join([re.escape(i) for i in hex_prefixes]) + ) + num = pat.sub('', num) + return num + +#***************************************************************** +# +#**************************************************************** if __name__ == '__main__': import doctest doctest.testmod() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-02 18:30:29
|
Revision: 122 http://fclient.svn.sourceforge.net/fclient/?rev=122&view=rev Author: jurner Date: 2008-02-02 10:30:26 -0800 (Sat, 02 Feb 2008) Log Message: ----------- some new methods Modified Paths: -------------- trunk/fclient/fclient_lib/pyex/namespace.py Modified: trunk/fclient/fclient_lib/pyex/namespace.py =================================================================== --- trunk/fclient/fclient_lib/pyex/namespace.py 2008-02-02 18:29:43 UTC (rev 121) +++ trunk/fclient/fclient_lib/pyex/namespace.py 2008-02-02 18:30:26 UTC (rev 122) @@ -5,15 +5,88 @@ #********************************************************************* # #********************************************************************* -def unique_filename(fpath, prefix='', names=None): - """Creates a filepath with a unique (human readable) filename - @param: fpath: filepath to patch +def split_ext(fpath, extensions=1): + """Splits a filepath into filepath and extension + @param fpath: (str) filepath to split + @param extensions: (int) maximum number of extensions to split (can be a negative integer aswell) + + >>> split_ext('foo.txt') + ('foo', '.txt') + + >>> split_ext('foo.txt.bar', extensions=2) + ('foo', '.txt.bar') + + >>> split_ext('foo.txt.bar', extensions=0) + ('foo.txt.bar', '') + + >>> split_ext('foo.txt', extensions=-2) + ('foo', '.txt') + + """ + if extensions == 0: + return fpath, '' + + if extensions == 1: + head, tail = os.path.splitext(fpath) + return head, tail + + elif extensions < 1: + out = [] + tmp_fpath = fpath + while extensions < 0: + tmp_fpath, ext = os.path.splitext(tmp_fpath) + if not ext: break + out.insert(0, ext) + extensions += 1 + return tmp_fpath, ''.join(out) + + elif extensions > 1: + out = [] + tmp_fpath = fpath + for i in xrange(extensions): + tmp_fpath, ext = os.path.splitext(tmp_fpath) + if not ext: break + out.insert(0, ext) + return tmp_fpath, ''.join(out) + +#********************************************************************* +# +#********************************************************************* +def strip_unique_filename_postfix(fpath, extensions=1, pattern=re.compile('\s\([1-9]\d*\)\Z')): + """Strips a posfix as added by L{unique_filename} from a filepath + @param fpath: (str) filepath to strip + @param extensions: (int) maximum number of extensions to split (may be a negative integer aswell) + @param pattern: regex pattern tu use. The filename part of fpath (without extension) will be split + by this pattern and the first part is used for further processing. + @return: (str) stripped filepath + + >>> strip_unique_filename_postfix('foo (1).txt') + 'foo.txt' + + >>> strip_unique_filename_postfix('foo (0).txt') + 'foo (0).txt' + + """ + filename, ext = split_ext(fpath, extensions=extensions) + filename = pattern.split(filename)[0] + return filename + ext + +#********************************************************************* +# +#********************************************************************* +def unique_filename(fpath, prefix='', names=None, extensions=1, ispostfixed=False): + """Creates a filepath with a unique (human readable) postfix + @param fpath: filepath to postfix @param prefix: prefix to add to the filename or '' @param names: list of filenames to patch agaunst or None to check files in the directory of filepath + @param extensions: (int) maximum number of extensions to split (may be a negative integer aswell) + @param ispostfixed: if True, the filepath is assumed to be already postfixed and the algo tries + to replace former postfixes - @return: a filepath with one of these 'MyFile (1).txt' patched filenames + @return: a filepath with one of these 'MyFile (1).txt' postfixed filenames + >>> names = ['foo.txt', 'foo (1).txt'] >>> unique_filename('foo.txt', names=names) 'foo (2).txt' @@ -28,6 +101,9 @@ >>> result == expected True + + # an explicite prefix may be passed aswell + >>> names = ['foo.txt', ] >>> unique_filename('foo.txt', names=names, prefix="Copy Of") 'Copy Of foo.txt' @@ -36,56 +112,78 @@ >>> unique_filename('foo.txt', names=names, prefix="Copy Of") 'Copy Of foo (1).txt' + + # the algo tries its best to replace already present postfixes if desired + + >>> names = ['foo.txt', 'foo (1).txt'] + >>> unique_filename('foo (1).txt', names=names, ispostfixed=True) + 'foo (2).txt' + + >>> names = ['foo.txt', 'foo (1).txt'] + >>> unique_filename('foo.txt', names=names, ispostfixed=True) + 'foo (2).txt' + + + # the number of extensions to be assumed may be passed explicitely + + >>> names = ['foo.txt', 'foo (1).txt'] + >>> unique_filename('foo.txt.bar', names=names, extensions=2) + 'foo.txt.bar' + + >>> names = ['foo.txt.bar', 'foo (1).txt'] + >>> unique_filename('foo.txt.bar', names=names, extensions=2) + 'foo (1).txt.bar' + """ filename = os.path.basename(fpath) dirname = os.path.dirname(fpath) if not filename: raise ValueError("No filename found: %s" % fpath) - + + if ispostfixed: + filename = strip_unique_filename_postfix(filename, extensions=extensions) + tmp_filename, tmp_ext = split_ext(filename, extensions=extensions) + n = 0 - tmp_filename = filename while True: if names is not None: - if tmp_filename not in names: break + if filename not in names: break else: - if not os.path.exists(os.path.join(dirname, tmp_filename)): break + if not os.path.exists(os.path.join(dirname, filename)): break n += 1 - tmp_filename, tmp_ext = os.path.splitext(filename) if prefix: if n == 1: - tmp_filename = '%s %s' % (prefix, tmp_filename) + filename = '%s %s' % (prefix, tmp_filename) else: - tmp_filename = '%s %s (%s)' % (prefix, tmp_filename, n -1) + filename = '%s %s (%s)' % (prefix, tmp_filename, n -1) else: - tmp_filename = '%s (%s)' % (tmp_filename, n) - tmp_filename = tmp_filename + tmp_ext + filename = '%s (%s)' % (tmp_filename, n) + filename = filename + tmp_ext - return os.path.join(dirname, tmp_filename) + return os.path.join(dirname, filename) - #********************************************************************* # #********************************************************************* -def unquote_uri(uri, slash='-'): +def unquote_uri(uri, slash=None): """Unquotes an uri so it can be used as a name in the filesystem @param uri: (str) uri to unquote - @param slasch: (str) substitution string shlashes to use or None to keep slashes + @param slash: (str) substitution string shlashes to use or None to keep slashes @return: (str) uri - >>> unquote_uri('foo/bar') + >>> unquote_uri('foo/bar', slash='-') 'foo-bar' >>> unquote_uri('foo/b%20ar') - 'foo-b ar' + 'foo/b ar' >>> unquote_uri('foo/b%34ar') - 'foo-b%34ar' + 'foo/b%34ar' >>> unquote_uri('foo/bar', slash='77') 'foo77bar' >>> unquote_uri('foo/bar', slash=None) 'foo/bar' """ - # impossible to handle all the dos and donts on oses. So do minimum # to enshure user readability if slash is not None: @@ -94,48 +192,10 @@ uri = uri.replace('%28', '(') uri = uri.replace('%29', ')') return uri - #********************************************************************* # #********************************************************************* -def split_extensions(fpath): - """Splits all extensions from a filepath - @param fpath: filepath to split extensions from - @return: (tuple) filepath, [extension1, extension(N) ...] - - >>> split_extensions('foo.aaa.bbb') - ('foo', ['.aaa', '.bbb']) - - >>> split_extensions('foo') - ('foo', []) - - >>> split_extensions('.foo.aaa') - ('.foo', ['.aaa']) - - >>> split_extensions('') - ('', []) - - """ - directory, name = os.path.split(fpath) - tmp_name = name - exts = [] - while True: - tmp_name, ext = os.path.splitext(tmp_name) - if not tmp_name: - name = ext - break - if not ext: - name = tmp_name - break - exts.append(ext) - - exts.reverse() - return os.path.join(directory, name), exts - -#********************************************************************* -# -#********************************************************************* if __name__ == '__main__': import doctest doctest.testmod() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-02 18:29:44
|
Revision: 121 http://fclient.svn.sourceforge.net/fclient/?rev=121&view=rev Author: jurner Date: 2008-02-02 10:29:43 -0800 (Sat, 02 Feb 2008) Log Message: ----------- fixed some docstrings for epydoc Modified Paths: -------------- trunk/fclient/fclient_lib/pyex/events.py Modified: trunk/fclient/fclient_lib/pyex/events.py =================================================================== --- trunk/fclient/fclient_lib/pyex/events.py 2008-02-02 18:29:09 UTC (rev 120) +++ trunk/fclient/fclient_lib/pyex/events.py 2008-02-02 18:29:43 UTC (rev 121) @@ -10,13 +10,14 @@ """Metaclass for events""" class Event(object): - """Event handler""" + """Event handler + @ivar observers: list of observers of the event + """ + def __init__(self, name): """ - @param name: name of the event - @attr name: name of the event - @attr observers: list of observers of the event + @param name: (str) name of the event """ self.name = name self.observers = [] @@ -66,14 +67,7 @@ always called with the event as first argument, followed by additional arguments, depending on the event. - Events have the following methods: - - 'name': name of the event - 'observers': list of observers listening to the event - - - Note: - Always make shure to disconnnect when event notification is no longer desired + @note: always make shure to disconnnect when event notification is no longer desired >>> class MyEvents(Events): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-02 18:29:16
|
Revision: 120 http://fclient.svn.sourceforge.net/fclient/?rev=120&view=rev Author: jurner Date: 2008-02-02 10:29:09 -0800 (Sat, 02 Feb 2008) Log Message: ----------- fixed some docstrings for epydoc Modified Paths: -------------- trunk/sandbox/fcp/fcp_lib/events.py Modified: trunk/sandbox/fcp/fcp_lib/events.py =================================================================== --- trunk/sandbox/fcp/fcp_lib/events.py 2008-02-02 18:28:43 UTC (rev 119) +++ trunk/sandbox/fcp/fcp_lib/events.py 2008-02-02 18:29:09 UTC (rev 120) @@ -10,13 +10,14 @@ """Metaclass for events""" class Event(object): - """Event handler""" + """Event handler + @ivar observers: list of observers of the event + """ + def __init__(self, name): """ - @param name: name of the event - @attr name: name of the event - @attr observers: list of observers of the event + @param name: (str) name of the event """ self.name = name self.observers = [] @@ -66,14 +67,7 @@ always called with the event as first argument, followed by additional arguments, depending on the event. - Events have the following methods: - - 'name': name of the event - 'observers': list of observers listening to the event - - - Note: - Always make shure to disconnnect when event notification is no longer desired + @note: always make shure to disconnnect when event notification is no longer desired >>> class MyEvents(Events): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-02 18:28:46
|
Revision: 119 http://fclient.svn.sourceforge.net/fclient/?rev=119&view=rev Author: jurner Date: 2008-02-02 10:28:43 -0800 (Sat, 02 Feb 2008) Log Message: ----------- fixed some docstrings for epydoc Modified Paths: -------------- trunk/sandbox/fcp/fcp_lib/namespace.py Modified: trunk/sandbox/fcp/fcp_lib/namespace.py =================================================================== --- trunk/sandbox/fcp/fcp_lib/namespace.py 2008-02-02 18:27:42 UTC (rev 118) +++ trunk/sandbox/fcp/fcp_lib/namespace.py 2008-02-02 18:28:43 UTC (rev 119) @@ -8,7 +8,7 @@ def split_ext(fpath, extensions=1): """Splits a filepath into filepath and extension @param fpath: (str) filepath to split - @param components: (int) maximum number of extensions to split (can be a negative integer aswell) + @param extensions: (int) maximum number of extensions to split (can be a negative integer aswell) >>> split_ext('foo.txt') ('foo', '.txt') @@ -76,7 +76,7 @@ #********************************************************************* def unique_filename(fpath, prefix='', names=None, extensions=1, ispostfixed=False): """Creates a filepath with a unique (human readable) postfix - @param: fpath: filepath to postfix + @param fpath: filepath to postfix @param prefix: prefix to add to the filename or '' @param names: list of filenames to patch agaunst or None to check files in the directory of filepath @@ -169,7 +169,7 @@ def unquote_uri(uri, slash=None): """Unquotes an uri so it can be used as a name in the filesystem @param uri: (str) uri to unquote - @param slasch: (str) substitution string shlashes to use or None to keep slashes + @param slash: (str) substitution string shlashes to use or None to keep slashes @return: (str) uri >>> unquote_uri('foo/bar', slash='-') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-02 18:27:37
|
Revision: 118 http://fclient.svn.sourceforge.net/fclient/?rev=118&view=rev Author: jurner Date: 2008-02-02 10:27:42 -0800 (Sat, 02 Feb 2008) Log Message: ----------- refactore unittests 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-02-02 18:27:21 UTC (rev 117) +++ trunk/sandbox/fcp/test_fcp/test_fcp2_0_client.py 2008-02-02 18:27:42 UTC (rev 118) @@ -18,6 +18,7 @@ import fcp2_0_client from fcp2_0_client import FcpClient +import fcp2_0_consts as consts sys.path.pop(0) @@ -32,7 +33,8 @@ #*********************************************************************************** # #*********************************************************************************** -class TestFcpClient(unittest.TestCase): +class BaseTestClient(unittest.TestCase): + """Base class that does not connect to FcpClient prior to each test""" def __init__(self, *args, **kwargs): @@ -52,8 +54,8 @@ self.events = [] # events received from the client self.messages = [] # messages the client sent self.tmpfiles = [] # temp files used for testing (will be removed on tearDown) - - def _captureBytesFromClient(self, bytes): + + def _captureMessagesFromClient(self, bytes): s = DummySocket() s.setResponse(bytes) self.messages.append(self.fcpClient.Message.fromSocket(s)) @@ -62,17 +64,21 @@ self.events.append( (event, msg) ) def connectClient(self): + """Connects to the client""" + enum = self.fcpClient.connect(duration=0.2, timeout=0.1) msg = enum.next() self.failIf(msg is not None) - self.socket.setResponseMessage( + #NOTE: have to send directly via socket here (our sendResponseMessage + # calls client.next() autkmatically) + self.socket.sendResponseMessage( 'NodeHello', FCPVersion='2.0', Node='Fred', - Version='???', - Revision='???', - Build='???', - ExRevision='???', + Version=str(self.fcpClient.ExpectedFcpVersion), + Revision='99999999', + Build='999999', + ExRevision='999999', Testnet='false', CompressionCodecs='1', ConnectionIdentifier='any', @@ -81,32 +87,115 @@ msg = enum.next() self.messages.pop(0) self.events.pop(0) + + + def assertHasNextEvent(self, + expectedEvent=None, + messageName=None, + param1=None, + param2=None, + param3=None, + param4=None, + param5=None, + data=None + ): + """Tests if we received a certain event from the client + @param expectedEvent: the event expected or None if no event is expected + @param messageName: expected mesageName or None if no message is expected + @param param1: tuple(paramName, value) of a message parameter expected + @param data: data expected along with the message or None + @return: message if a message was received or None + """ + if expectedEvent is None: + self.failIf(self.events) + else: + self.failUnless(self.events) + event, msg = self.events.pop(0) + self.assertEqual(event, expectedEvent) + + if messageName is not None: + self.assertEqual(msg.name, messageName) + if param1 is not None: + param1, value1 = param1 + self.failUnless(param1 in msg.params) + self.assertEqual(value1, msg[param1]) + if param2 is not None: + param2, value2 = param2 + self.failUnless(param2 in msg.params) + self.assertEqual(value2, msg[param2]) + if param3 is not None: + param3, value3 = param3 + self.failUnless(param3 in msg.params) + self.assertEqual(value3, msg[param3]) + if param4 is not None: + param4, value4 = param4 + self.failUnless(param4 in msg.params) + self.assertEqual(value4, msg[param4]) + if param5 is not None: + param5, value5 = param5 + self.failUnless(param5 in msg.params) + self.assertEqual(value5, msg[param5]) + + if data is not None: + self.assertEqual(data, msg.data) + + return msg + + def assertHasNextMessage(self, + messageName, + param1=None, + param2=None, + param3=None, + param4=None, + param5=None, + data=None + ): + """Tests if we received a certain message from the client + @param messageName: expected mesageName or None if no message is expected + @param param1: tuple(paramName, value) of a message parameter expected + @param data: data expected along with the message or None + + @return: message if a message was received or None + """ + if messageName is None: + self.failIf(self.messages) + else: + msg = self.messages.pop(0) + self.assertEqual(msg.name, messageName) + if param1 is not None: + param1, value1 = param1 + self.failUnless(param1 in msg.params) + self.assertEqual(value1, msg[param1]) + if param2 is not None: + param2, value2 = param2 + self.failUnless(param2 in msg.params) + self.assertEqual(value2, msg[param2]) + if param3 is not None: + param3, value3 = param3 + self.failUnless(param3 in msg.params) + self.assertEqual(value3, msg[param3]) + if param4 is not None: + param4, value4 = param4 + self.failUnless(param4 in msg.params) + self.assertEqual(value4, msg[param4]) + if param5 is not None: + param5, value5 = param5 + self.failUnless(param5 in msg.params) + self.assertEqual(value5, msg[param5]) + + if data is not None: + self.assertEqual(data, msg.data) + return msg + - def nextMessage(self): - """Returns the next message the client send or None""" - if self.messages: - return self.messages.pop(0) - return None + def sendResponseMessage(self, messageName, data=None, **params): + """Posts a message to the client""" + self.socket.sendResponseMessage(messageName, data=data, **params) + self.fcpClient.next() - def nextEvent(self): - """Returns the next tuple(event, message) the client triggered or (None, None)""" - if self.events: - return self.events.pop(0) - return (None, None) - - def hasNextEvent(self): - return bool(self.events) - - def hasNextMessage(self): - return bool(self.messages) - - - - ##################################################### - ## - ##################################################### + def setUp(self): self.oldSocketModule = fcp2_0_client.socket fcp2_0_client.socket = self.socketModule @@ -121,7 +210,7 @@ # capture all messages the client sent self.messages = [] # messages the client send - self.socket.setBytesReceiver(self._captureBytesFromClient) + self.socket.setBytesReceiver(self._captureMessagesFromClient) @@ -135,22 +224,37 @@ # clean up tmpfiles for fpath in self.tmpfiles: os.remove(fpath) + +#*********************************************************************************** +# +#*********************************************************************************** +class BaseTestConnectedClient(BaseTestClient): + """Base class that automatically connects to FcpClient prior to each test""" + def setUp(self): + BaseTestClient.setUp(self) + self.connectClient() - ####################################################### - ## - ## connect() test cases - ## - ####################################################### + +#*********************************************************************************** +# +#*********************************************************************************** +#TODO: class Test.... set/getDebugVerbosity / connectionName and friends... (BaseTestConnectedClient): + +#*********************************************************************************** +# +#*********************************************************************************** +class TestConnect(BaseTestClient): + + def testClose(self): - self.failIf(self.socket.closed) self.connectClient() self.fcpClient.close() self.failUnless(self.socket.closed) - def testConnectingFailed(self): + def testConnectFailed(self): # simulate a failed connection attempt enum = self.fcpClient.connect(duration=0.2, timeout=0.1) @@ -162,160 +266,271 @@ else: raise RuntimeError('Fell trough') + # check messages the client send - self.failUnless(len(self.messages) == 1) - msg = self.messages.pop(0) - self.failUnless(msg.name == self.fcpClient.Message.MessageClientHello) - + self.assertHasNextMessage(consts.Message.ClientHello) + # check events the client triggered - self.failUnless(len(self.events) == 1) - event, msg = self.events.pop(0) - self.failUnless(event.name == self.fcpClient.events.ClientDisconnected.name) - self.failUnless(msg.get('DisconnectReason', None) == FcpClient.DisconnectReason.ConnectingFailed) + self.assertHasNextEvent( + self.fcpClient.events.ClientDisconnected, + consts.Message.ClientDisconnected, + ('DisconnectReason', consts.DisconnectReason.ConnectingFailed), + ) + self.assertHasNextEvent(None) + # did the client clean up our socket? self.failUnless(self.socket.closed) - def testConnectingSucceeded(self): + def testConnecSucceeded(self): # simulate a successful connection attempt enum = self.fcpClient.connect(duration=0.2, timeout=0.1) msg = enum.next() self.failIf(msg is not None) - self.socket.setResponseMessage( + # check messages the client send message + self.assertHasNextMessage( + consts.Message.ClientHello + ) + + #NOTE: have to send directly via socket here (our sendResponseMessage + # calls client.next() autkmatically) + self.socket.sendResponseMessage( 'NodeHello', FCPVersion='2.0', Node='Fred', - Version='???', - Revision='???', - Build='???', - ExRevision='???', + Version=str(self.fcpClient.ExpectedFcpVersion), + Revision='99999999', + Build='999999', + ExRevision='999999', Testnet='false', CompressionCodecs='1', ConnectionIdentifier='any', NodeLanguage='en', ) msg = enum.next() + + # check events the client triggered + self.assertHasNextEvent( + self.fcpClient.events.ClientConnected, + consts.Message.NodeHello, + ) - # check messages the client received our response - self.failIf(msg is None) - self.failUnless(msg.name == self.fcpClient.Message.MessageNodeHello) + self.assertHasNextEvent(None) + + +#*********************************************************************************** +# +#*********************************************************************************** +#TODO: testCloseOnVersionMismatch +#TODO: testCloseOnDuplicateConnectionName +#TODO: testShutdown + +class TestConnection(BaseTestConnectedClient): + + def testBrokenSocket(self): - # check events the client triggered - self.failUnless(len(self.events) == 1) - event, msg = self.events.pop(0) - self.failUnless(event.name == self.fcpClient.events.ClientConnected.name) - self.failUnless(msg.name == self.fcpClient.Message.MessageNodeHello) + self.socket.close() + # send a test message + self.assertRaises(socket.error, self.fcpClient.sendMessage, 'test' ) + + # check if ClientDisconnected events has been triggered + self.assertHasNextEvent( + self.fcpClient.events.ClientDisconnected, + consts.Message.ClientSocketDied, + ) + self.assertHasNextEvent(None) + - #################################################### - ## - ## PersistentGet test cases - ## - #################################################### - def testEventRequestStarted(self): - - self.connectClient() +#*********************************************************************************** +# +#*********************************************************************************** +class TestClientGet(BaseTestConnectedClient): + + def testClientGetRegistered(self): # request a arbitrary file - myIdentifier = self.fcpClient.getFile( + myIdentifier = self.fcpClient.getData( 'arbitrary-uri', - 'arbitryry.txt' ) - - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageClientGet) - self.failIf(self.hasNextEvent() ) # no events should be triggered up to now + self.assertHasNextMessage( + consts.Message.ClientGet, + ) + self.assertHasNextEvent(None) + self.failUnless(self.fcpClient.getRequests() ) myRequest = self.fcpClient.getRequest(myIdentifier) self.assertEqual(myIdentifier, myRequest['Identifier']) - self.assertEqual(myRequest['FcStatus'], self.fcpClient.Message.StatusPending) + self.assertEqual(myRequest['FcStatus'], consts.MessageStatus.Pending) + + def testGetData(self): + + # request a arbitrary file + myIdentifier = self.fcpClient.getData( + 'arbitrary-uri', + ) + myRequest = self.fcpClient.getRequest(myIdentifier) + # respond to the file request - self.socket.setResponseMessage( + self.sendResponseMessage( 'PersistentGet', Started='false', **myRequest.params ) - self.fcpClient.next() - - event, msg = self.nextEvent() - self.failIf(event is None) - self.assertEqual(event, self.fcpClient.events.RequestStarted) - self.assertEqual(msg, myRequest) # ??? looks like an implemenation detail - self.assertEqual(myRequest['FcStatus'], self.fcpClient.Message.StatusStarted) + self.assertHasNextEvent( + self.fcpClient.events.RequestStarted, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Started) + ) + self.assertHasNextEvent(None) + + # simulate a progress + self.sendResponseMessage( + 'SimpleProgress', + Identifier=myIdentifier, + Total=10, + Required=8, + Failed=0, + FatallyFailed=0, + FinalizedTotal='true', + Succeeded=1, + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestProgress, + ) - self.failIf(self.hasNextEvent() ) - - + # finalize request + data = 'foo' + params = { + 'Identifier': myIdentifier, + 'Global': 'false', + 'DataLength': len(data), + 'Metadata.ContentType': 'any', + } + self.sendResponseMessage( + 'DataFound', + **params + ) + # we don't expect an event here.... + self.assertHasNextEvent(None) + + self.sendResponseMessage( + 'AllData', + data=data, + Identifier=myIdentifier, + Global='false', + DataLength=len(data), + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestCompleted, + data=data + ) + self.assertHasNextEvent(None) + - def testEventRequestModified(self): - - self.connectClient() - + def testgetFile(self): + # request a arbitrary file myIdentifier = self.fcpClient.getFile( 'arbitrary-uri', + 'arbitryry.txt' + ) + myRequest = self.fcpClient.getRequest(myIdentifier) + self.assertHasNextMessage(consts.Message.ClientGet) + + # respond to the file request + self.sendResponseMessage( + 'PersistentGet', + Started='false', + **myRequest.params + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestStarted, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Started) + ) + self.assertHasNextEvent(None) + + # finalize request + data = 'foo' + params = { + 'Identifier': myIdentifier, + 'Global': 'false', + 'DataLength': 123456, + 'Metadata.ContentType': 'any', + } + self.sendResponseMessage( + 'DataFound', + **params + ) + self.assertHasNextEvent( + self.fcpClient.events.RequestCompleted, + consts.Message.ClientGet, + ('FcStatus', consts.MessageStatus.Complete) + ) + self.assertHasNextEvent(None) + +#*********************************************************************************** +# +#*********************************************************************************** +#TODO: class TestClientPut(BaseTestConnectedClient): + +#*********************************************************************************** +# +#*********************************************************************************** +#TODO: testGetRequest() +#TODO: testGetRequest() +#TODO: testResendRequest() + +class TestRequests(BaseTestConnectedClient): + + def testModifyRequest(self): + + # request a arbitrary file + myIdentifier = self.fcpClient.getFile( + 'arbitrary-uri', 'arbitryry.txt', persistentUserData='foo', - priorityClass=self.fcpClient.Priority.Medium, + priorityClass=consts.Priority.Medium, ) - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageClientGet) + myRequest = self.fcpClient.getRequest(myIdentifier) + self.assertHasNextMessage(consts.Message.ClientGet) # respond to the file request - self.socket.setResponseMessage( + self.sendResponseMessage( 'PersistentGet', Started='false', - **msg.params + **myRequest.params ) - self.fcpClient.next() - event, msg = self.nextEvent() - self.failIf(event is None) - self.assertEqual(event, self.fcpClient.events.RequestStarted) - - - myRequest = self.fcpClient.getRequest(myIdentifier) - - + self.assertHasNextEvent(self.fcpClient.events.RequestStarted ) + # test modify persistent user data - self.fcpClient.modifyRequest(myIdentifier, persistentUserData='bar', priorityClass=self.fcpClient.Priority.High) - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageModifyPersistentRequest) + self.fcpClient.modifyRequest(myIdentifier, persistentUserData='bar', priorityClass=consts.Priority.High) + msg = self.assertHasNextMessage(consts.Message.ModifyPersistentRequest) # respond to the file request - self.socket.setResponseMessage( + self.sendResponseMessage( 'PersistentRequestModified', **msg.params ) - self.fcpClient.next() + self.assertHasNextEvent(self.fcpClient.events.RequestModified) - event, eventMsg = self.nextEvent() - self.failIf(event is None) - self.assertEqual(event, self.fcpClient.events.RequestModified) - self.failUnless(self.fcpClient.Message.ModifiedRequestPersistentUserData in eventMsg['FcModified']) - self.failUnless(self.fcpClient.Message.ModifiedRequestPriorityClass in eventMsg['FcModified']) + self.failUnless(consts.RequestModified.PersistentUserData in myRequest['FcModified']) + self.failUnless(consts.RequestModified.PriorityClass in myRequest['FcModified']) self.assertEqual('bar', myRequest['FcPersistentUserData']) - self.assertEqual(self.fcpClient.Priority.High, myRequest['PriorityClass']) - self.failIf(self.events) + self.assertEqual(consts.Priority.High, myRequest['PriorityClass']) - - - - + self.assertHasNextEvent(None) def testRemoveRequest(self): - - self.connectClient() - + # request a file myIdentifier = self.fcpClient.getFile( 'arbitrary-uri', @@ -324,75 +539,50 @@ myRequest = self.fcpClient.getRequest(myIdentifier) # respond to the file request - self.socket.setResponseMessage( + self.sendResponseMessage( 'PersistentGet', Started='false', **myRequest.params ) - self.fcpClient.next() - - + # ignore events and messages so far self.events = [] self.messages = [] - # now cancel request self.fcpClient.removeRequest(myIdentifier) # status of our request should be set to removed emidiately, but it should # not be removed from the client - self.assertEqual(myRequest['FcStatus'], self.fcpClient.Message.StatusRemoved) + self.assertEqual(myRequest['FcStatus'], consts.MessageStatus.Removed) self.failUnless(myIdentifier in self.fcpClient.getRequests()) # client schould send a RemovePersistentRequest - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageRemovePersistentRequest) - + self.assertHasNextMessage(consts.Message.RemovePersistentRequest) + # respond with a PersistentRequestRemoved - self.socket.setResponseMessage( + self.sendResponseMessage( 'PersistentRequestRemoved', - Identifier=msg['Identifier'] + Identifier=myIdentifier, ) - self.fcpClient.next() - + # now the request should have been removed self.failIf(self.fcpClient.getRequests()) - self.failIf(self.hasNextEvent() ) + # client never sends an event here + self.assertHasNextEvent(None) + +#*********************************************************************************** +# +#*********************************************************************************** +#TODO: testRestoreClientPut and friends +class TestRestoreRequests(BaseTestConnectedClient): - - #################################################### - ## - ## modifyRequest test cases - ## - #################################################### - - - #################################################### - ## - ## removeRequest test cases - ## - #################################################### - + def testRestorePersistentGet_InvalidIdentifier(self): - - - #################################################### - ## - ## restore persistent request test cases - ## - ## should be run after removeRequest test cases - ### - #################################################### - def testRestorePersistentRequest_InvalidIdentifier(self): - - self.connectClient() - # throw an invalid PersistentRequest at the client myIdentifier = 'true-invalid-request-identifier' - self.socket.setResponseMessage( + self.sendResponseMessage( 'PersistentGet', Identifier=myIdentifier, ReturnType='disk', @@ -401,27 +591,23 @@ Started='false', Global='false', ) - self.fcpClient.next() - + # the client should now to cancel the request - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageRemovePersistentRequest) - self.failUnless(msg['Identifier'] == myIdentifier) + self.assertHasNextMessage( + consts.Message.RemovePersistentRequest, + ('Identifier', myIdentifier) + ) requests = self.fcpClient.getRequests() self.failIf(requests) # the client should not trigger any events - self.failIf(self.hasNextEvent() ) - - - def testRestorePersistentRequest_ValidIdentifier(self): - - self.connectClient() - + self.assertHasNextEvent(None) + + + def testRestorePersistentGet_ValidIdentifier(self): + # we need a valid identifier to restore a request, so hack a bit - myIdentifier = self.fcpClient.getFile( 'arbitrary-uri', 'arbitryry.txt' @@ -430,17 +616,16 @@ identifier = myRequest['Identifier'] self.fcpClient.removeRequest(myIdentifier) - self.socket.setResponseMessage( + self.sendResponseMessage( 'PersistentRequestRemoved', Identifier=identifier, ) - self.fcpClient.next() self.messages = [] self.events = [] # throw a PersistentGet at the client with the identifier we hacked - self.socket.setResponseMessage( + self.sendResponseMessage( 'PersistentGet', Identifier=identifier, ReturnType='disk', @@ -449,47 +634,127 @@ Started='false', ClientToken=myRequest['ClientToken'] ) - self.fcpClient.next() - + # check if the client restored the request - event, msg = self.nextEvent() - self.failIf(event is None) - self.assertEqual(event, self.fcpClient.events.RequestRestored) + self.assertHasNextEvent( + self.fcpClient.events.RequestRestored, + consts.Message.ClientGet, + ('Identifier', myIdentifier) + ) - requests = self.fcpClient.getRequests() - self.failUnless(requests) - self.assertEqual(identifier, requests[msg['Identifier']]['Identifier']) + self.assertHasNextEvent(None) + +#*********************************************************************************** +# +#*********************************************************************************** +#TODO: testDDAReadDenied_ReadDissallowed +#TODO: testDDAWriteDenied +#TODO: testDDAWriteDenied_WriteDisallowed + +class TestDDA(BaseTestConnectedClient): + + def testDDAWriteDenied(self): + + # request a file + myIdentifier = self.fcpClient.getFile( + 'arbitrary-uri', + os.path.join(DIR, 'DDATest.txt') + ) - self.failIf(self.hasNextEvent() ) + # client schould send a ClientGet + self.assertHasNextMessage(consts.Message.ClientGet) + # respond with a ProtocolError + self.sendResponseMessage( + 'ProtocolError', + Code=25, # DDADenied + Identifier=myIdentifier, + ExtraDescription='An error occured', + Fatal='false', + Global='false', + ) + + # client should respond with a TestDDARequest + self.assertHasNextMessage( + consts.Message.TestDDARequest, + ('Directory', DIR), + ('WantWriteDirectory', True) + ) - #################################################### - ## - ## error test cases - ## - #################################################### - def testBrokenSocket(self): + #msg = self.nextMessage() + #self.failIf(msg is None) + #self.assertEqual(msg.name, consts.Message.TestDDARequest) + ##self.assertEqual(msg['Directory'], DIR) + #self.failIf(not msg['WantWriteDirectory']) - self.connectClient() - self.socket.close() - # send a test message - self.assertRaises(socket.error, self.fcpClient.sendMessage, 'test' ) + # respond with a TestDDAReply message + writeContent = 'blah' + fd, fpath = tempfile.mkstemp(dir=DIR) + os.close(fd) + self.sendResponseMessage( + 'TestDDAReply', + Directory=DIR, + WriteFilename=fpath, + ContentToWrite=writeContent, + ) + + # client should respond with a TestDDAResponse + self.assertHasNextMessage( + consts.Message.TestDDAResponse, + ('Directory', DIR) + ) + + # check if content was written + with open(fpath) as fp: + self.failUnless(fp.read() == writeContent) + + # respond with a TestDDAComplete message + self.sendResponseMessage( + 'TestDDAComplete', + Directory=DIR, + WriteDirectoryAllowed='true', + ) + + # check if our tempfile was removed + self.failIf(os.path.isfile(fpath)) + + # client sahould send a new ClientGet + msg = self.assertHasNextMessage(consts.Message.ClientGet) + + # no events should have been triggered upo to now + self.assertHasNextEvent(None) - # check if ClientDisconnected events has been triggered - event, msg = self.nextEvent() - self.failIf(event is None) - self.assertEqual(event, self.fcpClient.events.ClientDisconnected) - self.assertEqual(msg.name, self.fcpClient.Message.MessageClientSocketDied) + # respond with a PersistentGet + self.sendResponseMessage( + 'PersistentGet', + Started='false', + **msg.params + ) + + # check if client send expected events + self.assertHasNextEvent( + self.fcpClient.events.RequestStarted, + consts.Message.ClientGet, + ('Identifier', myIdentifier) + ) + self.assertHasNextEvent(None) - self.failIf(self.hasNextEvent() ) + requests = self.fcpClient.getRequests() + self.assertEqual(len(requests), 1) + + + #def testDDAReadDenied(self): - + # pass + +#*********************************************************************************** +# +#*********************************************************************************** +class TestCollisions(BaseTestConnectedClient): def testIdentifierCollision(self): - - self.connectClient() - + # request a file myIdentifier = self.fcpClient.getFile( 'arbitrary-uri', @@ -497,50 +762,37 @@ ) # client schould send a ClientGet - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageClientGet) + self.assertHasNextMessage(consts.Message.ClientGet) - # check if our request was registered - requests = self.fcpClient.getRequests() - self.failUnless(len(requests) == 1) # respond with an IdentifierCollision - self.socket.setResponseMessage( + self.sendResponseMessage( 'IdentifierCollision', - Identifier=msg['Identifier'] + Identifier=myIdentifier, ) - self.fcpClient.next() - + # client schould send a new ClientGet - msg2 = self.nextMessage() - self.failIf(msg2 is None) - self.assertEqual(msg2.name, self.fcpClient.Message.MessageClientGet) - + self.assertHasNextMessage(consts.Message.ClientGet) + # check client state requests = self.fcpClient.getRequests() self.assertEqual(len(requests), 1) # check if RequestModified event has been triggered - event, eventMsg = self.nextEvent() - self.failIf(event is None) - self.assertEqual(event, self.fcpClient.events.RequestModified) - self.failUnless(self.fcpClient.Message.ModifiedRequestIdentifier in eventMsg['FcModified']) - self.assertEqual(eventMsg['FcModified'][self.fcpClient.Message.ModifiedRequestIdentifier], myIdentifier) - self.assertNotEqual(eventMsg['Identifier'], myIdentifier) + msg = self.assertHasNextEvent( + self.fcpClient.events.RequestModified, + consts.Message.ClientGet, + ) - self.failIf(self.events) + self.failUnless(consts.RequestModified.Identifier in msg['FcModified']) + self.assertEqual(msg['FcModified'][consts.RequestModified.Identifier], myIdentifier) + self.assertNotEqual(msg['Identifier'], myIdentifier) + + self.assertHasNextEvent(None) - #################################################### - ## - ## test filename collisions - ## - #################################################### def testFilenameCollision_HandleRename(self): - - self.connectClient() - + # request a file fpath = os.path.join(DIR, 'test.txt') open(fpath, 'wb').close() @@ -549,62 +801,49 @@ myIdentifier = self.fcpClient.getFile( 'arbitrary-uri', fpath, - filenameCollision=self.fcpClient.FilenameCollision.HandleRename, + filenameCollision=consts.FilenameCollision.HandleRename, ) # client schould send a ClientGet - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageClientGet) + self.assertHasNextMessage(consts.Message.ClientGet) # check if our request was registered requests = self.fcpClient.getRequests() self.failUnless(len(requests) == 1) # now respond with a ProtocolError - self.socket.setResponseMessage( + self.sendResponseMessage( 'ProtocolError', - Identifier=msg['Identifier'], + Identifier=myIdentifier, Code='10', # disk target exists ExtraDescription='An error occured', Fatal='false', Global='false', ) - self.fcpClient.next() - + # client schould send a new ClientGet with a differing filename - msg2 = self.nextMessage() - self.failIf(msg2 is None) - self.assertEqual(msg2.name, self.fcpClient.Message.MessageClientGet) + msg = self.assertHasNextEvent( + self.fcpClient.events.RequestModified, + consts.Message.ClientGet + ) + + self.failUnless(consts.RequestModified.Filename in msg['FcModified']) + self.assertEqual(msg['FcModified'][consts.RequestModified.Filename], fpath) + self.assertNotEqual(msg['Filename'], fpath) - # check if filename was replaced - self.failIf(msg['Filename'] == msg2['Filename']) - - event, eventMsg = self.nextEvent() - self.failIf(event is None) - self.assertEqual(event, self.fcpClient.events.RequestModified) - self.failUnless(self.fcpClient.Message.ModifiedRequestFilename in eventMsg['FcModified']) - self.assertEqual(eventMsg['FcModified'][self.fcpClient.Message.ModifiedRequestFilename], fpath) - self.assertNotEqual(eventMsg['Filename'], fpath) - # check flags - filenameCollision = eventMsg['FcFilenameCollision'] + filenameCollision = msg['FcFilenameCollision'] self.assertEqual( - filenameCollision & self.fcpClient.FilenameCollision.MaskHandle, - self.fcpClient.FilenameCollision.HandleRename + filenameCollision & consts.FilenameCollision.MaskHandle, + consts.FilenameCollision.HandleRename ) - self.failUnless(filenameCollision & self.fcpClient.FilenameCollision.CollisionHandled) + self.failUnless(filenameCollision & consts.FilenameCollision.CollisionHandled) + self.assertHasNextEvent(None) - self.failIf(self.events) - - - def testFilenameCollision_HandleNever(self): - - self.connectClient() - + # request a file fpath = os.path.join(DIR, 'test.txt') open(fpath, 'wb').close() @@ -613,169 +852,92 @@ myIdentifier = self.fcpClient.getFile( 'arbitrary-uri', fpath, - filenameCollision=self.fcpClient.FilenameCollision.HandleNever, + filenameCollision=consts.FilenameCollision.HandleNever, ) myRequest = self.fcpClient.getRequest(myIdentifier) # client schould send a ClientGet - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageClientGet) + self.assertHasNextMessage(consts.Message.ClientGet) # check if our request was registered requests = self.fcpClient.getRequests() self.failUnless(len(requests) == 1) # now respond with a ProtocolError - self.socket.setResponseMessage( + self.sendResponseMessage( 'ProtocolError', - Identifier=msg['Identifier'], + Identifier=myIdentifier, Code='10', # disk target exists ExtraDescription='An error occured', Fatal='false', Global='false', ) - self.fcpClient.next() - + # client schould send no messages and trigger a RequestFailed event - msg2 = self.nextMessage() - self.failUnless(msg2 is None) - - event, eventMsg = self.nextEvent() - self.failIf(event is None) - self.assertEqual(event, self.fcpClient.events.RequestFailed) - #TODO: more checks here + self.assertHasNextEvent(self.fcpClient.events.RequestFailed) # request should have been removed self.failIf(self.fcpClient.getRequests()) - self.failIf(self.events) + self.assertHasNextEvent(None) - #################################################### - ## - ## DDA test cases - ## - #################################################### - def testDDAWriteDenied(self): - - self.connectClient() - - # request a file - myIdentifier = self.fcpClient.getFile( - 'arbitrary-uri', - os.path.join(DIR, 'DDATest.txt') - ) - - - # client schould send a ClientGet - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageClientGet) - - # check client state - requests = self.fcpClient.getRequests() - self.failUnless(len(requests) == 1) - - # respond with a ProtocolError - self.socket.setResponseMessage( - 'ProtocolError', - Code=25, # DDADenied - Identifier=msg['Identifier'], - ExtraDescription='An error occured', - Fatal='false', - Global='false', - ) - self.fcpClient.next() - - # client should respond with a TestDDARequest - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageTestDDARequest) - self.assertEqual(msg['Directory'], DIR) - self.failIf(not msg['WantWriteDirectory']) - - - # respond with a TestDDAReply message - writeContent = 'blah' - fd, fpath = tempfile.mkstemp(dir=DIR) - os.close(fd) - self.socket.setResponseMessage( - 'TestDDAReply', - Directory=msg['Directory'], - WriteFilename=fpath, - ContentToWrite=writeContent, - ) - self.fcpClient.next() - - # client should respond with a TestDDAResponse - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageTestDDAResponse) - self.assertEqual(msg['Directory'], DIR) - - # check if content was written - with open(fpath) as fp: - self.failUnless(fp.read() == writeContent) - - # respond with a TestDDAComplete message - self.socket.setResponseMessage( - 'TestDDAComplete', - Directory=msg['Directory'], - WriteDirectoryAllowed='true', - ) - self.fcpClient.next() - - # check if our tempfile was removed - self.failIf(os.path.isfile(fpath)) - - # client sahould send a new ClientGet - msg = self.nextMessage() - self.failIf(msg is None) - self.assertEqual(msg.name, self.fcpClient.Message.MessageClientGet) - - # no events should have been triggered upo to now - self.failIf(self.events) - - # respond with a PersistentGet - self.socket.setResponseMessage( - 'PersistentGet', - Started='false', - **msg.params - ) - self.fcpClient.next() - - # check if client send expected events - event, eventMsg = self.nextEvent() - self.failIf(event is None) - self.assertEqual(event, self.fcpClient.events.RequestStarted) - - # check client state - self.failUnless(msg['Identifier'] == myIdentifier) - requests = self.fcpClient.getRequests() - self.assertEqual(len(requests), 1) - - #################################################### - ## - ## - ## - #################################################### - +#*********************************************************************************** +# +#*********************************************************************************** +#TODO: class TestNodeAndPeers(BaseTestConnectedClient): +#*********************************************************************************** +# +#*********************************************************************************** +#TODO: class TestPlugins(BaseTestConnectedClient): + +#*********************************************************************************** +#TODO: class TestConfig(BaseTestConnectedClient): + +#*********************************************************************************** +# +#*********************************************************************************** +#TODO: class TestSSKKeypair(BaseTestConnectedClient): + +#*********************************************************************************** +# +#*********************************************************************************** +#TODO: class TestSubscribeUSK(BaseTestConnectedClient): + + + #********************************************************************************* # #********************************************************************************* def suite(): - return unittest.TestLoader().loadTestsFromTestCase(TestFcpClient) + tests = ( + TestConnect, + TestConnection, + TestClientGet, + TestRequests, + TestRestoreRequests, + TestDDA, + TestCollisions, + ) + + suite = unittest.TestSuite() + for test in tests: + suite.addTest(unittest.makeSuite(test)) + return suite + def test(): - unittest.main() + unittest.TextTestRunner(verbosity=1).run(suite()) -if __name__ == '__main__': - test() +if __name__ == "__main__": + test() + + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-02 18:27:17
|
Revision: 117 http://fclient.svn.sourceforge.net/fclient/?rev=117&view=rev Author: jurner Date: 2008-02-02 10:27:21 -0800 (Sat, 02 Feb 2008) Log Message: ----------- fix for data messages Modified Paths: -------------- trunk/sandbox/fcp/test_fcp/dummy_socket.py Modified: trunk/sandbox/fcp/test_fcp/dummy_socket.py =================================================================== --- trunk/sandbox/fcp/test_fcp/dummy_socket.py 2008-02-02 18:26:45 UTC (rev 116) +++ trunk/sandbox/fcp/test_fcp/dummy_socket.py 2008-02-02 18:27:21 UTC (rev 117) @@ -25,14 +25,17 @@ def setResponse(self, bytes): self.responseBytes += bytes - def setResponseMessage(self, name, data=None, **params): + def sendResponseMessage(self, name, data=None, **params): buf = [name, ] for name, value in params.items(): buf.append('%s=%s' % (name, value) ) - buf.append('EndMessage\n') + if data is None: + buf.append('EndMessage\n') + else: + buf.append('Data\n') self.responseBytes += '\n'.join(buf) if data: - assert 'DataLenght' in params + assert 'DataLength' in params assert params['DataLength'] == len(data) self.responseBytes += data This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-02 18:26:41
|
Revision: 116 http://fclient.svn.sourceforge.net/fclient/?rev=116&view=rev Author: jurner Date: 2008-02-02 10:26:45 -0800 (Sat, 02 Feb 2008) Log Message: ----------- ... Removed Paths: ------------- trunk/sandbox/fcp/test_fcp/dummy_socket.pyc Deleted: trunk/sandbox/fcp/test_fcp/dummy_socket.pyc =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-02 18:26:27
|
Revision: 115 http://fclient.svn.sourceforge.net/fclient/?rev=115&view=rev Author: jurner Date: 2008-02-02 10:26:29 -0800 (Sat, 02 Feb 2008) Log Message: ----------- ... Modified Paths: -------------- trunk/sandbox/fcp/test_fcp/dummy_socket.pyc Modified: trunk/sandbox/fcp/test_fcp/dummy_socket.pyc =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ju...@us...> - 2008-02-02 18:26:08
|
Revision: 114 http://fclient.svn.sourceforge.net/fclient/?rev=114&view=rev Author: jurner Date: 2008-02-02 10:26:10 -0800 (Sat, 02 Feb 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-02-02 11:27:23 UTC (rev 113) +++ trunk/sandbox/fcp/fcp2_0_client.py 2008-02-02 18:26:10 UTC (rev 114) @@ -580,9 +580,6 @@ # 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 @@ -971,6 +968,7 @@ if initialRequest is None: return False + #TODO: notify user ??? del self._requests[requestIdentifier] return True 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:27:18
|
Revision: 113 http://fclient.svn.sourceforge.net/fclient/?rev=113&view=rev Author: jurner Date: 2008-02-02 03:27:23 -0800 (Sat, 02 Feb 2008) Log Message: ----------- ... Added Paths: ----------- trunk/sandbox/fcp/fcp2_0_requests.py Removed Paths: ------------- trunk/sandbox/fcp/fcp_2_0_requests.py Copied: trunk/sandbox/fcp/fcp2_0_requests.py (from rev 112, trunk/sandbox/fcp/fcp_2_0_requests.py) =================================================================== --- trunk/sandbox/fcp/fcp2_0_requests.py (rev 0) +++ trunk/sandbox/fcp/fcp2_0_requests.py 2008-02-02 11:27:23 UTC (rev 113) @@ -0,0 +1,232 @@ +"""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 + + @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{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) + 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 + Deleted: trunk/sandbox/fcp/fcp_2_0_requests.py =================================================================== --- trunk/sandbox/fcp/fcp_2_0_requests.py 2008-02-02 11:26:43 UTC (rev 112) +++ trunk/sandbox/fcp/fcp_2_0_requests.py 2008-02-02 11:27:23 UTC (rev 113) @@ -1,232 +0,0 @@ -"""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 - - @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{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) - 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. |