Author: aum
Date: 2006-05-15 09:05:29 +0000 (Mon, 15 May 2006)
New Revision: 8705

Added:
   trunk/apps/pyFreenet/fcpsitemgr.py
   trunk/apps/pyFreenet/fcpxmlrpc.cgi
   trunk/apps/pyFreenet/setup.py
Removed:
   trunk/apps/pyFreenet/sitemgr.py
Modified:
   trunk/apps/pyFreenet/code.leo
   trunk/apps/pyFreenet/fcpxmlrpc.py
   trunk/apps/pyFreenet/updatesites.py
Log:
Added fcpxmlrpc.cgi, a CGI script which can be added to any website
to make it an XML-RPC server for freenet


Modified: trunk/apps/pyFreenet/code.leo
===================================================================
--- trunk/apps/pyFreenet/code.leo       2006-05-15 00:01:48 UTC (rev 8704)
+++ trunk/apps/pyFreenet/code.leo       2006-05-15 09:05:29 UTC (rev 8705)
@@ -17,12 +17,13 @@
 <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" tnodeList="aum.20060513182312"><vh>@nosent 
release.py</vh></v>
+<v t="aum.20060515193950" tnodeList="aum.20060515193950"><vh>@nosent 
setup.py</vh></v>
 </v>
 <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" a="E" 
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.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.20060506215707.1"><vh>imports</vh></v>
 <v t="aum.20060506220237"><vh>exceptions</vh></v>
 <v t="aum.20060506215707.2"><vh>globals</vh></v>
@@ -33,7 +34,7 @@
 <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" a="V"><vh>putdir</vh></v>
+<v t="aum.20060511001853"><vh>putdir</vh></v>
 </v>
 <v t="aum.20060506224238" a="E"><vh>Other High Level Methods</vh>
 <v t="aum.20060514224855"><vh>listenGlobal</vh></v>
@@ -81,7 +82,7 @@
 </v>
 </v>
 <v t="aum.20060513073239.1" a="E"><vh>XML-RPC Server</vh>
-<v t="aum.20060512172707" 
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.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.20060512172843"><vh>imports</vh></v>
 <v t="aum.20060512173027"><vh>globals</vh></v>
 <v t="aum.20060512175041" a="E"><vh>class FCPXMLRPCServer</vh>
@@ -100,9 +101,15 @@
 <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" 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.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>
@@ -943,6 +950,11 @@
     """
     if options==None:
         options = {}
+    
+    if options.has_key('file'):
+        raise Exception("file option not available over XML-RPC")
+    if options.has_key('dir'):
+        raise Exception("dir option not available over XML-RPC")

     return self.node.get(uri, **options)

@@ -953,12 +965,17 @@

     Arguments:
         - uri - the URI to insert under
-        - options - a mapping (dict) object containing various
-          options - refer to FCPNodeConnection.get documentation
+        - options - a mapping (dict) object containing various options,
+          refer to FCPNodeConnection.get documentation
     """
     if options==None:
         options = {}

+    if options.has_key('file'):
+        raise Exception("file option not available over XML-RPC")
+    if options.has_key('dir'):
+        raise Exception("dir option not available over XML-RPC")
+
     return self.node.put(uri, data=data, **options)

 </t>
@@ -7256,7 +7273,7 @@

 </t>
 <t tx="aum.20060514132715">import sys, os, time, commands, traceback
-import sitemgr
+import fcpsitemgr

 </t>
 <t tx="aum.20060514132715.1"># time we wait after starting fred, to allow the 
node to 'warm up'
@@ -7570,5 +7587,80 @@
 # TODO: demonstrate global requests

 </t>
+<t tx="aum.20060515193950">"""
+distutils installation script for pyfcp
+"""
+
+from distutils.core import setup
+setup(name="PyFCP",
+      version="0.1",
+      description="Freenet FCP access freesite management and XML-RPC modules",
+      author="David McNab",
+      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",
+                  ]
+
+    )
+
+</t>
+<t tx="aum.20060515195621">@first #! /usr/bin/env python
+
+# CGI-based XML-RPC interface to FCP
+# You can use this on your FCP server
+
+
+ at others
+
+import fcpxmlrpc
+
+</t>
+<t tx="aum.20060515195621.1"># hostname and port of FCP interface
+fcpHost = "10.0.0.1"
+fcpPort = 9481
+
+# verbosity for logging
+verbosity = fcp.DETAIL
+
+# where the logfile is
+logfile = "/tmp/fcpxmlrpc.log"
+
+</t>
+<t tx="aum.20060515195621.2">from SimpleXMLRPCServer import 
CGIXMLRPCRequestHandler
+
+import fcp
+from fcpxmlrpc import FreenetXMLRPCRequestHandler
+
+</t>
+<t tx="aum.20060515195621.3">def main():
+
+    # create the fcp node interface
+    node = fcp.FCPNodeConnection(host=fcpHost,
+                                 port=fcpPort,
+                                 verbosity=verbosity,
+                                 logfile=logfile,
+                                 )
+
+    # create the request handler
+    hdlr = FreenetXMLRPCRequestHandler(node)
+
+    # create the handler
+    handler = CGIXMLRPCRequestHandler()
+    handler.register_introspection_functions()
+
+    # link in the node wrapper
+    handler.register_instance(hdlr)
+
+    # now do the business
+    handler.handle_request()
+
+    node.shutdown()
+
+</t>
+<t tx="aum.20060515200029">if __name__ == '__main__':
+    main()
+
+</t>
 </tnodes>
 </leo_file>

Added: trunk/apps/pyFreenet/fcpsitemgr.py
===================================================================
--- trunk/apps/pyFreenet/fcpsitemgr.py  2006-05-15 00:01:48 UTC (rev 8704)
+++ trunk/apps/pyFreenet/fcpsitemgr.py  2006-05-15 09:05:29 UTC (rev 8705)
@@ -0,0 +1,249 @@
+#! /usr/bin/env python
+"""
+A small freesite insertion/management utility
+"""
+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"
+fcpPort = None
+#verbosity = fcp.DETAIL
+verbosity = None
+logfile = None
+
+class SiteMgr:
+    """
+    Manages insertion and updating of freesites
+    """
+    def __init__(self, configFile=None, **kw):
+        """
+        Creates a site manager object.
+        
+        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(logfile=logfile, **kw)
+    
+        # determine pathname for sites ini file
+        if configFile == None:
+            isDoze = sys.platform.lower().startswith("win")
+            homedir = os.path.expanduser("~")
+            if isDoze:
+                filename = "freesites.ini"
+            else:
+                filename = ".freesites"
+            configFile = os.path.join(homedir, filename)
+    
+        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()
+    
+    def __del__(self):
+    
+        try:
+            if hasattr(self, 'node'):
+                self.node.shutdown()
+            del self.node
+            self.node = None
+        except:
+            pass
+    
+    def createConfig(self):
+        """
+        Creates a whole new config
+        """
+        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]",
+            "",
+            "# for each new site, just take a copy of the following",
+            "# 2 lines, uncomment them and change as needed",
+            "",
+            "# [mysite]",
+            "# dir=/path/to/mysite/directory",
+            "",
+            "",
+            ]))
+    
+    def createNode(self, **kw):
+    
+        #kw = {}
+    
+        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
+    
+        #print kw
+        
+        self.node = fcp.FCPNodeConnection(**kw)
+    
+    def loadConfig(self):
+        """
+        Loads the sites config file into self.config as a SafeConfigParser
+        object
+        """
+        conf = self.config = SafeConfigParser()
+        conf.read(self.configFile)
+    
+        needToSave = False
+    
+        # 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()
+    
+    def saveConfig(self):
+        """
+        Saves the amended config file to disk
+        """
+        self.createConfig()
+    
+        f = file(self.configFile, "a")
+    
+        self.config.write(f)
+    
+        f.close()
+    
+    def update(self):
+        """
+        Insert/update all registered freesites
+        """
+        noSites = True
+    
+        log = self._log
+    
+        conf = self.config
+        for sitename in conf.sections():
+            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)
+            h = sha.new()
+            for f in files:
+                h.update(f['hash'])
+            hashNew = h.hexdigest()
+            if hashNew != hash:
+                log(INFO, "Updating site %s" % sitename)
+                log(INFO, "privatekey=%s" % privatekey)
+                noSites = False
+                try:
+                    res = self.node.put(privatekey,
+                                        dir=dir,
+                                        name=sitename,
+                                        version=version,
+                                        usk=True)
+                    log(INFO, "site %s updated successfully" % sitename)
+                except:
+                    traceback.print_exc()
+                    log(ERROR, "site %s failed to update" % sitename)
+                conf.set(sitename, "hash", hashNew)
+    
+        self.saveConfig()
+    
+        if noSites:
+            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]
+    print "This utility inserts/updates freesites, and is"
+    print "driven by a simple config file."
+    print
+    print "The first time you run this utility, a config file"
+    print "will be created for you in your home directory,"
+    print "You will be told where this file is (~/.freesites on *nix"
+    print "or ~/freesites.ini on doze)"
+    print "then you can edit this file and add details of"
+    print "your freesites, and run it again."
+    print
+    print "Note - freesites are only updated if they have"
+    print "changed since the last update, because a hash"
+    print "of each site gets stored in the config"
+
+    sys.exit(0)
+
+if __name__ == '__main__':
+
+    if '-h' in sys.argv:
+        help()
+
+    if '-v' in sys.argv:
+        verbosity = fcp.DETAIL
+
+    s = SiteMgr()
+    s.update()
+    s.shutdown()
+

Added: trunk/apps/pyFreenet/fcpxmlrpc.cgi
===================================================================
--- trunk/apps/pyFreenet/fcpxmlrpc.cgi  2006-05-15 00:01:48 UTC (rev 8704)
+++ trunk/apps/pyFreenet/fcpxmlrpc.cgi  2006-05-15 09:05:29 UTC (rev 8705)
@@ -0,0 +1,51 @@
+#! /usr/bin/env python
+
+# CGI-based XML-RPC interface to FCP
+# You can use this on your FCP server
+
+
+from SimpleXMLRPCServer import CGIXMLRPCRequestHandler
+
+import fcp
+from fcpxmlrpc import FreenetXMLRPCRequestHandler
+
+# hostname and port of FCP interface
+fcpHost = "10.0.0.1"
+fcpPort = 9481
+
+# verbosity for logging
+verbosity = fcp.DETAIL
+
+# where the logfile is
+logfile = "/tmp/fcpxmlrpc.log"
+
+def main():
+
+    # create the fcp node interface
+    node = fcp.FCPNodeConnection(host=fcpHost,
+                                 port=fcpPort,
+                                 verbosity=verbosity,
+                                 logfile=logfile,
+                                 )
+
+    # create the request handler
+    hdlr = FreenetXMLRPCRequestHandler(node)
+
+    # create the handler
+    handler = CGIXMLRPCRequestHandler()
+    handler.register_introspection_functions()
+
+    # link in the node wrapper
+    handler.register_instance(hdlr)
+
+    # now do the business
+    handler.handle_request()
+
+    node.shutdown()
+
+if __name__ == '__main__':
+    main()
+
+
+import fcpxmlrpc
+

Modified: trunk/apps/pyFreenet/fcpxmlrpc.py
===================================================================
--- trunk/apps/pyFreenet/fcpxmlrpc.py   2006-05-15 00:01:48 UTC (rev 8704)
+++ trunk/apps/pyFreenet/fcpxmlrpc.py   2006-05-15 09:05:29 UTC (rev 8705)
@@ -86,6 +86,11 @@
         """
         if options==None:
             options = {}
+        
+        if options.has_key('file'):
+            raise Exception("file option not available over XML-RPC")
+        if options.has_key('dir'):
+            raise Exception("dir option not available over XML-RPC")

         return self.node.get(uri, **options)

@@ -95,12 +100,17 @@

         Arguments:
             - uri - the URI to insert under
-            - options - a mapping (dict) object containing various
-              options - refer to FCPNodeConnection.get documentation
+            - options - a mapping (dict) object containing various options,
+              refer to FCPNodeConnection.get documentation
         """
         if options==None:
             options = {}

+        if options.has_key('file'):
+            raise Exception("file option not available over XML-RPC")
+        if options.has_key('dir'):
+            raise Exception("dir option not available over XML-RPC")
+    
         return self.node.put(uri, data=data, **options)

     def genkey(self):

Added: trunk/apps/pyFreenet/setup.py
===================================================================
--- trunk/apps/pyFreenet/setup.py       2006-05-15 00:01:48 UTC (rev 8704)
+++ trunk/apps/pyFreenet/setup.py       2006-05-15 09:05:29 UTC (rev 8705)
@@ -0,0 +1,17 @@
+"""
+distutils installation script for pyfcp
+"""
+
+from distutils.core import setup
+setup(name="PyFCP",
+      version="0.1",
+      description="Freenet FCP access freesite management and XML-RPC modules",
+      author="David McNab",
+      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",
+                  ]
+
+    )
+

Deleted: trunk/apps/pyFreenet/sitemgr.py
===================================================================
--- trunk/apps/pyFreenet/sitemgr.py     2006-05-15 00:01:48 UTC (rev 8704)
+++ trunk/apps/pyFreenet/sitemgr.py     2006-05-15 09:05:29 UTC (rev 8705)
@@ -1,249 +0,0 @@
-#! /usr/bin/env python
-"""
-A small freesite insertion/management utility
-"""
-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"
-fcpPort = None
-#verbosity = fcp.DETAIL
-verbosity = None
-logfile = None
-
-class SiteMgr:
-    """
-    Manages insertion and updating of freesites
-    """
-    def __init__(self, configFile=None, **kw):
-        """
-        Creates a site manager object.
-        
-        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(logfile=logfile, **kw)
-    
-        # determine pathname for sites ini file
-        if configFile == None:
-            isDoze = sys.platform.lower().startswith("win")
-            homedir = os.path.expanduser("~")
-            if isDoze:
-                filename = "freesites.ini"
-            else:
-                filename = ".freesites"
-            configFile = os.path.join(homedir, filename)
-    
-        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()
-    
-    def __del__(self):
-    
-        try:
-            if hasattr(self, 'node'):
-                self.node.shutdown()
-            del self.node
-            self.node = None
-        except:
-            pass
-    
-    def createConfig(self):
-        """
-        Creates a whole new config
-        """
-        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]",
-            "",
-            "# for each new site, just take a copy of the following",
-            "# 2 lines, uncomment them and change as needed",
-            "",
-            "# [mysite]",
-            "# dir=/path/to/mysite/directory",
-            "",
-            "",
-            ]))
-    
-    def createNode(self, **kw):
-    
-        #kw = {}
-    
-        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
-    
-        #print kw
-        
-        self.node = fcp.FCPNodeConnection(**kw)
-    
-    def loadConfig(self):
-        """
-        Loads the sites config file into self.config as a SafeConfigParser
-        object
-        """
-        conf = self.config = SafeConfigParser()
-        conf.read(self.configFile)
-    
-        needToSave = False
-    
-        # 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()
-    
-    def saveConfig(self):
-        """
-        Saves the amended config file to disk
-        """
-        self.createConfig()
-    
-        f = file(self.configFile, "a")
-    
-        self.config.write(f)
-    
-        f.close()
-    
-    def update(self):
-        """
-        Insert/update all registered freesites
-        """
-        noSites = True
-    
-        log = self._log
-    
-        conf = self.config
-        for sitename in conf.sections():
-            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)
-            h = sha.new()
-            for f in files:
-                h.update(f['hash'])
-            hashNew = h.hexdigest()
-            if hashNew != hash:
-                log(INFO, "Updating site %s" % sitename)
-                log(INFO, "privatekey=%s" % privatekey)
-                noSites = False
-                try:
-                    res = self.node.put(privatekey,
-                                        dir=dir,
-                                        name=sitename,
-                                        version=version,
-                                        usk=True)
-                    log(INFO, "site %s updated successfully" % sitename)
-                except:
-                    traceback.print_exc()
-                    log(ERROR, "site %s failed to update" % sitename)
-                conf.set(sitename, "hash", hashNew)
-    
-        self.saveConfig()
-    
-        if noSites:
-            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]
-    print "This utility inserts/updates freesites, and is"
-    print "driven by a simple config file."
-    print
-    print "The first time you run this utility, a config file"
-    print "will be created for you in your home directory,"
-    print "You will be told where this file is (~/.freesites on *nix"
-    print "or ~/freesites.ini on doze)"
-    print "then you can edit this file and add details of"
-    print "your freesites, and run it again."
-    print
-    print "Note - freesites are only updated if they have"
-    print "changed since the last update, because a hash"
-    print "of each site gets stored in the config"
-
-    sys.exit(0)
-
-if __name__ == '__main__':
-
-    if '-h' in sys.argv:
-        help()
-
-    if '-v' in sys.argv:
-        verbosity = fcp.DETAIL
-
-    s = SiteMgr()
-    s.update()
-    s.shutdown()
-

Modified: trunk/apps/pyFreenet/updatesites.py
===================================================================
--- trunk/apps/pyFreenet/updatesites.py 2006-05-15 00:01:48 UTC (rev 8704)
+++ trunk/apps/pyFreenet/updatesites.py 2006-05-15 09:05:29 UTC (rev 8705)
@@ -3,7 +3,7 @@
 A utility to update freesites from within a cron environment
 """
 import sys, os, time, commands, traceback
-import sitemgr
+import fcpsitemgr

 # time we wait after starting fred, to allow the node to 'warm up'
 # and make connections to its peers


Reply via email to