#!/usr/bin/env python # Christopher Jones # 06/16/2013 # getcvn.py # grabs the cvn when provided the partnumber import mechanize, cookielib, urllib, urllib2, BeautifulSoup, string, re, sys, getopt def SetupBrowser(): ## Initialize settings ## # Browser br = mechanize.Browser() # Cookie Jar cj = cookielib.LWPCookieJar() br.set_cookiejar(cj) # Browser options br.set_handle_equiv(True) #br.set_handle_gzip(True) br.set_handle_redirect(True) br.set_handle_referer(True) br.set_handle_robots(False) # Follows refresh 0 but not hangs on refresh > 0 br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=10) # User-Agent (this is cheating, ok?) br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')] ########################### return br def ProcessPage(html): soup = BeautifulSoup.BeautifulSoup(html) return soup def AppendFile(fileName,DataA,DataB): with open(fileName, "a") as myFile: myFile.write("\r\n{0}\t{1}".format(DataA,DataB)) def main(argv): partNumber = '' proxyServer = '' outputFile = '' verbose = 0 usage = "Usage: getcvn.py [-p partnumber] [-P proxy server Hostname] [-o Output file]\n\ Command Summary:\n\ -h\t\tHelp (View Usage)\n\ -o file\t\tSpecify output filename and location*\n\ -p partnumber\tGM OS Partnumber\n\ -P addr:port\tSpecify proxy address and port**\n\ -v\t\tVerbose\n\n\ * If output file is not specified then output will be stdout.\n\ ** Proxy-server is optional\n\ ex: getcvn.py -p 12639835 -P 99.88.250.22:8118 -o /home/out.txt" try: opts, args = getopt.getopt(argv,"hvp:P:o:",["partNumber=","proxyServer=","outputFile="]) except getopt.GetoptError: print "Invalid arguments!" print usage sys.exit(1) for opt, arg in opts: if opt == '-h': print usage sys.exit() elif opt in ("-p", "--partnumber"): partNumber = arg elif opt in ("-P", "--proxy-server"): proxyServer = arg elif opt in ("-o", "--ofile"): outputFile = arg elif opt in ("-v", "--verbose"): verbose = 1 if partNumber == '': print "No GM OS Partnumber Supplied!\nPlease Provide a Partnumber" print usage sys.exit(1) br = SetupBrowser() if proxyServer != '': br.set_proxies({'http': proxyServer}) if verbose == 1: br.set_debug_http(True) br.set_debug_redirects(True) br.set_debug_responses(True) # Open Website url = 'http://tis2web.service.gm.com/tis2web' try: r = br.open(url) except IOError, e: if hasattr(e, 'reason'): if proxyServer: print 'We failed to reach a server. Proxy may be down.' else: print 'We failed to reach a server.' print 'Reason: ', e.reason sys.exit(3) elif hasattr(e, 'code'): print 'The server couldn\'t fulfill the request.' print 'Error code: ', e.code sys.exit(3) # Read the Page soup = ProcessPage(br.response().read()) if verbose == 1: print soup # Get ID Data for Post ## Pull Form Action forms = soup.findAll("form") # Validate Data if not forms: print 'Unable to find: form data for page!' sys.exit(3) for form in forms: if (form['action']): postMessage = (form['action']) ## Pull Input Field IDs inputFields = soup.findAll("input") # Validate Data if not inputFields: print 'Unable to find: form input fields for page!' sys.exit(3) inputFieldIDs = [] for inputField in inputFields: if (inputField['name']): inputFieldIDs.append(inputField['name']) ## Pull Button Data for 'Get CVN' formButtons = soup.findAll("button") if not formButtons: print 'Unable to find: button data for page!' sys.exit(3) for button in formButtons: if (button['onclick']): buttonSubmitData = (button['onclick']) ## Extract ID from Data buttonID = re.findall(r"'([A-Z]\w*)'", buttonSubmitData) # Setup Post Data postURL = "{0}{1}&{2}=1&bm={3}#{3}".format(url,postMessage,buttonID[0],buttonID[1]) sendData = "{0}=&{1}={2}".format(inputFieldIDs[0],inputFieldIDs[1],partNumber) try: res = br.open(postURL, sendData) except IOError, e: if hasattr(e, 'reason'): print 'We failed to reach a server.' print 'Reason: ', e.reason elif hasattr(e, 'code'): print 'The server couldn\'t fulfill the request.' print 'Error code: ', e.code else: responseHTML = res.read() # print responseHTML soup = ProcessPage(responseHTML) # Pull CVN CVNData = soup.findAll('br', text = re.compile(r"sps-nao-nao")) if not CVNData: print 'No CVN Found For {0}'.format(partNumber) sys.exit(2) else: CVNChecksum = re.split(r" ([0-9A-Z]\w*) ", CVNData[0]) if outputFile != '': AppendFile(outputFile,partNumber,CVNChecksum[1]) else: print CVNChecksum[1] sys.exit(0) if __name__ == "__main__": main(sys.argv[1:])