Author: aum
Date: 2006-05-16 22:17:57 +0000 (Tue, 16 May 2006)
New Revision: 8723
Modified:
trunk/apps/pyFreenet/INSTALL
trunk/apps/pyFreenet/README
trunk/apps/pyFreenet/code.leo
trunk/apps/pyFreenet/fcpxmlrpc.cgi
trunk/apps/pyFreenet/setup.py
trunk/apps/pyFreenet/tutorial.py
Log:
Modified: trunk/apps/pyFreenet/INSTALL
===================================================================
--- trunk/apps/pyFreenet/INSTALL 2006-05-16 22:15:45 UTC (rev 8722)
+++ trunk/apps/pyFreenet/INSTALL 2006-05-16 22:17:57 UTC (rev 8723)
@@ -12,10 +12,6 @@
- *nix environment
- knowledge of where your freenet software is installed
-We recommend that you copy fcp.py and fcpxmlrpc.py to
-somewhere on your python sys.path
-(eg, /usr/lib/python2.3/site-packages).
+Installation:
+ - become root, then type 'python setup.py install'
-Alternatively, you could just have them in the same
-directory as your application, and import them from there
-
Modified: trunk/apps/pyFreenet/README
===================================================================
--- trunk/apps/pyFreenet/README 2006-05-16 22:15:45 UTC (rev 8722)
+++ trunk/apps/pyFreenet/README 2006-05-16 22:17:57 UTC (rev 8723)
@@ -6,18 +6,25 @@
This PyFCP release includes:
- - core fcp.py library module
+ - python package 'fcp', containing:
+ - 'core' - core FCP node interface
+ - 'sitemgr' - freesite management class
+ - 'xmlrpc' - freenet XML-RPC server
- - fcpxmlrpc.py - a server that exposes the basic FCP primitives
- over an XML-RPC connection
+ - freesitemgr - a console-based freesite management util, which will
+ get installed in your PATH
- - sitemgr.py - a utility for freesite insertion
- - updatesites.py - a cron-able wrapper for sitemgr.py
-
- - start.sh and stop.sh - short scripts to start/stop freenet,
- that can be executed in a plain shell cron environment
-
Refer to the API documentation in the 'html' directory
for detailed information.
+When you install this package (refer INSTALL), you should
+end up with a command 'freesitemgr' on your PATH.
+
+'freesitemgr' is a console-based freesite insertion utility
+which keeps your freesite configs and status in a single
+config file (~/.freesites, unless you specify otherwise).
+
+Invoke 'freesitemgr -h' (or if on windows, 'freesitemgr.py -h')
+and read the options.
+
Modified: trunk/apps/pyFreenet/code.leo
===================================================================
--- trunk/apps/pyFreenet/code.leo 2006-05-16 22:15:45 UTC (rev 8722)
+++ trunk/apps/pyFreenet/code.leo 2006-05-16 22:17:57 UTC (rev 8723)
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<leo_file>
<leo_header file_format="2" tnodes="0" max_tnode_index="8" clone_windows="0"/>
-<globals body_outline_ratio="0.312883435583">
+<globals body_outline_ratio="0.276950043821">
<global_window_position top="51" left="120" height="649" width="1141"/>
<global_log_window_position top="0" left="0" height="0" width="0"/>
</globals>
@@ -9,6 +9,7 @@
<find_panel_settings/>
<vnodes>
<v t="aum.20060506215300" a="E"><vh>PyFCP</vh></v>
+<v t="aum.20060516115529"><vh>TODO</vh></v>
<v t="aum.20060513180215" a="E"><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>
@@ -22,8 +23,9 @@
<v t="aum.20060514232355" a="E"><vh>Tutorials</vh>
<v t="aum.20060514232355.1" tnodeList="aum.20060514232355.1"><vh>@nosent
tutorial.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.20060514223716,aum.20060506231352.1,aum.20060506231352,aum.20060507003931,aum.20060511001853,aum.20060506224238,aum.20060514224855,aum.20060514224919,aum.20060514225725,aum.20060514223936,aum.20060514223822,aum.20060514223845,aum.20060514224020,aum.20060514124642,aum.20060514191601,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.20060513073239" a="E"><vh>Package 'fcp'</vh>
+<v t="aum.20060516141235" tnodeList="aum.20060516141235"><vh>@nosent
__init__.py</vh></v>
+<v t="aum.20060506215707" a="EV"
tnodeList="aum.20060506215707,aum.20060506215707.1,aum.20060506220237,aum.20060506215707.2,aum.20060506215707.3,aum.20060506220237.1,aum.20060506220237.2,aum.20060514223716,aum.20060506231352.1,aum.20060506231352,aum.20060507003931,aum.20060511001853,aum.20060506224238,aum.20060514224855,aum.20060514224919,aum.20060514225725,aum.20060514223936,aum.20060514223822,aum.20060514223845,aum.20060514224020,aum.20060514124642,aum.20060514191601,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
core.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>
@@ -63,7 +65,7 @@
<v t="aum.20060507124316"><vh>_log</vh></v>
</v>
</v>
-<v t="aum.20060511103841" a="E"><vh>class JobTicket</vh>
+<v t="aum.20060511103841"><vh>class JobTicket</vh>
<v t="aum.20060511103841.1"><vh>__init__</vh></v>
<v t="aum.20060511103952"><vh>isComplete</vh></v>
<v t="aum.20060511103952.1"><vh>wait</vh></v>
@@ -74,15 +76,37 @@
<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.1"><vh>util funcs</vh>
<v t="aum.20060509184020.2"><vh>toBool</vh></v>
<v t="aum.20060509224119"><vh>readdir</vh></v>
<v t="aum.20060509224221"><vh>guessMimetype</vh></v>
</v>
</v>
+<v t="aum.20060511101147" a="E"
tnodeList="aum.20060511101147,aum.20060511113333,aum.20060511113333.1,aum.20060516143534,aum.20060511114439,aum.20060511114439.1,aum.20060512150118,aum.20060511114439.2,aum.20060511114604,aum.20060511114604.1,aum.20060511120059,aum.20060516184736,aum.20060516192715,aum.20060516200626,aum.20060516194958,aum.20060516194016,aum.20060511113333.3,aum.20060513071956,aum.20060507124316,aum.20060511130507,aum.20060516142202,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.20060516143534"><vh>globals</vh></v>
+<v t="aum.20060511114439" a="E"><vh>class SiteMgr</vh>
+<v t="aum.20060511114439.1"><vh>__init__</vh></v>
+<v t="aum.20060512150118"><vh>__del__</vh></v>
+<v t="aum.20060511114439.2"><vh>createConfig</vh></v>
+<v t="aum.20060511114604"><vh>loadConfig</vh></v>
+<v t="aum.20060511114604.1"><vh>saveConfig</vh></v>
+<v t="aum.20060511120059"><vh>createNode</vh></v>
+<v t="aum.20060516184736"><vh>hasSite</vh></v>
+<v t="aum.20060516192715"><vh>addSite</vh></v>
+<v t="aum.20060516200626"><vh>removeSite</vh></v>
+<v t="aum.20060516194958"><vh>getSiteInfo</vh></v>
+<v t="aum.20060516194016"><vh>getSiteNames</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.20060513073239.1" a="E"><vh>XML-RPC Server</vh>
-<v t="aum.20060512172707" a="E"
tnodeList="aum.20060512172707,aum.20060512172843,aum.20060512173027,aum.20060512175041,aum.20060512175041.1,aum.20060512175218,aum.20060507155016,aum.20060507162314,aum.20060507162314.2,aum.20060507162314.3,aum.20060507162543.1,aum.20060507195029,aum.20060507163143,aum.20060507154638,aum.20060507195029.1,aum.20060506224545"><vh>@nosent
fcpxmlrpc.py</vh>
+<v t="aum.20060511130507"><vh>help</vh></v>
+<v t="aum.20060516142202"><vh>run</vh></v>
+<v t="aum.20060511120024"><vh>mainline</vh></v>
+</v>
+<v t="aum.20060512172707" a="E"
tnodeList="aum.20060512172707,aum.20060512172843,aum.20060512173027,aum.20060512175041,aum.20060512175041.1,aum.20060512175218,aum.20060507155016,aum.20060507162314,aum.20060507162314.2,aum.20060507162314.3,aum.20060507162543.1,aum.20060507195029,aum.20060507163143,aum.20060507154638,aum.20060507195029.1,aum.20060506224545"><vh>@nosent
xmlrpc.py</vh>
<v t="aum.20060512172843"><vh>imports</vh></v>
<v t="aum.20060512173027"><vh>globals</vh></v>
<v t="aum.20060512175041" a="E"><vh>class FCPXMLRPCServer</vh>
@@ -101,46 +125,55 @@
<v t="aum.20060507195029.1"><vh>main</vh></v>
<v t="aum.20060506224545"><vh>mainline</vh></v>
</v>
-<v t="aum.20060515195621" a="EV"
tnodeList="aum.20060515195621,aum.20060515195621.2,aum.20060515195621.1,aum.20060515195621.3,aum.20060515200029"><vh>@nosent
fcpxmlrpc.cgi</vh>
-<v t="aum.20060515195621.2"><vh>imports </vh></v>
-<v t="aum.20060515195621.1"><vh>configs</vh></v>
-<v t="aum.20060515195621.3"><vh>main</vh></v>
-<v t="aum.20060515200029"><vh>mainline</vh></v>
</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.20060507124316,aum.20060511130507,aum.20060511120024"><vh>@nosent
fcpsitemgr.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>
-<v t="aum.20060511114439.1"><vh>__init__</vh></v>
-<v t="aum.20060512150118"><vh>__del__</vh></v>
-<v t="aum.20060511114439.2"><vh>createConfig</vh></v>
-<v t="aum.20060511120059"><vh>createNode</vh></v>
-<v t="aum.20060511114604"><vh>loadConfig</vh></v>
-<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 t="aum.20060516145032" a="E"
tnodeList="aum.20060516145032,aum.20060516145032.1,aum.20060514132715,aum.20060514132715.1,aum.20060516150511,aum.20060516184736.1,aum.20060516193650,aum.20060516153119,aum.20060516143534.1,aum.20060516144850,aum.20060516143534.2,aum.20060514132715.2,aum.20060514132715.3"><vh>@nosent
freesitemgr.py</vh>
+<v t="aum.20060516145032.1" a="E"><vh>freesitemgr-script</vh>
+<v t="aum.20060514132715"><vh>imports</vh></v>
+<v t="aum.20060514132715.1"><vh>globals</vh></v>
+<v t="aum.20060516150511"><vh>editCreateConfig</vh></v>
+<v t="aum.20060516184736.1"><vh>addSite</vh></v>
+<v t="aum.20060516193650"><vh>removeSite</vh></v>
+<v t="aum.20060516153119"><vh>getYesNo</vh></v>
+<v t="aum.20060516143534.1"><vh>help</vh></v>
+<v t="aum.20060516144850"><vh>usage</vh></v>
+<v t="aum.20060516143534.2"><vh>main</vh></v>
+<v t="aum.20060514132715.2"><vh>main_old</vh></v>
+<v t="aum.20060514132715.3"><vh>mainline</vh></v>
</v>
-<v t="aum.20060511130507"><vh>help</vh></v>
-<v t="aum.20060511120024"><vh>mainline</vh></v>
</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.20060512140230" a="E"
tnodeList="aum.20060512140230,aum.20060516145032.1,aum.20060514132715,aum.20060514132715.1,aum.20060516150511,aum.20060516184736.1,aum.20060516193650,aum.20060516153119,aum.20060516143534.1,aum.20060516144850,aum.20060516143534.2,aum.20060514132715.2,aum.20060514132715.3"><vh>@nosent
freesitemgr</vh>
+<v t="aum.20060516145032.1" a="E"><vh>freesitemgr-script</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.20060516150511"><vh>editCreateConfig</vh></v>
+<v t="aum.20060516184736.1"><vh>addSite</vh></v>
+<v t="aum.20060516193650"><vh>removeSite</vh></v>
+<v t="aum.20060516153119"><vh>getYesNo</vh></v>
+<v t="aum.20060516143534.1"><vh>help</vh></v>
+<v t="aum.20060516144850"><vh>usage</vh></v>
+<v t="aum.20060516143534.2"><vh>main</vh></v>
+<v t="aum.20060514132715.2"><vh>main_old</vh></v>
<v t="aum.20060514132715.3"><vh>mainline</vh></v>
</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>
+<v t="aum.20060513073239.1" a="E"><vh>XML-RPC Server</vh>
+<v t="aum.20060515195621" a="E"
tnodeList="aum.20060515195621,aum.20060515195621.2,aum.20060515195621.1,aum.20060515195621.3,aum.20060515200029"><vh>@nosent
fcpxmlrpc.cgi</vh>
+<v t="aum.20060515195621.2"><vh>imports </vh></v>
+<v t="aum.20060515195621.1"><vh>configs</vh></v>
+<v t="aum.20060515195621.3"><vh>main</vh></v>
+<v t="aum.20060515200029"><vh>mainline</vh></v>
+</v>
+</v>
<v t="aum.20060513073239.5" a="E"><vh>Test files</vh>
<v t="aum.20060511003500" tnodeList="aum.20060511003500"><vh>@file
test.py</vh></v>
<v t="aum.20060512152233" tnodeList="aum.20060512152233"><vh>@file
genkey.py</vh></v>
</v>
-<v t="aum.20060513073239.6" a="E"><vh>Old stuff</vh>
-<v t="aum.20060509223528"><vh>file freenet_old.py</vh>
+<v t="aum.20060513073239.6"><vh>Old stuff</vh>
+<v t="aum.20060509223528" a="E"><vh>file freenet_old.py</vh>
<v t="aum.20060509223528.1"><vh>imports</vh></v>
<v t="aum.20060509223528.2"><vh>constants</vh></v>
<v t="aum.20060509223528.3"><vh>class node</vh></v>
@@ -275,7 +308,7 @@
An implementation of a freenet client library for
FCP v2, offering considerable flexibility.
-Clients should instantiate FCPNodeConnection, then execute
+Clients should instantiate FCPNode, then execute
its methods to perform tasks with FCP.
This module was written by aum, May 2006, released under the GNU Lesser General
@@ -287,6 +320,7 @@
@others
+
</t>
<t tx="aum.20060506215707.1">import sys, os, socket, time, thread
import threading, mimetypes, sha, Queue
@@ -320,13 +354,13 @@
DEBUG = 6
</t>
-<t tx="aum.20060506215707.3">class FCPNodeConnection:
+<t tx="aum.20060506215707.3">class FCPNode:
"""
Represents an interface to a freenet node via its FCP port,
and exposes primitives for the basic genkey, get, put and putdir
operations.
- Only one instance of FCPNodeConnection is needed across an entire
+ Only one instance of FCPNode is needed across an entire
running client application, because its methods are quite thread-safe.
Creating 2 or more instances is a waste of resources.
@@ -375,11 +409,12 @@
class FCPException(Exception):
def __init__(self, info=None):
- print "Creating fcp exception"
+ #print "Creating fcp exception"
if not info:
info = {}
self.info = info
- print "fcp exception created"
+ #print "fcp exception created"
+ Exception.__init__(self, str(info))
def __str__(self):
@@ -433,18 +468,23 @@
self.port = kw.get('port', defaultFCPPort)
# set up the logger
- logfile = kw.get('logfile', sys.stdout)
+ logfile = kw.get('logfile', None) or sys.stdout
if not hasattr(logfile, 'write'):
# might be a pathname
if not isinstance(logfile, str):
- raise Exception("Bad logfile, must be pathname or file object")
+ raise Exception("Bad logfile '%s', must be pathname or file
object" % logfile)
logfile = file(logfile, "a")
self.logfile = logfile
self.verbosity = kw.get('verbosity', 0)
# try to connect to node
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.socket.connect((self.host, self.port))
+ try:
+ self.socket.connect((self.host, self.port))
+ except Exception, e:
+ raise Exception("Failed to connect to %s:%s - %s" % (self.host,
+ self.port,
+ e))
# now do the hello
self._hello()
@@ -534,6 +574,8 @@
"""
log = self._log
+ log(DETAIL, "NODE: ----------------------------")
+
# shorthand, for reading n bytes
def read(n):
if n > 1:
@@ -650,6 +692,8 @@
- Global - default false - if evaluates to true, puts this request
on the global queue. Note the capital G in Global. If you set this,
persistence must be 'reboot' or 'forever'
+ - verbosity - default 0 - sets the Verbosity mask passed in the
+ FCP message
- dsnly - whether to only check local datastore
- ignoreds - don't check local datastore
@@ -685,6 +729,8 @@
else:
opts['Global'] = "false"
+ opts['Verbosity'] = kw.get('verbosity', 0)
+
if opts['Global'] == 'true' and opts['Persistence'] == 'connection':
raise Exception("Global requests must be persistent")
@@ -714,7 +760,6 @@
opts["DSOnly"] = "false"
opts['URI'] = uri
- opts['Verbosity'] = "0"
opts['MaxRetries'] = kw.get("maxretries", 3)
opts['MaxSize'] = kw.get("maxsize", "1000000000000")
@@ -836,6 +881,8 @@
- Global - default false - if evaluates to true, puts this request
on the global queue. Note the capital G in Global. If you set this,
persistence must be 'reboot' or 'forever'
+ - verbosity - default 0 - sets the Verbosity mask passed in the
+ FCP message
- maxretries - maximum number of retries, default 3
- priority - default 1
@@ -874,7 +921,7 @@
id = self._getUniqueId()
opts['Identifier'] = id
- opts['Verbosity'] = 0
+ opts['Verbosity'] = kw.get('verbosity', 0)
opts['MaxRetries'] = kw.get("maxretries", 3)
opts['PriorityClass'] = kw.get("priority", 1)
opts['GetCHKOnly'] = toBool(kw.get("chkonly", "false"))
@@ -946,7 +993,7 @@
Arguments:
- uri - the URI to retrieve
- options - a mapping (dict) object containing various
- options - refer to FCPNodeConnection.get documentation
+ options - refer to FCPNode.get documentation
"""
if options==None:
options = {}
@@ -966,7 +1013,7 @@
Arguments:
- uri - the URI to insert under
- options - a mapping (dict) object containing various options,
- refer to FCPNodeConnection.get documentation
+ refer to FCPNode.get documentation
"""
if options==None:
options = {}
@@ -1015,10 +1062,10 @@
" listen port number for xml-rpc requests, default %s" %
xmlrpcPort,
" --fcphost=",
" set hostname of freenet FCP interface, default %s" \
- % fcp.defaultFCPHost,
+ % core.defaultFCPHost,
" --fcpport=",
" set port number of freenet FCP interface, default %s" \
- % fcp.defaultFCPPort,
+ % core.defaultFCPPort,
])
sys.exit(ret)
@@ -1030,11 +1077,11 @@
"""
import getopt
- opts = {'verbosity': fcp.INFO,
+ opts = {'verbosity': core.INFO,
'host':xmlrpcHost,
'port':xmlrpcPort,
- 'fcpHost':fcp.defaultFCPHost,
- 'fcpPort':fcp.defaultFCPPort,
+ 'fcpHost':core.defaultFCPHost,
+ 'fcpPort':core.defaultFCPPort,
}
try:
@@ -1073,7 +1120,7 @@
#print "Verbosity=%s" % opts['verbosity']
- if opts['verbosity'] >= fcp.INFO:
+ if opts['verbosity'] >= core.INFO:
print "Launching Freenet XML-RPC server"
print "Listening on %s:%s" % (opts['host'], opts['port'])
print "Talking to Freenet FCP at %s:%s" % (opts['fcpHost'],
opts['fcpPort'])
@@ -6252,6 +6299,8 @@
- Global - default false - if evaluates to true, puts this request
on the global queue. Note the capital G in Global. If you set this,
persistence must be 'reboot' or 'forever'
+ - verbosity - default 0 - sets the Verbosity mask passed in the
+ FCP message
Returns:
- the URI under which the freesite can be retrieved
@@ -6286,7 +6335,7 @@
# build a big command buffer
msgLines = ["ClientPutComplexDir",
"Identifier=%s" % id,
- "Verbosity=0",
+ "Verbosity=%s" % kw.get('verbosity', 0),
"MaxRetries=%s" % maxretries,
"PriorityClass=%s" % priority,
"URI=%s" % uriFull,
@@ -6342,7 +6391,7 @@
</t>
<t tx="aum.20060511003500">from fcp import *
-n = FCPNodeConnection(host="thoth", verbosity=DETAIL)
+n = FCPNode(host="thoth", verbosity=DETAIL)
pub, priv = n.genkey()
@@ -6429,17 +6478,19 @@
self.lock.release()
return self.getResult()
</t>
-<t tx="aum.20060511113333">import fcp, sys, os, sha, traceback
+<t tx="aum.20060511113333"># standard lib imports
+import sys, os, sha, traceback, getopt
+from ConfigParser import SafeConfigParser
-# get log level constants
-from fcp import SILENT, FATAL, CRITICAL, ERROR, INFO, DETAIL, DEBUG
+# fcp imports
+import core
+from core import FCPNode
+from core import SILENT, FATAL, CRITICAL, ERROR, INFO, DETAIL, DEBUG
-from ConfigParser import SafeConfigParser
-
</t>
-<t tx="aum.20060511113333.1">fcpHost = "thoth"
-fcpPort = None
-#verbosity = fcp.DETAIL
+<t tx="aum.20060511113333.1">fcpHost = core.defaultFCPHost
+fcpPort = core.defaultFCPPort
+#verbosity = DETAIL
verbosity = None
logfile = None
@@ -6452,15 +6503,40 @@
log = self._log
+ kw = self.kw
+
+ # get a node handle
+ self.createNode(logfile=logfile, **kw)
+
conf = self.config
for sitename in conf.sections():
+
+ # fill in any incomplete details with site entries
+ needToSave = False
+ if not conf.has_option(sitename, "hash"):
+ needToSave = True
+ conf.set(sitename, "hash", "")
+
+ if not conf.has_option(sitename, "version"):
+ needToSave = True
+ conf.set(sitename, "version", "0")
+
+ if not conf.has_option(sitename, "privatekey"):
+ needToSave = True
+ pub, priv = self.node.genkey()
+ uri = pub.replace("SSK@", "USK@") + sitename + "/0"
+ conf.set(sitename, "uri", uri)
+ conf.set(sitename, "privatekey", priv)
+ if needToSave:
+ self.saveConfig()
+
uri = conf.get(sitename, "uri")
dir = conf.get(sitename, "dir")
hash = conf.get(sitename, "hash")
version = conf.get(sitename, "version")
privatekey = conf.get(sitename, "privatekey")
- files = fcp.readdir(dir, gethashes=True)
+ files = core.readdir(dir, gethashes=True)
h = sha.new()
for f in files:
h.update(f['hash'])
@@ -6474,7 +6550,8 @@
dir=dir,
name=sitename,
version=version,
- usk=True)
+ usk=True,
+ verbosity=self.Verbosity)
log(INFO, "site %s updated successfully" % sitename)
except:
traceback.print_exc()
@@ -6494,17 +6571,20 @@
@others
</t>
-<t tx="aum.20060511114439.1">def __init__(self, configFile=None, **kw):
+<t tx="aum.20060511114439.1">def __init__(self, **kw):
"""
Creates a site manager object.
Arguments:
- - configFile - ini-format file containing site specifications,
- defaults to ~/.freesitesrc on *nix or ~/freesites.ini
Keywords:
+ - configfile - pathname of where config file lives, defaults
+ to ~/.freesites (or ~/freesites.ini on doze)
- logfile - a pathname or open file object to which to write
log messages, defaults to sys.stdout
+ - verbosity - logging verbosity level, refer to fcp.core
+ - fcphost - hostname of fcp, default fcp.core.defaultFCPHost
+ - fcpport - port number of fcp, default fcp.core.defaultFCPPort
"""
# set up the logger
logfile = kw.pop('logfile', sys.stderr)
@@ -6515,11 +6595,17 @@
logfile = file(logfile, "a")
self.logfile = logfile
self.verbosity = kw.get('verbosity', 0)
+ self.Verbosity = kw.get('Verbosity', 0)
- # get a node handle
- self.createNode(logfile=logfile, **kw)
+ self.fcpHost = fcpHost
+ self.fcpPort = fcpPort
+ self.kw = kw
+
+ self.node = None
+
# determine pathname for sites ini file
+ configFile = kw.get('configfile', None)
if configFile == None:
isDoze = sys.platform.lower().startswith("win")
homedir = os.path.expanduser("~")
@@ -6531,29 +6617,39 @@
self.configFile = configFile
- if not os.path.isfile(configFile):
- self.createConfig()
- self._log(CRITICAL, "New config file created at %s" % configFile)
- self._log(CRITICAL, "Please edit that file and add your freesites")
-
- self.loadConfig()
+ if os.path.isfile(configFile):
+ self.loadConfig()
+ else:
+ self.config = SafeConfigParser()
+ self.config.set("DEFAULT", "fcphost", self.fcpHost)
+ self.config.set("DEFAULT", "fcpport", self.fcpPort)
</t>
-<t tx="aum.20060511114439.2">def createConfig(self):
+<t tx="aum.20060511114439.2">def createConfig(self, **kw):
"""
Creates a whole new config
"""
+ #if not kw.has_key("fcpHost"):
+ # kw['fcpHost'] = core.defaultFCPHost
+ #if not kw.has_key("fcpPort"):
+ # kw['fcpPort'] = core.defaultFCPPort
+
+ #self.fcpHost = kw['fcpHost']
+ #self.fcpPort = kw['fcpPort']
+
file(self.configFile, "w").write("\n".join([
"# config file for freesites",
"# being inserted via pyfcp 'sitemgr' utility",
"#",
"# edit this file with care",
"",
- "# ignore this, it's not used",
- "[DEFAULT]",
+# "# FCP access details",
+# "[DEFAULT]",
+# "fcpHost=%s" % self.fcpHost,
+# "fcpPort=%s" % self.fcpPort,
"",
- "# for each new site, just take a copy of the following",
- "# 2 lines, uncomment them and change as needed",
+ "# for each new site, just copy the following two lines",
+ "# to the end of this file, uncomment them, change as needed",
"",
"# [mysite]",
"# dir=/path/to/mysite/directory",
@@ -6570,33 +6666,22 @@
conf = self.config = SafeConfigParser()
conf.read(self.configFile)
- needToSave = False
+ try:
+ self.fcpHost = conf.get("DEFAULT", "fcphost")
+ except:
+ conf.set("DEFAULT", "fcphost", self.fcpHost)
+ try:
+ self.fcpPort = conf.getint("DEFAULT", "fcpport")
+ except:
+ conf.set("DEFAULT", "fcpport", self.fcpPort)
+
- # fill in any incomplete details with site entries
for sitename in conf.sections():
if not conf.has_option(sitename, "dir"):
raise Exception("Config file error: No directory specified for
site '%s'" \
% sitename)
- if not conf.has_option(sitename, "hash"):
- needToSave = True
- conf.set(sitename, "hash", "")
-
- if not conf.has_option(sitename, "version"):
- needToSave = True
- conf.set(sitename, "version", "0")
-
- if not conf.has_option(sitename, "privatekey"):
- needToSave = True
- pub, priv = self.node.genkey()
- uri = pub.replace("SSK@", "USK@") + sitename + "/0"
- conf.set(sitename, "uri", uri)
- conf.set(sitename, "privatekey", priv)
-
- if needToSave:
- self.saveConfig()
-
</t>
<t tx="aum.20060511114604.1">def saveConfig(self):
"""
@@ -6604,6 +6689,9 @@
"""
self.createConfig()
+ self.config.set("DEFAULT", "fcphost", self.fcpHost)
+ self.config.set("DEFAULT", "fcpport", self.fcpPort)
+
f = file(self.configFile, "a")
self.config.write(f)
@@ -6617,7 +6705,7 @@
help()
if '-v' in sys.argv:
- verbosity = fcp.DETAIL
+ verbosity = core.DETAIL
s = SiteMgr()
s.update()
@@ -6625,25 +6713,51 @@
</t>
<t tx="aum.20060511120059">def createNode(self, **kw):
+ """
+ Creates and saves a node object, if one not already present
+ """
+ if isinstance(self.node, FCPNode):
+ return
- #kw = {}
+ opts = {}
- if fcpHost and not kw.has_key("fcpHost"):
- kw['host'] = fcpHost
- if fcpPort and not kw.has_key("fcpPort"):
- kw['port'] = fcpPort
- if verbosity and not kw.has_key("verbosity"):
- kw['verbosity'] = verbosity
- if logfile and not kw.has_key("logfile"):
- kw['logfile'] = logfile
+ if kw.has_key("fcpHost"):
+ opts['host'] = kw['fcpHost']
+ else:
+ opts['host'] = self.fcpHost
- #print kw
+ if kw.has_key("fcpPort"):
+ opts['port'] = self.fcpPort
+ else:
+ opts['port'] = self.fcpPort
+
+ if kw.has_key("verbosity"):
+ opts['verbosity'] = kw['verbosity']
+ else:
+ opts['verbosity'] = core.INFO
+
+ opts['Verbosity'] = self.Verbosity
+
+ if kw.has_key("logfile"):
+ opts['logfile'] = kw['logfile'] or sys.stdout
+ else:
+ opts['logfile'] = sys.stdout
+
+ opts['name'] = 'freesitemgr'
+
+ print "createNode:"
+ print " kw=%s"% kw
+ print " opts=%s" % opts
+ #sys.exit(0)
- self.node = fcp.FCPNodeConnection(**kw)
+ self.node = FCPNode(**opts)
</t>
<t tx="aum.20060511130507">def help():
+
print "%s: A console-based, cron-able freesite inserter" % sys.argv[0]
+ print "Usage: %s" % sys.argv[0]
+
print "This utility inserts/updates freesites, and is"
print "driven by a simple config file."
print
@@ -6945,9 +7059,6 @@
</t>
<t tx="aum.20060512140230">@first #!/usr/bin/env python
-"""
-A utility to update freesites from within a cron environment
-"""
@others
</t>
<t tx="aum.20060512150118">def __del__(self):
@@ -6967,7 +7078,7 @@
import fcp
-n = fcp.FCPNodeConnection(host="thoth", verbosity=fcp.ERROR)
+n = fcp.FCPNode(host="thoth", verbosity=fcp.ERROR)
pub, priv = n.genkey()
print pub
print priv
@@ -6988,11 +7099,13 @@
@others
</t>
-<t tx="aum.20060512172843">import sys
+<t tx="aum.20060512172843"># standard library imports
+import sys
from SimpleXMLRPCServer import SimpleXMLRPCServer
from SocketServer import ThreadingMixIn
-import fcp
+# FCP imports
+import core
</t>
<t tx="aum.20060512173027"># where to listen, for the xml-rpc server
@@ -7026,11 +7139,11 @@
SimpleXMLRPCServer.__init__(self, (host, port))
# create the fcp node interface
- fcpHost = kw.get('fcpHost', fcp.defaultFCPHost)
- fcpPort = kw.get('fcpPort', fcp.defaultFCPPort)
- verbosity = kw.get('verbosity', fcp.SILENT)
+ fcpHost = kw.get('fcpHost', core.defaultFCPHost)
+ fcpPort = kw.get('fcpPort', core.defaultFCPPort)
+ verbosity = kw.get('verbosity', core.SILENT)
- node = self.node = fcp.FCPNodeConnection(host=fcpHost,
+ node = self.node = core.FCPNode(host=fcpHost,
port=fcpPort,
verbosity=verbosity,
)
@@ -7066,7 +7179,8 @@
self.node.shutdown()
</t>
-<t tx="aum.20060513073239"></t>
+<t tx="aum.20060513073239">@path fcp
+</t>
<t tx="aum.20060513073239.1"></t>
<t tx="aum.20060513073239.2"></t>
<t tx="aum.20060513073239.3">@first #!/bin/bash
@@ -7113,21 +7227,28 @@
This PyFCP release includes:
- - core fcp.py library module
+ - python package 'fcp', containing:
+ - 'core' - core FCP node interface
+ - 'sitemgr' - freesite management class
+ - 'xmlrpc' - freenet XML-RPC server
- - fcpxmlrpc.py - a server that exposes the basic FCP primitives
- over an XML-RPC connection
+ - freesitemgr - a console-based freesite management util, which will
+ get installed in your PATH
- - sitemgr.py - a utility for freesite insertion
- - updatesites.py - a cron-able wrapper for sitemgr.py
-
- - start.sh and stop.sh - short scripts to start/stop freenet,
- that can be executed in a plain shell cron environment
-
Refer to the API documentation in the 'html' directory
for detailed information.
+When you install this package (refer INSTALL), you should
+end up with a command 'freesitemgr' on your PATH.
+
+'freesitemgr' is a console-based freesite insertion utility
+which keeps your freesite configs and status in a single
+config file (~/.freesites, unless you specify otherwise).
+
+Invoke 'freesitemgr -h' (or if on windows, 'freesitemgr.py -h')
+and read the options.
+
</t>
<t tx="aum.20060513180716">@nocolor
INSTALL file for PyFCP
@@ -7144,13 +7265,9 @@
- *nix environment
- knowledge of where your freenet software is installed
-We recommend that you copy fcp.py and fcpxmlrpc.py to
-somewhere on your python sys.path
-(eg, /usr/lib/python2.3/site-packages).
+Installation:
+ - become root, then type 'python setup.py install'
-Alternatively, you could just have them in the same
-directory as your application, and import them from there
-
</t>
<t tx="aum.20060513180932">@nocolor
The PyFCP modules and scripts were written
@@ -7196,12 +7313,15 @@
import sys, os, commands
-version = "0.1"
+version = "0.1.2"
+
releaseDir = "pyfcp-%s" % version
tarball = releaseDir + ".tar.gz"
freesiteDir = "/thoth/home/david/freenet/mysites/pyfcp"
+thothTestDir = "/thoth/home/david/freenet/pyfcp"
+
file("release.log", "w").close()
def sh(cmd):
@@ -7213,10 +7333,11 @@
files = [
"AUTHORS", "README", "INSTALL", "COPYING", "BUGS", "CHANGELOG",
- "fcp.py",
+ "setup.py",
+ "fcp",
+ "freesitemgr", "freesitemgr.py",
"tutorial.py",
- "fcpxmlrpc.py", "sitemgr.py",
- "updatesites.py", "start.sh", "stop.sh",
+ "fcpxmlrpc.cgi",
"html",
]
@@ -7225,7 +7346,8 @@
os.mkdir(releaseDir)
print "Generate doco..."
-sh("epydoc -n \"PyFCP API Manual\" -o html fcp.py sitemgr.py fcpxmlrpc.py")
+#sh("rm -rf html/*")
+sh("epydoc -n \"PyFCP API Manual\" -o html fcp")
print "Copying release files..."
sh("cp -r %s %s" % (" ".join(files), releaseDir))
@@ -7236,6 +7358,10 @@
print "Releasing tarball to freesite..."
sh("cp -r %s %s" % (tarball, freesiteDir))
+print "Copying release files to thoth test dir..."
+sh("rm -rf %s/*" % thothTestDir)
+sh("cp -r %s/* %s" % (releaseDir, thothTestDir))
+
</t>
<t tx="aum.20060514124642">def refreshPersistentRequests(self, **kw):
"""
@@ -7272,31 +7398,43 @@
self.msgs.append(msg)
</t>
-<t tx="aum.20060514132715">import sys, os, time, commands, traceback
-import fcpsitemgr
+<t tx="aum.20060514132715">import sys, os, time, commands, traceback, getopt
+import fcp.core
+from fcp.sitemgr import SiteMgr
+
</t>
-<t tx="aum.20060514132715.1"># time we wait after starting fred, to allow the
node to 'warm up'
+<t tx="aum.20060514132715.1">progname = sys.argv[0]
+
+# 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"
+#freenetDir = "/home/david/freenet"
+homeDir = os.path.expanduser("~")
+
# 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")
+#freenetPidFile = os.path.join(freenetDir, "Freenet.pid")
-logFile = os.path.join(freenetDir, "updatesites.log")
-pidFile = os.path.join(freenetDir, "updatesites.pid")
+logFile = os.path.join(homeDir, "updatesites.log")
+pidFile = os.path.join(homeDir, "updatesites.pid")
+if sys.platform.startswith("win"):
+ confFileName = "freesites.ini"
+else:
+ confFileName = ".freesites"
+confFile = os.path.join(homeDir, confFileName)
+
</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):
+def main_old(verbose=None):
os.chdir(freenetDir)
@@ -7310,7 +7448,9 @@
f.write(str(os.getpid()))
f.close()
- logfile = file(logFile, "w")
+ #logfile = file(logFile, "w")
+ logfile = sys.stdout
+
logfile.write("----------------------\n")
logfile.write(time.asctime() + "\n")
@@ -7333,13 +7473,14 @@
# add verbosity argument if needed
if verbose:
- kw = {"verbosity" : sitemgr.fcp.DETAIL}
+ kw = {"verbosity" : fcp.DETAIL}
+ kw['Verbosity'] = 65535
else:
- kw = {"verbosity" : sitemgr.fcp.INFO}
+ kw = {"verbosity" : fcp.INFO}
# get a site manager object, and perform the actual insertions
print "Creating SiteMgr object"
- s = sitemgr.SiteMgr(logfile=logfile, **kw)
+ s = fcp.sitemgr.SiteMgr(logfile=logfile, **kw)
print "Starting updates"
try:
s.update()
@@ -7496,7 +7637,6 @@
import fcp
-
# ------------------------------------------
# state where our FCP port is
@@ -7509,7 +7649,7 @@
# we're setting a relatively high verbosity so you
# can see the traffic
-node = fcp.FCPNodeConnection(host=fcpHost, verbosity=fcp.DETAIL)
+node = fcp.FCPNode(host=fcpHost, verbosity=fcp.DETAIL)
# -----------------------------------------------
@@ -7590,7 +7730,13 @@
<t tx="aum.20060515193950">"""
distutils installation script for pyfcp
"""
+import sys
+if sys.platform.lower().startswith("win"):
+ freesitemgrScript = "freesitemgr.py"
+else:
+ freesitemgrScript = "freesitemgr"
+
from distutils.core import setup
setup(name="PyFCP",
version="0.1",
@@ -7599,9 +7745,12 @@
author_email="david at freenet.org.nz",
url ="http://127.0.0.1:8888/USK at
yhAqcwNdN1y1eyRQQwZfhu4dpn-tPNlZMeNRZxEg1bM,zBUodpjtZdJvzWmwYKgr8jO5V-yKxZvetsr8tADNg2U,AQABAAE/pyfcp/0",
- py_modules=["fcp", "fcpxmlrpc", "fcpsitemgr",
- ]
+ packages = ['fcp'],
+ scripts = [freesitemgrScript],
+
+# py_modules=["fcp", "fcpxmlrpc", "fcpsitemgr"]
+
)
</t>
@@ -7621,7 +7770,7 @@
fcpPort = 9481
# verbosity for logging
-verbosity = fcp.DETAIL
+verbosity = core.DETAIL
# where the logfile is
logfile = "/tmp/fcpxmlrpc.log"
@@ -7630,13 +7779,13 @@
<t tx="aum.20060515195621.2">from SimpleXMLRPCServer import
CGIXMLRPCRequestHandler
import fcp
-from fcpxmlrpc import FreenetXMLRPCRequestHandler
+from fcp.xmlrpc import FreenetXMLRPCRequestHandler
</t>
<t tx="aum.20060515195621.3">def main():
# create the fcp node interface
- node = fcp.FCPNodeConnection(host=fcpHost,
+ node = fcp.FCPNode(host=fcpHost,
port=fcpPort,
verbosity=verbosity,
logfile=logfile,
@@ -7662,5 +7811,409 @@
main()
</t>
+<t tx="aum.20060516115529">@nocolor
+
+* convert everything to a package 'fcp'
+
+ * create __init__.py, add __all__
+
+* stick a main() with getopt() into fcp.sitemgr
+
+ * options:
+ -c - create initial ~/.freesites, prompt to overwrite, prompt for:
+ - fcp host/port
+
+ -a - add a freesite
+ -u - update one or all freesites
+ -l - list freesites
+ -d - delete a freesite
+ -h - help
+
+ * no options - ask to run with -h
+
+* add a script which runs fcp.sitemgr
+
+* add a script which runs xmlrpc server
+
+* update setup.py
+
+</t>
+<t tx="aum.20060516141235">from core import FCPNode, JobTicket
+from core import ConnectionRefused, FCPException, FCPGetFailed, \
+ FCPPutFailed, FCPProtocolError
+
+from core import SILENT, FATAL, CRITICAL, ERROR, INFO, DETAIL, DEBUG
+
+
+__all__ = ['core', 'sitemgr', 'xmlrpc',
+ 'FCPNode', 'JobTicket',
+ 'ConnectionRefused', 'FCPException', 'FCPPutFailed',
+ 'FCPProtocolError',
+ ]
+
+
+</t>
+<t tx="aum.20060516142202">def run():
+ """
+ Runs the sitemgr in a console environment
+ """
+ import getopt
+
+ opts = {'verbosity': core.INFO,
+ 'host':xmlrpcHost,
+ 'port':xmlrpcPort,
+ 'fcpHost':core.defaultFCPHost,
+ 'fcpPort':core.defaultFCPPort,
+ }
+
+ try:
+ cmdopts, args = getopt.getopt(sys.argv[1:],
+ "?hv:",
+ ["help", "verbosity=", "host=", "port=",
+ "fcphost=", "fcpport="])
+ except getopt.GetoptError:
+ # print help information and exit:
+ usage()
+ sys.exit(2)
+ output = None
+ verbose = False
+ #print cmdopts
+ for o, a in cmdopts:
+ if o in ("-h", "--help"):
+ usage(ret=0)
+ elif o == "--host":
+ opts['host'] = a
+ elif o == "--port":
+ opts['port'] = int(a)
+
+</t>
+<t tx="aum.20060516143534"></t>
+<t tx="aum.20060516143534.1">def help():
+ """
+ dump help info and exit
+ """
+ print "%s: a console-based freesite insertion utility" % progname
+
+ print "Usage: %s [options] <command> <args>" % progname
+ print "Options:"
+ print " -h, --help"
+ print " - display this help message"
+ print " -f, --file=filename"
+ print " - use a different config file (default is %s)" % confFile
+ print " -v, --verbose"
+ print " - run verbosely"
+ print " -q, --quiet"
+ print " - run quietly"
+ print " -l, --logfile=filename"
+ print " - location of logfile (default %s)" % logFile
+ print
+ print "Available Commands:"
+ print " setup - create/edit freesite config file interactively"
+ print " add - add new freesite called <name> using
directory <dir>"
+ print " list [<name>] - display a summary of all freesites, or a"
+ print " detailed report of one site if <name>
given"
+ print " remove <name> - remove given freesite"
+ print " update - reinsert any freesites which have changed since"
+ print " they were last inserted"
+
+</t>
+<t tx="aum.20060516143534.2">def main():
+
+ # default job options
+ opts = {
+ "configfile" : confFile,
+ "verbosity" : fcp.core.INFO,
+ "logfile" : logFile,
+ }
+
+ # process command line switches
+ try:
+ cmdopts, args = getopt.getopt(
+ sys.argv[1:],
+ "?hvf:l:",
+ ["help", "verbose", "file=", "logfile=",
+ ]
+ )
+ except getopt.GetoptError:
+ # print help information and exit:
+ usage()
+ sys.exit(2)
+ output = None
+ verbose = False
+ #print cmdopts
+ for o, a in cmdopts:
+
+ if o in ("-?", "-h", "--help"):
+ help()
+ sys.exit(0)
+
+ if o in ("-v", "--verbosity"):
+ opts['verbosity'] = fcp.core.DETAIL
+ opts['Verbosity'] = 1023
+
+ if o in ("-q", "--quiet"):
+ opts['verbosity'] = fcp.core.SILENT
+
+ if o in ("-f", "--file"):
+ opts['configfile'] = a
+
+ if o in ("-l", "--logfile"):
+ opts['logfile'] = a
+
+ # process command
+ if len(args) < 1:
+ usage(msg="No command given")
+
+ cmd = args.pop(0)
+
+ if cmd not in ['setup','add','remove','list','update']:
+ usage(msg="Unrecognised command '%s'" % cmd)
+
+ # we now have a likely valid command, so now we need a sitemgr
+ sitemgr = SiteMgr(**opts)
+
+ if cmd == 'setup':
+ editCreateConfig(sitemgr)
+
+ elif cmd == 'add':
+ addSite(sitemgr)
+
+ elif cmd == 'remove':
+ if not args:
+ print "Remove site: no freesites selected"
+ return
+ for sitename in args:
+ removeSite(sitemgr, sitename)
+ pass
+ print "Removed freesites: " + " ".join(args)
+ return
+
+ elif cmd == 'list':
+ if not args:
+ # summary list
+ print " ".join(sitemgr.getSiteNames())
+ else:
+ for sitename in args:
+ if not sitemgr.hasSite(sitename):
+ print "No such site '%s'" % sitename
+ else:
+ info = sitemgr.getSiteInfo(sitename)
+ print "%s:" % sitename
+ print " dir: %s" % info['dir']
+ print " uri: %s" % info['uri']
+ print " privkey: %s" % info['privatekey']
+ print " version: %s" % info['version']
+
+ pass
+ return
+
+ elif cmd == 'update':
+ sitemgr.update()
+ pass
+
+</t>
+<t tx="aum.20060516144850">def usage(ret=-1, msg=None):
+ if msg != None:
+ print msg
+ print "Usage: %s [options] <command> [<arguments>]" % progname
+ print "Do '%s -h' for help" % progname
+
+ sys.exit(ret)
+
+</t>
+<t tx="aum.20060516145032">@first #!/usr/bin/env python
+ at others
+</t>
+<t tx="aum.20060516145032.1">"""
+A utility to update freesites from within a cron environment
+"""
+ at others
+</t>
+<t tx="aum.20060516150511">def editCreateConfig(sitemgr):
+ """
+ Creates an initial config file interactively
+ """
+ print "Setting up configuration file %s" % sitemgr.configFile
+
+ # get fcp hostname
+ fcpHost = raw_input("FCP Hostname [%s] (* for all): " %
sitemgr.fcpHost).strip()
+ if not fcpHost:
+ fcpHost = sitemgr.fcpHost
+ if fcpHost == '*':
+ fcpHost = ""
+
+ # get fcp port
+ while 1:
+ fcpPort = raw_input("FCP Port [%s]: " % sitemgr.fcpPort).strip()
+ if not fcpPort:
+ fcpPort = sitemgr.fcpPort
+ try:
+ fcpPort = int(fcpPort)
+ except:
+ continue
+ break
+
+ print "Trying FCP port at %s:%s" % (fcpHost, fcpPort)
+ try:
+ node = fcp.FCPNode(host=fcpHost, port=fcpPort)
+ except Exception, e:
+ print "Failed to connect to FCP Port: %s" % e
+ print "Setup aborted"
+ return
+ node.shutdown()
+
+ sitemgr.fcpHost = fcpHost
+ sitemgr.fcpPort = fcpPort
+
+ # confirm and save
+ if getyesno("Save configuration", True):
+ sitemgr.saveConfig()
+
+ print "Configuration saved to %s" % sitemgr.configFile
+
+</t>
+<t tx="aum.20060516153119">def getyesno(ques, default=False):
+ """
+ prompt for yes/no answer, with default
+ """
+ if default:
+ prmt = "[Y/n]"
+ else:
+ prmt = "[y/N]"
+
+ resp = raw_input(ques + " " + prmt + " ").strip().lower()
+
+ if not resp:
+ return default
+ elif resp[0] in ['y', 't']:
+ return True
+ else:
+ return False
+</t>
+<t tx="aum.20060516184736">def hasSite(self, sitename):
+ """
+ returns True if site is known in this config
+ """
+ return self.config.has_section(sitename)
+
+</t>
+<t tx="aum.20060516184736.1">def addSite(sitemgr):
+ """
+ Interactively adds a new site to config
+ """
+ print "Add new site"
+
+ while 1:
+ sitename = raw_input("Name of freesite, or empty line to cancel:
").strip()
+ if not sitename:
+ print "Add site aborted"
+ return
+ elif sitemgr.hasSite(sitename):
+ print "Freesite '%s' already exists" % sitename
+ continue
+ break
+
+ while 1:
+ sitedir = raw_input("Directory where freesite's files reside:
").strip()
+ if not sitedir:
+ print "Add site aborted"
+ return
+ sitedir = os.path.abspath(sitedir)
+ if not os.path.isdir(sitedir):
+ print "'%s' is not a directory, try again" % sitedir
+ continue
+ elif not os.path.isfile(os.path.join(sitedir, "index.html")):
+ print "'%s' has no index.html, try again" % sitedir
+ continue
+ break
+
+ # good to go - add the site
+ sitemgr.addSite(sitename, sitedir)
+
+ print "Added new freesite: '%s' => %s" % (sitename, sitedir)
+
+</t>
+<t tx="aum.20060516192715">def addSite(self, sitename, sitedir):
+
+ if self.hasSite(sitename):
+ raise Exception("Site %s already exists" % sitename)
+
+ conf = self.config
+ conf.add_section(sitename)
+ conf.set(sitename, "dir", sitedir)
+
+ self.saveConfig()
+
+</t>
+<t tx="aum.20060516193650">def removeSite(sitemgr, sitename):
+ """
+ tries to remove site from config
+ """
+ if not sitemgr.hasSite(sitename):
+ print "No such freesite '%s'" % sitename
+ return
+
+ if getyesno("Are you sure you wish to delete freesite '%s'", False):
+ sitemgr.removeSite(sitename)
+ print "Removed freesite '%s'" % sitename
+ else:
+ print "Freesite deletion aborted"
+
+</t>
+<t tx="aum.20060516194016">def getSiteNames(self):
+ return self.config.sections()
+
+</t>
+<t tx="aum.20060516194958">def getSiteInfo(self, sitename):
+ """
+ returns a record of info about given site
+ """
+ if not self.hasSite(sitename):
+ raise Exception("No such freesite '%s'" % sitename)
+
+ conf = self.config
+
+ if conf.has_option(sitename, "hash"):
+ hash = conf.get(sitename, "hash")
+ else:
+ hash = None
+
+ if conf.has_option(sitename, "version"):
+ version = conf.getint(sitename, "version")
+ else:
+ version = None
+
+ if conf.has_option(sitename, "privatekey"):
+ privkey = conf.get(sitename, "privatekey")
+ else:
+ privkey = None
+
+ if conf.has_option(sitename, "uri"):
+ uri = conf.get(sitename, "uri")
+ else:
+ uri = None
+
+ return {'name' : sitename,
+ 'dir' : conf.get(sitename, 'dir'),
+ 'hash' : hash,
+ 'version' : version,
+ 'privatekey' : privkey,
+ 'uri' : uri,
+ }
+
+</t>
+<t tx="aum.20060516200626">def removeSite(self, sitename):
+ """
+ Drops a freesite from the config
+ """
+ if not self.hasSite(sitename):
+ raise Exception("No such site '%s'" % sitename)
+
+ conf = self.config
+ conf.remove_section(sitename)
+
+ self.saveConfig()
+
+</t>
</tnodes>
</leo_file>
Modified: trunk/apps/pyFreenet/fcpxmlrpc.cgi
===================================================================
--- trunk/apps/pyFreenet/fcpxmlrpc.cgi 2006-05-16 22:15:45 UTC (rev 8722)
+++ trunk/apps/pyFreenet/fcpxmlrpc.cgi 2006-05-16 22:17:57 UTC (rev 8723)
@@ -7,14 +7,14 @@
from SimpleXMLRPCServer import CGIXMLRPCRequestHandler
import fcp
-from fcpxmlrpc import FreenetXMLRPCRequestHandler
+from fcp.xmlrpc import FreenetXMLRPCRequestHandler
# hostname and port of FCP interface
fcpHost = "10.0.0.1"
fcpPort = 9481
# verbosity for logging
-verbosity = fcp.DETAIL
+verbosity = core.DETAIL
# where the logfile is
logfile = "/tmp/fcpxmlrpc.log"
@@ -22,7 +22,7 @@
def main():
# create the fcp node interface
- node = fcp.FCPNodeConnection(host=fcpHost,
+ node = fcp.FCPNode(host=fcpHost,
port=fcpPort,
verbosity=verbosity,
logfile=logfile,
Modified: trunk/apps/pyFreenet/setup.py
===================================================================
--- trunk/apps/pyFreenet/setup.py 2006-05-16 22:15:45 UTC (rev 8722)
+++ trunk/apps/pyFreenet/setup.py 2006-05-16 22:17:57 UTC (rev 8723)
@@ -1,7 +1,13 @@
"""
distutils installation script for pyfcp
"""
+import sys
+if sys.platform.lower().startswith("win"):
+ freesitemgrScript = "freesitemgr.py"
+else:
+ freesitemgrScript = "freesitemgr"
+
from distutils.core import setup
setup(name="PyFCP",
version="0.1",
@@ -10,8 +16,11 @@
author_email="david at freenet.org.nz",
url ="http://127.0.0.1:8888/USK at
yhAqcwNdN1y1eyRQQwZfhu4dpn-tPNlZMeNRZxEg1bM,zBUodpjtZdJvzWmwYKgr8jO5V-yKxZvetsr8tADNg2U,AQABAAE/pyfcp/0",
- py_modules=["fcp", "fcpxmlrpc", "fcpsitemgr",
- ]
+ packages = ['fcp'],
+ scripts = [freesitemgrScript],
+
+# py_modules=["fcp", "fcpxmlrpc", "fcpsitemgr"]
+
)
Modified: trunk/apps/pyFreenet/tutorial.py
===================================================================
--- trunk/apps/pyFreenet/tutorial.py 2006-05-16 22:15:45 UTC (rev 8722)
+++ trunk/apps/pyFreenet/tutorial.py 2006-05-16 22:17:57 UTC (rev 8723)
@@ -16,7 +16,6 @@
import fcp
-
# ------------------------------------------
# state where our FCP port is
@@ -29,7 +28,7 @@
# we're setting a relatively high verbosity so you
# can see the traffic
-node = fcp.FCPNodeConnection(host=fcpHost, verbosity=fcp.DETAIL)
+node = fcp.FCPNode(host=fcpHost, verbosity=fcp.DETAIL)
# -----------------------------------------------