def test_get_document_or_404_not_found(self): """ get_document_or_404 should raise 404 on ResourceNotFound """ with mock_get_context(): with self.assertRaises(Http404): get_document_or_404(MockModel, 'ham', '123')
def test_get_document_or_404_wrapping_error(self): """ get_document_or_404 should raise 404 on WrappingAttributeError """ with mock_wrap_context(): with self.assertRaises(Http404): get_document_or_404(MockModel, 'ham', '123')
def get_ledgers(request, domain): """ Returns ledgers associated with a case in the format: { "section_id": { "product_id": amount, "product_id": amount, ... }, ... } """ case_id = request.REQUEST.get('case_id') if not case_id: return json_response( {'message': 'You must specify a case id to make this query.'}, status_code=400) case = get_document_or_404(CommCareCase, domain, case_id) ledger_map = get_current_ledger_transactions(case._id) def custom_json_handler(obj): if isinstance(obj, StockTransaction): return obj.stock_on_hand return json_handler(obj) return json_response( { 'entity_id': case_id, 'ledger': ledger_map, }, default=custom_json_handler, )
def rows(self): base_link_url = '{}?q={{id}}'.format(reverse('global_quick_find')) user_id = self.request.GET.get('individual') if not user_id: return [] # security check get_document_or_404(CommCareUser, self.domain, user_id) sync_log_ids = [row['id'] for row in SyncLog.view( "phone/sync_logs_by_user", startkey=[user_id, {}], endkey=[user_id], descending=True, reduce=False, limit=10 )] def _sync_log_to_row(sync_log): def _fmt_duration(duration): if isinstance(duration, int): return format_datatables_data( '<span class="{cls}">{text}</span>'.format( cls=_bootstrap_class(duration or 0, 60, 20), text=_('{} seconds').format(duration), ), duration ) else: return format_datatables_data( '<span class="label">{text}</span>'.format( text=_("Unknown"), ), -1, ) def _fmt_id(sync_log_id): href = base_link_url.format(id=sync_log_id) return '<a href="{href}" target="_blank">{id:.5}...</a>'.format( href=href, id=sync_log_id ) num_cases = len(sync_log.cases_on_phone) columns = [ _fmt_date(sync_log.date), format_datatables_data(num_cases, num_cases), _fmt_duration(sync_log.duration), ] if self.show_extra_columns: columns.append(_fmt_id(sync_log.get_id)) return columns return [ _sync_log_to_row(SyncLog.wrap(sync_log_json)) for sync_log_json in iter_docs(SyncLog.get_db(), sync_log_ids) ]
def delete_report(request, domain, report_id): if not (toggle_enabled(request, toggles.USER_CONFIGURABLE_REPORTS) or toggle_enabled(request, toggles.REPORT_BUILDER) or toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP) or has_report_builder_add_on_privilege(request)): raise Http404() config = get_document_or_404(ReportConfiguration, domain, report_id) # Delete the data source too if it's not being used by any other reports. try: data_source, __ = get_datasource_config(config.config_id, domain) except DataSourceConfigurationNotFoundError: # It's possible the data source has already been deleted, but that's fine with us. pass else: if data_source.get_report_count() <= 1: # No other reports reference this data source. data_source.deactivate() config.delete() did_purge_something = purge_report_from_mobile_ucr(config) messages.success(request, _(u'Report "{}" deleted!').format(config.title)) if did_purge_something: messages.warning( request, _(u"This report was used in one or more applications. " "It has been removed from there too.") ) redirect = request.GET.get("redirect", None) if not redirect: redirect = reverse('configurable_reports_home', args=[domain]) return HttpResponseRedirect(redirect)
def post(self, request, *args, **kwargs): if self.new_commcare_user_form.is_valid() and self.custom_data.is_valid(): username = self.new_commcare_user_form.cleaned_data['username'] password = self.new_commcare_user_form.cleaned_data['password'] phone_number = self.new_commcare_user_form.cleaned_data['phone_number'] if 'location_id' in request.GET: loc = get_document_or_404(Location, self.domain, request.GET.get('location_id')) user = CommCareUser.create( self.domain, username, password, phone_number=phone_number, device_id="Generated from HQ", user_data=self.custom_data.get_data_to_save(), ) if 'location_id' in request.GET: user.set_location(loc) if phone_number: initiate_sms_verification_workflow(user, phone_number) user_json = {'user_id': user._id, 'text': user.username_in_report} return self.render_json_response({"status": "success", "user": user_json}) return self.render_form("failure")
def post(self, request, *args, **kwargs): if self.new_commcare_user_form.is_valid( ) and self.custom_data.is_valid(): username = self.new_commcare_user_form.cleaned_data['username'] password = self.new_commcare_user_form.cleaned_data['password'] phone_number = self.new_commcare_user_form.cleaned_data[ 'phone_number'] if 'location_id' in request.GET: loc = get_document_or_404(Location, self.domain, request.GET.get('location_id')) couch_user = CommCareUser.create( self.domain, username, password, phone_number=phone_number, device_id="Generated from HQ", user_data=self.custom_data.get_data_to_save(), ) if 'location_id' in request.GET: couch_user.set_location(loc) return HttpResponseRedirect( reverse(EditCommCareUserView.urlname, args=[self.domain, couch_user.userID])) return self.get(request, *args, **kwargs)
def saved_report_context_data(self): def _get_context_for_saved_report(report_config): if report_config: report_config_data = report_config.to_json() report_config_data['filters'].update( report_config.get_date_range()) return report_config_data else: return ReportConfig.default() saved_report_config_id = self.request.GET.get('config_id') saved_report_config = get_document_or_404(ReportConfig, self.domain, saved_report_config_id) \ if saved_report_config_id else None return { 'report_configs': [ _get_context_for_saved_report(saved_report) for saved_report in ReportConfig.by_domain_and_owner(self.domain, self.request.couch_user._id, report_slug=self.slug) ], 'default_config': _get_context_for_saved_report(saved_report_config), 'datespan_filters': ReportConfig.datespan_filter_choices(self.datespan_filters, self.lang), }
def post(self, request, *args, **kwargs): if self.new_commcare_user_form.is_valid( ) and self.custom_data.is_valid(): username = self.new_commcare_user_form.cleaned_data['username'] password = self.new_commcare_user_form.cleaned_data['password'] phone_number = self.new_commcare_user_form.cleaned_data[ 'phone_number'] if 'location_id' in request.GET: loc = get_document_or_404(Location, self.domain, request.GET.get('location_id')) user = CommCareUser.create( self.domain, username, password, phone_number=phone_number, device_id="Generated from HQ", user_data=self.custom_data.get_data_to_save(), ) if 'location_id' in request.GET: user.set_location(loc) if phone_number: initiate_sms_verification_workflow(user, phone_number) user_json = {'user_id': user._id, 'text': user.username_in_report} return self.render_json_response({ "status": "success", "user": user_json }) return self.render_form("failure")
def choice_list_api(request, domain, report_id, filter_id): report = get_document_or_404(ReportConfiguration, domain, report_id) filter = report.get_ui_filter(filter_id) if filter is None: raise Http404(_(u'Filter {} not found!').format(filter_id)) def get_choices(data_source, filter, search_term=None, limit=20, page=0): # todo: we may want to log this as soon as mobile UCR stops hitting this # for misconfigured filters if not isinstance(filter, DynamicChoiceListFilter): return [] table = get_indicator_table(data_source) sql_column = table.c[filter.field] query = Session.query(sql_column) if search_term: query = query.filter(sql_column.contains(search_term)) offset = page * limit try: return [ v[0] for v in query.distinct().order_by(sql_column).limit( limit).offset(offset) ] except ProgrammingError: return [] return json_response( get_choices(report.config, filter, request.GET.get('q', None), limit=int(request.GET.get('limit', 20)), page=int(request.GET.get('page', 1)) - 1))
def delete_report(request, domain, report_id): if not (toggle_enabled(request, toggles.USER_CONFIGURABLE_REPORTS) or toggle_enabled(request, toggles.REPORT_BUILDER) or toggle_enabled(request, toggles.REPORT_BUILDER_BETA_GROUP) or has_report_builder_add_on_privilege(request)): raise Http404() config = get_document_or_404(ReportConfiguration, domain, report_id) # Delete the data source too if it's not being used by any other reports. try: data_source, __ = get_datasource_config(config.config_id, domain) except DataSourceConfigurationNotFoundError: # It's possible the data source has already been deleted, but that's fine with us. pass else: if data_source.get_report_count() <= 1: # No other reports reference this data source. data_source.deactivate() config.delete() did_purge_something = purge_report_from_mobile_ucr(config) messages.success(request, _(u'Report "{}" deleted!').format(config.title)) if did_purge_something: messages.warning( request, _(u"This report was used in one or more applications. " "It has been removed from there too.")) redirect = request.GET.get("redirect", None) if not redirect: redirect = reverse('configurable_reports_home', args=[domain]) return HttpResponseRedirect(redirect)
def export_data_source(request, domain, config_id): config = get_document_or_404(DataSourceConfiguration, domain, config_id) adapter = IndicatorSqlAdapter(config) q = adapter.get_query_object() table = adapter.get_table() try: params = process_url_params(request.GET, table.columns) except UserQueryError as e: return HttpResponse(e.message, status=400) q = q.filter_by(**params.keyword_filters) for sql_filter in params.sql_filters: q = q.filter(sql_filter) # build export def get_table(q): yield table.columns.keys() for row in q: yield row fd, path = tempfile.mkstemp() with os.fdopen(fd, 'wb') as tmpfile: try: tables = [[config.table_id, get_table(q)]] export_from_tables(tables, tmpfile, params.format) except exc.DataError: msg = _("There was a problem executing your query, please make " "sure your parameters are valid.") return HttpResponse(msg, status=400) return export_response(Temp(path), params.format, config.display_name)
def saved_report_context_data(self): def _get_context_for_saved_report(report_config): if report_config: report_config_data = report_config.to_json() report_config_data['filters'].update(report_config.get_date_range()) return report_config_data else: return ReportConfig.default() saved_report_config_id = self.request.GET.get('config_id') saved_report_config = get_document_or_404(ReportConfig, self.domain, saved_report_config_id) \ if saved_report_config_id else None datespan_filters = [] for f in self.datespan_filters: copy = dict(f) copy['display'] = localize(copy['display'], self.lang) datespan_filters.append(copy) return { 'report_configs': [ _get_context_for_saved_report(saved_report) for saved_report in ReportConfig.by_domain_and_owner( self.domain, self.request.couch_user._id, report_slug=self.slug ) ], 'default_config': _get_context_for_saved_report(saved_report_config), 'datespan_filters': [{ 'display': _('Choose a date filter...'), 'slug': None, }] + datespan_filters, }
def get_ledgers(request, domain): """ Returns ledgers associated with a case in the format: { "section_id": { "product_id": amount, "product_id": amount, ... }, ... } """ case_id = request.REQUEST.get('case_id') if not case_id: return json_response( {'message': 'You must specify a case id to make this query.'}, status_code=400 ) case = get_document_or_404(CommCareCase, domain, case_id) ledger_map = get_current_ledger_transactions(case._id) def custom_json_handler(obj): if isinstance(obj, StockTransaction): return obj.stock_on_hand return json_handler(obj) return json_response( { 'entity_id': case_id, 'ledger': ledger_map, }, default=custom_json_handler, )
def _delete_data_source_shared(request, domain, config_id): config = get_document_or_404(DataSourceConfiguration, domain, config_id) adapter = IndicatorSqlAdapter(get_engine(), config) adapter.drop_table() config.delete() messages.success(request, _(u'Data source "{}" has been deleted.'.format(config.display_name)))
def choice_list_api(request, domain, report_id, filter_id): report = get_document_or_404(ReportConfiguration, domain, report_id) filter = report.get_ui_filter(filter_id) if filter is None: raise Http404(_(u'Filter {} not found!').format(filter_id)) def get_choices(data_source, filter, search_term=None, limit=20, page=0): # todo: we may want to log this as soon as mobile UCR stops hitting this # for misconfigured filters if not isinstance(filter, DynamicChoiceListFilter): return [] table = get_indicator_table(data_source) sql_column = table.c[filter.field] query = Session.query(sql_column) if search_term: query = query.filter(sql_column.contains(search_term)) offset = page * limit try: return [v[0] for v in query.distinct().order_by(sql_column).limit(limit).offset(offset)] except ProgrammingError: return [] return json_response(get_choices( report.config, filter, request.GET.get('q', None), limit=int(request.GET.get('limit', 20)), page=int(request.GET.get('page', 1)) - 1 ))
def delete_data_source(request, domain, config_id): config = get_document_or_404(DataSourceConfiguration, domain, config_id) adapter = IndicatorSqlAdapter(get_engine(), config) adapter.drop_table() config.delete() messages.success(request, _(u'Data source "{}" has been deleted.'.format(config.display_name))) return HttpResponseRedirect(reverse('configurable_reports_home', args=[domain]))
def rows(self): user_id = self.request.GET.get('individual') if not user_id: return [] # security check get_document_or_404(CommCareUser, self.domain, user_id) sync_log_ids = [row['id'] for row in SyncLog.view( "phone/sync_logs_by_user", startkey=[user_id, {}], endkey=[user_id], descending=True, reduce=False, )] def _sync_log_to_row(sync_log): def _fmt_duration(duration): if isinstance(duration, int): return format_datatables_data( '<span class="{cls}">{text}</span>'.format( cls=_bootstrap_class(duration or 0, 20, 60), text=_('{} seconds').format(duration), ), duration ) else: return format_datatables_data( '<span class="label">{text}</span>'.format( text=_("Unknown"), ), -1, ) num_cases = len(sync_log.cases_on_phone) return [ _fmt_date(sync_log.date), format_datatables_data(num_cases, num_cases), _fmt_duration(sync_log.duration), ] return [ _sync_log_to_row(SyncLog.wrap(sync_log_json)) for sync_log_json in iter_docs(SyncLog.get_db(), sync_log_ids) ]
def get_datasource_config_or_404(config_id, domain): is_static = config_id.startswith(CustomDataSourceConfiguration._datasource_id_prefix) if is_static: config = CustomDataSourceConfiguration.by_id(config_id) if not config or config.domain != domain: raise Http404() else: config = get_document_or_404(DataSourceConfiguration, domain, config_id) return config, is_static
def delete_data_source_shared(domain, config_id, request=None): config = get_document_or_404(DataSourceConfiguration, domain, config_id) adapter = get_indicator_adapter(config) adapter.drop_table() config.delete() if request: messages.success( request, _(u'Data source "{}" has been deleted.'.format( config.display_name)))
def delete_data_source_shared(domain, config_id, request=None): config = get_document_or_404(DataSourceConfiguration, domain, config_id) adapter = get_indicator_adapter(config) adapter.drop_table() config.delete() if request: messages.success( request, _(u'Data source "{}" has been deleted.'.format(config.display_name)) )
def rebuild_data_source(request, domain, config_id): config = get_document_or_404(DataSourceConfiguration, domain, config_id) messages.success( request, _('Table "{}" is now being rebuilt. Data should start showing up soon').format( config.display_name ) ) rebuild_indicators.delay(config_id) return HttpResponseRedirect(reverse('edit_configurable_data_source', args=[domain, config._id]))
def undo_close_case_view(request, domain, case_id): case = get_document_or_404(CommCareCase, domain, case_id) if not case.closed: messages.info(request, u'Case {} is not closed.'.format(case.name)) else: closing_form_id = request.POST['closing_form'] assert closing_form_id in case.xform_ids form = XFormInstance.get(closing_form_id) form.archive(user=request.couch_user._id) messages.success(request, u'Case {} has been reopened.'.format(case.name)) return HttpResponseRedirect(reverse('case_details', args=[domain, case_id]))
def get_datasource_config_or_404(config_id, domain): is_static = config_id.startswith( CustomDataSourceConfiguration._datasource_id_prefix) if is_static: config = CustomDataSourceConfiguration.by_id(config_id) if not config or config.domain != domain: raise Http404() else: config = get_document_or_404(DataSourceConfiguration, domain, config_id) return config, is_static
def preview_data_source(request, domain, config_id): config = get_document_or_404(DataSourceConfiguration, domain, config_id) table = get_indicator_table(config) q = Session.query(table) context = _shared_context(domain) context.update({ 'data_source': config, 'columns': q.column_descriptions, 'data': q[:20], }) return render(request, "userreports/preview_data.html", context)
def dispatch(self, request, *args, **kwargs): report_id = kwargs['report_id'] report = get_document_or_404(ReportConfiguration, request.domain, report_id) if report.report_meta.created_by_builder: view_class = { 'chart': ConfigureChartReport, 'list': ConfigureListReport, 'worker': ConfigureWorkerReport, 'table': ConfigureTableReport }[report.report_meta.builder_report_type] return view_class.as_view(existing_report=report)(request, *args, **kwargs) raise Http404("Report was not created by the report builder")
def choice_list_api(request, domain, report_id, filter_id): report = get_document_or_404(ReportConfiguration, domain, report_id) filter = report.get_ui_filter(filter_id) def get_choices(data_source, filter, search_term=None, limit=20): table = get_indicator_table(data_source) sql_column = table.c[filter.name] query = Session.query(sql_column) if search_term: query = query.filter(sql_column.contains(search_term)) return [v[0] for v in query.distinct().limit(limit)] return json_response(get_choices(report.config, filter, request.GET.get('q', None)))
def dispatch(self, request, *args, **kwargs): report_id = kwargs['report_id'] report = get_document_or_404(ReportConfiguration, request.domain, report_id) if report.report_meta.created_by_builder: view_class = { 'chart': ConfigureChartReport, 'list': ConfigureListReport, 'worker': ConfigureWorkerReport, 'table': ConfigureTableReport }[report.report_meta.builder_report_type] try: return view_class.as_view(existing_report=report)(request, *args, **kwargs) except BadBuilderConfigError as e: messages.error(request, e.message) return HttpResponseRedirect(reverse(ConfigurableReport.slug, args=[request.domain, report_id])) raise Http404("Report was not created by the report builder")
def case_details(request, domain, case_id): timezone = util.get_timezone(request.couch_user, domain) try: case = get_document_or_404(CommCareCase, domain, case_id) except Http404: messages.info( request, "Sorry, we couldn't find that case. If you think this is a mistake please report an issue." ) return HttpResponseRedirect(CaseListReport.get_url(domain=domain)) try: owner_name = CommCareUser.get_by_user_id(case.owner_id, domain).raw_username except Exception: try: owning_group = Group.get(case.owner_id) owner_name = owning_group.display_name if owning_group.domain == domain else "" except Exception: owner_name = None try: username = CommCareUser.get_by_user_id(case.user_id, domain).raw_username except Exception: username = None return render( request, "reports/reportdata/case_details.html", { "domain": domain, "case_id": case_id, "case": case, "username": username, "owner_name": owner_name, "slug": CaseListReport.slug, "report": dict(name=case_inline_display(case), slug=CaseListReport.slug, is_async=False), "layout_flush_content": True, "timezone": timezone, "case_display_options": { "display": request.project.get_case_display(case), "timezone": timezone, "get_case_url": lambda case_id: reverse(case_details, args=[domain, case_id]), }, "show_case_rebuild": toggles.CASE_REBUILD.enabled(request.user.username), }, )
def close_case_view(request, domain, case_id): case = get_document_or_404(CommCareCase, domain, case_id) if case.closed: messages.info(request, u'Case {} is already closed.'.format(case.name)) else: form_id = close_case(case_id, domain, request.couch_user) msg = _(u'''Case {name} has been closed. <a href="javascript:document.getElementById('{html_form_id}').submit();">Undo</a>. You can also reopen the case in the future by archiving the last form in the case history. <form id="{html_form_id}" action="{url}" method="POST"> <input type="hidden" name="closing_form" value="{xform_id}" /> </form> '''.format( name=case.name, html_form_id='undo-close-case', xform_id=form_id, url=reverse('undo_close_case', args=[domain, case_id]), )) messages.success(request, mark_safe(msg), extra_tags='html') return HttpResponseRedirect(reverse('case_details', args=[domain, case_id]))
def delete_report(request, domain, report_id): config = get_document_or_404(ReportConfiguration, domain, report_id) # Delete the data source too if it's not being used by any other reports. data_source, __ = get_datasource_config_or_404(config.config_id, domain) if data_source.get_report_count() <= 1: # No other reports reference this data source. try: delete_data_source_shared(domain, data_source._id, request) except Http404: # It's possible the data source has already been deleted, but # that's fine with us. pass config.delete() messages.success(request, _(u'Report "{}" deleted!').format(config.title)) redirect = request.GET.get("redirect", None) if not redirect: redirect = reverse('configurable_reports_home', args=[domain]) return HttpResponseRedirect(redirect)
def delete_report(request, domain, report_id): config = get_document_or_404(ReportConfiguration, domain, report_id) # Delete the data source too if it's not being used by any other reports. data_source, __ = get_datasource_config_or_404(config.config_id, domain) if data_source.get_report_count() <= 1: # No other reports reference this data source. try: data_source.deactivate() except Http404: # It's possible the data source has already been deleted, but # that's fine with us. pass config.delete() messages.success(request, _(u'Report "{}" deleted!').format(config.title)) redirect = request.GET.get("redirect", None) if not redirect: redirect = reverse('configurable_reports_home', args=[domain]) return HttpResponseRedirect(redirect)
def export_case_transactions(request, domain, case_id): case = get_document_or_404(CommCareCase, domain, case_id) products_by_id = dict(SQLProduct.objects.filter(domain=domain).values_list('product_id', 'name')) headers = [ _('case id'), _('case name'), _('section'), _('date'), _('product_id'), _('product_name'), _('transaction amount'), _('type'), _('ending balance'), ] def _make_row(transaction): return [ transaction.case_id, case.name, transaction.section_id, transaction.report.date if transaction.report_id else '', transaction.product_id, products_by_id.get(transaction.product_id, _('unknown product')), transaction.quantity, transaction.type, transaction.stock_on_hand, ] query_set = StockTransaction.objects.select_related('report')\ .filter(case_id=case_id).order_by('section_id', 'report__date') formatted_table = [ [ 'stock transactions', [headers] + [_make_row(txn) for txn in query_set] ] ] tmp = StringIO() export_from_tables(formatted_table, tmp, 'xlsx') return export_response(tmp, 'xlsx', '{}-stock-transactions'.format(case.name))
def dispatch(self, request, *args, **kwargs): report_id = kwargs['report_id'] report = get_document_or_404(ReportConfiguration, request.domain, report_id) if report.report_meta.created_by_builder: view_class = { 'chart': ConfigureChartReport, 'list': ConfigureListReport, 'worker': ConfigureWorkerReport, 'table': ConfigureTableReport }[report.report_meta.builder_report_type] try: return view_class.as_view(existing_report=report)(request, *args, **kwargs) except BadBuilderConfigError as e: messages.error(request, e.message) return HttpResponseRedirect( reverse(ConfigurableReport.slug, args=[request.domain, report_id])) raise Http404("Report was not created by the report builder")
def post(self, request, *args, **kwargs): if self.new_commcare_user_form.is_valid() and self.custom_data.is_valid(): username = self.new_commcare_user_form.cleaned_data["username"] password = self.new_commcare_user_form.cleaned_data["password"] phone_number = self.new_commcare_user_form.cleaned_data["phone_number"] if "location_id" in request.GET: loc = get_document_or_404(Location, self.domain, request.GET.get("location_id")) couch_user = CommCareUser.create( self.domain, username, password, phone_number=phone_number, device_id="Generated from HQ", user_data=self.custom_data.get_data_to_save(), ) if "location_id" in request.GET: couch_user.set_location(loc) return HttpResponseRedirect(reverse(EditCommCareUserView.urlname, args=[self.domain, couch_user.userID])) return self.get(request, *args, **kwargs)
def saved_report_context_data(self): def _get_context_for_saved_report(report_config): if report_config: report_config_data = report_config.to_json() report_config_data['filters'].update(report_config.get_date_range()) return report_config_data else: return ReportConfig.default() saved_report_config_id = self.request.GET.get('config_id') saved_report_config = get_document_or_404(ReportConfig, self.domain, saved_report_config_id) \ if saved_report_config_id else None return { 'report_configs': [ _get_context_for_saved_report(saved_report) for saved_report in ReportConfig.by_domain_and_owner( self.domain, self.request.couch_user._id, report_slug=self.slug ) ], 'default_config': _get_context_for_saved_report(saved_report_config), 'datespan_filters': ReportConfig.datespan_filter_choices(self.datespan_filters, self.lang), }
def export_data_source(request, domain, config_id): format = request.GET.get('format', Format.UNZIPPED_CSV) config = get_document_or_404(DataSourceConfiguration, domain, config_id) table = get_indicator_table(config) q = Session.query(table) column_headers = [col['name'] for col in q.column_descriptions] # apply filtering if any filter_values = {key: value for key, value in request.GET.items() if key != 'format'} for key in filter_values: if key not in column_headers: return HttpResponse('Invalid filter parameter: {}'.format(key), status=400) q = q.filter_by(**filter_values) # build export def get_table(q): yield column_headers for row in q: yield row fd, path = tempfile.mkstemp() with os.fdopen(fd, 'wb') as temp: export_from_tables([[config.table_id, get_table(q)]], temp, format) return export_response(Temp(path), format, config.display_name)
def choice_list_api(request, domain, report_id, filter_id): report = get_document_or_404(ReportConfiguration, domain, report_id) filter = report.get_ui_filter(filter_id) def get_choices(data_source, filter, search_term=None, limit=20, page=0): table = get_indicator_table(data_source) sql_column = table.c[filter.field] query = Session.query(sql_column) if search_term: query = query.filter(sql_column.contains(search_term)) offset = page * limit try: return [v[0] for v in query.distinct().order_by(sql_column).limit(limit).offset(offset)] except ProgrammingError: return [] return json_response(get_choices( report.config, filter, request.GET.get('q', None), limit=int(request.GET.get('limit', 20)), page=int(request.GET.get('page', 1)) - 1 ))
def delete_report(request, domain, report_id): config = get_document_or_404(ReportConfiguration, domain, report_id) # Delete the data source too if it's not being used by any other reports. data_source_id = config.config_id report_count = ReportConfiguration.view( 'userreports/report_configs_by_data_source', reduce=True, key=[domain, data_source_id] ).one()['value'] if report_count <= 1: # No other reports reference this data source. try: _delete_data_source_shared(request, domain, data_source_id) except Http404: # It's possible the data source has already been deleted, but # that's fine with us. pass config.delete() messages.success(request, _(u'Report "{}" deleted!').format(config.title)) return HttpResponseRedirect(reverse('configurable_reports_home', args=[domain]))
def report_source_json(request, domain, report_id): config = get_document_or_404(ReportConfiguration, domain, report_id) del config._doc['_rev'] return json_response(config)
def data_source_status(request, domain, config_id): config = get_document_or_404(DataSourceConfiguration, domain, config_id) return json_response({'isBuilt': config.meta.build.finished})
def editable_user(self): try: return get_document_or_404(WebUser, self.domain, self.editable_user_id) except (ResourceNotFound, CouchUser.AccountTypeError): raise Http404()
def edit_report(request, domain, report_id): config = get_document_or_404(ReportConfiguration, domain, report_id) return _edit_report_shared(request, domain, config)
def get_query_results(export_instance, domain, id): export = get_document_or_404(export_instance, domain, id) query = get_case_export_base_query(domain, export.case_type) results = query.run() return results
def rows(self): base_link_url = '{}?q={{id}}'.format(reverse('global_quick_find')) user_id = self.request.GET.get('individual') if not user_id: return [] # security check get_document_or_404(CommCareUser, self.domain, user_id) sync_log_ids = [ row['id'] for row in SyncLog.view( "phone/sync_logs_by_user", startkey=[user_id, {}], endkey=[user_id], descending=True, reduce=False, limit=self.limit, ) ] def _sync_log_to_row(sync_log): def _fmt_duration(duration): if isinstance(duration, int): return format_datatables_data( '<span class="{cls}">{text}</span>'.format( cls=_bootstrap_class(duration or 0, 60, 20), text=_('{} seconds').format(duration), ), duration) else: return format_datatables_data( '<span class="label">{text}</span>'.format( text=_("Unknown"), ), -1, ) def _fmt_id(sync_log_id): href = base_link_url.format(id=sync_log_id) return '<a href="{href}" target="_blank">{id:.5}...</a>'.format( href=href, id=sync_log_id) def _fmt_error_info(sync_log): if not sync_log.had_state_error: return u'<span class="label label-success">✓</span>' else: return ( u'<span class="label label-important">X</span>' u'State error {}<br>Expected hash: {:.10}...').format( _naturaltime_with_hover(sync_log.error_date), sync_log.error_hash, ) num_cases = sync_log.case_count() columns = [ _fmt_date(sync_log.date), format_datatables_data(num_cases, num_cases), _fmt_duration(sync_log.duration), ] if self.show_extra_columns: columns.append(_fmt_id(sync_log.get_id)) columns.append(sync_log.log_format) columns.append( _fmt_id(sync_log.previous_log_id) if sync_log. previous_log_id else '---') columns.append(_fmt_error_info(sync_log)) columns.append('{:.10}...'.format(sync_log.get_state_hash())) columns.append(_naturaltime_with_hover( sync_log.last_submitted)) columns.append(u'{}<br>{:.10}'.format( _naturaltime_with_hover(sync_log.last_cached), sync_log.hash_at_last_cached)) return columns return [ _sync_log_to_row(properly_wrap_sync_log(sync_log_json)) for sync_log_json in iter_docs(SyncLog.get_db(), sync_log_ids) ]
request.project.get_case_display(case), "timezone": timezone, "get_case_url": lambda case_id: reverse(case_details, args=[domain, case_id]) }, "show_case_rebuild": toggles.CASE_REBUILD.enabled(request.user.username), }) @require_case_view_permission @login_and_domain_required @require_GET def case_xml(request, domain, case_id): case = get_document_or_404(CommCareCase, domain, case_id) version = request.GET.get('version', V2) return HttpResponse(case.to_xml(version), content_type='text/xml') @require_case_view_permission @require_permission(Permissions.edit_data) @require_POST def rebuild_case_view(request, domain, case_id): case = get_document_or_404(CommCareCase, domain, case_id) rebuild_case(case_id) messages.success(request, _(u'Case %s was rebuilt from its forms.' % case.name)) return HttpResponseRedirect(reverse('case_details', args=[domain, case_id]))
def case_details(request, domain, case_id): timezone = util.get_timezone(request.couch_user, domain) try: case = get_document_or_404(CommCareCase, domain, case_id)
def saved_report_config(self): config_id = self.request.GET.get('config_id') return get_document_or_404(ReportConfig, self.domain, config_id) if config_id else None
def rows(self): base_link_url = '{}?id={{id}}'.format(reverse('raw_couch')) user_id = self.request.GET.get('individual') if not user_id: return [] # security check get_document_or_404(CommCareUser, self.domain, user_id) def _sync_log_to_row(sync_log): def _fmt_duration(duration): if isinstance(duration, int): return format_datatables_data( '<span class="{cls}">{text}</span>'.format( cls=_bootstrap_class(duration or 0, 60, 20), text=_('{} seconds').format(duration), ), duration ) else: return format_datatables_data( '<span class="label label-default">{text}</span>'.format( text=_("Unknown"), ), -1, ) def _fmt_id(sync_log_id): href = base_link_url.format(id=sync_log_id) return '<a href="{href}" target="_blank">{id:.5}...</a>'.format( href=href, id=sync_log_id ) def _fmt_error_info(sync_log): if not sync_log.had_state_error: return u'<span class="label label-success">✓</span>' else: return (u'<span class="label label-danger">X</span>' u'State error {}<br>Expected hash: {:.10}...').format( _naturaltime_with_hover(sync_log.error_date), sync_log.error_hash, ) def _get_state_hash_display(sync_log): try: return u'{:.10}...'.format(sync_log.get_state_hash()) except SyncLogAssertionError as e: return _(u'Error computing hash! {}').format(e) num_cases = sync_log.case_count() columns = [ _fmt_date(sync_log.date), format_datatables_data(num_cases, num_cases), _fmt_duration(sync_log.duration), ] if self.show_extra_columns: columns.append(_fmt_id(sync_log.get_id)) columns.append(sync_log.log_format) columns.append(_fmt_id(sync_log.previous_log_id) if sync_log.previous_log_id else '---') columns.append(_fmt_error_info(sync_log)) columns.append(_get_state_hash_display(sync_log)) columns.append(_naturaltime_with_hover(sync_log.last_submitted)) columns.append(u'{}<br>{:.10}'.format(_naturaltime_with_hover(sync_log.last_cached), sync_log.hash_at_last_cached)) return columns return [_sync_log_to_row(sync_log) for sync_log in get_sync_logs_for_user(user_id, self.limit)]