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.
|