# This program can be configured to be a personal # review daemon. # A more general review daemon may be found on the # Perforce website at: # http://www.perforce.com/perforce/loadsupp.html#daemon # I have this one set up to # look for jobs modified or created with # Subsystem: p4dti selected. # The field Subsystem was created by using # 'p4 jobspec' and modifying the jobs form. # This uses the logger function and -G to # create a python marshalled dictionary. # Module functions, from the bottom up, when an email is generated. # '__main__' # Repeat polling or run once. # calls 'dowork.' # Updates the counter jobsequence if necessary. # calls 'selectjob' # Looks for match of search criteria. # calls 'makemessage' # Generated an email message from the job contents. # calls 'sendmail' # Sends message to recipient. # Gerry Thompson Python Class Perforce Software 2002 # Version 1.3 import os, string, time, marshal fieldname = 'Subsystem:' # This is a field in the jobspec. fieldvalue = 'p4dti' # I am looking only for 'p4dti' jobs. p4port = 'localhost:1666' # This is a Perforce server. p4user = 'bruno' # Perforce user name to use. p4password = 'apassword' # If user has a password, include in p4 below. p4path = 'p4' # Path to p4 executable. admin = 'myname+admin@perforce.com' # My 'From' address for email. to = 'myname@perforce.com' # My email address. mailhost = 'mailserver' # SMTP mail host name. repeat = 1 # Repeat of 0 will run once, sleeptime = 100 # otherwise repeat after sleeptime, in seconds. p4 = p4path + ' -u'+ p4user + ' -p' + p4port # + ' -P ' + p4password def sendmail(fromaddress, toaddress, message): from smtplib import SMTP fullmessage = 'From: '+ fromaddress + '\r\nTo: '+ toaddress +\ '\r\nSubject: ' + message server = SMTP(mailhost) server.sendmail(fromaddress,toaddress, fullmessage) # Use the python mail script. server.quit() def makemessage(onejob): message = 'A job has been submitted to the '+ fieldvalue + ' subsystem.' + '\n' + '\n' # This first line will be the subject line of the email. for aline in os.popen(p4 + ' job -o ' + onejob,'r').readlines(): if aline[0] != '#': # Do not include comments. if aline[0] != '\n': # Do not include spaces. message = message + aline # print message # Print the message instead of mailing it. sendmail(admin, to, message) # If a mail server is installed uncomment to send the mail. def selectjob (singlejob): for aline in os.popen(p4 + ' job -o ' + singlejob,'r').readlines(): # Output the job. if aline[0] != '#': # Skip comment lines in jobs output. if aline[0] != '\n': # skip blank lines in jobs output. list = string.split(aline, ) # Create a list, breaking on spaces. if len(list) > 1: # If the list isn't empty if list[0] == fieldname: # Select jobs by fieldname of 'Subsystem:'. if list[1] == fieldvalue: # Select jobs by fieldvalue of 'p4dti'. makemessage(singlejob) # Create a message. else: break # Stop searching if there is no match. def findjobs(): update = 0 oldjobs = os.popen(p4 + ' counter jobsequence', 'r') # What is the last sequence number processed? startcounter = oldjobs.readline() # Get the number as a string. beginningcounter = int(startcounter) # Convert the string to an integer. latestcounter = os.popen(p4 + ' counter logger', 'r')# What is the current sequence number? currentcounter = latestcounter.readline() # Get the number as a string. endcounter = int(currentcounter) # Convert the string to an integer. while beginningcounter < endcounter: # Go through all events the logger logged. update = 1 joblist = os.popen(p4 + ' -G logger -c '+ str(endcounter) ,'r') # get a report from logger of what jobdict = marshal.load(joblist) # events took place in dictionary format. # for key in jobdict.keys(): These two lines will list keys # print "%s: %s" % (key,jobdict[key]) and values. # The next part looks for a key called 'job'. The value will be the job name. if jobdict['key'] == 'job': # Look for a key called 'job'. job = jobdict['attr'] # If key 'job' found give job the jobname. selectjob(job) endcounter = endcounter - 1 return update # Does the jobsequence counter need to be updated? def dowork(): if findjobs(): latest = os.popen(p4 + ' counter logger', 'r') # Get p4 output of the logger sequence number.. update = latest.readline() # Number is retrieved. os.system(p4 + ' counter jobsequence '+ update) # My counter gets the update. if __name__ == '__main__': while (repeat): dowork() time.sleep(sleeptime) else: dowork()