Пример #1
0
def prepare_form_multimedia(request, domain):
    """Gets the download_id for the multimedia zip and sends it to the
    exportDownloadService in download_export.ng.js to begin polling for the
    zip file download.
    """
    form_or_case = request.POST.get('form_or_case')
    sms_export = json.loads(request.POST.get('sms_export'))
    permissions = ExportsPermissionsManager(form_or_case, domain, request.couch_user)
    permissions.access_download_export_or_404()

    view_helper = DownloadExportViewHelper.get(request, domain, form_or_case, sms_export)
    filter_form_data = json.loads(request.POST.get('form_data'))
    export_specs = json.loads(request.POST.get('exports'))
    try:
        filter_form = view_helper.get_filter_form(filter_form_data)
    except ExportFormValidationException:
        return json_response({
            'error': _("Please check that you've submitted all required filters."),
        })

    download = DownloadBase()
    export_object = view_helper.get_export(export_specs[0]['export_id'])
    task_kwargs = filter_form.get_multimedia_task_kwargs(export_object, download.download_id, filter_form_data)
    from corehq.apps.reports.tasks import build_form_multimedia_zip
    download.set_task(build_form_multimedia_zip.delay(**task_kwargs))

    return json_response({
        'success': True,
        'download_id': download.download_id,
    })
Пример #2
0
def prepare_form_multimedia(request, domain):
    """Gets the download_id for the multimedia zip and sends it to the
    exportDownloadService in download_export.ng.js to begin polling for the
    zip file download.
    """
    form_or_case = request.POST.get('form_or_case')
    sms_export = json.loads(request.POST.get('sms_export'))
    permissions = ExportsPermissionsManager(form_or_case, domain,
                                            request.couch_user)
    permissions.access_download_export_or_404()

    view_helper = DownloadExportViewHelper.get(request, domain, form_or_case,
                                               sms_export)
    filter_form_data = json.loads(request.POST.get('form_data'))
    export_specs = json.loads(request.POST.get('exports'))
    try:
        filter_form = view_helper.get_filter_form(filter_form_data)
    except ExportFormValidationException:
        return JsonResponse({
            'error':
            _("Please check that you've submitted all required filters."),
        })

    download = DownloadBase()
    export_object = view_helper.get_export(export_specs[0]['export_id'])
    task_kwargs = filter_form.get_multimedia_task_kwargs(
        export_object, download.download_id, filter_form_data)
    from corehq.apps.reports.tasks import build_form_multimedia_zip
    download.set_task(build_form_multimedia_zip.delay(**task_kwargs))

    return JsonResponse({
        'success': True,
        'download_id': download.download_id,
    })
Пример #3
0
def update_emailed_export_data(request, domain):
    permissions = ExportsPermissionsManager(request.GET.get('model_type'), domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=json.loads(request.POST.get('is_deid')))

    export_instance_id = request.POST.get('export_id')
    rebuild_saved_export(export_instance_id, manual=True)
    return json_response({'success': True})
Пример #4
0
def prepare_custom_export(request, domain):
    """Uses the current exports download framework (with some nasty filters)
    to return the current download id to POLL for the download status.
    :return: {
        'success': True,
        'download_id': '<some uuid>',
    }
    """
    form_or_case = request.POST.get('form_or_case')
    sms_export = json.loads(request.POST.get('sms_export'))
    permissions = ExportsPermissionsManager(form_or_case, domain, request.couch_user)
    permissions.access_download_export_or_404()

    view_helper = DownloadExportViewHelper.get(request, domain, form_or_case, sms_export)

    filter_form_data = json.loads(request.POST.get('form_data'))
    try:
        filter_form = view_helper.get_filter_form(filter_form_data)
    except ExportFormValidationException:
        return json_response({
            'error': _("Form did not validate."),
        })
    export_filters = filter_form.get_export_filters(request, filter_form_data)
    export_es_filters = [f.to_es_filter() for f in export_filters]

    export_specs = json.loads(request.POST.get('exports'))
    export_ids = [spec['export_id'] for spec in export_specs]
    export_instances = [view_helper.get_export(export_id) for export_id in export_ids]

    try:
        _check_deid_permissions(permissions, export_instances)
        _check_export_size(domain, export_instances, export_filters)
    except ExportAsyncException as e:
        return json_response({
            'error': str(e),
        })

    # Generate filename
    if len(export_instances) > 1:
        filename = "{}_custom_bulk_export_{}".format(domain, date.today().isoformat())
    else:
        filename = "{} {}".format(export_instances[0].name, date.today().isoformat())

    download = get_export_download(
        domain,
        export_ids,
        view_helper.model,
        request.couch_user.username,
        es_filters=export_es_filters,
        owner_id=request.couch_user.get_id,
        filename=filename,
    )

    view_helper.send_preparation_analytics(export_instances, export_filters)

    return json_response({
        'success': True,
        'download_id': download.download_id,
    })
Пример #5
0
def get_saved_export_progress(request, domain):
    permissions = ExportsPermissionsManager(request.GET.get('model_type'), domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=json.loads(request.GET.get('is_deid')))

    export_instance_id = request.GET.get('export_instance_id')
    return json_response({
        'taskStatus': _get_task_status_json(export_instance_id),
    })
Пример #6
0
    def dispatch(self, request, *args, **kwargs):
        self.permissions = ExportsPermissionsManager(self.form_or_case,
                                                     request.domain,
                                                     request.couch_user)
        self.permissions.access_list_exports_or_404(is_deid=self.is_deid)

        return super(BaseExportListView,
                     self).dispatch(request, *args, **kwargs)
Пример #7
0
    def dispatch(self, request, *args, **kwargs):
        self.permissions = ExportsPermissionsManager(self.form_or_case,
                                                     request.domain,
                                                     request.couch_user)
        self.permissions.access_download_export_or_404()

        return super(BaseDownloadExportView,
                     self).dispatch(request, *args, **kwargs)
Пример #8
0
def get_saved_export_progress(request, domain):
    permissions = ExportsPermissionsManager(request.GET.get('model_type'), domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=json.loads(request.GET.get('is_deid')))

    export_instance_id = request.GET.get('export_instance_id')
    return json_response({
        'taskStatus': _get_task_status_json(export_instance_id),
    })
Пример #9
0
def submit_app_data_drilldown_form(request, domain):
    if json.loads(request.POST.get('is_deid')):
        raise Http404()

    model_type = request.POST.get('model_type')
    permissions = ExportsPermissionsManager(model_type, domain,
                                            request.couch_user)
    permissions.access_list_exports_or_404(is_deid=False)

    form_data = json.loads(request.POST.get('form_data'))
    is_daily_saved_export = json.loads(
        request.POST.get('is_daily_saved_export'))
    is_feed = json.loads(request.POST.get('is_feed'))

    create_form = CreateExportTagForm(permissions.has_form_export_permissions,
                                      permissions.has_case_export_permissions,
                                      form_data)
    if not create_form.is_valid():
        return json_response({
            'success': False,
            'error': _("The form did not validate."),
        })

    from corehq.apps.export.views.new import (
        CreateNewCaseFeedView,
        CreateNewCustomCaseExportView,
        CreateNewCustomFormExportView,
        CreateNewDailySavedCaseExport,
        CreateNewDailySavedFormExport,
        CreateNewFormFeedView,
    )

    if is_daily_saved_export:
        if create_form.cleaned_data['model_type'] == "case":
            export_tag = create_form.cleaned_data['case_type']
            cls = CreateNewCaseFeedView if is_feed else CreateNewDailySavedCaseExport
        else:
            export_tag = create_form.cleaned_data['form']
            cls = CreateNewFormFeedView if is_feed else CreateNewDailySavedFormExport
    elif model_type == 'form':
        export_tag = create_form.cleaned_data['form']
        cls = CreateNewCustomFormExportView
    elif model_type == 'case':
        export_tag = create_form.cleaned_data['case_type']
        cls = CreateNewCustomCaseExportView

    url_params = '?export_tag="{}"'.format(export_tag)
    app_id = create_form.cleaned_data['application']
    if app_id != ApplicationDataRMIHelper.UNKNOWN_SOURCE:
        url_params += '&app_id={}'.format(app_id)

    return json_response({
        'success':
        True,
        'url':
        reverse(cls.urlname, args=[domain]) + url_params,
    })
Пример #10
0
class BaseExportListView(BaseProjectDataView):
    template_name = 'export/export_list.html'
    lead_text = ugettext_lazy('''
        Exports are a way to download data in a variety of formats (CSV, Excel, etc.)
        for use in third-party data analysis tools.
    ''')

    @method_decorator(login_and_domain_required)
    def dispatch(self, request, *args, **kwargs):
        self.permissions = ExportsPermissionsManager(self.form_or_case,
                                                     request.domain,
                                                     request.couch_user)
        self.permissions.access_list_exports_or_404(is_deid=self.is_deid)

        return super(BaseExportListView,
                     self).dispatch(request, *args, **kwargs)

    @property
    def page_context(self):
        return {
            'create_export_form':
            self.create_export_form if not self.is_deid else None,
            'create_export_form_title':
            self.create_export_form_title if not self.is_deid else None,
            'bulk_download_url':
            self.bulk_download_url,
            'allow_bulk_export':
            self.allow_bulk_export,
            'has_edit_permissions':
            self.permissions.has_edit_permissions,
            'is_deid':
            self.is_deid,
            "export_type_caps":
            _("Export"),
            "export_type":
            _("export"),
            "export_type_caps_plural":
            _("Exports"),
            "export_type_plural":
            _("exports"),
            'my_export_type':
            _('My Exports'),
            'shared_export_type':
            _('Exports Shared with Me'),
            "model_type":
            self.form_or_case,
            "static_model_type":
            True,
            'max_exportable_rows':
            MAX_EXPORTABLE_ROWS,
            'lead_text':
            mark_safe(self.lead_text),
            "export_filter_form": (DashboardFeedFilterForm(self.domain_object)
                                   if self.include_saved_filters else None),
            'create_url':
            '#createExportOptionsModal',
        }
Пример #11
0
def update_emailed_export_data(request, domain):
    permissions = ExportsPermissionsManager(request.GET.get('model_type'),
                                            domain, request.couch_user)
    permissions.access_list_exports_or_404(
        is_deid=json.loads(request.POST.get('is_deid')))

    export_instance_id = request.POST.get('export_id')
    rebuild_saved_export(export_instance_id, manual=True)
    return json_response({'success': True})
Пример #12
0
def prepare_custom_export(request, domain):
    """Uses the current exports download framework (with some nasty filters)
    to return the current download id to POLL for the download status.
    :return: {
        'success': True,
        'download_id': '<some uuid>',
    }
    """
    form_or_case = request.POST.get('form_or_case')
    sms_export = json.loads(request.POST.get('sms_export'))
    permissions = ExportsPermissionsManager(form_or_case, domain, request.couch_user)
    permissions.access_download_export_or_404()

    view_helper = DownloadExportViewHelper.get(request, domain, form_or_case, sms_export)

    filter_form_data = json.loads(request.POST.get('form_data'))
    try:
        filter_form = view_helper.get_filter_form(filter_form_data)
    except ExportFormValidationException:
        return json_response({
            'error': _("Form did not validate."),
        })
    export_filters = filter_form.get_export_filters(request, filter_form_data)

    export_specs = json.loads(request.POST.get('exports'))
    export_ids = [spec['export_id'] for spec in export_specs]
    export_instances = [view_helper.get_export(export_id) for export_id in export_ids]

    try:
        _check_deid_permissions(permissions, export_instances)
        _check_export_size(domain, export_instances, export_filters)
    except ExportAsyncException as e:
        return json_response({
            'error': six.text_type(e),
        })

    # Generate filename
    if len(export_instances) > 1:
        filename = "{}_custom_bulk_export_{}".format(domain, date.today().isoformat())
    else:
        filename = "{} {}".format(export_instances[0].name, date.today().isoformat())

    download = get_export_download(
        domain,
        export_ids,
        view_helper.model,
        request.couch_user.username,
        filters=export_filters,
        filename=filename,
    )

    view_helper.send_preparation_analytics(export_instances, export_filters)

    return json_response({
        'success': True,
        'download_id': download.download_id,
    })
Пример #13
0
def submit_app_data_drilldown_form(request, domain):
    if json.loads(request.POST.get('is_deid')):
        raise Http404()

    model_type = request.POST.get('model_type')
    permissions = ExportsPermissionsManager(model_type, domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=False)

    form_data = json.loads(request.POST.get('form_data'))
    is_daily_saved_export = json.loads(request.POST.get('is_daily_saved_export'))
    is_feed = json.loads(request.POST.get('is_feed'))

    create_form = CreateExportTagForm(
        permissions.has_form_export_permissions,
        permissions.has_case_export_permissions,
        form_data
    )
    if not create_form.is_valid():
        return json_response({
            'success': False,
            'error': _("The form did not validate."),
        })

    from corehq.apps.export.views.new import (
        CreateNewCaseFeedView,
        CreateNewCustomCaseExportView,
        CreateNewCustomFormExportView,
        CreateNewDailySavedCaseExport,
        CreateNewDailySavedFormExport,
        CreateNewFormFeedView,
    )

    if is_daily_saved_export:
        if create_form.cleaned_data['model_type'] == "case":
            export_tag = create_form.cleaned_data['case_type']
            cls = CreateNewCaseFeedView if is_feed else CreateNewDailySavedCaseExport
        else:
            export_tag = create_form.cleaned_data['form']
            cls = CreateNewFormFeedView if is_feed else CreateNewDailySavedFormExport
    elif model_type == 'form':
        export_tag = create_form.cleaned_data['form']
        cls = CreateNewCustomFormExportView
    elif model_type == 'case':
        export_tag = create_form.cleaned_data['case_type']
        cls = CreateNewCustomCaseExportView

    url_params = '?export_tag="{}"'.format(export_tag)
    app_id = create_form.cleaned_data['application']
    if app_id != ApplicationDataRMIHelper.UNKNOWN_SOURCE:
        url_params += '&app_id={}'.format(app_id)

    return json_response({
        'success': True,
        'url': reverse(cls.urlname, args=[domain]) + url_params,
    })
Пример #14
0
def toggle_saved_export_enabled(request, domain):
    permissions = ExportsPermissionsManager(request.GET.get('model_type'), domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=json.loads(request.POST.get('is_deid')))

    export_instance_id = request.POST.get('export_id')
    export_instance = get_properly_wrapped_export_instance(export_instance_id)
    export_instance.auto_rebuild_enabled = not json.loads(request.POST.get('is_auto_rebuild_enabled'))
    export_instance.save()
    return json_response({
        'success': True,
        'isAutoRebuildEnabled': export_instance.auto_rebuild_enabled
    })
Пример #15
0
def toggle_saved_export_enabled(request, domain):
    permissions = ExportsPermissionsManager(request.GET.get('model_type'), domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=json.loads(request.POST.get('is_deid')))

    export_instance_id = request.POST.get('export_id')
    export_instance = get_properly_wrapped_export_instance(export_instance_id)
    export_instance.auto_rebuild_enabled = not json.loads(request.POST.get('is_auto_rebuild_enabled'))
    export_instance.save()
    return json_response({
        'success': True,
        'isAutoRebuildEnabled': export_instance.auto_rebuild_enabled
    })
Пример #16
0
def prepare_form_multimedia(request, domain):
    """Gets the download_id for the multimedia zip and sends it to the
    exportDownloadService in download_export.ng.js to begin polling for the
    zip file download.
    """
    form_or_case = request.POST.get('form_or_case')
    sms_export = json.loads(request.POST.get('sms_export'))
    permissions = ExportsPermissionsManager(form_or_case, domain,
                                            request.couch_user)
    permissions.access_download_export_or_404()

    view_helper = DownloadExportViewHelper.get(request, domain, form_or_case,
                                               sms_export)
    filter_form_data = json.loads(request.POST.get('form_data'))
    export_specs = json.loads(request.POST.get('exports'))
    try:
        filter_form = view_helper.get_filter_form(filter_form_data)
    except ExportFormValidationException:
        return json_response({
            'error':
            _("Please check that you've submitted all required filters."),
        })

    export = view_helper.get_export(export_specs[0]['export_id'])
    datespan = filter_form.cleaned_data['date_range']
    user_types = filter_form.get_es_user_types(filter_form_data)

    if media_export_is_too_big(domain, export.app_id, export.xmlns, datespan,
                               user_types):
        return json_response({
            'success':
            False,
            'error':
            _("This is too many files to export at once.  "
              "Please modify your filters to select fewer forms."),
        })

    download = DownloadBase()
    download.set_task(
        build_form_multimedia_zip.delay(
            domain=domain,
            export_id=export.get_id,
            datespan=datespan,
            user_types=user_types,
            download_id=download.download_id,
            owner_id=request.couch_user.get_id,
        ))

    return json_response({
        'success': True,
        'download_id': download.download_id,
    })
Пример #17
0
def has_multimedia(request, domain):
    """Checks to see if this form export has multimedia available to export
    """
    form_or_case = request.GET.get('form_or_case')
    if form_or_case != 'form':
        raise ValueError("has_multimedia is only available for form exports")
    permissions = ExportsPermissionsManager(form_or_case, domain, request.couch_user)
    permissions.access_download_export_or_404()
    export_object = FormExportInstance.get(request.GET.get('export_id'))
    return json_response({
        'success': True,
        'hasMultimedia': export_object.has_multimedia,
    })
Пример #18
0
def update_emailed_export_data(request, domain):

    permissions = ExportsPermissionsManager(request.GET.get('model_type'), domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=json.loads(request.POST.get('is_deid')))

    export_instance_id = request.POST.get('export_id')
    try:
        rebuild_saved_export(export_instance_id, manual=True)
    except XlsLengthException:
        return json_response({
            'error': _('This file has more than 256 columns, which is not supported by xls. '
                       'Please change the output type to csv or xlsx in the export configuration page '
                       'to export this file.')
        })
    return json_response({'success': True})
Пример #19
0
def update_emailed_export_data(request, domain):

    permissions = ExportsPermissionsManager(request.GET.get('model_type'), domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=json.loads(request.POST.get('is_deid')))

    export_instance_id = request.POST.get('export_id')
    try:
        rebuild_saved_export(export_instance_id, manual=True)
    except XlsLengthException:
        return json_response({
            'error': _('This file has more than 256 columns, which is not supported by xls. '
                       'Please change the output type to csv or xlsx in the export configuration page '
                       'to export this file.')
        })
    return json_response({'success': True})
Пример #20
0
 def __init__(self, request):
     super(ExportListHelper, self).__init__()
     self.request = request
     self.domain = request.domain
     self.permissions = ExportsPermissionsManager(self.form_or_case,
                                                  self.domain,
                                                  request.couch_user)
Пример #21
0
def get_exports_page(request, domain):
    permissions = ExportsPermissionsManager(request.GET.get('model_type'), domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=json.loads(request.GET.get('is_deid')))

    helper = ExportListHelper.get(request, form_or_case=request.GET.get('model_type'),
                                  is_daily_saved_export=json.loads(request.GET.get('is_daily_saved_export')),
                                  is_feed=json.loads(request.GET.get('is_feed')),
                                  is_deid=json.loads(request.GET.get('is_deid')))
    page = int(request.GET.get('page', 1))
    limit = int(request.GET.get('limit', 5))
    my_exports = json.loads(request.GET.get('my_exports'))
    (exports, total) = helper.get_exports_page(page, limit, my_exports=my_exports)
    return json_response({
        'exports': exports,
        'total': total,
    })
Пример #22
0
def get_exports_page(request, domain):
    permissions = ExportsPermissionsManager(request.GET.get('model_type'), domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=json.loads(request.GET.get('is_deid')))

    helper = ExportListHelper.get(request, form_or_case=request.GET.get('model_type'),
                                  is_daily_saved_export=json.loads(request.GET.get('is_daily_saved_export')),
                                  is_feed=json.loads(request.GET.get('is_feed')),
                                  is_deid=json.loads(request.GET.get('is_deid')))
    page = int(request.GET.get('page', 1))
    limit = int(request.GET.get('limit', 5))
    my_exports = json.loads(request.GET.get('my_exports'))
    (exports, total) = helper.get_exports_page(page, limit, my_exports=my_exports)
    return json_response({
        'exports': exports,
        'total': total,
    })
Пример #23
0
def poll_custom_export_download(request, domain):
    """Polls celery to see how the export download task is going.
    :return: final response: {
        'success': True,
        'dropbox_url': '<url>',
        'download_url: '<url>',
        <task info>
    }
    """
    form_or_case = request.GET.get('form_or_case')
    permissions = ExportsPermissionsManager(form_or_case, domain,
                                            request.couch_user)
    permissions.access_download_export_or_404()
    download_id = request.GET.get('download_id')
    try:
        context = get_download_context(download_id)
    except TaskFailedError as e:
        if e.exception_name == 'XlsLengthException':
            return JsonResponse({
                'error':
                _('This file has more than 256 columns, which is not supported by xls. '
                  'Please change the output type to csv or xlsx to export this file.'
                  )
            })
        else:
            notify_exception(request,
                             "Export download failed",
                             details={
                                 'download_id': download_id,
                                 'errors': e.errors,
                                 'exception_name': e.exception_name
                             })

            return JsonResponse({
                'error': _("Download task failed to start."),
            })

    if context.get('is_ready', False):
        context.update({
            'dropbox_url':
            reverse('dropbox_upload', args=(download_id, )),
            'download_url':
            "{}?get_file".format(
                reverse('retrieve_download', args=(download_id, ))),
        })
    context['is_poll_successful'] = True
    return json_response(context)
Пример #24
0
def get_app_data_drilldown_values(request, domain):
    if json.loads(request.GET.get('is_deid')):
        raise Http404()

    model_type = request.GET.get('model_type')
    permissions = ExportsPermissionsManager(model_type, domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=False)

    rmi_helper = ApplicationDataRMIHelper(domain, request.couch_user)
    if model_type == 'form':
        response = rmi_helper.get_form_rmi_response()
    elif model_type == 'case':
        response = rmi_helper.get_case_rmi_response()
    else:
        response = rmi_helper.get_dual_model_rmi_response()

    return json_response(response)
Пример #25
0
def get_app_data_drilldown_values(request, domain):
    if json.loads(request.GET.get('is_deid')):
        raise Http404()

    model_type = request.GET.get('model_type')
    permissions = ExportsPermissionsManager(model_type, domain, request.couch_user)
    permissions.access_list_exports_or_404(is_deid=False)

    rmi_helper = ApplicationDataRMIHelper(domain, request.couch_user)
    if model_type == 'form':
        response = rmi_helper.get_form_rmi_response()
    elif model_type == 'case':
        response = rmi_helper.get_case_rmi_response()
    else:
        response = rmi_helper.get_dual_model_rmi_response()

    return json_response(response)
Пример #26
0
def has_multimedia(request, domain):
    """Checks to see if this form export has multimedia available to export
    """
    form_or_case = request.GET.get('form_or_case')
    if form_or_case != 'form':
        raise ValueError("has_multimedia is only available for form exports")
    permissions = ExportsPermissionsManager(form_or_case, domain,
                                            request.couch_user)
    permissions.access_download_export_or_404()
    export_object = FormExportInstance.get(request.GET.get('export_id'))
    if isinstance(export_object, ExportInstance):
        has_multimedia = export_object.has_multimedia
    else:
        has_multimedia = forms_have_multimedia(
            domain, export_object.app_id, getattr(export_object, 'xmlns', ''))
    return JsonResponse({
        'success': True,
        'hasMultimedia': has_multimedia,
    })
Пример #27
0
def poll_custom_export_download(request, domain):
    """Polls celery to see how the export download task is going.
    :return: final response: {
        'success': True,
        'dropbox_url': '<url>',
        'download_url: '<url>',
        <task info>
    }
    """
    form_or_case = request.GET.get('form_or_case')
    permissions = ExportsPermissionsManager(form_or_case, domain, request.couch_user)
    permissions.access_download_export_or_404()
    download_id = request.GET.get('download_id')
    try:
        context = get_download_context(download_id)
    except TaskFailedError as e:
        if e.exception_name == 'XlsLengthException':
            return JsonResponse({
                'error': _(
                    'This file has more than 256 columns, which is not supported by xls. '
                    'Please change the output type to csv or xlsx to export this file.')
            })
        else:
            notify_exception(
                request, "Export download failed",
                details={'download_id': download_id, 'errors': e.errors,
                         'exception_name': e.exception_name})

            return JsonResponse({
                'error': _("Download task failed to start."),
            })

    if context.get('is_ready', False):
        context.update({
            'dropbox_url': reverse('dropbox_upload', args=(download_id,)),
            'download_url': "{}?get_file".format(
                reverse('retrieve_download', args=(download_id,))
            ),
        })
    context['is_poll_successful'] = True
    return json_response(context)
Пример #28
0
def has_multimedia(request, domain):
    """Checks to see if this form export has multimedia available to export
    """
    form_or_case = request.GET.get('form_or_case')
    if form_or_case != 'form':
        raise ValueError("has_multimedia is only available for form exports")
    permissions = ExportsPermissionsManager(form_or_case, domain, request.couch_user)
    permissions.access_download_export_or_404()
    export_object = FormExportInstance.get(request.GET.get('export_id'))
    if isinstance(export_object, ExportInstance):
        has_multimedia = export_object.has_multimedia
    else:
        has_multimedia = forms_have_multimedia(
            domain,
            export_object.app_id,
            getattr(export_object, 'xmlns', '')
        )
    return json_response({
        'success': True,
        'hasMultimedia': has_multimedia,
    })
Пример #29
0
def commit_filters(request, domain):
    permissions = ExportsPermissionsManager(request.POST.get('model_type'),
                                            domain, request.couch_user)
    if not permissions.has_edit_permissions:
        raise Http404
    export_id = request.POST.get('export_id')
    form_data = json.loads(request.POST.get('form_data'))
    export = get_properly_wrapped_export_instance(export_id)
    if export.is_daily_saved_export and not domain_has_privilege(
            domain, DAILY_SAVED_EXPORT):
        raise Http404
    if export.export_format == "html" and not domain_has_privilege(
            domain, EXCEL_DASHBOARD):
        raise Http404
    if export.is_odata_config and not domain_has_privilege(domain, ODATA_FEED):
        raise Http404
    if not export.filters.is_location_safe_for_user(request):
        return location_restricted_response(request)
    domain_object = Domain.get_by_name(domain)
    filter_form = DashboardFeedFilterForm(domain_object,
                                          form_data,
                                          couch_user=request.couch_user)
    if filter_form.is_valid():
        old_can_access_all_locations = export.filters.can_access_all_locations
        old_accessible_location_ids = export.filters.accessible_location_ids
        filters = filter_form.to_export_instance_filters(
            # using existing location restrictions prevents a less restricted user from modifying
            # restrictions on an export that a more restricted user created (which would mean the more
            # restricted user would lose access to the export)
            old_can_access_all_locations,
            old_accessible_location_ids,
            export.type)
        if export.filters != filters:
            export.filters = filters
            export.save()
            if export.is_daily_saved_export:
                rebuild_saved_export(export_id, manual=True)
        return json_response({
            'success':
            True,
            'locationRestrictions':
            ExportListHelper.get_location_restriction_names(
                export.filters.accessible_location_ids),
        })
    else:
        return json_response({
            'success':
            False,
            'error':
            _("Problem saving dashboard feed filters: Invalid form"),
        })
Пример #30
0
def poll_custom_export_download(request, domain):
    """Polls celery to see how the export download task is going.
    :return: final response: {
        'success': True,
        'dropbox_url': '<url>',
        'download_url: '<url>',
        <task info>
    }
    """
    form_or_case = request.GET.get('form_or_case')
    permissions = ExportsPermissionsManager(form_or_case, domain,
                                            request.couch_user)
    permissions.access_download_export_or_404()
    download_id = request.GET.get('download_id')
    try:
        context = get_download_context(download_id)
    except TaskFailedError as e:
        notify_exception(request,
                         "Export download failed",
                         details={
                             'download_id': download_id,
                             'errors': e.errors
                         })
        return JsonResponse({
            'error': _("Download task failed to start."),
        })
    if context.get('is_ready', False):
        context.update({
            'dropbox_url':
            reverse('dropbox_upload', args=(download_id, )),
            'download_url':
            "{}?get_file".format(
                reverse('retrieve_download', args=(download_id, ))),
        })
    context['is_poll_successful'] = True
    return JsonResponse(context)
Пример #31
0
class BaseExportListView(BaseProjectDataView):
    template_name = 'export/export_list.html'

    lead_text = ugettext_lazy('''
        Exports are a way to download data in a variety of formats (CSV, Excel, etc.)
        for use in third-party data analysis tools.
    ''')

    @use_select2
    @method_decorator(login_and_domain_required)
    def dispatch(self, request, *args, **kwargs):
        self.permissions = ExportsPermissionsManager(self.form_or_case, request.domain, request.couch_user)
        self.permissions.access_list_exports_or_404(is_deid=self.is_deid)

        return super(BaseExportListView, self).dispatch(request, *args, **kwargs)

    @property
    def page_context(self):
        return {
            'create_export_form': self.create_export_form if not self.is_deid else None,
            'create_export_form_title': self.create_export_form_title if not self.is_deid else None,
            'bulk_download_url': self.bulk_download_url,
            'allow_bulk_export': self.allow_bulk_export,
            'has_edit_permissions': self.permissions.has_edit_permissions,
            'is_deid': self.is_deid,
            "export_type_caps": _("Export"),
            "export_type": _("export"),
            "export_type_caps_plural": _("Exports"),
            "export_type_plural": _("exports"),
            'my_export_type': _('My Exports'),
            'shared_export_type': _('Exports Shared with Me'),
            "model_type": self.form_or_case,
            "static_model_type": True,
            'max_exportable_rows': MAX_EXPORTABLE_ROWS,
            'lead_text': self.lead_text,
        }
Пример #32
0
class BaseDownloadExportView(HQJSONResponseMixin, BaseProjectDataView):
    template_name = 'export/download_export.html'
    http_method_names = ['get', 'post']
    show_date_range = False
    check_for_multimedia = False
    sms_export = False
    # To serve filters for export from mobile_user_and_group_slugs
    export_filter_class = None

    @use_daterangepicker
    @use_select2
    @method_decorator(login_and_domain_required)
    def dispatch(self, request, *args, **kwargs):
        self.permissions = ExportsPermissionsManager(self.form_or_case, request.domain, request.couch_user)
        self.permissions.access_download_export_or_404()

        return super(BaseDownloadExportView, self).dispatch(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        if not request.is_ajax():
            context = self.get_context_data(**kwargs)
            return self.render_to_response(context)
        return super(BaseDownloadExportView, self).post(request, *args, **kwargs)

    @property
    @memoized
    def view_helper(self):
        return DownloadExportViewHelper.get(self.request, self.domain, self.form_or_case, self.sms_export)

    @property
    @memoized
    def timezone(self):
        return get_timezone(self.domain, self.request.couch_user)

    @property
    @memoized
    def default_datespan(self):
        return datespan_from_beginning(self.domain_object, self.timezone)

    @property
    def page_context(self):
        context = {
            'download_export_form': self.download_export_form,
            'export_list': self.export_list,
            'form_or_case': self.form_or_case,
            'max_column_size': self.max_column_size,
            'show_date_range': self.show_date_range,
            'check_for_multimedia': self.check_for_multimedia,
            'sms_export': self.sms_export,
            'user_types': HQUserType.human_readable
        }
        if (
            self.default_datespan.startdate is not None
            and self.default_datespan.enddate is not None
        ):
            context.update({
                'default_date_range': '{startdate}{separator}{enddate}'.format(
                    startdate=self.default_datespan.startdate.strftime('%Y-%m-%d'),
                    enddate=self.default_datespan.enddate.strftime('%Y-%m-%d'),
                    separator=DateRangePickerWidget.separator,
                ),
            })
        else:
            context.update({
                'default_date_range': _(
                    "You have no submissions in this project."
                ),
                'show_no_submissions_warning': True,
            })
        if self.export_filter_class:
            context['dynamic_filters'] = self.export_filter_class(
                self.request, self.request.domain
            ).render()
        return context

    @property
    @memoized
    def download_export_form(self):
        return self.view_helper.filter_form_class(self.domain_object, timezone=self.timezone)

    @property
    def export_id(self):
        return self.kwargs.get('export_id')

    @property
    def page_url(self):
        if self.export_id:
            return reverse(self.urlname, args=(self.domain, self.export_id))
        return reverse(self.urlname, args=(self.domain,))

    @property
    def export_list(self):
        exports = []
        if (
            self.request.method == 'POST'
            and 'export_list' in self.request.POST
            and not self.request.is_ajax()
        ):
            raw_export_list = json.loads(self.request.POST['export_list'])
            exports = [self.view_helper.get_export(e['id']) for e in raw_export_list]
        elif self.export_id or self.sms_export:
            exports = [self.view_helper.get_export(self.export_id)]

        if not self.permissions.has_view_permissions:
            if self.permissions.has_deid_view_permissions:
                exports = [x for x in exports if x.is_safe]
            else:
                raise Http404()

        # if there are no exports, this page doesn't exist
        if not exports:
            raise Http404()

        exports = [self.download_export_form.format_export_data(e) for e in exports]
        return exports

    @property
    def max_column_size(self):
        try:
            return int(self.request.GET.get('max_column_size', 2000))
        except TypeError:
            return 2000
Пример #33
0
def prepare_custom_export(request, domain):
    """Uses the current exports download framework (with some nasty filters)
    to return the current download id to POLL for the download status.
    :return: {
        'success': True,
        'download_id': '<some uuid>',
    }
    """
    form_or_case = request.POST.get('form_or_case')
    sms_export = json.loads(request.POST.get('sms_export'))
    permissions = ExportsPermissionsManager(form_or_case, domain,
                                            request.couch_user)
    permissions.access_download_export_or_404()

    view_helper = DownloadExportViewHelper.get(request, domain, form_or_case,
                                               sms_export)

    filter_form_data = json.loads(request.POST.get('form_data'))
    try:
        filter_form = view_helper.get_filter_form(filter_form_data)
    except ExportFormValidationException:
        return JsonResponse({
            'error': _("Form did not validate."),
        })
    export_filters = filter_form.get_export_filters(request, filter_form_data)

    export_specs = json.loads(request.POST.get('exports'))
    export_ids = [spec['export_id'] for spec in export_specs]
    export_instances = [
        view_helper.get_export(export_id) for export_id in export_ids
    ]

    try:
        _check_deid_permissions(permissions, export_instances)
        _check_export_size(domain, export_instances, export_filters)
    except ExportAsyncException as e:
        return JsonResponse({
            'error': six.text_type(e),
        })

    # Generate filename
    if len(export_instances) > 1:
        filename = "{}_custom_bulk_export_{}".format(domain,
                                                     date.today().isoformat())
    else:
        filename = "{} {}".format(export_instances[0].name,
                                  date.today().isoformat())

    try:
        download = get_export_download(
            domain,
            export_ids,
            view_helper.model,
            request.couch_user.username,
            filters=export_filters,
            filename=filename,
        )
    except XlsLengthException:
        return JsonResponse({
            'error':
            _('This file has more than 256 columns, which is not supported by xls. '
              'Please change the output type to csv or xlsx to export this file.'
              )
        })

    view_helper.send_preparation_analytics(export_instances, export_filters)

    return JsonResponse({
        'success': True,
        'download_id': download.download_id,
    })
Пример #34
0
class BaseDownloadExportView(HQJSONResponseMixin, BaseProjectDataView):
    template_name = 'export/download_export.html'
    http_method_names = ['get', 'post']
    show_date_range = False
    check_for_multimedia = False
    sms_export = False
    # To serve filters for export from mobile_user_and_group_slugs
    export_filter_class = None

    @use_daterangepicker
    @use_select2
    @method_decorator(login_and_domain_required)
    def dispatch(self, request, *args, **kwargs):
        self.permissions = ExportsPermissionsManager(self.form_or_case,
                                                     request.domain,
                                                     request.couch_user)
        self.permissions.access_download_export_or_404()

        return super(BaseDownloadExportView,
                     self).dispatch(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        if not request.is_ajax():
            context = self.get_context_data(**kwargs)
            return self.render_to_response(context)
        return super(BaseDownloadExportView,
                     self).post(request, *args, **kwargs)

    @property
    @memoized
    def view_helper(self):
        return DownloadExportViewHelper.get(self.request, self.domain,
                                            self.form_or_case, self.sms_export)

    @property
    @memoized
    def timezone(self):
        return get_timezone(self.domain, self.request.couch_user)

    @property
    @memoized
    def default_datespan(self):
        return datespan_from_beginning(self.domain_object, self.timezone)

    @property
    def page_context(self):
        context = {
            'download_export_form': self.download_export_form,
            'export_list': self.export_list,
            'form_or_case': self.form_or_case,
            'max_column_size': self.max_column_size,
            'show_date_range': self.show_date_range,
            'check_for_multimedia': self.check_for_multimedia,
            'sms_export': self.sms_export,
            'user_types': HQUserType.human_readable
        }
        if (self.default_datespan.startdate is not None
                and self.default_datespan.enddate is not None):
            context.update({
                'default_date_range':
                '{startdate}{separator}{enddate}'.format(
                    startdate=self.default_datespan.startdate.strftime(
                        '%Y-%m-%d'),
                    enddate=self.default_datespan.enddate.strftime('%Y-%m-%d'),
                    separator=DateRangePickerWidget.separator,
                ),
            })
        else:
            context.update({
                'default_date_range':
                _("You have no submissions in this project."),
                'show_no_submissions_warning':
                True,
            })
        if self.export_filter_class:
            context['dynamic_filters'] = self.export_filter_class(
                self.request, self.request.domain).render()
        return context

    @property
    @memoized
    def download_export_form(self):
        return self.view_helper.filter_form_class(self.domain_object,
                                                  timezone=self.timezone)

    @property
    def export_id(self):
        return self.kwargs.get('export_id')

    @property
    def page_url(self):
        if self.export_id:
            return reverse(self.urlname, args=(self.domain, self.export_id))
        return reverse(self.urlname, args=(self.domain, ))

    @property
    def export_list(self):
        exports = []
        if (self.request.method == 'POST'
                and 'export_list' in self.request.POST
                and not self.request.is_ajax()):
            raw_export_list = json.loads(self.request.POST['export_list'])
            exports = [
                self.view_helper.get_export(e['id']) for e in raw_export_list
            ]
        elif self.export_id or self.sms_export:
            exports = [self.view_helper.get_export(self.export_id)]

        if not self.permissions.has_view_permissions:
            if self.permissions.has_deid_view_permissions:
                exports = [x for x in exports if x.is_safe]
            else:
                raise Http404()

        # if there are no exports, this page doesn't exist
        if not exports:
            raise Http404()

        exports = [
            self.download_export_form.format_export_data(e) for e in exports
        ]
        return exports

    @property
    def max_column_size(self):
        try:
            return int(self.request.GET.get('max_column_size', 2000))
        except TypeError:
            return 2000
Пример #35
0
    def dispatch(self, request, *args, **kwargs):
        self.permissions = ExportsPermissionsManager(self.form_or_case, request.domain, request.couch_user)
        self.permissions.access_list_exports_or_404(is_deid=self.is_deid)

        return super(BaseExportListView, self).dispatch(request, *args, **kwargs)
Пример #36
0
    def dispatch(self, request, *args, **kwargs):
        self.permissions = ExportsPermissionsManager(self.form_or_case, request.domain, request.couch_user)
        self.permissions.access_download_export_or_404()

        return super(BaseDownloadExportView, self).dispatch(request, *args, **kwargs)
Пример #37
0
 def __init__(self, *args, **kwargs):
     super(DataPaginator, self).__init__(*args, **kwargs)
     self.permissions = ExportsPermissionsManager(None, self.request.domain,
                                                  self.request.couch_user)