[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[TSVN] Easy repo creation with TortoiseSVN client/Linux server

From: S Murthy Kambhampaty <smk_va_at_yahoo.com>
Date: 2004-08-09 19:10:59 CEST

To facilitate repository creation by Windows users on
a Linux SVN server, without requiring user access to
the Linux box, I created the attached python program
and associated start script for /etc/init.d. The
python program monitors a give directory for
(sub-)directory creation, and creates a subversion
repository on the newly created directory. The start
script starts and stops the python script with the
user-specified SVNRepoRoot, and logs to a
user-specified directory.

The python script is based on the test script which
comes with python-fam, which handles signals real
nicely. It could be revised to clean up the messages
that end up in the log file.

Hope this helps someone else, and feedback regarding
improvements is always welcome.

Cheers,
   Murthy

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

#!/usr/bin/python

#
# FN: ReposCreateLite.py
# DT: 2004/07/29 18:19:00
# AU: S. Murthy Kambhampaty
# AB: Monitors a given directory for object creation,
# - If a directory is created, creates a subversion repository in it
# - If the created object is other than a directory, it is deleted!!!
#

MonitorMan="SysAdmin@myDN"
MXDN="@myDN" # Mail exchanger's domain name

import commands, errno, _fam, getopt, os, signal \
        , select, smtplib, string, sys, time
from time import localtime, strftime

if len(sys.argv) != 2:
        print 'usage: %s <directory>' % sys.argv[0]
        sys.exit(1)

# Get the name of the repository root and make sure that it exists
RepoRoot=sys.argv[1]
if not(os.path.isdir(RepoRoot)):
        print >> sys.stderr, "The given path \"" +RepoRoot +"\" is not a directory. Exiting ..."
        sys.exit(2)
else:
        os.chdir(RepoRoot)

# Get the repository owner's name, uid, and gid; ; BTW, python
# does not do usernames
RRUser=commands.getoutput(r'stat -c %U "' +RepoRoot +r'"')
RRStat=os.stat(RepoRoot)

# Define some signal handlers
def handle_stop(signum, frame):
        global suspend

        print 'Suspended!'
        suspend=1

def handle_cont(signum, frame):
        global cont

        print 'Resumed!'
        signal.signal(signal.SIGCONT, handle_cont)
        cont=1

def handle_int(signum, frame):
        global intr

        print 'Interrupted!'
        signal.signal(signal.SIGINT, handle_int)
        intr=1

def handle_usr1(signum, frame):
        global usr1

        print 'Got USR1!'
        signal.signal(signal.SIGUSR1, handle_usr1)
        usr1=1

def handle_usr2(signum, frame):
        global usr2

        print 'Got USR2!'
        signal.signal(signal.SIGUSR2, handle_usr2)
        usr2=1

signal.signal(signal.SIGTSTP, handle_stop)
signal.signal(signal.SIGCONT, handle_cont)
signal.signal(signal.SIGINT, handle_int)
signal.signal(signal.SIGUSR1, handle_usr1)
signal.signal(signal.SIGUSR2, handle_usr2)

suspend = None
cont = None
intr = None
usr1 = None
usr2 = None

# Define the action to be taken on folder creation
def MakeSVNRepo(fev):
        """Convert newly created directories into subversion repositories

                If the newly created object is not a directory, it is deleted.
                Also, Windows gives new folders a defaul name of "New Folder"
                until a real name is assigned. Simply screening "New Folder"
                seems to solve this. It may be preferable to match all names
                "New Folder*", but as this script is stopped and started with
                the host operating system in the present application, it is not
                necessary.
        """
        #global MonitorMan, MXDN, RRUser, RRStat
        _FAMEvtCode, _RName=(fev.code2str(), str(fev.filename))
        if _FAMEvtCode != "created": return
        if _RName == "New Folder": return
        if os.path.isdir(_RName) == False:
                # This is a little cold, but only directories belong here
                # so delete non-directories
                _PTime=strftime("%x %X", localtime())
                os.remove(_RName)
                print >> sys.stderr, "%s: Removing non-directory \"%s\"" % (_PTime, _RName)
                sys.stderr.flush()
                return
        # If the altered object clears all of the above tests it's
        # ready to become a directory. This is not totally failsafe
        # but mostly works.

        # Get some info about the altered object
        _RUser=commands.getoutput(r'stat -c %U "' +_RName +r'"')
        _Rstat=os.stat(_RName)
        _PTime=strftime("%x %X", localtime(_Rstat.st_ctime))
        # Change ownership to the repository root's user
        os.chown(_RName, RRStat.st_uid, RRStat.st_gid)
        # Now create the repository
        _RC=commands.getoutput(r'su - ' +RRUser +r' -c "umask 002; svnadmin create \"' +_RName +r'\""')
        # _RV=commands.getoutput(r'su - ' +RRUser +r' -c "svnadmin verify \"' +_RName +r'\""')
        # Prepare and send an e-mail notifying the folder creator
        # that her repository was created
        _toAddr=_RUser +MXDN
        _theMsg=("Subject: SVN repository created\n\n%s: The repository \"%s\" was created for \"%s\"" % (_PTime, _RName, _RUser))
        _MailSVR=smtplib.SMTP('localhost')
        _MailSVR.sendmail(MonitorMan, _toAddr, _theMsg)
        _MailSVR.quit()
        print >> sys.stdout, "%s: Created repository \"%s\" for \"%s\"" % (_PTime, _RName, _RUser)
        sys.stdout.flush()

# Get started
conn=_fam.open()
fReq=conn.monitorDirectory(RepoRoot, None)

# Here's where the action begins, but it comes after
# a long list of signal response instructions
while True:
        if suspend:
                fReq.suspendMonitor()
                print >> sys.stdout, 'Suspended monitoring of request %i' % fReq.requestID()
                suspend=None
                signal.signal(signal.SIGTSTP, handle_stop)
                sys.stdout.flush()
        if cont:
                fReq.resumeMonitor()
                print >> sys.stdout, 'Resumed monitoring of request %i' % fReq.requestID()
                cont=None
                sys.stdout.flush()
        if intr:
                # The dealloc methods of all objects should handle
                # FAMCancelMonitor and FAMClose
                sys.exit(0)
        if usr1:
                # Cancel all requests, close the connection, and reopen it.
                # This makes sure long-lived clients can connect, monitor, and
                # disconnect repeatedly without leaking.
                usr1 = None
                sleeptime = 1
                print >> sys.stdout, 'Cancelling monitoring of request %i' % fReq.requestID()
                fReq.cancelMonitor()
                conn.close()
                print >> sys.stdout, 'Closed connection, sleeping %d...' % sleeptime
                time.sleep(sleeptime)
                conn=_fam.open()
                fReq=conn.monitorDirectory(RepoRoot, None)
                sys.stdout.flush()
        if usr2:
                # Clean things up like a well-behaved client and exit.
                print >> sys.stdout, 'Cancelling monitoring of request %i' % fReq.requestID()
                fReq.cancelMonitor()
                conn.close()
                print >> sys.stdout, 'Closed connection'
                sys.exit(0)
        try:
          ri, ro, re=select.select([conn], [], [])
        except select.error, er:
                errnumber, strerr=er
                if errnumber == errno.EINTR:
                        continue
                else:
                        print strerr
                        sys.exit(1)
        while conn.pending():
                fev=conn.nextEvent()
                MakeSVNRepo(fev)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tortoisesvn.tigris.org
For additional commands, e-mail: dev-help@tortoisesvn.tigris.org

Received on Mon Aug 9 20:43:16 2004

This is an archived mail posted to the TortoiseSVN Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.