def display(self) -> None: while True: clear() print(thick_separator) print('Argus - {}'.format(self.menu_header)) print(thick_separator) for menu_option in self.active_menu: # Menu header if menu_option.hotkey is None: print('') else: print('{:2}: {foo}'.format(menu_option.hotkey, foo=menu_option.entry_name)) print(thin_separator) c_input = get_input('>') # brute force ftw. for menu_option in self.active_menu: if c_input == menu_option.hotkey: if menu_option.entry_method is not None: menu_option.entry_method() if menu_option.needs_pause: pause()
def _display_readme(self): while True: print('======================================') print(' How To Use Argus ') print('======================================') clear() fn = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'readme.md') in_user_guide = False with open(fn, "r") as myfile: for line in myfile: if "<!-- start_user_guide -->" in line: in_user_guide = True line = line.replace('<!-- start_user_guide -->', '') print(line) elif in_user_guide: if "<!-- end_user_guide -->" not in line: print(line) else: in_user_guide = False line = line.replace('<!-- end_user_guide -->', '') print(line) i = get_input('[q] to quit.') if i == 'q': break
def add_organization(self) -> None: while True: if len(self._organizations.keys()) != 0: print('Known organizations:') for known_org in self._organizations.keys(): print(' {}'.format(known_org)) org_name = get_input('Enter a new org name, [q] to quit:', False) if org_name == 'q': break new_org = set() # type: Set[str] while True: clear() print('Org: {}'.format(org_name)) for team_name in new_org: print(' {}'.format(team_name)) choice = get_input('[a]dd a new team to this org, [q]uit') if choice == 'q': break elif choice == 'a': new_team = self.pick_team(list(new_org)) if new_team is not None: new_org.add(new_team.name) else: print('Bad choice. Try again.') pause() if new_org is not None: self._organizations[org_name] = new_org self._save_config() print('New org {} added.'.format(org_name)) break
def display_escalations(self) -> None: jira_connection_name = pick_value( 'Select a JIRA Connection to view Escalation type tickets:', list(self._jira_connections.keys())) if jira_connection_name is None: return jira_connection = self._jira_connections[jira_connection_name] jira_issues = JiraUtils.get_issues_by_query( jira_connection, 'type = \'Escalation\' AND resolution = unresolved') issue_keys = [] for issue in jira_issues: issue_keys.append(issue.issue_key) df = DisplayFilter.default() while True: print_separator(30) print(os.linesep + 'Escalations' + os.linesep) print_separator(30) clear() df.display_and_return_sorted_issues(self, jira_issues) i = get_input('[#] Integer to open issue in browser. [q] to quit.') if i == 'q': break try: c_input = int(i) - 1 JiraUtils.open_issue_in_browser(jira_connection.url, issue_keys[c_input]) except ValueError: print('Bad input. Try again') pause()
def list_dashboards(self): if len(self.jira_dashboards) == 0: print('No dashboards. Create one first.') return clear() print('Dashboards]') for dashboard in list(self.jira_dashboards.values()): print('{}'.format(dashboard))
def run_org_report(self, jira_manager: 'JiraManager') -> None: """ Sub-menu driven method to run a specific type of report across multiple teams within an organization """ org_name = None if len(self._organizations) == 0: # We don't prompt for addition now since we'd have to pass in main menu context to do that from here. print('No organizations found. Please use the Team Management menu to define a new organization before running a report.') pause() return while True: clear() if org_name is None: print_separator(40) org_name = pick_value('Run reports against which organization?', list(self._organizations.keys())) # None return from pick_team == cancel if org_name is None: return for team_name in sorted(self._organizations[org_name]): active_team = self._teams[team_name] print('Populating tickets for team: {}'.format(active_team.name)) TeamManager.populate_owned_jira_issues(jira_manager, active_team.members) print('---------------------') print('- Org Menu -') print('---------------------') print('t: Change active org. Current: {}'.format(org_name)) self._print_report_menu() print('q: Cancel') print('---------------------') choice = get_input(':') if choice == 'q': return elif choice == 't': org_name = None try: report_type = ReportType.from_int(int(choice)) if report_type == ReportType.UNKNOWN: print('Bad input: {}. Try again.'.format(choice)) pause() else: report_to_run = TeamManager.reports[report_type] if TeamManager.reports[report_type].needs_duration: report_to_run.since = time_utils.since_now(ReportFilter.get_since()) # making mypy happy assert org_name is not None self._run_org_report(jira_manager, org_name, report_to_run) pause() except (ValueError, TypeError) as e: print('Error on input: {}. Try again'.format(e)) traceback.print_exc() pause()
def edit_team(self, jira_manager, team_name=None): # type: (JiraManager, str) -> None if team_name is None: team_name = pick_value('Edit which team?', list(self._teams.keys()), True, 'Cancel') if team_name is None: return None team = self._teams[team_name] jira_connection = jira_manager.get_jira_connection( team.jira_connection_name) while True: clear() print('-------------------------') print('[Edit {}]'.format(team)) print('-------------------------') cmd = get_input( '[A]dd more members, [R]emove a member, or [Q]uit?') if cmd == 'a': assignees = jira_connection.pick_assignees(sys.maxsize) if assignees is None or len(assignees) == 0: print('No assignees chosen. Returning.') return None for assignee in assignees: if assignee in team.member_names: print( 'Assignee already exists in {}. Skipping.'.format( team.name)) continue else: team.add_member(assignee, jira_connection) print('Added {} to {}.'.format(assignee, team.name)) self._save_config() elif cmd == 'r': assignee = pick_value('Remove which assignee?', team.member_names, True, 'Cancel') if assignee is None: continue confirm = get_input('Delete {} from {}: Are you sure?'.format( assignee, team.name)) if confirm == 'y': team.delete_member(assignee) elif cmd == 'q': break else: print('Bad input. Valid input: A, R, or Q.') pause() self._save_config()
def print_report(self, job_list: List[JenkinsJob]) -> None: clear() format_str = '{:<5}{:<60}{:<30}{:<25}{:<25}{:<15}{:<30}{:<25}' separator = ('-' * len(format_str.format('', '', '', '', '', '', '', ''))) builds_to_check, recent_builds_to_check = get_build_options() print(separator) print(format_str.format('#', 'Job Name', 'Connection', 'Test Result', 'Last Build Date', 'Job Health', 'Failed Build History ({})'.format(builds_to_check), 'Recent Failed Builds ({})'.format(recent_builds_to_check))) print(separator) for i, job in enumerate(job_list, start=1): print(format_str.format(i, job.name, self.job_dict[job], job.last_build_tests, job.last_build_date, job.health, job.build_history, job.recent_history)) print(separator)
def run_team_reports(self, jira_manager: 'JiraManager') -> None: """ Sub-menu driven method to run some specific reports of interest against teams. This will take into account linked members and run the report for all tickets across multiple JIRA connections. """ selected_team = None if len(self._teams) == 0: # We don't prompt for addition now since we'd have to pass in main menu context to do that from here. print('No teams found. Please use the Team Management menu to define a new team before running a report.') pause() return while True: clear() if selected_team is None: print('No active team. Please select a team:') selected_team = self.pick_team() # None return from pick_team == cancel if selected_team is None: return TeamManager.populate_owned_jira_issues(jira_manager, selected_team.members) print('---------------------') print('- Team Menu -') print('---------------------') print('t: Change active root team. Current: {}'.format(selected_team.name)) self._print_report_menu() print('q: Cancel') print('---------------------') choice = get_input(':') if choice == 'q': return elif choice == 't': selected_team = None try: report_type = ReportType.from_int(int(choice)) if report_type == ReportType.UNKNOWN: print('Bad input: {}. Try again.'.format(choice)) pause() else: assert selected_team is not None TeamManager._run_report(jira_manager, selected_team, TeamManager.reports[report_type]) except (ValueError, TypeError) as e: print('Error on input: {}. Try again'.format(e)) traceback.print_exc() pause()
def print_test_report(tests: List[JenkinsTest]) -> None: clear() format_str = '{:<5}{:<130}{:<30}{:<25}' separator = ('-' * len(format_str.format('', '', '', ''))) builds_to_check, recent_builds_to_check = get_build_options() print(separator) print( format_str.format( '#', 'Test Name', 'Failed Test History ({})'.format(builds_to_check), 'Recent Failed Tests ({})'.format(recent_builds_to_check))) print(separator) for i, jenkins_test in enumerate(tests): print( format_str.format(i, jenkins_test.name, jenkins_test.failure_history, jenkins_test.recent_history)) print(separator)
def pick_project(self, skip_cached: bool = False) -> Optional[str]: self._refresh_project_names() coll = self.possible_projects[:] if skip_cached: for project_name in list(self._cached_jira_projects.keys()): coll.remove(project_name) pick = None # Loop to allow trying different substrings while pick is None: ss = get_input('Enter portion of name (\'q\' to quit):', lowered=False) if ss.lower() == 'q': return None matches = sorted([x for x in coll if ss in x]) if len(matches) == 0: print('No matches found. Try again.') continue pick = pick_value('Which:', matches, True, 'Enter different substring') if pick is None: clear() return pick
def run_team_reports(self, jira_manager): """ Sub-menu driven method to run some specific reports of interest against teams. This will take into account linked members and run the report for all tickets across multiple JIRA connections. """ selected_team = None if len(self._teams) == 0: # We don't prompt for addition now since we'd have to pass in main menu context to do that from here. print( 'No teams found. Please use the Team Management menu to define a new team before running a report.' ) pause() return reports = { ReportType.MOMENTUM: ReportMomentum(), ReportType.CURRENT_LOAD: ReportCurrentLoad(), ReportType.TEST_LOAD: ReportTestLoad(), ReportType.REVIEW_LOAD: ReportReviewLoad() } while True: clear() if selected_team is None: selected_team = self.pick_team() # None return from pick_team == cancel if selected_team is None: return TeamManager.populate_owned_jira_issues(jira_manager, selected_team.members) print('---------------------') print('- Team Menu -') print('---------------------') print('t: Change active root team. Current: {}'.format( selected_team.name)) print( '{}: Run a momentum report: closed tickets, closed test tickets, closed reviews for a custom time frame' .format(ReportType.MOMENTUM)) print( '{}: Team load report: assigned bugs, assigned tests, assigned features, assigned reviews, patch available reviews' .format(ReportType.CURRENT_LOAD)) print( '{}: Test load report: snapshot of currently assigned tests and closed tests in a custom time frame' .format(ReportType.TEST_LOAD)) print( '{}: Review load report: snapshot of currently assigned reviews, Patch Available reviews, and finished reviews in a custom time frame' .format(ReportType.REVIEW_LOAD)) print('q: Cancel') print('---------------------') choice = get_input(':') if choice == 'q': return elif choice == 't': selected_team = None try: report_type = ReportType.from_int(int(choice)) if report_type == ReportType.UNKNOWN: print('Bad input: {}. Try again.'.format(choice)) pause() else: TeamManager._run_report(jira_manager, selected_team, reports[report_type]) except (ValueError, TypeError) as e: print('Error on input: {}. Try again'.format(e)) traceback.print_exc() pause()