def add_label_view(self): name = get_input('Name this view: ') jira_connection_name = pick_value( 'Which JIRA Connection does this belong to? ', list(self._jira_connections.keys())) jira_connection = self._jira_connections[jira_connection_name] new_view = JiraView(name, jira_connection) self.jira_views[name] = new_view jira_filter = JiraFilter('labels', jira_connection) while True: label = get_input('Add which label? ([q] to quit)') if label == 'q': break if label.isspace() or label == '': continue print('Adding label: [{}]'.format(label)) jira_filter.include(label) res_jf = JiraFilter('Resolution', jira_connection) res_jf.include('unresolved') new_view.add_raw_filter(jira_filter) new_view.add_raw_filter(res_jf) self._save_config() new_view.display_view(self) print('Creating new view with label(s): {}'.format(','.join( jira_filter._includes)))
def add_view(self) -> None: if len(self._jira_connections) == 0: if is_yes( 'No JiraConnections to add a JiraView to. Would you like to add a connection now?' ): self.add_connection() else: return None view_name = get_input('Name this view:') jira_connection_name = pick_value( 'Which JIRA Connection does this belong to?', list(self._jira_connections.keys())) if jira_connection_name is None: return new_view = JiraView(view_name, self._jira_connections[jira_connection_name]) self.jira_views[view_name] = new_view new_view.edit_view(self, self.team_manager) self._save_config()
def add_multi_jira_dashboard(self): options = sorted(self._jira_connections.keys()) add_new = 'Add a new Jira Connection' options.append(add_new) pairs = [] while True: print('Current contents of report]') for jira_connection, user in pairs: print(' Connection: {} User: {}'.format( jira_connection.connection_name, user)) command = pick_value('[Connection inclusion]', options, True, 'Done', False) if command is None: break elif command == add_new: new_conn = self.add_connection() else: new_conn = self._jira_connections[command] print('Selecting user name from {}'.format( new_conn.connection_name)) user = new_conn.pick_single_assignee() if user is None: break pairs.append((new_conn, user)) # Any error in the user addition process can bubble up with only 1 user selected if len(pairs) <= 1: print( 'Found less than the required minimum of 2 entries. Not adding report.' ) return name = '' while name == '': name = get_input('Name this report:') new_dash = JiraDashboard(name, {}) # Create a JiraView for each of these and then dump them into the dashboard for jira_connection, user in pairs: view_name = '{}_{}'.format(jira_connection.connection_name, user) if view_name in list(self.jira_views.keys()): print( 'Already found a view named {} in jira_views. Using that instead.' .format(view_name)) new_jira_view = self.jira_views[view_name] else: new_jira_view = JiraView( '{}_{}'.format(jira_connection.connection_name, user), jira_connection) new_jira_view.add_single_filter('assignee', user, 'i', 'OR') new_jira_view.add_single_filter('reviewer', user, 'i', 'OR') new_jira_view.add_single_filter('reviewer2', user, 'i', 'OR') new_jira_view.add_single_filter('resolution', 'unresolved', 'i', 'AND') self.jira_views[new_jira_view.name] = new_jira_view new_dash.add_jira_view(new_jira_view) self.jira_dashboards[name] = new_dash print('Completed configuration of new report: {}'.format(name)) self._save_config()
def __init__(self, team_manager): """ Recreates any JiraConnections and JiraViews based on saved data in conf/jira.cfg """ # Holds connected Jira objects to be queried by JiraViews self._jira_connections = {} # type: Dict[str, JiraConnection] # JiraViews, caching filters for different ways to view Jira Data. Implicit 1:1 JiraConnection to JiraView self.jira_views = {} # type: Dict[str, JiraView] self.jira_dashboards = {} # type: Dict[str, JiraDashboard] # Used during JiraDependency resolution to notify user of missing JiraProjects self.missing_project_counts = {} # type: Dict[str, int] self._display_filter = DisplayFilter.default() if os.path.exists(jira_conf_file): config_parser = configparser.RawConfigParser() config_parser.read(jira_conf_file) connection_names = [] if config_parser.has_section( 'JiraManager') and config_parser.has_option( 'JiraManager', 'Connections'): connection_names = config_parser.get('JiraManager', 'Connections').split(',') # JiraConnections are the root of our container hierarchy for connection_name in connection_names: if connection_name == '': pass try: jira_connection = JiraConnection.from_file(connection_name) # If we had an error on init we obviously cannot add this if jira_connection is None: continue self._jira_connections[ jira_connection.connection_name] = jira_connection except ConfigError as ce: print('ConfigError with project {}: {}'.format( connection_name, ce)) # Construct JiraViews so they can be used during JiraDashboard creation. view_names = [] if config_parser.has_option('JiraManager', 'Views'): view_names = config_parser.get('JiraManager', 'Views').split(',') for name in view_names: try: jv = JiraView.from_file(self, name, team_manager) self.jira_views[jv.name] = jv except ConfigError as ce: print('ConfigError with jira view {}: {}'.format(name, ce)) if config_parser.has_section('Dashboards'): for dash in config_parser.options('Dashboards'): dash_views = {} for view in view_names: if view not in self.jira_views: print( 'Found dashboard {} with invalid view: {}. Skipping init: manually remove from config.' .format(dash, view)) break dash_views[view] = self.jira_views[view] self.jira_dashboards[dash] = JiraDashboard( dash, dash_views) if len(self._jira_connections) == 0: print_separator(30) print( 'No JIRA Connections found. Prompting to add first connection.' ) self.add_connection() # Initialize JiraProjects from locally cached files for file_name in os.listdir(jira_project_dir): full_path = os.path.join(jira_project_dir, file_name) print( 'Processing locally cached JiraProject: {}'.format(full_path)) # Init based on matching the name of this connection and .cfg print_separator(30) try: new_jira_project = JiraProject.from_file(full_path, self) if new_jira_project is None: print('Error initializing from {}. Skipping'.format( full_path)) break if new_jira_project.jira_connection is None: add = get_input( 'Did not find JiraConnection for JiraProject: {}. Would you like to add one now? (y/n)' ) if add == 'y': new_jira_connection = self.add_connection( 'Name the connection (reference url: {}):'.format( new_jira_project.url)) new_jira_connection.save_config() new_jira_project.jira_connection = new_jira_connection else: print( 'Did not add JiraConnection, so cannot link and use JiraProject.' ) continue print('Updating with new data from JIRA instance') new_jira_project.refresh() new_jira_project.jira_connection.add_and_link_jira_project( new_jira_project) except (configparser.NoSectionError, ConfigError) as e: print( 'WARNING! Encountered error initializing JiraProject from file {}: {}' .format(full_path, e)) print( 'This JiraProject will not be initialized. Remove it manually from disk in conf/jira/projects and data/jira/' ) if os.path.exists('conf/custom_params.cfg'): config_parser = configparser.RawConfigParser() config_parser.read('conf/custom_params.cfg') custom_projects = config_parser.get('CUSTOM_PROJECTS', 'project_names').split(',') for project_name in custom_projects: argus_debug( 'Processing immutable config for custom project: {}'. format(project_name)) # Find the JiraConnection w/matching URL, if any url = config_parser.get(project_name, 'url').rstrip('/') jira_project = self.maybe_get_cached_jira_project( url, project_name) if jira_project is not None: # Don't need to cache since already done on ctor for JiraProject argus_debug('Project already initialized. Skipping.') continue # Didn't find the JiraProject, so we need to build one, cache, and link. custom_fields = {} field_names = config_parser.get(project_name, 'custom_fields').split(',') for field in field_names: custom_fields[field] = config_parser.get( project_name, field) parent_jira_connection = None for jira_connection in list(self._jira_connections.values()): if jira_connection.url == url: parent_jira_connection = jira_connection break # Create a JiraConnection for this JiraProject if we do not yet have one if parent_jira_connection is None: print( 'WARNING! Did not find JiraConnection for project: {}, attempting to match url: {}' .format(project_name, url)) print('Known JiraConnections and their urls:') for jira_connection in list( self._jira_connections.values()): print(' {}: {}'.format( jira_connection.connection_name, jira_connection.url)) if is_yes('Would you like to add one now?'): parent_jira_connection = self.add_connection( 'Name the connection (reference url: {}):'.format( url)) else: print( 'JiraProject data and config will not be added nor cached. Either add it manually or restart Argus and reply y' ) break new_jira_project = JiraProject(parent_jira_connection, project_name, url, custom_fields) new_jira_project.refresh() parent_jira_connection.add_and_link_jira_project( new_jira_project) print('Resolving dependencies between JiraIssues') self._resolve_issue_dependencies() print('JiraManager initialization complete.')