[Csmail-patches] CVSROOT syncmail,1.1,1.2
Status: Pre-Alpha
Brought to you by:
mastergaurav
From: <mas...@us...> - 2004-02-07 15:13:19
|
Update of /cvsroot/csmail/CVSROOT In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5890 Modified Files: syncmail Log Message: 2004-02-07 Gaurav Vaish <mastergaurav@> * syncmail: My new copy. Index: syncmail =================================================================== RCS file: /cvsroot/csmail/CVSROOT/syncmail,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** syncmail 24 Jul 2002 10:18:21 -0000 1.1 --- syncmail 7 Feb 2004 15:10:18 -0000 1.2 *************** *** 1,4 **** #! /usr/bin/python ! # -*- Python -*- """Complicated notification for CVS checkins. --- 1,6 ---- #! /usr/bin/python ! ! # NOTE: Until SourceForge installs a modern version of Python on the cvs ! # servers, this script MUST be compatible with Python 1.5.2. """Complicated notification for CVS checkins. *************** *** 11,19 **** set this up, create a loginfo entry that looks something like this: ! mymodule /path/to/syncmail %%s som...@yo...main ! In this example, whenever a checkin that matches `mymodule' is made, the ! syncmail script is invoked, which will generate the diff containing email, and ! send it to som...@yo...main. Note: This module used to also do repository synchronizations via --- 13,21 ---- set this up, create a loginfo entry that looks something like this: ! mymodule /path/to/this/script %%s som...@yo...main ! In this example, whenever a checkin that matches `mymodule' is made, this ! script is invoked, which will generate the diff containing email, and send it ! to som...@yo...main. Note: This module used to also do repository synchronizations via *************** *** 21,26 **** this is no longer necessary. The syncing functionality has been ripped out in the 3.0, which simplifies it considerably. Access the 2.x versions ! to refer to this functionality. Because of this, the script's name is ! misleading. It no longer makes sense to run this script from the command line. Doing so --- 23,27 ---- this is no longer necessary. The syncing functionality has been ripped out in the 3.0, which simplifies it considerably. Access the 2.x versions ! to refer to this functionality. Because of this, the script is misnamed. It no longer makes sense to run this script from the command line. Doing so *************** *** 29,44 **** Usage: ! syncmail [options] <%%S> email-addr [email-addr ...] ! Where options is: --cvsroot=<path> ! Use <path> as the environment variable CVSROOT. Otherwise this ! variable must exist in the environment. ! --help ! -h Print this text. <%%S> CVS %%s loginfo expansion. When invoked by CVS, this will be a single --- 30,65 ---- Usage: ! %(PROGRAM)s [options] <%%S> email-addr [email-addr ...] ! Where options are: --cvsroot=<path> ! Use <path> as the environment variable CVSROOT. Otherwise this ! variable must exist in the environment. ! --context=# ! -C # ! Include # lines of context around lines that differ (default: 2). ! ! -c ! Produce a context diff (default). ! ! -u ! Produce a unified diff (smaller). ! ! --quiet / -q ! Don't print as much status to stdout. ! ! --fromhost=hostname ! -f hostname ! The hostname that email messages appear to be coming from. The From: ! header will of the outgoing message will look like user@hostname. By ! default, hostname is the machine's fully qualified domain name. ! ! --help / -h Print this text. + The rest of the command line arguments are: + <%%S> CVS %%s loginfo expansion. When invoked by CVS, this will be a single *************** *** 50,64 **** email-addrs At least one email address. - """ - import os import sys ! import string import time import getopt ! # Notification command ! MAILCMD = '/usr/bin/mail -s "CVS: %(SUBJECT)s" %(PEOPLE)s 2>&1 > /dev/null' # Diff trimming stuff --- 71,108 ---- email-addrs At least one email address. """ import os import sys ! import re import time + import string import getopt + import smtplib + import pwd + import socket ! try: ! from socket import getfqdn ! except ImportError: ! def getfqdn(): ! # Python 1.5.2 :( ! hostname = socket.gethostname() ! byaddr = socket.gethostbyaddr(socket.gethostbyname(hostname)) ! aliases = byaddr[1] ! aliases.insert(0, byaddr[0]) ! aliases.insert(0, hostname) ! for fqdn in aliases: ! if '.' in fqdn: ! break ! else: ! fqdn = 'localhost.localdomain' ! return fqdn ! ! ! from cStringIO import StringIO ! ! # Which SMTP server to do we connect to? Empty string means localhost. ! MAILHOST = '' ! MAILPORT = 25 # Diff trimming stuff *************** *** 66,96 **** DIFF_TAIL_LINES = 20 DIFF_TRUNCATE_IF_LARGER = 1000 - #DIFF_HEAD_LINES = 1 - #DIFF_TAIL_LINES = 1 - #DIFF_TRUNCATE_IF_LARGER = 1 ! def usage(errcode, msg=''): print __doc__ % globals() ! if msg: print msg ! sys.exit(errorcode) ! def calculate_diff(filespec): ! try: ! file, oldrev, newrev = string.split(filespec, ',') ! except ValueError: ! # No diff to report ! return '***** Bogus filespec: %s' % filespec if oldrev == 'NONE': try: ! fp = open(file) lines = fp.readlines() fp.close() ! lines.insert(0, '--- NEW FILE ---\n') except IOError, e: lines = ['***** Error reading new file: ', ! str(e)] elif newrev == 'NONE': lines = ['--- %s DELETED ---\n' % file] --- 110,183 ---- DIFF_TAIL_LINES = 20 DIFF_TRUNCATE_IF_LARGER = 1000 + EMPTYSTRING = '' + SPACE = ' ' + DOT = '.' + COMMASPACE = ', ' ! PROGRAM = sys.argv[0] ! ! BINARY_EXPLANATION_LINES = [ ! "(This appears to be a binary file; contents omitted.)\n" ! ] ! ! REVCRE = re.compile("^(NONE|[0-9.]+)$") ! NOVERSION = "Couldn't generate diff; no version number found in filespec: %s" ! BACKSLASH = "Couldn't generate diff: backslash in filespec's filename: %s" ! ! def usage(code, msg=''): print __doc__ % globals() ! if msg: ! print msg ! sys.exit(code) + def calculate_diff(filespec, contextlines): + file, oldrev, newrev = string.split(filespec, ',') + # Make sure we can find a CVS version number + if not REVCRE.match(oldrev): + return NOVERSION % filespec + if not REVCRE.match(newrev): + return NOVERSION % filespec + if string.find(file, '\\') <> -1: + # I'm sorry, a file name that contains a backslash is just too much. + # XXX if someone wants to figure out how to escape the backslashes in + # a safe way to allow filenames containing backslashes, this is the + # place to do it. --Zooko 2002-03-17 + return BACKSLASH % filespec ! if string.find(file, "'") <> -1: ! # Those crazy users put single-quotes in their file names! Now we ! # have to escape everything that is meaningful inside double-quotes. ! filestr = string.replace(file, '`', '\`') ! filestr = string.replace(filestr, '"', '\"') ! filestr = string.replace(filestr, '$', '\$') ! # and quote it with double-quotes. ! filestr = '"' + filestr + '"' ! else: ! # quote it with single-quotes. ! filestr = "'" + file + "'" if oldrev == 'NONE': try: ! if os.path.exists(file): ! fp = open(file) ! else: ! update_cmd = "cvs -fn update -r %s -p %s" % (newrev, filestr) ! fp = os.popen(update_cmd) lines = fp.readlines() fp.close() ! # Is this a binary file? Let's look at the first few ! # lines to figure it out: ! for line in lines[:5]: ! for c in string.rstrip(line): ! if c in string.whitespace: ! continue ! if c < ' ' or c > chr(127): ! lines = BINARY_EXPLANATION_LINES[:] ! break ! lines.insert(0, '--- NEW FILE: %s ---\n' % file) except IOError, e: lines = ['***** Error reading new file: ', ! str(e), '\n***** file: ', file, ' cwd: ', os.getcwd()] elif newrev == 'NONE': lines = ['--- %s DELETED ---\n' % file] *************** *** 98,103 **** # This /has/ to happen in the background, otherwise we'll run into CVS # lock contention. What a crock. ! diffcmd = '/usr/bin/cvs -f diff -kk -u -r %s -r %s %s' % ( ! oldrev, newrev, file) fp = os.popen(diffcmd) lines = fp.readlines() --- 185,194 ---- # This /has/ to happen in the background, otherwise we'll run into CVS # lock contention. What a crock. ! #if contextlines > 0: ! # difftype = "-C " + str(contextlines) ! #else: ! difftype = "-u" ! diffcmd = "/usr/bin/cvs -f diff -kk %s --minimal -r %s -r %s %s" \ ! % (difftype, oldrev, newrev, filestr) fp = os.popen(diffcmd) lines = fp.readlines() *************** *** 106,124 **** ## if sts: ## return 'Error code %d occurred during diff\n' % (sts >> 8) ! ## ! ##--------------------------------------------------------------- ! ## ALL LINES TO BE Printed. Doesn't matter how large is the diff ! ##--------------------------------------------------------------- ! ## ! ## if len(lines) > DIFF_TRUNCATE_IF_LARGER: ! ## removedlines = len(lines) - DIFF_HEAD_LINES - DIFF_TAIL_LINES ! ## del lines[DIFF_HEAD_LINES:-DIFF_TAIL_LINES] ! ## lines.insert(DIFF_HEAD_LINES, ! ## '[...%d lines suppressed...]\n' % removedlines) return string.join(lines, '') ! ! ! def blast_mail(mailcmd, filestodiff): # cannot wait for child process or that will cause parent to retain cvs # lock for too long. Urg! --- 197,208 ---- ## if sts: ## return 'Error code %d occurred during diff\n' % (sts >> 8) ! if len(lines) > DIFF_TRUNCATE_IF_LARGER: ! removedlines = len(lines) - DIFF_HEAD_LINES - DIFF_TAIL_LINES ! del lines[DIFF_HEAD_LINES:-DIFF_TAIL_LINES] ! lines.insert(DIFF_HEAD_LINES, ! '[...%d lines suppressed...]\n' % removedlines) return string.join(lines, '') ! def blast_mail(subject, people, filestodiff, contextlines, fromhost): # cannot wait for child process or that will cause parent to retain cvs # lock for too long. Urg! *************** *** 127,151 **** # give up the lock you cvs thang! time.sleep(2) ! fp = os.popen(mailcmd, 'w') ! fp.write(sys.stdin.read()) ! fp.write('\n') ! # append the diffs if available ! for file in filestodiff: ! fp.write(calculate_diff(file)) ! fp.write('\n') ! fp.close() ! # doesn't matter what code we return, it isn't waited on os._exit(0) - - # scan args for options def main(): try: ! opts, args = getopt.getopt(sys.argv[1:], 'h', ['cvsroot=', 'help']) except getopt.error, msg: usage(1, msg) # parse the options for opt, arg in opts: if opt in ('-h', '--help'): --- 211,255 ---- # give up the lock you cvs thang! time.sleep(2) ! # Create the smtp connection to the localhost ! conn = smtplib.SMTP() ! conn.connect(MAILHOST, MAILPORT) ! user = pwd.getpwuid(os.getuid())[0] ! domain = fromhost or getfqdn() ! author = '%s@%s' % (user, domain) ! s = StringIO() ! sys.stdout = s ! try: ! print '''\ ! From: %(author)s ! To: %(people)s ! Subject: %(subject)s ! ''' % {'author' : author, ! 'people' : string.join(people, COMMASPACE), ! 'subject': subject, ! } ! s.write(sys.stdin.read()) ! # append the diffs if available ! print ! for file in filestodiff: ! print calculate_diff(file, contextlines) ! finally: ! sys.stdout = sys.__stdout__ ! resp = conn.sendmail(author, people, s.getvalue()) ! conn.close() os._exit(0) # scan args for options def main(): try: ! opts, args = getopt.getopt( ! sys.argv[1:], 'hC:cuqf:', ! ['fromhost=', 'context=', 'cvsroot=', 'help', 'quiet']) except getopt.error, msg: usage(1, msg) # parse the options + contextlines = 2 + verbose = 1 + fromhost = None for opt, arg in opts: if opt in ('-h', '--help'): *************** *** 153,156 **** --- 257,271 ---- elif opt == '--cvsroot': os.environ['CVSROOT'] = arg + elif opt in ('-C', '--context'): + contextlines = int(arg) + elif opt == '-c': + if contextlines <= 0: + contextlines = 2 + elif opt == '-u': + contextlines = 0 + elif opt in ('-q', '--quiet'): + verbose = 0 + elif opt in ('-f', '--fromhost'): + fromhost = arg # What follows is the specification containing the files that were *************** *** 160,164 **** if not args: usage(1, 'No CVS module specified') ! SUBJECT = args[0] specs = string.split(args[0]) del args[0] --- 275,279 ---- if not args: usage(1, 'No CVS module specified') ! subject = args[0] specs = string.split(args[0]) del args[0] *************** *** 169,189 **** # Now do the mail command ! PEOPLE = string.join(args) ! mailcmd = MAILCMD % vars() - print 'Mailing %s...' % PEOPLE if specs == ['-', 'Imported', 'sources']: return if specs[-3:] == ['-', 'New', 'directory']: del specs[-3:] ! blast_mail(mailcmd, specs[1:]) ! if __name__ == '__main__': - print 'Running syncmail...' main() - print '...syncmail done.' sys.exit(0) - - --- 284,313 ---- # Now do the mail command ! people = args ! ! if verbose: ! print 'Mailing %s...' % string.join(people, COMMASPACE) if specs == ['-', 'Imported', 'sources']: return if specs[-3:] == ['-', 'New', 'directory']: del specs[-3:] ! elif len(specs) > 2: ! L = specs[:2] ! for s in specs[2:]: ! prev = L[-1] ! if string.count(prev, ',') < 2: ! L[-1] = "%s %s" % (prev, s) ! else: ! L.append(s) ! specs = L + if verbose: + print 'Generating notification message...' + blast_mail(subject, people, specs[1:], contextlines, fromhost) + if verbose: + print 'Generating notification message... done.' if __name__ == '__main__': main() sys.exit(0) |