Author: aum
Date: 2006-05-14 05:23:40 +0000 (Sun, 14 May 2006)
New Revision: 8697
Modified:
trunk/apps/pyFreenet/code.leo
trunk/apps/pyFreenet/fcp.py
trunk/apps/pyFreenet/html/private/SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html
trunk/apps/pyFreenet/html/private/SimpleXMLRPCServer.SimpleXMLRPCServer-class.html
trunk/apps/pyFreenet/html/private/SocketServer.BaseServer-class.html
trunk/apps/pyFreenet/html/private/SocketServer.TCPServer-class.html
trunk/apps/pyFreenet/html/private/SocketServer.ThreadingMixIn-class.html
trunk/apps/pyFreenet/html/private/exceptions.Exception-class.html
trunk/apps/pyFreenet/html/private/fcp-module.html
trunk/apps/pyFreenet/html/private/fcp.ConnectionRefused-class.html
trunk/apps/pyFreenet/html/private/fcp.FCPException-class.html
trunk/apps/pyFreenet/html/private/fcp.FCPGetFailed-class.html
trunk/apps/pyFreenet/html/private/fcp.FCPNodeConnection-class.html
trunk/apps/pyFreenet/html/private/fcp.FCPProtocolError-class.html
trunk/apps/pyFreenet/html/private/fcp.FCPPutFailed-class.html
trunk/apps/pyFreenet/html/private/fcp.JobTicket-class.html
trunk/apps/pyFreenet/html/private/fcpxmlrpc-module.html
trunk/apps/pyFreenet/html/private/fcpxmlrpc.FCPXMLRPCServer-class.html
trunk/apps/pyFreenet/html/private/fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html
trunk/apps/pyFreenet/html/private/help.html
trunk/apps/pyFreenet/html/private/indices.html
trunk/apps/pyFreenet/html/private/sitemgr-module.html
trunk/apps/pyFreenet/html/private/sitemgr.SiteMgr-class.html
trunk/apps/pyFreenet/html/private/trees.html
trunk/apps/pyFreenet/html/public/SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html
trunk/apps/pyFreenet/html/public/SimpleXMLRPCServer.SimpleXMLRPCServer-class.html
trunk/apps/pyFreenet/html/public/SocketServer.TCPServer-class.html
trunk/apps/pyFreenet/html/public/SocketServer.ThreadingMixIn-class.html
trunk/apps/pyFreenet/html/public/exceptions.Exception-class.html
trunk/apps/pyFreenet/html/public/fcp-module.html
trunk/apps/pyFreenet/html/public/fcp.ConnectionRefused-class.html
trunk/apps/pyFreenet/html/public/fcp.FCPException-class.html
trunk/apps/pyFreenet/html/public/fcp.FCPGetFailed-class.html
trunk/apps/pyFreenet/html/public/fcp.FCPNodeConnection-class.html
trunk/apps/pyFreenet/html/public/fcp.FCPProtocolError-class.html
trunk/apps/pyFreenet/html/public/fcp.FCPPutFailed-class.html
trunk/apps/pyFreenet/html/public/fcp.JobTicket-class.html
trunk/apps/pyFreenet/html/public/fcpxmlrpc-module.html
trunk/apps/pyFreenet/html/public/fcpxmlrpc.FCPXMLRPCServer-class.html
trunk/apps/pyFreenet/html/public/fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html
trunk/apps/pyFreenet/html/public/help.html
trunk/apps/pyFreenet/html/public/indices.html
trunk/apps/pyFreenet/html/public/sitemgr-module.html
trunk/apps/pyFreenet/html/public/sitemgr.SiteMgr-class.html
trunk/apps/pyFreenet/html/public/trees.html
trunk/apps/pyFreenet/sitemgr.py
trunk/apps/pyFreenet/updatesites.py
Log:
Added support for persistent requests:
- get, put and putdir methods accept 'persistence' keyword arg
- on connect, the persistence messages sent by the mode for prior
persistent jobs are captured into self.persistentJobs
Improved control over logging in sitemgr.py and updatesites.py
Modified: trunk/apps/pyFreenet/code.leo
===================================================================
--- trunk/apps/pyFreenet/code.leo 2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/code.leo 2006-05-14 05:23:40 UTC (rev 8697)
@@ -1,36 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<leo_file>
<leo_header file_format="2" tnodes="0" max_tnode_index="6" clone_windows="0"/>
-<globals body_outline_ratio="0.313893653516">
- <global_window_position top="87" left="116" height="649" width="1141"/>
+<globals body_outline_ratio="0.260297984224">
+ <global_window_position top="33" left="118" height="649" width="1141"/>
<global_log_window_position top="0" left="0" height="0" width="0"/>
</globals>
<preferences/>
<find_panel_settings/>
<vnodes>
<v t="aum.20060506215300" a="E"><vh>PyFCP</vh></v>
-<v t="aum.20060513180215" a="E"><vh>Release files</vh>
+<v t="aum.20060513180215"><vh>Release files</vh>
<v t="aum.20060513180215.1" tnodeList="aum.20060513180215.1"><vh>@nosent
README</vh></v>
<v t="aum.20060513180716" tnodeList="aum.20060513180716"><vh>@nosent
INSTALL</vh></v>
<v t="aum.20060513180932" tnodeList="aum.20060513180932"><vh>@nosent
AUTHORS</vh></v>
<v t="aum.20060513181137" tnodeList="aum.20060513181137"><vh>@nosent
COPYING</vh></v>
<v t="aum.20060513181205" tnodeList="aum.20060513181205"><vh>@nosent
BUGS</vh></v>
<v t="aum.20060513181313" tnodeList="aum.20060513181313"><vh>@nosent
CHANGELOG</vh></v>
-<v t="aum.20060513182312" a="V" tnodeList="aum.20060513182312"><vh>@nosent
release.py</vh></v>
+<v t="aum.20060513182312" tnodeList="aum.20060513182312"><vh>@nosent
release.py</vh></v>
</v>
<v t="aum.20060513073239" a="E"><vh>Main library module</vh>
-<v t="aum.20060506215707"
tnodeList="aum.20060506215707,aum.20060506215707.1,aum.20060506220237,aum.20060506215707.2,aum.20060506215707.3,aum.20060506220237.1,aum.20060506220237.2,aum.20060506224238,aum.20060506231352.1,aum.20060506231352,aum.20060507003931,aum.20060511001853,aum.20060511205201,aum.20060506232639,aum.20060506232639.1,aum.20060511222538,aum.20060512101715,aum.20060511205201.1,aum.20060511205201.2,aum.20060506223545,aum.20060506224238.1,aum.20060506231352.2,aum.20060506220856,aum.20060506222005,aum.20060507124316,aum.20060511103841,aum.20060511103841.1,aum.20060511103952,aum.20060511103952.1,aum.20060512181209,aum.20060512102840,aum.20060509184020.1,aum.20060509184020.2,aum.20060509224119,aum.20060509224221"><vh>@nosent
fcp.py</vh>
+<v t="aum.20060506215707" a="E"
tnodeList="aum.20060506215707,aum.20060506215707.1,aum.20060506220237,aum.20060506215707.2,aum.20060506215707.3,aum.20060506220237.1,aum.20060506220237.2,aum.20060506224238,aum.20060506231352.1,aum.20060506231352,aum.20060507003931,aum.20060511001853,aum.20060514124642,aum.20060511205201,aum.20060506232639,aum.20060506232639.1,aum.20060511222538,aum.20060512101715,aum.20060511205201.1,aum.20060511205201.2,aum.20060506223545,aum.20060506224238.1,aum.20060506231352.2,aum.20060506220856,aum.20060506222005,aum.20060507124316,aum.20060511103841,aum.20060511103841.1,aum.20060511103952,aum.20060511103952.1,aum.20060514134235,aum.20060512181209,aum.20060514162944,aum.20060514124934,aum.20060512102840,aum.20060514164052,aum.20060509184020.1,aum.20060509184020.2,aum.20060509224119,aum.20060509224221"><vh>@nosent
fcp.py</vh>
<v t="aum.20060506215707.1"><vh>imports</vh></v>
<v t="aum.20060506220237"><vh>exceptions</vh></v>
<v t="aum.20060506215707.2"><vh>globals</vh></v>
<v t="aum.20060506215707.3" a="E"><vh>class FCPNodeConnection</vh>
-<v t="aum.20060506220237.1"><vh>__init__</vh></v>
+<v t="aum.20060506220237.1" a="V"><vh>__init__</vh></v>
<v t="aum.20060506220237.2"><vh>__del__</vh></v>
<v t="aum.20060506224238" a="E"><vh>High Level Methods</vh>
<v t="aum.20060506231352.1"><vh>genkey</vh></v>
<v t="aum.20060506231352"><vh>get</vh></v>
<v t="aum.20060507003931"><vh>put</vh></v>
<v t="aum.20060511001853"><vh>putdir</vh></v>
+<v t="aum.20060514124642"><vh>refreshPersistentRequests</vh></v>
<v t="aum.20060511205201"><vh>shutdown</vh></v>
</v>
<v t="aum.20060506232639" a="E"><vh>Manager Thread</vh>
@@ -52,8 +53,12 @@
<v t="aum.20060511103841.1"><vh>__init__</vh></v>
<v t="aum.20060511103952"><vh>isDone</vh></v>
<v t="aum.20060511103952.1"><vh>wait</vh></v>
+<v t="aum.20060514134235"><vh>getResult</vh></v>
<v t="aum.20060512181209"><vh>callback</vh></v>
+<v t="aum.20060514162944"><vh>cancel</vh></v>
+<v t="aum.20060514124934"><vh>_appendMsg</vh></v>
<v t="aum.20060512102840"><vh>_putResult</vh></v>
+<v t="aum.20060514164052"><vh>__repr__</vh></v>
</v>
<v t="aum.20060509184020.1" a="E"><vh>util funcs</vh>
<v t="aum.20060509184020.2"><vh>toBool</vh></v>
@@ -84,7 +89,7 @@
</v>
</v>
<v t="aum.20060513073239.2" a="E"><vh>Freesite management</vh>
-<v t="aum.20060511101147"
tnodeList="aum.20060511101147,aum.20060511113333,aum.20060511113333.1,aum.20060511114439,aum.20060511114439.1,aum.20060512150118,aum.20060511114439.2,aum.20060511120059,aum.20060511114604,aum.20060511114604.1,aum.20060511113333.3,aum.20060513071956,aum.20060511130507,aum.20060511120024"><vh>@nosent
sitemgr.py</vh>
+<v t="aum.20060511101147" a="E"
tnodeList="aum.20060511101147,aum.20060511113333,aum.20060511113333.1,aum.20060511114439,aum.20060511114439.1,aum.20060512150118,aum.20060511114439.2,aum.20060511120059,aum.20060511114604,aum.20060511114604.1,aum.20060511113333.3,aum.20060513071956,aum.20060507124316,aum.20060511130507,aum.20060511120024"><vh>@nosent
sitemgr.py</vh>
<v t="aum.20060511113333"><vh>imports</vh></v>
<v t="aum.20060511113333.1"><vh>config</vh></v>
<v t="aum.20060511114439" a="E"><vh>class SiteMgr</vh>
@@ -96,11 +101,17 @@
<v t="aum.20060511114604.1"><vh>saveConfig</vh></v>
<v t="aum.20060511113333.3"><vh>update</vh></v>
<v t="aum.20060513071956"><vh>shutdown</vh></v>
+<v t="aum.20060507124316"><vh>_log</vh></v>
</v>
<v t="aum.20060511130507"><vh>help</vh></v>
<v t="aum.20060511120024"><vh>mainline</vh></v>
</v>
-<v t="aum.20060512140230" tnodeList="aum.20060512140230"><vh>@nosent
updatesites.py</vh></v>
+<v t="aum.20060512140230" a="E"
tnodeList="aum.20060512140230,aum.20060514132715,aum.20060514132715.1,aum.20060514132715.2,aum.20060514132715.3"><vh>@nosent
updatesites.py</vh>
+<v t="aum.20060514132715"><vh>imports</vh></v>
+<v t="aum.20060514132715.1"><vh>globals</vh></v>
+<v t="aum.20060514132715.2"><vh>main</vh></v>
+<v t="aum.20060514132715.3"><vh>mainline</vh></v>
+</v>
<v t="aum.20060513073239.3" tnodeList="aum.20060513073239.3"><vh>@nosent
start.sh</vh></v>
<v t="aum.20060513073239.4" tnodeList="aum.20060513073239.4"><vh>@nosent
stop.sh</vh></v>
</v>
@@ -372,14 +383,32 @@
"""
Create a connection object
- Arguments:
- - clientName - name of client to use with reqs, defaults to random
+ Keyword Arguments:
+ - name - name of client to use with reqs, defaults to random. This
+ is crucial if you plan on making persistent requests
- host - hostname, defaults to defaultFCPHost
- port - port number, defaults to defaultFCPPort
- logfile - a pathname or writable file object, to which log messages
should be written, defaults to stdout
- verbosity - how detailed the log messages should be, defaults to 0
(silence)
+
+ Attributes of interest:
+ - jobs - a dict of currently running jobs (persistent and
nonpersistent).
+ keys are job ids and values are JobTicket objects
+ - persistentJobs - a dict of persistent jobs from this session and
+ previous sessions
+ keys are job ids and values are JobTicket objects
+
+ Notes:
+ - when the connection is created, a 'hello' handshake takes place.
+ After that handshake, the node sends back a list of outstanding
persistent
+ requests left over from the last connection (based on the value of
+ the 'name' keyword passed into this constructor).
+
+ This object then wraps all this info into JobTicket instances and
stores
+ them in the self.persistentJobs dict
+
"""
# grab and save parms
self.name = kw.get('clientName', self._getUniqueId())
@@ -387,7 +416,7 @@
self.port = kw.get('port', defaultFCPPort)
# set up the logger
- logfile = kw.get('logfile', sys.stderr)
+ logfile = kw.get('logfile', sys.stdout)
if not hasattr(logfile, 'write'):
# might be a pathname
if not isinstance(logfile, str):
@@ -405,6 +434,7 @@
# the pending job tickets
self.jobs = {} # keyed by request ID
+ self.persistentJobs = {} # ditto
# queue for incoming client requests
self.clientReqQueue = Queue.Queue()
@@ -597,6 +627,10 @@
Keywords:
- async - whether to return immediately with a job ticket object,
default
False (wait for completion)
+ - persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to
+ be recalled in subsequent FCP sessions
+
- dsnly - whether to only check local datastore
- ignoreds - don't check local datastore
- file - if given, this is a pathname to which to store the retrieved
key
@@ -616,12 +650,16 @@
# format the request
opts = {}
- id = self._getUniqueId()
+ id = kw.pop("id", None)
+ if not id:
+ id = self._getUniqueId()
opts['async'] = kw.pop('async', False)
if kw.has_key('callback'):
opts['callback'] = kw['callback']
+ opts['Persistence'] = kw.pop('persistence', 'connection')
+
file = kw.pop("file", None)
if file:
opts['ReturnType'] = "disk"
@@ -676,7 +714,9 @@
- if status is 'failed' or 'pending', this will contain
a dict containing the response from node
"""
- id = self._getUniqueId()
+ id = kw.pop("id", None)
+ if not id:
+ id = self._getUniqueId()
return self._submitCmd(id, "GenerateSSK", Identifier=id, **kw)
@@ -760,11 +800,15 @@
- mimetype - the mime type, default text/plain
Keywords valid for all modes:
- - maxretries - maximum number of retries, default 3
- - priority - default 1
- async - whether to do the job asynchronously, returning a job ticket
object (default False)
+ - persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to
+ be recalled in subsequent FCP sessions
+ - maxretries - maximum number of retries, default 3
+ - priority - default 1
+
Notes:
- exactly one of 'file', 'data' or 'dir' keyword arguments must be
present
"""
@@ -782,10 +826,16 @@
if kw.has_key('callback'):
opts['callback'] = kw['callback']
+ opts['Persistence'] = kw.pop('persistence', 'connection')
+
opts['URI'] = uri
opts['Metadata.ContentType'] = kw.get("mimetype", "text/plain")
- id = self._getUniqueId()
+
+ id = kw.pop("id", None)
+ if not id:
+ id = self._getUniqueId()
opts['Identifier'] = id
+
opts['Verbosity'] = 0
opts['MaxRetries'] = kw.get("maxretries", 3)
opts['PriorityClass'] = kw.get("priority", 1)
@@ -823,6 +873,7 @@
return
if not msg.endswith("\n"): msg += "\n"
+
self.logfile.write(msg)
self.logfile.flush()
@@ -6145,7 +6196,10 @@
- maxretries - maximum number of retries, default 3
- priority - default 1
- - async - default False - if True, return a job ticket
+ - async - default False - if True, return immediately with a job ticket
+ - persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to
+ be recalled in subsequent FCP sessions
Returns:
- the URI under which the freesite can be retrieved
@@ -6167,7 +6221,9 @@
maxretries = kw.get('maxretries', 3)
priority = kw.get('priority', 1)
- id = self._getUniqueId()
+ id = kw.pop("id", None)
+ if not id:
+ id = self._getUniqueId()
# derive final URI for insert
uriFull = uri + sitename + "/"
@@ -6182,6 +6238,7 @@
"MaxRetries=%s" % maxretries,
"PriorityClass=%s" % priority,
"URI=%s" % uriFull,
+ "Persistence=%s" % kw.get("persistence", "connection"),
]
# scan directory and add its files
@@ -6221,6 +6278,7 @@
rawcmd=fullbuf,
async=kw.get('async', False),
callback=kw.get('callback', False),
+ Persistence=kw.get('Persistence', 'connection'),
)
</t>
@@ -6253,18 +6311,22 @@
@others
</t>
-<t tx="aum.20060511103841.1">def __init__(self, id, cmd, kw):
+<t tx="aum.20060511103841.1">def __init__(self, node, id, cmd, persistent, kw):
"""
You should never instantiate a JobTicket object yourself
"""
+ self.node = node
self.id = id
self.cmd = cmd
+ self.isPersistent = persistent
+ self.kw = kw
+ self.msgs = []
+
callback = kw.pop('callback', None)
if callback:
self.callback = callback
- self.kw = kw
self.lock = threading.Lock()
self.lock.acquire()
@@ -6284,14 +6346,13 @@
"""
self.lock.acquire()
self.lock.release()
- if isinstance(self.result, Exception):
- raise self.result
- else:
- return self.result
-
+ return self.getResult()
</t>
<t tx="aum.20060511113333">import fcp, sys, os, sha, traceback
+# get log level constants
+from fcp import SILENT, FATAL, CRITICAL, ERROR, INFO, DETAIL, DEBUG
+
from ConfigParser import SafeConfigParser
</t>
@@ -6308,6 +6369,8 @@
"""
noSites = True
+ log = self._log
+
conf = self.config
for sitename in conf.sections():
uri = conf.get(sitename, "uri")
@@ -6322,8 +6385,8 @@
h.update(f['hash'])
hashNew = h.hexdigest()
if hashNew != hash:
- print "Updating site %s" % sitename
- print "privatekey=%s" % privatekey
+ log(INFO, "Updating site %s" % sitename)
+ log(INFO, "privatekey=%s" % privatekey)
noSites = False
try:
res = self.node.put(privatekey,
@@ -6331,16 +6394,16 @@
name=sitename,
version=version,
usk=True)
- print "site %s updated successfully" % sitename
+ log(INFO, "site %s updated successfully" % sitename)
except:
traceback.print_exc()
- print "site %s failed to update" % sitename
+ log(ERROR, "site %s failed to update" % sitename)
conf.set(sitename, "hash", hashNew)
self.saveConfig()
if noSites:
- print "No sites needed updating"
+ log(INFO, "No sites needed updating")
</t>
<t tx="aum.20060511114439">class SiteMgr:
@@ -6357,9 +6420,23 @@
Arguments:
- configFile - ini-format file containing site specifications,
defaults to ~/.freesitesrc on *nix or ~/freesites.ini
+
+ Keywords:
+ - logfile - a pathname or open file object to which to write
+ log messages, defaults to sys.stdout
"""
+ # set up the logger
+ logfile = kw.pop('logfile', sys.stderr)
+ if not hasattr(logfile, 'write'):
+ # might be a pathname
+ if not isinstance(logfile, str):
+ raise Exception("Bad logfile, must be pathname or file object")
+ logfile = file(logfile, "a")
+ self.logfile = logfile
+ self.verbosity = kw.get('verbosity', 0)
+
# get a node handle
- self.createNode(**kw)
+ self.createNode(logfile=logfile, **kw)
# determine pathname for sites ini file
if configFile == None:
@@ -6375,8 +6452,8 @@
if not os.path.isfile(configFile):
self.createConfig()
- print "New config file created at %s"
- print "Please edit that file and add your freesites"
+ self._log(CRITICAL, "New config file created at %s" % configFile)
+ self._log(CRITICAL, "Please edit that file and add your freesites")
self.loadConfig()
@@ -6535,15 +6612,23 @@
log = self._log
# find the job this relates to
- id = msg['Identifier']
+ id = msg.get('Identifier', '__global')
+
hdr = msg['header']
job = self.jobs.get(id, None)
-
+
# bail if job not known
if not job:
- log(ERROR, "Received %s for unknown job %s" % (hdr, id))
- return
+ if hdr.startswith("Persistent"):
+ # we have a persistent job from last connection
+ log(INFO, "Got %s from prior session" % hdr)
+ job = JobTicket(self, id, hdr, True, msg)
+ self.jobs[id] = job
+ self.persistentJobs[id] = job
+ else:
+ log(ERROR, "Received %s for unknown job %s" % (hdr, id))
+ return
# action from here depends on what kind of message we got
@@ -6564,6 +6649,7 @@
# handle ClientGet responses
if hdr == 'DataFound':
+ log(INFO, "Got DataFound for URI=%s" % job.kw['URI'])
mimetype = msg['Metadata.ContentType']
if job.kw.has_key('Filename'):
# already stored to disk, done
@@ -6580,9 +6666,21 @@
job._putResult(result)
del self.jobs[id]
return
-
+
# otherwise, we're expecting an AllData and will react to it then
else:
+ # is this a persistent get?
+ if job.kw['ReturnType'] == 'direct' \
+ and job.kw['Persistence'] != 'connection':
+ # gotta poll for request status so we can get our data
+ # FIXME: this is a hack, clean it up
+ log(INFO, "Request was persistent")
+ if not hasattr(job, "gotPersistentDataFound"):
+ job.gotPersistentDataFound = True
+ log(INFO, " --> sending GetRequestStatus")
+ self._txMsg("GetRequestStatus",
+ Identifier=job.kw['Identifier'])
+
job.callback('pending', msg)
job.mimetype = mimetype
return
@@ -6652,18 +6750,24 @@
if hdr == 'PersistentGet':
job.callback('pending', msg)
+ job._appendMsg(msg)
return
if hdr == 'PersistentPut':
job.callback('pending', msg)
+ job._appendMsg(msg)
return
- if hdr == 'EndListPersistentRequests':
+ if hdr == 'PersistentPutDir':
job.callback('pending', msg)
+ job._appendMsg(msg)
return
- if hdr == 'PersistentPutDir':
- job.callback('pending', msg)
+ if hdr == 'EndListPersistentRequests':
+ job._appendMsg(msg)
+ job.callback('successful', job.msgs)
+ job._putResult(job.msgs)
+ del self.jobs[job.id]
return
# -----------------------------
@@ -6690,20 +6794,21 @@
job._putResult(FCPException(msg))
del self.jobs[id]
return
-
</t>
-<t tx="aum.20060511205201.2">def _on_clientReq(self, req):
+<t tx="aum.20060511205201.2">def _on_clientReq(self, job):
"""
- takes an incoming requests from client and transmits it to
+ takes an incoming request job from client and transmits it to
the fcp port, and also registers it so the manager thread
can action responses from the fcp port.
"""
- id = req.id
- cmd = req.cmd
- kw = req.kw
+ id = job.id
+ cmd = job.cmd
+ kw = job.kw
# register the req
- self.jobs[id] = req
+ self.jobs[id] = job
+ if job.kw.get("Persistence", "connection") != "connection":
+ self.persistentJobs[id] = job
# now can send, since we're the only one who will
self._txMsg(cmd, **kw)
@@ -6740,9 +6845,9 @@
object which the client can poll or block on later
"""
async = kw.pop('async', False)
+ persistent = kw.get("Persistence", "connection") != "connection"
+ job = JobTicket(self, id, cmd, persistent, kw)
- job = JobTicket(id, cmd, kw)
-
self.clientReqQueue.put(job)
self._log(DEBUG, "_submitCmd: id=%s cmd=%s kw=%s" % (id, cmd,
str(kw)[:256]))
@@ -6763,68 +6868,10 @@
</t>
<t tx="aum.20060512140230">@first #!/usr/bin/env python
-
-import sys, os, time, commands
-import sitemgr
-
-# time we wait after starting fred, to allow the node to 'warm up'
-# and make connections to its peers
-startupTime = 180
-
-# directory where we have freenet installed,
-# change it as needed
-freenetDir = "/home/david/freenet"
-
-# derive path of freenet pid file, the (non)existence
-# of which is the easiest test of whether the freenet
-# node is running
-pidFile = os.path.join(freenetDir, "Freenet.pid")
-
-# small wrapper which, if freenet isn't already running,
-# starts it prior to inserting then stops it after
-# inserting
-def main(verbose=None):
-
- if verbose == None:
- verbose = ('-v' in sys.argv)
-
- print "--------------------------------------------"
- print "Start of site updating run"
-
- # start freenet and let it warm up, if it's not already running
- if not os.path.isfile(pidFile):
- startingFreenet = True
- os.chdir(freenetDir)
- print "Starting freenet..."
- print os.system("%s/start.sh &" % freenetDir)
- print "Letting node settle for %s seconds..." % startupTime
- time.sleep(startupTime)
- else:
- print "Freenet node is already running!"
- startingFreenet = False
-
- # add verbosity argument if needed
- if verbose:
- kw = {"verbosity" : sitemgr.fcp.DETAIL}
- else:
- kw = {}
-
- # get a site manager object, and perform the actual insertions
- s = sitemgr.SiteMgr(**kw)
- s.update()
- del s
-
- # kill freenet if it was dynamically started
- if startingFreenet:
- print "Waiting %s for inserts to finish..." % startupTime
- time.sleep(startupTime)
- print "Stopping node..."
- os.system("./run.sh stop")
- print "Node stopped"
-
-if __name__ == '__main__':
- main()
-
+"""
+A utility to update freesites from within a cron environment
+"""
+ at others
</t>
<t tx="aum.20060512150118">def __del__(self):
@@ -7111,5 +7158,167 @@
sh("cp -r %s %s" % (tarball, freesiteDir))
</t>
+<t tx="aum.20060514124642">def refreshPersistentRequests(self, **kw):
+ """
+ Sends a ListPersistentRequests to node, to ensure that
+ our records of persistent requests are up to date.
+
+ Since, upon connection, the node sends us a list of all
+ outstanding persistent requests anyway, I can't really
+ see much use for this method. I've only added the method
+ for FCP spec compliance
+ """
+ self._log(INFO, "listPersistentRequests")
+
+ if self.jobs.has_key('__global'):
+ raise Exception("An existing non-identifier job is currently pending")
+
+ # ---------------------------------
+ # format the request
+ opts = {}
+
+ id = '__global'
+ opts['Identifier'] = id
+
+ opts['async'] = kw.pop('async', False)
+ if kw.has_key('callback'):
+ opts['callback'] = kw['callback']
+
+ # ---------------------------------
+ # now enqueue the request
+ return self._submitCmd(id, "ListPersistentRequests", **opts)
+
+</t>
+<t tx="aum.20060514124934">def _appendMsg(self, msg):
+ self.msgs.append(msg)
+
+</t>
+<t tx="aum.20060514132715">import sys, os, time, commands
+import sitemgr
+
+</t>
+<t tx="aum.20060514132715.1"># time we wait after starting fred, to allow the
node to 'warm up'
+# and make connections to its peers
+startupTime = 180
+
+# directory where we have freenet installed,
+# change it as needed
+freenetDir = "/home/david/freenet"
+
+# derive path of freenet pid file, the (non)existence
+# of which is the easiest test of whether the freenet
+# node is running
+freenetPidFile = os.path.join(freenetDir, "Freenet.pid")
+
+logFile = os.path.join(freenetDir, "updatesites.log")
+pidFile = os.path.join(freenetDir, "updatesites.pid")
+
+</t>
+<t tx="aum.20060514132715.2"># small wrapper which, if freenet isn't already
running,
+# starts it prior to inserting then stops it after
+# inserting
+def main(verbose=None):
+
+ if verbose == None:
+ verbose = ('-v' in sys.argv)
+
+ if os.path.isfile(pidFile):
+ print "updatesites.py already running: pid=%s" % file(pidFile).read()
+ sys.exit(1)
+ f = file(pidFile, "w")
+ f.write(str(os.getpid()))
+ f.close()
+
+ try:
+ print "--------------------------------------------"
+ print "Start of site updating run"
+
+ # start freenet and let it warm up, if it's not already running
+ if not os.path.isfile(freenetPidFile):
+ startingFreenet = True
+ os.chdir(freenetDir)
+ print "Starting freenet..."
+ print os.system("%s/start.sh &" % freenetDir)
+ print "Letting node settle for %s seconds..." % startupTime
+ time.sleep(startupTime)
+ else:
+ print "Freenet node is already running!"
+ startingFreenet = False
+
+ # add verbosity argument if needed
+ if verbose:
+ kw = {"verbosity" : sitemgr.fcp.DETAIL}
+ else:
+ kw = {"verbosity" : sitemgr.fcp.INFO}
+
+ # get a site manager object, and perform the actual insertions
+ s = sitemgr.SiteMgr(**kw)
+ s.update()
+ del s
+
+ # kill freenet if it was dynamically started
+ if startingFreenet:
+ print "Waiting %s for inserts to finish..." % startupTime
+ time.sleep(startupTime)
+ print "Stopping node..."
+ os.system("./run.sh stop")
+ print "Node stopped"
+ except:
+ pass
+
+ # can now drop our pidfile
+ os.unlink(pidFile)
+
+</t>
+<t tx="aum.20060514132715.3">if __name__ == '__main__':
+ main()
+
+</t>
+<t tx="aum.20060514134235">def getResult(self):
+ """
+ Returns result of job, or None if job still not complete
+
+ If result is an exception object, then raises it
+ """
+ if isinstance(self.result, Exception):
+ raise self.result
+ else:
+ return self.result
+
+</t>
+<t tx="aum.20060514162944">def cancel(self):
+ """
+ Cancels the job, if it is persistent
+
+ Does nothing if the job was not persistent
+ """
+ if not self.isPersistent:
+ return
+
+ # remove from node's jobs lists
+ try:
+ del self.node.jobs[self.id]
+ except:
+ pass
+ if self.isPersistent:
+ try:
+ del self.node.persistentJobs[self.id]
+ except:
+ pass
+
+ # send the cancel
+ self.node._txMsg("RemovePersistentRequest",
+ Global="false",
+ Identifier=self.id)
+
+</t>
+<t tx="aum.20060514164052">def __repr__(self):
+ if self.kw.has_key("URI"):
+ uri = " URI=%s" % self.kw['URI']
+ else:
+ uri = ""
+ return "<FCP job %s:%s%s" % (self.id, self.cmd, uri)
+
+</t>
</tnodes>
</leo_file>
Modified: trunk/apps/pyFreenet/fcp.py
===================================================================
--- trunk/apps/pyFreenet/fcp.py 2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/fcp.py 2006-05-14 05:23:40 UTC (rev 8697)
@@ -122,14 +122,32 @@
"""
Create a connection object
- Arguments:
- - clientName - name of client to use with reqs, defaults to random
+ Keyword Arguments:
+ - name - name of client to use with reqs, defaults to random. This
+ is crucial if you plan on making persistent requests
- host - hostname, defaults to defaultFCPHost
- port - port number, defaults to defaultFCPPort
- logfile - a pathname or writable file object, to which log
messages
should be written, defaults to stdout
- verbosity - how detailed the log messages should be, defaults to 0
(silence)
+
+ Attributes of interest:
+ - jobs - a dict of currently running jobs (persistent and
nonpersistent).
+ keys are job ids and values are JobTicket objects
+ - persistentJobs - a dict of persistent jobs from this session and
+ previous sessions
+ keys are job ids and values are JobTicket objects
+
+ Notes:
+ - when the connection is created, a 'hello' handshake takes place.
+ After that handshake, the node sends back a list of outstanding
persistent
+ requests left over from the last connection (based on the value
of
+ the 'name' keyword passed into this constructor).
+
+ This object then wraps all this info into JobTicket instances
and stores
+ them in the self.persistentJobs dict
+
"""
# grab and save parms
self.name = kw.get('clientName', self._getUniqueId())
@@ -137,7 +155,7 @@
self.port = kw.get('port', defaultFCPPort)
# set up the logger
- logfile = kw.get('logfile', sys.stderr)
+ logfile = kw.get('logfile', sys.stdout)
if not hasattr(logfile, 'write'):
# might be a pathname
if not isinstance(logfile, str):
@@ -155,6 +173,7 @@
# the pending job tickets
self.jobs = {} # keyed by request ID
+ self.persistentJobs = {} # ditto
# queue for incoming client requests
self.clientReqQueue = Queue.Queue()
@@ -192,7 +211,9 @@
- if status is 'failed' or 'pending', this will contain
a dict containing the response from node
"""
- id = self._getUniqueId()
+ id = kw.pop("id", None)
+ if not id:
+ id = self._getUniqueId()
return self._submitCmd(id, "GenerateSSK", Identifier=id, **kw)
@@ -203,6 +224,10 @@
Keywords:
- async - whether to return immediately with a job ticket object,
default
False (wait for completion)
+ - persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to
+ be recalled in subsequent FCP sessions
+
- dsnly - whether to only check local datastore
- ignoreds - don't check local datastore
- file - if given, this is a pathname to which to store the
retrieved key
@@ -222,12 +247,16 @@
# format the request
opts = {}
- id = self._getUniqueId()
+ id = kw.pop("id", None)
+ if not id:
+ id = self._getUniqueId()
opts['async'] = kw.pop('async', False)
if kw.has_key('callback'):
opts['callback'] = kw['callback']
+ opts['Persistence'] = kw.pop('persistence', 'connection')
+
file = kw.pop("file", None)
if file:
opts['ReturnType'] = "disk"
@@ -291,11 +320,15 @@
- mimetype - the mime type, default text/plain
Keywords valid for all modes:
- - maxretries - maximum number of retries, default 3
- - priority - default 1
- async - whether to do the job asynchronously, returning a job
ticket
object (default False)
+ - persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to
+ be recalled in subsequent FCP sessions
+ - maxretries - maximum number of retries, default 3
+ - priority - default 1
+
Notes:
- exactly one of 'file', 'data' or 'dir' keyword arguments must be
present
"""
@@ -313,10 +346,16 @@
if kw.has_key('callback'):
opts['callback'] = kw['callback']
+ opts['Persistence'] = kw.pop('persistence', 'connection')
+
opts['URI'] = uri
opts['Metadata.ContentType'] = kw.get("mimetype", "text/plain")
- id = self._getUniqueId()
+
+ id = kw.pop("id", None)
+ if not id:
+ id = self._getUniqueId()
opts['Identifier'] = id
+
opts['Verbosity'] = 0
opts['MaxRetries'] = kw.get("maxretries", 3)
opts['PriorityClass'] = kw.get("priority", 1)
@@ -362,7 +401,10 @@
- maxretries - maximum number of retries, default 3
- priority - default 1
- - async - default False - if True, return a job ticket
+ - async - default False - if True, return immediately with a job
ticket
+ - persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to
+ be recalled in subsequent FCP sessions
Returns:
- the URI under which the freesite can be retrieved
@@ -384,7 +426,9 @@
maxretries = kw.get('maxretries', 3)
priority = kw.get('priority', 1)
- id = self._getUniqueId()
+ id = kw.pop("id", None)
+ if not id:
+ id = self._getUniqueId()
# derive final URI for insert
uriFull = uri + sitename + "/"
@@ -399,6 +443,7 @@
"MaxRetries=%s" % maxretries,
"PriorityClass=%s" % priority,
"URI=%s" % uriFull,
+ "Persistence=%s" % kw.get("persistence", "connection"),
]
# scan directory and add its files
@@ -438,8 +483,39 @@
rawcmd=fullbuf,
async=kw.get('async', False),
callback=kw.get('callback', False),
+ Persistence=kw.get('Persistence', 'connection'),
)
+ def refreshPersistentRequests(self, **kw):
+ """
+ Sends a ListPersistentRequests to node, to ensure that
+ our records of persistent requests are up to date.
+
+ Since, upon connection, the node sends us a list of all
+ outstanding persistent requests anyway, I can't really
+ see much use for this method. I've only added the method
+ for FCP spec compliance
+ """
+ self._log(INFO, "listPersistentRequests")
+
+ if self.jobs.has_key('__global'):
+ raise Exception("An existing non-identifier job is currently
pending")
+
+ # ---------------------------------
+ # format the request
+ opts = {}
+
+ id = '__global'
+ opts['Identifier'] = id
+
+ opts['async'] = kw.pop('async', False)
+ if kw.has_key('callback'):
+ opts['callback'] = kw['callback']
+
+ # ---------------------------------
+ # now enqueue the request
+ return self._submitCmd(id, "ListPersistentRequests", **opts)
+
def shutdown(self):
"""
Terminates the manager thread
@@ -536,9 +612,9 @@
object which the client can poll or block on later
"""
async = kw.pop('async', False)
+ persistent = kw.get("Persistence", "connection") != "connection"
+ job = JobTicket(self, id, cmd, persistent, kw)
- job = JobTicket(id, cmd, kw)
-
self.clientReqQueue.put(job)
self._log(DEBUG, "_submitCmd: id=%s cmd=%s kw=%s" % (id, cmd,
str(kw)[:256]))
@@ -558,15 +634,23 @@
log = self._log
# find the job this relates to
- id = msg['Identifier']
+ id = msg.get('Identifier', '__global')
+
hdr = msg['header']
job = self.jobs.get(id, None)
-
+
# bail if job not known
if not job:
- log(ERROR, "Received %s for unknown job %s" % (hdr, id))
- return
+ if hdr.startswith("Persistent"):
+ # we have a persistent job from last connection
+ log(INFO, "Got %s from prior session" % hdr)
+ job = JobTicket(self, id, hdr, True, msg)
+ self.jobs[id] = job
+ self.persistentJobs[id] = job
+ else:
+ log(ERROR, "Received %s for unknown job %s" % (hdr, id))
+ return
# action from here depends on what kind of message we got
@@ -587,6 +671,7 @@
# handle ClientGet responses
if hdr == 'DataFound':
+ log(INFO, "Got DataFound for URI=%s" % job.kw['URI'])
mimetype = msg['Metadata.ContentType']
if job.kw.has_key('Filename'):
# already stored to disk, done
@@ -603,9 +688,21 @@
job._putResult(result)
del self.jobs[id]
return
-
+
# otherwise, we're expecting an AllData and will react to it then
else:
+ # is this a persistent get?
+ if job.kw['ReturnType'] == 'direct' \
+ and job.kw['Persistence'] != 'connection':
+ # gotta poll for request status so we can get our data
+ # FIXME: this is a hack, clean it up
+ log(INFO, "Request was persistent")
+ if not hasattr(job, "gotPersistentDataFound"):
+ job.gotPersistentDataFound = True
+ log(INFO, " --> sending GetRequestStatus")
+ self._txMsg("GetRequestStatus",
+ Identifier=job.kw['Identifier'])
+
job.callback('pending', msg)
job.mimetype = mimetype
return
@@ -675,18 +772,24 @@
if hdr == 'PersistentGet':
job.callback('pending', msg)
+ job._appendMsg(msg)
return
if hdr == 'PersistentPut':
job.callback('pending', msg)
+ job._appendMsg(msg)
return
- if hdr == 'EndListPersistentRequests':
+ if hdr == 'PersistentPutDir':
job.callback('pending', msg)
+ job._appendMsg(msg)
return
- if hdr == 'PersistentPutDir':
- job.callback('pending', msg)
+ if hdr == 'EndListPersistentRequests':
+ job._appendMsg(msg)
+ job.callback('successful', job.msgs)
+ job._putResult(job.msgs)
+ del self.jobs[job.id]
return
# -----------------------------
@@ -713,19 +816,20 @@
job._putResult(FCPException(msg))
del self.jobs[id]
return
-
- def _on_clientReq(self, req):
+ def _on_clientReq(self, job):
"""
- takes an incoming requests from client and transmits it to
+ takes an incoming request job from client and transmits it to
the fcp port, and also registers it so the manager thread
can action responses from the fcp port.
"""
- id = req.id
- cmd = req.cmd
- kw = req.kw
+ id = job.id
+ cmd = job.cmd
+ kw = job.kw
# register the req
- self.jobs[id] = req
+ self.jobs[id] = job
+ if job.kw.get("Persistence", "connection") != "connection":
+ self.persistentJobs[id] = job
# now can send, since we're the only one who will
self._txMsg(cmd, **kw)
@@ -892,6 +996,7 @@
return
if not msg.endswith("\n"): msg += "\n"
+
self.logfile.write(msg)
self.logfile.flush()
@@ -907,18 +1012,22 @@
- poll the job for completion status
- receive a callback upon completion
"""
- def __init__(self, id, cmd, kw):
+ def __init__(self, node, id, cmd, persistent, kw):
"""
You should never instantiate a JobTicket object yourself
"""
+ self.node = node
self.id = id
self.cmd = cmd
+ self.isPersistent = persistent
+ self.kw = kw
+ self.msgs = []
+
callback = kw.pop('callback', None)
if callback:
self.callback = callback
- self.kw = kw
self.lock = threading.Lock()
self.lock.acquire()
@@ -936,6 +1045,13 @@
"""
self.lock.acquire()
self.lock.release()
+ return self.getResult()
+ def getResult(self):
+ """
+ Returns result of job, or None if job still not complete
+
+ If result is an exception object, then raises it
+ """
if isinstance(self.result, Exception):
raise self.result
else:
@@ -948,6 +1064,34 @@
"""
# no action needed
+ def cancel(self):
+ """
+ Cancels the job, if it is persistent
+
+ Does nothing if the job was not persistent
+ """
+ if not self.isPersistent:
+ return
+
+ # remove from node's jobs lists
+ try:
+ del self.node.jobs[self.id]
+ except:
+ pass
+ if self.isPersistent:
+ try:
+ del self.node.persistentJobs[self.id]
+ except:
+ pass
+
+ # send the cancel
+ self.node._txMsg("RemovePersistentRequest",
+ Global="false",
+ Identifier=self.id)
+
+ def _appendMsg(self, msg):
+ self.msgs.append(msg)
+
def _putResult(self, result):
"""
Called by manager thread to indicate job is complete,
@@ -956,6 +1100,13 @@
self.result = result
self.lock.release()
+ def __repr__(self):
+ if self.kw.has_key("URI"):
+ uri = " URI=%s" % self.kw['URI']
+ else:
+ uri = ""
+ return "<FCP job %s:%s%s" % (self.id, self.cmd, uri)
+
def toBool(arg):
try:
Modified:
trunk/apps/pyFreenet/html/private/SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html
===================================================================
---
trunk/apps/pyFreenet/html/private/SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++
trunk/apps/pyFreenet/html/private/SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -309,7 +309,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified:
trunk/apps/pyFreenet/html/private/SimpleXMLRPCServer.SimpleXMLRPCServer-class.html
===================================================================
---
trunk/apps/pyFreenet/html/private/SimpleXMLRPCServer.SimpleXMLRPCServer-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++
trunk/apps/pyFreenet/html/private/SimpleXMLRPCServer.SimpleXMLRPCServer-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -232,7 +232,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/SocketServer.BaseServer-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/SocketServer.BaseServer-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/SocketServer.BaseServer-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -278,7 +278,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/SocketServer.TCPServer-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/SocketServer.TCPServer-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/SocketServer.TCPServer-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -382,7 +382,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified:
trunk/apps/pyFreenet/html/private/SocketServer.ThreadingMixIn-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/SocketServer.ThreadingMixIn-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/SocketServer.ThreadingMixIn-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -157,7 +157,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/exceptions.Exception-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/exceptions.Exception-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/exceptions.Exception-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -86,7 +86,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/fcp-module.html
===================================================================
--- trunk/apps/pyFreenet/html/private/fcp-module.html 2006-05-13 21:59:31 UTC
(rev 8696)
+++ trunk/apps/pyFreenet/html/private/fcp-module.html 2006-05-14 05:23:40 UTC
(rev 8697)
@@ -458,7 +458,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/fcp.ConnectionRefused-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/fcp.ConnectionRefused-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/fcp.ConnectionRefused-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -89,7 +89,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/fcp.FCPException-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/fcp.FCPException-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/fcp.FCPException-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -93,7 +93,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/fcp.FCPGetFailed-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/fcp.FCPGetFailed-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/fcp.FCPGetFailed-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -91,7 +91,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/fcp.FCPNodeConnection-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/fcp.FCPNodeConnection-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/fcp.FCPNodeConnection-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -132,6 +132,12 @@
<br />
Inserts a freesite</td></tr>
<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
+ <td><code><span class="summary-sig"><a
href="fcp.FCPNodeConnection-class.html#refreshPersistentRequests"
class="summary-sig-name"><code>refreshPersistentRequests</code></a>(<span
class=summary-sig-arg>self</span>,
+ <span class="summary-sig-kwarg">**kw</span>)</span></code>
+<br />
+Sends a ListPersistentRequests to node, to ensure that our records of
+persistent requests are up to date.</td></tr>
+<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
<td><code><span class="summary-sig"><a
href="fcp.FCPNodeConnection-class.html#shutdown"
class="summary-sig-name"><code>shutdown</code></a>(<span
class=summary-sig-arg>self</span>)</span></code>
<br />
Terminates the manager thread</td></tr>
@@ -160,9 +166,9 @@
Returns True if a message is coming in from the node</td></tr>
<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
<td><code><span class="summary-sig"><a
href="../private/fcp.FCPNodeConnection-class.html#_on_clientReq"
class="summary-sig-name"><code>_on_clientReq</code></a>(<span
class=summary-sig-arg>self</span>,
- <span class=summary-sig-arg>req</span>)</span></code>
+ <span class=summary-sig-arg>job</span>)</span></code>
<br />
-takes an incoming requests from client and transmits it to the fcp
+takes an incoming request job from client and transmits it to the fcp
port, and also registers it so the manager thread can action responses
from the fcp port.</td></tr>
<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
@@ -203,11 +209,11 @@
<br /><i>(Constructor)</i>
</h3>
<p>Create a connection object</p>
- Arguments:
+ Keyword Arguments:
<ul>
<li>
- clientName - name of client to use with reqs, defaults to
- random
+ name - name of client to use with reqs, defaults to random. This
+ is crucial if you plan on making persistent requests
</li>
<li>
host - hostname, defaults to defaultFCPHost
@@ -224,6 +230,30 @@
0 (silence)
</li>
</ul>
+ Attributes of interest:
+ <ul>
+ <li>
+ jobs - a dict of currently running jobs (persistent and
+ nonpersistent). keys are job ids and values are JobTicket
+ objects
+ </li>
+ <li>
+ persistentJobs - a dict of persistent jobs from this session and
+ previous sessions keys are job ids and values are JobTicket
+ objects
+ </li>
+ </ul>
+ Notes:
+ <ul>
+ <li>
+ <p>when the connection is created, a 'hello' handshake takes place.
+ After that handshake, the node sends back a list of outstanding
+ persistent requests left over from the last connection (based on
+ the value of the 'name' keyword passed into this constructor).</p>
+ This object then wraps all this info into JobTicket instances
+ and stores them in the self.persistentJobs dict
+ </li>
+ </ul>
<dl><dt></dt><dd>
</dd></dl>
</td></tr></table>
@@ -292,6 +322,11 @@
default False (wait for completion)
</li>
<li>
+ persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to be
+ recalled in subsequent FCP sessions
+ </li>
+ <li>
dsnly - whether to only check local datastore
</li>
<li>
@@ -388,15 +423,20 @@
Keywords valid for all modes:
<ul>
<li>
+ async - whether to do the job asynchronously, returning a job
+ ticket object (default False)
+ </li>
+ <li>
+ persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to be
+ recalled in subsequent FCP sessions
+ </li>
+ <li>
maxretries - maximum number of retries, default 3
</li>
<li>
priority - default 1
</li>
- <li>
- async - whether to do the job asynchronously, returning a job
- ticket object (default False)
- </li>
</ul>
Notes:
<ul>
@@ -444,8 +484,14 @@
priority - default 1
</li>
<li>
- async - default False - if True, return a job ticket
+ async - default False - if True, return immediately with a job
+ ticket
</li>
+ <li>
+ persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to be
+ recalled in subsequent FCP sessions
+ </li>
</ul>
Returns:
<ul>
@@ -457,6 +503,20 @@
</dd></dl>
</td></tr></table>
+<a name="refreshPersistentRequests"></a>
+<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
+ <h3><span class="sig"><span
class="sig-name">refreshPersistentRequests</span>(<span
class=sig-arg>self</span>,
+ <span class="sig-kwarg">**kw</span>)</span>
+ </h3>
+ <p>Sends a ListPersistentRequests to node, to ensure that our records
+ of persistent requests are up to date.</p>
+ Since, upon connection, the node sends us a list of all outstanding
+ persistent requests anyway, I can't really see much use for this
+ method. I've only added the method for FCP spec compliance
+ <dl><dt></dt><dd>
+ </dd></dl>
+</td></tr></table>
+
<a name="shutdown"></a>
<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
<h3><span class="sig"><span class="sig-name">shutdown</span>(<span
class=sig-arg>self</span>)</span>
@@ -519,11 +579,11 @@
<a name="_on_clientReq"></a>
<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
<h3><span class="sig"><span class="sig-name">_on_clientReq</span>(<span
class=sig-arg>self</span>,
- <span class=sig-arg>req</span>)</span>
+ <span class=sig-arg>job</span>)</span>
</h3>
- takes an incoming requests from client and transmits it to the fcp
- port, and also registers it so the manager thread can action responses
- from the fcp port.
+ takes an incoming request job from client and transmits it to the
+ fcp port, and also registers it so the manager thread can action
+ responses from the fcp port.
<dl><dt></dt><dd>
</dd></dl>
</td></tr></table>
@@ -650,7 +710,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/fcp.FCPProtocolError-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/fcp.FCPProtocolError-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/fcp.FCPProtocolError-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -91,7 +91,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/fcp.FCPPutFailed-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/fcp.FCPPutFailed-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/fcp.FCPPutFailed-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -91,7 +91,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/fcp.JobTicket-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/fcp.JobTicket-class.html 2006-05-13
21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/fcp.JobTicket-class.html 2006-05-14
05:23:40 UTC (rev 8697)
@@ -67,12 +67,17 @@
<th colspan="2">Method Summary</th></tr>
<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
<td><code><span class="summary-sig"><a
href="fcp.JobTicket-class.html#__init__"
class="summary-sig-name"><code>__init__</code></a>(<span
class=summary-sig-arg>self</span>,
+ <span class=summary-sig-arg>node</span>,
<span class=summary-sig-arg>id</span>,
<span class=summary-sig-arg>cmd</span>,
+ <span class=summary-sig-arg>persistent</span>,
<span class=summary-sig-arg>kw</span>)</span></code>
<br />
You should never instantiate a JobTicket object yourself</td></tr>
<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
+ <td><code><a name="__repr__"></a><span class="summary-sig"><span
class="summary-sig-name">__repr__</span>(<span
class=summary-sig-arg>self</span>)</span></code>
+</td></tr>
+<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
<td><code><span class="summary-sig"><a
href="fcp.JobTicket-class.html#callback"
class="summary-sig-name"><code>callback</code></a>(<span
class=summary-sig-arg>self</span>,
<span class=summary-sig-arg>status</span>,
<span class=summary-sig-arg>value</span>)</span></code>
@@ -80,6 +85,14 @@
This will be replaced in job ticket instances wherever user provides
callback arguments</td></tr>
<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
+ <td><code><span class="summary-sig"><a
href="fcp.JobTicket-class.html#cancel"
class="summary-sig-name"><code>cancel</code></a>(<span
class=summary-sig-arg>self</span>)</span></code>
+<br />
+Cancels the job, if it is persistent</td></tr>
+<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
+ <td><code><span class="summary-sig"><a
href="fcp.JobTicket-class.html#getResult"
class="summary-sig-name"><code>getResult</code></a>(<span
class=summary-sig-arg>self</span>)</span></code>
+<br />
+Returns result of job, or None if job still not complete</td></tr>
+<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
<td><code><span class="summary-sig"><a
href="fcp.JobTicket-class.html#isComplete"
class="summary-sig-name"><code>isComplete</code></a>(<span
class=summary-sig-arg>self</span>)</span></code>
<br />
Returns True if the job has been completed</td></tr>
@@ -89,6 +102,10 @@
<br />
Waits forever (or for a given timeout) for a job to complete</td></tr>
<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
+ <td><code><a name="_appendMsg"></a><span class="summary-sig"><span
class="summary-sig-name">_appendMsg</span>(<span
class=summary-sig-arg>self</span>,
+ <span class=summary-sig-arg>msg</span>)</span></code>
+</td></tr>
+<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
<td><code><span class="summary-sig"><a
href="../private/fcp.JobTicket-class.html#_putResult"
class="summary-sig-name"><code>_putResult</code></a>(<span
class=summary-sig-arg>self</span>,
<span class=summary-sig-arg>result</span>)</span></code>
<br />
@@ -106,8 +123,10 @@
<a name="__init__"></a>
<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
<h3><span class="sig"><span class="sig-name">__init__</span>(<span
class=sig-arg>self</span>,
+ <span class=sig-arg>node</span>,
<span class=sig-arg>id</span>,
<span class=sig-arg>cmd</span>,
+ <span class=sig-arg>persistent</span>,
<span class=sig-arg>kw</span>)</span>
<br /><i>(Constructor)</i>
</h3>
@@ -128,6 +147,26 @@
</dd></dl>
</td></tr></table>
+<a name="cancel"></a>
+<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
+ <h3><span class="sig"><span class="sig-name">cancel</span>(<span
class=sig-arg>self</span>)</span>
+ </h3>
+ <p>Cancels the job, if it is persistent</p>
+ Does nothing if the job was not persistent
+ <dl><dt></dt><dd>
+ </dd></dl>
+</td></tr></table>
+
+<a name="getResult"></a>
+<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
+ <h3><span class="sig"><span class="sig-name">getResult</span>(<span
class=sig-arg>self</span>)</span>
+ </h3>
+ <p>Returns result of job, or None if job still not complete</p>
+ If result is an exception object, then raises it
+ <dl><dt></dt><dd>
+ </dd></dl>
+</td></tr></table>
+
<a name="isComplete"></a>
<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
<h3><span class="sig"><span class="sig-name">isComplete</span>(<span
class=sig-arg>self</span>)</span>
@@ -178,7 +217,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/fcpxmlrpc-module.html
===================================================================
--- trunk/apps/pyFreenet/html/private/fcpxmlrpc-module.html 2006-05-13
21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/fcpxmlrpc-module.html 2006-05-14
05:23:40 UTC (rev 8697)
@@ -185,7 +185,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/fcpxmlrpc.FCPXMLRPCServer-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/fcpxmlrpc.FCPXMLRPCServer-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/fcpxmlrpc.FCPXMLRPCServer-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -294,7 +294,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified:
trunk/apps/pyFreenet/html/private/fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html
===================================================================
---
trunk/apps/pyFreenet/html/private/fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++
trunk/apps/pyFreenet/html/private/fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -142,7 +142,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/help.html
===================================================================
--- trunk/apps/pyFreenet/html/private/help.html 2006-05-13 21:59:31 UTC (rev
8696)
+++ trunk/apps/pyFreenet/html/private/help.html 2006-05-14 05:23:40 UTC (rev
8697)
@@ -225,7 +225,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/indices.html
===================================================================
--- trunk/apps/pyFreenet/html/private/indices.html 2006-05-13 21:59:31 UTC
(rev 8696)
+++ trunk/apps/pyFreenet/html/private/indices.html 2006-05-14 05:23:40 UTC
(rev 8697)
@@ -67,10 +67,14 @@
<td>Method in class <a
href="fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html"><code>fcpxmlrpc.FreenetXMLRPCRequestHandler</code></a></td></tr>
<tr><td width="15%"><a
href="sitemgr.SiteMgr-class.html#__init__"><code>__init__</code></a></td>
<td>Method in class <a
href="sitemgr.SiteMgr-class.html"><code>sitemgr.SiteMgr</code></a></td></tr>
+ <tr><td width="15%"><a
href="fcp.JobTicket-class.html#__repr__"><code>__repr__</code></a></td>
+ <td>Method in class <a
href="fcp.JobTicket-class.html"><code>fcp.JobTicket</code></a></td></tr>
<tr><td width="15%"><a
href="exceptions.Exception-class.html#__str__"><code>__str__</code></a></td>
<td>Method in class <a
href="exceptions.Exception-class.html"><code>exceptions.Exception</code></a></td></tr>
<tr><td width="15%"><a
href="fcp.FCPException-class.html#__str__"><code>__str__</code></a></td>
<td>Method in class <a
href="fcp.FCPException-class.html"><code>fcp.FCPException</code></a></td></tr>
+ <tr><td width="15%"><a
href="../private/fcp.JobTicket-class.html#_appendMsg"><code>_appendMsg</code></a></td>
+ <td>Method in class <a
href="fcp.JobTicket-class.html"><code>fcp.JobTicket</code></a></td></tr>
<tr><td width="15%"><a
href="../private/SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html#_dispatch"><code>_dispatch</code></a></td>
<td>Method in class <a
href="SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html"><code>SimpleXMLRPCServer.SimpleXMLRPCDispatcher</code></a></td></tr>
<tr><td width="15%"><a
href="../private/fcp.FCPNodeConnection-class.html#_getUniqueId"><code>_getUniqueId</code></a></td>
@@ -79,6 +83,8 @@
<td>Method in class <a
href="fcp.FCPNodeConnection-class.html"><code>fcp.FCPNodeConnection</code></a></td></tr>
<tr><td width="15%"><a
href="../private/fcp.FCPNodeConnection-class.html#_log"><code>_log</code></a></td>
<td>Method in class <a
href="fcp.FCPNodeConnection-class.html"><code>fcp.FCPNodeConnection</code></a></td></tr>
+ <tr><td width="15%"><a
href="../private/sitemgr.SiteMgr-class.html#_log"><code>_log</code></a></td>
+ <td>Method in class <a
href="sitemgr.SiteMgr-class.html"><code>sitemgr.SiteMgr</code></a></td></tr>
<tr><td width="15%"><a
href="../private/SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html#_marshaled_dispatch"><code>_marshaled_dispatch</code></a></td>
<td>Method in class <a
href="SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html"><code>SimpleXMLRPCServer.SimpleXMLRPCDispatcher</code></a></td></tr>
<tr><td width="15%"><a
href="../private/fcp.FCPNodeConnection-class.html#_mgrThread"><code>_mgrThread</code></a></td>
@@ -113,6 +119,8 @@
<td>Class in module <code>SocketServer</code></td></tr>
<tr><td width="15%"><a
href="fcp.JobTicket-class.html#callback"><code>callback</code></a></td>
<td>Method in class <a
href="fcp.JobTicket-class.html"><code>fcp.JobTicket</code></a></td></tr>
+ <tr><td width="15%"><a
href="fcp.JobTicket-class.html#cancel"><code>cancel</code></a></td>
+ <td>Method in class <a
href="fcp.JobTicket-class.html"><code>fcp.JobTicket</code></a></td></tr>
<tr><td width="15%"><a
href="../private/SocketServer.BaseServer-class.html#close_request"><code>close_request</code></a></td>
<td>Method in class <a
href="../private/SocketServer.BaseServer-class.html"><code>SocketServer.BaseServer</code></a></td></tr>
<tr><td width="15%"><a
href="SocketServer.TCPServer-class.html#close_request"><code>close_request</code></a></td>
@@ -181,6 +189,8 @@
<td>Method in class <a
href="fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html"><code>fcpxmlrpc.FreenetXMLRPCRequestHandler</code></a></td></tr>
<tr><td width="15%"><a
href="SocketServer.TCPServer-class.html#get_request"><code>get_request</code></a></td>
<td>Method in class <a
href="SocketServer.TCPServer-class.html"><code>SocketServer.TCPServer</code></a></td></tr>
+ <tr><td width="15%"><a
href="fcp.JobTicket-class.html#getResult"><code>getResult</code></a></td>
+ <td>Method in class <a
href="fcp.JobTicket-class.html"><code>fcp.JobTicket</code></a></td></tr>
<tr><td width="15%"><a
href="fcp-module.html#guessMimetype"><code>guessMimetype</code></a></td>
<td>Function in module <a
href="fcp-module.html"><code>fcp</code></a></td></tr>
<tr><td width="15%"><a
href="../private/SocketServer.BaseServer-class.html#handle_error"><code>handle_error</code></a></td>
@@ -219,6 +229,8 @@
<td>Method in class <a
href="fcp.FCPNodeConnection-class.html"><code>fcp.FCPNodeConnection</code></a></td></tr>
<tr><td width="15%"><a
href="fcp-module.html#readdir"><code>readdir</code></a></td>
<td>Function in module <a
href="fcp-module.html"><code>fcp</code></a></td></tr>
+ <tr><td width="15%"><a
href="fcp.FCPNodeConnection-class.html#refreshPersistentRequests"><code>refreshPersistentRequests</code></a></td>
+ <td>Method in class <a
href="fcp.FCPNodeConnection-class.html"><code>fcp.FCPNodeConnection</code></a></td></tr>
<tr><td width="15%"><a
href="SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html#register_function"><code>register_function</code></a></td>
<td>Method in class <a
href="SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html"><code>SimpleXMLRPCServer.SimpleXMLRPCDispatcher</code></a></td></tr>
<tr><td width="15%"><a
href="SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html#register_instance"><code>register_instance</code></a></td>
@@ -322,7 +334,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/sitemgr-module.html
===================================================================
--- trunk/apps/pyFreenet/html/private/sitemgr-module.html 2006-05-13
21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/sitemgr-module.html 2006-05-14
05:23:40 UTC (rev 8697)
@@ -185,7 +185,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/sitemgr.SiteMgr-class.html
===================================================================
--- trunk/apps/pyFreenet/html/private/sitemgr.SiteMgr-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/private/sitemgr.SiteMgr-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -84,6 +84,12 @@
<td><code><span class="summary-sig"><a
href="sitemgr.SiteMgr-class.html#update"
class="summary-sig-name"><code>update</code></a>(<span
class=summary-sig-arg>self</span>)</span></code>
<br />
Insert/update all registered freesites</td></tr>
+<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
+ <td><code><span class="summary-sig"><a
href="../private/sitemgr.SiteMgr-class.html#_log"
class="summary-sig-name"><code>_log</code></a>(<span
class=summary-sig-arg>self</span>,
+ <span class=summary-sig-arg>level</span>,
+ <span class=summary-sig-arg>msg</span>)</span></code>
+<br />
+Logs a message.</td></tr>
</table><br />
@@ -108,6 +114,13 @@
defaults to ~/.freesitesrc on *nix or ~/freesites.ini
</li>
</ul>
+ Keywords:
+ <ul>
+ <li>
+ logfile - a pathname or open file object to which to write log
+ messages, defaults to sys.stdout
+ </li>
+ </ul>
<dl><dt></dt><dd>
</dd></dl>
</td></tr></table>
@@ -148,6 +161,17 @@
<dl><dt></dt><dd>
</dd></dl>
</td></tr></table>
+
+<a name="_log"></a>
+<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
+ <h3><span class="sig"><span class="sig-name">_log</span>(<span
class=sig-arg>self</span>,
+ <span class=sig-arg>level</span>,
+ <span class=sig-arg>msg</span>)</span>
+ </h3>
+ Logs a message. If level > verbosity, don't output it
+ <dl><dt></dt><dd>
+ </dd></dl>
+</td></tr></table>
<br />
@@ -169,7 +193,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/private/trees.html
===================================================================
--- trunk/apps/pyFreenet/html/private/trees.html 2006-05-13 21:59:31 UTC
(rev 8696)
+++ trunk/apps/pyFreenet/html/private/trees.html 2006-05-14 05:23:40 UTC
(rev 8697)
@@ -120,7 +120,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified:
trunk/apps/pyFreenet/html/public/SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html
===================================================================
---
trunk/apps/pyFreenet/html/public/SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++
trunk/apps/pyFreenet/html/public/SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -258,7 +258,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified:
trunk/apps/pyFreenet/html/public/SimpleXMLRPCServer.SimpleXMLRPCServer-class.html
===================================================================
---
trunk/apps/pyFreenet/html/public/SimpleXMLRPCServer.SimpleXMLRPCServer-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++
trunk/apps/pyFreenet/html/public/SimpleXMLRPCServer.SimpleXMLRPCServer-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -186,7 +186,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/SocketServer.TCPServer-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/SocketServer.TCPServer-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/SocketServer.TCPServer-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -348,7 +348,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified:
trunk/apps/pyFreenet/html/public/SocketServer.ThreadingMixIn-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/SocketServer.ThreadingMixIn-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/SocketServer.ThreadingMixIn-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -157,7 +157,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/exceptions.Exception-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/exceptions.Exception-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/exceptions.Exception-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -86,7 +86,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/fcp-module.html
===================================================================
--- trunk/apps/pyFreenet/html/public/fcp-module.html 2006-05-13 21:59:31 UTC
(rev 8696)
+++ trunk/apps/pyFreenet/html/public/fcp-module.html 2006-05-14 05:23:40 UTC
(rev 8697)
@@ -458,7 +458,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/fcp.ConnectionRefused-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/fcp.ConnectionRefused-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/fcp.ConnectionRefused-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -89,7 +89,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/fcp.FCPException-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/fcp.FCPException-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/fcp.FCPException-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -93,7 +93,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/fcp.FCPGetFailed-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/fcp.FCPGetFailed-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/fcp.FCPGetFailed-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -91,7 +91,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/fcp.FCPNodeConnection-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/fcp.FCPNodeConnection-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/fcp.FCPNodeConnection-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -132,6 +132,12 @@
<br />
Inserts a freesite</td></tr>
<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
+ <td><code><span class="summary-sig"><a
href="fcp.FCPNodeConnection-class.html#refreshPersistentRequests"
class="summary-sig-name"><code>refreshPersistentRequests</code></a>(<span
class=summary-sig-arg>self</span>,
+ <span class="summary-sig-kwarg">**kw</span>)</span></code>
+<br />
+Sends a ListPersistentRequests to node, to ensure that our records of
+persistent requests are up to date.</td></tr>
+<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
<td><code><span class="summary-sig"><a
href="fcp.FCPNodeConnection-class.html#shutdown"
class="summary-sig-name"><code>shutdown</code></a>(<span
class=summary-sig-arg>self</span>)</span></code>
<br />
Terminates the manager thread</td></tr>
@@ -151,11 +157,11 @@
<br /><i>(Constructor)</i>
</h3>
<p>Create a connection object</p>
- Arguments:
+ Keyword Arguments:
<ul>
<li>
- clientName - name of client to use with reqs, defaults to
- random
+ name - name of client to use with reqs, defaults to random. This
+ is crucial if you plan on making persistent requests
</li>
<li>
host - hostname, defaults to defaultFCPHost
@@ -172,6 +178,30 @@
0 (silence)
</li>
</ul>
+ Attributes of interest:
+ <ul>
+ <li>
+ jobs - a dict of currently running jobs (persistent and
+ nonpersistent). keys are job ids and values are JobTicket
+ objects
+ </li>
+ <li>
+ persistentJobs - a dict of persistent jobs from this session and
+ previous sessions keys are job ids and values are JobTicket
+ objects
+ </li>
+ </ul>
+ Notes:
+ <ul>
+ <li>
+ <p>when the connection is created, a 'hello' handshake takes place.
+ After that handshake, the node sends back a list of outstanding
+ persistent requests left over from the last connection (based on
+ the value of the 'name' keyword passed into this constructor).</p>
+ This object then wraps all this info into JobTicket instances
+ and stores them in the self.persistentJobs dict
+ </li>
+ </ul>
<dl><dt></dt><dd>
</dd></dl>
</td></tr></table>
@@ -240,6 +270,11 @@
default False (wait for completion)
</li>
<li>
+ persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to be
+ recalled in subsequent FCP sessions
+ </li>
+ <li>
dsnly - whether to only check local datastore
</li>
<li>
@@ -336,15 +371,20 @@
Keywords valid for all modes:
<ul>
<li>
+ async - whether to do the job asynchronously, returning a job
+ ticket object (default False)
+ </li>
+ <li>
+ persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to be
+ recalled in subsequent FCP sessions
+ </li>
+ <li>
maxretries - maximum number of retries, default 3
</li>
<li>
priority - default 1
</li>
- <li>
- async - whether to do the job asynchronously, returning a job
- ticket object (default False)
- </li>
</ul>
Notes:
<ul>
@@ -392,8 +432,14 @@
priority - default 1
</li>
<li>
- async - default False - if True, return a job ticket
+ async - default False - if True, return immediately with a job
+ ticket
</li>
+ <li>
+ persistence - default 'connection' - the kind of persistence for
+ this request. If 'reboot' or 'forever', this job will be able to be
+ recalled in subsequent FCP sessions
+ </li>
</ul>
Returns:
<ul>
@@ -405,6 +451,20 @@
</dd></dl>
</td></tr></table>
+<a name="refreshPersistentRequests"></a>
+<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
+ <h3><span class="sig"><span
class="sig-name">refreshPersistentRequests</span>(<span
class=sig-arg>self</span>,
+ <span class="sig-kwarg">**kw</span>)</span>
+ </h3>
+ <p>Sends a ListPersistentRequests to node, to ensure that our records
+ of persistent requests are up to date.</p>
+ Since, upon connection, the node sends us a list of all outstanding
+ persistent requests anyway, I can't really see much use for this
+ method. I've only added the method for FCP spec compliance
+ <dl><dt></dt><dd>
+ </dd></dl>
+</td></tr></table>
+
<a name="shutdown"></a>
<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
<h3><span class="sig"><span class="sig-name">shutdown</span>(<span
class=sig-arg>self</span>)</span>
@@ -436,7 +496,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/fcp.FCPProtocolError-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/fcp.FCPProtocolError-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/fcp.FCPProtocolError-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -91,7 +91,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/fcp.FCPPutFailed-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/fcp.FCPPutFailed-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/fcp.FCPPutFailed-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -91,7 +91,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/fcp.JobTicket-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/fcp.JobTicket-class.html 2006-05-13
21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/fcp.JobTicket-class.html 2006-05-14
05:23:40 UTC (rev 8697)
@@ -67,12 +67,17 @@
<th colspan="2">Method Summary</th></tr>
<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
<td><code><span class="summary-sig"><a
href="fcp.JobTicket-class.html#__init__"
class="summary-sig-name"><code>__init__</code></a>(<span
class=summary-sig-arg>self</span>,
+ <span class=summary-sig-arg>node</span>,
<span class=summary-sig-arg>id</span>,
<span class=summary-sig-arg>cmd</span>,
+ <span class=summary-sig-arg>persistent</span>,
<span class=summary-sig-arg>kw</span>)</span></code>
<br />
You should never instantiate a JobTicket object yourself</td></tr>
<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
+ <td><code><a name="__repr__"></a><span class="summary-sig"><span
class="summary-sig-name">__repr__</span>(<span
class=summary-sig-arg>self</span>)</span></code>
+</td></tr>
+<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
<td><code><span class="summary-sig"><a
href="fcp.JobTicket-class.html#callback"
class="summary-sig-name"><code>callback</code></a>(<span
class=summary-sig-arg>self</span>,
<span class=summary-sig-arg>status</span>,
<span class=summary-sig-arg>value</span>)</span></code>
@@ -80,6 +85,14 @@
This will be replaced in job ticket instances wherever user provides
callback arguments</td></tr>
<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
+ <td><code><span class="summary-sig"><a
href="fcp.JobTicket-class.html#cancel"
class="summary-sig-name"><code>cancel</code></a>(<span
class=summary-sig-arg>self</span>)</span></code>
+<br />
+Cancels the job, if it is persistent</td></tr>
+<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
+ <td><code><span class="summary-sig"><a
href="fcp.JobTicket-class.html#getResult"
class="summary-sig-name"><code>getResult</code></a>(<span
class=summary-sig-arg>self</span>)</span></code>
+<br />
+Returns result of job, or None if job still not complete</td></tr>
+<tr><td align="right" valign="top" width="15%"><font
size="-1"> </font></td>
<td><code><span class="summary-sig"><a
href="fcp.JobTicket-class.html#isComplete"
class="summary-sig-name"><code>isComplete</code></a>(<span
class=summary-sig-arg>self</span>)</span></code>
<br />
Returns True if the job has been completed</td></tr>
@@ -100,8 +113,10 @@
<a name="__init__"></a>
<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
<h3><span class="sig"><span class="sig-name">__init__</span>(<span
class=sig-arg>self</span>,
+ <span class=sig-arg>node</span>,
<span class=sig-arg>id</span>,
<span class=sig-arg>cmd</span>,
+ <span class=sig-arg>persistent</span>,
<span class=sig-arg>kw</span>)</span>
<br /><i>(Constructor)</i>
</h3>
@@ -122,6 +137,26 @@
</dd></dl>
</td></tr></table>
+<a name="cancel"></a>
+<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
+ <h3><span class="sig"><span class="sig-name">cancel</span>(<span
class=sig-arg>self</span>)</span>
+ </h3>
+ <p>Cancels the job, if it is persistent</p>
+ Does nothing if the job was not persistent
+ <dl><dt></dt><dd>
+ </dd></dl>
+</td></tr></table>
+
+<a name="getResult"></a>
+<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
+ <h3><span class="sig"><span class="sig-name">getResult</span>(<span
class=sig-arg>self</span>)</span>
+ </h3>
+ <p>Returns result of job, or None if job still not complete</p>
+ If result is an exception object, then raises it
+ <dl><dt></dt><dd>
+ </dd></dl>
+</td></tr></table>
+
<a name="isComplete"></a>
<table width="100%" class="func-details" bgcolor="#e0e0e0"><tr><td>
<h3><span class="sig"><span class="sig-name">isComplete</span>(<span
class=sig-arg>self</span>)</span>
@@ -161,7 +196,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/fcpxmlrpc-module.html
===================================================================
--- trunk/apps/pyFreenet/html/public/fcpxmlrpc-module.html 2006-05-13
21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/fcpxmlrpc-module.html 2006-05-14
05:23:40 UTC (rev 8697)
@@ -185,7 +185,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/fcpxmlrpc.FCPXMLRPCServer-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/fcpxmlrpc.FCPXMLRPCServer-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/fcpxmlrpc.FCPXMLRPCServer-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -254,7 +254,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified:
trunk/apps/pyFreenet/html/public/fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html
===================================================================
---
trunk/apps/pyFreenet/html/public/fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html
2006-05-13 21:59:31 UTC (rev 8696)
+++
trunk/apps/pyFreenet/html/public/fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html
2006-05-14 05:23:40 UTC (rev 8697)
@@ -142,7 +142,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/help.html
===================================================================
--- trunk/apps/pyFreenet/html/public/help.html 2006-05-13 21:59:31 UTC (rev
8696)
+++ trunk/apps/pyFreenet/html/public/help.html 2006-05-14 05:23:40 UTC (rev
8697)
@@ -225,7 +225,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/indices.html
===================================================================
--- trunk/apps/pyFreenet/html/public/indices.html 2006-05-13 21:59:31 UTC
(rev 8696)
+++ trunk/apps/pyFreenet/html/public/indices.html 2006-05-14 05:23:40 UTC
(rev 8697)
@@ -65,6 +65,8 @@
<td>Method in class <a
href="fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html"><code>fcpxmlrpc.FreenetXMLRPCRequestHandler</code></a></td></tr>
<tr><td width="15%"><a
href="sitemgr.SiteMgr-class.html#__init__"><code>__init__</code></a></td>
<td>Method in class <a
href="sitemgr.SiteMgr-class.html"><code>sitemgr.SiteMgr</code></a></td></tr>
+ <tr><td width="15%"><a
href="fcp.JobTicket-class.html#__repr__"><code>__repr__</code></a></td>
+ <td>Method in class <a
href="fcp.JobTicket-class.html"><code>fcp.JobTicket</code></a></td></tr>
<tr><td width="15%"><a
href="exceptions.Exception-class.html#__str__"><code>__str__</code></a></td>
<td>Method in class <a
href="exceptions.Exception-class.html"><code>exceptions.Exception</code></a></td></tr>
<tr><td width="15%"><a
href="fcp.FCPException-class.html#__str__"><code>__str__</code></a></td>
@@ -83,6 +85,8 @@
<td>Variable in class <a
href="SocketServer.TCPServer-class.html"><code>SocketServer.TCPServer</code></a></td></tr>
<tr><td width="15%"><a
href="fcp.JobTicket-class.html#callback"><code>callback</code></a></td>
<td>Method in class <a
href="fcp.JobTicket-class.html"><code>fcp.JobTicket</code></a></td></tr>
+ <tr><td width="15%"><a
href="fcp.JobTicket-class.html#cancel"><code>cancel</code></a></td>
+ <td>Method in class <a
href="fcp.JobTicket-class.html"><code>fcp.JobTicket</code></a></td></tr>
<tr><td width="15%"><a
href="SocketServer.TCPServer-class.html#close_request"><code>close_request</code></a></td>
<td>Method in class <a
href="SocketServer.TCPServer-class.html"><code>SocketServer.TCPServer</code></a></td></tr>
<tr><td width="15%"><a
href="fcp.ConnectionRefused-class.html"><code>ConnectionRefused</code></a></td>
@@ -147,6 +151,8 @@
<td>Method in class <a
href="fcpxmlrpc.FreenetXMLRPCRequestHandler-class.html"><code>fcpxmlrpc.FreenetXMLRPCRequestHandler</code></a></td></tr>
<tr><td width="15%"><a
href="SocketServer.TCPServer-class.html#get_request"><code>get_request</code></a></td>
<td>Method in class <a
href="SocketServer.TCPServer-class.html"><code>SocketServer.TCPServer</code></a></td></tr>
+ <tr><td width="15%"><a
href="fcp.JobTicket-class.html#getResult"><code>getResult</code></a></td>
+ <td>Method in class <a
href="fcp.JobTicket-class.html"><code>fcp.JobTicket</code></a></td></tr>
<tr><td width="15%"><a
href="fcp-module.html#guessMimetype"><code>guessMimetype</code></a></td>
<td>Function in module <a
href="fcp-module.html"><code>fcp</code></a></td></tr>
<tr><td width="15%"><a
href="sitemgr-module.html#help"><code>help</code></a></td>
@@ -179,6 +185,8 @@
<td>Method in class <a
href="fcp.FCPNodeConnection-class.html"><code>fcp.FCPNodeConnection</code></a></td></tr>
<tr><td width="15%"><a
href="fcp-module.html#readdir"><code>readdir</code></a></td>
<td>Function in module <a
href="fcp-module.html"><code>fcp</code></a></td></tr>
+ <tr><td width="15%"><a
href="fcp.FCPNodeConnection-class.html#refreshPersistentRequests"><code>refreshPersistentRequests</code></a></td>
+ <td>Method in class <a
href="fcp.FCPNodeConnection-class.html"><code>fcp.FCPNodeConnection</code></a></td></tr>
<tr><td width="15%"><a
href="SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html#register_function"><code>register_function</code></a></td>
<td>Method in class <a
href="SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html"><code>SimpleXMLRPCServer.SimpleXMLRPCDispatcher</code></a></td></tr>
<tr><td width="15%"><a
href="SimpleXMLRPCServer.SimpleXMLRPCDispatcher-class.html#register_instance"><code>register_instance</code></a></td>
@@ -274,7 +282,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/sitemgr-module.html
===================================================================
--- trunk/apps/pyFreenet/html/public/sitemgr-module.html 2006-05-13
21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/sitemgr-module.html 2006-05-14
05:23:40 UTC (rev 8697)
@@ -185,7 +185,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/sitemgr.SiteMgr-class.html
===================================================================
--- trunk/apps/pyFreenet/html/public/sitemgr.SiteMgr-class.html 2006-05-13
21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/html/public/sitemgr.SiteMgr-class.html 2006-05-14
05:23:40 UTC (rev 8697)
@@ -108,6 +108,13 @@
defaults to ~/.freesitesrc on *nix or ~/freesites.ini
</li>
</ul>
+ Keywords:
+ <ul>
+ <li>
+ logfile - a pathname or open file object to which to write log
+ messages, defaults to sys.stdout
+ </li>
+ </ul>
<dl><dt></dt><dd>
</dd></dl>
</td></tr></table>
@@ -169,7 +176,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/html/public/trees.html
===================================================================
--- trunk/apps/pyFreenet/html/public/trees.html 2006-05-13 21:59:31 UTC (rev
8696)
+++ trunk/apps/pyFreenet/html/public/trees.html 2006-05-14 05:23:40 UTC (rev
8697)
@@ -108,7 +108,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
- <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sat May 13
18:31:10 2006</font></td>
+ <td align="left"><font size="-2">Generated by Epydoc 2.1 on Sun May 14
17:22:43 2006</font></td>
<td align="right"><a href="http://epydoc.sourceforge.net"
><font size="-2">http://epydoc.sf.net</font></a></td>
</tr>
Modified: trunk/apps/pyFreenet/sitemgr.py
===================================================================
--- trunk/apps/pyFreenet/sitemgr.py 2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/sitemgr.py 2006-05-14 05:23:40 UTC (rev 8697)
@@ -4,6 +4,9 @@
"""
import fcp, sys, os, sha, traceback
+# get log level constants
+from fcp import SILENT, FATAL, CRITICAL, ERROR, INFO, DETAIL, DEBUG
+
from ConfigParser import SafeConfigParser
fcpHost = "thoth"
@@ -23,9 +26,23 @@
Arguments:
- configFile - ini-format file containing site specifications,
defaults to ~/.freesitesrc on *nix or ~/freesites.ini
+
+ Keywords:
+ - logfile - a pathname or open file object to which to write
+ log messages, defaults to sys.stdout
"""
+ # set up the logger
+ logfile = kw.pop('logfile', sys.stderr)
+ if not hasattr(logfile, 'write'):
+ # might be a pathname
+ if not isinstance(logfile, str):
+ raise Exception("Bad logfile, must be pathname or file object")
+ logfile = file(logfile, "a")
+ self.logfile = logfile
+ self.verbosity = kw.get('verbosity', 0)
+
# get a node handle
- self.createNode(**kw)
+ self.createNode(logfile=logfile, **kw)
# determine pathname for sites ini file
if configFile == None:
@@ -41,8 +58,8 @@
if not os.path.isfile(configFile):
self.createConfig()
- print "New config file created at %s"
- print "Please edit that file and add your freesites"
+ self._log(CRITICAL, "New config file created at %s" % configFile)
+ self._log(CRITICAL, "Please edit that file and add your freesites")
self.loadConfig()
@@ -148,6 +165,8 @@
"""
noSites = True
+ log = self._log
+
conf = self.config
for sitename in conf.sections():
uri = conf.get(sitename, "uri")
@@ -162,8 +181,8 @@
h.update(f['hash'])
hashNew = h.hexdigest()
if hashNew != hash:
- print "Updating site %s" % sitename
- print "privatekey=%s" % privatekey
+ log(INFO, "Updating site %s" % sitename)
+ log(INFO, "privatekey=%s" % privatekey)
noSites = False
try:
res = self.node.put(privatekey,
@@ -171,20 +190,32 @@
name=sitename,
version=version,
usk=True)
- print "site %s updated successfully" % sitename
+ log(INFO, "site %s updated successfully" % sitename)
except:
traceback.print_exc()
- print "site %s failed to update" % sitename
+ log(ERROR, "site %s failed to update" % sitename)
conf.set(sitename, "hash", hashNew)
self.saveConfig()
if noSites:
- print "No sites needed updating"
+ log(INFO, "No sites needed updating")
def shutdown(self):
self.node.shutdown()
+ def _log(self, level, msg):
+ """
+ Logs a message. If level > verbosity, don't output it
+ """
+ if level > self.verbosity:
+ return
+
+ if not msg.endswith("\n"): msg += "\n"
+
+ self.logfile.write(msg)
+ self.logfile.flush()
+
def help():
print "%s: A console-based, cron-able freesite inserter" % sys.argv[0]
Modified: trunk/apps/pyFreenet/updatesites.py
===================================================================
--- trunk/apps/pyFreenet/updatesites.py 2006-05-13 21:59:31 UTC (rev 8696)
+++ trunk/apps/pyFreenet/updatesites.py 2006-05-14 05:23:40 UTC (rev 8697)
@@ -1,5 +1,7 @@
#!/usr/bin/env python
-
+"""
+A utility to update freesites from within a cron environment
+"""
import sys, os, time, commands
import sitemgr
@@ -14,8 +16,11 @@
# derive path of freenet pid file, the (non)existence
# of which is the easiest test of whether the freenet
# node is running
-pidFile = os.path.join(freenetDir, "Freenet.pid")
+freenetPidFile = os.path.join(freenetDir, "Freenet.pid")
+logFile = os.path.join(freenetDir, "updatesites.log")
+pidFile = os.path.join(freenetDir, "updatesites.pid")
+
# small wrapper which, if freenet isn't already running,
# starts it prior to inserting then stops it after
# inserting
@@ -24,40 +29,53 @@
if verbose == None:
verbose = ('-v' in sys.argv)
- print "--------------------------------------------"
- print "Start of site updating run"
+ if os.path.isfile(pidFile):
+ print "updatesites.py already running: pid=%s" % file(pidFile).read()
+ sys.exit(1)
+ f = file(pidFile, "w")
+ f.write(str(os.getpid()))
+ f.close()
+
+ try:
+ print "--------------------------------------------"
+ print "Start of site updating run"
+
+ # start freenet and let it warm up, if it's not already running
+ if not os.path.isfile(freenetPidFile):
+ startingFreenet = True
+ os.chdir(freenetDir)
+ print "Starting freenet..."
+ print os.system("%s/start.sh &" % freenetDir)
+ print "Letting node settle for %s seconds..." % startupTime
+ time.sleep(startupTime)
+ else:
+ print "Freenet node is already running!"
+ startingFreenet = False
- # start freenet and let it warm up, if it's not already running
- if not os.path.isfile(pidFile):
- startingFreenet = True
- os.chdir(freenetDir)
- print "Starting freenet..."
- print os.system("%s/start.sh &" % freenetDir)
- print "Letting node settle for %s seconds..." % startupTime
- time.sleep(startupTime)
- else:
- print "Freenet node is already running!"
- startingFreenet = False
+ # add verbosity argument if needed
+ if verbose:
+ kw = {"verbosity" : sitemgr.fcp.DETAIL}
+ else:
+ kw = {"verbosity" : sitemgr.fcp.INFO}
+
+ # get a site manager object, and perform the actual insertions
+ s = sitemgr.SiteMgr(**kw)
+ s.update()
+ del s
+
+ # kill freenet if it was dynamically started
+ if startingFreenet:
+ print "Waiting %s for inserts to finish..." % startupTime
+ time.sleep(startupTime)
+ print "Stopping node..."
+ os.system("./run.sh stop")
+ print "Node stopped"
+ except:
+ pass
- # add verbosity argument if needed
- if verbose:
- kw = {"verbosity" : sitemgr.fcp.DETAIL}
- else:
- kw = {}
+ # can now drop our pidfile
+ os.unlink(pidFile)
- # get a site manager object, and perform the actual insertions
- s = sitemgr.SiteMgr(**kw)
- s.update()
- del s
-
- # kill freenet if it was dynamically started
- if startingFreenet:
- print "Waiting %s for inserts to finish..." % startupTime
- time.sleep(startupTime)
- print "Stopping node..."
- os.system("./run.sh stop")
- print "Node stopped"
-
if __name__ == '__main__':
main()