def get_ajax(self, params): try: data_source = self.data_source if len(data_source.inner_columns ) > 50 and not DISABLE_COLUMN_LIMIT_IN_UCR.enabled( self.domain): raise UserReportsError( _("This report has too many columns to be displayed")) data_source.set_filter_values(self.filter_values) sort_column = params.get('iSortCol_0') sort_order = params.get('sSortDir_0', 'ASC') echo = int(params.get('sEcho', 1)) if sort_column and echo != 1: data_source.set_order_by([ (data_source.top_level_columns[int(sort_column)].column_id, sort_order.upper()) ]) datatables_params = DatatablesParams.from_request_dict(params) page = list( data_source.get_data(start=datatables_params.start, limit=datatables_params.count)) total_records = data_source.get_total_records() total_row = data_source.get_total_row( ) if data_source.has_total_row else None except UserReportsError as e: if settings.DEBUG: raise return self.render_json_response({ 'error': e.message, 'aaData': [], 'iTotalRecords': 0, 'iTotalDisplayRecords': 0, }) except TableNotFoundWarning: if self.spec.report_meta.created_by_builder: msg = _( "The database table backing your report does not exist yet. " "Please wait while the report is populated.") else: msg = _( "The database table backing your report does not exist yet. " "You must rebuild the data source before viewing the report." ) return self.render_json_response({'warning': msg}) json_response = { 'aaData': page, "sEcho": params.get('sEcho', 0), "iTotalRecords": total_records, "iTotalDisplayRecords": total_records, } if total_row is not None: json_response["total_row"] = total_row if data_source.data_source.config.backend_id == UCR_LABORATORY_BACKEND: compare_ucr_dbs.delay(self.domain, self.report_config_id, self.filter_values, sort_column, sort_order, params) return self.render_json_response(json_response)
def get_total_row(self): def _clean_total_row(aggregations, aggregation_name): agg = getattr(aggregations, aggregation_name) if hasattr(agg, 'value'): return agg.value elif hasattr(agg, 'doc_count'): return agg.doc_count else: return '' def _get_relevant_column_ids(col): col_id_to_expanded_col = get_expanded_columns(self.top_level_columns, self.config) return col_id_to_expanded_col.get(col.column_id, [col.column_id]) aggregations = self._get_total_aggregated_results() total_row = [] for col in self.top_level_columns: for col_id in _get_relevant_column_ids(col): if not col.calculate_total: total_row.append('') continue elif getattr(col, 'aggregation', '') == 'simple': # could have this append '', but doing this for # compatibility with SQL raise UserReportsError(ugettext("You cannot calculate the total of a simple column")) total_row.append(_clean_total_row(aggregations, safe_es_column(col_id))) if total_row and total_row[0] is '': total_row[0] = ugettext('Total') return total_row
def get_ajax(self, request): try: data_source = self.data_source if len(data_source.columns) > 50: raise UserReportsError(_("This report has too many columns to be displayed")) data_source.set_filter_values(self.filter_values) sort_column = request.GET.get('iSortCol_0') sort_order = request.GET.get('sSortDir_0', 'ASC') echo = int(request.GET.get('sEcho', 1)) if sort_column and echo != 1: data_source.set_order_by( [(data_source.column_configs[int(sort_column)].column_id, sort_order.upper())] ) datatables_params = DatatablesParams.from_request_dict(request.GET) page = list(data_source.get_data(start=datatables_params.start, limit=datatables_params.count)) total_records = data_source.get_total_records() total_row = data_source.get_total_row() if data_source.has_total_row else None except UserReportsError as e: if settings.DEBUG: raise return self.render_json_response({ 'error': e.message, 'aaData': [], 'iTotalRecords': 0, 'iTotalDisplayRecords': 0, }) except TableNotFoundWarning: if self.spec.report_meta.created_by_builder: msg = _( "The database table backing your report does not exist yet. " "Please wait while the report is populated." ) else: msg = _( "The database table backing your report does not exist yet. " "You must rebuild the data source before viewing the report." ) return self.render_json_response({ 'warning': msg }) json_response = { 'aaData': page, "sEcho": self.request_dict.get('sEcho', 0), "iTotalRecords": total_records, "iTotalDisplayRecords": total_records, } if total_row is not None: json_response["total_row"] = total_row return self.render_json_response(json_response)
def _inner(*args, **kwargs): try: return func(*args, **kwargs) except ( ColumnNotFoundException, ProgrammingError, InvalidQueryColumn, ) as e: error = translate_programming_error(e) if isinstance(error, TableNotFoundWarning): raise error raise UserReportsError(str(e))
def _inner(*args, **kwargs): try: return func(*args, **kwargs) except ( ColumnNotFoundException, ProgrammingError, InvalidQueryColumn, ) as e: if not settings.UNIT_TESTING: _soft_assert(False, unicode(e)) raise UserReportsError(unicode(e)) except TableNotFoundException: raise TableNotFoundWarning
def _inner(*args, **kwargs): try: return func(*args, **kwargs) except ( ColumnNotFoundException, ProgrammingError, InvalidQueryColumn, ) as e: error = translate_programming_error(e) if isinstance(error, TableNotFoundWarning): raise error if not settings.UNIT_TESTING: _soft_assert(False, six.text_type(e)) raise UserReportsError(six.text_type(e))
def get_data(self, slugs=None): try: ret = super(ConfigurableReportDataSource, self).get_data(slugs) for report_column in self.column_configs: report_column.format_data(ret) except ( ColumnNotFoundException, ProgrammingError, ) as e: raise UserReportsError(e.message) except TableNotFoundException as e: raise TableNotFoundWarning # TODO: Should sort in the database instead of memory, but not currently supported by sqlagg. try: # If a sort order is specified, sort by it. if self._order_by: for col in reversed(self._order_by): sort_column_id, order = col is_descending = order == DESCENDING try: matching_report_column = self._column_configs[ sort_column_id] except KeyError: raise SortConfigurationError( 'Sort column {} not found in report!'.format( sort_column_id)) def get_datatype(report_column): """ Given a report column, get the data type by trying to pull it out from the data source config of the db column it points at. Defaults to "string" """ try: field = report_column.field except AttributeError: # if the report column doesn't have a field object, default to string. # necessary for percent columns return 'string' matching_indicators = filter( lambda configured_indicator: configured_indicator[ 'column_id'] == field, self.config.configured_indicators) if not len(matching_indicators) == 1: raise SortConfigurationError( 'Number of indicators matching column %(col)s is %(num_matching)d' % { 'col': col[0], 'num_matching': len(matching_indicators), }) return matching_indicators[0]['datatype'] datatype = get_datatype(matching_report_column) def sort_by(row): value = row.get(sort_column_id, None) return value or get_default_sort_value(datatype) ret.sort(key=sort_by, reverse=is_descending) return ret # Otherwise sort by the first column else: return sorted( ret, key=lambda x: x.get(self.column_configs[0].column_id, next(x.itervalues()))) except (SortConfigurationError, TypeError): # if the data isn't sortable according to the report spec # just return the data in the order we got it return ret