def new(self, **kwargs): """Opens new bug It automatically generates bug_url from product as bugzilla wants product name in GET response Args: product: Product name in the site component: Component name in bugzilla page security: Whether it is security vulnerability url: External url status: Initial but status. (NEW, RESOLVED) assigned_to: Email address to assign alias: Bug alias (NOT IMPLEMENTED) blocks: Bugs that this bug blocks dependson: Bug that depends on. cc: E-mail addresses to CC Returns: Integer indicating the bugzilla id for new bug Raises: BugzillaError: Required arguments are not provided """ log = logging.getLogger("bugzilla.NEW") args = BugStruct(**kwargs) # control required vars if not (args.has("component") and args.has("product") and args.has("title") and args.has("description")): raise BugzillaError( "Missing argument. Component, Product, Title and Description are needed" ) bug_url = self.constants.get_new_bug_url(args.product) log.debug("Opening new bug page") self.browser.open(bug_url) log.debug("Selecting form name: Create") self.browser.select_form(name="Create") log.debug("Adding component, title and comment") self.browser["component"] = [args.component] self.browser["short_desc"] = args.title self.browser["comment"] = args.description if args.has("url"): log.debug("URL: %s" % args.url) self.browser["bug_file_loc"] = args.url if args.has("security"): log.debug("Security: 1") self.browser["bit-10"] = ["1"] if args.has("status"): log.debug("Bug_status: %s" % args.status) self.browser["bug_status"] = [args.status] if args.has("assigned_to"): log.debug("Assign: %s" % args.assigned_to) self.browser["assigned_to"] = args.assigned_to if args.has("dependson"): log.debug("Depends on: %s" % args.dependson) self.browser["dependson"] = args.dependson if args.has("blocks"): log.debug("Blocks: %s" % args.blocks) self.browser["blocked"] = args.blocks if args.has("version"): log.debug("Version: %s" % args.version) self.browser["version"] = [args.version] if args.has("cc"): log.debug("CC: %s" % args.cc) self.browser["cc"] = args.cc # FIXME: Our bugzilla page doesn't show alias field. # FIXME: Uncomment it when it is done # if args.has("alias"): # self.browser["alias"] = args.alias response = self.browser.submit() response = response.read() log.info("Bug submitted") # get bug id. re_compile = re.compile("Bug (.*?) Submitted") bug_id = re.findall(re_compile, response) if len(bug_id) != 0: return bug_id[0] else: log.error("Wohoops. Unexpected data returned after submitting.") return False
def modify(self, **kwargs): # TODO: Implement Product/Component/CC list """Modifies the bug. All arguments can be supplied. This function modifies the form on the page and submits just like an ordinary browser does. Args: bug_id: Bug id to edit title: New bug title comment: Comment to write status: Status (NEW, ASSIGNED, RESOLVED) resolution: (FIXED, INVALID, WONTFIX, LATER, REMIND, DUPLICATE) security: Whether it is security or not assigned_to: E-mail address to assign a bug blocks: Bugs that this bug blocks dependson: Bug that depends on. cc: Add e-mail address to cc list Raises: BugzillaError: You should first login to modify the bug ModifyError: Changes are not applied """ log = logging.getLogger("bugzilla.MODIFY") args = BugStruct(**kwargs) if not args.has("bug_id"): raise BugzillaError("Bug id is needed to modify") if not self.is_logged_in: log.error("Login is needed") raise LoginError("You should first login to comment") log.info("Opening bug #%s to modify" % args.bug_id) bug_data = self._bug_open(args.bug_id, xml=False) # do we have permission to see this bug? if bug_data.find(self.constants.NO_PERMISSON_STRING) > -1: log.error("Don't have permission to modify the bug") raise BugzillaError("You don't have permission to see this bug") log.info("Opened bug #%s page" % args.bug_id) log.debug("Selecting changeform") self.browser.select_form(name="changeform") # for x in self.browser.forms(): # print x if args.has("title"): log.debug("New title: %s" % args.title) self.browser["short_desc"] = args.title if args.has("status"): log.debug("Bug_status: %s" % args.status) self.browser["bug_status"] = [args.status] if args.has("resolution"): log.debug("Resolution: %s" % args.resolution) self.browser["resolution"] = [args.resolution] if args.has("comment"): log.debug("Setting comment") self.browser["comment"] = args.comment if args.has("security"): # Pardus has specific setting for security vulnerabilities that will not be public. The checkbox name is "bit-10" log.debug("Marking as security") if args.security == "1": # if the bug has bit-10 field set if len(self.browser["bit-10"]) != 0: log.warning( "Bug is already in security group, not setting security tag" ) else: self.browser["bit-10"] = ["1"] # marking as non-security else: if len(self.browser["bit-10"]) == 0: log.warning( "Bug is already public, not setting security tag..") else: self.browser["bit-10"] = [] if args.has("assigned_to"): log.debug("Assigned: %s" % args.assigned_to) self.browser["assigned_to"] = args.assigned_to if args.has("keywords"): log.debug("Keywords: %s" % args.keywords) self.browser["keywords"] += ", %s" % args.keywords if args.has("dependson"): log.debug("Dependson: %s" % args.dependson) self.browser["dependson"] = args.dependson if args.has("blocks"): log.debug("Blocks: %s" % args.blocks) self.browser["blocked"] = args.blocks if args.has("cc"): log.debug("CC: %s" % args.cc) self.browser["newcc"] = args.cc if args.has("version"): log.debug("Version: %s" % args.version) self.browser["version"] = [args.version] log.info("Submitting the changes") response = self.browser.submit() response = response.read() # is everything alright? if response.find(self.constants.BUG_PROCESS_OK_STRING) > -1: log.info("Changes have been submitted") return True else: # something is wrong. log.error("Errr, something is wrong in returned value.") #print response raise ModifyError("Unexpected return value", response)
def new(self, **kwargs): """Opens new bug It automatically generates bug_url from product as bugzilla wants product name in GET response Args: product: Product name in the site component: Component name in bugzilla page security: Whether it is security vulnerability url: External url status: Initial but status. (NEW, RESOLVED) assigned_to: Email address to assign alias: Bug alias (NOT IMPLEMENTED) blocks: Bugs that this bug blocks dependson: Bug that depends on. cc: E-mail addresses to CC Returns: Integer indicating the bugzilla id for new bug Raises: BugzillaError: Required arguments are not provided """ log = logging.getLogger("bugzilla.NEW") args = BugStruct(**kwargs) # control required vars if not (args.has("component") and args.has("product") and args.has("title") and args.has("description")): raise BugzillaError("Missing argument. Component, Product, Title and Description are needed") bug_url = self.constants.get_new_bug_url(args.product) log.debug("Opening new bug page") self.browser.open(bug_url) log.debug("Selecting form name: Create") self.browser.select_form(name="Create") log.debug("Adding component, title and comment") self.browser["component"] = [args.component] self.browser["short_desc"] = args.title self.browser["comment"] = args.description if args.has("url"): log.debug("URL: %s" % args.url) self.browser["bug_file_loc"] = args.url if args.has("security"): log.debug("Security: 1") self.browser["bit-10"] = ["1"] if args.has("status"): log.debug("Bug_status: %s" % args.status) self.browser["bug_status"] = [args.status] if args.has("assigned_to"): log.debug("Assign: %s" % args.assigned_to) self.browser["assigned_to"] = args.assigned_to if args.has("dependson"): log.debug("Depends on: %s" % args.dependson) self.browser["dependson"] = args.dependson if args.has("blocks"): log.debug("Blocks: %s" % args.blocks) self.browser["blocked"] = args.blocks if args.has("version"): log.debug("Version: %s" % args.version) self.browser["version"] = [args.version] if args.has("cc"): log.debug("CC: %s" % args.cc) self.browser["cc"] = args.cc # FIXME: Our bugzilla page doesn't show alias field. # FIXME: Uncomment it when it is done # if args.has("alias"): # self.browser["alias"] = args.alias response = self.browser.submit() response = response.read() log.info("Bug submitted") # get bug id. re_compile = re.compile("Bug (.*?) Submitted") bug_id = re.findall(re_compile, response) if len(bug_id) != 0: return bug_id[0] else: log.error("Wohoops. Unexpected data returned after submitting.") return False
def main(): log = logging.getLogger("bugzilla.BIN") parser = setup_parser() (global_opts, args) = parser.parse_args() global_opts = BugStruct(**global_opts.__dict__) # Get our action from these args if len(args) and args[0] in cmdlist: action = args.pop(0) else: parser.error("command must be one of: %s" % ','.join(cmdlist)) action_parser = setup_action_parser(action) (opt, args) = action_parser.parse_args(args) opt = BugStruct(**opt.__dict__) # Helper functions def check_valid_resolutions(): """Checks if valid resolution is given for --resolution and --close""" # make it upper-case for easy-of-use if opt.resolution: opt.resolution = opt.resolution.upper() if not opt.resolution in VALID_RESOLUTIONS: parser.error("resolution must be one of: %s" % ','.join(VALID_RESOLUTIONS)) sys.exit(1) elif opt.close: opt.close = opt.close.upper() # --close is an alias for -s RESOLVED -r FIXED. # When --close is used, only resolution is appended. So control it. # # bugspy.py modify -b 12346 --close invalid # if not opt.close in VALID_RESOLUTIONS: parser.error("resolution must be one of: %s" % ','.join(VALID_RESOLUTIONS)) sys.exit(1) def check_valid_statuses(): # make it upper-case for easy-of-use opt.status = opt.status.upper() if not opt.status in VALID_STATUSES: parser.error("status must be one of: %s" % ','.join(VALID_STATUSES)) def check_valid_keywords(): # make it upper-case for easy-of-use opt.keywords = opt.keywords.upper() if not opt.keywords in VALID_KEYWORDS: parser.error("keyword must be one of: %s" % ','.join(VALID_KEYWORDS)) if not os.path.exists(CONFIG_FILE) and action != "generate-config": log.error("Configuation file is not found, please generate it first") sys.exit(1) c = BugspyConfig() bugzilla = Bugzilla(c.bugzillaurl, c.username, c.password) if action == "generate-config": if os.path.exists(CONFIG_FILE): log.warning( "Configuration file exists. Please edit ~/.bugspy.conf with your text editor. Exiting..." ) sys.exit(1) # check arguments if not (opt.user and opt.password and opt.bugzilla_url): parser.error("Missing argument! See --help") sys.exit(1) config_data = CONFIG_TEMPLATE % { "bugzilla": opt.bugzilla_url, "user": opt.user, "password": opt.password } log.info("Writing configuration file") open(CONFIG_FILE, "w+").write(config_data) log.info( "Configuration file is written. You can edit ~/.bugspy.conf for later use" ) if action == "modify": modify = {} if not opt.bug_id: log.error("Bud id must be provided!") sys.exit(1) modify["bug_id"] = opt.bug_id if opt.comment: modify["comment"] = opt.comment if opt.status: check_valid_statuses() if opt.status == "RESOLVED" and not opt.resolution: parser.error("RESOLVED should be used along with RESOLUTION.") sys.exit(1) modify["status"] = opt.status if opt.resolution: check_valid_resolutions() # we cannot set resolution on NEW bugs bugzilla.login() bug_info = bugzilla.get(opt.bug_id) if bug_info.has("status") and bug_info.status == "NEW": log.error( "You cannot change resolution on NEW bugs. Maybe you want to this?: --status RESOLVED --resolution %s" % opt.resolution) sys.exit(1) modify["resolution"] = opt.resolution if opt.close and not opt.resolution: check_valid_resolutions() modify["status"] = "RESOLVED" modify["resolution"] = opt.close if opt.title: modify["title"] = opt.title if opt.assigned_to: modify["assigned_to"] = opt.assigned_to if opt.security: modify["security"] = opt.security if opt.keywords: modify["keywords"] = opt.keywords if opt.blocks: modify["blocks"] = opt.blocks if opt.depends: modify["dependson"] = opt.depends if opt.cc: modify["cc"] = opt.cc if opt.version: if not opt.version in VALID_VERSIONS: parser.error("version must be one of: %s" % ', '.join(VALID_VERSIONS)) modify["version"] = opt.version try: bugzilla.login() bugzilla.modify(**modify) except BugzillaError, e: log.error(e.msg)
def modify(self, **kwargs): # TODO: Implement Product/Component/CC list """Modifies the bug. All arguments can be supplied. This function modifies the form on the page and submits just like an ordinary browser does. Args: bug_id: Bug id to edit title: New bug title comment: Comment to write status: Status (NEW, ASSIGNED, RESOLVED) resolution: (FIXED, INVALID, WONTFIX, LATER, REMIND, DUPLICATE) security: Whether it is security or not assigned_to: E-mail address to assign a bug blocks: Bugs that this bug blocks dependson: Bug that depends on. cc: Add e-mail address to cc list Raises: BugzillaError: You should first login to modify the bug ModifyError: Changes are not applied """ log = logging.getLogger("bugzilla.MODIFY") args = BugStruct(**kwargs) if not args.has("bug_id"): raise BugzillaError("Bug id is needed to modify") if not self.is_logged_in: log.error("Login is needed") raise LoginError("You should first login to comment") log.info("Opening bug #%s to modify" % args.bug_id) bug_data = self._bug_open(args.bug_id, xml=False) # do we have permission to see this bug? if bug_data.find(self.constants.NO_PERMISSON_STRING) > -1: log.error("Don't have permission to modify the bug") raise BugzillaError("You don't have permission to see this bug") log.info("Opened bug #%s page" % args.bug_id) log.debug("Selecting changeform") self.browser.select_form(name="changeform") # for x in self.browser.forms(): # print x if args.has("title"): log.debug("New title: %s" % args.title) self.browser["short_desc"] = args.title if args.has("status"): log.debug("Bug_status: %s" % args.status) self.browser["bug_status"] = [args.status] if args.has("resolution"): log.debug("Resolution: %s" % args.resolution) self.browser["resolution"] = [args.resolution] if args.has("comment"): log.debug("Setting comment") self.browser["comment"] = args.comment if args.has("security"): # Pardus has specific setting for security vulnerabilities that will not be public. The checkbox name is "bit-10" log.debug("Marking as security") if args.security == "1": # if the bug has bit-10 field set if len(self.browser["bit-10"]) != 0: log.warning("Bug is already in security group, not setting security tag") else: self.browser["bit-10"] = ["1"] # marking as non-security else: if len(self.browser["bit-10"]) == 0: log.warning("Bug is already public, not setting security tag..") else: self.browser["bit-10"] = [] if args.has("assigned_to"): log.debug("Assigned: %s" % args.assigned_to) self.browser["assigned_to"] = args.assigned_to if args.has("keywords"): log.debug("Keywords: %s" % args.keywords) self.browser["keywords"] += ", %s" % args.keywords if args.has("dependson"): log.debug("Dependson: %s" % args.dependson) self.browser["dependson"] = args.dependson if args.has("blocks"): log.debug("Blocks: %s" % args.blocks) self.browser["blocked"] = args.blocks if args.has("cc"): log.debug("CC: %s" % args.cc) self.browser["newcc"] = args.cc if args.has("version"): log.debug("Version: %s" % args.version) self.browser["version"] = [args.version] log.info("Submitting the changes") response = self.browser.submit() response = response.read() # is everything alright? if response.find(self.constants.BUG_PROCESS_OK_STRING) > -1: log.info("Changes have been submitted") return True else: # something is wrong. log.error("Errr, something is wrong in returned value.") #print response raise ModifyError("Unexpected return value", response)