0

我遇到了这个错误。有人可以建议这里有什么问题吗?

Traceback (most recent call last):
  File ".\move2ready.py", line 318, in <module>
    main()
  File ".\move2ready.py", line 268, in main
    success = moveToReady(prism, cr, pl_name)
  File ".\move2ready.py", line 153, in moveToReady
    retval = prism.saveChangeRequest(CR)
  File ".\move2ready.py", line 75, in saveChangeRequest
    request = self.soapclient.factory.create('ns4:SaveCRRequest')
  File "build\bdist.win32\egg\suds\client.py", line 234, in create
suds.TypeNotFound: Type not found: 'ns4:SaveCRRequest'

完整代码:

#!/usr/bin/env python2.6

'''
When moving Prism CRs to the Ready state, it becomes quite tedious when users have to modify the state from from Open to Analysis to Fix to Ready for each CR. It will be time-saving if we have just ONE command line utility program that is able to pull a list of CRs from any intermediate 
state, either Open or Analysis or Fix, and to Ready automatically.

Command line options:
    -h / --help show this help message and exit 
    -c / --cr (required) provide the list of CR numbers separated by space. 
    -o / --fo provide an output file whose content is a summary of the results.. 
    -p / --pl (required) provide the PL name. 
    -i / --fi (required if --cr is not specified) provide an input file which contains the list of CRs. 

How to use:
    Example 1:
        python .\move2ready.py --cr 320538 320899 --pl MSM0000.NA.0.0
    Example 2:
        python .\move2ready.py --fi ./cr.txt --fo ./out.txt --pl MSM0000.NA.0.0
        Note: A typical cr.txt can be:
                 CR320538 
                 CR320899 
                 CR321167 
                 CR322928
'''

import datetime
import sys
import logging
import re
import getpass
from time import strftime as date
from optparse import OptionParser

try: 
  import suds
  from suds.client import Client
  from suds.transport import http
  from suds.transport.https import WindowsHttpAuthenticated
except ImportError:
  print '''###### ERROR ######  
One or more prerequisite packages are missing.
Please install SUDS and NTLM Python packages before running this script.

To install SUDS and NTLM:
  1. Find and install the correct version of Python SetupTools. (http://pypi.python.org/pypi/setuptools)
  2. Copy the source files for SUDS and NTLM to a local directory (http://http://pypi.python.org)
  3. For both SUDS and NTLM, cd into THE local directory, and run " Python setup.py install "
  4. Close all command prompts and open a new one. That's it. :)

move2ready.py terminated!
'''

class Prism:
  def __init__(self, url, q_user, q_passwd):
    self.url = url
    user = q_user
    user = user.rstrip()
    passwd = q_passwd
    passwd = passwd.rstrip()

    try:
      self.soapclient = Client(url, transport=WindowsHttpAuthenticated(username=user, password=passwd))
      request = self.soapclient.factory.create('ns2:CRRequest')
    except:
      print 'Prism authentication failed!'
      sys.exit()

  def getChangeRequestById(self, key):
    request = self.soapclient.factory.create('ns2:CRRequest') 
    request['ChangeRequestId'] = key
    response = self.soapclient.service.GetChangeRequestById([request])
    return response['ChangeRequest']

  def saveChangeRequest(self, CR):
    request = self.soapclient.factory.create('ns4:SaveCRRequest')
    request['ChangeRequest'] = CR
    request['UserName'] = 'admin'
    response = self.soapclient.service.SaveChangeRequest([request])
    return response['ChangeRequestId']

  def editObject(self, obj, **kwargs):
    for key, value in kwargs.iteritems():
      if key in obj:
        obj[key] = value
    return obj

  def updateChangeRequest(self, CR, **kwargs):
    newCR=editObject(CR, kwargs)
    saveChangeRequest(newCR)

  def updateChangeRequestById(self, CRkey, **kwargs):
    CR = getChangeRequestById(CRkey)
    return updateChangeRequest(CR, kwargs)
# end of Prism class

# Find the index of specified PL name among all PL names associated with this CR
def findTargetPlIndex(PL_all, pl_name, attr_name):
  target_index = 0
  for pl in PL_all:
    if (pl[attr_name].lower() == pl_name.lower()):
      return target_index
    target_index += 1
  print "[ERROR] The specified PL name is not found in this CR."
  exit(-1)
# end of findTargetPlIndex

# When one move is performed, add some auto-generated text as Analysis Text
def addAnalysisText(CR, text):
  if CR['Analysis'] == None:
    CR['Analysis'] = []
    CR['Analysis'].append({'Text':"Analyzed by move2ready tool"}) 
  #else:
    #CR['Analysis']['Text'] += "\n\n" + text  
    #CR['Analysis']['Text'] += "\n\n" +
# end of addAnalysisText

def moveToReady(prism, cr_id, pl_name):
  print "======================================"
  print "Start processing CR:" + cr_id + "..."

  CR = prism.getChangeRequestById(cr_id)
  PL_all = CR['ProductLines']['ProductLineEntity']
  PL_index = findTargetPlIndex(PL_all, pl_name, 'ProductLineName')
  PL = PL_all[PL_index]

  # Move from open to analysis
  if PL['Status'] == "Open":
    print "Moving from Open to Analysis..."
    PL['Status'] = "Analysis"
    PL['AnalysisDueDate'] = datetime.datetime.today()
    PL['Priority'] = "2"
    retval = prism.saveChangeRequest(CR)

  CR = prism.getChangeRequestById(cr_id)
  PL = CR['ProductLines']['ProductLineEntity'][PL_index]

  # Move from analysis to fix
  if PL['Status'] == "Analysis":
    print "Moving from Analysis to fix..."
    PL['Status'] = "Fix"
    addAnalysisText(CR, "move2ready utility moved this CR to Fix")
    PL['ReadyDate'] = datetime.datetime.today() # required field
    retval = prism.saveChangeRequest(CR)

  CR = prism.getChangeRequestById(cr_id)
  PL = CR['ProductLines']['ProductLineEntity'][PL_index]

  # Move from Fix to Ready
  if PL['Status'] == "Fix":
    print "Moving from Fix to Ready..."
    PL['Status'] = "Ready"
    addAnalysisText(CR, "move2ready utility moved this CR to Ready")
    retval = prism.saveChangeRequest(CR)

  CR = prism.getChangeRequestById(cr_id)
  PL = CR['ProductLines']['ProductLineEntity'][PL_index]

  CR = prism.getChangeRequestById(cr_id)
  PL = CR['ProductLines']['ProductLineEntity'][PL_index]
  if PL['Status'] == "Ready":
    return True
  else:
    return False
# end of moveToReady 

# Handle variable number of arguments for an option
def vararg_callback(option, opt_str, value, parser):
  assert value is None
  value = []

  def floatable(str):
    try:
      float(str)
      return True
    except ValueError:
      return False

  for arg in parser.rargs:
    if arg[:2] == "--" and len(arg) > 2:
      break
    if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
      break
    value.append(arg)

  del parser.rargs[:len(value)]
  setattr(parser.values, option.dest, value)
# end of vararg_callback method

def handleCommandArgs():
  desc = 'move2ready tool helps Prism users to move one or multiple CRs to Ready state automatically.'
  usage = 'Python move2ready.py [options], version=1.0.0'
  parser = OptionParser(description=desc, usage=usage)

  parser.add_option('-c', '--cr', \
            dest='cr', \
            help='provide the list of CR numbers separated by space. E.g. --cr 320899 330022', \
            action='callback', \
            callback=vararg_callback)

  parser.add_option('-i', '--fi', \
            dest='fi', \
            help='provide an input file which contains the list of CRs you want to move. ', \
            action='store')

  parser.add_option('-o', '--fo', \
            dest='fo', \
            help='provide an output file whose content is a summary of the results.', \
            action='store')

  parser.add_option('-p', '--pl', \
            dest='pl', \
            help='provide the PL name. E.g. --pl MPSS.NI.2.0',\
            action='store')

  (options, args) = parser.parse_args()

  if not (options.fi or options.cr):
    parser.error('No action requested, you must add "--cr" or "--fi" as argument.\n')
    exit(1)

  if not options.pl:
    parser.error('No action requested, you must add "--pl" as argument.\n')
    exit(1)

  return options
# end of handleCommandArgs

#extract pure numeric CR values   
def getCRFromFile(cr_list):
  clean_cr_list = []
  for cr in cr_list:
    clean_cr_list.append(re.findall(r'\d+', cr)[-1])

  return clean_cr_list
# end of getCRFromFile

def main():
  options      = handleCommandArgs()
  file_in      = options.fi
  file_out     = options.fo
  cr_list      = options.cr
  pl_name      = options.pl

  # Use fi option to parse file-in which has cr lists
  if cr_list == None:
       f = open(file_in)
       cr_list = f.readlines()
       cr_list = getCRFromFile(cr_list)
       f.close()

  # Use fo option to parse file-out which saves the echo info
  echo_to_file = False if file_out == None else True
  if echo_to_file:
    f = open(file_out, 'a+')
    f.write('\n=====================================\n')
    f.write(str(date('%Y-%m-%d %H:%M:%S')))
    f.write('\n')
    f.close()

  username = raw_input('Enter your QualPass username (e.g. NA\jsmith): ')
  password = getpass.getpass()
  url = 'http://prism:8000/ChangeRequestWebService.svc?wsdl';
  prism = Prism(url, username, password)

  for cr in cr_list:
    try:
      result_log = ''
      success = moveToReady(prism, cr, pl_name)
      if success:
        result_log = '[CR: ' + cr + '] ' + 'Successfully moved to Ready.\n'; 
        print '''     
              .______      ___           _______.     _______.
              |   _  \    /   \         /       |    /       |
              |  |_)  |  /  ^  \       |   (----`   |   (----`
              |   ___/  /  /_\  \       \   \        \   \    
              |  |     /  _____  \  .----)   |   .----)   |   
              | _|    /__/     \__\ |_______/    |_______/    

        '''
      else:
        result_log = '[CR: ' + cr + '] ' + 'Failed to move to Ready\n';   
        print '''
               _______    ___       __   __      
              |   ____|  /   \     |  | |  |     
              |  |__    /  ^  \    |  | |  |     
              |   __|  /  /_\  \   |  | |  |     
              |  |    /  _____  \  |  | |  `----.
              |__|   /__/     \__\ |__| |_______|

        '''

      if echo_to_file:
        f = open(file_out, 'a+')
        f.write(result_log)
        f.close()
      else:
        print result_log

    except suds.WebFault as detail:
        print '[CR: ' + cr + '] ',
        print detail
        print '''
               _______    ___       __   __      
              |   ____|  /   \     |  | |  |     
              |  |__    /  ^  \    |  | |  |     
              |   __|  /  /_\  \   |  | |  |     
              |  |    /  _____  \  |  | |  `----.
              |__|   /__/     \__\ |__| |_______|

        '''

    if echo_to_file:
        f = open(file_out, 'a+')
        f.write(result_log)
        f.close()

if __name__ == '__main__':
  main()
4

1 回答 1

1

这条线好像有问题

request = self.soapclient.factory.create('ns4:SaveCRRequest')

我的猜测是该ns4:SaveCRRequest对象不存在于

http://prism:8000/ChangeRequestWebService.svc?wsdl

网络服务。

于 2012-12-21T05:11:52.270 回答