def _parse_maintainer_scope(self, text): maintainer = {} maintainer['subsystem'] = "" maintainer['maintainer'] = [] maintainer['maillist'] = "" maintainer['status'] = "" maintainer['file-include-pattern'] = [] maintainer['file-exclude-pattern'] = [] for lnumber, line in enumerate(text): if line[0] == '[': # subsystem name maintainer['subsystem'] = line[1:line.rfind(']')].strip() elif line[0:2] == 'M:': # Maintainer maintainer['maintainer'].append((line[2:line.find('<')].strip(), line[line.find('<') + 1:line.find('>')].strip())) elif line[0:2] == 'L:': # mailinglist maintainer['maillist'] = line[2:].strip() elif line[0:2] == 'S:': # Status maintainer['status'] = line[2:].strip() elif line[0:2] == 'F:': # File pattern maintainer['file-include-pattern'].append(self._env_parser.parse(line[2:].strip())) elif line[0:2] == 'X:': # Exclude pattern maintainer['file-exclude-pattern'].append(self._env_parser.parse(line[2:].strip())) else: logger.warn("Unable to intrpret line %s [must start with one of [MLSFX :[%s]", lnumber, line) return maintainer
def get_changemetric_for_function(self, session, function_id, metric): ''' This should be rewritten so that it is more agnostic in how it returns the data to the client. It should only return the query itself, and not transform it into dictionarys and whatnot. The view (who is using this function) makes alot of assumptions as to how the data is returned from here and relies that OrmWrapper transforms data so that it fits the view. Any transformations (for the sake of clients) should rather instead be done by the views themselves. Args: session (sqlalchemy.orm.session) function_id (int): The function for which the data is gathered metric (str): The metric we are fetching data for. Usually this is mapped to a concrete ORM type in the global METRIC_MAPPING dict. continuous (bool): Indicates wether the metric is continuous or not. Returns: dict: A dictionary with the dates and total metric values for the component ''' total_dict = collections.OrderedDict() if metric == "defect_modifications": result = session.query(DefectModification.date, literal_column('1'))\ .filter(DefectModification.function_id == function_id, DefectModification.date.isnot(None))\ .group_by(DefectModification.version_id).order_by(DefectModification.date) else: try: metric_column = METRIC_MAPPING[metric] except KeyError: logger.warn( "Incorrect metric supplied, beware of SQL injection attacks! metric=%s", metric) return total_dict result = session.query(ChangeMetric.date, metric_column).filter(ChangeMetric.function_id == function_id, ChangeMetric.date.isnot(None), metric_column.isnot(None))\ .group_by(ChangeMetric.version_id).order_by(ChangeMetric.date) for (date_, metric) in result: total_dict[date_] = metric return total_dict
def dump_data(data, response_type='application/json', filename=None): ''' Function used when dumping raw data to the clients. It can handle both csv and json data and dumps the correct format according to the response_type parameter passed by the client. The HttpResponse is flagged with the content type and can usually be parsed automatically on the frontend using jquery.ajax() which guesses the correct response type based on the `content_type` in the `HttpResponse`. ''' if response_type in ('csv', 'text/csv'): response = HttpResponse(content_type=response_type) filename = filename or "file" response['Content-Disposition'] = 'attachment; filename="{0}.csv"'.format(filename) response = _toCSV(data, response) elif response_type in ('json', 'application/json'): response = HttpResponse(_toJSON(data), content_type=response_type) else: logger.warn('Unknown response_type %s', response_type) return response
def get_changemetric_for_function(self, session, function_id, metric): ''' This should be rewritten so that it is more agnostic in how it returns the data to the client. It should only return the query itself, and not transform it into dictionarys and whatnot. The view (who is using this function) makes alot of assumptions as to how the data is returned from here and relies that OrmWrapper transforms data so that it fits the view. Any transformations (for the sake of clients) should rather instead be done by the views themselves. Args: session (sqlalchemy.orm.session) function_id (int): The function for which the data is gathered metric (str): The metric we are fetching data for. Usually this is mapped to a concrete ORM type in the global METRIC_MAPPING dict. continuous (bool): Indicates wether the metric is continuous or not. Returns: dict: A dictionary with the dates and total metric values for the component ''' total_dict = collections.OrderedDict() if metric == "defect_modifications": result = session.query(DefectModification.date, literal_column('1'))\ .filter(DefectModification.function_id == function_id, DefectModification.date.isnot(None))\ .group_by(DefectModification.version_id).order_by(DefectModification.date) else: try: metric_column = METRIC_MAPPING[metric] except KeyError: logger.warn("Incorrect metric supplied, beware of SQL injection attacks! metric=%s", metric) return total_dict result = session.query(ChangeMetric.date, metric_column).filter(ChangeMetric.function_id == function_id, ChangeMetric.date.isnot(None), metric_column.isnot(None))\ .group_by(ChangeMetric.version_id).order_by(ChangeMetric.date) for (date_, metric) in result: total_dict[date_] = metric return total_dict
def dump_data(data, response_type='application/json', filename=None): ''' Function used when dumping raw data to the clients. It can handle both csv and json data and dumps the correct format according to the response_type parameter passed by the client. The HttpResponse is flagged with the content type and can usually be parsed automatically on the frontend using jquery.ajax() which guesses the correct response type based on the `content_type` in the `HttpResponse`. ''' if response_type in ('csv', 'text/csv'): response = HttpResponse(content_type=response_type) filename = filename or "file" response[ 'Content-Disposition'] = 'attachment; filename="{0}.csv"'.format( filename) response = _toCSV(data, response) elif response_type in ('json', 'application/json'): response = HttpResponse(_toJSON(data), content_type=response_type) else: logger.warn('Unknown response_type %s', response_type) return response
def get_changemetric_for_file(self, session, file_id, metric, continuous=None): ''' This should be rewritten so that it is more agnostic in how it returns the data to the client. It should only return the query itself, and not transform it into dictionarys and whatnot. The view (who is using this function) makes alot of assumptions as to how the data is returned from here and relies that OrmWrapper transforms data so that it fits the view. Any transformations (for the sake of clients) should rather instead be done by the views themselves. Args: session (sqlalchemy.orm.session) file_id (int): The file for which the data is gathered metric (str): The metric we are fetching data for. Usually this is mapped to a concrete ORM type in the global METRIC_MAPPING dict. continuous (bool): Indicates wether the metric is continuous or not. Returns: dict: A dictionary with the dates and total metric values for the component ''' total_dict = collections.OrderedDict() if continuous is None: continuous = METRICS[metric]['continuous'] if metric == "defect_modifications": result = session.query(DefectModification.date, literal_column('1'))\ .filter(DefectModification.file_id == file_id, DefectModification.date.isnot(None))\ .group_by(DefectModification.version_id).order_by(DefectModification.date) for (date_, metric_data) in result: total_dict[date_] = metric_data else: # Handles generic metrics (nloc, complexity, added...) and changerate try: metric_column = METRIC_MAPPING[metric] except KeyError: logger.warn( "Incorrect metric supplied, beware of SQL injection attacks! metric=%s", metric) return total_dict change_metrics = session.query( ChangeMetric.function_id, ChangeMetric.date, metric_column).filter(ChangeMetric.file_id == file_id) all_dates = set() all_functions = {} all_functions_date = {} for function_id, date_, metric_total in change_metrics: if date_ is not None: all_dates.add(date_) all_functions.setdefault(function_id, []).append( (date_, metric_total)) all_functions_date.setdefault(date_, []).append( (metric_total)) all_dates = sorted(all_dates) ''' Sort all_entities so that we can assume that dates are *always* in descending order, this assumption is later used in calculate_continous() ''' for entrys in all_functions.itervalues(): entrys.sort(key=lambda entry: entry[0], reverse=True) for date_ in all_dates: if continuous: metric = self._calculate_continuous(all_functions, date_) else: metric = self._calculate_discontinous( all_functions_date, date_) total_dict[date_] = metric return total_dict
def get_changemetric_for_file(self, session, file_id, metric, continuous=None): ''' This should be rewritten so that it is more agnostic in how it returns the data to the client. It should only return the query itself, and not transform it into dictionarys and whatnot. The view (who is using this function) makes alot of assumptions as to how the data is returned from here and relies that OrmWrapper transforms data so that it fits the view. Any transformations (for the sake of clients) should rather instead be done by the views themselves. Args: session (sqlalchemy.orm.session) file_id (int): The file for which the data is gathered metric (str): The metric we are fetching data for. Usually this is mapped to a concrete ORM type in the global METRIC_MAPPING dict. continuous (bool): Indicates wether the metric is continuous or not. Returns: dict: A dictionary with the dates and total metric values for the component ''' total_dict = collections.OrderedDict() if continuous is None: continuous = METRICS[metric]['continuous'] if metric == "defect_modifications": result = session.query(DefectModification.date, literal_column('1'))\ .filter(DefectModification.file_id == file_id, DefectModification.date.isnot(None))\ .group_by(DefectModification.version_id).order_by(DefectModification.date) for (date_, metric_data) in result: total_dict[date_] = metric_data else: # Handles generic metrics (nloc, complexity, added...) and changerate try: metric_column = METRIC_MAPPING[metric] except KeyError: logger.warn("Incorrect metric supplied, beware of SQL injection attacks! metric=%s", metric) return total_dict change_metrics = session.query(ChangeMetric.function_id, ChangeMetric.date, metric_column).filter(ChangeMetric.file_id == file_id) all_dates = set() all_functions = {} all_functions_date = {} for function_id, date_, metric_total in change_metrics: if date_ is not None: all_dates.add(date_) all_functions.setdefault(function_id, []).append((date_, metric_total)) all_functions_date.setdefault(date_, []).append((metric_total)) all_dates = sorted(all_dates) ''' Sort all_entities so that we can assume that dates are *always* in descending order, this assumption is later used in calculate_continous() ''' for entrys in all_functions.itervalues(): entrys.sort(key=lambda entry: entry[0], reverse=True) for date_ in all_dates: if continuous: metric = self._calculate_continuous(all_functions, date_) else: metric = self._calculate_discontinous(all_functions_date, date_) total_dict[date_] = metric return total_dict