def format_issue( issue , mode = 0, formatter=None, comments_only=False): fields = {} global colorfunc status_color="blue" status_string = get_issue_status ( issue.setdefault("status","1")).lower() if status_string in ["resolved","closed"]: status_color="green" elif status_string in ["open","unassigned","reopened"]: status_color="red" special_fields = {"status":get_issue_status,"priority":get_issue_priority,"type":get_issue_type} if formatter: groups = re.compile("(%([\w]+))").findall(formatter) ret_str = formatter for k, v in groups: if v.lower() in special_fields.keys(): meth = special_fields[v.lower()] key=issue[v.lower()] mappings = meth(None) data = "" for item in mappings: if item['id'] == key: data = item['name'] ret_str = ret_str.replace(k, data) else: ret_str = ret_str.replace(k, str(issue.setdefault(v.lower(),""))) return ret_str if mode >= 0: # minimal fields["issue"] = issue["key"] fields["status"] = colorfunc( get_issue_status ( issue["status"] ) , status_color ) fields["reporter"] = issue.setdefault("reporter","") fields["assignee"] = issue.setdefault("assignee","") fields["summary"] = issue.setdefault("summary","") fields["link"] = colorfunc( "%s/browse/%s" % ( jirabase, issue["key"]), "white",attrs=["underline"]) if mode >= 1 or comments_only: fields["description"] = issue.setdefault("description","") fields["priority"] = get_issue_priority( issue.setdefault("priority","")) fields["type"] = get_issue_type( issue.setdefault("type","") ) comments = get_comments ( issue["key"] ) fields["comments"] = "\n" for comment in comments: comment_str = comment["body"].strip() fields["comments"] += "%s %s : %s\n" % ( colorfunc(comment["created"], "blue"), colorfunc(comment["author"], "green"), comment_str ) if comments_only: return fields["comments"].strip() elif mode < 0: url_str = colorfunc("%s/browse/%s" % (jirabase, issue["key"]), "white", attrs=["underline"]) ret_str = colorfunc(issue["key"],status_color) +" "+ issue.setdefault("summary","") + " " + url_str if not color: ret_str += " [%s] " % get_issue_status(issue["status"]) return ret_str for k,v in fields.items(): if not v: fields[k] = "" return "\n".join( " : ".join((k.ljust(20),v)) for k,v in fields.items() ) + "\n"
def issue_header(issue): """get a single line string for an issue""" return "%s (%s)" % (colorfunc("%s, %s: %s" % (issue.key, issue.fields.issuetype.name, issue.fields.summary), None, attrs=['bold', 'underline']), colorfunc("%s, %s" % (issue.fields.status.name, issue.fields.priority.name), issue_status_color(issue.fields.status.name), attrs=['bold']))
def _validate_jira_url(): jirabase = config('jirabase') try: urllib2.urlopen('%s/rpc/soap/jirasoapservice-v2?wsdl' % jirabase) return Client('%s/rpc/soap/jirasoapservice-v2?wsdl' % jirabase) except (socket.gaierror, IOError): print colorfunc('invalid url %s. Please provide the correct url for your jira instance' % jirabase, 'red') config('jirabase', unset=True) return _validate_jira_url() except Exception, ex: raise ex
def main(): try: parser = setup_argparser() args = parser.parse_args() logging.debug(args) except Exception, ex: sys.exit(colorfunc(str(ex), 'red'))
def _validate_login(token=None): if token: try: JIRAOBJ.service.getPriorities(token) return token except WebFault: return _validate_login() try: token = JIRAOBJ.service.login(config('user'), config('password')) open(os.path.expanduser('~/.jira-cli/token'), 'w').write(token) return token except WebFault: print colorfunc('username or password incorrect, try again.', 'red') config('user', unset=True) config('password', unset=True) return _validate_login()
def issue_format(issue, show_desc=False, show_comments=False): """return a dict with fields which describe the issue""" fields = OrderedDict() if hasattr(issue.fields, "parent"): fields['parent'] = "%s" % (issue.fields.parent.key) if show_desc: fields['description'] = "\n%s" % (issue.fields.description) fields['created'] = "%s, by %s" % (dtstr2dt(issue.fields.created), issue.fields.reporter.name) if hasattr(issue.fields.assignee, 'name'): fields['assignee'] = issue.fields.assignee.name fields['updated'] = dtstr2dt(issue.fields.updated) if hasattr(issue.fields, 'versions') and issue.fields.fixVersions: fields['versions'] = ", ".join([x.name for x in issue.fields.fixVersions]) if hasattr(issue.fields, 'components') and issue.fields.components: fields['components'] = ", ".join([x.name for x in issue.fields.components]) if hasattr(issue.fields, 'labels') and issue.fields.labels: fields['labels'] = ", ".join(issue.fields.labels) if hasattr(issue.fields, 'attachment') and issue.fields.attachment: fields['attachment'] = ", ".join([x.filename for x in issue.fields.attachment]) if hasattr(issue.fields, 'issuelinks') and issue.fields.issuelinks: link_list = list() # inward issue: the issue to link from # outward issue: the issue to link to for link in issue.fields.issuelinks: if 'outwardIssue' in link.raw: link_list.append(link.raw['outwardIssue']) elif 'inwardIssue' in link.raw: link_list.append(link.raw['inwardIssue']) fields['issuelinks'] = ", ".join([x['key'] for x in link_list]) if show_comments: if hasattr(issue.fields, 'comment'): formatted_issues = ["%s\n%s" % (colorfunc("%s, %s" % (dtstr2dt(x.updated), x.updateAuthor.name), None, attrs=['reverse']), x.body) for x in issue.fields.comment.comments] fields['comments'] = "%s\n%s" % (len(issue.fields.comment.comments), "\n\n".join(formatted_issues)) else: fields['comments'] = "0" else: # show only the number of comments if hasattr(issue.fields, 'comment') and issue.fields.comment.comments: fields['comments'] = "%s" % (len(issue.fields.comment.comments)) transitions = jira.transitions(issue) fields['trans'] = ", ".join([x['name'] + "(" + x['id'] + ")" for x in transitions]) # print(dir(issue.fields)) # add empty strings if field not available for k, v in fields.items(): if not v: fields[k] = "" return fields
def _login(u,p): username,password = u,p if not u: sys.stderr.write("enter username:"******"enter password:"******"username or password incorrect, try again.", "red") return _login(None,None)
def _validate_jira_url(url=None): global jiraobj, token, jirabase if not url: jirabase = raw_input("base url for your jira instance (e.g http://issues.apache.org/jira):") else: jirabase = url try: jiraobj = xmlrpclib.ServerProxy("%s/rpc/xmlrpc" % jirabase ) # lame ping method jiraobj.getIssueTypes() except (xml.parsers.expat.ExpatError, xmlrpclib.ProtocolError,socket.gaierror, IOError), e: print >> colorfunc("invalid url %s. Please provide the correct url for your jira installation" % jirabase, "red") return _validate_jira_url()
def _validate_jira_url(url=None): global jiraobj, token, jirabase if not url: jirabase = raw_input("base url for your jira instance (e.g http://issues.apache.org/jira):") else: jirabase = url try: urllib2.urlopen('%s/rpc/soap/jirasoapservice-v2?wsdl' % jirabase) jiraobj = Client('%s/rpc/soap/jirasoapservice-v2?wsdl' % jirabase) # lame ping method jiraobj.service.getIssueTypes() except (socket.gaierror, IOError): print >> sys.stderr, colorfunc("invalid url %s. Please provide the correct url for your jira installation" % jirabase, "red") return _validate_jira_url() except WebFault,e: open(os.path.expanduser("~/.jira-cli/config"),"w").write(jirabase)
def filter_list_print(filter_list): """print a list of filters""" for f in filter_list: # header print("%s" % (colorfunc("%s, %s" % (f.id, f.name), None, attrs=['bold', 'underline']))) # fields to show for the filter fields = OrderedDict() fields['Url'] = f.viewUrl fields['description'] = getattr(f, 'description', '') fields['owner'] = f.owner.name fields['jql'] = f.jql # add empty strings if field not available for k, v in fields.items(): if not v: fields[k] = "" print("\n".join(" : ".join((k.ljust(20), v)) for k, v in fields.items()) + "\n")
def print_error(msg, severity=CRITICAL): color = 'red' if severity == CRITICAL else 'yellow' sys.stderr.write(colorfunc(msg, color) + "\n")
def command_progress(args): '''entry point for 'progress' subcommand ''' def find_by_attr(list, attr, value): return next((x for x in list if x[attr].lower() == value), None) if not args.issue: raise Exception('issue id must be provided') available_actions = get_actions(args.issue) available_actions_names = [action.name.lower() for action in available_actions] if args.actions: for idx, action in enumerate(available_actions, start=1): print '%d. %s: "%s"' % (idx, colorfunc(action.id, 'green'), action.name) if args.start: if any(map(lambda a: a in available_actions_names, ['start progress', 'in progress >>'])): action = None for a in ['start progress', 'in progress >>']: action = find_by_attr(available_actions, 'name', a) if action: break print format_issue(progress(args.issue, action), 0, args.format) else: sys.exit('unable to start progress on "%s", available actions are: "%s"' % (args.issue, available_actions_names)) if args.stop: if 'stop progress' in available_actions_names: print format_issue(progress(args.issue, find_by_attr(available_actions, 'name', 'stop progress')), 0, args.format) else: sys.exit('unable to stop progress on "%s", available actions are: "%s"' % (args.issue, available_actions_names)) if args.toggle: if 'start progress' in available_actions_names: print format_issue(progress(args.issue, find_by_attr(available_actions, 'name', 'start progress')), 0, args.format) elif 'stop progress' in available_actions_names: print format_issue(progress(args.issue, find_by_attr(available_actions, 'name', 'stop progress')), 0, args.format) else: sys.exit('unable to toggle progress on "%s", available actions are: "%s"' % (args.issue, available_actions_names)) if args.transist: if args.transist.lower() in available_actions_names: print format_issue(progress(args.issue, find_by_attr(available_actions, 'name', args.transist.lower())), 0, args.format) available_actions = get_actions(args.issue) available_actions_names = [action.name.lower() for action in available_actions] print 'available actions from this state are:' for idx, action in enumerate(available_actions, start=1): print '%d. %s: "%s"' % (idx, colorfunc(action.id, 'green'), action.name) else: sys.exit('unable to perform transition "%s" on "%s", available actions are: "%s"' % (args.transist, args.issue, available_actions_names)) if args.close: if 'close issue' in available_actions_names: print format_issue(progress(args.issue, find_by_attr(available_actions, 'name', 'close issue')), 0, args.format) else: sys.exit('unable to close "%s", available actions are: "%s"' % (args.issue, available_actions_names))
def command_list(args): ''' entry point for 'list' subcommand ''' if not any([ args.filters, args.prios, args.statuses, args.types, args.search, args.jqlsearch, args.filter, args.project, ]): if not args.issue: raise Exception('issue id must be provided') for issue in args.issue: issue_id = get_issue(issue) mode = (0 if not args.verbose else 1) mode = (-1 if args.oneline else mode) print format_issue(issue_id, mode, args.format, args.commentsonly) if args.filters: for idx, filt in enumerate(get_filters(), start=1): print '%d. %s: %s (Owner: %s)' % (idx, colorfunc(filt.id, 'green'), filt.name, colorfunc(filt.author, 'blue' )) if args.types: for idx, typ in enumerate(get_issue_type(None), start=1): print '%d. %s: %s' % (idx, colorfunc(typ['name'], 'green'), typ['description']) if args.statuses: for idx, status in enumerate(get_issue_status(None), start=1): print '%d. %s: %s' % (idx, colorfunc(status['name'], 'green'), status['description']) if args.prios: for idx, prio in enumerate(get_issue_priority(None), start=1): print '%d. %s: %s' % (idx, colorfunc(prio['name'], 'green'), prio['description']) if args.project: for idx, comp in enumerate(get_components(args.project), start=1): print '%d. %s: %s' % (idx, colorfunc(comp['id'], 'green'), comp['name']) if args.search: issues = search_issues(args.search) for issue in issues: mode = (0 if not args.verbose else 1) mode = (-1 if args.oneline else mode) print format_issue(issue, mode, args.format) if args.jqlsearch: issues = search_issues_jql(args.jqlsearch) mode = (0 if not args.verbose else 1) mode = (-1 if args.oneline else mode) for issue in issues: print format_issue(issue, mode, args.format) if args.filter: for filt in args.filter: issues = get_issues_by_filter(get_filter_by_name(filt)) for issue in issues: mode = (0 if not args.verbose else 1) mode = (-1 if args.oneline else mode) print format_issue(issue, mode, args.format, args.commentsonly)
def format_issue(issue, mode=0, formatter=None, comments_only=False): ''' formatting output for a issue according the different modes ''' # @TODO rework 'mode' to use args too # @TODO better formatting for "multiline" fields fields = {} status_string = get_issue_status(issue.status).lower() status_color = 'blue' if status_string in ['resolved', 'closed']: status_color = 'green' elif status_string in ['open', 'unassigned', 'reopened']: status_color = 'red' special_fields = {'status': get_issue_status, 'priority': get_issue_priority, 'type': get_issue_type} if formatter: groups = re.compile('(\$([\w]+))').findall(formatter) ret_str = formatter for key, value in groups: if value.lower() in special_fields.keys(): issue_id = issue[value.lower()] meth = special_fields[value.lower()] mappings = meth(None) data = '' for item in mappings: if item['id'] == issue_id: data = item['name'] ret_str = ret_str.replace(key, data) else: ret_str = ret_str.replace(key, str(getattr(issue, value))) return ret_str if mode >= 0: fields['issue'] = issue['key'] fields['status'] = colorfunc(get_issue_status(issue['status']), status_color) fields['reporter'] = issue.reporter fields['assignee'] = issue.assignee fields['summary'] = issue.summary fields['link'] = colorfunc('%s/browse/%s' % (config('jirabase'), issue['key']), 'white', attrs=['underline']) if mode >= 1 or comments_only: fields['description'] = issue.description.strip() fields['priority'] = get_issue_priority(issue.priority) fields['type'] = get_issue_type(issue.type) fields['components'] = ', '.join([component.name for component in issue.components]) comments = get_comments(issue['key']) fields['comments'] = '' for comment in comments: comment_body = comment['body'].strip() fields['comments'] += '\n' + 20 * ' ' + ': %s %s - "%s"' % (colorfunc(comment['created'], 'blue'), colorfunc(comment['author'], 'green'), comment_body) if comments_only: return fields['comments'].strip() elif mode < 0: url_str = colorfunc('%s/browse/%s' % (config('jirabase'), issue['key']), 'white', attrs=['underline']) if CONFIG['color']: ret_str = colorfunc(issue['key'], status_color) else: ret_str = issue['key'] + ' [%s] ' % get_issue_status(issue['status']) ret_str += ' ' + issue.summary + ' ' + url_str return ret_str.encode('utf-8') for key, value in fields.items(): if not value: fields[key] = '' return '\n'.join(': '.join((k.ljust(20), v.encode('utf-8'))) for (k, v) in fields.items()) + '\n'
def main(): """ """ example_usage = """ ------------------------------------------------------------------------------------------ view jira: jira-cli BE-193 view multiple jiras: jira-cli XYZ-123 ZZZ-123 ABC-123 add a comment: jira-cli -j BE-193 -c "i am sam" create a new issue: jira-cli -n bug -p BE -t "i am sam" "and this is my long description ending here" ------------------------------------------------------------------------------------------ """ parser = optparse.OptionParser() parser.usage = example_usage parser.add_option("-c", "--comment", dest="comment", help="comment on a jira", action="store_true") parser.add_option("", "--comments-only", dest="commentsonly", help="show only the comments for a jira", action="store_true") parser.add_option("-j", "--jira-id", dest="jira_id", help="issue id") parser.add_option( "", "--filter", dest="filter", help= "filter(s) to use for listing jiras. use a comma to separate multiple filters" ) parser.add_option("-n", "--new", dest="issue_type", help="create a new issue with given title") parser.add_option("", "--priority", dest="issue_priority", help="priority of new issue", default="minor") parser.add_option("-t", "--title", dest="issue_title", help="new issue title") parser.add_option("-p", "--project", dest="jira_project", help="the jira project to act on") parser.add_option("", "--oneline", dest="oneline", help="print only one line of info", action="store_true") parser.add_option("", "--list-jira-types", dest="listtypes", help="print out the different jira 'types'", action="store_true") parser.add_option("", "--list-filters", dest="listfilters", help="print out the different jira filters available", action="store_true") parser.add_option("-v", dest="verbose", action="store_true", help="print extra information") parser.add_option("-s", "--search", dest="search", help="search criteria") parser.add_option("", "--search-jql", dest="search_jql", help="JQL expression") parser.add_option("-f", "--format", dest="format", default=None, help="""format for outputting information. allowed tokens: %status,%priority,%updated,%votes,%components,%project,%reporter,%created,%fixVersions,%summary,%environment,%assignee,%key,%affectsVersions,%type. examples: "%priority,%reporter","(%key) %priority, reported by %reporter" """) parser.add_option("", "--user", dest="username", help="username to login as", default=None) parser.add_option("", "--password", dest="password", help="passowrd", default=None) opts, args = parser.parse_args() check_auth(opts.username, opts.password) try: if opts.listfilters: idx = 1 for f in get_filters(): print("%d. %s (Owner: %s)" % (idx, f["name"], colorfunc(f["author"], "green"))) idx += 1 elif opts.listtypes: print("Priorities:") for el in get_issue_priority(None): print(el["name"], ":", el["description"]) print() print("Issue Types:") for el in get_issue_type(None): print(el["name"], ":", el["description"]) else: if opts.issue_type: project = opts.jira_project if args: description = " ".join(args) else: description = default_editor_text print( format_issue( dict( create_issue(project, opts.issue_type, opts.issue_title, description, opts.issue_priority)), 0, opts.format)) elif opts.comment: if not opts.jira_id: parser.error("specify the jira to comment on") print( add_comment( opts.jira_id, " ".join(args) if args else default_editor_text)) elif opts.search or opts.search_jql: project = opts.jira_project if (project is None): issues = search_issues( opts.search) if opts.search else search_issues_jql( opts.search_jql) else: jira_max_int = pow(2, 31) - 1 issues = search_issues_with_project( project, opts.search, jira_max_int) for issue in issues: mode = 0 if not opts.verbose else 1 mode = -1 if opts.oneline else mode print(format_issue(dict(issue), mode, opts.format)) else: # otherwise we're just showing the jira. # maybe by filter if opts.filter: for f in opts.filter.split(","): issues = get_issues_from_filter(f) for issue in issues: mode = 0 if not opts.verbose else 1 mode = -1 if opts.oneline else mode print( format_issue(dict(issue), mode, opts.format, opts.commentsonly)) else: if not (opts.jira_id or args): parser.error("jira id must be provided") if args: for arg in args: issue = get_jira(arg) mode = 0 if not opts.verbose else 1 mode = -1 if opts.oneline else mode print( format_issue(dict(issue), mode, opts.format, opts.commentsonly)) if opts.jira_id: issue = get_jira(opts.jira_id) print( format_issue(dict(issue), 0 if not opts.verbose else 1, opts.format)) except Exception as e: parser.error(colorfunc(str(e), "red"))
def issue_format(jira_obj, issue, show_desc=False, show_comments=False, show_trans=False): """return a dict with fields which describe the issue""" fields = OrderedDict() if hasattr(issue.fields, "parent"): fields['parent'] = "%s" % (issue.fields.parent.key) if show_desc: fields['description'] = "\n%s" % (issue.fields.description) fields['created'] = "%s, by %s" % (dtstr2dt( issue.fields.created), issue.fields.reporter.name) if hasattr(issue.fields.assignee, 'name'): fields['assignee'] = issue.fields.assignee.name fields['updated'] = dtstr2dt(issue.fields.updated) if hasattr(issue.fields, 'versions') and len(issue.fields.fixVersions) > 0: fields['versions'] = ", ".join( map(lambda x: x.name, issue.fields.fixVersions)) if hasattr(issue.fields, 'components') and \ len(issue.fields.components) > 0: fields['components'] = ", ".join( map(lambda x: x.name, issue.fields.components)) if hasattr(issue.fields, 'labels') and len(issue.fields.labels) > 0: fields['labels'] = ", ".join(map(lambda x: x, issue.fields.labels)) if hasattr(issue.fields, 'attachment') and \ len(issue.fields.attachment) > 0: fields['attachment'] = ", ".join( map(lambda x: x.filename, issue.fields.attachment)) if hasattr(issue.fields, 'issuelinks') and \ len(issue.fields.issuelinks) > 0: link_list = list() # inward issue: the issue to link from # outward issue: the issue to link to for link in issue.fields.issuelinks: if 'outwardIssue' in link.raw: link_list.append(link.raw['outwardIssue']) elif 'inwardIssue' in link.raw: link_list.append(link.raw['inwardIssue']) fields['issuelinks'] = ", ".join(map(lambda x: x['key'], link_list)) if show_comments: if hasattr(issue.fields, 'comment'): fields['comments'] = "%s\n%s" % (len( issue.fields.comment.comments), "\n\n".join( map( lambda x: "%s\n%s" % (colorfunc("%s, %s" % (dtstr2dt(x.updated), x.updateAuthor.name), None, attrs=['reverse']), x.body), issue.fields.comment.comments))) # noqa else: fields['comments'] = "0" else: # show only the number of comments if hasattr(issue.fields, 'comment') and \ len(issue.fields.comment.comments) > 0: fields['comments'] = "%s" % (len(issue.fields.comment.comments)) if show_trans: transitions = jira_obj.transitions(issue) fields['trans'] = ", ".join( map(lambda x: x['name'] + "(" + x['id'] + ")", transitions)) # print(dir(issue.fields)) # add empty strings if field not available for k, v in fields.items(): if not v: fields[k] = "" return fields
def main(): """ """ example_usage = """ ------------------------------------------------------------------------------------------ view jira: jira-cli BE-193 view multiple jiras: jira-cli XYZ-123 ZZZ-123 ABC-123 add a comment: jira-cli -j BE-193 -c "i am sam" create a new issue: jira-cli -n bug -p BE -t "i am sam" "and this is my long description ending here" ------------------------------------------------------------------------------------------ """ parser = optparse.OptionParser() parser.usage = example_usage parser.add_option("-c", "--comment", dest="comment", help="comment on a jira", action="store_true") parser.add_option("", "--comments-only", dest="commentsonly", help="show only the comments for a jira", action="store_true") parser.add_option("-j", "--jira-id", dest="jira_id", help="issue id") parser.add_option("", "--filter", dest="filter", help="filter(s) to use for listing jiras. use a comma to separate multiple filters") parser.add_option("-n", "--new", dest="issue_type", help="create a new issue with given title") parser.add_option("", "--priority", dest="issue_priority", help="priority of new issue", default="minor") parser.add_option("-t", "--title", dest="issue_title", help="new issue title") parser.add_option("-p", "--project", dest="jira_project", help="the jira project to act on") parser.add_option("", "--oneline", dest="oneline", help="print only one line of info", action="store_true") parser.add_option("", "--list-jira-types", dest="listtypes", help="print out the different jira 'types'", action="store_true") parser.add_option("", "--list-filters", dest="listfilters", help="print out the different jira filters available", action="store_true") parser.add_option("-v", dest="verbose", action="store_true", help="print extra information") parser.add_option("-s", "--search", dest="search", help="search criteria") parser.add_option("", "--search-jql", dest="search_jql", help="JQL expression") parser.add_option("-f", "--format", dest="format", default=None, help="""format for outputting information. allowed tokens: %status,%priority,%updated,%votes,%components,%project,%reporter,%created,%fixVersions,%summary,%environment,%assignee,%key,%affectsVersions,%type. examples: "%priority,%reporter","(%key) %priority, reported by %reporter" """) parser.add_option("","--user",dest="username", help="username to login as" , default=None) parser.add_option("","--password",dest="password", help="passowrd", default = None ) opts, args = parser.parse_args() check_auth(opts.username, opts.password) try: if opts.listfilters: idx=1 for f in get_filters(): print "%d. %s (Owner: %s)" % (idx, f["name"], colorfunc(f["author"],"green")) idx+=1 elif opts.listtypes: print "Priorities:" for el in get_issue_priority(None): print el["name"], ":", el["description"] print print "Issue Types:" for el in get_issue_type(None): print el["name"], ":", el["description"] else: if opts.issue_type: project = opts.jira_project if args: description = " ".join(args) else: description = default_editor_text print format_issue ( dict(create_issue ( project, opts.issue_type, opts.issue_title, description, opts.issue_priority) ), 0, opts.format) elif opts.comment: if not opts.jira_id: parser.error("specify the jira to comment on") print add_comment(opts.jira_id, " ".join(args) if args else default_editor_text) elif opts.search or opts.search_jql: project = opts.jira_project if (project is None): issues = search_issues ( opts.search ) if opts.search else search_issues_jql(opts.search_jql) else: jira_max_int = pow(2,31)-1 issues = search_issues_with_project( project, opts.search, jira_max_int) for issue in issues: mode = 0 if not opts.verbose else 1 mode = -1 if opts.oneline else mode print format_issue( dict(issue), mode, opts.format ) else: # otherwise we're just showing the jira. # maybe by filter if opts.filter: for f in opts.filter.split(","): issues = get_issues_from_filter(f) for issue in issues: mode = 0 if not opts.verbose else 1 mode = -1 if opts.oneline else mode print format_issue( dict(issue), mode , opts.format, opts.commentsonly) else: if not (opts.jira_id or args): parser.error("jira id must be provided") if args: for arg in args: issue = get_jira(arg) mode = 0 if not opts.verbose else 1 mode = -1 if opts.oneline else mode print format_issue( dict(issue), mode , opts.format, opts.commentsonly) if opts.jira_id: issue = get_jira(opts.jira_id) print format_issue( dict(issue), 0 if not opts.verbose else 1, opts.format) except Exception, e: parser.error(colorfunc(str(e), "red"))
def format_issue(issue, mode=0, formatter=None, comments_only=False): fields = {} global colorfunc status_color = "blue" status_string = get_issue_status(issue.setdefault("status", "1")).lower() if status_string in ["resolved", "closed"]: status_color = "green" elif status_string in ["open", "unassigned", "reopened"]: status_color = "red" special_fields = { "status": get_issue_status, "priority": get_issue_priority, "type": get_issue_type } if formatter: groups = re.compile("(%([\w]+))").findall(formatter) ret_str = formatter for k, v in groups: if v.lower() in special_fields.keys(): meth = special_fields[v.lower()] key = issue[v.lower()] mappings = meth(None) data = "" for item in mappings: if item['id'] == key: data = item['name'] ret_str = ret_str.replace(k, data) else: ret_str = ret_str.replace(k, str(issue.setdefault(v.lower(), ""))) return ret_str if mode >= 0: # minimal fields["issue"] = issue["key"] fields["status"] = colorfunc(get_issue_status(issue["status"]), status_color) fields["reporter"] = issue.setdefault("reporter", "") fields["assignee"] = issue.setdefault("assignee", "") fields["summary"] = issue.setdefault("summary", "") fields["link"] = colorfunc("%s/browse/%s" % (jirabase, issue["key"]), "white", attrs=["underline"]) if mode >= 1 or comments_only: fields["description"] = issue.setdefault("description", "") fields["priority"] = get_issue_priority( issue.setdefault("priority", "")) fields["type"] = get_issue_type(issue.setdefault("type", "")) comments = get_comments(issue["key"]) fields["comments"] = "\n" for comment in comments: comment_str = comment["body"].strip() fields["comments"] += "%s %s : %s\n" % (colorfunc( comment["created"], "blue"), colorfunc(comment["author"], "green"), comment_str) if comments_only: return fields["comments"].strip() elif mode < 0: url_str = colorfunc("%s/browse/%s" % (jirabase, issue["key"]), "white", attrs=["underline"]) ret_str = colorfunc(issue["key"], status_color) + " " + issue.setdefault( "summary", "") + " " + url_str if not color: ret_str += " [%s] " % get_issue_status(issue["status"]) return ret_str for k, v in fields.items(): if not v: fields[k] = "" return "\n".join(" : ".join((k.ljust(20), v)) for k, v in fields.items()) + "\n"