Modified: subversion/branches/ev2-export/tools/server-side/svnpubsub/svntweet.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/ev2-export/tools/server-side/svnpubsub/svntweet.py?rev=1297221&r1=1295003&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/tools/server-side/svnpubsub/svntweet.py 
(original)
+++ subversion/branches/ev2-export/tools/server-side/svnpubsub/svntweet.py Mon 
Mar  5 20:34:22 2012
@@ -21,7 +21,7 @@
 #
 # Example:
 #  svntweet.py  my-config.json
-#  
+#
 # With my-config.json containing stream paths and the twitter auth info:
 #    {"stream": "http://svn-master.apache.org:2069/commits/xml";,
 #     "username": "asfcommits",
@@ -90,9 +90,9 @@ class Revision:
         self.log = None
         self.date = None
 
-class StreamHandler(handler.ContentHandler):   
+class StreamHandler(handler.ContentHandler):
     def __init__(self, bdec):
-        handler.ContentHandler.__init__(self) 
+        handler.ContentHandler.__init__(self)
         self.bdec =  bdec
         self.rev = None
         self.text_value = None
@@ -115,7 +115,7 @@ class StreamHandler(handler.ContentHandl
             self.bdec.stillalive()
     def characters(self, data):
         if self.text_value is not None:
-            self.text_value = self.text_value + data 
+            self.text_value = self.text_value + data
         else:
             self.text_value = data
 
@@ -179,7 +179,7 @@ class BigDoEverythingClasss(object):
     def pageStart(self):
         log.msg("Stream Connection Established")
         self.failures = 0
-        
+
     def _restartStream(self):
         (self.stream, self.transport) = connectTo(self.url, self)
         self.stream.deferred.addBoth(self.streamDead)
@@ -253,6 +253,6 @@ def main(config_file):
 if __name__ == "__main__":
     if len(sys.argv) != 2:
         print "invalid args, read source code"
-        sys.exit(0) 
+        sys.exit(0)
     log.startLogging(sys.stdout)
     main(sys.argv[1])

Modified: subversion/branches/ev2-export/tools/server-side/svnpubsub/svnwcsub.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/ev2-export/tools/server-side/svnpubsub/svnwcsub.py?rev=1297221&r1=1295003&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/tools/server-side/svnpubsub/svnwcsub.py 
(original)
+++ subversion/branches/ev2-export/tools/server-side/svnpubsub/svnwcsub.py Mon 
Mar  5 20:34:22 2012
@@ -36,8 +36,9 @@ import os
 import re
 import ConfigParser
 import time
-import logging
+import logging.handlers
 import Queue
+import optparse
 
 from twisted.internet import reactor, task, threads
 from twisted.internet.utils import getProcessOutput
@@ -130,7 +131,7 @@ class WorkingCopy(object):
         uuid = info['Repository UUID']
         relpath = url[len(repos):]  # also has leading '/'
         return [relpath, url, repos, uuid]
-        
+
 
 class HTTPStream(HTTPClientFactory):
     protocol = HTTPPageDownloader
@@ -154,9 +155,9 @@ class Revision:
         self.rev = rev
         self.dirs_changed = []
 
-class StreamHandler(handler.ContentHandler):   
+class StreamHandler(handler.ContentHandler):
     def __init__(self, stream, bdec):
-        handler.ContentHandler.__init__(self) 
+        handler.ContentHandler.__init__(self)
         self.stream = stream
         self.bdec =  bdec
         self.rev = None
@@ -167,7 +168,7 @@ class StreamHandler(handler.ContentHandl
         """
         <commit revision="7">
                         <dirs_changed><path>/</path></dirs_changed>
-                      </commit> 
+                      </commit>
         """
         if name == "commit":
             self.rev = Revision(attrs['repository'], int(attrs['revision']))
@@ -175,7 +176,7 @@ class StreamHandler(handler.ContentHandl
             self.bdec.stillalive(self.stream)
     def characters(self, data):
         if self.text_value is not None:
-            self.text_value = self.text_value + data 
+            self.text_value = self.text_value + data
         else:
             self.text_value = data
 
@@ -230,7 +231,6 @@ class BigDoEverythingClasss(object):
         self.svnbin = config.get_value('svnbin')
         self.env = config.get_env()
         self.worker = BackgroundWorker(self.svnbin, self.env)
-        self.worker.start()
         self.service = service
         self.failures = 0
         self.alive = time.time()
@@ -333,12 +333,15 @@ class BackgroundWorker(threading.Thread)
         threading.Thread.__init__(self)
 
         # The main thread/process should not wait for this thread to exit.
-        self.daemon = True
+        ### compat with Python 2.5
+        self.setDaemon(True)
 
         self.svnbin = svnbin
         self.env = env
         self.q = Queue.Queue()
 
+        self.has_started = False
+
     def run(self):
         while True:
             if self.q.qsize() > BACKLOG_TOO_HIGH:
@@ -360,6 +363,12 @@ class BackgroundWorker(threading.Thread)
             self.q.task_done()
 
     def add_work(self, operation, wc):
+        # Start the thread when work first arrives. Thread-start needs to
+        # be delayed in case the process forks itself to become a daemon.
+        if not self.has_started:
+            self.start()
+            self.has_started = True
+
         self.q.put((operation, wc))
 
     def _update(self, wc):
@@ -443,21 +452,93 @@ class ReloadableConfig(ConfigParser.Safe
         return str(option)
 
 
-def main(config_file):
+def prepare_logging(logfile):
+    "Log to the specified file, or to stdout if None."
+
+    if logfile:
+        # Rotate logs daily, keeping 7 days worth.
+        handler = logging.handlers.TimedRotatingFileHandler(
+          logfile, when='midnight', backupCount=7,
+          )
+    else:
+        handler = logging.StreamHandler(sys.stdout)
+
+    # Add a timestamp to the log records
+    formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s',
+                                  '%Y-%m-%d %H:%M:%S')
+    handler.setFormatter(formatter)
+
+    # Apply the handler to the root logger
+    root = logging.getLogger()
+    root.addHandler(handler)
+    
+    ### use logging.INFO for now. switch to cmdline option or a config?
+    root.setLevel(logging.INFO)
+
+
+def handle_options(options):
+    # Set up the logging, then process the rest of the options.
+    prepare_logging(options.logfile)
+
+    if options.pidfile:
+        pid = os.getpid()
+        open(options.pidfile, 'w').write('%s\n' % pid)
+        logging.info('pid %d written to %s', pid, options.pidfile)
+
+    if options.uid:
+        try:
+            uid = int(options.uid)
+        except ValueError:
+            import pwd
+            uid = pwd.getpwnam(options.uid)[2]
+        logging.info('setting uid %d', uid)
+        os.setuid(uid)
+
+    if options.gid:
+        try:
+            gid = int(options.gid)
+        except ValueError:
+            import grp
+            gid = grp.getgrnam(options.gid)[2]
+        logging.info('setting gid %d', gid)
+        os.setgid(gid)
+
+    if options.umask:
+        umask = int(options.umask, 8)
+        os.umask(umask)
+        logging.info('umask set to %03o', umask)
+
+
+def main(args):
+    parser = optparse.OptionParser(
+        description='An SvnPubSub client to keep working copies synchronized '
+                    'with a repository.',
+        usage='Usage: %prog [options] CONFIG_FILE',
+        )
+    parser.add_option('--logfile',
+                      help='filename for logging')
+    parser.add_option('--pidfile',
+                      help="the process' PID will be written to this file")
+    parser.add_option('--uid',
+                      help='switch to this UID before running')
+    parser.add_option('--gid',
+                      help='switch to this GID before running')
+    parser.add_option('--umask',
+                      help='set this (octal) umask before running')
+
+    options, extra = parser.parse_args(args)
+
+    if len(extra) != 1:
+        parser.error('CONFIG_FILE is required')
+    config_file = extra[0]
+
+    # Process any provided options.
+    handle_options(options)
+
     c = ReloadableConfig(config_file)
     big = BigDoEverythingClasss(c)
     reactor.run()
 
 
 if __name__ == "__main__":
-    if len(sys.argv) != 2:
-        print "invalid args, read source code"
-        sys.exit(0)
-
-    ### use logging.INFO for now. review/adjust the calls above for the
-    ### proper logging level. then remove the level (to return to default).
-    ### future: switch to config for logfile and loglevel.
-    logging.basicConfig(level=logging.INFO, stream=sys.stdout,
-                        datefmt='%Y-%m-%d %H:%M:%S',
-                        format='%(asctime)s [%(levelname)s] %(message)s')
-    main(sys.argv[1])
+    main(sys.argv[1:])

Modified: subversion/branches/ev2-export/tools/server-side/svnpubsub/test.conf
URL: 
http://svn.apache.org/viewvc/subversion/branches/ev2-export/tools/server-side/svnpubsub/test.conf?rev=1297221&r1=1295003&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/tools/server-side/svnpubsub/test.conf 
(original)
+++ subversion/branches/ev2-export/tools/server-side/svnpubsub/test.conf Mon 
Mar  5 20:34:22 2012
@@ -1,4 +1,9 @@
-# For use with testserver.py
+# For use with connecting to testserver.py
 
 [DEFAULT]
+svnbin: svn
 streams: http://127.0.0.1:2069/commits/xml
+
+[env]
+
+[track]

Modified: subversion/branches/ev2-export/tools/server-side/svnpubsub/watcher.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/ev2-export/tools/server-side/svnpubsub/watcher.py?rev=1297221&r1=1295003&r2=1297221&view=diff
==============================================================================
--- subversion/branches/ev2-export/tools/server-side/svnpubsub/watcher.py 
(original)
+++ subversion/branches/ev2-export/tools/server-side/svnpubsub/watcher.py Mon 
Mar  5 20:34:22 2012
@@ -53,5 +53,5 @@ def main(config_file):
 if __name__ == "__main__":
   if len(sys.argv) != 2:
     print "invalid args, read source code"
-    sys.exit(0) 
+    sys.exit(0)
   main(sys.argv[1])


Reply via email to