17078Smjnelson#! /usr/bin/python 27078Smjnelson# 37078Smjnelson# CDDL HEADER START 47078Smjnelson# 57078Smjnelson# The contents of this file are subject to the terms of the 67078Smjnelson# Common Development and Distribution License (the "License"). 77078Smjnelson# You may not use this file except in compliance with the License. 87078Smjnelson# 97078Smjnelson# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107078Smjnelson# or http://www.opensolaris.org/os/licensing. 117078Smjnelson# See the License for the specific language governing permissions 127078Smjnelson# and limitations under the License. 137078Smjnelson# 147078Smjnelson# When distributing Covered Code, include this CDDL HEADER in each 157078Smjnelson# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167078Smjnelson# If applicable, add the following below this CDDL HEADER, with the 177078Smjnelson# fields enclosed by brackets "[]" replaced with your own identifying 187078Smjnelson# information: Portions Copyright [yyyy] [name of copyright owner] 197078Smjnelson# 207078Smjnelson# CDDL HEADER END 217078Smjnelson# 227078Smjnelson 237078Smjnelson# 247078Smjnelson# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 257078Smjnelson# Use is subject to license terms. 267078Smjnelson# 277078Smjnelson 287078Smjnelson# 297078Smjnelson# Various database lookup classes/methods, i.e.: 307078Smjnelson# * monaco 317078Smjnelson# * bugs.opensolaris.org (b.o.o.) 327078Smjnelson# * opensolaris.org/cgi/arc.py (for ARC) 337078Smjnelson# 347078Smjnelson 357078Smjnelsonimport re 367078Smjnelsonimport urllib 378042SJohn.Sonnenschein@Sun.COMimport urllib2 387078Smjnelsonimport htmllib 397078Smjnelsonimport os 407078Smjnelsonfrom socket import socket, AF_INET, SOCK_STREAM 417078Smjnelson 427078Smjnelsonfrom onbld.Checks import onSWAN 437078Smjnelson 447078Smjnelsonclass BugException(Exception): 457078Smjnelson def __init__(self, data=''): 467078Smjnelson self.data = data 477078Smjnelson Exception.__init__(self, data) 487078Smjnelson 497078Smjnelson def __str__(self): 507078Smjnelson return "Unknown error: %s" % self.data 517078Smjnelson 527078Smjnelsonclass NonExistentBug(BugException): 537078Smjnelson def __str__(self): 547078Smjnelson return "Bug %s does not exist" % self.data 557078Smjnelson 568042SJohn.Sonnenschein@Sun.COMclass BugDBException(Exception): 578042SJohn.Sonnenschein@Sun.COM def __init__(self, data=''): 588042SJohn.Sonnenschein@Sun.COM self.data = data 598042SJohn.Sonnenschein@Sun.COM Exception.__init__(self, data) 607078Smjnelson 618042SJohn.Sonnenschein@Sun.COM def __str__(self): 628042SJohn.Sonnenschein@Sun.COM return "Unknown bug database: %s" % self.data 637078Smjnelson 647078Smjnelsonclass BugDB(object): 657078Smjnelson """Lookup change requests. 667078Smjnelson 677078Smjnelson Object can be used on or off of SWAN, using either monaco or 687078Smjnelson bugs.opensolaris.org as a database. 697078Smjnelson 707078Smjnelson Usage: 717078Smjnelson bdb = BugDB() 727078Smjnelson r = bdb.lookup("6455550") 737078Smjnelson print r["6455550"]["synopsis"] 747078Smjnelson r = bdb.lookup(["6455550", "6505625"]) 757078Smjnelson print r["6505625"]["synopsis"] 767078Smjnelson """ 777078Smjnelson 788042SJohn.Sonnenschein@Sun.COM def __init__(self, priority = ("bugster",), forceBoo = False): 797078Smjnelson """Create a BugDB object. 807078Smjnelson 817078Smjnelson Keyword argument: 827078Smjnelson forceBoo: use b.o.o even from SWAN (default=False) 838042SJohn.Sonnenschein@Sun.COM priority: use bug databases in this order 847078Smjnelson """ 858042SJohn.Sonnenschein@Sun.COM self.__validBugDB = ["bugster"] 868042SJohn.Sonnenschein@Sun.COM self.__onSWAN = not forceBoo and onSWAN() 878042SJohn.Sonnenschein@Sun.COM for database in priority: 888042SJohn.Sonnenschein@Sun.COM if database not in self.__validBugDB: 898042SJohn.Sonnenschein@Sun.COM raise BugDBException, database 908042SJohn.Sonnenschein@Sun.COM self.__priority = priority 918042SJohn.Sonnenschein@Sun.COM 928042SJohn.Sonnenschein@Sun.COM 938042SJohn.Sonnenschein@Sun.COM def __boobug(self, cr): 948042SJohn.Sonnenschein@Sun.COM cr = str(cr) 958042SJohn.Sonnenschein@Sun.COM url = "http://bugs.opensolaris.org/view_bug.do" 968042SJohn.Sonnenschein@Sun.COM req = urllib2.Request(url, urllib.urlencode({"bug_id": cr})) 978042SJohn.Sonnenschein@Sun.COM results = {} 988042SJohn.Sonnenschein@Sun.COM try: 998042SJohn.Sonnenschein@Sun.COM data = urllib2.urlopen(req).readlines() 1008042SJohn.Sonnenschein@Sun.COM except urllib2.HTTPError, e: 1018042SJohn.Sonnenschein@Sun.COM if e.code != 404: 1028042SJohn.Sonnenschein@Sun.COM print "ERROR: HTTP error at " + \ 1038042SJohn.Sonnenschein@Sun.COM req.get_full_url() + \ 1048042SJohn.Sonnenschein@Sun.COM " got error: " + str(e.code) 1058042SJohn.Sonnenschein@Sun.COM raise e 1068042SJohn.Sonnenschein@Sun.COM else: 1078042SJohn.Sonnenschein@Sun.COM raise NonExistentBug 1088042SJohn.Sonnenschein@Sun.COM except urllib2.URLError, e: 1098042SJohn.Sonnenschein@Sun.COM print "ERROR: could not connect to " + \ 1108042SJohn.Sonnenschein@Sun.COM req.get_full_url() + \ 1118042SJohn.Sonnenschein@Sun.COM ' got error: "' + e.reason[1] + '"' 1128042SJohn.Sonnenschein@Sun.COM raise e 1138042SJohn.Sonnenschein@Sun.COM htmlParser = htmllib.HTMLParser(None) 1148042SJohn.Sonnenschein@Sun.COM metaHtmlRe = re.compile(r'^<meta name="([^"]+)" content="([^"]*)">$') 1158042SJohn.Sonnenschein@Sun.COM for line in data: 1168042SJohn.Sonnenschein@Sun.COM m = metaHtmlRe.search(line) 1178042SJohn.Sonnenschein@Sun.COM if not m: 1188042SJohn.Sonnenschein@Sun.COM continue 1198042SJohn.Sonnenschein@Sun.COM val = urllib.unquote(m.group(2)) 1208042SJohn.Sonnenschein@Sun.COM htmlParser.save_bgn() 1218042SJohn.Sonnenschein@Sun.COM htmlParser.feed(val) 1228042SJohn.Sonnenschein@Sun.COM results[m.group(1)] = htmlParser.save_end() 1238042SJohn.Sonnenschein@Sun.COM htmlParser.close() 1248042SJohn.Sonnenschein@Sun.COM 1258042SJohn.Sonnenschein@Sun.COM if "synopsis" not in results: 1268042SJohn.Sonnenschein@Sun.COM raise NonExistentBug(cr) 1278042SJohn.Sonnenschein@Sun.COM 1288042SJohn.Sonnenschein@Sun.COM results["cr_number"] = cr 1298042SJohn.Sonnenschein@Sun.COM results["sub_category"] = results.pop("subcategory") 1308042SJohn.Sonnenschein@Sun.COM results["status"] = results.pop("state") 1318042SJohn.Sonnenschein@Sun.COM results["date_submitted"] = results.pop("submit_date") 1328042SJohn.Sonnenschein@Sun.COM 1338042SJohn.Sonnenschein@Sun.COM return results 1348042SJohn.Sonnenschein@Sun.COM 1358042SJohn.Sonnenschein@Sun.COM 1368042SJohn.Sonnenschein@Sun.COM def __monaco(self, crs): 1378042SJohn.Sonnenschein@Sun.COM """Return all info for requested change reports. 1388042SJohn.Sonnenschein@Sun.COM 1398042SJohn.Sonnenschein@Sun.COM Argument: 1408042SJohn.Sonnenschein@Sun.COM crs: list of change request ids 1418042SJohn.Sonnenschein@Sun.COM 1428042SJohn.Sonnenschein@Sun.COM Returns: 1438042SJohn.Sonnenschein@Sun.COM Dictionary, mapping CR=>dictionary, where the nested dictionary 1448042SJohn.Sonnenschein@Sun.COM is a mapping of field=>value 1458042SJohn.Sonnenschein@Sun.COM """ 1468042SJohn.Sonnenschein@Sun.COM 1478042SJohn.Sonnenschein@Sun.COM # 1488042SJohn.Sonnenschein@Sun.COM # We request synopsis last, and split on only 1498042SJohn.Sonnenschein@Sun.COM # the number of separators that we expect to 1508042SJohn.Sonnenschein@Sun.COM # see such that a | in the synopsis doesn't 1518042SJohn.Sonnenschein@Sun.COM # throw us out of whack. 1528042SJohn.Sonnenschein@Sun.COM # 1538042SJohn.Sonnenschein@Sun.COM monacoFields = [ "cr_number", "category", "sub_category", 1548042SJohn.Sonnenschein@Sun.COM "area", "release", "build", "responsible_manager", 1558042SJohn.Sonnenschein@Sun.COM "responsible_engineer", "priority", "status", "sub_status", 1568042SJohn.Sonnenschein@Sun.COM "submitted_by", "date_submitted", "synopsis" ] 1578042SJohn.Sonnenschein@Sun.COM cmd = [] 1588042SJohn.Sonnenschein@Sun.COM cmd.append("set What = cr." + ', cr.'.join(monacoFields)) 1598042SJohn.Sonnenschein@Sun.COM cmd.append("") 1608042SJohn.Sonnenschein@Sun.COM cmd.append("set Which = cr.cr_number in (" + ','.join(crs) +")") 1618042SJohn.Sonnenschein@Sun.COM cmd.append("") 1628042SJohn.Sonnenschein@Sun.COM cmd.append("set FinalClauses = order by cr.cr_number") 1638042SJohn.Sonnenschein@Sun.COM cmd.append("") 1648042SJohn.Sonnenschein@Sun.COM cmd.append("doMeta genQuery cr") 1658042SJohn.Sonnenschein@Sun.COM url = "http://hestia.sfbay.sun.com/cgi-bin/expert?format=" 1668042SJohn.Sonnenschein@Sun.COM url += "Pipe-delimited+text;Go=2;no_header=on;cmds=" 1678042SJohn.Sonnenschein@Sun.COM url += urllib.quote_plus("\n".join(cmd)) 1688042SJohn.Sonnenschein@Sun.COM results = {} 1698042SJohn.Sonnenschein@Sun.COM try: 1708042SJohn.Sonnenschein@Sun.COM data = urllib2.urlopen(url).readlines() 1718042SJohn.Sonnenschein@Sun.COM except urllib2.HTTPError, e: 1728042SJohn.Sonnenschein@Sun.COM print "ERROR: HTTP error at " + url + \ 1738042SJohn.Sonnenschein@Sun.COM " got error: " + str(e.code) 1748042SJohn.Sonnenschein@Sun.COM raise e 1758042SJohn.Sonnenschein@Sun.COM 1768042SJohn.Sonnenschein@Sun.COM except urllib2.URLError, e: 1778042SJohn.Sonnenschein@Sun.COM print "ERROR: could not connect to " + url + \ 1788042SJohn.Sonnenschein@Sun.COM ' got error: "' + e.reason[1] + '"' 1798042SJohn.Sonnenschein@Sun.COM raise e 1808042SJohn.Sonnenschein@Sun.COM for line in data: 1818042SJohn.Sonnenschein@Sun.COM line = line.rstrip('\n') 1828042SJohn.Sonnenschein@Sun.COM values = line.split('|', len(monacoFields) - 1) 1838042SJohn.Sonnenschein@Sun.COM v = 0 1848042SJohn.Sonnenschein@Sun.COM cr = values[0] 1858042SJohn.Sonnenschein@Sun.COM results[cr] = {} 1868042SJohn.Sonnenschein@Sun.COM for field in monacoFields: 1878042SJohn.Sonnenschein@Sun.COM results[cr][field] = values[v] 1888042SJohn.Sonnenschein@Sun.COM v += 1 1898042SJohn.Sonnenschein@Sun.COM return results 1907078Smjnelson 1917078Smjnelson def lookup(self, crs): 1927078Smjnelson """Return all info for requested change reports. 1937078Smjnelson 1947078Smjnelson Argument: 1957078Smjnelson crs: one change request id (may be integer, string, or list), 1967078Smjnelson or multiple change request ids (must be a list) 1977078Smjnelson 1987078Smjnelson Returns: 1997078Smjnelson Dictionary, mapping CR=>dictionary, where the nested dictionary 2007078Smjnelson is a mapping of field=>value 2017078Smjnelson """ 2028042SJohn.Sonnenschein@Sun.COM results = {} 2037078Smjnelson if not isinstance(crs, list): 2047078Smjnelson crs = [str(crs)] 2058042SJohn.Sonnenschein@Sun.COM for database in self.__priority: 2068042SJohn.Sonnenschein@Sun.COM if database == "bugster": 2078042SJohn.Sonnenschein@Sun.COM if self.__onSWAN: 2088042SJohn.Sonnenschein@Sun.COM results.update(self.__monaco(crs)) 2098042SJohn.Sonnenschein@Sun.COM # else we're off-swan and querying via boo, which we can 2108042SJohn.Sonnenschein@Sun.COM # only do one bug at a time 2118042SJohn.Sonnenschein@Sun.COM else: 2128042SJohn.Sonnenschein@Sun.COM for cr in crs: 2138042SJohn.Sonnenschein@Sun.COM cr = str(cr) 2148042SJohn.Sonnenschein@Sun.COM try: 2158042SJohn.Sonnenschein@Sun.COM results[cr] = self.__boobug(cr) 2168042SJohn.Sonnenschein@Sun.COM except NonExistentBug: 2178042SJohn.Sonnenschein@Sun.COM continue 2187078Smjnelson 2198042SJohn.Sonnenschein@Sun.COM # the CR has already been found by one bug database 2208042SJohn.Sonnenschein@Sun.COM # so don't bother looking it up in the others 2218042SJohn.Sonnenschein@Sun.COM for cr in crs: 2228042SJohn.Sonnenschein@Sun.COM if cr in results: 2238042SJohn.Sonnenschein@Sun.COM crs.remove(cr) 2248042SJohn.Sonnenschein@Sun.COM 2258042SJohn.Sonnenschein@Sun.COM return results 2268042SJohn.Sonnenschein@Sun.COM#################################################################### 2278042SJohn.Sonnenschein@Sun.COMdef ARC(arclist): 2288042SJohn.Sonnenschein@Sun.COM opts = {} 2298042SJohn.Sonnenschein@Sun.COM url = "http://opensolaris.org/cgi/arc.py" 2308042SJohn.Sonnenschein@Sun.COM opts["n"] = str(len(arclist)) 2318042SJohn.Sonnenschein@Sun.COM for i, arc in enumerate(arclist): 2328042SJohn.Sonnenschein@Sun.COM arc, case = arc 2338042SJohn.Sonnenschein@Sun.COM opts["arc" + str(i)] = arc 2348042SJohn.Sonnenschein@Sun.COM opts["case" + str(i)] = case 2358042SJohn.Sonnenschein@Sun.COM req = urllib2.Request(url, urllib.urlencode(opts)) 2368042SJohn.Sonnenschein@Sun.COM try: 2378042SJohn.Sonnenschein@Sun.COM data = urllib2.urlopen(req).readlines() 2388042SJohn.Sonnenschein@Sun.COM except urllib2.HTTPError, e: 239*8174SJohn.Sonnenschein@Sun.COM print "ERROR: HTTP error at " + req.get_full_url() + \ 2408042SJohn.Sonnenschein@Sun.COM " got error: " + str(e.code) 2418042SJohn.Sonnenschein@Sun.COM raise e 2427078Smjnelson 2438042SJohn.Sonnenschein@Sun.COM except urllib2.URLError, e: 244*8174SJohn.Sonnenschein@Sun.COM print "ERROR: could not connect to " + req.get_full_url() + \ 2458042SJohn.Sonnenschein@Sun.COM ' got error: "' + e.reason[1] + '"' 2468042SJohn.Sonnenschein@Sun.COM raise e 2478042SJohn.Sonnenschein@Sun.COM ret = {} 2488042SJohn.Sonnenschein@Sun.COM for line in data: 2498042SJohn.Sonnenschein@Sun.COM oneline = line.rstrip('\n') 2508042SJohn.Sonnenschein@Sun.COM fields = oneline.split('|') 2518042SJohn.Sonnenschein@Sun.COM # check if each is valid ( fields[0]::validity ) 2528042SJohn.Sonnenschein@Sun.COM if fields[0] != "0": 2538042SJohn.Sonnenschein@Sun.COM continue 2548042SJohn.Sonnenschein@Sun.COM arc, case = fields[1].split(" ") 2558042SJohn.Sonnenschein@Sun.COM ret[(arc, case)] = fields[2] 2568042SJohn.Sonnenschein@Sun.COM return ret 2577078Smjnelson 2587078Smjnelson#################################################################### 2597078Smjnelson 2607078Smjnelson# Pointers to the webrti server hostname & port to use 2617078Smjnelson# Using it directly is probably not *officially* supported, so we'll 2627078Smjnelson# have a pointer to the official `webrticli` command line interface 2637078Smjnelson# if using a direct socket connection fails for some reason, so we 2647078Smjnelson# have a fallback 2657078SmjnelsonWEBRTI_HOST = 'webrti.sfbay.sun.com' 2667078SmjnelsonWEBRTI_PORT = 9188 2677764SJohn.Sonnenschein@Sun.COMWEBRTICLI = '/net/onnv.sfbay.sun.com/export/onnv-gate/public/bin/webrticli' 2687078Smjnelson 2697078Smjnelson 2707078Smjnelsonclass RtiException(Exception): 2717078Smjnelson def __init__(self, data=''): 2727078Smjnelson self.data = data 2737078Smjnelson Exception.__init__(self, data) 2747078Smjnelson 2757078Smjnelson def __str__(self): 2767078Smjnelson return "Unknown error: %s" % self.data 2777078Smjnelson 2787078Smjnelsonclass RtiCallFailed(RtiException): 2797078Smjnelson def __str__(self): 2807078Smjnelson return "Unable to call webrti: %s" % self.data 2817078Smjnelson 2827078Smjnelsonclass RtiSystemProblem(RtiException): 2837078Smjnelson def __str__(self): 2847078Smjnelson return "RTI status cannot be determined: %s" % self.data 2857078Smjnelson 2867078Smjnelsonclass RtiIncorrectCR(RtiException): 2877078Smjnelson def __str__(self): 2887078Smjnelson return "Incorrect CR number specified: %s" % self.data 2897078Smjnelson 2907078Smjnelsonclass RtiNotFound(RtiException): 2917078Smjnelson def __str__(self): 2927078Smjnelson return "RTI not found: %s" % self.data 2937078Smjnelson 2947078Smjnelsonclass RtiNeedConsolidation(RtiException): 2957078Smjnelson def __str__(self): 2967078Smjnelson return "More than one consolidation has this CR: %s" % self.data 2977078Smjnelson 2987078Smjnelsonclass RtiBadGate(RtiException): 2997078Smjnelson def __str__(self): 3007078Smjnelson return "Incorrect gate name specified: %s" % self.data 3017078Smjnelson 3027078Smjnelsonclass RtiOffSwan(RtiException): 3037078Smjnelson def __str__(self): 3047078Smjnelson return "RTI status checks need SWAN access: %s" % self.data 3057078Smjnelson 3067078SmjnelsonWEBRTI_ERRORS = { 3077078Smjnelson '1': RtiSystemProblem, 3087078Smjnelson '2': RtiIncorrectCR, 3097078Smjnelson '3': RtiNotFound, 3107078Smjnelson '4': RtiNeedConsolidation, 3117078Smjnelson '5': RtiBadGate, 3127078Smjnelson} 3137078Smjnelson 3147078Smjnelson# Our Rti object which we'll use to represent an Rti query 3157078Smjnelson# It's really just a wrapper around the Rti connection, and attempts 3167078Smjnelson# to establish a direct socket connection and query the webrti server 3177078Smjnelson# directly (thus avoiding a system/fork/exec call). If it fails, it 3187078Smjnelson# falls back to the webrticli command line client. 3197078Smjnelson 3207078SmjnelsonreturnCodeRe = re.compile(r'.*RETURN_CODE=(\d+)') 3217078Smjnelsonclass Rti: 3227078Smjnelson """Lookup an RTI. 3237078Smjnelson 3247078Smjnelson Usage: 3257078Smjnelson r = Rti("6640538") 3267078Smjnelson print r.rtiNumber(); 3277078Smjnelson """ 3287078Smjnelson 3297078Smjnelson def __init__(self, cr, gate=None, consolidation=None): 3307078Smjnelson """Create an Rti object for the specified change request. 3317078Smjnelson 3327078Smjnelson Argument: 3337078Smjnelson cr: change request id 3347078Smjnelson 3357078Smjnelson Keyword arguments, to limit scope of RTI search: 3367078Smjnelson gate: path to gate workspace (default=None) 3377078Smjnelson consolidation: consolidation name (default=None) 3387078Smjnelson """ 3397078Smjnelson 3407078Smjnelson bufSz = 1024 3417078Smjnelson addr = (WEBRTI_HOST, WEBRTI_PORT) 3427078Smjnelson # If the passed 'cr' was given as an int, then wrap it 3437078Smjnelson # into a string to make our life easier 3447078Smjnelson if isinstance(cr, int): 3457078Smjnelson cr = str(cr) 3467078Smjnelson self.__queryCr = cr 3477078Smjnelson self.__queryGate = gate 3487078Smjnelson self.__queryConsolidation = consolidation 3497078Smjnelson 3507764SJohn.Sonnenschein@Sun.COM self.__webRtiOutput = [] 3517764SJohn.Sonnenschein@Sun.COM self.__mainCR = [] 3527764SJohn.Sonnenschein@Sun.COM self.__rtiNumber = [] 3537764SJohn.Sonnenschein@Sun.COM self.__consolidation = [] 3547764SJohn.Sonnenschein@Sun.COM self.__project = [] 3557764SJohn.Sonnenschein@Sun.COM self.__status = [] 3567764SJohn.Sonnenschein@Sun.COM self.__rtiType = [] 3577078Smjnelson try: 3587078Smjnelson # try to use a direct connection to the 3597078Smjnelson # webrti server first 3607078Smjnelson sock = socket(AF_INET, SOCK_STREAM) 3617078Smjnelson sock.connect(addr) 3627078Smjnelson command = "WEBRTICLI/1.0\nRTIstatus\n%s\n" % cr 3637078Smjnelson if consolidation: 3647078Smjnelson command += "-c\n%s\n" % consolidation 3657078Smjnelson if gate: 3667078Smjnelson command += "-g\n%s\n" % gate 3677078Smjnelson command += "\n" 3687078Smjnelson sock.send(command) 3697078Smjnelson dataList = [] 3707078Smjnelson # keep receiving data from the socket until the 3717078Smjnelson # server closes the connection 3727078Smjnelson stillReceiving = True 3737078Smjnelson while stillReceiving: 3747078Smjnelson dataPiece = sock.recv(bufSz) 3757078Smjnelson if dataPiece: 3767078Smjnelson dataList.append(dataPiece) 3777078Smjnelson else: 3787078Smjnelson stillReceiving = False 3797078Smjnelson # create the lines, skipping the first 3807078Smjnelson # ("WEBRTCLI/1.0\n") 3817078Smjnelson data = '\n'.join(''.join(dataList).split('\n')[1:]) 3827078Smjnelson except: 3837078Smjnelson if not onSWAN(): 3847078Smjnelson raise RtiOffSwan(cr) 3857078Smjnelson 3867078Smjnelson if not os.path.exists(WEBRTICLI): 3877078Smjnelson raise RtiCallFailed('not found') 3887078Smjnelson 3897078Smjnelson # fallback to the "supported" webrticli interface 3907078Smjnelson command = WEBRTICLI 3917078Smjnelson if consolidation: 3927078Smjnelson command += " -c " + consolidation 3937078Smjnelson if gate: 3947078Smjnelson command += " -g " + gate 3957078Smjnelson command += " RTIstatus " + cr 3967078Smjnelson 3977078Smjnelson try: 3987078Smjnelson cliPipe = os.popen(command) 3997078Smjnelson except: 4007078Smjnelson # we couldn't call the webrticli for some 4017078Smjnelson # reason, so return a failure 4027078Smjnelson raise RtiCallFailed('unknown') 4037078Smjnelson 4047078Smjnelson data = cliPipe.readline() 4057078Smjnelson 4067078Smjnelson # parse the data to see if we got a return code 4077078Smjnelson # if we did, then that's bad. if we didn't, 4087078Smjnelson # then our call was successfully 4097078Smjnelson m = returnCodeRe.search(data) 4107078Smjnelson if m: 4117078Smjnelson # we got a return code, set it in our 4127078Smjnelson # object, set the webRtiOutput for debugging 4137078Smjnelson # or logging, and return a failure 4147078Smjnelson if m.group(1) in WEBRTI_ERRORS: 4157078Smjnelson exc = WEBRTI_ERRORS[m.group(1)] 4167078Smjnelson else: 4177078Smjnelson exc = RtiException 4187078Smjnelson raise exc(data) 4197078Smjnelson 4207764SJohn.Sonnenschein@Sun.COM data = data.splitlines() 4217078Smjnelson # At this point, we should have valid data 4227764SJohn.Sonnenschein@Sun.COM for line in data: 4237764SJohn.Sonnenschein@Sun.COM line = line.rstrip('\r\n') 4247764SJohn.Sonnenschein@Sun.COM self.__webRtiOutput.append(line) 4257764SJohn.Sonnenschein@Sun.COM fields = line.split(':') 4267764SJohn.Sonnenschein@Sun.COM self.__mainCR.append(fields[0]) 4277764SJohn.Sonnenschein@Sun.COM self.__rtiNumber.append(fields[1]) 4287764SJohn.Sonnenschein@Sun.COM self.__consolidation.append(fields[2]) 4297764SJohn.Sonnenschein@Sun.COM self.__project.append(fields[3]) 4307764SJohn.Sonnenschein@Sun.COM self.__status.append(fields[4]) 4317764SJohn.Sonnenschein@Sun.COM self.__rtiType.append(fields[5]) 4327078Smjnelson 4337078Smjnelson # accessors in case callers need the raw data 4347078Smjnelson def mainCR(self): 4357078Smjnelson return self.__mainCR 4367078Smjnelson def rtiNumber(self): 4377078Smjnelson return self.__rtiNumber 4387078Smjnelson def consolidation(self): 4397078Smjnelson return self.__consolidation 4407078Smjnelson def project(self): 4417078Smjnelson return self.__project 4427078Smjnelson def status(self): 4437078Smjnelson return self.__status 4447078Smjnelson def rtiType(self): 4457078Smjnelson return self.__rtiType 4467078Smjnelson def queryCr(self): 4477078Smjnelson return self.__queryCr 4487078Smjnelson def queryGate(self): 4497078Smjnelson return self.__queryGate 4507078Smjnelson def queryConsolidation(self): 4517078Smjnelson return self.__queryConsolidation 4527078Smjnelson 4537078Smjnelson # in practice, most callers only care about the following 4547078Smjnelson def accepted(self): 4557764SJohn.Sonnenschein@Sun.COM for status in self.__status: 4567764SJohn.Sonnenschein@Sun.COM if status != "S_ACCEPTED": 4577764SJohn.Sonnenschein@Sun.COM return False 4587764SJohn.Sonnenschein@Sun.COM return True 4597078Smjnelson 4607078Smjnelson # for logging/debugging in case the caller wants the raw webrti output 4617078Smjnelson def webRtiOutput(self): 4627078Smjnelson return self.__webRtiOutput 4637078Smjnelson 464